diff options
286 files changed, 10135 insertions, 1120 deletions
@@ -1048,9 +1048,11 @@ u-boot.ldr: u-boot # binman # --------------------------------------------------------------------------- +# Use 'make BINMAN_DEBUG=1' to enable debugging quiet_cmd_binman = BINMAN $@ -cmd_binman = $(srctree)/tools/binman/binman -d u-boot.dtb -O . \ - -I . -I $(srctree)/board/$(BOARDDIR) $< +cmd_binman = $(srctree)/tools/binman/binman -u -d u-boot.dtb -O . -m \ + -I . -I $(srctree) -I $(srctree)/board/$(BOARDDIR) \ + $(if $(BINMAN_DEBUG),-D) $(BINMAN_$(@F)) $< OBJCOPYFLAGS_u-boot.ldr.hex := -I binary -O ihex diff --git a/arch/Kconfig b/arch/Kconfig index 9fdd2f7e66..947070fdd3 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -91,6 +91,7 @@ config SANDBOX select SPI select SUPPORT_OF_CONTROL imply BITREVERSE + select BLOBLIST imply CMD_DM imply CMD_GETTIME imply CMD_HASH diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index f0e7fde137..f5d4d39683 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -528,6 +528,12 @@ config ARCH_BCM283X imply CMD_DM imply FAT_WRITE +config ARCH_BCM6858 + bool "Broadcom BCM6858 family" + select DM + select OF_CONTROL + imply CMD_DM + config TARGET_VEXPRESS_CA15_TC2 bool "Support vexpress_ca15_tc2" select CPU_V7A @@ -1490,6 +1496,7 @@ source "board/armltd/vexpress/Kconfig" source "board/armltd/vexpress64/Kconfig" source "board/broadcom/bcm23550_w1d/Kconfig" source "board/broadcom/bcm28155_ap/Kconfig" +source "board/broadcom/bcm968580xref/Kconfig" source "board/broadcom/bcmcygnus/Kconfig" source "board/broadcom/bcmnsp/Kconfig" source "board/broadcom/bcmns2/Kconfig" diff --git a/arch/arm/cpu/armv8/Kconfig b/arch/arm/cpu/armv8/Kconfig index c8bebabdf6..ff42791fb4 100644 --- a/arch/arm/cpu/armv8/Kconfig +++ b/arch/arm/cpu/armv8/Kconfig @@ -144,6 +144,13 @@ config ARMV8_PSCI_CPUS_PER_CLUSTER A value 0 or no definition of it works for single cluster system. System with multi-cluster should difine their own exact value. +config ARMV8_EA_EL3_FIRST + bool "External aborts and SError interrupt exception are taken in EL3" + default n + help + Exception handling at all exception levels for External Abort and + SError interrupt exception are taken in EL3. + if SYS_HAS_ARMV8_SECURE_BASE config ARMV8_SECURE_BASE diff --git a/arch/arm/cpu/armv8/psci.S b/arch/arm/cpu/armv8/psci.S index 097f91bace..358df8fee9 100644 --- a/arch/arm/cpu/armv8/psci.S +++ b/arch/arm/cpu/armv8/psci.S @@ -236,6 +236,28 @@ handle_sync: b unhandled_exception +#ifdef CONFIG_ARMV8_EA_EL3_FIRST +/* + * Override this function if custom error handling is + * needed for asynchronous aborts + */ +ENTRY(plat_error_handler) + ret +ENDPROC(plat_error_handler) +.weak plat_error_handler + +handle_error: + bl psci_get_cpu_id + bl psci_get_cpu_stack_top + mov x9, #1 + msr spsel, x9 + mov sp, x0 + + bl plat_error_handler /* Platform specific error handling */ +deadloop: + b deadloop /* Never return */ +#endif + .align 11 .globl el3_exception_vectors el3_exception_vectors: @@ -261,7 +283,11 @@ el3_exception_vectors: .align 7 b unhandled_exception /* FIQ, Lower EL using AArch64 */ .align 7 +#ifdef CONFIG_ARMV8_EA_EL3_FIRST + b handle_error /* SError, Lower EL using AArch64 */ +#else b unhandled_exception /* SError, Lower EL using AArch64 */ +#endif .align 7 b unhandled_exception /* Sync, Lower EL using AArch32 */ .align 7 diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 1cbb45d679..84b7e5335c 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -100,6 +100,7 @@ dtb-$(CONFIG_ARCH_MVEBU) += \ armada-7040-db-nand.dtb \ armada-8040-db.dtb \ armada-8040-mcbin.dtb \ + armada-8040-clearfog-gt-8k.dtb \ armada-xp-gp.dtb \ armada-xp-maxbcm.dtb \ armada-xp-synology-ds414.dtb \ @@ -559,7 +560,7 @@ dtb-$(CONFIG_TARGET_STM32MP1) += \ stm32mp157c-ed1.dtb \ stm32mp157c-ev1.dtb -dtb-$(CONFIG_SOC_K3_AM6) += k3-am654-base-board.dtb +dtb-$(CONFIG_SOC_K3_AM6) += k3-am654-base-board.dtb k3-am654-r5-base-board.dtb targets += $(dtb-y) diff --git a/arch/arm/dts/am3517-evm.dts b/arch/arm/dts/am3517-evm.dts index 98aadb0f81..1d158cfda1 100644 --- a/arch/arm/dts/am3517-evm.dts +++ b/arch/arm/dts/am3517-evm.dts @@ -127,6 +127,7 @@ status = "okay"; pinctrl-names = "default"; enable-gpios = <&gpio6 16 GPIO_ACTIVE_HIGH>; /* gpio176, lcd INI */ + vcc-supply = <&vdd_io_reg>; port { lcd_in: endpoint { @@ -154,6 +155,7 @@ bl: backlight { compatible = "pwm-backlight"; pinctrl-names = "default"; + power-supply = <&vdd_io_reg>; pinctrl-0 = <&backlight_pins>; pwms = <&pwm11 0 5000000 0>; brightness-levels = <0 10 20 30 40 50 60 70 80 90 100>; @@ -168,6 +170,13 @@ ti,timers = <&timer11>; #pwm-cells = <3>; }; + + /* HS USB Host PHY on PORT 1 */ + hsusb1_phy: hsusb1_phy { + compatible = "usb-nop-xceiv"; + reset-gpios = <&gpio2 25 GPIO_ACTIVE_LOW>; /* gpio_57 */ + #phy-cells = <0>; + }; }; &davinci_emac { @@ -203,6 +212,7 @@ reg = <0x21>; gpio-controller; #gpio-cells = <2>; + vcc-supply = <&vdd_io_reg>; }; }; @@ -220,15 +230,21 @@ cd-gpios = <&gpio4 31 GPIO_ACTIVE_HIGH>; /* gpio_127 */ }; -&mmc2 { +&mmc3 { status = "disabled"; }; -&mmc3 { - status = "disabled"; +&usbhshost { + port1-mode = "ehci-phy"; +}; + +&usbhsehci { + phys = <&hsusb1_phy>; }; &omap3_pmx_core { + pinctrl-names = "default"; + pinctrl-0 = <&hsusb1_rst_pins>; leds_pins: pinmux_leds_pins { pinctrl-single,pins = < @@ -287,4 +303,32 @@ OMAP3_CORE1_IOPAD(0x20fa, PIN_OUTPUT | MUX_MODE0) /* dss_data15.dss_data15 */ >; }; + + hsusb1_rst_pins: pinmux_hsusb1_rst_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x20ba, PIN_OUTPUT | MUX_MODE4) /* gpmc_ncs6.gpio_57 */ + >; + }; +}; + +&omap3_pmx_core2 { + pinctrl-names = "default"; + pinctrl-0 = <&hsusb1_pins>; + + hsusb1_pins: pinmux_hsusb1_pins { + pinctrl-single,pins = < + OMAP3430_CORE2_IOPAD(0x25d8, PIN_OUTPUT | MUX_MODE3) /* etk_clk.hsusb1_stp */ + OMAP3430_CORE2_IOPAD(0x25da, PIN_OUTPUT | MUX_MODE3) /* etk_ctl.hsusb1_clk */ + OMAP3430_CORE2_IOPAD(0x25ec, PIN_INPUT | MUX_MODE3) /* etk_d8.hsusb1_dir */ + OMAP3430_CORE2_IOPAD(0x25ee, PIN_INPUT | MUX_MODE3) /* etk_d9.hsusb1_nxt */ + OMAP3430_CORE2_IOPAD(0x25dc, PIN_INPUT | MUX_MODE3) /* etk_d0.hsusb1_data0 */ + OMAP3430_CORE2_IOPAD(0x25de, PIN_INPUT | MUX_MODE3) /* etk_d1.hsusb1_data1 */ + OMAP3430_CORE2_IOPAD(0x25e0, PIN_INPUT | MUX_MODE3) /* etk_d2.hsusb1_data2 */ + OMAP3430_CORE2_IOPAD(0x25ea, PIN_INPUT | MUX_MODE3) /* etk_d7.hsusb1_data3 */ + OMAP3430_CORE2_IOPAD(0x25e4, PIN_INPUT | MUX_MODE3) /* etk_d4.hsusb1_data4 */ + OMAP3430_CORE2_IOPAD(0x25e6, PIN_INPUT | MUX_MODE3) /* etk_d5.hsusb1_data5 */ + OMAP3430_CORE2_IOPAD(0x25e8, PIN_INPUT | MUX_MODE3) /* etk_d6.hsusb1_data6 */ + OMAP3430_CORE2_IOPAD(0x25e2, PIN_INPUT | MUX_MODE3) /* etk_d3.hsusb1_data7 */ + >; + }; }; diff --git a/arch/arm/dts/am3517-som.dtsi b/arch/arm/dts/am3517-som.dtsi index a6d5ff73c1..dae6e458e5 100644 --- a/arch/arm/dts/am3517-som.dtsi +++ b/arch/arm/dts/am3517-som.dtsi @@ -14,6 +14,32 @@ cpu0-supply = <&vdd_core_reg>; }; }; + + wl12xx_buffer: wl12xx_buf { + compatible = "regulator-fixed"; + regulator-name = "wl1271_buf"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + pinctrl-names = "default"; + pinctrl-0 = <&wl12xx_buffer_pins>; + gpio = <&gpio5 1 GPIO_ACTIVE_LOW>; /* gpio 129 */ + regulator-always-on; + vin-supply = <&vdd_1v8_reg>; + }; + + wl12xx_vmmc2: wl12xx_vmmc2 { + compatible = "regulator-fixed"; + regulator-name = "vwl1271"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + pinctrl-names = "default"; + pinctrl-0 = <&wl12xx_wkup_pins>; + gpio = <&gpio1 3 GPIO_ACTIVE_HIGH >; /* gpio 3 */ + startup-delay-us = <70000>; + enable-active-high; + regulator-always-on; + vin-supply = <&wl12xx_buffer>; + }; }; &gpmc { @@ -64,7 +90,6 @@ regulators { vdd_core_reg: VDCDC1 { regulator-name = "vdd_core"; - compatible = "regulator-fixed"; regulator-always-on; regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1200000>; @@ -72,7 +97,6 @@ vdd_io_reg: VDCDC2 { regulator-name = "vdd_io"; - compatible = "regulator-fixed"; regulator-always-on; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; @@ -80,7 +104,6 @@ vdd_1v8_reg: VDCDC3 { regulator-name = "vdd_1v8"; - compatible = "regulator-fixed"; regulator-always-on; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; @@ -88,7 +111,6 @@ vdd_usb18_reg: LDO1 { regulator-name = "vdd_usb18"; - compatible = "regulator-fixed"; regulator-always-on; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; @@ -96,7 +118,6 @@ vdd_usb33_reg: LDO2 { regulator-name = "vdd_usb33"; - compatible = "regulator-fixed"; regulator-always-on; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; @@ -126,8 +147,63 @@ }; }; +&mmc2 { + interrupts-extended = <&intc 86 /* &omap3_pmx_core 0x12c */>; + + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_pins>; + vmmc-supply = <&wl12xx_vmmc2>; + non-removable; + bus-width = <4>; + cap-power-off-card; + #address-cells = <1>; + #size-cells = <0>; + wlcore: wlcore@2 { + compatible = "ti,wl1271"; + reg = <2>; + interrupt-parent = <&gpio6>; + interrupts = <10 IRQ_TYPE_LEVEL_HIGH>; /* gpio_170 */ + ref-clock-frequency = <26000000>; + tcxo-clock-frequency = <26000000>; + }; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2_pins>; + + bluetooth { + compatible = "ti,wl1271-st"; + enable-gpios = <&gpio2 24 GPIO_ACTIVE_HIGH>; /* gpio 56 */ + max-speed = <3000000>; + }; +}; + &omap3_pmx_core { + wl12xx_buffer_pins: pinmux_wl12xx_buffer_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x2156, PIN_OUTPUT | MUX_MODE4) /* mmc1_dat7.gpio_129 */ + >; + }; + + mmc2_pins: pinmux_mmc2_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x2158, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc2_clk.mmc2_clk */ + OMAP3_CORE1_IOPAD(0x215a, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc2_cmd.mmc2_cmd */ + OMAP3_CORE1_IOPAD(0x215c, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc2_dat0.mmc2_dat0 */ + OMAP3_CORE1_IOPAD(0x215e, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc2_dat1.mmc2_dat1 */ + OMAP3_CORE1_IOPAD(0x2160, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc2_dat2.mmc2_dat2 */ + OMAP3_CORE1_IOPAD(0x2162, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc2_dat3.mmc2_dat3 */ + OMAP3_CORE1_IOPAD(0x2164, PIN_OUTPUT | MUX_MODE1) /* mmc2_dat4.mmc2_dir_dat0 */ + OMAP3_CORE1_IOPAD(0x2166, PIN_OUTPUT | MUX_MODE1) /* mmc2_dat5.mmc2_dir_dat1 */ + OMAP3_CORE1_IOPAD(0x2168, PIN_OUTPUT | MUX_MODE1) /* mmc2_dat6.mmc2_dir_cmd */ + OMAP3_CORE1_IOPAD(0x216a, PIN_INPUT | MUX_MODE1) /* mmc2_dat7.mmc2_clkin */ + OMAP3_CORE1_IOPAD(0x21c6, PIN_INPUT_PULLUP | MUX_MODE4) /* hdq_sio.gpio_170 */ + >; + }; + rtc_pins: pinmux_rtc_pins { pinctrl-single,pins = < OMAP3_CORE1_IOPAD(0x20b6, PIN_INPUT_PULLUP | MUX_MODE4) /* gpmc_ncs4.gpio_55 */ @@ -139,4 +215,23 @@ OMAP3_CORE1_IOPAD(0x20d2, PIN_INPUT | MUX_MODE4) /* gpmc_wait3.gpio_65 */ >; }; + + uart2_pins: pinmux_uart2_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x2174, PIN_INPUT_PULLUP | MUX_MODE0) /* uart2_cts */ + OMAP3_CORE1_IOPAD(0x2176, PIN_OUTPUT_PULLUP | MUX_MODE0) /* uart2_rts */ + OMAP3_CORE1_IOPAD(0x2178, PIN_OUTPUT | MUX_MODE0) /* uart2_tx */ + OMAP3_CORE1_IOPAD(0x217a, PIN_INPUT | MUX_MODE0) /* uart2_rx */ + OMAP3_CORE1_IOPAD(0x20b8, PIN_INPUT | MUX_MODE0) /* gpio_56 */ + >; + }; +}; + +&omap3_pmx_wkup { + + wl12xx_wkup_pins: pinmux_wl12xx_wkup_pins { + pinctrl-single,pins = < + OMAP3_WKUP_IOPAD(0x2a0c, PIN_OUTPUT | MUX_MODE4) /* sys_boot1.gpio_3 */ + >; + }; }; diff --git a/arch/arm/dts/am3517.dtsi b/arch/arm/dts/am3517.dtsi index 4b6062b631..23ea381d36 100644 --- a/arch/arm/dts/am3517.dtsi +++ b/arch/arm/dts/am3517.dtsi @@ -91,6 +91,11 @@ }; }; +/* Table Table 5-79 of the TRM shows 480ab000 is reserved */ +&usb_otg_hs { + status = "disabled"; +}; + &iva { status = "disabled"; }; diff --git a/arch/arm/dts/armada-8040-clearfog-gt-8k.dts b/arch/arm/dts/armada-8040-clearfog-gt-8k.dts new file mode 100644 index 0000000000..498105f25f --- /dev/null +++ b/arch/arm/dts/armada-8040-clearfog-gt-8k.dts @@ -0,0 +1,315 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2018 SolidRun ltd + */ + +#include "armada-8040.dtsi" + +/ { + model = "ClearFog-GT-8K"; + compatible = "solidrun,clearfog-gt-8k", + "marvell,armada8040"; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + aliases { + i2c0 = &cpm_i2c0; + i2c1 = &cpm_i2c1; + spi0 = &cps_spi1; + }; + + memory@00000000 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>; + }; + + simple-bus { + compatible = "simple-bus"; + + reg_usb3h0_vbus: usb3-vbus0 { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&cpm_xhci_vbus_pins>; + regulator-name = "reg-usb3h0-vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + startup-delay-us = <300000>; + shutdown-delay-us = <500000>; + regulator-force-boot-off; + gpio = <&cpm_gpio1 15 GPIO_ACTIVE_LOW>; /* GPIO[47] */ + }; + }; +}; + +&uart0 { + status = "okay"; +}; + +&ap_pinctl { + /* + * MPP Bus: + * eMMC [0-10] + * UART0 [11,19] + */ + /* 0 1 2 3 4 5 6 7 8 9 */ + pin-func = < 1 1 1 1 1 1 1 1 1 1 + 1 3 0 0 0 0 0 0 0 3 >; +}; + +/* on-board eMMC */ +&ap_sdhci0 { + pinctrl-names = "default"; + pinctrl-0 = <&ap_emmc_pins>; + bus-width = <8>; + status = "okay"; +}; + +&cpm_pinctl { + /* + * MPP Bus: + * [0-31] = 0xff: Keep default CP0_shared_pins: + * [11] CLKOUT_MPP_11 (out) + * [23] LINK_RD_IN_CP2CP (in) + * [25] CLKOUT_MPP_25 (out) + * [29] AVS_FB_IN_CP2CP (in) + * [32, 33, 34] pci0/1/2 reset + * [35-38] CP0 I2C1 and I2C0 + * [39] GPIO reset button + * [40,41] LED0 and LED1 + * [43] 1512 phy reset + * [47] USB VBUS EN (active low) + * [48] FAN PWM + * [49] SFP+ present signal + * [50] TPM interrupt + * [51] WLAN0 disable + * [52] WLAN1 disable + * [53] LTE disable + * [54] NFC reset + * [55] Micro SD card detect + * [56-61] Micro SD + */ + /* 0 1 2 3 4 5 6 7 8 9 */ + pin-func = < 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff + 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff + 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff + 0xff 0 0 0 0 2 2 2 2 0 + 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0xe 0xe 0xe 0xe + 0xe 0xe 0 >; + + cpm_xhci_vbus_pins: cpm-xhci-vbus-pins { + marvell,pins = < 47 >; + marvell,function = <0>; + }; + + cps_1g_phy_reset: cps-1g-phy-reset { + marvell,pins = < 43 >; + marvell,function = <0>; + }; +}; + +/* uSD slot */ +&cpm_sdhci0 { + pinctrl-names = "default"; + pinctrl-0 = <&cpm_sdhci_pins>; + bus-width = <4>; + status = "okay"; +}; + +&cpm_pcie0 { + num-lanes = <1>; + status = "okay"; +}; + +&cpm_i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&cpm_i2c0_pins>; + status = "okay"; + clock-frequency = <100000>; +}; + +&cpm_i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&cpm_i2c1_pins>; + status = "okay"; + clock-frequency = <100000>; +}; + +&cpm_sata0 { + status = "okay"; +}; + +&cpm_comphy { + /* + * CP0 Serdes Configuration: + * Lane 0: PCIe0 (x1) + * Lane 1: Not connected + * Lane 2: SFI (10G) + * Lane 3: Not connected + * Lane 4: USB 3.0 host port1 (can be PCIe) + * Lane 5: Not connected + */ + phy0 { + phy-type = <PHY_TYPE_PEX0>; + }; + phy1 { + phy-type = <PHY_TYPE_UNCONNECTED>; + }; + phy2 { + phy-type = <PHY_TYPE_SFI>; + }; + phy3 { + phy-type = <PHY_TYPE_UNCONNECTED>; + }; + phy4 { + phy-type = <PHY_TYPE_USB3_HOST1>; + }; + phy5 { + phy-type = <PHY_TYPE_UNCONNECTED>; + }; +}; + +&cpm_ethernet { + pinctrl-names = "default"; + status = "okay"; +}; + +/* 10G SFI SFP */ +&cpm_eth0 { + status = "okay"; + phy-mode = "sfi"; +}; + +&cps_sata0 { + status = "okay"; +}; + +&cps_usb3_0 { + vbus-supply = <®_usb3h0_vbus>; + status = "okay"; +}; + +&cps_utmi0 { + status = "okay"; +}; + +&cps_pinctl { + /* + * MPP Bus: + * [0-5] TDM + * [6] VHV Enable + * [7] CP1 SPI0 CSn1 (FXS) + * [8] CP1 SPI0 CSn0 (TPM) + * [9.11]CP1 SPI0 MOSI/MISO/CLK + * [13] CP1 SPI1 MISO (TDM and SPI ROM shared) + * [14] CP1 SPI1 CS0n (64Mb SPI ROM) + * [15] CP1 SPI1 MOSI (TDM and SPI ROM shared) + * [16] CP1 SPI1 CLK (TDM and SPI ROM shared) + * [24] Topaz switch reset + * [26] Buzzer + * [27] CP1 SMI MDIO + * [28] CP1 SMI MDC + * [29] CP0 10G SFP TX Disable + * [30] WPS button + * [31] Front panel button + * [32-62] = 0xff: Keep default CP1_shared_pins: + */ + /* 0 1 2 3 4 5 6 7 8 9 */ + pin-func = < 0x4 0x4 0x4 0x4 0x4 0x4 0x0 0x4 0x4 0x4 + 0x4 0x4 0x0 0x3 0x3 0x3 0x3 0xff 0xff 0xff + 0xff 0xff 0xff 0xff 0x0 0xff 0x0 0x8 0x8 0x0 + 0x0 0x0 0x0 0xff 0xff 0xff 0xff 0xff 0xff 0xff + 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff + 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff + 0xff 0xff 0xff>; +}; + +&cps_spi1 { + pinctrl-names = "default"; + pinctrl-0 = <&cps_spi1_pins>; + status = "okay"; + + spi-flash@0 { + compatible = "jedec,spi-nor", "spi-flash"; + reg = <0>; + spi-max-frequency = <10000000>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "U-Boot"; + reg = <0 0x200000>; + }; + partition@200000 { + label = "Filesystem"; + reg = <0x200000 0xce0000>; + }; + }; + }; +}; + +&cps_comphy { + /* + * CP1 Serdes Configuration: + * Lane 0: SATA 1 (RX swapped). Can be PCIe0 + * Lane 1: Not used + * Lane 2: USB HOST 0 + * Lane 3: SGMII1 - Connected to 1512 port + * Lane 4: Not used + * Lane 5: SGMII2 - Connected to Topaz switch + */ + phy0 { + phy-type = <PHY_TYPE_SATA1>; + phy-invert = <PHY_POLARITY_RXD_INVERT>; + }; + phy1 { + phy-type = <PHY_TYPE_UNCONNECTED>; + }; + phy2 { + phy-type = <PHY_TYPE_USB3_HOST0>; + }; + phy3 { + phy-type = <PHY_TYPE_SGMII1>; + phy-speed = <PHY_SPEED_1_25G>; + }; + phy4 { + phy-type = <PHY_TYPE_UNCONNECTED>; + }; + phy5 { + phy-type = <PHY_TYPE_SGMII2>; + phy-speed = <PHY_SPEED_3_125G>; + }; +}; + +&cps_mdio { + phy0: ethernet-phy@0 { + reg = <0>; + }; +}; + +&cps_ethernet { + pinctrl-names = "default"; + pinctrl-0 = <&cps_1g_phy_reset>; + status = "okay"; +}; + +/* 1G SGMII */ +&cps_eth1 { + status = "okay"; + phy-mode = "sgmii"; + phy = <&phy0>; + phy-reset-gpios = <&cpm_gpio1 11 GPIO_ACTIVE_LOW>; +}; + +/* 2.5G to Topaz switch */ +&cps_eth2 { + status = "okay"; + phy-mode = "sgmii"; + phy-speed = <2500>; + phy-reset-gpios = <&cps_gpio0 24 GPIO_ACTIVE_LOW>; +}; diff --git a/arch/arm/dts/at91sam9260-smartweb.dts b/arch/arm/dts/at91sam9260-smartweb.dts index e59781bf45..a22de2d927 100644 --- a/arch/arm/dts/at91sam9260-smartweb.dts +++ b/arch/arm/dts/at91sam9260-smartweb.dts @@ -89,6 +89,7 @@ }; watchdog@fffffd40 { + timeout-sec = <15>; status = "okay"; }; diff --git a/arch/arm/dts/at91sam9g20-taurus.dts b/arch/arm/dts/at91sam9g20-taurus.dts index 7931c0af7b..cee228bb8c 100644 --- a/arch/arm/dts/at91sam9g20-taurus.dts +++ b/arch/arm/dts/at91sam9g20-taurus.dts @@ -98,6 +98,7 @@ }; watchdog@fffffd40 { + timeout-sec = <15>; status = "okay"; }; diff --git a/arch/arm/dts/bcm6858.dtsi b/arch/arm/dts/bcm6858.dtsi new file mode 100644 index 0000000000..9869d729d3 --- /dev/null +++ b/arch/arm/dts/bcm6858.dtsi @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Philippe Reynes <philippe.reynes@softathome.com> + */ + +#include "skeleton64.dtsi" + +/ { + compatible = "brcm,bcm6858"; + #address-cells = <2>; + #size-cells = <2>; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + u-boot,dm-pre-reloc; + + cpu0: cpu@0 { + compatible = "arm,cortex-a53", "arm,armv8"; + device_type = "cpu"; + reg = <0x0 0x0>; + next-level-cache = <&l2>; + u-boot,dm-pre-reloc; + }; + + cpu1: cpu@1 { + compatible = "arm,cortex-a53", "arm,armv8"; + device_type = "cpu"; + reg = <0x0 0x1>; + next-level-cache = <&l2>; + u-boot,dm-pre-reloc; + }; + + cpu2: cpu@2 { + compatible = "arm,cortex-a53", "arm,armv8"; + device_type = "cpu"; + reg = <0x0 0x2>; + next-level-cache = <&l2>; + u-boot,dm-pre-reloc; + }; + + cpu3: cpu@3 { + compatible = "arm,cortex-a53", "arm,armv8"; + device_type = "cpu"; + reg = <0x0 0x3>; + next-level-cache = <&l2>; + u-boot,dm-pre-reloc; + }; + + l2: l2-cache0 { + compatible = "cache"; + u-boot,dm-pre-reloc; + }; + }; + + clocks { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + u-boot,dm-pre-reloc; + + periph_osc: periph-osc { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <200000000>; + u-boot,dm-pre-reloc; + }; + }; + + ubus { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <2>; + u-boot,dm-pre-reloc; + + uart0: serial@ff800640 { + compatible = "brcm,bcm6858-uart"; + reg = <0x0 0xff800640 0x0 0x18>; + clocks = <&periph_osc>; + + status = "disabled"; + }; + }; +}; diff --git a/arch/arm/dts/bcm968580xref.dts b/arch/arm/dts/bcm968580xref.dts new file mode 100644 index 0000000000..0c59f94710 --- /dev/null +++ b/arch/arm/dts/bcm968580xref.dts @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Philippe Reynes <philippe.reynes@softathome.com> + */ + +/dts-v1/; + +#include "bcm6858.dtsi" + +/ { + model = "Broadcom bcm68580xref"; + compatible = "broadcom,bcm68580xref", "brcm,bcm6858"; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x20000000>; + }; +}; + +&uart0 { + u-boot,dm-pre-reloc; + status = "okay"; +}; diff --git a/arch/arm/dts/k3-am65-main.dtsi b/arch/arm/dts/k3-am65-main.dtsi index 2409344df4..adcd6341e4 100644 --- a/arch/arm/dts/k3-am65-main.dtsi +++ b/arch/arm/dts/k3-am65-main.dtsi @@ -8,13 +8,13 @@ &cbass_main { gic500: interrupt-controller@1800000 { compatible = "arm,gic-v3"; - #address-cells = <1>; - #size-cells = <1>; + #address-cells = <2>; + #size-cells = <2>; ranges; #interrupt-cells = <3>; interrupt-controller; - reg = <0x01800000 0x10000>, /* GICD */ - <0x01880000 0x90000>; /* GICR */ + reg = <0x00 0x01800000 0x00 0x10000>, /* GICD */ + <0x00 0x01880000 0x00 0x90000>; /* GICR */ /* * vcpumntirq: * virtual CPU interface maintenance interrupt @@ -23,9 +23,50 @@ gic_its: gic-its@18200000 { compatible = "arm,gic-v3-its"; - reg = <0x01820000 0x10000>; + reg = <0x00 0x01820000 0x00 0x10000>; msi-controller; #msi-cells = <1>; }; }; + + secure_proxy_main: mailbox@32c00000 { + compatible = "ti,am654-secure-proxy"; + #mbox-cells = <1>; + reg-names = "target_data", "rt", "scfg"; + reg = <0x00 0x32c00000 0x00 0x100000>, + <0x00 0x32400000 0x00 0x100000>, + <0x00 0x32800000 0x00 0x100000>; + interrupt-names = "rx_011"; + interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>; + }; + + main_uart0: serial@2800000 { + compatible = "ti,am654-uart"; + reg = <0x00 0x02800000 0x00 0x100>; + reg-shift = <2>; + reg-io-width = <4>; + interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>; + clock-frequency = <48000000>; + current-speed = <115200>; + }; + + main_uart1: serial@2810000 { + compatible = "ti,am654-uart"; + reg = <0x00 0x02810000 0x00 0x100>; + reg-shift = <2>; + reg-io-width = <4>; + interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>; + clock-frequency = <48000000>; + current-speed = <115200>; + }; + + main_uart2: serial@2820000 { + compatible = "ti,am654-uart"; + reg = <0x00 0x02820000 0x00 0x100>; + reg-shift = <2>; + reg-io-width = <4>; + interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>; + clock-frequency = <48000000>; + current-speed = <115200>; + }; }; diff --git a/arch/arm/dts/k3-am65-mcu.dtsi b/arch/arm/dts/k3-am65-mcu.dtsi new file mode 100644 index 0000000000..8c611d16df --- /dev/null +++ b/arch/arm/dts/k3-am65-mcu.dtsi @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Device Tree Source for AM6 SoC Family MCU Domain peripherals + * + * Copyright (C) 2016-2018 Texas Instruments Incorporated - http://www.ti.com/ + */ + +&cbass_mcu { + mcu_uart0: serial@40a00000 { + compatible = "ti,am654-uart"; + reg = <0x00 0x40a00000 0x00 0x100>; + reg-shift = <2>; + reg-io-width = <4>; + interrupts = <GIC_SPI 565 IRQ_TYPE_LEVEL_HIGH>; + clock-frequency = <96000000>; + current-speed = <115200>; + }; +}; diff --git a/arch/arm/dts/k3-am65-wakeup.dtsi b/arch/arm/dts/k3-am65-wakeup.dtsi new file mode 100644 index 0000000000..8d7b47f9df --- /dev/null +++ b/arch/arm/dts/k3-am65-wakeup.dtsi @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Device Tree Source for AM6 SoC Family Wakeup Domain peripherals + * + * Copyright (C) 2016-2018 Texas Instruments Incorporated - http://www.ti.com/ + */ + +&cbass_wakeup { + dmsc: dmsc { + compatible = "ti,k2g-sci"; + ti,host-id = <12>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + mbox-names = "rx", "tx"; + + mboxes= <&secure_proxy_main 11>, + <&secure_proxy_main 13>; + + k3_pds: power-controller { + compatible = "ti,sci-pm-domain"; + #power-domain-cells = <1>; + }; + + k3_clks: clocks { + compatible = "ti,k2g-sci-clk"; + #clock-cells = <2>; + }; + + k3_reset: reset-controller { + compatible = "ti,sci-reset"; + #reset-cells = <2>; + }; + }; + + wkup_uart0: serial@42300000 { + compatible = "ti,am654-uart"; + reg = <0x42300000 0x100>; + reg-shift = <2>; + reg-io-width = <4>; + interrupts = <GIC_SPI 697 IRQ_TYPE_LEVEL_HIGH>; + clock-frequency = <48000000>; + current-speed = <115200>; + }; +}; diff --git a/arch/arm/dts/k3-am65.dtsi b/arch/arm/dts/k3-am65.dtsi index cede1fa098..3d4bf369d0 100644 --- a/arch/arm/dts/k3-am65.dtsi +++ b/arch/arm/dts/k3-am65.dtsi @@ -16,6 +16,14 @@ #address-cells = <2>; #size-cells = <2>; + aliases { + serial0 = &wkup_uart0; + serial1 = &mcu_uart0; + serial2 = &main_uart0; + serial3 = &main_uart1; + serial4 = &main_uart2; + }; + chosen { }; firmware { @@ -46,38 +54,38 @@ cbass_main: interconnect@100000 { compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x00100000 0x00 0x00100000 0x00020000>, /* ctrl mmr */ - <0x00600000 0x00 0x00600000 0x00001100>, /* GPIO */ - <0x00900000 0x00 0x00900000 0x00012000>, /* serdes */ - <0x01000000 0x00 0x01000000 0x0af02400>, /* Most peripherals */ - <0x30800000 0x00 0x30800000 0x0bc00000>, /* MAIN NAVSS */ + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x00 0x00100000 0x00 0x00100000 0x00 0x00020000>, /* ctrl mmr */ + <0x00 0x00600000 0x00 0x00600000 0x00 0x00001100>, /* GPIO */ + <0x00 0x00900000 0x00 0x00900000 0x00 0x00012000>, /* serdes */ + <0x00 0x01000000 0x00 0x01000000 0x00 0x0af02400>, /* Most peripherals */ + <0x00 0x30800000 0x00 0x30800000 0x00 0x0bc00000>, /* MAIN NAVSS */ /* MCUSS Range */ - <0x28380000 0x00 0x28380000 0x03880000>, - <0x40200000 0x00 0x40200000 0x00900100>, - <0x42040000 0x00 0x42040000 0x03ac2400>, - <0x45100000 0x00 0x45100000 0x00c24000>, - <0x46000000 0x00 0x46000000 0x00200000>, - <0x47000000 0x00 0x47000000 0x00068400>; + <0x00 0x28380000 0x00 0x28380000 0x00 0x03880000>, + <0x00 0x40200000 0x00 0x40200000 0x00 0x00900100>, + <0x00 0x42040000 0x00 0x42040000 0x00 0x03ac2400>, + <0x00 0x45100000 0x00 0x45100000 0x00 0x00c24000>, + <0x00 0x46000000 0x00 0x46000000 0x00 0x00200000>, + <0x00 0x47000000 0x00 0x47000000 0x00 0x00068400>; cbass_mcu: interconnect@28380000 { compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x28380000 0x28380000 0x03880000>, /* MCU NAVSS*/ - <0x40200000 0x40200000 0x00900100>, /* First peripheral window */ - <0x42040000 0x42040000 0x03ac2400>, /* WKUP */ - <0x45100000 0x45100000 0x00c24000>, /* MMRs, remaining NAVSS */ - <0x46000000 0x46000000 0x00200000>, /* CPSW */ - <0x47000000 0x47000000 0x00068400>; /* OSPI space 1 */ + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x00 0x28380000 0x00 0x28380000 0x00 0x03880000>, /* MCU NAVSS*/ + <0x00 0x40200000 0x00 0x40200000 0x00 0x00900100>, /* First peripheral window */ + <0x00 0x42040000 0x00 0x42040000 0x00 0x03ac2400>, /* WKUP */ + <0x00 0x45100000 0x00 0x45100000 0x00 0x00c24000>, /* MMRs, remaining NAVSS */ + <0x00 0x46000000 0x00 0x46000000 0x00 0x00200000>, /* CPSW */ + <0x00 0x47000000 0x00 0x47000000 0x00 0x00068400>; /* OSPI space 1 */ cbass_wakeup: interconnect@42040000 { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; /* WKUP Basic peripherals */ - ranges = <0x42040000 0x42040000 0x03ac2400>; + ranges = <0x42040000 0x00 0x42040000 0x03ac2400>; }; }; }; @@ -85,3 +93,5 @@ /* Now include the peripherals for each bus segments */ #include "k3-am65-main.dtsi" +#include "k3-am65-mcu.dtsi" +#include "k3-am65-wakeup.dtsi" diff --git a/arch/arm/dts/k3-am654-base-board-ddr4-1600MHz.dtsi b/arch/arm/dts/k3-am654-base-board-ddr4-1600MHz.dtsi new file mode 100644 index 0000000000..e861cb7c67 --- /dev/null +++ b/arch/arm/dts/k3-am654-base-board-ddr4-1600MHz.dtsi @@ -0,0 +1,156 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ + * This file was generated by the AM65x_DRA80xM EMIF Tool: + * http://www.ti.com/lit/pdf/spracj0 + * Configuration Parameters + * Memory Type: DDR4 + * Data Rate: 1600 + * ECC Enabled: No + * Data Width: 32 + */ +#define DDR_PLL_FREQUENCY 400000000 +#define DDRCTL_MSTR 0x41040010 +#define DDRCTL_RFSHCTL0 0x00210070 +#define DDRCTL_ECCCFG0 0x00000000 +#define DDRCTL_RFSHTMG 0x0061008C +#define DDRCTL_CRCPARCTL0 0x00008000 +#define DDRCTL_CRCPARCTL1 0x1A000000 +#define DDRCTL_CRCPARCTL2 0x0048051E +#define DDRCTL_INIT0 0x400100C4 +#define DDRCTL_INIT1 0x004F0000 +#define DDRCTL_INIT3 0x02140501 +#define DDRCTL_INIT4 0x00000020 +#define DDRCTL_INIT5 0x00100000 +#define DDRCTL_INIT6 0x00000480 +#define DDRCTL_INIT7 0x000004E8 +#define DDRCTL_DRAMTMG0 0x0C0A1B0D +#define DDRCTL_DRAMTMG1 0x00030313 +#define DDRCTL_DRAMTMG2 0x0506050A +#define DDRCTL_DRAMTMG3 0x0000400C +#define DDRCTL_DRAMTMG4 0x06020206 +#define DDRCTL_DRAMTMG5 0x04040302 +#define DDRCTL_DRAMTMG6 0x00000004 +#define DDRCTL_DRAMTMG7 0x00000404 +#define DDRCTL_DRAMTMG8 0x03030C05 +#define DDRCTL_DRAMTMG9 0x00020208 +#define DDRCTL_DRAMTMG10 0x001C180A +#define DDRCTL_DRAMTMG11 0x1106010E +#define DDRCTL_DRAMTMG12 0x00020008 +#define DDRCTL_DRAMTMG13 0x0B100002 +#define DDRCTL_DRAMTMG14 0x00000000 +#define DDRCTL_DRAMTMG15 0x0000003F +#define DDRCTL_DRAMTMG17 0x00500028 +#define DDRCTL_ZQCTL0 0x21000040 +#define DDRCTL_ZQCTL1 0x0202FAF0 +#define DDRCTL_DFITMG0 0x04888206 +#define DDRCTL_DFITMG1 0x000A0606 +#define DDRCTL_DFITMG2 0x00000604 +#define DDRCTL_DFIMISC 0x00000001 +#define DDRCTL_ADDRMAP0 0x001F1F1F +#define DDRCTL_ADDRMAP1 0x003F0808 +#define DDRCTL_ADDRMAP2 0x00000000 +#define DDRCTL_ADDRMAP3 0x00000000 +#define DDRCTL_ADDRMAP4 0x00001F1F +#define DDRCTL_ADDRMAP5 0x08080808 +#define DDRCTL_ADDRMAP6 0x08080808 +#define DDRCTL_ADDRMAP7 0x00000F0F +#define DDRCTL_ADDRMAP8 0x00000A0A +#define DDRCTL_ADDRMAP9 0x00000000 +#define DDRCTL_ADDRMAP10 0x00000000 +#define DDRCTL_ADDRMAP11 0x001F1F00 +#define DDRCTL_DQMAP0 0x00000000 +#define DDRCTL_DQMAP1 0x00000000 +#define DDRCTL_DQMAP4 0x00000000 +#define DDRCTL_DQMAP5 0x00000000 +#define DDRCTL_PWRCTL 0x00000000 +#define DDRCTL_RANKCTL 0x00000000 +#define DDRCTL_ODTCFG 0x0600060C +#define DDRCTL_ODTMAP 0x00000001 +#define DDRPHY_PGCR0 0x07001E00 +#define DDRPHY_PGCR1 0x020046C0 +#define DDRPHY_PGCR2 0x00F0BFE0 +#define DDRPHY_PGCR3 0x55AA0080 +#define DDRPHY_PGCR6 0x00013001 +#define DDRPHY_PTR2 0x00083DEF +#define DDRPHY_PTR3 0x00061A80 +#define DDRPHY_PTR4 0x00000120 +#define DDRPHY_PTR5 0x00027100 +#define DDRPHY_PTR6 0x04000320 +#define DDRPHY_PLLCR0 0x021c4000 +#define DDRPHY_DXCCR 0x00000038 +#define DDRPHY_DSGCR 0x02A0C129 +#define DDRPHY_DCR 0x0000040C +#define DDRPHY_DTPR0 0x041A0B06 +#define DDRPHY_DTPR1 0x28140000 +#define DDRPHY_DTPR2 0x0034E300 +#define DDRPHY_DTPR3 0x02800800 +#define DDRPHY_DTPR4 0x31180805 +#define DDRPHY_DTPR5 0x00250B06 +#define DDRPHY_DTPR6 0x00000505 +#define DDRPHY_ZQCR 0x008A2A58 +#define DDRPHY_ZQ0PR0 0x000077DD +#define DDRPHY_ZQ1PR0 0x000077DD +#define DDRPHY_MR0 0x00000214 +#define DDRPHY_MR1 0x00000501 +#define DDRPHY_MR2 0x00000000 +#define DDRPHY_MR3 0x00000020 +#define DDRPHY_MR4 0x00000000 +#define DDRPHY_MR5 0x00000480 +#define DDRPHY_MR6 0x000004E8 +#define DDRPHY_MR11 0x00000000 +#define DDRPHY_MR12 0x00000000 +#define DDRPHY_MR13 0x00000000 +#define DDRPHY_MR14 0x00000000 +#define DDRPHY_MR22 0x00000000 +#define DDRPHY_VTCR0 0xF3C32028 +#define DDRPHY_DX8SL0PLLCR0 0x021c4000 +#define DDRPHY_DX8SL1PLLCR0 0x021c4000 +#define DDRPHY_DX8SL2PLLCR0 0x021c4000 +#define DDRPHY_DTCR0 0x8000B1C7 +#define DDRPHY_DTCR1 0x00010236 +#define DDRPHY_ACIOCR5 0x04800000 +#define DDRPHY_IOVCR0 0x0F0C0C0C +#define DDRPHY_DX0GCR0 0x00000000 +#define DDRPHY_DX0GCR1 0x00000000 +#define DDRPHY_DX0GCR2 0x00000000 +#define DDRPHY_DX0GCR3 0x00000000 +#define DDRPHY_DX1GCR0 0x00000000 +#define DDRPHY_DX1GCR1 0x00000000 +#define DDRPHY_DX1GCR2 0x00000000 +#define DDRPHY_DX1GCR3 0x00000000 +#define DDRPHY_DX2GCR0 0x40700204 +#define DDRPHY_DX2GCR1 0x00007FFF +#define DDRPHY_DX2GCR2 0x00000000 +#define DDRPHY_DX2GCR3 0xFFC0010B +#define DDRPHY_DX3GCR0 0x40700204 +#define DDRPHY_DX3GCR1 0x00007FFF +#define DDRPHY_DX3GCR2 0x00000000 +#define DDRPHY_DX3GCR3 0xFFC0010B +#define DDRPHY_DX4GCR0 0x40703220 +#define DDRPHY_DX4GCR1 0x55556000 +#define DDRPHY_DX4GCR2 0xAAAA0000 +#define DDRPHY_DX4GCR3 0xFFE18587 +#define DDRPHY_DX0GCR4 0x0E00B03C +#define DDRPHY_DX1GCR4 0x0E00B03C +#define DDRPHY_DX2GCR4 0x0E00B03C +#define DDRPHY_DX3GCR4 0x0E00B03C +#define DDRPHY_DX4GCR4 0x0E00B03C +#define DDRPHY_PGCR5 0x01010004 +#define DDRPHY_DX0GCR5 0x00000049 +#define DDRPHY_DX1GCR5 0x00000049 +#define DDRPHY_DX2GCR5 0x00000049 +#define DDRPHY_DX3GCR5 0x00000049 +#define DDRPHY_DX4GCR5 0x00000049 +#define DDRPHY_DX0GTR0 0x00020002 +#define DDRPHY_DX1GTR0 0x00020002 +#define DDRPHY_DX2GTR0 0x00020002 +#define DDRPHY_DX3GTR0 0x00020002 +#define DDRPHY_DX4GTR0 0x00020002 +#define DDRPHY_ODTCR 0x00010000 +#define DDRPHY_DX8SL0IOCR 0x04800000 +#define DDRPHY_DX8SL1IOCR 0x04800000 +#define DDRPHY_DX8SL2IOCR 0x04800000 +#define DDRPHY_DX8SL0DXCTL2 0x00141830 +#define DDRPHY_DX8SL1DXCTL2 0x00141830 +#define DDRPHY_DX8SL2DXCTL2 0x00141830 diff --git a/arch/arm/dts/k3-am654-base-board-u-boot.dtsi b/arch/arm/dts/k3-am654-base-board-u-boot.dtsi index d4ecb3be10..143eb6d630 100644 --- a/arch/arm/dts/k3-am654-base-board-u-boot.dtsi +++ b/arch/arm/dts/k3-am654-base-board-u-boot.dtsi @@ -17,56 +17,10 @@ &cbass_main{ u-boot,dm-spl; - secure_proxy: secure_proxy@32c00000 { - compatible = "ti,am654-secure-proxy"; - #mbox-cells = <1>; - reg-names = "target_data", "rt", "scfg"; - reg = <0x32c00000 0x100000>, - <0x32400000 0x100000>, - <0x32800000 0x100000>; - interrupt-names = "rx_011"; - interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>; - }; - - dmsc: dmsc { - compatible = "ti,k2g-sci"; - ti,host-id = <12>; - #address-cells = <1>; - #size-cells = <1>; - ranges; - /* - * In case of rare platforms that does not use am6 as - * system master, use /delete-property/ - */ - ti,system-reboot-controller; - mbox-names = "rx", "tx"; - - mboxes= <&secure_proxy 11>, - <&secure_proxy 13>; - - k3_pds: power-controller { - compatible = "ti,sci-pm-domain"; - #power-domain-cells = <1>; - }; - - k3_clks: clocks { - compatible = "ti,k2g-sci-clk"; - #clock-cells = <2>; - }; - - k3_reset: reset-controller { - compatible = "ti,sci-reset"; - #reset-cells = <2>; - }; - - k3_sysreset: sysreset-controller { - compatible = "ti,sci-sysreset"; - }; - }; main_pmx0: pinmux@11c000 { compatible = "pinctrl-single"; - reg = <0x11c000 0x2e4>; + reg = <0x0 0x11c000 0x0 0x2e4>; #pinctrl-cells = <1>; pinctrl-single,register-width = <32>; pinctrl-single,function-mask = <0xffffffff>; @@ -74,28 +28,16 @@ main_pmx1: pinmux@11c2e8 { compatible = "pinctrl-single"; - reg = <0x11c2e8 0x24>; + reg = <0x0 0x11c2e8 0x0 0x24>; #pinctrl-cells = <1>; pinctrl-single,register-width = <32>; pinctrl-single,function-mask = <0xffffffff>; }; - main_uart0: serial@2800000 { - compatible = "ti,am654-uart", "ti,omap4-uart", "ns16550a"; - reg = <0x02800000 0x100>; - reg-shift = <2>; - reg-io-width = <4>; - interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>; - clock-frequency = <48000000>; - current-speed = <115200>; - status = "disabled"; - u-boot,dm-pre-reloc; - }; - sdhci0: sdhci@04F80000 { compatible = "arasan,sdhci-5.1"; - reg = <0x4F80000 0x1000>, - <0x4F90000 0x400>; + reg = <0x0 0x4F80000 0x0 0x1000>, + <0x0 0x4F90000 0x0 0x400>; clocks = <&k3_clks 47 1>; power-domains = <&k3_pds 47>; max-frequency = <25000000>; @@ -103,8 +45,8 @@ sdhci1: sdhci@04FA0000 { compatible = "arasan,sdhci-5.1"; - reg = <0x4FA0000 0x1000>, - <0x4FB0000 0x400>; + reg = <0x0 0x4FA0000 0x0 0x1000>, + <0x0 0x4FB0000 0x0 0x400>; clocks = <&k3_clks 48 1>; power-domains = <&k3_pds 48>; max-frequency = <25000000>; @@ -112,12 +54,31 @@ }; -&secure_proxy { +&cbass_mcu { + u-boot,dm-spl; + wkup_pmx0: pinmux@4301c000 { + compatible = "pinctrl-single"; + reg = <0x0 0x4301c000 0x0 0x118>; + #pinctrl-cells = <1>; + pinctrl-single,register-width = <32>; + pinctrl-single,function-mask = <0xffffffff>; + }; +}; + +&cbass_wakeup { + u-boot,dm-spl; +}; + +&secure_proxy_main { u-boot,dm-spl; }; &dmsc { u-boot,dm-spl; + k3_sysreset: sysreset-controller { + compatible = "ti,sci-sysreset"; + u-boot,dm-spl; + }; }; &k3_pds { @@ -141,6 +102,7 @@ AM65X_IOPAD(0x01ec, PIN_INPUT | MUX_MODE0) /* (AG11) UART0_CTSn */ AM65X_IOPAD(0x01f0, PIN_OUTPUT | MUX_MODE0) /* (AD11) UART0_RTSn */ >; + u-boot,dm-spl; }; main_mmc0_pins_default: main_mmc0_pins_default { @@ -157,6 +119,7 @@ AM65X_IOPAD(0x0188, PIN_INPUT_PULLUP | MUX_MODE0) /* (D25) MMC0_DAT7 */ AM65X_IOPAD(0x01b0, PIN_INPUT | MUX_MODE0) /* (C25) MMC0_DS */ >; + u-boot,dm-spl; }; main_mmc1_pins_default: main_mmc1_pins_default { @@ -170,6 +133,7 @@ AM65X_IOPAD(0x02dc, PIN_INPUT_PULLUP | MUX_MODE0) /* (B24) MMC1_SDCD */ AM65X_IOPAD(0x02e0, PIN_INPUT | MUX_MODE0) /* (C24) MMC1_SDWP */ >; + u-boot,dm-spl; }; }; diff --git a/arch/arm/dts/k3-am654-ddr.dtsi b/arch/arm/dts/k3-am654-ddr.dtsi new file mode 100644 index 0000000000..964eb173eb --- /dev/null +++ b/arch/arm/dts/k3-am654-ddr.dtsi @@ -0,0 +1,196 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ + */ + +/ { + memorycontroller: memorycontroller@0298e000 { + compatible = "ti,am654-ddrss"; + reg = <0x0 0x0298e000 0x0 0x200>, + <0x0 0x02980000 0x0 0x4000>, + <0x0 0x02988000 0x0 0x2000>; + reg-names = "ss", "ctl", "phy"; + clocks = <&k3_clks 20 0>; + power-domains = <&k3_pds 20>, + <&k3_pds 244>; + assigned-clocks = <&k3_clks 20 1>; + assigned-clock-rates = <DDR_PLL_FREQUENCY>; + u-boot,dm-spl; + + ti,ctl-reg = < + DDRCTL_DFIMISC + DDRCTL_DFITMG0 + DDRCTL_DFITMG1 + DDRCTL_DFITMG2 + DDRCTL_INIT0 + DDRCTL_INIT1 + DDRCTL_INIT3 + DDRCTL_INIT4 + DDRCTL_INIT5 + DDRCTL_INIT6 + DDRCTL_INIT7 + DDRCTL_MSTR + DDRCTL_ODTCFG + DDRCTL_ODTMAP + DDRCTL_RANKCTL + DDRCTL_RFSHCTL0 + DDRCTL_RFSHTMG + DDRCTL_ZQCTL0 + DDRCTL_ZQCTL1 + >; + + ti,ctl-crc = < + DDRCTL_CRCPARCTL0 + DDRCTL_CRCPARCTL1 + DDRCTL_CRCPARCTL2 + >; + + ti,ctl-ecc = < + DDRCTL_ECCCFG0 + >; + + ti,ctl-map = < + DDRCTL_ADDRMAP0 + DDRCTL_ADDRMAP1 + DDRCTL_ADDRMAP2 + DDRCTL_ADDRMAP3 + DDRCTL_ADDRMAP4 + DDRCTL_ADDRMAP5 + DDRCTL_ADDRMAP6 + DDRCTL_ADDRMAP7 + DDRCTL_ADDRMAP8 + DDRCTL_ADDRMAP9 + DDRCTL_ADDRMAP10 + DDRCTL_ADDRMAP11 + DDRCTL_DQMAP0 + DDRCTL_DQMAP1 + DDRCTL_DQMAP4 + DDRCTL_DQMAP5 + >; + + ti,ctl-pwr = < + DDRCTL_PWRCTL + >; + + ti,ctl-timing = < + DDRCTL_DRAMTMG0 + DDRCTL_DRAMTMG1 + DDRCTL_DRAMTMG2 + DDRCTL_DRAMTMG3 + DDRCTL_DRAMTMG4 + DDRCTL_DRAMTMG5 + DDRCTL_DRAMTMG6 + DDRCTL_DRAMTMG7 + DDRCTL_DRAMTMG8 + DDRCTL_DRAMTMG9 + DDRCTL_DRAMTMG11 + DDRCTL_DRAMTMG12 + DDRCTL_DRAMTMG13 + DDRCTL_DRAMTMG14 + DDRCTL_DRAMTMG15 + DDRCTL_DRAMTMG17 + >; + + ti,phy-cfg = < + DDRPHY_DCR + DDRPHY_DSGCR + DDRPHY_DX0GCR0 + DDRPHY_DX0GCR1 + DDRPHY_DX0GCR2 + DDRPHY_DX0GCR3 + DDRPHY_DX0GCR4 + DDRPHY_DX0GCR5 + DDRPHY_DX0GTR0 + DDRPHY_DX1GCR0 + DDRPHY_DX1GCR1 + DDRPHY_DX1GCR2 + DDRPHY_DX1GCR3 + DDRPHY_DX1GCR4 + DDRPHY_DX1GCR5 + DDRPHY_DX1GTR0 + DDRPHY_DX2GCR0 + DDRPHY_DX2GCR1 + DDRPHY_DX2GCR2 + DDRPHY_DX2GCR3 + DDRPHY_DX2GCR4 + DDRPHY_DX2GCR5 + DDRPHY_DX2GTR0 + DDRPHY_DX3GCR0 + DDRPHY_DX3GCR1 + DDRPHY_DX3GCR2 + DDRPHY_DX3GCR3 + DDRPHY_DX3GCR4 + DDRPHY_DX3GCR5 + DDRPHY_DX3GTR0 + DDRPHY_DX4GCR0 + DDRPHY_DX4GCR1 + DDRPHY_DX4GCR2 + DDRPHY_DX4GCR3 + DDRPHY_DX4GCR4 + DDRPHY_DX4GCR5 + DDRPHY_DX4GTR0 + DDRPHY_DX8SL0DXCTL2 + DDRPHY_DX8SL0IOCR + DDRPHY_DX8SL0PLLCR0 + DDRPHY_DX8SL1DXCTL2 + DDRPHY_DX8SL1IOCR + DDRPHY_DX8SL1PLLCR0 + DDRPHY_DX8SL2DXCTL2 + DDRPHY_DX8SL2IOCR + DDRPHY_DX8SL2PLLCR0 + DDRPHY_DXCCR + DDRPHY_ODTCR + DDRPHY_PGCR0 + DDRPHY_PGCR1 + DDRPHY_PGCR2 + DDRPHY_PGCR3 + DDRPHY_PGCR5 + DDRPHY_PGCR6 + >; + + ti,phy-ctl = < + DDRPHY_DTCR0 + DDRPHY_DTCR1 + DDRPHY_MR0 + DDRPHY_MR1 + DDRPHY_MR2 + DDRPHY_MR3 + DDRPHY_MR4 + DDRPHY_MR5 + DDRPHY_MR6 + DDRPHY_MR11 + DDRPHY_MR12 + DDRPHY_MR13 + DDRPHY_MR14 + DDRPHY_MR22 + DDRPHY_PLLCR0 + DDRPHY_VTCR0 + >; + + ti,phy-ioctl = < + DDRPHY_ACIOCR5 + DDRPHY_IOVCR0 + >; + + ti,phy-timing = < + DDRPHY_DTPR0 + DDRPHY_DTPR1 + DDRPHY_DTPR2 + DDRPHY_DTPR3 + DDRPHY_DTPR4 + DDRPHY_DTPR5 + DDRPHY_DTPR6 + DDRPHY_PTR2 + DDRPHY_PTR3 + DDRPHY_PTR4 + DDRPHY_PTR5 + DDRPHY_PTR6 + >; + + ti,phy-zq = < + DDRPHY_ZQ0PR0 + DDRPHY_ZQ1PR0 + DDRPHY_ZQCR + >; + }; +}; diff --git a/arch/arm/dts/k3-am654-r5-base-board.dts b/arch/arm/dts/k3-am654-r5-base-board.dts new file mode 100644 index 0000000000..081a2eceb2 --- /dev/null +++ b/arch/arm/dts/k3-am654-r5-base-board.dts @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2016-2018 Texas Instruments Incorporated - http://www.ti.com/ + */ + +/dts-v1/; + +#include "k3-am654.dtsi" +#include "k3-am654-base-board-u-boot.dtsi" +#include "k3-am654-base-board-ddr4-1600MHz.dtsi" +#include "k3-am654-ddr.dtsi" + +/ { + compatible = "ti,am654-evm", "ti,am654"; + model = "Texas Instruments AM654 R5 Base Board"; + + aliases { + serial0 = &wkup_uart0; + serial2 = &main_uart0; + }; + + chosen { + stdout-path = "serial2:115200n8"; + tick-timer = &timer1; + }; + + aliases { + remoteproc0 = &sysctrler; + remoteproc1 = &a53_0; + }; + + a53_0: a53@0 { + compatible = "ti,am654-rproc"; + reg = <0x0 0x00a90000 0x0 0x10>; + power-domains = <&k3_pds 61>, + <&k3_pds 202>; + resets = <&k3_reset 202 0>; + assigned-clocks = <&k3_clks 202 0>; + assigned-clock-rates = <800000000>; + ti,sci = <&dmsc>; + ti,sci-proc-id = <32>; + ti,sci-host-id = <10>; + u-boot,dm-spl; + }; + + vtt_supply: vtt_supply { + compatible = "regulator-gpio"; + regulator-name = "vtt"; + regulator-min-microvolt = <0>; + regulator-max-microvolt = <3300000>; + gpios = <&wkup_gpio0 28 GPIO_ACTIVE_HIGH>; + states = <0 0x0 3300000 0x1>; + u-boot,dm-spl; + }; +}; + +&cbass_main { + timer1: timer@40400000 { + compatible = "ti,omap5430-timer"; + reg = <0x0 0x40400000 0x0 0x80>; + ti,timer-alwon; + clock-frequency = <25000000>; + u-boot,dm-pre-reloc; + }; +}; + +&cbass_mcu { + mcu_secproxy: secproxy@28380000 { + compatible = "ti,am654-secure-proxy"; + reg = <0x0 0x2a380000 0x0 0x80000>, + <0x0 0x2a400000 0x0 0x80000>, + <0x0 0x2a480000 0x0 0x80000>; + reg-names = "rt", "scfg", "target_data"; + #mbox-cells = <1>; + u-boot,dm-spl; + }; +}; + +&cbass_wakeup { + sysctrler: sysctrler { + compatible = "ti,am654-system-controller"; + mboxes= <&mcu_secproxy 4>, <&mcu_secproxy 5>; + mbox-names = "tx", "rx"; + u-boot,dm-spl; + }; + + wkup_gpio0: wkup_gpio0@42110000 { + compatible = "ti,k2g-gpio", "ti,keystone-gpio"; + reg = <0x42110000 0x100>; + gpio-controller; + #gpio-cells = <2>; + ti,ngpio = <56>; + ti,davinci-gpio-unbanked = <0>; + clocks = <&k3_clks 59 0>; + clock-names = "gpio"; + u-boot,dm-spl; + }; + +}; + +&dmsc { + mboxes= <&mcu_secproxy 7>, <&mcu_secproxy 6>, <&mcu_secproxy 5>; + mbox-names = "tx", "rx", "notify"; + ti,host-id = <4>; + ti,secure-host; +}; + +&wkup_uart0 { + u-boot,dm-spl; + pinctrl-names = "default"; + pinctrl-0 = <&wkup_uart0_pins_default>; + status = "okay"; +}; + +&wkup_pmx0 { + u-boot,dm-spl; + wkup_uart0_pins_default: wkup_uart0_pins_default { + pinctrl-single,pins = < + AM65X_WKUP_IOPAD(0x00a0, PIN_INPUT | MUX_MODE0) /* (AB1) WKUP_UART0_RXD */ + AM65X_WKUP_IOPAD(0x00a4, PIN_OUTPUT | MUX_MODE0) /* (AB5) WKUP_UART0_TXD */ + AM65X_WKUP_IOPAD(0x00c8, PIN_INPUT | MUX_MODE1) /* (AC2) WKUP_GPIO0_6.WKUP_UART0_CTSn */ + AM65X_WKUP_IOPAD(0x00cc, PIN_OUTPUT | MUX_MODE1) /* (AC1) WKUP_GPIO0_7.WKUP_UART0_RTSn */ + >; + u-boot,dm-spl; + }; + + wkup_vtt_pins_default: wkup_vtt_pins_default { + pinctrl-single,pins = < + AM65X_WKUP_IOPAD(0x0040, PIN_OUTPUT_PULLUP | MUX_MODE7) /* WKUP_GPIO0_28 */ + >; + u-boot,dm-spl; + }; +}; + +&memorycontroller { + vtt-supply = <&vtt_supply>; + pinctrl-names = "default"; + pinctrl-0 = <&wkup_vtt_pins_default>; +}; diff --git a/arch/arm/include/asm/armv8/mmu.h b/arch/arm/include/asm/armv8/mmu.h index 62d00d15c2..4a573208df 100644 --- a/arch/arm/include/asm/armv8/mmu.h +++ b/arch/arm/include/asm/armv8/mmu.h @@ -7,6 +7,8 @@ #ifndef _ASM_ARMV8_MMU_H_ #define _ASM_ARMV8_MMU_H_ +#include <linux/const.h> + /* * block/section address mask and size definitions. */ diff --git a/arch/arm/include/asm/macro.h b/arch/arm/include/asm/macro.h index d5a7a8bb61..bb33b4bc89 100644 --- a/arch/arm/include/asm/macro.h +++ b/arch/arm/include/asm/macro.h @@ -193,6 +193,10 @@ lr .req x30 SCR_EL3_SMD_DIS | SCR_EL3_RES1 |\ SCR_EL3_NS_EN) #endif + +#ifdef CONFIG_ARMV8_EA_EL3_FIRST + orr \tmp, \tmp, #SCR_EL3_EA_EN +#endif msr scr_el3, \tmp /* Return to the EL2_SP2 mode from EL3 */ diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index c1f87f9caf..aed2e3c51e 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -29,6 +29,7 @@ #define SCR_EL3_HCE_EN (1 << 8) /* Hypervisor Call enable */ #define SCR_EL3_SMD_DIS (1 << 7) /* Secure Monitor Call disable */ #define SCR_EL3_RES1 (3 << 4) /* Reserved, RES1 */ +#define SCR_EL3_EA_EN (1 << 3) /* External aborts taken to EL3 */ #define SCR_EL3_NS_EN (1 << 0) /* EL0 and EL1 in Non-scure state */ /* diff --git a/arch/arm/lib/memcpy.S b/arch/arm/lib/memcpy.S index 0ca61210da..f7fb77235c 100644 --- a/arch/arm/lib/memcpy.S +++ b/arch/arm/lib/memcpy.S @@ -59,7 +59,7 @@ #endif ENTRY(memcpy) cmp r0, r1 - moveq pc, lr + bxeq lr enter r4, lr @@ -147,7 +147,8 @@ ENTRY(memcpy) str1b r0, r4, cs, abort=21f str1b r0, ip, cs, abort=21f - exit r4, pc + exit r4, lr + bx lr 9: rsb ip, ip, #4 cmp ip, #2 @@ -256,7 +257,8 @@ ENTRY(memcpy) .endm .macro copy_abort_end - ldmfd sp!, {r4, pc} + ldmfd sp!, {r4, lr} + bx lr .endm ENDPROC(memcpy) diff --git a/arch/arm/mach-at91/include/mach/at91_wdt.h b/arch/arm/mach-at91/include/mach/at91_wdt.h index 99b0cc812d..cd2272367b 100644 --- a/arch/arm/mach-at91/include/mach/at91_wdt.h +++ b/arch/arm/mach-at91/include/mach/at91_wdt.h @@ -4,7 +4,7 @@ * * Copyright (C) 2008 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> * Copyright (C) 2007 Andrew Victor - * Copyright (C) 2007 Atmel Corporation. + * Copyright (C) 2018 Microchip Technology Inc. * * Watchdog Timer (WDT) - System peripherals regsters. * Based on AT91SAM9261 datasheet revision D. @@ -27,9 +27,13 @@ typedef struct at91_wdt { #endif +/* Watchdog Control Register */ +#define AT91_WDT_CR 0x00 #define AT91_WDT_CR_WDRSTT 1 #define AT91_WDT_CR_KEY 0xa5000000 /* KEY Password */ +/* Watchdog Mode Register*/ +#define AT91_WDT_MR 0X04 #define AT91_WDT_MR_WDV(x) (x & 0xfff) #define AT91_WDT_MR_WDFIEN 0x00001000 #define AT91_WDT_MR_WDRSTEN 0x00002000 diff --git a/arch/arm/mach-at91/spl.c b/arch/arm/mach-at91/spl.c index 8bfb2a452b..6da6d41be2 100644 --- a/arch/arm/mach-at91/spl.c +++ b/arch/arm/mach-at91/spl.c @@ -11,7 +11,7 @@ #include <asm/arch/clk.h> #include <spl.h> -#if !defined(CONFIG_AT91SAM9_WATCHDOG) +#if !defined(CONFIG_WDT_AT91) void at91_disable_wdt(void) { struct at91_wdt *wdt = (struct at91_wdt *)ATMEL_BASE_WDT; diff --git a/arch/arm/mach-at91/spl_at91.c b/arch/arm/mach-at91/spl_at91.c index 8c368042a6..23ebaa99b1 100644 --- a/arch/arm/mach-at91/spl_at91.c +++ b/arch/arm/mach-at91/spl_at91.c @@ -76,7 +76,7 @@ void __weak spl_board_init(void) void board_init_f(ulong dummy) { lowlevel_clock_init(); -#if !defined(CONFIG_AT91SAM9_WATCHDOG) +#if !defined(CONFIG_WDT_AT91) at91_disable_wdt(); #endif diff --git a/arch/arm/mach-at91/spl_atmel.c b/arch/arm/mach-at91/spl_atmel.c index 597ff8c036..ef745c9477 100644 --- a/arch/arm/mach-at91/spl_atmel.c +++ b/arch/arm/mach-at91/spl_atmel.c @@ -98,7 +98,7 @@ void board_init_f(ulong dummy) configure_2nd_sram_as_l2_cache(); #endif -#if !defined(CONFIG_AT91SAM9_WATCHDOG) +#if !defined(CONFIG_WDT_AT91) /* disable watchdog */ at91_disable_wdt(); #endif diff --git a/arch/arm/mach-k3/Kconfig b/arch/arm/mach-k3/Kconfig index 2df6197af7..e677a2e01b 100644 --- a/arch/arm/mach-k3/Kconfig +++ b/arch/arm/mach-k3/Kconfig @@ -47,5 +47,23 @@ config SYS_K3_BOOT_PARAM_TABLE_INDEX Address at which ROM stores the value which determines if SPL is booted up by primary boot media or secondary boot media. +config SYS_K3_KEY + string "Key used to generate x509 certificate" + help + This option enables to provide a custom key that can be used for + generating x509 certificate for spl binary. If not needed leave + it blank so that a random key is generated and used. + +config SYS_K3_BOOT_CORE_ID + int + default 16 + +config SYS_K3_SPL_ATF + bool "Start Cortex-A from SPL" + depends on SPL && CPU_V7R + help + Enabling this will try to start Cortex-A (typically with ATF) + after SPL from R5. + source "board/ti/am65x/Kconfig" endif diff --git a/arch/arm/mach-k3/Makefile b/arch/arm/mach-k3/Makefile index e9b7ee5210..406dda3b02 100644 --- a/arch/arm/mach-k3/Makefile +++ b/arch/arm/mach-k3/Makefile @@ -5,3 +5,5 @@ obj-$(CONFIG_SOC_K3_AM6) += am6_init.o obj-$(CONFIG_ARM64) += arm64-mmu.o +obj-$(CONFIG_CPU_V7R) += r5_mpu.o +obj-y += common.o diff --git a/arch/arm/mach-k3/am6_init.c b/arch/arm/mach-k3/am6_init.c index 68f0b8c011..e2fe00c422 100644 --- a/arch/arm/mach-k3/am6_init.c +++ b/arch/arm/mach-k3/am6_init.c @@ -10,6 +10,8 @@ #include <asm/io.h> #include <spl.h> #include <asm/arch/hardware.h> +#include "common.h" +#include <dm.h> #ifdef CONFIG_SPL_BUILD static void mmr_unlock(u32 base, u32 partition) @@ -56,6 +58,10 @@ static void store_boot_index_from_rom(void) void board_init_f(ulong dummy) { +#if defined(CONFIG_K3_AM654_DDRSS) + struct udevice *dev; + int ret; +#endif /* * Cannot delay this further as there is a chance that * K3_BOOT_PARAM_TABLE_INDEX can be over written by SPL MALLOC section. @@ -65,11 +71,23 @@ void board_init_f(ulong dummy) /* Make all control module registers accessible */ ctrl_mmr_unlock(); +#ifdef CONFIG_CPU_V7R + setup_k3_mpu_regions(); +#endif + /* Init DM early in-order to invoke system controller */ spl_early_init(); /* Prepare console output */ preloader_console_init(); + +#ifdef CONFIG_K3_AM654_DDRSS + ret = uclass_get_device(UCLASS_RAM, 0, &dev); + if (ret) { + printf("DRAM init failed: %d\n", ret); + return; + } +#endif } u32 spl_boot_mode(const u32 boot_device) diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c new file mode 100644 index 0000000000..cc89d4a296 --- /dev/null +++ b/arch/arm/mach-k3/common.c @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * K3: Common Architecture initialization + * + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ + * Lokesh Vutla <lokeshvutla@ti.com> + */ + +#include <common.h> +#include <spl.h> +#include "common.h" +#include <dm.h> +#include <remoteproc.h> + +#ifdef CONFIG_SYS_K3_SPL_ATF +void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) +{ + int ret; + + /* + * It is assumed that remoteproc device 1 is the corresponding + * cortex A core which runs ATF. Make sure DT reflects the same. + */ + ret = rproc_dev_init(1); + if (ret) { + printf("%s: ATF failed to Initialize on rproc: ret= %d\n", + __func__, ret); + hang(); + } + + ret = rproc_load(1, spl_image->entry_point, 0x200); + if (ret) { + printf("%s: ATF failed to load on rproc: ret= %d\n", + __func__, ret); + hang(); + } + + /* Add an extra newline to differentiate the ATF logs from SPL*/ + printf("Starting ATF on ARM64 core...\n\n"); + + ret = rproc_start(1); + if (ret) { + printf("%s: ATF failed to start on rproc: ret= %d\n", + __func__, ret); + hang(); + } + + debug("ATF started. Wait indefiniely\n"); + while (1) + asm volatile("wfe"); +} +#endif diff --git a/arch/arm/mach-k3/common.h b/arch/arm/mach-k3/common.h new file mode 100644 index 0000000000..ac7e80d9af --- /dev/null +++ b/arch/arm/mach-k3/common.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * K3: Architecture common definitions + * + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ + * Lokesh Vutla <lokeshvutla@ti.com> + */ + +#include <asm/armv7_mpu.h> + +void setup_k3_mpu_regions(void); diff --git a/arch/arm/mach-k3/config.mk b/arch/arm/mach-k3/config.mk index 9b86ddc715..7fc0b3f357 100644 --- a/arch/arm/mach-k3/config.mk +++ b/arch/arm/mach-k3/config.mk @@ -5,6 +5,65 @@ ifdef CONFIG_SPL_BUILD +# Openssl is required to generate x509 certificate. +# Error out if openssl is not available. +ifeq ($(shell which openssl),) +$(error "No openssl in $(PATH), consider installing openssl") +endif + +SHA_VALUE= $(shell openssl dgst -sha512 -hex $(obj)/u-boot-spl.bin | sed -e "s/^.*= //g") +IMAGE_SIZE= $(shell cat $(obj)/u-boot-spl.bin | wc -c) +LOADADDR= $(shell echo $(CONFIG_SPL_TEXT_BASE) | sed -e "s/^0x//g") +MAX_SIZE= $(shell printf "%d" $(CONFIG_SYS_K3_MAX_DOWNLODABLE_IMAGE_SIZE)) + +# Parameters to get populated into the x509 template +SED_OPTS= -e s/TEST_IMAGE_LENGTH/$(IMAGE_SIZE)/ +SED_OPTS+= -e s/TEST_IMAGE_SHA_VAL/$(SHA_VALUE)/ +SED_OPTS+= -e s/TEST_CERT_TYPE/1/ # CERT_TYPE_PRIMARY_IMAGE_BIN +SED_OPTS+= -e s/TEST_BOOT_CORE/$(CONFIG_SYS_K3_BOOT_CORE_ID)/ +SED_OPTS+= -e s/TEST_BOOT_ARCH_WIDTH/32/ +SED_OPTS+= -e s/TEST_BOOT_ADDR/$(LOADADDR)/ + +# Command to generate ecparam key +quiet_cmd_genkey = OPENSSL $@ +cmd_genkey = openssl ecparam -out $@ -name prime256v1 -genkey + +# Command to generate x509 certificate +quiet_cmd_gencert = OPENSSL $@ +cmd_gencert = cat $(srctree)/tools/k3_x509template.txt | sed $(SED_OPTS) > u-boot-spl-x509.txt; \ + openssl req -new -x509 -key $(KEY) -nodes -outform DER -out $@ -config u-boot-spl-x509.txt -sha512 + +# If external key is not provided, generate key using openssl. +ifeq ($(CONFIG_SYS_K3_KEY), "") +KEY=u-boot-spl-eckey.pem +else +KEY=$(patsubst "%",%,$(CONFIG_SYS_K3_KEY)) +endif + +u-boot-spl-eckey.pem: FORCE + $(call if_changed,genkey) + +# tiboot3.bin is mandated by ROM and ROM only supports R5 boot. +# So restrict tiboot3.bin creation for CPU_V7R. +ifdef CONFIG_CPU_V7R +u-boot-spl-cert.bin: $(KEY) $(obj)/u-boot-spl.bin image_check FORCE + $(call if_changed,gencert) + +image_check: $(obj)/u-boot-spl.bin FORCE + @if [ $(IMAGE_SIZE) -gt $(MAX_SIZE) ]; then \ + echo "===============================================" >&2; \ + echo "ERROR: Final Image too big. " >&2; \ + echo "$< size = $(IMAGE_SIZE), max size = $(MAX_SIZE)" >&2; \ + echo "===============================================" >&2; \ + exit 1; \ + fi + +tiboot3.bin: u-boot-spl-cert.bin $(obj)/u-boot-spl.bin FORCE + $(call if_changed,cat) + +ALL-y += tiboot3.bin +endif + ifdef CONFIG_ARM64 SPL_ITS := u-boot-spl-k3.its $(SPL_ITS): FORCE diff --git a/arch/arm/mach-k3/include/mach/sys_proto.h b/arch/arm/mach-k3/include/mach/sys_proto.h new file mode 100644 index 0000000000..0b2007981a --- /dev/null +++ b/arch/arm/mach-k3/include/mach/sys_proto.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ + * Andreas Dannenberg <dannenberg@ti.com> + */ + +#ifndef _SYS_PROTO_H_ +#define _SYS_PROTO_H_ + +void sdelay(unsigned long loops); +u32 wait_on_value(u32 read_bit_mask, u32 match_value, void *read_addr, + u32 bound); + +#endif diff --git a/arch/arm/mach-k3/r5_mpu.c b/arch/arm/mach-k3/r5_mpu.c new file mode 100644 index 0000000000..ee076ed877 --- /dev/null +++ b/arch/arm/mach-k3/r5_mpu.c @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * K3: R5 MPU region definitions + * + * Copyright (C) 2017-2018 Texas Instruments Incorporated - http://www.ti.com/ + * Lokesh Vutla <lokeshvutla@ti.com> + */ + +#include <common.h> +#include <asm/io.h> +#include <linux/kernel.h> +#include "common.h" + +struct mpu_region_config k3_mpu_regions[16] = { + /* + * Make all 4GB as Device Memory and not executable. We are overriding + * it with next region for any requirement. + */ + {0x00000000, REGION_0, XN_EN, PRIV_RW_USR_RW, SHARED_WRITE_BUFFERED, + REGION_4GB}, + + /* SPL code area marking it as WB and Write allocate. */ + {CONFIG_SPL_TEXT_BASE, REGION_1, XN_DIS, PRIV_RW_USR_RW, + O_I_WB_RD_WR_ALLOC, REGION_8MB}, + + /* U-Boot's code area marking it as WB and Write allocate */ + {CONFIG_SYS_SDRAM_BASE, REGION_2, XN_DIS, PRIV_RW_USR_RW, + O_I_WB_RD_WR_ALLOC, REGION_2GB}, + {0x0, 3, 0x0, 0x0, 0x0, 0x0}, + {0x0, 4, 0x0, 0x0, 0x0, 0x0}, + {0x0, 5, 0x0, 0x0, 0x0, 0x0}, + {0x0, 6, 0x0, 0x0, 0x0, 0x0}, + {0x0, 7, 0x0, 0x0, 0x0, 0x0}, + {0x0, 8, 0x0, 0x0, 0x0, 0x0}, + {0x0, 9, 0x0, 0x0, 0x0, 0x0}, + {0x0, 10, 0x0, 0x0, 0x0, 0x0}, + {0x0, 11, 0x0, 0x0, 0x0, 0x0}, + {0x0, 12, 0x0, 0x0, 0x0, 0x0}, + {0x0, 13, 0x0, 0x0, 0x0, 0x0}, + {0x0, 14, 0x0, 0x0, 0x0, 0x0}, + {0x0, 15, 0x0, 0x0, 0x0, 0x0}, +}; + +void setup_k3_mpu_regions(void) +{ + setup_mpu_regions(k3_mpu_regions, ARRAY_SIZE(k3_mpu_regions)); +} diff --git a/arch/arm/mach-mvebu/arm64-common.c b/arch/arm/mach-mvebu/arm64-common.c index f47273fde9..47bbf69944 100644 --- a/arch/arm/mach-mvebu/arm64-common.c +++ b/arch/arm/mach-mvebu/arm64-common.c @@ -7,6 +7,7 @@ #include <dm.h> #include <fdtdec.h> #include <linux/libfdt.h> +#include <linux/sizes.h> #include <pci.h> #include <asm/io.h> #include <asm/system.h> @@ -45,15 +46,62 @@ const struct mbus_dram_target_info *mvebu_mbus_dram_info(void) /* DRAM init code ... */ +#define MV_SIP_DRAM_SIZE 0x82000010 + +static u64 a8k_dram_scan_ap_sz(void) +{ + struct pt_regs pregs; + + pregs.regs[0] = MV_SIP_DRAM_SIZE; + pregs.regs[1] = SOC_REGS_PHY_BASE; + smc_call(&pregs); + + return pregs.regs[0]; +} + +static void a8k_dram_init_banksize(void) +{ + /* + * The firmware (ATF) leaves a 1G whole above the 3G mark for IO + * devices. Higher RAM is mapped at 4G. + * + * Config 2 DRAM banks: + * Bank 0 - max size 4G - 1G + * Bank 1 - ram size - 4G + 1G + */ + phys_size_t max_bank0_size = SZ_4G - SZ_1G; + + gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; + if (gd->ram_size <= max_bank0_size) { + gd->bd->bi_dram[0].size = gd->ram_size; + return; + } + + gd->bd->bi_dram[0].size = max_bank0_size; + if (CONFIG_NR_DRAM_BANKS > 1) { + gd->bd->bi_dram[1].start = SZ_4G; + gd->bd->bi_dram[1].size = gd->ram_size - max_bank0_size; + } +} + int dram_init_banksize(void) { - fdtdec_setup_memory_banksize(); + if (CONFIG_IS_ENABLED(ARMADA_8K)) + a8k_dram_init_banksize(); + else + fdtdec_setup_memory_banksize(); return 0; } int dram_init(void) { + if (CONFIG_IS_ENABLED(ARMADA_8K)) { + gd->ram_size = a8k_dram_scan_ap_sz(); + if (gd->ram_size != 0) + return 0; + } + if (fdtdec_setup_mem_size_base() != 0) return -EINVAL; diff --git a/arch/arm/mach-stm32mp/cpu.c b/arch/arm/mach-stm32mp/cpu.c index 0e01f8e613..b8933587ad 100644 --- a/arch/arm/mach-stm32mp/cpu.c +++ b/arch/arm/mach-stm32mp/cpu.c @@ -306,7 +306,7 @@ static int setup_mac_address(void) ret = misc_read(dev, BSEC_OTP_MAC * 4 + STM32_BSEC_OTP_OFFSET, otp, sizeof(otp)); - if (ret) + if (ret < 0) return ret; for (i = 0; i < 6; i++) @@ -344,7 +344,7 @@ static int setup_serial_number(void) ret = misc_read(dev, BSEC_OTP_SERIAL * 4 + STM32_BSEC_OTP_OFFSET, otp, sizeof(otp)); - if (ret) + if (ret < 0) return ret; sprintf(serial_string, "%08x%08x%08x", otp[0], otp[1], otp[2]); diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index 560dc9b25d..3c54f5106d 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig @@ -230,6 +230,7 @@ config MACH_SUN8I_A83T select PHY_SUN4I_USB select SUNXI_GEN_SUN6I select MMC_SUNXI_HAS_NEW_MODE + select MMC_SUNXI_HAS_MODE_SWITCH select SUPPORT_SPL config MACH_SUN8I_H3 @@ -281,6 +282,7 @@ config MACH_SUN50I select SUN6I_PRCM select SUNXI_DE2 select SUNXI_GEN_SUN6I + select MMC_SUNXI_HAS_NEW_MODE select SUPPORT_SPL select SUNXI_DRAM_DW select SUNXI_DRAM_DW_32BIT diff --git a/arch/arm/mach-sunxi/dram_sun8i_a33.c b/arch/arm/mach-sunxi/dram_sun8i_a33.c index d9aa0c6d7e..1da2727f98 100644 --- a/arch/arm/mach-sunxi/dram_sun8i_a33.c +++ b/arch/arm/mach-sunxi/dram_sun8i_a33.c @@ -334,7 +334,7 @@ unsigned long sunxi_dram_init(void) struct dram_para para = { .cs1 = 0, .bank = 1, - .rank = 1, + .rank = 2, .rows = 15, .bus_width = 16, .page_size = 2048, diff --git a/arch/arm/mach-tegra/tegra186/nvtboot_mem.c b/arch/arm/mach-tegra/tegra186/nvtboot_mem.c index 5c9467bfe8..62142821a5 100644 --- a/arch/arm/mach-tegra/tegra186/nvtboot_mem.c +++ b/arch/arm/mach-tegra/tegra186/nvtboot_mem.c @@ -6,11 +6,10 @@ #include <common.h> #include <fdt_support.h> #include <fdtdec.h> +#include <linux/sizes.h> #include <asm/arch/tegra.h> #include <asm/armv8/mmu.h> -#define SZ_4G 0x100000000ULL - /* * Size of a region that's large enough to hold the relocated U-Boot and all * other allocations made around it (stack, heap, page tables, etc.) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 6d646ef999..1b1b1d7d00 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -74,9 +74,12 @@ config ARCH_MT7620 imply CMD_DM select DISPLAY_CPUINFO select DM + imply DM_ETH + imply DM_GPIO select DM_SERIAL imply DM_SPI imply DM_SPI_FLASH + select ARCH_MISC_INIT if WATCHDOG select MIPS_TUNE_24KC select OF_CONTROL select ROM_EXCEPTION_VECTORS diff --git a/arch/mips/config.mk b/arch/mips/config.mk index 22223a0f3e..9d3a84539a 100644 --- a/arch/mips/config.mk +++ b/arch/mips/config.mk @@ -25,12 +25,14 @@ ifdef CONFIG_32BIT PLATFORM_CPPFLAGS += -mabi=32 PLATFORM_LDFLAGS += -m $(32bit-emul) OBJCOPYFLAGS += -O $(32bit-bfd) +CONFIG_STANDALONE_LOAD_ADDR ?= 0x80200000 endif ifdef CONFIG_64BIT PLATFORM_CPPFLAGS += -mabi=64 PLATFORM_LDFLAGS += -m$(64bit-emul) OBJCOPYFLAGS += -O $(64bit-bfd) +CONFIG_STANDALONE_LOAD_ADDR ?= 0xffffffff80200000 endif PLATFORM_CPPFLAGS += -D__MIPS__ @@ -65,3 +67,5 @@ PLATFORM_LDFLAGS += -G 0 -static -n -nostdlib PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections LDFLAGS_FINAL += --gc-sections OBJCOPYFLAGS += -j .text -j .rodata -j .data -j .u_boot_list + +LDFLAGS_STANDALONE += --gc-sections diff --git a/arch/mips/cpu/mips32/config.mk b/arch/mips/cpu/mips32/config.mk deleted file mode 100644 index a0247596f5..0000000000 --- a/arch/mips/cpu/mips32/config.mk +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0+ -# -# (C) Copyright 2003 -# Wolfgang Denk, DENX Software Engineering, <wd@denx.de> - -CONFIG_STANDALONE_LOAD_ADDR ?= 0x80200000 \ - -T $(srctree)/examples/standalone/mips.lds diff --git a/arch/mips/cpu/mips64/config.mk b/arch/mips/cpu/mips64/config.mk deleted file mode 100644 index cd96bbcce9..0000000000 --- a/arch/mips/cpu/mips64/config.mk +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0+ -# -# (C) Copyright 2003 -# Wolfgang Denk, DENX Software Engineering, <wd@denx.de> - -CONFIG_STANDALONE_LOAD_ADDR ?= 0xffffffff80200000 \ - -T $(srctree)/examples/standalone/mips64.lds diff --git a/arch/mips/dts/gardena-smart-gateway-mt7688.dts b/arch/mips/dts/gardena-smart-gateway-mt7688.dts index ee99c3d17c..d8d88686bb 100644 --- a/arch/mips/dts/gardena-smart-gateway-mt7688.dts +++ b/arch/mips/dts/gardena-smart-gateway-mt7688.dts @@ -6,6 +6,7 @@ /dts-v1/; #include "mt7628a.dtsi" +#include <dt-bindings/gpio/gpio.h> / { compatible = "gardena,smart-gateway-mt7688", "ralink,mt7628a-soc"; @@ -21,8 +22,65 @@ reg = <0x0 0x08000000>; }; + leds { + compatible = "gpio-leds"; + + power_blue { + label = "smartgw:power:blue"; + gpios = <&gpio0 18 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + power_green { + label = "smartgw:power:green"; + gpios = <&gpio0 19 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + power_red { + label = "smartgw:power:red"; + gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + radio_blue { + label = "smartgw:radio:blue"; + gpios = <&gpio0 23 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + radio_green { + label = "smartgw:radio:green"; + gpios = <&gpio0 24 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + radio_red { + label = "smartgw:radio:red"; + gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + internet_blue { + label = "smartgw:internet:blue"; + gpios = <&gpio0 26 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + internet_green { + label = "smartgw:internet:green"; + gpios = <&gpio0 27 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + internet_red { + label = "smartgw:internet:red"; + gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + }; + chosen { - bootargs = "console=ttyS0,57600"; stdout-path = &uart0; }; }; diff --git a/arch/mips/dts/linkit-smart-7688.dts b/arch/mips/dts/linkit-smart-7688.dts index df4bf907c6..c9db136f30 100644 --- a/arch/mips/dts/linkit-smart-7688.dts +++ b/arch/mips/dts/linkit-smart-7688.dts @@ -22,7 +22,6 @@ }; chosen { - bootargs = "console=ttyS0,57600"; stdout-path = &uart2; }; }; diff --git a/arch/mips/dts/mt7628a.dtsi b/arch/mips/dts/mt7628a.dtsi index c14259b170..70e34cfdbc 100644 --- a/arch/mips/dts/mt7628a.dtsi +++ b/arch/mips/dts/mt7628a.dtsi @@ -48,6 +48,17 @@ mask = <0x1>; }; + watchdog: watchdog@100 { + compatible = "ralink,mt7628a-wdt", "mediatek,mt7621-wdt"; + reg = <0x100 0x30>; + + resets = <&resetc 8>; + reset-names = "wdt"; + + interrupt-parent = <&intc>; + interrupts = <24>; + }; + intc: interrupt-controller@200 { compatible = "ralink,rt2880-intc"; reg = <0x200 0x100>; @@ -71,6 +82,38 @@ reg = <0x300 0x100>; }; + gpio@600 { + #address-cells = <1>; + #size-cells = <0>; + + compatible = "mtk,mt7628-gpio", "mtk,mt7621-gpio"; + reg = <0x600 0x100>; + + interrupt-parent = <&intc>; + interrupts = <6>; + + gpio0: bank@0 { + reg = <0>; + compatible = "mtk,mt7621-gpio-bank"; + gpio-controller; + #gpio-cells = <2>; + }; + + gpio1: bank@1 { + reg = <1>; + compatible = "mtk,mt7621-gpio-bank"; + gpio-controller; + #gpio-cells = <2>; + }; + + gpio2: bank@2 { + reg = <2>; + compatible = "mtk,mt7621-gpio-bank"; + gpio-controller; + #gpio-cells = <2>; + }; + }; + spi0: spi@b00 { compatible = "ralink,mt7621-spi"; reg = <0xb00 0x40>; @@ -120,6 +163,14 @@ }; }; + eth@10110000 { + compatible = "mediatek,mt7622-eth"; + reg = <0x10100000 0x10000 + 0x10110000 0x8000>; + + syscon = <&sysc>; + }; + usb_phy: usb-phy@10120000 { compatible = "mediatek,mt7628-usbphy"; reg = <0x10120000 0x1000>; diff --git a/arch/mips/include/asm/mach-generic/spaces.h b/arch/mips/include/asm/mach-generic/spaces.h index b7eac323cd..539d0a566d 100644 --- a/arch/mips/include/asm/mach-generic/spaces.h +++ b/arch/mips/include/asm/mach-generic/spaces.h @@ -7,7 +7,7 @@ #ifndef _ASM_MACH_GENERIC_SPACES_H #define _ASM_MACH_GENERIC_SPACES_H -#include <asm/const.h> +#include <linux/const.h> /* * This gives the physical RAM offset. diff --git a/arch/mips/include/asm/u-boot-mips.h b/arch/mips/include/asm/u-boot-mips.h index f4bfbdc693..88438b9576 100644 --- a/arch/mips/include/asm/u-boot-mips.h +++ b/arch/mips/include/asm/u-boot-mips.h @@ -7,4 +7,6 @@ void exc_handler(void); void except_vec3_generic(void); void except_vec_ejtag_debug(void); +int arch_misc_init(void); + #endif /* _U_BOOT_MIPS_H_ */ diff --git a/arch/mips/mach-mt7620/Kconfig b/arch/mips/mach-mt7620/Kconfig index 13a7bd2cc0..4ebcb4b053 100644 --- a/arch/mips/mach-mt7620/Kconfig +++ b/arch/mips/mach-mt7620/Kconfig @@ -24,6 +24,7 @@ choice config BOARD_GARDENA_SMART_GATEWAY_MT7688 bool "Gardena Smart Gateway" depends on SOC_MT7620 + select BOARD_LATE_INIT select SUPPORTS_BOOT_RAM help Gardena Smart Gateway boards have a MT7688 SoC with 128 MiB of RAM diff --git a/arch/mips/mach-mt7620/cpu.c b/arch/mips/mach-mt7620/cpu.c index 457f09f32c..87cc973b75 100644 --- a/arch/mips/mach-mt7620/cpu.c +++ b/arch/mips/mach-mt7620/cpu.c @@ -6,6 +6,7 @@ #include <common.h> #include <dm.h> #include <ram.h> +#include <wdt.h> #include <asm/io.h> #include <linux/io.h> #include <linux/sizes.h> @@ -67,3 +68,42 @@ int print_cpuinfo(void) return 0; } + +#ifdef CONFIG_WATCHDOG +static struct udevice *watchdog_dev; + +/* Called by macro WATCHDOG_RESET */ +void watchdog_reset(void) +{ + static ulong next_reset; + ulong now; + + if (!watchdog_dev) + return; + + now = get_timer(0); + + /* Do not reset the watchdog too often */ + if (now > next_reset) { + next_reset = now + 1000; /* reset every 1000ms */ + wdt_reset(watchdog_dev); + } +} + +int arch_misc_init(void) +{ + /* Init watchdog */ + if (uclass_get_device_by_seq(UCLASS_WDT, 0, &watchdog_dev)) { + debug("Watchdog: Not found by seq!\n"); + if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) { + puts("Watchdog: Not found!\n"); + return 0; + } + } + + wdt_start(watchdog_dev, 60000, 0); /* 60 seconds */ + printf("Watchdog: Started\n"); + + return 0; +} +#endif diff --git a/arch/mips/mach-mt7620/lowlevel_init.S b/arch/mips/mach-mt7620/lowlevel_init.S index 1a50f160fe..aa707e0de6 100644 --- a/arch/mips/mach-mt7620/lowlevel_init.S +++ b/arch/mips/mach-mt7620/lowlevel_init.S @@ -108,6 +108,12 @@ CPLL_READY: sw t3, 0(t0) CPLL_DONE: + /* Reset MC */ + lw t2, 0x34(s0) + ori t2, BIT(10) + sw t2, 0x34(s0) + nop + /* * SDR and DDR initialization: delay 200us */ diff --git a/arch/nds32/config.mk b/arch/nds32/config.mk index c5520fd8d8..12cec368d3 100644 --- a/arch/nds32/config.mk +++ b/arch/nds32/config.mk @@ -12,8 +12,8 @@ ifeq ($(CROSS_COMPILE),) CROSS_COMPILE := nds32le-linux- endif -CONFIG_STANDALONE_LOAD_ADDR = 0x300000 \ - -T $(srctree)/examples/standalone/nds32.lds +CONFIG_STANDALONE_LOAD_ADDR = 0x300000 +LDFLAGS_STANDALONE += -T $(srctree)/examples/standalone/nds32.lds PLATFORM_RELFLAGS += -fno-common -mrelax PLATFORM_RELFLAGS += -gdwarf-2 diff --git a/arch/nds32/cpu/n1213/start.S b/arch/nds32/cpu/n1213/start.S index aa9457f5e4..cf966e2132 100644 --- a/arch/nds32/cpu/n1213/start.S +++ b/arch/nds32/cpu/n1213/start.S @@ -201,14 +201,6 @@ update_gp: #endif /* - * Do CPU critical regs init only at reboot, - * not when booting from ram - */ -#ifdef CONFIG_INIT_CRITICAL - jal cpu_init_crit ! Do CPU critical regs init -#endif - -/* * Set stackpointer in internal RAM to call board_init_f * $sp must be 8-byte alignment for ABI compliance. */ @@ -319,49 +311,6 @@ call_board_init_r: jr $lp /* jump to board_init_r() */ /* - * Initialize CPU critical registers - * - * 1. Setup control registers - * 1.1 Mask all IRQs - * 1.2 Flush cache and TLB - * 1.3 Disable MMU and cache - * 2. Setup memory timing - */ - -cpu_init_crit: - - move $r0, $lp /* push ra */ - - /* Disable Interrupts by clear GIE in $PSW reg */ - setgie.d - - /* Flush caches and TLB */ - /* Invalidate caches */ - jal invalidate_icac - jal invalidate_dcac - - /* Flush TLB */ - mfsr $p0, $MMU_CFG - andi $p0, $p0, 0x3 ! MMPS - li $p1, 0x2 ! TLB MMU - bne $p0, $p1, 1f - tlbop flushall ! Flush TLB - -1: - ! Disable MMU, Dcache - ! Whitiger is MMU disabled when reset - ! Disable the D$ - mfsr $p0, MR_CAC_CTL ! Get the $CACHE_CTL reg - li $p1, DIS_DCAC - and $p0, $p0, $p1 ! Set DC_EN bit - mtsr $p0, MR_CAC_CTL ! write back the $CACHE_CTL reg - isb - - move $lp, $r0 -2: - ret - -/* * Invalidate I$ */ invalidate_icac: diff --git a/arch/powerpc/include/asm/spl.h b/arch/powerpc/include/asm/spl.h index cd6d31c71a..60a7d37d30 100644 --- a/arch/powerpc/include/asm/spl.h +++ b/arch/powerpc/include/asm/spl.h @@ -8,7 +8,4 @@ #define BOOT_DEVICE_NOR 1 -/* Linker symbols */ -extern char __bss_start[], __bss_end[]; - #endif diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 168ca3de7c..3e0af55e71 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -16,27 +16,45 @@ config TARGET_QEMU_VIRT endchoice +# board-specific options below source "board/AndesTech/ax25-ae350/Kconfig" source "board/emulation/qemu-riscv/Kconfig" +# platform-specific options below +source "arch/riscv/cpu/ax25/Kconfig" + +# architecture-specific options below + choice - prompt "CPU selection" - default CPU_RISCV_32 + prompt "Base ISA" + default ARCH_RV32I -config CPU_RISCV_32 - bool "RISC-V 32-bit" +config ARCH_RV32I + bool "RV32I" select 32BIT help - Choose this option to build an U-Boot for RISCV32 architecture. + Choose this option to target the RV32I base integer instruction set. -config CPU_RISCV_64 - bool "RISC-V 64-bit" +config ARCH_RV64I + bool "RV64I" select 64BIT + select PHYS_64BIT help - Choose this option to build an U-Boot for RISCV64 architecture. + Choose this option to target the RV64I base integer instruction set. endchoice +config RISCV_ISA_C + bool "Emit compressed instructions" + default y + help + Adds "C" to the ISA subsets that the toolchain is allowed to emit + when building U-Boot, which results in compressed instructions in the + U-Boot binary. + +config RISCV_ISA_A + def_bool y + config 32BIT bool diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile index 8fb6a889d8..55d7c6550e 100644 --- a/arch/riscv/Makefile +++ b/arch/riscv/Makefile @@ -3,6 +3,26 @@ # Copyright (C) 2017 Andes Technology Corporation. # Rick Chen, Andes Technology Corporation <rick@andestech.com> +ifeq ($(CONFIG_ARCH_RV64I),y) + ARCH_BASE = rv64im + ABI = lp64 +endif +ifeq ($(CONFIG_ARCH_RV32I),y) + ARCH_BASE = rv32im + ABI = ilp32 +endif +ifeq ($(CONFIG_RISCV_ISA_A),y) + ARCH_A = a +endif +ifeq ($(CONFIG_RISCV_ISA_C),y) + ARCH_C = c +endif + +ARCH_FLAGS = -march=$(ARCH_BASE)$(ARCH_A)$(ARCH_C) -mabi=$(ABI) + +PLATFORM_CPPFLAGS += $(ARCH_FLAGS) +CFLAGS_EFI += $(ARCH_FLAGS) + head-y := arch/riscv/cpu/start.o libs-y += arch/riscv/cpu/ diff --git a/arch/riscv/config.mk b/arch/riscv/config.mk index ed9eb0c24c..ff4fe64001 100644 --- a/arch/riscv/config.mk +++ b/arch/riscv/config.mk @@ -14,24 +14,21 @@ 64bit-emul := elf64lriscv ifdef CONFIG_32BIT -PLATFORM_CPPFLAGS += -march=rv32ima -mabi=ilp32 PLATFORM_LDFLAGS += -m $(32bit-emul) -CFLAGS_EFI += -march=rv32ima -mabi=ilp32 EFI_LDS := elf_riscv32_efi.lds endif ifdef CONFIG_64BIT -PLATFORM_CPPFLAGS += -march=rv64ima -mabi=lp64 PLATFORM_LDFLAGS += -m $(64bit-emul) -CFLAGS_EFI += -march=rv64ima -mabi=lp64 EFI_LDS := elf_riscv64_efi.lds endif -CONFIG_STANDALONE_LOAD_ADDR = 0x00000000 \ - -T $(srctree)/examples/standalone/riscv.lds +CONFIG_STANDALONE_LOAD_ADDR = 0x00000000 +LDFLAGS_STANDALONE += -T $(srctree)/examples/standalone/riscv.lds PLATFORM_CPPFLAGS += -ffixed-gp -fpic -PLATFORM_RELFLAGS += -fno-common -gdwarf-2 -ffunction-sections +PLATFORM_RELFLAGS += -fno-common -gdwarf-2 -ffunction-sections \ + -fdata-sections LDFLAGS_u-boot += --gc-sections -static -pie EFI_CRT0 := crt0_riscv_efi.o diff --git a/arch/riscv/cpu/ax25/Kconfig b/arch/riscv/cpu/ax25/Kconfig new file mode 100644 index 0000000000..6c7022f0f5 --- /dev/null +++ b/arch/riscv/cpu/ax25/Kconfig @@ -0,0 +1,7 @@ +config RISCV_NDS + bool "AndeStar V5 ISA support" + default n + help + Say Y here if you plan to run U-Boot on AndeStar v5 + platforms and use some specific features which are + provided by Andes Technology AndeStar V5 Families. diff --git a/arch/riscv/cpu/ax25/Makefile b/arch/riscv/cpu/ax25/Makefile index 2ab0342fe8..318baccb09 100644 --- a/arch/riscv/cpu/ax25/Makefile +++ b/arch/riscv/cpu/ax25/Makefile @@ -4,3 +4,4 @@ # Rick Chen, Andes Technology Corporation <rick@andestech.com> obj-y := cpu.o +obj-y += cache.o diff --git a/arch/riscv/cpu/ax25/cache.c b/arch/riscv/cpu/ax25/cache.c new file mode 100644 index 0000000000..6600ac2fac --- /dev/null +++ b/arch/riscv/cpu/ax25/cache.c @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2017 Andes Technology Corporation + * Rick Chen, Andes Technology Corporation <rick@andestech.com> + */ + +#include <common.h> + +void icache_enable(void) +{ +#ifndef CONFIG_SYS_ICACHE_OFF +#ifdef CONFIG_RISCV_NDS + asm volatile ( + "csrr t1, mcache_ctl\n\t" + "ori t0, t1, 0x1\n\t" + "csrw mcache_ctl, t0\n\t" + ); +#endif +#endif +} + +void icache_disable(void) +{ +#ifndef CONFIG_SYS_ICACHE_OFF +#ifdef CONFIG_RISCV_NDS + asm volatile ( + "fence.i\n\t" + "csrr t1, mcache_ctl\n\t" + "andi t0, t1, ~0x1\n\t" + "csrw mcache_ctl, t0\n\t" + ); +#endif +#endif +} + +void dcache_enable(void) +{ +#ifndef CONFIG_SYS_DCACHE_OFF +#ifdef CONFIG_RISCV_NDS + asm volatile ( + "csrr t1, mcache_ctl\n\t" + "ori t0, t1, 0x2\n\t" + "csrw mcache_ctl, t0\n\t" + ); +#endif +#endif +} + +void dcache_disable(void) +{ +#ifndef CONFIG_SYS_DCACHE_OFF +#ifdef CONFIG_RISCV_NDS + asm volatile ( + "fence\n\t" + "csrr t1, mcache_ctl\n\t" + "andi t0, t1, ~0x2\n\t" + "csrw mcache_ctl, t0\n\t" + ); +#endif +#endif +} + +int icache_status(void) +{ + int ret = 0; + +#ifdef CONFIG_RISCV_NDS + asm volatile ( + "csrr t1, mcache_ctl\n\t" + "andi %0, t1, 0x01\n\t" + : "=r" (ret) + : + : "memory" + ); +#endif + + return ret; +} + +int dcache_status(void) +{ + int ret = 0; + +#ifdef CONFIG_RISCV_NDS + asm volatile ( + "csrr t1, mcache_ctl\n\t" + "andi %0, t1, 0x02\n\t" + : "=r" (ret) + : + : "memory" + ); +#endif + + return ret; +} diff --git a/arch/riscv/cpu/ax25/cpu.c b/arch/riscv/cpu/ax25/cpu.c index fddcc156c3..76689b21d3 100644 --- a/arch/riscv/cpu/ax25/cpu.c +++ b/arch/riscv/cpu/ax25/cpu.c @@ -6,6 +6,7 @@ /* CPU specific code */ #include <common.h> +#include <asm/cache.h> /* * cleanup_before_linux() is called just before we call linux @@ -18,6 +19,9 @@ int cleanup_before_linux(void) disable_interrupts(); /* turn off I/D-cache */ + cache_flush(); + icache_disable(); + dcache_disable(); return 0; } diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c index ae57fb8313..d9f820c44c 100644 --- a/arch/riscv/cpu/cpu.c +++ b/arch/riscv/cpu/cpu.c @@ -6,6 +6,12 @@ #include <common.h> #include <asm/csr.h> +/* + * prior_stage_fdt_address must be stored in the data section since it is used + * before the bss section is available. + */ +phys_addr_t prior_stage_fdt_address __attribute__((section(".data"))); + enum { ISA_INVALID = 0, ISA_32BIT, diff --git a/arch/riscv/cpu/qemu/cpu.c b/arch/riscv/cpu/qemu/cpu.c index 6c7a32755a..25d97d0b41 100644 --- a/arch/riscv/cpu/qemu/cpu.c +++ b/arch/riscv/cpu/qemu/cpu.c @@ -15,7 +15,7 @@ int cleanup_before_linux(void) { disable_interrupts(); - /* turn off I/D-cache */ + cache_flush(); return 0; } diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S index 7cd7755190..15e1b8199a 100644 --- a/arch/riscv/cpu/start.S +++ b/arch/riscv/cpu/start.S @@ -16,56 +16,47 @@ #include <asm/encoding.h> #ifdef CONFIG_32BIT -#define LREG lw -#define SREG sw -#define REGBYTES 4 +#define LREG lw +#define SREG sw +#define REGBYTES 4 #define RELOC_TYPE R_RISCV_32 #define SYM_INDEX 0x8 #define SYM_SIZE 0x10 #else -#define LREG ld -#define SREG sd -#define REGBYTES 8 +#define LREG ld +#define SREG sd +#define REGBYTES 8 #define RELOC_TYPE R_RISCV_64 #define SYM_INDEX 0x20 #define SYM_SIZE 0x18 #endif -.section .text +.section .text .globl _start _start: - j handle_reset + /* save hart id and dtb pointer */ + mv s0, a0 + mv s1, a1 -nmi_vector: - j nmi_vector + li t0, CONFIG_SYS_SDRAM_BASE + SREG a2, 0(t0) + la t0, trap_entry + csrw mtvec, t0 -trap_vector: - j trap_entry + /* mask all interrupts */ + csrw mie, zero -.global trap_entry -handle_reset: - li t0, CONFIG_SYS_SDRAM_BASE - SREG a2, 0(t0) - la t0, trap_entry - csrw mtvec, t0 - csrwi mstatus, 0 - csrwi mie, 0 - -/* - * Do CPU critical regs init only at reboot, - * not when booting from ram - */ -#ifdef CONFIG_INIT_CRITICAL - jal cpu_init_crit /* Do CPU critical regs init */ -#endif + /* Enable cache */ + jal icache_enable + jal dcache_enable /* * Set stackpointer in internal/ex RAM to call board_init_f */ call_board_init_f: - li t0, -16 - li t1, CONFIG_SYS_INIT_SP_ADDR - and sp, t1, t0 /* force 16 byte alignment */ + li t0, -16 + li t1, CONFIG_SYS_INIT_SP_ADDR + and sp, t1, t0 /* force 16 byte alignment */ #ifdef CONFIG_DEBUG_UART jal debug_uart_init @@ -75,11 +66,15 @@ call_board_init_f_0: mv a0, sp jal board_init_f_alloc_reserve mv sp, a0 + + la t0, prior_stage_fdt_address + SREG s1, 0(t0) + jal board_init_f_init_reserve - mv a0, zero /* a0 <-- boot_flags = 0 */ - la t5, board_init_f - jr t5 /* jump to board_init_f() */ + mv a0, zero /* a0 <-- boot_flags = 0 */ + la t5, board_init_f + jr t5 /* jump to board_init_f() */ /* * void relocate_code (addr_sp, gd, addr_moni) @@ -90,203 +85,200 @@ call_board_init_f_0: */ .globl relocate_code relocate_code: - mv s2, a0 /* save addr_sp */ - mv s3, a1 /* save addr of gd */ - mv s4, a2 /* save addr of destination */ + mv s2, a0 /* save addr_sp */ + mv s3, a1 /* save addr of gd */ + mv s4, a2 /* save addr of destination */ /* *Set up the stack */ stack_setup: - mv sp, s2 - la t0, _start - sub t6, s4, t0 /* t6 <- relocation offset */ - beq t0, s4, clear_bss /* skip relocation */ + mv sp, s2 + la t0, _start + sub t6, s4, t0 /* t6 <- relocation offset */ + beq t0, s4, clear_bss /* skip relocation */ - mv t1, s4 /* t1 <- scratch for copy_loop */ - la t3, __bss_start - sub t3, t3, t0 /* t3 <- __bss_start_ofs */ - add t2, t0, t3 /* t2 <- source end address */ + mv t1, s4 /* t1 <- scratch for copy_loop */ + la t3, __bss_start + sub t3, t3, t0 /* t3 <- __bss_start_ofs */ + add t2, t0, t3 /* t2 <- source end address */ copy_loop: - LREG t5, 0(t0) - addi t0, t0, REGBYTES - SREG t5, 0(t1) - addi t1, t1, REGBYTES - blt t0, t2, copy_loop + LREG t5, 0(t0) + addi t0, t0, REGBYTES + SREG t5, 0(t1) + addi t1, t1, REGBYTES + blt t0, t2, copy_loop /* * Update dynamic relocations after board_init_f */ fix_rela_dyn: - la t1, __rel_dyn_start - la t2, __rel_dyn_end - beq t1, t2, clear_bss - add t1, t1, t6 /* t1 <- rela_dyn_start in RAM */ - add t2, t2, t6 /* t2 <- rela_dyn_end in RAM */ + la t1, __rel_dyn_start + la t2, __rel_dyn_end + beq t1, t2, clear_bss + add t1, t1, t6 /* t1 <- rela_dyn_start in RAM */ + add t2, t2, t6 /* t2 <- rela_dyn_end in RAM */ /* * skip first reserved entry: address, type, addend */ - bne t1, t2, 7f + bne t1, t2, 7f 6: - LREG t5, -(REGBYTES*2)(t1) /* t5 <-- relocation info:type */ - li t3, R_RISCV_RELATIVE /* reloc type R_RISCV_RELATIVE */ - bne t5, t3, 8f /* skip non-RISCV_RELOC entries */ - LREG t3, -(REGBYTES*3)(t1) - LREG t5, -(REGBYTES)(t1) /* t5 <-- addend */ - add t5, t5, t6 /* t5 <-- location to fix up in RAM */ - add t3, t3, t6 /* t3 <-- location to fix up in RAM */ - SREG t5, 0(t3) + LREG t5, -(REGBYTES*2)(t1) /* t5 <-- relocation info:type */ + li t3, R_RISCV_RELATIVE /* reloc type R_RISCV_RELATIVE */ + bne t5, t3, 8f /* skip non-RISCV_RELOC entries */ + LREG t3, -(REGBYTES*3)(t1) + LREG t5, -(REGBYTES)(t1) /* t5 <-- addend */ + add t5, t5, t6 /* t5 <-- location to fix up in RAM */ + add t3, t3, t6 /* t3 <-- location to fix up in RAM */ + SREG t5, 0(t3) 7: - addi t1, t1, (REGBYTES*3) - ble t1, t2, 6b + addi t1, t1, (REGBYTES*3) + ble t1, t2, 6b 8: - la t4, __dyn_sym_start - add t4, t4, t6 + la t4, __dyn_sym_start + add t4, t4, t6 9: - LREG t5, -(REGBYTES*2)(t1) /* t5 <-- relocation info:type */ - srli t0, t5, SYM_INDEX /* t0 <--- sym table index */ - andi t5, t5, 0xFF /* t5 <--- relocation type */ - li t3, RELOC_TYPE - bne t5, t3, 10f /* skip non-addned entries */ + LREG t5, -(REGBYTES*2)(t1) /* t5 <-- relocation info:type */ + srli t0, t5, SYM_INDEX /* t0 <--- sym table index */ + andi t5, t5, 0xFF /* t5 <--- relocation type */ + li t3, RELOC_TYPE + bne t5, t3, 10f /* skip non-addned entries */ - LREG t3, -(REGBYTES*3)(t1) - li t5, SYM_SIZE - mul t0, t0, t5 - add s1, t4, t0 - LREG t5, REGBYTES(s1) - add t5, t5, t6 /* t5 <-- location to fix up in RAM */ - add t3, t3, t6 /* t3 <-- location to fix up in RAM */ - SREG t5, 0(t3) + LREG t3, -(REGBYTES*3)(t1) + li t5, SYM_SIZE + mul t0, t0, t5 + add s5, t4, t0 + LREG t5, REGBYTES(s5) + add t5, t5, t6 /* t5 <-- location to fix up in RAM */ + add t3, t3, t6 /* t3 <-- location to fix up in RAM */ + SREG t5, 0(t3) 10: - addi t1, t1, (REGBYTES*3) - ble t1, t2, 9b + addi t1, t1, (REGBYTES*3) + ble t1, t2, 9b /* * trap update */ - la t0, trap_entry - add t0, t0, t6 - csrw mtvec, t0 + la t0, trap_entry + add t0, t0, t6 + csrw mtvec, t0 clear_bss: - la t0, __bss_start /* t0 <- rel __bss_start in FLASH */ - add t0, t0, t6 /* t0 <- rel __bss_start in RAM */ - la t1, __bss_end /* t1 <- rel __bss_end in FLASH */ - add t1, t1, t6 /* t1 <- rel __bss_end in RAM */ - li t2, 0x00000000 /* clear */ - beq t0, t1, call_board_init_r + la t0, __bss_start /* t0 <- rel __bss_start in FLASH */ + add t0, t0, t6 /* t0 <- rel __bss_start in RAM */ + la t1, __bss_end /* t1 <- rel __bss_end in FLASH */ + add t1, t1, t6 /* t1 <- rel __bss_end in RAM */ + beq t0, t1, call_board_init_r clbss_l: - SREG t2, 0(t0) /* clear loop... */ - addi t0, t0, REGBYTES - bne t0, t1, clbss_l + SREG zero, 0(t0) /* clear loop... */ + addi t0, t0, REGBYTES + bne t0, t1, clbss_l /* * We are done. Do not return, instead branch to second part of board * initialization, now running from RAM. */ call_board_init_r: - la t0, board_init_r - mv t4, t0 /* offset of board_init_r() */ - add t4, t4, t6 /* real address of board_init_r() */ + jal invalidate_icache_all + jal flush_dcache_all + la t0, board_init_r + mv t4, t0 /* offset of board_init_r() */ + add t4, t4, t6 /* real address of board_init_r() */ /* * setup parameters for board_init_r */ - mv a0, s3 /* gd_t */ - mv a1, s4 /* dest_addr */ + mv a0, s3 /* gd_t */ + mv a1, s4 /* dest_addr */ /* * jump to it ... */ - jr t4 /* jump to board_init_r() */ + jr t4 /* jump to board_init_r() */ /* * trap entry */ +.align 2 trap_entry: - addi sp, sp, -32*REGBYTES - SREG x1, 1*REGBYTES(sp) - SREG x2, 2*REGBYTES(sp) - SREG x3, 3*REGBYTES(sp) - SREG x4, 4*REGBYTES(sp) - SREG x5, 5*REGBYTES(sp) - SREG x6, 6*REGBYTES(sp) - SREG x7, 7*REGBYTES(sp) - SREG x8, 8*REGBYTES(sp) - SREG x9, 9*REGBYTES(sp) - SREG x10, 10*REGBYTES(sp) - SREG x11, 11*REGBYTES(sp) - SREG x12, 12*REGBYTES(sp) - SREG x13, 13*REGBYTES(sp) - SREG x14, 14*REGBYTES(sp) - SREG x15, 15*REGBYTES(sp) - SREG x16, 16*REGBYTES(sp) - SREG x17, 17*REGBYTES(sp) - SREG x18, 18*REGBYTES(sp) - SREG x19, 19*REGBYTES(sp) - SREG x20, 20*REGBYTES(sp) - SREG x21, 21*REGBYTES(sp) - SREG x22, 22*REGBYTES(sp) - SREG x23, 23*REGBYTES(sp) - SREG x24, 24*REGBYTES(sp) - SREG x25, 25*REGBYTES(sp) - SREG x26, 26*REGBYTES(sp) - SREG x27, 27*REGBYTES(sp) - SREG x28, 28*REGBYTES(sp) - SREG x29, 29*REGBYTES(sp) - SREG x30, 30*REGBYTES(sp) - SREG x31, 31*REGBYTES(sp) - csrr a0, mcause - csrr a1, mepc - mv a2, sp - jal handle_trap - csrw mepc, a0 + addi sp, sp, -32*REGBYTES + SREG x1, 1*REGBYTES(sp) + SREG x2, 2*REGBYTES(sp) + SREG x3, 3*REGBYTES(sp) + SREG x4, 4*REGBYTES(sp) + SREG x5, 5*REGBYTES(sp) + SREG x6, 6*REGBYTES(sp) + SREG x7, 7*REGBYTES(sp) + SREG x8, 8*REGBYTES(sp) + SREG x9, 9*REGBYTES(sp) + SREG x10, 10*REGBYTES(sp) + SREG x11, 11*REGBYTES(sp) + SREG x12, 12*REGBYTES(sp) + SREG x13, 13*REGBYTES(sp) + SREG x14, 14*REGBYTES(sp) + SREG x15, 15*REGBYTES(sp) + SREG x16, 16*REGBYTES(sp) + SREG x17, 17*REGBYTES(sp) + SREG x18, 18*REGBYTES(sp) + SREG x19, 19*REGBYTES(sp) + SREG x20, 20*REGBYTES(sp) + SREG x21, 21*REGBYTES(sp) + SREG x22, 22*REGBYTES(sp) + SREG x23, 23*REGBYTES(sp) + SREG x24, 24*REGBYTES(sp) + SREG x25, 25*REGBYTES(sp) + SREG x26, 26*REGBYTES(sp) + SREG x27, 27*REGBYTES(sp) + SREG x28, 28*REGBYTES(sp) + SREG x29, 29*REGBYTES(sp) + SREG x30, 30*REGBYTES(sp) + SREG x31, 31*REGBYTES(sp) + csrr a0, mcause + csrr a1, mepc + mv a2, sp + jal handle_trap + csrw mepc, a0 /* * Remain in M-mode after mret */ - li t0, MSTATUS_MPP - csrs mstatus, t0 - LREG x1, 1*REGBYTES(sp) - LREG x2, 2*REGBYTES(sp) - LREG x3, 3*REGBYTES(sp) - LREG x4, 4*REGBYTES(sp) - LREG x5, 5*REGBYTES(sp) - LREG x6, 6*REGBYTES(sp) - LREG x7, 7*REGBYTES(sp) - LREG x8, 8*REGBYTES(sp) - LREG x9, 9*REGBYTES(sp) - LREG x10, 10*REGBYTES(sp) - LREG x11, 11*REGBYTES(sp) - LREG x12, 12*REGBYTES(sp) - LREG x13, 13*REGBYTES(sp) - LREG x14, 14*REGBYTES(sp) - LREG x15, 15*REGBYTES(sp) - LREG x16, 16*REGBYTES(sp) - LREG x17, 17*REGBYTES(sp) - LREG x18, 18*REGBYTES(sp) - LREG x19, 19*REGBYTES(sp) - LREG x20, 20*REGBYTES(sp) - LREG x21, 21*REGBYTES(sp) - LREG x22, 22*REGBYTES(sp) - LREG x23, 23*REGBYTES(sp) - LREG x24, 24*REGBYTES(sp) - LREG x25, 25*REGBYTES(sp) - LREG x26, 26*REGBYTES(sp) - LREG x27, 27*REGBYTES(sp) - LREG x28, 28*REGBYTES(sp) - LREG x29, 29*REGBYTES(sp) - LREG x30, 30*REGBYTES(sp) - LREG x31, 31*REGBYTES(sp) - addi sp, sp, 32*REGBYTES + li t0, MSTATUS_MPP + csrs mstatus, t0 + LREG x1, 1*REGBYTES(sp) + LREG x2, 2*REGBYTES(sp) + LREG x3, 3*REGBYTES(sp) + LREG x4, 4*REGBYTES(sp) + LREG x5, 5*REGBYTES(sp) + LREG x6, 6*REGBYTES(sp) + LREG x7, 7*REGBYTES(sp) + LREG x8, 8*REGBYTES(sp) + LREG x9, 9*REGBYTES(sp) + LREG x10, 10*REGBYTES(sp) + LREG x11, 11*REGBYTES(sp) + LREG x12, 12*REGBYTES(sp) + LREG x13, 13*REGBYTES(sp) + LREG x14, 14*REGBYTES(sp) + LREG x15, 15*REGBYTES(sp) + LREG x16, 16*REGBYTES(sp) + LREG x17, 17*REGBYTES(sp) + LREG x18, 18*REGBYTES(sp) + LREG x19, 19*REGBYTES(sp) + LREG x20, 20*REGBYTES(sp) + LREG x21, 21*REGBYTES(sp) + LREG x22, 22*REGBYTES(sp) + LREG x23, 23*REGBYTES(sp) + LREG x24, 24*REGBYTES(sp) + LREG x25, 25*REGBYTES(sp) + LREG x26, 26*REGBYTES(sp) + LREG x27, 27*REGBYTES(sp) + LREG x28, 28*REGBYTES(sp) + LREG x29, 29*REGBYTES(sp) + LREG x30, 30*REGBYTES(sp) + LREG x31, 31*REGBYTES(sp) + addi sp, sp, 32*REGBYTES mret - -#ifdef CONFIG_INIT_CRITICAL -cpu_init_crit: - ret -#endif diff --git a/arch/riscv/dts/Makefile b/arch/riscv/dts/Makefile index a1b06ffc6f..b400defb38 100644 --- a/arch/riscv/dts/Makefile +++ b/arch/riscv/dts/Makefile @@ -1,6 +1,5 @@ # SPDX-License-Identifier: GPL-2.0+ -dtb-$(CONFIG_TARGET_AX25_AE350) += ae350.dtb targets += $(dtb-y) DTC_FLAGS += -R 4 -p 0x1000 diff --git a/arch/riscv/dts/ae350.dts b/arch/riscv/dts/ae350.dts index 4717ae88bc..e48c298645 100644 --- a/arch/riscv/dts/ae350.dts +++ b/arch/riscv/dts/ae350.dts @@ -12,15 +12,14 @@ }; chosen { - bootargs = "console=ttyS0,38400n8 earlyprintk=uart8250-32bit,0xf0300000 debug loglevel=7"; + bootargs = "console=ttyS0,38400n8 debug loglevel=7"; stdout-path = "uart0:38400n8"; }; cpus { #address-cells = <1>; #size-cells = <0>; - timebase-frequency = <10000000>; - + timebase-frequency = <60000000>; CPU0: cpu@0 { device_type = "cpu"; reg = <0>; @@ -29,7 +28,8 @@ riscv,isa = "rv64imafdc"; mmu-type = "riscv,sv39"; clock-frequency = <60000000>; - + d-cache-size = <0x8000>; + d-cache-line-size = <32>; CPU0_intc: interrupt-controller { #interrupt-cells = <1>; interrupt-controller; @@ -48,13 +48,6 @@ #size-cells = <2>; compatible = "andestech,riscv-ae350-soc"; ranges; - }; - - plmt0@e6000000 { - compatible = "riscv,plmt0"; - interrupts-extended = <&CPU0_intc 7>; - reg = <0x0 0xe6000000 0x0 0x100000>; - }; plic0: interrupt-controller@e4000000 { compatible = "riscv,plic0"; @@ -62,7 +55,7 @@ #interrupt-cells = <2>; interrupt-controller; reg = <0x0 0xe4000000 0x0 0x2000000>; - riscv,ndev=<31>; + riscv,ndev=<71>; interrupts-extended = <&CPU0_intc 11 &CPU0_intc 9>; }; @@ -76,6 +69,13 @@ interrupts-extended = <&CPU0_intc 3>; }; + plmt0@e6000000 { + compatible = "riscv,plmt0"; + interrupts-extended = <&CPU0_intc 7>; + reg = <0x0 0xe6000000 0x0 0x100000>; + }; + }; + spiclk: virt_100mhz { #clock-cells = <0>; compatible = "fixed-clock"; @@ -85,7 +85,7 @@ timer0: timer@f0400000 { compatible = "andestech,atcpit100"; reg = <0x0 0xf0400000 0x0 0x1000>; - clock-frequency = <40000000>; + clock-frequency = <60000000>; interrupts = <3 4>; interrupt-parent = <&plic0>; }; @@ -119,11 +119,89 @@ interrupt-parent = <&plic0>; }; + dma0: dma@f0c00000 { + compatible = "andestech,atcdmac300"; + reg = <0x0 0xf0c00000 0x0 0x1000>; + interrupts = <10 4 64 4 65 4 66 4 67 4 68 4 69 4 70 4 71 4>; + dma-channels = <8>; + interrupt-parent = <&plic0>; + }; + + lcd0: lcd@e0200000 { + compatible = "andestech,atflcdc100"; + reg = <0x0 0xe0200000 0x0 0x1000>; + interrupts = <20 4>; + interrupt-parent = <&plic0>; + }; + smc0: smc@e0400000 { compatible = "andestech,atfsmc020"; reg = <0x0 0xe0400000 0x0 0x1000>; }; + snd0: snd@f0d00000 { + compatible = "andestech,atfac97"; + reg = <0x0 0xf0d00000 0x0 0x1000>; + interrupts = <17 4>; + interrupt-parent = <&plic0>; + }; + + virtio_mmio@fe007000 { + interrupts = <0x17 0x4>; + interrupt-parent = <0x2>; + reg = <0x0 0xfe007000 0x0 0x1000>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@fe006000 { + interrupts = <0x16 0x4>; + interrupt-parent = <0x2>; + reg = <0x0 0xfe006000 0x0 0x1000>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@fe005000 { + interrupts = <0x15 0x4>; + interrupt-parent = <0x2>; + reg = <0x0 0xfe005000 0x0 0x1000>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@fe004000 { + interrupts = <0x14 0x4>; + interrupt-parent = <0x2>; + reg = <0x0 0xfe004000 0x0 0x1000>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@fe003000 { + interrupts = <0x13 0x4>; + interrupt-parent = <0x2>; + reg = <0x0 0xfe003000 0x0 0x1000>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@fe002000 { + interrupts = <0x12 0x4>; + interrupt-parent = <0x2>; + reg = <0x0 0xfe002000 0x0 0x1000>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@fe001000 { + interrupts = <0x11 0x4>; + interrupt-parent = <0x2>; + reg = <0x0 0xfe001000 0x0 0x1000>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@fe000000 { + interrupts = <0x10 0x4>; + interrupt-parent = <0x2>; + reg = <0x0 0xfe000000 0x0 0x1000>; + compatible = "virtio,mmio"; + }; + nor@0,0 { compatible = "cfi-flash"; reg = <0x0 0x88000000 0x0 0x1000>; @@ -138,9 +216,8 @@ #size-cells = <0>; num-cs = <1>; clocks = <&spiclk>; - interrupts = <3 4>; + interrupts = <4 4>; interrupt-parent = <&plic0>; - flash@0 { compatible = "spi-flash"; spi-max-frequency = <50000000>; diff --git a/arch/riscv/dts/ae350_32.dts b/arch/riscv/dts/ae350_32.dts new file mode 100644 index 0000000000..0679827313 --- /dev/null +++ b/arch/riscv/dts/ae350_32.dts @@ -0,0 +1,229 @@ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "andestech,a25"; + model = "andestech,a25"; + + aliases { + uart0 = &serial0; + spi0 = &spi; + }; + + chosen { + bootargs = "console=ttyS0,38400n8 debug loglevel=7"; + stdout-path = "uart0:38400n8"; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + timebase-frequency = <60000000>; + CPU0: cpu@0 { + device_type = "cpu"; + reg = <0>; + status = "okay"; + compatible = "riscv"; + riscv,isa = "rv32imafdc"; + mmu-type = "riscv,sv32"; + clock-frequency = <60000000>; + d-cache-size = <0x8000>; + d-cache-line-size = <32>; + CPU0_intc: interrupt-controller { + #interrupt-cells = <1>; + interrupt-controller; + compatible = "riscv,cpu-intc"; + }; + }; + }; + + memory@0 { + device_type = "memory"; + reg = <0x00000000 0x40000000>; + }; + + soc { + #address-cells = <1>; + #size-cells = <1>; + compatible = "andestech,riscv-ae350-soc"; + ranges; + + plic0: interrupt-controller@e4000000 { + compatible = "riscv,plic0"; + #address-cells = <1>; + #interrupt-cells = <1>; + interrupt-controller; + reg = <0xe4000000 0x2000000>; + riscv,ndev=<71>; + interrupts-extended = <&CPU0_intc 11 &CPU0_intc 9>; + }; + + plic1: interrupt-controller@e6400000 { + compatible = "riscv,plic1"; + #address-cells = <1>; + #interrupt-cells = <1>; + interrupt-controller; + reg = <0xe6400000 0x400000>; + riscv,ndev=<1>; + interrupts-extended = <&CPU0_intc 3>; + }; + + plmt0@e6000000 { + compatible = "riscv,plmt0"; + interrupts-extended = <&CPU0_intc 7>; + reg = <0xe6000000 0x100000>; + }; + }; + + spiclk: virt_100mhz { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <100000000>; + }; + + timer0: timer@f0400000 { + compatible = "andestech,atcpit100"; + reg = <0xf0400000 0x1000>; + clock-frequency = <60000000>; + interrupts = <3 4>; + interrupt-parent = <&plic0>; + }; + + serial0: serial@f0300000 { + compatible = "andestech,uart16550", "ns16550a"; + reg = <0xf0300000 0x1000>; + interrupts = <9 4>; + clock-frequency = <19660800>; + reg-shift = <2>; + reg-offset = <32>; + no-loopback-test = <1>; + interrupt-parent = <&plic0>; + }; + + mac0: mac@e0100000 { + compatible = "andestech,atmac100"; + reg = <0xe0100000 0x1000>; + interrupts = <19 4>; + interrupt-parent = <&plic0>; + }; + + mmc0: mmc@f0e00000 { + compatible = "andestech,atfsdc010"; + max-frequency = <100000000>; + clock-freq-min-max = <400000 100000000>; + fifo-depth = <0x10>; + reg = <0xf0e00000 0x1000>; + interrupts = <18 4>; + cap-sd-highspeed; + interrupt-parent = <&plic0>; + }; + + dma0: dma@f0c00000 { + compatible = "andestech,atcdmac300"; + reg = <0xf0c00000 0x1000>; + interrupts = <10 4 64 4 65 4 66 4 67 4 68 4 69 4 70 4 71 4>; + dma-channels = <8>; + interrupt-parent = <&plic0>; + }; + + lcd0: lcd@e0200000 { + compatible = "andestech,atflcdc100"; + reg = <0xe0200000 0x1000>; + interrupts = <20 4>; + interrupt-parent = <&plic0>; + }; + + smc0: smc@e0400000 { + compatible = "andestech,atfsmc020"; + reg = <0xe0400000 0x1000>; + }; + + snd0: snd@f0d00000 { + compatible = "andestech,atfac97"; + reg = <0xf0d00000 0x1000>; + interrupts = <17 4>; + interrupt-parent = <&plic0>; + }; + + virtio_mmio@fe007000 { + interrupts = <0x17 0x4>; + interrupt-parent = <0x2>; + reg = <0xfe007000 0x1000>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@fe006000 { + interrupts = <0x16 0x4>; + interrupt-parent = <0x2>; + reg = <0xfe006000 0x1000>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@fe005000 { + interrupts = <0x15 0x4>; + interrupt-parent = <0x2>; + reg = <0xfe005000 0x1000>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@fe004000 { + interrupts = <0x14 0x4>; + interrupt-parent = <0x2>; + reg = <0xfe004000 0x1000>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@fe003000 { + interrupts = <0x13 0x4>; + interrupt-parent = <0x2>; + reg = <0xfe003000 0x1000>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@fe002000 { + interrupts = <0x12 0x4>; + interrupt-parent = <0x2>; + reg = <0xfe002000 0x1000>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@fe001000 { + interrupts = <0x11 0x4>; + interrupt-parent = <0x2>; + reg = <0xfe001000 0x1000>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@fe000000 { + interrupts = <0x10 0x4>; + interrupt-parent = <0x2>; + reg = <0xfe000000 0x1000>; + compatible = "virtio,mmio"; + }; + + nor@0,0 { + compatible = "cfi-flash"; + reg = <0x88000000 0x1000>; + bank-width = <2>; + device-width = <1>; + }; + + spi: spi@f0b00000 { + compatible = "andestech,atcspi200"; + reg = <0xf0b00000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + num-cs = <1>; + clocks = <&spiclk>; + interrupts = <4 4>; + interrupt-parent = <&plic0>; + flash@0 { + compatible = "spi-flash"; + spi-max-frequency = <50000000>; + reg = <0>; + spi-cpol; + spi-cpha; + }; + }; +}; diff --git a/arch/riscv/dts/ae350_64.dts b/arch/riscv/dts/ae350_64.dts new file mode 100644 index 0000000000..e48c298645 --- /dev/null +++ b/arch/riscv/dts/ae350_64.dts @@ -0,0 +1,229 @@ +/dts-v1/; + +/ { + #address-cells = <2>; + #size-cells = <2>; + compatible = "andestech,ax25"; + model = "andestech,ax25"; + + aliases { + uart0 = &serial0; + spi0 = &spi; + }; + + chosen { + bootargs = "console=ttyS0,38400n8 debug loglevel=7"; + stdout-path = "uart0:38400n8"; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + timebase-frequency = <60000000>; + CPU0: cpu@0 { + device_type = "cpu"; + reg = <0>; + status = "okay"; + compatible = "riscv"; + riscv,isa = "rv64imafdc"; + mmu-type = "riscv,sv39"; + clock-frequency = <60000000>; + d-cache-size = <0x8000>; + d-cache-line-size = <32>; + CPU0_intc: interrupt-controller { + #interrupt-cells = <1>; + interrupt-controller; + compatible = "riscv,cpu-intc"; + }; + }; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x00000000 0x0 0x40000000>; + }; + + soc { + #address-cells = <2>; + #size-cells = <2>; + compatible = "andestech,riscv-ae350-soc"; + ranges; + + plic0: interrupt-controller@e4000000 { + compatible = "riscv,plic0"; + #address-cells = <2>; + #interrupt-cells = <2>; + interrupt-controller; + reg = <0x0 0xe4000000 0x0 0x2000000>; + riscv,ndev=<71>; + interrupts-extended = <&CPU0_intc 11 &CPU0_intc 9>; + }; + + plic1: interrupt-controller@e6400000 { + compatible = "riscv,plic1"; + #address-cells = <2>; + #interrupt-cells = <2>; + interrupt-controller; + reg = <0x0 0xe6400000 0x0 0x400000>; + riscv,ndev=<1>; + interrupts-extended = <&CPU0_intc 3>; + }; + + plmt0@e6000000 { + compatible = "riscv,plmt0"; + interrupts-extended = <&CPU0_intc 7>; + reg = <0x0 0xe6000000 0x0 0x100000>; + }; + }; + + spiclk: virt_100mhz { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <100000000>; + }; + + timer0: timer@f0400000 { + compatible = "andestech,atcpit100"; + reg = <0x0 0xf0400000 0x0 0x1000>; + clock-frequency = <60000000>; + interrupts = <3 4>; + interrupt-parent = <&plic0>; + }; + + serial0: serial@f0300000 { + compatible = "andestech,uart16550", "ns16550a"; + reg = <0x0 0xf0300000 0x0 0x1000>; + interrupts = <9 4>; + clock-frequency = <19660800>; + reg-shift = <2>; + reg-offset = <32>; + no-loopback-test = <1>; + interrupt-parent = <&plic0>; + }; + + mac0: mac@e0100000 { + compatible = "andestech,atmac100"; + reg = <0x0 0xe0100000 0x0 0x1000>; + interrupts = <19 4>; + interrupt-parent = <&plic0>; + }; + + mmc0: mmc@f0e00000 { + compatible = "andestech,atfsdc010"; + max-frequency = <100000000>; + clock-freq-min-max = <400000 100000000>; + fifo-depth = <0x10>; + reg = <0x0 0xf0e00000 0x0 0x1000>; + interrupts = <18 4>; + cap-sd-highspeed; + interrupt-parent = <&plic0>; + }; + + dma0: dma@f0c00000 { + compatible = "andestech,atcdmac300"; + reg = <0x0 0xf0c00000 0x0 0x1000>; + interrupts = <10 4 64 4 65 4 66 4 67 4 68 4 69 4 70 4 71 4>; + dma-channels = <8>; + interrupt-parent = <&plic0>; + }; + + lcd0: lcd@e0200000 { + compatible = "andestech,atflcdc100"; + reg = <0x0 0xe0200000 0x0 0x1000>; + interrupts = <20 4>; + interrupt-parent = <&plic0>; + }; + + smc0: smc@e0400000 { + compatible = "andestech,atfsmc020"; + reg = <0x0 0xe0400000 0x0 0x1000>; + }; + + snd0: snd@f0d00000 { + compatible = "andestech,atfac97"; + reg = <0x0 0xf0d00000 0x0 0x1000>; + interrupts = <17 4>; + interrupt-parent = <&plic0>; + }; + + virtio_mmio@fe007000 { + interrupts = <0x17 0x4>; + interrupt-parent = <0x2>; + reg = <0x0 0xfe007000 0x0 0x1000>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@fe006000 { + interrupts = <0x16 0x4>; + interrupt-parent = <0x2>; + reg = <0x0 0xfe006000 0x0 0x1000>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@fe005000 { + interrupts = <0x15 0x4>; + interrupt-parent = <0x2>; + reg = <0x0 0xfe005000 0x0 0x1000>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@fe004000 { + interrupts = <0x14 0x4>; + interrupt-parent = <0x2>; + reg = <0x0 0xfe004000 0x0 0x1000>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@fe003000 { + interrupts = <0x13 0x4>; + interrupt-parent = <0x2>; + reg = <0x0 0xfe003000 0x0 0x1000>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@fe002000 { + interrupts = <0x12 0x4>; + interrupt-parent = <0x2>; + reg = <0x0 0xfe002000 0x0 0x1000>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@fe001000 { + interrupts = <0x11 0x4>; + interrupt-parent = <0x2>; + reg = <0x0 0xfe001000 0x0 0x1000>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@fe000000 { + interrupts = <0x10 0x4>; + interrupt-parent = <0x2>; + reg = <0x0 0xfe000000 0x0 0x1000>; + compatible = "virtio,mmio"; + }; + + nor@0,0 { + compatible = "cfi-flash"; + reg = <0x0 0x88000000 0x0 0x1000>; + bank-width = <2>; + device-width = <1>; + }; + + spi: spi@f0b00000 { + compatible = "andestech,atcspi200"; + reg = <0x0 0xf0b00000 0x0 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + num-cs = <1>; + clocks = <&spiclk>; + interrupts = <4 4>; + interrupt-parent = <&plic0>; + flash@0 { + compatible = "spi-flash"; + spi-max-frequency = <50000000>; + reg = <0>; + spi-cpol; + spi-cpha; + }; + }; +}; diff --git a/arch/riscv/include/asm/barrier.h b/arch/riscv/include/asm/barrier.h new file mode 100644 index 0000000000..a3f60a8458 --- /dev/null +++ b/arch/riscv/include/asm/barrier.h @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2012 ARM Ltd. + * Copyright (C) 2013 Regents of the University of California + * Copyright (C) 2017 SiFive + * + * Taken from Linux arch/riscv/include/asm/barrier.h, which is based on + * arch/arm/include/asm/barrier.h + */ + +#ifndef _ASM_RISCV_BARRIER_H +#define _ASM_RISCV_BARRIER_H + +#ifndef __ASSEMBLY__ + +#define nop() __asm__ __volatile__ ("nop") + +#define RISCV_FENCE(p, s) \ + __asm__ __volatile__ ("fence " #p "," #s : : : "memory") + +/* These barriers need to enforce ordering on both devices or memory. */ +#define mb() RISCV_FENCE(iorw,iorw) +#define rmb() RISCV_FENCE(ir,ir) +#define wmb() RISCV_FENCE(ow,ow) + +/* These barriers do not need to enforce ordering on devices, just memory. */ +#define __smp_mb() RISCV_FENCE(rw,rw) +#define __smp_rmb() RISCV_FENCE(r,r) +#define __smp_wmb() RISCV_FENCE(w,w) + +#define __smp_store_release(p, v) \ +do { \ + compiletime_assert_atomic_type(*p); \ + RISCV_FENCE(rw,w); \ + WRITE_ONCE(*p, v); \ +} while (0) + +#define __smp_load_acquire(p) \ +({ \ + typeof(*p) ___p1 = READ_ONCE(*p); \ + compiletime_assert_atomic_type(*p); \ + RISCV_FENCE(r,rw); \ + ___p1; \ +}) + +/* + * This is a very specific barrier: it's currently only used in two places in + * the kernel, both in the scheduler. See include/linux/spinlock.h for the two + * orderings it guarantees, but the "critical section is RCsc" guarantee + * mandates a barrier on RISC-V. The sequence looks like: + * + * lr.aq lock + * sc lock <= LOCKED + * smp_mb__after_spinlock() + * // critical section + * lr lock + * sc.rl lock <= UNLOCKED + * + * The AQ/RL pair provides a RCpc critical section, but there's not really any + * way we can take advantage of that here because the ordering is only enforced + * on that one lock. Thus, we're just doing a full fence. + */ +#define smp_mb__after_spinlock() RISCV_FENCE(rw,rw) + +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_RISCV_BARRIER_H */ diff --git a/arch/riscv/include/asm/cache.h b/arch/riscv/include/asm/cache.h index ca83dd67c2..ec8fe201d3 100644 --- a/arch/riscv/include/asm/cache.h +++ b/arch/riscv/include/asm/cache.h @@ -7,6 +7,9 @@ #ifndef _ASM_RISCV_CACHE_H #define _ASM_RISCV_CACHE_H +/* cache */ +void cache_flush(void); + /* * The current upper bound for RISCV L1 data cache line sizes is 32 bytes. * We use that value for aligning DMA buffers unless the board config has diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h index 50fccea5c8..29624fdbb5 100644 --- a/arch/riscv/include/asm/csr.h +++ b/arch/riscv/include/asm/csr.h @@ -8,6 +8,8 @@ #ifndef _ASM_RISCV_CSR_H #define _ASM_RISCV_CSR_H +#include <linux/const.h> + /* Status register flags */ #define SR_SIE _AC(0x00000002, UL) /* Supervisor Interrupt Enable */ #define SR_SPIE _AC(0x00000020, UL) /* Previous Supervisor IE */ diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h index f4a76d8720..acf5a96449 100644 --- a/arch/riscv/include/asm/io.h +++ b/arch/riscv/include/asm/io.h @@ -10,22 +10,13 @@ #ifdef __KERNEL__ #include <linux/types.h> +#include <asm/barrier.h> #include <asm/byteorder.h> static inline void sync(void) { } -/* - * Given a physical address and a length, return a virtual address - * that can be used to access the memory range with the caching - * properties specified by "flags". - */ -#define MAP_NOCACHE (0) -#define MAP_WRCOMBINE (0) -#define MAP_WRBACK (0) -#define MAP_WRTHROUGH (0) - #ifdef CONFIG_ARCH_MAP_SYSMEM static inline void *map_sysmem(phys_addr_t paddr, unsigned long len) { @@ -48,24 +39,6 @@ static inline phys_addr_t map_to_sysmem(const void *ptr) } #endif -static inline void * -map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags) -{ - return (void *)paddr; -} - -/* - * Take down a mapping set up by map_physmem(). - */ -static inline void unmap_physmem(void *vaddr, unsigned long flags) -{ -} - -static inline phys_addr_t virt_to_phys(void *vaddr) -{ - return (phys_addr_t)(vaddr); -} - /* * Generic virtual read/write. Note that we don't support half-word * read/writes. We define __arch_*[bl] here, and leave __arch_*w @@ -74,12 +47,12 @@ static inline phys_addr_t virt_to_phys(void *vaddr) #define __arch_getb(a) (*(unsigned char *)(a)) #define __arch_getw(a) (*(unsigned short *)(a)) #define __arch_getl(a) (*(unsigned int *)(a)) -#define __arch_getq(a) (*(unsigned long *)(a)) +#define __arch_getq(a) (*(unsigned long long *)(a)) #define __arch_putb(v, a) (*(unsigned char *)(a) = (v)) #define __arch_putw(v, a) (*(unsigned short *)(a) = (v)) #define __arch_putl(v, a) (*(unsigned int *)(a) = (v)) -#define __arch_putq(v, a) (*(unsigned long *)(a) = (v)) +#define __arch_putq(v, a) (*(unsigned long long *)(a) = (v)) #define __raw_writeb(v, a) __arch_putb(v, a) #define __raw_writew(v, a) __arch_putw(v, a) @@ -91,13 +64,9 @@ static inline phys_addr_t virt_to_phys(void *vaddr) #define __raw_readl(a) __arch_getl(a) #define __raw_readq(a) __arch_getq(a) -/* - * TODO: The kernel offers some more advanced versions of barriers, it might - * have some advantages to use them instead of the simple one here. - */ -#define dmb() __asm__ __volatile__ ("" : : : "memory") -#define __iormb() dmb() -#define __iowmb() dmb() +#define dmb() mb() +#define __iormb() rmb() +#define __iowmb() wmb() static inline void writeb(u8 val, volatile void __iomem *addr) { @@ -152,7 +121,7 @@ static inline u32 readl(const volatile void __iomem *addr) static inline u64 readq(const volatile void __iomem *addr) { - u32 val; + u64 val; val = __arch_getq(addr); __iormb(); @@ -487,4 +456,7 @@ out: #endif /* __mem_isa */ #endif /* __KERNEL__ */ + +#include <asm-generic/io.h> + #endif /* __ASM_RISCV_IO_H */ diff --git a/arch/riscv/include/asm/posix_types.h b/arch/riscv/include/asm/posix_types.h index 7438dbeb03..0fc052082a 100644 --- a/arch/riscv/include/asm/posix_types.h +++ b/arch/riscv/include/asm/posix_types.h @@ -37,10 +37,10 @@ typedef unsigned short __kernel_gid_t; #ifdef __GNUC__ typedef __SIZE_TYPE__ __kernel_size_t; #else -typedef unsigned int __kernel_size_t; +typedef unsigned long __kernel_size_t; #endif -typedef int __kernel_ssize_t; -typedef int __kernel_ptrdiff_t; +typedef long __kernel_ssize_t; +typedef long __kernel_ptrdiff_t; typedef long __kernel_time_t; typedef long __kernel_suseconds_t; typedef long __kernel_clock_t; diff --git a/arch/riscv/include/asm/types.h b/arch/riscv/include/asm/types.h index bd8627196d..403cf9a48f 100644 --- a/arch/riscv/include/asm/types.h +++ b/arch/riscv/include/asm/types.h @@ -21,7 +21,11 @@ typedef unsigned short umode_t; */ #ifdef __KERNEL__ +#ifdef CONFIG_ARCH_RV64I +#define BITS_PER_LONG 64 +#else #define BITS_PER_LONG 32 +#endif #include <stddef.h> diff --git a/arch/riscv/lib/bootm.c b/arch/riscv/lib/bootm.c index 2b5ccce933..124aeefff8 100644 --- a/arch/riscv/lib/bootm.c +++ b/arch/riscv/lib/bootm.c @@ -8,6 +8,8 @@ #include <common.h> #include <command.h> +#include <dm.h> +#include <dm/root.h> #include <image.h> #include <asm/byteorder.h> #include <asm/csr.h> @@ -26,26 +28,41 @@ int arch_fixup_fdt(void *blob) return 0; } -int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) +/** + * announce_and_cleanup() - Print message and prepare for kernel boot + * + * @fake: non-zero to do everything except actually boot + */ +static void announce_and_cleanup(int fake) { - void (*kernel)(ulong hart, void *dtb); - - /* - * allow the PREP bootm subcommand, it is required for bootm to work - */ - if (flag & BOOTM_STATE_OS_PREP) - return 0; + printf("\nStarting kernel ...%s\n\n", fake ? + "(fake run for tracing)" : ""); + bootstage_mark_name(BOOTSTAGE_ID_BOOTM_HANDOFF, "start_kernel"); +#ifdef CONFIG_BOOTSTAGE_FDT + bootstage_fdt_add_report(); +#endif +#ifdef CONFIG_BOOTSTAGE_REPORT + bootstage_report(); +#endif - if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) - return 1; +#ifdef CONFIG_USB_DEVICE + udc_disconnect(); +#endif - kernel = (void (*)(ulong, void *))images->ep; + board_quiesce_devices(); - bootstage_mark(BOOTSTAGE_ID_RUN_OS); + /* + * Call remove function of all devices with a removal flag set. + * This may be useful for last-stage operations, like cancelling + * of DMA operation or releasing device internal buffers. + */ + dm_remove_devices_flags(DM_REMOVE_ACTIVE_ALL); - debug("## Transferring control to Linux (at address %08lx) ...\n", - (ulong)kernel); + cleanup_before_linux(); +} +static void boot_prep_linux(bootm_headers_t *images) +{ if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) { #ifdef CONFIG_OF_LIBFDT debug("using: FDT\n"); @@ -54,24 +71,50 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) hang(); } #endif + } else { + printf("Device tree not found or missing FDT support\n"); + hang(); } +} - /* we assume that the kernel is in place */ - printf("\nStarting kernel ...\n\n"); +static void boot_jump_linux(bootm_headers_t *images, int flag) +{ + void (*kernel)(ulong hart, void *dtb); + int fake = (flag & BOOTM_STATE_OS_FAKE_GO); - /* - * Call remove function of all devices with a removal flag set. - * This may be useful for last-stage operations, like cancelling - * of DMA operation or releasing device internal buffers. - */ - dm_remove_devices_flags(DM_REMOVE_ACTIVE_ALL); + kernel = (void (*)(ulong, void *))images->ep; - cleanup_before_linux(); + bootstage_mark(BOOTSTAGE_ID_RUN_OS); + + debug("## Transferring control to Linux (at address %08lx) ...\n", + (ulong)kernel); - if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) - kernel(csr_read(mhartid), images->ft_addr); + announce_and_cleanup(fake); - /* does not return */ + if (!fake) { + if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) + kernel(csr_read(mhartid), images->ft_addr); + } +} + +int do_bootm_linux(int flag, int argc, char * const argv[], + bootm_headers_t *images) +{ + /* No need for those on RISC-V */ + if (flag & BOOTM_STATE_OS_BD_T || flag & BOOTM_STATE_OS_CMDLINE) + return -1; - return 1; + if (flag & BOOTM_STATE_OS_PREP) { + boot_prep_linux(images); + return 0; + } + + if (flag & (BOOTM_STATE_OS_GO | BOOTM_STATE_OS_FAKE_GO)) { + boot_jump_linux(images, flag); + return 0; + } + + boot_prep_linux(images); + boot_jump_linux(images, flag); + return 0; } diff --git a/arch/riscv/lib/cache.c b/arch/riscv/lib/cache.c index 1d67c49c2c..ae5c60716f 100644 --- a/arch/riscv/lib/cache.c +++ b/arch/riscv/lib/cache.c @@ -6,44 +6,68 @@ #include <common.h> +void invalidate_icache_all(void) +{ + asm volatile ("fence.i" ::: "memory"); +} + +void flush_dcache_all(void) +{ + asm volatile ("fence" :::"memory"); +} void flush_dcache_range(unsigned long start, unsigned long end) { + flush_dcache_all(); } void invalidate_icache_range(unsigned long start, unsigned long end) { + /* + * RISC-V does not have an instruction for invalidating parts of the + * instruction cache. Invalidate all of it instead. + */ + invalidate_icache_all(); } void invalidate_dcache_range(unsigned long start, unsigned long end) { + flush_dcache_all(); +} + +void cache_flush(void) +{ + invalidate_icache_all(); + flush_dcache_all(); } void flush_cache(unsigned long addr, unsigned long size) { + invalidate_icache_all(); + flush_dcache_all(); } -void icache_enable(void) +__weak void icache_enable(void) { } -void icache_disable(void) +__weak void icache_disable(void) { } -int icache_status(void) +__weak int icache_status(void) { return 0; } -void dcache_enable(void) +__weak void dcache_enable(void) { } -void dcache_disable(void) +__weak void dcache_disable(void) { } -int dcache_status(void) +__weak int dcache_status(void) { return 0; } diff --git a/arch/riscv/lib/interrupts.c b/arch/riscv/lib/interrupts.c index 0a0995a7af..903a1c4cd5 100644 --- a/arch/riscv/lib/interrupts.c +++ b/arch/riscv/lib/interrupts.c @@ -12,7 +12,7 @@ #include <asm/system.h> #include <asm/encoding.h> -static void _exit_trap(int code, uint epc, struct pt_regs *regs); +static void _exit_trap(ulong code, ulong epc, struct pt_regs *regs); int interrupt_init(void) { @@ -34,9 +34,9 @@ int disable_interrupts(void) return 0; } -uint handle_trap(uint mcause, uint epc, struct pt_regs *regs) +ulong handle_trap(ulong mcause, ulong epc, struct pt_regs *regs) { - uint is_int; + ulong is_int; is_int = (mcause & MCAUSE_INT); if ((is_int) && ((mcause & MCAUSE_CAUSE) == IRQ_M_EXT)) @@ -60,16 +60,33 @@ __attribute__((weak)) void timer_interrupt(struct pt_regs *regs) { } -static void _exit_trap(int code, uint epc, struct pt_regs *regs) +static void _exit_trap(ulong code, ulong epc, struct pt_regs *regs) { static const char * const exception_code[] = { "Instruction address misaligned", "Instruction access fault", "Illegal instruction", "Breakpoint", - "Load address misaligned" + "Load address misaligned", + "Load access fault", + "Store/AMO address misaligned", + "Store/AMO access fault", + "Environment call from U-mode", + "Environment call from S-mode", + "Reserved", + "Environment call from M-mode", + "Instruction page fault", + "Load page fault", + "Reserved", + "Store/AMO page fault", }; - printf("exception code: %d , %s , epc %08x , ra %08lx\n", - code, exception_code[code], epc, regs->ra); + if (code < ARRAY_SIZE(exception_code)) { + printf("exception code: %ld , %s , epc %lx , ra %lx\n", + code, exception_code[code], epc, regs->ra); + } else { + printf("Reserved\n"); + } + + hang(); } diff --git a/arch/riscv/lib/setjmp.S b/arch/riscv/lib/setjmp.S index 8f5a6a23aa..72bc9241f6 100644 --- a/arch/riscv/lib/setjmp.S +++ b/arch/riscv/lib/setjmp.S @@ -6,7 +6,7 @@ #include <config.h> #include <linux/linkage.h> -#ifdef CONFIG_CPU_RISCV_64 +#ifdef CONFIG_ARCH_RV64I #define STORE_IDX(reg, idx) sd reg, (idx*8)(a0) #define LOAD_IDX(reg, idx) ld reg, (idx*8)(a0) #else diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c index 6098945049..fdfb209f77 100644 --- a/arch/sandbox/cpu/cpu.c +++ b/arch/sandbox/cpu/cpu.c @@ -2,7 +2,7 @@ /* * Copyright (c) 2011 The Chromium OS Authors. */ -#define DEBUG + #include <common.h> #include <dm.h> #include <errno.h> @@ -105,8 +105,8 @@ void *phys_to_virt(phys_addr_t paddr) state = state_get_current(); list_for_each_entry(mentry, &state->mapmem_head, sibling_node) { if (mentry->tag == paddr) { - printf("%s: Used map from %lx to %p\n", __func__, - (ulong)paddr, mentry->ptr); + debug("%s: Used map from %lx to %p\n", __func__, + (ulong)paddr, mentry->ptr); return mentry->ptr; } } @@ -152,7 +152,7 @@ phys_addr_t virt_to_phys(void *ptr) __func__, ptr, (ulong)gd->ram_size); os_abort(); } - printf("%s: Used map from %p to %lx\n", __func__, ptr, mentry->tag); + debug("%s: Used map from %p to %lx\n", __func__, ptr, mentry->tag); return mentry->tag; } diff --git a/arch/sandbox/cpu/eth-raw-os.c b/arch/sandbox/cpu/eth-raw-os.c index 75bfaa4c90..8d05bc2eda 100644 --- a/arch/sandbox/cpu/eth-raw-os.c +++ b/arch/sandbox/cpu/eth-raw-os.c @@ -11,6 +11,7 @@ #include <netinet/in.h> #include <netinet/ip.h> #include <netinet/udp.h> +#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -23,6 +24,8 @@ #include <linux/if_ether.h> #include <linux/if_packet.h> +#include <os.h> + struct sandbox_eth_raw_if_nameindex *sandbox_eth_raw_if_nameindex(void) { return (struct sandbox_eth_raw_if_nameindex *)if_nameindex(); @@ -71,7 +74,7 @@ static int _raw_packet_start(struct eth_sandbox_raw_priv *priv, /* Prepare device struct */ priv->local_bind_sd = -1; - priv->device = malloc(sizeof(struct sockaddr_ll)); + priv->device = os_malloc(sizeof(struct sockaddr_ll)); if (priv->device == NULL) return -ENOMEM; device = priv->device; @@ -144,7 +147,7 @@ static int _local_inet_start(struct eth_sandbox_raw_priv *priv) /* Prepare device struct */ priv->local_bind_sd = -1; priv->local_bind_udp_port = 0; - priv->device = malloc(sizeof(struct sockaddr_in)); + priv->device = os_malloc(sizeof(struct sockaddr_in)); if (priv->device == NULL) return -ENOMEM; device = priv->device; @@ -279,7 +282,7 @@ int sandbox_eth_raw_os_recv(void *packet, int *length, void sandbox_eth_raw_os_stop(struct eth_sandbox_raw_priv *priv) { - free(priv->device); + os_free(priv->device); priv->device = NULL; close(priv->sd); priv->sd = -1; diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c index 325ded51d8..aa92694342 100644 --- a/arch/sandbox/cpu/os.c +++ b/arch/sandbox/cpu/os.c @@ -98,9 +98,8 @@ void os_exit(int exit_code) exit(exit_code); } -int os_write_file(const char *name, const void *buf, int size) +int os_write_file(const char *fname, const void *buf, int size) { - char fname[256]; int fd; fd = os_open(fname, OS_O_WRONLY | OS_O_CREAT | OS_O_TRUNC); @@ -110,14 +109,53 @@ int os_write_file(const char *name, const void *buf, int size) } if (os_write(fd, buf, size) != size) { printf("Cannot write to file '%s'\n", fname); + os_close(fd); return -EIO; } os_close(fd); - printf("Write '%s', size %#x (%d)\n", name, size, size); return 0; } +int os_read_file(const char *fname, void **bufp, int *sizep) +{ + off_t size; + int ret = -EIO; + int fd; + + fd = os_open(fname, OS_O_RDONLY); + if (fd < 0) { + printf("Cannot open file '%s'\n", fname); + goto err; + } + size = os_lseek(fd, 0, OS_SEEK_END); + if (size < 0) { + printf("Cannot seek to end of file '%s'\n", fname); + goto err; + } + if (os_lseek(fd, 0, OS_SEEK_SET) < 0) { + printf("Cannot seek to start of file '%s'\n", fname); + goto err; + } + *bufp = os_malloc(size); + if (!*bufp) { + printf("Not enough memory to read file '%s'\n", fname); + ret = -ENOMEM; + goto err; + } + if (os_read(fd, *bufp, size) != size) { + printf("Cannot read from file '%s'\n", fname); + goto err; + } + os_close(fd); + *sizep = size; + + return 0; +err: + os_close(fd); + return ret; +} + /* Restore tty state when we exit */ static struct termios orig_term; static bool term_setup; @@ -343,7 +381,7 @@ void os_dirent_free(struct os_dirent_node *node) while (node) { next = node->next; - free(node); + os_free(node); node = next; } } @@ -368,7 +406,7 @@ int os_dirent_ls(const char *dirname, struct os_dirent_node **headp) /* Create a buffer upfront, with typically sufficient size */ dirlen = strlen(dirname) + 2; len = dirlen + 256; - fname = malloc(len); + fname = os_malloc(len); if (!fname) { ret = -ENOMEM; goto done; @@ -381,7 +419,7 @@ int os_dirent_ls(const char *dirname, struct os_dirent_node **headp) ret = errno; break; } - next = malloc(sizeof(*node) + strlen(entry->d_name) + 1); + next = os_malloc(sizeof(*node) + strlen(entry->d_name) + 1); if (!next) { os_dirent_free(head); ret = -ENOMEM; @@ -390,10 +428,10 @@ int os_dirent_ls(const char *dirname, struct os_dirent_node **headp) if (dirlen + strlen(entry->d_name) > len) { len = dirlen + strlen(entry->d_name); old_fname = fname; - fname = realloc(fname, len); + fname = os_realloc(fname, len); if (!fname) { - free(old_fname); - free(next); + os_free(old_fname); + os_free(next); os_dirent_free(head); ret = -ENOMEM; goto done; @@ -427,7 +465,7 @@ int os_dirent_ls(const char *dirname, struct os_dirent_node **headp) done: closedir(dir); - free(fname); + os_free(fname); return ret; } @@ -525,20 +563,48 @@ static int make_exec(char *fname, const void *data, int size) return 0; } -static int add_args(char ***argvp, const char *add_args[], int count) +/** + * add_args() - Allocate a new argv with the given args + * + * This is used to create a new argv array with all the old arguments and some + * new ones that are passed in + * + * @argvp: Returns newly allocated args list + * @add_args: Arguments to add, each a string + * @count: Number of arguments in @add_args + * @return 0 if OK, -ENOMEM if out of memory + */ +static int add_args(char ***argvp, char *add_args[], int count) { - char **argv; + char **argv, **ap; int argc; - for (argv = *argvp, argc = 0; (*argvp)[argc]; argc++) + for (argc = 0; (*argvp)[argc]; argc++) ; - argv = malloc((argc + count + 1) * sizeof(char *)); + argv = os_malloc((argc + count + 1) * sizeof(char *)); if (!argv) { printf("Out of memory for %d argv\n", count); return -ENOMEM; } - memcpy(argv, *argvp, argc * sizeof(char *)); + for (ap = *argvp, argc = 0; *ap; ap++) { + char *arg = *ap; + + /* Drop args that we don't want to propagate */ + if (*arg == '-' && strlen(arg) == 2) { + switch (arg[1]) { + case 'j': + case 'm': + ap++; + continue; + } + } else if (!strcmp(arg, "--rm_memory")) { + ap++; + continue; + } + argv[argc++] = arg; + } + memcpy(argv + argc, add_args, count * sizeof(char *)); argv[argc + count] = NULL; @@ -546,21 +612,27 @@ static int add_args(char ***argvp, const char *add_args[], int count) return 0; } -int os_jump_to_image(const void *dest, int size) +/** + * os_jump_to_file() - Jump to a new program + * + * This saves the memory buffer, sets up arguments to the new process, then + * execs it. + * + * @fname: Filename to exec + * @return does not return on success, any return value is an error + */ +static int os_jump_to_file(const char *fname) { struct sandbox_state *state = state_get_current(); - char fname[30], mem_fname[30]; + char mem_fname[30]; int fd, err; - const char *extra_args[5]; + char *extra_args[5]; char **argv = state->argv; + int argc; #ifdef DEBUG - int argc, i; + int i; #endif - err = make_exec(fname, dest, size); - if (err) - return err; - strcpy(mem_fname, "/tmp/u-boot.mem.XXXXXX"); fd = mkstemp(mem_fname); if (fd < 0) @@ -573,14 +645,16 @@ int os_jump_to_image(const void *dest, int size) os_fd_restore(); extra_args[0] = "-j"; - extra_args[1] = fname; + extra_args[1] = (char *)fname; extra_args[2] = "-m"; extra_args[3] = mem_fname; - extra_args[4] = "--rm_memory"; - err = add_args(&argv, extra_args, - sizeof(extra_args) / sizeof(extra_args[0])); + argc = 4; + if (state->ram_buf_rm) + extra_args[argc++] = "--rm_memory"; + err = add_args(&argv, extra_args, argc); if (err) return err; + argv[0] = (char *)fname; #ifdef DEBUG for (i = 0; argv[i]; i++) @@ -591,13 +665,28 @@ int os_jump_to_image(const void *dest, int size) os_exit(2); err = execv(fname, argv); - free(argv); - if (err) + os_free(argv); + if (err) { + perror("Unable to run image"); + printf("Image filename '%s'\n", mem_fname); return err; + } return unlink(fname); } +int os_jump_to_image(const void *dest, int size) +{ + char fname[30]; + int err; + + err = make_exec(fname, dest, size); + if (err) + return err; + + return os_jump_to_file(fname); +} + int os_find_u_boot(char *fname, int maxlen) { struct sandbox_state *state = state_get_current(); @@ -661,17 +750,7 @@ int os_find_u_boot(char *fname, int maxlen) int os_spl_to_uboot(const char *fname) { - struct sandbox_state *state = state_get_current(); - char *argv[state->argc + 1]; - int ret; - - memcpy(argv, state->argv, sizeof(char *) * (state->argc + 1)); - argv[0] = (char *)fname; - ret = execv(fname, argv); - if (ret) - return ret; - - return unlink(fname); + return os_jump_to_file(fname); } void os_localtime(struct rtc_time *rt) diff --git a/arch/sandbox/cpu/spl.c b/arch/sandbox/cpu/spl.c index 42c149a498..5005ed2f54 100644 --- a/arch/sandbox/cpu/spl.c +++ b/arch/sandbox/cpu/spl.c @@ -37,12 +37,39 @@ static int spl_board_load_image(struct spl_image_info *spl_image, return ret; } - /* Hopefully this will not return */ - return os_spl_to_uboot(fname); + /* Set up spl_image to boot from jump_to_image_no_args() */ + spl_image->arg = strdup(fname); + if (!spl_image->arg) + return log_msg_ret("Setup exec filename", -ENOMEM); + + return 0; } SPL_LOAD_IMAGE_METHOD("sandbox", 0, BOOT_DEVICE_BOARD, spl_board_load_image); void spl_board_init(void) { + struct sandbox_state *state = state_get_current(); + struct udevice *dev; + preloader_console_init(); + if (state->show_of_platdata) { + /* + * Scan all the devices so that we can output their platform + * data. See sandbox_spl_probe(). + */ + printf("Scanning misc devices\n"); + for (uclass_first_device(UCLASS_MISC, &dev); + dev; + uclass_next_device(&dev)) + ; + } +} + +void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) +{ + const char *fname = spl_image->arg; + + os_fd_restore(); + os_spl_to_uboot(fname); + hang(); } diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c index 2ee3b48565..b1566a8143 100644 --- a/arch/sandbox/cpu/start.c +++ b/arch/sandbox/cpu/start.c @@ -283,6 +283,15 @@ static int sandbox_cmdline_cb_log_level(struct sandbox_state *state, SANDBOX_CMDLINE_OPT_SHORT(log_level, 'L', 1, "Set log level (0=panic, 7=debug)"); +static int sandbox_cmdline_cb_show_of_platdata(struct sandbox_state *state, + const char *arg) +{ + state->show_of_platdata = true; + + return 0; +} +SANDBOX_CMDLINE_OPT(show_of_platdata, 0, "Show of-platdata in SPL"); + int board_run_command(const char *cmdline) { printf("## Commands are disabled. Please enable CONFIG_CMDLINE.\n"); @@ -296,6 +305,16 @@ static void setup_ram_buf(struct sandbox_state *state) gd->ram_size = state->ram_size; } +void state_show(struct sandbox_state *state) +{ + char **p; + + printf("Arguments:\n"); + for (p = state->argv; *p; p++) + printf("%s ", *p); + printf("\n"); +} + int main(int argc, char *argv[]) { struct sandbox_state *state; diff --git a/arch/sandbox/cpu/u-boot-spl.lds b/arch/sandbox/cpu/u-boot-spl.lds index f97abdfa05..de65b01b33 100644 --- a/arch/sandbox/cpu/u-boot-spl.lds +++ b/arch/sandbox/cpu/u-boot-spl.lds @@ -14,7 +14,7 @@ SECTIONS } __u_boot_sandbox_option_start = .; - _u_boot_sandbox_getopt : { *(.u_boot_sandbox_getopt) } + _u_boot_sandbox_getopt : { KEEP(*(.u_boot_sandbox_getopt)) } __u_boot_sandbox_option_end = .; __bss_start = .; diff --git a/arch/sandbox/dts/sandbox.dts b/arch/sandbox/dts/sandbox.dts index fb866e8807..1cda911d1f 100644 --- a/arch/sandbox/dts/sandbox.dts +++ b/arch/sandbox/dts/sandbox.dts @@ -20,6 +20,7 @@ cros_ec: cros-ec { reg = <0 0>; + u-boot,dm-pre-reloc; compatible = "google,cros-ec-sandbox"; /* @@ -27,6 +28,7 @@ * that the STM32L flash erases to 0, not 0xff. */ flash { + u-boot,dm-pre-reloc; image-pos = <0x08000000>; size = <0x20000>; erase-value = <0>; @@ -59,6 +61,7 @@ }; gpio_a: gpios@0 { + u-boot,dm-pre-reloc; gpio-controller; compatible = "sandbox,gpio"; #gpio-cells = <1>; @@ -67,6 +70,7 @@ }; gpio_b: gpios@1 { + u-boot,dm-pre-reloc; gpio-controller; compatible = "sandbox,gpio"; #gpio-cells = <2>; @@ -178,12 +182,14 @@ }; spi@0 { + u-boot,dm-pre-reloc; #address-cells = <1>; #size-cells = <0>; reg = <0 0>; compatible = "sandbox,spi"; cs-gpios = <0>, <&gpio_a 0>; firmware_storage_spi: flash@0 { + u-boot,dm-pre-reloc; reg = <0>; compatible = "spansion,m25p16", "sandbox,spi-flash"; spi-max-frequency = <40000000>; @@ -239,6 +245,7 @@ }; tpm { + u-boot,dm-pre-reloc; compatible = "google,sandbox-tpm"; }; @@ -256,6 +263,7 @@ /* Needs to be available prior to relocation */ uart0: serial { + u-boot,dm-spl; compatible = "sandbox,serial"; sandbox,text-colour = "cyan"; pinctrl-names = "default"; @@ -350,3 +358,10 @@ #include "cros-ec-keyboard.dtsi" #include "sandbox_pmic.dtsi" + +&cros_ec { + u-boot,dm-pre-reloc; + keyboard-controller { + u-boot,dm-pre-reloc; + }; +}; diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 024aa7c512..2c6b422312 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -727,6 +727,10 @@ sandbox_virtio2 { compatible = "sandbox,virtio2"; }; + + pinctrl { + compatible = "sandbox,pinctrl"; + }; }; #include "sandbox_pmic.dtsi" diff --git a/arch/sandbox/include/asm/handoff.h b/arch/sandbox/include/asm/handoff.h new file mode 100644 index 0000000000..be4e7b0fae --- /dev/null +++ b/arch/sandbox/include/asm/handoff.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Architecture-specific SPL handoff information for sandbox + * + * Copyright 2018 Google, Inc + * Written by Simon Glass <sjg@chromium.org> + */ + +#ifndef __handoff_h +#define __handoff_h + +#define TEST_HANDOFF_MAGIC 0x14f93c7b + +struct arch_spl_handoff { + ulong magic; /* Used for testing */ +}; + +#endif diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h index dcb6d5f568..8fabe70a86 100644 --- a/arch/sandbox/include/asm/state.h +++ b/arch/sandbox/include/asm/state.h @@ -89,6 +89,7 @@ struct sandbox_state { bool skip_delays; /* Ignore any time delays (for test) */ bool show_test_output; /* Don't suppress stdout in tests */ int default_log_level; /* Default log level for sandbox */ + bool show_of_platdata; /* Show of-platdata in SPL */ /* Pointer to information for each SPI bus/cs */ struct sandbox_spi_info spi[CONFIG_SANDBOX_SPI_MAX_BUS] @@ -242,6 +243,13 @@ bool state_get_skip_delays(void); void state_reset_for_test(struct sandbox_state *state); /** + * state_show() - Show information about the sandbox state + * + * @param state Sandbox state to show + */ +void state_show(struct sandbox_state *state); + +/** * Initialize the test system state */ int state_init(void); diff --git a/arch/sandbox/include/asm/test.h b/arch/sandbox/include/asm/test.h index 8e60f80ae7..5e81839295 100644 --- a/arch/sandbox/include/asm/test.h +++ b/arch/sandbox/include/asm/test.h @@ -113,4 +113,12 @@ int sandbox_osd_get_mem(struct udevice *dev, u8 *buf, size_t buflen); int sandbox_pwm_get_config(struct udevice *dev, uint channel, uint *period_nsp, uint *duty_nsp, bool *enablep, bool *polarityp); +/** + * sandbox_sf_set_block_protect() - Set the BP bits of the status register + * + * @dev: Device to update + * @bp_mask: BP bits to set (bits 2:0, so a value of 0 to 7) + */ +void sandbox_sf_set_block_protect(struct udevice *dev, int bp_mask); + #endif diff --git a/arch/sh/config.mk b/arch/sh/config.mk index 92abee17ad..6ef44638ab 100644 --- a/arch/sh/config.mk +++ b/arch/sh/config.mk @@ -9,7 +9,7 @@ endif CONFIG_STANDALONE_LOAD_ADDR ?= 0x8C000000 ifeq ($(CPU),sh2) -CONFIG_STANDALONE_LOAD_ADDR += -EB +LDFLAGS_STANDALONE += -EB endif PLATFORM_CPPFLAGS += -DCONFIG_SH -D__SH__ diff --git a/board/AndesTech/ax25-ae350/MAINTAINERS b/board/AndesTech/ax25-ae350/MAINTAINERS index 508c6ace72..d87446ee1c 100644 --- a/board/AndesTech/ax25-ae350/MAINTAINERS +++ b/board/AndesTech/ax25-ae350/MAINTAINERS @@ -3,4 +3,6 @@ M: Rick Chen <rick@andestech.com> S: Maintained F: board/AndesTech/ax25-ae350/ F: include/configs/ax25-ae350.h +F: configs/a25-ae350_32_defconfig +F: configs/ax25-ae350_64_defconfig F: configs/ax25-ae350_defconfig diff --git a/board/armltd/integrator/README b/board/armltd/integrator/README index 5a0e934924..af9dcc1f4f 100644 --- a/board/armltd/integrator/README +++ b/board/armltd/integrator/README @@ -36,9 +36,7 @@ In case c) it may be necessary for U-Boot to perform CM dependent initialization Configuring U-Boot : ------------------ The makefile contains targets for Integrator platforms of both types -fitted with all current variants of CM. If these targets are to be used with -boot process c) above then CONFIG_INIT_CRITICAL may need to be defined to ensure -that the CM is correctly configured. +fitted with all current variants of CM. There are also targets independent of CM. These may not be suitable for boot process c) above. They have been preserved for backward compatibility with diff --git a/board/broadcom/bcm968580xref/Kconfig b/board/broadcom/bcm968580xref/Kconfig new file mode 100644 index 0000000000..b5730367a2 --- /dev/null +++ b/board/broadcom/bcm968580xref/Kconfig @@ -0,0 +1,17 @@ +if ARCH_BCM6858 + +config SYS_VENDOR + default "broadcom" + +config SYS_BOARD + default "bcm968580xref" + +config SYS_CONFIG_NAME + default "broadcom_bcm968580xref" + +endif + +config TARGET_BCM968580XREF + bool "Support Broadcom bcm968580xref" + depends on ARCH_BCM6858 + select ARM64 diff --git a/board/broadcom/bcm968580xref/MAINTAINERS b/board/broadcom/bcm968580xref/MAINTAINERS new file mode 100644 index 0000000000..1ecdfbc0bb --- /dev/null +++ b/board/broadcom/bcm968580xref/MAINTAINERS @@ -0,0 +1,6 @@ +BROADCOM BCM968580XREF +M: Philippe Reynes <philippe.reynes@softathome.com> +S: Maintained +F: board/broadcom/bcm968580xref/ +F: include/configs/broadcom_bcm968580xref.h +F: configs/bcm968580_ram_defconfig diff --git a/board/broadcom/bcm968580xref/Makefile b/board/broadcom/bcm968580xref/Makefile new file mode 100644 index 0000000000..5cd393b196 --- /dev/null +++ b/board/broadcom/bcm968580xref/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0+ + +obj-y += bcm968580xref.o diff --git a/board/broadcom/bcm968580xref/bcm968580xref.c b/board/broadcom/bcm968580xref/bcm968580xref.c new file mode 100644 index 0000000000..2e547f5170 --- /dev/null +++ b/board/broadcom/bcm968580xref/bcm968580xref.c @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Philippe Reynes <philippe.reynes@softathome.com> + */ + +#include <common.h> +#include <fdtdec.h> +#include <linux/io.h> + +#ifdef CONFIG_ARM64 +#include <asm/armv8/mmu.h> + +static struct mm_region broadcom_bcm968580xref_mem_map[] = { + { + /* RAM */ + .virt = 0x00000000UL, + .phys = 0x00000000UL, + .size = 8UL * SZ_1G, + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE + }, { + /* SoC */ + .virt = 0x80000000UL, + .phys = 0x80000000UL, + .size = 0xff80000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* List terminator */ + 0, + } +}; + +struct mm_region *mem_map = broadcom_bcm968580xref_mem_map; +#endif + +int board_init(void) +{ + return 0; +} + +int dram_init(void) +{ + if (fdtdec_setup_mem_size_base() != 0) + printf("fdtdec_setup_mem_size_base() has failed\n"); + + return 0; +} + +int dram_init_banksize(void) +{ + fdtdec_setup_memory_banksize(); + + return 0; +} + +int print_cpuinfo(void) +{ + return 0; +} diff --git a/board/emulation/qemu-riscv/Kconfig b/board/emulation/qemu-riscv/Kconfig index 37a80db6a9..33ca253432 100644 --- a/board/emulation/qemu-riscv/Kconfig +++ b/board/emulation/qemu-riscv/Kconfig @@ -29,5 +29,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy imply CMD_EXT2 imply CMD_EXT4 imply CMD_FAT + imply BOARD_LATE_INIT + imply OF_BOARD_SETUP endif diff --git a/board/emulation/qemu-riscv/qemu-riscv.c b/board/emulation/qemu-riscv/qemu-riscv.c index 2730a288fb..d6167aaef1 100644 --- a/board/emulation/qemu-riscv/qemu-riscv.c +++ b/board/emulation/qemu-riscv/qemu-riscv.c @@ -9,8 +9,6 @@ #include <virtio_types.h> #include <virtio.h> -#define MROM_FDT_ADDR 0x1020 - int board_init(void) { /* @@ -22,11 +20,70 @@ int board_init(void) return 0; } -void *board_fdt_blob_setup(void) +int board_late_init(void) { - /* - * QEMU loads a generated DTB for us immediately - * after the reset vectors in the MROM - */ - return (void *)MROM_FDT_ADDR; + ulong kernel_start; + ofnode chosen_node; + int ret; + + chosen_node = ofnode_path("/chosen"); + if (!ofnode_valid(chosen_node)) { + debug("No chosen node found, can't get kernel start address\n"); + return 0; + } + +#ifdef CONFIG_ARCH_RV64I + ret = ofnode_read_u64(chosen_node, "riscv,kernel-start", + (u64 *)&kernel_start); +#else + ret = ofnode_read_u32(chosen_node, "riscv,kernel-start", + (u32 *)&kernel_start); +#endif + if (ret) { + debug("Can't find kernel start address in device tree\n"); + return 0; + } + + env_set_hex("kernel_start", kernel_start); + + return 0; +} + +/* + * QEMU specifies the location of Linux (supplied with the -kernel argument) + * in the device tree using the riscv,kernel-start and riscv,kernel-end + * properties. We currently rely on the SBI implementation of BBL to run + * Linux and therefore embed Linux as payload in BBL. This causes an issue, + * because BBL detects the kernel properties in the device tree and ignores + * the Linux payload as a result. To work around this issue, we clear the + * kernel properties before booting Linux. + * + * This workaround can be removed, once we do not require BBL for its SBI + * implementation anymore. + */ +int ft_board_setup(void *blob, bd_t *bd) +{ + int chosen_offset, ret; + + chosen_offset = fdt_path_offset(blob, "/chosen"); + if (chosen_offset < 0) + return 0; + +#ifdef CONFIG_ARCH_RV64I + ret = fdt_setprop_u64(blob, chosen_offset, "riscv,kernel-start", 0); +#else + ret = fdt_setprop_u32(blob, chosen_offset, "riscv,kernel-start", 0); +#endif + if (ret) + return ret; + +#ifdef CONFIG_ARCH_RV64I + ret = fdt_setprop_u64(blob, chosen_offset, "riscv,kernel-end", 0); +#else + ret = fdt_setprop_u32(blob, chosen_offset, "riscv,kernel-end", 0); +#endif + if (ret) + return ret; + + return 0; } diff --git a/board/gardena/smart-gateway-mt7688/board.c b/board/gardena/smart-gateway-mt7688/board.c index 5ff546f505..3a1838e44a 100644 --- a/board/gardena/smart-gateway-mt7688/board.c +++ b/board/gardena/smart-gateway-mt7688/board.c @@ -4,14 +4,26 @@ */ #include <common.h> -#include <asm/io.h> +#include <led.h> +#include <linux/io.h> + +#define MT76XX_AGPIO_CFG 0x1000003c int board_early_init_f(void) { - /* - * Nothing to be done here for this board (no UART setup etc) - * right now. We might need some pin muxing, so lets keep this - * function for now. - */ + void __iomem *gpio_mode; + + /* Configure digital vs analog GPIOs */ + gpio_mode = ioremap_nocache(MT76XX_AGPIO_CFG, 0x100); + iowrite32(0x00fe01ff, gpio_mode); + + return 0; +} + +int board_late_init(void) +{ + if (IS_ENABLED(CONFIG_LED)) + led_default_state(); + return 0; } diff --git a/board/samsung/common/board.c b/board/samsung/common/board.c index c4b6baedf0..6fd26a3a91 100644 --- a/board/samsung/common/board.c +++ b/board/samsung/common/board.c @@ -306,14 +306,16 @@ int checkboard(void) #ifdef CONFIG_BOARD_LATE_INIT int board_late_init(void) { - stdio_print_current_devices(); + struct udevice *dev; + int ret; - if (cros_ec_get_error()) { + stdio_print_current_devices(); + ret = uclass_first_device_err(UCLASS_CROS_EC, &dev); + if (ret && ret != -ENODEV) { /* Force console on */ gd->flags &= ~GD_FLG_SILENT; - printf("cros-ec communications failure %d\n", - cros_ec_get_error()); + printf("cros-ec communications failure %d\n", ret); puts("\nPlease reset with Power+Refresh\n\n"); panic("Cannot init cros-ec device"); return -1; diff --git a/board/sandbox/README.sandbox b/board/sandbox/README.sandbox index a28fc9f36c..9b09404294 100644 --- a/board/sandbox/README.sandbox +++ b/board/sandbox/README.sandbox @@ -247,25 +247,28 @@ sudo /path/to/u-boot -D DHCP .... -set autoload no -set ethact eth1 +setenv autoload no +setenv ethrotate no +setenv ethact eth1 dhcp PING .... -set autoload no -set ethact eth1 +setenv autoload no +setenv ethrotate no +setenv ethact eth1 dhcp ping $gatewayip TFTP .... -set autoload no -set ethact eth1 +setenv autoload no +setenv ethrotate no +setenv ethact eth1 dhcp -set serverip WWW.XXX.YYY.ZZZ +setenv serverip WWW.XXX.YYY.ZZZ tftpboot u-boot.bin The bridge also supports (to a lesser extent) the localhost interface, 'lo'. @@ -287,7 +290,8 @@ operation being tested on the lo interface. TFTP .... -set ethact eth5 +setenv ethrotate no +setenv ethact eth5 tftpboot u-boot.bin @@ -418,7 +422,19 @@ coverage in U-Boot is limited, as we need to work to improve it. Note that many of these tests are implemented as commands which you can run natively on your board if desired (and enabled). -It would be useful to have a central script to run all of these. +To run all tests use "make check". + + +Memory Map +---------- + +Sandbox has its own emulated memory starting at 0. Here are some of the things +that are mapped into that memory: + + 0 CONFIG_SYS_FDT_LOAD_ADDR Device tree + e000 CONFIG_BLOBLIST_ADDR Blob list + 10000 CONFIG_MALLOC_F_ADDR Early memory allocation + -- Simon Glass <sjg@chromium.org> diff --git a/board/sandbox/sandbox.c b/board/sandbox/sandbox.c index 0e87674826..397e7561d4 100644 --- a/board/sandbox/sandbox.c +++ b/board/sandbox/sandbox.c @@ -59,12 +59,15 @@ int board_init(void) #ifdef CONFIG_BOARD_LATE_INIT int board_late_init(void) { - if (cros_ec_get_error()) { + struct udevice *dev; + int ret; + + ret = uclass_first_device_err(UCLASS_CROS_EC, &dev); + if (ret && ret != -ENODEV) { /* Force console on */ gd->flags &= ~GD_FLG_SILENT; - printf("cros-ec communications failure %d\n", - cros_ec_get_error()); + printf("cros-ec communications failure %d\n", ret); puts("\nPlease reset with Power+Refresh\n\n"); panic("Cannot init cros-ec device"); return -1; diff --git a/board/seeed/linkit-smart-7688/board.c b/board/seeed/linkit-smart-7688/board.c index a28abc00b8..d3d3d50c2c 100644 --- a/board/seeed/linkit-smart-7688/board.c +++ b/board/seeed/linkit-smart-7688/board.c @@ -6,12 +6,15 @@ #include <common.h> #include <asm/io.h> -#define MT76XX_GPIO1_MODE 0xb0000060 +#define MT76XX_GPIO1_MODE 0x10000060 void board_debug_uart_init(void) { + void __iomem *gpio_mode; + /* Select UART2 mode instead of GPIO mode (default) */ - clrbits_le32((void __iomem *)MT76XX_GPIO1_MODE, GENMASK(27, 26)); + gpio_mode = ioremap_nocache(MT76XX_GPIO1_MODE, 0x100); + clrbits_le32(gpio_mode, GENMASK(27, 26)); } int board_early_init_f(void) diff --git a/board/solidrun/clearfog/MAINTAINERS b/board/solidrun/clearfog/MAINTAINERS index 298e5011c7..6646d96206 100644 --- a/board/solidrun/clearfog/MAINTAINERS +++ b/board/solidrun/clearfog/MAINTAINERS @@ -4,3 +4,4 @@ S: Maintained F: board/soldrun/clearfog/ F: include/configs/clearfog.h F: configs/clearfog_defconfig +F: configs/clearfog_gt_8k_defconfig diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS index 478e37285f..9b6e0c4c21 100644 --- a/board/sunxi/MAINTAINERS +++ b/board/sunxi/MAINTAINERS @@ -380,10 +380,16 @@ M: Hauke Mehrtens <hauke@hauke-m.de> S: Maintained F: configs/orangepi_r1_defconfig +PINEBOOK BOARD: +M: Vasily Khoruzhick <anarsoul@gmail.com> +S: Maintained +F: configs/pinebook_defconfig + PINE64 BOARDS M: Andre Przywara <andre.przywara@arm.com> S: Maintained F: configs/pine64_plus_defconfig +F: configs/pine64-lts_defconfig PINE H64 BOARD M: Icenowy Zheng <icenowy@aosc.io> diff --git a/board/ti/am65x/Kconfig b/board/ti/am65x/Kconfig index 591600483e..d4b36dbb42 100644 --- a/board/ti/am65x/Kconfig +++ b/board/ti/am65x/Kconfig @@ -12,6 +12,14 @@ config TARGET_AM654_A53_EVM select ARM64 select SOC_K3_AM6 +config TARGET_AM654_R5_EVM + bool "TI K3 based AM654 EVM running on R5" + select CPU_V7R + select SYS_THUMB_BUILD + select SOC_K3_AM6 + select K3_AM654_DDRSS + imply SYS_K3_SPL_ATF + endchoice if TARGET_AM654_A53_EVM @@ -26,3 +34,19 @@ config SYS_CONFIG_NAME default "am65x_evm" endif + +if TARGET_AM654_R5_EVM + +config SYS_BOARD + default "am65x" + +config SYS_VENDOR + default "ti" + +config SYS_CONFIG_NAME + default "am65x_evm" + +config SPL_LDSCRIPT + default "arch/arm/mach-omap2/u-boot-spl.lds" + +endif diff --git a/board/ti/am65x/MAINTAINERS b/board/ti/am65x/MAINTAINERS index ca1ce58f72..7c52e7599e 100644 --- a/board/ti/am65x/MAINTAINERS +++ b/board/ti/am65x/MAINTAINERS @@ -4,3 +4,4 @@ S: Maintained F: board/ti/am65x/ F: include/configs/am65x_evm.h F: configs/am65x_evm_a53_defconfig +F: configs/am65x_evm_r5_defconfig diff --git a/board/ti/am65x/README b/board/ti/am65x/README index e7f4ff6578..0b82bd557b 100644 --- a/board/ti/am65x/README +++ b/board/ti/am65x/README @@ -37,13 +37,13 @@ instead use Flacon boot flow to reduce boot time. | +--------+ | | | | : | | | | +--------+ | +-----------+ | | -| | *rom* |----------|-->| Reset rls | | | +| | *ROM* |----------|-->| Reset rls | | | | +--------+ | +-----------+ | | | | | | : | | -| | rom | | : | | +| | ROM | | : | | | |services| | : | | | | | | +-------------+ | | -| | | | | *R5 rom* | | | +| | | | | *R5 ROM* | | | | | | | +-------------+ | | | | |<---------|---|Load and auth| | | | | | | | tiboot3.bin | | | @@ -52,17 +52,25 @@ instead use Flacon boot flow to reduce boot time. | | | | : | | | | | | : | | | | | | +-------------+ | | -| | Start | | | *R5 SPL* | | | -| | System | | +-------------+ | | -| |Firmware|<---------|---|Load and auth| | | -| +--------+ | | sysfw bin | | | -| : | +-------------+ | | -| +---------+ | | DDR | | | -| | *SYSFW* | | | config | | | -| +---------+ | +-------------+ | | -| | |<--------|---| Load | | | -| | | | | tispl.bin | | | +| | | | | *R5 SPL* | | | +| | | | +-------------+ | | +| | | | | Load | | | +| | | | | sysfw.itb | | | +| | Start | | +-------------+ | | +| | System |<---------|---| Start | | | +| |Firmware| | | SYSFW | | | +| +--------+ | +-------------+ | | +| : | | | | | +| +---------+ | | Load | | | +| | *SYSFW* | | | system | | | +| +---------+ | | Config data | | | +| | |<--------|---| | | | +| | | | +-------------+ | | +| | | | | | | | +| | | | | DDR | | | +| | | | | config | | | | | | | +-------------+ | | +| | | | | | | | | | |<--------|---| Start A53 | | | | | | | | and Reset | | | | | | | +-------------+ | | @@ -82,7 +90,7 @@ instead use Flacon boot flow to reduce boot time. | | | | | +-----------+ | | | | | | : | | | | | | +-----------+ | -| | |<--------|-----------------------|---->| *u-boot* | | +| | |<--------|-----------------------|---->| *U-Boot* | | | | | | | +-----------+ | | | | | | | prompt | | | | | | | +-----------+ | @@ -96,9 +104,8 @@ requests DMSC to get these services done as shown in the above diagram. Sources: -------- 1. SYSFW: - System Firmware repo is closed source and the binaries are delivered - to users with NDA. Please contact TI to get the System Firmware - Binary named ti-sci-firmware-am6x.bin that runs on AM65x SoC. + Tree: git://git.ti.com/processor-firmware/system-firmware-image-gen.git + Branch: master 2. ATF: Tree: https://github.com/ARM-software/arm-trusted-firmware.git @@ -115,9 +122,7 @@ Sources: Build procedure: ---------------- 1. SYSFW: - ROM expects a signed binary that contains the X509 certificate. So -the binary ti-sci-firmware-am6x.bin cannot be uses as-is and needs to be signed. -Contact TI on the procedure to sign the system firmware binary. +$ make CROSS_COMPILE=arm-linux-gnueabihf- 2. ATF: $ make CROSS_COMPILE=aarch64-linux-gnu- ARCH=aarch64 PLAT=k3 TARGET_BOARD=generic SPD=opteed @@ -128,14 +133,79 @@ $ make PLATFORM=k3-am65x CFG_ARM64_core=y 4. U-Boot: 4.1. R5: - TBD. +$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- am65x_evm_r5_defconfig O=/tmp/r5 +$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- O=/tmp/r5 4.2. A53: $ make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- am65x_evm_a53_defconfig O=/tmp/a53 -$ make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- ATF=<path to ATF dir>/build/k3/generic/release/bl31.bin TEE=<path to OPTEE OS dir>/out/arm-plat-k3/core/tee-pager.bin O=/tmp/a53 +$ make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- ATF=<path to ATF dir>/build/k3/generic/release/bl31.bin TEE=<path to OPTEE OS dir>/out/arm-plat-k3/core/tee-pager.bin O=/tmp/a53 Target Images -------------- Copy the below images to an SD card and boot: +- sysfw.itb from step 1 - tiboot3.bin from step 4.1 - tispl.bin, u-boot.img from 4.2 + +Image formats: +-------------- + +- tiboot3.bin: + +-----------------------+ + | X.509 | + | Certificate | + | +-------------------+ | + | | | | + | | R5 | | + | | u-boot-spl.bin | | + | | | | + | +-------------------+ | + | | | | + | | FIT header | | + | | +---------------+ | | + | | | | | | + | | | DTB 1...N | | | + | | +---------------+ | | + | +-------------------+ | + +-----------------------+ + +- tispl.bin + +-----------------------+ + | | + | FIT HEADER | + | +-------------------+ | + | | | | + | | A53 ATF | | + | +-------------------+ | + | | | | + | | A53 OPTEE | | + | +-------------------+ | + | | | | + | | A53 SPL | | + | +-------------------+ | + | | | | + | | SPL DTB 1...N | | + | +-------------------+ | + +-----------------------+ + +- sysfw.itb + +-----------------------+ + | | + | FIT HEADER | + | +-------------------+ | + | | | | + | | sysfw.bin | | + | +-------------------+ | + | | | | + | | board config | | + | +-------------------+ | + | | | | + | | PM config | | + | +-------------------+ | + | | | | + | | RM config | | + | +-------------------+ | + | | | | + | | Secure config | | + | +-------------------+ | + +-----------------------+ diff --git a/cmd/Kconfig b/cmd/Kconfig index d609f9d1c9..e2973b3c51 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -953,6 +953,14 @@ config CMD_PCMCIA about 1990. These devices are typically removable memory or network cards using a standard 68-pin connector. +config CMD_PINMUX + bool "pinmux - show pins muxing" + default y if PINCTRL + help + Parse all available pin-controllers and show pins muxing. This + is useful for debug purpoer to check the pin muxing and to know if + a pin is configured as a GPIO or as an alternate function. + config CMD_POWEROFF bool "poweroff" help diff --git a/cmd/Makefile b/cmd/Makefile index 12a1330b06..5ec2f9e8eb 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -103,6 +103,7 @@ ifdef CONFIG_PCI obj-$(CONFIG_CMD_PCI) += pci.o endif obj-y += pcmcia.o +obj-$(CONFIG_CMD_PINMUX) += pinmux.o obj-$(CONFIG_CMD_PXE) += pxe.o obj-$(CONFIG_CMD_WOL) += wol.o obj-$(CONFIG_CMD_QFW) += qfw.o @@ -114,6 +115,7 @@ obj-$(CONFIG_CMD_ROCKUSB) += rockusb.o obj-$(CONFIG_SANDBOX) += host.o obj-$(CONFIG_CMD_SATA) += sata.o obj-$(CONFIG_CMD_NVME) += nvme.o +obj-$(CONFIG_SANDBOX) += sb.o obj-$(CONFIG_CMD_SF) += sf.o obj-$(CONFIG_CMD_SCSI) += scsi.o disk.o obj-$(CONFIG_CMD_SHA1SUM) += sha1sum.o @@ -35,7 +35,7 @@ static int do_adc_info(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { struct udevice *dev; - unsigned int data_mask; + unsigned int data_mask, ch_mask; int ret, vss, vdd; if (argc < 2) @@ -49,6 +49,10 @@ static int do_adc_info(cmd_tbl_t *cmdtp, int flag, int argc, printf("ADC Device '%s' :\n", argv[1]); + ret = adc_channel_mask(dev, &ch_mask); + if (!ret) + printf("channel mask: %x\n", ch_mask); + ret = adc_data_mask(dev, &data_mask); if (!ret) printf("data mask: %x\n", data_mask); @@ -67,8 +71,9 @@ static int do_adc_info(cmd_tbl_t *cmdtp, int flag, int argc, static int do_adc_single(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { + struct udevice *dev; unsigned int data; - int ret; + int ret, uV; if (argc < 3) return CMD_RET_USAGE; @@ -81,7 +86,62 @@ static int do_adc_single(cmd_tbl_t *cmdtp, int flag, int argc, return CMD_RET_FAILURE; } - printf("%u\n", data); + ret = uclass_get_device_by_name(UCLASS_ADC, argv[1], &dev); + if (!ret && !adc_raw_to_uV(dev, data, &uV)) + printf("%u, %d uV\n", data, uV); + else + printf("%u\n", data); + + return CMD_RET_SUCCESS; +} + +static int do_adc_scan(cmd_tbl_t *cmdtp, int flag, int argc, + char *const argv[]) +{ + struct adc_channel ch[ADC_MAX_CHANNEL]; + struct udevice *dev; + unsigned int ch_mask; + int i, chan, ret, uV; + + if (argc < 2) + return CMD_RET_USAGE; + + ret = uclass_get_device_by_name(UCLASS_ADC, argv[1], &dev); + if (ret) { + pr_err("Can't get the ADC %s: %d\n", argv[1], ret); + return CMD_RET_FAILURE; + } + + switch (argc) { + case 3: + ch_mask = simple_strtoul(argv[2], NULL, 0); + if (ch_mask) + break; + case 2: + ret = adc_channel_mask(dev, &ch_mask); + if (ret) { + pr_err("Can't get mask for %s: %d\n", dev->name, ret); + return CMD_RET_FAILURE; + } + break; + } + + ret = adc_channels_single_shot(dev->name, ch_mask, ch); + if (ret) { + pr_err("Can't get single shot for %s (chans mask: 0x%x): %d\n", + dev->name, ch_mask, ret); + return CMD_RET_FAILURE; + } + + for (chan = 0, i = 0; chan < ADC_MAX_CHANNEL; chan++) { + if (!(ch_mask & ADC_CHANNEL(chan))) + continue; + if (!adc_raw_to_uV(dev, ch[i].data, &uV)) + printf("[%02d]: %u, %d uV\n", ch[i].id, ch[i].data, uV); + else + printf("[%02d]: %u\n", ch[i].id, ch[i].data); + i++; + } return CMD_RET_SUCCESS; } @@ -90,6 +150,7 @@ static cmd_tbl_t cmd_adc_sub[] = { U_BOOT_CMD_MKENT(list, 1, 1, do_adc_list, "", ""), U_BOOT_CMD_MKENT(info, 2, 1, do_adc_info, "", ""), U_BOOT_CMD_MKENT(single, 3, 1, do_adc_single, "", ""), + U_BOOT_CMD_MKENT(scan, 3, 1, do_adc_scan, "", ""), }; static int do_adc(cmd_tbl_t *cmdtp, int flag, int argc, @@ -115,6 +176,7 @@ static int do_adc(cmd_tbl_t *cmdtp, int flag, int argc, static char adc_help_text[] = "list - list ADC devices\n" "adc info <name> - Get ADC device info\n" - "adc single <name> <channel> - Get Single data of ADC device channel"; + "adc single <name> <channel> - Get Single data of ADC device channel\n" + "adc scan <name> [channel mask] - Scan all [or masked] ADC channels"; U_BOOT_CMD(adc, 4, 1, do_adc, "ADC sub-system", adc_help_text); diff --git a/cmd/bdinfo.c b/cmd/bdinfo.c index 60b438766d..cbeba6ba28 100644 --- a/cmd/bdinfo.c +++ b/cmd/bdinfo.c @@ -16,7 +16,7 @@ DECLARE_GLOBAL_DATA_PTR; __maybe_unused static void print_num(const char *name, ulong value) { - printf("%-12s= 0x%08lX\n", name, value); + printf("%-12s= 0x%0*lx\n", name, 2 * (int)sizeof(value), value); } __maybe_unused @@ -348,7 +348,7 @@ static int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, CONFIG_VAL(SYS_MALLOC_F_LEN)); #endif if (gd->fdt_blob) - printf("fdt_blob = %p\n", gd->fdt_blob); + print_num("fdt_blob", (ulong)gd->fdt_blob); return 0; } @@ -202,7 +202,7 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) fdt_strerror(err)); return 1; } - working_fdt = newaddr; + set_working_fdt_addr((ulong)newaddr); #ifdef CONFIG_OF_SYSTEM_SETUP /* Call the board-specific fixup routine */ } else if (strncmp(argv[1], "sys", 3) == 0) { diff --git a/cmd/host.c b/cmd/host.c index 645dba4de8..f7d3eae5b1 100644 --- a/cmd/host.c +++ b/cmd/host.c @@ -168,11 +168,6 @@ static int do_host(cmd_tbl_t *cmdtp, int flag, int argc, } U_BOOT_CMD( - sb, 8, 1, do_host, - "Deprecated: use 'host' command instead.", "" -); - -U_BOOT_CMD( host, 8, 1, do_host, "Miscellaneous host commands", "load hostfs - <addr> <filename> [<bytes> <offset>] - " diff --git a/cmd/pinmux.c b/cmd/pinmux.c new file mode 100644 index 0000000000..6c8ec5164d --- /dev/null +++ b/cmd/pinmux.c @@ -0,0 +1,146 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018, STMicroelectronics - All Rights Reserved + */ + +#include <common.h> +#include <command.h> +#include <dm.h> +#include <errno.h> +#include <dm/pinctrl.h> +#include <dm/uclass-internal.h> + +#define LIMIT_DEVNAME 30 + +static struct udevice *currdev; + +static int do_dev(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + const char *name; + int ret; + + switch (argc) { + case 2: + name = argv[1]; + ret = uclass_get_device_by_name(UCLASS_PINCTRL, name, &currdev); + if (ret) { + printf("Can't get the pin-controller: %s!\n", name); + return CMD_RET_FAILURE; + } + case 1: + if (!currdev) { + printf("Pin-controller device is not set!\n"); + return CMD_RET_USAGE; + } + + printf("dev: %s\n", currdev->name); + } + + return CMD_RET_SUCCESS; +} + +static int show_pinmux(struct udevice *dev) +{ + char pin_name[PINNAME_SIZE]; + char pin_mux[PINMUX_SIZE]; + int pins_count; + int i; + int ret; + + pins_count = pinctrl_get_pins_count(dev); + + if (pins_count == -ENOSYS) { + printf("Ops get_pins_count not supported\n"); + return pins_count; + } + + for (i = 0; i < pins_count; i++) { + ret = pinctrl_get_pin_name(dev, i, pin_name, PINNAME_SIZE); + if (ret == -ENOSYS) { + printf("Ops get_pin_name not supported\n"); + return ret; + } + + ret = pinctrl_get_pin_muxing(dev, i, pin_mux, PINMUX_SIZE); + if (ret) { + printf("Ops get_pin_muxing error (%d)\n", ret); + return ret; + } + + printf("%-*s: %-*s\n", PINNAME_SIZE, pin_name, + PINMUX_SIZE, pin_mux); + } + + return 0; +} + +static int do_status(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + struct udevice *dev; + int ret = CMD_RET_USAGE; + + if (currdev && (argc < 2 || strcmp(argv[1], "-a"))) + return show_pinmux(currdev); + + if (argc < 2 || strcmp(argv[1], "-a")) + return ret; + + uclass_foreach_dev_probe(UCLASS_PINCTRL, dev) { + /* insert a separator between each pin-controller display */ + printf("--------------------------\n"); + printf("%s:\n", dev->name); + ret = show_pinmux(dev); + if (ret < 0) + printf("Can't display pin muxing for %s\n", + dev->name); + } + + return ret; +} + +static int do_list(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + struct udevice *dev; + + printf("| %-*.*s| %-*.*s| %s\n", + LIMIT_DEVNAME, LIMIT_DEVNAME, "Device", + LIMIT_DEVNAME, LIMIT_DEVNAME, "Driver", + "Parent"); + + uclass_foreach_dev_probe(UCLASS_PINCTRL, dev) { + printf("| %-*.*s| %-*.*s| %s\n", + LIMIT_DEVNAME, LIMIT_DEVNAME, dev->name, + LIMIT_DEVNAME, LIMIT_DEVNAME, dev->driver->name, + dev->parent->name); + } + + return CMD_RET_SUCCESS; +} + +static cmd_tbl_t pinmux_subcmd[] = { + U_BOOT_CMD_MKENT(dev, 2, 1, do_dev, "", ""), + U_BOOT_CMD_MKENT(list, 1, 1, do_list, "", ""), + U_BOOT_CMD_MKENT(status, 2, 1, do_status, "", ""), +}; + +static int do_pinmux(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + cmd_tbl_t *cmd; + + argc--; + argv++; + + cmd = find_cmd_tbl(argv[0], pinmux_subcmd, ARRAY_SIZE(pinmux_subcmd)); + if (!cmd || argc > cmd->maxargs) + return CMD_RET_USAGE; + + return cmd->cmd(cmdtp, flag, argc, argv); +} + +U_BOOT_CMD(pinmux, CONFIG_SYS_MAXARGS, 1, do_pinmux, + "show pin-controller muxing", + "list - list UCLASS_PINCTRL devices\n" + "pinmux dev [pincontroller-name] - select pin-controller device\n" + "pinmux status [-a] - print pin-controller muxing [for all]\n" +) diff --git a/cmd/sb.c b/cmd/sb.c new file mode 100644 index 0000000000..5701e03797 --- /dev/null +++ b/cmd/sb.c @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018, Google Inc. + * Written by Simon Glass <sjg@chromium.org> + */ + +#include <common.h> +#include <dm.h> +#include <spl.h> +#include <asm/state.h> + +static int do_sb_handoff(cmd_tbl_t *cmdtp, int flag, int argc, + char *const argv[]) +{ +#if CONFIG_IS_ENABLED(HANDOFF) + if (gd->spl_handoff) + printf("SPL handoff magic %lx\n", gd->spl_handoff->arch.magic); + else + printf("SPL handoff info not received\n"); + + return 0; +#else + printf("Command not supported\n"); + + return CMD_RET_USAGE; +#endif +} + +static int do_sb_state(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + struct sandbox_state *state; + + state = state_get_current(); + state_show(state); + + return 0; +} + +static cmd_tbl_t cmd_sb_sub[] = { + U_BOOT_CMD_MKENT(handoff, 1, 0, do_sb_handoff, "", ""), + U_BOOT_CMD_MKENT(state, 1, 0, do_sb_state, "", ""), +}; + +static int do_sb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + cmd_tbl_t *c; + + /* Skip past 'sb' */ + argc--; + argv++; + + c = find_cmd_tbl(argv[0], cmd_sb_sub, ARRAY_SIZE(cmd_sb_sub)); + if (c) + return c->cmd(cmdtp, flag, argc, argv); + else + return CMD_RET_USAGE; +} + +U_BOOT_CMD( + sb, 8, 1, do_sb, + "Sandbox status commands", + "handoff - Show handoff data received from SPL\n" + "sb state - Show sandbox state" +); diff --git a/common/Kconfig b/common/Kconfig index d7300c212f..57bd16d962 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -27,6 +27,15 @@ config SPL_BOOTSTAGE information when SPL finishes and load it when U-Boot proper starts up. +config TPL_BOOTSTAGE + bool "Boot timing and reported in TPL" + depends on BOOTSTAGE + help + Enable recording of boot time in SPL. To make this visible to U-Boot + proper, enable BOOTSTAGE_STASH as well. This will stash the timing + information when TPL finishes and load it when U-Boot proper starts + up. + config BOOTSTAGE_REPORT bool "Display a detailed boot timing report before booting the OS" depends on BOOTSTAGE @@ -290,6 +299,10 @@ config SPL_LOGLEVEL int default LOGLEVEL +config TPL_LOGLEVEL + int + default LOGLEVEL + config SILENT_CONSOLE bool "Support a silent console" help @@ -444,6 +457,16 @@ config LOG config SPL_LOG bool "Enable logging support in SPL" + depends on LOG + help + This enables support for logging of status and debug messages. These + can be displayed on the console, recorded in a memory buffer, or + discarded if not needed. Logging supports various categories and + levels of severity. + +config TPL_LOG + bool "Enable logging support in TPL" + depends on LOG help This enables support for logging of status and debug messages. These can be displayed on the console, recorded in a memory buffer, or @@ -486,6 +509,24 @@ config SPL_LOG_MAX_LEVEL 6 - detail 7 - debug +config TPL_LOG_MAX_LEVEL + int "Maximum log level to record in TPL" + depends on TPL_LOG + default 3 + help + This selects the maximum log level that will be recorded. Any value + higher than this will be ignored. If possible log statements below + this level will be discarded at build time. Levels: + + 0 - panic + 1 - critical + 2 - error + 3 - warning + 4 - note + 5 - info + 6 - detail + 7 - debug + config LOG_CONSOLE bool "Allow log output to the console" depends on LOG @@ -496,9 +537,19 @@ config LOG_CONSOLE log message is shown - other details like level, category, file and line number are omitted. -config LOG_SPL_CONSOLE +config SPL_LOG_CONSOLE + bool "Allow log output to the console in SPL" + depends on SPL_LOG + default y + help + Enables a log driver which writes log records to the console. + Generally the console is the serial port or LCD display. Only the + log message is shown - other details like level, category, file and + line number are omitted. + +config TPL_LOG_CONSOLE bool "Allow log output to the console in SPL" - depends on LOG_SPL + depends on TPL_LOG default y help Enables a log driver which writes log records to the console. @@ -660,6 +711,22 @@ config AVB_VERIFY * Helpers to access MMC, similar to drivers/fastboot/fb_mmc.c. * Helpers to alloc/init/free avb ops. +config SPL_HASH + bool # "Support hashing API (SHA1, SHA256, etc.)" + help + This provides a way to hash data in memory using various supported + algorithms (such as SHA1, MD5, CRC32). The API is defined in hash.h + and the algorithms it supports are defined in common/hash.c. See + also CMD_HASH for command-line access. + +config TPL_HASH + bool # "Support hashing API (SHA1, SHA256, etc.)" + help + This provides a way to hash data in memory using various supported + algorithms (such as SHA1, MD5, CRC32). The API is defined in hash.h + and the algorithms it supports are defined in common/hash.c. See + also CMD_HASH for command-line access. + endmenu menu "Update support" @@ -683,4 +750,52 @@ config UPDATE_TFTP_MSEC_MAX endmenu +menu "Blob list" + +config BLOBLIST + bool "Support for a bloblist" + help + This enables support for a bloblist in U-Boot, which can be passed + from TPL to SPL to U-Boot proper (and potentially to Linux). The + blob list supports multiple binary blobs of data, each with a tag, + so that different U-Boot components can store data which can survive + through to the next stage of the boot. + +config SPL_BLOBLIST + bool "Support for a bloblist in SPL" + depends on BLOBLIST + default y if SPL + help + This enables a bloblist in SPL. If this is the first part of U-Boot + to run, then the bloblist is set up in SPL and passed to U-Boot + proper. If TPL also has a bloblist, then SPL uses the one from there. + +config TPL_BLOBLIST + bool "Support for a bloblist in TPL" + depends on BLOBLIST + default y if TPL + help + This enables a bloblist in TPL. The bloblist is set up in TPL and + passed to SPL and U-Boot proper. + +config BLOBLIST_SIZE + hex "Size of bloblist" + depends on BLOBLIST + default 0x400 + help + Sets the size of the bloblist in bytes. This must include all + overhead (alignment, bloblist header, record header). The bloblist + is set up in the first part of U-Boot to run (TPL, SPL or U-Boot + proper), and this sane bloblist is used for subsequent stages. + +config BLOBLIST_ADDR + hex "Address of bloblist" + depends on BLOBLIST + default 0xe000 if SANDBOX + help + Sets the address of the bloblist, set up by the first part of U-Boot + which runs. Subsequent U-Boot stages typically use the same address. + +endmenu + source "common/spl/Kconfig" diff --git a/common/Makefile b/common/Makefile index a2388364d9..88079d1072 100644 --- a/common/Makefile +++ b/common/Makefile @@ -61,6 +61,7 @@ obj-$(CONFIG_CMDLINE) += cli_readline.o cli_simple.o endif # !CONFIG_SPL_BUILD obj-$(CONFIG_$(SPL_TPL_)BOOTSTAGE) += bootstage.o +obj-$(CONFIG_$(SPL_TPL_)BLOBLIST) += bloblist.o ifdef CONFIG_SPL_BUILD ifdef CONFIG_SPL_DFU_SUPPORT @@ -68,6 +69,7 @@ obj-$(CONFIG_DFU_OVER_USB) += dfu.o endif obj-$(CONFIG_SPL_DFU_SUPPORT) += cli_hush.o 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 @@ -76,7 +78,8 @@ ifdef CONFIG_SPL_USB_HOST_SUPPORT obj-$(CONFIG_SPL_USB_SUPPORT) += usb.o usb_hub.o obj-$(CONFIG_USB_STORAGE) += usb_storage.o endif -endif +endif # CONFIG_SPL_BUILD + #others obj-$(CONFIG_DDR_SPD) += ddr_spd.o obj-$(CONFIG_SPD_EEPROM) += ddr_spd.o @@ -90,14 +93,16 @@ obj-$(CONFIG_SPL_SERIAL_SUPPORT) += console.o endif else obj-y += console.o -endif +endif # CONFIG_SPL_BUILD + obj-$(CONFIG_CROS_EC) += cros_ec.o obj-y += dlmalloc.o ifdef CONFIG_SYS_MALLOC_F -ifneq ($(CONFIG_$(SPL_)SYS_MALLOC_F_LEN),0) +ifneq ($(CONFIG_$(SPL_TPL_)SYS_MALLOC_F_LEN),0) obj-y += malloc_simple.o endif endif + obj-y += image.o obj-$(CONFIG_ANDROID_BOOT_IMAGE) += image-android.o obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += image-fdt.o @@ -118,8 +123,8 @@ obj-y += cli.o obj-$(CONFIG_FSL_DDR_INTERACTIVE) += cli_simple.o cli_readline.o obj-$(CONFIG_DFU_OVER_USB) += dfu.o obj-y += command.o -obj-$(CONFIG_$(SPL_)LOG) += log.o -obj-$(CONFIG_$(SPL_)LOG_CONSOLE) += log_console.o +obj-$(CONFIG_$(SPL_TPL_)LOG) += log.o +obj-$(CONFIG_$(SPL_TPL_)LOG_CONSOLE) += log_console.o obj-y += s_record.o obj-$(CONFIG_CMD_LOADB) += xyzModem.o obj-$(CONFIG_$(SPL_TPL_)YMODEM_SUPPORT) += xyzModem.o diff --git a/common/bloblist.c b/common/bloblist.c new file mode 100644 index 0000000000..b4cf169b05 --- /dev/null +++ b/common/bloblist.c @@ -0,0 +1,239 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 Google, Inc + * Written by Simon Glass <sjg@chromium.org> + */ + +#include <common.h> +#include <bloblist.h> +#include <log.h> +#include <mapmem.h> +#include <spl.h> + +DECLARE_GLOBAL_DATA_PTR; + +struct bloblist_rec *bloblist_first_blob(struct bloblist_hdr *hdr) +{ + if (hdr->alloced <= hdr->hdr_size) + return NULL; + return (struct bloblist_rec *)((void *)hdr + hdr->hdr_size); +} + +struct bloblist_rec *bloblist_next_blob(struct bloblist_hdr *hdr, + struct bloblist_rec *rec) +{ + ulong offset; + + offset = (void *)rec - (void *)hdr; + offset += rec->hdr_size + ALIGN(rec->size, BLOBLIST_ALIGN); + if (offset >= hdr->alloced) + return NULL; + return (struct bloblist_rec *)((void *)hdr + offset); +} + +#define foreach_rec(_rec, _hdr) \ + for (_rec = bloblist_first_blob(_hdr); \ + _rec; \ + _rec = bloblist_next_blob(_hdr, _rec)) + +static struct bloblist_rec *bloblist_findrec(uint tag) +{ + struct bloblist_hdr *hdr = gd->bloblist; + struct bloblist_rec *rec; + + if (!hdr) + return NULL; + + foreach_rec(rec, hdr) { + if (rec->tag == tag) + return rec; + } + + return NULL; +} + +static int bloblist_addrec(uint tag, int size, struct bloblist_rec **recp) +{ + struct bloblist_hdr *hdr = gd->bloblist; + struct bloblist_rec *rec; + int new_alloced; + + new_alloced = hdr->alloced + sizeof(*rec) + + ALIGN(size, BLOBLIST_ALIGN); + if (new_alloced >= hdr->size) { + log(LOGC_BLOBLIST, LOGL_ERR, + "Failed to allocate %x bytes size=%x, need size>=%x\n", + size, hdr->size, new_alloced); + return log_msg_ret("bloblist add", -ENOSPC); + } + rec = (void *)hdr + hdr->alloced; + hdr->alloced = new_alloced; + + rec->tag = tag; + rec->hdr_size = sizeof(*rec); + rec->size = size; + rec->spare = 0; + *recp = rec; + + return 0; +} + +static int bloblist_ensurerec(uint tag, struct bloblist_rec **recp, int size) +{ + struct bloblist_rec *rec; + + rec = bloblist_findrec(tag); + if (rec) { + if (size && size != rec->size) + return -ESPIPE; + } else { + int ret; + + ret = bloblist_addrec(tag, size, &rec); + if (ret) + return ret; + } + *recp = rec; + + return 0; +} + +void *bloblist_find(uint tag, int size) +{ + struct bloblist_rec *rec; + + rec = bloblist_findrec(tag); + if (!rec) + return NULL; + if (size && size != rec->size) + return NULL; + + return (void *)rec + rec->hdr_size; +} + +void *bloblist_add(uint tag, int size) +{ + struct bloblist_rec *rec; + + if (bloblist_addrec(tag, size, &rec)) + return NULL; + + return rec + 1; +} + +int bloblist_ensure_size(uint tag, int size, void **blobp) +{ + struct bloblist_rec *rec; + int ret; + + ret = bloblist_ensurerec(tag, &rec, size); + if (ret) + return ret; + *blobp = (void *)rec + rec->hdr_size; + + return 0; +} + +void *bloblist_ensure(uint tag, int size) +{ + struct bloblist_rec *rec; + + if (bloblist_ensurerec(tag, &rec, size)) + return NULL; + + return (void *)rec + rec->hdr_size; +} + +static u32 bloblist_calc_chksum(struct bloblist_hdr *hdr) +{ + struct bloblist_rec *rec; + u32 chksum; + + chksum = crc32(0, (unsigned char *)hdr, + offsetof(struct bloblist_hdr, chksum)); + foreach_rec(rec, hdr) { + chksum = crc32(chksum, (void *)rec, rec->hdr_size); + chksum = crc32(chksum, (void *)rec + rec->hdr_size, rec->size); + } + + return chksum; +} + +int bloblist_new(ulong addr, uint size, uint flags) +{ + struct bloblist_hdr *hdr; + + if (size < sizeof(*hdr)) + return log_ret(-ENOSPC); + if (addr & (BLOBLIST_ALIGN - 1)) + return log_ret(-EFAULT); + hdr = map_sysmem(addr, size); + memset(hdr, '\0', sizeof(*hdr)); + hdr->version = BLOBLIST_VERSION; + hdr->hdr_size = sizeof(*hdr); + hdr->flags = flags; + hdr->magic = BLOBLIST_MAGIC; + hdr->size = size; + hdr->alloced = hdr->hdr_size; + hdr->chksum = 0; + gd->bloblist = hdr; + + return 0; +} + +int bloblist_check(ulong addr, uint size) +{ + struct bloblist_hdr *hdr; + u32 chksum; + + hdr = map_sysmem(addr, sizeof(*hdr)); + if (hdr->magic != BLOBLIST_MAGIC) + return log_msg_ret("Bad magic", -ENOENT); + if (hdr->version != BLOBLIST_VERSION) + return log_msg_ret("Bad version", -EPROTONOSUPPORT); + if (size && hdr->size != size) + return log_msg_ret("Bad size", -EFBIG); + chksum = bloblist_calc_chksum(hdr); + if (hdr->chksum != chksum) { + log(LOGC_BLOBLIST, LOGL_ERR, "Checksum %x != %x\n", hdr->chksum, + chksum); + return log_msg_ret("Bad checksum", -EIO); + } + gd->bloblist = hdr; + + return 0; +} + +int bloblist_finish(void) +{ + struct bloblist_hdr *hdr = gd->bloblist; + + hdr->chksum = bloblist_calc_chksum(hdr); + + return 0; +} + +int bloblist_init(void) +{ + bool expected; + int ret = -ENOENT; + + /** + * Wed expect to find an existing bloblist in the first phase of U-Boot + * that runs + */ + expected = !u_boot_first_phase(); + if (expected) + ret = bloblist_check(CONFIG_BLOBLIST_ADDR, + CONFIG_BLOBLIST_SIZE); + if (ret) { + log(LOGC_BLOBLIST, expected ? LOGL_WARNING : LOGL_DEBUG, + "Existing bloblist not found: creating new bloblist\n"); + ret = bloblist_new(CONFIG_BLOBLIST_ADDR, CONFIG_BLOBLIST_SIZE, + 0); + } else { + log(LOGC_BLOBLIST, LOGL_DEBUG, "Found existing bloblist\n"); + } + + return ret; +} diff --git a/common/board_f.c b/common/board_f.c index 96503ff8d3..835b7247c5 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -10,6 +10,7 @@ */ #include <common.h> +#include <bloblist.h> #include <console.h> #include <cpu.h> #include <dm.h> @@ -24,6 +25,9 @@ #include <post.h> #include <relocate.h> #include <spi.h> +#ifdef CONFIG_SPL +#include <spl.h> +#endif #include <status_led.h> #include <sysreset.h> #include <timer.h> @@ -91,7 +95,7 @@ static int init_func_watchdog_init(void) { # if defined(CONFIG_HW_WATCHDOG) && \ (defined(CONFIG_M68K) || defined(CONFIG_MICROBLAZE) || \ - defined(CONFIG_SH) || defined(CONFIG_AT91SAM9_WATCHDOG) || \ + defined(CONFIG_SH) || \ defined(CONFIG_DESIGNWARE_WATCHDOG) || \ defined(CONFIG_IMX_WATCHDOG)) hw_watchdog_init(); @@ -285,6 +289,17 @@ static int setup_mon_len(void) return 0; } +static int setup_spl_handoff(void) +{ +#if CONFIG_IS_ENABLED(HANDOFF) + gd->spl_handoff = bloblist_find(BLOBLISTT_SPL_HANDOFF, + sizeof(struct spl_handoff)); + debug("Found SPL hand-off info %p\n", gd->spl_handoff); +#endif + + return 0; +} + __weak int arch_cpu_init(void) { return 0; @@ -560,6 +575,16 @@ static int reserve_stacks(void) return arch_reserve_stacks(); } +static int reserve_bloblist(void) +{ +#ifdef CONFIG_BLOBLIST + gd->start_addr_sp -= CONFIG_BLOBLIST_SIZE; + gd->new_bloblist = map_sysmem(gd->start_addr_sp, CONFIG_BLOBLIST_SIZE); +#endif + + return 0; +} + static int display_new_sp(void) { debug("New Stack Pointer is: %08lx\n", gd->start_addr_sp); @@ -666,6 +691,24 @@ static int reloc_bootstage(void) return 0; } +static int reloc_bloblist(void) +{ +#ifdef CONFIG_BLOBLIST + if (gd->flags & GD_FLG_SKIP_RELOC) + return 0; + if (gd->new_bloblist) { + int size = CONFIG_BLOBLIST_SIZE; + + debug("Copying bloblist from %p to %p, size %x\n", + gd->bloblist, gd->new_bloblist, size); + memcpy(gd->new_bloblist, gd->bloblist, size); + gd->bloblist = gd->new_bloblist; + } +#endif + + return 0; +} + static int setup_reloc(void) { if (gd->flags & GD_FLG_SKIP_RELOC) { @@ -813,6 +856,10 @@ static const init_fnc_t init_sequence_f[] = { initf_malloc, log_init, initf_bootstage, /* uses its own timer, so does not need DM */ +#ifdef CONFIG_BLOBLIST + bloblist_init, +#endif + setup_spl_handoff, initf_console_record, #if defined(CONFIG_HAVE_FSP) arch_fsp_init, @@ -913,6 +960,7 @@ static const init_fnc_t init_sequence_f[] = { reserve_global_data, reserve_fdt, reserve_bootstage, + reserve_bloblist, reserve_arch, reserve_stacks, dram_init_banksize, @@ -932,6 +980,7 @@ static const init_fnc_t init_sequence_f[] = { INIT_FUNC_WATCHDOG_RESET reloc_fdt, reloc_bootstage, + reloc_bloblist, setup_reloc, #if defined(CONFIG_X86) || defined(CONFIG_ARC) copy_uboot_to_ram, diff --git a/common/console.c b/common/console.c index 9a94f32192..0b0dd76256 100644 --- a/common/console.c +++ b/common/console.c @@ -535,6 +535,13 @@ void putc(const char c) void puts(const char *s) { +#ifdef CONFIG_SANDBOX + /* sandbox can send characters to stdout before it has a console */ + if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) { + os_puts(s); + return; + } +#endif #ifdef CONFIG_DEBUG_UART if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) { while (*s) { diff --git a/common/cros_ec.c b/common/cros_ec.c index 4ca15e19d5..e66471ebd1 100644 --- a/common/cros_ec.c +++ b/common/cros_ec.c @@ -25,15 +25,3 @@ struct udevice *board_get_cros_ec_dev(void) } return dev; } - -int cros_ec_get_error(void) -{ - struct udevice *dev; - int ret; - - ret = uclass_get_device(UCLASS_CROS_EC, 0, &dev); - if (ret && ret != -ENODEV) - return ret; - - return 0; -} diff --git a/common/image-sig.c b/common/image-sig.c index 5a269d3289..5d860e1266 100644 --- a/common/image-sig.c +++ b/common/image-sig.c @@ -334,6 +334,11 @@ int fit_config_check_sig(const void *fit, int noffset, int required_keynode, return -1; } + if (prop && prop_len > 0 && prop[prop_len - 1] != '\0') { + *err_msgp = "hashed-nodes property must be null-terminated"; + return -1; + } + /* Add a sanity check here since we are using the stack */ if (count > IMAGE_MAX_HASHED_NODES) { *err_msgp = "Number of hashed nodes exceeds maximum"; diff --git a/common/init/Makefile b/common/init/Makefile index 4902635f53..853b56d1e5 100644 --- a/common/init/Makefile +++ b/common/init/Makefile @@ -5,3 +5,4 @@ # obj-y += board_init.o +obj-$(CONFIG_$(SPL_TPL_)HANDOFF) += handoff.o diff --git a/common/init/handoff.c b/common/init/handoff.c new file mode 100644 index 0000000000..e00b43e6a7 --- /dev/null +++ b/common/init/handoff.c @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Passing basic information from SPL to U-Boot proper + * + * Copyright 2018 Google, Inc + */ + +#include <common.h> +#include <handoff.h> + +DECLARE_GLOBAL_DATA_PTR; + +void handoff_save_dram(struct spl_handoff *ho) +{ + ho->ram_size = gd->ram_size; +#ifdef CONFIG_NR_DRAM_BANKS + { + struct bd_info *bd = gd->bd; + int i; + + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { + ho->ram_bank[i].start = bd->bi_dram[i].start; + ho->ram_bank[i].size = bd->bi_dram[i].size; + } + } +#endif +} + +void handoff_load_dram_size(struct spl_handoff *ho) +{ + gd->ram_size = ho->ram_size; +} + +void handoff_load_dram_banks(struct spl_handoff *ho) +{ +#ifdef CONFIG_NR_DRAM_BANKS + { + struct bd_info *bd = gd->bd; + int i; + + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { + bd->bi_dram[i].start = ho->ram_bank[i].start; + bd->bi_dram[i].size = ho->ram_bank[i].size; + } + } +#endif +} diff --git a/common/spl/Kconfig b/common/spl/Kconfig index d0564621d4..0ddbffc7d1 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -25,8 +25,28 @@ config SPL_FRAMEWORK supports MMC, NAND and YMODEM and other methods loading of U-Boot and the Linux Kernel. If unsure, say Y. +config HANDOFF + bool "Pass hand-off information from SPL to U-Boot proper" + depends on 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. + Enable this to locate the handoff information in U-Boot proper, early + in boot. It is available in gd->handoff. The state state is set up + in SPL (or TPL if that is being used). + if SPL +config SPL_HANDOFF + bool "Pass hand-off information from SPL to U-Boot proper" + depends on HANDOFF + default y + help + This option enables SPL to write handoff information. This can be + used to pass information like the size of SDRAM from SPL to U-Boot + proper. Also SPL can receive information from TPL in the same place + if that is enabled. + config SPL_LDSCRIPT string "Linker script for the SPL stage" default "arch/$(ARCH)/cpu/u-boot-spl.lds" @@ -135,12 +155,21 @@ config SPL_SEPARATE_BSS location is used. Normally we put the device tree at the end of BSS but with this option enabled, it goes at _image_binary_end. -config SPL_DISABLE_BANNER_PRINT - bool "Disable output of the SPL banner 'U-Boot SPL ...'" +config SPL_BANNER_PRINT + bool "Enable output of the SPL banner 'U-Boot SPL ...'" + default y + help + If this option is enabled, SPL will print the banner with version + info. Disabling this option could be useful to reduce TPL boot time + (e.g. approx. 6 ms faster, when output on i.MX6 with 115200 baud). + +config TPL_BANNER_PRINT + bool "Enable output of the TPL banner 'U-Boot TPL ...'" + default y help If this option is enabled, SPL will not print the banner with version - info. Selecting this option could be useful to reduce SPL boot time - (e.g. approx. 6 ms slower, when output on i.MX6 with 115200 baud). + info. Disabling this option could be useful to reduce SPL boot time + (e.g. approx. 6 ms faster, when output on i.MX6 with 115200 baud). config SPL_DISPLAY_PRINT bool "Display a board-specific message in SPL" @@ -295,6 +324,16 @@ config SPL_HASH_SUPPORT this option to build system-specific drivers for hash acceleration as part of an SPL build. +config TPL_HASH_SUPPORT + bool "Support hashing drivers in TPL" + select SHA1 + select SHA256 + help + Enable hashing drivers in SPL. These drivers can be used to + accelerate secure boot processing in secure applications. Enable + this option to build system-specific drivers for hash acceleration + as part of an SPL build. + config SPL_DMA_SUPPORT bool "Support DMA drivers" help @@ -376,7 +415,7 @@ config SPL_FPGA_SUPPORT within SPL. config SPL_GPIO_SUPPORT - bool "Support GPIO" + bool "Support GPIO in SPL" help Enable support for GPIOs (General-purpose Input/Output) in SPL. GPIOs allow U-Boot to read the state of an input line (high or @@ -848,6 +887,16 @@ config TPL if TPL +config TPL_HANDOFF + bool "Pass hand-off information from TPL to SPL and U-Boot proper" + depends on HANDOFF + default y + help + This option enables TPL to write handoff information. This can be + used to pass information like the size of SDRAM from TPL to U-Boot + proper. The information is also available to SPL if it is useful + there. + config TPL_BOARD_INIT bool "Call board-specific initialization in TPL" help @@ -928,6 +977,17 @@ config TPL_ENV_SUPPORT help Enable environment support in TPL. See SPL_ENV_SUPPORT for details. +config TPL_GPIO_SUPPORT + bool "Support GPIO in TPL" + help + Enable support for GPIOs (General-purpose Input/Output) in TPL. + GPIOs allow U-Boot to read the state of an input line (high or + low) and set the state of an output line. This can be used to + drive LEDs, control power to various system parts and read user + input. GPIOs can be useful in TPL to enable a 'sign-of-life' LED, + for example. Enable this option to build the drivers in + drivers/gpio as part of an TPL build. + config TPL_I2C_SUPPORT bool "Support I2C" help @@ -963,6 +1023,22 @@ config TPL_NAND_SUPPORT help Enable support for NAND in TPL. See SPL_NAND_SUPPORT for details. +config TPL_PCI_SUPPORT + bool "Support PCI drivers" + help + Enable support for PCI in TPL. For platforms that need PCI to boot, + or must perform some init using PCI in SPL, this provides the + necessary driver support. This enables the drivers in drivers/pci + as part of a TPL build. + +config TPL_PCH_SUPPORT + bool "Support PCH drivers" + help + Enable support for PCH (Platform Controller Hub) devices in TPL. + These are used to set up GPIOs and the SPI peripheral early in + boot. This enables the drivers in drivers/pch as part of a TPL + build. + config TPL_RAM_SUPPORT bool "Support booting from RAM" help @@ -977,6 +1053,15 @@ config TPL_RAM_DEVICE be already in memory when TPL takes over, e.g. loaded by the boot ROM. +config TPL_RTC_SUPPORT + bool "Support RTC drivers" + help + Enable RTC (Real-time Clock) support in TPL. This includes support + for reading and setting the time. Some RTC devices also have some + non-volatile (battery-backed) memory which is accessible if + needed. This enables the drivers in drivers/rtc as part of an TPL + build. + config TPL_SERIAL_SUPPORT bool "Support serial" select TPL_PRINTF diff --git a/common/spl/spl.c b/common/spl/spl.c index 12f9359c0a..35120b6efd 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -7,8 +7,10 @@ */ #include <common.h> +#include <bloblist.h> #include <binman_sym.h> #include <dm.h> +#include <handoff.h> #include <spl.h> #include <asm/u-boot.h> #include <nand.h> @@ -44,6 +46,14 @@ static bd_t bdata __attribute__ ((section(".data"))); */ __weak void show_boot_progress(int val) {} +#if defined(CONFIG_SPL_OS_BOOT) || CONFIG_IS_ENABLED(HANDOFF) +/* weak, default platform-specific function to initialize dram banks */ +__weak int dram_init_banksize(void) +{ + return 0; +} +#endif + /* * Default function to determine if u-boot or the OS should * be started. This implementation always returns 1. @@ -57,19 +67,12 @@ __weak void show_boot_progress(int val) {} #ifdef CONFIG_SPL_OS_BOOT __weak int spl_start_uboot(void) { - puts("SPL: Please implement spl_start_uboot() for your board\n"); - puts("SPL: Direct Linux boot not active!\n"); + puts(SPL_TPL_PROMPT + "Please implement spl_start_uboot() for your board\n"); + puts(SPL_TPL_PROMPT "Direct Linux boot not active!\n"); return 1; } -/* weak default platform specific function to initialize - * dram banks - */ -__weak int dram_init_banksize(void) -{ - return 0; -} - /* * Weak default function for arch specific zImage check. Return zero * and fill start and end address if image is recognized. @@ -100,13 +103,13 @@ void spl_fixup_fdt(void) /* fixup the memory dt node */ err = fdt_shrink_to_minimum(fdt_blob, 0); if (err == 0) { - printf("spl: fdt_shrink_to_minimum err - %d\n", err); + printf(SPL_TPL_PROMPT "fdt_shrink_to_minimum err - %d\n", err); return; } err = arch_fixup_fdt(fdt_blob); if (err) { - printf("spl: arch_fixup_fdt err - %d\n", err); + printf(SPL_TPL_PROMPT "arch_fixup_fdt err - %d\n", err); return; } #endif @@ -185,7 +188,7 @@ static int spl_load_fit_image(struct spl_image_info *spl_image, spl_image->os = IH_OS_U_BOOT; spl_image->name = "U-Boot"; - debug("spl: payload image: %32s load addr: 0x%lx size: %d\n", + debug(SPL_TPL_PROMPT "payload image: %32s load addr: 0x%lx size: %d\n", spl_image->name, spl_image->load_addr, spl_image->size); #ifdef CONFIG_SPL_FIT_SIGNATURE @@ -255,7 +258,8 @@ int spl_parse_image_header(struct spl_image_info *spl_image, } spl_image->os = image_get_os(header); spl_image->name = image_get_name(header); - debug("spl: payload image: %32s load addr: 0x%lx size: %d\n", + debug(SPL_TPL_PROMPT + "payload image: %32s load addr: 0x%lx size: %d\n", spl_image->name, spl_image->load_addr, spl_image->size); #else /* LEGACY image not supported */ @@ -284,7 +288,8 @@ int spl_parse_image_header(struct spl_image_info *spl_image, spl_image->load_addr = CONFIG_SYS_LOAD_ADDR; spl_image->entry_point = CONFIG_SYS_LOAD_ADDR; spl_image->size = end - start; - debug("spl: payload zImage, load addr: 0x%lx size: %d\n", + debug(SPL_TPL_PROMPT + "payload zImage, load addr: 0x%lx size: %d\n", spl_image->load_addr, spl_image->size); return 0; } @@ -316,6 +321,44 @@ __weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) image_entry(); } +#if CONFIG_IS_ENABLED(HANDOFF) +/** + * Set up the SPL hand-off information + * + * This is initially empty (zero) but can be written by + */ +static int setup_spl_handoff(void) +{ + struct spl_handoff *ho; + + ho = bloblist_ensure(BLOBLISTT_SPL_HANDOFF, sizeof(struct spl_handoff)); + if (!ho) + return -ENOENT; + + return 0; +} + +static int write_spl_handoff(void) +{ + struct spl_handoff *ho; + + ho = bloblist_find(BLOBLISTT_SPL_HANDOFF, sizeof(struct spl_handoff)); + if (!ho) + return -ENOENT; + handoff_save_dram(ho); +#ifdef CONFIG_SANDBOX + ho->arch.magic = TEST_HANDOFF_MAGIC; +#endif + debug(SPL_TPL_PROMPT "Wrote SPL handoff\n"); + + return 0; +} +#else +static inline int setup_spl_handoff(void) { return 0; } +static inline int write_spl_handoff(void) { return 0; } + +#endif /* HANDOFF */ + static int spl_common_init(bool setup_malloc) { int ret; @@ -336,6 +379,30 @@ static int spl_common_init(bool setup_malloc) return ret; } bootstage_mark_name(BOOTSTAGE_ID_START_SPL, "spl"); +#if CONFIG_IS_ENABLED(LOG) + ret = log_init(); + if (ret) { + debug("%s: Failed to set up logging\n", __func__); + return ret; + } +#endif + if (CONFIG_IS_ENABLED(BLOBLIST)) { + ret = bloblist_init(); + if (ret) { + debug("%s: Failed to set up bloblist: ret=%d\n", + __func__, ret); + return ret; + } + } + if (CONFIG_IS_ENABLED(HANDOFF)) { + int ret; + + ret = setup_spl_handoff(); + if (ret) { + puts(SPL_TPL_PROMPT "Cannot set up SPL handoff\n"); + hang(); + } + } if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) { ret = fdtdec_setup(); if (ret) { @@ -359,6 +426,10 @@ static int spl_common_init(bool setup_malloc) void spl_set_bd(void) { + /* + * NOTE: On some platforms (e.g. x86) bdata may be in flash and not + * writeable. + */ if (!gd->bd) gd->bd = &bdata; } @@ -453,7 +524,7 @@ static int boot_from_devices(struct spl_image_info *spl_image, if (loader) printf("Trying to boot from %s\n", loader->name); else - puts("SPL: Unsupported Boot Device!\n"); + puts(SPL_TPL_PROMPT "Unsupported Boot Device!\n"); #endif if (loader && !spl_load_image(spl_image, loader)) { spl_image->boot_device = spl_boot_list[i]; @@ -474,15 +545,12 @@ void board_init_r(gd_t *dummy1, ulong dummy2) BOOT_DEVICE_NONE, }; struct spl_image_info spl_image; + int ret; - debug(">>spl:board_init_r()\n"); + debug(">>" SPL_TPL_PROMPT "board_init_r()\n"); spl_set_bd(); -#ifdef CONFIG_SPL_OS_BOOT - dram_init_banksize(); -#endif - #if defined(CONFIG_SYS_SPL_MALLOC_START) mem_malloc_init(CONFIG_SYS_SPL_MALLOC_START, CONFIG_SYS_SPL_MALLOC_SIZE); @@ -504,6 +572,9 @@ void board_init_r(gd_t *dummy1, ulong dummy2) spl_board_init(); #endif + if (IS_ENABLED(CONFIG_SPL_OS_BOOT) || CONFIG_IS_ENABLED(HANDOFF)) + dram_init_banksize(); + bootcount_inc(); memset(&spl_image, '\0', sizeof(spl_image)); @@ -515,11 +586,23 @@ void board_init_r(gd_t *dummy1, ulong dummy2) if (boot_from_devices(&spl_image, spl_boot_list, ARRAY_SIZE(spl_boot_list))) { - puts("SPL: failed to boot from all boot devices\n"); + puts(SPL_TPL_PROMPT "failed to boot from all boot devices\n"); hang(); } spl_perform_fixups(&spl_image); + if (CONFIG_IS_ENABLED(HANDOFF)) { + ret = write_spl_handoff(); + if (ret) + printf(SPL_TPL_PROMPT + "SPL hand-off write failed (err=%d)\n", ret); + } + if (CONFIG_IS_ENABLED(BLOBLIST)) { + ret = bloblist_finish(); + if (ret) + printf("Warning: Failed to finish bloblist (ret=%d)\n", + ret); + } #ifdef CONFIG_CPU_V7M spl_image.entry_point |= 0x1; @@ -556,8 +639,6 @@ void board_init_r(gd_t *dummy1, ulong dummy2) gd->malloc_ptr / 1024); #endif #ifdef CONFIG_BOOTSTAGE_STASH - int ret; - bootstage_mark_name(BOOTSTAGE_ID_END_SPL, "end_spl"); ret = bootstage_stash((void *)CONFIG_BOOTSTAGE_STASH_ADDR, CONFIG_BOOTSTAGE_STASH_SIZE); @@ -583,9 +664,9 @@ void preloader_console_init(void) gd->have_console = 1; -#ifndef CONFIG_SPL_DISABLE_BANNER_PRINT - puts("\nU-Boot SPL " PLAIN_VERSION " (" U_BOOT_DATE " - " \ - U_BOOT_TIME " " U_BOOT_TZ ")\n"); +#if CONFIG_IS_ENABLED(BANNER_PRINT) + puts("\nU-Boot " SPL_TPL_NAME " " PLAIN_VERSION " (" U_BOOT_DATE " - " + U_BOOT_TIME " " U_BOOT_TZ ")\n"); #endif #ifdef CONFIG_SPL_DISPLAY_PRINT spl_display_print(); @@ -15,6 +15,7 @@ PLATFORM_CPPFLAGS := PLATFORM_LDFLAGS := LDFLAGS := LDFLAGS_FINAL := +LDFLAGS_STANDALONE := OBJCOPYFLAGS := # clear VENDOR for tcsh VENDOR := @@ -75,4 +76,5 @@ LDFLAGS_FINAL += -Bstatic export PLATFORM_CPPFLAGS export RELFLAGS export LDFLAGS_FINAL +export LDFLAGS_STANDALONE export CONFIG_STANDALONE_LOAD_ADDR diff --git a/configs/ax25-ae350_defconfig b/configs/a25-ae350_32_defconfig index d7c4f40e58..5837b48903 100644 --- a/configs/ax25-ae350_defconfig +++ b/configs/a25-ae350_32_defconfig @@ -1,7 +1,6 @@ CONFIG_RISCV=y CONFIG_SYS_TEXT_BASE=0x00000000 CONFIG_TARGET_AX25_AE350=y -CONFIG_CPU_RISCV_64=y CONFIG_DISTRO_DEFAULTS=y CONFIG_NR_DRAM_BANKS=2 CONFIG_FIT=y @@ -16,7 +15,7 @@ CONFIG_CMD_SF_TEST=y CONFIG_BOOTP_PREFER_SERVERIP=y CONFIG_CMD_CACHE=y CONFIG_OF_BOARD=y -CONFIG_DEFAULT_DEVICE_TREE="ae350" +CONFIG_DEFAULT_DEVICE_TREE="ae350_32" CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_NET_RANDOM_ETHADDR=y CONFIG_MMC=y diff --git a/configs/am3517_evm_defconfig b/configs/am3517_evm_defconfig index 882163f8c1..14805575ab 100644 --- a/configs/am3517_evm_defconfig +++ b/configs/am3517_evm_defconfig @@ -1,5 +1,4 @@ CONFIG_ARM=y -# CONFIG_SYS_THUMB_BUILD is not set CONFIG_ARCH_OMAP2PLUS=y CONFIG_SYS_TEXT_BASE=0x80100000 CONFIG_TI_COMMON_CMD_OPTIONS=y @@ -34,9 +33,7 @@ CONFIG_MTDIDS_DEFAULT="nand0=omap2-nand.0" CONFIG_MTDPARTS_DEFAULT="mtdparts=omap2-nand.0:512k(MLO),1920k(u-boot),256k(u-boot-env),8m(kernel),512k(dtb),-(rootfs)" CONFIG_CMD_UBI=y CONFIG_OF_CONTROL=y -CONFIG_SPL_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="am3517-evm" -CONFIG_SPL_OF_PLATDATA=y # CONFIG_ENV_IS_IN_FAT is not set CONFIG_ENV_IS_IN_NAND=y CONFIG_DM_PCA953X=y diff --git a/configs/am65x_evm_r5_defconfig b/configs/am65x_evm_r5_defconfig new file mode 100644 index 0000000000..237b9e8229 --- /dev/null +++ b/configs/am65x_evm_r5_defconfig @@ -0,0 +1,87 @@ +CONFIG_ARM=y +CONFIG_ARCH_K3=y +CONFIG_SPL_GPIO_SUPPORT=y +CONFIG_SPL_LIBCOMMON_SUPPORT=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_SOC_K3_AM6=y +CONFIG_TARGET_AM654_R5_EVM=y +CONFIG_SPL_MMC_SUPPORT=y +CONFIG_SPL_SERIAL_SUPPORT=y +CONFIG_SPL_DRIVERS_MISC_SUPPORT=y +CONFIG_SPL_STACK_R_ADDR=0x82000000 +CONFIG_SPL_FAT_SUPPORT=y +CONFIG_SPL_LIBDISK_SUPPORT=y +CONFIG_NR_DRAM_BANKS=2 +# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_SPL_LOAD_FIT=y +CONFIG_USE_BOOTCOMMAND=y +# CONFIG_DISPLAY_CPUINFO is not set +CONFIG_SPL_SYS_MALLOC_SIMPLE=y +CONFIG_SPL_STACK_R=y +CONFIG_SPL_SEPARATE_BSS=y +CONFIG_SPL_I2C_SUPPORT=y +CONFIG_SPL_DM_MAILBOX=y +CONFIG_SPL_DM_RESET=y +CONFIG_SPL_POWER_SUPPORT=y +CONFIG_SPL_POWER_DOMAIN=y +CONFIG_SPL_RAM_SUPPORT=y +CONFIG_SPL_RAM_DEVICE=y +CONFIG_SPL_REMOTEPROC=y +CONFIG_SPL_YMODEM_SUPPORT=y +CONFIG_HUSH_PARSER=y +CONFIG_CMD_BOOTZ=y +CONFIG_CMD_ASKENV=y +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_MMC=y +CONFIG_CMD_REMOTEPROC=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_TIME=y +CONFIG_CMD_FAT=y +CONFIG_OF_CONTROL=y +CONFIG_SPL_OF_CONTROL=y +CONFIG_DEFAULT_DEVICE_TREE="k3-am654-r5-base-board" +CONFIG_SPL_MULTI_DTB_FIT=y +CONFIG_SPL_MULTI_DTB_FIT_NO_COMPRESSION=y +CONFIG_ENV_IS_IN_FAT=y +CONFIG_ENV_FAT_INTERFACE="mmc" +CONFIG_ENV_FAT_DEVICE_AND_PART="1:1" +CONFIG_DM=y +CONFIG_SPL_DM=y +CONFIG_SPL_DM_SEQ_ALIAS=y +CONFIG_SPL_OF_TRANSLATE=y +CONFIG_CLK=y +CONFIG_SPL_CLK=y +CONFIG_CLK_TI_SCI=y +CONFIG_TI_SCI_PROTOCOL=y +CONFIG_DM_GPIO=y +CONFIG_DA8XX_GPIO=y +CONFIG_DM_MAILBOX=y +CONFIG_K3_SEC_PROXY=y +CONFIG_MISC=y +CONFIG_DM_MMC=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_K3_ARASAN=y +CONFIG_PINCTRL=y +# CONFIG_PINCTRL_GENERIC is not set +CONFIG_SPL_PINCTRL=y +# CONFIG_SPL_PINCTRL_GENERIC is not set +CONFIG_PINCTRL_SINGLE=y +CONFIG_POWER_DOMAIN=y +CONFIG_TI_SCI_POWER_DOMAIN=y +CONFIG_DM_REGULATOR=y +CONFIG_SPL_DM_REGULATOR=y +CONFIG_DM_REGULATOR_GPIO=y +CONFIG_SPL_DM_REGULATOR_GPIO=y +CONFIG_RAM=y +CONFIG_SPL_RAM=y +CONFIG_K3_SYSTEM_CONTROLLER=y +CONFIG_REMOTEPROC_K3=y +CONFIG_DM_RESET=y +CONFIG_RESET_TI_SCI=y +CONFIG_DM_SERIAL=y +CONFIG_SYSRESET=y +CONFIG_SYSRESET_TI_SCI=y +CONFIG_TIMER=y +CONFIG_SPL_TIMER=y +CONFIG_OMAP_TIMER=y diff --git a/configs/ax25-ae350_64_defconfig b/configs/ax25-ae350_64_defconfig new file mode 100644 index 0000000000..b250d3fc7e --- /dev/null +++ b/configs/ax25-ae350_64_defconfig @@ -0,0 +1,37 @@ +CONFIG_RISCV=y +CONFIG_SYS_TEXT_BASE=0x00000000 +CONFIG_TARGET_AX25_AE350=y +CONFIG_ARCH_RV64I=y +CONFIG_DISTRO_DEFAULTS=y +CONFIG_NR_DRAM_BANKS=2 +CONFIG_FIT=y +CONFIG_BOOTDELAY=3 +CONFIG_BOARD_EARLY_INIT_F=y +CONFIG_SYS_PROMPT="RISC-V # " +CONFIG_CMD_IMLS=y +CONFIG_CMD_MMC=y +CONFIG_CMD_SF=y +CONFIG_CMD_SF_TEST=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_BOOTP_PREFER_SERVERIP=y +CONFIG_CMD_CACHE=y +CONFIG_OF_BOARD=y +CONFIG_DEFAULT_DEVICE_TREE="ae350_64" +CONFIG_ENV_IS_IN_SPI_FLASH=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_MMC=y +CONFIG_FTSDC010=y +CONFIG_FTSDC010_SDIO=y +CONFIG_MTD_NOR_FLASH=y +CONFIG_FLASH_CFI_DRIVER=y +CONFIG_CFI_FLASH=y +CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y +CONFIG_SYS_FLASH_CFI=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_FTMAC100=y +CONFIG_BAUDRATE=38400 +CONFIG_SYS_NS16550=y +CONFIG_SPI=y +CONFIG_ATCSPI200_SPI=y +CONFIG_ATCPIT100_TIMER=y diff --git a/configs/bcm968580_ram_defconfig b/configs/bcm968580_ram_defconfig new file mode 100644 index 0000000000..abe90ee75f --- /dev/null +++ b/configs/bcm968580_ram_defconfig @@ -0,0 +1,36 @@ +CONFIG_ARM=y +CONFIG_ARCH_BCM6858=y +CONFIG_SYS_TEXT_BASE=0x10000000 +CONFIG_SYS_MALLOC_F_LEN=0x8000 +CONFIG_SPL_SYS_MALLOC_F_LEN=0x400 +CONFIG_TARGET_BCM968580XREF=y +CONFIG_ENV_VARS_UBOOT_CONFIG=y +CONFIG_NR_DRAM_BANKS=1 +CONFIG_TPL_SYS_MALLOC_F_LEN=0x400 +CONFIG_FIT=y +CONFIG_FIT_SIGNATURE=y +CONFIG_FIT_VERBOSE=y +CONFIG_IMAGE_FORMAT_LEGACY=y +CONFIG_SUPPORT_RAW_INITRD=y +CONFIG_DISPLAY_BOARDINFO_LATE=y +CONFIG_HUSH_PARSER=y +CONFIG_CMD_BOOTEFI_SELFTEST=y +CONFIG_DOS_PARTITION=y +CONFIG_ISO_PARTITION=y +CONFIG_EFI_PARTITION=y +CONFIG_OF_EMBED=y +CONFIG_DEFAULT_DEVICE_TREE="bcm968580xref" +# CONFIG_NET is not set +CONFIG_BLK=y +CONFIG_CLK=y +CONFIG_FIRMWARE=y +# CONFIG_MMC is not set +CONFIG_SPECIFY_CONSOLE_INDEX=y +# CONFIG_SPL_SERIAL_PRESENT is not set +CONFIG_CONS_INDEX=0 +CONFIG_DM_SERIAL=y +CONFIG_SERIAL_SEARCH_ALL=y +CONFIG_BCM6858_SERIAL=y +CONFIG_SYSRESET=y +CONFIG_REGEX=y +# CONFIG_GENERATE_SMBIOS_TABLE is not set diff --git a/configs/clearfog_defconfig b/configs/clearfog_defconfig index 9167a9450d..2e59686291 100644 --- a/configs/clearfog_defconfig +++ b/configs/clearfog_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_THUMB_BUILD=y CONFIG_ARCH_MVEBU=y CONFIG_SYS_TEXT_BASE=0x00800000 CONFIG_SPL_GPIO_SUPPORT=y diff --git a/configs/clearfog_gt_8k_defconfig b/configs/clearfog_gt_8k_defconfig new file mode 100644 index 0000000000..6cd1f89b23 --- /dev/null +++ b/configs/clearfog_gt_8k_defconfig @@ -0,0 +1,75 @@ +CONFIG_ARM=y +CONFIG_ARCH_MVEBU=y +CONFIG_SYS_TEXT_BASE=0x00000000 +CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_TARGET_MVEBU_ARMADA_8K=y +CONFIG_DEBUG_UART_BASE=0xf0512000 +CONFIG_DEBUG_UART_CLOCK=200000000 +CONFIG_DEFAULT_DEVICE_TREE="armada-8040-clearfog-gt-8k" +CONFIG_SMBIOS_PRODUCT_NAME="" +CONFIG_DEBUG_UART=y +CONFIG_AHCI=y +CONFIG_DISTRO_DEFAULTS=y +CONFIG_NR_DRAM_BANKS=1 +# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_SYS_CONSOLE_INFO_QUIET=y +# CONFIG_DISPLAY_CPUINFO is not set +# CONFIG_DISPLAY_BOARDINFO is not set +CONFIG_DISPLAY_BOARDINFO_LATE=y +CONFIG_ARCH_EARLY_INIT_R=y +CONFIG_BOARD_EARLY_INIT_F=y +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MMC=y +CONFIG_CMD_PCI=y +CONFIG_CMD_SF=y +CONFIG_CMD_SPI=y +CONFIG_CMD_USB=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_TFTPPUT=y +CONFIG_CMD_CACHE=y +CONFIG_CMD_TIME=y +CONFIG_CMD_MVEBU_BUBT=y +CONFIG_CMD_REGULATOR=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_MAC_PARTITION=y +CONFIG_ENV_IS_IN_SPI_FLASH=y +CONFIG_AHCI_MVEBU=y +CONFIG_DM_GPIO=y +CONFIG_DM_I2C=y +CONFIG_SYS_I2C_MVTWSI=y +CONFIG_MISC=y +CONFIG_DM_MMC=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_XENON=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_SPI_FLASH_SPANSION=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_SPI_FLASH_WINBOND=y +CONFIG_PHYLIB=y +CONFIG_PHY_GIGE=y +CONFIG_PCI=y +CONFIG_DM_PCI=y +CONFIG_PCIE_DW_MVEBU=y +CONFIG_MVEBU_COMPHY_SUPPORT=y +CONFIG_PINCTRL=y +CONFIG_PINCTRL_ARMADA_8K=y +CONFIG_DM_REGULATOR_FIXED=y +# CONFIG_SPL_SERIAL_PRESENT is not set +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_DEBUG_UART_ANNOUNCE=y +CONFIG_SYS_NS16550=y +CONFIG_KIRKWOOD_SPI=y +CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_STORAGE=y +CONFIG_USB_HOST_ETHER=y +CONFIG_USB_ETHER_ASIX=y +CONFIG_USB_ETHER_MCS7830=y +CONFIG_USB_ETHER_RTL8152=y +CONFIG_USB_ETHER_SMSC95XX=y +CONFIG_SMBIOS_MANUFACTURER="" diff --git a/configs/corvus_defconfig b/configs/corvus_defconfig index b1e7c35fa9..a1af2f1342 100644 --- a/configs/corvus_defconfig +++ b/configs/corvus_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_THUMB_BUILD=y # CONFIG_SPL_USE_ARCH_MEMCPY is not set # CONFIG_SPL_USE_ARCH_MEMSET is not set CONFIG_ARCH_AT91=y diff --git a/configs/gardena-smart-gateway-mt7688-ram_defconfig b/configs/gardena-smart-gateway-mt7688-ram_defconfig index 262dea3115..91359698ab 100644 --- a/configs/gardena-smart-gateway-mt7688-ram_defconfig +++ b/configs/gardena-smart-gateway-mt7688-ram_defconfig @@ -1,56 +1,76 @@ CONFIG_MIPS=y CONFIG_SYS_TEXT_BASE=0x80010000 CONFIG_ARCH_MT7620=y -# CONFIG_MIPS_BOOT_CMDLINE_LEGACY is not set # CONFIG_MIPS_BOOT_ENV_LEGACY is not set CONFIG_MIPS_BOOT_FDT=y +CONFIG_ENV_VARS_UBOOT_CONFIG=y CONFIG_NR_DRAM_BANKS=1 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_FIT=y +CONFIG_FIT_SIGNATURE=y +CONFIG_IMAGE_FORMAT_LEGACY=y CONFIG_OF_STDOUT_VIA_ALIAS=y CONFIG_SYS_CONSOLE_INFO_QUIET=y +CONFIG_VERSION_VARIABLE=y CONFIG_BOARD_EARLY_INIT_F=y CONFIG_HUSH_PARSER=y -CONFIG_CMD_CPU=y CONFIG_CMD_LICENSE=y -# CONFIG_CMD_BOOTD is not set # CONFIG_CMD_ELF is not set # CONFIG_CMD_XIMG is not set CONFIG_CMD_MEMINFO=y # CONFIG_CMD_FLASH is not set +CONFIG_CMD_GPIO=y # CONFIG_CMD_LOADS is not set +CONFIG_CMD_MTD=y CONFIG_CMD_SF=y CONFIG_CMD_SPI=y -# CONFIG_CMD_NET is not set +CONFIG_CMD_DHCP=y +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y +CONFIG_CMD_BOOTCOUNT=y CONFIG_CMD_TIME=y +CONFIG_CMD_UUID=y CONFIG_CMD_MTDPARTS=y CONFIG_MTDIDS_DEFAULT="spi-nand0=spi-nand0" -CONFIG_MTDPARTS_DEFAULT="mtdparts=spi-nand0:-(ubi)" +CONFIG_MTDPARTS_DEFAULT="mtdparts=spi-nand0:-(nand)" CONFIG_CMD_UBI=y CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="gardena-smart-gateway-mt7688" CONFIG_ENV_IS_IN_SPI_FLASH=y +CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set CONFIG_HAVE_BLOCK_DEVICE=y +CONFIG_BOOTCOUNT_LIMIT=y +CONFIG_SYS_BOOTCOUNT_SINGLEWORD=y +CONFIG_SYS_BOOTCOUNT_ADDR=0xb000006c CONFIG_CLK=y -CONFIG_CPU=y -CONFIG_DM_GPIO=y CONFIG_LED=y CONFIG_LED_BLINK=y CONFIG_LED_GPIO=y CONFIG_MTD=y +CONFIG_MTD_SPI_NAND=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_GIGADEVICE=y CONFIG_SPI_FLASH_MACRONIX=y CONFIG_SPI_FLASH_SPANSION=y CONFIG_SPI_FLASH_STMICRO=y CONFIG_SPI_FLASH_WINBOND=y +CONFIG_SPI_FLASH_XMC=y CONFIG_SPI_FLASH_MTD=y +CONFIG_MTD_UBI_BEB_LIMIT=22 +CONFIG_PHYLIB=y +CONFIG_PHY_FIXED=y +CONFIG_MT7628_ETH=y CONFIG_PHY=y CONFIG_POWER_DOMAIN=y CONFIG_RAM=y CONFIG_DM_RESET=y -CONFIG_BAUDRATE=57600 # CONFIG_SPL_SERIAL_PRESENT is not set CONFIG_SYS_NS16550=y CONFIG_SPI=y +CONFIG_MT7621_SPI=y CONFIG_SYSRESET_SYSCON=y +CONFIG_WATCHDOG=y +CONFIG_WDT=y +CONFIG_WDT_MT7621=y +CONFIG_LZMA=y diff --git a/configs/gardena-smart-gateway-mt7688_defconfig b/configs/gardena-smart-gateway-mt7688_defconfig index 6463e891b7..bd8b035dea 100644 --- a/configs/gardena-smart-gateway-mt7688_defconfig +++ b/configs/gardena-smart-gateway-mt7688_defconfig @@ -4,56 +4,76 @@ CONFIG_ARCH_MT7620=y CONFIG_BOOT_ROM=y CONFIG_ONBOARD_DDR2_SIZE_1024MBIT=y CONFIG_ONBOARD_DDR2_CHIP_WIDTH_16BIT=y -# CONFIG_MIPS_BOOT_CMDLINE_LEGACY is not set # CONFIG_MIPS_BOOT_ENV_LEGACY is not set CONFIG_MIPS_BOOT_FDT=y +CONFIG_ENV_VARS_UBOOT_CONFIG=y CONFIG_NR_DRAM_BANKS=1 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_FIT=y +CONFIG_FIT_SIGNATURE=y +CONFIG_IMAGE_FORMAT_LEGACY=y CONFIG_OF_STDOUT_VIA_ALIAS=y CONFIG_SYS_CONSOLE_INFO_QUIET=y +CONFIG_VERSION_VARIABLE=y CONFIG_BOARD_EARLY_INIT_F=y CONFIG_HUSH_PARSER=y -CONFIG_CMD_CPU=y CONFIG_CMD_LICENSE=y -# CONFIG_CMD_BOOTD is not set # CONFIG_CMD_ELF is not set # CONFIG_CMD_XIMG is not set CONFIG_CMD_MEMINFO=y # CONFIG_CMD_FLASH is not set +CONFIG_CMD_GPIO=y # CONFIG_CMD_LOADS is not set +CONFIG_CMD_MTD=y CONFIG_CMD_SF=y CONFIG_CMD_SPI=y -# CONFIG_CMD_NET is not set +CONFIG_CMD_DHCP=y +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y +CONFIG_CMD_BOOTCOUNT=y CONFIG_CMD_TIME=y +CONFIG_CMD_UUID=y CONFIG_CMD_MTDPARTS=y CONFIG_MTDIDS_DEFAULT="spi-nand0=spi-nand0" -CONFIG_MTDPARTS_DEFAULT="mtdparts=spi-nand0:-(ubi)" +CONFIG_MTDPARTS_DEFAULT="mtdparts=spi-nand0:-(nand)" CONFIG_CMD_UBI=y CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="gardena-smart-gateway-mt7688" CONFIG_ENV_IS_IN_SPI_FLASH=y +CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set CONFIG_HAVE_BLOCK_DEVICE=y +CONFIG_BOOTCOUNT_LIMIT=y +CONFIG_SYS_BOOTCOUNT_SINGLEWORD=y +CONFIG_SYS_BOOTCOUNT_ADDR=0xb000006c CONFIG_CLK=y -CONFIG_CPU=y -CONFIG_DM_GPIO=y CONFIG_LED=y CONFIG_LED_BLINK=y CONFIG_LED_GPIO=y CONFIG_MTD=y +CONFIG_MTD_SPI_NAND=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_GIGADEVICE=y CONFIG_SPI_FLASH_MACRONIX=y CONFIG_SPI_FLASH_SPANSION=y CONFIG_SPI_FLASH_STMICRO=y CONFIG_SPI_FLASH_WINBOND=y +CONFIG_SPI_FLASH_XMC=y CONFIG_SPI_FLASH_MTD=y +CONFIG_MTD_UBI_BEB_LIMIT=22 +CONFIG_PHYLIB=y +CONFIG_PHY_FIXED=y +CONFIG_MT7628_ETH=y CONFIG_PHY=y CONFIG_POWER_DOMAIN=y CONFIG_RAM=y CONFIG_DM_RESET=y -CONFIG_BAUDRATE=57600 # CONFIG_SPL_SERIAL_PRESENT is not set CONFIG_SYS_NS16550=y CONFIG_SPI=y +CONFIG_MT7621_SPI=y CONFIG_SYSRESET_SYSCON=y +CONFIG_WATCHDOG=y +CONFIG_WDT=y +CONFIG_WDT_MT7621=y +CONFIG_LZMA=y diff --git a/configs/linkit-smart-7688-ram_defconfig b/configs/linkit-smart-7688-ram_defconfig index 77cd1c1575..2d20e9edd9 100644 --- a/configs/linkit-smart-7688-ram_defconfig +++ b/configs/linkit-smart-7688-ram_defconfig @@ -1,35 +1,38 @@ CONFIG_MIPS=y CONFIG_SYS_TEXT_BASE=0x80010000 CONFIG_ARCH_MT7620=y -# CONFIG_MIPS_BOOT_CMDLINE_LEGACY is not set +CONFIG_BOARD_LINKIT_SMART_7688=y # CONFIG_MIPS_BOOT_ENV_LEGACY is not set CONFIG_MIPS_BOOT_FDT=y CONFIG_NR_DRAM_BANKS=1 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_FIT=y +CONFIG_FIT_SIGNATURE=y +CONFIG_IMAGE_FORMAT_LEGACY=y CONFIG_OF_STDOUT_VIA_ALIAS=y CONFIG_SYS_CONSOLE_INFO_QUIET=y CONFIG_BOARD_EARLY_INIT_F=y CONFIG_HUSH_PARSER=y -CONFIG_CMD_CPU=y CONFIG_CMD_LICENSE=y -# CONFIG_CMD_BOOTD is not set # CONFIG_CMD_ELF is not set # CONFIG_CMD_XIMG is not set CONFIG_CMD_MEMINFO=y # CONFIG_CMD_FLASH is not set +CONFIG_CMD_GPIO=y # CONFIG_CMD_LOADS is not set CONFIG_CMD_SF=y CONFIG_CMD_SPI=y -# CONFIG_CMD_NET is not set +CONFIG_CMD_DHCP=y +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y CONFIG_CMD_TIME=y CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="linkit-smart-7688" CONFIG_ENV_IS_IN_SPI_FLASH=y +CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set CONFIG_HAVE_BLOCK_DEVICE=y CONFIG_CLK=y -CONFIG_CPU=y -CONFIG_DM_GPIO=y CONFIG_LED=y CONFIG_LED_BLINK=y CONFIG_LED_GPIO=y @@ -40,12 +43,17 @@ CONFIG_SPI_FLASH_SPANSION=y CONFIG_SPI_FLASH_STMICRO=y CONFIG_SPI_FLASH_WINBOND=y CONFIG_SPI_FLASH_MTD=y +CONFIG_PHYLIB=y +CONFIG_PHY_FIXED=y +CONFIG_MT7628_ETH=y CONFIG_PHY=y CONFIG_POWER_DOMAIN=y CONFIG_RAM=y CONFIG_DM_RESET=y -CONFIG_BAUDRATE=57600 # CONFIG_SPL_SERIAL_PRESENT is not set CONFIG_SYS_NS16550=y CONFIG_SPI=y +CONFIG_MT7621_SPI=y CONFIG_SYSRESET_SYSCON=y +CONFIG_LZMA=y +CONFIG_LZO=y diff --git a/configs/linkit-smart-7688_defconfig b/configs/linkit-smart-7688_defconfig index 62cdda1e0a..5add29fb33 100644 --- a/configs/linkit-smart-7688_defconfig +++ b/configs/linkit-smart-7688_defconfig @@ -1,39 +1,42 @@ CONFIG_MIPS=y CONFIG_SYS_TEXT_BASE=0x9c000000 CONFIG_ARCH_MT7620=y +CONFIG_BOARD_LINKIT_SMART_7688=y CONFIG_BOOT_ROM=y CONFIG_ONBOARD_DDR2_SIZE_1024MBIT=y CONFIG_ONBOARD_DDR2_CHIP_WIDTH_16BIT=y -# CONFIG_MIPS_BOOT_CMDLINE_LEGACY is not set # CONFIG_MIPS_BOOT_ENV_LEGACY is not set CONFIG_MIPS_BOOT_FDT=y CONFIG_NR_DRAM_BANKS=1 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_FIT=y +CONFIG_FIT_SIGNATURE=y +CONFIG_IMAGE_FORMAT_LEGACY=y CONFIG_OF_STDOUT_VIA_ALIAS=y CONFIG_SYS_CONSOLE_INFO_QUIET=y CONFIG_BOARD_EARLY_INIT_F=y CONFIG_HUSH_PARSER=y -CONFIG_CMD_CPU=y CONFIG_CMD_LICENSE=y -# CONFIG_CMD_BOOTD is not set # CONFIG_CMD_ELF is not set # CONFIG_CMD_XIMG is not set # CONFIG_CMD_CRC32 is not set CONFIG_CMD_MEMINFO=y # CONFIG_CMD_FLASH is not set +CONFIG_CMD_GPIO=y # CONFIG_CMD_LOADS is not set CONFIG_CMD_SF=y CONFIG_CMD_SPI=y -# CONFIG_CMD_NET is not set +CONFIG_CMD_DHCP=y +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y CONFIG_CMD_TIME=y CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="linkit-smart-7688" CONFIG_ENV_IS_IN_SPI_FLASH=y +CONFIG_NET_RANDOM_ETHADDR=y # CONFIG_DM_DEVICE_REMOVE is not set CONFIG_HAVE_BLOCK_DEVICE=y CONFIG_CLK=y -CONFIG_CPU=y -CONFIG_DM_GPIO=y CONFIG_LED=y CONFIG_LED_BLINK=y CONFIG_LED_GPIO=y @@ -44,12 +47,17 @@ CONFIG_SPI_FLASH_SPANSION=y CONFIG_SPI_FLASH_STMICRO=y CONFIG_SPI_FLASH_WINBOND=y CONFIG_SPI_FLASH_MTD=y +CONFIG_PHYLIB=y +CONFIG_PHY_FIXED=y +CONFIG_MT7628_ETH=y CONFIG_PHY=y CONFIG_POWER_DOMAIN=y CONFIG_RAM=y CONFIG_DM_RESET=y -CONFIG_BAUDRATE=57600 # CONFIG_SPL_SERIAL_PRESENT is not set CONFIG_SYS_NS16550=y CONFIG_SPI=y +CONFIG_MT7621_SPI=y CONFIG_SYSRESET_SYSCON=y +CONFIG_LZMA=y +CONFIG_LZO=y diff --git a/configs/omap35_logic_defconfig b/configs/omap35_logic_defconfig index a23f6a33d6..80219eeacf 100644 --- a/configs/omap35_logic_defconfig +++ b/configs/omap35_logic_defconfig @@ -1,5 +1,6 @@ CONFIG_ARM=y CONFIG_ARCH_OMAP2PLUS=y +CONFIG_SYS_TEXT_BASE=0x80100000 CONFIG_TI_COMMON_CMD_OPTIONS=y # CONFIG_SPL_GPIO_SUPPORT is not set CONFIG_SYS_MALLOC_F_LEN=0x2000 @@ -29,9 +30,7 @@ CONFIG_MTDIDS_DEFAULT="nand0=omap2-nand.0" CONFIG_MTDPARTS_DEFAULT="mtdparts=omap2-nand.0:512k(MLO),1792k(u-boot),128k(spl-os),128k(u-boot-env),6m(kernel),-(fs)" CONFIG_CMD_UBI=y CONFIG_OF_CONTROL=y -CONFIG_SPL_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="logicpd-torpedo-35xx-devkit" -CONFIG_SPL_OF_PLATDATA=y # CONFIG_ENV_IS_IN_FAT is not set CONFIG_ENV_IS_IN_NAND=y CONFIG_SPL_DM=y diff --git a/configs/omap35_logic_somlv_defconfig b/configs/omap35_logic_somlv_defconfig index f28ca5bcbf..8a8c7147c3 100644 --- a/configs/omap35_logic_somlv_defconfig +++ b/configs/omap35_logic_somlv_defconfig @@ -1,5 +1,6 @@ CONFIG_ARM=y CONFIG_ARCH_OMAP2PLUS=y +CONFIG_SYS_TEXT_BASE=0x80100000 CONFIG_TI_COMMON_CMD_OPTIONS=y # CONFIG_SPL_GPIO_SUPPORT is not set CONFIG_SYS_MALLOC_F_LEN=0x2000 @@ -29,9 +30,7 @@ CONFIG_MTDIDS_DEFAULT="nand0=omap2-nand.0,nor0=physmap-flash.0" CONFIG_MTDPARTS_DEFAULT="mtdparts=omap2-nand.0:512k(MLO),1792k(u-boot),128k(spl-os),128k(u-boot-env),6m(kernel),-(fs);physmap-flash.0:-(nor)" CONFIG_CMD_UBI=y CONFIG_OF_CONTROL=y -CONFIG_SPL_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="logicpd-som-lv-35xx-devkit" -CONFIG_SPL_OF_PLATDATA=y # CONFIG_ENV_IS_IN_FAT is not set CONFIG_ENV_IS_IN_NAND=y CONFIG_SPL_DM=y diff --git a/configs/omap3_logic_defconfig b/configs/omap3_logic_defconfig index 45e5b504f7..969387a37c 100644 --- a/configs/omap3_logic_defconfig +++ b/configs/omap3_logic_defconfig @@ -1,5 +1,6 @@ CONFIG_ARM=y CONFIG_ARCH_OMAP2PLUS=y +CONFIG_SYS_TEXT_BASE=0x80100000 CONFIG_TI_COMMON_CMD_OPTIONS=y # CONFIG_SPL_GPIO_SUPPORT is not set CONFIG_SYS_MALLOC_F_LEN=0x2000 @@ -29,9 +30,7 @@ CONFIG_MTDIDS_DEFAULT="nand0=omap2-nand.0" CONFIG_MTDPARTS_DEFAULT="mtdparts=omap2-nand.0:512k(MLO),1792k(u-boot),128k(spl-os),128k(u-boot-env),6m(kernel),-(fs)" CONFIG_CMD_UBI=y CONFIG_OF_CONTROL=y -CONFIG_SPL_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="logicpd-torpedo-37xx-devkit" -CONFIG_SPL_OF_PLATDATA=y # CONFIG_ENV_IS_IN_FAT is not set CONFIG_ENV_IS_IN_NAND=y CONFIG_SPL_DM=y diff --git a/configs/omap3_logic_somlv_defconfig b/configs/omap3_logic_somlv_defconfig index e733584ebe..396543e56b 100644 --- a/configs/omap3_logic_somlv_defconfig +++ b/configs/omap3_logic_somlv_defconfig @@ -1,5 +1,6 @@ CONFIG_ARM=y CONFIG_ARCH_OMAP2PLUS=y +CONFIG_SYS_TEXT_BASE=0x80100000 CONFIG_TI_COMMON_CMD_OPTIONS=y # CONFIG_SPL_GPIO_SUPPORT is not set CONFIG_SYS_MALLOC_F_LEN=0x2000 @@ -28,9 +29,7 @@ CONFIG_MTDIDS_DEFAULT="nand0=omap2-nand.0,nor0=physmap-flash.0" CONFIG_MTDPARTS_DEFAULT="mtdparts=omap2-nand.0:512k(MLO),1792k(u-boot),128k(spl-os),128k(u-boot-env),6m(kernel),-(fs);physmap-flash.0:-(nor)" CONFIG_CMD_UBI=y CONFIG_OF_CONTROL=y -CONFIG_SPL_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="logicpd-som-lv-37xx-devkit" -CONFIG_SPL_OF_PLATDATA=y # CONFIG_ENV_IS_IN_FAT is not set CONFIG_ENV_IS_IN_NAND=y CONFIG_SPL_DM=y diff --git a/configs/picosam9g45_defconfig b/configs/picosam9g45_defconfig index 0b6234fbd9..699e2e230a 100644 --- a/configs/picosam9g45_defconfig +++ b/configs/picosam9g45_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_THUMB_BUILD=y CONFIG_ARCH_AT91=y CONFIG_SYS_TEXT_BASE=0x23f00000 CONFIG_TARGET_PICOSAM9G45=y @@ -39,3 +40,7 @@ CONFIG_USB_EHCI_HCD=y CONFIG_USB_STORAGE=y CONFIG_LCD=y CONFIG_OF_LIBFDT=y +CONFIG_DM=y +CONFIG_SPL_DM=y +CONFIG_WDT=y +CONFIG_WDT_AT91=y diff --git a/configs/qemu-riscv32_defconfig b/configs/qemu-riscv32_defconfig index ff1fb1f30e..6334d8c0fc 100644 --- a/configs/qemu-riscv32_defconfig +++ b/configs/qemu-riscv32_defconfig @@ -1,6 +1,9 @@ CONFIG_RISCV=y CONFIG_TARGET_QEMU_VIRT=y +CONFIG_DISTRO_DEFAULTS=y CONFIG_NR_DRAM_BANKS=1 +CONFIG_FIT=y CONFIG_DISPLAY_CPUINFO=y CONFIG_DISPLAY_BOARDINFO=y -CONFIG_OF_BOARD=y +# CONFIG_CMD_MII is not set +CONFIG_OF_PRIOR_STAGE=y diff --git a/configs/qemu-riscv64_defconfig b/configs/qemu-riscv64_defconfig index d6c1a5d646..2d9ead93a2 100644 --- a/configs/qemu-riscv64_defconfig +++ b/configs/qemu-riscv64_defconfig @@ -1,7 +1,10 @@ CONFIG_RISCV=y CONFIG_TARGET_QEMU_VIRT=y -CONFIG_CPU_RISCV_64=y +CONFIG_ARCH_RV64I=y +CONFIG_DISTRO_DEFAULTS=y CONFIG_NR_DRAM_BANKS=1 +CONFIG_FIT=y CONFIG_DISPLAY_CPUINFO=y CONFIG_DISPLAY_BOARDINFO=y -CONFIG_OF_BOARD=y +# CONFIG_CMD_MII is not set +CONFIG_OF_PRIOR_STAGE=y diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig index f44e80e8c3..452a2ef4a5 100644 --- a/configs/sandbox_spl_defconfig +++ b/configs/sandbox_spl_defconfig @@ -22,6 +22,7 @@ CONFIG_CONSOLE_RECORD=y CONFIG_CONSOLE_RECORD_OUT_SIZE=0x1000 CONFIG_SILENT_CONSOLE=y CONFIG_DISPLAY_BOARDINFO_LATE=y +CONFIG_HANDOFF=y CONFIG_SPL_BOARD_INIT=y CONFIG_SPL_ENV_SUPPORT=y CONFIG_CMD_CPU=y diff --git a/configs/smartweb_defconfig b/configs/smartweb_defconfig index cf6f2757ca..e9c2b63509 100644 --- a/configs/smartweb_defconfig +++ b/configs/smartweb_defconfig @@ -59,3 +59,6 @@ CONFIG_USB_ETHER_ASIX=y CONFIG_USB_ETHER_MCS7830=y CONFIG_SPL_TINY_MEMSET=y # CONFIG_EFI_LOADER is not set +CONFIG_WDT=y +CONFIG_WDT_AT91=y +CONFIG_AT91_HW_WDT_TIMEOUT=y diff --git a/configs/taurus_defconfig b/configs/taurus_defconfig index ee5da43ccb..e53e075d48 100644 --- a/configs/taurus_defconfig +++ b/configs/taurus_defconfig @@ -61,3 +61,6 @@ CONFIG_USB_GADGET_VENDOR_NUM=0x0908 CONFIG_USB_GADGET_PRODUCT_NUM=0x02d2 CONFIG_USB_GADGET_DOWNLOAD=y CONFIG_USE_TINY_PRINTF=y +CONFIG_WDT=y +CONFIG_WDT_AT91=y +CONFIG_AT91_HW_WDT_TIMEOUT=y diff --git a/configs/wb45n_defconfig b/configs/wb45n_defconfig index 33591d73e0..9d881e5d41 100644 --- a/configs/wb45n_defconfig +++ b/configs/wb45n_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_THUMB_BUILD=y CONFIG_ARCH_AT91=y CONFIG_SYS_TEXT_BASE=0x23f00000 CONFIG_TARGET_WB45N=y diff --git a/doc/README.at91 b/doc/README.at91 index 67412136ee..39dd5632ba 100644 --- a/doc/README.at91 +++ b/doc/README.at91 @@ -171,4 +171,4 @@ III. Watchdog support your code (make sure not to disable it in AT91Bootstrap for instance). In the U-Boot configuration, the AT91 watchdog support is enabled using - the CONFIG_AT91SAM9_WATCHDOG and CONFIG_HW_WATCHDOG options. + the CONFIG_WDT and CONFIG_WDT_AT91 options. diff --git a/doc/README.bloblist b/doc/README.bloblist new file mode 100644 index 0000000000..b0e787b97d --- /dev/null +++ b/doc/README.bloblist @@ -0,0 +1,82 @@ +# SPDX-License-Identifier: GPL-2.0+ + +Blob Lists - bloblist +===================== + +Introduction +------------ + +A bloblist provides a way to store collections of binary information (blobs) in +a central structure. Each record of information is assigned a tag so that its +owner can find it and update it. Each record is generally described by a C +structure defined by the code that owns it. + + +Passing state through the boot process +-------------------------------------- + +The bloblist is created when the first U-Boot component runs (often SPL, +sometimes TPL). It is passed through to each successive part of the boot and +can be accessed as needed. This provides a way to transfer state from one part +to the next. For example, TPL may determine that a watchdog reset occurred by +reading an SoC register. Reading the register may reset the value, so that it +cannot be read a second time. So TPL can store that in a bloblist record which +can be passed through to SPL and U-Boot proper, which can print a message +indicating that something went wrong and the watchdog fired. + + +Blobs +----- + +While each blob in the bloblist can be of any length, bloblists are designed to +hold small amounts of data, typically a few KB at most. It is not possible to +change the length of a blob once it has been written. Each blob is normally +created from a C structure which can beused to access its fields. + + +Blob tags +--------- + +Each blob has a tag which is a 32-bit number. This uniquely identifies the +owner of the blob. Blob tags are listed in enum blob_tag_t and are named +with a BLOBT_ prefix. + + +Single structure +---------------- + +There is normally only one bloblist in U-Boot. Since a bloblist can store +multiple blobs it does not seem useful to allow multiple bloblists. Of course +there could be reasons for this, such as needing to spread the blobs around in +different memory areas due to fragmented memory, but it is simpler to just have +a single bloblist. + + +API +--- + +Bloblist provides a fairly simple API which allows blobs to be created and +found. All access is via the blob's tag. + + +Finishing the bloblist +---------------------- + +When a part of U-Boot is about to jump to the next part, it can 'finish' the +bloblist in preparation for the next stage. This involves adding a checksum so +that the next stage can make sure that the data arrived safely. While the +bloblist is in use, changes can be made which will affect the checksum, so it +is easier to calculate the checksum at the end after all changes are made. + + +Future work +----------- + +Bootstage has a mechanism to 'stash' its records for passing to the next part. +This should move to using bloblist, to avoid having its own mechanism for +passing information between U-Boot parts. + + +Simon Glass +sjg@chromium.org +12-Aug-2018 diff --git a/doc/README.distro b/doc/README.distro index f8e9752a0f..ab6e6f4e74 100644 --- a/doc/README.distro +++ b/doc/README.distro @@ -292,7 +292,7 @@ Each entry in the macro defines a single boot device (e.g. a specific eMMC device or SD card) or type of boot device (e.g. USB disk). The parameters to the func macro (passed in by the internal implementation of the header) are: -- Upper-case disk type (MMC, SATA, SCSI, IDE, USB, DHCP, PXE). +- Upper-case disk type (MMC, SATA, SCSI, IDE, USB, DHCP, PXE, VIRTIO). - Lower-case disk type (same options as above). - ID of the specific disk (MMC only) or ignored for other types. @@ -398,6 +398,7 @@ The list of possible targets consists of: * scsi * ide * usb + * virtio Other *boot* variables than the ones defined above are only for internal use of the boot environment and are not guaranteed to exist or work in the same diff --git a/doc/README.trace b/doc/README.trace index 74ba26a5a4..2e7ca3319a 100644 --- a/doc/README.trace +++ b/doc/README.trace @@ -88,7 +88,7 @@ stdin=serial stdout=serial Environment size: 117/8188 bytes -=>sb save host 0 trace 0 ${profoffset} +=>host save host 0 trace 0 ${profoffset} 11405888 bytes written in 10 ms (1.1 GiB/s) =>reset diff --git a/doc/README.watchdog b/doc/README.watchdog index 7097c8766b..f23c923910 100644 --- a/doc/README.watchdog +++ b/doc/README.watchdog @@ -14,7 +14,7 @@ CONFIG_WATCHDOG_TIMEOUT_MSECS If not given, will default to maximum timeout. This would be 128000 msec for i.mx31/35/5x/6x. -CONFIG_AT91SAM9_WATCHDOG +CONFIG_WDT_AT91 Available for AT91SAM9 to service the watchdog. CONFIG_FTWDT010_WATCHDOG diff --git a/doc/device-tree-bindings/ram/k3-am654-ddrss.txt b/doc/device-tree-bindings/ram/k3-am654-ddrss.txt new file mode 100644 index 0000000000..4ed731c524 --- /dev/null +++ b/doc/device-tree-bindings/ram/k3-am654-ddrss.txt @@ -0,0 +1,46 @@ +Texas Instruments' K3 AM654 DDRSS +================================= + +K3 based AM654 devices has DDR memory subsystem that comprises +Synopys DDR controller, Synopsis DDR phy and wrapper logic to +integrate these blocks into the device. This DDR subsystem +provides an interface to external SDRAM devices. This DDRSS driver +adds support for the initialization of the external SDRAM devices by +configuring the DDRSS registers and using the buitin PHY +initialization routines. + +DDRSS device node: +================== +Required properties: +-------------------- +- compatible: Shall be: "ti,am654-ddrss" +- reg-names ss - Map the sub system wrapper logic region + ctl - Map the controller region + phy - Map the PHY region +- reg: Contains the register map per reg-names. +- power-domains: Should contain a phandle to a PM domain provider node + and an args specifier containing the DDRSS device id + value. This property is as per the binding, + doc/device-tree-bindings/power/ti,sci-pm-domain.txt +- clocks: Must contain an entry for enabling DDR clock. Should + be defined as per the appropriate clock bindings consumer + usage in doc/device-tree-bindings/clock/ti,sci-clk.txt + + +Optional Properties: +-------------------- +- clock-frequency: Frequency at which DDR pll should be locked. + If not provided, default frequency will be used. + +Example (AM65x): +================ + memory-controller: memory-controller@298e000 { + compatible = "ti,am654-ddrss"; + reg = <0x0298e000 0x200>, + <0x02980000 0x4000>, + <0x02988000 0x2000>; + reg-names = "ss", "ctl", "phy"; + clocks = <&k3_clks 20 0>; + power-domains = <&k3_pds 20>; + u-boot,dm-spl; + }; diff --git a/doc/device-tree-bindings/w1-eeprom/ds2502.txt b/doc/device-tree-bindings/w1-eeprom/ds2502.txt new file mode 100644 index 0000000000..7f05fc432e --- /dev/null +++ b/doc/device-tree-bindings/w1-eeprom/ds2502.txt @@ -0,0 +1,33 @@ +Maxim DS2502 driver device binding - one wire protocol add only memory from Maxim +======================= + +This memory needs to be connected to a onewire bus, as a child node. +The bus will read the device serial number and match this node with a found +device on the bus +Also check doc/device-tree-bindings/w1 for onewire bus drivers + +Driver: +- drivers/w1-eeprom/ds2502.c + +Ds2502 device-tree node properties: +Required: +* compatible = "maxim,ds2502" + +Optional: +* none + +Example: + eeprom1: eeprom@0 { + compatible = "maxim,ds2502"; + }; + +Example with parent bus: + onewire { + compatible = "fsl,imx53-owire"; + reg = <0x63fa4000 0x4000>; + + eeprom1: eeprom@0 { + compatible = "maxim,ds2502"; + }; + }; + diff --git a/drivers/Makefile b/drivers/Makefile index 4453c62ad3..55de10926e 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -2,14 +2,19 @@ obj-$(CONFIG_$(SPL_TPL_)CLK) += clk/ obj-$(CONFIG_$(SPL_TPL_)DM) += core/ +obj-$(CONFIG_$(SPL_TPL_)GPIO_SUPPORT) += gpio/ obj-$(CONFIG_$(SPL_TPL_)DRIVERS_MISC_SUPPORT) += misc/ sysreset/ firmware/ obj-$(CONFIG_$(SPL_TPL_)I2C_SUPPORT) += i2c/ +obj-$(CONFIG_$(SPL_TPL_)INPUT) += input/ obj-$(CONFIG_$(SPL_TPL_)LED) += led/ obj-$(CONFIG_$(SPL_TPL_)MMC_SUPPORT) += mmc/ obj-$(CONFIG_$(SPL_TPL_)NAND_SUPPORT) += mtd/nand/raw/ +obj-$(CONFIG_$(SPL_TPL_)PCH_SUPPORT) += pch/ +obj-$(CONFIG_$(SPL_TPL_)PCI_SUPPORT) += pci/ obj-$(CONFIG_$(SPL_TPL_)PHY) += phy/ obj-$(CONFIG_$(SPL_TPL_)PINCTRL) += pinctrl/ obj-$(CONFIG_$(SPL_TPL_)RAM) += ram/ +obj-$(CONFIG_$(SPL_TPL_)RTC_SUPPORT) += rtc/ obj-$(CONFIG_$(SPL_TPL_)SERIAL_SUPPORT) += serial/ obj-$(CONFIG_$(SPL_TPL_)SPI_FLASH_SUPPORT) += mtd/spi/ obj-$(CONFIG_$(SPL_TPL_)SPI_SUPPORT) += spi/ @@ -17,6 +22,7 @@ obj-$(CONFIG_$(SPL_TPL_)TIMER) += timer/ obj-$(CONFIG_$(SPL_TPL_)VIRTIO) += virtio/ obj-$(CONFIG_$(SPL_)DM_MAILBOX) += mailbox/ obj-$(CONFIG_$(SPL_)REMOTEPROC) += remoteproc/ +obj-$(CONFIG_$(SPL_TPL_)TPM) += tpm/ ifndef CONFIG_TPL_BUILD ifdef CONFIG_SPL_BUILD @@ -24,7 +30,6 @@ ifdef CONFIG_SPL_BUILD obj-$(CONFIG_SPL_BOOTCOUNT_LIMIT) += bootcount/ obj-$(CONFIG_SPL_CPU_SUPPORT) += cpu/ obj-$(CONFIG_SPL_CRYPTO_SUPPORT) += crypto/ -obj-$(CONFIG_SPL_GPIO_SUPPORT) += gpio/ obj-$(CONFIG_SPL_MPC8XXX_INIT_DDR_SUPPORT) += ddr/fsl/ obj-$(CONFIG_ARMADA_38X) += ddr/marvell/a38x/ obj-$(CONFIG_ARMADA_XP) += ddr/marvell/axp/ @@ -40,9 +45,6 @@ obj-$(CONFIG_SPL_DMA_SUPPORT) += dma/ obj-$(CONFIG_SPL_ETH_SUPPORT) += net/ obj-$(CONFIG_SPL_ETH_SUPPORT) += net/phy/ obj-$(CONFIG_SPL_USB_ETHER) += net/phy/ -obj-$(CONFIG_SPL_PCI_SUPPORT) += pci/ -obj-$(CONFIG_SPL_PCH_SUPPORT) += pch/ -obj-$(CONFIG_SPL_RTC_SUPPORT) += rtc/ obj-$(CONFIG_SPL_MUSB_NEW_SUPPORT) += usb/musb-new/ obj-$(CONFIG_SPL_USB_GADGET_SUPPORT) += usb/gadget/ obj-$(CONFIG_SPL_USB_GADGET_SUPPORT) += usb/gadget/udc/ @@ -92,7 +94,6 @@ obj-y += scsi/ obj-y += sound/ obj-y += spmi/ obj-y += sysreset/ -obj-y += tpm/ obj-y += video/ obj-y += watchdog/ obj-$(CONFIG_QE) += qe/ diff --git a/drivers/adc/adc-uclass.c b/drivers/adc/adc-uclass.c index 738c1eabdc..0a492eba54 100644 --- a/drivers/adc/adc-uclass.c +++ b/drivers/adc/adc-uclass.c @@ -6,6 +6,7 @@ #include <common.h> #include <errno.h> +#include <div64.h> #include <dm.h> #include <dm/lists.h> #include <dm/device-internal.h> @@ -77,6 +78,18 @@ int adc_data_mask(struct udevice *dev, unsigned int *data_mask) return 0; } +int adc_channel_mask(struct udevice *dev, unsigned int *channel_mask) +{ + struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); + + if (!uc_pdata) + return -ENOSYS; + + *channel_mask = uc_pdata->channel_mask; + + return 0; +} + int adc_stop(struct udevice *dev) { const struct adc_ops *ops = dev_get_driver_ops(dev); @@ -329,6 +342,30 @@ int adc_vss_value(struct udevice *dev, int *uV) return 0; } +int adc_raw_to_uV(struct udevice *dev, unsigned int raw, int *uV) +{ + unsigned int data_mask; + int ret, val, vref; + u64 raw64 = raw; + + ret = adc_vdd_value(dev, &vref); + if (ret) + return ret; + + if (!adc_vss_value(dev, &val)) + vref -= val; + + ret = adc_data_mask(dev, &data_mask); + if (ret) + return ret; + + raw64 *= vref; + do_div(raw64, data_mask); + *uV = raw64; + + return 0; +} + static int adc_vdd_platdata_set(struct udevice *dev) { struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev); diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c index 2b15978e14..04b369aa5a 100644 --- a/drivers/clk/clk-uclass.c +++ b/drivers/clk/clk-uclass.c @@ -243,10 +243,6 @@ int clk_set_defaults(struct udevice *dev) { int ret; - /* If this is running pre-reloc state, don't take any action. */ - if (!(gd->flags & GD_FLG_RELOC)) - return 0; - debug("%s(%s)\n", __func__, dev_read_name(dev)); ret = clk_set_default_parents(dev); diff --git a/drivers/clk/clk_meson.c b/drivers/clk/clk_meson.c index 236d7342b7..c44858822d 100644 --- a/drivers/clk/clk_meson.c +++ b/drivers/clk/clk_meson.c @@ -600,7 +600,8 @@ static unsigned long meson_clk81_get_rate(struct clk *clk) reg = readl(priv->addr + HHI_MPEG_CLK_CNTL); reg = reg & ((1 << 7) - 1); - return parent_rate / reg; + /* clk81 divider is zero based */ + return parent_rate / (reg + 1); } static long mpll_rate_from_params(unsigned long parent_rate, diff --git a/drivers/clk/clk_vexpress_osc.c b/drivers/clk/clk_vexpress_osc.c index 7fef4b2e31..c692a6d0b8 100644 --- a/drivers/clk/clk_vexpress_osc.c +++ b/drivers/clk/clk_vexpress_osc.c @@ -29,7 +29,7 @@ static ulong vexpress_osc_clk_get_rate(struct clk *clk) data = CLK_FUNCTION | priv->osc; err = misc_read(vexpress_cfg, 0, &data, sizeof(data)); - if (err) + if (err < 0) return err; return data; @@ -53,7 +53,7 @@ static ulong vexpress_osc_clk_set_rate(struct clk *clk, ulong rate) buffer[0] = CLK_FUNCTION | priv->osc; buffer[1] = rate; err = misc_write(vexpress_cfg, 0, buffer, 2 * sizeof(u32)); - if (err) + if (err < 0) return err; return rate; diff --git a/drivers/core/dump.c b/drivers/core/dump.c index 9068084404..04217cbde8 100644 --- a/drivers/core/dump.c +++ b/drivers/core/dump.c @@ -15,8 +15,8 @@ static void show_devices(struct udevice *dev, int depth, int last_flag) int i, is_last; struct udevice *child; - /* print the first 11 characters to not break the tree-format. */ - printf(" %-10.10s %d [ %c ] %-10.10s ", dev->uclass->uc_drv->name, + /* print the first 20 characters to not break the tree-format. */ + printf(" %-10.10s %d [ %c ] %-20.20s ", dev->uclass->uc_drv->name, dev_get_uclass_index(dev, NULL), dev->flags & DM_FLAG_ACTIVATED ? '+' : ' ', dev->driver->name); @@ -49,8 +49,8 @@ void dm_dump_all(void) root = dm_root(); if (root) { - printf(" Class index Probed Driver Name\n"); - printf("-----------------------------------------\n"); + printf(" Class index Probed Driver Name\n"); + printf("-----------------------------------------------------------\n"); show_devices(root, -1, 0); } } diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c index 6cfcde8918..d9c5719a87 100644 --- a/drivers/core/uclass.c +++ b/drivers/core/uclass.c @@ -562,6 +562,19 @@ int uclass_next_device(struct udevice **devp) return uclass_get_device_tail(dev, ret, devp); } +int uclass_next_device_err(struct udevice **devp) +{ + int ret; + + ret = uclass_next_device(devp); + if (ret) + return ret; + else if (!*devp) + return -ENODEV; + + return 0; +} + int uclass_first_device_check(enum uclass_id id, struct udevice **devp) { int ret; diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 5cd8b34400..35344e57c6 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -314,4 +314,12 @@ config MPC8XXX_GPIO Aside from the standard functions of input/output mode, and output value setting, the open-drain feature, which can configure individual GPIOs to work as open-drain outputs, is supported. + +config MT7621_GPIO + bool "MediaTek MT7621 GPIO driver" + depends on DM_GPIO && ARCH_MT7620 + default y + help + Say yes here to support MediaTek MT7621 compatible GPIOs. + endmenu diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index f186120684..7ed9a4ec42 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -58,3 +58,4 @@ obj-$(CONFIG_MVEBU_GPIO) += mvebu_gpio.o obj-$(CONFIG_MSM_GPIO) += msm_gpio.o obj-$(CONFIG_$(SPL_)PCF8575_GPIO) += pcf8575_gpio.o obj-$(CONFIG_PM8916_GPIO) += pm8916_gpio.o +obj-$(CONFIG_MT7621_GPIO) += mt7621_gpio.o diff --git a/drivers/gpio/mt7621_gpio.c b/drivers/gpio/mt7621_gpio.c new file mode 100644 index 0000000000..54d313d6f1 --- /dev/null +++ b/drivers/gpio/mt7621_gpio.c @@ -0,0 +1,183 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Stefan Roese <sr@denx.de> + * + * Based on the Linux driver version which is: + * Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org> + * Copyright (C) 2013 John Crispin <blogic@openwrt.org> + */ + +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <fdtdec.h> +#include <malloc.h> +#include <linux/io.h> +#include <asm/io.h> +#include <asm/gpio.h> +#include <dm/device-internal.h> +#include <dt-bindings/gpio/gpio.h> + +#define MTK_MAX_BANK 3 +#define MTK_BANK_WIDTH 32 + +enum mediatek_gpio_reg { + GPIO_REG_CTRL = 0, + GPIO_REG_POL, + GPIO_REG_DATA, + GPIO_REG_DSET, + GPIO_REG_DCLR, + GPIO_REG_REDGE, + GPIO_REG_FEDGE, + GPIO_REG_HLVL, + GPIO_REG_LLVL, + GPIO_REG_STAT, + GPIO_REG_EDGE, +}; + +static void __iomem *mediatek_gpio_membase; + +struct mediatek_gpio_platdata { + char bank_name[3]; /* Name of bank, e.g. "PA", "PB" etc */ + int gpio_count; + int bank; +}; + +static u32 reg_offs(struct mediatek_gpio_platdata *plat, int reg) +{ + return (reg * 0x10) + (plat->bank * 0x4); +} + +static int mediatek_gpio_get_value(struct udevice *dev, unsigned int offset) +{ + struct mediatek_gpio_platdata *plat = dev_get_platdata(dev); + + return !!(ioread32(mediatek_gpio_membase + + reg_offs(plat, GPIO_REG_DATA)) & BIT(offset)); +} + +static int mediatek_gpio_set_value(struct udevice *dev, unsigned int offset, + int value) +{ + struct mediatek_gpio_platdata *plat = dev_get_platdata(dev); + + iowrite32(BIT(offset), mediatek_gpio_membase + + reg_offs(plat, value ? GPIO_REG_DSET : GPIO_REG_DCLR)); + + return 0; +} + +static int mediatek_gpio_direction_input(struct udevice *dev, unsigned int offset) +{ + struct mediatek_gpio_platdata *plat = dev_get_platdata(dev); + + clrbits_le32(mediatek_gpio_membase + reg_offs(plat, GPIO_REG_CTRL), + BIT(offset)); + + return 0; +} + +static int mediatek_gpio_direction_output(struct udevice *dev, unsigned int offset, + int value) +{ + struct mediatek_gpio_platdata *plat = dev_get_platdata(dev); + + setbits_le32(mediatek_gpio_membase + reg_offs(plat, GPIO_REG_CTRL), + BIT(offset)); + mediatek_gpio_set_value(dev, offset, value); + + return 0; +} + +static int mediatek_gpio_get_function(struct udevice *dev, unsigned int offset) +{ + struct mediatek_gpio_platdata *plat = dev_get_platdata(dev); + u32 t; + + t = ioread32(mediatek_gpio_membase + reg_offs(plat, GPIO_REG_CTRL)); + if (t & BIT(offset)) + return GPIOF_OUTPUT; + + return GPIOF_INPUT; +} + +static const struct dm_gpio_ops gpio_mediatek_ops = { + .direction_input = mediatek_gpio_direction_input, + .direction_output = mediatek_gpio_direction_output, + .get_value = mediatek_gpio_get_value, + .set_value = mediatek_gpio_set_value, + .get_function = mediatek_gpio_get_function, +}; + +static int gpio_mediatek_probe(struct udevice *dev) +{ + struct mediatek_gpio_platdata *plat = dev_get_platdata(dev); + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); + + /* Tell the uclass how many GPIOs we have */ + if (plat) { + uc_priv->gpio_count = plat->gpio_count; + uc_priv->bank_name = plat->bank_name; + } + + return 0; +} + +/** + * We have a top-level GPIO device with no actual GPIOs. It has a child + * device for each Mediatek bank. + */ +static int gpio_mediatek_bind(struct udevice *parent) +{ + struct mediatek_gpio_platdata *plat = parent->platdata; + ofnode node; + int bank = 0; + int ret; + + /* If this is a child device, there is nothing to do here */ + if (plat) + return 0; + + mediatek_gpio_membase = dev_remap_addr(parent); + if (!mediatek_gpio_membase) + return -EINVAL; + + for (node = dev_read_first_subnode(parent); ofnode_valid(node); + node = dev_read_next_subnode(node)) { + struct mediatek_gpio_platdata *plat; + struct udevice *dev; + + plat = calloc(1, sizeof(*plat)); + if (!plat) + return -ENOMEM; + plat->bank_name[0] = 'P'; + plat->bank_name[1] = 'A' + bank; + plat->bank_name[2] = '\0'; + plat->gpio_count = MTK_BANK_WIDTH; + plat->bank = bank; + + ret = device_bind(parent, parent->driver, + plat->bank_name, plat, -1, &dev); + if (ret) + return ret; + + dev->node = node; + bank++; + } + + return 0; +} + +static const struct udevice_id mediatek_gpio_ids[] = { + { .compatible = "mtk,mt7621-gpio" }, + { } +}; + +U_BOOT_DRIVER(gpio_mediatek) = { + .name = "gpio_mediatek", + .id = UCLASS_GPIO, + .ops = &gpio_mediatek_ops, + .of_match = mediatek_gpio_ids, + .bind = gpio_mediatek_bind, + .probe = gpio_mediatek_probe, +}; diff --git a/drivers/gpio/pca953x_gpio.c b/drivers/gpio/pca953x_gpio.c index 0bb484498a..341527acc5 100644 --- a/drivers/gpio/pca953x_gpio.c +++ b/drivers/gpio/pca953x_gpio.c @@ -130,6 +130,25 @@ static int pca953x_read_regs(struct udevice *dev, int reg, u8 *val) return ret; } +static int pca953x_write_regs(struct udevice *dev, int reg, u8 *val) +{ + struct pca953x_info *info = dev_get_platdata(dev); + int ret = 0; + + if (info->gpio_count <= 8) { + ret = dm_i2c_write(dev, reg, val, 1); + } else if (info->gpio_count <= 16) { + ret = dm_i2c_write(dev, reg << 1, val, info->bank_count); + } else if (info->gpio_count == 40) { + /* Auto increment */ + ret = dm_i2c_write(dev, (reg << 3) | 0x80, val, info->bank_count); + } else { + return -EINVAL; + } + + return ret; +} + static int pca953x_is_output(struct udevice *dev, int offset) { struct pca953x_info *info = dev_get_platdata(dev); @@ -251,6 +270,7 @@ static int pca953x_probe(struct udevice *dev) int ret; int size; const u8 *tmp; + u8 val[MAX_BANK]; addr = dev_read_addr(dev); if (addr == 0) @@ -296,6 +316,14 @@ static int pca953x_probe(struct udevice *dev) snprintf(name, sizeof(name), "gpio@%x_", info->addr); } + /* Clear the polarity registers to no invert */ + memset(val, 0, MAX_BANK); + ret = pca953x_write_regs(dev, PCA953X_INVERT, val); + if (ret < 0) { + dev_err(dev, "Error writing invert register\n"); + return ret; + } + str = strdup(name); if (!str) return -ENOMEM; diff --git a/drivers/gpio/stm32f7_gpio.c b/drivers/gpio/stm32f7_gpio.c index b903dc46b3..a690c437eb 100644 --- a/drivers/gpio/stm32f7_gpio.c +++ b/drivers/gpio/stm32f7_gpio.c @@ -65,11 +65,31 @@ static int stm32_gpio_set_value(struct udevice *dev, unsigned offset, int value) return 0; } +static int stm32_gpio_get_function(struct udevice *dev, unsigned int offset) +{ + struct stm32_gpio_priv *priv = dev_get_priv(dev); + struct stm32_gpio_regs *regs = priv->regs; + int bits_index = MODE_BITS(offset); + int mask = MODE_BITS_MASK << bits_index; + u32 mode; + + mode = (readl(®s->moder) & mask) >> bits_index; + if (mode == STM32_GPIO_MODE_OUT) + return GPIOF_OUTPUT; + if (mode == STM32_GPIO_MODE_IN) + return GPIOF_INPUT; + if (mode == STM32_GPIO_MODE_AN) + return GPIOF_UNUSED; + + return GPIOF_FUNC; +} + static const struct dm_gpio_ops gpio_stm32_ops = { .direction_input = stm32_gpio_direction_input, .direction_output = stm32_gpio_direction_output, .get_value = stm32_gpio_get_value, .set_value = stm32_gpio_set_value, + .get_function = stm32_gpio_get_function, }; static int gpio_stm32_probe(struct udevice *dev) diff --git a/drivers/i2c/stm32f7_i2c.c b/drivers/i2c/stm32f7_i2c.c index 36ec610c8e..3872364d6b 100644 --- a/drivers/i2c/stm32f7_i2c.c +++ b/drivers/i2c/stm32f7_i2c.c @@ -58,7 +58,7 @@ struct stm32_i2c_regs { #define STM32_I2C_CR2_ADD10 BIT(11) #define STM32_I2C_CR2_RD_WRN BIT(10) #define STM32_I2C_CR2_SADD10_MASK GENMASK(9, 0) -#define STM32_I2C_CR2_SADD10(n) ((n & STM32_I2C_CR2_SADD10_MASK)) +#define STM32_I2C_CR2_SADD10(n) (n & STM32_I2C_CR2_SADD10_MASK) #define STM32_I2C_CR2_SADD7_MASK GENMASK(7, 1) #define STM32_I2C_CR2_SADD7(n) ((n & 0x7f) << 1) #define STM32_I2C_CR2_RESET_MASK (STM32_I2C_CR2_HEAD10R \ @@ -197,7 +197,7 @@ struct stm32_i2c_priv { int speed; }; -static struct stm32_i2c_spec i2c_specs[] = { +static const struct stm32_i2c_spec i2c_specs[] = { [STM32_I2C_SPEED_STANDARD] = { .rate = STANDARD_RATE, .rate_min = 8000, @@ -236,7 +236,7 @@ static struct stm32_i2c_spec i2c_specs[] = { }, }; -static struct stm32_i2c_setup stm32f7_setup = { +static const struct stm32_i2c_setup stm32f7_setup = { .rise_time = STM32_I2C_RISE_TIME_DEFAULT, .fall_time = STM32_I2C_FALL_TIME_DEFAULT, .dnf = STM32_I2C_DNF_DEFAULT, @@ -255,7 +255,7 @@ static int stm32_i2c_check_device_busy(struct stm32_i2c_priv *i2c_priv) } static void stm32_i2c_message_start(struct stm32_i2c_priv *i2c_priv, - struct i2c_msg *msg, bool stop) + struct i2c_msg *msg, bool stop) { struct stm32_i2c_regs *regs = i2c_priv->regs; u32 cr2 = readl(®s->cr2); @@ -299,7 +299,7 @@ static void stm32_i2c_message_start(struct stm32_i2c_priv *i2c_priv, */ static void stm32_i2c_handle_reload(struct stm32_i2c_priv *i2c_priv, - struct i2c_msg *msg, bool stop) + struct i2c_msg *msg, bool stop) { struct stm32_i2c_regs *regs = i2c_priv->regs; u32 cr2 = readl(®s->cr2); @@ -317,7 +317,7 @@ static void stm32_i2c_handle_reload(struct stm32_i2c_priv *i2c_priv, } static int stm32_i2c_wait_flags(struct stm32_i2c_priv *i2c_priv, - u32 flags, u32 *status) + u32 flags, u32 *status) { struct stm32_i2c_regs *regs = i2c_priv->regs; u32 time_start = get_timer(0); @@ -392,7 +392,7 @@ static int stm32_i2c_check_end_of_message(struct stm32_i2c_priv *i2c_priv) } static int stm32_i2c_message_xfer(struct stm32_i2c_priv *i2c_priv, - struct i2c_msg *msg, bool stop) + struct i2c_msg *msg, bool stop) { struct stm32_i2c_regs *regs = i2c_priv->regs; u32 status; @@ -465,7 +465,7 @@ static int stm32_i2c_message_xfer(struct stm32_i2c_priv *i2c_priv, } static int stm32_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, - int nmsgs) + int nmsgs) { struct stm32_i2c_priv *i2c_priv = dev_get_priv(bus); int ret; @@ -594,6 +594,7 @@ static int stm32_i2c_choose_solution(struct stm32_i2c_setup *setup, for (l = 0; l < STM32_SCLL_MAX; l++) { u32 tscl_l = (l + 1) * prescaler + tsync; + if ((tscl_l < i2c_specs[setup->speed].l_min) || (i2cclk >= ((tscl_l - af_delay_min - dnf_delay) / 4))) { @@ -634,8 +635,8 @@ static int stm32_i2c_choose_solution(struct stm32_i2c_setup *setup, } static int stm32_i2c_compute_timing(struct stm32_i2c_priv *i2c_priv, - struct stm32_i2c_setup *setup, - struct stm32_i2c_timings *output) + struct stm32_i2c_setup *setup, + struct stm32_i2c_timings *output) { struct stm32_i2c_timings *v, *_v; struct list_head solutions; @@ -643,28 +644,28 @@ static int stm32_i2c_compute_timing(struct stm32_i2c_priv *i2c_priv, if (setup->speed >= STM32_I2C_SPEED_END) { pr_err("%s: speed out of bound {%d/%d}\n", __func__, - setup->speed, STM32_I2C_SPEED_END - 1); + setup->speed, STM32_I2C_SPEED_END - 1); return -EINVAL; } if ((setup->rise_time > i2c_specs[setup->speed].rise_max) || (setup->fall_time > i2c_specs[setup->speed].fall_max)) { pr_err("%s :timings out of bound Rise{%d>%d}/Fall{%d>%d}\n", - __func__, - setup->rise_time, i2c_specs[setup->speed].rise_max, - setup->fall_time, i2c_specs[setup->speed].fall_max); + __func__, + setup->rise_time, i2c_specs[setup->speed].rise_max, + setup->fall_time, i2c_specs[setup->speed].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); + setup->dnf, STM32_I2C_DNF_MAX); return -EINVAL; } if (setup->speed_freq > i2c_specs[setup->speed].rate) { pr_err("%s: Freq {%d/%d}\n", __func__, - setup->speed_freq, i2c_specs[setup->speed].rate); + setup->speed_freq, i2c_specs[setup->speed].rate); return -EINVAL; } @@ -693,7 +694,7 @@ exit: } static int stm32_i2c_setup_timing(struct stm32_i2c_priv *i2c_priv, - struct stm32_i2c_timings *timing) + struct stm32_i2c_timings *timing) { struct stm32_i2c_setup *setup = i2c_priv->setup; int ret = 0; diff --git a/drivers/misc/altera_sysid.c b/drivers/misc/altera_sysid.c index 883b2a35e0..eff33f7343 100644 --- a/drivers/misc/altera_sysid.c +++ b/drivers/misc/altera_sysid.c @@ -35,7 +35,7 @@ void display_sysid(void) if (ret) return; ret = misc_read(dev, 0, &sysid, sizeof(sysid)); - if (ret) + if (ret < 0) return; stamp = sysid[1]; diff --git a/drivers/misc/cros_ec.c b/drivers/misc/cros_ec.c index 190505c11c..2dcdb3d8d6 100644 --- a/drivers/misc/cros_ec.c +++ b/drivers/misc/cros_ec.c @@ -13,6 +13,8 @@ * is not reset. */ +#define LOG_CATEGORY UCLASS_CROS_EC + #include <common.h> #include <command.h> #include <dm.h> @@ -41,6 +43,54 @@ enum { CROS_EC_CMD_HASH_TIMEOUT_MS = 2000, }; +#define INVALID_HCMD 0xFF + +/* + * Map UHEPI masks to non UHEPI commands in order to support old EC FW + * which does not support UHEPI command. + */ +static const struct { + u8 set_cmd; + u8 clear_cmd; + u8 get_cmd; +} event_map[] = { + [EC_HOST_EVENT_MAIN] = { + INVALID_HCMD, EC_CMD_HOST_EVENT_CLEAR, + INVALID_HCMD, + }, + [EC_HOST_EVENT_B] = { + INVALID_HCMD, EC_CMD_HOST_EVENT_CLEAR_B, + EC_CMD_HOST_EVENT_GET_B, + }, + [EC_HOST_EVENT_SCI_MASK] = { + EC_CMD_HOST_EVENT_SET_SCI_MASK, INVALID_HCMD, + EC_CMD_HOST_EVENT_GET_SCI_MASK, + }, + [EC_HOST_EVENT_SMI_MASK] = { + EC_CMD_HOST_EVENT_SET_SMI_MASK, INVALID_HCMD, + EC_CMD_HOST_EVENT_GET_SMI_MASK, + }, + [EC_HOST_EVENT_ALWAYS_REPORT_MASK] = { + INVALID_HCMD, INVALID_HCMD, INVALID_HCMD, + }, + [EC_HOST_EVENT_ACTIVE_WAKE_MASK] = { + EC_CMD_HOST_EVENT_SET_WAKE_MASK, INVALID_HCMD, + EC_CMD_HOST_EVENT_GET_WAKE_MASK, + }, + [EC_HOST_EVENT_LAZY_WAKE_MASK_S0IX] = { + EC_CMD_HOST_EVENT_SET_WAKE_MASK, INVALID_HCMD, + EC_CMD_HOST_EVENT_GET_WAKE_MASK, + }, + [EC_HOST_EVENT_LAZY_WAKE_MASK_S3] = { + EC_CMD_HOST_EVENT_SET_WAKE_MASK, INVALID_HCMD, + EC_CMD_HOST_EVENT_GET_WAKE_MASK, + }, + [EC_HOST_EVENT_LAZY_WAKE_MASK_S5] = { + EC_CMD_HOST_EVENT_SET_WAKE_MASK, INVALID_HCMD, + EC_CMD_HOST_EVENT_GET_WAKE_MASK, + }, +}; + void cros_ec_dump_data(const char *name, int cmd, const uint8_t *data, int len) { #ifdef DEBUG @@ -227,7 +277,7 @@ static int send_command_proto3(struct cros_ec_dev *cdev, return handle_proto3_response(cdev, dinp, din_len); } -static int send_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version, +static int send_command(struct cros_ec_dev *dev, uint cmd, int cmd_version, const void *dout, int dout_len, uint8_t **dinp, int din_len) { @@ -330,7 +380,7 @@ static int ec_command_inptr(struct udevice *dev, uint8_t cmd, * @param din_len Maximum size of response in bytes * @return number of bytes in response, or -ve on error */ -static int ec_command(struct udevice *dev, uint8_t cmd, int cmd_version, +static int ec_command(struct udevice *dev, uint cmd, int cmd_version, const void *dout, int dout_len, void *din, int din_len) { @@ -365,10 +415,14 @@ int cros_ec_scan_keyboard(struct udevice *dev, struct mbkp_keyscan *scan) int cros_ec_read_id(struct udevice *dev, char *id, int maxlen) { struct ec_response_get_version *r; + int ret; - if (ec_command_inptr(dev, EC_CMD_GET_VERSION, 0, NULL, 0, - (uint8_t **)&r, sizeof(*r)) != sizeof(*r)) + ret = ec_command_inptr(dev, EC_CMD_GET_VERSION, 0, NULL, 0, + (uint8_t **)&r, sizeof(*r)); + if (ret != sizeof(*r)) { + log_err("Got rc %d, expected %d\n", ret, sizeof(*r)); return -1; + } if (maxlen > (int)sizeof(r->version_string_ro)) maxlen = sizeof(r->version_string_ro); @@ -381,6 +435,7 @@ int cros_ec_read_id(struct udevice *dev, char *id, int maxlen) memcpy(id, r->version_string_rw, maxlen); break; default: + log_err("Invalid EC image %d\n", r->current_image); return -1; } @@ -563,6 +618,36 @@ int cros_ec_info(struct udevice *dev, struct ec_response_mkbp_info *info) return 0; } +int cros_ec_get_event_mask(struct udevice *dev, uint type, uint32_t *mask) +{ + struct ec_response_host_event_mask rsp; + int ret; + + ret = ec_command(dev, type, 0, NULL, 0, &rsp, sizeof(rsp)); + if (ret < 0) + return ret; + else if (ret != sizeof(rsp)) + return -EINVAL; + + *mask = rsp.mask; + + return 0; +} + +int cros_ec_set_event_mask(struct udevice *dev, uint type, uint32_t mask) +{ + struct ec_params_host_event_mask req; + int ret; + + req.mask = mask; + + ret = ec_command(dev, type, 0, &req, sizeof(req), NULL, 0); + if (ret < 0) + return ret; + + return 0; +} + int cros_ec_get_host_events(struct udevice *dev, uint32_t *events_ptr) { struct ec_response_host_event_mask *resp; @@ -616,6 +701,17 @@ int cros_ec_flash_protect(struct udevice *dev, uint32_t set_mask, return 0; } +int cros_ec_entering_mode(struct udevice *dev, int mode) +{ + int rc; + + rc = ec_command(dev, EC_CMD_ENTERING_MODE, 0, &mode, sizeof(mode), + NULL, 0); + if (rc) + return -1; + return 0; +} + static int cros_ec_check_version(struct udevice *dev) { struct cros_ec_dev *cdev = dev_get_uclass_priv(dev); @@ -650,16 +746,14 @@ static int cros_ec_check_version(struct udevice *dev) cdev->protocol_version = 3; req.in_data = 0; if (ec_command_inptr(dev, EC_CMD_HELLO, 0, &req, sizeof(req), - (uint8_t **)&resp, sizeof(*resp)) > 0) { + (uint8_t **)&resp, sizeof(*resp)) > 0) return 0; - } /* Try sending a version 2 packet */ cdev->protocol_version = 2; if (ec_command_inptr(dev, EC_CMD_HELLO, 0, &req, sizeof(req), - (uint8_t **)&resp, sizeof(*resp)) > 0) { + (uint8_t **)&resp, sizeof(*resp)) > 0) return 0; - } /* * Fail if we're still here, since the EC doesn't understand any @@ -822,6 +916,9 @@ int cros_ec_flash_write(struct udevice *dev, const uint8_t *data, uint32_t end, off; int ret; + if (!burst) + return -EINVAL; + /* * TODO: round up to the nearest multiple of write size. Can get away * without that on link right now because its write size is 4 bytes. @@ -845,6 +942,35 @@ int cros_ec_flash_write(struct udevice *dev, const uint8_t *data, } /** + * Run verification on a slot + * + * @param me CrosEc instance + * @param region Region to run verification on + * @return 0 if success or not applicable. Non-zero if verification failed. + */ +int cros_ec_efs_verify(struct udevice *dev, enum ec_flash_region region) +{ + struct ec_params_efs_verify p; + int rv; + + log_info("EFS: EC is verifying updated image...\n"); + p.region = region; + + rv = ec_command(dev, EC_CMD_EFS_VERIFY, 0, &p, sizeof(p), NULL, 0); + if (rv >= 0) { + log_info("EFS: Verification success\n"); + return 0; + } + if (rv == -EC_RES_INVALID_COMMAND) { + log_info("EFS: EC doesn't support EFS_VERIFY command\n"); + return 0; + } + log_info("EFS: Verification failed\n"); + + return rv; +} + +/** * Read a single block from the flash * * Read a block of data from the EC flash. The size must not exceed the flash @@ -934,15 +1060,17 @@ int cros_ec_read_nvdata(struct udevice *dev, uint8_t *block, int size) struct ec_params_vbnvcontext p; int len; - if (size != EC_VBNV_BLOCK_SIZE) + if (size != EC_VBNV_BLOCK_SIZE && size != EC_VBNV_BLOCK_SIZE_V2) return -EINVAL; p.op = EC_VBNV_CONTEXT_OP_READ; len = ec_command(dev, EC_CMD_VBNV_CONTEXT, EC_VER_VBNV_CONTEXT, - &p, sizeof(p), block, EC_VBNV_BLOCK_SIZE); - if (len < EC_VBNV_BLOCK_SIZE) + &p, sizeof(uint32_t) + size, block, size); + if (len != size) { + log_err("Expected %d bytes, got %d\n", size, len); return -EIO; + } return 0; } @@ -952,19 +1080,33 @@ int cros_ec_write_nvdata(struct udevice *dev, const uint8_t *block, int size) struct ec_params_vbnvcontext p; int len; - if (size != EC_VBNV_BLOCK_SIZE) + if (size != EC_VBNV_BLOCK_SIZE && size != EC_VBNV_BLOCK_SIZE_V2) return -EINVAL; p.op = EC_VBNV_CONTEXT_OP_WRITE; - memcpy(p.block, block, sizeof(p.block)); + memcpy(p.block, block, size); len = ec_command_inptr(dev, EC_CMD_VBNV_CONTEXT, EC_VER_VBNV_CONTEXT, - &p, sizeof(p), NULL, 0); + &p, sizeof(uint32_t) + size, NULL, 0); if (len < 0) return -1; return 0; } +int cros_ec_battery_cutoff(struct udevice *dev, uint8_t flags) +{ + struct ec_params_battery_cutoff p; + int len; + + p.flags = flags; + len = ec_command(dev, EC_CMD_BATTERY_CUT_OFF, 1, &p, sizeof(p), + NULL, 0); + + if (len < 0) + return -1; + return 0; +} + int cros_ec_set_ldo(struct udevice *dev, uint8_t index, uint8_t state) { struct ec_params_ldo_set params; @@ -1139,9 +1281,209 @@ int cros_ec_i2c_tunnel(struct udevice *dev, int port, struct i2c_msg *in, return 0; } +int cros_ec_check_feature(struct udevice *dev, int feature) +{ + struct ec_response_get_features r; + int rv; + + rv = ec_command(dev, EC_CMD_GET_FEATURES, 0, &r, sizeof(r), NULL, 0); + if (rv) + return rv; + + if (feature >= 8 * sizeof(r.flags)) + return -1; + + return r.flags[feature / 32] & EC_FEATURE_MASK_0(feature); +} + +/* + * Query the EC for specified mask indicating enabled events. + * The EC maintains separate event masks for SMI, SCI and WAKE. + */ +static int cros_ec_uhepi_cmd(struct udevice *dev, uint mask, uint action, + uint64_t *value) +{ + int ret; + struct ec_params_host_event req; + struct ec_response_host_event rsp; + + req.action = action; + req.mask_type = mask; + if (action != EC_HOST_EVENT_GET) + req.value = *value; + else + *value = 0; + ret = ec_command(dev, EC_CMD_HOST_EVENT, 0, &req, sizeof(req), &rsp, + sizeof(rsp)); + + if (action != EC_HOST_EVENT_GET) + return ret; + if (ret == 0) + *value = rsp.value; + + return ret; +} + +static int cros_ec_handle_non_uhepi_cmd(struct udevice *dev, uint hcmd, + uint action, uint64_t *value) +{ + int ret = -1; + struct ec_params_host_event_mask req; + struct ec_response_host_event_mask rsp; + + if (hcmd == INVALID_HCMD) + return ret; + + if (action != EC_HOST_EVENT_GET) + req.mask = (uint32_t)*value; + else + *value = 0; + + ret = ec_command(dev, hcmd, 0, &req, sizeof(req), &rsp, sizeof(rsp)); + if (action != EC_HOST_EVENT_GET) + return ret; + if (ret == 0) + *value = rsp.mask; + + return ret; +} + +bool cros_ec_is_uhepi_supported(struct udevice *dev) +{ +#define UHEPI_SUPPORTED 1 +#define UHEPI_NOT_SUPPORTED 2 + static int uhepi_support; + + if (!uhepi_support) { + uhepi_support = cros_ec_check_feature(dev, + EC_FEATURE_UNIFIED_WAKE_MASKS) > 0 ? UHEPI_SUPPORTED : + UHEPI_NOT_SUPPORTED; + log_debug("Chrome EC: UHEPI %s\n", + uhepi_support == UHEPI_SUPPORTED ? "supported" : + "not supported"); + } + return uhepi_support == UHEPI_SUPPORTED; +} + +static int cros_ec_get_mask(struct udevice *dev, uint type) +{ + u64 value = 0; + + if (cros_ec_is_uhepi_supported(dev)) { + cros_ec_uhepi_cmd(dev, type, EC_HOST_EVENT_GET, &value); + } else { + assert(type < ARRAY_SIZE(event_map)); + cros_ec_handle_non_uhepi_cmd(dev, event_map[type].get_cmd, + EC_HOST_EVENT_GET, &value); + } + return value; +} + +static int cros_ec_clear_mask(struct udevice *dev, uint type, u64 mask) +{ + if (cros_ec_is_uhepi_supported(dev)) + return cros_ec_uhepi_cmd(dev, type, EC_HOST_EVENT_CLEAR, &mask); + + assert(type < ARRAY_SIZE(event_map)); + + return cros_ec_handle_non_uhepi_cmd(dev, event_map[type].clear_cmd, + EC_HOST_EVENT_CLEAR, &mask); +} + +uint64_t cros_ec_get_events_b(struct udevice *dev) +{ + return cros_ec_get_mask(dev, EC_HOST_EVENT_B); +} + +int cros_ec_clear_events_b(struct udevice *dev, uint64_t mask) +{ + log_debug("Chrome EC: clear events_b mask to 0x%016llx\n", mask); + + return cros_ec_clear_mask(dev, EC_HOST_EVENT_B, mask); +} + +int cros_ec_read_limit_power(struct udevice *dev, int *limit_powerp) +{ + struct ec_params_charge_state p; + struct ec_response_charge_state r; + int ret; + + p.cmd = CHARGE_STATE_CMD_GET_PARAM; + p.get_param.param = CS_PARAM_LIMIT_POWER; + ret = ec_command(dev, EC_CMD_CHARGE_STATE, 0, &p, sizeof(p), + &r, sizeof(r)); + + /* + * If our EC doesn't support the LIMIT_POWER parameter, assume that + * LIMIT_POWER is not requested. + */ + if (ret == -EC_RES_INVALID_PARAM || ret == -EC_RES_INVALID_COMMAND) { + log_warning("PARAM_LIMIT_POWER not supported by EC\n"); + return -ENOSYS; + } + + if (ret != sizeof(r.get_param)) + return -EINVAL; + + *limit_powerp = r.get_param.value; + return 0; +} + +int cros_ec_config_powerbtn(struct udevice *dev, uint32_t flags) +{ + struct ec_params_config_power_button params; + int ret; + + params.flags = flags; + ret = ec_command(dev, EC_CMD_CONFIG_POWER_BUTTON, 0, + ¶ms, sizeof(params), NULL, 0); + if (ret < 0) + return ret; + + return 0; +} + +int cros_ec_get_lid_shutdown_mask(struct udevice *dev) +{ + u32 mask; + int ret; + + ret = cros_ec_get_event_mask(dev, EC_CMD_HOST_EVENT_GET_SMI_MASK, + &mask); + if (ret < 0) + return ret; + + return !!(mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_CLOSED)); +} + +int cros_ec_set_lid_shutdown_mask(struct udevice *dev, int enable) +{ + u32 mask; + int ret; + + ret = cros_ec_get_event_mask(dev, EC_CMD_HOST_EVENT_GET_SMI_MASK, + &mask); + if (ret < 0) + return ret; + + // Set lid close event state in the EC SMI event mask + if (enable) + mask |= EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_CLOSED); + else + mask &= ~EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_CLOSED); + + ret = cros_ec_set_event_mask(dev, EC_CMD_HOST_EVENT_SET_SMI_MASK, mask); + if (ret < 0) + return ret; + + printf("EC: %sabled lid close event\n", enable ? "en" : "dis"); + return 0; +} + UCLASS_DRIVER(cros_ec) = { .id = UCLASS_CROS_EC, .name = "cros_ec", .per_device_auto_alloc_size = sizeof(struct cros_ec_dev), .post_bind = dm_scan_fdt_dev, + .flags = DM_UC_FLAG_ALLOC_PRIV_DMA, }; diff --git a/drivers/misc/cros_ec_sandbox.c b/drivers/misc/cros_ec_sandbox.c index d741554d8a..429f1a9b26 100644 --- a/drivers/misc/cros_ec_sandbox.c +++ b/drivers/misc/cros_ec_sandbox.c @@ -74,7 +74,7 @@ struct ec_keymatrix_entry { * @recovery_req: Keyboard recovery requested */ struct ec_state { - uint8_t vbnv_context[EC_VBNV_BLOCK_SIZE]; + u8 vbnv_context[EC_VBNV_BLOCK_SIZE_V2]; struct fdt_cros_ec ec_config; uint8_t *flash_data; int flash_data_len; diff --git a/drivers/misc/fs_loader.c b/drivers/misc/fs_loader.c index b7bb96a458..baa5f8302a 100644 --- a/drivers/misc/fs_loader.c +++ b/drivers/misc/fs_loader.c @@ -55,11 +55,9 @@ static int select_fs_dev(struct device_platdata *plat) node = ofnode_get_by_phandle(plat->phandlepart.phandle); - int of_offset = ofnode_to_offset(node); - struct udevice *dev; - ret = device_get_global_by_of_offset(of_offset, &dev); + ret = device_get_global_by_ofnode(node, &dev); if (!ret) { struct blk_desc *desc = blk_get_by_device(dev); if (desc) { @@ -190,8 +188,9 @@ static int fw_get_filesystem_firmware(struct device_platdata *plat, ret = fs_read(fw_priv->name, (ulong)map_to_sysmem(firmware->data), fw_priv->offset, firmware->size, &actread); + if (ret) { - debug("Error: %d Failed to read %s from flash %lld != %d.\n", + debug("Error: %d Failed to read %s from flash %lld != %zu.\n", ret, fw_priv->name, actread, firmware->size); } else { ret = actread; diff --git a/drivers/misc/misc_sandbox.c b/drivers/misc/misc_sandbox.c index e4164f76fb..f7c5b2e25f 100644 --- a/drivers/misc/misc_sandbox.c +++ b/drivers/misc/misc_sandbox.c @@ -20,7 +20,7 @@ int misc_sandbox_read(struct udevice *dev, int offset, void *buf, int size) memcpy(buf, priv->mem + offset, size); - return 0; + return size; } int misc_sandbox_write(struct udevice *dev, int offset, const void *buf, @@ -30,7 +30,7 @@ int misc_sandbox_write(struct udevice *dev, int offset, const void *buf, memcpy(priv->mem + offset, buf, size); - return 0; + return size; } int misc_sandbox_ioctl(struct udevice *dev, unsigned long request, void *buf) diff --git a/drivers/misc/rockchip-efuse.c b/drivers/misc/rockchip-efuse.c index 8a213c9e27..2520c6a38e 100644 --- a/drivers/misc/rockchip-efuse.c +++ b/drivers/misc/rockchip-efuse.c @@ -65,7 +65,7 @@ static int dump_efuses(cmd_tbl_t *cmdtp, int flag, } ret = misc_read(dev, 0, &fuses, sizeof(fuses)); - if (ret) { + if (ret < 0) { printf("%s: misc_read failed\n", __func__); return 0; } diff --git a/drivers/misc/stm32mp_fuse.c b/drivers/misc/stm32mp_fuse.c index 2d661351a1..33943a231b 100644 --- a/drivers/misc/stm32mp_fuse.c +++ b/drivers/misc/stm32mp_fuse.c @@ -29,6 +29,9 @@ int fuse_read(u32 bank, u32 word, u32 *val) return ret; ret = misc_read(dev, word * 4 + STM32_BSEC_SHADOW_OFFSET, val, 4); + if (ret < 0) + return ret; + ret = 0; break; default: @@ -54,6 +57,9 @@ int fuse_prog(u32 bank, u32 word, u32 val) return ret; ret = misc_write(dev, word * 4 + STM32_BSEC_OTP_OFFSET, &val, 4); + if (ret < 0) + return ret; + ret = 0; break; default: @@ -78,6 +84,9 @@ int fuse_sense(u32 bank, u32 word, u32 *val) if (ret) return ret; ret = misc_read(dev, word * 4 + STM32_BSEC_OTP_OFFSET, val, 4); + if (ret < 0) + return ret; + ret = 0; break; default: @@ -103,6 +112,9 @@ int fuse_override(u32 bank, u32 word, u32 val) return ret; ret = misc_write(dev, word * 4 + STM32_BSEC_SHADOW_OFFSET, &val, 4); + if (ret < 0) + return ret; + ret = 0; break; default: diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 27246ee465..3f7458d409 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -569,6 +569,10 @@ config MMC_SUNXI_HAS_NEW_MODE bool depends on MMC_SUNXI +config MMC_SUNXI_HAS_MODE_SWITCH + bool + depends on MMC_SUNXI + config GENERIC_ATMEL_MCI bool "Atmel Multimedia Card Interface support" depends on DM_MMC && BLK && ARCH_AT91 diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index 147eb9b4d5..9bf040cb40 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -98,24 +98,21 @@ static int mmc_resource_init(int sdc_no) static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz) { unsigned int pll, pll_hz, div, n, oclk_dly, sclk_dly; - bool new_mode = false; + bool new_mode = true; bool calibrate = false; u32 val = 0; - if (IS_ENABLED(CONFIG_MMC_SUNXI_HAS_NEW_MODE) && (priv->mmc_no == 2)) - new_mode = true; + if (!IS_ENABLED(CONFIG_MMC_SUNXI_HAS_NEW_MODE)) + new_mode = false; + + /* A83T support new mode only on eMMC */ + if (IS_ENABLED(CONFIG_MACH_SUN8I_A83T) && priv->mmc_no != 2) + new_mode = false; #if defined(CONFIG_MACH_SUN50I) || defined(CONFIG_MACH_SUN50I_H6) calibrate = true; #endif - /* - * The MMC clock has an extra /2 post-divider when operating in the new - * mode. - */ - if (new_mode) - hz = hz * 2; - if (hz <= 24000000) { pll = CCM_MMC_CTRL_OSCM24; pll_hz = 24000000; @@ -176,7 +173,9 @@ static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz) if (new_mode) { #ifdef CONFIG_MMC_SUNXI_HAS_NEW_MODE +#ifdef CONFIG_MMC_SUNXI_HAS_MODE_SWITCH val = CCM_MMC_CTRL_MODE_SEL_NEW; +#endif setbits_le32(&priv->reg->ntsr, SUNXI_MMC_NTSR_MODE_SEL_NEW); #endif } else if (!calibrate) { diff --git a/drivers/mtd/nand/raw/lpc32xx_nand_mlc.c b/drivers/mtd/nand/raw/lpc32xx_nand_mlc.c index 5d4ffea608..79d1489dc7 100644 --- a/drivers/mtd/nand/raw/lpc32xx_nand_mlc.c +++ b/drivers/mtd/nand/raw/lpc32xx_nand_mlc.c @@ -82,6 +82,10 @@ struct lpc32xx_nand_mlc_registers { static struct lpc32xx_nand_mlc_registers __iomem *lpc32xx_nand_mlc_registers = (struct lpc32xx_nand_mlc_registers __iomem *)MLC_NAND_BASE; +#if !defined(CONFIG_SYS_MAX_NAND_CHIPS) +#define CONFIG_SYS_MAX_NAND_CHIPS 1 +#endif + #define clkdiv(v, w, o) (((1+(clk/v)) & w) << o) /** diff --git a/drivers/mtd/nand/raw/lpc32xx_nand_slc.c b/drivers/mtd/nand/raw/lpc32xx_nand_slc.c index 99f6e15f4e..8615b112a2 100644 --- a/drivers/mtd/nand/raw/lpc32xx_nand_slc.c +++ b/drivers/mtd/nand/raw/lpc32xx_nand_slc.c @@ -2,13 +2,12 @@ /* * LPC32xx SLC NAND flash controller driver * - * (C) Copyright 2015 Vladimir Zapolskiy <vz@mleia.com> + * (C) Copyright 2015-2018 Vladimir Zapolskiy <vz@mleia.com> + * Copyright (c) 2015 Tyco Fire Protection Products. * * Hardware ECC support original source code * Copyright (C) 2008 by NXP Semiconductors * Author: Kevin Wells - * - * Copyright (c) 2015 Tyco Fire Protection Products. */ #include <common.h> @@ -22,10 +21,6 @@ #include <asm/arch/dma.h> #include <asm/arch/cpu.h> -#if defined(CONFIG_DMA_LPC32XX) && defined(CONFIG_SPL_BUILD) -#warning "DMA support in SPL image is not tested" -#endif - struct lpc32xx_nand_slc_regs { u32 data; u32 addr; @@ -78,16 +73,14 @@ struct lpc32xx_nand_slc_regs { * Note: For large page devices, the default layouts are used. */ static struct nand_ecclayout lpc32xx_nand_oob_16 = { .eccbytes = 6, - .eccpos = {10, 11, 12, 13, 14, 15}, + .eccpos = { 10, 11, 12, 13, 14, 15, }, .oobfree = { - {.offset = 0, - . length = 4}, - {.offset = 6, - . length = 4} - } + { .offset = 0, .length = 4, }, + { .offset = 6, .length = 4, }, + } }; -#if defined(CONFIG_DMA_LPC32XX) +#if defined(CONFIG_DMA_LPC32XX) && !defined(CONFIG_SPL_BUILD) #define ECCSTEPS (CONFIG_SYS_NAND_PAGE_SIZE / CONFIG_SYS_NAND_ECCSIZE) /* @@ -165,7 +158,7 @@ static int lpc32xx_nand_dev_ready(struct mtd_info *mtd) return readl(&lpc32xx_nand_slc_regs->stat) & STAT_NAND_READY; } -#if defined(CONFIG_DMA_LPC32XX) +#if defined(CONFIG_DMA_LPC32XX) && !defined(CONFIG_SPL_BUILD) /* * Prepares DMA descriptors for NAND RD/WR operations * If the size is < 256 Bytes then it is assumed to be @@ -324,7 +317,6 @@ static void lpc32xx_nand_xfer(struct mtd_info *mtd, const u8 *buf, if (unlikely(ret < 0)) BUG(); - /* Wait for NAND to be ready */ while (!lpc32xx_nand_dev_ready(mtd)) ; @@ -404,46 +396,18 @@ int lpc32xx_correct_data(struct mtd_info *mtd, u_char *dat, return ret2; } -#endif -#if defined(CONFIG_DMA_LPC32XX) static void lpc32xx_dma_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) { lpc32xx_nand_xfer(mtd, buf, len, 1); } -#else -static void lpc32xx_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) -{ - while (len-- > 0) - *buf++ = readl(&lpc32xx_nand_slc_regs->data); -} -#endif -static uint8_t lpc32xx_read_byte(struct mtd_info *mtd) -{ - return readl(&lpc32xx_nand_slc_regs->data); -} - -#if defined(CONFIG_DMA_LPC32XX) static void lpc32xx_dma_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) { lpc32xx_nand_xfer(mtd, buf, len, 0); } -#else -static void lpc32xx_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) -{ - while (len-- > 0) - writel(*buf++, &lpc32xx_nand_slc_regs->data); -} -#endif - -static void lpc32xx_write_byte(struct mtd_info *mtd, uint8_t byte) -{ - writel(byte, &lpc32xx_nand_slc_regs->data); -} -#if defined(CONFIG_DMA_LPC32XX) /* Reuse the logic from "nand_read_page_hwecc()" */ static int lpc32xx_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *buf, int oob_required, int page) @@ -511,8 +475,30 @@ static int lpc32xx_write_page_hwecc(struct mtd_info *mtd, return 0; } +#else +static void lpc32xx_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) +{ + while (len-- > 0) + *buf++ = readl(&lpc32xx_nand_slc_regs->data); +} + +static void lpc32xx_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) +{ + while (len-- > 0) + writel(*buf++, &lpc32xx_nand_slc_regs->data); +} #endif +static uint8_t lpc32xx_read_byte(struct mtd_info *mtd) +{ + return readl(&lpc32xx_nand_slc_regs->data); +} + +static void lpc32xx_write_byte(struct mtd_info *mtd, uint8_t byte) +{ + writel(byte, &lpc32xx_nand_slc_regs->data); +} + /* * LPC32xx has only one SLC NAND controller, don't utilize * CONFIG_SYS_NAND_SELF_INIT to be able to reuse this function @@ -520,7 +506,7 @@ static int lpc32xx_write_page_hwecc(struct mtd_info *mtd, */ int board_nand_init(struct nand_chip *lpc32xx_chip) { -#if defined(CONFIG_DMA_LPC32XX) +#if defined(CONFIG_DMA_LPC32XX) && !defined(CONFIG_SPL_BUILD) int ret; /* Acquire a channel for our use */ @@ -543,7 +529,7 @@ int board_nand_init(struct nand_chip *lpc32xx_chip) lpc32xx_chip->read_byte = lpc32xx_read_byte; lpc32xx_chip->write_byte = lpc32xx_write_byte; -#if defined(CONFIG_DMA_LPC32XX) +#if defined(CONFIG_DMA_LPC32XX) && !defined(CONFIG_SPL_BUILD) /* Hardware ECC calculation is supported when DMA driver is selected */ lpc32xx_chip->ecc.mode = NAND_ECC_HW; diff --git a/drivers/mtd/spi/sandbox.c b/drivers/mtd/spi/sandbox.c index 7fef754c63..7b9891cb98 100644 --- a/drivers/mtd/spi/sandbox.c +++ b/drivers/mtd/spi/sandbox.c @@ -57,6 +57,8 @@ static const char *sandbox_sf_state_name(enum sandbox_sf_state state) /* Bits for the status register */ #define STAT_WIP (1 << 0) #define STAT_WEL (1 << 1) +#define STAT_BP_SHIFT 2 +#define STAT_BP_MASK (7 << STAT_BP_SHIFT) /* Assume all SPI flashes have 3 byte addresses since they do atm */ #define SF_ADDR_LEN 3 @@ -102,6 +104,14 @@ struct sandbox_spi_flash_plat_data { int cs; }; +void sandbox_sf_set_block_protect(struct udevice *dev, int bp_mask) +{ + struct sandbox_spi_flash *sbsf = dev_get_priv(dev); + + sbsf->status &= ~STAT_BP_MASK; + sbsf->status |= bp_mask << STAT_BP_SHIFT; +} + /** * This is a very strange probe function. If it has platform data (which may * have come from the device tree) then this function gets the filename and diff --git a/drivers/mtd/spi/sf-uclass.c b/drivers/mtd/spi/sf-uclass.c index 662525f016..719a2fd23a 100644 --- a/drivers/mtd/spi/sf-uclass.c +++ b/drivers/mtd/spi/sf-uclass.c @@ -28,6 +28,15 @@ int spi_flash_erase_dm(struct udevice *dev, u32 offset, size_t len) return log_ret(sf_get_ops(dev)->erase(dev, offset, len)); } +int spl_flash_get_sw_write_prot(struct udevice *dev) +{ + struct dm_spi_flash_ops *ops = sf_get_ops(dev); + + if (!ops->get_sw_write_prot) + return -ENOSYS; + return log_ret(ops->get_sw_write_prot(dev)); +} + /* * TODO(sjg@chromium.org): This is an old-style function. We should remove * it when all SPI flash drivers use dm diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h index 26f5c7c995..46a5044417 100644 --- a/drivers/mtd/spi/sf_internal.h +++ b/drivers/mtd/spi/sf_internal.h @@ -170,6 +170,9 @@ int spi_flash_cmd_write(struct spi_slave *spi, const u8 *cmd, size_t cmd_len, /* Flash erase(sectors) operation, support all possible erase commands */ int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len); +/* Get software write-protect value (BP bits) */ +int spi_flash_cmd_get_sw_write_prot(struct spi_flash *flash); + /* Lock stmicro spi flash region */ int stm_lock(struct spi_flash *flash, u32 ofs, size_t len); diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index 94fde2ae7a..5a2e932de8 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -124,6 +124,13 @@ static int spi_flash_std_erase(struct udevice *dev, u32 offset, size_t len) return spi_flash_cmd_erase_ops(flash, offset, len); } +static int spi_flash_std_get_sw_write_prot(struct udevice *dev) +{ + struct spi_flash *flash = dev_get_uclass_priv(dev); + + return spi_flash_cmd_get_sw_write_prot(flash); +} + static int spi_flash_std_probe(struct udevice *dev) { struct spi_slave *slave = dev_get_parent_priv(dev); @@ -141,6 +148,7 @@ static const struct dm_spi_flash_ops spi_flash_std_ops = { .read = spi_flash_std_read, .write = spi_flash_std_write, .erase = spi_flash_std_erase, + .get_sw_write_prot = spi_flash_std_get_sw_write_prot, }; static const struct udevice_id spi_flash_std_ids[] = { diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c index a87bacd4ac..0c2392f28a 100644 --- a/drivers/mtd/spi/spi_flash.c +++ b/drivers/mtd/spi/spi_flash.c @@ -110,6 +110,18 @@ static int write_cr(struct spi_flash *flash, u8 wc) } #endif +int spi_flash_cmd_get_sw_write_prot(struct spi_flash *flash) +{ + u8 status; + int ret; + + ret = read_sr(flash, &status); + if (ret) + return ret; + + return (status >> 2) & 7; +} + #ifdef CONFIG_SPI_FLASH_BAR /* * This "clean_bar" is necessary in a situation when one was accessing diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c index 3ba3a1ff8b..c9798445c7 100644 --- a/drivers/net/sun8i_emac.c +++ b/drivers/net/sun8i_emac.c @@ -60,6 +60,10 @@ #define SC_ETCS_MASK GENMASK(1, 0) #define SC_ETCS_EXT_GMII 0x1 #define SC_ETCS_INT_GMII 0x2 +#define SC_ETXDC_MASK GENMASK(12, 10) +#define SC_ETXDC_OFFSET 10 +#define SC_ERXDC_MASK GENMASK(9, 5) +#define SC_ERXDC_OFFSET 5 #define CONFIG_MDIO_TIMEOUT (3 * CONFIG_SYS_HZ) @@ -140,6 +144,8 @@ struct emac_eth_dev { struct sun8i_eth_pdata { struct eth_pdata eth_pdata; u32 reset_delays[3]; + int tx_delay_ps; + int rx_delay_ps; }; @@ -273,7 +279,8 @@ static int sun8i_emac_set_syscon_ephy(struct emac_eth_dev *priv, u32 *reg) return 0; } -static int sun8i_emac_set_syscon(struct emac_eth_dev *priv) +static int sun8i_emac_set_syscon(struct sun8i_eth_pdata *pdata, + struct emac_eth_dev *priv) { int ret; u32 reg; @@ -312,6 +319,14 @@ static int sun8i_emac_set_syscon(struct emac_eth_dev *priv) return -EINVAL; } + if (pdata->tx_delay_ps) + reg |= ((pdata->tx_delay_ps / 100) << SC_ETXDC_OFFSET) + & SC_ETXDC_MASK; + + if (pdata->rx_delay_ps) + reg |= ((pdata->rx_delay_ps / 100) << SC_ERXDC_OFFSET) + & SC_ERXDC_MASK; + writel(reg, priv->sysctl_reg + 0x30); return 0; @@ -784,13 +799,14 @@ static void sun8i_emac_eth_stop(struct udevice *dev) static int sun8i_emac_eth_probe(struct udevice *dev) { - struct eth_pdata *pdata = dev_get_platdata(dev); + struct sun8i_eth_pdata *sun8i_pdata = dev_get_platdata(dev); + struct eth_pdata *pdata = &sun8i_pdata->eth_pdata; struct emac_eth_dev *priv = dev_get_priv(dev); priv->mac_reg = (void *)pdata->iobase; sun8i_emac_board_setup(priv); - sun8i_emac_set_syscon(priv); + sun8i_emac_set_syscon(sun8i_pdata, priv); sun8i_mdio_init(dev->name, dev); priv->bus = miiphy_get_dev_by_name(dev->name); @@ -891,6 +907,18 @@ static int sun8i_emac_eth_ofdata_to_platdata(struct udevice *dev) if (!priv->use_internal_phy) parse_phy_pins(dev); + sun8i_pdata->tx_delay_ps = fdtdec_get_int(gd->fdt_blob, node, + "allwinner,tx-delay-ps", 0); + if (sun8i_pdata->tx_delay_ps < 0 || sun8i_pdata->tx_delay_ps > 700) + printf("%s: Invalid TX delay value %d\n", __func__, + sun8i_pdata->tx_delay_ps); + + sun8i_pdata->rx_delay_ps = fdtdec_get_int(gd->fdt_blob, node, + "allwinner,rx-delay-ps", 0); + if (sun8i_pdata->rx_delay_ps < 0 || sun8i_pdata->rx_delay_ps > 3100) + printf("%s: Invalid RX delay value %d\n", __func__, + sun8i_pdata->rx_delay_ps); + #ifdef CONFIG_DM_GPIO if (fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev), "snps,reset-active-low")) diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index 0c52337f33..2cf55cb743 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -774,16 +774,19 @@ int pci_bind_bus_devices(struct udevice *bus) found_multi = false; if (PCI_FUNC(bdf) && !found_multi) continue; + /* Check only the first access, we don't expect problems */ - ret = pci_bus_read_config(bus, bdf, PCI_HEADER_TYPE, - &header_type, PCI_SIZE_8); + ret = pci_bus_read_config(bus, bdf, PCI_VENDOR_ID, &vendor, + PCI_SIZE_16); if (ret) goto error; - pci_bus_read_config(bus, bdf, PCI_VENDOR_ID, &vendor, - PCI_SIZE_16); + if (vendor == 0xffff || vendor == 0x0000) continue; + pci_bus_read_config(bus, bdf, PCI_HEADER_TYPE, + &header_type, PCI_SIZE_8); + if (!PCI_FUNC(bdf)) found_multi = header_type & 0x80; diff --git a/drivers/pinctrl/pinctrl-sandbox.c b/drivers/pinctrl/pinctrl-sandbox.c index 755ac08bdf..0786afe747 100644 --- a/drivers/pinctrl/pinctrl-sandbox.c +++ b/drivers/pinctrl/pinctrl-sandbox.c @@ -17,6 +17,14 @@ static const char * const sandbox_pins[] = { "W1" }; +static const char * const sandbox_pins_muxing[] = { + "I2C SCL", + "I2C SDA", + "Uart TX", + "Uart RX", + "1-wire gpio", +}; + static const char * const sandbox_groups[] = { "i2c", "serial_a", @@ -56,6 +64,15 @@ static const char *sandbox_get_pin_name(struct udevice *dev, unsigned selector) return sandbox_pins[selector]; } +static int sandbox_get_pin_muxing(struct udevice *dev, + unsigned int selector, + char *buf, int size) +{ + snprintf(buf, size, "%s", sandbox_pins_muxing[selector]); + + return 0; +} + static int sandbox_get_groups_count(struct udevice *dev) { return ARRAY_SIZE(sandbox_groups); @@ -123,6 +140,7 @@ static int sandbox_pinconf_group_set(struct udevice *dev, const struct pinctrl_ops sandbox_pinctrl_ops = { .get_pins_count = sandbox_get_pins_count, .get_pin_name = sandbox_get_pin_name, + .get_pin_muxing = sandbox_get_pin_muxing, .get_groups_count = sandbox_get_groups_count, .get_group_name = sandbox_get_group_name, .get_functions_count = sandbox_get_functions_count, diff --git a/drivers/pinctrl/pinctrl-uclass.c b/drivers/pinctrl/pinctrl-uclass.c index c38bb212ed..6db0445067 100644 --- a/drivers/pinctrl/pinctrl-uclass.c +++ b/drivers/pinctrl/pinctrl-uclass.c @@ -249,6 +249,40 @@ int pinctrl_get_gpio_mux(struct udevice *dev, int banknum, int index) return ops->get_gpio_mux(dev, banknum, index); } +int pinctrl_get_pins_count(struct udevice *dev) +{ + struct pinctrl_ops *ops = pinctrl_get_ops(dev); + + if (!ops->get_pins_count) + return -ENOSYS; + + return ops->get_pins_count(dev); +} + +int pinctrl_get_pin_name(struct udevice *dev, int selector, char *buf, + int size) +{ + struct pinctrl_ops *ops = pinctrl_get_ops(dev); + + if (!ops->get_pin_name) + return -ENOSYS; + + snprintf(buf, size, ops->get_pin_name(dev, selector)); + + return 0; +} + +int pinctrl_get_pin_muxing(struct udevice *dev, int selector, char *buf, + int size) +{ + struct pinctrl_ops *ops = pinctrl_get_ops(dev); + + if (!ops->get_pin_muxing) + return -ENOSYS; + + return ops->get_pin_muxing(dev, selector, buf, size); +} + /** * pinconfig_post_bind() - post binding for PINCTRL uclass * Recursively bind child nodes as pinconfig devices in case of full pinctrl. diff --git a/drivers/pinctrl/pinctrl_stm32.c b/drivers/pinctrl/pinctrl_stm32.c index 31285cdd57..6d4117d941 100644 --- a/drivers/pinctrl/pinctrl_stm32.c +++ b/drivers/pinctrl/pinctrl_stm32.c @@ -14,6 +14,194 @@ DECLARE_GLOBAL_DATA_PTR; #define OTYPE_MSK 1 #define AFR_MASK 0xF +#ifndef CONFIG_SPL_BUILD +struct stm32_pinctrl_priv { + int pinctrl_ngpios; + struct list_head gpio_dev; +}; + +struct stm32_gpio_bank { + struct udevice *gpio_dev; + struct list_head list; +}; + +#define MAX_PIN_PER_BANK 16 + +static char pin_name[PINNAME_SIZE]; +#define PINMUX_MODE_COUNT 5 +static const char * const pinmux_mode[PINMUX_MODE_COUNT] = { + "gpio input", + "gpio output", + "analog", + "unknown", + "alt function", +}; + +static int stm32_pinctrl_get_af(struct udevice *dev, unsigned int offset) +{ + struct stm32_gpio_priv *priv = dev_get_priv(dev); + struct stm32_gpio_regs *regs = priv->regs; + u32 af; + u32 alt_shift = (offset % 8) * 4; + u32 alt_index = offset / 8; + + af = (readl(®s->afr[alt_index]) & + GENMASK(alt_shift + 3, alt_shift)) >> alt_shift; + + return af; +} + +static int stm32_pinctrl_get_pins_count(struct udevice *dev) +{ + struct stm32_pinctrl_priv *priv = dev_get_priv(dev); + struct gpio_dev_priv *uc_priv; + struct stm32_gpio_bank *gpio_bank; + + /* + * if get_pins_count has already been executed once on this + * pin-controller, no need to run it again + */ + if (priv->pinctrl_ngpios) + return priv->pinctrl_ngpios; + + /* + * walk through all banks to retrieve the pin-controller + * pins number + */ + list_for_each_entry(gpio_bank, &priv->gpio_dev, list) { + uc_priv = dev_get_uclass_priv(gpio_bank->gpio_dev); + + priv->pinctrl_ngpios += uc_priv->gpio_count; + } + + return priv->pinctrl_ngpios; +} + +static struct udevice *stm32_pinctrl_get_gpio_dev(struct udevice *dev, + unsigned int selector) +{ + struct stm32_pinctrl_priv *priv = dev_get_priv(dev); + struct stm32_gpio_bank *gpio_bank; + struct gpio_dev_priv *uc_priv; + int first_pin = 0; + + /* look up for the bank which owns the requested pin */ + list_for_each_entry(gpio_bank, &priv->gpio_dev, list) { + uc_priv = dev_get_uclass_priv(gpio_bank->gpio_dev); + + if (selector < (first_pin + uc_priv->gpio_count)) + /* we found the bank */ + return gpio_bank->gpio_dev; + + first_pin += uc_priv->gpio_count; + } + + return NULL; +} + +static const char *stm32_pinctrl_get_pin_name(struct udevice *dev, + unsigned int selector) +{ + struct gpio_dev_priv *uc_priv; + struct udevice *gpio_dev; + + /* look up for the bank which owns the requested pin */ + gpio_dev = stm32_pinctrl_get_gpio_dev(dev, selector); + if (!gpio_dev) { + snprintf(pin_name, PINNAME_SIZE, "Error"); + } else { + uc_priv = dev_get_uclass_priv(gpio_dev); + + snprintf(pin_name, PINNAME_SIZE, "%s%d", + uc_priv->bank_name, + selector % MAX_PIN_PER_BANK); + } + + return pin_name; +} + +static int stm32_pinctrl_get_pin_muxing(struct udevice *dev, + unsigned int selector, + char *buf, + int size) +{ + struct udevice *gpio_dev; + const char *label; + int gpio_pin; + int mode; + int af_num; + + /* look up for the bank which owns the requested pin */ + gpio_dev = stm32_pinctrl_get_gpio_dev(dev, selector); + + if (!gpio_dev) + return -ENODEV; + + /* translate pin-controller pin number to gpio pin number */ + gpio_pin = selector % MAX_PIN_PER_BANK; + + mode = gpio_get_raw_function(gpio_dev, gpio_pin, &label); + + dev_dbg(dev, "selector = %d gpio_pin = %d mode = %d\n", + selector, gpio_pin, mode); + + switch (mode) { + case GPIOF_UNKNOWN: + /* should never happen */ + return -EINVAL; + case GPIOF_UNUSED: + snprintf(buf, size, "%s", pinmux_mode[mode]); + break; + case GPIOF_FUNC: + af_num = stm32_pinctrl_get_af(gpio_dev, gpio_pin); + snprintf(buf, size, "%s %d", pinmux_mode[mode], af_num); + break; + case GPIOF_OUTPUT: + case GPIOF_INPUT: + snprintf(buf, size, "%s %s", + pinmux_mode[mode], label ? label : ""); + break; + } + + return 0; +} + +int stm32_pinctrl_probe(struct udevice *dev) +{ + struct stm32_pinctrl_priv *priv = dev_get_priv(dev); + struct udevice *gpio_dev; + struct udevice *child; + struct stm32_gpio_bank *gpio_bank; + int ret; + + INIT_LIST_HEAD(&priv->gpio_dev); + + /* + * parse pin-controller sub-nodes (ie gpio bank nodes) and fill + * a list with all gpio device reference which belongs to the + * current pin-controller. This list is used to find pin_name and + * pin muxing + */ + list_for_each_entry(child, &dev->child_head, sibling_node) { + ret = uclass_get_device_by_name(UCLASS_GPIO, child->name, + &gpio_dev); + if (ret < 0) + continue; + + gpio_bank = malloc(sizeof(*gpio_bank)); + if (!gpio_bank) { + dev_err(dev, "Not enough memory\n"); + return -ENOMEM; + } + + gpio_bank->gpio_dev = gpio_dev; + list_add_tail(&gpio_bank->list, &priv->gpio_dev); + } + + return 0; +} +#endif + static int stm32_gpio_config(struct gpio_desc *desc, const struct stm32_gpio_ctl *ctl) { @@ -182,6 +370,11 @@ static struct pinctrl_ops stm32_pinctrl_ops = { #else /* PINCTRL_FULL */ .set_state_simple = stm32_pinctrl_set_state_simple, #endif /* PINCTRL_FULL */ +#ifndef CONFIG_SPL_BUILD + .get_pin_name = stm32_pinctrl_get_pin_name, + .get_pins_count = stm32_pinctrl_get_pins_count, + .get_pin_muxing = stm32_pinctrl_get_pin_muxing, +#endif }; static const struct udevice_id stm32_pinctrl_ids[] = { @@ -195,9 +388,13 @@ static const struct udevice_id stm32_pinctrl_ids[] = { }; U_BOOT_DRIVER(pinctrl_stm32) = { - .name = "pinctrl_stm32", - .id = UCLASS_PINCTRL, - .of_match = stm32_pinctrl_ids, - .ops = &stm32_pinctrl_ops, - .bind = dm_scan_fdt_dev, + .name = "pinctrl_stm32", + .id = UCLASS_PINCTRL, + .of_match = stm32_pinctrl_ids, + .ops = &stm32_pinctrl_ops, + .bind = dm_scan_fdt_dev, +#ifndef CONFIG_SPL_BUILD + .probe = stm32_pinctrl_probe, + .priv_auto_alloc_size = sizeof(struct stm32_pinctrl_priv), +#endif }; diff --git a/drivers/ram/Kconfig b/drivers/ram/Kconfig index 54bb4b419f..fbf7d7b20f 100644 --- a/drivers/ram/Kconfig +++ b/drivers/ram/Kconfig @@ -43,4 +43,15 @@ config MPC83XX_SDRAM the RAM through the use of SPD (Serial Presence Detect) is supported via device tree settings. +config K3_AM654_DDRSS + bool "Enable AM654 DDRSS support" + depends on RAM && SOC_K3_AM6 + help + K3 based AM654 devices has DDR memory subsystem that comprises + Synopys DDR controller, Synopsis DDR phy and wrapper logic to + intergrate these blocks into the device. This DDR subsystem + provides an interface to external SDRAM devices. Enabling this + config add support for the initialization of the external + SDRAM devices connected to DDR subsystem. + source "drivers/ram/stm32mp1/Kconfig" diff --git a/drivers/ram/Makefile b/drivers/ram/Makefile index cfba57f0fd..e14c1cf592 100644 --- a/drivers/ram/Makefile +++ b/drivers/ram/Makefile @@ -11,3 +11,5 @@ obj-$(CONFIG_STM32_SDRAM) += stm32_sdram.o obj-$(CONFIG_ARCH_BMIPS) += bmips_ram.o obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ + +obj-$(CONFIG_K3_AM654_DDRSS) += k3-am654-ddrss.o diff --git a/drivers/ram/k3-am654-ddrss.c b/drivers/ram/k3-am654-ddrss.c new file mode 100644 index 0000000000..7957f678a1 --- /dev/null +++ b/drivers/ram/k3-am654-ddrss.c @@ -0,0 +1,825 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Texas Instruments' AM654 DDRSS driver + * + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ + * Lokesh Vutla <lokeshvutla@ti.com> + */ + +#include <common.h> +#include <clk.h> +#include <dm.h> +#include <ram.h> +#include <asm/io.h> +#include <power-domain.h> +#include <dm.h> +#include <asm/arch/sys_proto.h> +#include <power/regulator.h> +#include "k3-am654-ddrss.h" + +#define LDELAY 10000 + +/* DDRSS PHY configuration register fixed values */ +#define DDRSS_DDRPHY_RANKIDR_RANK0 0 + +/** + * struct am654_ddrss_desc - Description of ddrss integration. + * @dev: DDRSS device pointer + * @ddrss_ss_cfg: DDRSS wrapper logic region base address + * @ddrss_ctl_cfg: DDRSS controller region base address + * @ddrss_phy_cfg: DDRSS PHY region base address + * @ddrss_clk: DDRSS clock description + * @vtt_supply: VTT Supply regulator + * @ddrss_pwrdmn: DDRSS power domain description + * @params: SDRAM configuration parameters + */ +struct am654_ddrss_desc { + struct udevice *dev; + void __iomem *ddrss_ss_cfg; + void __iomem *ddrss_ctl_cfg; + void __iomem *ddrss_phy_cfg; + struct clk ddrss_clk; + struct udevice *vtt_supply; + struct power_domain ddrcfg_pwrdmn; + struct power_domain ddrdata_pwrdmn; + struct ddrss_params params; +}; + +static inline u32 ddrss_readl(void __iomem *addr, unsigned int offset) +{ + return readl(addr + offset); +} + +static inline void ddrss_writel(void __iomem *addr, unsigned int offset, + u32 data) +{ + debug("%s: addr = 0x%p, value = 0x%x\n", __func__, addr + offset, data); + writel(data, addr + offset); +} + +#define ddrss_ctl_writel(off, val) ddrss_writel(ddrss->ddrss_ctl_cfg, off, val) +#define ddrss_ctl_readl(off) ddrss_readl(ddrss->ddrss_ctl_cfg, off) + +static inline u32 am654_ddrss_get_type(struct am654_ddrss_desc *ddrss) +{ + return ddrss_ctl_readl(DDRSS_DDRCTL_MSTR) & MSTR_DDR_TYPE_MASK; +} + +/** + * am654_ddrss_dram_wait_for_init_complete() - Wait for init to complete + * + * After detecting the DDR type this function will pause until the + * initialization is complete. Each DDR type has mask of multiple bits. + * The size of the field depends on the DDR Type. If the initialization + * does not complete and error will be returned and will cause the boot to halt. + * + */ +static int am654_ddrss_dram_wait_for_init_complt(struct am654_ddrss_desc *ddrss) +{ + u32 val, mask; + + val = am654_ddrss_get_type(ddrss); + + switch (val) { + case DDR_TYPE_LPDDR4: + case DDR_TYPE_DDR4: + mask = DDR4_STAT_MODE_MASK; + break; + case DDR_TYPE_DDR3: + mask = DDR3_STAT_MODE_MASK; + break; + default: + printf("Unsupported DDR type 0x%x\n", val); + return -EINVAL; + } + + if (!wait_on_value(mask, DDR_MODE_NORMAL, + ddrss->ddrss_ctl_cfg + DDRSS_DDRCTL_STAT, LDELAY)) + return -ETIMEDOUT; + + return 0; +} + +/** + * am654_ddrss_ctrl_configuration() - Configure Controller specific registers + * @dev: corresponding ddrss device + */ +static void am654_ddrss_ctrl_configuration(struct am654_ddrss_desc *ddrss) +{ + struct ddrss_ddrctl_timing_params *tmg = &ddrss->params.ctl_timing; + struct ddrss_ddrctl_reg_params *reg = &ddrss->params.ctl_reg; + struct ddrss_ddrctl_ecc_params *ecc = &ddrss->params.ctl_ecc; + struct ddrss_ddrctl_crc_params *crc = &ddrss->params.ctl_crc; + struct ddrss_ddrctl_map_params *map = &ddrss->params.ctl_map; + u32 val; + + debug("%s: DDR controller register configuration started\n", __func__); + + ddrss_ctl_writel(DDRSS_DDRCTL_MSTR, reg->ddrctl_mstr); + ddrss_ctl_writel(DDRSS_DDRCTL_RFSHCTL0, reg->ddrctl_rfshctl0); + ddrss_ctl_writel(DDRSS_DDRCTL_RFSHTMG, reg->ddrctl_rfshtmg); + + ddrss_ctl_writel(DDRSS_DDRCTL_ECCCFG0, ecc->ddrctl_ecccfg0); + ddrss_ctl_writel(DDRSS_DDRCTL_CRCPARCTL0, crc->ddrctl_crcparctl0); + ddrss_ctl_writel(DDRSS_DDRCTL_CRCPARCTL1, crc->ddrctl_crcparctl1); + ddrss_ctl_writel(DDRSS_DDRCTL_CRCPARCTL2, crc->ddrctl_crcparctl2); + + ddrss_ctl_writel(DDRSS_DDRCTL_INIT0, reg->ddrctl_init0); + ddrss_ctl_writel(DDRSS_DDRCTL_INIT1, reg->ddrctl_init1); + ddrss_ctl_writel(DDRSS_DDRCTL_INIT3, reg->ddrctl_init3); + ddrss_ctl_writel(DDRSS_DDRCTL_INIT4, reg->ddrctl_init4); + ddrss_ctl_writel(DDRSS_DDRCTL_INIT5, reg->ddrctl_init5); + ddrss_ctl_writel(DDRSS_DDRCTL_INIT6, reg->ddrctl_init6); + ddrss_ctl_writel(DDRSS_DDRCTL_INIT7, reg->ddrctl_init7); + + ddrss_ctl_writel(DDRSS_DDRCTL_DRAMTMG0, tmg->ddrctl_dramtmg0); + ddrss_ctl_writel(DDRSS_DDRCTL_DRAMTMG1, tmg->ddrctl_dramtmg1); + ddrss_ctl_writel(DDRSS_DDRCTL_DRAMTMG2, tmg->ddrctl_dramtmg2); + ddrss_ctl_writel(DDRSS_DDRCTL_DRAMTMG3, tmg->ddrctl_dramtmg3); + ddrss_ctl_writel(DDRSS_DDRCTL_DRAMTMG4, tmg->ddrctl_dramtmg4); + ddrss_ctl_writel(DDRSS_DDRCTL_DRAMTMG5, tmg->ddrctl_dramtmg5); + ddrss_ctl_writel(DDRSS_DDRCTL_DRAMTMG8, tmg->ddrctl_dramtmg8); + ddrss_ctl_writel(DDRSS_DDRCTL_DRAMTMG9, tmg->ddrctl_dramtmg9); + ddrss_ctl_writel(DDRSS_DDRCTL_DRAMTMG11, tmg->ddrctl_dramtmg11); + ddrss_ctl_writel(DDRSS_DDRCTL_DRAMTMG12, tmg->ddrctl_dramtmg12); + ddrss_ctl_writel(DDRSS_DDRCTL_DRAMTMG13, tmg->ddrctl_dramtmg13); + ddrss_ctl_writel(DDRSS_DDRCTL_DRAMTMG15, tmg->ddrctl_dramtmg15); + ddrss_ctl_writel(DDRSS_DDRCTL_DRAMTMG17, tmg->ddrctl_dramtmg17); + + ddrss_ctl_writel(DDRSS_DDRCTL_ZQCTL0, reg->ddrctl_zqctl0); + ddrss_ctl_writel(DDRSS_DDRCTL_ZQCTL1, reg->ddrctl_zqctl1); + + ddrss_ctl_writel(DDRSS_DDRCTL_DFITMG0, reg->ddrctl_dfitmg0); + ddrss_ctl_writel(DDRSS_DDRCTL_DFITMG1, reg->ddrctl_dfitmg1); + ddrss_ctl_writel(DDRSS_DDRCTL_DFITMG2, reg->ddrctl_dfitmg2); + + ddrss_ctl_writel(DDRSS_DDRCTL_ADDRMAP0, map->ddrctl_addrmap0); + ddrss_ctl_writel(DDRSS_DDRCTL_ADDRMAP1, map->ddrctl_addrmap1); + ddrss_ctl_writel(DDRSS_DDRCTL_ADDRMAP2, map->ddrctl_addrmap2); + ddrss_ctl_writel(DDRSS_DDRCTL_ADDRMAP3, map->ddrctl_addrmap3); + ddrss_ctl_writel(DDRSS_DDRCTL_ADDRMAP4, map->ddrctl_addrmap4); + ddrss_ctl_writel(DDRSS_DDRCTL_ADDRMAP5, map->ddrctl_addrmap5); + ddrss_ctl_writel(DDRSS_DDRCTL_ADDRMAP6, map->ddrctl_addrmap6); + ddrss_ctl_writel(DDRSS_DDRCTL_ADDRMAP7, map->ddrctl_addrmap7); + ddrss_ctl_writel(DDRSS_DDRCTL_ADDRMAP8, map->ddrctl_addrmap8); + ddrss_ctl_writel(DDRSS_DDRCTL_ADDRMAP9, map->ddrctl_addrmap9); + ddrss_ctl_writel(DDRSS_DDRCTL_ADDRMAP10, map->ddrctl_addrmap10); + ddrss_ctl_writel(DDRSS_DDRCTL_ADDRMAP11, map->ddrctl_addrmap11); + + ddrss_ctl_writel(DDRSS_DDRCTL_ODTCFG, reg->ddrctl_odtcfg); + ddrss_ctl_writel(DDRSS_DDRCTL_ODTMAP, reg->ddrctl_odtmap); + + /* Disable refreshes */ + val = ddrss_ctl_readl(DDRSS_DDRCTL_RFSHCTL3); + val |= 0x01; + ddrss_ctl_writel(DDRSS_DDRCTL_RFSHCTL3, val); + + debug("%s: DDR controller configuration completed\n", __func__); +} + +#define ddrss_phy_writel(off, val) \ + do { \ + ddrss_writel(ddrss->ddrss_phy_cfg, off, val); \ + sdelay(10); /* Delay at least 20 clock cycles */ \ + } while (0) + +#define ddrss_phy_readl(off) \ + ({ \ + u32 val = ddrss_readl(ddrss->ddrss_phy_cfg, off); \ + sdelay(10); /* Delay at least 20 clock cycles */ \ + val; \ + }) + +/** + * am654_ddrss_phy_configuration() - Configure PHY specific registers + * @ddrss: corresponding ddrss device + */ +static void am654_ddrss_phy_configuration(struct am654_ddrss_desc *ddrss) +{ + struct ddrss_ddrphy_ioctl_params *ioctl = &ddrss->params.phy_ioctl; + struct ddrss_ddrphy_timing_params *tmg = &ddrss->params.phy_timing; + struct ddrss_ddrphy_ctrl_params *ctrl = &ddrss->params.phy_ctrl; + struct ddrss_ddrphy_cfg_params *cfg = &ddrss->params.phy_cfg; + struct ddrss_ddrphy_zq_params *zq = &ddrss->params.phy_zq; + + debug("%s: DDR phy register configuration started\n", __func__); + + ddrss_phy_writel(DDRSS_DDRPHY_PGCR1, cfg->ddrphy_pgcr1); + ddrss_phy_writel(DDRSS_DDRPHY_PGCR2, cfg->ddrphy_pgcr2); + ddrss_phy_writel(DDRSS_DDRPHY_PGCR3, cfg->ddrphy_pgcr3); + ddrss_phy_writel(DDRSS_DDRPHY_PGCR6, cfg->ddrphy_pgcr6); + + ddrss_phy_writel(DDRSS_DDRPHY_PTR3, tmg->ddrphy_ptr3); + ddrss_phy_writel(DDRSS_DDRPHY_PTR4, tmg->ddrphy_ptr4); + ddrss_phy_writel(DDRSS_DDRPHY_PTR5, tmg->ddrphy_ptr5); + ddrss_phy_writel(DDRSS_DDRPHY_PTR6, tmg->ddrphy_ptr6); + + ddrss_phy_writel(DDRSS_DDRPHY_PLLCR0, ctrl->ddrphy_pllcr0); + + ddrss_phy_writel(DDRSS_DDRPHY_DXCCR, cfg->ddrphy_dxccr); + ddrss_phy_writel(DDRSS_DDRPHY_DSGCR, cfg->ddrphy_dsgcr); + + ddrss_phy_writel(DDRSS_DDRPHY_DCR, cfg->ddrphy_dcr); + + ddrss_phy_writel(DDRSS_DDRPHY_DTPR0, tmg->ddrphy_dtpr0); + ddrss_phy_writel(DDRSS_DDRPHY_DTPR1, tmg->ddrphy_dtpr1); + ddrss_phy_writel(DDRSS_DDRPHY_DTPR2, tmg->ddrphy_dtpr2); + ddrss_phy_writel(DDRSS_DDRPHY_DTPR3, tmg->ddrphy_dtpr3); + ddrss_phy_writel(DDRSS_DDRPHY_DTPR4, tmg->ddrphy_dtpr4); + ddrss_phy_writel(DDRSS_DDRPHY_DTPR5, tmg->ddrphy_dtpr5); + ddrss_phy_writel(DDRSS_DDRPHY_DTPR6, tmg->ddrphy_dtpr6); + + ddrss_phy_writel(DDRSS_DDRPHY_ZQCR, zq->ddrphy_zqcr); + ddrss_phy_writel(DDRSS_DDRPHY_ZQ0PR0, zq->ddrphy_zq0pr0); + ddrss_phy_writel(DDRSS_DDRPHY_ZQ1PR0, zq->ddrphy_zq1pr0); + + ddrss_phy_writel(DDRSS_DDRPHY_MR0, ctrl->ddrphy_mr0); + ddrss_phy_writel(DDRSS_DDRPHY_MR1, ctrl->ddrphy_mr1); + ddrss_phy_writel(DDRSS_DDRPHY_MR2, ctrl->ddrphy_mr2); + ddrss_phy_writel(DDRSS_DDRPHY_MR3, ctrl->ddrphy_mr3); + ddrss_phy_writel(DDRSS_DDRPHY_MR4, ctrl->ddrphy_mr4); + ddrss_phy_writel(DDRSS_DDRPHY_MR5, ctrl->ddrphy_mr5); + ddrss_phy_writel(DDRSS_DDRPHY_MR6, ctrl->ddrphy_mr6); + + ddrss_phy_writel(DDRSS_DDRPHY_VTCR0, ctrl->ddrphy_vtcr0); + + ddrss_phy_writel(DDRSS_DDRPHY_DX8SL0PLLCR0, cfg->ddrphy_dx8sl0pllcr0); + ddrss_phy_writel(DDRSS_DDRPHY_DX8SL1PLLCR0, cfg->ddrphy_dx8sl1pllcr0); + ddrss_phy_writel(DDRSS_DDRPHY_DX8SL2PLLCR0, cfg->ddrphy_dx8sl2pllcr0); + + ddrss_phy_writel(DDRSS_DDRPHY_DTCR0, ctrl->ddrphy_dtcr0); + ddrss_phy_writel(DDRSS_DDRPHY_DTCR1, ctrl->ddrphy_dtcr1); + + ddrss_phy_writel(DDRSS_DDRPHY_ACIOCR5, ioctl->ddrphy_aciocr5); + ddrss_phy_writel(DDRSS_DDRPHY_IOVCR0, ioctl->ddrphy_iovcr0); + + ddrss_phy_writel(DDRSS_DDRPHY_DX4GCR0, cfg->ddrphy_dx4gcr0); + ddrss_phy_writel(DDRSS_DDRPHY_DX4GCR1, cfg->ddrphy_dx4gcr1); + ddrss_phy_writel(DDRSS_DDRPHY_DX4GCR2, cfg->ddrphy_dx4gcr2); + ddrss_phy_writel(DDRSS_DDRPHY_DX4GCR3, cfg->ddrphy_dx4gcr3); + + ddrss_phy_writel(DDRSS_DDRPHY_DX0GCR4, cfg->ddrphy_dx0gcr4); + ddrss_phy_writel(DDRSS_DDRPHY_DX1GCR4, cfg->ddrphy_dx1gcr4); + ddrss_phy_writel(DDRSS_DDRPHY_DX2GCR4, cfg->ddrphy_dx2gcr4); + ddrss_phy_writel(DDRSS_DDRPHY_DX3GCR4, cfg->ddrphy_dx3gcr4); + + ddrss_phy_writel(DDRSS_DDRPHY_PGCR5, cfg->ddrphy_pgcr5); + ddrss_phy_writel(DDRSS_DDRPHY_DX0GCR5, cfg->ddrphy_dx0gcr5); + ddrss_phy_writel(DDRSS_DDRPHY_DX1GCR5, cfg->ddrphy_dx1gcr5); + ddrss_phy_writel(DDRSS_DDRPHY_DX2GCR5, cfg->ddrphy_dx2gcr5); + ddrss_phy_writel(DDRSS_DDRPHY_DX3GCR5, cfg->ddrphy_dx3gcr5); + + ddrss_phy_writel(DDRSS_DDRPHY_RANKIDR, DDRSS_DDRPHY_RANKIDR_RANK0); + + ddrss_phy_writel(DDRSS_DDRPHY_DX0GTR0, cfg->ddrphy_dx0gtr0); + ddrss_phy_writel(DDRSS_DDRPHY_DX1GTR0, cfg->ddrphy_dx1gtr0); + ddrss_phy_writel(DDRSS_DDRPHY_DX2GTR0, cfg->ddrphy_dx2gtr0); + ddrss_phy_writel(DDRSS_DDRPHY_DX3GTR0, cfg->ddrphy_dx3gtr0); + ddrss_phy_writel(DDRSS_DDRPHY_ODTCR, cfg->ddrphy_odtcr); + + ddrss_phy_writel(DDRSS_DDRPHY_DX8SL0IOCR, cfg->ddrphy_dx8sl0iocr); + ddrss_phy_writel(DDRSS_DDRPHY_DX8SL1IOCR, cfg->ddrphy_dx8sl1iocr); + ddrss_phy_writel(DDRSS_DDRPHY_DX8SL2IOCR, cfg->ddrphy_dx8sl2iocr); + + ddrss_phy_writel(DDRSS_DDRPHY_DX8SL0DXCTL2, cfg->ddrphy_dx8sl0dxctl2); + ddrss_phy_writel(DDRSS_DDRPHY_DX8SL1DXCTL2, cfg->ddrphy_dx8sl1dxctl2); + ddrss_phy_writel(DDRSS_DDRPHY_DX8SL2DXCTL2, cfg->ddrphy_dx8sl2dxctl2); + + debug("%s: DDR phy register configuration completed\n", __func__); +} + +static int __phy_builtin_init_routine(struct am654_ddrss_desc *ddrss, + u32 init_value, u32 sts_mask, + u32 err_mask) +{ + int ret; + + ddrss_phy_writel(DDRSS_DDRPHY_PIR, init_value | PIR_INIT_MASK); + + sdelay(5); /* Delay at least 10 clock cycles */ + + if (!wait_on_value(sts_mask, sts_mask, + ddrss->ddrss_phy_cfg + DDRSS_DDRPHY_PGSR0, LDELAY)) + return -ETIMEDOUT; + + sdelay(16); /* Delay at least 32 clock cycles */ + + ret = ddrss_phy_readl(DDRSS_DDRPHY_PGSR0); + debug("%s: PGSR0 val = 0x%x\n", __func__, ret); + if (ret & err_mask) + return -EINVAL; + + return 0; +} + +int write_leveling(struct am654_ddrss_desc *ddrss) +{ + int ret; + + debug("%s: Write leveling started\n", __func__); + + ret = __phy_builtin_init_routine(ddrss, PIR_WL_MASK, PGSR0_WLDONE_MASK, + PGSR0_WLERR_MASK); + if (ret) { + if (ret == -ETIMEDOUT) + printf("%s: ERROR: Write leveling timedout\n", + __func__); + else + printf("%s:ERROR: Write leveling failed\n", __func__); + return ret; + } + + debug("%s: Write leveling completed\n", __func__); + return 0; +} + +int read_dqs_training(struct am654_ddrss_desc *ddrss) +{ + int ret; + + debug("%s: Read DQS training started\n", __func__); + + ret = __phy_builtin_init_routine(ddrss, PIR_QSGATE_MASK, + PGSR0_QSGDONE_MASK, PGSR0_QSGERR_MASK); + if (ret) { + if (ret == -ETIMEDOUT) + printf("%s: ERROR: Read DQS timedout\n", __func__); + else + printf("%s:ERROR: Read DQS Gate training failed\n", + __func__); + return ret; + } + + debug("%s: Read DQS training completed\n", __func__); + return 0; +} + +int rest_training(struct am654_ddrss_desc *ddrss) +{ + int ret; + u32 val; + u32 dgsl0, dgsl1, dgsl2, dgsl3, rddly, rd2wr_wr2rd; + + debug("%s: Rest of the training started\n", __func__); + + debug("%s: Write Leveling adjustment\n", __func__); + ret = __phy_builtin_init_routine(ddrss, PIR_WLADJ_MASK, + PGSR0_WLADONE_MASK, PGSR0_WLAERR_MASK); + if (ret) { + if (ret == -ETIMEDOUT) + printf("%s:ERROR: Write Leveling adjustment timedout\n", + __func__); + else + printf("%s: ERROR: Write Leveling adjustment failed\n", + __func__); + return ret; + } + + debug("%s: Read Deskew adjustment\n", __func__); + ret = __phy_builtin_init_routine(ddrss, PIR_RDDSKW_MASK, + PGSR0_RDDONE_MASK, PGSR0_RDERR_MASK); + if (ret) { + if (ret == -ETIMEDOUT) + printf("%s: ERROR: Read Deskew timedout\n", __func__); + else + printf("%s: ERROR: Read Deskew failed\n", __func__); + return ret; + } + + debug("%s: Write Deskew adjustment\n", __func__); + ret = __phy_builtin_init_routine(ddrss, PIR_WRDSKW_MASK, + PGSR0_WDDONE_MASK, PGSR0_WDERR_MASK); + if (ret) { + if (ret == -ETIMEDOUT) + printf("%s: ERROR: Write Deskew timedout\n", __func__); + else + printf("%s: ERROR: Write Deskew failed\n", __func__); + return ret; + } + + debug("%s: Read Eye training\n", __func__); + ret = __phy_builtin_init_routine(ddrss, PIR_RDEYE_MASK, + PGSR0_REDONE_MASK, PGSR0_REERR_MASK); + if (ret) { + if (ret == -ETIMEDOUT) + printf("%s: ERROR: Read Eye training timedout\n", + __func__); + else + printf("%s: ERROR: Read Eye training failed\n", + __func__); + return ret; + } + + debug("%s: Write Eye training\n", __func__); + ret = __phy_builtin_init_routine(ddrss, PIR_WREYE_MASK, + PGSR0_WEDONE_MASK, PGSR0_WEERR_MASK); + if (ret) { + if (ret == -ETIMEDOUT) + printf("%s: ERROR: Write Eye training timedout\n", + __func__); + else + printf("%s: ERROR: Write Eye training failed\n", + __func__); + return ret; + } + + debug("%s: VREF training\n", __func__); + ret = __phy_builtin_init_routine(ddrss, PIR_VREF_MASK, PGSR0_VDONE_MASK, + PGSR0_VERR_MASK); + if (ret) { + if (ret == -ETIMEDOUT) + printf("%s: ERROR: VREF training timedout\n", __func__); + else + printf("%s: ERROR: VREF training failed\n", __func__); + return ret; + } + + ddrss_phy_writel(DDRSS_DDRPHY_RANKIDR, 0x00000000); + dgsl0 = (ddrss_phy_readl(DDRSS_DDRPHY_DX0GTR0) & 0x1F) >> 2; + dgsl1 = (ddrss_phy_readl(DDRSS_DDRPHY_DX1GTR0) & 0x1F) >> 2; + dgsl2 = (ddrss_phy_readl(DDRSS_DDRPHY_DX2GTR0) & 0x1F) >> 2; + dgsl3 = (ddrss_phy_readl(DDRSS_DDRPHY_DX3GTR0) & 0x1F) >> 2; + + rddly = dgsl0; + if (dgsl1 < rddly) + rddly = dgsl1; + if (dgsl2 < rddly) + rddly = dgsl2; + if (dgsl3 < rddly) + rddly = dgsl3; + + rddly += 5; + + /* Update rddly based on dgsl values */ + val = (ddrss_phy_readl(DDRSS_DDRPHY_DX0GCR0) & ~0xF00000); + val |= (rddly << 20); + ddrss_phy_writel(DDRSS_DDRPHY_DX0GCR0, val); + + val = (ddrss_phy_readl(DDRSS_DDRPHY_DX1GCR0) & ~0xF00000); + val |= (rddly << 20); + ddrss_phy_writel(DDRSS_DDRPHY_DX1GCR0, val); + + val = (ddrss_phy_readl(DDRSS_DDRPHY_DX2GCR0) & ~0xF00000); + val |= (rddly << 20); + ddrss_phy_writel(DDRSS_DDRPHY_DX2GCR0, val); + + val = (ddrss_phy_readl(DDRSS_DDRPHY_DX3GCR0) & ~0xF00000); + val |= (rddly << 20); + ddrss_phy_writel(DDRSS_DDRPHY_DX3GCR0, val); + + /* + * Add system latency derived from training back into rd2wr and wr2rd + * rd2wr = RL + BL/2 + 1 + WR_PREAMBLE - WL + max(DXnGTR0.DGSL) / 2 + * wr2rd = CWL + PL + BL/2 + tWTR_L + max(DXnGTR0.DGSL) / 2 + */ + + /* Select rank 0 */ + ddrss_phy_writel(DDRSS_DDRPHY_RANKIDR, 0x00000000); + + dgsl0 = (ddrss_phy_readl(DDRSS_DDRPHY_DX0GTR0) & 0x1F); + dgsl1 = (ddrss_phy_readl(DDRSS_DDRPHY_DX1GTR0) & 0x1F); + dgsl2 = (ddrss_phy_readl(DDRSS_DDRPHY_DX2GTR0) & 0x1F); + dgsl3 = (ddrss_phy_readl(DDRSS_DDRPHY_DX3GTR0) & 0x1F); + + /* Find maximum value across all bytes */ + rd2wr_wr2rd = dgsl0; + if (dgsl1 > rd2wr_wr2rd) + rd2wr_wr2rd = dgsl1; + if (dgsl2 > rd2wr_wr2rd) + rd2wr_wr2rd = dgsl2; + if (dgsl3 > rd2wr_wr2rd) + rd2wr_wr2rd = dgsl3; + + rd2wr_wr2rd >>= 1; + + /* Now add in adjustment to DRAMTMG2 bit fields for rd2wr and wr2rd */ + /* Clear VSWCTL.sw_done */ + ddrss_ctl_writel(DDRSS_DDRCTL_SWCTL, + ddrss_ctl_readl(DDRSS_DDRCTL_SWCTL) & ~0x1); + /* Adjust rd2wr */ + ddrss_ctl_writel(DDRSS_DDRCTL_DRAMTMG2, + ddrss_ctl_readl(DDRSS_DDRCTL_DRAMTMG2) + + (rd2wr_wr2rd << 8)); + /* Adjust wr2rd */ + ddrss_ctl_writel(DDRSS_DDRCTL_DRAMTMG2, + ddrss_ctl_readl(DDRSS_DDRCTL_DRAMTMG2) + + rd2wr_wr2rd); + /* Set VSWCTL.sw_done */ + ddrss_ctl_writel(DDRSS_DDRCTL_SWCTL, + ddrss_ctl_readl(DDRSS_DDRCTL_SWCTL) | 0x1); + /* Wait until settings are applied */ + while (!(ddrss_ctl_readl(DDRSS_DDRCTL_SWSTAT) & 0x1)) { + /* Do nothing */ + }; + + debug("%s: Rest of the training completed\n", __func__); + return 0; +} + +/** + * am654_ddrss_init() - Initialization sequence for enabling the SDRAM + * device attached to ddrss. + * @dev: corresponding ddrss device + * + * Does all the initialization sequence that is required to get attached + * ddr in a working state. After this point, ddr should be accessible. + * Return: 0 if all went ok, else corresponding error message. + */ +static int am654_ddrss_init(struct am654_ddrss_desc *ddrss) +{ + int ret; + + debug("%s(ddrss=%p)\n", __func__, ddrss); + + ddrss_writel(ddrss->ddrss_ss_cfg, DDRSS_V2H_CTL_REG, 0x000073FF); + + am654_ddrss_ctrl_configuration(ddrss); + + /* Release the reset to the controller */ + clrbits_le32(ddrss->ddrss_ss_cfg + DDRSS_SS_CTL_REG, + SS_CTL_REG_CTL_ARST_MASK); + + am654_ddrss_phy_configuration(ddrss); + + ret = __phy_builtin_init_routine(ddrss, PIR_PHY_INIT, 0x1, 0); + if (ret) { + dev_err(ddrss->dev, "PHY initialization failed %d\n", ret); + return ret; + } + + ret = __phy_builtin_init_routine(ddrss, PIR_DRAM_INIT, + PGSR0_DRAM_INIT_MASK, 0); + if (ret) { + dev_err(ddrss->dev, "DRAM initialization failed %d\n", ret); + return ret; + } + + ret = am654_ddrss_dram_wait_for_init_complt(ddrss); + if (ret) { + printf("%s: ERROR: DRAM Wait for init complete timedout\n", + __func__); + return ret; + } + + ret = write_leveling(ddrss); + if (ret) + return ret; + + ret = read_dqs_training(ddrss); + if (ret) + return ret; + + ret = rest_training(ddrss); + if (ret) + return ret; + + /* Enabling refreshes after training is done */ + ddrss_ctl_writel(DDRSS_DDRCTL_RFSHCTL3, + ddrss_ctl_readl(DDRSS_DDRCTL_RFSHCTL3) & ~0x1); + + /* Disable PUBMODE after training is done */ + ddrss_phy_writel(DDRSS_DDRPHY_PGCR1, + ddrss_phy_readl(DDRSS_DDRPHY_PGCR1) & ~0x40); + + return 0; +} + +/** + * am654_ddrss_power_on() - Enable power and clocks for ddrss + * @dev: corresponding ddrss device + * + * Tries to enable all the corresponding clocks to the ddrss and sets it + * to the right frequency and then power on the ddrss. + * Return: 0 if all went ok, else corresponding error message. + */ +static int am654_ddrss_power_on(struct am654_ddrss_desc *ddrss) +{ + int ret; + + debug("%s(ddrss=%p)\n", __func__, ddrss); + + ret = clk_enable(&ddrss->ddrss_clk); + if (ret) { + dev_err(ddrss->dev, "clk_enable() failed: %d\n", ret); + return ret; + } + + ret = power_domain_on(&ddrss->ddrcfg_pwrdmn); + if (ret) { + dev_err(ddrss->dev, "power_domain_on() failed: %d\n", ret); + return ret; + } + + ret = power_domain_on(&ddrss->ddrdata_pwrdmn); + if (ret) { + dev_err(ddrss->dev, "power_domain_on() failed: %d\n", ret); + return ret; + } + + /* VTT enable */ +#if CONFIG_IS_ENABLED(DM_REGULATOR) + device_get_supply_regulator(ddrss->dev, "vtt-supply", + &ddrss->vtt_supply); + ret = regulator_set_value(ddrss->vtt_supply, 3300000); + if (ret) + return ret; + debug("VTT regulator enabled\n"); +#endif + + return 0; +} + +/** + * am654_ddrss_ofdata_to_priv() - generate private data from device tree + * @dev: corresponding ddrss device + * + * Return: 0 if all went ok, else corresponding error message. + */ +static int am654_ddrss_ofdata_to_priv(struct udevice *dev) +{ + struct am654_ddrss_desc *ddrss = dev_get_priv(dev); + phys_addr_t reg; + int ret; + + debug("%s(dev=%p)\n", __func__, dev); + + ret = clk_get_by_index(dev, 0, &ddrss->ddrss_clk); + if (ret) { + dev_err(dev, "clk_get failed: %d\n", ret); + return ret; + } + + ret = power_domain_get_by_index(dev, &ddrss->ddrcfg_pwrdmn, 0); + if (ret) { + dev_err(dev, "power_domain_get() failed: %d\n", ret); + return ret; + } + + ret = power_domain_get_by_index(dev, &ddrss->ddrdata_pwrdmn, 1); + if (ret) { + dev_err(dev, "power_domain_get() failed: %d\n", ret); + return ret; + } + + reg = devfdt_get_addr_name(dev, "ss"); + if (reg == FDT_ADDR_T_NONE) { + dev_err(dev, "No reg property for DDRSS wrapper logic\n"); + return -EINVAL; + } + ddrss->ddrss_ss_cfg = (void *)reg; + + reg = devfdt_get_addr_name(dev, "ctl"); + if (reg == FDT_ADDR_T_NONE) { + dev_err(dev, "No reg property for Controller region\n"); + return -EINVAL; + } + ddrss->ddrss_ctl_cfg = (void *)reg; + + reg = devfdt_get_addr_name(dev, "phy"); + if (reg == FDT_ADDR_T_NONE) { + dev_err(dev, "No reg property for PHY region\n"); + return -EINVAL; + } + ddrss->ddrss_phy_cfg = (void *)reg; + + ret = dev_read_u32_array(dev, "ti,ctl-reg", + (u32 *)&ddrss->params.ctl_reg, + sizeof(ddrss->params.ctl_reg) / sizeof(u32)); + if (ret) { + dev_err(dev, "Cannot read ti,ctl-reg params\n"); + return ret; + } + + ret = dev_read_u32_array(dev, "ti,ctl-crc", + (u32 *)&ddrss->params.ctl_crc, + sizeof(ddrss->params.ctl_crc) / sizeof(u32)); + if (ret) { + dev_err(dev, "Cannot read ti,ctl-crc params\n"); + return ret; + } + + ret = dev_read_u32_array(dev, "ti,ctl-ecc", + (u32 *)&ddrss->params.ctl_ecc, + sizeof(ddrss->params.ctl_ecc) / sizeof(u32)); + if (ret) { + dev_err(dev, "Cannot read ti,ctl-ecc params\n"); + return ret; + } + + ret = dev_read_u32_array(dev, "ti,ctl-map", + (u32 *)&ddrss->params.ctl_map, + sizeof(ddrss->params.ctl_map) / sizeof(u32)); + if (ret) { + dev_err(dev, "Cannot read ti,ctl-map params\n"); + return ret; + } + + ret = dev_read_u32_array(dev, "ti,ctl-pwr", + (u32 *)&ddrss->params.ctl_pwr, + sizeof(ddrss->params.ctl_pwr) / sizeof(u32)); + if (ret) { + dev_err(dev, "Cannot read ti,ctl-pwr params\n"); + return ret; + } + + ret = dev_read_u32_array(dev, "ti,ctl-timing", + (u32 *)&ddrss->params.ctl_timing, + sizeof(ddrss->params.ctl_timing) / + sizeof(u32)); + if (ret) { + dev_err(dev, "Cannot read ti,ctl-timing params\n"); + return ret; + } + + ret = dev_read_u32_array(dev, "ti,phy-cfg", + (u32 *)&ddrss->params.phy_cfg, + sizeof(ddrss->params.phy_cfg) / sizeof(u32)); + if (ret) { + dev_err(dev, "Cannot read ti,phy-cfg params\n"); + return ret; + } + + ret = dev_read_u32_array(dev, "ti,phy-ctl", + (u32 *)&ddrss->params.phy_ctrl, + sizeof(ddrss->params.phy_ctrl) / sizeof(u32)); + if (ret) { + dev_err(dev, "Cannot read ti,phy-ctl params\n"); + return ret; + } + + ret = dev_read_u32_array(dev, "ti,phy-ioctl", + (u32 *)&ddrss->params.phy_ioctl, + sizeof(ddrss->params.phy_ioctl) / sizeof(u32)); + if (ret) { + dev_err(dev, "Cannot read ti,phy-ioctl params\n"); + return ret; + } + + ret = dev_read_u32_array(dev, "ti,phy-timing", + (u32 *)&ddrss->params.phy_timing, + sizeof(ddrss->params.phy_timing) / + sizeof(u32)); + if (ret) { + dev_err(dev, "Cannot read ti,phy-timing params\n"); + return ret; + } + + ret = dev_read_u32_array(dev, "ti,phy-zq", (u32 *)&ddrss->params.phy_zq, + sizeof(ddrss->params.phy_zq) / sizeof(u32)); + if (ret) { + dev_err(dev, "Cannot read ti,phy-zq params\n"); + return ret; + } + + return ret; +} + +/** + * am654_ddrss_probe() - Basic probe + * @dev: corresponding ddrss device + * + * Return: 0 if all went ok, else corresponding error message + */ +static int am654_ddrss_probe(struct udevice *dev) +{ + struct am654_ddrss_desc *ddrss = dev_get_priv(dev); + int ret; + + debug("%s(dev=%p)\n", __func__, dev); + + ret = am654_ddrss_ofdata_to_priv(dev); + if (ret) + return ret; + + ddrss->dev = dev; + ret = am654_ddrss_power_on(ddrss); + if (ret) + return ret; + + ret = am654_ddrss_init(ddrss); + + return ret; +} + +static int am654_ddrss_get_info(struct udevice *dev, struct ram_info *info) +{ + return 0; +} + +static struct ram_ops am654_ddrss_ops = { + .get_info = am654_ddrss_get_info, +}; + +static const struct udevice_id am654_ddrss_ids[] = { + { .compatible = "ti,am654-ddrss" }, + { } +}; + +U_BOOT_DRIVER(am654_ddrss) = { + .name = "am654_ddrss", + .id = UCLASS_RAM, + .of_match = am654_ddrss_ids, + .ops = &am654_ddrss_ops, + .probe = am654_ddrss_probe, + .priv_auto_alloc_size = sizeof(struct am654_ddrss_desc), +}; diff --git a/drivers/ram/k3-am654-ddrss.h b/drivers/ram/k3-am654-ddrss.h new file mode 100644 index 0000000000..78d73cd9fc --- /dev/null +++ b/drivers/ram/k3-am654-ddrss.h @@ -0,0 +1,1189 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * AM654: DDRSS Register definitions and structures. + * + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ + * Lokesh Vutla <lokeshvutla@ti.com> + * + */ + +#ifndef __K3_AM654_DDRSS_H +#define __K3_AM654_DDRSS_H + +/* DDRSS subsystem wrapper logic registers */ +#define DDRSS_SS_ID_REV_REG 0x00000000 +#define DDRSS_SS_CTL_REG 0x00000004 +#define DDRSS_V2H_CTL_REG 0x00000020 + +#define SS_CTL_REG_CTL_ARST_SHIFT 0x0 +#define SS_CTL_REG_CTL_ARST_MASK BIT(SS_CTL_REG_CTL_ARST_SHIFT) + +/* DDRSS controller configuration registers */ +#define DDRSS_DDRCTL_MSTR 0x00000000 +#define DDRSS_DDRCTL_STAT 0x00000004 +#define DDRSS_DDRCTL_MRCTRL0 0x00000010 +#define DDRSS_DDRCTL_MRCTRL1 0x00000014 +#define DDRSS_DDRCTL_MRSTAT 0x00000018 +#define DDRSS_DDRCTL_MRCTRL2 0x0000001C +#define DDRSS_DDRCTL_DERATEEN 0x00000020 +#define DDRSS_DDRCTL_DERATEINT 0x00000024 +#define DDRSS_DDRCTL_MSTR2 0x00000028 +#define DDRSS_DDRCTL_PWRCTL 0x00000030 +#define DDRSS_DDRCTL_PWRTMG 0x00000034 +#define DDRSS_DDRCTL_HWLPCTL 0x00000038 +#define DDRSS_DDRCTL_RFSHCTL0 0x00000050 +#define DDRSS_DDRCTL_RFSHCTL1 0x00000054 +#define DDRSS_DDRCTL_RFSHCTL2 0x00000058 +#define DDRSS_DDRCTL_RFSHCTL3 0x00000060 +#define DDRSS_DDRCTL_RFSHTMG 0x00000064 +#define DDRSS_DDRCTL_ECCCFG0 0x00000070 +#define DDRSS_DDRCTL_ECCCFG1 0x00000074 +#define DDRSS_DDRCTL_ECCSTAT 0x00000078 +#define DDRSS_DDRCTL_ECCCLR 0x0000007C +#define DDRSS_DDRCTL_ECCERRCNT 0x00000080 +#define DDRSS_DDRCTL_ECCCADDR0 0x00000084 +#define DDRSS_DDRCTL_ECCCADDR1 0x00000088 +#define DDRSS_DDRCTL_ECCCSYN0 0x0000008C +#define DDRSS_DDRCTL_ECCCSYN2 0x00000094 +#define DDRSS_DDRCTL_ECCBITMASK0 0x00000098 +#define DDRSS_DDRCTL_ECCBITMASK2 0x000000A0 +#define DDRSS_DDRCTL_ECCUADDR0 0x000000A4 +#define DDRSS_DDRCTL_ECCUADDR1 0x000000A8 +#define DDRSS_DDRCTL_ECCUSYN0 0x000000AC +#define DDRSS_DDRCTL_ECCUSYN2 0x000000B4 +#define DDRSS_DDRCTL_ECCPOISONADDR0 0x000000B8 +#define DDRSS_DDRCTL_ECCPOISONADDR1 0x000000BC +#define DDRSS_DDRCTL_CRCPARCTL0 0x000000C0 +#define DDRSS_DDRCTL_CRCPARCTL1 0x000000C4 +#define DDRSS_DDRCTL_CRCPARCTL2 0x000000C8 +#define DDRSS_DDRCTL_CRCPARSTAT 0x000000CC +#define DDRSS_DDRCTL_INIT0 0x000000D0 +#define DDRSS_DDRCTL_INIT1 0x000000D4 +#define DDRSS_DDRCTL_INIT2 0x000000D8 +#define DDRSS_DDRCTL_INIT3 0x000000DC +#define DDRSS_DDRCTL_INIT4 0x000000E0 +#define DDRSS_DDRCTL_INIT5 0x000000E4 +#define DDRSS_DDRCTL_INIT6 0x000000E8 +#define DDRSS_DDRCTL_INIT7 0x000000EC +#define DDRSS_DDRCTL_DIMMCTL 0x000000F0 +#define DDRSS_DDRCTL_RANKCTL 0x000000F4 +#define DDRSS_DDRCTL_DRAMTMG0 0x00000100 +#define DDRSS_DDRCTL_DRAMTMG1 0x00000104 +#define DDRSS_DDRCTL_DRAMTMG2 0x00000108 +#define DDRSS_DDRCTL_DRAMTMG3 0x0000010C +#define DDRSS_DDRCTL_DRAMTMG4 0x00000110 +#define DDRSS_DDRCTL_DRAMTMG5 0x00000114 +#define DDRSS_DDRCTL_DRAMTMG6 0x00000118 +#define DDRSS_DDRCTL_DRAMTMG7 0x0000011C +#define DDRSS_DDRCTL_DRAMTMG8 0x00000120 +#define DDRSS_DDRCTL_DRAMTMG9 0x00000124 +#define DDRSS_DDRCTL_DRAMTMG10 0x00000128 +#define DDRSS_DDRCTL_DRAMTMG11 0x0000012C +#define DDRSS_DDRCTL_DRAMTMG12 0x00000130 +#define DDRSS_DDRCTL_DRAMTMG13 0x00000134 +#define DDRSS_DDRCTL_DRAMTMG14 0x00000138 +#define DDRSS_DDRCTL_DRAMTMG15 0x0000013C +#define DDRSS_DDRCTL_DRAMTMG17 0x00000144 +#define DDRSS_DDRCTL_ZQCTL0 0x00000180 +#define DDRSS_DDRCTL_ZQCTL1 0x00000184 +#define DDRSS_DDRCTL_ZQCTL2 0x00000188 +#define DDRSS_DDRCTL_ZQSTAT 0x0000018C +#define DDRSS_DDRCTL_DFITMG0 0x00000190 +#define DDRSS_DDRCTL_DFITMG1 0x00000194 +#define DDRSS_DDRCTL_DFILPCFG0 0x00000198 +#define DDRSS_DDRCTL_DFILPCFG1 0x0000019C +#define DDRSS_DDRCTL_DFIUPD0 0x000001A0 +#define DDRSS_DDRCTL_DFIUPD1 0x000001A4 +#define DDRSS_DDRCTL_DFIUPD2 0x000001A8 +#define DDRSS_DDRCTL_DFIMISC 0x000001B0 +#define DDRSS_DDRCTL_DFITMG2 0x000001B4 +#define DDRSS_DDRCTL_DFITMG3 0x000001B8 +#define DDRSS_DDRCTL_DFISTAT 0x000001BC +#define DDRSS_DDRCTL_DBICTL 0x000001C0 +#define DDRSS_DDRCTL_DFIPHYMSTR 0x000001C4 +#define DDRSS_DDRCTL_ADDRMAP0 0x00000200 +#define DDRSS_DDRCTL_ADDRMAP1 0x00000204 +#define DDRSS_DDRCTL_ADDRMAP2 0x00000208 +#define DDRSS_DDRCTL_ADDRMAP3 0x0000020C +#define DDRSS_DDRCTL_ADDRMAP4 0x00000210 +#define DDRSS_DDRCTL_ADDRMAP5 0x00000214 +#define DDRSS_DDRCTL_ADDRMAP6 0x00000218 +#define DDRSS_DDRCTL_ADDRMAP7 0x0000021C +#define DDRSS_DDRCTL_ADDRMAP8 0x00000220 +#define DDRSS_DDRCTL_ADDRMAP9 0x00000224 +#define DDRSS_DDRCTL_ADDRMAP10 0x00000228 +#define DDRSS_DDRCTL_ADDRMAP11 0x0000022C +#define DDRSS_DDRCTL_ODTCFG 0x00000240 +#define DDRSS_DDRCTL_ODTMAP 0x00000244 +#define DDRSS_DDRCTL_SCHED 0x00000250 +#define DDRSS_DDRCTL_SCHED1 0x00000254 +#define DDRSS_DDRCTL_PERFHPR1 0x0000025C +#define DDRSS_DDRCTL_PERFLPR1 0x00000264 +#define DDRSS_DDRCTL_PERFWR1 0x0000026C +#define DDRSS_DDRCTL_DQMAP0 0x00000280 +#define DDRSS_DDRCTL_DQMAP1 0x00000284 +#define DDRSS_DDRCTL_DQMAP4 0x00000290 +#define DDRSS_DDRCTL_DQMAP5 0x00000294 +#define DDRSS_DDRCTL_DBG0 0x00000300 +#define DDRSS_DDRCTL_DBG1 0x00000304 +#define DDRSS_DDRCTL_DBGCAM 0x00000308 +#define DDRSS_DDRCTL_DBGCMD 0x0000030C +#define DDRSS_DDRCTL_DBGSTAT 0x00000310 +#define DDRSS_DDRCTL_SWCTL 0x00000320 +#define DDRSS_DDRCTL_SWSTAT 0x00000324 +#define DDRSS_DDRCTL_ADVECCINDEX 0x00000374 +#define DDRSS_DDRCTL_ECCPOISONPAT0 0x0000037C +#define DDRSS_DDRCTL_ECCPOISONPAT2 0x00000384 +#define DDRSS_DDRCTL_CAPARPOISONCTL 0x000003A0 +#define DDRSS_DDRCTL_CAPARPOISONSTAT 0x000003A4 +#define DDRSS_DDRCTL_DERATEEN_SHDW 0x00002020 +#define DDRSS_DDRCTL_DERATEINT_SHDW 0x00002024 +#define DDRSS_DDRCTL_RFSHCTL0_SHDW 0x00002050 +#define DDRSS_DDRCTL_RFSHTMG_SHDW 0x00002064 +#define DDRSS_DDRCTL_INIT3_SHDW 0x000020DC +#define DDRSS_DDRCTL_INIT4_SHDW 0x000020E0 +#define DDRSS_DDRCTL_INIT6_SHDW 0x000020E8 +#define DDRSS_DDRCTL_INIT7_SHDW 0x000020EC +#define DDRSS_DDRCTL_DRAMTMG0_SHDW 0x00002100 +#define DDRSS_DDRCTL_DRAMTMG1_SHDW 0x00002104 +#define DDRSS_DDRCTL_DRAMTMG2_SHDW 0x00002108 +#define DDRSS_DDRCTL_DRAMTMG3_SHDW 0x0000210C +#define DDRSS_DDRCTL_DRAMTMG4_SHDW 0x00002110 +#define DDRSS_DDRCTL_DRAMTMG5_SHDW 0x00002114 +#define DDRSS_DDRCTL_DRAMTMG6_SHDW 0x00002118 +#define DDRSS_DDRCTL_DRAMTMG7_SHDW 0x0000211C +#define DDRSS_DDRCTL_DRAMTMG8_SHDW 0x00002120 +#define DDRSS_DDRCTL_DRAMTMG9_SHDW 0x00002124 +#define DDRSS_DDRCTL_DRAMTMG10_SHDW 0x00002128 +#define DDRSS_DDRCTL_DRAMTMG11_SHDW 0x0000212C +#define DDRSS_DDRCTL_DRAMTMG12_SHDW 0x00002130 +#define DDRSS_DDRCTL_DRAMTMG13_SHDW 0x00002134 +#define DDRSS_DDRCTL_DRAMTMG14_SHDW 0x00002138 +#define DDRSS_DDRCTL_DRAMTMG15_SHDW 0x0000213C +#define DDRSS_DDRCTL_ZQCTL0_SHDW 0x00002180 +#define DDRSS_DDRCTL_DFITMG0_SHDW 0x00002190 +#define DDRSS_DDRCTL_DFITMG1_SHDW 0x00002194 +#define DDRSS_DDRCTL_DFITMG2_SHDW 0x000021B4 +#define DDRSS_DDRCTL_DFITMG3_SHDW 0x000021B8 +#define DDRSS_DDRCTL_ODTCFG_SHDW 0x00002240 + +#define MSTR_DDR_TYPE_MASK GENMASK(5, 0) +#define DDR_TYPE_LPDDR4 0x20 +#define DDR_TYPE_DDR4 0x10 +#define DDR_TYPE_DDR3 0x1 + +#define DDR3_STAT_MODE_MASK GENMASK(1, 0) +#define DDR4_STAT_MODE_MASK GENMASK(2, 0) +#define DDR_MODE_NORMAL 0x1 + +/* DDRSS PHY configuration registers */ +#define DDRSS_DDRPHY_RIDR 0x00000000 +#define DDRSS_DDRPHY_PIR 0x00000004 +#define DDRSS_DDRPHY_PGCR0 0x00000010 +#define DDRSS_DDRPHY_PGCR1 0x00000014 +#define DDRSS_DDRPHY_PGCR2 0x00000018 +#define DDRSS_DDRPHY_PGCR3 0x0000001C +#define DDRSS_DDRPHY_PGCR4 0x00000020 +#define DDRSS_DDRPHY_PGCR5 0x00000024 +#define DDRSS_DDRPHY_PGCR6 0x00000028 +#define DDRSS_DDRPHY_PGCR7 0x0000002C +#define DDRSS_DDRPHY_PGSR0 0x00000030 +#define DDRSS_DDRPHY_PGSR1 0x00000034 +#define DDRSS_DDRPHY_PGSR2 0x00000038 +#define DDRSS_DDRPHY_PTR0 0x00000040 +#define DDRSS_DDRPHY_PTR1 0x00000044 +#define DDRSS_DDRPHY_PTR2 0x00000048 +#define DDRSS_DDRPHY_PTR3 0x0000004C +#define DDRSS_DDRPHY_PTR4 0x00000050 +#define DDRSS_DDRPHY_PTR5 0x00000054 +#define DDRSS_DDRPHY_PTR6 0x00000058 +#define DDRSS_DDRPHY_PLLCR0 0x00000068 +#define DDRSS_DDRPHY_PLLCR1 0x0000006C +#define DDRSS_DDRPHY_PLLCR2 0x00000070 +#define DDRSS_DDRPHY_PLLCR3 0x00000074 +#define DDRSS_DDRPHY_PLLCR4 0x00000078 +#define DDRSS_DDRPHY_PLLCR5 0x0000007C +#define DDRSS_DDRPHY_DXCCR 0x00000088 +#define DDRSS_DDRPHY_DSGCR 0x00000090 +#define DDRSS_DDRPHY_ODTCR 0x00000098 +#define DDRSS_DDRPHY_AACR 0x000000A0 +#define DDRSS_DDRPHY_GPR0 0x000000C0 +#define DDRSS_DDRPHY_GPR1 0x000000C4 +#define DDRSS_DDRPHY_DCR 0x00000100 +#define DDRSS_DDRPHY_DTPR0 0x00000110 +#define DDRSS_DDRPHY_DTPR1 0x00000114 +#define DDRSS_DDRPHY_DTPR2 0x00000118 +#define DDRSS_DDRPHY_DTPR3 0x0000011C +#define DDRSS_DDRPHY_DTPR4 0x00000120 +#define DDRSS_DDRPHY_DTPR5 0x00000124 +#define DDRSS_DDRPHY_DTPR6 0x00000128 +#define DDRSS_DDRPHY_RDIMMGCR0 0x00000140 +#define DDRSS_DDRPHY_RDIMMGCR1 0x00000144 +#define DDRSS_DDRPHY_RDIMMGCR2 0x00000148 +#define DDRSS_DDRPHY_RDIMMCR0 0x00000150 +#define DDRSS_DDRPHY_RDIMMCR1 0x00000154 +#define DDRSS_DDRPHY_RDIMMCR2 0x00000158 +#define DDRSS_DDRPHY_RDIMMCR3 0x0000015C +#define DDRSS_DDRPHY_RDIMMCR4 0x00000160 +#define DDRSS_DDRPHY_SCHCR0 0x00000168 +#define DDRSS_DDRPHY_SCHCR1 0x0000016C +#define DDRSS_DDRPHY_MR0 0x00000180 +#define DDRSS_DDRPHY_MR1 0x00000184 +#define DDRSS_DDRPHY_MR2 0x00000188 +#define DDRSS_DDRPHY_MR3 0x0000018C +#define DDRSS_DDRPHY_MR4 0x00000190 +#define DDRSS_DDRPHY_MR5 0x00000194 +#define DDRSS_DDRPHY_MR6 0x00000198 +#define DDRSS_DDRPHY_MR7 0x0000019C +#define DDRSS_DDRPHY_MR11 0x000001AC +#define DDRSS_DDRPHY_MR12 0x000001B0 +#define DDRSS_DDRPHY_MR13 0x000001B4 +#define DDRSS_DDRPHY_MR14 0x000001B8 +#define DDRSS_DDRPHY_MR22 0x000001D8 +#define DDRSS_DDRPHY_DTCR0 0x00000200 +#define DDRSS_DDRPHY_DTCR1 0x00000204 +#define DDRSS_DDRPHY_DTAR0 0x00000208 +#define DDRSS_DDRPHY_DTAR1 0x0000020C +#define DDRSS_DDRPHY_DTAR2 0x00000210 +#define DDRSS_DDRPHY_DTDR0 0x00000218 +#define DDRSS_DDRPHY_DTDR1 0x0000021C +#define DDRSS_DDRPHY_DTEDR0 0x00000230 +#define DDRSS_DDRPHY_DTEDR1 0x00000234 +#define DDRSS_DDRPHY_DTEDR2 0x00000238 +#define DDRSS_DDRPHY_VTDR 0x0000023C +#define DDRSS_DDRPHY_CATR0 0x00000240 +#define DDRSS_DDRPHY_CATR1 0x00000244 +#define DDRSS_DDRPHY_PGCR8 0x00000248 +#define DDRSS_DDRPHY_DQSDR0 0x00000250 +#define DDRSS_DDRPHY_DQSDR1 0x00000254 +#define DDRSS_DDRPHY_DQSDR2 0x00000258 +#define DDRSS_DDRPHY_DCUAR 0x00000300 +#define DDRSS_DDRPHY_DCUDR 0x00000304 +#define DDRSS_DDRPHY_DCURR 0x00000308 +#define DDRSS_DDRPHY_DCULR 0x0000030C +#define DDRSS_DDRPHY_DCUGCR 0x00000310 +#define DDRSS_DDRPHY_DCUTPR 0x00000314 +#define DDRSS_DDRPHY_DCUSR0 0x00000318 +#define DDRSS_DDRPHY_DCUSR1 0x0000031C +#define DDRSS_DDRPHY_BISTRR 0x00000400 +#define DDRSS_DDRPHY_BISTWCR 0x00000404 +#define DDRSS_DDRPHY_BISTMSKR0 0x00000408 +#define DDRSS_DDRPHY_BISTMSKR1 0x0000040C +#define DDRSS_DDRPHY_BISTMSKR2 0x00000410 +#define DDRSS_DDRPHY_BISTLSR 0x00000414 +#define DDRSS_DDRPHY_BISTAR0 0x00000418 +#define DDRSS_DDRPHY_BISTAR1 0x0000041C +#define DDRSS_DDRPHY_BISTAR2 0x00000420 +#define DDRSS_DDRPHY_BISTAR3 0x00000424 +#define DDRSS_DDRPHY_BISTAR4 0x00000428 +#define DDRSS_DDRPHY_BISTUDPR 0x0000042C +#define DDRSS_DDRPHY_BISTGSR 0x00000430 +#define DDRSS_DDRPHY_BISTWER0 0x00000434 +#define DDRSS_DDRPHY_BISTWER1 0x00000438 +#define DDRSS_DDRPHY_BISTBER0 0x0000043C +#define DDRSS_DDRPHY_BISTBER1 0x00000440 +#define DDRSS_DDRPHY_BISTBER2 0x00000444 +#define DDRSS_DDRPHY_BISTBER3 0x00000448 +#define DDRSS_DDRPHY_BISTBER4 0x0000044C +#define DDRSS_DDRPHY_BISTWCSR 0x00000450 +#define DDRSS_DDRPHY_BISTFWR0 0x00000454 +#define DDRSS_DDRPHY_BISTFWR1 0x00000458 +#define DDRSS_DDRPHY_BISTFWR2 0x0000045C +#define DDRSS_DDRPHY_BISTBER5 0x00000460 +#define DDRSS_DDRPHY_RANKIDR 0x000004DC +#define DDRSS_DDRPHY_RIOCR0 0x000004E0 +#define DDRSS_DDRPHY_RIOCR1 0x000004E4 +#define DDRSS_DDRPHY_RIOCR2 0x000004E8 +#define DDRSS_DDRPHY_RIOCR3 0x000004EC +#define DDRSS_DDRPHY_RIOCR4 0x000004F0 +#define DDRSS_DDRPHY_RIOCR5 0x000004F4 +#define DDRSS_DDRPHY_ACIOCR0 0x00000500 +#define DDRSS_DDRPHY_ACIOCR1 0x00000504 +#define DDRSS_DDRPHY_ACIOCR2 0x00000508 +#define DDRSS_DDRPHY_ACIOCR3 0x0000050C +#define DDRSS_DDRPHY_ACIOCR4 0x00000510 +#define DDRSS_DDRPHY_ACIOCR5 0x00000514 +#define DDRSS_DDRPHY_IOVCR0 0x00000520 +#define DDRSS_DDRPHY_IOVCR1 0x00000524 +#define DDRSS_DDRPHY_VTCR0 0x00000528 +#define DDRSS_DDRPHY_VTCR1 0x0000052C +#define DDRSS_DDRPHY_ACBDLR0 0x00000540 +#define DDRSS_DDRPHY_ACBDLR1 0x00000544 +#define DDRSS_DDRPHY_ACBDLR2 0x00000548 +#define DDRSS_DDRPHY_ACBDLR3 0x0000054C +#define DDRSS_DDRPHY_ACBDLR4 0x00000550 +#define DDRSS_DDRPHY_ACBDLR5 0x00000554 +#define DDRSS_DDRPHY_ACBDLR6 0x00000558 +#define DDRSS_DDRPHY_ACBDLR7 0x0000055C +#define DDRSS_DDRPHY_ACBDLR8 0x00000560 +#define DDRSS_DDRPHY_ACBDLR9 0x00000564 +#define DDRSS_DDRPHY_ACBDLR10 0x00000568 +#define DDRSS_DDRPHY_ACBDLR11 0x0000056C +#define DDRSS_DDRPHY_ACBDLR12 0x00000570 +#define DDRSS_DDRPHY_ACBDLR13 0x00000574 +#define DDRSS_DDRPHY_ACBDLR14 0x00000578 +#define DDRSS_DDRPHY_ACBDLR15 0x0000057C +#define DDRSS_DDRPHY_ACBDLR16 0x00000580 +#define DDRSS_DDRPHY_ACLCDLR 0x00000584 +#define DDRSS_DDRPHY_ACMDLR0 0x000005A0 +#define DDRSS_DDRPHY_ACMDLR1 0x000005A4 +#define DDRSS_DDRPHY_ZQCR 0x00000680 +#define DDRSS_DDRPHY_ZQ0PR0 0x00000684 +#define DDRSS_DDRPHY_ZQ0PR1 0x00000688 +#define DDRSS_DDRPHY_ZQ0DR0 0x0000068C +#define DDRSS_DDRPHY_ZQ0DR1 0x00000690 +#define DDRSS_DDRPHY_ZQ0OR0 0x00000694 +#define DDRSS_DDRPHY_ZQ0OR1 0x00000698 +#define DDRSS_DDRPHY_ZQ0SR 0x0000069C +#define DDRSS_DDRPHY_ZQ1PR0 0x000006A4 +#define DDRSS_DDRPHY_ZQ1PR1 0x000006A8 +#define DDRSS_DDRPHY_ZQ1DR0 0x000006AC +#define DDRSS_DDRPHY_ZQ1DR1 0x000006B0 +#define DDRSS_DDRPHY_ZQ1OR0 0x000006B4 +#define DDRSS_DDRPHY_ZQ1OR1 0x000006B8 +#define DDRSS_DDRPHY_ZQ1SR 0x000006BC +#define DDRSS_DDRPHY_ZQ2PR0 0x000006C4 +#define DDRSS_DDRPHY_ZQ2PR1 0x000006C8 +#define DDRSS_DDRPHY_ZQ2DR0 0x000006CC +#define DDRSS_DDRPHY_ZQ2DR1 0x000006D0 +#define DDRSS_DDRPHY_ZQ2OR0 0x000006D4 +#define DDRSS_DDRPHY_ZQ2OR1 0x000006D8 +#define DDRSS_DDRPHY_ZQ2SR 0x000006DC +#define DDRSS_DDRPHY_ZQ3PR0 0x000006E4 +#define DDRSS_DDRPHY_ZQ3PR1 0x000006E8 +#define DDRSS_DDRPHY_ZQ3DR0 0x000006EC +#define DDRSS_DDRPHY_ZQ3DR1 0x000006F0 +#define DDRSS_DDRPHY_ZQ3OR0 0x000006F4 +#define DDRSS_DDRPHY_ZQ3OR1 0x000006F8 +#define DDRSS_DDRPHY_ZQ3SR 0x000006FC +#define DDRSS_DDRPHY_DX0GCR0 0x00000700 +#define DDRSS_DDRPHY_DX0GCR1 0x00000704 +#define DDRSS_DDRPHY_DX0GCR2 0x00000708 +#define DDRSS_DDRPHY_DX0GCR3 0x0000070C +#define DDRSS_DDRPHY_DX0GCR4 0x00000710 +#define DDRSS_DDRPHY_DX0GCR5 0x00000714 +#define DDRSS_DDRPHY_DX0GCR6 0x00000718 +#define DDRSS_DDRPHY_DX0GCR7 0x0000071C +#define DDRSS_DDRPHY_DX0GCR8 0x00000720 +#define DDRSS_DDRPHY_DX0GCR9 0x00000724 +#define DDRSS_DDRPHY_DX0DQMAP0 0x00000728 +#define DDRSS_DDRPHY_DX0DQMAP1 0x0000072C +#define DDRSS_DDRPHY_DX0BDLR0 0x00000740 +#define DDRSS_DDRPHY_DX0BDLR1 0x00000744 +#define DDRSS_DDRPHY_DX0BDLR2 0x00000748 +#define DDRSS_DDRPHY_DX0BDLR3 0x00000750 +#define DDRSS_DDRPHY_DX0BDLR4 0x00000754 +#define DDRSS_DDRPHY_DX0BDLR5 0x00000758 +#define DDRSS_DDRPHY_DX0BDLR6 0x00000760 +#define DDRSS_DDRPHY_DX0BDLR7 0x00000764 +#define DDRSS_DDRPHY_DX0BDLR8 0x00000768 +#define DDRSS_DDRPHY_DX0BDLR9 0x0000076C +#define DDRSS_DDRPHY_DX0LCDLR0 0x00000780 +#define DDRSS_DDRPHY_DX0LCDLR1 0x00000784 +#define DDRSS_DDRPHY_DX0LCDLR2 0x00000788 +#define DDRSS_DDRPHY_DX0LCDLR3 0x0000078C +#define DDRSS_DDRPHY_DX0LCDLR4 0x00000790 +#define DDRSS_DDRPHY_DX0LCDLR5 0x00000794 +#define DDRSS_DDRPHY_DX0MDLR0 0x000007A0 +#define DDRSS_DDRPHY_DX0MDLR1 0x000007A4 +#define DDRSS_DDRPHY_DX0GTR0 0x000007C0 +#define DDRSS_DDRPHY_DX0RSR0 0x000007D0 +#define DDRSS_DDRPHY_DX0RSR1 0x000007D4 +#define DDRSS_DDRPHY_DX0RSR2 0x000007D8 +#define DDRSS_DDRPHY_DX0RSR3 0x000007DC +#define DDRSS_DDRPHY_DX0GSR0 0x000007E0 +#define DDRSS_DDRPHY_DX0GSR1 0x000007E4 +#define DDRSS_DDRPHY_DX0GSR2 0x000007E8 +#define DDRSS_DDRPHY_DX0GSR3 0x000007EC +#define DDRSS_DDRPHY_DX0GSR4 0x000007F0 +#define DDRSS_DDRPHY_DX0GSR5 0x000007F4 +#define DDRSS_DDRPHY_DX0GSR6 0x000007F8 +#define DDRSS_DDRPHY_DX1GCR0 0x00000800 +#define DDRSS_DDRPHY_DX1GCR1 0x00000804 +#define DDRSS_DDRPHY_DX1GCR2 0x00000808 +#define DDRSS_DDRPHY_DX1GCR3 0x0000080C +#define DDRSS_DDRPHY_DX1GCR4 0x00000810 +#define DDRSS_DDRPHY_DX1GCR5 0x00000814 +#define DDRSS_DDRPHY_DX1GCR6 0x00000818 +#define DDRSS_DDRPHY_DX1GCR7 0x0000081C +#define DDRSS_DDRPHY_DX1GCR8 0x00000820 +#define DDRSS_DDRPHY_DX1GCR9 0x00000824 +#define DDRSS_DDRPHY_DX1DQMAP0 0x00000828 +#define DDRSS_DDRPHY_DX1DQMAP1 0x0000082C +#define DDRSS_DDRPHY_DX1BDLR0 0x00000840 +#define DDRSS_DDRPHY_DX1BDLR1 0x00000844 +#define DDRSS_DDRPHY_DX1BDLR2 0x00000848 +#define DDRSS_DDRPHY_DX1BDLR3 0x00000850 +#define DDRSS_DDRPHY_DX1BDLR4 0x00000854 +#define DDRSS_DDRPHY_DX1BDLR5 0x00000858 +#define DDRSS_DDRPHY_DX1BDLR6 0x00000860 +#define DDRSS_DDRPHY_DX1BDLR7 0x00000864 +#define DDRSS_DDRPHY_DX1BDLR8 0x00000868 +#define DDRSS_DDRPHY_DX1BDLR9 0x0000086C +#define DDRSS_DDRPHY_DX1LCDLR0 0x00000880 +#define DDRSS_DDRPHY_DX1LCDLR1 0x00000884 +#define DDRSS_DDRPHY_DX1LCDLR2 0x00000888 +#define DDRSS_DDRPHY_DX1LCDLR3 0x0000088C +#define DDRSS_DDRPHY_DX1LCDLR4 0x00000890 +#define DDRSS_DDRPHY_DX1LCDLR5 0x00000894 +#define DDRSS_DDRPHY_DX1MDLR0 0x000008A0 +#define DDRSS_DDRPHY_DX1MDLR1 0x000008A4 +#define DDRSS_DDRPHY_DX1GTR0 0x000008C0 +#define DDRSS_DDRPHY_DX1RSR0 0x000008D0 +#define DDRSS_DDRPHY_DX1RSR1 0x000008D4 +#define DDRSS_DDRPHY_DX1RSR2 0x000008D8 +#define DDRSS_DDRPHY_DX1RSR3 0x000008DC +#define DDRSS_DDRPHY_DX1GSR0 0x000008E0 +#define DDRSS_DDRPHY_DX1GSR1 0x000008E4 +#define DDRSS_DDRPHY_DX1GSR2 0x000008E8 +#define DDRSS_DDRPHY_DX1GSR3 0x000008EC +#define DDRSS_DDRPHY_DX1GSR4 0x000008F0 +#define DDRSS_DDRPHY_DX1GSR5 0x000008F4 +#define DDRSS_DDRPHY_DX1GSR6 0x000008F8 +#define DDRSS_DDRPHY_DX2GCR0 0x00000900 +#define DDRSS_DDRPHY_DX2GCR1 0x00000904 +#define DDRSS_DDRPHY_DX2GCR2 0x00000908 +#define DDRSS_DDRPHY_DX2GCR3 0x0000090C +#define DDRSS_DDRPHY_DX2GCR4 0x00000910 +#define DDRSS_DDRPHY_DX2GCR5 0x00000914 +#define DDRSS_DDRPHY_DX2GCR6 0x00000918 +#define DDRSS_DDRPHY_DX2GCR7 0x0000091C +#define DDRSS_DDRPHY_DX2GCR8 0x00000920 +#define DDRSS_DDRPHY_DX2GCR9 0x00000924 +#define DDRSS_DDRPHY_DX2DQMAP0 0x00000928 +#define DDRSS_DDRPHY_DX2DQMAP1 0x0000092C +#define DDRSS_DDRPHY_DX2BDLR0 0x00000940 +#define DDRSS_DDRPHY_DX2BDLR1 0x00000944 +#define DDRSS_DDRPHY_DX2BDLR2 0x00000948 +#define DDRSS_DDRPHY_DX2BDLR3 0x00000950 +#define DDRSS_DDRPHY_DX2BDLR4 0x00000954 +#define DDRSS_DDRPHY_DX2BDLR5 0x00000958 +#define DDRSS_DDRPHY_DX2BDLR6 0x00000960 +#define DDRSS_DDRPHY_DX2BDLR7 0x00000964 +#define DDRSS_DDRPHY_DX2BDLR8 0x00000968 +#define DDRSS_DDRPHY_DX2BDLR9 0x0000096C +#define DDRSS_DDRPHY_DX2LCDLR0 0x00000980 +#define DDRSS_DDRPHY_DX2LCDLR1 0x00000984 +#define DDRSS_DDRPHY_DX2LCDLR2 0x00000988 +#define DDRSS_DDRPHY_DX2LCDLR3 0x0000098C +#define DDRSS_DDRPHY_DX2LCDLR4 0x00000990 +#define DDRSS_DDRPHY_DX2LCDLR5 0x00000994 +#define DDRSS_DDRPHY_DX2MDLR0 0x000009A0 +#define DDRSS_DDRPHY_DX2MDLR1 0x000009A4 +#define DDRSS_DDRPHY_DX2GTR0 0x000009C0 +#define DDRSS_DDRPHY_DX2RSR0 0x000009D0 +#define DDRSS_DDRPHY_DX2RSR1 0x000009D4 +#define DDRSS_DDRPHY_DX2RSR2 0x000009D8 +#define DDRSS_DDRPHY_DX2RSR3 0x000009DC +#define DDRSS_DDRPHY_DX2GSR0 0x000009E0 +#define DDRSS_DDRPHY_DX2GSR1 0x000009E4 +#define DDRSS_DDRPHY_DX2GSR2 0x000009E8 +#define DDRSS_DDRPHY_DX2GSR3 0x000009EC +#define DDRSS_DDRPHY_DX2GSR4 0x000009F0 +#define DDRSS_DDRPHY_DX2GSR5 0x000009F4 +#define DDRSS_DDRPHY_DX2GSR6 0x000009F8 +#define DDRSS_DDRPHY_DX3GCR0 0x00000A00 +#define DDRSS_DDRPHY_DX3GCR1 0x00000A04 +#define DDRSS_DDRPHY_DX3GCR2 0x00000A08 +#define DDRSS_DDRPHY_DX3GCR3 0x00000A0C +#define DDRSS_DDRPHY_DX3GCR4 0x00000A10 +#define DDRSS_DDRPHY_DX3GCR5 0x00000A14 +#define DDRSS_DDRPHY_DX3GCR6 0x00000A18 +#define DDRSS_DDRPHY_DX3GCR7 0x00000A1C +#define DDRSS_DDRPHY_DX3GCR8 0x00000A20 +#define DDRSS_DDRPHY_DX3GCR9 0x00000A24 +#define DDRSS_DDRPHY_DX3DQMAP0 0x00000A28 +#define DDRSS_DDRPHY_DX3DQMAP1 0x00000A2C +#define DDRSS_DDRPHY_DX3BDLR0 0x00000A40 +#define DDRSS_DDRPHY_DX3BDLR1 0x00000A44 +#define DDRSS_DDRPHY_DX3BDLR2 0x00000A48 +#define DDRSS_DDRPHY_DX3BDLR3 0x00000A50 +#define DDRSS_DDRPHY_DX3BDLR4 0x00000A54 +#define DDRSS_DDRPHY_DX3BDLR5 0x00000A58 +#define DDRSS_DDRPHY_DX3BDLR6 0x00000A60 +#define DDRSS_DDRPHY_DX3BDLR7 0x00000A64 +#define DDRSS_DDRPHY_DX3BDLR8 0x00000A68 +#define DDRSS_DDRPHY_DX3BDLR9 0x00000A6C +#define DDRSS_DDRPHY_DX3LCDLR0 0x00000A80 +#define DDRSS_DDRPHY_DX3LCDLR1 0x00000A84 +#define DDRSS_DDRPHY_DX3LCDLR2 0x00000A88 +#define DDRSS_DDRPHY_DX3LCDLR3 0x00000A8C +#define DDRSS_DDRPHY_DX3LCDLR4 0x00000A90 +#define DDRSS_DDRPHY_DX3LCDLR5 0x00000A94 +#define DDRSS_DDRPHY_DX3MDLR0 0x00000AA0 +#define DDRSS_DDRPHY_DX3MDLR1 0x00000AA4 +#define DDRSS_DDRPHY_DX3GTR0 0x00000AC0 +#define DDRSS_DDRPHY_DX3RSR0 0x00000AD0 +#define DDRSS_DDRPHY_DX3RSR1 0x00000AD4 +#define DDRSS_DDRPHY_DX3RSR2 0x00000AD8 +#define DDRSS_DDRPHY_DX3RSR3 0x00000ADC +#define DDRSS_DDRPHY_DX3GSR0 0x00000AE0 +#define DDRSS_DDRPHY_DX3GSR1 0x00000AE4 +#define DDRSS_DDRPHY_DX3GSR2 0x00000AE8 +#define DDRSS_DDRPHY_DX3GSR3 0x00000AEC +#define DDRSS_DDRPHY_DX3GSR4 0x00000AF0 +#define DDRSS_DDRPHY_DX3GSR5 0x00000AF4 +#define DDRSS_DDRPHY_DX3GSR6 0x00000AF8 +#define DDRSS_DDRPHY_DX4GCR0 0x00000B00 +#define DDRSS_DDRPHY_DX4GCR1 0x00000B04 +#define DDRSS_DDRPHY_DX4GCR2 0x00000B08 +#define DDRSS_DDRPHY_DX4GCR3 0x00000B0C +#define DDRSS_DDRPHY_DX4GCR4 0x00000B10 +#define DDRSS_DDRPHY_DX4GCR5 0x00000B14 +#define DDRSS_DDRPHY_DX4GCR6 0x00000B18 +#define DDRSS_DDRPHY_DX4GCR7 0x00000B1C +#define DDRSS_DDRPHY_DX4GCR8 0x00000B20 +#define DDRSS_DDRPHY_DX4GCR9 0x00000B24 +#define DDRSS_DDRPHY_DX4DQMAP0 0x00000B28 +#define DDRSS_DDRPHY_DX4DQMAP1 0x00000B2C +#define DDRSS_DDRPHY_DX4BDLR0 0x00000B40 +#define DDRSS_DDRPHY_DX4BDLR1 0x00000B44 +#define DDRSS_DDRPHY_DX4BDLR2 0x00000B48 +#define DDRSS_DDRPHY_DX4BDLR3 0x00000B50 +#define DDRSS_DDRPHY_DX4BDLR4 0x00000B54 +#define DDRSS_DDRPHY_DX4BDLR5 0x00000B58 +#define DDRSS_DDRPHY_DX4BDLR6 0x00000B60 +#define DDRSS_DDRPHY_DX4BDLR7 0x00000B64 +#define DDRSS_DDRPHY_DX4BDLR8 0x00000B68 +#define DDRSS_DDRPHY_DX4BDLR9 0x00000B6C +#define DDRSS_DDRPHY_DX4LCDLR0 0x00000B80 +#define DDRSS_DDRPHY_DX4LCDLR1 0x00000B84 +#define DDRSS_DDRPHY_DX4LCDLR2 0x00000B88 +#define DDRSS_DDRPHY_DX4LCDLR3 0x00000B8C +#define DDRSS_DDRPHY_DX4LCDLR4 0x00000B90 +#define DDRSS_DDRPHY_DX4LCDLR5 0x00000B94 +#define DDRSS_DDRPHY_DX4MDLR0 0x00000BA0 +#define DDRSS_DDRPHY_DX4MDLR1 0x00000BA4 +#define DDRSS_DDRPHY_DX4GTR0 0x00000BC0 +#define DDRSS_DDRPHY_DX4RSR0 0x00000BD0 +#define DDRSS_DDRPHY_DX4RSR1 0x00000BD4 +#define DDRSS_DDRPHY_DX4RSR2 0x00000BD8 +#define DDRSS_DDRPHY_DX4RSR3 0x00000BDC +#define DDRSS_DDRPHY_DX4GSR0 0x00000BE0 +#define DDRSS_DDRPHY_DX4GSR1 0x00000BE4 +#define DDRSS_DDRPHY_DX4GSR2 0x00000BE8 +#define DDRSS_DDRPHY_DX4GSR3 0x00000BEC +#define DDRSS_DDRPHY_DX4GSR4 0x00000BF0 +#define DDRSS_DDRPHY_DX4GSR5 0x00000BF4 +#define DDRSS_DDRPHY_DX4GSR6 0x00000BF8 +#define DDRSS_DDRPHY_DX5GCR0 0x00000C00 +#define DDRSS_DDRPHY_DX5GCR1 0x00000C04 +#define DDRSS_DDRPHY_DX5GCR2 0x00000C08 +#define DDRSS_DDRPHY_DX5GCR3 0x00000C0C +#define DDRSS_DDRPHY_DX5GCR4 0x00000C10 +#define DDRSS_DDRPHY_DX5GCR5 0x00000C14 +#define DDRSS_DDRPHY_DX5GCR6 0x00000C18 +#define DDRSS_DDRPHY_DX5GCR7 0x00000C1C +#define DDRSS_DDRPHY_DX5GCR8 0x00000C20 +#define DDRSS_DDRPHY_DX5GCR9 0x00000C24 +#define DDRSS_DDRPHY_DX5DQMAP0 0x00000C28 +#define DDRSS_DDRPHY_DX5DQMAP1 0x00000C2C +#define DDRSS_DDRPHY_DX5BDLR0 0x00000C40 +#define DDRSS_DDRPHY_DX5BDLR1 0x00000C44 +#define DDRSS_DDRPHY_DX5BDLR2 0x00000C48 +#define DDRSS_DDRPHY_DX5BDLR3 0x00000C50 +#define DDRSS_DDRPHY_DX5BDLR4 0x00000C54 +#define DDRSS_DDRPHY_DX5BDLR5 0x00000C58 +#define DDRSS_DDRPHY_DX5BDLR6 0x00000C60 +#define DDRSS_DDRPHY_DX5BDLR7 0x00000C64 +#define DDRSS_DDRPHY_DX5BDLR8 0x00000C68 +#define DDRSS_DDRPHY_DX5BDLR9 0x00000C6C +#define DDRSS_DDRPHY_DX5LCDLR0 0x00000C80 +#define DDRSS_DDRPHY_DX5LCDLR1 0x00000C84 +#define DDRSS_DDRPHY_DX5LCDLR2 0x00000C88 +#define DDRSS_DDRPHY_DX5LCDLR3 0x00000C8C +#define DDRSS_DDRPHY_DX5LCDLR4 0x00000C90 +#define DDRSS_DDRPHY_DX5LCDLR5 0x00000C94 +#define DDRSS_DDRPHY_DX5MDLR0 0x00000CA0 +#define DDRSS_DDRPHY_DX5MDLR1 0x00000CA4 +#define DDRSS_DDRPHY_DX5GTR0 0x00000CC0 +#define DDRSS_DDRPHY_DX5RSR0 0x00000CD0 +#define DDRSS_DDRPHY_DX5RSR1 0x00000CD4 +#define DDRSS_DDRPHY_DX5RSR2 0x00000CD8 +#define DDRSS_DDRPHY_DX5RSR3 0x00000CDC +#define DDRSS_DDRPHY_DX5GSR0 0x00000CE0 +#define DDRSS_DDRPHY_DX5GSR1 0x00000CE4 +#define DDRSS_DDRPHY_DX5GSR2 0x00000CE8 +#define DDRSS_DDRPHY_DX5GSR3 0x00000CEC +#define DDRSS_DDRPHY_DX5GSR4 0x00000CF0 +#define DDRSS_DDRPHY_DX5GSR5 0x00000CF4 +#define DDRSS_DDRPHY_DX5GSR6 0x00000CF8 +#define DDRSS_DDRPHY_DX6GCR0 0x00000D00 +#define DDRSS_DDRPHY_DX6GCR1 0x00000D04 +#define DDRSS_DDRPHY_DX6GCR2 0x00000D08 +#define DDRSS_DDRPHY_DX6GCR3 0x00000D0C +#define DDRSS_DDRPHY_DX6GCR4 0x00000D10 +#define DDRSS_DDRPHY_DX6GCR5 0x00000D14 +#define DDRSS_DDRPHY_DX6GCR6 0x00000D18 +#define DDRSS_DDRPHY_DX6GCR7 0x00000D1C +#define DDRSS_DDRPHY_DX6GCR8 0x00000D20 +#define DDRSS_DDRPHY_DX6GCR9 0x00000D24 +#define DDRSS_DDRPHY_DX6DQMAP0 0x00000D28 +#define DDRSS_DDRPHY_DX6DQMAP1 0x00000D2C +#define DDRSS_DDRPHY_DX6BDLR0 0x00000D40 +#define DDRSS_DDRPHY_DX6BDLR1 0x00000D44 +#define DDRSS_DDRPHY_DX6BDLR2 0x00000D48 +#define DDRSS_DDRPHY_DX6BDLR3 0x00000D50 +#define DDRSS_DDRPHY_DX6BDLR4 0x00000D54 +#define DDRSS_DDRPHY_DX6BDLR5 0x00000D58 +#define DDRSS_DDRPHY_DX6BDLR6 0x00000D60 +#define DDRSS_DDRPHY_DX6BDLR7 0x00000D64 +#define DDRSS_DDRPHY_DX6BDLR8 0x00000D68 +#define DDRSS_DDRPHY_DX6BDLR9 0x00000D6C +#define DDRSS_DDRPHY_DX6LCDLR0 0x00000D80 +#define DDRSS_DDRPHY_DX6LCDLR1 0x00000D84 +#define DDRSS_DDRPHY_DX6LCDLR2 0x00000D88 +#define DDRSS_DDRPHY_DX6LCDLR3 0x00000D8C +#define DDRSS_DDRPHY_DX6LCDLR4 0x00000D90 +#define DDRSS_DDRPHY_DX6LCDLR5 0x00000D94 +#define DDRSS_DDRPHY_DX6MDLR0 0x00000DA0 +#define DDRSS_DDRPHY_DX6MDLR1 0x00000DA4 +#define DDRSS_DDRPHY_DX6GTR0 0x00000DC0 +#define DDRSS_DDRPHY_DX6RSR0 0x00000DD0 +#define DDRSS_DDRPHY_DX6RSR1 0x00000DD4 +#define DDRSS_DDRPHY_DX6RSR2 0x00000DD8 +#define DDRSS_DDRPHY_DX6RSR3 0x00000DDC +#define DDRSS_DDRPHY_DX6GSR0 0x00000DE0 +#define DDRSS_DDRPHY_DX6GSR1 0x00000DE4 +#define DDRSS_DDRPHY_DX6GSR2 0x00000DE8 +#define DDRSS_DDRPHY_DX6GSR3 0x00000DEC +#define DDRSS_DDRPHY_DX6GSR4 0x00000DF0 +#define DDRSS_DDRPHY_DX6GSR5 0x00000DF4 +#define DDRSS_DDRPHY_DX6GSR6 0x00000DF8 +#define DDRSS_DDRPHY_DX7GCR0 0x00000E00 +#define DDRSS_DDRPHY_DX7GCR1 0x00000E04 +#define DDRSS_DDRPHY_DX7GCR2 0x00000E08 +#define DDRSS_DDRPHY_DX7GCR3 0x00000E0C +#define DDRSS_DDRPHY_DX7GCR4 0x00000E10 +#define DDRSS_DDRPHY_DX7GCR5 0x00000E14 +#define DDRSS_DDRPHY_DX7GCR6 0x00000E18 +#define DDRSS_DDRPHY_DX7GCR7 0x00000E1C +#define DDRSS_DDRPHY_DX7GCR8 0x00000E20 +#define DDRSS_DDRPHY_DX7GCR9 0x00000E24 +#define DDRSS_DDRPHY_DX7DQMAP0 0x00000E28 +#define DDRSS_DDRPHY_DX7DQMAP1 0x00000E2C +#define DDRSS_DDRPHY_DX7BDLR0 0x00000E40 +#define DDRSS_DDRPHY_DX7BDLR1 0x00000E44 +#define DDRSS_DDRPHY_DX7BDLR2 0x00000E48 +#define DDRSS_DDRPHY_DX7BDLR3 0x00000E50 +#define DDRSS_DDRPHY_DX7BDLR4 0x00000E54 +#define DDRSS_DDRPHY_DX7BDLR5 0x00000E58 +#define DDRSS_DDRPHY_DX7BDLR6 0x00000E60 +#define DDRSS_DDRPHY_DX7BDLR7 0x00000E64 +#define DDRSS_DDRPHY_DX7BDLR8 0x00000E68 +#define DDRSS_DDRPHY_DX7BDLR9 0x00000E6C +#define DDRSS_DDRPHY_DX7LCDLR0 0x00000E80 +#define DDRSS_DDRPHY_DX7LCDLR1 0x00000E84 +#define DDRSS_DDRPHY_DX7LCDLR2 0x00000E88 +#define DDRSS_DDRPHY_DX7LCDLR3 0x00000E8C +#define DDRSS_DDRPHY_DX7LCDLR4 0x00000E90 +#define DDRSS_DDRPHY_DX7LCDLR5 0x00000E94 +#define DDRSS_DDRPHY_DX7MDLR0 0x00000EA0 +#define DDRSS_DDRPHY_DX7MDLR1 0x00000EA4 +#define DDRSS_DDRPHY_DX7GTR0 0x00000EC0 +#define DDRSS_DDRPHY_DX7RSR0 0x00000ED0 +#define DDRSS_DDRPHY_DX7RSR1 0x00000ED4 +#define DDRSS_DDRPHY_DX7RSR2 0x00000ED8 +#define DDRSS_DDRPHY_DX7RSR3 0x00000EDC +#define DDRSS_DDRPHY_DX7GSR0 0x00000EE0 +#define DDRSS_DDRPHY_DX7GSR1 0x00000EE4 +#define DDRSS_DDRPHY_DX7GSR2 0x00000EE8 +#define DDRSS_DDRPHY_DX7GSR3 0x00000EEC +#define DDRSS_DDRPHY_DX7GSR4 0x00000EF0 +#define DDRSS_DDRPHY_DX7GSR5 0x00000EF4 +#define DDRSS_DDRPHY_DX7GSR6 0x00000EF8 +#define DDRSS_DDRPHY_DX8GCR0 0x00000F00 +#define DDRSS_DDRPHY_DX8GCR1 0x00000F04 +#define DDRSS_DDRPHY_DX8GCR2 0x00000F08 +#define DDRSS_DDRPHY_DX8GCR3 0x00000F0C +#define DDRSS_DDRPHY_DX8GCR4 0x00000F10 +#define DDRSS_DDRPHY_DX8GCR5 0x00000F14 +#define DDRSS_DDRPHY_DX8GCR6 0x00000F18 +#define DDRSS_DDRPHY_DX8GCR7 0x00000F1C +#define DDRSS_DDRPHY_DX8GCR8 0x00000F20 +#define DDRSS_DDRPHY_DX8GCR9 0x00000F24 +#define DDRSS_DDRPHY_DX8DQMAP0 0x00000F28 +#define DDRSS_DDRPHY_DX8DQMAP1 0x00000F2C +#define DDRSS_DDRPHY_DX8BDLR0 0x00000F40 +#define DDRSS_DDRPHY_DX8BDLR1 0x00000F44 +#define DDRSS_DDRPHY_DX8BDLR2 0x00000F48 +#define DDRSS_DDRPHY_DX8BDLR3 0x00000F50 +#define DDRSS_DDRPHY_DX8BDLR4 0x00000F54 +#define DDRSS_DDRPHY_DX8BDLR5 0x00000F58 +#define DDRSS_DDRPHY_DX8BDLR6 0x00000F60 +#define DDRSS_DDRPHY_DX8BDLR7 0x00000F64 +#define DDRSS_DDRPHY_DX8BDLR8 0x00000F68 +#define DDRSS_DDRPHY_DX8BDLR9 0x00000F6C +#define DDRSS_DDRPHY_DX8LCDLR0 0x00000F80 +#define DDRSS_DDRPHY_DX8LCDLR1 0x00000F84 +#define DDRSS_DDRPHY_DX8LCDLR2 0x00000F88 +#define DDRSS_DDRPHY_DX8LCDLR3 0x00000F8C +#define DDRSS_DDRPHY_DX8LCDLR4 0x00000F90 +#define DDRSS_DDRPHY_DX8LCDLR5 0x00000F94 +#define DDRSS_DDRPHY_DX8MDLR0 0x00000FA0 +#define DDRSS_DDRPHY_DX8MDLR1 0x00000FA4 +#define DDRSS_DDRPHY_DX8GTR0 0x00000FC0 +#define DDRSS_DDRPHY_DX8RSR0 0x00000FD0 +#define DDRSS_DDRPHY_DX8RSR1 0x00000FD4 +#define DDRSS_DDRPHY_DX8RSR2 0x00000FD8 +#define DDRSS_DDRPHY_DX8RSR3 0x00000FDC +#define DDRSS_DDRPHY_DX8GSR0 0x00000FE0 +#define DDRSS_DDRPHY_DX8GSR1 0x00000FE4 +#define DDRSS_DDRPHY_DX8GSR2 0x00000FE8 +#define DDRSS_DDRPHY_DX8GSR3 0x00000FEC +#define DDRSS_DDRPHY_DX8GSR4 0x00000FF0 +#define DDRSS_DDRPHY_DX8GSR5 0x00000FF4 +#define DDRSS_DDRPHY_DX8GSR6 0x00000FF8 +#define DDRSS_DDRPHY_DX8SL0OSC 0x00001400 +#define DDRSS_DDRPHY_DX8SL0PLLCR0 0x00001404 +#define DDRSS_DDRPHY_DX8SL0PLLCR1 0x00001408 +#define DDRSS_DDRPHY_DX8SL0PLLCR2 0x0000140C +#define DDRSS_DDRPHY_DX8SL0PLLCR3 0x00001410 +#define DDRSS_DDRPHY_DX8SL0PLLCR4 0x00001414 +#define DDRSS_DDRPHY_DX8SL0PLLCR5 0x00001418 +#define DDRSS_DDRPHY_DX8SL0DQSCTL 0x0000141C +#define DDRSS_DDRPHY_DX8SL0TRNCTL 0x00001420 +#define DDRSS_DDRPHY_DX8SL0DDLCTL 0x00001424 +#define DDRSS_DDRPHY_DX8SL0DXCTL1 0x00001428 +#define DDRSS_DDRPHY_DX8SL0DXCTL2 0x0000142C +#define DDRSS_DDRPHY_DX8SL0IOCR 0x00001430 +#define DDRSS_DDRPHY_DX4SL0IOCR 0x00001434 +#define DDRSS_DDRPHY_DX8SL1OSC 0x00001440 +#define DDRSS_DDRPHY_DX8SL1PLLCR0 0x00001444 +#define DDRSS_DDRPHY_DX8SL1PLLCR1 0x00001448 +#define DDRSS_DDRPHY_DX8SL1PLLCR2 0x0000144C +#define DDRSS_DDRPHY_DX8SL1PLLCR3 0x00001450 +#define DDRSS_DDRPHY_DX8SL1PLLCR4 0x00001454 +#define DDRSS_DDRPHY_DX8SL1PLLCR5 0x00001458 +#define DDRSS_DDRPHY_DX8SL1DQSCTL 0x0000145C +#define DDRSS_DDRPHY_DX8SL1TRNCTL 0x00001460 +#define DDRSS_DDRPHY_DX8SL1DDLCTL 0x00001464 +#define DDRSS_DDRPHY_DX8SL1DXCTL1 0x00001468 +#define DDRSS_DDRPHY_DX8SL1DXCTL2 0x0000146C +#define DDRSS_DDRPHY_DX8SL1IOCR 0x00001470 +#define DDRSS_DDRPHY_DX4SL1IOCR 0x00001474 +#define DDRSS_DDRPHY_DX8SL2OSC 0x00001480 +#define DDRSS_DDRPHY_DX8SL2PLLCR0 0x00001484 +#define DDRSS_DDRPHY_DX8SL2PLLCR1 0x00001488 +#define DDRSS_DDRPHY_DX8SL2PLLCR2 0x0000148C +#define DDRSS_DDRPHY_DX8SL2PLLCR3 0x00001490 +#define DDRSS_DDRPHY_DX8SL2PLLCR4 0x00001494 +#define DDRSS_DDRPHY_DX8SL2PLLCR5 0x00001498 +#define DDRSS_DDRPHY_DX8SL2DQSCTL 0x0000149C +#define DDRSS_DDRPHY_DX8SL2TRNCTL 0x000014A0 +#define DDRSS_DDRPHY_DX8SL2DDLCTL 0x000014A4 +#define DDRSS_DDRPHY_DX8SL2DXCTL1 0x000014A8 +#define DDRSS_DDRPHY_DX8SL2DXCTL2 0x000014AC +#define DDRSS_DDRPHY_DX8SL2IOCR 0x000014B0 +#define DDRSS_DDRPHY_DX4SL2IOCR 0x000014B4 +#define DDRSS_DDRPHY_DX8SL3OSC 0x000014C0 +#define DDRSS_DDRPHY_DX8SL3PLLCR0 0x000014C4 +#define DDRSS_DDRPHY_DX8SL3PLLCR1 0x000014C8 +#define DDRSS_DDRPHY_DX8SL3PLLCR2 0x000014CC +#define DDRSS_DDRPHY_DX8SL3PLLCR3 0x000014D0 +#define DDRSS_DDRPHY_DX8SL3PLLCR4 0x000014D4 +#define DDRSS_DDRPHY_DX8SL3PLLCR5 0x000014D8 +#define DDRSS_DDRPHY_DX8SL3DQSCTL 0x000014DC +#define DDRSS_DDRPHY_DX8SL3TRNCTL 0x000014E0 +#define DDRSS_DDRPHY_DX8SL3DDLCTL 0x000014E4 +#define DDRSS_DDRPHY_DX8SL3DXCTL1 0x000014E8 +#define DDRSS_DDRPHY_DX8SL3DXCTL2 0x000014EC +#define DDRSS_DDRPHY_DX8SL3IOCR 0x000014F0 +#define DDRSS_DDRPHY_DX4SL3IOCR 0x000014F4 +#define DDRSS_DDRPHY_DX8SL4OSC 0x00001500 +#define DDRSS_DDRPHY_DX8SL4PLLCR0 0x00001504 +#define DDRSS_DDRPHY_DX8SL4PLLCR1 0x00001508 +#define DDRSS_DDRPHY_DX8SL4PLLCR2 0x0000150C +#define DDRSS_DDRPHY_DX8SL4PLLCR3 0x00001510 +#define DDRSS_DDRPHY_DX8SL4PLLCR4 0x00001514 +#define DDRSS_DDRPHY_DX8SL4PLLCR5 0x00001518 +#define DDRSS_DDRPHY_DX8SL4DQSCTL 0x0000151C +#define DDRSS_DDRPHY_DX8SL4TRNCTL 0x00001520 +#define DDRSS_DDRPHY_DX8SL4DDLCTL 0x00001524 +#define DDRSS_DDRPHY_DX8SL4DXCTL1 0x00001528 +#define DDRSS_DDRPHY_DX8SL4DXCTL2 0x0000152C +#define DDRSS_DDRPHY_DX8SL4IOCR 0x00001530 +#define DDRSS_DDRPHY_DX4SL4IOCR 0x00001534 +#define DDRSS_DDRPHY_DX8SL5OSC 0x00001540 +#define DDRSS_DDRPHY_DX8SL5PLLCR0 0x00001544 +#define DDRSS_DDRPHY_DX8SL5PLLCR1 0x00001548 +#define DDRSS_DDRPHY_DX8SL5PLLCR2 0x0000154C +#define DDRSS_DDRPHY_DX8SL5PLLCR3 0x00001550 +#define DDRSS_DDRPHY_DX8SL5PLLCR4 0x00001554 +#define DDRSS_DDRPHY_DX8SL5PLLCR5 0x00001558 +#define DDRSS_DDRPHY_DX8SL5DQSCTL 0x0000155C +#define DDRSS_DDRPHY_DX8SL5TRNCTL 0x00001560 +#define DDRSS_DDRPHY_DX8SL5DDLCTL 0x00001564 +#define DDRSS_DDRPHY_DX8SL5DXCTL1 0x00001568 +#define DDRSS_DDRPHY_DX8SL5DXCTL2 0x0000156C +#define DDRSS_DDRPHY_DX8SL5IOCR 0x00001570 +#define DDRSS_DDRPHY_DX4SL5IOCR 0x00001574 +#define DDRSS_DDRPHY_DX8SL6OSC 0x00001580 +#define DDRSS_DDRPHY_DX8SL6PLLCR0 0x00001584 +#define DDRSS_DDRPHY_DX8SL6PLLCR1 0x00001588 +#define DDRSS_DDRPHY_DX8SL6PLLCR2 0x0000158C +#define DDRSS_DDRPHY_DX8SL6PLLCR3 0x00001590 +#define DDRSS_DDRPHY_DX8SL6PLLCR4 0x00001594 +#define DDRSS_DDRPHY_DX8SL6PLLCR5 0x00001598 +#define DDRSS_DDRPHY_DX8SL6DQSCTL 0x0000159C +#define DDRSS_DDRPHY_DX8SL6TRNCTL 0x000015A0 +#define DDRSS_DDRPHY_DX8SL6DDLCTL 0x000015A4 +#define DDRSS_DDRPHY_DX8SL6DXCTL1 0x000015A8 +#define DDRSS_DDRPHY_DX8SL6DXCTL2 0x000015AC +#define DDRSS_DDRPHY_DX8SL6IOCR 0x000015B0 +#define DDRSS_DDRPHY_DX4SL6IOCR 0x000015B4 +#define DDRSS_DDRPHY_DX8SL7OSC 0x000015C0 +#define DDRSS_DDRPHY_DX8SL7PLLCR0 0x000015C4 +#define DDRSS_DDRPHY_DX8SL7PLLCR1 0x000015C8 +#define DDRSS_DDRPHY_DX8SL7PLLCR2 0x000015CC +#define DDRSS_DDRPHY_DX8SL7PLLCR3 0x000015D0 +#define DDRSS_DDRPHY_DX8SL7PLLCR4 0x000015D4 +#define DDRSS_DDRPHY_DX8SL7PLLCR5 0x000015D8 +#define DDRSS_DDRPHY_DX8SL7DQSCTL 0x000015DC +#define DDRSS_DDRPHY_DX8SL7TRNCTL 0x000015E0 +#define DDRSS_DDRPHY_DX8SL7DDLCTL 0x000015E4 +#define DDRSS_DDRPHY_DX8SL7DXCTL1 0x000015E8 +#define DDRSS_DDRPHY_DX8SL7DXCTL2 0x000015EC +#define DDRSS_DDRPHY_DX8SL7IOCR 0x000015F0 +#define DDRSS_DDRPHY_DX4SL7IOCR 0x000015F4 +#define DDRSS_DDRPHY_DX8SL8OSC 0x00001600 +#define DDRSS_DDRPHY_DX8SL8PLLCR0 0x00001604 +#define DDRSS_DDRPHY_DX8SL8PLLCR1 0x00001608 +#define DDRSS_DDRPHY_DX8SL8PLLCR2 0x0000160C +#define DDRSS_DDRPHY_DX8SL8PLLCR3 0x00001610 +#define DDRSS_DDRPHY_DX8SL8PLLCR4 0x00001614 +#define DDRSS_DDRPHY_DX8SL8PLLCR5 0x00001618 +#define DDRSS_DDRPHY_DX8SL8DQSCTL 0x0000161C +#define DDRSS_DDRPHY_DX8SL8TRNCTL 0x00001620 +#define DDRSS_DDRPHY_DX8SL8DDLCTL 0x00001624 +#define DDRSS_DDRPHY_DX8SL8DXCTL1 0x00001628 +#define DDRSS_DDRPHY_DX8SL8DXCTL2 0x0000162C +#define DDRSS_DDRPHY_DX8SL8IOCR 0x00001630 +#define DDRSS_DDRPHY_DX4SL8IOCR 0x00001634 +#define DDRSS_DDRPHY_DX8SLBOSC 0x000017C0 +#define DDRSS_DDRPHY_DX8SLBPLLCR0 0x000017C4 +#define DDRSS_DDRPHY_DX8SLBPLLCR1 0x000017C8 +#define DDRSS_DDRPHY_DX8SLBPLLCR2 0x000017CC +#define DDRSS_DDRPHY_DX8SLBPLLCR3 0x000017D0 +#define DDRSS_DDRPHY_DX8SLBPLLCR4 0x000017D4 +#define DDRSS_DDRPHY_DX8SLBPLLCR5 0x000017D8 +#define DDRSS_DDRPHY_DX8SLBDQSCTL 0x000017DC +#define DDRSS_DDRPHY_DX8SLBTRNCTL 0x000017E0 +#define DDRSS_DDRPHY_DX8SLBDDLCTL 0x000017E4 +#define DDRSS_DDRPHY_DX8SLBDXCTL1 0x000017E8 +#define DDRSS_DDRPHY_DX8SLBDXCTL2 0x000017EC +#define DDRSS_DDRPHY_DX8SLBIOCR 0x000017F0 +#define DDRSS_DDRPHY_DX4SLBIOCR 0x000017F4 + +#define PIR_INIT_SHIFT 0 +#define PIR_INIT_MASK BIT(PIR_INIT_SHIFT) +#define PIR_ZCAL_SHIFT 1 +#define PIR_ZCAL_MASK BIT(PIR_ZCAL_SHIFT) +#define PIR_CA_SHIFT 2 +#define PIR_CA_MASK BIT(PIR_CA_SHIFT) +#define PIR_PLLINIT_SHIFT 4 +#define PIR_PLLINIT_MASK BIT(PIR_PLLINIT_SHIFT) +#define PIR_DCAL_SHIFT 5 +#define PIR_DCAL_MASK BIT(PIR_DCAL_SHIFT) +#define PIR_PHYRST_SHIFT 6 +#define PIR_PHYRST_MASK BIT(PIR_PHYRST_SHIFT) +#define PIR_DRAMRST_SHIFT 7 +#define PIR_DRAMRST_MASK BIT(PIR_DRAMRST_SHIFT) +#define PIR_DRAMINIT_SHIFT 8 +#define PIR_DRAMINIT_MASK BIT(PIR_DRAMINIT_SHIFT) +#define PIR_WL_SHIFT 9 +#define PIR_WL_MASK BIT(PIR_WL_SHIFT) +#define PIR_QSGATE_SHIFT 10 +#define PIR_QSGATE_MASK BIT(PIR_QSGATE_SHIFT) +#define PIR_WLADJ_SHIFT 11 +#define PIR_WLADJ_MASK BIT(PIR_WLADJ_SHIFT) +#define PIR_RDDSKW_SHIFT 12 +#define PIR_RDDSKW_MASK BIT(PIR_RDDSKW_SHIFT) +#define PIR_WRDSKW_SHIFT 13 +#define PIR_WRDSKW_MASK BIT(PIR_WRDSKW_SHIFT) +#define PIR_RDEYE_SHIFT 14 +#define PIR_RDEYE_MASK BIT(PIR_RDEYE_SHIFT) +#define PIR_WREYE_SHIFT 15 +#define PIR_WREYE_MASK BIT(PIR_WREYE_SHIFT) +#define PIR_SRD_SHIFT 16 +#define PIR_SRD_MASK BIT(PIR_SRD_SHIFT) +#define PIR_VREF_SHIFT 17 +#define PIR_VREF_MASK BIT(PIR_VREF_SHIFT) +#define PIR_CTLDINIT_SHIFT 18 +#define PIR_CTLDINIT_MASK BIT(PIR_CTLDINIT_SHIFT) +#define PIR_RDIMMINIT_SHIFT 19 +#define PIR_RDIMMINIT_MASK BIT(PIR_RDIMMINIT_SHIFT) +#define PIR_DQS2DQ_SHIFT 20 +#define PIR_DQS2DQ_MASK BIT(PIR_DQS2DQ_SHIFT) +#define PIR_DCALPSE_SHIFT 29 +#define PIR_DCALPSE_MASK BIT(PIR_DCALPSE_SHIFT) +#define PIR_ZCALBYP_SHIFT 30 +#define PIR_ZCALBYP_MASK BIT(PIR_ZCALBYP_SHIFT) + +#define PIR_PHY_INIT (PIR_ZCAL_MASK | PIR_PLLINIT_MASK | \ + PIR_DCAL_MASK | PIR_PHYRST_MASK) +#define PIR_DRAM_INIT (PIR_DRAMRST_MASK | PIR_DRAMINIT_MASK) +#define PIR_DATA_TR_INIT (PIR_WL_MASK | PIR_QSGATE_MASK | \ + PIR_WLADJ_MASK | PIR_RDDSKW_MASK | \ + PIR_WRDSKW_MASK | PIR_RDEYE_MASK \ + PIR_WREYE_MASK) + +#define PGSR0_IDONE_SHIFT 0 +#define PGSR0_IDONE_MASK BIT(PGSR0_IDONE_SHIFT) +#define PGSR0_PLDONE_SHIFT 1 +#define PGSR0_PLDONE_MASK BIT(PGSR0_PLDONE_SHIFT) +#define PGSR0_DCDONE_SHIFT 2 +#define PGSR0_DCDONE_MASK BIT(PGSR0_DCDONE_SHIFT) +#define PGSR0_ZCDONE_SHIFT 3 +#define PGSR0_ZCDONE_MASK BIT(PGSR0_ZCDONE_SHIFT) +#define PGSR0_DIDONE_SHIFT 4 +#define PGSR0_DIDONE_MASK BIT(PGSR0_DIDONE_SHIFT) +#define PGSR0_WLDONE_SHIFT 5 +#define PGSR0_WLDONE_MASK BIT(PGSR0_WLDONE_SHIFT) +#define PGSR0_QSGDONE_SHIFT 6 +#define PGSR0_QSGDONE_MASK BIT(PGSR0_QSGDONE_SHIFT) +#define PGSR0_WLADONE_SHIFT 7 +#define PGSR0_WLADONE_MASK BIT(PGSR0_WLADONE_SHIFT) +#define PGSR0_RDDONE_SHIFT 8 +#define PGSR0_RDDONE_MASK BIT(PGSR0_RDDONE_SHIFT) +#define PGSR0_WDDONE_SHIFT 9 +#define PGSR0_WDDONE_MASK BIT(PGSR0_WDDONE_SHIFT) +#define PGSR0_REDONE_SHIFT 10 +#define PGSR0_REDONE_MASK BIT(PGSR0_REDONE_SHIFT) +#define PGSR0_WEDONE_SHIFT 11 +#define PGSR0_WEDONE_MASK BIT(PGSR0_WEDONE_SHIFT) +#define PGSR0_CADONE_SHIFT 12 +#define PGSR0_CADONE_MASK BIT(PGSR0_CADONE_SHIFT) +#define PGSR0_SRDDONE_SHIFT 13 +#define PGSR0_SRDDONE_MASK BIT(PGSR0_SRDDONE_SHIFT) +#define PGSR0_VDONE_SHIFT 14 +#define PGSR0_VDONE_MASK BIT(PGSR0_VDONE_SHIFT) +#define PGSR0_DQS2DQDONE_SHIFT 15 +#define PGSR0_DQS2DQDONE_MASK BIT(PGSR0_DQS2DQDONE_SHIFT) +#define PGSR0_DQS2DQERR_SHIFT 18 +#define PGSR0_DQS2DQERR_MASK BIT(PGSR0_DQS2DQERR_SHIFT) +#define PGSR0_VERR_SHIFT 19 +#define PGSR0_VERR_MASK BIT(PGSR0_VERR_SHIFT) +#define PGSR0_ZCERR_SHIFT 20 +#define PGSR0_ZCERR_MASK BIT(PGSR0_ZCERR_SHIFT) +#define PGSR0_WLERR_SHIFT 21 +#define PGSR0_WLERR_MASK BIT(PGSR0_WLERR_SHIFT) +#define PGSR0_QSGERR_SHIFT 22 +#define PGSR0_QSGERR_MASK BIT(PGSR0_QSGERR_SHIFT) +#define PGSR0_WLAERR_SHIFT 23 +#define PGSR0_WLAERR_MASK BIT(PGSR0_WLAERR_SHIFT) +#define PGSR0_RDERR_SHIFT 24 +#define PGSR0_RDERR_MASK BIT(PGSR0_RDERR_SHIFT) +#define PGSR0_WDERR_SHIFT 25 +#define PGSR0_WDERR_MASK BIT(PGSR0_WDERR_SHIFT) +#define PGSR0_REERR_SHIFT 26 +#define PGSR0_REERR_MASK BIT(PGSR0_REERR_SHIFT) +#define PGSR0_WEERR_SHIFT 27 +#define PGSR0_WEERR_MASK BIT(PGSR0_WEERR_SHIFT) +#define PGSR0_CAERR_SHIFT 28 +#define PGSR0_CAERR_MASK BIT(PGSR0_CAERR_SHIFT) +#define PGSR0_CAWRN_SHIFT 29 +#define PGSR0_CAWRN_MASK BIT(PGSR0_CAWRN_SHIFT) +#define PGSR0_SRDERR_SHIFT 30 +#define PGSR0_SRDERR_MASK BIT(PGSR0_SRDERR_SHIFT) +#define PGSR0_APLOCK_SHIFT 31 +#define PGSR0_APLOCK_MASK BIT(PGSR0_APLOCK_SHIFT) + +#define PGSR0_PHY_INIT_MASK (PGSR0_IDONE_MASK | PGSR0_PLDONE_MASK |\ + PGSR0_DCDONE_MASK | PGSR0_ZCDONE_MASK |\ + PGSR0_APLOCK_MASK) +#define PGSR0_DRAM_INIT_MASK (PGSR0_PHY_INIT_MASK | \ + PGSR0_DIDONE_MASK) +#define PGSR0_DATA_TR_INIT_MASK (PGSR0_DRAM_INIT_MASK) + +struct ddrss_ddrctl_reg_params { + u32 ddrctl_dfimisc; + u32 ddrctl_dfitmg0; + u32 ddrctl_dfitmg1; + u32 ddrctl_dfitmg2; + u32 ddrctl_init0; + u32 ddrctl_init1; + u32 ddrctl_init3; + u32 ddrctl_init4; + u32 ddrctl_init5; + u32 ddrctl_init6; + u32 ddrctl_init7; + u32 ddrctl_mstr; + u32 ddrctl_odtcfg; + u32 ddrctl_odtmap; + u32 ddrctl_rankctl; + u32 ddrctl_rfshctl0; + u32 ddrctl_rfshtmg; + u32 ddrctl_zqctl0; + u32 ddrctl_zqctl1; +}; + +struct ddrss_ddrctl_crc_params { + u32 ddrctl_crcparctl0; + u32 ddrctl_crcparctl1; + u32 ddrctl_crcparctl2; +}; + +struct ddrss_ddrctl_ecc_params { + u32 ddrctl_ecccfg0; +}; + +struct ddrss_ddrctl_map_params { + u32 ddrctl_addrmap0; + u32 ddrctl_addrmap1; + u32 ddrctl_addrmap2; + u32 ddrctl_addrmap3; + u32 ddrctl_addrmap4; + u32 ddrctl_addrmap5; + u32 ddrctl_addrmap6; + u32 ddrctl_addrmap7; + u32 ddrctl_addrmap8; + u32 ddrctl_addrmap9; + u32 ddrctl_addrmap10; + u32 ddrctl_addrmap11; + u32 ddrctl_dqmap0; + u32 ddrctl_dqmap1; + u32 ddrctl_dqmap4; + u32 ddrctl_dqmap5; +}; + +struct ddrss_ddrctl_pwr_params { + u32 ddrctl_pwrctl; +}; + +struct ddrss_ddrctl_timing_params { + u32 ddrctl_dramtmg0; + u32 ddrctl_dramtmg1; + u32 ddrctl_dramtmg2; + u32 ddrctl_dramtmg3; + u32 ddrctl_dramtmg4; + u32 ddrctl_dramtmg5; + u32 ddrctl_dramtmg6; + u32 ddrctl_dramtmg7; + u32 ddrctl_dramtmg8; + u32 ddrctl_dramtmg9; + u32 ddrctl_dramtmg11; + u32 ddrctl_dramtmg12; + u32 ddrctl_dramtmg13; + u32 ddrctl_dramtmg14; + u32 ddrctl_dramtmg15; + u32 ddrctl_dramtmg17; +}; + +struct ddrss_ddrphy_cfg_params { + u32 ddrphy_dcr; + u32 ddrphy_dsgcr; + u32 ddrphy_dx0gcr0; + u32 ddrphy_dx0gcr1; + u32 ddrphy_dx0gcr2; + u32 ddrphy_dx0gcr3; + u32 ddrphy_dx0gcr4; + u32 ddrphy_dx0gcr5; + u32 ddrphy_dx0gtr0; + u32 ddrphy_dx1gcr0; + u32 ddrphy_dx1gcr1; + u32 ddrphy_dx1gcr2; + u32 ddrphy_dx1gcr3; + u32 ddrphy_dx1gcr4; + u32 ddrphy_dx1gcr5; + u32 ddrphy_dx1gtr0; + u32 ddrphy_dx2gcr0; + u32 ddrphy_dx2gcr1; + u32 ddrphy_dx2gcr2; + u32 ddrphy_dx2gcr3; + u32 ddrphy_dx2gcr4; + u32 ddrphy_dx2gcr5; + u32 ddrphy_dx2gtr0; + u32 ddrphy_dx3gcr0; + u32 ddrphy_dx3gcr1; + u32 ddrphy_dx3gcr2; + u32 ddrphy_dx3gcr3; + u32 ddrphy_dx3gcr4; + u32 ddrphy_dx3gcr5; + u32 ddrphy_dx3gtr0; + u32 ddrphy_dx4gcr0; + u32 ddrphy_dx4gcr1; + u32 ddrphy_dx4gcr2; + u32 ddrphy_dx4gcr3; + u32 ddrphy_dx4gcr4; + u32 ddrphy_dx4gcr5; + u32 ddrphy_dx4gtr0; + u32 ddrphy_dx8sl0dxctl2; + u32 ddrphy_dx8sl0iocr; + u32 ddrphy_dx8sl0pllcr0; + u32 ddrphy_dx8sl1dxctl2; + u32 ddrphy_dx8sl1iocr; + u32 ddrphy_dx8sl1pllcr0; + u32 ddrphy_dx8sl2dxctl2; + u32 ddrphy_dx8sl2iocr; + u32 ddrphy_dx8sl2pllcr0; + u32 ddrphy_dxccr; + u32 ddrphy_odtcr; + u32 ddrphy_pgcr0; + u32 ddrphy_pgcr1; + u32 ddrphy_pgcr2; + u32 ddrphy_pgcr3; + u32 ddrphy_pgcr5; + u32 ddrphy_pgcr6; +}; + +struct ddrss_ddrphy_ctrl_params { + u32 ddrphy_dtcr0; + u32 ddrphy_dtcr1; + u32 ddrphy_mr0; + u32 ddrphy_mr1; + u32 ddrphy_mr2; + u32 ddrphy_mr3; + u32 ddrphy_mr4; + u32 ddrphy_mr5; + u32 ddrphy_mr6; + u32 ddrphy_mr11; + u32 ddrphy_mr12; + u32 ddrphy_mr13; + u32 ddrphy_mr14; + u32 ddrphy_mr22; + u32 ddrphy_pllcr0; + u32 ddrphy_vtcr0; +}; + +struct ddrss_ddrphy_ioctl_params { + u32 ddrphy_aciocr5; + u32 ddrphy_iovcr0; +}; + +struct ddrss_ddrphy_timing_params { + u32 ddrphy_dtpr0; + u32 ddrphy_dtpr1; + u32 ddrphy_dtpr2; + u32 ddrphy_dtpr3; + u32 ddrphy_dtpr4; + u32 ddrphy_dtpr5; + u32 ddrphy_dtpr6; + u32 ddrphy_ptr2; + u32 ddrphy_ptr3; + u32 ddrphy_ptr4; + u32 ddrphy_ptr5; + u32 ddrphy_ptr6; +}; + +struct ddrss_ddrphy_zq_params { + u32 ddrphy_zq0pr0; + u32 ddrphy_zq1pr0; + u32 ddrphy_zqcr; +}; + +struct ddrss_params { + struct ddrss_ddrctl_reg_params ctl_reg; + struct ddrss_ddrctl_crc_params ctl_crc; + struct ddrss_ddrctl_ecc_params ctl_ecc; + struct ddrss_ddrctl_map_params ctl_map; + struct ddrss_ddrctl_pwr_params ctl_pwr; + struct ddrss_ddrctl_timing_params ctl_timing; + struct ddrss_ddrphy_cfg_params phy_cfg; + struct ddrss_ddrphy_ctrl_params phy_ctrl; + struct ddrss_ddrphy_ioctl_params phy_ioctl; + struct ddrss_ddrphy_timing_params phy_timing; + struct ddrss_ddrphy_zq_params phy_zq; +}; + +#endif /* __K3_AM654_DDRSS_H */ diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 597db4b9cb..6625a65b58 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -500,6 +500,12 @@ config BCM6345_SERIAL help Select this to enable UART on BCM6345 SoCs. +config BCM6858_SERIAL + bool "Support for BCM6858 UART" + depends on DM_SERIAL && ARCH_BCM6858 + help + Select this to enable UART on BCM6358 SoCs. + config FSL_LINFLEXUART bool "Freescale Linflex UART support" depends on DM_SERIAL diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 03dc29ee2e..a48458f955 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -35,6 +35,7 @@ obj-$(CONFIG_AR933X_UART) += serial_ar933x.o obj-$(CONFIG_ARM_DCC) += arm_dcc.o obj-$(CONFIG_ATMEL_USART) += atmel_usart.o obj-$(CONFIG_BCM6345_SERIAL) += serial_bcm6345.o +obj-$(CONFIG_BCM6858_SERIAL) += serial_bcm6858.o obj-$(CONFIG_EFI_APP) += serial_efi.o obj-$(CONFIG_LPC32XX_HSUART) += lpc32xx_hsuart.o obj-$(CONFIG_MCFUART) += mcfuart.o diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c index 1e6fc6c668..f21c240e64 100644 --- a/drivers/serial/ns16550.c +++ b/drivers/serial/ns16550.c @@ -148,10 +148,13 @@ int ns16550_calc_divisor(NS16550_t port, int clock, int baudrate) static void NS16550_setbrg(NS16550_t com_port, int baud_divisor) { - serial_out(UART_LCR_BKSE | UART_LCRVAL, &com_port->lcr); + /* to keep serial format, read lcr before writing BKSE */ + int lcr_val = serial_in(&com_port->lcr) & ~UART_LCR_BKSE; + + serial_out(UART_LCR_BKSE | lcr_val, &com_port->lcr); serial_out(baud_divisor & 0xff, &com_port->dll); serial_out((baud_divisor >> 8) & 0xff, &com_port->dlm); - serial_out(UART_LCRVAL, &com_port->lcr); + serial_out(lcr_val, &com_port->lcr); } void NS16550_init(NS16550_t com_port, int baud_divisor) @@ -181,6 +184,8 @@ void NS16550_init(NS16550_t com_port, int baud_divisor) serial_out(UART_MCRVAL, &com_port->mcr); serial_out(ns16550_getfcr(com_port), &com_port->fcr); + /* initialize serial config to 8N1 before writing baudrate */ + serial_out(UART_LCRVAL, &com_port->lcr); if (baud_divisor != -1) NS16550_setbrg(com_port, baud_divisor); #if defined(CONFIG_ARCH_OMAP2PLUS) || defined(CONFIG_SOC_DA8XX) || \ @@ -348,6 +353,39 @@ static int ns16550_serial_setbrg(struct udevice *dev, int baudrate) return 0; } +static int ns16550_serial_setconfig(struct udevice *dev, uint serial_config) +{ + struct NS16550 *const com_port = dev_get_priv(dev); + int lcr_val = UART_LCR_WLS_8; + uint parity = SERIAL_GET_PARITY(serial_config); + uint bits = SERIAL_GET_BITS(serial_config); + uint stop = SERIAL_GET_STOP(serial_config); + + /* + * only parity config is implemented, check if other serial settings + * are the default one. + */ + if (bits != SERIAL_8_BITS || stop != SERIAL_ONE_STOP) + return -ENOTSUPP; /* not supported in driver*/ + + switch (parity) { + case SERIAL_PAR_NONE: + /* no bits to add */ + break; + case SERIAL_PAR_ODD: + lcr_val |= UART_LCR_PEN; + break; + case SERIAL_PAR_EVEN: + lcr_val |= UART_LCR_PEN | UART_LCR_EPS; + break; + default: + return -ENOTSUPP; /* not supported in driver*/ + } + + serial_out(lcr_val, &com_port->lcr); + return 0; +} + int ns16550_serial_probe(struct udevice *dev) { struct NS16550 *const com_port = dev_get_priv(dev); @@ -454,6 +492,7 @@ const struct dm_serial_ops ns16550_serial_ops = { .pending = ns16550_serial_pending, .getc = ns16550_serial_getc, .setbrg = ns16550_serial_setbrg, + .setconfig = ns16550_serial_setconfig }; #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) diff --git a/drivers/serial/serial_bcm6858.c b/drivers/serial/serial_bcm6858.c new file mode 100644 index 0000000000..8aa37055f0 --- /dev/null +++ b/drivers/serial/serial_bcm6858.c @@ -0,0 +1,300 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Philippe Reynes <philippe.reynes@softathome.com> + * + * Derived from linux/drivers/tty/serial/bcm63xx_uart.c: + * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> + * Derived from linux/drivers/tty/serial/serial_bcm6345.c + * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com> + */ + +#include <clk.h> +#include <dm.h> +#include <debug_uart.h> +#include <errno.h> +#include <serial.h> +#include <asm/io.h> +#include <asm/types.h> + +/* UART Control register */ +#define UART_CTL_REG 0x0 +#define UART_CTL_RXTIMEOUT_MASK 0x1f +#define UART_CTL_RXTIMEOUT_5 0x5 +#define UART_CTL_RSTRXFIFO_SHIFT 6 +#define UART_CTL_RSTRXFIFO_MASK (1 << UART_CTL_RSTRXFIFO_SHIFT) +#define UART_CTL_RSTTXFIFO_SHIFT 7 +#define UART_CTL_RSTTXFIFO_MASK (1 << UART_CTL_RSTTXFIFO_SHIFT) +#define UART_CTL_STOPBITS_SHIFT 8 +#define UART_CTL_STOPBITS_MASK (0xf << UART_CTL_STOPBITS_SHIFT) +#define UART_CTL_STOPBITS_1 (0x7 << UART_CTL_STOPBITS_SHIFT) +#define UART_CTL_BITSPERSYM_SHIFT 12 +#define UART_CTL_BITSPERSYM_MASK (0x3 << UART_CTL_BITSPERSYM_SHIFT) +#define UART_CTL_BITSPERSYM_8 (0x3 << UART_CTL_BITSPERSYM_SHIFT) +#define UART_CTL_XMITBRK_SHIFT 14 +#define UART_CTL_XMITBRK_MASK (1 << UART_CTL_XMITBRK_SHIFT) +#define UART_CTL_RSVD_SHIFT 15 +#define UART_CTL_RSVD_MASK (1 << UART_CTL_RSVD_SHIFT) +#define UART_CTL_RXPAREVEN_SHIFT 16 +#define UART_CTL_RXPAREVEN_MASK (1 << UART_CTL_RXPAREVEN_SHIFT) +#define UART_CTL_RXPAREN_SHIFT 17 +#define UART_CTL_RXPAREN_MASK (1 << UART_CTL_RXPAREN_SHIFT) +#define UART_CTL_TXPAREVEN_SHIFT 18 +#define UART_CTL_TXPAREVEN_MASK (1 << UART_CTL_TXPAREVEN_SHIFT) +#define UART_CTL_TXPAREN_SHIFT 19 +#define UART_CTL_TXPAREN_MASK (1 << UART_CTL_TXPAREN_SHIFT) +#define UART_CTL_LOOPBACK_SHIFT 20 +#define UART_CTL_LOOPBACK_MASK (1 << UART_CTL_LOOPBACK_SHIFT) +#define UART_CTL_RXEN_SHIFT 21 +#define UART_CTL_RXEN_MASK (1 << UART_CTL_RXEN_SHIFT) +#define UART_CTL_TXEN_SHIFT 22 +#define UART_CTL_TXEN_MASK (1 << UART_CTL_TXEN_SHIFT) +#define UART_CTL_BRGEN_SHIFT 23 +#define UART_CTL_BRGEN_MASK (1 << UART_CTL_BRGEN_SHIFT) + +/* UART Baudword register */ +#define UART_BAUD_REG 0x4 + +/* UART FIFO Config register */ +#define UART_FIFO_CFG_REG 0x8 +#define UART_FIFO_CFG_RX_SHIFT 8 +#define UART_FIFO_CFG_RX_MASK (0xf << UART_FIFO_CFG_RX_SHIFT) +#define UART_FIFO_CFG_RX_4 (0x4 << UART_FIFO_CFG_RX_SHIFT) +#define UART_FIFO_CFG_TX_SHIFT 12 +#define UART_FIFO_CFG_TX_MASK (0xf << UART_FIFO_CFG_TX_SHIFT) +#define UART_FIFO_CFG_TX_4 (0x4 << UART_FIFO_CFG_TX_SHIFT) + +/* UART Interrupt register */ +#define UART_IR_REG 0x10 +#define UART_IR_STAT(x) (1 << (x)) +#define UART_IR_TXEMPTY 5 +#define UART_IR_RXOVER 7 +#define UART_IR_RXNOTEMPTY 11 + +/* UART FIFO register */ +#define UART_FIFO_REG 0x14 +#define UART_FIFO_VALID_MASK 0xff +#define UART_FIFO_FRAMEERR_SHIFT 8 +#define UART_FIFO_FRAMEERR_MASK (1 << UART_FIFO_FRAMEERR_SHIFT) +#define UART_FIFO_PARERR_SHIFT 9 +#define UART_FIFO_PARERR_MASK (1 << UART_FIFO_PARERR_SHIFT) +#define UART_FIFO_BRKDET_SHIFT 10 +#define UART_FIFO_BRKDET_MASK (1 << UART_FIFO_BRKDET_SHIFT) +#define UART_FIFO_ANYERR_MASK (UART_FIFO_FRAMEERR_MASK | \ + UART_FIFO_PARERR_MASK | \ + UART_FIFO_BRKDET_MASK) + +struct bcm6858_serial_priv { + void __iomem *base; + ulong uartclk; +}; + +/* enable rx & tx operation on uart */ +static void bcm6858_serial_enable(void __iomem *base) +{ + setbits_le32(base + UART_CTL_REG, UART_CTL_BRGEN_MASK | + UART_CTL_TXEN_MASK | UART_CTL_RXEN_MASK); +} + +/* disable rx & tx operation on uart */ +static void bcm6858_serial_disable(void __iomem *base) +{ + clrbits_le32(base + UART_CTL_REG, UART_CTL_BRGEN_MASK | + UART_CTL_TXEN_MASK | UART_CTL_RXEN_MASK); +} + +/* clear all unread data in rx fifo and unsent data in tx fifo */ +static void bcm6858_serial_flush(void __iomem *base) +{ + /* empty rx and tx fifo */ + setbits_le32(base + UART_CTL_REG, UART_CTL_RSTRXFIFO_MASK | + UART_CTL_RSTTXFIFO_MASK); + + /* read any pending char to make sure all irq status are cleared */ + readl(base + UART_FIFO_REG); +} + +static int bcm6858_serial_init(void __iomem *base, ulong clk, u32 baudrate) +{ + u32 val; + + /* mask all irq and flush port */ + bcm6858_serial_disable(base); + bcm6858_serial_flush(base); + + /* set uart control config */ + clrsetbits_le32(base + UART_CTL_REG, + /* clear rx timeout */ + UART_CTL_RXTIMEOUT_MASK | + /* clear stop bits */ + UART_CTL_STOPBITS_MASK | + /* clear bits per symbol */ + UART_CTL_BITSPERSYM_MASK | + /* clear xmit break */ + UART_CTL_XMITBRK_MASK | + /* clear reserved bit */ + UART_CTL_RSVD_MASK | + /* disable parity */ + UART_CTL_RXPAREN_MASK | + UART_CTL_TXPAREN_MASK | + /* disable loopback */ + UART_CTL_LOOPBACK_MASK, + /* set timeout to 5 */ + UART_CTL_RXTIMEOUT_5 | + /* set 8 bits/symbol */ + UART_CTL_BITSPERSYM_8 | + /* set 1 stop bit */ + UART_CTL_STOPBITS_1 | + /* set parity to even */ + UART_CTL_RXPAREVEN_MASK | + UART_CTL_TXPAREVEN_MASK); + + /* set uart fifo config */ + clrsetbits_le32(base + UART_FIFO_CFG_REG, + /* clear fifo config */ + UART_FIFO_CFG_RX_MASK | + UART_FIFO_CFG_TX_MASK, + /* set fifo config to 4 */ + UART_FIFO_CFG_RX_4 | + UART_FIFO_CFG_TX_4); + + /* set baud rate */ + val = ((clk / baudrate) >> 4); + if (val & 0x1) + val = (val >> 1); + else + val = (val >> 1) - 1; + writel(val, base + UART_BAUD_REG); + + /* clear interrupts */ + writel(0, base + UART_IR_REG); + + /* enable uart */ + bcm6858_serial_enable(base); + + return 0; +} + +static int bcm6858_serial_pending(struct udevice *dev, bool input) +{ + struct bcm6858_serial_priv *priv = dev_get_priv(dev); + u32 val = readl(priv->base + UART_IR_REG); + + if (input) + return !!(val & UART_IR_STAT(UART_IR_RXNOTEMPTY)); + else + return !(val & UART_IR_STAT(UART_IR_TXEMPTY)); +} + +static int bcm6858_serial_setbrg(struct udevice *dev, int baudrate) +{ + struct bcm6858_serial_priv *priv = dev_get_priv(dev); + + return bcm6858_serial_init(priv->base, priv->uartclk, baudrate); +} + +static int bcm6858_serial_putc(struct udevice *dev, const char ch) +{ + struct bcm6858_serial_priv *priv = dev_get_priv(dev); + u32 val; + + val = readl(priv->base + UART_IR_REG); + if (!(val & UART_IR_STAT(UART_IR_TXEMPTY))) + return -EAGAIN; + + writel(ch, priv->base + UART_FIFO_REG); + + return 0; +} + +static int bcm6858_serial_getc(struct udevice *dev) +{ + struct bcm6858_serial_priv *priv = dev_get_priv(dev); + u32 val; + + val = readl(priv->base + UART_IR_REG); + if (val & UART_IR_STAT(UART_IR_RXOVER)) + setbits_le32(priv->base + UART_CTL_REG, + UART_CTL_RSTRXFIFO_MASK); + + if (!(val & UART_IR_STAT(UART_IR_RXNOTEMPTY))) + return -EAGAIN; + + val = readl(priv->base + UART_FIFO_REG); + if (val & UART_FIFO_ANYERR_MASK) + return -EAGAIN; + + return val & UART_FIFO_VALID_MASK; +} + +static int bcm6858_serial_probe(struct udevice *dev) +{ + struct bcm6858_serial_priv *priv = dev_get_priv(dev); + struct clk clk; + int ret; + + /* get address */ + priv->base = dev_remap_addr(dev); + if (!priv->base) + return -EINVAL; + + /* get clock rate */ + ret = clk_get_by_index(dev, 0, &clk); + if (ret < 0) + return ret; + priv->uartclk = clk_get_rate(&clk); + clk_free(&clk); + + /* initialize serial */ + return bcm6858_serial_init(priv->base, priv->uartclk, CONFIG_BAUDRATE); +} + +static const struct dm_serial_ops bcm6858_serial_ops = { + .putc = bcm6858_serial_putc, + .pending = bcm6858_serial_pending, + .getc = bcm6858_serial_getc, + .setbrg = bcm6858_serial_setbrg, +}; + +static const struct udevice_id bcm6858_serial_ids[] = { + { .compatible = "brcm,bcm6858-uart" }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(bcm6858_serial) = { + .name = "bcm6858-uart", + .id = UCLASS_SERIAL, + .of_match = bcm6858_serial_ids, + .probe = bcm6858_serial_probe, + .priv_auto_alloc_size = sizeof(struct bcm6858_serial_priv), + .ops = &bcm6858_serial_ops, + .flags = DM_FLAG_PRE_RELOC, +}; + +#ifdef CONFIG_DEBUG_UART_BCM6858 +static inline void _debug_uart_init(void) +{ + void __iomem *base = (void __iomem *)CONFIG_DEBUG_UART_BASE; + + bcm6858_serial_init(base, CONFIG_DEBUG_UART_CLOCK, CONFIG_BAUDRATE); +} + +static inline void wait_xfered(void __iomem *base) +{ + do { + u32 val = readl(base + UART_IR_REG); + if (val & UART_IR_STAT(UART_IR_TXEMPTY)) + break; + } while (1); +} + +static inline void _debug_uart_putc(int ch) +{ + void __iomem *base = (void __iomem *)CONFIG_DEBUG_UART_BASE; + + wait_xfered(base); + writel(ch, base + UART_FIFO_REG); + wait_xfered(base); +} + +DEBUG_UART_FUNCS +#endif diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c index b84255bd27..2bc289a74c 100644 --- a/drivers/spi/spi-uclass.c +++ b/drivers/spi/spi-uclass.c @@ -15,6 +15,8 @@ DECLARE_GLOBAL_DATA_PTR; +#define SPI_DEFAULT_SPEED_HZ 100000 + static int spi_set_speed_mode(struct udevice *bus, int speed, int mode) { struct dm_spi_ops *ops; @@ -58,7 +60,7 @@ int dm_spi_claim_bus(struct udevice *dev) speed = spi->max_hz; } if (!speed) - speed = 100000; + speed = SPI_DEFAULT_SPEED_HZ; if (speed != slave->speed) { int ret = spi_set_speed_mode(bus, speed, slave->mode); @@ -300,7 +302,13 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode, } plat = dev_get_parent_platdata(dev); plat->cs = cs; - plat->max_hz = speed; + if (speed) { + plat->max_hz = speed; + } else { + printf("Warning: SPI speed fallback to %u kHz\n", + SPI_DEFAULT_SPEED_HZ / 1000); + plat->max_hz = SPI_DEFAULT_SPEED_HZ; + } plat->mode = mode; created = true; } else if (ret) { @@ -374,7 +382,8 @@ int spi_slave_ofdata_to_platdata(struct udevice *dev, int value; plat->cs = dev_read_u32_default(dev, "reg", -1); - plat->max_hz = dev_read_u32_default(dev, "spi-max-frequency", 0); + plat->max_hz = dev_read_u32_default(dev, "spi-max-frequency", + SPI_DEFAULT_SPEED_HZ); if (dev_read_bool(dev, "spi-cpol")) mode |= SPI_CPOL; if (dev_read_bool(dev, "spi-cpha")) diff --git a/drivers/tpm/tpm_tis_sandbox.c b/drivers/tpm/tpm_tis_sandbox.c index 79517f015a..3336f559e5 100644 --- a/drivers/tpm/tpm_tis_sandbox.c +++ b/drivers/tpm/tpm_tis_sandbox.c @@ -187,9 +187,11 @@ static int sandbox_tpm_xfer(struct udevice *dev, const uint8_t *sendbuf, code = get_unaligned_be32(sendbuf + sizeof(uint16_t) + sizeof(uint32_t)); +#ifdef DEBUG printf("tpm: %zd bytes, recv_len %zd, cmd = %x\n", send_size, *recv_len, code); print_buffer(0, sendbuf, 1, send_size, 0); +#endif switch (code) { case TPM_CMD_GET_CAPABILITY: type = get_unaligned_be32(sendbuf + 14); @@ -306,6 +308,10 @@ static int sandbox_tpm_xfer(struct udevice *dev, const uint8_t *sendbuf, printf("Unknown tpm command %02x\n", code); return -ENOSYS; } +#ifdef DEBUG + printf("tpm: rx recv_len %zd\n", *recv_len); + print_buffer(0, recvbuf, 1, *recv_len, 0); +#endif return 0; } diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index db40a1396b..2ca19d4049 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -352,7 +352,7 @@ static void vidconsole_escape_char(struct udevice *dev, char ch) switch (val) { case 0: /* all attributes off */ - video_set_default_colors(vid_priv); + video_set_default_colors(dev->parent, false); break; case 1: /* bold */ diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c index 44dfa71b6f..b6551b69d3 100644 --- a/drivers/video/video-uclass.c +++ b/drivers/video/video-uclass.c @@ -115,18 +115,29 @@ int video_clear(struct udevice *dev) return 0; } -void video_set_default_colors(struct video_priv *priv) +void video_set_default_colors(struct udevice *dev, bool invert) { + struct video_priv *priv = dev_get_uclass_priv(dev); + int fore, back; + #ifdef CONFIG_SYS_WHITE_ON_BLACK /* White is used when switching to bold, use light gray here */ - priv->fg_col_idx = VID_LIGHT_GRAY; - priv->colour_fg = vid_console_color(priv, VID_LIGHT_GRAY); - priv->colour_bg = vid_console_color(priv, VID_BLACK); + fore = VID_LIGHT_GRAY; + back = VID_BLACK; #else - priv->fg_col_idx = VID_BLACK; - priv->colour_fg = vid_console_color(priv, VID_BLACK); - priv->colour_bg = vid_console_color(priv, VID_WHITE); + fore = VID_BLACK; + back = VID_WHITE; #endif + if (invert) { + int temp; + + temp = fore; + fore = back; + back = temp; + } + priv->fg_col_idx = fore; + priv->colour_fg = vid_console_color(priv, fore); + priv->colour_bg = vid_console_color(priv, back); } /* Flush video activity to the caches */ @@ -219,7 +230,7 @@ static int video_post_probe(struct udevice *dev) priv->fb_size = priv->line_length * priv->ysize; /* Set up colors */ - video_set_default_colors(priv); + video_set_default_colors(dev, false); if (!CONFIG_IS_ENABLED(NO_FB_CLEAR)) video_clear(dev); diff --git a/drivers/w1-eeprom/Kconfig b/drivers/w1-eeprom/Kconfig index 4b7f3c4e0b..34aca4b900 100644 --- a/drivers/w1-eeprom/Kconfig +++ b/drivers/w1-eeprom/Kconfig @@ -18,6 +18,19 @@ config W1_EEPROM_DS24XXX help Maxim DS24 EEPROMs 1-Wire EEPROM support +config W1_EEPROM_DS2502 + bool "Enable Maxim DS2502 Add-Only Memory support" + depends on W1 + help + Maxim DS2502 1-Wire add-only memory support. + This device has 128 bytes of data memory, organized as 4 pages of + 32 bytes and 8 out of band status bytes that may be used to redirect + pages, allowing data to be modified up to 4 times (by external + programming). + + The device may be seen as a 32 byte memory, using the page redirection + or as a 128 byte memory, ignoring the page redirection. + config W1_EEPROM_SANDBOX bool "Enable sandbox onewire EEPROM driver" depends on W1 diff --git a/drivers/w1-eeprom/Makefile b/drivers/w1-eeprom/Makefile index 03cc4c8ac8..83f4008bb5 100644 --- a/drivers/w1-eeprom/Makefile +++ b/drivers/w1-eeprom/Makefile @@ -1,5 +1,6 @@ obj-$(CONFIG_W1_EEPROM) += w1-eeprom-uclass.o obj-$(CONFIG_W1_EEPROM_DS24XXX) += ds24xxx.o +obj-$(CONFIG_W1_EEPROM_DS2502) += ds2502.o obj-$(CONFIG_W1_EEPROM_SANDBOX) += eep_sandbox.o diff --git a/drivers/w1-eeprom/ds2502.c b/drivers/w1-eeprom/ds2502.c new file mode 100644 index 0000000000..76ca460ed7 --- /dev/null +++ b/drivers/w1-eeprom/ds2502.c @@ -0,0 +1,244 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Driver for DS-2502 One wire "Add only Memory". + * + * The chip has 4 pages of 32 bytes. + * In addition it has 8 out of band status bytes that are used, by software, + * as page redirection bytes by an algorithm described in the data sheet. + * This is useful since data cannot be erased once written but it can be + * "patched" up to four times by switching pages. + * + * So, when a read request is entirely in the first page automatically + * apply the page redirection bytes (which allows the device to be seen as + * a 32 byte PROM, writable 4 times). + * + * If the read request is outside of or larger than the first page then read + * the raw data (which allows the device to be seen as a 128 byte PROM, + * writable once). + * + * Copyright (c) 2018 Flowbird + * Martin Fuzzey <martin.fuzzey@flowbird.group> + */ + +#include <common.h> +#include <dm.h> +#include <linux/err.h> +#include <w1-eeprom.h> +#include <w1.h> + +#define DS2502_PAGE_SIZE 32 +#define DS2502_PAGE_COUNT 4 +#define DS2502_STATUS_SIZE 8 + +#define DS2502_CMD_READ_STATUS 0xAA +#define DS2502_CMD_READ_GEN_CRC 0xC3 + +/* u-boot crc8() is CCITT CRC8, we need x^8 + x^5 + x^4 + 1 LSB first */ +static unsigned int ds2502_crc8(const u8 *buf, int len) +{ + static const u8 poly = 0x8C; /* (1 + x^4 + x^5) + x^8 */ + u8 crc = 0; + int i; + + for (i = 0; i < len; i++) { + u8 data = buf[i]; + int j; + + for (j = 0; j < 8; j++) { + u8 mix = (crc ^ data) & 1; + + crc >>= 1; + if (mix) + crc ^= poly; + data >>= 1; + } + } + return crc; +} + +static int ds2502_read(struct udevice *dev, u8 cmd, + int bytes_in_page, int pos, + u8 *buf, int bytes_for_user) +{ + int retry; + int ret = 0; + + for (retry = 0; retry < 3; retry++) { + u8 pagebuf[DS2502_PAGE_SIZE + 1]; /* 1 byte for CRC8 */ + u8 crc; + int i; + + ret = w1_reset_select(dev); + if (ret) + return ret; + + /* send read to end of page and generate CRC command */ + pagebuf[0] = cmd; + pagebuf[1] = pos & 0xff; + pagebuf[2] = pos >> 8; + crc = ds2502_crc8(pagebuf, 3); + for (i = 0; i < 3; i++) + w1_write_byte(dev, pagebuf[i]); + + /* Check command CRC */ + ret = w1_read_byte(dev); + if (ret < 0) { + dev_dbg(dev, "Error %d reading command CRC\n", ret); + continue; + } + + if (ret != crc) { + dev_dbg(dev, + "bad CRC8 for cmd %02x got=%02X exp=%02X\n", + cmd, ret, crc); + ret = -EIO; + continue; + } + + /* read data and check CRC */ + ret = w1_read_buf(dev, pagebuf, bytes_in_page + 1); + if (ret < 0) { + dev_dbg(dev, "Error %d reading data\n", ret); + continue; + } + + crc = ds2502_crc8(pagebuf, bytes_in_page); + if (crc == pagebuf[bytes_in_page]) { + memcpy(buf, pagebuf, bytes_for_user); + ret = 0; + break; + } + dev_dbg(dev, "Bad CRC8 got=%02X exp=%02X pos=%04X\n", + pagebuf[bytes_in_page], crc, pos); + ret = -EIO; + } + + return ret; +} + +static inline int ds2502_read_status_bytes(struct udevice *dev, u8 *buf) +{ + return ds2502_read(dev, DS2502_CMD_READ_STATUS, + DS2502_STATUS_SIZE, 0, + buf, DS2502_STATUS_SIZE); +} + +/* + * Status bytes (from index 1) contain 1's complement page indirection + * So for N writes: + * N=1: ff ff ff ff ff ff ff 00 + * N=2: ff fe ff ff ff ff ff 00 + * N=3: ff fe fd ff ff ff ff 00 + * N=4: ff fe fd fc ff ff ff 00 + */ +static int ds2502_indirect_page(struct udevice *dev, u8 *status, int page) +{ + int page_seen = 0; + + do { + u8 sb = status[page + 1]; + + if (sb == 0xff) + break; + + page = ~sb & 0xff; + + if (page >= DS2502_PAGE_COUNT) { + dev_err(dev, + "Illegal page redirection status byte %02x\n", + sb); + return -EINVAL; + } + + if (page_seen & (1 << page)) { + dev_err(dev, "Infinite loop in page redirection\n"); + return -EINVAL; + } + + page_seen |= (1 << page); + } while (1); + + return page; +} + +static int ds2502_read_buf(struct udevice *dev, unsigned int offset, + u8 *buf, unsigned int count) +{ + unsigned int min_page = offset / DS2502_PAGE_SIZE; + unsigned int max_page = (offset + count - 1) / DS2502_PAGE_SIZE; + int xfered = 0; + u8 status_bytes[DS2502_STATUS_SIZE]; + int i; + int ret; + + if (min_page >= DS2502_PAGE_COUNT || max_page >= DS2502_PAGE_COUNT) + return -EINVAL; + + if (min_page == 0 && max_page == 0) { + ret = ds2502_read_status_bytes(dev, status_bytes); + if (ret) + return ret; + } else { + /* Dummy one to one page redirection */ + memset(status_bytes, 0xff, sizeof(status_bytes)); + } + + for (i = min_page; i <= max_page; i++) { + int page; + int pos; + int bytes_in_page; + int bytes_for_user; + + page = ds2502_indirect_page(dev, status_bytes, i); + if (page < 0) + return page; + dev_dbg(dev, "page logical %d => physical %d\n", i, page); + + pos = page * DS2502_PAGE_SIZE; + if (i == min_page) + pos += offset % DS2502_PAGE_SIZE; + + bytes_in_page = DS2502_PAGE_SIZE - (pos % DS2502_PAGE_SIZE); + + if (i == max_page) + bytes_for_user = count - xfered; + else + bytes_for_user = bytes_in_page; + + ret = ds2502_read(dev, DS2502_CMD_READ_GEN_CRC, + bytes_in_page, pos, + &buf[xfered], bytes_for_user); + if (ret < 0) + return ret; + + xfered += bytes_for_user; + } + + return 0; +} + +static int ds2502_probe(struct udevice *dev) +{ + struct w1_device *w1; + + w1 = dev_get_parent_platdata(dev); + w1->id = 0; + return 0; +} + +static const struct w1_eeprom_ops ds2502_ops = { + .read_buf = ds2502_read_buf, +}; + +static const struct udevice_id ds2502_id[] = { + { .compatible = "maxim,ds2502", .data = W1_FAMILY_DS2502 }, + { }, +}; + +U_BOOT_DRIVER(ds2502) = { + .name = "ds2502", + .id = UCLASS_W1_EEPROM, + .of_match = ds2502_id, + .ops = &ds2502_ops, + .probe = ds2502_probe, +}; diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 02f4e1e32f..4796da0823 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -118,4 +118,22 @@ config IMX_WATCHDOG Select this to enable the IMX and LSCH2 of Layerscape watchdog driver. +config WDT_AT91 + bool "AT91 watchdog timer support" + depends on WDT + help + Select this to enable Microchip watchdog timer, which can be found on + some AT91 devices. + +config AT91_HW_WDT_TIMEOUT + bool "AT91 watchdog timeout specified" + depends on WDT_AT91 + +config WDT_MT7621 + bool "MediaTek MT7621 watchdog timer support" + depends on WDT && ARCH_MT7620 + help + Select this to enable Ralink / Mediatek watchdog timer, + which can be found on some MediaTek chips. + endmenu diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 08406caa0f..b8f2842f7e 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -3,7 +3,7 @@ # (C) Copyright 2008 # Wolfgang Denk, DENX Software Engineering, wd@denx.de. -obj-$(CONFIG_AT91SAM9_WATCHDOG) += at91sam9_wdt.o +obj-$(CONFIG_WDT_AT91) += at91sam9_wdt.o obj-$(CONFIG_FTWDT010_WATCHDOG) += ftwdt010_wdt.o ifneq (,$(filter $(SOC), mx25 mx31 mx35 mx5 mx6 mx7 vf610)) obj-y += imx_watchdog.o @@ -23,3 +23,4 @@ obj-$(CONFIG_BCM2835_WDT) += bcm2835_wdt.o obj-$(CONFIG_WDT_ORION) += orion_wdt.o obj-$(CONFIG_WDT_CDNS) += cdns_wdt.o obj-$(CONFIG_MPC8xx_WATCHDOG) += mpc8xx_wdt.o +obj-$(CONFIG_WDT_MT7621) += mt7621_wdt.o diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c index fca2849918..13f8772e41 100644 --- a/drivers/watchdog/at91sam9_wdt.c +++ b/drivers/watchdog/at91sam9_wdt.c @@ -2,7 +2,7 @@ /* * [origin: Linux kernel drivers/watchdog/at91sam9_wdt.c] * - * Watchdog driver for Atmel AT91SAM9x processors. + * Watchdog driver for AT91SAM9x processors. * * Copyright (C) 2008 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> * Copyright (C) 2008 Renaud CERRATO r.cerrato@til-technologies.fr @@ -14,38 +14,47 @@ * write to this register. Inform Linux to it too */ -#include <common.h> -#include <watchdog.h> -#include <asm/arch/hardware.h> #include <asm/io.h> #include <asm/arch/at91_wdt.h> +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <wdt.h> + +DECLARE_GLOBAL_DATA_PTR; /* * AT91SAM9 watchdog runs a 12bit counter @ 256Hz, * use this to convert a watchdog - * value from/to milliseconds. + * value from seconds. */ -#define ms_to_ticks(t) (((t << 8) / 1000) - 1) -#define ticks_to_ms(t) (((t + 1) * 1000) >> 8) +#define WDT_SEC2TICKS(s) (((s) << 8) - 1) /* Hardware timeout in seconds */ -#if !defined(CONFIG_AT91_HW_WDT_TIMEOUT) -#define WDT_HW_TIMEOUT 2 -#else -#define WDT_HW_TIMEOUT CONFIG_AT91_HW_WDT_TIMEOUT -#endif +#define WDT_MAX_TIMEOUT 16 +#define WDT_MIN_TIMEOUT 0 +#define WDT_DEFAULT_TIMEOUT 2 + +struct at91_wdt_priv { + void __iomem *regs; + u32 regval; + u32 timeout; +}; /* * Set the watchdog time interval in 1/256Hz (write-once) * Counter is 12 bit. */ -static int at91_wdt_settimeout(unsigned int timeout) +static int at91_wdt_start(struct udevice *dev, u64 timeout_s, ulong flags) { - unsigned int reg; - at91_wdt_t *wd = (at91_wdt_t *) ATMEL_BASE_WDT; + struct at91_wdt_priv *priv = dev_get_priv(dev); + u32 timeout = WDT_SEC2TICKS(timeout_s); + + if (timeout_s > WDT_MAX_TIMEOUT || timeout_s < WDT_MIN_TIMEOUT) + timeout = priv->timeout; /* Check if disabled */ - if (readl(&wd->mr) & AT91_WDT_MR_WDDIS) { + if (readl(priv->regs + AT91_WDT_MR) & AT91_WDT_MR_WDDIS) { printf("sorry, watchdog is disabled\n"); return -1; } @@ -57,24 +66,71 @@ static int at91_wdt_settimeout(unsigned int timeout) * 4096 / 256 = 16 seconds. */ - reg = AT91_WDT_MR_WDRSTEN /* causes watchdog reset */ + priv->regval = AT91_WDT_MR_WDRSTEN /* causes watchdog reset */ | AT91_WDT_MR_WDDBGHLT /* disabled in debug mode */ | AT91_WDT_MR_WDD(0xfff) /* restart at any time */ | AT91_WDT_MR_WDV(timeout); /* timer value */ - writel(reg, &wd->mr); + writel(priv->regval, priv->regs + AT91_WDT_MR); + + return 0; +} + +static int at91_wdt_stop(struct udevice *dev) +{ + struct at91_wdt_priv *priv = dev_get_priv(dev); + + /* Disable Watchdog Timer */ + priv->regval |= AT91_WDT_MR_WDDIS; + writel(priv->regval, priv->regs + AT91_WDT_MR); return 0; } -void hw_watchdog_reset(void) +static int at91_wdt_reset(struct udevice *dev) { - at91_wdt_t *wd = (at91_wdt_t *) ATMEL_BASE_WDT; - writel(AT91_WDT_CR_WDRSTT | AT91_WDT_CR_KEY, &wd->cr); + struct at91_wdt_priv *priv = dev_get_priv(dev); + + writel(AT91_WDT_CR_WDRSTT | AT91_WDT_CR_KEY, priv->regs + AT91_WDT_CR); + + return 0; } -void hw_watchdog_init(void) +static const struct wdt_ops at91_wdt_ops = { + .start = at91_wdt_start, + .stop = at91_wdt_stop, + .reset = at91_wdt_reset, +}; + +static const struct udevice_id at91_wdt_ids[] = { + { .compatible = "atmel,at91sam9260-wdt" }, + {} +}; + +static int at91_wdt_probe(struct udevice *dev) { - /* 16 seconds timer, resets enabled */ - at91_wdt_settimeout(ms_to_ticks(WDT_HW_TIMEOUT * 1000)); + struct at91_wdt_priv *priv = dev_get_priv(dev); + + priv->regs = dev_remap_addr(dev); + if (!priv->regs) + return -EINVAL; + +#ifdef CONFIG_AT91_HW_WDT_TIMEOUT + priv->timeout = dev_read_u32_default(dev, "timeout-sec", + WDT_DEFAULT_TIMEOUT); + debug("%s: timeout %d", __func__, priv->timeout); +#endif + + debug("%s: Probing wdt%u\n", __func__, dev->seq); + + return 0; } + +U_BOOT_DRIVER(at91_wdt) = { + .name = "at91_wdt", + .id = UCLASS_WDT, + .of_match = at91_wdt_ids, + .priv_auto_alloc_size = sizeof(struct at91_wdt_priv), + .ops = &at91_wdt_ops, + .probe = at91_wdt_probe, +}; diff --git a/drivers/watchdog/mt7621_wdt.c b/drivers/watchdog/mt7621_wdt.c new file mode 100644 index 0000000000..38866141e4 --- /dev/null +++ b/drivers/watchdog/mt7621_wdt.c @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Ralink / Mediatek RT288x/RT3xxx/MT76xx built-in hardware watchdog timer + * + * Copyright (C) 2018 Stefan Roese <sr@denx.de> + * + * Based on the Linux driver version which is: + * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> + * Copyright (C) 2013 John Crispin <blogic@openwrt.org> + */ + +#include <common.h> +#include <dm.h> +#include <wdt.h> +#include <linux/io.h> + +DECLARE_GLOBAL_DATA_PTR; + +struct mt762x_wdt { + void __iomem *regs; +}; + +#define TIMER_REG_TMRSTAT 0x00 +#define TIMER_REG_TMR1CTL 0x20 +#define TIMER_REG_TMR1LOAD 0x24 + +#define TMR1CTL_ENABLE BIT(7) +#define TMR1CTL_RESTART BIT(9) +#define TMR1CTL_PRESCALE_SHIFT 16 + +static int mt762x_wdt_ping(struct mt762x_wdt *priv) +{ + writel(TMR1CTL_RESTART, priv->regs + TIMER_REG_TMRSTAT); + + return 0; +} + +static int mt762x_wdt_start(struct udevice *dev, u64 ms, ulong flags) +{ + struct mt762x_wdt *priv = dev_get_priv(dev); + + /* set the prescaler to 1ms == 1000us */ + writel(1000 << TMR1CTL_PRESCALE_SHIFT, priv->regs + TIMER_REG_TMR1CTL); + writel(ms, priv->regs + TIMER_REG_TMR1LOAD); + + setbits_le32(priv->regs + TIMER_REG_TMR1CTL, TMR1CTL_ENABLE); + + return 0; +} + +static int mt762x_wdt_stop(struct udevice *dev) +{ + struct mt762x_wdt *priv = dev_get_priv(dev); + + mt762x_wdt_ping(priv); + + clrbits_le32(priv->regs + TIMER_REG_TMR1CTL, TMR1CTL_ENABLE); + + return 0; +} + +static int mt762x_wdt_reset(struct udevice *dev) +{ + struct mt762x_wdt *priv = dev_get_priv(dev); + + mt762x_wdt_ping(priv); + + return 0; +} + +static int mt762x_wdt_probe(struct udevice *dev) +{ + struct mt762x_wdt *priv = dev_get_priv(dev); + + priv->regs = dev_remap_addr(dev); + if (!priv->regs) + return -EINVAL; + + mt762x_wdt_stop(dev); + + return 0; +} + +static const struct wdt_ops mt762x_wdt_ops = { + .start = mt762x_wdt_start, + .reset = mt762x_wdt_reset, + .stop = mt762x_wdt_stop, +}; + +static const struct udevice_id mt762x_wdt_ids[] = { + { .compatible = "mediatek,mt7621-wdt" }, + {} +}; + +U_BOOT_DRIVER(mt762x_wdt) = { + .name = "mt762x_wdt", + .id = UCLASS_WDT, + .of_match = mt762x_wdt_ids, + .probe = mt762x_wdt_probe, + .priv_auto_alloc_size = sizeof(struct mt762x_wdt), + .ops = &mt762x_wdt_ops, +}; diff --git a/dts/Makefile b/dts/Makefile index 9a9a3d5c98..cd6e9a968e 100644 --- a/dts/Makefile +++ b/dts/Makefile @@ -61,4 +61,4 @@ dtbs: $(obj)/dt.dtb $(obj)/dt-spl.dtb clean-files := dt.dtb.S dt-spl.dtb.S # Let clean descend into dts directories -subdir- += ../arch/arm/dts ../arch/microblaze/dts ../arch/mips/dts ../arch/sandbox/dts ../arch/x86/dts ../arch/powerpc/dts +subdir- += ../arch/arm/dts ../arch/microblaze/dts ../arch/mips/dts ../arch/sandbox/dts ../arch/x86/dts ../arch/powerpc/dts ../arch/riscv/dts diff --git a/examples/standalone/Makefile b/examples/standalone/Makefile index 09364d84a0..f01816f24f 100644 --- a/examples/standalone/Makefile +++ b/examples/standalone/Makefile @@ -45,6 +45,8 @@ endif # source file. ccflags-y += $(call cc-option,-fno-toplevel-reorder) +LDFLAGS_STANDALONE += -Ttext $(CONFIG_STANDALONE_LOAD_ADDR) + ######################################################################### quiet_cmd_link_lib = LD $@ @@ -54,17 +56,17 @@ $(LIB): $(LIBOBJS) FORCE $(call if_changed,link_lib) quiet_cmd_link_elf = LD $@ - cmd_link_elf = $(LD) $(LDFLAGS) -g -Ttext $(CONFIG_STANDALONE_LOAD_ADDR) \ + cmd_link_elf = $(LD) $(LDFLAGS) $(LDFLAGS_STANDALONE) -g \ -o $@ -e $(SYM_PREFIX)$(@F) $< $(LIB) $(PLATFORM_LIBGCC) $(ELF): $(obj)/%: $(obj)/%.o $(LIB) FORCE $(call if_changed,link_elf) -$(obj)/%.srec: OBJCOPYFLAGS := -O srec +$(obj)/%.srec: OBJCOPYFLAGS += -O srec $(obj)/%.srec: $(obj)/% FORCE $(call if_changed,objcopy) -$(obj)/%.bin: OBJCOPYFLAGS := -O binary +$(obj)/%.bin: OBJCOPYFLAGS += -O binary $(obj)/%.bin: $(obj)/% FORCE $(call if_changed,objcopy) diff --git a/examples/standalone/mips.lds b/examples/standalone/mips.lds deleted file mode 100644 index 163d6efefd..0000000000 --- a/examples/standalone/mips.lds +++ /dev/null @@ -1,42 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * (C) Copyright 2003 - * Wolfgang Denk Engineering, <wd@denx.de> - */ - -/* -OUTPUT_FORMAT("elf32-bigmips", "elf32-bigmips", "elf32-bigmips") -*/ -OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", "elf32-tradlittlemips") -OUTPUT_ARCH(mips) -SECTIONS -{ - .text : - { - *(.text*) - } - - . = ALIGN(4); - .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } - - . = ALIGN(4); - .data : { *(.data*) } - - . = .; - _gp = ALIGN(16) + 0x7ff0; - - .got : { - __got_start = .; - *(.got) - __got_end = .; - } - - .sdata : { *(.sdata*) } - - . = ALIGN(4); - __bss_start = .; - .sbss (NOLOAD) : { *(.sbss*) } - .bss (NOLOAD) : { *(.bss*) . = ALIGN(4); } - - _end = .; -} diff --git a/examples/standalone/mips64.lds b/examples/standalone/mips64.lds deleted file mode 100644 index d67396ab71..0000000000 --- a/examples/standalone/mips64.lds +++ /dev/null @@ -1,42 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * (C) Copyright 2003 - * Wolfgang Denk Engineering, <wd@denx.de> - */ - -/* -OUTPUT_FORMAT("elf32-bigmips", "elf32-bigmips", "elf32-bigmips") -*/ -OUTPUT_FORMAT("elf64-tradbigmips", "elf64-tradbigmips", "elf64-tradlittlemips") -OUTPUT_ARCH(mips) -SECTIONS -{ - .text : - { - *(.text*) - } - - . = ALIGN(4); - .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } - - . = ALIGN(4); - .data : { *(.data*) } - - . = .; - _gp = ALIGN(16) + 0x7ff0; - - .got : { - __got_start = .; - *(.got) - __got_end = .; - } - - .sdata : { *(.sdata*) } - - . = ALIGN(4); - __bss_start = .; - .sbss (NOLOAD) : { *(.sbss*) } - .bss (NOLOAD) : { *(.bss*) . = ALIGN(4); } - - _end = .; -} diff --git a/fs/Makefile b/fs/Makefile index bad0c2cc33..f21cd23f03 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -5,6 +5,7 @@ # Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. ifdef CONFIG_SPL_BUILD +obj-$(CONFIG_FS_LOADER) += fs.o obj-$(CONFIG_SPL_FAT_SUPPORT) += fat/ obj-$(CONFIG_SPL_EXT_SUPPORT) += ext4/ else diff --git a/fs/fat/fat.c b/fs/fat/fat.c index b08949d370..4bc3030ab8 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -725,7 +725,10 @@ static void *next_cluster(fat_itr *itr) if (itr->last_cluster) return NULL; - sect = clust_to_sect(itr->fsdata, itr->next_clust); + if (itr->fsdata->fatsize != 32 && itr->is_root) + sect = mydata->rootdir_sect; + else + sect = clust_to_sect(itr->fsdata, itr->next_clust); debug("FAT read(sect=%d), clust_size=%d, DIRENTSPERBLOCK=%zd\n", sect, itr->fsdata->clust_size, DIRENTSPERBLOCK); diff --git a/include/adc.h b/include/adc.h index d04c9c4926..5841dfb54b 100644 --- a/include/adc.h +++ b/include/adc.h @@ -219,6 +219,17 @@ int adc_channels_data(struct udevice *dev, unsigned int channel_mask, int adc_data_mask(struct udevice *dev, unsigned int *data_mask); /** + * adc_channel_mask() - get channel mask for given ADC device + * + * This can be used if adc uclass platform data is filled. + * + * @dev: ADC device to check + * @channel_mask: pointer to the returned channel bitmask + * @return: 0 if OK, -ve on error + */ +int adc_channel_mask(struct udevice *dev, unsigned int *channel_mask); + +/** * adc_channel_single_shot() - get output data of conversion for the ADC * device's channel. This function searches for the device with the given name, * starts the given channel conversion and returns the output data. @@ -284,4 +295,14 @@ int adc_vss_value(struct udevice *dev, int *uV); */ int adc_stop(struct udevice *dev); +/** + * adc_raw_to_uV() - converts raw value to microvolts for given ADC device. + * + * @dev: ADC device used from conversion + * @raw: raw value to convert + * @uV: converted value in microvolts + * @return: 0 on success or -ve on error + */ +int adc_raw_to_uV(struct udevice *dev, unsigned int raw, int *uV); + #endif diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index c83fc01b76..dffd6b2602 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -122,6 +122,13 @@ typedef struct global_data { struct list_head log_head; /* List of struct log_device */ int log_fmt; /* Mask containing log format info */ #endif +#if CONFIG_IS_ENABLED(BLOBLIST) + struct bloblist_hdr *bloblist; /* Bloblist information */ + struct bloblist_hdr *new_bloblist; /* Relocated blolist info */ +# ifdef CONFIG_SPL + struct spl_handoff *spl_handoff; +# endif +#endif } gd_t; #endif diff --git a/include/bloblist.h b/include/bloblist.h new file mode 100644 index 0000000000..85144010ab --- /dev/null +++ b/include/bloblist.h @@ -0,0 +1,195 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * This provides a standard way of passing information between boot phases + * (TPL -> SPL -> U-Boot proper.) + * + * A list of blobs of data, tagged with their owner. The list resides in memory + * and can be updated by SPL, U-Boot, etc. + * + * Copyright 2018 Google, Inc + * Written by Simon Glass <sjg@chromium.org> + */ + +#ifndef __BLOBLIST_H +#define __BLOBLIST_H + +enum { + BLOBLIST_VERSION = 0, + BLOBLIST_MAGIC = 0xb00757a3, + BLOBLIST_ALIGN = 16, +}; + +enum bloblist_tag_t { + BLOBLISTT_NONE = 0, + + /* Vendor-specific tags are permitted here */ + BLOBLISTT_EC_HOSTEVENT, /* Chromium OS EC host-event mask */ + BLOBLISTT_SPL_HANDOFF, /* Hand-off info from SPL */ + BLOBLISTT_VBOOT_CTX, /* Chromium OS verified boot context */ + BLOBLISTT_VBOOT_HANDOFF, /* Chromium OS internal handoff info */ +}; + +/** + * struct bloblist_hdr - header for the bloblist + * + * This is stored at the start of the bloblist which is always on a 16-byte + * boundary. Records follow this header. The bloblist normally stays in the + * same place in memory as SPL and U-Boot execute, but it can be safely moved + * around. + * + * None of the bloblist structures contain pointers but it is possible to put + * pointers inside a bloblist record if desired. This is not encouraged, + * since it can make part of the bloblist inaccessible if the pointer is + * no-longer valid. It is better to just store all the data inside a bloblist + * record. + * + * Each bloblist record is aligned to a 16-byte boundary and follows immediately + * from the last. + * + * @version: BLOBLIST_VERSION + * @hdr_size: Size of this header, normally sizeof(struct bloblist_hdr). The + * first bloblist_rec starts at this offset from the start of the header + * @flags: Space for BLOBLISTF_... flags (none yet) + * @magic: BLOBLIST_MAGIC + * @size: Total size of all records (non-zero if valid) including this header. + * The bloblist extends for this many bytes from the start of this header. + * @alloced: Total size allocated for this bloblist. When adding new records, + * the bloblist can grow up to this size. This starts out as + * sizeof(bloblist_hdr) since we need at least that much space to store a + * valid bloblist + * @spare: Space space + * @chksum: CRC32 for the entire bloblist allocated area. Since any of the + * blobs can be altered after being created, this checksum is only valid + * when the bloblist is finalised before jumping to the next stage of boot. + * Note: @chksum is last to make it easier to exclude it from the checksum + * calculation. + */ +struct bloblist_hdr { + u32 version; + u32 hdr_size; + u32 flags; + u32 magic; + + u32 size; + u32 alloced; + u32 spare; + u32 chksum; +}; + +/** + * struct bloblist_rec - record for the bloblist + * + * NOTE: Only exported for testing purposes. Do not use this struct. + * + * The bloblist contains a number of records each consisting of this record + * structure followed by the data contained. Each records is 16-byte aligned. + * + * @tag: Tag indicating what the record contains + * @hdr_size: Size of this header, normally sizeof(struct bloblist_rec). The + * record's data starts at this offset from the start of the record + * @size: Size of record in bytes, excluding the header size. This does not + * need to be aligned (e.g. 3 is OK). + * @spare: Spare space for other things + */ +struct bloblist_rec { + u32 tag; + u32 hdr_size; + u32 size; + u32 spare; +}; + +/** + * bloblist_find() - Find a blob + * + * Searches the bloblist and returns the blob with the matching tag + * + * @tag: Tag to search for (enum bloblist_tag_t) + * @size: Expected size of the blob + * @return pointer to blob if found, or NULL if not found, or a blob was found + * but it is the wrong size + */ +void *bloblist_find(uint tag, int size); + +/** + * bloblist_add() - Add a new blob + * + * Add a new blob to the bloblist + * + * This should only be called if you konw there is no existing blob for a + * particular tag. It is typically safe to call in the first phase of U-Boot + * (e.g. TPL or SPL). After that, bloblist_ensure() should be used instead. + * + * @tag: Tag to add (enum bloblist_tag_t) + * @size: Size of the blob + * @return pointer to the newly added block, or NULL if there is not enough + * space for the blob + */ +void *bloblist_add(uint tag, int size); + +/** + * bloblist_ensure_size() - Find or add a blob + * + * Find an existing blob, or add a new one if not found + * + * @tag: Tag to add (enum bloblist_tag_t) + * @size: Size of the blob + * @blobp: Returns a pointer to blob on success + * @return 0 if OK, -ENOSPC if it is missing and could not be added due to lack + * of space, or -ESPIPE it exists but has the wrong size + */ +int bloblist_ensure_size(uint tag, int size, void **blobp); + +/** + * bloblist_ensure() - Find or add a blob + * + * Find an existing blob, or add a new one if not found + * + * @tag: Tag to add (enum bloblist_tag_t) + * @size: Size of the blob + * @return pointer to blob, or NULL if it is missing and could not be added due + * to lack of space, or it exists but has the wrong size + */ +void *bloblist_ensure(uint tag, int size); + +/** + * bloblist_new() - Create a new, empty bloblist of a given size + * + * @addr: Address of bloblist + * @size: Initial size for bloblist + * @flags: Flags to use for bloblist + * @return 0 if OK, -EFAULT if addr is not aligned correctly, -ENOSPC is the + * area is not large enough + */ +int bloblist_new(ulong addr, uint size, uint flags); + +/** + * bloblist_check() - Check if a bloblist exists + * + * @addr: Address of bloblist + * @size: Expected size of blobsize, or 0 to detect the size + * @return 0 if OK, -ENOENT if the magic number doesn't match (indicating that + * there problem is no bloblist at the given address), -EPROTONOSUPPORT + * if the version does not match, -EIO if the checksum does not match, + * -EFBIG if the expected size does not match the detected size + */ +int bloblist_check(ulong addr, uint size); + +/** + * bloblist_finish() - Set up the bloblist for the next U-Boot part + * + * This sets the correct checksum for the bloblist. This ensures that the + * bloblist will be detected correctly by the next phase of U-Boot. + * + * @return 0 + */ +int bloblist_finish(void); + +/** + * bloblist_init() - Init the bloblist system with a single bloblist + * + * This uses CONFIG_BLOBLIST_ADDR and CONFIG_BLOBLIST_SIZE to set up a bloblist + * for use by U-Boot. + */ +int bloblist_init(void); + +#endif /* __BLOBLIST_H */ diff --git a/include/common.h b/include/common.h index 8b9f859c07..8b56137032 100644 --- a/include/common.h +++ b/include/common.h @@ -14,9 +14,6 @@ typedef volatile unsigned long vu_long; typedef volatile unsigned short vu_short; typedef volatile unsigned char vu_char; -/* Allow sharing constants with type modifiers between C and assembly. */ -#define _AC(X, Y) (X##Y) - #include <config.h> #include <errno.h> #include <time.h> @@ -541,16 +538,10 @@ int cpu_release(u32 nr, int argc, char * const argv[]); #else /* __ASSEMBLY__ */ -/* Drop a C type modifier (like in 3UL) for constants used in assembly. */ -#define _AC(X, Y) X - #endif /* __ASSEMBLY__ */ /* Put only stuff here that the assembler can digest */ -/* Declare an unsigned long constant digestable both by C and an assembler. */ -#define UL(x) _AC(x, UL) - #ifdef CONFIG_POST #define CONFIG_HAS_POST #ifndef CONFIG_POST_ALT_LIST @@ -558,11 +549,6 @@ int cpu_release(u32 nr, int argc, char * const argv[]); #endif #endif -#ifdef CONFIG_INIT_CRITICAL -#error CONFIG_INIT_CRITICAL is deprecated! -#error Read section CONFIG_SKIP_LOWLEVEL_INIT in README. -#endif - #define ROUND(a,b) (((a) + (b) - 1) & ~((b) - 1)) /* diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h index 373fee78a9..555efb7433 100644 --- a/include/config_distro_bootcmd.h +++ b/include/config_distro_bootcmd.h @@ -99,9 +99,9 @@ #define BOOTEFI_NAME "bootia32.efi" #elif defined(CONFIG_X86_RUN_64BIT) #define BOOTEFI_NAME "bootx64.efi" -#elif defined(CONFIG_CPU_RISCV_32) +#elif defined(CONFIG_ARCH_RV32I) #define BOOTEFI_NAME "bootriscv32.efi" -#elif defined(CONFIG_CPU_RISCV_64) +#elif defined(CONFIG_ARCH_RV64I) #define BOOTEFI_NAME "bootriscv64.efi" #endif #endif @@ -242,6 +242,18 @@ BOOT_TARGET_DEVICES_references_USB_without_CONFIG_CMD_USB #endif +#ifdef CONFIG_CMD_VIRTIO +#define BOOTENV_SHARED_VIRTIO BOOTENV_SHARED_BLKDEV(virtio) +#define BOOTENV_DEV_VIRTIO BOOTENV_DEV_BLKDEV +#define BOOTENV_DEV_NAME_VIRTIO BOOTENV_DEV_NAME_BLKDEV +#else +#define BOOTENV_SHARED_VIRTIO +#define BOOTENV_DEV_VIRTIO \ + BOOT_TARGET_DEVICES_references_VIRTIO_without_CONFIG_CMD_VIRTIO +#define BOOTENV_DEV_NAME_VIRTIO \ + BOOT_TARGET_DEVICES_references_VIRTIO_without_CONFIG_CMD_VIRTIO +#endif + #if defined(CONFIG_CMD_DHCP) #if defined(CONFIG_EFI_LOADER) /* http://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xml */ @@ -257,10 +269,10 @@ #elif defined(__i386__) #define BOOTENV_EFI_PXE_ARCH "0x6" #define BOOTENV_EFI_PXE_VCI "PXEClient:Arch:00006:UNDI:003000" -#elif defined(CONFIG_CPU_RISCV_32) || ((defined(__riscv) && __riscv_xlen == 32)) +#elif defined(CONFIG_ARCH_RV32I) || ((defined(__riscv) && __riscv_xlen == 32)) #define BOOTENV_EFI_PXE_ARCH "0x19" #define BOOTENV_EFI_PXE_VCI "PXEClient:Arch:00025:UNDI:003000" -#elif defined(CONFIG_CPU_RISCV_64) || ((defined(__riscv) && __riscv_xlen == 64)) +#elif defined(CONFIG_ARCH_RV64I) || ((defined(__riscv) && __riscv_xlen == 64)) #define BOOTENV_EFI_PXE_ARCH "0x1b" #define BOOTENV_EFI_PXE_VCI "PXEClient:Arch:00027:UNDI:003000" #elif defined(CONFIG_SANDBOX) @@ -350,20 +362,22 @@ BOOTENV_SHARED_IDE \ BOOTENV_SHARED_UBIFS \ BOOTENV_SHARED_EFI \ + BOOTENV_SHARED_VIRTIO \ "boot_prefixes=/ /boot/\0" \ "boot_scripts=boot.scr.uimg boot.scr\0" \ "boot_script_dhcp=boot.scr.uimg\0" \ BOOTENV_BOOT_TARGETS \ \ + "boot_syslinux_conf=extlinux/extlinux.conf\0" \ "boot_extlinux=" \ "sysboot ${devtype} ${devnum}:${distro_bootpart} any " \ - "${scriptaddr} ${prefix}extlinux/extlinux.conf\0" \ + "${scriptaddr} ${prefix}${boot_syslinux_conf}\0" \ \ "scan_dev_for_extlinux=" \ "if test -e ${devtype} " \ "${devnum}:${distro_bootpart} " \ - "${prefix}extlinux/extlinux.conf; then " \ - "echo Found ${prefix}extlinux/extlinux.conf; " \ + "${prefix}${boot_syslinux_conf}; then " \ + "echo Found ${prefix}${boot_syslinux_conf}; " \ "run boot_extlinux; " \ "echo SCRIPT FAILED: continuing...; " \ "fi\0" \ diff --git a/include/configs/am3517_evm.h b/include/configs/am3517_evm.h index 0463e42048..4e7e5209d4 100644 --- a/include/configs/am3517_evm.h +++ b/include/configs/am3517_evm.h @@ -12,16 +12,6 @@ #ifndef __CONFIG_H #define __CONFIG_H -/* - * 1MB into the SDRAM to allow for SPL's bss at the beginning of SDRAM - * 64 bytes before this address should be set aside for u-boot.img's - * header. That is 0x800FFFC0--0x80100000 should not be used for any - * other needs. - */ - -#define CONFIG_SYS_SPL_MALLOC_START 0x80208000 -#define CONFIG_SYS_SPL_MALLOC_SIZE 0x100000 - #include <configs/ti_omap3_common.h> #undef CONFIG_DM_I2C_COMPAT @@ -176,8 +166,6 @@ /* Physical Memory Map */ #define CONFIG_SYS_CS0_SIZE (256 * 1024 * 1024) -#define CONFIG_SYS_INIT_RAM_ADDR 0x4020f800 -#define CONFIG_SYS_INIT_RAM_SIZE 0x800 /* FLASH and environment organization */ @@ -203,10 +191,6 @@ #undef CONFIG_SPL_TEXT_BASE #define CONFIG_SPL_TEXT_BASE 0x40200000 -#undef CONFIG_SPL_BSS_START_ADDR -#define CONFIG_SPL_BSS_START_ADDR 0x80000000 -#define CONFIG_SPL_BSS_MAX_SIZE 0x80000 /* 512 KB */ - #define CONFIG_SYS_MMCSD_FS_BOOT_PARTITION 1 #define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME "u-boot.img" diff --git a/include/configs/am65x_evm.h b/include/configs/am65x_evm.h index 65015df131..484c5ef2fe 100644 --- a/include/configs/am65x_evm.h +++ b/include/configs/am65x_evm.h @@ -21,6 +21,12 @@ /* SPL Loader Configuration */ #ifdef CONFIG_TARGET_AM654_A53_EVM #define CONFIG_SPL_TEXT_BASE 0x80080000 +#else +#define CONFIG_SPL_TEXT_BASE 0x41c00000 +#endif + +#ifdef CONFIG_SYS_K3_SPL_ATF +#define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME "tispl.bin" #endif #define CONFIG_SKIP_LOWLEVEL_INIT diff --git a/include/configs/broadcom_bcm968580xref.h b/include/configs/broadcom_bcm968580xref.h new file mode 100644 index 0000000000..1c0945e140 --- /dev/null +++ b/include/configs/broadcom_bcm968580xref.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2018 Philippe Reynes <philippe.reynes@softathome.com> + */ + +#include <linux/sizes.h> + +/* + * common + */ + +/* UART */ +#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, \ + 230400, 500000, 1500000 } +/* Memory usage */ +#define CONFIG_SYS_MAXARGS 24 +#define CONFIG_SYS_MALLOC_LEN (1024 * 1024) + +/* + * 6858 + */ + +/* RAM */ +#define CONFIG_SYS_SDRAM_BASE 0x00000000 + +/* U-Boot */ +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_TEXT_BASE + SZ_16M) +#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_TEXT_BASE + +#define CONFIG_SKIP_LOWLEVEL_INIT + +/* + * 968580xref + */ + +#define CONFIG_ENV_SIZE (8 * 1024) diff --git a/include/configs/db-88f6820-amc.h b/include/configs/db-88f6820-amc.h index 2f1ffa2754..e68246cc0f 100644 --- a/include/configs/db-88f6820-amc.h +++ b/include/configs/db-88f6820-amc.h @@ -10,11 +10,6 @@ * High Level Configuration Options (easy to change) */ -/* - * TEXT_BASE needs to be below 16MiB, since this area is scrubbed - * for DDR ECC byte filling in the SPL before loading the main - * U-Boot into it. - */ #define CONFIG_SYS_TCLK 200000000 /* 200MHz */ /* diff --git a/include/configs/db-88f6820-gp.h b/include/configs/db-88f6820-gp.h index f2aa21a43e..3900cbed2d 100644 --- a/include/configs/db-88f6820-gp.h +++ b/include/configs/db-88f6820-gp.h @@ -10,11 +10,6 @@ * High Level Configuration Options (easy to change) */ -/* - * TEXT_BASE needs to be below 16MiB, since this area is scrubbed - * for DDR ECC byte filling in the SPL before loading the main - * U-Boot into it. - */ #define CONFIG_SYS_TCLK 250000000 /* 250MHz */ /* diff --git a/include/configs/gardena-smart-gateway-mt7688.h b/include/configs/gardena-smart-gateway-mt7688.h index 0184147068..b10857a757 100644 --- a/include/configs/gardena-smart-gateway-mt7688.h +++ b/include/configs/gardena-smart-gateway-mt7688.h @@ -30,7 +30,7 @@ /* Memory usage */ #define CONFIG_SYS_MAXARGS 64 -#define CONFIG_SYS_MALLOC_LEN (1024 * 1024) +#define CONFIG_SYS_MALLOC_LEN (16 * 1024 * 1024) #define CONFIG_SYS_BOOTPARAMS_LEN (128 * 1024) #define CONFIG_SYS_CBSIZE 512 @@ -38,7 +38,7 @@ #define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE /* Environment settings */ -#define CONFIG_ENV_OFFSET 0x80000 +#define CONFIG_ENV_OFFSET 0xa0000 #define CONFIG_ENV_SIZE (64 << 10) #define CONFIG_ENV_SECT_SIZE (64 << 10) #define CONFIG_SYS_REDUNDAND_ENVIRONMENT diff --git a/include/configs/linkit-smart-7688.h b/include/configs/linkit-smart-7688.h index 78efa23279..3bae92d0ee 100644 --- a/include/configs/linkit-smart-7688.h +++ b/include/configs/linkit-smart-7688.h @@ -38,7 +38,7 @@ #define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE /* Environment settings */ -#define CONFIG_ENV_OFFSET 0x40000 +#define CONFIG_ENV_OFFSET 0x80000 #define CONFIG_ENV_SIZE (16 << 10) #define CONFIG_ENV_SECT_SIZE (64 << 10) diff --git a/include/configs/picosam9g45.h b/include/configs/picosam9g45.h index 0b240e7ebc..c2882e6daf 100644 --- a/include/configs/picosam9g45.h +++ b/include/configs/picosam9g45.h @@ -57,10 +57,6 @@ */ #define CONFIG_BOOTP_BOOTFILESIZE -/* Enable the watchdog */ -#define CONFIG_AT91SAM9_WATCHDOG -#define CONFIG_HW_WATCHDOG - /* * Command line configuration. */ diff --git a/include/configs/qemu-riscv.h b/include/configs/qemu-riscv.h index d279c233b2..b29d155d09 100644 --- a/include/configs/qemu-riscv.h +++ b/include/configs/qemu-riscv.h @@ -15,7 +15,35 @@ #define CONFIG_SYS_MALLOC_LEN SZ_8M +#define CONFIG_SYS_BOOTM_LEN SZ_16M + /* Environment options */ #define CONFIG_ENV_SIZE SZ_4K +#define BOOT_TARGET_DEVICES(func) \ + func(QEMU, qemu, na) \ + func(VIRTIO, virtio, 0) \ + func(DHCP, dhcp, na) + +#include <config_distro_bootcmd.h> + +#define BOOTENV_DEV_QEMU(devtypeu, devtypel, instance) \ + "bootcmd_qemu=" \ + "if env exists kernel_start; then " \ + "bootm ${kernel_start} - ${fdtcontroladdr};" \ + "fi;\0" + +#define BOOTENV_DEV_NAME_QEMU(devtypeu, devtypel, instance) \ + "qemu " + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "fdt_high=0xffffffffffffffff\0" \ + "initrd_high=0xffffffffffffffff\0" \ + "kernel_addr_r=0x81000000\0" \ + "fdt_addr_r=0x82000000\0" \ + "scriptaddr=0x82100000\0" \ + "pxefile_addr_r=0x82200000\0" \ + "ramdisk_addr_r=0x82300000\0" \ + BOOTENV + #endif /* __CONFIG_H */ diff --git a/include/configs/smartweb.h b/include/configs/smartweb.h index 114b87e1b3..28af575bf2 100644 --- a/include/configs/smartweb.h +++ b/include/configs/smartweb.h @@ -112,13 +112,6 @@ "root=/dev/nfs ip=dhcp nfsroot=${serverip}:/srv/nfs/rootfs; " \ "dhcp" -/* Enable the watchdog */ -#define CONFIG_AT91SAM9_WATCHDOG -#if !defined(CONFIG_SPL_BUILD) -#define CONFIG_HW_WATCHDOG -#endif -#define CONFIG_AT91_HW_WDT_TIMEOUT 15 - #if !defined(CONFIG_SPL_BUILD) /* USB configuration */ #define CONFIG_USB_ATMEL diff --git a/include/configs/taurus.h b/include/configs/taurus.h index 4fdb0dd962..f283ab7fca 100644 --- a/include/configs/taurus.h +++ b/include/configs/taurus.h @@ -85,13 +85,6 @@ #define CONFIG_RMII #define CONFIG_AT91_WANTS_COMMON_PHY -#define CONFIG_AT91SAM9_WATCHDOG -#define CONFIG_AT91_HW_WDT_TIMEOUT 15 -#if !defined(CONFIG_SPL_BUILD) -/* Enable the watchdog */ -#define CONFIG_HW_WATCHDOG -#endif - /* USB */ #if defined(CONFIG_BOARD_TAURUS) #define CONFIG_USB_ATMEL diff --git a/include/configs/ti_armv7_common.h b/include/configs/ti_armv7_common.h index 55b9b45eec..0f892e51d1 100644 --- a/include/configs/ti_armv7_common.h +++ b/include/configs/ti_armv7_common.h @@ -165,7 +165,9 @@ /* FAT sd card locations. */ #define CONFIG_SYS_MMCSD_FS_BOOT_PARTITION 1 +#ifndef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME #define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME "u-boot.img" +#endif #ifdef CONFIG_SPL_OS_BOOT /* FAT */ diff --git a/include/cros_ec.h b/include/cros_ec.h index 4771e6b7d1..f4b9b7a5c2 100644 --- a/include/cros_ec.h +++ b/include/cros_ec.h @@ -187,6 +187,14 @@ int cros_ec_flash_protect(struct udevice *dev, uint32_t set_mask, uint32_t set_flags, struct ec_response_flash_protect *resp); +/** + * Notify EC of current boot mode + * + * @param dev CROS-EC device + * @param vboot_mode Verified boot mode + * @return 0 if ok, <0 on error + */ +int cros_ec_entering_mode(struct udevice *dev, int mode); /** * Run internal tests on the cros_ec interface. @@ -397,4 +405,85 @@ struct i2c_msg; int cros_ec_i2c_tunnel(struct udevice *dev, int port, struct i2c_msg *msg, int nmsgs); +/** + * cros_ec_get_events_b() - Get event mask B + * + * @return value of event mask, default value of 0 if it could not be read + */ +uint64_t cros_ec_get_events_b(struct udevice *dev); + +/** + * cros_ec_clear_events_b() - Clear even mask B + * + * Any pending events in the B range are cleared + * + * @return 0 if OK, -ve on error + */ +int cros_ec_clear_events_b(struct udevice *dev, uint64_t mask); + +/** + * cros_ec_efs_verify() - tell the EC to verify one of its images + * + * @param dev CROS-EC device + * @param region Flash region to query + * @return 0 if OK, -ve on error + */ +int cros_ec_efs_verify(struct udevice *dev, enum ec_flash_region region); + +/** + * cros_ec_battery_cutoff() - Request that the battery be cut off + * + * This tells the battery to stop supplying power. This is used before shipping + * a device to ensure that the battery remains charged while the device is + * shipped or sitting on the shelf waiting to be purchased. + * + * @param dev CROS-EC device + * @param flags Flags to use (EC_BATTERY_CUTOFF_FLAG_...) + * @return 0 if OK, -ve on error + */ +int cros_ec_battery_cutoff(struct udevice *dev, uint8_t flags); + +/** + * cros_ec_read_limit_power() - Check if power is limited by batter/charger + * + * Sometimes the battery is low and / or the device is connected to a charger + * that cannot supply much power. + * + * @param dev CROS-EC device + * @param limit_powerp Returns whether power is limited (0 or 1) + * @return 0 if OK, -ENOSYS if the EC does not support this comment, -EINVAL + * if the EC returned an invalid response + */ +int cros_ec_read_limit_power(struct udevice *dev, int *limit_powerp); + +/** + * cros_ec_config_powerbtn() - Configure the behaviour of the power button + * + * @param dev CROS-EC device + * @param flags Flags to use (EC_POWER_BUTTON_...) + * @return 0 if OK, -ve on error + */ +int cros_ec_config_powerbtn(struct udevice *dev, uint32_t flags); + +/** + * cros_ec_get_lid_shutdown_mask() - Set the lid shutdown mask + * + * Determines whether a lid close event is reported + * + * @param dev CROS-EC device + * @return shufdown mas if OK, -ve on error + */ +int cros_ec_get_lid_shutdown_mask(struct udevice *dev); + +/** + * cros_ec_set_lid_shutdown_mask() - Set the lid shutdown mask + * + * Set whether a lid close event is reported + * + * @param dev CROS-EC device + * @param enable true to enable reporting, false to disable + * @return shufdown mas if OK, -ve on error + */ +int cros_ec_set_lid_shutdown_mask(struct udevice *dev, int enable); + #endif diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 2fc9fa39a3..92539b8b5f 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -237,6 +237,16 @@ int ofnode_read_u32_default(ofnode ref, const char *propname, u32 def); int ofnode_read_s32_default(ofnode node, const char *propname, s32 def); /** + * ofnode_read_u64() - Read a 64-bit integer from a property + * + * @node: valid node reference to read property from + * @propname: name of the property to read from + * @outp: place to put value (if found) + * @return 0 if OK, -ve on error + */ +int ofnode_read_u64(ofnode node, const char *propname, u64 *outp); + +/** * ofnode_read_u64_default() - Read a 64-bit integer from a property * * @ref: valid node reference to read property from diff --git a/include/dm/pinctrl.h b/include/dm/pinctrl.h index 80de3f3fed..63a7d55b88 100644 --- a/include/dm/pinctrl.h +++ b/include/dm/pinctrl.h @@ -6,6 +6,9 @@ #ifndef __PINCTRL_H #define __PINCTRL_H +#define PINNAME_SIZE 10 +#define PINMUX_SIZE 40 + /** * struct pinconf_param - pin config parameters * @@ -66,6 +69,7 @@ struct pinconf_param { * pointing a config node. (necessary for pinctrl_full) * @set_state_simple: do needed pinctrl operations for a peripherl @periph. * (necessary for pinctrl_simple) + * @get_pin_muxing: display the muxing of a given pin. */ struct pinctrl_ops { int (*get_pins_count)(struct udevice *dev); @@ -129,6 +133,24 @@ struct pinctrl_ops { * @return mux value (SoC-specific, e.g. 0 for input, 1 for output) */ int (*get_gpio_mux)(struct udevice *dev, int banknum, int index); + + /** + * get_pin_muxing() - show pin muxing + * + * This allows to display the muxing of a given pin. It's useful for + * debug purpose to know if a pin is configured as GPIO or as an + * alternate function and which one. + * Typically it is used by a PINCTRL driver with knowledge of the SoC + * pinctrl setup. + * + * @dev: Pinctrl device to use + * @selector: Pin selector + * @buf Pin's muxing description + * @size Pin's muxing description length + * return 0 if OK, -ve on error + */ + int (*get_pin_muxing)(struct udevice *dev, unsigned int selector, + char *buf, int size); }; #define pinctrl_get_ops(dev) ((struct pinctrl_ops *)(dev)->driver->ops) @@ -348,4 +370,41 @@ int pinctrl_decode_pin_config(const void *blob, int node); */ int pinctrl_get_gpio_mux(struct udevice *dev, int banknum, int index); +/** + * pinctrl_get_pin_muxing() - Returns the muxing description + * + * This allows to display the muxing description of the given pin for + * debug purpose + * + * @dev: Pinctrl device to use + * @selector Pin index within pin-controller + * @buf Pin's muxing description + * @size Pin's muxing description length + * @return 0 if OK, -ve on error + */ +int pinctrl_get_pin_muxing(struct udevice *dev, int selector, char *buf, + int size); + +/** + * pinctrl_get_pins_count() - display pin-controller pins number + * + * This allows to know the number of pins owned by a given pin-controller + * + * @dev: Pinctrl device to use + * @return pins number if OK, -ve on error + */ +int pinctrl_get_pins_count(struct udevice *dev); + +/** + * pinctrl_get_pin_name() - Returns the pin's name + * + * This allows to display the pin's name for debug purpose + * + * @dev: Pinctrl device to use + * @selector Pin index within pin-controller + * @buf Pin's name + * @return 0 if OK, -ve on error + */ +int pinctrl_get_pin_name(struct udevice *dev, int selector, char *buf, + int size); #endif /* __PINCTRL_H */ diff --git a/include/dm/uclass.h b/include/dm/uclass.h index 4ef0d0f0c0..1bc62d523e 100644 --- a/include/dm/uclass.h +++ b/include/dm/uclass.h @@ -308,6 +308,18 @@ int uclass_first_device_err(enum uclass_id id, struct udevice **devp); int uclass_next_device(struct udevice **devp); /** + * uclass_next_device_err() - Get the next device in a uclass + * + * The device returned is probed if necessary, and ready for use + * + * @devp: On entry, pointer to device to lookup. On exit, returns pointer + * to the next device in the uclass if no error occurred, or -ENODEV if + * there is no next device. + * @return 0 if found, -ENODEV if not found, other -ve on error + */ +int uclass_next_device_err(struct udevice **devp); + +/** * uclass_first_device_check() - Get the first device in a uclass * * The device returned is probed if necessary, and ready for use @@ -381,4 +393,20 @@ int uclass_resolve_seq(struct udevice *dev); #define uclass_foreach_dev_safe(pos, next, uc) \ list_for_each_entry_safe(pos, next, &uc->dev_head, uclass_node) +/** + * uclass_foreach_dev_probe() - Helper function to iteration through devices + * of given uclass + * + * This creates a for() loop which works through the available devices in + * a uclass in order from start to end. Devices are probed if necessary, + * and ready for use. + * + * @id: Uclass ID + * @dev: struct udevice * to hold the current device. Set to NULL when there + * are no more devices. + */ +#define uclass_foreach_dev_probe(id, dev) \ + for (int _ret = uclass_first_device_err(id, &dev); !_ret && dev; \ + _ret = uclass_next_device_err(&dev)) + #endif diff --git a/include/fdtdec.h b/include/fdtdec.h index c26df50543..b15da00fb2 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -956,6 +956,7 @@ int fdtdec_setup(void); * Called when CONFIG_OF_BOARD is defined, or if CONFIG_OF_SEPARATE is defined * and the board implements it. */ +void *board_fdt_blob_setup(void); /* * Decode the size of memory diff --git a/include/handoff.h b/include/handoff.h new file mode 100644 index 0000000000..aacb0f5ebf --- /dev/null +++ b/include/handoff.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Passing basic information from SPL to U-Boot proper + * + * Copyright 2018 Google, Inc + */ + +#ifndef __HANDOFF_H +#define __HANDOFF_H + +#if CONFIG_IS_ENABLED(HANDOFF) + +#include <asm/handoff.h> + +/** + * struct spl_handoff - information passed from SPL to U-Boot proper + * + * @ram_size: Value to use for gd->ram_size + */ +struct spl_handoff { + struct arch_spl_handoff arch; + u64 ram_size; +#ifdef CONFIG_NR_DRAM_BANKS + struct { + u64 start; + u64 size; + } ram_bank[CONFIG_NR_DRAM_BANKS]; +#endif +}; + +void handoff_save_dram(struct spl_handoff *ho); +void handoff_load_dram_size(struct spl_handoff *ho); +void handoff_load_dram_banks(struct spl_handoff *ho); +#endif + +#endif diff --git a/arch/mips/include/asm/const.h b/include/linux/const.h index ed43b5d534..379c889232 100644 --- a/arch/mips/include/asm/const.h +++ b/include/linux/const.h @@ -1,11 +1,9 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * const.h: Macros for dealing with constants. - */ - +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _LINUX_CONST_H #define _LINUX_CONST_H +/* const.h: Macros for dealing with constants. */ + /* Some constant macros are used in both assembler and * C code. Therefore we cannot annotate them always with * 'UL' and other type specifiers unilaterally. We @@ -16,12 +14,21 @@ */ #ifdef __ASSEMBLY__ +#define _AC(X,Y) X #define _AT(T,X) X #else +#define __AC(X,Y) (X##Y) +#define _AC(X,Y) __AC(X,Y) #define _AT(T,X) ((T)(X)) #endif -#define _BITUL(x) (_AC(1,UL) << (x)) -#define _BITULL(x) (_AC(1,ULL) << (x)) +#define _UL(x) (_AC(x, UL)) +#define _ULL(x) (_AC(x, ULL)) + +#define _BITUL(x) (_UL(1) << (x)) +#define _BITULL(x) (_ULL(1) << (x)) + +#define UL(x) (_UL(x)) +#define ULL(x) (_ULL(x)) -#endif /* !(_LINUX_CONST_H) */ +#endif /* _LINUX_CONST_H */ diff --git a/include/linux/sizes.h b/include/linux/sizes.h index ce3e8150c1..fbde0bc7e8 100644 --- a/include/linux/sizes.h +++ b/include/linux/sizes.h @@ -8,6 +8,8 @@ #ifndef __LINUX_SIZES_H__ #define __LINUX_SIZES_H__ +#include <linux/const.h> + #define SZ_1 0x00000001 #define SZ_2 0x00000002 #define SZ_4 0x00000004 @@ -44,4 +46,6 @@ #define SZ_1G 0x40000000 #define SZ_2G 0x80000000 +#define SZ_4G _AC(0x100000000, ULL) + #endif /* __LINUX_SIZES_H__ */ diff --git a/include/log.h b/include/log.h index a872fc6ef5..c88a1b5eb4 100644 --- a/include/log.h +++ b/include/log.h @@ -47,6 +47,8 @@ enum log_category_t { LOGC_DT, /* Device-tree */ LOGC_EFI, /* EFI implementation */ LOGC_ALLOC, /* Memory allocation */ + LOGC_SANDBOX, /* Related to the sandbox board */ + LOGC_BLOBLIST, /* Bloblist */ LOGC_COUNT, /* Number of log categories */ LOGC_END, /* Sentinel value for a list of log categories */ @@ -107,6 +109,8 @@ int _log(enum log_category_t cat, enum log_level_t level, const char *file, #define log_io(_fmt...) #endif +#if CONFIG_IS_ENABLED(LOG) + /* Emit a log record if the level is less that the maximum */ #define log(_cat, _level, _fmt, _args...) ({ \ int _l = _level; \ @@ -115,6 +119,9 @@ int _log(enum log_category_t cat, enum log_level_t level, const char *file, __func__, \ pr_fmt(_fmt), ##_args); \ }) +#else +#define log(_cat, _level, _fmt, _args...) +#endif #ifdef DEBUG #define _DEBUG 1 @@ -174,7 +181,16 @@ void __assert_fail(const char *assertion, const char *file, unsigned int line, ({ if (!(x) && _DEBUG) \ __assert_fail(#x, __FILE__, __LINE__, __func__); }) -#ifdef CONFIG_LOG_ERROR_RETURN +#if CONFIG_IS_ENABLED(LOG) && defined(CONFIG_LOG_ERROR_RETURN) +/* + * Log an error return value, possibly with a message. Usage: + * + * return log_ret(fred_call()); + * + * or: + * + * return log_msg_ret("fred failed", fred_call()); + */ #define log_ret(_ret) ({ \ int __ret = (_ret); \ if (__ret < 0) \ @@ -189,8 +205,9 @@ void __assert_fail(const char *assertion, const char *file, unsigned int line, __ret; \ }) #else +/* Non-logging versions of the above which just return the error code */ #define log_ret(_ret) (_ret) -#define log_msg_ret(_msg, _ret) (_ret) +#define log_msg_ret(_msg, _ret) ((void)(_msg), _ret) #endif /** diff --git a/include/misc.h b/include/misc.h index 50515852b2..12d1325ee2 100644 --- a/include/misc.h +++ b/include/misc.h @@ -13,7 +13,7 @@ * @buf: pointer to data buffer * @size: data size in bytes to read the device * - * Return: 0 if OK, -ve on error + * Return: number of bytes read if OK (may be 0 if EOF), -ve on error */ int misc_read(struct udevice *dev, int offset, void *buf, int size); @@ -24,7 +24,7 @@ int misc_read(struct udevice *dev, int offset, void *buf, int size); * @buf: pointer to data buffer * @size: data size in bytes to write the device * - * Return: 0 if OK, -ve on error + * Return: number of bytes written if OK (may be < @size), -ve on error */ int misc_write(struct udevice *dev, int offset, void *buf, int size); @@ -90,7 +90,7 @@ struct misc_ops { * @buf: pointer to data buffer * @size: data size in bytes to read the device * - * Return: 0 if OK, -ve on error + * Return: number of bytes read if OK (may be 0 if EOF), -ve on error */ int (*read)(struct udevice *dev, int offset, void *buf, int size); @@ -101,7 +101,7 @@ struct misc_ops { * @buf: pointer to data buffer * @size: data size in bytes to write the device * - * Return: 0 if OK, -ve on error + * Return: number of bytes written if OK (may be < @size), -ve on error */ int (*write)(struct udevice *dev, int offset, const void *buf, int size); diff --git a/include/os.h b/include/os.h index 28eb625284..6f33b08cf0 100644 --- a/include/os.h +++ b/include/os.h @@ -350,4 +350,18 @@ int os_mprotect_allow(void *start, size_t len); */ int os_write_file(const char *name, const void *buf, int size); +/** + * os_read_file() - Read a file from the host filesystem + * + * This can be useful when reading test data into sandbox for use by test + * routines. The data is allocated using os_malloc() and should be freed by + * the caller. + * + * @name: File path to read from + * @bufp: Returns buffer containing data read + * @sizep: Returns size of data + * @return 0 if OK, -ve on error + */ +int os_read_file(const char *name, void **bufp, int *sizep); + #endif diff --git a/include/serial.h b/include/serial.h index 020cd392e8..ec25db6e60 100644 --- a/include/serial.h +++ b/include/serial.h @@ -195,9 +195,7 @@ struct dm_serial_ops { * Set up a new config for this device. * * @dev: Device pointer - * @parity: parity to use - * @bits: bits number to use - * @stop: stop bits number to use + * @serial_config: number of bits, parity and number of stopbits to use * @return 0 if OK, -ve on error */ int (*setconfig)(struct udevice *dev, uint serial_config); diff --git a/include/spi_flash.h b/include/spi_flash.h index 0ec98fb55d..e427e960d5 100644 --- a/include/spi_flash.h +++ b/include/spi_flash.h @@ -112,6 +112,19 @@ struct dm_spi_flash_ops { int (*write)(struct udevice *dev, u32 offset, size_t len, const void *buf); int (*erase)(struct udevice *dev, u32 offset, size_t len); + /** + * get_sw_write_prot() - Check state of software write-protect feature + * + * SPI flash chips can lock a region of the flash defined by a + * 'protected area'. This function checks if this protected area is + * defined. + * + * @dev: SPI flash device + * @return 0 if no region is write-protected, 1 if a region is + * write-protected, -ENOSYS if the driver does not implement this, + * other -ve value on error + */ + int (*get_sw_write_prot)(struct udevice *dev); }; /* Access the serial operations for a device */ @@ -153,6 +166,20 @@ int spi_flash_write_dm(struct udevice *dev, u32 offset, size_t len, */ int spi_flash_erase_dm(struct udevice *dev, u32 offset, size_t len); +/** + * spl_flash_get_sw_write_prot() - Check state of software write-protect feature + * + * SPI flash chips can lock a region of the flash defined by a + * 'protected area'. This function checks if this protected area is + * defined. + * + * @dev: SPI flash device + * @return 0 if no region is write-protected, 1 if a region is + * write-protected, -ENOSYS if the driver does not implement this, + * other -ve value on error + */ +int spl_flash_get_sw_write_prot(struct udevice *dev); + int spi_flash_probe_bus_cs(unsigned int busnum, unsigned int cs, unsigned int max_hz, unsigned int spi_mode, struct udevice **devp); diff --git a/include/spl.h b/include/spl.h index 9a439f468b..ee92832f0a 100644 --- a/include/spl.h +++ b/include/spl.h @@ -11,6 +11,7 @@ /* Platform-specific defines */ #include <linux/compiler.h> #include <asm/spl.h> +#include <handoff.h> /* Value in r0 indicates we booted from U-Boot */ #define UBOOT_NOT_LOADED_FROM_SPL 0x13578642 @@ -21,6 +22,46 @@ #define MMCSD_MODE_FS 2 #define MMCSD_MODE_EMMCBOOT 3 +/* + * u_boot_first_phase() - check if this is the first U-Boot phase + * + * U-Boot has up to three phases: TPL, SPL and U-Boot proper. Depending on the + * build flags we can determine whether the current build is for the first + * phase of U-Boot or not. If there is no SPL, then this is U-Boot proper. If + * there is SPL but no TPL, the the first phase is SPL. If there is TPL, then + * it is the first phase. + * + * @returns true if this is the first phase of U-Boot + * + */ +static inline bool u_boot_first_phase(void) +{ + if (IS_ENABLED(CONFIG_TPL)) { + if (IS_ENABLED(CONFIG_TPL_BUILD)) + return true; + } else if (IS_ENABLED(CONFIG_SPL)) { + if (IS_ENABLED(CONFIG_SPL_BUILD)) + return true; + } else { + return true; + } + + return false; +} + +/* A string name for SPL or TPL */ +#ifdef CONFIG_SPL_BUILD +# ifdef CONFIG_TPL_BUILD +# define SPL_TPL_NAME "tpl" +# else +# define SPL_TPL_NAME "spl" +# endif +# define SPL_TPL_PROMPT SPL_TPL_NAME ": " +#else +# define SPL_TPL_NAME "" +# define SPL_TPL_PROMPT "" +#endif + struct spl_image_info { const char *name; u8 os; diff --git a/include/test/suites.h b/include/test/suites.h index abb3a4b816..77d863b4a6 100644 --- a/include/test/suites.h +++ b/include/test/suites.h @@ -23,6 +23,7 @@ struct unit_test; int cmd_ut_category(const char *name, struct unit_test *tests, int n_ents, int argc, char * const argv[]); +int do_ut_bloblist(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]); int do_ut_compression(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]); int do_ut_dm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); int do_ut_env(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); diff --git a/include/video.h b/include/video.h index 75200f0e45..3f9139eea4 100644 --- a/include/video.h +++ b/include/video.h @@ -191,9 +191,10 @@ void video_set_flush_dcache(struct udevice *dev, bool flush); /** * Set default colors and attributes * - * @priv device information + * @dev: video device + * @invert true to invert colours */ -void video_set_default_colors(struct video_priv *priv); +void video_set_default_colors(struct udevice *dev, bool invert); #endif /* CONFIG_DM_VIDEO */ diff --git a/include/w1.h b/include/w1.h index 399177a12e..b958b1c92c 100644 --- a/include/w1.h +++ b/include/w1.h @@ -12,6 +12,7 @@ #define W1_FAMILY_DS24B33 0x23 #define W1_FAMILY_DS2431 0x2d +#define W1_FAMILY_DS2502 0x09 #define W1_FAMILY_EEP_SANDBOX 0xfe struct w1_device { diff --git a/lib/Kconfig b/lib/Kconfig index 847e797a3a..0333ab172f 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -301,6 +301,14 @@ config LZO help This enables support for LZO compression algorithm.r +config SPL_LZ4 + bool "Enable LZ4 decompression support in SPL" + help + This enables support for tge LZ4 decompression algorithm in SPL. LZ4 + is a lossless data compression algorithm that is focused on + fast compression and decompression speed. It belongs to the LZ77 + family of byte-oriented compression schemes. + config SPL_LZO bool "Enable LZO decompression support in SPL" help diff --git a/lib/Makefile b/lib/Makefile index fb6944128a..4d2e22027d 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -38,7 +38,6 @@ obj-$(CONFIG_IMAGE_SPARSE) += image-sparse.o obj-y += initcall.o obj-$(CONFIG_LMB) += lmb.o obj-y += ldiv.o -obj-$(CONFIG_LZ4) += lz4_wrapper.o obj-$(CONFIG_MD5) += md5.o obj-y += net_utils.o obj-$(CONFIG_PHYSMEM) += physmem.o @@ -64,6 +63,7 @@ obj-$(CONFIG_SHA256) += sha256.o obj-$(CONFIG_$(SPL_)ZLIB) += zlib/ obj-$(CONFIG_$(SPL_)GZIP) += gunzip.o obj-$(CONFIG_$(SPL_)LZO) += lzo/ +obj-$(CONFIG_$(SPL_)LZ4) += lz4_wrapper.o obj-$(CONFIG_LIBAVB) += libavb/ diff --git a/lib/fdtdec.c b/lib/fdtdec.c index a420ba1885..d28f2cbb1c 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1198,7 +1198,8 @@ static int uncompress_blob(const void *src, ulong sz_src, void **dstp) # else static int uncompress_blob(const void *src, ulong sz_src, void **dstp) { - return -ENOTSUPP; + *dstp = (void *)src; + return 0; } # endif #endif diff --git a/lib/libfdt/fdt_region.c b/lib/libfdt/fdt_region.c index d3b9a60e99..7e9fa9272e 100644 --- a/lib/libfdt/fdt_region.c +++ b/lib/libfdt/fdt_region.c @@ -96,6 +96,9 @@ int fdt_find_regions(const void *fdt, char * const inc[], int inc_count, break; case FDT_END_NODE: + /* Depth must never go below -1 */ + if (depth < 0) + return -FDT_ERR_BADSTRUCTURE; include = want; want = stack[depth--]; while (end > path && *--end != '/') diff --git a/lib/string.c b/lib/string.c index c4ca944bb4..af17c16f61 100644 --- a/lib/string.c +++ b/lib/string.c @@ -15,6 +15,7 @@ * reentrant and should be faster). Use only strsep() in new code, please. */ +#include <config.h> #include <linux/types.h> #include <linux/string.h> #include <linux/ctype.h> diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index 0627024e71..7dd9d60541 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -82,7 +82,6 @@ CONFIG_AT91SAM9G20EK_2MMC CONFIG_AT91SAM9G45EKES CONFIG_AT91SAM9G45_LCD_BASE CONFIG_AT91SAM9M10G45EK -CONFIG_AT91SAM9_WATCHDOG CONFIG_AT91_CAN CONFIG_AT91_EFLASH CONFIG_AT91_GPIO_PULLUP @@ -962,7 +961,6 @@ CONFIG_IMX_OTP CONFIG_IMX_VIDEO_SKIP CONFIG_INETSPACE_V2 CONFIG_INITRD_TAG -CONFIG_INIT_CRITICAL CONFIG_INIT_IGNORE_ERROR CONFIG_INI_ALLOW_MULTILINE CONFIG_INI_CASE_INSENSITIVE diff --git a/test/Makefile b/test/Makefile index 1e434730b6..2fe41f489c 100644 --- a/test/Makefile +++ b/test/Makefile @@ -2,6 +2,7 @@ # # (C) Copyright 2012 The Chromium Authors +obj-$(CONFIG_SANDBOX) += bloblist.o obj-$(CONFIG_UNIT_TEST) += cmd_ut.o obj-$(CONFIG_UNIT_TEST) += ut.o obj-$(CONFIG_SANDBOX) += command_ut.o diff --git a/test/bloblist.c b/test/bloblist.c new file mode 100644 index 0000000000..89bdb012e3 --- /dev/null +++ b/test/bloblist.c @@ -0,0 +1,187 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2018, Google Inc. All rights reserved. + */ + +#include <common.h> +#include <bloblist.h> +#include <log.h> +#include <mapmem.h> +#include <test/suites.h> +#include <test/test.h> +#include <test/ut.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* Declare a new compression test */ +#define BLOBLIST_TEST(_name, _flags) \ + UNIT_TEST(_name, _flags, bloblist_test) + +enum { + TEST_TAG = 1, + TEST_TAG2 = 2, + TEST_TAG_MISSING = 3, + + TEST_SIZE = 10, + TEST_SIZE2 = 20, + + TEST_ADDR = CONFIG_BLOBLIST_ADDR, + TEST_BLOBLIST_SIZE = 0x100, +}; + +static struct bloblist_hdr *clear_bloblist(void) +{ + struct bloblist_hdr *hdr; + + /* Clear out any existing bloblist so we have a clean slate */ + hdr = map_sysmem(CONFIG_BLOBLIST_ADDR, TEST_BLOBLIST_SIZE); + memset(hdr, '\0', TEST_BLOBLIST_SIZE); + + return hdr; +} + +static int bloblist_test_init(struct unit_test_state *uts) +{ + struct bloblist_hdr *hdr; + + hdr = clear_bloblist(); + ut_asserteq(-ENOENT, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); + ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); + hdr->version++; + ut_asserteq(-EPROTONOSUPPORT, bloblist_check(TEST_ADDR, + TEST_BLOBLIST_SIZE)); + + ut_asserteq(-ENOSPC, bloblist_new(TEST_ADDR, 0x10, 0)); + ut_asserteq(-EFAULT, bloblist_new(1, TEST_BLOBLIST_SIZE, 0)); + ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); + + ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); + ut_assertok(bloblist_finish()); + ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); + hdr->flags++; + ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); + + return 1; +} +BLOBLIST_TEST(bloblist_test_init, 0); + +static int bloblist_test_blob(struct unit_test_state *uts) +{ + struct bloblist_hdr *hdr; + struct bloblist_rec *rec, *rec2; + char *data; + + /* At the start there should be no records */ + hdr = clear_bloblist(); + ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE)); + ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); + + /* Add a record and check that we can find it */ + data = bloblist_add(TEST_TAG, TEST_SIZE); + rec = (void *)(hdr + 1); + ut_asserteq_ptr(rec + 1, data); + data = bloblist_find(TEST_TAG, TEST_SIZE); + ut_asserteq_ptr(rec + 1, data); + + /* Check the 'ensure' method */ + ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE)); + ut_assertnull(bloblist_ensure(TEST_TAG, TEST_SIZE2)); + rec2 = (struct bloblist_rec *)(data + ALIGN(TEST_SIZE, BLOBLIST_ALIGN)); + + /* Check for a non-existent record */ + ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE)); + ut_asserteq_ptr(rec2 + 1, bloblist_ensure(TEST_TAG2, TEST_SIZE2)); + ut_assertnull(bloblist_find(TEST_TAG_MISSING, 0)); + + return 0; +} +BLOBLIST_TEST(bloblist_test_blob, 0); + +static int bloblist_test_bad_blob(struct unit_test_state *uts) +{ + struct bloblist_hdr *hdr; + void *data; + + hdr = clear_bloblist(); + ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); + data = hdr + 1; + data += sizeof(struct bloblist_rec); + ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE)); + ut_asserteq_ptr(data, bloblist_ensure(TEST_TAG, TEST_SIZE)); + + return 0; +} +BLOBLIST_TEST(bloblist_test_bad_blob, 0); + +static int bloblist_test_checksum(struct unit_test_state *uts) +{ + struct bloblist_hdr *hdr; + char *data, *data2; + + hdr = clear_bloblist(); + ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0)); + ut_assertok(bloblist_finish()); + ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); + + /* + * Now change things amd make sure that the checksum notices. We cannot + * change the size or alloced fields, since that will crash the code. + * It has to rely on these being correct. + */ + hdr->flags--; + ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); + hdr->flags++; + + hdr->size--; + ut_asserteq(-EFBIG, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); + hdr->size++; + + hdr->spare++; + ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); + hdr->spare--; + + hdr->chksum++; + ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); + hdr->chksum--; + + /* Make sure the checksum changes when we add blobs */ + data = bloblist_add(TEST_TAG, TEST_SIZE); + ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); + + data2 = bloblist_add(TEST_TAG2, TEST_SIZE2); + ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); + ut_assertok(bloblist_finish()); + + /* It should also change if we change the data */ + ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); + *data += 1; + ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); + *data -= 1; + + ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); + *data2 += 1; + ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); + *data2 -= 1; + + /* + * Changing data outside the range of valid data should not affect + * the checksum. + */ + ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); + data[TEST_SIZE]++; + data2[TEST_SIZE2]++; + ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE)); + + return 0; +} + +BLOBLIST_TEST(bloblist_test_checksum, 0); + +int do_ut_bloblist(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + struct unit_test *tests = ll_entry_start(struct unit_test, + bloblist_test); + const int n_ents = ll_entry_count(struct unit_test, bloblist_test); + + return cmd_ut_category("bloblist", tests, n_ents, argc, argv); +} diff --git a/test/cmd_ut.c b/test/cmd_ut.c index b7e01a4847..56924a5272 100644 --- a/test/cmd_ut.c +++ b/test/cmd_ut.c @@ -55,6 +55,8 @@ static cmd_tbl_t cmd_ut_sub[] = { #ifdef CONFIG_SANDBOX U_BOOT_CMD_MKENT(compression, CONFIG_SYS_MAXARGS, 1, do_ut_compression, "", ""), + U_BOOT_CMD_MKENT(bloblist, CONFIG_SYS_MAXARGS, 1, do_ut_bloblist, + "", ""), #endif }; @@ -97,6 +99,7 @@ static int do_ut(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) static char ut_help_text[] = "all - execute all enabled tests\n" #ifdef CONFIG_SANDBOX + "ut bloblist - Test bloblist implementation\n" "ut compression - Test compressors and bootm decompression\n" #endif #ifdef CONFIG_UT_DM diff --git a/test/dm/adc.c b/test/dm/adc.c index 13eda3bd23..1f82304f41 100644 --- a/test/dm/adc.c +++ b/test/dm/adc.c @@ -22,10 +22,14 @@ static int dm_test_adc_bind(struct unit_test_state *uts) { struct udevice *dev; + unsigned int channel_mask; ut_assertok(uclass_get_device_by_name(UCLASS_ADC, "adc", &dev)); ut_asserteq_str(SANDBOX_ADC_DEVNAME, dev->name); + ut_assertok(adc_channel_mask(dev, &channel_mask)); + ut_asserteq((1 << SANDBOX_ADC_CHANNELS) - 1, channel_mask); + return 0; } DM_TEST(dm_test_adc_bind, DM_TESTF_SCAN_FDT); @@ -160,3 +164,34 @@ static int dm_test_adc_multi_channel_shot(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_adc_multi_channel_shot, DM_TESTF_SCAN_FDT); + +static const int dm_test_adc_uV_data[SANDBOX_ADC_CHANNELS] = { + ((u64)SANDBOX_ADC_CHANNEL0_DATA * SANDBOX_BUCK2_INITIAL_EXPECTED_UV) / + SANDBOX_ADC_DATA_MASK, + ((u64)SANDBOX_ADC_CHANNEL1_DATA * SANDBOX_BUCK2_INITIAL_EXPECTED_UV) / + SANDBOX_ADC_DATA_MASK, + ((u64)SANDBOX_ADC_CHANNEL2_DATA * SANDBOX_BUCK2_INITIAL_EXPECTED_UV) / + SANDBOX_ADC_DATA_MASK, + ((u64)SANDBOX_ADC_CHANNEL3_DATA * SANDBOX_BUCK2_INITIAL_EXPECTED_UV) / + SANDBOX_ADC_DATA_MASK, +}; + +static int dm_test_adc_raw_to_uV(struct unit_test_state *uts) +{ + struct adc_channel *tdata = adc_channel_test_data; + unsigned int i, data; + struct udevice *dev; + int uV; + + ut_assertok(uclass_get_device_by_name(UCLASS_ADC, "adc", &dev)); + /* Test each ADC channel's value in microvolts */ + for (i = 0; i < SANDBOX_ADC_CHANNELS; i++, tdata++) { + ut_assertok(adc_start_channel(dev, tdata->id)); + ut_assertok(adc_channel_data(dev, tdata->id, &data)); + ut_assertok(adc_raw_to_uV(dev, data, &uV)); + ut_asserteq(dm_test_adc_uV_data[i], uV); + } + + return 0; +} +DM_TEST(dm_test_adc_raw_to_uV, DM_TESTF_SCAN_FDT); diff --git a/test/dm/misc.c b/test/dm/misc.c index 61279665ef..4d4232adf1 100644 --- a/test/dm/misc.c +++ b/test/dm/misc.c @@ -21,9 +21,9 @@ static int dm_test_misc(struct unit_test_state *uts) ut_assertok(uclass_get_device_by_name(UCLASS_MISC, "misc-test", &dev)); /* Read / write tests */ - ut_assertok(misc_write(dev, 0, "TEST", 4)); - ut_assertok(misc_write(dev, 4, "WRITE", 5)); - ut_assertok(misc_read(dev, 0, buf, 9)); + ut_asserteq(4, misc_write(dev, 0, "TEST", 4)); + ut_asserteq(5, misc_write(dev, 4, "WRITE", 5)); + ut_asserteq(9, misc_read(dev, 0, buf, 9)); ut_assertok(memcmp(buf, "TESTWRITE", 9)); diff --git a/test/dm/sf.c b/test/dm/sf.c index 35241b9f57..3788d59052 100644 --- a/test/dm/sf.c +++ b/test/dm/sf.c @@ -6,16 +6,67 @@ #include <common.h> #include <dm.h> #include <fdtdec.h> +#include <mapmem.h> +#include <os.h> #include <spi.h> #include <spi_flash.h> #include <asm/state.h> +#include <asm/test.h> #include <dm/test.h> #include <dm/util.h> #include <test/ut.h> -/* Test that sandbox SPI flash works correctly */ +/* Simple test of sandbox SPI flash */ static int dm_test_spi_flash(struct unit_test_state *uts) { + struct udevice *dev, *emul; + int full_size = 0x200000; + int size = 0x10000; + u8 *src, *dst; + int i; + + src = map_sysmem(0x20000, full_size); + ut_assertok(os_write_file("spi.bin", src, full_size)); + ut_assertok(uclass_first_device_err(UCLASS_SPI_FLASH, &dev)); + + dst = map_sysmem(0x20000 + full_size, full_size); + ut_assertok(spi_flash_read_dm(dev, 0, size, dst)); + ut_assertok(memcmp(src, dst, size)); + + /* Erase */ + ut_assertok(spi_flash_erase_dm(dev, 0, size)); + ut_assertok(spi_flash_read_dm(dev, 0, size, dst)); + for (i = 0; i < size; i++) + ut_asserteq(dst[i], 0xff); + + /* Write some new data */ + for (i = 0; i < size; i++) + src[i] = i; + ut_assertok(spi_flash_write_dm(dev, 0, size, src)); + ut_assertok(spi_flash_read_dm(dev, 0, size, dst)); + ut_assertok(memcmp(src, dst, size)); + + /* Try the write-protect stuff */ + ut_assertok(uclass_first_device_err(UCLASS_SPI_EMUL, &emul)); + ut_asserteq(0, spl_flash_get_sw_write_prot(dev)); + sandbox_sf_set_block_protect(emul, 1); + ut_asserteq(1, spl_flash_get_sw_write_prot(dev)); + sandbox_sf_set_block_protect(emul, 0); + ut_asserteq(0, spl_flash_get_sw_write_prot(dev)); + + /* + * Since we are about to destroy all devices, we must tell sandbox + * to forget the emulation device + */ + sandbox_sf_unbind_emul(state_get_current(), 0, 0); + + return 0; +} +DM_TEST(dm_test_spi_flash, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* Functional test that sandbox SPI flash works correctly */ +static int dm_test_spi_flash_func(struct unit_test_state *uts) +{ /* * Create an empty test file and run the SPI flash tests. This is a * long way from being a unit test, but it does test SPI device and @@ -28,7 +79,7 @@ static int dm_test_spi_flash(struct unit_test_state *uts) * benefit is worth the extra complexity. */ ut_asserteq(0, run_command_list( - "sb save hostfs - 0 spi.bin 200000;" + "host save hostfs - 0 spi.bin 200000;" "sf probe;" "sf test 0 10000", -1, 0)); /* @@ -39,4 +90,4 @@ static int dm_test_spi_flash(struct unit_test_state *uts) return 0; } -DM_TEST(dm_test_spi_flash, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); +DM_TEST(dm_test_spi_flash_func, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); diff --git a/test/fs/fs-test.sh b/test/fs/fs-test.sh index 86308cfe2d..721af71d44 100755 --- a/test/fs/fs-test.sh +++ b/test/fs/fs-test.sh @@ -194,7 +194,7 @@ function test_image() { ;; sb) - PREFIX="sb " + PREFIX="host " WRITE="save" SUFFIX="fs -" ;; @@ -217,11 +217,11 @@ function test_image() { # In u-boot commands, <interface> stands for host or hostfs # hostfs maps to the host fs. - # host maps to the "sb bind" that we do + # host maps to the "host bind" that we do $UBOOT << EOF sb=$5 -setenv bind 'if test "\$sb" != sb; then sb bind 0 "$1"; fi' +setenv bind 'if test "\$sb" != sb; then host bind 0 "$1"; fi' run bind # Test Case 1 - ls ${PREFIX}ls host${SUFFIX} $6 @@ -229,7 +229,7 @@ ${PREFIX}ls host${SUFFIX} $6 ${PREFIX}ls host${SUFFIX} invalid_d # # We want ${PREFIX}size host 0:0 $3 for host commands and -# sb size hostfs - $3 for hostfs commands. +# host size hostfs - $3 for hostfs commands. # 1MB is 0x0010 0000 # Test Case 2a - size of small file ${PREFIX}size host${SUFFIX} ${FPATH}$FILE_SMALL @@ -575,7 +575,7 @@ TOTAL_PASS=0 # In each loop, for a given file system image, we test both the # fs command, like load/size/write, the file system specific command -# like: ext4load/ext4size/ext4write and the sb load/ls/save commands. +# like: ext4load/ext4size/ext4write and the host load/ls/save commands. for fs in ext4 fat16 fat32; do echo "Creating $fs image if not already present." @@ -583,11 +583,11 @@ for fs in ext4 fat16 fat32; do MD5_FILE_FS="${MD5_FILE}.${fs}" create_image $IMAGE $fs - # sb commands test + # host commands test echo "Creating files in $fs image if not already present." create_files $IMAGE $MD5_FILE_FS - # Lets mount the image and test sb hostfs commands + # Lets mount the image and test host hostfs commands mkdir -p "$MOUNT_DIR" case "$fs" in fat*) diff --git a/test/py/tests/test_bind.py b/test/py/tests/test_bind.py index f21b7059ea..dee3fee566 100644 --- a/test/py/tests/test_bind.py +++ b/test/py/tests/test_bind.py @@ -13,7 +13,7 @@ def in_tree(response, name, uclass, drv, depth, last_child): else: leaf = leaf + '`' leaf = leaf + '-- ' + name - line = ' *{:10.10} [0-9]* \[ [ +] \] {:10.10} {}$'.format(uclass, drv,leaf) + line = ' *{:10.10} [0-9]* \[ [ +] \] {:20.20} {}$'.format(uclass, drv, leaf) prog = re.compile(line) for l in lines: if prog.match(l): @@ -28,31 +28,31 @@ def test_bind_unbind_with_node(u_boot_console): response = u_boot_console.run_command("bind /bind-test generic_simple_bus") assert response == '' tree = u_boot_console.run_command("dm tree") - assert in_tree(tree, "bind-test", "simple_bus", "generic_simple", 0, True) + assert in_tree(tree, "bind-test", "simple_bus", "generic_simple_bus", 0, True) assert in_tree(tree, "bind-test-child1", "phy", "phy_sandbox", 1, False) - assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple", 1, True) + assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple_bus", 1, True) #Unbind child #1. No error expected and all devices should be there except for bind-test-child1 response = u_boot_console.run_command("unbind /bind-test/bind-test-child1") assert response == '' tree = u_boot_console.run_command("dm tree") - assert in_tree(tree, "bind-test", "simple_bus", "generic_simple", 0, True) + assert in_tree(tree, "bind-test", "simple_bus", "generic_simple_bus", 0, True) assert "bind-test-child1" not in tree - assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple", 1, True) + assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple_bus", 1, True) #bind child #1. No error expected and all devices should be there response = u_boot_console.run_command("bind /bind-test/bind-test-child1 phy_sandbox") assert response == '' tree = u_boot_console.run_command("dm tree") - assert in_tree(tree, "bind-test", "simple_bus", "generic_simple", 0, True) + assert in_tree(tree, "bind-test", "simple_bus", "generic_simple_bus", 0, True) assert in_tree(tree, "bind-test-child1", "phy", "phy_sandbox", 1, True) - assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple", 1, False) + assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple_bus", 1, False) #Unbind child #2. No error expected and all devices should be there except for bind-test-child2 response = u_boot_console.run_command("unbind /bind-test/bind-test-child2") assert response == '' tree = u_boot_console.run_command("dm tree") - assert in_tree(tree, "bind-test", "simple_bus", "generic_simple", 0, True) + assert in_tree(tree, "bind-test", "simple_bus", "generic_simple_bus", 0, True) assert in_tree(tree, "bind-test-child1", "phy", "phy_sandbox", 1, True) assert "bind-test-child2" not in tree @@ -61,9 +61,9 @@ def test_bind_unbind_with_node(u_boot_console): response = u_boot_console.run_command("bind /bind-test/bind-test-child2 generic_simple_bus") assert response == '' tree = u_boot_console.run_command("dm tree") - assert in_tree(tree, "bind-test", "simple_bus", "generic_simple", 0, True) + assert in_tree(tree, "bind-test", "simple_bus", "generic_simple_bus", 0, True) assert in_tree(tree, "bind-test-child1", "phy", "phy_sandbox", 1, False) - assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple", 1, True) + assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple_bus", 1, True) #Unbind parent. No error expected. All devices should be removed and unbound response = u_boot_console.run_command("unbind /bind-test") @@ -89,9 +89,9 @@ def test_bind_unbind_with_node(u_boot_console): response = u_boot_console.run_command("bind /bind-test generic_simple_bus") assert response == '' tree = u_boot_console.run_command("dm tree") - assert in_tree(tree, "bind-test", "simple_bus", "generic_simple", 0, True) + assert in_tree(tree, "bind-test", "simple_bus", "generic_simple_bus", 0, True) assert in_tree(tree, "bind-test-child1", "phy", "phy_sandbox", 1, False) - assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple", 1, True) + assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple_bus", 1, True) response = u_boot_console.run_command("unbind /bind-test") assert response == '' @@ -138,7 +138,7 @@ def test_bind_unbind_with_uclass(u_boot_console): response = u_boot_console.run_command("unbind simple_bus {}".format(child_of_child2_index)) assert response == '' tree = u_boot_console.run_command("dm tree") - assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple", 1, True) + assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple_bus", 1, True) assert not in_tree(tree, "generic_simple_bus", "simple_bus", "generic_simple_bus", 2, True) child_of_child2_line = get_next_line(tree, "bind-test-child2") assert child_of_child2_line == "" @@ -161,7 +161,7 @@ def test_bind_unbind_with_uclass(u_boot_console): assert response == '' tree = u_boot_console.run_command("dm tree") - assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple", 1, True) + assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple_bus", 1, True) child_of_child2_line = get_next_line(tree, "bind-test-child2") assert child_of_child2_line == "" diff --git a/test/py/tests/test_fit.py b/test/py/tests/test_fit.py index 34696e9767..49d6fea571 100755 --- a/test/py/tests/test_fit.py +++ b/test/py/tests/test_fit.py @@ -99,15 +99,15 @@ base_fdt = ''' # then run the 'bootm' command, then save out memory from the places where # we expect 'bootm' to write things. Then quit. base_script = ''' -sb load hostfs 0 %(fit_addr)x %(fit)s +host load hostfs 0 %(fit_addr)x %(fit)s fdt addr %(fit_addr)x bootm start %(fit_addr)x bootm loados -sb save hostfs 0 %(kernel_addr)x %(kernel_out)s %(kernel_size)x -sb save hostfs 0 %(fdt_addr)x %(fdt_out)s %(fdt_size)x -sb save hostfs 0 %(ramdisk_addr)x %(ramdisk_out)s %(ramdisk_size)x -sb save hostfs 0 %(loadables1_addr)x %(loadables1_out)s %(loadables1_size)x -sb save hostfs 0 %(loadables2_addr)x %(loadables2_out)s %(loadables2_size)x +host save hostfs 0 %(kernel_addr)x %(kernel_out)s %(kernel_size)x +host save hostfs 0 %(fdt_addr)x %(fdt_out)s %(fdt_size)x +host save hostfs 0 %(ramdisk_addr)x %(ramdisk_out)s %(ramdisk_size)x +host save hostfs 0 %(loadables1_addr)x %(loadables1_out)s %(loadables1_size)x +host save hostfs 0 %(loadables2_addr)x %(loadables2_out)s %(loadables2_size)x ''' @pytest.mark.boardspec('sandbox') diff --git a/test/py/tests/test_handoff.py b/test/py/tests/test_handoff.py new file mode 100644 index 0000000000..0ee972298c --- /dev/null +++ b/test/py/tests/test_handoff.py @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (c) 2016 Google, Inc + +import pytest + +# Magic number to check that SPL handoff is working +TEST_HANDOFF_MAGIC = 0x14f93c7b + +@pytest.mark.boardspec('sandbox') +@pytest.mark.buildconfigspec('spl') +def test_handoff(u_boot_console): + """Test that of-platdata can be generated and used in sandbox""" + cons = u_boot_console + response = cons.run_command('sb handoff') + assert ('SPL handoff magic %x' % TEST_HANDOFF_MAGIC) in response diff --git a/test/py/tests/test_ofplatdata.py b/test/py/tests/test_ofplatdata.py index dd8a09f032..98103ee71a 100644 --- a/test/py/tests/test_ofplatdata.py +++ b/test/py/tests/test_ofplatdata.py @@ -3,11 +3,40 @@ import pytest -OF_PLATDATA_OUTPUT = '' +OF_PLATDATA_OUTPUT = ''' +of-platdata probe: +bool 1 +byte 05 +bytearray 06 00 00 +int 1 +intarray 2 3 4 0 +longbytearray 09 0a 0b 0c 0d 0e 0f 10 11 +string message +stringarray "multi-word" "message" "" +of-platdata probe: +bool 0 +byte 08 +bytearray 01 23 34 +int 3 +intarray 5 0 0 0 +longbytearray 09 00 00 00 00 00 00 00 00 +string message2 +stringarray "another" "multi-word" "message" +of-platdata probe: +bool 0 +byte 00 +bytearray 00 00 00 +int 0 +intarray 0 0 0 0 +longbytearray 00 00 00 00 00 00 00 00 00 +string <NULL> +stringarray "one" "" "" +''' @pytest.mark.buildconfigspec('spl_of_platdata') def test_ofplatdata(u_boot_console): """Test that of-platdata can be generated and used in sandbox""" cons = u_boot_console + cons.restart_uboot_with_flags(['--show_of_platdata']) output = cons.get_spawn_output().replace('\r', '') assert OF_PLATDATA_OUTPUT in output diff --git a/test/py/tests/test_pinmux.py b/test/py/tests/test_pinmux.py new file mode 100644 index 0000000000..25394f1faf --- /dev/null +++ b/test/py/tests/test_pinmux.py @@ -0,0 +1,66 @@ +# SPDX-License-Identifier: GPL-2.0 + +import pytest +import u_boot_utils + +@pytest.mark.buildconfigspec('cmd_pinmux') +def test_pinmux_usage_1(u_boot_console): + """Test that 'pinmux' command without parameters displays + pinmux usage.""" + output = u_boot_console.run_command('pinmux') + assert 'Usage:' in output + +@pytest.mark.buildconfigspec('cmd_pinmux') +def test_pinmux_usage_2(u_boot_console): + """Test that 'pinmux status' executed without previous "pinmux dev" + command displays pinmux usage.""" + output = u_boot_console.run_command('pinmux status') + assert 'Usage:' in output + +@pytest.mark.buildconfigspec('cmd_pinmux') +@pytest.mark.boardspec('sandbox') +def test_pinmux_status_all(u_boot_console): + """Test that 'pinmux status -a' displays pin's muxing.""" + output = u_boot_console.run_command('pinmux status -a') + assert ('SCL : I2C SCL' in output) + assert ('SDA : I2C SDA' in output) + assert ('TX : Uart TX' in output) + assert ('RX : Uart RX' in output) + assert ('W1 : 1-wire gpio' in output) + +@pytest.mark.buildconfigspec('cmd_pinmux') +@pytest.mark.boardspec('sandbox') +def test_pinmux_list(u_boot_console): + """Test that 'pinmux list' returns the pin-controller list.""" + output = u_boot_console.run_command('pinmux list') + assert 'sandbox_pinctrl' in output + +@pytest.mark.buildconfigspec('cmd_pinmux') +def test_pinmux_dev_bad(u_boot_console): + """Test that 'pinmux dev' returns an error when trying to select a + wrong pin controller.""" + pincontroller = 'bad_pin_controller_name' + output = u_boot_console.run_command('pinmux dev ' + pincontroller) + expected_output = 'Can\'t get the pin-controller: ' + pincontroller + '!' + assert (expected_output in output) + +@pytest.mark.buildconfigspec('cmd_pinmux') +@pytest.mark.boardspec('sandbox') +def test_pinmux_dev(u_boot_console): + """Test that 'pinmux dev' select the wanted pin controller.""" + pincontroller = 'pinctrl' + output = u_boot_console.run_command('pinmux dev ' + pincontroller) + expected_output = 'dev: ' + pincontroller + assert (expected_output in output) + +@pytest.mark.buildconfigspec('cmd_pinmux') +@pytest.mark.boardspec('sandbox') +def test_pinmux_status(u_boot_console): + """Test that 'pinmux status' displays selected pincontroller's pin + muxing descriptions.""" + output = u_boot_console.run_command('pinmux status') + assert ('SCL : I2C SCL' in output) + assert ('SDA : I2C SDA' in output) + assert ('TX : Uart TX' in output) + assert ('RX : Uart RX' in output) + assert ('W1 : 1-wire gpio' in output) diff --git a/test/py/tests/test_vboot.py b/test/py/tests/test_vboot.py index e9cbd57fba..92144d4c1e 100644 --- a/test/py/tests/test_vboot.py +++ b/test/py/tests/test_vboot.py @@ -74,7 +74,7 @@ def test_vboot(u_boot_console): cons.restart_uboot() with cons.log.section('Verified boot %s %s' % (sha_algo, test_type)): output = cons.run_command_list( - ['sb load hostfs - 100 %stest.fit' % tmpdir, + ['host load hostfs - 100 %stest.fit' % tmpdir, 'fdt addr 100', 'bootm 100']) assert(expect_string in ''.join(output)) diff --git a/test/py/u_boot_console_base.py b/test/py/u_boot_console_base.py index 326b2ac51f..e044eb3ea1 100644 --- a/test/py/u_boot_console_base.py +++ b/test/py/u_boot_console_base.py @@ -16,7 +16,7 @@ import sys import u_boot_spawn # Regexes for text we expect U-Boot to send to the console. -pattern_u_boot_spl_signon = re.compile('(U-Boot SPL \\d{4}\\.\\d{2}[^\r\n]*\\))') +pattern_u_boot_spl_signon = re.compile('(U-Boot spl \\d{4}\\.\\d{2}[^\r\n]*\\))') pattern_u_boot_main_signon = re.compile('(U-Boot \\d{4}\\.\\d{2}[^\r\n]*\\))') pattern_stop_autoboot_prompt = re.compile('Hit any key to stop autoboot: ') pattern_unknown_command = re.compile('Unknown command \'.*\' - try \'help\'') diff --git a/test/py/u_boot_console_sandbox.py b/test/py/u_boot_console_sandbox.py index 778f6d0983..836f5a9e2b 100644 --- a/test/py/u_boot_console_sandbox.py +++ b/test/py/u_boot_console_sandbox.py @@ -24,6 +24,7 @@ class ConsoleSandbox(ConsoleBase): """ super(ConsoleSandbox, self).__init__(log, config, max_fifo_fill=1024) + self.sandbox_flags = [] def get_spawn(self): """Connect to a fresh U-Boot instance. @@ -51,8 +52,25 @@ class ConsoleSandbox(ConsoleBase): '-d', self.config.dtb ] + cmd += self.sandbox_flags return Spawn(cmd, cwd=self.config.source_dir) + def restart_uboot_with_flags(self, flags): + """Run U-Boot with the given command-line flags + + Args: + flags: List of flags to pass, each a string + + Returns: + A u_boot_spawn.Spawn object that is attached to U-Boot. + """ + + try: + self.sandbox_flags = flags + return self.restart_uboot() + finally: + self.sandbox_flags = [] + def kill(self, sig): """Send a specific Unix signal to the sandbox process. @@ -19,7 +19,7 @@ run_test "sandbox" ./test/py/test.py --bd sandbox --build # Run tests which require sandbox_spl run_test "sandbox_spl" ./test/py/test.py --bd sandbox_spl --build \ - -k test_ofplatdata.py + -k 'test_ofplatdata or test_handoff' # Run tests for the flat-device-tree version of sandbox. This is a special # build which does not enable CONFIG_OF_LIVE for the live device tree, so we can diff --git a/tools/.gitignore b/tools/.gitignore index c8cdaef90c..e5ede22842 100644 --- a/tools/.gitignore +++ b/tools/.gitignore @@ -24,6 +24,7 @@ /mksunxiboot /mxsboot /ncb +/prelink-riscv /proftool /relocate-rela /sunxi-spl-image-builder diff --git a/tools/binman/README b/tools/binman/README index b64dedf2eb..04ed2b799c 100644 --- a/tools/binman/README +++ b/tools/binman/README @@ -723,6 +723,12 @@ If you need to specify a particular device-tree compiler to use, you can define the DTC environment variable. This can be useful when the system dtc is too old. +To enable a full backtrace and other debugging features in binman, pass +BINMAN_DEBUG=1 to your build: + + make sandbox_defconfig + make BINMAN_DEBUG=1 + History / Credits ----------------- diff --git a/tools/binman/etype/blob.py b/tools/binman/etype/blob.py index 642a0e482a..ae80bbee53 100644 --- a/tools/binman/etype/blob.py +++ b/tools/binman/etype/blob.py @@ -60,7 +60,7 @@ class Entry_blob(Entry): except AttributeError: data = lz4.compress(data) ''' - data = tools.Run('lz4', '-c', self._pathname, ) + data = tools.Run('lz4', '-c', self._pathname) self.SetContents(data) return True diff --git a/tools/binman/etype/u_boot_elf.py b/tools/binman/etype/u_boot_elf.py index 134b6cc15b..f83860dc0a 100644 --- a/tools/binman/etype/u_boot_elf.py +++ b/tools/binman/etype/u_boot_elf.py @@ -30,9 +30,8 @@ class Entry_u_boot_elf(Entry_blob): out_fname = tools.GetOutputFilename('%s.stripped' % uniq) tools.WriteFile(out_fname, tools.ReadFile(self._pathname)) tools.Run('strip', out_fname) - self.SetContents(tools.ReadFile(out_fname)) - else: - self.SetContents(tools.ReadFile(self._pathname)) + self._pathname = out_fname + Entry_blob.ReadBlobContents(self) return True def GetDefaultFilename(self): diff --git a/tools/buildman/builder.py b/tools/buildman/builder.py index 05f8299541..6a6c83bf33 100644 --- a/tools/buildman/builder.py +++ b/tools/buildman/builder.py @@ -290,6 +290,7 @@ class Builder: self._re_function = re.compile('(.*): In function.*') self._re_files = re.compile('In file included from.*') self._re_warning = re.compile('(.*):(\d*):(\d*): warning: .*') + self._re_dtb_warning = re.compile('(.*): Warning .*') self._re_note = re.compile('(.*):(\d*):(\d*): note: this is the location of the previous.*') self.queue = Queue.Queue() @@ -788,7 +789,8 @@ class Builder: self._re_files.match(line)): last_func = line else: - is_warning = self._re_warning.match(line) + is_warning = (self._re_warning.match(line) or + self._re_dtb_warning.match(line)) is_note = self._re_note.match(line) if is_warning or (last_was_warning and is_note): if last_func: @@ -1194,10 +1196,11 @@ class Builder: Print(' ' + line, newline=True, colour=col) - better = [] # List of boards fixed since last commit - worse = [] # List of new broken boards since last commit - new = [] # List of boards that didn't exist last time - unknown = [] # List of boards that were not built + ok_boards = [] # List of boards fixed since last commit + warn_boards = [] # List of boards with warnings since last commit + err_boards = [] # List of new broken boards since last commit + new_boards = [] # List of boards that didn't exist last time + unknown_boards = [] # List of boards that were not built for target in board_dict: if target not in board_selected: @@ -1208,13 +1211,19 @@ class Builder: base_outcome = self._base_board_dict[target].rc outcome = board_dict[target] if outcome.rc == OUTCOME_UNKNOWN: - unknown.append(target) + unknown_boards.append(target) elif outcome.rc < base_outcome: - better.append(target) + if outcome.rc == OUTCOME_WARNING: + warn_boards.append(target) + else: + ok_boards.append(target) elif outcome.rc > base_outcome: - worse.append(target) + if outcome.rc == OUTCOME_WARNING: + warn_boards.append(target) + else: + err_boards.append(target) else: - new.append(target) + new_boards.append(target) # Get a list of errors that have appeared, and disappeared better_err, worse_err = _CalcErrorDelta(self._base_err_lines, @@ -1223,16 +1232,18 @@ class Builder: self._base_warn_line_boards, warn_lines, warn_line_boards, 'w') # Display results by arch - if (better or worse or unknown or new or worse_err or better_err - or worse_warn or better_warn): + if any((ok_boards, warn_boards, err_boards, unknown_boards, new_boards, + worse_err, better_err, worse_warn, better_warn)): arch_list = {} - self.AddOutcome(board_selected, arch_list, better, '', + self.AddOutcome(board_selected, arch_list, ok_boards, '', self.col.GREEN) - self.AddOutcome(board_selected, arch_list, worse, '+', + self.AddOutcome(board_selected, arch_list, warn_boards, 'w+', + self.col.YELLOW) + self.AddOutcome(board_selected, arch_list, err_boards, '+', self.col.RED) - self.AddOutcome(board_selected, arch_list, new, '*', self.col.BLUE) + self.AddOutcome(board_selected, arch_list, new_boards, '*', self.col.BLUE) if self._show_unknown: - self.AddOutcome(board_selected, arch_list, unknown, '?', + self.AddOutcome(board_selected, arch_list, unknown_boards, '?', self.col.MAGENTA) for arch, target_list in arch_list.iteritems(): Print('%10s: %s' % (arch, target_list)) diff --git a/tools/buildman/cmdline.py b/tools/buildman/cmdline.py index 49a8a13118..93d09ca08d 100644 --- a/tools/buildman/cmdline.py +++ b/tools/buildman/cmdline.py @@ -66,7 +66,7 @@ def ParseArgs(): parser.add_option('-l', '--list-error-boards', action='store_true', default=False, help='Show a list of boards next to each error/warning') parser.add_option('--list-tool-chains', action='store_true', default=False, - help='List available tool chains') + help='List available tool chains (use -v to see probing detail)') parser.add_option('-n', '--dry-run', action='store_true', dest='dry_run', default=False, help="Do a dry run (describe actions, but do nothing)") parser.add_option('-N', '--no-subdirs', action='store_true', dest='no_subdirs', diff --git a/tools/buildman/control.py b/tools/buildman/control.py index 96f8ccfe07..c900211510 100644 --- a/tools/buildman/control.py +++ b/tools/buildman/control.py @@ -164,7 +164,7 @@ def DoBuildman(options, args, toolchains=None, make_func=None, boards=None, if no_toolchains: toolchains.GetSettings() - toolchains.Scan(options.list_tool_chains) + toolchains.Scan(options.list_tool_chains and options.verbose) if options.list_tool_chains: toolchains.List() print diff --git a/tools/buildman/test.py b/tools/buildman/test.py index 61a462655f..de02f61be6 100644 --- a/tools/buildman/test.py +++ b/tools/buildman/test.py @@ -46,8 +46,9 @@ make[1]: *** [main.o] Error 1 make: *** [common/libcommon.o] Error 2 Make failed ''', - '''main.c: In function 'main_loop3': -main.c:280:6: warning: unused variable 'mary' [-Wunused-variable] + '''arch/arm/dts/socfpga_arria10_socdk_sdmmc.dtb: Warning \ +(avoid_unnecessary_addr_size): /clocks: unnecessary #address-cells/#size-cells \ +without "ranges" or child "reg" property ''', '''powerpc-linux-ld: warning: dot moved backwards before `.bss' powerpc-linux-ld: warning: dot moved backwards before `.bss' @@ -96,6 +97,8 @@ boards = [ BASE_DIR = 'base' +OUTCOME_OK, OUTCOME_WARN, OUTCOME_ERR = range(3) + class Options: """Class that holds build options""" pass @@ -165,9 +168,10 @@ class TestBuild(unittest.TestCase): result.combined = result.stdout + result.stderr return result - def assertSummary(self, text, arch, plus, boards, ok=False): + def assertSummary(self, text, arch, plus, boards, outcome=OUTCOME_ERR): col = self._col - expected_colour = col.GREEN if ok else col.RED + expected_colour = (col.GREEN if outcome == OUTCOME_OK else + col.YELLOW if outcome == OUTCOME_WARN else col.RED) expect = '%10s: ' % arch # TODO(sjg@chromium.org): If plus is '', we shouldn't need this expect += ' ' + col.Color(expected_colour, plus) @@ -191,6 +195,8 @@ class TestBuild(unittest.TestCase): build.do_make = self.Make board_selected = self.boards.GetSelectedDict() + # Build the boards for the pre-defined commits and warnings/errors + # associated with each. This calls our Make() to inject the fake output. build.BuildBoards(self.commits, board_selected, keep_outputs=False, verbose=False) lines = terminal.GetPrintTestLines() @@ -206,33 +212,49 @@ class TestBuild(unittest.TestCase): build.ShowSummary(self.commits, board_selected) #terminal.EchoPrintTestLines() lines = terminal.GetPrintTestLines() + + # Upstream commit: no errors self.assertEqual(lines[0].text, '01: %s' % commits[0][1]) + + # Second commit: all archs should fail with warnings self.assertEqual(lines[1].text, '02: %s' % commits[1][1]) - # We expect all archs to fail col = terminal.Color() - self.assertSummary(lines[2].text, 'sandbox', '+', ['board4']) - self.assertSummary(lines[3].text, 'arm', '+', ['board1']) - self.assertSummary(lines[4].text, 'powerpc', '+', ['board2', 'board3']) - - # Now we should have the compiler warning + self.assertSummary(lines[2].text, 'sandbox', 'w+', ['board4'], + outcome=OUTCOME_WARN) + self.assertSummary(lines[3].text, 'arm', 'w+', ['board1'], + outcome=OUTCOME_WARN) + self.assertSummary(lines[4].text, 'powerpc', 'w+', ['board2', 'board3'], + outcome=OUTCOME_WARN) + + # Second commit: The warnings should be listed self.assertEqual(lines[5].text, 'w+%s' % errors[0].rstrip().replace('\n', '\nw+')) self.assertEqual(lines[5].colour, col.MAGENTA) + # Third commit: Still fails self.assertEqual(lines[6].text, '03: %s' % commits[2][1]) self.assertSummary(lines[7].text, 'sandbox', '+', ['board4']) - self.assertSummary(lines[8].text, 'arm', '', ['board1'], ok=True) + self.assertSummary(lines[8].text, 'arm', '', ['board1'], + outcome=OUTCOME_OK) self.assertSummary(lines[9].text, 'powerpc', '+', ['board2', 'board3']) - # Compiler error + # Expect a compiler error self.assertEqual(lines[10].text, '+%s' % errors[1].rstrip().replace('\n', '\n+')) + # Fourth commit: Compile errors are fixed, just have warning for board3 self.assertEqual(lines[11].text, '04: %s' % commits[3][1]) - self.assertSummary(lines[12].text, 'sandbox', '', ['board4'], ok=True) - self.assertSummary(lines[13].text, 'powerpc', '', ['board2', 'board3'], - ok=True) + self.assertSummary(lines[12].text, 'sandbox', 'w+', ['board4'], + outcome=OUTCOME_WARN) + expect = '%10s: ' % 'powerpc' + expect += ' ' + col.Color(col.GREEN, '') + expect += ' ' + expect += col.Color(col.GREEN, ' %s' % 'board2') + expect += ' ' + col.Color(col.YELLOW, 'w+') + expect += ' ' + expect += col.Color(col.YELLOW, ' %s' % 'board3') + self.assertEqual(lines[13].text, expect) # Compile error fixed self.assertEqual(lines[14].text, '-%s' % @@ -243,9 +265,11 @@ class TestBuild(unittest.TestCase): errors[2].rstrip().replace('\n', '\nw+')) self.assertEqual(lines[15].colour, col.MAGENTA) + # Fifth commit self.assertEqual(lines[16].text, '05: %s' % commits[4][1]) self.assertSummary(lines[17].text, 'sandbox', '+', ['board4']) - self.assertSummary(lines[18].text, 'powerpc', '', ['board3'], ok=True) + self.assertSummary(lines[18].text, 'powerpc', '', ['board3'], + outcome=OUTCOME_OK) # The second line of errors[3] is a duplicate, so buildman will drop it expect = errors[3].rstrip().split('\n') @@ -256,8 +280,10 @@ class TestBuild(unittest.TestCase): self.assertEqual(lines[20].text, 'w-%s' % errors[2].rstrip().replace('\n', '\nw-')) + # Sixth commit self.assertEqual(lines[21].text, '06: %s' % commits[5][1]) - self.assertSummary(lines[22].text, 'sandbox', '', ['board4'], ok=True) + self.assertSummary(lines[22].text, 'sandbox', '', ['board4'], + outcome=OUTCOME_OK) # The second line of errors[3] is a duplicate, so buildman will drop it expect = errors[3].rstrip().split('\n') @@ -268,6 +294,7 @@ class TestBuild(unittest.TestCase): self.assertEqual(lines[24].text, 'w-%s' % errors[0].rstrip().replace('\n', '\nw-')) + # Seventh commit self.assertEqual(lines[25].text, '07: %s' % commits[6][1]) self.assertSummary(lines[26].text, 'sandbox', '+', ['board4']) diff --git a/tools/k3_x509template.txt b/tools/k3_x509template.txt new file mode 100644 index 0000000000..bd3a9ab056 --- /dev/null +++ b/tools/k3_x509template.txt @@ -0,0 +1,48 @@ + [ req ] + distinguished_name = req_distinguished_name + x509_extensions = v3_ca + prompt = no + dirstring_type = nobmp + + [ req_distinguished_name ] + C = US + ST = TX + L = Dallas + O = Texas Instruments Incorporated + OU = Processors + CN = TI Support + emailAddress = support@ti.com + + [ v3_ca ] + basicConstraints = CA:true + 1.3.6.1.4.1.294.1.1 = ASN1:SEQUENCE:boot_seq + 1.3.6.1.4.1.294.1.2 = ASN1:SEQUENCE:image_integrity + 1.3.6.1.4.1.294.1.3 = ASN1:SEQUENCE:swrv +# 1.3.6.1.4.1.294.1.4 = ASN1:SEQUENCE:encryption + 1.3.6.1.4.1.294.1.8 = ASN1:SEQUENCE:debug + + [ boot_seq ] + certType = INTEGER:TEST_CERT_TYPE + bootCore = INTEGER:TEST_BOOT_CORE + bootCoreOpts = INTEGER:TEST_BOOT_ARCH_WIDTH + destAddr = FORMAT:HEX,OCT:TEST_BOOT_ADDR + imageSize = INTEGER:TEST_IMAGE_LENGTH + + [ image_integrity ] + shaType = OID:2.16.840.1.101.3.4.2.3 + shaValue = FORMAT:HEX,OCT:TEST_IMAGE_SHA_VAL + + [ swrv ] + swrv = INTEGER:0 + +# [ encryption ] +# initalVector = FORMAT:HEX,OCT:TEST_IMAGE_ENC_IV +# randomString = FORMAT:HEX,OCT:TEST_IMAGE_ENC_RS +# iterationCnt = INTEGER:TEST_IMAGE_KEY_DERIVE_INDEX +# salt = FORMAT:HEX,OCT:TEST_IMAGE_KEY_DERIVE_SALT + + [ debug ] + debugType = INTEGER:4 + coreDbgEn = INTEGER:0 + coreDbgSecEn = INTEGER:0 + debugUID = FORMAT:HEX,OCT:0000000000000000000000000000000000000000000000000000000000000000 |