summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/dts/am335x-guardian.dts102
-rw-r--r--arch/arm/dts/am335x-icev2-u-boot.dtsi21
-rw-r--r--arch/arm/dts/am437x-idk-evm-u-boot.dtsi14
-rw-r--r--arch/arm/dts/am571x-idk-u-boot.dtsi5
-rw-r--r--arch/arm/dts/am572x-idk-u-boot.dtsi5
-rw-r--r--arch/arm/dts/am574x-idk-u-boot.dtsi5
-rw-r--r--arch/arm/dts/am57xx-idk-common-u-boot.dtsi23
-rw-r--r--arch/arm/dts/k3-am65-mcu.dtsi40
-rw-r--r--arch/arm/dts/k3-am654-base-board.dts5
-rw-r--r--arch/arm/dts/k3-am654-r5-base-board.dts19
-rw-r--r--arch/arm/dts/k3-j721e-common-proc-board.dts16
-rw-r--r--arch/arm/dts/k3-j721e-main.dtsi111
-rw-r--r--arch/arm/dts/k3-j721e-mcu-wakeup.dtsi38
-rw-r--r--arch/arm/mach-k3/Kconfig21
-rw-r--r--arch/arm/mach-k3/arm64-mmu.c24
-rw-r--r--arch/arm/mach-k3/common.c71
-rw-r--r--arch/arm/mach-k3/common.h7
-rw-r--r--arch/arm/mach-k3/include/mach/hardware.h18
-rw-r--r--arch/arm/mach-k3/sysfw-loader.c21
-rw-r--r--arch/arm/mach-omap2/am33xx/Kconfig1
-rw-r--r--arch/arm/mach-omap2/emif-common.c53
-rw-r--r--arch/arm/mach-omap2/omap5/dra7xx_iodelay.c11
-rw-r--r--board/bosch/guardian/board.c53
-rw-r--r--board/bosch/guardian/mux.c32
-rw-r--r--board/ti/am335x/board.c4
-rw-r--r--board/ti/am43xx/board.c5
-rw-r--r--board/ti/am57xx/board.c5
-rw-r--r--board/ti/am65x/README32
-rw-r--r--board/ti/am65x/evm.c15
-rw-r--r--board/ti/j721e/README227
-rw-r--r--cmd/ti/ddr3.c17
-rw-r--r--common/spl/spl_ymodem.c9
-rw-r--r--configs/am335x_evm_defconfig2
-rw-r--r--configs/am335x_guardian_defconfig25
-rw-r--r--configs/am43xx_evm_defconfig3
-rw-r--r--configs/am57xx_evm_defconfig2
-rw-r--r--configs/am65x_evm_a53_defconfig6
-rw-r--r--configs/am65x_evm_r5_defconfig1
-rw-r--r--configs/am65x_hs_evm_a53_defconfig1
-rw-r--r--configs/j721e_evm_a72_defconfig7
-rw-r--r--doc/device-tree-bindings/clock/ti,cdce9xx.txt49
-rw-r--r--doc/device-tree-bindings/remoteproc/ti,k3-dsp-rproc.txt101
-rw-r--r--doc/device-tree-bindings/remoteproc/ti,k3-r5f-rproc.txt164
-rw-r--r--drivers/clk/Kconfig7
-rw-r--r--drivers/clk/Makefile1
-rw-r--r--drivers/clk/clk-cdce9xx.c254
-rw-r--r--drivers/core/device.c11
-rw-r--r--drivers/mmc/am654_sdhci.c13
-rw-r--r--drivers/remoteproc/Kconfig20
-rw-r--r--drivers/remoteproc/Makefile2
-rw-r--r--drivers/remoteproc/rproc-elf-loader.c179
-rw-r--r--drivers/remoteproc/sandbox_testproc.c4
-rw-r--r--drivers/remoteproc/stm32_copro.c21
-rw-r--r--drivers/remoteproc/ti_k3_dsp_rproc.c354
-rw-r--r--drivers/remoteproc/ti_k3_r5f_rproc.c816
-rw-r--r--drivers/remoteproc/ti_sci_proc.h27
-rw-r--r--include/configs/am335x_guardian.h11
-rw-r--r--include/configs/am65x_evm.h11
-rw-r--r--include/configs/j721e_evm.h14
-rw-r--r--include/configs/tao3530.h2
-rw-r--r--include/configs/ti_armv7_common.h2
-rw-r--r--include/dm/device.h9
-rw-r--r--include/environment/ti/k3_rproc.h52
-rw-r--r--include/remoteproc.h76
-rw-r--r--include/spl.h3
-rw-r--r--test/dm/bus.c41
-rw-r--r--test/dm/remoteproc.c7
67 files changed, 3135 insertions, 193 deletions
diff --git a/arch/arm/dts/am335x-guardian.dts b/arch/arm/dts/am335x-guardian.dts
index f3f022c375..5ed2133e78 100644
--- a/arch/arm/dts/am335x-guardian.dts
+++ b/arch/arm/dts/am335x-guardian.dts
@@ -32,12 +32,19 @@
gpio_keys {
compatible = "gpio-keys";
pinctrl-names = "default";
- pinctrl-0 = <&gpio_keys_pins>;
+ pinctrl-0 = <&guardian_button_pins>;
- button21 {
+ select-button {
+ label = "guardian-select-button";
+ linux,code = <KEY_5>;
+ gpios = <&gpio1 31 GPIO_ACTIVE_LOW>;
+ wakeup-source;
+ };
+
+ power-button {
label = "guardian-power-button";
linux,code = <KEY_POWER>;
- gpios = <&gpio2 21 0>;
+ gpios = <&gpio2 21 GPIO_ACTIVE_LOW>;
wakeup-source;
};
};
@@ -45,19 +52,12 @@
leds {
compatible = "gpio-leds";
pinctrl-names = "default";
- pinctrl-0 = <&leds_pins>;
-
- led1 {
- label = "green:heartbeat";
- gpios = <&gpio1 27 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "heartbeat";
- default-state = "off";
- };
+ pinctrl-0 = <&guardian_led_pins>;
- led2 {
- label = "green:mmc0";
+ life-led {
+ label = "guardian:life-led";
gpios = <&gpio1 26 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "mmc0";
+ linux,default-trigger = "heartbeat";
default-state = "off";
};
};
@@ -140,22 +140,25 @@
gpmc,device-width = <1>;
gpmc,sync-clk-ps = <0>;
gpmc,cs-on-ns = <0>;
- gpmc,cs-rd-off-ns = <44>;
- gpmc,cs-wr-off-ns = <44>;
- gpmc,adv-on-ns = <6>;
- gpmc,adv-rd-off-ns = <34>;
- gpmc,adv-wr-off-ns = <44>;
+ gpmc,cs-rd-off-ns = <30>;
+ gpmc,cs-wr-off-ns = <30>;
+ gpmc,adv-on-ns = <0>;
+ gpmc,adv-rd-off-ns = <30>;
+ gpmc,adv-wr-off-ns = <30>;
gpmc,we-on-ns = <0>;
- gpmc,we-off-ns = <40>;
- gpmc,oe-on-ns = <0>;
- gpmc,oe-off-ns = <54>;
- gpmc,access-ns = <64>;
- gpmc,rd-cycle-ns = <82>;
- gpmc,wr-cycle-ns = <82>;
+ gpmc,we-off-ns = <15>;
+ gpmc,oe-on-ns = <1>;
+ gpmc,oe-off-ns = <15>;
+ gpmc,access-ns = <30>;
+ gpmc,rd-cycle-ns = <30>;
+ gpmc,wr-cycle-ns = <30>;
+ gpmc,wait-on-read = "true";
+ gpmc,wait-on-write = "true";
gpmc,bus-turnaround-ns = <0>;
gpmc,cycle2cycle-delay-ns = <0>;
gpmc,clk-activation-ns = <0>;
- gpmc,wr-access-ns = <40>;
+ gpmc,wait-monitoring-ns = <0>;
+ gpmc,wr-access-ns = <0>;
gpmc,wr-data-mux-bus-ns = <0>;
/*
@@ -199,18 +202,8 @@
};
partition@6 {
- label = "u-boot-env";
- reg = <0x300000 0x40000>;
- };
-
- partition@7 {
- label = "u-boot-env.backup1";
- reg = <0x340000 0x40000>;
- };
-
- partition@8 {
label = "UBI";
- reg = <0x380000 0x1fc80000>;
+ reg = <0x300000 0x1fd00000>;
};
};
};
@@ -326,6 +319,12 @@
status = "okay";
};
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_pins>;
+ status = "okay";
+};
+
&usb {
status = "okay";
};
@@ -354,7 +353,7 @@
&am33xx_pinmux {
pinctrl-names = "default";
- pinctrl-0 = <&clkout2_pin &gpio_pins>;
+ pinctrl-0 = <&clkout2_pin &guardian_interface_pins>;
clkout2_pin: pinmux_clkout2_pin {
pinctrl-single,pins = <
@@ -368,16 +367,25 @@
>;
};
- gpio_keys_pins: pinmux_gpio_keys_pins {
+ guardian_button_pins: pinmux_gpio_keys_pins {
pinctrl-single,pins = <
AM33XX_IOPAD(0x940, PIN_INPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x884, PIN_INPUT | MUX_MODE7)
>;
};
- gpio_pins: pinmux_gpio_pins {
+ guardian_interface_pins: pinmux_guardian_interface_pins {
pinctrl-single,pins = <
- AM33XX_IOPAD(0x928, PIN_OUTPUT | MUX_MODE7)
- AM33XX_IOPAD(0x990, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x928, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x990, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x9ac, PIN_OUTPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x980, PIN_INPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x984, PIN_INPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x928, PIN_OUTPUT_PULLUP | MUX_MODE7)
+ AM33XX_IOPAD(0x90c, PIN_OUTPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x944, PIN_OUTPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x91c, PIN_INPUT | MUX_MODE7)
+ AM33XX_IOPAD(0x918, PIN_OUTPUT_PULLDOWN | MUX_MODE7)
>;
};
@@ -452,10 +460,9 @@
>;
};
- leds_pins: pinmux_leds_pins {
+ guardian_led_pins: pinmux_leds_pins {
pinctrl-single,pins = <
AM33XX_IOPAD(0x868, PIN_OUTPUT | MUX_MODE7)
- AM33XX_IOPAD(0x86c, PIN_OUTPUT | MUX_MODE7)
>;
};
@@ -487,6 +494,13 @@
>;
};
+ uart2_pins: pinmux_uart2_pins {
+ pinctrl-single,pins = <
+ AM33XX_IOPAD(0x92c, PIN_INPUT_PULLUP | MUX_MODE1)
+ AM33XX_IOPAD(0x930, PIN_OUTPUT_PULLDOWN | MUX_MODE1)
+ >;
+ };
+
nandflash_pins: pinmux_nandflash_pins {
pinctrl-single,pins = <
AM33XX_IOPAD(0x800, PIN_INPUT | MUX_MODE0)
diff --git a/arch/arm/dts/am335x-icev2-u-boot.dtsi b/arch/arm/dts/am335x-icev2-u-boot.dtsi
new file mode 100644
index 0000000000..cc9569af03
--- /dev/null
+++ b/arch/arm/dts/am335x-icev2-u-boot.dtsi
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
+ */
+/ {
+ xtal25mhz: xtal25mhz {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ };
+};
+
+&i2c0 {
+ cdce913: cdce913@65 {
+ compatible = "ti,cdce913";
+ reg = <0x65>;
+ clocks = <&xtal25mhz>;
+ #clock-cells = <1>;
+ xtal-load-pf = <0>;
+ };
+};
diff --git a/arch/arm/dts/am437x-idk-evm-u-boot.dtsi b/arch/arm/dts/am437x-idk-evm-u-boot.dtsi
index 3aa9195e44..50fe09cfc3 100644
--- a/arch/arm/dts/am437x-idk-evm-u-boot.dtsi
+++ b/arch/arm/dts/am437x-idk-evm-u-boot.dtsi
@@ -9,6 +9,12 @@
ocp {
u-boot,dm-spl;
};
+
+ xtal25mhz: xtal25mhz {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ };
};
&uart0 {
@@ -17,6 +23,14 @@
&i2c0 {
u-boot,dm-spl;
+
+ cdce913: cdce913@65 {
+ compatible = "ti,cdce913";
+ reg = <0x65>;
+ clocks = <&xtal25mhz>;
+ #clock-cells = <1>;
+ xtal-load-pf = <0>;
+ };
};
&mmc1 {
diff --git a/arch/arm/dts/am571x-idk-u-boot.dtsi b/arch/arm/dts/am571x-idk-u-boot.dtsi
new file mode 100644
index 0000000000..65199200ed
--- /dev/null
+++ b/arch/arm/dts/am571x-idk-u-boot.dtsi
@@ -0,0 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
+ */
+#include "am57xx-idk-common-u-boot.dtsi"
diff --git a/arch/arm/dts/am572x-idk-u-boot.dtsi b/arch/arm/dts/am572x-idk-u-boot.dtsi
new file mode 100644
index 0000000000..65199200ed
--- /dev/null
+++ b/arch/arm/dts/am572x-idk-u-boot.dtsi
@@ -0,0 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
+ */
+#include "am57xx-idk-common-u-boot.dtsi"
diff --git a/arch/arm/dts/am574x-idk-u-boot.dtsi b/arch/arm/dts/am574x-idk-u-boot.dtsi
new file mode 100644
index 0000000000..65199200ed
--- /dev/null
+++ b/arch/arm/dts/am574x-idk-u-boot.dtsi
@@ -0,0 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
+ */
+#include "am57xx-idk-common-u-boot.dtsi"
diff --git a/arch/arm/dts/am57xx-idk-common-u-boot.dtsi b/arch/arm/dts/am57xx-idk-common-u-boot.dtsi
new file mode 100644
index 0000000000..b07aea0048
--- /dev/null
+++ b/arch/arm/dts/am57xx-idk-common-u-boot.dtsi
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
+ */
+#include "omap5-u-boot.dtsi"
+
+/ {
+ xtal25mhz: xtal25mhz {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ };
+};
+
+&i2c1 {
+ cdce913: cdce913@65 {
+ compatible = "ti,cdce913";
+ reg = <0x65>;
+ clocks = <&xtal25mhz>;
+ #clock-cells = <1>;
+ xtal-load-pf = <0>;
+ };
+};
diff --git a/arch/arm/dts/k3-am65-mcu.dtsi b/arch/arm/dts/k3-am65-mcu.dtsi
index c9bfd9b80f..c42e7553c7 100644
--- a/arch/arm/dts/k3-am65-mcu.dtsi
+++ b/arch/arm/dts/k3-am65-mcu.dtsi
@@ -2,7 +2,7 @@
/*
* Device Tree Source for AM6 SoC Family MCU Domain peripherals
*
- * Copyright (C) 2016-2018 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2016-2019 Texas Instruments Incorporated - http://www.ti.com/
*/
&cbass_mcu {
@@ -26,4 +26,42 @@
clocks = <&k3_clks 114 1>;
power-domains = <&k3_pds 114 TI_SCI_PD_EXCLUSIVE>;
};
+
+ mcu_r5fss0: r5fss@41000000 {
+ compatible = "ti,am654-r5fss";
+ lockstep-mode = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x41000000 0x00 0x41000000 0x20000>,
+ <0x41400000 0x00 0x41400000 0x20000>;
+ power-domains = <&k3_pds 129 TI_SCI_PD_EXCLUSIVE>;
+
+ mcu_r5fss0_core0: r5f@41000000 {
+ compatible = "ti,am654-r5f";
+ reg = <0x41000000 0x00008000>,
+ <0x41010000 0x00008000>;
+ reg-names = "atcm", "btcm";
+ ti,sci = <&dmsc>;
+ ti,sci-dev-id = <159>;
+ ti,sci-proc-ids = <0x01 0xFF>;
+ resets = <&k3_reset 159 1>;
+ atcm-enable = <1>;
+ btcm-enable = <1>;
+ loczrama = <1>;
+ };
+
+ mcu_r5fss0_core1: r5f@41400000 {
+ compatible = "ti,am654-r5f";
+ reg = <0x41400000 0x00008000>,
+ <0x41410000 0x00008000>;
+ reg-names = "atcm", "btcm";
+ ti,sci = <&dmsc>;
+ ti,sci-dev-id = <245>;
+ ti,sci-proc-ids = <0x02 0xFF>;
+ resets = <&k3_reset 245 1>;
+ atcm-enable = <1>;
+ btcm-enable = <1>;
+ loczrama = <1>;
+ };
+ };
};
diff --git a/arch/arm/dts/k3-am654-base-board.dts b/arch/arm/dts/k3-am654-base-board.dts
index e73b9aa6b1..573ead0b4d 100644
--- a/arch/arm/dts/k3-am654-base-board.dts
+++ b/arch/arm/dts/k3-am654-base-board.dts
@@ -17,6 +17,11 @@
bootargs = "earlycon=ns16550a,mmio32,0x02800000";
};
+ aliases {
+ remoteproc0 = &mcu_r5fss0_core0;
+ remoteproc1 = &mcu_r5fss0_core1;
+ };
+
memory@80000000 {
device_type = "memory";
/* 4G RAM */
diff --git a/arch/arm/dts/k3-am654-r5-base-board.dts b/arch/arm/dts/k3-am654-r5-base-board.dts
index 7ed307f0d8..e31ed4fe64 100644
--- a/arch/arm/dts/k3-am654-r5-base-board.dts
+++ b/arch/arm/dts/k3-am654-r5-base-board.dts
@@ -16,6 +16,7 @@
aliases {
serial0 = &wkup_uart0;
+ serial1 = &mcu_uart0;
serial2 = &main_uart0;
};
@@ -118,6 +119,14 @@
status = "okay";
};
+&mcu_uart0 {
+ u-boot,dm-spl;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcu_uart0_pins_default>;
+ clock-frequency = <48000000>;
+ status = "okay";
+};
+
&main_uart0 {
power-domains = <&k3_pds 146 TI_SCI_PD_SHARED>;
};
@@ -141,6 +150,16 @@
u-boot,dm-spl;
};
+ mcu_uart0_pins_default: mcu_uart0_pins_default {
+ pinctrl-single,pins = <
+ AM65X_WKUP_IOPAD(0x0044, PIN_INPUT, 4) /* (P4) MCU_OSPI1_D1.MCU_UART0_RXD */
+ AM65X_WKUP_IOPAD(0x0048, PIN_OUTPUT, 4) /* (P5) MCU_OSPI1_D2.MCU_UART0_TXD */
+ AM65X_WKUP_IOPAD(0x004C, PIN_INPUT, 4) /* (P1) MCU_OSPI1_D3.MCU_UART0_CTSn */
+ AM65X_WKUP_IOPAD(0x0054, PIN_OUTPUT, 4) /* (N3) MCU_OSPI1_CSn1.MCU_UART0_RTSn */
+ >;
+ u-boot,dm-spl;
+ };
+
wkup_i2c0_pins_default: wkup-i2c0-pins-default {
pinctrl-single,pins = <
AM65X_WKUP_IOPAD(0x00e0, PIN_INPUT, 0) /* (AC7) WKUP_I2C0_SCL */
diff --git a/arch/arm/dts/k3-j721e-common-proc-board.dts b/arch/arm/dts/k3-j721e-common-proc-board.dts
index b5b8c3c5cc..c978cabd13 100644
--- a/arch/arm/dts/k3-j721e-common-proc-board.dts
+++ b/arch/arm/dts/k3-j721e-common-proc-board.dts
@@ -12,6 +12,18 @@
stdout-path = "serial2:115200n8";
bootargs = "console=ttyS2,115200n8 earlycon=ns16550a,mmio32,0x02800000";
};
+
+ aliases {
+ remoteproc0 = &mcu_r5fss0_core0;
+ remoteproc1 = &mcu_r5fss0_core1;
+ remoteproc2 = &main_r5fss0_core0;
+ remoteproc3 = &main_r5fss0_core1;
+ remoteproc4 = &main_r5fss1_core0;
+ remoteproc5 = &main_r5fss1_core1;
+ remoteproc6 = &c66_0;
+ remoteproc7 = &c66_1;
+ remoteproc8 = &c71_0;
+ };
};
&wkup_uart0 {
@@ -19,6 +31,10 @@
status = "disabled";
};
+&main_uart0 {
+ power-domains = <&k3_pds 146 TI_SCI_PD_SHARED>;
+};
+
&main_uart3 {
/* UART not brought out */
status = "disabled";
diff --git a/arch/arm/dts/k3-j721e-main.dtsi b/arch/arm/dts/k3-j721e-main.dtsi
index 3445784293..6bd59bac52 100644
--- a/arch/arm/dts/k3-j721e-main.dtsi
+++ b/arch/arm/dts/k3-j721e-main.dtsi
@@ -228,4 +228,115 @@
ti,trm-icp = <0x8>;
dma-coherent;
};
+
+ main_r5fss0: r5fss@5c00000 {
+ compatible = "ti,j721e-r5fss";
+ lockstep-mode = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x5c00000 0x00 0x5c00000 0x20000>,
+ <0x5d00000 0x00 0x5d00000 0x20000>;
+ power-domains = <&k3_pds 243 TI_SCI_PD_EXCLUSIVE>;
+
+ main_r5fss0_core0: r5f@5c00000 {
+ compatible = "ti,j721e-r5f";
+ reg = <0x5c00000 0x00008000>,
+ <0x5c10000 0x00008000>;
+ reg-names = "atcm", "btcm";
+ ti,sci = <&dmsc>;
+ ti,sci-dev-id = <245>;
+ ti,sci-proc-ids = <0x06 0xFF>;
+ resets = <&k3_reset 245 1>;
+ atcm-enable = <1>;
+ btcm-enable = <1>;
+ loczrama = <1>;
+ };
+
+ main_r5fss0_core1: r5f@5d00000 {
+ compatible = "ti,j721e-r5f";
+ reg = <0x5d00000 0x00008000>,
+ <0x5d10000 0x00008000>;
+ reg-names = "atcm", "btcm";
+ ti,sci = <&dmsc>;
+ ti,sci-dev-id = <246>;
+ ti,sci-proc-ids = <0x07 0xFF>;
+ resets = <&k3_reset 246 1>;
+ atcm-enable = <1>;
+ btcm-enable = <1>;
+ loczrama = <1>;
+ };
+ };
+
+ main_r5fss1: r5fss@5e00000 {
+ compatible = "ti,j721e-r5fss";
+ lockstep-mode = <1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x5e00000 0x00 0x5e00000 0x20000>,
+ <0x5f00000 0x00 0x5f00000 0x20000>;
+ power-domains = <&k3_pds 244 TI_SCI_PD_EXCLUSIVE>;
+
+ main_r5fss1_core0: r5f@5e00000 {
+ compatible = "ti,j721e-r5f";
+ reg = <0x5e00000 0x00008000>,
+ <0x5e10000 0x00008000>;
+ reg-names = "atcm", "btcm";
+ ti,sci = <&dmsc>;
+ ti,sci-dev-id = <247>;
+ ti,sci-proc-ids = <0x08 0xFF>;
+ resets = <&k3_reset 247 1>;
+ atcm-enable = <1>;
+ btcm-enable = <1>;
+ loczrama = <1>;
+ };
+
+ main_r5fss1_core1: r5f@5f00000 {
+ compatible = "ti,j721e-r5f";
+ reg = <0x5f00000 0x00008000>,
+ <0x5f10000 0x00008000>;
+ reg-names = "atcm", "btcm";
+ ti,sci = <&dmsc>;
+ ti,sci-dev-id = <248>;
+ ti,sci-proc-ids = <0x09 0xFF>;
+ resets = <&k3_reset 248 1>;
+ atcm-enable = <1>;
+ btcm-enable = <1>;
+ loczrama = <1>;
+ };
+ };
+
+ c66_0: dsp@4d80800000 {
+ compatible = "ti,j721e-c66-dsp";
+ reg = <0x4d 0x80800000 0x00 0x00048000>,
+ <0x4d 0x80e00000 0x00 0x00008000>,
+ <0x4d 0x80f00000 0x00 0x00008000>;
+ reg-names = "l2sram", "l1pram", "l1dram";
+ ti,sci = <&dmsc>;
+ ti,sci-dev-id = <142>;
+ ti,sci-proc-ids = <0x03 0xFF>;
+ resets = <&k3_reset 142 1>;
+ };
+
+ c66_1: dsp@4d81800000 {
+ compatible = "ti,j721e-c66-dsp";
+ reg = <0x4d 0x81800000 0x00 0x00048000>,
+ <0x4d 0x81e00000 0x00 0x00008000>,
+ <0x4d 0x81f00000 0x00 0x00008000>;
+ reg-names = "l2sram", "l1pram", "l1dram";
+ ti,sci = <&dmsc>;
+ ti,sci-dev-id = <143>;
+ ti,sci-proc-ids = <0x04 0xFF>;
+ resets = <&k3_reset 143 1>;
+ };
+
+ c71_0: dsp@64800000 {
+ compatible = "ti,j721e-c71-dsp";
+ reg = <0x00 0x64800000 0x00 0x00080000>,
+ <0x00 0x64e00000 0x00 0x0000c000>;
+ reg-names = "l2sram", "l1dram";
+ ti,sci = <&dmsc>;
+ ti,sci-dev-id = <15>;
+ ti,sci-proc-ids = <0x30 0xFF>;
+ resets = <&k3_reset 15 1>;
+ };
};
diff --git a/arch/arm/dts/k3-j721e-mcu-wakeup.dtsi b/arch/arm/dts/k3-j721e-mcu-wakeup.dtsi
index 1175fa9a50..b958b5b3c1 100644
--- a/arch/arm/dts/k3-j721e-mcu-wakeup.dtsi
+++ b/arch/arm/dts/k3-j721e-mcu-wakeup.dtsi
@@ -69,4 +69,42 @@
clocks = <&k3_clks 149 0>;
clock-names = "fclk";
};
+
+ mcu_r5fss0: r5fss@41000000 {
+ compatible = "ti,j721e-r5fss";
+ lockstep-mode = <1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x41000000 0x00 0x41000000 0x20000>,
+ <0x41400000 0x00 0x41400000 0x20000>;
+ power-domains = <&k3_pds 249 TI_SCI_PD_EXCLUSIVE>;
+
+ mcu_r5fss0_core0: r5f@41000000 {
+ compatible = "ti,j721e-r5f";
+ reg = <0x41000000 0x00008000>,
+ <0x41010000 0x00008000>;
+ reg-names = "atcm", "btcm";
+ ti,sci = <&dmsc>;
+ ti,sci-dev-id = <250>;
+ ti,sci-proc-ids = <0x01 0xFF>;
+ resets = <&k3_reset 250 1>;
+ atcm-enable = <1>;
+ btcm-enable = <1>;
+ loczrama = <1>;
+ };
+
+ mcu_r5fss0_core1: r5f@41400000 {
+ compatible = "ti,j721e-r5f";
+ reg = <0x41400000 0x00008000>,
+ <0x41410000 0x00008000>;
+ reg-names = "atcm", "btcm";
+ ti,sci = <&dmsc>;
+ ti,sci-dev-id = <251>;
+ ti,sci-proc-ids = <0x02 0xFF>;
+ resets = <&k3_reset 251 1>;
+ atcm-enable = <1>;
+ btcm-enable = <1>;
+ loczrama = <1>;
+ };
+ };
};
diff --git a/arch/arm/mach-k3/Kconfig b/arch/arm/mach-k3/Kconfig
index de1c1cc73f..5583241943 100644
--- a/arch/arm/mach-k3/Kconfig
+++ b/arch/arm/mach-k3/Kconfig
@@ -66,6 +66,27 @@ config SYS_K3_BOOT_CORE_ID
int
default 16
+config K3_EARLY_CONS
+ bool "Activate to allow for an early console during SPL"
+ depends on SPL
+ help
+ Turn this option on to enable an early console functionality in SPL
+ before the main console is being brought up. This can be useful in
+ situations where the main console is dependent on System Firmware
+ (SYSFW) being up and running, which is usually not the case during
+ the very early stages of boot. Using this early console functionality
+ will allow for an alternate serial port to be used to support things
+ like UART-based boot and early diagnostic messages until the main
+ console is ready to get activated.
+
+config K3_EARLY_CONS_IDX
+ depends on K3_EARLY_CONS
+ int "Index of serial device to use for SPL early console"
+ default 1
+ help
+ Use this option to set the index of the serial device to be used
+ for the early console during SPL execution.
+
config K3_LOAD_SYSFW
bool
depends on SPL
diff --git a/arch/arm/mach-k3/arm64-mmu.c b/arch/arm/mach-k3/arm64-mmu.c
index 82778d2197..7f908eee80 100644
--- a/arch/arm/mach-k3/arm64-mmu.c
+++ b/arch/arm/mach-k3/arm64-mmu.c
@@ -14,7 +14,7 @@
#ifdef CONFIG_SOC_K3_AM6
/* NR_DRAM_BANKS + 32bit IO + 64bit IO + terminator */
-#define NR_MMU_REGIONS (CONFIG_NR_DRAM_BANKS + 3)
+#define NR_MMU_REGIONS (CONFIG_NR_DRAM_BANKS + 5)
/* ToDo: Add 64bit IO */
struct mm_region am654_mem_map[NR_MMU_REGIONS] = {
@@ -28,7 +28,19 @@ struct mm_region am654_mem_map[NR_MMU_REGIONS] = {
}, {
.virt = 0x80000000UL,
.phys = 0x80000000UL,
- .size = 0x80000000UL,
+ .size = 0x20000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_INNER_SHARE
+ }, {
+ .virt = 0xa0000000UL,
+ .phys = 0xa0000000UL,
+ .size = 0x02100000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) |
+ PTE_BLOCK_INNER_SHARE
+ }, {
+ .virt = 0xa2100000UL,
+ .phys = 0xa2100000UL,
+ .size = 0x5df00000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
}, {
@@ -68,13 +80,13 @@ struct mm_region j721e_mem_map[NR_MMU_REGIONS] = {
}, {
.virt = 0xa0000000UL,
.phys = 0xa0000000UL,
- .size = 0x0bc00000UL,
+ .size = 0x1bc00000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) |
PTE_BLOCK_NON_SHARE
}, {
- .virt = 0xabc00000UL,
- .phys = 0xabc00000UL,
- .size = 0x54400000UL,
+ .virt = 0xbbc00000UL,
+ .phys = 0xbbc00000UL,
+ .size = 0x44400000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
}, {
diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c
index c16afc654f..f8274b39d6 100644
--- a/arch/arm/mach-k3/common.c
+++ b/arch/arm/mach-k3/common.c
@@ -14,19 +14,48 @@
#include <linux/soc/ti/ti_sci_protocol.h>
#include <fdt_support.h>
#include <asm/arch/sys_proto.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
struct ti_sci_handle *get_ti_sci_handle(void)
{
struct udevice *dev;
int ret;
- ret = uclass_get_device(UCLASS_FIRMWARE, 0, &dev);
+ ret = uclass_get_device_by_driver(UCLASS_FIRMWARE,
+ DM_GET_DRIVER(ti_sci), &dev);
if (ret)
panic("Failed to get SYSFW (%d)\n", ret);
return (struct ti_sci_handle *)ti_sci_get_handle_from_sysfw(dev);
}
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_K3_EARLY_CONS
+int early_console_init(void)
+{
+ struct udevice *dev;
+ int ret;
+
+ gd->baudrate = CONFIG_BAUDRATE;
+
+ ret = uclass_get_device_by_seq(UCLASS_SERIAL, CONFIG_K3_EARLY_CONS_IDX,
+ &dev);
+ if (ret) {
+ printf("Error getting serial dev for early console! (%d)\n",
+ ret);
+ return ret;
+ }
+
+ gd->cur_serial_dev = dev;
+ gd->flags |= GD_FLG_SERIAL_READY;
+ gd->have_console = 1;
+
+ return 0;
+}
+#endif
+
#ifdef CONFIG_SYS_K3_SPL_ATF
void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
{
@@ -164,3 +193,43 @@ void reset_cpu(ulong ignored)
{
}
#endif
+
+#if defined(CONFIG_DISPLAY_CPUINFO)
+int print_cpuinfo(void)
+{
+ u32 soc, rev;
+ char *name;
+
+ soc = (readl(CTRLMMR_WKUP_JTAG_DEVICE_ID) &
+ DEVICE_ID_FAMILY_MASK) >> DEVICE_ID_FAMILY_SHIFT;
+ rev = (readl(CTRLMMR_WKUP_JTAG_ID) &
+ JTAG_ID_VARIANT_MASK) >> JTAG_ID_VARIANT_SHIFT;
+
+ printf("SoC: ");
+ switch (soc) {
+ case AM654:
+ name = "AM654";
+ break;
+ case J721E:
+ name = "J721E";
+ break;
+ default:
+ name = "Unknown Silicon";
+ };
+
+ printf("%s PG ", name);
+ switch (rev) {
+ case REV_PG1_0:
+ name = "1.0";
+ break;
+ case REV_PG2_0:
+ name = "2.0";
+ break;
+ default:
+ name = "Unknown Revision";
+ };
+ printf("%s\n", name);
+
+ return 0;
+}
+#endif
diff --git a/arch/arm/mach-k3/common.h b/arch/arm/mach-k3/common.h
index ac7e80d9af..8f9a023921 100644
--- a/arch/arm/mach-k3/common.h
+++ b/arch/arm/mach-k3/common.h
@@ -8,4 +8,11 @@
#include <asm/armv7_mpu.h>
+#define AM654 2
+#define J721E 4
+
+#define REV_PG1_0 0
+#define REV_PG2_0 1
+
void setup_k3_mpu_regions(void);
+int early_console_init(void);
diff --git a/arch/arm/mach-k3/include/mach/hardware.h b/arch/arm/mach-k3/include/mach/hardware.h
index 4e629822aa..d670d5a56e 100644
--- a/arch/arm/mach-k3/include/mach/hardware.h
+++ b/arch/arm/mach-k3/include/mach/hardware.h
@@ -13,4 +13,22 @@
#ifdef CONFIG_SOC_K3_J721E
#include "j721e_hardware.h"
#endif
+
+/* Assuming these addresses and definitions stay common across K3 devices */
+#define CTRLMMR_WKUP_JTAG_DEVICE_ID 0x43000018
+#define DEVICE_ID_FAMILY_SHIFT 26
+#define DEVICE_ID_FAMILY_MASK (0x3f << 26)
+#define DEVICE_ID_BASE_SHIFT 11
+#define DEVICE_ID_BASE_MASK (0x1fff << 11)
+#define DEVICE_ID_SPEED_SHIFT 6
+#define DEVICE_ID_SPEED_MASK (0x1f << 6)
+#define DEVICE_ID_TEMP_SHIFT 3
+#define DEVICE_ID_TEMP_MASK (0x7 << 3)
+
+#define CTRLMMR_WKUP_JTAG_ID 0x43000014
+#define JTAG_ID_VARIANT_SHIFT 28
+#define JTAG_ID_VARIANT_MASK (0xf << 28)
+#define JTAG_ID_PARTNO_SHIFT 12
+#define JTAG_ID_PARTNO_MASK (0x7ff << 1)
+
#endif /* _ASM_ARCH_HARDWARE_H_ */
diff --git a/arch/arm/mach-k3/sysfw-loader.c b/arch/arm/mach-k3/sysfw-loader.c
index 7a482bdc8a..5903bbe12a 100644
--- a/arch/arm/mach-k3/sysfw-loader.c
+++ b/arch/arm/mach-k3/sysfw-loader.c
@@ -12,6 +12,9 @@
#include <remoteproc.h>
#include <linux/soc/ti/ti_sci_protocol.h>
#include <asm/arch/sys_proto.h>
+#include "common.h"
+
+DECLARE_GLOBAL_DATA_PTR;
/* Name of the FIT image nodes for SYSFW and its config data */
#define SYSFW_FIRMWARE "sysfw.bin"
@@ -215,6 +218,24 @@ void k3_sysfw_loader(void (*config_pm_done_callback)(void))
#endif
break;
#endif
+#if CONFIG_IS_ENABLED(YMODEM_SUPPORT)
+ case BOOT_DEVICE_UART:
+#ifdef CONFIG_K3_EARLY_CONS
+ /*
+ * Establish a serial console if not yet available as required
+ * for UART-based boot. For this use the early console feature
+ * that allows setting up a UART for use before SYSFW has been
+ * brought up. Note that the associated UART module's clocks
+ * must have gotten enabled by the ROM bootcode which will be
+ * the case when continuing to boot serially from the same
+ * UART that the ROM loaded the initial bootloader from.
+ */
+ if (!gd->have_console)
+ early_console_init();
+#endif
+ ret = spl_ymodem_load_image(&spl_image, &bootdev);
+ break;
+#endif
default:
panic("Loading SYSFW image from device %u not supported!\n",
bootdev.boot_device);
diff --git a/arch/arm/mach-omap2/am33xx/Kconfig b/arch/arm/mach-omap2/am33xx/Kconfig
index 7f6b344c82..39d9c2873b 100644
--- a/arch/arm/mach-omap2/am33xx/Kconfig
+++ b/arch/arm/mach-omap2/am33xx/Kconfig
@@ -89,6 +89,7 @@ config TARGET_AM335X_SHC
config TARGET_AM335X_GUARDIAN
bool "Support am335x based guardian board from bosch"
+ select BOARD_LATE_INIT
select DM
select DM_SERIAL
select DM_GPIO
diff --git a/arch/arm/mach-omap2/emif-common.c b/arch/arm/mach-omap2/emif-common.c
index b384343a3f..290f9dcdb0 100644
--- a/arch/arm/mach-omap2/emif-common.c
+++ b/arch/arm/mach-omap2/emif-common.c
@@ -348,52 +348,63 @@ static void dra7_reset_ddr_data(u32 base, u32 size)
static void dra7_enable_ecc(u32 base, const struct emif_regs *regs)
{
struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
- u32 rgn, size;
+ u32 rgn, rgn_start, size, ctrl_reg;
/* ECC available only on dra76x EMIF1 */
if ((base != EMIF1_BASE) || !is_dra76x())
return;
if (regs->emif_ecc_ctrl_reg & EMIF_ECC_CTRL_REG_ECC_EN_MASK) {
+ /* Disable high-order interleaving */
+ clrbits_le32(MA_PRIORITY, MA_HIMEM_INTERLEAVE_UN_MASK);
+
+#ifdef CONFIG_DRA7XX
+ /* Clear the status flags and other history */
+ writel(readl(&emif->emif_1b_ecc_err_cnt),
+ &emif->emif_1b_ecc_err_cnt);
+ writel(0xffffffff, &emif->emif_1b_ecc_err_dist_1);
+ writel(0x2, &emif->emif_1b_ecc_err_addr_log);
+ writel(0x1, &emif->emif_2b_ecc_err_addr_log);
+ writel(EMIF_INT_WR_ECC_ERR_SYS_MASK |
+ EMIF_INT_TWOBIT_ECC_ERR_SYS_MASK |
+ EMIF_INT_ONEBIT_ECC_ERR_SYS_MASK,
+ &emif->emif_irqstatus_sys);
+#endif
writel(regs->emif_ecc_address_range_1,
&emif->emif_ecc_address_range_1);
writel(regs->emif_ecc_address_range_2,
&emif->emif_ecc_address_range_2);
- writel(regs->emif_ecc_ctrl_reg, &emif->emif_ecc_ctrl_reg);
+
+ /* Disable RMW and ECC verification for read accesses */
+ ctrl_reg = (regs->emif_ecc_ctrl_reg &
+ ~EMIF_ECC_REG_RMW_EN_MASK) |
+ EMIF_ECC_CTRL_REG_ECC_VERIFY_DIS_MASK;
+ writel(ctrl_reg, &emif->emif_ecc_ctrl_reg);
/* Set region1 memory with 0 */
- rgn = ((regs->emif_ecc_address_range_1 &
- EMIF_ECC_REG_ECC_START_ADDR_MASK) << 16) +
- CONFIG_SYS_SDRAM_BASE;
+ rgn_start = (regs->emif_ecc_address_range_1 &
+ EMIF_ECC_REG_ECC_START_ADDR_MASK) << 16;
+ rgn = rgn_start + CONFIG_SYS_SDRAM_BASE;
size = (regs->emif_ecc_address_range_1 &
- EMIF_ECC_REG_ECC_END_ADDR_MASK) + 0x10000;
+ EMIF_ECC_REG_ECC_END_ADDR_MASK) + 0x10000 - rgn_start;
if (regs->emif_ecc_ctrl_reg &
EMIF_ECC_REG_ECC_ADDR_RGN_1_EN_MASK)
dra7_reset_ddr_data(rgn, size);
/* Set region2 memory with 0 */
- rgn = ((regs->emif_ecc_address_range_2 &
- EMIF_ECC_REG_ECC_START_ADDR_MASK) << 16) +
- CONFIG_SYS_SDRAM_BASE;
+ rgn_start = (regs->emif_ecc_address_range_2 &
+ EMIF_ECC_REG_ECC_START_ADDR_MASK) << 16;
+ rgn = rgn_start + CONFIG_SYS_SDRAM_BASE;
size = (regs->emif_ecc_address_range_2 &
- EMIF_ECC_REG_ECC_END_ADDR_MASK) + 0x10000;
+ EMIF_ECC_REG_ECC_END_ADDR_MASK) + 0x10000 - rgn_start;
if (regs->emif_ecc_ctrl_reg &
EMIF_ECC_REG_ECC_ADDR_RGN_2_EN_MASK)
dra7_reset_ddr_data(rgn, size);
-#ifdef CONFIG_DRA7XX
- /* Clear the status flags and other history */
- writel(readl(&emif->emif_1b_ecc_err_cnt),
- &emif->emif_1b_ecc_err_cnt);
- writel(0xffffffff, &emif->emif_1b_ecc_err_dist_1);
- writel(0x1, &emif->emif_2b_ecc_err_addr_log);
- writel(EMIF_INT_WR_ECC_ERR_SYS_MASK |
- EMIF_INT_TWOBIT_ECC_ERR_SYS_MASK |
- EMIF_INT_ONEBIT_ECC_ERR_SYS_MASK,
- &emif->emif_irqstatus_sys);
-#endif
+ /* Default value enables RMW and ECC verification */
+ writel(regs->emif_ecc_ctrl_reg, &emif->emif_ecc_ctrl_reg);
}
}
diff --git a/arch/arm/mach-omap2/omap5/dra7xx_iodelay.c b/arch/arm/mach-omap2/omap5/dra7xx_iodelay.c
index e2abb7d058..9eda57c450 100644
--- a/arch/arm/mach-omap2/omap5/dra7xx_iodelay.c
+++ b/arch/arm/mach-omap2/omap5/dra7xx_iodelay.c
@@ -202,8 +202,9 @@ void __recalibrate_iodelay_end(int ret)
return;
}
- if (!ret)
- ret = isolate_io(DEISOLATE_IO);
+ /* Deisolate IO if it is already isolated */
+ if (readl((*ctrl)->ctrl_core_sma_sw_0) & CTRL_ISOLATE_MASK)
+ isolate_io(DEISOLATE_IO);
/* lock IODELAY CONFIG registers */
writel(CFG_IODELAY_LOCK_KEY, (*ctrl)->iodelay_config_base +
@@ -240,6 +241,12 @@ void __recalibrate_iodelay_end(int ret)
debug("IODELAY: IO delay recalibration successfully completed\n");
}
+ /* If there is an error during iodelay recalibration, SoC is in a bad
+ * state. Do not progress any further.
+ */
+ if (ret)
+ hang();
+
return;
}
diff --git a/board/bosch/guardian/board.c b/board/bosch/guardian/board.c
index ec0c4a17f6..072aa4ebb8 100644
--- a/board/bosch/guardian/board.c
+++ b/board/bosch/guardian/board.c
@@ -172,6 +172,8 @@ void sdram_init(void)
int board_init(void)
{
+ save_omap_boot_params();
+
#if defined(CONFIG_HW_WATCHDOG)
hw_watchdog_init();
#endif
@@ -183,3 +185,54 @@ int board_init(void)
#endif
return 0;
}
+
+#ifdef CONFIG_BOARD_LATE_INIT
+static void set_bootmode_env(void)
+{
+ char *boot_device_name = NULL;
+ char *boot_mode_gpio = "gpio@44e07000_14";
+ int ret;
+ int value;
+
+ struct gpio_desc boot_mode_desc;
+
+ switch (gd->arch.omap_boot_device) {
+ case BOOT_DEVICE_NAND:
+ boot_device_name = "nand";
+ break;
+ case BOOT_DEVICE_USBETH:
+ boot_device_name = "usbeth";
+ break;
+ default:
+ break;
+ }
+
+ if (boot_device_name)
+ env_set("boot_device", boot_device_name);
+
+ ret = dm_gpio_lookup_name(boot_mode_gpio, &boot_mode_desc);
+ if (ret) {
+ printf("%s is not found\n", boot_mode_gpio);
+ goto err;
+ }
+
+ ret = dm_gpio_request(&boot_mode_desc, "setup_bootmode_env");
+ if (ret && ret != -EBUSY) {
+ printf("requesting gpio: %s failed\n", boot_mode_gpio);
+ goto err;
+ }
+
+ value = dm_gpio_get_value(&boot_mode_desc);
+ value ? env_set("swi_status", "0") : env_set("swi_status", "1");
+ return;
+
+err:
+ env_set("swi_status", "err");
+}
+
+int board_late_init(void)
+{
+ set_bootmode_env();
+ return 0;
+}
+#endif /* CONFIG_BOARD_LATE_INIT */
diff --git a/board/bosch/guardian/mux.c b/board/bosch/guardian/mux.c
index 708c3e7fdd..20a1f2522f 100644
--- a/board/bosch/guardian/mux.c
+++ b/board/bosch/guardian/mux.c
@@ -26,24 +26,16 @@ static struct module_pin_mux i2c0_pin_mux[] = {
{-1},
};
-static struct module_pin_mux adc_voltages_en[] = {
- {OFFSET(mcasp0_ahclkx), (MODE(7) | PULLUP_EN)},
- {-1},
-};
-
-static struct module_pin_mux asp_power_en[] = {
- {OFFSET(mcasp0_aclkx), (MODE(7) | PULLUP_EN)},
- {-1},
-};
-
-static struct module_pin_mux switch_off_3v6_pin_mux[] = {
- {OFFSET(mii1_txd0), (MODE(7) | PULLUP_EN)},
- /*
- * The uart1 lines are made floating inputs, based on the Guardian
- * A2 Sample Power Supply Schematics
- */
- {OFFSET(uart1_rxd), (MODE(7) | PULLUDDIS)},
- {OFFSET(uart1_txd), (MODE(7) | PULLUDDIS)},
+static struct module_pin_mux guardian_interfaces_pin_mux[] = {
+ {OFFSET(mcasp0_ahclkx), (MODE(7) | PULLDOWN_EN)},
+ {OFFSET(mcasp0_aclkx), (MODE(7) | PULLUP_EN)},
+ {OFFSET(mii1_txd0), (MODE(7) | PULLUP_EN)},
+ {OFFSET(uart1_rxd), (MODE(7) | RXACTIVE | PULLUDDIS)},
+ {OFFSET(uart1_txd), (MODE(7) | PULLUDDIS)},
+ {OFFSET(mii1_crs), (MODE(7) | PULLDOWN_EN)},
+ {OFFSET(rmii1_refclk), (MODE(7) | PULLDOWN_EN)},
+ {OFFSET(mii1_txd3), (MODE(7) | PULLUDDIS)},
+ {OFFSET(mii1_rxdv), (MODE(7) | PULLDOWN_EN)},
{-1},
};
@@ -93,7 +85,5 @@ void enable_board_pin_mux(void)
#ifdef CONFIG_NAND
configure_module_pin_mux(nand_pin_mux);
#endif
- configure_module_pin_mux(adc_voltages_en);
- configure_module_pin_mux(asp_power_en);
- configure_module_pin_mux(switch_off_3v6_pin_mux);
+ configure_module_pin_mux(guardian_interfaces_pin_mux);
}
diff --git a/board/ti/am335x/board.c b/board/ti/am335x/board.c
index 7eaa6cd96d..499c872227 100644
--- a/board/ti/am335x/board.c
+++ b/board/ti/am335x/board.c
@@ -791,6 +791,7 @@ int board_init(void)
#ifdef CONFIG_BOARD_LATE_INIT
int board_late_init(void)
{
+ struct udevice *dev;
#if !defined(CONFIG_SPL_BUILD)
uint8_t mac_addr[6];
uint32_t mac_hi, mac_lo;
@@ -871,6 +872,9 @@ int board_late_init(void)
env_set("serial#", board_serial);
}
+ /* Just probe the potentially supported cdce913 device */
+ uclass_get_device(UCLASS_CLK, 0, &dev);
+
return 0;
}
#endif
diff --git a/board/ti/am43xx/board.c b/board/ti/am43xx/board.c
index 2e09cc20e8..f5ecf871bc 100644
--- a/board/ti/am43xx/board.c
+++ b/board/ti/am43xx/board.c
@@ -720,6 +720,7 @@ static int device_okay(const char *path)
int board_late_init(void)
{
+ struct udevice *dev;
#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
set_board_info_env(NULL);
@@ -737,6 +738,10 @@ int board_late_init(void)
if (device_okay("/ocp/omap_dwc3@483c0000"))
enable_usb_clocks(1);
#endif
+
+ /* Just probe the potentially supported cdce913 device */
+ uclass_get_device(UCLASS_CLK, 0, &dev);
+
return 0;
}
#endif
diff --git a/board/ti/am57xx/board.c b/board/ti/am57xx/board.c
index f78e6c2e1f..237a834c53 100644
--- a/board/ti/am57xx/board.c
+++ b/board/ti/am57xx/board.c
@@ -30,6 +30,7 @@
#include <dwc3-omap-uboot.h>
#include <ti-usb-phy-uboot.h>
#include <mmc.h>
+#include <dm/uclass.h>
#include "../common/board_detect.h"
#include "mux_data.h"
@@ -689,6 +690,7 @@ int board_late_init(void)
{
setup_board_eeprom_env();
u8 val;
+ struct udevice *dev;
/*
* DEV_CTRL.DEV_ON = 1 please - else palmas switches off in 8 seconds
@@ -720,6 +722,9 @@ int board_late_init(void)
am57x_idk_lcd_detect();
+ /* Just probe the potentially supported cdce913 device */
+ uclass_get_device(UCLASS_CLK, 0, &dev);
+
#if !defined(CONFIG_SPL_BUILD)
board_ti_set_ethaddr(2);
#endif
diff --git a/board/ti/am65x/README b/board/ti/am65x/README
index 16384e05ea..2e3fd9c4a8 100644
--- a/board/ti/am65x/README
+++ b/board/ti/am65x/README
@@ -261,3 +261,35 @@ To boot kernel from eMMC, use the following commands:
=> setenv mmcdev 0
=> setenv bootpart 0
=> boot
+
+UART:
+-----
+ROM supports booting from MCU_UART0 via X-Modem protocol. The entire UART-based
+boot process up to U-Boot (proper) prompt goes through different stages and uses
+different UART peripherals as follows:
+
+ WHO | Loading WHAT | HW Module | Protocol
+----------+---------------+-------------+------------
+Boot ROM | tiboot3.bin | MCU_UART0 | X-Modem(*)
+R5 SPL | sysfw.itb | MCU_UART0 | Y-Modem(*)
+R5 SPL | tispl.bin | MAIN_UART0 | Y-Modem
+A53 SPL | u-boot.img | MAIN_UART0 | Y-Modem
+
+(*) Note that in addition to X/Y-Modem related protocol timeouts the DMSC
+ watchdog timeout of 3min (typ.) needs to be observed until System Firmware
+ is fully loaded (from sysfw.itb) and started.
+
+Example bash script sequence for running on a Linux host PC feeding all boot
+artifacts needed to the device:
+
+MCU_DEV=/dev/ttyUSB1
+MAIN_DEV=/dev/ttyUSB0
+
+stty -F $MCU_DEV 115200 cs8 -cstopb -parenb
+stty -F $MAIN_DEV 115200 cs8 -cstopb -parenb
+
+sb --xmodem tiboot3.bin > $MCU_DEV < $MCU_DEV
+sb --ymodem sysfw.itb > $MCU_DEV < $MCU_DEV
+sb --ymodem tispl.bin > $MAIN_DEV < $MAIN_DEV
+sleep 1
+sb --xmodem u-boot.img > $MAIN_DEV < $MAIN_DEV
diff --git a/board/ti/am65x/evm.c b/board/ti/am65x/evm.c
index ad333ad883..544f872459 100644
--- a/board/ti/am65x/evm.c
+++ b/board/ti/am65x/evm.c
@@ -127,6 +127,19 @@ int do_board_detect(void)
return ret;
}
+int checkboard(void)
+{
+ struct ti_am6_eeprom *ep = TI_AM6_EEPROM_DATA;
+
+ if (do_board_detect())
+ /* EEPROM not populated */
+ printf("Board: %s rev %s\n", "AM6-COMPROCEVM", "E3");
+ else
+ printf("Board: %s rev %s\n", ep->name, ep->version);
+
+ return 0;
+}
+
static void setup_board_eeprom_env(void)
{
char *name = "am65x";
@@ -272,7 +285,7 @@ static int probe_daughtercards(void)
if (strncmp(ep.name, cards[i].card_name, sizeof(ep.name)))
continue;
- printf("detected %s\n", cards[i].card_name);
+ printf("Detected: %s rev %s\n", ep.name, ep.version);
/*
* Populate any MAC addresses from daughtercard into the U-Boot
diff --git a/board/ti/j721e/README b/board/ti/j721e/README
new file mode 100644
index 0000000000..5be7d099db
--- /dev/null
+++ b/board/ti/j721e/README
@@ -0,0 +1,227 @@
+Introduction:
+-------------
+The J721e family of SoCs are part of K3 Multicore SoC architecture platform
+targeting automotive applications. They are designed as a low power, high
+performance and highly integrated device architecture, adding significant
+enhancement on processing power, graphics capability, video and imaging
+processing, virtualization and coherent memory support.
+
+The device is partitioned into three functional domains, each containing
+specific processing cores and peripherals:
+1. Wake-up (WKUP) domain:
+ - Device Management and Security Controller (DMSC)
+2. Microcontroller (MCU) domain:
+ - Dual Core ARM Cortex-R5F processor
+3. MAIN domain:
+ - Dual core 64-bit ARM Cortex-A72
+ - 2 x Dual cortex ARM Cortex-R5 subsystem
+ - 2 x C66x Digital signal processor sub system
+ - C71x Digital signal processor sub-system with MMA.
+
+More info can be found in TRM: http://www.ti.com/lit/pdf/spruil1
+
+Boot Flow:
+----------
+Boot flow is similar to that of AM65x SoC and extending it with remoteproc
+support. Below is the pictorial representation of boot flow:
+
++------------------------------------------------------------------------+-----------------------+
+| DMSC | MCU R5 | A72 | MAIN R5/C66x/C7x |
++------------------------------------------------------------------------+-----------------------+
+| +--------+ | | | |
+| | Reset | | | | |
+| +--------+ | | | |
+| : | | | |
+| +--------+ | +-----------+ | | |
+| | *ROM* |----------|-->| Reset rls | | | |
+| +--------+ | +-----------+ | | |
+| | | | : | | |
+| | ROM | | : | | |
+| |services| | : | | |
+| | | | +-------------+ | | |
+| | | | | *R5 ROM* | | | |
+| | | | +-------------+ | | |
+| | |<---------|---|Load and auth| | | |
+| | | | | tiboot3.bin | | | |
+| | | | +-------------+ | | |
+| | | | : | | |
+| | | | : | | |
+| | | | : | | |
+| | | | +-------------+ | | |
+| | | | | *R5 SPL* | | | |
+| | | | +-------------+ | | |
+| | | | | Load | | | |
+| | | | | sysfw.itb | | | |
+| | Start | | +-------------+ | | |
+| | System |<---------|---| Start | | | |
+| |Firmware| | | SYSFW | | | |
+| +--------+ | +-------------+ | | |
+| : | | | | | |
+| +---------+ | | Load | | | |
+| | *SYSFW* | | | system | | | |
+| +---------+ | | Config data | | | |
+| | |<--------|---| | | | |
+| | | | +-------------+ | | |
+| | | | | DDR | | | |
+| | | | | config | | | |
+| | | | +-------------+ | | |
+| | | | | Load | | | |
+| | | | | tispl.bin | | | |
+| | | | +-------------+ | | |
+| | | | | Load R5 | | | |
+| | | | | firmware | | | |
+| | | | +-------------+ | | |
+| | |<--------|---| Start A72 | | | |
+| | | | | and jump to | | | |
+| | | | | next image | | | |
+| | | | +-------------+ | | |
+| | | | | +-----------+ | |
+| | |---------|-----------------------|---->| Reset rls | | |
+| | | | | +-----------+ | |
+| | DMSC | | | : | |
+| |Services | | | +-----------+ | |
+| | |<--------|-----------------------|---->|*ATF/OPTEE*| | |
+| | | | | +-----------+ | |
+| | | | | : | |
+| | | | | +-----------+ | |
+| | |<--------|-----------------------|---->| *A72 SPL* | | |
+| | | | | +-----------+ | |
+| | | | | | Load | | |
+| | | | | | u-boot.img| | |
+| | | | | +-----------+ | |
+| | | | | : | |
+| | | | | +-----------+ | |
+| | |<--------|-----------------------|---->| *U-Boot* | | |
+| | | | | +-----------+ | |
+| | | | | | prompt | | |
+| | | | | +-----------+ | |
+| | | | | | Load R5 | | |
+| | | | | | Firmware | | |
+| | | | | +-----------+ | |
+| | |<--------|-----------------------|-----| Start R5 | | +-----------+ |
+| | |---------|-----------------------|-----+-----------+-----|----->| R5 starts | |
+| | | | | | Load C6 | | +-----------+ |
+| | | | | | Firmware | | |
+| | | | | +-----------+ | |
+| | |<--------|-----------------------|-----| Start C6 | | +-----------+ |
+| | |---------|-----------------------|-----+-----------+-----|----->| C6 starts | |
+| | | | | | Load C7 | | +-----------+ |
+| | | | | | Firmware | | |
+| | | | | +-----------+ | |
+| | |<--------|-----------------------|-----| Start C7 | | +-----------+ |
+| | |---------|-----------------------|-----+-----------+-----|----->| C7 starts | |
+| +---------+ | | | +-----------+ |
+| | | | |
++------------------------------------------------------------------------+-----------------------+
+
+- Here DMSC acts as master and provides all the critical services. R5/A72
+requests DMSC to get these services done as shown in the above diagram.
+
+Sources:
+--------
+1. SYSFW:
+ 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
+ Branch: master
+
+3. OPTEE:
+ Tree: https://github.com/OP-TEE/optee_os.git
+ Branch: master
+
+4. U-Boot:
+ Tree: https://gitlab.denx.de/u-boot/u-boot
+ Branch: master
+
+Build procedure:
+----------------
+1. SYSFW:
+$ make CROSS_COMPILE=arm-linux-gnueabihf-
+
+2. ATF:
+$ make CROSS_COMPILE=aarch64-linux-gnu- ARCH=aarch64 PLAT=k3 TARGET_BOARD=generic SPD=opteed
+
+3. OPTEE:
+$ make PLATFORM=k3-j721e CFG_ARM64_core=y
+
+4. U-Boot:
+
+4.1. R5:
+$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- j721e_evm_r5_defconfig O=/tmp/r5
+$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- O=/tmp/r5
+
+4.2. A72:
+$ make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- j721e_evm_a72_defconfig O=/tmp/a72
+$ 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/a72
+
+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 |
+ | +-------------------+ |
+ | | | |
+ | | A72 ATF | |
+ | +-------------------+ |
+ | | | |
+ | | A72 OPTEE | |
+ | +-------------------+ |
+ | | | |
+ | | A72 SPL | |
+ | +-------------------+ |
+ | | | |
+ | | SPL DTB 1...N | |
+ | +-------------------+ |
+ +-----------------------+
+
+- sysfw.itb
+ +-----------------------+
+ | |
+ | FIT HEADER |
+ | +-------------------+ |
+ | | | |
+ | | sysfw.bin | |
+ | +-------------------+ |
+ | | | |
+ | | board config | |
+ | +-------------------+ |
+ | | | |
+ | | PM config | |
+ | +-------------------+ |
+ | | | |
+ | | RM config | |
+ | +-------------------+ |
+ | | | |
+ | | Secure config | |
+ | +-------------------+ |
+ +-----------------------+
diff --git a/cmd/ti/ddr3.c b/cmd/ti/ddr3.c
index b82cbe152d..448a7f54a9 100644
--- a/cmd/ti/ddr3.c
+++ b/cmd/ti/ddr3.c
@@ -202,10 +202,6 @@ static int ddr_memory_ecc_err(u32 addr, u32 ecc_err)
writel(val2, addr);
val3 = readl(addr);
- printf("\tECC test: addr 0x%x, read data 0x%x, written data 0x%x, err pattern: 0x%x, read after write data 0x%x\n",
- addr, val1, val2, ecc_err, val3);
-
- puts("\tECC test: Enabling DDR ECC ...\n");
#ifdef CONFIG_ARCH_KEYSTONE
ecc_ctrl = ECC_START_ADDR1 | (ECC_END_ADDR1 << 16);
writel(ecc_ctrl, EMIF1_BASE + KS2_DDR3_ECC_ADDR_RANGE1_OFFSET);
@@ -214,6 +210,11 @@ static int ddr_memory_ecc_err(u32 addr, u32 ecc_err)
writel(ecc_ctrl, &emif->emif_ecc_ctrl_reg);
#endif
+ printf("\tECC test: addr 0x%x, read data 0x%x, written data 0x%x, err pattern: 0x%x, read after write data 0x%x\n",
+ addr, val1, val2, ecc_err, val3);
+
+ puts("\tECC test: Enabled DDR ECC ...\n");
+
val1 = readl(addr);
printf("\tECC test: addr 0x%x, read data 0x%x\n", addr, val1);
@@ -242,8 +243,8 @@ static int is_addr_valid(u32 addr)
if (ecc_ctrl & EMIF_ECC_REG_ECC_ADDR_RGN_1_EN_MASK) {
start_addr = ((range & EMIF_ECC_REG_ECC_START_ADDR_MASK) << 16)
+ CONFIG_SYS_SDRAM_BASE;
- end_addr = start_addr + (range & EMIF_ECC_REG_ECC_END_ADDR_MASK)
- + 0xFFFF;
+ end_addr = (range & EMIF_ECC_REG_ECC_END_ADDR_MASK) + 0xFFFF +
+ CONFIG_SYS_SDRAM_BASE;
if ((addr >= start_addr) && (addr <= end_addr))
/* addr within ecc address range 1 */
return 1;
@@ -254,8 +255,8 @@ static int is_addr_valid(u32 addr)
range = readl(&emif->emif_ecc_address_range_2);
start_addr = ((range & EMIF_ECC_REG_ECC_START_ADDR_MASK) << 16)
+ CONFIG_SYS_SDRAM_BASE;
- end_addr = start_addr + (range & EMIF_ECC_REG_ECC_END_ADDR_MASK)
- + 0xFFFF;
+ end_addr = (range & EMIF_ECC_REG_ECC_END_ADDR_MASK) + 0xFFFF +
+ CONFIG_SYS_SDRAM_BASE;
if ((addr >= start_addr) && (addr <= end_addr))
/* addr within ecc address range 2 */
return 1;
diff --git a/common/spl/spl_ymodem.c b/common/spl/spl_ymodem.c
index 20f4260062..c02c05624d 100644
--- a/common/spl/spl_ymodem.c
+++ b/common/spl/spl_ymodem.c
@@ -44,7 +44,8 @@ static ulong ymodem_read_fit(struct spl_load_info *load, ulong offset,
while (info->image_read < offset) {
res = xyzModem_stream_read(buf, BUF_SIZE, &err);
if (res <= 0)
- return res;
+ break;
+
info->image_read += res;
}
@@ -57,7 +58,7 @@ static ulong ymodem_read_fit(struct spl_load_info *load, ulong offset,
while (info->image_read < offset + size) {
res = xyzModem_stream_read(buf, BUF_SIZE, &err);
if (res <= 0)
- return res;
+ break;
memcpy(addr, buf, res);
info->image_read += res;
@@ -67,8 +68,8 @@ static ulong ymodem_read_fit(struct spl_load_info *load, ulong offset,
return size;
}
-static int spl_ymodem_load_image(struct spl_image_info *spl_image,
- struct spl_boot_device *bootdev)
+int spl_ymodem_load_image(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
{
ulong size = 0;
int err;
diff --git a/configs/am335x_evm_defconfig b/configs/am335x_evm_defconfig
index 2aa9b65caf..93a28b290b 100644
--- a/configs/am335x_evm_defconfig
+++ b/configs/am335x_evm_defconfig
@@ -77,3 +77,5 @@ CONFIG_DYNAMIC_CRC_TABLE=y
CONFIG_RSA=y
CONFIG_LZO=y
# CONFIG_OF_LIBFDT_OVERLAY is not set
+CONFIG_CLK=y
+CONFIG_CLK_CDCE9XX=y
diff --git a/configs/am335x_guardian_defconfig b/configs/am335x_guardian_defconfig
index 3cada51d35..3ce324193f 100644
--- a/configs/am335x_guardian_defconfig
+++ b/configs/am335x_guardian_defconfig
@@ -6,11 +6,10 @@ CONFIG_SPL_LIBCOMMON_SUPPORT=y
CONFIG_SPL_LIBGENERIC_SUPPORT=y
CONFIG_AM33XX=y
CONFIG_TARGET_AM335X_GUARDIAN=y
-CONFIG_SPL_MMC_SUPPORT=y
+# CONFIG_SPL_MMC_SUPPORT is not set
CONFIG_SPL_SERIAL_SUPPORT=y
CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
CONFIG_ENV_SIZE=0x040000
-CONFIG_ENV_OFFSET=0x300000
CONFIG_SPL=y
CONFIG_BOOTSTAGE_STASH_ADDR=0x0
CONFIG_SPL_LIBDISK_SUPPORT=y
@@ -21,6 +20,7 @@ CONFIG_VERSION_VARIABLE=y
CONFIG_ARCH_MISC_INIT=y
# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
CONFIG_SPL_SEPARATE_BSS=y
+# CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR is not set
CONFIG_SPL_ENV_SUPPORT=y
CONFIG_SPL_ETH_SUPPORT=y
CONFIG_SPL_I2C_SUPPORT=y
@@ -30,8 +30,8 @@ CONFIG_SPL_NET_VCI_STRING="Guardian U-Boot SPL"
CONFIG_SPL_POWER_SUPPORT=y
CONFIG_SPL_USB_GADGET=y
CONFIG_SPL_USB_ETHER=y
-CONFIG_SPL_WATCHDOG_SUPPORT=y
-CONFIG_SPL_YMODEM_SUPPORT=y
+# CONFIG_SPL_WATCHDOG_SUPPORT is not set
+# CONFIG_SPL_YMODEM_SUPPORT is not set
CONFIG_AUTOBOOT_KEYED=y
CONFIG_AUTOBOOT_PROMPT="Press SPACE to abort autoboot in %d seconds\n"
CONFIG_AUTOBOOT_DELAY_STR="d"
@@ -43,14 +43,14 @@ CONFIG_CMD_ASKENV=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_GPT=y
CONFIG_CMD_I2C=y
-CONFIG_CMD_MMC=y
+# CONFIG_CMD_MMC is not set
CONFIG_CMD_MTD=y
CONFIG_CMD_NAND=y
CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_EXT4_WRITE=y
CONFIG_CMD_MTDPARTS=y
-CONFIG_MTDPARTS_DEFAULT="mtdparts=nand.0:256k(SPL),256k(SPL.backup1),256k(SPL.backup2),256k(SPL.backup3),1m(u-boot),1m(u-boot.backup1),256k(u-boot-env),256k(u-boot-env.backup1),-(UBI)"
+CONFIG_MTDPARTS_DEFAULT="mtdparts=nand.0:256k(SPL),256k(SPL.backup1),256k(SPL.backup2),256k(SPL.backup3),1m(u-boot),1m(u-boot.backup1),-(UBI)"
CONFIG_CMD_UBI=y
# CONFIG_SPL_DOS_PARTITION is not set
# CONFIG_ISO_PARTITION is not set
@@ -58,14 +58,17 @@ CONFIG_CMD_UBI=y
CONFIG_OF_CONTROL=y
CONFIG_SPL_OF_CONTROL=y
CONFIG_DEFAULT_DEVICE_TREE="am335x-guardian"
-CONFIG_ENV_IS_IN_NAND=y
+CONFIG_OF_SEPARATE=y
+CONFIG_ENV_IS_NOWHERE=y
CONFIG_SPL_ENV_IS_NOWHERE=y
CONFIG_SPL_DM=y
+CONFIG_SPL_DM_USB=y
CONFIG_BOOTCOUNT_LIMIT=y
CONFIG_BOOTCOUNT_ENV=y
CONFIG_MISC=y
-CONFIG_DM_MMC=y
-CONFIG_MMC_OMAP_HS=y
+# CONFIG_DM_MMC is not set
+# CONFIG_MMC is not set
+# CONFIG_MMC_OMAP_HS is not set
CONFIG_MTD=y
CONFIG_NAND=y
CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
@@ -78,15 +81,19 @@ CONFIG_PHY=y
CONFIG_NOP_PHY=y
CONFIG_PINCTRL=y
CONFIG_PINCTRL_SINGLE=y
+# CONFIG_WATCHDOG is not set
+CONFIG_SPL_WDT=y
CONFIG_USB=y
CONFIG_DM_USB_GADGET=y
CONFIG_SPL_DM_USB_GADGET=y
CONFIG_USB_MUSB_HOST=y
CONFIG_USB_MUSB_GADGET=y
CONFIG_USB_MUSB_TI=y
+CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
CONFIG_USB_GADGET_VENDOR_NUM=0x0451
CONFIG_USB_GADGET_PRODUCT_NUM=0xd022
CONFIG_USB_ETHER=y
+# CONFIG_USB_STORAGE is not set
CONFIG_FAT_WRITE=y
diff --git a/configs/am43xx_evm_defconfig b/configs/am43xx_evm_defconfig
index 7c74047f3a..5e3e01c915 100644
--- a/configs/am43xx_evm_defconfig
+++ b/configs/am43xx_evm_defconfig
@@ -18,6 +18,7 @@ CONFIG_SPL_MTD_SUPPORT=y
CONFIG_SPL_NET_SUPPORT=y
CONFIG_SPL_NET_VCI_STRING="AM43xx U-Boot SPL"
CONFIG_SPL_OS_BOOT=y
+CONFIG_SPL_USB_HOST_SUPPORT=y
CONFIG_SPL_USB_GADGET=y
CONFIG_SPL_USB_ETHER=y
CONFIG_CMD_SPL=y
@@ -78,3 +79,5 @@ CONFIG_USB_GADGET_VENDOR_NUM=0x0403
CONFIG_USB_GADGET_PRODUCT_NUM=0xbd00
CONFIG_USB_GADGET_DOWNLOAD=y
CONFIG_USB_ETHER=y
+CONFIG_CLK=y
+CONFIG_CLK_CDCE9XX=y
diff --git a/configs/am57xx_evm_defconfig b/configs/am57xx_evm_defconfig
index 3b613e135c..e2f558cde7 100644
--- a/configs/am57xx_evm_defconfig
+++ b/configs/am57xx_evm_defconfig
@@ -98,3 +98,5 @@ CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
CONFIG_USB_GADGET_VENDOR_NUM=0x0451
CONFIG_USB_GADGET_PRODUCT_NUM=0xd022
+CONFIG_CLK=y
+CONFIG_CLK_CDCE9XX=y
diff --git a/configs/am65x_evm_a53_defconfig b/configs/am65x_evm_a53_defconfig
index e5b127c75c..c60978c9be 100644
--- a/configs/am65x_evm_a53_defconfig
+++ b/configs/am65x_evm_a53_defconfig
@@ -12,13 +12,13 @@ CONFIG_NR_DRAM_BANKS=2
CONFIG_SPL_STACK_R_ADDR=0x82000000
CONFIG_SPL_FS_FAT=y
CONFIG_SPL_LIBDISK_SUPPORT=y
+# CONFIG_PSCI_RESET is not set
CONFIG_SPL_TEXT_BASE=0x80080000
CONFIG_DISTRO_DEFAULTS=y
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL_LOAD_FIT=y
CONFIG_OF_BOARD_SETUP=y
-CONFIG_BOOTCOMMAND="run findfdt; run envboot; run init_${boot}; run get_kern_${boot}; run get_fdt_${boot}; run get_overlay_${boot}; run run_kern"
-# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_BOOTCOMMAND="run findfdt; run envboot; run init_${boot}; run boot_rprocs; run get_kern_${boot}; run get_fdt_${boot}; run get_overlay_${boot}; run run_kern"
CONFIG_SPL_SYS_MALLOC_SIMPLE=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_SEPARATE_BSS=y
@@ -35,6 +35,7 @@ CONFIG_CMD_GPT=y
CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
CONFIG_CMD_PCI=y
+CONFIG_CMD_REMOTEPROC=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_TIME=y
# CONFIG_ISO_PARTITION is not set
@@ -83,6 +84,7 @@ CONFIG_SPL_PINCTRL=y
CONFIG_PINCTRL_SINGLE=y
CONFIG_POWER_DOMAIN=y
CONFIG_TI_SCI_POWER_DOMAIN=y
+CONFIG_REMOTEPROC_TI_K3_R5F=y
CONFIG_DM_RESET=y
CONFIG_RESET_TI_SCI=y
CONFIG_DM_SERIAL=y
diff --git a/configs/am65x_evm_r5_defconfig b/configs/am65x_evm_r5_defconfig
index 077aa37e00..d0619e9b7a 100644
--- a/configs/am65x_evm_r5_defconfig
+++ b/configs/am65x_evm_r5_defconfig
@@ -5,6 +5,7 @@ CONFIG_SPL_LIBCOMMON_SUPPORT=y
CONFIG_SPL_LIBGENERIC_SUPPORT=y
CONFIG_SYS_MALLOC_F_LEN=0x55000
CONFIG_SOC_K3_AM6=y
+CONFIG_K3_EARLY_CONS=y
CONFIG_TARGET_AM654_R5_EVM=y
CONFIG_SPL_MMC_SUPPORT=y
CONFIG_SPL_SERIAL_SUPPORT=y
diff --git a/configs/am65x_hs_evm_a53_defconfig b/configs/am65x_hs_evm_a53_defconfig
index e9fceea58c..caee953426 100644
--- a/configs/am65x_hs_evm_a53_defconfig
+++ b/configs/am65x_hs_evm_a53_defconfig
@@ -21,7 +21,6 @@ CONFIG_SPL_LOAD_FIT=y
CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y
CONFIG_OF_BOARD_SETUP=y
CONFIG_BOOTCOMMAND="run findfdt; run envboot; run init_${boot}; run get_fit_${boot}; run get_overlaystring; run run_fit"
-# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_SPL_SYS_MALLOC_SIMPLE=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_SEPARATE_BSS=y
diff --git a/configs/j721e_evm_a72_defconfig b/configs/j721e_evm_a72_defconfig
index 5cb933d878..6729e03620 100644
--- a/configs/j721e_evm_a72_defconfig
+++ b/configs/j721e_evm_a72_defconfig
@@ -14,12 +14,12 @@ CONFIG_SPL_FS_FAT=y
CONFIG_SPL_LIBDISK_SUPPORT=y
CONFIG_SPL_SPI_FLASH_SUPPORT=y
CONFIG_SPL_SPI_SUPPORT=y
+# CONFIG_PSCI_RESET is not set
CONFIG_SPL_TEXT_BASE=0x80080000
CONFIG_DISTRO_DEFAULTS=y
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL_LOAD_FIT=y
-CONFIG_BOOTCOMMAND="run findfdt; run envboot; run init_${boot}; run get_kern_${boot}; run get_fdt_${boot}; run get_overlay_${boot}; run run_kern"
-# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_BOOTCOMMAND="run findfdt; run envboot; run init_${boot}; run boot_rprocs; run get_kern_${boot}; run get_fdt_${boot}; run get_overlay_${boot}; run run_kern"
CONFIG_SPL_SYS_MALLOC_SIMPLE=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_SEPARATE_BSS=y
@@ -34,6 +34,7 @@ CONFIG_SPL_YMODEM_SUPPORT=y
CONFIG_CMD_ASKENV=y
# CONFIG_CMD_FLASH is not set
CONFIG_CMD_MMC=y
+CONFIG_CMD_REMOTEPROC=y
CONFIG_CMD_SF=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_TIME=y
@@ -72,6 +73,8 @@ CONFIG_SPL_PINCTRL=y
CONFIG_PINCTRL_SINGLE=y
CONFIG_POWER_DOMAIN=y
CONFIG_TI_SCI_POWER_DOMAIN=y
+CONFIG_REMOTEPROC_TI_K3_DSP=y
+CONFIG_REMOTEPROC_TI_K3_R5F=y
CONFIG_DM_RESET=y
CONFIG_RESET_TI_SCI=y
CONFIG_DM_SERIAL=y
diff --git a/doc/device-tree-bindings/clock/ti,cdce9xx.txt b/doc/device-tree-bindings/clock/ti,cdce9xx.txt
new file mode 100644
index 0000000000..0d01f2d5cc
--- /dev/null
+++ b/doc/device-tree-bindings/clock/ti,cdce9xx.txt
@@ -0,0 +1,49 @@
+Binding for TI CDCE913/925/937/949 programmable I2C clock synthesizers.
+
+Reference
+This binding uses the common clock binding[1].
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+[2] http://www.ti.com/product/cdce913
+[3] http://www.ti.com/product/cdce925
+[4] http://www.ti.com/product/cdce937
+[5] http://www.ti.com/product/cdce949
+
+The driver provides clock sources for each output Y1 through Y5.
+
+Required properties:
+ - compatible: Shall be one of the following:
+ - "ti,cdce913": 1-PLL, 3 Outputs
+ - "ti,cdce925": 2-PLL, 5 Outputs
+ - "ti,cdce937": 3-PLL, 7 Outputs
+ - "ti,cdce949": 4-PLL, 9 Outputs
+ - reg: I2C device address.
+ - clocks: Points to a fixed parent clock that provides the input frequency.
+ - #clock-cells: From common clock bindings: Shall be 1.
+
+Optional properties:
+ - xtal-load-pf: Crystal load-capacitor value to fine-tune performance on a
+ board, or to compensate for external influences.
+
+For all PLL1, PLL2, ... an optional child node can be used to specify spread
+spectrum clocking parameters for a board.
+ - spread-spectrum: SSC mode as defined in the data sheet.
+ - spread-spectrum-center: Use "centered" mode instead of "max" mode. When
+ present, the clock runs at the requested frequency on average. Otherwise
+ the requested frequency is the maximum value of the SCC range.
+
+
+Example:
+
+ clockgen: cdce925pw@64 {
+ compatible = "cdce925";
+ reg = <0x64>;
+ clocks = <&xtal_27Mhz>;
+ #clock-cells = <1>;
+ xtal-load-pf = <5>;
+ /* PLL options to get SSC 1% centered */
+ PLL2 {
+ spread-spectrum = <4>;
+ spread-spectrum-center;
+ };
+ };
diff --git a/doc/device-tree-bindings/remoteproc/ti,k3-dsp-rproc.txt b/doc/device-tree-bindings/remoteproc/ti,k3-dsp-rproc.txt
new file mode 100644
index 0000000000..80ab7a4090
--- /dev/null
+++ b/doc/device-tree-bindings/remoteproc/ti,k3-dsp-rproc.txt
@@ -0,0 +1,101 @@
+TI K3 DSP devices
+=================
+
+The TI K3 family of SoCs usually have one or more TI DSP Core sub-systems that
+are used to offload some of the processor-intensive tasks or algorithms, for
+achieving various system level goals.
+
+These processor sub-systems usually contain additional sub-modules like L1
+and/or L2 caches/SRAMs, an Interrupt Controller, an external memory controller,
+a dedicated local power/sleep controller etc. The DSP processor cores in the
+K3 SoCs is usually either a TMS320C66x CorePac processor or a TMS320C71x CorePac
+processor.
+
+DSP Device Node:
+================
+Each DSP Core sub-system is represented as a single DT node. Each node has a
+number of required or optional properties that enable the OS running on the
+host processor (Arm CorePac) to perform the device management of the remote
+processor and to communicate with the remote processor.
+
+Required properties:
+--------------------
+The following are the mandatory properties:
+
+- compatible: Should be one of the following,
+ "ti,j721e-c66-dsp" for C66x DSPs on K3 J721E SoCs
+ "ti,j721e-c71-dsp" for C71x DSPs on K3 J721E SoCs
+
+- reg: Should contain an entry for each value in 'reg-names'.
+ Each entry should have the memory region's start address
+ and the size of the region, the representation matching
+ the parent node's '#address-cells' and '#size-cells' values.
+
+- reg-names: Should contain strings with the following names, each
+ representing a specific internal memory region (if
+ present), and should be defined in this order,
+ "l2sram", "l1pram", "l1dram"
+ NOTE: C71x DSPs do not have a "l1pram" memory.
+
+- ti,sci: Should be a phandle to the TI-SCI System Controller node
+
+- ti,sci-dev-id: Should contain the TI-SCI device id corresponding to the
+ DSP Core. Please refer to the corresponding System
+ Controller documentation for valid values for the DSP
+ cores.
+
+- ti,sci-proc-ids: Should contain 2 integer values. The first cell should
+ contain the TI-SCI processor id for the DSP core device
+ and the second cell should contain the TI-SCI host id to
+ which the processor control ownership should be
+ transferred to.
+
+- resets: Should contain the phandle to the reset controller node
+ managing the resets for this device, and a reset
+ specifier. Please refer to the following reset bindings
+ for the reset argument specifier,
+ Documentation/devicetree/bindings/reset/ti,sci-reset.txt
+
+Example:
+---------
+
+1. J721E SoC
+ /* J721E remoteproc alias */
+ aliases {
+ rproc6 = &c66_0;
+ rproc8 = &c71_0;
+ };
+
+ cbass_main: interconnect@100000 {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges = <0x00 0x64800000 0x00 0x64800000 0x00 0x00800000>, /* C71_0 */
+ <0x4d 0x80800000 0x4d 0x80800000 0x00 0x00800000>, /* C66_0 */
+ <0x4d 0x81800000 0x4d 0x81800000 0x00 0x00800000>; /* C66_1 */
+
+ /* J721E C66_0 DSP node */
+ c66_0: dsp@4d80800000 {
+ compatible = "ti,j721e-c66-dsp";
+ reg = <0x4d 0x80800000 0x00 0x00048000>,
+ <0x4d 0x80e00000 0x00 0x00008000>,
+ <0x4d 0x80f00000 0x00 0x00008000>;
+ reg-names = "l2sram", "l1pram", "l1dram";
+ ti,sci = <&dmsc>;
+ ti,sci-dev-id = <142>;
+ ti,sci-proc-ids = <0x03 0xFF>;
+ resets = <&k3_reset 142 1>;
+ };
+
+ /* J721E C71_0 DSP node */
+ c71_0: dsp@64800000 {
+ compatible = "ti,j721e-c71-dsp";
+ reg = <0x00 0x64800000 0x00 0x00080000>,
+ <0x00 0x64e00000 0x00 0x0000c000>;
+ reg-names = "l2sram", "l1dram";
+ ti,sci = <&dmsc>;
+ ti,sci-dev-id = <15>;
+ ti,sci-proc-ids = <0x30 0xFF>;
+ resets = <&k3_reset 15 1>;
+ };
+ };
diff --git a/doc/device-tree-bindings/remoteproc/ti,k3-r5f-rproc.txt b/doc/device-tree-bindings/remoteproc/ti,k3-r5f-rproc.txt
new file mode 100644
index 0000000000..c2fa6e8344
--- /dev/null
+++ b/doc/device-tree-bindings/remoteproc/ti,k3-r5f-rproc.txt
@@ -0,0 +1,164 @@
+TI K3 R5F processor subsystems
+==============================
+
+The TI K3 family of SoCs usually have one or more dual-core Arm Cortex
+R5F processor subsystems/clusters (R5FSS). The dual core cluster can be
+used either in a LockStep mode providing safety/fault tolerance features
+or in a Split mode providing two individual compute cores for doubling
+the compute capacity. These are used together with other processors
+present on the SoC to achieve various system level goals.
+
+R5F Sub-System Device Node:
+===========================
+Each Dual-Core R5F sub-system is represented as a single DTS node representing
+the cluster, with a pair of child DT nodes representing the individual R5F
+cores. Each node has a number of required or optional properties that enable
+the OS running on the host processor to perform the device management of the
+remote processor and to communicate with the remote processor.
+
+Required properties:
+--------------------
+The following are the mandatory properties:
+
+- compatible: Should be one of the following,
+ "ti,am654-r5fss" for R5F clusters/subsystems on
+ K3 AM65x SoCs
+ "ti,j721e-r5fss" for R5F clusters/subsystems on
+ K3 J721E SoCs
+- power-domains: Should contain a phandle to a PM domain provider node
+ and an args specifier containing the R5FSS device id
+ value. This property is as per the binding,
+ Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt
+- #address-cells: Should be 1
+- #size-cells: Should be 1
+- ranges: Standard ranges definition providing translations for
+ R5F TCM address spaces
+
+Optional properties:
+--------------------
+- lockstep-mode: Configuration Mode for the Dual R5F cores within the R5F
+ cluster. Should be either a value of 1 (LockStep mode) or
+ 0 (Split mode), default is LockStep mode if omitted.
+
+
+R5F Processor Child Nodes:
+==========================
+The R5F Sub-System device node should define two R5F child nodes, each node
+representing a TI instantiation of the Arm Cortex R5F core. There are some
+specific integration differences for the IP like the usage of a Region Address
+Translator (RAT) for translating the larger SoC bus addresses into a 32-bit
+address space for the processor.
+
+Required properties:
+--------------------
+The following are the mandatory properties:
+
+- compatible: Should be one of the following,
+ "ti,am654-r5f" for the R5F cores in K3 AM65x SoCs
+ "ti,j721e-r5f" for the R5F cores in K3 J721E SOCs
+- reg: Should contain an entry for each value in 'reg-names'.
+ Each entry should have the memory region's start address
+ and the size of the region, the representation matching
+ the parent node's '#address-cells' and '#size-cells' values.
+- reg-names: Should contain strings with the following names, each
+ representing a specific internal memory region, and
+ should be defined in this order,
+ "atcm", "btcm"
+- ti,sci: Should be a phandle to the TI-SCI System Controller node
+- ti,sci-dev-id: Should contain the TI-SCI device id corresponding to the
+ R5F Core. Please refer to the corresponding System
+ Controller documentation for valid values for the R5F
+ cores.
+- ti,sci-proc-ids: Should contain 2 integer values. The first cell should
+ contain the TI-SCI processor id for the R5F core device
+ and the second cell should contain the TI-SCI host id to
+ which the processor control ownership should be
+ transferred to.
+- resets: Should contain the phandle to the reset controller node
+ managing the resets for this device, and a reset
+ specifier. Please refer to the following reset bindings
+ for the reset argument specifier,
+ Documentation/devicetree/bindings/reset/ti,sci-reset.txt
+ for AM65x and J721E SoCs
+
+Optional properties:
+--------------------
+The following properties are optional properties for each of the R5F cores:
+
+- atcm-enable: R5F core configuration mode dictating if ATCM should be
+ enabled. Should be either a value of 1 (enabled) or
+ 0 (disabled), default is disabled if omitted. R5F view
+ of ATCM dictated by loczrama property.
+- btcm-enable: R5F core configuration mode dictating if BTCM should be
+ enabled. Should be either a value of 1 (enabled) or
+ 0 (disabled), default is enabled if omitted. R5F view
+ of BTCM dictated by loczrama property.
+- loczrama: R5F core configuration mode dictating which TCM should
+ appear at address 0 (from core's view). Should be either
+ a value of 1 (ATCM at 0x0) or 0 (BTCM at 0x0), default
+ value is 1 if omitted.
+
+Example:
+--------
+1. AM654 SoC
+ /* AM65x remoteproc alias */
+ aliases {
+ remoteproc0 = &mcu_r5fss0_core0;
+ };
+
+ cbass_main: interconnect@100000 {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges = <0x00 0x41000000 0x00 0x41000000 0x00 0x00020000>,
+ <0x00 0x41400000 0x00 0x41400000 0x00 0x00020000>,
+ <0x00 0x41c00000 0x00 0x41c00000 0x00 0x00080000>;
+
+ cbass_mcu: interconnect@28380000 {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges = <0x00 0x41000000 0x00 0x41000000 0x00 0x00020000>, /* MCU R5F Core0 */
+ <0x00 0x41400000 0x00 0x41400000 0x00 0x00020000>, /* MCU R5F Core1 */
+ <0x00 0x41c00000 0x00 0x41c00000 0x00 0x00080000>; /* MCU SRAM */
+
+ /* AM65x MCU R5FSS node */
+ mcu_r5fss0: r5fss@41000000 {
+ compatible = "ti,am654-r5fss";
+ power-domains = <&k3_pds 129>;
+ lockstep-mode = <1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x41000000 0x00 0x41000000 0x20000>,
+ <0x41400000 0x00 0x41400000 0x20000>;
+
+ mcu_r5f0: r5f@41000000 {
+ compatible = "ti,am654-r5f";
+ reg = <0x41000000 0x00008000>,
+ <0x41010000 0x00008000>;
+ reg-names = "atcm", "btcm";
+ ti,sci = <&dmsc>;
+ ti,sci-dev-id = <159>;
+ ti,sci-proc-ids = <0x01 0xFF>;
+ resets = <&k3_reset 159 1>;
+ atcm-enable = <1>;
+ btcm-enable = <1>;
+ loczrama = <1>;
+ };
+
+ mcu_r5f1: r5f@41400000 {
+ compatible = "ti,am654-r5f";
+ reg = <0x41400000 0x00008000>,
+ <0x41410000 0x00008000>;
+ reg-names = "atcm", "btcm";
+ ti,sci = <&dmsc>;
+ ti,sci-dev-id = <245>;
+ ti,sci-proc-ids = <0x02 0xFF>;
+ resets = <&k3_reset 245 1>;
+ atcm-enable = <1>;
+ btcm-enable = <1>;
+ loczrama = <1>;
+ };
+ };
+ };
+ };
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 0035f0a9c6..16d4237f89 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -134,6 +134,13 @@ config CLK_STM32MP1
Enable the STM32 clock (RCC) driver. Enable support for
manipulating STM32MP1's on-SoC clocks.
+config CLK_CDCE9XX
+ bool "Enable CDCD9XX clock driver"
+ depends on CLK
+ help
+ Enable the clock synthesizer driver for CDCE913/925/937/949
+ series of chips.
+
source "drivers/clk/analogbits/Kconfig"
source "drivers/clk/at91/Kconfig"
source "drivers/clk/exynos/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index d7cea3b8bf..8de6777468 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -44,3 +44,4 @@ obj-$(CONFIG_SANDBOX_CLK_CCF) += clk_sandbox_ccf.o
obj-$(CONFIG_STM32H7) += clk_stm32h7.o
obj-$(CONFIG_CLK_TI_SCI) += clk-ti-sci.o
obj-$(CONFIG_CLK_VERSAL) += clk_versal.o
+obj-$(CONFIG_CLK_CDCE9XX) += clk-cdce9xx.o
diff --git a/drivers/clk/clk-cdce9xx.c b/drivers/clk/clk-cdce9xx.c
new file mode 100644
index 0000000000..5d1489ab0e
--- /dev/null
+++ b/drivers/clk/clk-cdce9xx.c
@@ -0,0 +1,254 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Texas Instruments CDCE913/925/937/949 clock synthesizer driver
+ *
+ * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
+ * Tero Kristo <t-kristo@ti.com>
+ *
+ * Based on Linux kernel clk-cdce925.c.
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <clk-uclass.h>
+#include <i2c.h>
+
+#define MAX_NUMBER_OF_PLLS 4
+#define MAX_NUMER_OF_OUTPUTS 9
+
+#define CDCE9XX_REG_GLOBAL1 0x01
+#define CDCE9XX_REG_Y1SPIPDIVH 0x02
+#define CDCE9XX_REG_PDIV1L 0x03
+#define CDCE9XX_REG_XCSEL 0x05
+
+#define CDCE9XX_PDIV1_H_MASK 0x3
+
+#define CDCE9XX_REG_PDIV(clk) (0x16 + (((clk) - 1) & 1) + \
+ ((clk) - 1) / 2 * 0x10)
+
+#define CDCE9XX_PDIV_MASK 0x7f
+
+#define CDCE9XX_BYTE_TRANSFER BIT(7)
+
+struct cdce9xx_chip_info {
+ int num_plls;
+ int num_outputs;
+};
+
+struct cdce9xx_clk_data {
+ struct udevice *i2c;
+ struct cdce9xx_chip_info *chip;
+ u32 xtal_rate;
+};
+
+static const struct cdce9xx_chip_info cdce913_chip_info = {
+ .num_plls = 1, .num_outputs = 3,
+};
+
+static const struct cdce9xx_chip_info cdce925_chip_info = {
+ .num_plls = 2, .num_outputs = 5,
+};
+
+static const struct cdce9xx_chip_info cdce937_chip_info = {
+ .num_plls = 3, .num_outputs = 7,
+};
+
+static const struct cdce9xx_chip_info cdce949_chip_info = {
+ .num_plls = 4, .num_outputs = 9,
+};
+
+static int cdce9xx_reg_read(struct udevice *dev, u8 addr, u8 *buf)
+{
+ struct cdce9xx_clk_data *data = dev_get_priv(dev);
+ int ret;
+
+ ret = dm_i2c_read(data->i2c, addr | CDCE9XX_BYTE_TRANSFER, buf, 1);
+ if (ret)
+ dev_err(dev, "%s: failed for addr:%x, ret:%d\n", __func__,
+ addr, ret);
+
+ return ret;
+}
+
+static int cdce9xx_reg_write(struct udevice *dev, u8 addr, u8 val)
+{
+ struct cdce9xx_clk_data *data = dev_get_priv(dev);
+ int ret;
+
+ ret = dm_i2c_write(data->i2c, addr | CDCE9XX_BYTE_TRANSFER, &val, 1);
+ if (ret)
+ dev_err(dev, "%s: failed for addr:%x, ret:%d\n", __func__,
+ addr, ret);
+
+ return ret;
+}
+
+static int cdce9xx_clk_of_xlate(struct clk *clk,
+ struct ofnode_phandle_args *args)
+{
+ struct cdce9xx_clk_data *data = dev_get_priv(clk->dev);
+
+ if (args->args_count != 1)
+ return -EINVAL;
+
+ if (args->args[0] > data->chip->num_outputs)
+ return -EINVAL;
+
+ clk->id = args->args[0];
+
+ return 0;
+}
+
+static int cdce9xx_clk_probe(struct udevice *dev)
+{
+ struct cdce9xx_clk_data *data = dev_get_priv(dev);
+ struct cdce9xx_chip_info *chip = (void *)dev_get_driver_data(dev);
+ int ret;
+ u32 val;
+ struct clk clk;
+
+ val = (u32)dev_read_addr_ptr(dev);
+
+ ret = i2c_get_chip(dev->parent, val, 1, &data->i2c);
+ if (ret) {
+ dev_err(dev, "I2C probe failed.\n");
+ return ret;
+ }
+
+ data->chip = chip;
+
+ ret = clk_get_by_index(dev, 0, &clk);
+ data->xtal_rate = clk_get_rate(&clk);
+
+ val = dev_read_u32_default(dev, "xtal-load-pf", -1);
+ if (val >= 0)
+ cdce9xx_reg_write(dev, CDCE9XX_REG_XCSEL, val << 3);
+
+ return 0;
+}
+
+static u16 cdce9xx_clk_get_pdiv(struct clk *clk)
+{
+ u8 val;
+ u16 pdiv;
+ int ret;
+
+ if (clk->id == 0) {
+ ret = cdce9xx_reg_read(clk->dev, CDCE9XX_REG_Y1SPIPDIVH, &val);
+ if (ret)
+ return 0;
+
+ pdiv = (val & CDCE9XX_PDIV1_H_MASK) << 8;
+
+ ret = cdce9xx_reg_read(clk->dev, CDCE9XX_REG_PDIV1L, &val);
+ if (ret)
+ return 0;
+
+ pdiv |= val;
+ } else {
+ ret = cdce9xx_reg_read(clk->dev, CDCE9XX_REG_PDIV(clk->id),
+ &val);
+ if (ret)
+ return 0;
+
+ pdiv = val & CDCE9XX_PDIV_MASK;
+ }
+
+ return pdiv;
+}
+
+static u32 cdce9xx_clk_get_parent_rate(struct clk *clk)
+{
+ struct cdce9xx_clk_data *data = dev_get_priv(clk->dev);
+
+ return data->xtal_rate;
+}
+
+static ulong cdce9xx_clk_get_rate(struct clk *clk)
+{
+ u32 parent_rate;
+ u16 pdiv;
+
+ parent_rate = cdce9xx_clk_get_parent_rate(clk);
+
+ pdiv = cdce9xx_clk_get_pdiv(clk);
+
+ return parent_rate / pdiv;
+}
+
+static ulong cdce9xx_clk_set_rate(struct clk *clk, ulong rate)
+{
+ u32 parent_rate;
+ int pdiv;
+ u32 diff;
+ u8 val;
+ int ret;
+
+ parent_rate = cdce9xx_clk_get_parent_rate(clk);
+
+ pdiv = parent_rate / rate;
+
+ diff = rate - parent_rate / pdiv;
+
+ if (rate - parent_rate / (pdiv + 1) < diff)
+ pdiv++;
+
+ if (clk->id == 0) {
+ ret = cdce9xx_reg_read(clk->dev, CDCE9XX_REG_Y1SPIPDIVH, &val);
+ if (ret)
+ return ret;
+
+ val &= ~CDCE9XX_PDIV1_H_MASK;
+
+ val |= (pdiv >> 8);
+
+ ret = cdce9xx_reg_write(clk->dev, CDCE9XX_REG_Y1SPIPDIVH, val);
+ if (ret)
+ return ret;
+
+ ret = cdce9xx_reg_write(clk->dev, CDCE9XX_REG_PDIV1L,
+ (pdiv & 0xff));
+ if (ret)
+ return ret;
+ } else {
+ ret = cdce9xx_reg_read(clk->dev, CDCE9XX_REG_PDIV(clk->id),
+ &val);
+ if (ret)
+ return ret;
+
+ val &= ~CDCE9XX_PDIV_MASK;
+
+ val |= pdiv;
+
+ ret = cdce9xx_reg_write(clk->dev, CDCE9XX_REG_PDIV(clk->id),
+ val);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct udevice_id cdce9xx_clk_of_match[] = {
+ { .compatible = "ti,cdce913", .data = (u32)&cdce913_chip_info },
+ { .compatible = "ti,cdce925", .data = (u32)&cdce925_chip_info },
+ { .compatible = "ti,cdce937", .data = (u32)&cdce937_chip_info },
+ { .compatible = "ti,cdce949", .data = (u32)&cdce949_chip_info },
+ { /* sentinel */ },
+};
+
+static const struct clk_ops cdce9xx_clk_ops = {
+ .of_xlate = cdce9xx_clk_of_xlate,
+ .get_rate = cdce9xx_clk_get_rate,
+ .set_rate = cdce9xx_clk_set_rate,
+};
+
+U_BOOT_DRIVER(cdce9xx_clk) = {
+ .name = "cdce9xx-clk",
+ .id = UCLASS_CLK,
+ .of_match = cdce9xx_clk_of_match,
+ .probe = cdce9xx_clk_probe,
+ .priv_auto_alloc_size = sizeof(struct cdce9xx_clk_data),
+ .ops = &cdce9xx_clk_ops,
+};
diff --git a/drivers/core/device.c b/drivers/core/device.c
index 84f0f0fbf0..ce66c72e5e 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -568,6 +568,17 @@ int device_get_child(struct udevice *parent, int index, struct udevice **devp)
return -ENODEV;
}
+int device_get_child_count(struct udevice *parent)
+{
+ struct udevice *dev;
+ int count = 0;
+
+ list_for_each_entry(dev, &parent->child_head, sibling_node)
+ count++;
+
+ return count;
+}
+
int device_find_child_by_seq(struct udevice *parent, int seq_or_req_seq,
bool find_req_seq, struct udevice **devp)
{
diff --git a/drivers/mmc/am654_sdhci.c b/drivers/mmc/am654_sdhci.c
index 1793a3f99a..7cd5516197 100644
--- a/drivers/mmc/am654_sdhci.c
+++ b/drivers/mmc/am654_sdhci.c
@@ -219,23 +219,10 @@ static int am654_sdhci_probe(struct udevice *dev)
struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
struct sdhci_host *host = dev_get_priv(dev);
struct mmc_config *cfg = &plat->cfg;
- struct power_domain sdhci_pwrdmn;
struct clk clk;
unsigned long clock;
int ret;
- ret = power_domain_get_by_index(dev, &sdhci_pwrdmn, 0);
- if (!ret) {
- ret = power_domain_on(&sdhci_pwrdmn);
- if (ret) {
- dev_err(dev, "Power domain on failed (%d)\n", ret);
- return ret;
- }
- } else if (ret != -ENOENT && ret != -ENODEV && ret != -ENOSYS) {
- dev_err(dev, "failed to get power domain (%d)\n", ret);
- return ret;
- }
-
ret = clk_get_by_index(dev, 0, &clk);
if (ret) {
dev_err(dev, "failed to get clock\n");
diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index f54a245424..7c2e4804b5 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -52,6 +52,26 @@ config REMOTEPROC_TI_K3_ARM64
on various TI K3 family of SoCs through the remote processor
framework.
+config REMOTEPROC_TI_K3_DSP
+ bool "TI K3 C66 and C71 remoteproc support"
+ select REMOTEPROC
+ depends on ARCH_K3
+ depends on TI_SCI_PROTOCOL
+ help
+ Say y here to support TI's C66/C71 remote processor subsystems
+ on various TI K3 family of SoCs through the remote processor
+ framework.
+
+config REMOTEPROC_TI_K3_R5F
+ bool "TI K3 R5F remoteproc support"
+ select REMOTEPROC
+ depends on ARCH_K3
+ depends on TI_SCI_PROTOCOL
+ help
+ Say y here to support TI's R5F remote processor subsystems
+ on various TI K3 family of SoCs through the remote processor
+ framework.
+
config REMOTEPROC_TI_POWER
bool "Support for TI Power processor"
select REMOTEPROC
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index 271ba55b09..69ae7bd1e8 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -11,4 +11,6 @@ obj-$(CONFIG_K3_SYSTEM_CONTROLLER) += k3_system_controller.o
obj-$(CONFIG_REMOTEPROC_SANDBOX) += sandbox_testproc.o
obj-$(CONFIG_REMOTEPROC_STM32_COPRO) += stm32_copro.o
obj-$(CONFIG_REMOTEPROC_TI_K3_ARM64) += ti_k3_arm64_rproc.o
+obj-$(CONFIG_REMOTEPROC_TI_K3_DSP) += ti_k3_dsp_rproc.o
+obj-$(CONFIG_REMOTEPROC_TI_K3_R5F) += ti_k3_r5f_rproc.o
obj-$(CONFIG_REMOTEPROC_TI_POWER) += ti_power_proc.o
diff --git a/drivers/remoteproc/rproc-elf-loader.c b/drivers/remoteproc/rproc-elf-loader.c
index 67937a7595..b38a226065 100644
--- a/drivers/remoteproc/rproc-elf-loader.c
+++ b/drivers/remoteproc/rproc-elf-loader.c
@@ -64,13 +64,90 @@ int rproc_elf32_sanity_check(ulong addr, ulong size)
return 0;
}
-/* A very simple elf loader, assumes the image is valid */
-int rproc_elf32_load_image(struct udevice *dev, unsigned long addr)
+/* Basic function to verify ELF64 image format */
+int rproc_elf64_sanity_check(ulong addr, ulong size)
+{
+ Elf64_Ehdr *ehdr = (Elf64_Ehdr *)addr;
+ char class;
+
+ if (!addr) {
+ pr_debug("Invalid fw address?\n");
+ return -EFAULT;
+ }
+
+ if (size < sizeof(Elf64_Ehdr)) {
+ pr_debug("Image is too small\n");
+ return -ENOSPC;
+ }
+
+ class = ehdr->e_ident[EI_CLASS];
+
+ if (!IS_ELF(*ehdr) || ehdr->e_type != ET_EXEC || class != ELFCLASS64) {
+ pr_debug("Not an executable ELF64 image\n");
+ return -EPROTONOSUPPORT;
+ }
+
+ /* We assume the firmware has the same endianness as the host */
+# ifdef __LITTLE_ENDIAN
+ if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB) {
+# else /* BIG ENDIAN */
+ if (ehdr->e_ident[EI_DATA] != ELFDATA2MSB) {
+# endif
+ pr_debug("Unsupported firmware endianness\n");
+ return -EILSEQ;
+ }
+
+ if (size < ehdr->e_shoff + sizeof(Elf64_Shdr)) {
+ pr_debug("Image is too small\n");
+ return -ENOSPC;
+ }
+
+ if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG)) {
+ pr_debug("Image is corrupted (bad magic)\n");
+ return -EBADF;
+ }
+
+ if (ehdr->e_phnum == 0) {
+ pr_debug("No loadable segments\n");
+ return -ENOEXEC;
+ }
+
+ if (ehdr->e_phoff > size) {
+ pr_debug("Firmware size is too small\n");
+ return -ENOSPC;
+ }
+
+ return 0;
+}
+
+/* Basic function to verify ELF image format */
+int rproc_elf_sanity_check(ulong addr, ulong size)
+{
+ Elf32_Ehdr *ehdr = (Elf32_Ehdr *)addr;
+
+ if (!addr) {
+ dev_err(dev, "Invalid firmware address\n");
+ return -EFAULT;
+ }
+
+ if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
+ return rproc_elf64_sanity_check(addr, size);
+ else
+ return rproc_elf32_sanity_check(addr, size);
+}
+
+int rproc_elf32_load_image(struct udevice *dev, unsigned long addr, ulong size)
{
Elf32_Ehdr *ehdr; /* Elf header structure pointer */
Elf32_Phdr *phdr; /* Program header structure pointer */
const struct dm_rproc_ops *ops;
- unsigned int i;
+ unsigned int i, ret;
+
+ ret = rproc_elf32_sanity_check(addr, size);
+ if (ret) {
+ dev_err(dev, "Invalid ELF32 Image %d\n", ret);
+ return ret;
+ }
ehdr = (Elf32_Ehdr *)addr;
phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff);
@@ -86,7 +163,8 @@ int rproc_elf32_load_image(struct udevice *dev, unsigned long addr)
continue;
if (ops->device_to_virt)
- dst = ops->device_to_virt(dev, (ulong)dst);
+ dst = ops->device_to_virt(dev, (ulong)dst,
+ phdr->p_memsz);
dev_dbg(dev, "Loading phdr %i to 0x%p (%i bytes)\n",
i, dst, phdr->p_filesz);
@@ -104,3 +182,96 @@ int rproc_elf32_load_image(struct udevice *dev, unsigned long addr)
return 0;
}
+
+int rproc_elf64_load_image(struct udevice *dev, ulong addr, ulong size)
+{
+ const struct dm_rproc_ops *ops = rproc_get_ops(dev);
+ u64 da, memsz, filesz, offset;
+ Elf64_Ehdr *ehdr;
+ Elf64_Phdr *phdr;
+ int i, ret = 0;
+ void *ptr;
+
+ dev_dbg(dev, "%s: addr = 0x%lx size = 0x%lx\n", __func__, addr, size);
+
+ if (rproc_elf64_sanity_check(addr, size))
+ return -EINVAL;
+
+ ehdr = (Elf64_Ehdr *)addr;
+ phdr = (Elf64_Phdr *)(addr + (ulong)ehdr->e_phoff);
+
+ /* go through the available ELF segments */
+ for (i = 0; i < ehdr->e_phnum; i++, phdr++) {
+ da = phdr->p_paddr;
+ memsz = phdr->p_memsz;
+ filesz = phdr->p_filesz;
+ offset = phdr->p_offset;
+
+ if (phdr->p_type != PT_LOAD)
+ continue;
+
+ dev_dbg(dev, "%s:phdr: type %d da 0x%llx memsz 0x%llx filesz 0x%llx\n",
+ __func__, phdr->p_type, da, memsz, filesz);
+
+ ptr = (void *)(uintptr_t)da;
+ if (ops->device_to_virt) {
+ ptr = ops->device_to_virt(dev, da, phdr->p_memsz);
+ if (!ptr) {
+ dev_err(dev, "bad da 0x%llx mem 0x%llx\n", da,
+ memsz);
+ ret = -EINVAL;
+ break;
+ }
+ }
+
+ if (filesz)
+ memcpy(ptr, (void *)addr + offset, filesz);
+ if (filesz != memsz)
+ memset(ptr + filesz, 0x00, memsz - filesz);
+
+ flush_cache(rounddown((ulong)ptr, ARCH_DMA_MINALIGN),
+ roundup((ulong)ptr + filesz, ARCH_DMA_MINALIGN) -
+ rounddown((ulong)ptr, ARCH_DMA_MINALIGN));
+ }
+
+ return ret;
+}
+
+int rproc_elf_load_image(struct udevice *dev, ulong addr, ulong size)
+{
+ Elf32_Ehdr *ehdr = (Elf32_Ehdr *)addr;
+
+ if (!addr) {
+ dev_err(dev, "Invalid firmware address\n");
+ return -EFAULT;
+ }
+
+ if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
+ return rproc_elf64_load_image(dev, addr, size);
+ else
+ return rproc_elf32_load_image(dev, addr, size);
+}
+
+static ulong rproc_elf32_get_boot_addr(ulong addr)
+{
+ Elf32_Ehdr *ehdr = (Elf32_Ehdr *)addr;
+
+ return ehdr->e_entry;
+}
+
+static ulong rproc_elf64_get_boot_addr(ulong addr)
+{
+ Elf64_Ehdr *ehdr = (Elf64_Ehdr *)addr;
+
+ return ehdr->e_entry;
+}
+
+ulong rproc_elf_get_boot_addr(struct udevice *dev, ulong addr)
+{
+ Elf32_Ehdr *ehdr = (Elf32_Ehdr *)addr;
+
+ if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
+ return rproc_elf64_get_boot_addr(addr);
+ else
+ return rproc_elf32_get_boot_addr(addr);
+}
diff --git a/drivers/remoteproc/sandbox_testproc.c b/drivers/remoteproc/sandbox_testproc.c
index 5f35119ab7..eeee49c4dd 100644
--- a/drivers/remoteproc/sandbox_testproc.c
+++ b/drivers/remoteproc/sandbox_testproc.c
@@ -306,9 +306,11 @@ static int sandbox_testproc_ping(struct udevice *dev)
* sandbox_testproc_device_to_virt() - Convert device address to virtual address
* @dev: device to operate upon
* @da: device address
+ * @size: Size of the memory region @da is pointing to
* @return converted virtual address
*/
-static void *sandbox_testproc_device_to_virt(struct udevice *dev, ulong da)
+static void *sandbox_testproc_device_to_virt(struct udevice *dev, ulong da,
+ ulong size)
{
u64 paddr;
diff --git a/drivers/remoteproc/stm32_copro.c b/drivers/remoteproc/stm32_copro.c
index ad941f67e8..40bba37211 100644
--- a/drivers/remoteproc/stm32_copro.c
+++ b/drivers/remoteproc/stm32_copro.c
@@ -107,11 +107,13 @@ static int stm32_copro_set_hold_boot(struct udevice *dev, bool hold)
* stm32_copro_device_to_virt() - Convert device address to virtual address
* @dev: corresponding STM32 remote processor device
* @da: device address
+ * @size: Size of the memory region @da is pointing to
* @return converted virtual address
*/
-static void *stm32_copro_device_to_virt(struct udevice *dev, ulong da)
+static void *stm32_copro_device_to_virt(struct udevice *dev, ulong da,
+ ulong size)
{
- fdt32_t in_addr = cpu_to_be32(da);
+ fdt32_t in_addr = cpu_to_be32(da), end_addr;
u64 paddr;
paddr = dev_translate_dma_address(dev, &in_addr);
@@ -120,6 +122,12 @@ static void *stm32_copro_device_to_virt(struct udevice *dev, ulong da)
return NULL;
}
+ end_addr = cpu_to_be32(da + size - 1);
+ if (dev_translate_dma_address(dev, &end_addr) == OF_BAD_ADDR) {
+ dev_err(dev, "Unable to convert address %ld\n", da + size - 1);
+ return NULL;
+ }
+
return phys_to_virt(paddr);
}
@@ -147,14 +155,7 @@ static int stm32_copro_load(struct udevice *dev, ulong addr, ulong size)
return ret;
}
- /* Support only ELF32 image */
- ret = rproc_elf32_sanity_check(addr, size);
- if (ret) {
- dev_err(dev, "Invalid ELF32 image (%d)\n", ret);
- return ret;
- }
-
- return rproc_elf32_load_image(dev, addr);
+ return rproc_elf32_load_image(dev, addr, size);
}
/**
diff --git a/drivers/remoteproc/ti_k3_dsp_rproc.c b/drivers/remoteproc/ti_k3_dsp_rproc.c
new file mode 100644
index 0000000000..c5dc6b25da
--- /dev/null
+++ b/drivers/remoteproc/ti_k3_dsp_rproc.c
@@ -0,0 +1,354 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Texas Instruments' K3 DSP Remoteproc driver
+ *
+ * Copyright (C) 2018-2019 Texas Instruments Incorporated - http://www.ti.com/
+ * Lokesh Vutla <lokeshvutla@ti.com>
+ *
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <remoteproc.h>
+#include <errno.h>
+#include <clk.h>
+#include <reset.h>
+#include <asm/io.h>
+#include <power-domain.h>
+#include <linux/soc/ti/ti_sci_protocol.h>
+#include "ti_sci_proc.h"
+
+#define KEYSTONE_RPROC_LOCAL_ADDRESS_MASK (SZ_16M - 1)
+
+/**
+ * struct k3_dsp_mem - internal memory structure
+ * @cpu_addr: MPU virtual address of the memory region
+ * @bus_addr: Bus address used to access the memory region
+ * @dev_addr: Device address from remoteproc view
+ * @size: Size of the memory region
+ */
+struct k3_dsp_mem {
+ void __iomem *cpu_addr;
+ phys_addr_t bus_addr;
+ phys_addr_t dev_addr;
+ size_t size;
+};
+
+/**
+ * struct k3_dsp_privdata - Structure representing Remote processor data.
+ * @rproc_rst: rproc reset control data
+ * @tsp: Pointer to TISCI proc contrl handle
+ * @mem: Array of available memories
+ * @num_mem: Number of available memories
+ */
+struct k3_dsp_privdata {
+ struct reset_ctl dsp_rst;
+ struct ti_sci_proc tsp;
+ struct k3_dsp_mem *mem;
+ int num_mems;
+};
+
+/**
+ * k3_dsp_load() - Load up the Remote processor image
+ * @dev: rproc device pointer
+ * @addr: Address at which image is available
+ * @size: size of the image
+ *
+ * Return: 0 if all goes good, else appropriate error message.
+ */
+static int k3_dsp_load(struct udevice *dev, ulong addr, ulong size)
+{
+ struct k3_dsp_privdata *dsp = dev_get_priv(dev);
+ u32 boot_vector;
+ int ret;
+
+ dev_dbg(dev, "%s addr = 0x%lx, size = 0x%lx\n", __func__, addr, size);
+ ret = ti_sci_proc_request(&dsp->tsp);
+ if (ret)
+ return ret;
+
+ ret = rproc_elf_load_image(dev, addr, size);
+ if (ret < 0) {
+ dev_err(dev, "Loading elf failed %d\n", ret);
+ goto proc_release;
+ }
+
+ boot_vector = rproc_elf_get_boot_addr(dev, addr);
+
+ dev_dbg(dev, "%s: Boot vector = 0x%x\n", __func__, boot_vector);
+
+ ret = ti_sci_proc_set_config(&dsp->tsp, boot_vector, 0, 0);
+proc_release:
+ ti_sci_proc_release(&dsp->tsp);
+ return ret;
+}
+
+/**
+ * k3_dsp_start() - Start the remote processor
+ * @dev: rproc device pointer
+ *
+ * Return: 0 if all went ok, else return appropriate error
+ */
+static int k3_dsp_start(struct udevice *dev)
+{
+ struct k3_dsp_privdata *dsp = dev_get_priv(dev);
+ int ret;
+
+ dev_dbg(dev, "%s\n", __func__);
+
+ ret = ti_sci_proc_request(&dsp->tsp);
+ if (ret)
+ return ret;
+ /*
+ * Setting the right clock frequency would have taken care by
+ * assigned-clock-rates during the device probe. So no need to
+ * set the frequency again here.
+ */
+ ret = ti_sci_proc_power_domain_on(&dsp->tsp);
+ if (ret)
+ goto proc_release;
+
+ ret = reset_deassert(&dsp->dsp_rst);
+
+proc_release:
+ ti_sci_proc_release(&dsp->tsp);
+
+ return ret;
+}
+
+static int k3_dsp_stop(struct udevice *dev)
+{
+ struct k3_dsp_privdata *dsp = dev_get_priv(dev);
+
+ dev_dbg(dev, "%s\n", __func__);
+
+ ti_sci_proc_request(&dsp->tsp);
+ reset_assert(&dsp->dsp_rst);
+ ti_sci_proc_power_domain_off(&dsp->tsp);
+ ti_sci_proc_release(&dsp->tsp);
+
+ return 0;
+}
+
+/**
+ * k3_dsp_init() - Initialize the remote processor
+ * @dev: rproc device pointer
+ *
+ * Return: 0 if all went ok, else return appropriate error
+ */
+static int k3_dsp_init(struct udevice *dev)
+{
+ dev_dbg(dev, "%s\n", __func__);
+
+ return 0;
+}
+
+static int k3_dsp_reset(struct udevice *dev)
+{
+ dev_dbg(dev, "%s\n", __func__);
+
+ return 0;
+}
+
+static void *k3_dsp_da_to_va(struct udevice *dev, ulong da, ulong len)
+{
+ struct k3_dsp_privdata *dsp = dev_get_priv(dev);
+ phys_addr_t bus_addr, dev_addr;
+ void __iomem *va = NULL;
+ size_t size;
+ u32 offset;
+ int i;
+
+ dev_dbg(dev, "%s\n", __func__);
+
+ if (len <= 0)
+ return NULL;
+
+ for (i = 0; i < dsp->num_mems; i++) {
+ bus_addr = dsp->mem[i].bus_addr;
+ dev_addr = dsp->mem[i].dev_addr;
+ size = dsp->mem[i].size;
+
+ if (da >= dev_addr && ((da + len) <= (dev_addr + size))) {
+ offset = da - dev_addr;
+ va = dsp->mem[i].cpu_addr + offset;
+ return (__force void *)va;
+ }
+
+ if (da >= bus_addr && (da + len) <= (bus_addr + size)) {
+ offset = da - bus_addr;
+ va = dsp->mem[i].cpu_addr + offset;
+ return (__force void *)va;
+ }
+ }
+
+ /* Assume it is DDR region and return da */
+ return map_physmem(da, len, MAP_NOCACHE);
+}
+
+static const struct dm_rproc_ops k3_dsp_ops = {
+ .init = k3_dsp_init,
+ .load = k3_dsp_load,
+ .start = k3_dsp_start,
+ .stop = k3_dsp_stop,
+ .reset = k3_dsp_reset,
+ .device_to_virt = k3_dsp_da_to_va,
+};
+
+static int ti_sci_proc_of_to_priv(struct udevice *dev, struct ti_sci_proc *tsp)
+{
+ u32 ids[2];
+ int ret;
+
+ dev_dbg(dev, "%s\n", __func__);
+
+ tsp->sci = ti_sci_get_by_phandle(dev, "ti,sci");
+ if (IS_ERR(tsp->sci)) {
+ dev_err(dev, "ti_sci get failed: %ld\n", PTR_ERR(tsp->sci));
+ return PTR_ERR(tsp->sci);
+ }
+
+ ret = dev_read_u32_array(dev, "ti,sci-proc-ids", ids, 2);
+ if (ret) {
+ dev_err(dev, "Proc IDs not populated %d\n", ret);
+ return ret;
+ }
+
+ tsp->ops = &tsp->sci->ops.proc_ops;
+ tsp->proc_id = ids[0];
+ tsp->host_id = ids[1];
+ tsp->dev_id = dev_read_u32_default(dev, "ti,sci-dev-id",
+ TI_SCI_RESOURCE_NULL);
+ if (tsp->dev_id == TI_SCI_RESOURCE_NULL) {
+ dev_err(dev, "Device ID not populated %d\n", ret);
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static int k3_dsp_of_get_memories(struct udevice *dev)
+{
+ static const char * const mem_names[] = {"l2sram", "l1pram", "l1dram"};
+ struct k3_dsp_privdata *dsp = dev_get_priv(dev);
+ int i;
+
+ dev_dbg(dev, "%s\n", __func__);
+
+ dsp->num_mems = ARRAY_SIZE(mem_names);
+ dsp->mem = calloc(dsp->num_mems, sizeof(*dsp->mem));
+ if (!dsp->mem)
+ return -ENOMEM;
+
+ for (i = 0; i < dsp->num_mems; i++) {
+ /* C71 cores only have a L1P Cache, there are no L1P SRAMs */
+ if (device_is_compatible(dev, "ti,j721e-c71-dsp") &&
+ !strcmp(mem_names[i], "l1pram")) {
+ dsp->mem[i].bus_addr = FDT_ADDR_T_NONE;
+ dsp->mem[i].dev_addr = FDT_ADDR_T_NONE;
+ dsp->mem[i].cpu_addr = NULL;
+ dsp->mem[i].size = 0;
+ continue;
+ }
+
+ dsp->mem[i].bus_addr = dev_read_addr_size_name(dev, mem_names[i],
+ (fdt_addr_t *)&dsp->mem[i].size);
+ if (dsp->mem[i].bus_addr == FDT_ADDR_T_NONE) {
+ dev_err(dev, "%s bus address not found\n", mem_names[i]);
+ return -EINVAL;
+ }
+ dsp->mem[i].cpu_addr = map_physmem(dsp->mem[i].bus_addr,
+ dsp->mem[i].size,
+ MAP_NOCACHE);
+ dsp->mem[i].dev_addr = dsp->mem[i].bus_addr &
+ KEYSTONE_RPROC_LOCAL_ADDRESS_MASK;
+
+ dev_dbg(dev, "memory %8s: bus addr %pa size 0x%zx va %p da %pa\n",
+ mem_names[i], &dsp->mem[i].bus_addr,
+ dsp->mem[i].size, dsp->mem[i].cpu_addr,
+ &dsp->mem[i].dev_addr);
+ }
+
+ return 0;
+}
+
+/**
+ * k3_of_to_priv() - generate private data from device tree
+ * @dev: corresponding k3 dsp processor device
+ * @dsp: pointer to driver specific private data
+ *
+ * Return: 0 if all goes good, else appropriate error message.
+ */
+static int k3_dsp_of_to_priv(struct udevice *dev, struct k3_dsp_privdata *dsp)
+{
+ int ret;
+
+ dev_dbg(dev, "%s\n", __func__);
+
+ ret = reset_get_by_index(dev, 0, &dsp->dsp_rst);
+ if (ret) {
+ dev_err(dev, "reset_get() failed: %d\n", ret);
+ return ret;
+ }
+
+ ret = ti_sci_proc_of_to_priv(dev, &dsp->tsp);
+ if (ret)
+ return ret;
+
+ ret = k3_dsp_of_get_memories(dev);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+/**
+ * k3_dsp_probe() - Basic probe
+ * @dev: corresponding k3 remote processor device
+ *
+ * Return: 0 if all goes good, else appropriate error message.
+ */
+static int k3_dsp_probe(struct udevice *dev)
+{
+ struct k3_dsp_privdata *dsp;
+ int ret;
+
+ dev_dbg(dev, "%s\n", __func__);
+
+ dsp = dev_get_priv(dev);
+
+ ret = k3_dsp_of_to_priv(dev, dsp);
+ if (ret) {
+ dev_dbg(dev, "%s: Probe failed with error %d\n", __func__, ret);
+ return ret;
+ }
+
+ dev_dbg(dev, "Remoteproc successfully probed\n");
+
+ return 0;
+}
+
+static int k3_dsp_remove(struct udevice *dev)
+{
+ struct k3_dsp_privdata *dsp = dev_get_priv(dev);
+
+ free(dsp->mem);
+
+ return 0;
+}
+
+static const struct udevice_id k3_dsp_ids[] = {
+ { .compatible = "ti,j721e-c66-dsp"},
+ { .compatible = "ti,j721e-c71-dsp"},
+ {}
+};
+
+U_BOOT_DRIVER(k3_dsp) = {
+ .name = "k3_dsp",
+ .of_match = k3_dsp_ids,
+ .id = UCLASS_REMOTEPROC,
+ .ops = &k3_dsp_ops,
+ .probe = k3_dsp_probe,
+ .remove = k3_dsp_remove,
+ .priv_auto_alloc_size = sizeof(struct k3_dsp_privdata),
+};
diff --git a/drivers/remoteproc/ti_k3_r5f_rproc.c b/drivers/remoteproc/ti_k3_r5f_rproc.c
new file mode 100644
index 0000000000..ae1e4b9e04
--- /dev/null
+++ b/drivers/remoteproc/ti_k3_r5f_rproc.c
@@ -0,0 +1,816 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Texas Instruments' K3 R5 Remoteproc driver
+ *
+ * Copyright (C) 2018-2019 Texas Instruments Incorporated - http://www.ti.com/
+ * Lokesh Vutla <lokeshvutla@ti.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <remoteproc.h>
+#include <errno.h>
+#include <clk.h>
+#include <reset.h>
+#include <asm/io.h>
+#include <linux/kernel.h>
+#include <linux/soc/ti/ti_sci_protocol.h>
+#include "ti_sci_proc.h"
+
+/*
+ * R5F's view of this address can either be for ATCM or BTCM with the other
+ * at address 0x0 based on loczrama signal.
+ */
+#define K3_R5_TCM_DEV_ADDR 0x41010000
+
+/* R5 TI-SCI Processor Configuration Flags */
+#define PROC_BOOT_CFG_FLAG_R5_DBG_EN 0x00000001
+#define PROC_BOOT_CFG_FLAG_R5_DBG_NIDEN 0x00000002
+#define PROC_BOOT_CFG_FLAG_R5_LOCKSTEP 0x00000100
+#define PROC_BOOT_CFG_FLAG_R5_TEINIT 0x00000200
+#define PROC_BOOT_CFG_FLAG_R5_NMFI_EN 0x00000400
+#define PROC_BOOT_CFG_FLAG_R5_TCM_RSTBASE 0x00000800
+#define PROC_BOOT_CFG_FLAG_R5_BTCM_EN 0x00001000
+#define PROC_BOOT_CFG_FLAG_R5_ATCM_EN 0x00002000
+#define PROC_BOOT_CFG_FLAG_GEN_IGN_BOOTVECTOR 0x10000000
+
+/* R5 TI-SCI Processor Control Flags */
+#define PROC_BOOT_CTRL_FLAG_R5_CORE_HALT 0x00000001
+
+/* R5 TI-SCI Processor Status Flags */
+#define PROC_BOOT_STATUS_FLAG_R5_WFE 0x00000001
+#define PROC_BOOT_STATUS_FLAG_R5_WFI 0x00000002
+#define PROC_BOOT_STATUS_FLAG_R5_CLK_GATED 0x00000004
+#define PROC_BOOT_STATUS_FLAG_R5_LOCKSTEP_PERMITTED 0x00000100
+
+#define NR_CORES 2
+
+enum cluster_mode {
+ CLUSTER_MODE_SPLIT = 0,
+ CLUSTER_MODE_LOCKSTEP,
+};
+
+/**
+ * struct k3_r5_mem - internal memory structure
+ * @cpu_addr: MPU virtual address of the memory region
+ * @bus_addr: Bus address used to access the memory region
+ * @dev_addr: Device address from remoteproc view
+ * @size: Size of the memory region
+ */
+struct k3_r5f_mem {
+ void __iomem *cpu_addr;
+ phys_addr_t bus_addr;
+ u32 dev_addr;
+ size_t size;
+};
+
+/**
+ * struct k3_r5f_core - K3 R5 core structure
+ * @dev: cached device pointer
+ * @cluster: pointer to the parent cluster.
+ * @reset: reset control handle
+ * @tsp: TI-SCI processor control handle
+ * @mem: Array of available internal memories
+ * @num_mem: Number of available memories
+ * @atcm_enable: flag to control ATCM enablement
+ * @btcm_enable: flag to control BTCM enablement
+ * @loczrama: flag to dictate which TCM is at device address 0x0
+ * @in_use: flag to tell if the core is already in use.
+ */
+struct k3_r5f_core {
+ struct udevice *dev;
+ struct k3_r5f_cluster *cluster;
+ struct reset_ctl reset;
+ struct ti_sci_proc tsp;
+ struct k3_r5f_mem *mem;
+ int num_mems;
+ u32 atcm_enable;
+ u32 btcm_enable;
+ u32 loczrama;
+ bool in_use;
+};
+
+/**
+ * struct k3_r5f_cluster - K3 R5F Cluster structure
+ * @mode: Mode to configure the Cluster - Split or LockStep
+ * @cores: Array of pointers to R5 cores within the cluster
+ */
+struct k3_r5f_cluster {
+ enum cluster_mode mode;
+ struct k3_r5f_core *cores[NR_CORES];
+};
+
+static bool is_primary_core(struct k3_r5f_core *core)
+{
+ return core == core->cluster->cores[0];
+}
+
+static int k3_r5f_proc_request(struct k3_r5f_core *core)
+{
+ struct k3_r5f_cluster *cluster = core->cluster;
+ int i, ret;
+
+ if (cluster->mode == CLUSTER_MODE_LOCKSTEP) {
+ for (i = 0; i < NR_CORES; i++) {
+ ret = ti_sci_proc_request(&cluster->cores[i]->tsp);
+ if (ret)
+ goto proc_release;
+ }
+ } else {
+ ret = ti_sci_proc_request(&core->tsp);
+ }
+
+ return 0;
+
+proc_release:
+ while (i >= 0) {
+ ti_sci_proc_release(&cluster->cores[i]->tsp);
+ i--;
+ }
+ return ret;
+}
+
+static void k3_r5f_proc_release(struct k3_r5f_core *core)
+{
+ struct k3_r5f_cluster *cluster = core->cluster;
+ int i;
+
+ if (cluster->mode == CLUSTER_MODE_LOCKSTEP)
+ for (i = 0; i < NR_CORES; i++)
+ ti_sci_proc_release(&cluster->cores[i]->tsp);
+ else
+ ti_sci_proc_release(&core->tsp);
+}
+
+static int k3_r5f_lockstep_release(struct k3_r5f_cluster *cluster)
+{
+ int ret, c;
+
+ dev_dbg(dev, "%s\n", __func__);
+
+ for (c = NR_CORES - 1; c >= 0; c--) {
+ ret = ti_sci_proc_power_domain_on(&cluster->cores[c]->tsp);
+ if (ret)
+ goto unroll_module_reset;
+ }
+
+ /* deassert local reset on all applicable cores */
+ for (c = NR_CORES - 1; c >= 0; c--) {
+ ret = reset_deassert(&cluster->cores[c]->reset);
+ if (ret)
+ goto unroll_local_reset;
+ }
+
+ return 0;
+
+unroll_local_reset:
+ while (c < NR_CORES) {
+ reset_assert(&cluster->cores[c]->reset);
+ c++;
+ }
+ c = 0;
+unroll_module_reset:
+ while (c < NR_CORES) {
+ ti_sci_proc_power_domain_off(&cluster->cores[c]->tsp);
+ c++;
+ }
+
+ return ret;
+}
+
+static int k3_r5f_split_release(struct k3_r5f_core *core)
+{
+ int ret;
+
+ dev_dbg(dev, "%s\n", __func__);
+
+ ret = ti_sci_proc_power_domain_on(&core->tsp);
+ if (ret) {
+ dev_err(core->dev, "module-reset deassert failed, ret = %d\n",
+ ret);
+ return ret;
+ }
+
+ ret = reset_deassert(&core->reset);
+ if (ret) {
+ dev_err(core->dev, "local-reset deassert failed, ret = %d\n",
+ ret);
+ if (ti_sci_proc_power_domain_off(&core->tsp))
+ dev_warn(core->dev, "module-reset assert back failed\n");
+ }
+
+ return ret;
+}
+
+static int k3_r5f_prepare(struct udevice *dev)
+{
+ struct k3_r5f_core *core = dev_get_priv(dev);
+ struct k3_r5f_cluster *cluster = core->cluster;
+ int ret = 0;
+
+ dev_dbg(dev, "%s\n", __func__);
+
+ if (cluster->mode == CLUSTER_MODE_LOCKSTEP)
+ ret = k3_r5f_lockstep_release(cluster);
+ else
+ ret = k3_r5f_split_release(core);
+
+ if (ret)
+ dev_err(dev, "Unable to enable cores for TCM loading %d\n",
+ ret);
+
+ return ret;
+}
+
+static int k3_r5f_core_sanity_check(struct k3_r5f_core *core)
+{
+ struct k3_r5f_cluster *cluster = core->cluster;
+
+ if (core->in_use) {
+ dev_err(dev, "Invalid op: Trying to load/start on already running core %d\n",
+ core->tsp.proc_id);
+ return -EINVAL;
+ }
+
+ if (cluster->mode == CLUSTER_MODE_LOCKSTEP && !cluster->cores[1]) {
+ printf("Secondary core is not probed in this cluster\n");
+ return -EAGAIN;
+ }
+
+ if (cluster->mode == CLUSTER_MODE_LOCKSTEP && !is_primary_core(core)) {
+ dev_err(dev, "Invalid op: Trying to start secondary core %d in lockstep mode\n",
+ core->tsp.proc_id);
+ return -EINVAL;
+ }
+
+ if (cluster->mode == CLUSTER_MODE_SPLIT && !is_primary_core(core)) {
+ if (!core->cluster->cores[0]->in_use) {
+ dev_err(dev, "Invalid seq: Enable primary core before loading secondary core\n");
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * k3_r5f_load() - Load up the Remote processor image
+ * @dev: rproc device pointer
+ * @addr: Address at which image is available
+ * @size: size of the image
+ *
+ * Return: 0 if all goes good, else appropriate error message.
+ */
+static int k3_r5f_load(struct udevice *dev, ulong addr, ulong size)
+{
+ struct k3_r5f_core *core = dev_get_priv(dev);
+ u32 boot_vector;
+ int ret;
+
+ dev_dbg(dev, "%s addr = 0x%lx, size = 0x%lx\n", __func__, addr, size);
+
+ ret = k3_r5f_core_sanity_check(core);
+ if (ret)
+ return ret;
+
+ ret = k3_r5f_proc_request(core);
+ if (ret)
+ return ret;
+
+ ret = k3_r5f_prepare(dev);
+ if (ret) {
+ dev_err(dev, "R5f prepare failed for core %d\n",
+ core->tsp.proc_id);
+ goto proc_release;
+ }
+
+ /* Zero out TCMs so that ECC can be effective on all TCM addresses */
+ if (core->atcm_enable)
+ memset(core->mem[0].cpu_addr, 0x00, core->mem[0].size);
+ if (core->btcm_enable)
+ memset(core->mem[1].cpu_addr, 0x00, core->mem[1].size);
+
+ ret = rproc_elf_load_image(dev, addr, size);
+ if (ret < 0) {
+ dev_err(dev, "Loading elf failedi %d\n", ret);
+ goto proc_release;
+ }
+
+ boot_vector = rproc_elf_get_boot_addr(dev, addr);
+
+ dev_dbg(dev, "%s: Boot vector = 0x%x\n", __func__, boot_vector);
+
+ ret = ti_sci_proc_set_config(&core->tsp, boot_vector, 0, 0);
+
+proc_release:
+ k3_r5f_proc_release(core);
+
+ return ret;
+}
+
+static int k3_r5f_core_halt(struct k3_r5f_core *core)
+{
+ int ret;
+
+ ret = ti_sci_proc_set_control(&core->tsp,
+ PROC_BOOT_CTRL_FLAG_R5_CORE_HALT, 0);
+ if (ret)
+ dev_err(core->dev, "Core %d failed to stop\n",
+ core->tsp.proc_id);
+
+ return ret;
+}
+
+static int k3_r5f_core_run(struct k3_r5f_core *core)
+{
+ int ret;
+
+ ret = ti_sci_proc_set_control(&core->tsp,
+ 0, PROC_BOOT_CTRL_FLAG_R5_CORE_HALT);
+ if (ret) {
+ dev_err(core->dev, "Core %d failed to start\n",
+ core->tsp.proc_id);
+ return ret;
+ }
+
+ return 0;
+}
+
+/**
+ * k3_r5f_start() - Start the remote processor
+ * @dev: rproc device pointer
+ *
+ * Return: 0 if all went ok, else return appropriate error
+ */
+static int k3_r5f_start(struct udevice *dev)
+{
+ struct k3_r5f_core *core = dev_get_priv(dev);
+ struct k3_r5f_cluster *cluster = core->cluster;
+ int ret, c;
+
+ dev_dbg(dev, "%s\n", __func__);
+
+ ret = k3_r5f_core_sanity_check(core);
+ if (ret)
+ return ret;
+
+ ret = k3_r5f_proc_request(core);
+ if (ret)
+ return ret;
+
+ if (cluster->mode == CLUSTER_MODE_LOCKSTEP) {
+ if (is_primary_core(core)) {
+ for (c = NR_CORES - 1; c >= 0; c--) {
+ ret = k3_r5f_core_run(cluster->cores[c]);
+ if (ret)
+ goto unroll_core_run;
+ }
+ } else {
+ dev_err(dev, "Invalid op: Trying to start secondary core %d in lockstep mode\n",
+ core->tsp.proc_id);
+ ret = -EINVAL;
+ goto proc_release;
+ }
+ } else {
+ ret = k3_r5f_core_run(core);
+ if (ret)
+ goto proc_release;
+ }
+
+ core->in_use = true;
+
+ k3_r5f_proc_release(core);
+ return 0;
+
+unroll_core_run:
+ while (c < NR_CORES) {
+ k3_r5f_core_halt(cluster->cores[c]);
+ c++;
+ }
+proc_release:
+ k3_r5f_proc_release(core);
+
+ return ret;
+}
+
+static int k3_r5f_split_reset(struct k3_r5f_core *core)
+{
+ int ret;
+
+ dev_dbg(dev, "%s\n", __func__);
+
+ if (reset_assert(&core->reset))
+ ret = -EINVAL;
+
+ if (ti_sci_proc_power_domain_off(&core->tsp))
+ ret = -EINVAL;
+
+ return ret;
+}
+
+static int k3_r5f_lockstep_reset(struct k3_r5f_cluster *cluster)
+{
+ int ret = 0, c;
+
+ dev_dbg(dev, "%s\n", __func__);
+
+ for (c = 0; c < NR_CORES; c++)
+ if (reset_assert(&cluster->cores[c]->reset))
+ ret = -EINVAL;
+
+ /* disable PSC modules on all applicable cores */
+ for (c = 0; c < NR_CORES; c++)
+ if (ti_sci_proc_power_domain_off(&cluster->cores[c]->tsp))
+ ret = -EINVAL;
+
+ return ret;
+}
+
+static int k3_r5f_unprepare(struct udevice *dev)
+{
+ struct k3_r5f_core *core = dev_get_priv(dev);
+ struct k3_r5f_cluster *cluster = core->cluster;
+ int ret;
+
+ dev_dbg(dev, "%s\n", __func__);
+
+ if (cluster->mode == CLUSTER_MODE_LOCKSTEP) {
+ if (is_primary_core(core))
+ ret = k3_r5f_lockstep_reset(cluster);
+ } else {
+ ret = k3_r5f_split_reset(core);
+ }
+
+ if (ret)
+ dev_warn(dev, "Unable to enable cores for TCM loading %d\n",
+ ret);
+
+ return 0;
+}
+
+static int k3_r5f_stop(struct udevice *dev)
+{
+ struct k3_r5f_core *core = dev_get_priv(dev);
+ struct k3_r5f_cluster *cluster = core->cluster;
+ int c, ret;
+
+ dev_dbg(dev, "%s\n", __func__);
+
+ ret = k3_r5f_proc_request(core);
+ if (ret)
+ return ret;
+
+ core->in_use = false;
+
+ if (cluster->mode == CLUSTER_MODE_LOCKSTEP) {
+ if (is_primary_core(core)) {
+ for (c = 0; c < NR_CORES; c++)
+ k3_r5f_core_halt(cluster->cores[c]);
+ } else {
+ dev_err(dev, "Invalid op: Trying to stop secondary core in lockstep mode\n");
+ ret = -EINVAL;
+ goto proc_release;
+ }
+ } else {
+ k3_r5f_core_halt(core);
+ }
+
+ ret = k3_r5f_unprepare(dev);
+proc_release:
+ k3_r5f_proc_release(core);
+ return ret;
+}
+
+static void *k3_r5f_da_to_va(struct udevice *dev, ulong da, ulong size)
+{
+ struct k3_r5f_core *core = dev_get_priv(dev);
+ void __iomem *va = NULL;
+ phys_addr_t bus_addr;
+ u32 dev_addr, offset;
+ ulong mem_size;
+ int i;
+
+ dev_dbg(dev, "%s\n", __func__);
+
+ if (size <= 0)
+ return NULL;
+
+ for (i = 0; i < core->num_mems; i++) {
+ bus_addr = core->mem[i].bus_addr;
+ dev_addr = core->mem[i].dev_addr;
+ mem_size = core->mem[i].size;
+
+ if (da >= bus_addr && (da + size) <= (bus_addr + mem_size)) {
+ offset = da - bus_addr;
+ va = core->mem[i].cpu_addr + offset;
+ return (__force void *)va;
+ }
+
+ if (da >= dev_addr && (da + size) <= (dev_addr + mem_size)) {
+ offset = da - dev_addr;
+ va = core->mem[i].cpu_addr + offset;
+ return (__force void *)va;
+ }
+ }
+
+ /* Assume it is DDR region and return da */
+ return map_physmem(da, size, MAP_NOCACHE);
+}
+
+static int k3_r5f_init(struct udevice *dev)
+{
+ return 0;
+}
+
+static int k3_r5f_reset(struct udevice *dev)
+{
+ return 0;
+}
+
+static const struct dm_rproc_ops k3_r5f_rproc_ops = {
+ .init = k3_r5f_init,
+ .reset = k3_r5f_reset,
+ .start = k3_r5f_start,
+ .stop = k3_r5f_stop,
+ .load = k3_r5f_load,
+ .device_to_virt = k3_r5f_da_to_va,
+};
+
+static int k3_r5f_rproc_configure(struct k3_r5f_core *core)
+{
+ struct k3_r5f_cluster *cluster = core->cluster;
+ u32 set_cfg = 0, clr_cfg = 0, cfg, ctrl, sts;
+ u64 boot_vec = 0;
+ int ret;
+
+ dev_dbg(dev, "%s\n", __func__);
+
+ ret = ti_sci_proc_request(&core->tsp);
+ if (ret < 0)
+ return ret;
+
+ /* Do not touch boot vector now. Load will take care of it. */
+ clr_cfg |= PROC_BOOT_CFG_FLAG_GEN_IGN_BOOTVECTOR;
+
+ ret = ti_sci_proc_get_status(&core->tsp, &boot_vec, &cfg, &ctrl, &sts);
+ if (ret)
+ goto out;
+
+ /* Sanity check for Lockstep mode */
+ if (cluster->mode && is_primary_core(core) &&
+ !(sts & PROC_BOOT_STATUS_FLAG_R5_LOCKSTEP_PERMITTED)) {
+ dev_err(core->dev, "LockStep mode not permitted on this device\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* Primary core only configuration */
+ if (is_primary_core(core)) {
+ /* always enable ARM mode */
+ clr_cfg |= PROC_BOOT_CFG_FLAG_R5_TEINIT;
+ if (cluster->mode == CLUSTER_MODE_LOCKSTEP)
+ set_cfg |= PROC_BOOT_CFG_FLAG_R5_LOCKSTEP;
+ else
+ clr_cfg |= PROC_BOOT_CFG_FLAG_R5_LOCKSTEP;
+ }
+
+ if (core->atcm_enable)
+ set_cfg |= PROC_BOOT_CFG_FLAG_R5_ATCM_EN;
+ else
+ clr_cfg |= PROC_BOOT_CFG_FLAG_R5_ATCM_EN;
+
+ if (core->btcm_enable)
+ set_cfg |= PROC_BOOT_CFG_FLAG_R5_BTCM_EN;
+ else
+ clr_cfg |= PROC_BOOT_CFG_FLAG_R5_BTCM_EN;
+
+ if (core->loczrama)
+ set_cfg |= PROC_BOOT_CFG_FLAG_R5_TCM_RSTBASE;
+ else
+ clr_cfg |= PROC_BOOT_CFG_FLAG_R5_TCM_RSTBASE;
+
+ ret = k3_r5f_core_halt(core);
+ if (ret)
+ goto out;
+
+ ret = ti_sci_proc_set_config(&core->tsp, boot_vec, set_cfg, clr_cfg);
+out:
+ ti_sci_proc_release(&core->tsp);
+ return ret;
+}
+
+static int ti_sci_proc_of_to_priv(struct udevice *dev, struct ti_sci_proc *tsp)
+{
+ u32 ids[2];
+ int ret;
+
+ dev_dbg(dev, "%s\n", __func__);
+
+ tsp->sci = ti_sci_get_by_phandle(dev, "ti,sci");
+ if (IS_ERR(tsp->sci)) {
+ dev_err(dev, "ti_sci get failed: %ld\n", PTR_ERR(tsp->sci));
+ return PTR_ERR(tsp->sci);
+ }
+
+ ret = dev_read_u32_array(dev, "ti,sci-proc-ids", ids, 2);
+ if (ret) {
+ dev_err(dev, "Proc IDs not populated %d\n", ret);
+ return ret;
+ }
+
+ tsp->ops = &tsp->sci->ops.proc_ops;
+ tsp->proc_id = ids[0];
+ tsp->host_id = ids[1];
+ tsp->dev_id = dev_read_u32_default(dev, "ti,sci-dev-id",
+ TI_SCI_RESOURCE_NULL);
+ if (tsp->dev_id == TI_SCI_RESOURCE_NULL) {
+ dev_err(dev, "Device ID not populated %d\n", ret);
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static int k3_r5f_of_to_priv(struct k3_r5f_core *core)
+{
+ int ret;
+
+ dev_dbg(dev, "%s\n", __func__);
+
+ core->atcm_enable = dev_read_u32_default(core->dev, "atcm-enable", 0);
+ core->btcm_enable = dev_read_u32_default(core->dev, "btcm-enable", 1);
+ core->loczrama = dev_read_u32_default(core->dev, "loczrama", 1);
+
+ ret = ti_sci_proc_of_to_priv(core->dev, &core->tsp);
+ if (ret)
+ return ret;
+
+ ret = reset_get_by_index(core->dev, 0, &core->reset);
+ if (ret) {
+ dev_err(core->dev, "Reset lines not available: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int k3_r5f_core_of_get_memories(struct k3_r5f_core *core)
+{
+ static const char * const mem_names[] = {"atcm", "btcm"};
+ struct udevice *dev = core->dev;
+ int i;
+
+ dev_dbg(dev, "%s\n", __func__);
+
+ core->num_mems = ARRAY_SIZE(mem_names);
+ core->mem = calloc(core->num_mems, sizeof(*core->mem));
+ if (!core->mem)
+ return -ENOMEM;
+
+ for (i = 0; i < core->num_mems; i++) {
+ core->mem[i].bus_addr = dev_read_addr_size_name(dev,
+ mem_names[i],
+ (fdt_addr_t *)&core->mem[i].size);
+ if (core->mem[i].bus_addr == FDT_ADDR_T_NONE) {
+ dev_err(dev, "%s bus address not found\n",
+ mem_names[i]);
+ return -EINVAL;
+ }
+ core->mem[i].cpu_addr = map_physmem(core->mem[i].bus_addr,
+ core->mem[i].size,
+ MAP_NOCACHE);
+ if (!strcmp(mem_names[i], "atcm")) {
+ core->mem[i].dev_addr = core->loczrama ?
+ 0 : K3_R5_TCM_DEV_ADDR;
+ } else {
+ core->mem[i].dev_addr = core->loczrama ?
+ K3_R5_TCM_DEV_ADDR : 0;
+ }
+
+ dev_dbg(dev, "memory %8s: bus addr %pa size 0x%zx va %p da 0x%x\n",
+ mem_names[i], &core->mem[i].bus_addr,
+ core->mem[i].size, core->mem[i].cpu_addr,
+ core->mem[i].dev_addr);
+ }
+
+ return 0;
+}
+
+/**
+ * k3_r5f_probe() - Basic probe
+ * @dev: corresponding k3 remote processor device
+ *
+ * Return: 0 if all goes good, else appropriate error message.
+ */
+static int k3_r5f_probe(struct udevice *dev)
+{
+ struct k3_r5f_cluster *cluster = dev_get_priv(dev->parent);
+ struct k3_r5f_core *core = dev_get_priv(dev);
+ bool r_state;
+ int ret;
+
+ dev_dbg(dev, "%s\n", __func__);
+
+ core->dev = dev;
+ ret = k3_r5f_of_to_priv(core);
+ if (ret)
+ return ret;
+
+ core->cluster = cluster;
+ /* Assume Primary core gets probed first */
+ if (!cluster->cores[0])
+ cluster->cores[0] = core;
+ else
+ cluster->cores[1] = core;
+
+ ret = k3_r5f_core_of_get_memories(core);
+ if (ret) {
+ dev_err(dev, "Rproc getting internal memories failed\n");
+ return ret;
+ }
+
+ ret = core->tsp.sci->ops.dev_ops.is_on(core->tsp.sci, core->tsp.dev_id,
+ &r_state, &core->in_use);
+ if (ret)
+ return ret;
+
+ if (core->in_use) {
+ dev_info(dev, "Core %d is already in use. No rproc commands work\n",
+ core->tsp.proc_id);
+ return 0;
+ }
+
+ /* Make sure Local reset is asserted. Redundant? */
+ reset_assert(&core->reset);
+
+ ret = k3_r5f_rproc_configure(core);
+ if (ret) {
+ dev_err(dev, "rproc configure failed %d\n", ret);
+ return ret;
+ }
+
+ dev_dbg(dev, "Remoteproc successfully probed\n");
+
+ return 0;
+}
+
+static int k3_r5f_remove(struct udevice *dev)
+{
+ struct k3_r5f_core *core = dev_get_priv(dev);
+
+ free(core->mem);
+
+ ti_sci_proc_release(&core->tsp);
+
+ return 0;
+}
+
+static const struct udevice_id k3_r5f_rproc_ids[] = {
+ { .compatible = "ti,am654-r5f"},
+ { .compatible = "ti,j721e-r5f"},
+ {}
+};
+
+U_BOOT_DRIVER(k3_r5f_rproc) = {
+ .name = "k3_r5f_rproc",
+ .of_match = k3_r5f_rproc_ids,
+ .id = UCLASS_REMOTEPROC,
+ .ops = &k3_r5f_rproc_ops,
+ .probe = k3_r5f_probe,
+ .remove = k3_r5f_remove,
+ .priv_auto_alloc_size = sizeof(struct k3_r5f_core),
+};
+
+static int k3_r5f_cluster_probe(struct udevice *dev)
+{
+ struct k3_r5f_cluster *cluster = dev_get_priv(dev);
+
+ dev_dbg(dev, "%s\n", __func__);
+
+ cluster->mode = dev_read_u32_default(dev, "lockstep-mode",
+ CLUSTER_MODE_LOCKSTEP);
+
+ if (device_get_child_count(dev) != 2) {
+ dev_err(dev, "Invalid number of R5 cores");
+ return -EINVAL;
+ }
+
+ dev_dbg(dev, "%s: Cluster successfully probed in %s mode\n",
+ __func__, cluster->mode ? "lockstep" : "split");
+
+ return 0;
+}
+
+static const struct udevice_id k3_r5fss_ids[] = {
+ { .compatible = "ti,am654-r5fss"},
+ { .compatible = "ti,j721e-r5fss"},
+ {}
+};
+
+U_BOOT_DRIVER(k3_r5fss) = {
+ .name = "k3_r5fss",
+ .of_match = k3_r5fss_ids,
+ .id = UCLASS_MISC,
+ .probe = k3_r5f_cluster_probe,
+ .priv_auto_alloc_size = sizeof(struct k3_r5f_cluster),
+};
diff --git a/drivers/remoteproc/ti_sci_proc.h b/drivers/remoteproc/ti_sci_proc.h
index ccfc39ec88..f8299d1aff 100644
--- a/drivers/remoteproc/ti_sci_proc.h
+++ b/drivers/remoteproc/ti_sci_proc.h
@@ -19,12 +19,14 @@
* @proc_id: processor id for the consumer remoteproc device
* @host_id: host id to pass the control over for this consumer remoteproc
* device
+ * @dev_id: Device ID as identified by system controller.
*/
struct ti_sci_proc {
const struct ti_sci_handle *sci;
const struct ti_sci_proc_ops *ops;
u8 proc_id;
u8 host_id;
+ u16 dev_id;
};
static inline int ti_sci_proc_request(struct ti_sci_proc *tsp)
@@ -118,4 +120,29 @@ static inline int ti_sci_proc_set_control(struct ti_sci_proc *tsp,
return ret;
}
+static inline int ti_sci_proc_power_domain_on(struct ti_sci_proc *tsp)
+{
+ int ret;
+
+ debug("%s: dev_id = %d\n", __func__, tsp->dev_id);
+
+ ret = tsp->sci->ops.dev_ops.get_device_exclusive(tsp->sci, tsp->dev_id);
+ if (ret)
+ pr_err("Power-domain on failed for dev = %d\n", tsp->dev_id);
+
+ return ret;
+}
+
+static inline int ti_sci_proc_power_domain_off(struct ti_sci_proc *tsp)
+{
+ int ret;
+
+ debug("%s: dev_id = %d\n", __func__, tsp->dev_id);
+
+ ret = tsp->sci->ops.dev_ops.put_device(tsp->sci, tsp->dev_id);
+ if (ret)
+ pr_err("Power-domain off failed for dev = %d\n", tsp->dev_id);
+
+ return ret;
+}
#endif /* REMOTEPROC_TI_SCI_PROC_H */
diff --git a/include/configs/am335x_guardian.h b/include/configs/am335x_guardian.h
index 8bde198313..b45b8d2eec 100644
--- a/include/configs/am335x_guardian.h
+++ b/include/configs/am335x_guardian.h
@@ -16,10 +16,14 @@
#define CONFIG_TIMESTAMP
#endif
+#define CONFIG_SYS_BOOTM_LEN (16 << 20)
+
/* Clock Defines */
#define V_OSCK 24000000 /* Clock output from T2 */
#define V_SCLK (V_OSCK)
+#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
+
#ifndef CONFIG_SPL_BUILD
#define MEM_LAYOUT_ENV_SETTINGS \
@@ -30,7 +34,6 @@
"ramdisk_addr_r=0x88080000\0" \
#define BOOT_TARGET_DEVICES(func) \
- func(MMC, mmc, 0) \
func(UBIFS, ubifs, 0) \
func(PXE, pxe, na) \
func(DHCP, dhcp, na)
@@ -44,11 +47,12 @@
MEM_LAYOUT_ENV_SETTINGS \
BOOTENV \
"bootlimit=3\0" \
+ "bootubivol=rootfs\0" \
"altbootcmd=" \
"setenv boot_config \"extlinux-rollback.conf\"; " \
"run distro_bootcmd\0"
-#endif /* CONFIG_SPL_BUILD */
+#endif /* ! CONFIG_SPL_BUILD */
/* NS16550 Configuration */
#define CONFIG_SYS_NS16550_COM1 0x44e09000 /* UART0 */
@@ -65,9 +69,6 @@
#define CONFIG_SYS_BOOTCOUNT_LE
#ifdef CONFIG_NAND
-#define CONFIG_ENV_OFFSET 0x300000
-#define CONFIG_ENV_OFFSET_REDUND 0x340000
-#define CONFIG_ENV_SIZE 0x040000
#define CONFIG_SYS_NAND_5_ADDR_CYCLE
#define CONFIG_SYS_NAND_PAGE_COUNT (CONFIG_SYS_NAND_BLOCK_SIZE / \
diff --git a/include/configs/am65x_evm.h b/include/configs/am65x_evm.h
index 0249a20ba8..1149d55937 100644
--- a/include/configs/am65x_evm.h
+++ b/include/configs/am65x_evm.h
@@ -12,6 +12,7 @@
#include <linux/sizes.h>
#include <config_distro_bootcmd.h>
#include <environment/ti/mmc.h>
+#include <environment/ti/k3_rproc.h>
#define CONFIG_ENV_SIZE (128 << 10)
@@ -98,12 +99,20 @@
"${bootdir}/${name_fit}\0" \
"partitions=" PARTS_DEFAULT
+#ifdef DEFAULT_RPROCS
+#undef DEFAULT_RPROCS
+#endif
+#define DEFAULT_RPROCS "" \
+ "0 /lib/firmware/am65x-mcu-r5f0_0-fw " \
+ "1 /lib/firmware/am65x-mcu-r5f0_1-fw "
+
/* Incorporate settings into the U-Boot environment */
#define CONFIG_EXTRA_ENV_SETTINGS \
DEFAULT_MMC_TI_ARGS \
DEFAULT_FIT_TI_ARGS \
EXTRA_ENV_AM65X_BOARD_SETTINGS \
- EXTRA_ENV_AM65X_BOARD_SETTINGS_MMC
+ EXTRA_ENV_AM65X_BOARD_SETTINGS_MMC \
+ EXTRA_ENV_RPROC_SETTINGS
/* MMC ENV related defines */
#ifdef CONFIG_ENV_IS_IN_MMC
diff --git a/include/configs/j721e_evm.h b/include/configs/j721e_evm.h
index 5fe77ef16d..dbe226b46d 100644
--- a/include/configs/j721e_evm.h
+++ b/include/configs/j721e_evm.h
@@ -12,6 +12,7 @@
#include <linux/sizes.h>
#include <config_distro_bootcmd.h>
#include <environment/ti/mmc.h>
+#include <environment/ti/k3_rproc.h>
#define CONFIG_ENV_SIZE (128 << 10)
@@ -87,11 +88,22 @@
"get_kern_mmc=load mmc ${bootpart} ${loadaddr} " \
"${bootdir}/${name_kern}\0"
+#ifdef DEFAULT_RPROCS
+#undef DEFAULT_RPROCS
+#endif
+#define DEFAULT_RPROCS "" \
+ "3 /lib/firmware/j7-main-r5f0_1-fw " \
+ "4 /lib/firmware/j7-main-r5f1_0-fw " \
+ "6 /lib/firmware/j7-c66_0-fw " \
+ "7 /lib/firmware/j7-c66_1-fw " \
+ "8 /lib/firmware/j7-c71_0-fw "
+
/* Incorporate settings into the U-Boot environment */
#define CONFIG_EXTRA_ENV_SETTINGS \
DEFAULT_MMC_TI_ARGS \
EXTRA_ENV_J721E_BOARD_SETTINGS \
- EXTRA_ENV_J721E_BOARD_SETTINGS_MMC
+ EXTRA_ENV_J721E_BOARD_SETTINGS_MMC \
+ EXTRA_ENV_RPROC_SETTINGS
/* Now for the remaining common defines */
#include <configs/ti_armv7_common.h>
diff --git a/include/configs/tao3530.h b/include/configs/tao3530.h
index c34e785d9e..7a54fe3e1e 100644
--- a/include/configs/tao3530.h
+++ b/include/configs/tao3530.h
@@ -114,7 +114,7 @@
"bootm ${loadaddr}\0" \
#define CONFIG_BOOTCOMMAND \
- "if mmc rescan ${mmcdev}; then " \
+ "mmc dev ${mmcdev}; if mmc rescan; then " \
"if run loadbootscript; then " \
"run bootscript; " \
"else " \
diff --git a/include/configs/ti_armv7_common.h b/include/configs/ti_armv7_common.h
index 2de6bc2390..6d15304a65 100644
--- a/include/configs/ti_armv7_common.h
+++ b/include/configs/ti_armv7_common.h
@@ -60,7 +60,7 @@
"do;" \
"setenv overlaystring ${overlaystring}'#'${overlay};" \
"done;\0" \
- "run_fit=bootm ${loadaddr}#${fdtfile}${overlaystring}\0" \
+ "run_fit=bootm ${addr_fit}#${fdtfile}${overlaystring}\0" \
"loadfit=run args_mmc; run run_fit;\0" \
/*
diff --git a/include/dm/device.h b/include/dm/device.h
index d1210429e9..defda0aebc 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -405,6 +405,15 @@ const char *dev_get_uclass_name(const struct udevice *dev);
int device_get_child(struct udevice *parent, int index, struct udevice **devp);
/**
+ * device_get_child_count() - Get the available child count of a device
+ *
+ * Returns the number of children to a device.
+ *
+ * @parent: Parent device to check
+ */
+int device_get_child_count(struct udevice *parent);
+
+/**
* device_find_child_by_seq() - Find a child device based on a sequence
*
* This searches for a device with the given seq or req_seq.
diff --git a/include/environment/ti/k3_rproc.h b/include/environment/ti/k3_rproc.h
new file mode 100644
index 0000000000..3418cb42be
--- /dev/null
+++ b/include/environment/ti/k3_rproc.h
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * rproc environment variable definitions for various TI K3 SoCs.
+ */
+
+#ifndef __TI_RPROC_H
+#define __TI_RPROC_H
+
+/*
+ * should contain a list of <rproc_id fw_name> tuplies,
+ * override in board config files with the actual list
+ */
+#define DEFAULT_RPROCS ""
+
+#ifdef CONFIG_CMD_REMOTEPROC
+#define EXTRA_ENV_RPROC_SETTINGS \
+ "dorprocboot=0\0" \
+ "boot_rprocs=" \
+ "if test ${dorprocboot} -eq 1 && test ${boot} = mmc; then "\
+ "rproc init;" \
+ "run boot_rprocs_mmc;" \
+ "fi;\0" \
+ "rproc_load_and_boot_one=" \
+ "if load mmc ${bootpart} $loadaddr ${rproc_fw}; then " \
+ "if rproc load ${rproc_id} ${loadaddr} ${filesize}; then "\
+ "rproc start ${rproc_id};" \
+ "fi;" \
+ "fi\0" \
+ "boot_rprocs_mmc=" \
+ "env set rproc_id;" \
+ "env set rproc_fw;" \
+ "for i in ${rproc_fw_binaries} ; do " \
+ "if test -z \"${rproc_id}\" ; then " \
+ "env set rproc_id $i;" \
+ "else " \
+ "env set rproc_fw $i;" \
+ "run rproc_load_and_boot_one;" \
+ "env set rproc_id;" \
+ "env set rproc_fw;" \
+ "fi;" \
+ "done\0" \
+ "rproc_fw_binaries=" \
+ DEFAULT_RPROCS \
+ "\0"
+#else
+#define EXTRA_ENV_RPROC_SETTINGS \
+ "boot_rprocs= \0"
+#endif /* CONFIG_CMD_REMOTEPROC */
+
+#endif /* __TI_RPROC_H */
diff --git a/include/remoteproc.h b/include/remoteproc.h
index 4987194905..046cd9e54e 100644
--- a/include/remoteproc.h
+++ b/include/remoteproc.h
@@ -122,9 +122,10 @@ struct dm_rproc_ops {
*
* @dev: Remote proc device
* @da: Device address
+ * @size: Size of the memory region @da is pointing to
* @return virtual address.
*/
- void * (*device_to_virt)(struct udevice *dev, ulong da);
+ void * (*device_to_virt)(struct udevice *dev, ulong da, ulong size);
};
/* Accessor */
@@ -214,12 +215,68 @@ int rproc_is_running(int id);
int rproc_elf32_sanity_check(ulong addr, ulong size);
/**
+ * rproc_elf64_sanity_check() - Verify if an image is a valid ELF32 one
+ *
+ * Check if a valid ELF64 image exists at the given memory location. Verify
+ * basic ELF64 format requirements like magic number and sections size.
+ *
+ * @addr: address of the image to verify
+ * @size: size of the image
+ * @return 0 if the image looks good, else appropriate error value.
+ */
+int rproc_elf64_sanity_check(ulong addr, ulong size);
+
+/**
+ * rproc_elf_sanity_check() - Verify if an image is a valid ELF one
+ *
+ * Check if a valid ELF image exists at the given memory location. Auto
+ * detects ELF32/ELF64 and verifies basic ELF64/ELF32 format requirements
+ * like magic number and sections size.
+ *
+ * @addr: address of the image to verify
+ * @size: size of the image
+ * @return 0 if the image looks good, else appropriate error value.
+ */
+int rproc_elf_sanity_check(ulong addr, ulong size);
+
+/**
* rproc_elf32_load_image() - load an ELF32 image
* @dev: device loading the ELF32 image
* @addr: valid ELF32 image address
+ * @size: size of the image
* @return 0 if the image is successfully loaded, else appropriate error value.
*/
-int rproc_elf32_load_image(struct udevice *dev, unsigned long addr);
+int rproc_elf32_load_image(struct udevice *dev, unsigned long addr, ulong size);
+
+/**
+ * rproc_elf64_load_image() - load an ELF64 image
+ * @dev: device loading the ELF64 image
+ * @addr: valid ELF64 image address
+ * @size: size of the image
+ * @return 0 if the image is successfully loaded, else appropriate error value.
+ */
+int rproc_elf64_load_image(struct udevice *dev, ulong addr, ulong size);
+
+/**
+ * rproc_elf_load_image() - load an ELF image
+ * @dev: device loading the ELF image
+ * @addr: valid ELF image address
+ * @size: size of the image
+ *
+ * Auto detects if the image is ELF32 or ELF64 image and load accordingly.
+ * @return 0 if the image is successfully loaded, else appropriate error value.
+ */
+int rproc_elf_load_image(struct udevice *dev, unsigned long addr, ulong size);
+
+/**
+ * rproc_elf_get_boot_addr() - Get rproc's boot address.
+ * @dev: device loading the ELF image
+ * @addr: valid ELF image address
+ *
+ * This function returns the entry point address of the ELF
+ * image.
+ */
+ulong rproc_elf_get_boot_addr(struct udevice *dev, ulong addr);
#else
static inline int rproc_init(void) { return -ENOSYS; }
static inline int rproc_dev_init(int id) { return -ENOSYS; }
@@ -232,8 +289,21 @@ static inline int rproc_ping(int id) { return -ENOSYS; }
static inline int rproc_is_running(int id) { return -ENOSYS; }
static inline int rproc_elf32_sanity_check(ulong addr,
ulong size) { return -ENOSYS; }
+static inline int rproc_elf64_sanity_check(ulong addr,
+ ulong size) { return -ENOSYS; }
+static inline int rproc_elf_sanity_check(ulong addr,
+ ulong size) { return -ENOSYS; }
static inline int rproc_elf32_load_image(struct udevice *dev,
- unsigned long addr) { return -ENOSYS; }
+ unsigned long addr, ulong size)
+{ return -ENOSYS; }
+static inline int rproc_elf64_load_image(struct udevice *dev, ulong addr,
+ ulong size)
+{ return -ENOSYS; }
+static inline int rproc_elf_load_image(struct udevice *dev, ulong addr,
+ ulong size)
+{ return -ENOSYS; }
+static inline ulong rproc_elf_get_boot_addr(struct udevice *dev, ulong addr)
+{ return 0; }
#endif
#endif /* _RPROC_H_ */
diff --git a/include/spl.h b/include/spl.h
index 4359636d87..b5387ef273 100644
--- a/include/spl.h
+++ b/include/spl.h
@@ -434,6 +434,9 @@ int spl_mmc_load(struct spl_image_info *spl_image,
int raw_part,
unsigned long raw_sect);
+int spl_ymodem_load_image(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev);
+
/**
* spl_invoke_atf - boot using an ARM trusted firmware image
*/
diff --git a/test/dm/bus.c b/test/dm/bus.c
index 93f3acd430..1ad45adb60 100644
--- a/test/dm/bus.c
+++ b/test/dm/bus.c
@@ -8,6 +8,7 @@
#include <os.h>
#endif
#include <dm.h>
+#include <dm/device.h>
#include <dm/device-internal.h>
#include <dm/test.h>
#include <dm/uclass-internal.h>
@@ -371,7 +372,6 @@ static int test_bus_parent_platdata(struct unit_test_state *uts)
{
struct dm_test_parent_platdata *plat;
struct udevice *bus, *dev;
- int child_count;
/* Check that the bus has no children */
ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus));
@@ -380,7 +380,7 @@ static int test_bus_parent_platdata(struct unit_test_state *uts)
ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
- for (device_find_first_child(bus, &dev), child_count = 0;
+ for (device_find_first_child(bus, &dev);
dev;
device_find_next_child(&dev)) {
/* Check that platform data is allocated */
@@ -399,22 +399,20 @@ static int test_bus_parent_platdata(struct unit_test_state *uts)
ut_asserteq_ptr(plat, dev_get_parent_platdata(dev));
ut_asserteq(1, plat->count);
ut_assertok(device_probe(dev));
- child_count++;
}
- ut_asserteq(3, child_count);
+ ut_asserteq(3, device_get_child_count(bus));
/* Removing the bus should also have no effect (it is still bound) */
device_remove(bus, DM_REMOVE_NORMAL);
- for (device_find_first_child(bus, &dev), child_count = 0;
+ for (device_find_first_child(bus, &dev);
dev;
device_find_next_child(&dev)) {
/* Check that platform data is allocated */
plat = dev_get_parent_platdata(dev);
ut_assert(plat != NULL);
ut_asserteq(1, plat->count);
- child_count++;
}
- ut_asserteq(3, child_count);
+ ut_asserteq(3, device_get_child_count(bus));
/* Unbind all the children */
do {
@@ -425,16 +423,15 @@ static int test_bus_parent_platdata(struct unit_test_state *uts)
/* Now the child platdata should be removed and re-added */
device_probe(bus);
- for (device_find_first_child(bus, &dev), child_count = 0;
+ for (device_find_first_child(bus, &dev);
dev;
device_find_next_child(&dev)) {
/* Check that platform data is allocated */
plat = dev_get_parent_platdata(dev);
ut_assert(plat != NULL);
ut_asserteq(0, plat->count);
- child_count++;
}
- ut_asserteq(3, child_count);
+ ut_asserteq(3, device_get_child_count(bus));
return 0;
}
@@ -480,19 +477,17 @@ static int dm_test_bus_child_post_bind(struct unit_test_state *uts)
{
struct dm_test_parent_platdata *plat;
struct udevice *bus, *dev;
- int child_count;
ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
- for (device_find_first_child(bus, &dev), child_count = 0;
+ for (device_find_first_child(bus, &dev);
dev;
device_find_next_child(&dev)) {
/* Check that platform data is allocated */
plat = dev_get_parent_platdata(dev);
ut_assert(plat != NULL);
ut_asserteq(1, plat->bind_flag);
- child_count++;
}
- ut_asserteq(3, child_count);
+ ut_asserteq(3, device_get_child_count(bus));
return 0;
}
@@ -503,19 +498,17 @@ static int dm_test_bus_child_post_bind_uclass(struct unit_test_state *uts)
{
struct dm_test_parent_platdata *plat;
struct udevice *bus, *dev;
- int child_count;
ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
- for (device_find_first_child(bus, &dev), child_count = 0;
+ for (device_find_first_child(bus, &dev);
dev;
device_find_next_child(&dev)) {
/* Check that platform data is allocated */
plat = dev_get_parent_platdata(dev);
ut_assert(plat != NULL);
ut_asserteq(2, plat->uclass_bind_flag);
- child_count++;
}
- ut_asserteq(3, child_count);
+ ut_asserteq(3, device_get_child_count(bus));
return 0;
}
@@ -529,14 +522,13 @@ DM_TEST(dm_test_bus_child_post_bind_uclass,
static int dm_test_bus_child_pre_probe_uclass(struct unit_test_state *uts)
{
struct udevice *bus, *dev;
- int child_count;
/*
* See testfdt_drv_probe() which effectively checks that the uclass
* flag is set before that method is called
*/
ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
- for (device_find_first_child(bus, &dev), child_count = 0;
+ for (device_find_first_child(bus, &dev);
dev;
device_find_next_child(&dev)) {
struct dm_test_priv *priv = dev_get_priv(dev);
@@ -549,9 +541,8 @@ static int dm_test_bus_child_pre_probe_uclass(struct unit_test_state *uts)
ut_assert(priv != NULL);
ut_asserteq(1, priv->uclass_flag);
ut_asserteq(1, priv->uclass_total);
- child_count++;
}
- ut_asserteq(3, child_count);
+ ut_asserteq(3, device_get_child_count(bus));
return 0;
}
@@ -565,14 +556,13 @@ DM_TEST(dm_test_bus_child_pre_probe_uclass,
static int dm_test_bus_child_post_probe_uclass(struct unit_test_state *uts)
{
struct udevice *bus, *dev;
- int child_count;
/*
* See testfdt_drv_probe() which effectively initializes that
* the uclass postp flag is set to a value
*/
ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
- for (device_find_first_child(bus, &dev), child_count = 0;
+ for (device_find_first_child(bus, &dev);
dev;
device_find_next_child(&dev)) {
struct dm_test_priv *priv = dev_get_priv(dev);
@@ -584,9 +574,8 @@ static int dm_test_bus_child_post_probe_uclass(struct unit_test_state *uts)
priv = dev_get_priv(dev);
ut_assert(priv != NULL);
ut_asserteq(0, priv->uclass_postp);
- child_count++;
}
- ut_asserteq(3, child_count);
+ ut_asserteq(3, device_get_child_count(bus));
return 0;
}
diff --git a/test/dm/remoteproc.c b/test/dm/remoteproc.c
index a2c4be7c27..1d9a9b32d5 100644
--- a/test/dm/remoteproc.c
+++ b/test/dm/remoteproc.c
@@ -171,12 +171,11 @@ static int dm_test_remoteproc_elf(struct unit_test_state *uts)
ut_assertnonnull(loaded_firmware);
memset(loaded_firmware, 0, loaded_firmware_size);
- /* Verify valid ELF format */
- ut_assertok(rproc_elf32_sanity_check((ulong)valid_elf32, size));
-
/* Load firmware in loaded_firmware, and verify it */
- ut_assertok(rproc_elf32_load_image(dev, (unsigned long)valid_elf32));
+ ut_assertok(rproc_elf32_load_image(dev, (ulong)valid_elf32, size));
ut_assertok(memcmp(loaded_firmware, valid_elf32, loaded_firmware_size));
+ ut_asserteq(rproc_elf_get_boot_addr(dev, (unsigned long)valid_elf32),
+ 0x08000000);
unmap_physmem(loaded_firmware, MAP_NOCACHE);
/* Invalid ELF Magic */