Преглед на файлове

Merge tag 'ti-v2020.07-next' of https://gitlab.denx.de/u-boot/custodians/u-boot-ti into next

K3 J721E:
* OSPI boot support
* Support for loading remote cores in R5 SPL
* PMIC ESM Support
* Minor fixes for R5F and C7x remoteproc drivers

K3 AM654:
* Update AVS class 0 voltages.
* Add I2C nodes

DRA7xx/AM57xx:
* Fixed Android boot on AM57xx

AM33/AM43/Davinci:
* switch to driver model for the net and mdio driver for baltos
* Add DM/DTS support for omap video driver
* Enable fastboot on am335x-evm
Tom Rini преди 4 години
родител
ревизия
2738f0edea
променени са 80 файла, в които са добавени 2332 реда и са изтрити 568 реда
  1. 2 0
      arch/arm/dts/am335x-brppt1-mmc.dts
  2. 2 0
      arch/arm/dts/am335x-brppt1-nand.dts
  3. 2 0
      arch/arm/dts/am335x-brppt1-spi.dts
  4. 1 0
      arch/arm/dts/am335x-brsmarc1.dts
  5. 2 0
      arch/arm/dts/am335x-brxre1.dts
  6. 6 0
      arch/arm/dts/am335x-evm-u-boot.dtsi
  7. 12 0
      arch/arm/dts/am335x-evmsk-u-boot.dtsi
  8. 4 0
      arch/arm/dts/am335x-guardian-u-boot.dtsi
  9. 4 0
      arch/arm/dts/am335x-pdu001-u-boot.dtsi
  10. 12 0
      arch/arm/dts/am335x-pxm50-u-boot.dtsi
  11. 12 0
      arch/arm/dts/am335x-rut-u-boot.dtsi
  12. 4 0
      arch/arm/dts/da850-evm-u-boot.dtsi
  13. 38 0
      arch/arm/dts/k3-am65-mcu.dtsi
  14. 11 2
      arch/arm/dts/k3-am65.dtsi
  15. 19 0
      arch/arm/dts/k3-am654-base-board-u-boot.dtsi
  16. 84 0
      arch/arm/dts/k3-am654-base-board.dts
  17. 39 0
      arch/arm/dts/k3-am654-r5-base-board.dts
  18. 28 0
      arch/arm/dts/k3-j721e-common-proc-board-u-boot.dtsi
  19. 33 0
      arch/arm/dts/k3-j721e-common-proc-board.dts
  20. 33 0
      arch/arm/dts/k3-j721e-mcu-wakeup.dtsi
  21. 34 0
      arch/arm/dts/k3-j721e-r5-common-proc-board-u-boot.dtsi
  22. 89 0
      arch/arm/dts/k3-j721e-r5-common-proc-board.dts
  23. 36 0
      arch/arm/dts/k3-j721e-som-p0.dtsi
  24. 3 0
      arch/arm/dts/k3-j721e.dtsi
  25. 0 64
      arch/arm/mach-imx/imx_bootaux.c
  26. 8 0
      arch/arm/mach-k3/Kconfig
  27. 5 4
      arch/arm/mach-k3/am6_init.c
  28. 14 1
      arch/arm/mach-k3/arm64-mmu.c
  29. 117 11
      arch/arm/mach-k3/common.c
  30. 3 0
      arch/arm/mach-k3/common.h
  31. 37 0
      arch/arm/mach-k3/j721e_init.c
  32. 3 1
      arch/arm/mach-k3/r5_mpu.c
  33. 30 19
      arch/arm/mach-k3/sysfw-loader.c
  34. 4 0
      arch/arm/mach-omap2/am33xx/clock_am33xx.c
  35. 1 1
      board/BuR/common/br_resetc.c
  36. 3 0
      board/BuR/common/bur_common.h
  37. 1 1
      board/BuR/common/common.c
  38. 57 2
      board/ti/am65x/README
  39. 49 2
      board/ti/j721e/README
  40. 26 0
      board/ti/j721e/evm.c
  41. 1 0
      cmd/Kconfig
  42. 0 229
      cmd/elf.c
  43. 2 0
      configs/am335x_baltos_defconfig
  44. 4 0
      configs/am335x_evm_defconfig
  45. 25 0
      configs/am65x_evm_a53_defconfig
  46. 17 0
      configs/am65x_evm_r5_defconfig
  47. 71 4
      configs/am65x_hs_evm_a53_defconfig
  48. 24 0
      configs/am65x_hs_evm_r5_defconfig
  49. 8 1
      configs/j721e_evm_a72_defconfig
  50. 12 3
      configs/j721e_evm_r5_defconfig
  51. 7 1
      configs/j721e_hs_evm_a72_defconfig
  52. 7 0
      configs/j721e_hs_evm_r5_defconfig
  53. 25 0
      doc/device-tree-bindings/misc/esm-k3.txt
  54. 19 0
      doc/device-tree-bindings/misc/esm-pmic.txt
  55. 66 0
      doc/device-tree-bindings/video/tilcdc/panel.txt
  56. 82 0
      doc/device-tree-bindings/video/tilcdc/tilcdc.txt
  57. 2 1
      drivers/Makefile
  58. 3 4
      drivers/dma/ti/k3-udma.c
  59. 0 77
      drivers/firmware/ti_sci.c
  60. 0 5
      drivers/firmware/ti_sci.h
  61. 12 0
      drivers/misc/Kconfig
  62. 2 0
      drivers/misc/Makefile
  63. 69 0
      drivers/misc/esm_pmic.c
  64. 6 6
      drivers/misc/k3_avs.c
  65. 87 0
      drivers/misc/k3_esm.c
  66. 2 2
      drivers/power/pmic/tps65941.c
  67. 115 13
      drivers/remoteproc/ti_k3_dsp_rproc.c
  68. 6 3
      drivers/remoteproc/ti_k3_r5f_rproc.c
  69. 6 0
      drivers/video/Kconfig
  70. 475 92
      drivers/video/am335x-fb.c
  71. 10 6
      drivers/video/am335x-fb.h
  72. 20 1
      include/configs/am65x_evm.h
  73. 2 0
      include/configs/brxre1.h
  74. 16 2
      include/configs/j721e_evm.h
  75. 4 0
      include/elf.h
  76. 4 4
      include/environment/ti/boot.h
  77. 0 6
      include/linux/soc/ti/ti_sci_protocol.h
  78. 6 0
      lib/Kconfig
  79. 1 0
      lib/Makefile
  80. 246 0
      lib/elf.c

+ 2 - 0
arch/arm/dts/am335x-brppt1-mmc.dts

@@ -53,6 +53,8 @@
 		bkl-pwm = <&pwmbacklight>;
 		bkl-tps = <&tps_bl>;
 
+		u-boot,dm-pre-reloc;
+
 		panel-info {
 			ac-bias		= <255>;
 			ac-bias-intrpt	= <0>;

+ 2 - 0
arch/arm/dts/am335x-brppt1-nand.dts

@@ -53,6 +53,8 @@
 		bkl-pwm = <&pwmbacklight>;
 		bkl-tps = <&tps_bl>;
 
+		u-boot,dm-pre-reloc;
+
 		panel-info {
 			ac-bias		= <255>;
 			ac-bias-intrpt	= <0>;

+ 2 - 0
arch/arm/dts/am335x-brppt1-spi.dts

@@ -54,6 +54,8 @@
 		bkl-pwm = <&pwmbacklight>;
 		bkl-tps = <&tps_bl>;
 
+		u-boot,dm-pre-reloc;
+
 		panel-info {
 			ac-bias		= <255>;
 			ac-bias-intrpt	= <0>;

+ 1 - 0
arch/arm/dts/am335x-brsmarc1.dts

@@ -59,6 +59,7 @@
 		/*backlight = <&tps_bl>; */
 		compatible = "ti,tilcdc,panel";
 		status = "okay";
+		u-boot,dm-pre-reloc;
 
 		panel-info {
 			ac-bias		= <255>;

+ 2 - 0
arch/arm/dts/am335x-brxre1.dts

@@ -79,6 +79,8 @@
 
 		backlight = <&tps_bl>;
 
+		u-boot,dm-pre-reloc;
+
 		panel-info {
 			ac-bias		= <255>;
 			ac-bias-intrpt	= <0>;

+ 6 - 0
arch/arm/dts/am335x-evm-u-boot.dtsi

@@ -3,6 +3,12 @@
  * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/
  */
 
+/ {
+	panel {
+		u-boot,dm-pre-reloc;
+	};
+};
+
 
 &mmc3 {
 	status = "disabled";

+ 12 - 0
arch/arm/dts/am335x-evmsk-u-boot.dtsi

@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * am335x-evmsk U-Boot Additions
+ *
+ * Copyright (C) 2020 Dario Binacchi <dariobin@libero.it>
+ */
+
+/ {
+	panel {
+		u-boot,dm-pre-reloc;
+	};
+};

+ 4 - 0
arch/arm/dts/am335x-guardian-u-boot.dtsi

@@ -8,6 +8,10 @@
 	ocp {
 		u-boot,dm-pre-reloc;
 	};
+
+	panel {
+		u-boot,dm-pre-reloc;
+	};
 };
 
 &l4_wkup {

+ 4 - 0
arch/arm/dts/am335x-pdu001-u-boot.dtsi

@@ -7,6 +7,10 @@
 	ocp {
 		u-boot,dm-pre-reloc;
 	};
+
+	panel {
+		u-boot,dm-pre-reloc;
+	};
 };
 
 &l4_wkup {

+ 12 - 0
arch/arm/dts/am335x-pxm50-u-boot.dtsi

@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * am335x-pxm50 U-Boot Additions
+ *
+ * Copyright (C) 2020 Dario Binacchi <dariobin@libero.it>
+ */
+
+/ {
+	panel {
+		u-boot,dm-pre-reloc;
+	};
+};

+ 12 - 0
arch/arm/dts/am335x-rut-u-boot.dtsi

@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * am335x-rut U-Boot Additions
+ *
+ * Copyright (C) 2020 Dario Binacchi <dariobin@libero.it>
+ */
+
+/ {
+	panel {
+		u-boot,dm-pre-reloc;
+	};
+};

+ 4 - 0
arch/arm/dts/da850-evm-u-boot.dtsi

@@ -14,6 +14,10 @@
 	nand {
 		compatible = "ti,davinci-nand";
 	};
+
+	panel {
+		u-boot,dm-pre-reloc;
+	};
 };
 
 &eth0 {

+ 38 - 0
arch/arm/dts/k3-am65-mcu.dtsi

@@ -64,4 +64,42 @@
 			loczrama = <1>;
 		};
 	};
+
+	fss: fss@47000000 {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		ospi0: spi@47040000 {
+			compatible = "ti,am654-ospi", "cdns,qspi-nor";
+			reg = <0x0 0x47040000 0x0 0x100>,
+				<0x5 0x00000000 0x1 0x0000000>;
+			interrupts = <GIC_SPI 552 IRQ_TYPE_LEVEL_HIGH>;
+			cdns,fifo-depth = <256>;
+			cdns,fifo-width = <4>;
+			cdns,trigger-address = <0x0>;
+			clocks = <&k3_clks 248 0>;
+			assigned-clocks = <&k3_clks 248 0>;
+			assigned-clock-parents = <&k3_clks 248 2>;
+			assigned-clock-rates = <166666666>;
+			power-domains = <&k3_pds 248 TI_SCI_PD_EXCLUSIVE>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		ospi1: spi@47050000 {
+			compatible = "ti,am654-ospi", "cdns,qspi-nor";
+			reg = <0x0 0x47050000 0x0 0x100>,
+				<0x7 0x00000000 0x1 0x00000000>;
+			interrupts = <GIC_SPI 553 IRQ_TYPE_LEVEL_HIGH>;
+			cdns,fifo-depth = <256>;
+			cdns,fifo-width = <4>;
+			cdns,trigger-address = <0x0>;
+			clocks = <&k3_clks 249 6>;
+			power-domains = <&k3_pds 249 TI_SCI_PD_EXCLUSIVE>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
 };

+ 11 - 2
arch/arm/dts/k3-am65.dtsi

@@ -30,6 +30,8 @@
 		i2c3 = &main_i2c1;
 		i2c4 = &main_i2c2;
 		i2c5 = &main_i2c3;
+		spi0 = &ospi0;
+		spi1 = &ospi1;
 	};
 
 	chosen { };
@@ -79,7 +81,11 @@
 			 <0x00 0x42040000 0x00 0x42040000 0x00 0x03ac2400>,
 			 <0x00 0x45100000 0x00 0x45100000 0x00 0x00c24000>,
 			 <0x00 0x46000000 0x00 0x46000000 0x00 0x00200000>,
-			 <0x00 0x47000000 0x00 0x47000000 0x00 0x00068400>;
+			 <0x00 0x47000000 0x00 0x47000000 0x00 0x00068400>,
+			 <0x00 0x50000000 0x00 0x50000000 0x00 0x8000000>,
+			 <0x00 0x70000000 0x00 0x70000000 0x00 0x200000>,
+			 <0x05 0x00000000 0x05 0x00000000 0x01 0x0000000>,
+			 <0x07 0x00000000 0x07 0x00000000 0x01 0x0000000>;
 
 		cbass_mcu: interconnect@28380000 {
 			compatible = "simple-bus";
@@ -93,7 +99,10 @@
 				 <0x00 0x42040000 0x00 0x42040000 0x00 0x03ac2400>, /* WKUP */
 				 <0x00 0x45100000 0x00 0x45100000 0x00 0x00c24000>, /* MMRs, remaining NAVSS */
 				 <0x00 0x46000000 0x00 0x46000000 0x00 0x00200000>, /* CPSW */
-				 <0x00 0x47000000 0x00 0x47000000 0x00 0x00068400>; /* OSPI space 1 */
+				 <0x00 0x47000000 0x00 0x47000000 0x00 0x00068400>, /* OSPI space 1 */
+				 <0x00 0x50000000 0x00 0x50000000 0x00 0x8000000>, /*  FSS OSPI0 data region 1 */
+				 <0x05 0x00000000 0x05 0x00000000 0x01 0x0000000>, /* FSS OSPI0 data region 3*/
+				 <0x07 0x00000000 0x07 0x00000000 0x01 0x0000000>; /* FSS OSPI1 data region 3*/
 
 			cbass_wakeup: interconnect@42040000 {
 				compatible = "simple-bus";

+ 19 - 0
arch/arm/dts/k3-am654-base-board-u-boot.dtsi

@@ -52,6 +52,7 @@
 		#address-cells = <2>;
 		#size-cells = <2>;
 		ranges;
+		u-boot,dm-spl;
 
 		ti,sci-dev-id = <119>;
 
@@ -68,6 +69,7 @@
 			ti,dma-ring-reset-quirk;
 			ti,sci = <&dmsc>;
 			ti,sci-dev-id = <195>;
+			u-boot,dm-spl;
 		};
 
 		mcu_udmap: udmap@285c0000 {
@@ -90,6 +92,7 @@
 						<0x4>; /* RX_CHAN */
 			ti,sci-rm-range-rflow = <0x5>; /* GP RFLOW */
 			dma-coherent;
+			u-boot,dm-spl;
 		};
 	};
 
@@ -314,6 +317,10 @@
 			AM65X_WKUP_IOPAD(0x0088, PIN_INPUT, 0) /* (L4) MCU_MDIO0_MDIO */
 		>;
 	};
+
+	mcu-fss0-ospi0-pins-default {
+		u-boot,dm-spl;
+	};
 };
 
 &main_uart0 {
@@ -374,3 +381,15 @@
 &usb1 {
 	dr_mode = "peripheral";
 };
+
+&fss {
+	u-boot,dm-spl;
+};
+
+&ospi0 {
+	u-boot,dm-spl;
+
+	 flash@0{
+		u-boot,dm-spl;
+	};
+};

+ 84 - 0
arch/arm/dts/k3-am654-base-board.dts

@@ -64,6 +64,29 @@
 			AM65X_IOPAD(0x02c0, PIN_OUTPUT, 0) /* (AC8) USB1_DRVVBUS */
 		>;
 	};
+
+	main_i2c2_pins_default: main-i2c2-pins-default {
+		pinctrl-single,pins = <
+			AM65X_IOPAD(0x0074, PIN_INPUT, 5) /* (T27) GPMC0_CSn3.I2C2_SCL */
+			AM65X_IOPAD(0x0070, PIN_INPUT, 5) /* (R25) GPMC0_CSn2.I2C2_SDA */
+		>;
+	};
+};
+
+&main_pmx1 {
+	main_i2c0_pins_default: main-i2c0-pins-default {
+		pinctrl-single,pins = <
+			AM65X_IOPAD(0x0000, PIN_INPUT, 0) /* (D20) I2C0_SCL */
+			AM65X_IOPAD(0x0004, PIN_INPUT, 0) /* (C21) I2C0_SDA */
+		>;
+	};
+
+	main_i2c1_pins_default: main-i2c1-pins-default {
+		pinctrl-single,pins = <
+			AM65X_IOPAD(0x0008, PIN_INPUT, 0) /* (B21) I2C1_SCL */
+			AM65X_IOPAD(0x000c, PIN_INPUT, 0) /* (E21) I2C1_SDA */
+		>;
+	};
 };
 
 &wkup_pmx0 {
@@ -73,6 +96,22 @@
 			AM65X_WKUP_IOPAD(0x00e4, PIN_INPUT, 0) /* (AD6) WKUP_I2C0_SDA */
 		>;
 	};
+
+	mcu_fss0_ospi0_pins_default: mcu-fss0-ospi0-pins_default {
+		pinctrl-single,pins = <
+			AM65X_WKUP_IOPAD(0x0000, PIN_OUTPUT, 0) /* (V1) MCU_OSPI0_CLK */
+			AM65X_WKUP_IOPAD(0x0008, PIN_INPUT, 0)	 /* (U2) MCU_OSPI0_DQS */
+			AM65X_WKUP_IOPAD(0x000c, PIN_INPUT, 0)  /* (U4) MCU_OSPI0_D0 */
+			AM65X_WKUP_IOPAD(0x0010, PIN_INPUT, 0)  /* (U5) MCU_OSPI0_D1 */
+			AM65X_WKUP_IOPAD(0x0014, PIN_INPUT, 0)  /* (T2) MCU_OSPI0_D2 */
+			AM65X_WKUP_IOPAD(0x0018, PIN_INPUT, 0)  /* (T3) MCU_OSPI0_D3 */
+			AM65X_WKUP_IOPAD(0x001c, PIN_INPUT, 0)  /* (T4) MCU_OSPI0_D4 */
+			AM65X_WKUP_IOPAD(0x0020, PIN_INPUT, 0)  /* (T5) MCU_OSPI0_D5 */
+			AM65X_WKUP_IOPAD(0x0024, PIN_INPUT, 0)  /* (R2) MCU_OSPI0_D6 */
+			AM65X_WKUP_IOPAD(0x0028, PIN_INPUT, 0)  /* (R3) MCU_OSPI0_D7 */
+			AM65X_WKUP_IOPAD(0x002c, PIN_OUTPUT, 0) /* (R4) MCU_OSPI0_CSn0 */
+		>;
+	};
 };
 
 &sdhci0 {
@@ -96,6 +135,31 @@
 	};
 };
 
+&main_i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c0_pins_default>;
+	clock-frequency = <400000>;
+
+	pca9555: gpio@21 {
+		compatible = "nxp,pca9555";
+		reg = <0x21>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+};
+
+&main_i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c1_pins_default>;
+	clock-frequency = <400000>;
+};
+
+&main_i2c2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_i2c2_pins_default>;
+	clock-frequency = <400000>;
+};
+
 &dwc3_1 {
 	status = "okay";
 };
@@ -117,3 +181,23 @@
 &usb0_phy {
 	status = "disabled";
 };
+
+&ospi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_fss0_ospi0_pins_default>;
+
+	flash@0{
+		compatible = "jedec,spi-nor";
+		reg = <0x0>;
+		spi-tx-bus-width = <1>;
+		spi-rx-bus-width = <8>;
+		spi-max-frequency = <40000000>;
+		cdns,tshsl-ns = <60>;
+		cdns,tsd2d-ns = <60>;
+		cdns,tchsh-ns = <60>;
+		cdns,tslch-ns = <60>;
+		cdns,read-delay = <0>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+	};
+};

+ 39 - 0
arch/arm/dts/k3-am654-r5-base-board.dts

@@ -179,6 +179,22 @@
 			AM65X_WKUP_IOPAD(0x00e4, PIN_INPUT, 0) /* (AD6) WKUP_I2C0_SDA */
 		>;
 	};
+
+	mcu_fss0_ospi0_pins_default: mcu-fss0-ospi0-pins_default {
+		pinctrl-single,pins = <
+			AM65X_WKUP_IOPAD(0x0000, PIN_OUTPUT, 0) /* (V1) MCU_OSPI0_CLK */
+			AM65X_WKUP_IOPAD(0x0008, PIN_INPUT, 0)	 /* (U2) MCU_OSPI0_DQS */
+			AM65X_WKUP_IOPAD(0x000c, PIN_INPUT, 0)  /* (U4) MCU_OSPI0_D0 */
+			AM65X_WKUP_IOPAD(0x0010, PIN_INPUT, 0)  /* (U5) MCU_OSPI0_D1 */
+			AM65X_WKUP_IOPAD(0x0014, PIN_INPUT, 0)  /* (T2) MCU_OSPI0_D2 */
+			AM65X_WKUP_IOPAD(0x0018, PIN_INPUT, 0)  /* (T3) MCU_OSPI0_D3 */
+			AM65X_WKUP_IOPAD(0x001c, PIN_INPUT, 0)  /* (T4) MCU_OSPI0_D4 */
+			AM65X_WKUP_IOPAD(0x0020, PIN_INPUT, 0)  /* (T5) MCU_OSPI0_D5 */
+			AM65X_WKUP_IOPAD(0x0024, PIN_INPUT, 0)  /* (R2) MCU_OSPI0_D6 */
+			AM65X_WKUP_IOPAD(0x0028, PIN_INPUT, 0)  /* (R3) MCU_OSPI0_D7 */
+			AM65X_WKUP_IOPAD(0x002c, PIN_OUTPUT, 0) /* (R4) MCU_OSPI0_CSn0 */
+		>;
+	};
 };
 
 &main_pmx0 {
@@ -239,3 +255,26 @@
 		u-boot,dm-spl;
 	};
 };
+
+&ospi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_fss0_ospi0_pins_default>;
+
+	reg = <0x0 0x47040000 0x0 0x100>,
+	      <0x0 0x50000000 0x0 0x8000000>;
+
+	flash@0{
+		compatible = "jedec,spi-nor";
+		reg = <0x0>;
+		spi-tx-bus-width = <1>;
+		spi-rx-bus-width = <8>;
+		spi-max-frequency = <40000000>;
+		cdns,tshsl-ns = <60>;
+		cdns,tsd2d-ns = <60>;
+		cdns,tchsh-ns = <60>;
+		cdns,tslch-ns = <60>;
+		cdns,read-delay = <0>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+	};
+};

+ 28 - 0
arch/arm/dts/k3-j721e-common-proc-board-u-boot.dtsi

@@ -349,3 +349,31 @@
 &exp2 {
 	u-boot,dm-spl;
 };
+
+&mcu_fss0_ospi0_pins_default {
+	u-boot,dm-spl;
+};
+
+&fss {
+	u-boot,dm-spl;
+};
+
+&ospi0 {
+	u-boot,dm-spl;
+
+	flash@0 {
+		u-boot,dm-spl;
+	};
+};
+
+&ospi1 {
+	u-boot,dm-spl;
+
+	flash@0 {
+		u-boot,dm-spl;
+	};
+};
+
+&mcu_fss0_ospi1_pins_default {
+	u-boot,dm-spl;
+};

+ 33 - 0
arch/arm/dts/k3-j721e-common-proc-board.dts

@@ -123,6 +123,19 @@
 			J721E_WKUP_IOPAD(0xfc, PIN_INPUT_PULLUP, 0) /* (H24) WKUP_I2C0_SDA */
 		>;
 	};
+
+	mcu_fss0_ospi1_pins_default: mcu-fss0-ospi1-pins-default {
+		pinctrl-single,pins = <
+			J721E_WKUP_IOPAD(0x34, PIN_OUTPUT, 0) /* (F22) MCU_OSPI1_CLK */
+			J721E_WKUP_IOPAD(0x50, PIN_OUTPUT, 0) /* (C22) MCU_OSPI1_CSn0 */
+			J721E_WKUP_IOPAD(0x40, PIN_INPUT, 0) /* (D22) MCU_OSPI1_D0 */
+			J721E_WKUP_IOPAD(0x44, PIN_INPUT, 0) /* (G22) MCU_OSPI1_D1 */
+			J721E_WKUP_IOPAD(0x48, PIN_INPUT, 0) /* (D23) MCU_OSPI1_D2 */
+			J721E_WKUP_IOPAD(0x4c, PIN_INPUT, 0) /* (C23) MCU_OSPI1_D3 */
+			J721E_WKUP_IOPAD(0x3c, PIN_INPUT, 0) /* (B23) MCU_OSPI1_DQS */
+			J721E_WKUP_IOPAD(0x38, PIN_INPUT, 0) /* (A23) MCU_OSPI1_LBCLKO */
+		>;
+	};
 };
 
 &usbss0 {
@@ -172,3 +185,23 @@
 		#gpio-cells = <2>;
 	};
 };
+
+&ospi1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_fss0_ospi1_pins_default>;
+
+	flash@0{
+		compatible = "jedec,spi-nor";
+		reg = <0x0>;
+		spi-tx-bus-width = <1>;
+		spi-rx-bus-width = <4>;
+		spi-max-frequency = <40000000>;
+		cdns,tshsl-ns = <60>;
+		cdns,tsd2d-ns = <60>;
+		cdns,tchsh-ns = <60>;
+		cdns,tslch-ns = <60>;
+		cdns,read-delay = <2>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+	};
+};

+ 33 - 0
arch/arm/dts/k3-j721e-mcu-wakeup.dtsi

@@ -143,6 +143,39 @@
 			assigned-clocks = <&k3_clks 102 0>;
 			assigned-clock-rates = <250000000>;
 		};
+
+		ospi0: spi@47040000 {
+			compatible = "ti,am654-ospi";
+			reg = <0x0 0x47040000 0x0 0x100>,
+				<0x5 0x00000000 0x1 0x0000000>;
+			interrupts = <GIC_SPI 840 IRQ_TYPE_LEVEL_HIGH>;
+			cdns,fifo-depth = <256>;
+			cdns,fifo-width = <4>;
+			cdns,trigger-address = <0x0>;
+			clocks = <&k3_clks 103 0>;
+			assigned-clocks = <&k3_clks 103 0>;
+			assigned-clock-parents = <&k3_clks 103 2>;
+			assigned-clock-rates = <166666666>;
+			power-domains = <&k3_pds 103 TI_SCI_PD_EXCLUSIVE>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		ospi1: spi@47050000 {
+			compatible = "ti,am654-ospi";
+			reg = <0x0 0x47050000 0x0 0x100>,
+				<0x7 0x00000000 0x1 0x00000000>;
+			interrupts = <GIC_SPI 841 IRQ_TYPE_LEVEL_HIGH>;
+			cdns,fifo-depth = <256>;
+			cdns,fifo-width = <4>;
+			cdns,trigger-address = <0x0>;
+			clocks = <&k3_clks 104 0>;
+			assigned-clocks = <&k3_clks 104 0>;
+			assigned-clock-rates = <133333333>;
+			power-domains = <&k3_pds 104 TI_SCI_PD_EXCLUSIVE>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
 	};
 
 	mcu_i2c0: i2c@40b00000 {

+ 34 - 0
arch/arm/dts/k3-j721e-r5-common-proc-board-u-boot.dtsi

@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/ {
+	chosen {
+		firmware-loader = &fs_loader0;
+	};
+
+	fs_loader0: fs_loader@0 {
+		u-boot,dm-pre-reloc;
+		compatible = "u-boot,fs-loader";
+	};
+};
+
+&main_r5fss0 {
+	u-boot,dm-spl;
+};
+
+&main_r5fss0_core0 {
+	u-boot,dm-spl;
+};
+
+&main_r5fss0_core1 {
+	u-boot,dm-spl;
+};
+
+&tps659413a {
+	esm: esm {
+		compatible = "ti,tps659413-esm";
+		u-boot,dm-spl;
+	};
+};

+ 89 - 0
arch/arm/dts/k3-j721e-r5-common-proc-board.dts

@@ -13,6 +13,8 @@
 	aliases {
 		remoteproc0 = &sysctrler;
 		remoteproc1 = &a72_0;
+		remoteproc2 = &main_r5fss0_core0;
+		remoteproc3 = &main_r5fss0_core1;
 	};
 
 	chosen {
@@ -75,6 +77,15 @@
 	};
 };
 
+&cbass_main {
+	main_esm: esm@700000 {
+		compatible = "ti,j721e-esm";
+		reg = <0x0 0x700000 0x0 0x1000>;
+		ti,esm-pins = <344>, <345>;
+		u-boot,dm-spl;
+	};
+};
+
 &dmsc {
 	mboxes= <&mcu_secproxy 8>, <&mcu_secproxy 6>, <&mcu_secproxy 5>;
 	mbox-names = "tx", "rx", "notify";
@@ -107,6 +118,36 @@
 			J721E_WKUP_IOPAD(0xfc, PIN_INPUT_PULLUP, 0) /* (H24) WKUP_I2C0_SDA */
 		>;
 	};
+
+	mcu_fss0_ospi0_pins_default: mcu-fss0-ospi0-pins-default {
+		pinctrl-single,pins = <
+			J721E_WKUP_IOPAD(0x0000, PIN_OUTPUT, 0) /* MCU_OSPI0_CLK */
+			J721E_WKUP_IOPAD(0x0008, PIN_INPUT, 0)  /* MCU_OSPI0_DQS */
+			J721E_WKUP_IOPAD(0x000c, PIN_INPUT, 0)  /* MCU_OSPI0_D0 */
+			J721E_WKUP_IOPAD(0x0010, PIN_INPUT, 0)  /* MCU_OSPI0_D1 */
+			J721E_WKUP_IOPAD(0x0014, PIN_INPUT, 0)  /* MCU_OSPI0_D2 */
+			J721E_WKUP_IOPAD(0x0018, PIN_INPUT, 0)  /* MCU_OSPI0_D3 */
+			J721E_WKUP_IOPAD(0x001c, PIN_INPUT, 0)  /* MCU_OSPI0_D4 */
+			J721E_WKUP_IOPAD(0x0020, PIN_INPUT, 0)  /* MCU_OSPI0_D5 */
+			J721E_WKUP_IOPAD(0x0024, PIN_INPUT, 0)  /* MCU_OSPI0_D6 */
+			J721E_WKUP_IOPAD(0x0028, PIN_INPUT, 0)  /* MCU_OSPI0_D7 */
+			J721E_WKUP_IOPAD(0x002c, PIN_OUTPUT, 0) /* MCU_OSPI0_CSn0 */
+		>;
+	};
+
+	mcu_fss0_ospi1_pins_default: mcu-fss0-ospi1-pins-default {
+		u-boot,dm-spl;
+		pinctrl-single,pins = <
+			J721E_WKUP_IOPAD(0x34, PIN_OUTPUT, 0) /* (F22) MCU_OSPI1_CLK */
+			J721E_WKUP_IOPAD(0x50, PIN_OUTPUT, 0) /* (C22) MCU_OSPI1_CSn0 */
+			J721E_WKUP_IOPAD(0x40, PIN_INPUT, 0) /* (D22) MCU_OSPI1_D0 */
+			J721E_WKUP_IOPAD(0x44, PIN_INPUT, 0) /* (G22) MCU_OSPI1_D1 */
+			J721E_WKUP_IOPAD(0x48, PIN_INPUT, 0) /* (D23) MCU_OSPI1_D2 */
+			J721E_WKUP_IOPAD(0x4c, PIN_INPUT, 0) /* (C23) MCU_OSPI1_D3 */
+			J721E_WKUP_IOPAD(0x3c, PIN_INPUT, 0) /* (B23) MCU_OSPI1_DQS */
+			J721E_WKUP_IOPAD(0x38, PIN_INPUT, 0) /* (A23) MCU_OSPI1_LBCLKO */
+		>;
+	};
 };
 
 &main_pmx0 {
@@ -256,4 +297,52 @@
 	};
 };
 
+&ospi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_fss0_ospi0_pins_default>;
+
+	reg = <0x0 0x47040000 0x0 0x100>,
+	      <0x0 0x50000000 0x0 0x8000000>;
+
+	flash@0{
+		compatible = "jedec,spi-nor";
+		reg = <0x0>;
+		spi-tx-bus-width = <1>;
+		spi-rx-bus-width = <8>;
+		spi-max-frequency = <40000000>;
+		cdns,tshsl-ns = <60>;
+		cdns,tsd2d-ns = <60>;
+		cdns,tchsh-ns = <60>;
+		cdns,tslch-ns = <60>;
+		cdns,read-delay = <0>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+	};
+};
+
+&ospi1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_fss0_ospi1_pins_default>;
+	u-boot,dm-spl;
+
+	reg = <0x0 0x47050000 0x0 0x100>,
+	      <0x0 0x58000000 0x0 0x8000000>;
+
+	flash@0{
+		compatible = "jedec,spi-nor";
+		reg = <0x0>;
+		spi-tx-bus-width = <1>;
+		spi-rx-bus-width = <4>;
+		spi-max-frequency = <40000000>;
+		cdns,tshsl-ns = <60>;
+		cdns,tsd2d-ns = <60>;
+		cdns,tchsh-ns = <60>;
+		cdns,tslch-ns = <60>;
+		cdns,read-delay = <2>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		u-boot,dm-spl;
+	};
+};
+
 #include "k3-j721e-common-proc-board-u-boot.dtsi"

+ 36 - 0
arch/arm/dts/k3-j721e-som-p0.dtsi

@@ -47,6 +47,22 @@
 			J721E_WKUP_IOPAD(0x28, PIN_INPUT, 1) /* (G21) MCU_OSPI0_D7.MCU_HYPERBUS0_DQ7 */
 		>;
 	};
+
+	mcu_fss0_ospi0_pins_default: mcu-fss0-ospi0-pins-default {
+		pinctrl-single,pins = <
+			J721E_WKUP_IOPAD(0x0000, PIN_OUTPUT, 0) /* MCU_OSPI0_CLK */
+			J721E_WKUP_IOPAD(0x0008, PIN_INPUT, 0)  /* MCU_OSPI0_DQS */
+			J721E_WKUP_IOPAD(0x000c, PIN_INPUT, 0)  /* MCU_OSPI0_D0 */
+			J721E_WKUP_IOPAD(0x0010, PIN_INPUT, 0)  /* MCU_OSPI0_D1 */
+			J721E_WKUP_IOPAD(0x0014, PIN_INPUT, 0)  /* MCU_OSPI0_D2 */
+			J721E_WKUP_IOPAD(0x0018, PIN_INPUT, 0)  /* MCU_OSPI0_D3 */
+			J721E_WKUP_IOPAD(0x001c, PIN_INPUT, 0)  /* MCU_OSPI0_D4 */
+			J721E_WKUP_IOPAD(0x0020, PIN_INPUT, 0)  /* MCU_OSPI0_D5 */
+			J721E_WKUP_IOPAD(0x0024, PIN_INPUT, 0)  /* MCU_OSPI0_D6 */
+			J721E_WKUP_IOPAD(0x0028, PIN_INPUT, 0)  /* MCU_OSPI0_D7 */
+			J721E_WKUP_IOPAD(0x002c, PIN_OUTPUT, 0) /* MCU_OSPI0_CSn0 */
+		>;
+	};
 };
 
 &hbmc {
@@ -61,3 +77,23 @@
 		reg = <0x0 0x0 0x4000000>;
 	};
 };
+
+&ospi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcu_fss0_ospi0_pins_default>;
+
+	flash@0{
+		compatible = "jedec,spi-nor";
+		reg = <0x0>;
+		spi-tx-bus-width = <1>;
+		spi-rx-bus-width = <8>;
+		spi-max-frequency = <40000000>;
+		cdns,tshsl-ns = <60>;
+		cdns,tsd2d-ns = <60>;
+		cdns,tchsh-ns = <60>;
+		cdns,tslch-ns = <60>;
+		cdns,read-delay = <0>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+	};
+};

+ 3 - 0
arch/arm/dts/k3-j721e.dtsi

@@ -40,6 +40,8 @@
 		i2c7 = &main_i2c4;
 		i2c8 = &main_i2c5;
 		i2c9 = &main_i2c6;
+		spi0 = &ospi0;
+		spi1 = &ospi1;
 	};
 
 	chosen { };
@@ -135,6 +137,7 @@
 		#size-cells = <2>;
 		ranges = <0x00 0x00100000 0x00 0x00100000 0x00 0x00020000>, /* ctrl mmr */
 			 <0x00 0x00600000 0x00 0x00600000 0x00 0x00031100>, /* GPIO */
+			 <0x00 0x00700000 0x00 0x00700000 0x00 0x00001000>, /* ESM */
 			 <0x00 0x00900000 0x00 0x00900000 0x00 0x00012000>, /* serdes */
 			 <0x00 0x00A40000 0x00 0x00A40000 0x00 0x00000800>, /* timesync router */
 			 <0x00 0x01000000 0x00 0x01000000 0x00 0x0af02400>, /* Most peripherals */

+ 0 - 64
arch/arm/mach-imx/imx_bootaux.c

@@ -12,70 +12,6 @@
 #include <linux/compiler.h>
 #include <cpu_func.h>
 
-#ifndef CONFIG_IMX8M
-const __weak struct rproc_att hostmap[] = { };
-
-static const struct rproc_att *get_host_mapping(unsigned long auxcore)
-{
-	const struct rproc_att *mmap = hostmap;
-
-	while (mmap && mmap->size) {
-		if (mmap->da <= auxcore &&
-		    mmap->da + mmap->size > auxcore)
-			return mmap;
-		mmap++;
-	}
-
-	return NULL;
-}
-
-/*
- * A very simple elf loader, assumes the image is valid, returns the
- * entry point address.
- */
-static unsigned long load_elf_image_phdr(unsigned long addr)
-{
-	Elf32_Ehdr *ehdr; /* ELF header structure pointer */
-	Elf32_Phdr *phdr; /* Program header structure pointer */
-	int i;
-
-	ehdr = (Elf32_Ehdr *)addr;
-	phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff);
-
-	/* Load each program header */
-	for (i = 0; i < ehdr->e_phnum; ++i, ++phdr) {
-		const struct rproc_att *mmap = get_host_mapping(phdr->p_paddr);
-		void *dst, *src;
-
-		if (phdr->p_type != PT_LOAD)
-			continue;
-
-		if (!mmap) {
-			printf("Invalid aux core address: %08x",
-			       phdr->p_paddr);
-			return 0;
-		}
-
-		dst = (void *)(phdr->p_paddr - mmap->da) + mmap->sa;
-		src = (void *)addr + phdr->p_offset;
-
-		debug("Loading phdr %i to 0x%p (%i bytes)\n",
-		      i, dst, phdr->p_filesz);
-
-		if (phdr->p_filesz)
-			memcpy(dst, src, phdr->p_filesz);
-		if (phdr->p_filesz != phdr->p_memsz)
-			memset(dst + phdr->p_filesz, 0x00,
-			       phdr->p_memsz - phdr->p_filesz);
-		flush_cache((unsigned long)dst &
-			    ~(CONFIG_SYS_CACHELINE_SIZE - 1),
-			    ALIGN(phdr->p_filesz, CONFIG_SYS_CACHELINE_SIZE));
-	}
-
-	return ehdr->e_entry;
-}
-#endif
-
 int arch_auxiliary_core_up(u32 core_id, ulong addr)
 {
 	ulong stack, pc;

+ 8 - 0
arch/arm/mach-k3/Kconfig

@@ -126,6 +126,14 @@ config K3_SYSFW_IMAGE_SIZE_MAX
 	  tree blob. Keep it as tight as possible, as this directly affects the
 	  overall SPL memory footprint.
 
+config K3_SYSFW_IMAGE_SPI_OFFS
+	hex "SPI offset of SYSFW firmware and configuration blob"
+	depends on K3_LOAD_SYSFW
+	default	0x6C0000
+	help
+	  Offset of the combined System Firmware and configuration image tree
+	  blob to be loaded when booting from a SPI flash memory.
+
 config SYS_K3_SPL_ATF
 	bool "Start Cortex-A from SPL"
 	depends on SPL && CPU_V7R

+ 5 - 4
arch/arm/mach-k3/am6_init.c

@@ -161,10 +161,8 @@ void board_init_f(ulong dummy)
 		pinctrl_select_state(dev, "default");
 
 	/*
-	 * Load, start up, and configure system controller firmware. Provide
-	 * the U-Boot console init function to the SYSFW post-PM configuration
-	 * callback hook, effectively switching on (or over) the console
-	 * output.
+	 * Load, start up, and configure system controller firmware while
+	 * also populating the SYSFW post-PM configuration callback hook.
 	 */
 	k3_sysfw_loader(k3_mmc_stop_clock, k3_mmc_restart_clock);
 
@@ -181,6 +179,9 @@ void board_init_f(ulong dummy)
 	preloader_console_init();
 #endif
 
+	/* Output System Firmware version info */
+	k3_sysfw_print_ver();
+
 	/* Perform EEPROM-based board detection */
 	do_board_detect();
 

+ 14 - 1
arch/arm/mach-k3/arm64-mmu.c

@@ -49,6 +49,13 @@ struct mm_region am654_mem_map[NR_MMU_REGIONS] = {
 		.size = 0x80000000UL,
 		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
 			 PTE_BLOCK_INNER_SHARE
+	}, {
+		.virt = 0x500000000UL,
+		.phys = 0x500000000UL,
+		.size = 0x400000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+			 PTE_BLOCK_NON_SHARE |
+			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
 	}, {
 		/* List terminator */
 		0,
@@ -60,7 +67,7 @@ struct mm_region *mem_map = am654_mem_map;
 
 #ifdef CONFIG_SOC_K3_J721E
 /* NR_DRAM_BANKS + 32bit IO + 64bit IO + terminator */
-#define NR_MMU_REGIONS	(CONFIG_NR_DRAM_BANKS + 5)
+#define NR_MMU_REGIONS	(CONFIG_NR_DRAM_BANKS + 6)
 
 /* ToDo: Add 64bit IO */
 struct mm_region j721e_mem_map[NR_MMU_REGIONS] = {
@@ -102,6 +109,12 @@ struct mm_region j721e_mem_map[NR_MMU_REGIONS] = {
 		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 			 PTE_BLOCK_NON_SHARE |
 			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	}, {
+		.virt = 0x4d80000000UL,
+		.phys = 0x4d80000000UL,
+		.size = 0x0002000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) |
+			 PTE_BLOCK_INNER_SHARE
 	}, {
 		/* List terminator */
 		0,

+ 117 - 11
arch/arm/mach-k3/common.c

@@ -17,6 +17,10 @@
 #include <asm/arch/sys_proto.h>
 #include <asm/hardware.h>
 #include <asm/io.h>
+#include <fs_loader.h>
+#include <fs.h>
+#include <env.h>
+#include <elf.h>
 
 struct ti_sci_handle *get_ti_sci_handle(void)
 {
@@ -31,6 +35,28 @@ struct ti_sci_handle *get_ti_sci_handle(void)
 	return (struct ti_sci_handle *)ti_sci_get_handle_from_sysfw(dev);
 }
 
+void k3_sysfw_print_ver(void)
+{
+	struct ti_sci_handle *ti_sci = get_ti_sci_handle();
+	char fw_desc[sizeof(ti_sci->version.firmware_description) + 1];
+
+	/*
+	 * Output System Firmware version info. Note that since the
+	 * 'firmware_description' field is not guaranteed to be zero-
+	 * terminated we manually add a \0 terminator if needed. Further
+	 * note that we intentionally no longer rely on the extended
+	 * printf() formatter '%.*s' to not having to require a more
+	 * full-featured printf() implementation.
+	 */
+	strncpy(fw_desc, ti_sci->version.firmware_description,
+		sizeof(ti_sci->version.firmware_description));
+	fw_desc[sizeof(fw_desc) - 1] = '\0';
+
+	printf("SYSFW ABI: %d.%d (firmware rev 0x%04x '%s')\n",
+	       ti_sci->version.abi_major, ti_sci->version.abi_minor,
+	       ti_sci->version.firmware_revision, fw_desc);
+}
+
 DECLARE_GLOBAL_DATA_PTR;
 
 #ifdef CONFIG_K3_EARLY_CONS
@@ -58,23 +84,98 @@ int early_console_init(void)
 #endif
 
 #ifdef CONFIG_SYS_K3_SPL_ATF
+
+void init_env(void)
+{
+#ifdef CONFIG_SPL_ENV_SUPPORT
+	char *part;
+
+	env_init();
+	env_relocate();
+	switch (spl_boot_device()) {
+	case BOOT_DEVICE_MMC2:
+		part = env_get("bootpart");
+		env_set("storage_interface", "mmc");
+		env_set("fw_dev_part", part);
+		break;
+	case BOOT_DEVICE_SPI:
+		env_set("storage_interface", "ubi");
+		env_set("fw_ubi_mtdpart", "UBI");
+		env_set("fw_ubi_volume", "UBI0");
+		break;
+	default:
+		printf("%s from device %u not supported!\n",
+		       __func__, spl_boot_device());
+		return;
+	}
+#endif
+}
+
+#ifdef CONFIG_FS_LOADER
+int load_firmware(char *name_fw, char *name_loadaddr, u32 *loadaddr)
+{
+	struct udevice *fsdev;
+	char *name = NULL;
+	int size = 0;
+
+	*loadaddr = 0;
+#ifdef CONFIG_SPL_ENV_SUPPORT
+	switch (spl_boot_device()) {
+	case BOOT_DEVICE_MMC2:
+		name = env_get(name_fw);
+		*loadaddr = env_get_hex(name_loadaddr, *loadaddr);
+		break;
+	default:
+		printf("Loading rproc fw image from device %u not supported!\n",
+		       spl_boot_device());
+		return 0;
+	}
+#endif
+	if (!*loadaddr)
+		return 0;
+
+	if (!uclass_get_device(UCLASS_FS_FIRMWARE_LOADER, 0, &fsdev)) {
+		size = request_firmware_into_buf(fsdev, name, (void *)*loadaddr,
+						 0, 0);
+	}
+
+	return size;
+}
+#else
+int load_firmware(char *name_fw, char *name_loadaddr, u32 *loadaddr)
+{
+	return 0;
+}
+#endif
+
+__weak void start_non_linux_remote_cores(void)
+{
+}
+
 void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
 {
+	typedef void __noreturn (*image_entry_noargs_t)(void);
 	struct ti_sci_handle *ti_sci = get_ti_sci_handle();
-	int ret;
+	u32 loadaddr = 0;
+	int ret, size;
 
 	/* Release all the exclusive devices held by SPL before starting ATF */
 	ti_sci->ops.dev_ops.release_exclusive_devices(ti_sci);
 
+	ret = rproc_init();
+	if (ret)
+		panic("rproc failed to be initialized (%d)\n", ret);
+
+	init_env();
+	start_non_linux_remote_cores();
+	size = load_firmware("name_mcur5f0_0fw", "addr_mcur5f0_0load",
+			     &loadaddr);
+
+
 	/*
 	 * It is assumed that remoteproc device 1 is the corresponding
 	 * Cortex-A core which runs ATF. Make sure DT reflects the same.
 	 */
-	ret = rproc_dev_init(1);
-	if (ret)
-		panic("%s: ATF failed to initialize on rproc (%d)\n", __func__,
-		      ret);
-
 	ret = rproc_load(1, spl_image->entry_point, 0x200);
 	if (ret)
 		panic("%s: ATF failed to load on rproc (%d)\n", __func__, ret);
@@ -85,13 +186,18 @@ void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
 	ret = rproc_start(1);
 	if (ret)
 		panic("%s: ATF failed to start on rproc (%d)\n", __func__, ret);
+	if (!(size > 0 && valid_elf_image(loadaddr))) {
+		debug("Shutting down...\n");
+		release_resources_for_core_shutdown();
+
+		while (1)
+			asm volatile("wfe");
+	}
 
-	debug("Releasing resources...\n");
-	release_resources_for_core_shutdown();
+	image_entry_noargs_t image_entry =
+		(image_entry_noargs_t)load_elf_image_phdr(loadaddr);
 
-	debug("Finalizing core shutdown...\n");
-	while (1)
-		asm volatile("wfe");
+	image_entry();
 }
 #endif
 

+ 3 - 0
arch/arm/mach-k3/common.h

@@ -24,3 +24,6 @@ void setup_k3_mpu_regions(void);
 int early_console_init(void);
 void disable_linefill_optimization(void);
 void remove_fwl_configs(struct fwl_data *fwl_data, size_t fwl_data_size);
+void start_non_linux_remote_cores(void);
+int load_firmware(char *name_fw, char *name_loadaddr, u32 *loadaddr);
+void k3_sysfw_print_ver(void);

+ 37 - 0
arch/arm/mach-k3/j721e_init.c

@@ -19,6 +19,7 @@
 #include <dm/uclass-internal.h>
 #include <dm/pinctrl.h>
 #include <mmc.h>
+#include <remoteproc.h>
 
 #ifdef CONFIG_SPL_BUILD
 #ifdef CONFIG_K3_LOAD_SYSFW
@@ -202,6 +203,9 @@ void board_init_f(ulong dummy)
 	preloader_console_init();
 #endif
 
+	/* Output System Firmware version info */
+	k3_sysfw_print_ver();
+
 	/* Perform EEPROM-based board detection */
 	do_board_detect();
 
@@ -326,3 +330,36 @@ void release_resources_for_core_shutdown(void)
 	}
 }
 #endif
+
+#ifdef CONFIG_SYS_K3_SPL_ATF
+void start_non_linux_remote_cores(void)
+{
+	int size = 0, ret;
+	u32 loadaddr = 0;
+
+	size = load_firmware("name_mainr5f0_0fw", "addr_mainr5f0_0load",
+			     &loadaddr);
+	if (size <= 0)
+		goto err_load;
+
+	/* assuming remoteproc 2 is aliased for the needed remotecore */
+	ret = rproc_load(2, loadaddr, size);
+	if (ret) {
+		printf("Firmware failed to start on rproc (%d)\n", ret);
+		goto err_load;
+	}
+
+	ret = rproc_start(2);
+	if (ret) {
+		printf("Firmware init failed on rproc (%d)\n", ret);
+		goto err_load;
+	}
+
+	printf("Remoteproc 2 started successfully\n");
+
+	return;
+
+err_load:
+	rproc_reset(2);
+}
+#endif

+ 3 - 1
arch/arm/mach-k3/r5_mpu.c

@@ -26,7 +26,9 @@ struct mpu_region_config k3_mpu_regions[16] = {
 	/* U-Boot's code area marking it as WB and Write allocate */
 	{CONFIG_SYS_SDRAM_BASE, REGION_2, XN_DIS, PRIV_RW_USR_RW,
 	 O_I_WB_RD_WR_ALLOC, REGION_2GB},
-	{0x0, 3, 0x0, 0x0, 0x0, 0x0},
+	/* mcu_r5fss0_core0 BTCM area marking it as WB and Write allocate. */
+	{0x41010000, 3, XN_DIS, PRIV_RW_USR_RW, O_I_WB_RD_WR_ALLOC,
+	 REGION_8MB},
 	{0x0, 4, 0x0, 0x0, 0x0, 0x0},
 	{0x0, 5, 0x0, 0x0, 0x0, 0x0},
 	{0x0, 6, 0x0, 0x0, 0x0, 0x0},

+ 30 - 19
arch/arm/mach-k3/sysfw-loader.c

@@ -14,6 +14,8 @@
 #include <g_dnl.h>
 #include <usb.h>
 #include <dfu.h>
+#include <dm/uclass-internal.h>
+#include <spi_flash.h>
 
 #include <asm/arch/sys_proto.h>
 #include "common.h"
@@ -197,13 +199,33 @@ exit:
 }
 #endif
 
+#if CONFIG_IS_ENABLED(SPI_LOAD)
+static void *k3_sysfw_get_spi_addr(void)
+{
+	struct udevice *dev;
+	fdt_addr_t addr;
+	int ret;
+
+	ret = uclass_find_device_by_seq(UCLASS_SPI, CONFIG_SF_DEFAULT_BUS,
+					true, &dev);
+	if (ret)
+		return NULL;
+
+	addr = dev_read_addr_index(dev, 1);
+	if (addr == FDT_ADDR_T_NONE)
+		return NULL;
+
+	return (void *)(addr + CONFIG_K3_SYSFW_IMAGE_SPI_OFFS);
+}
+#endif
+
 void k3_sysfw_loader(void (*config_pm_pre_callback) (void),
 		     void (*config_pm_done_callback)(void))
 {
 	struct spl_image_info spl_image = { 0 };
 	struct spl_boot_device bootdev = { 0 };
 	struct ti_sci_handle *ti_sci;
-	int ret;
+	int ret = 0;
 
 	/* Reserve a block of aligned memory for loading the SYSFW image */
 	sysfw_load_address = memalign(ARCH_DMA_MINALIGN,
@@ -244,6 +266,13 @@ void k3_sysfw_loader(void (*config_pm_pre_callback) (void),
 #endif
 		break;
 #endif
+#if CONFIG_IS_ENABLED(SPI_LOAD)
+	case BOOT_DEVICE_SPI:
+		sysfw_load_address = k3_sysfw_get_spi_addr();
+		if (!sysfw_load_address)
+			ret = -ENODEV;
+		break;
+#endif
 #if CONFIG_IS_ENABLED(YMODEM_SUPPORT)
 	case BOOT_DEVICE_UART:
 #ifdef CONFIG_K3_EARLY_CONS
@@ -305,22 +334,4 @@ void k3_sysfw_loader(void (*config_pm_pre_callback) (void),
 	 */
 	if (config_pm_done_callback)
 		config_pm_done_callback();
-
-	/*
-	 * Output System Firmware version info. Note that since the
-	 * 'firmware_description' field is not guaranteed to be zero-
-	 * terminated we manually add a \0 terminator if needed. Further
-	 * note that we intentionally no longer rely on the extended
-	 * printf() formatter '%.*s' to not having to require a more
-	 * full-featured printf() implementation.
-	 */
-	char fw_desc[sizeof(ti_sci->version.firmware_description) + 1];
-
-	strncpy(fw_desc, ti_sci->version.firmware_description,
-		sizeof(ti_sci->version.firmware_description));
-	fw_desc[sizeof(fw_desc) - 1] = '\0';
-
-	printf("SYSFW ABI: %d.%d (firmware rev 0x%04x '%s')\n",
-	       ti_sci->version.abi_major, ti_sci->version.abi_minor,
-	       ti_sci->version.firmware_revision, fw_desc);
 }

+ 4 - 0
arch/arm/mach-omap2/am33xx/clock_am33xx.c

@@ -226,6 +226,10 @@ void enable_basic_clocks(void)
 		&cmper->usb0clkctrl,
 		&cmper->emiffwclkctrl,
 		&cmper->emifclkctrl,
+#if CONFIG_IS_ENABLED(AM335X_LCD)
+		&cmper->lcdclkctrl,
+		&cmper->lcdcclkstctrl,
+#endif
 		0
 	};
 

+ 1 - 1
board/BuR/common/br_resetc.c

@@ -22,7 +22,7 @@
 #define BMODE_PME		12
 #define BMODE_DIAG		15
 
-#ifdef CONFIG_LCD
+#if CONFIG_IS_ENABLED(LCD) && !CONFIG_IS_ENABLED(DM_VIDEO)
 #include <lcd.h>
 #define LCD_SETCURSOR(x, y)	lcd_position_cursor(x, y)
 #define LCD_PUTS(x)		lcd_puts(x)

+ 3 - 0
board/BuR/common/bur_common.h

@@ -11,9 +11,12 @@
 #ifndef _BUR_COMMON_H_
 #define _BUR_COMMON_H_
 
+#if !CONFIG_IS_ENABLED(DM_VIDEO)
 #include <../../../drivers/video/am335x-fb.h>
 
 int load_lcdtiming(struct am335x_lcdpanel *panel);
+#endif
+
 void br_summaryscreen(void);
 void pmicsetup(u32 mpupll, unsigned int bus);
 void enable_uart0_pin_mux(void);

+ 1 - 1
board/BuR/common/common.c

@@ -20,7 +20,7 @@ DECLARE_GLOBAL_DATA_PTR;
 
 /* --------------------------------------------------------------------------*/
 #if defined(CONFIG_LCD) && defined(CONFIG_AM335X_LCD) && \
-	!defined(CONFIG_SPL_BUILD)
+	!defined(CONFIG_DM_VIDEO) && !defined(CONFIG_SPL_BUILD)
 #include <asm/arch/hardware.h>
 #include <asm/arch/cpu.h>
 #include <asm/gpio.h>

+ 57 - 2
board/ti/am65x/README

@@ -104,7 +104,7 @@ 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
+	Tree: git://git.ti.com/k3-image-gen/k3-image-gen.git
 	Branch: master
 
 2. ATF:
@@ -138,7 +138,7 @@ $ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- O=/tmp/r5
 
 4.2. A53:
 $ make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- am65x_evm_a53_defconfig O=/tmp/a53
-$ make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- ATF=<path to ATF dir>/build/k3/generic/release/bl31.bin TEE=<path to OPTEE OS dir>/out/arm-plat-k3/core/tee-pager.bin O=/tmp/a53
+$ make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- ATF=<path to ATF dir>/build/k3/generic/release/bl31.bin TEE=<path to OPTEE OS dir>/out/arm-plat-k3/core/tee-pager_v2.bin O=/tmp/a53
 
 Target Images
 --------------
@@ -262,6 +262,61 @@ To boot kernel from eMMC, use the following commands:
 => setenv bootpart 0
 => boot
 
+OSPI:
+-----
+ROM supports booting from OSPI from offset 0x0.
+
+Flashing images to OSPI:
+
+Below commands can be used to download tiboot3.bin, tispl.bin, u-boot.img,
+and sysfw.itb over tftp and then flash those to OSPI at their respective
+addresses.
+
+=> sf probe
+=> tftp ${loadaddr} tiboot3.bin
+=> sf update $loadaddr 0x0 $filesize
+=> tftp ${loadaddr} tispl.bin
+=> sf update $loadaddr 0x80000 $filesize
+=> tftp ${loadaddr} u-boot.img
+=> sf update $loadaddr 0x280000 $filesize
+=> tftp ${loadaddr} sysfw.itb
+=> sf update $loadaddr 0x6C0000 $filesize
+
+Flash layout for OSPI:
+
+         0x0 +----------------------------+
+             |     ospi.tiboot3(512K)     |
+             |                            |
+     0x80000 +----------------------------+
+             |     ospi.tispl(2M)         |
+             |                            |
+    0x280000 +----------------------------+
+             |     ospi.u-boot(4M)        |
+             |                            |
+    0x680000 +----------------------------+
+             |     ospi.env(128K)         |
+             |                            |
+    0x6A0000 +----------------------------+
+	     |	 ospi.env.backup (128K)   |
+	     |                            |
+    0x6C0000 +----------------------------+
+             |      ospi.sysfw(1M)        |
+             |                            |
+    0x7C0000 +----------------------------+
+	     |      padding (256k)        |
+    0x800000 +----------------------------+
+             |     ospi.rootfs(UBIFS)     |
+             |                            |
+             +----------------------------+
+
+Kernel Image and DT are expected to be present in the /boot folder of UBIFS
+ospi.rootfs just like in SD card case. U-Boot looks for UBI volume named
+"rootfs" for rootfs.
+
+To boot kernel from OSPI, at the U-Boot prompt:
+=> setenv boot ubi
+=> boot
+
 UART:
 -----
 ROM supports booting from MCU_UART0 via X-Modem protocol. The entire UART-based

+ 49 - 2
board/ti/j721e/README

@@ -120,7 +120,7 @@ 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
+	Tree: git://git.ti.com/k3-image-gen/k3-image-gen.git
 	Branch: master
 
 2. ATF:
@@ -154,7 +154,7 @@ $ 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
+$ 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_v2.bin O=/tmp/a72
 
 Target Images
 --------------
@@ -225,3 +225,50 @@ Image formats:
                 | |    Secure config  | |
                 | +-------------------+ |
                 +-----------------------+
+
+OSPI:
+-----
+ROM supports booting from OSPI from offset 0x0.
+
+Flashing images to OSPI:
+
+Below commands can be used to download tiboot3.bin, tispl.bin, u-boot.img,
+and sysfw.itb over tftp and then flash those to OSPI at their respective
+addresses.
+
+=> sf probe
+=> tftp ${loadaddr} tiboot3.bin
+=> sf update $loadaddr 0x0 $filesize
+=> tftp ${loadaddr} tispl.bin
+=> sf update $loadaddr 0x80000 $filesize
+=> tftp ${loadaddr} u-boot.img
+=> sf update $loadaddr 0x280000 $filesize
+=> tftp ${loadaddr} sysfw.itb
+=> sf update $loadaddr 0x6C0000 $filesize
+
+Flash layout for OSPI:
+
+         0x0 +----------------------------+
+             |     ospi.tiboot3(512K)     |
+             |                            |
+     0x80000 +----------------------------+
+             |     ospi.tispl(2M)         |
+             |                            |
+    0x280000 +----------------------------+
+             |     ospi.u-boot(4M)        |
+             |                            |
+    0x680000 +----------------------------+
+             |     ospi.env(128K)         |
+             |                            |
+    0x6A0000 +----------------------------+
+	     |	 ospi.env.backup (128K)   |
+	     |                            |
+    0x6C0000 +----------------------------+
+             |      ospi.sysfw(1M)        |
+             |                            |
+    0x7C0000 +----------------------------+
+	     |      padding (256k)        |
+    0x800000 +----------------------------+
+             |     ospi.rootfs(UBIFS)     |
+             |                            |
+             +----------------------------+

+ 26 - 0
board/ti/j721e/evm.c

@@ -15,6 +15,8 @@
 #include <asm/io.h>
 #include <spl.h>
 #include <asm/arch/sys_proto.h>
+#include <dm.h>
+#include <dm/uclass-internal.h>
 
 #include "../common/board_detect.h"
 
@@ -343,5 +345,29 @@ int board_late_init(void)
 
 void spl_board_init(void)
 {
+#if defined(CONFIG_ESM_K3) || defined(CONFIG_ESM_PMIC)
+	struct udevice *dev;
+	int ret;
+#endif
+
 	probe_daughtercards();
+
+#ifdef CONFIG_ESM_K3
+	if (board_ti_k3_is("J721EX-PM2-SOM")) {
+		ret = uclass_get_device_by_driver(UCLASS_MISC,
+						  DM_GET_DRIVER(k3_esm), &dev);
+		if (ret)
+			printf("ESM init failed: %d\n", ret);
+	}
+#endif
+
+#ifdef CONFIG_ESM_PMIC
+	if (board_ti_k3_is("J721EX-PM2-SOM")) {
+		ret = uclass_get_device_by_driver(UCLASS_MISC,
+						  DM_GET_DRIVER(pmic_esm),
+						  &dev);
+		if (ret)
+			printf("ESM PMIC init failed: %d\n", ret);
+	}
+#endif
 }

+ 1 - 0
cmd/Kconfig

@@ -399,6 +399,7 @@ config CMD_ABOOTIMG
 config CMD_ELF
 	bool "bootelf, bootvx"
 	default y
+	select LIB_ELF
 	help
 	  Boot an ELF/vxWorks image from the memory.
 

+ 0 - 229
cmd/elf.c

@@ -18,211 +18,6 @@
 #include <linux/linkage.h>
 #endif
 
-/*
- * A very simple ELF64 loader, assumes the image is valid, returns the
- * entry point address.
- *
- * Note if U-Boot is 32-bit, the loader assumes the to segment's
- * physical address and size is within the lower 32-bit address space.
- */
-static unsigned long load_elf64_image_phdr(unsigned long addr)
-{
-	Elf64_Ehdr *ehdr; /* Elf header structure pointer */
-	Elf64_Phdr *phdr; /* Program header structure pointer */
-	int i;
-
-	ehdr = (Elf64_Ehdr *)addr;
-	phdr = (Elf64_Phdr *)(addr + (ulong)ehdr->e_phoff);
-
-	/* Load each program header */
-	for (i = 0; i < ehdr->e_phnum; ++i) {
-		void *dst = (void *)(ulong)phdr->p_paddr;
-		void *src = (void *)addr + phdr->p_offset;
-
-		debug("Loading phdr %i to 0x%p (%lu bytes)\n",
-		      i, dst, (ulong)phdr->p_filesz);
-		if (phdr->p_filesz)
-			memcpy(dst, src, phdr->p_filesz);
-		if (phdr->p_filesz != phdr->p_memsz)
-			memset(dst + phdr->p_filesz, 0x00,
-			       phdr->p_memsz - phdr->p_filesz);
-		flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
-			    roundup(phdr->p_memsz, ARCH_DMA_MINALIGN));
-		++phdr;
-	}
-
-	if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags &
-					    EF_PPC64_ELFV1_ABI)) {
-		/*
-		 * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function
-		 * descriptor pointer with the first double word being the
-		 * address of the entry point of the function.
-		 */
-		uintptr_t addr = ehdr->e_entry;
-
-		return *(Elf64_Addr *)addr;
-	}
-
-	return ehdr->e_entry;
-}
-
-static unsigned long load_elf64_image_shdr(unsigned long addr)
-{
-	Elf64_Ehdr *ehdr; /* Elf header structure pointer */
-	Elf64_Shdr *shdr; /* Section header structure pointer */
-	unsigned char *strtab = 0; /* String table pointer */
-	unsigned char *image; /* Binary image pointer */
-	int i; /* Loop counter */
-
-	ehdr = (Elf64_Ehdr *)addr;
-
-	/* Find the section header string table for output info */
-	shdr = (Elf64_Shdr *)(addr + (ulong)ehdr->e_shoff +
-			     (ehdr->e_shstrndx * sizeof(Elf64_Shdr)));
-
-	if (shdr->sh_type == SHT_STRTAB)
-		strtab = (unsigned char *)(addr + (ulong)shdr->sh_offset);
-
-	/* Load each appropriate section */
-	for (i = 0; i < ehdr->e_shnum; ++i) {
-		shdr = (Elf64_Shdr *)(addr + (ulong)ehdr->e_shoff +
-				     (i * sizeof(Elf64_Shdr)));
-
-		if (!(shdr->sh_flags & SHF_ALLOC) ||
-		    shdr->sh_addr == 0 || shdr->sh_size == 0) {
-			continue;
-		}
-
-		if (strtab) {
-			debug("%sing %s @ 0x%08lx (%ld bytes)\n",
-			      (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load",
-			       &strtab[shdr->sh_name],
-			       (unsigned long)shdr->sh_addr,
-			       (long)shdr->sh_size);
-		}
-
-		if (shdr->sh_type == SHT_NOBITS) {
-			memset((void *)(uintptr_t)shdr->sh_addr, 0,
-			       shdr->sh_size);
-		} else {
-			image = (unsigned char *)addr + (ulong)shdr->sh_offset;
-			memcpy((void *)(uintptr_t)shdr->sh_addr,
-			       (const void *)image, shdr->sh_size);
-		}
-		flush_cache(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
-			    roundup((shdr->sh_addr + shdr->sh_size),
-				     ARCH_DMA_MINALIGN) -
-			            rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
-	}
-
-	if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags &
-					    EF_PPC64_ELFV1_ABI)) {
-		/*
-		 * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function
-		 * descriptor pointer with the first double word being the
-		 * address of the entry point of the function.
-		 */
-		uintptr_t addr = ehdr->e_entry;
-
-		return *(Elf64_Addr *)addr;
-	}
-
-	return ehdr->e_entry;
-}
-
-/*
- * A very simple ELF loader, assumes the image is valid, returns the
- * entry point address.
- *
- * The loader firstly reads the EFI class to see if it's a 64-bit image.
- * If yes, call the ELF64 loader. Otherwise continue with the ELF32 loader.
- */
-static unsigned long load_elf_image_phdr(unsigned long addr)
-{
-	Elf32_Ehdr *ehdr; /* Elf header structure pointer */
-	Elf32_Phdr *phdr; /* Program header structure pointer */
-	int i;
-
-	ehdr = (Elf32_Ehdr *)addr;
-	if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
-		return load_elf64_image_phdr(addr);
-
-	phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff);
-
-	/* Load each program header */
-	for (i = 0; i < ehdr->e_phnum; ++i) {
-		void *dst = (void *)(uintptr_t)phdr->p_paddr;
-		void *src = (void *)addr + phdr->p_offset;
-
-		debug("Loading phdr %i to 0x%p (%i bytes)\n",
-		      i, dst, phdr->p_filesz);
-		if (phdr->p_filesz)
-			memcpy(dst, src, phdr->p_filesz);
-		if (phdr->p_filesz != phdr->p_memsz)
-			memset(dst + phdr->p_filesz, 0x00,
-			       phdr->p_memsz - phdr->p_filesz);
-		flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
-			    roundup(phdr->p_memsz, ARCH_DMA_MINALIGN));
-		++phdr;
-	}
-
-	return ehdr->e_entry;
-}
-
-static unsigned long load_elf_image_shdr(unsigned long addr)
-{
-	Elf32_Ehdr *ehdr; /* Elf header structure pointer */
-	Elf32_Shdr *shdr; /* Section header structure pointer */
-	unsigned char *strtab = 0; /* String table pointer */
-	unsigned char *image; /* Binary image pointer */
-	int i; /* Loop counter */
-
-	ehdr = (Elf32_Ehdr *)addr;
-	if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
-		return load_elf64_image_shdr(addr);
-
-	/* Find the section header string table for output info */
-	shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
-			     (ehdr->e_shstrndx * sizeof(Elf32_Shdr)));
-
-	if (shdr->sh_type == SHT_STRTAB)
-		strtab = (unsigned char *)(addr + shdr->sh_offset);
-
-	/* Load each appropriate section */
-	for (i = 0; i < ehdr->e_shnum; ++i) {
-		shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
-				     (i * sizeof(Elf32_Shdr)));
-
-		if (!(shdr->sh_flags & SHF_ALLOC) ||
-		    shdr->sh_addr == 0 || shdr->sh_size == 0) {
-			continue;
-		}
-
-		if (strtab) {
-			debug("%sing %s @ 0x%08lx (%ld bytes)\n",
-			      (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load",
-			       &strtab[shdr->sh_name],
-			       (unsigned long)shdr->sh_addr,
-			       (long)shdr->sh_size);
-		}
-
-		if (shdr->sh_type == SHT_NOBITS) {
-			memset((void *)(uintptr_t)shdr->sh_addr, 0,
-			       shdr->sh_size);
-		} else {
-			image = (unsigned char *)addr + shdr->sh_offset;
-			memcpy((void *)(uintptr_t)shdr->sh_addr,
-			       (const void *)image, shdr->sh_size);
-		}
-		flush_cache(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
-			    roundup((shdr->sh_addr + shdr->sh_size),
-				    ARCH_DMA_MINALIGN) -
-			    rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
-	}
-
-	return ehdr->e_entry;
-}
-
 /* Allow ports to override the default behavior */
 static unsigned long do_bootelf_exec(ulong (*entry)(int, char * const[]),
 				     int argc, char * const argv[])
@@ -238,30 +33,6 @@ static unsigned long do_bootelf_exec(ulong (*entry)(int, char * const[]),
 	return ret;
 }
 
-/*
- * Determine if a valid ELF image exists at the given memory location.
- * First look at the ELF header magic field, then make sure that it is
- * executable.
- */
-int valid_elf_image(unsigned long addr)
-{
-	Elf32_Ehdr *ehdr; /* Elf header structure pointer */
-
-	ehdr = (Elf32_Ehdr *)addr;
-
-	if (!IS_ELF(*ehdr)) {
-		printf("## No elf image at address 0x%08lx\n", addr);
-		return 0;
-	}
-
-	if (ehdr->e_type != ET_EXEC) {
-		printf("## Not a 32-bit elf image at address 0x%08lx\n", addr);
-		return 0;
-	}
-
-	return 1;
-}
-
 /* Interpreter command to boot an arbitrary ELF image from memory */
 int do_bootelf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {

+ 2 - 0
configs/am335x_baltos_defconfig

@@ -55,6 +55,8 @@ CONFIG_SYS_NAND_U_BOOT_OFFS=0x00080000
 CONFIG_PHY_ADDR_ENABLE=y
 CONFIG_PHY_ATHEROS=y
 CONFIG_PHY_SMSC=y
+CONFIG_DM_ETH=y
+CONFIG_DM_MDIO=y
 CONFIG_MII=y
 CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SPI=y

+ 4 - 0
configs/am335x_evm_defconfig

@@ -40,10 +40,14 @@ CONFIG_SPL_ENV_IS_NOWHERE=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_CLK=y
 CONFIG_CLK_CDCE9XX=y
+CONFIG_DFU_TFTP=y
 CONFIG_DFU_MMC=y
 CONFIG_DFU_NAND=y
 CONFIG_DFU_RAM=y
 CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=1
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
 CONFIG_DM_I2C=y
 CONFIG_MISC=y
 CONFIG_DM_MMC=y

+ 25 - 0
configs/am65x_evm_a53_defconfig

@@ -16,6 +16,8 @@ CONFIG_NR_DRAM_BANKS=2
 CONFIG_ENV_OFFSET_REDUND=0x6A0000
 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
@@ -29,10 +31,17 @@ CONFIG_SPL_STACK_R=y
 CONFIG_SPL_SEPARATE_BSS=y
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x1400
+CONFIG_SPL_DMA=y
 CONFIG_SPL_I2C_SUPPORT=y
 CONFIG_SPL_DM_MAILBOX=y
+CONFIG_SPL_MTD_SUPPORT=y
 CONFIG_SPL_DM_RESET=y
 CONFIG_SPL_POWER_DOMAIN=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+# CONFIG_SPL_SPI_FLASH_TINY is not set
+CONFIG_SPL_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPL_SPI_LOAD=y
+CONFIG_SYS_SPI_U_BOOT_OFFS=0x280000
 CONFIG_SPL_YMODEM_SUPPORT=y
 CONFIG_CMD_ASKENV=y
 CONFIG_CMD_DFU=y
@@ -41,9 +50,13 @@ CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_PCI=y
 CONFIG_CMD_REMOTEPROC=y
+CONFIG_CMD_SF=y
 CONFIG_CMD_USB=y
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_TIME=y
+CONFIG_MTDIDS_DEFAULT="nor0=47040000.spi.0"
+CONFIG_MTDPARTS_DEFAULT="mtdparts=47040000.spi.0:512k(ospi.tiboot3),2m(ospi.tispl),4m(ospi.u-boot),128k(ospi.env),128k(ospi.env.backup),1m(ospi.sysfw),-@8m(ospi.rootfs)"
+CONFIG_CMD_UBI=y
 # CONFIG_ISO_PARTITION is not set
 CONFIG_OF_CONTROL=y
 CONFIG_SPL_OF_CONTROL=y
@@ -58,11 +71,13 @@ CONFIG_DM=y
 CONFIG_SPL_DM=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_SPL_REGMAP=y
+CONFIG_SPL_OF_TRANSLATE=y
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
 CONFIG_CLK_TI_SCI=y
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
+CONFIG_DFU_SF=y
 CONFIG_DMA_CHANNELS=y
 CONFIG_TI_K3_NAVSS_UDMA=y
 CONFIG_TI_SCI_PROTOCOL=y
@@ -79,6 +94,13 @@ CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_ADMA=y
 CONFIG_SPL_MMC_SDHCI_ADMA=y
 CONFIG_MMC_SDHCI_AM654=y
+CONFIG_MTD=y
+CONFIG_DM_MTD=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT
+CONFIG_SPI_FLASH_STMICRO=y
+# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
+CONFIG_SPI_FLASH_MTD=y
 CONFIG_PHY_TI=y
 CONFIG_PHY_FIXED=y
 CONFIG_DM_ETH=y
@@ -103,6 +125,9 @@ CONFIG_DM_RESET=y
 CONFIG_RESET_TI_SCI=y
 CONFIG_DM_SERIAL=y
 CONFIG_SOC_TI=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_CADENCE_QSPI=y
 CONFIG_SYSRESET=y
 CONFIG_SPL_SYSRESET=y
 CONFIG_SYSRESET_TI_SCI=y

+ 17 - 0
configs/am65x_evm_r5_defconfig

@@ -16,6 +16,8 @@ CONFIG_SPL_STACK_R_ADDR=0x82000000
 CONFIG_NR_DRAM_BANKS=2
 CONFIG_SPL_FS_FAT=y
 CONFIG_SPL_LIBDISK_SUPPORT=y
+CONFIG_SPL_SPI_FLASH_SUPPORT=y
+CONFIG_SPL_SPI_SUPPORT=y
 CONFIG_SPL_TEXT_BASE=0x41c00000
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
 CONFIG_SPL_LOAD_FIT=y
@@ -26,6 +28,7 @@ CONFIG_SPL_SEPARATE_BSS=y
 CONFIG_SPL_EARLY_BSS=y
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x400
+CONFIG_SPL_DMA=y
 CONFIG_SPL_I2C_SUPPORT=y
 CONFIG_SPL_DM_MAILBOX=y
 CONFIG_SPL_DM_RESET=y
@@ -34,6 +37,10 @@ CONFIG_SPL_POWER_DOMAIN=y
 CONFIG_SPL_RAM_SUPPORT=y
 CONFIG_SPL_RAM_DEVICE=y
 CONFIG_SPL_REMOTEPROC=y
+# CONFIG_SPL_SPI_FLASH_TINY is not set
+CONFIG_SPL_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPL_SPI_LOAD=y
+CONFIG_SYS_SPI_U_BOOT_OFFS=0x80000
 CONFIG_SPL_YMODEM_SUPPORT=y
 CONFIG_HUSH_PARSER=y
 CONFIG_CMD_BOOTZ=y
@@ -63,6 +70,8 @@ CONFIG_SPL_OF_TRANSLATE=y
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
 CONFIG_CLK_TI_SCI=y
+CONFIG_DMA_CHANNELS=y
+CONFIG_TI_K3_NAVSS_UDMA=y
 CONFIG_TI_SCI_PROTOCOL=y
 CONFIG_DA8XX_GPIO=y
 CONFIG_DM_I2C=y
@@ -77,6 +86,10 @@ CONFIG_SUPPORT_EMMC_BOOT=y
 CONFIG_MMC_SDHCI=y
 CONFIG_SPL_MMC_SDHCI_ADMA=y
 CONFIG_MMC_SDHCI_AM654=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_STMICRO=y
+# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
 CONFIG_PINCTRL=y
 # CONFIG_PINCTRL_GENERIC is not set
 CONFIG_SPL_PINCTRL=y
@@ -96,6 +109,10 @@ CONFIG_REMOTEPROC_TI_K3_ARM64=y
 CONFIG_DM_RESET=y
 CONFIG_RESET_TI_SCI=y
 CONFIG_DM_SERIAL=y
+CONFIG_SOC_TI=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_CADENCE_QSPI=y
 CONFIG_SYSRESET=y
 CONFIG_SPL_SYSRESET=y
 CONFIG_SYSRESET_TI_SCI=y

+ 71 - 4
configs/am65x_hs_evm_a53_defconfig

@@ -7,6 +7,7 @@ CONFIG_SYS_MALLOC_F_LEN=0x8000
 CONFIG_SOC_K3_AM6=y
 CONFIG_TARGET_AM654_A53_EVM=y
 CONFIG_ENV_SIZE=0x20000
+CONFIG_ENV_OFFSET=0x680000
 CONFIG_DM_GPIO=y
 CONFIG_SPL_MMC_SUPPORT=y
 CONFIG_SPL_SERIAL_SUPPORT=y
@@ -15,6 +16,9 @@ CONFIG_SPL_STACK_R_ADDR=0x82000000
 CONFIG_NR_DRAM_BANKS=2
 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
@@ -23,38 +27,60 @@ 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_CONSOLE_MUX=y
 CONFIG_SPL_SYS_MALLOC_SIMPLE=y
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_SEPARATE_BSS=y
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x1400
+CONFIG_SPL_DMA=y
 CONFIG_SPL_I2C_SUPPORT=y
 CONFIG_SPL_DM_MAILBOX=y
+CONFIG_SPL_MTD_SUPPORT=y
 CONFIG_SPL_DM_RESET=y
 CONFIG_SPL_POWER_DOMAIN=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+# CONFIG_SPL_SPI_FLASH_TINY is not set
+CONFIG_SPL_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPL_SPI_LOAD=y
+CONFIG_SYS_SPI_U_BOOT_OFFS=0x280000
 CONFIG_SPL_YMODEM_SUPPORT=y
 CONFIG_CMD_ASKENV=y
+CONFIG_CMD_DFU=y
+CONFIG_CMD_GPT=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
+CONFIG_CMD_PCI=y
+CONFIG_CMD_REMOTEPROC=y
+CONFIG_CMD_SF=y
+CONFIG_CMD_USB=y
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_TIME=y
+CONFIG_MTDIDS_DEFAULT="nor0=47040000.spi.0"
+CONFIG_MTDPARTS_DEFAULT="mtdparts=47040000.spi.0:512k(ospi.tiboot3),2m(ospi.tispl),4m(ospi.u-boot),128k(ospi.env),128k(ospi.env.backup),1m(ospi.sysfw),-@8m(ospi.rootfs)"
+CONFIG_CMD_UBI=y
 # CONFIG_ISO_PARTITION is not set
-# CONFIG_EFI_PARTITION is not set
 CONFIG_OF_CONTROL=y
 CONFIG_SPL_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="k3-am654-base-board"
 CONFIG_SPL_MULTI_DTB_FIT=y
 CONFIG_SPL_MULTI_DTB_FIT_NO_COMPRESSION=y
-CONFIG_ENV_IS_IN_FAT=y
-CONFIG_ENV_FAT_INTERFACE="mmc"
-CONFIG_ENV_FAT_DEVICE_AND_PART="1:1"
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
+CONFIG_ENV_OFFSET_REDUND=0x6A0000
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_DM=y
 CONFIG_SPL_DM=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_SPL_REGMAP=y
+CONFIG_SPL_OF_TRANSLATE=y
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
 CONFIG_CLK_TI_SCI=y
+CONFIG_DFU_MMC=y
+CONFIG_DFU_RAM=y
+CONFIG_DFU_SF=y
 CONFIG_DMA_CHANNELS=y
 CONFIG_TI_K3_NAVSS_UDMA=y
 CONFIG_TI_SCI_PROTOCOL=y
@@ -62,10 +88,33 @@ CONFIG_DM_PCA953X=y
 CONFIG_DM_I2C=y
 CONFIG_I2C_SET_DEFAULT_BUS_NUM=y
 CONFIG_SYS_I2C_OMAP24XX=y
+CONFIG_DM_KEYBOARD=y
 CONFIG_DM_MAILBOX=y
 CONFIG_K3_SEC_PROXY=y
 CONFIG_DM_MMC=y
 CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_ADMA=y
+CONFIG_SPL_MMC_SDHCI_ADMA=y
+CONFIG_MMC_SDHCI_AM654=y
+CONFIG_MTD=y
+CONFIG_DM_MTD=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT
+CONFIG_SPI_FLASH_STMICRO=y
+# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_PHY_TI=y
+CONFIG_PHY_FIXED=y
+CONFIG_DM_ETH=y
+CONFIG_E1000=y
+CONFIG_CMD_E1000=y
+CONFIG_TI_AM65_CPSW_NUSS=y
+CONFIG_PCI=y
+CONFIG_DM_PCI=y
+CONFIG_PCI_KEYSTONE=y
+CONFIG_PHY=y
+CONFIG_AM654_PHY=y
+CONFIG_OMAP_USB2_PHY=y
 CONFIG_PINCTRL=y
 # CONFIG_PINCTRL_GENERIC is not set
 CONFIG_SPL_PINCTRL=y
@@ -73,11 +122,29 @@ 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
 CONFIG_SOC_TI=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_CADENCE_QSPI=y
 CONFIG_SYSRESET=y
 CONFIG_SPL_SYSRESET=y
 CONFIG_SYSRESET_TI_SCI=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_DM_USB_GADGET=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_DWC3=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_DWC3_GENERIC=y
+CONFIG_USB_KEYBOARD=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments"
+CONFIG_USB_GADGET_VENDOR_NUM=0x0451
+CONFIG_USB_GADGET_PRODUCT_NUM=0x6162
+CONFIG_USB_GADGET_DOWNLOAD=y
+CONFIG_FAT_WRITE=y
 CONFIG_OF_LIBFDT_OVERLAY=y

+ 24 - 0
configs/am65x_hs_evm_r5_defconfig

@@ -6,6 +6,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_ENV_SIZE=0x20000
 CONFIG_DM_GPIO=y
@@ -16,6 +17,8 @@ CONFIG_SPL_STACK_R_ADDR=0x82000000
 CONFIG_NR_DRAM_BANKS=2
 CONFIG_SPL_FS_FAT=y
 CONFIG_SPL_LIBDISK_SUPPORT=y
+CONFIG_SPL_SPI_FLASH_SUPPORT=y
+CONFIG_SPL_SPI_SUPPORT=y
 CONFIG_SPL_TEXT_BASE=0x41c00000
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
 CONFIG_SPL_LOAD_FIT=y
@@ -27,6 +30,7 @@ CONFIG_SPL_SEPARATE_BSS=y
 CONFIG_SPL_EARLY_BSS=y
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x400
+CONFIG_SPL_DMA=y
 CONFIG_SPL_I2C_SUPPORT=y
 CONFIG_SPL_DM_MAILBOX=y
 CONFIG_SPL_DM_RESET=y
@@ -35,6 +39,10 @@ CONFIG_SPL_POWER_DOMAIN=y
 CONFIG_SPL_RAM_SUPPORT=y
 CONFIG_SPL_RAM_DEVICE=y
 CONFIG_SPL_REMOTEPROC=y
+# CONFIG_SPL_SPI_FLASH_TINY is not set
+CONFIG_SPL_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPL_SPI_LOAD=y
+CONFIG_SYS_SPI_U_BOOT_OFFS=0x80000
 CONFIG_SPL_YMODEM_SUPPORT=y
 CONFIG_HUSH_PARSER=y
 CONFIG_CMD_BOOTZ=y
@@ -58,10 +66,14 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_DM=y
 CONFIG_SPL_DM=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_REGMAP=y
+CONFIG_SPL_REGMAP=y
 CONFIG_SPL_OF_TRANSLATE=y
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
 CONFIG_CLK_TI_SCI=y
+CONFIG_DMA_CHANNELS=y
+CONFIG_TI_K3_NAVSS_UDMA=y
 CONFIG_TI_SCI_PROTOCOL=y
 CONFIG_DA8XX_GPIO=y
 CONFIG_DM_I2C=y
@@ -70,8 +82,15 @@ CONFIG_SYS_I2C_OMAP24XX=y
 CONFIG_DM_MAILBOX=y
 CONFIG_K3_SEC_PROXY=y
 CONFIG_MISC=y
+CONFIG_K3_AVS0=y
 CONFIG_DM_MMC=y
 CONFIG_MMC_SDHCI=y
+CONFIG_SPL_MMC_SDHCI_ADMA=y
+CONFIG_MMC_SDHCI_AM654=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_STMICRO=y
+# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
 CONFIG_PINCTRL=y
 # CONFIG_PINCTRL_GENERIC is not set
 CONFIG_SPL_PINCTRL=y
@@ -83,6 +102,7 @@ CONFIG_DM_REGULATOR=y
 CONFIG_SPL_DM_REGULATOR=y
 CONFIG_DM_REGULATOR_GPIO=y
 CONFIG_SPL_DM_REGULATOR_GPIO=y
+CONFIG_DM_REGULATOR_TPS62360=y
 CONFIG_RAM=y
 CONFIG_SPL_RAM=y
 CONFIG_K3_SYSTEM_CONTROLLER=y
@@ -90,6 +110,10 @@ CONFIG_REMOTEPROC_TI_K3_ARM64=y
 CONFIG_DM_RESET=y
 CONFIG_RESET_TI_SCI=y
 CONFIG_DM_SERIAL=y
+CONFIG_SOC_TI=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_CADENCE_QSPI=y
 CONFIG_SYSRESET=y
 CONFIG_SPL_SYSRESET=y
 CONFIG_SYSRESET_TI_SCI=y

+ 8 - 1
configs/j721e_evm_a72_defconfig

@@ -31,6 +31,7 @@ CONFIG_SPL_STACK_R=y
 CONFIG_SPL_SEPARATE_BSS=y
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x1400
+CONFIG_SPL_DMA=y
 CONFIG_SPL_ENV_SUPPORT=y
 CONFIG_SPL_I2C_SUPPORT=y
 CONFIG_SPL_DM_MAILBOX=y
@@ -39,6 +40,8 @@ CONFIG_SPL_POWER_SUPPORT=y
 CONFIG_SPL_POWER_DOMAIN=y
 CONFIG_SPL_RAM_SUPPORT=y
 CONFIG_SPL_RAM_DEVICE=y
+# CONFIG_SPL_SPI_FLASH_TINY is not set
+CONFIG_SPL_SPI_FLASH_SFDP_SUPPORT=y
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_SYS_SPI_U_BOOT_OFFS=0x280000
 CONFIG_SPL_USB_GADGET=y
@@ -60,7 +63,8 @@ CONFIG_CMD_USB_MASS_STORAGE=y
 CONFIG_CMD_TIME=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_MTDIDS_DEFAULT="nor0=47040000.spi.0,nor0=47034000.hyperbus"
-CONFIG_MTDPARTS_DEFAULT="mtdparts=47034000.hyperbus:512k(hbmc.tiboot3),2m(hbmc.tispl),4m(hbmc.u-boot),256k(hbmc.env),1m(hbmc.sysfw),-@8m(hbmc.rootfs)"
+CONFIG_MTDPARTS_DEFAULT="mtdparts=47040000.spi.0:512k(ospi.tiboot3),2m(ospi.tispl),4m(ospi.u-boot),128k(ospi.env),128k(ospi.env.backup),1m(ospi.sysfw),-@8m(ospi.rootfs);47034000.hyperbus:512k(hbmc.tiboot3),2m(hbmc.tispl),4m(hbmc.u-boot),256k(hbmc.env),1m(hbmc.sysfw),-@8m(hbmc.rootfs)"
+CONFIG_CMD_UBI=y
 # CONFIG_ISO_PARTITION is not set
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_OF_CONTROL=y
@@ -116,7 +120,10 @@ CONFIG_FLASH_CFI_MTD=y
 CONFIG_SYS_FLASH_CFI=y
 CONFIG_HBMC_AM654=y
 CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT
 CONFIG_SPI_FLASH_STMICRO=y
+# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
+CONFIG_SPI_FLASH_MTD=y
 CONFIG_PHY_TI=y
 CONFIG_PHY_FIXED=y
 CONFIG_DM_ETH=y

+ 12 - 3
configs/j721e_evm_r5_defconfig

@@ -8,7 +8,6 @@ CONFIG_SOC_K3_J721E=y
 CONFIG_K3_EARLY_CONS=y
 CONFIG_TARGET_J721E_R5_EVM=y
 CONFIG_ENV_SIZE=0x20000
-CONFIG_ENV_OFFSET=0x680000
 CONFIG_DM_GPIO=y
 CONFIG_SPL_MMC_SUPPORT=y
 CONFIG_SPL_SERIAL_SUPPORT=y
@@ -29,7 +28,9 @@ CONFIG_SPL_SEPARATE_BSS=y
 CONFIG_SPL_EARLY_BSS=y
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x400
+CONFIG_SPL_DMA=y
 CONFIG_SPL_ENV_SUPPORT=y
+CONFIG_SPL_FS_EXT4=y
 CONFIG_SPL_I2C_SUPPORT=y
 CONFIG_SPL_DM_MAILBOX=y
 CONFIG_SPL_DM_RESET=y
@@ -38,6 +39,8 @@ CONFIG_SPL_POWER_DOMAIN=y
 CONFIG_SPL_RAM_SUPPORT=y
 CONFIG_SPL_RAM_DEVICE=y
 CONFIG_SPL_REMOTEPROC=y
+# CONFIG_SPL_SPI_FLASH_TINY is not set
+CONFIG_SPL_SPI_FLASH_SFDP_SUPPORT=y
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_SYS_SPI_U_BOOT_OFFS=0x80000
 CONFIG_SPL_USB_GADGET=y
@@ -55,8 +58,6 @@ CONFIG_CMD_FAT=y
 CONFIG_OF_CONTROL=y
 CONFIG_SPL_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="k3-j721e-r5-common-proc-board"
-CONFIG_ENV_IS_IN_MMC=y
-CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_DM=y
 CONFIG_SPL_DM=y
@@ -67,6 +68,8 @@ CONFIG_SPL_OF_TRANSLATE=y
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
 CONFIG_CLK_TI_SCI=y
+CONFIG_DMA_CHANNELS=y
+CONFIG_TI_K3_NAVSS_UDMA=y
 CONFIG_TI_SCI_PROTOCOL=y
 CONFIG_DA8XX_GPIO=y
 CONFIG_DM_PCA953X=y
@@ -85,6 +88,7 @@ CONFIG_SPL_MMC_SDHCI_ADMA=y
 CONFIG_MMC_SDHCI_AM654=y
 CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
 CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_PINCTRL=y
 # CONFIG_PINCTRL_GENERIC is not set
@@ -100,9 +104,11 @@ CONFIG_SPL_DM_REGULATOR=y
 CONFIG_DM_REGULATOR_TPS65941=y
 CONFIG_K3_SYSTEM_CONTROLLER=y
 CONFIG_REMOTEPROC_TI_K3_ARM64=y
+CONFIG_REMOTEPROC_TI_K3_R5F=y
 CONFIG_DM_RESET=y
 CONFIG_RESET_TI_SCI=y
 CONFIG_DM_SERIAL=y
+CONFIG_SOC_TI=y
 CONFIG_SPI=y
 CONFIG_DM_SPI=y
 CONFIG_CADENCE_QSPI=y
@@ -126,3 +132,6 @@ CONFIG_USB_GADGET_PRODUCT_NUM=0x6163
 CONFIG_USB_GADGET_DOWNLOAD=y
 CONFIG_FS_EXT4=y
 CONFIG_FS_FAT_MAX_CLUSTSIZE=16384
+CONFIG_ESM_K3=y
+CONFIG_ESM_PMIC=y
+CONFIG_SPL_BOARD_INIT=y

+ 7 - 1
configs/j721e_hs_evm_a72_defconfig

@@ -36,6 +36,8 @@ CONFIG_SPL_DM_MAILBOX=y
 CONFIG_SPL_DM_RESET=y
 CONFIG_SPL_POWER_SUPPORT=y
 CONFIG_SPL_POWER_DOMAIN=y
+# CONFIG_SPL_SPI_FLASH_TINY is not set
+CONFIG_SPL_SPI_FLASH_SFDP_SUPPORT=y
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_SYS_SPI_U_BOOT_OFFS=0x280000
 CONFIG_SPL_YMODEM_SUPPORT=y
@@ -54,7 +56,8 @@ CONFIG_CMD_USB_MASS_STORAGE=y
 CONFIG_CMD_TIME=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_MTDIDS_DEFAULT="nor0=47040000.spi.0,nor0=47034000.hyperbus"
-CONFIG_MTDPARTS_DEFAULT="mtdparts=47034000.hyperbus:512k(hbmc.tiboot3),2m(hbmc.tispl),4m(hbmc.u-boot),256k(hbmc.env),1m(hbmc.sysfw),-@8m(hbmc.rootfs)"
+CONFIG_MTDPARTS_DEFAULT="mtdparts=47040000.spi.0:512k(ospi.tiboot3),2m(ospi.tispl),4m(ospi.u-boot),128k(ospi.env),128k(ospi.env.backup),1m(ospi.sysfw),-@8m(ospi.rootfs);47034000.hyperbus:512k(hbmc.tiboot3),2m(hbmc.tispl),4m(hbmc.u-boot),256k(hbmc.env),1m(hbmc.sysfw),-@8m(hbmc.rootfs)"
+CONFIG_CMD_UBI=y
 # CONFIG_ISO_PARTITION is not set
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_OF_CONTROL=y
@@ -107,7 +110,10 @@ CONFIG_FLASH_CFI_MTD=y
 CONFIG_SYS_FLASH_CFI=y
 CONFIG_HBMC_AM654=y
 CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT
 CONFIG_SPI_FLASH_STMICRO=y
+# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
+CONFIG_SPI_FLASH_MTD=y
 CONFIG_PHY_TI=y
 CONFIG_PHY_FIXED=y
 CONFIG_DM_ETH=y

+ 7 - 0
configs/j721e_hs_evm_r5_defconfig

@@ -28,6 +28,7 @@ CONFIG_USE_BOOTCOMMAND=y
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_SEPARATE_BSS=y
 CONFIG_SPL_EARLY_BSS=y
+CONFIG_SPL_DMA=y
 CONFIG_SPL_ENV_SUPPORT=y
 CONFIG_SPL_I2C_SUPPORT=y
 CONFIG_SPL_DM_MAILBOX=y
@@ -37,6 +38,8 @@ CONFIG_SPL_POWER_DOMAIN=y
 CONFIG_SPL_RAM_SUPPORT=y
 CONFIG_SPL_RAM_DEVICE=y
 CONFIG_SPL_REMOTEPROC=y
+# CONFIG_SPL_SPI_FLASH_TINY is not set
+CONFIG_SPL_SPI_FLASH_SFDP_SUPPORT=y
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_SYS_SPI_U_BOOT_OFFS=0x80000
 CONFIG_SPL_YMODEM_SUPPORT=y
@@ -63,6 +66,8 @@ CONFIG_SPL_OF_TRANSLATE=y
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
 CONFIG_CLK_TI_SCI=y
+CONFIG_DMA_CHANNELS=y
+CONFIG_TI_K3_NAVSS_UDMA=y
 CONFIG_TI_SCI_PROTOCOL=y
 CONFIG_DA8XX_GPIO=y
 CONFIG_DM_I2C=y
@@ -79,6 +84,7 @@ CONFIG_SPL_MMC_SDHCI_ADMA=y
 CONFIG_MMC_SDHCI_AM654=y
 CONFIG_MTD=y
 CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
 CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_PINCTRL=y
 # CONFIG_PINCTRL_GENERIC is not set
@@ -97,6 +103,7 @@ CONFIG_REMOTEPROC_TI_K3_ARM64=y
 CONFIG_DM_RESET=y
 CONFIG_RESET_TI_SCI=y
 CONFIG_DM_SERIAL=y
+CONFIG_SOC_TI=y
 CONFIG_SPI=y
 CONFIG_DM_SPI=y
 CONFIG_CADENCE_QSPI=y

+ 25 - 0
doc/device-tree-bindings/misc/esm-k3.txt

@@ -0,0 +1,25 @@
+Texas Instruments K3 ESM Binding
+======================
+
+ESM (Error Signaling Module) is an IP block on TI K3 devices that allows
+handling of safety events somewhat similar to what interrupt controller
+would do. The safety signals have their separate paths within the SoC,
+and they are handled by the ESM, which routes them to the proper
+destination, which can be system reset, interrupt controller, etc. In
+the simplest configuration the signals are just routed to reset the
+SoC.
+
+Required properties :
+- compatible	: "ti,j721e-esm"
+- ti,esm-pins	: integer array of esm events IDs to route to external event
+		  pin which can be used to reset the SoC. The array can
+		  have arbitrary amount of event IDs listed on it.
+
+Example
+=======
+
+	main_esm: esm@700000 {
+		compatible = "ti,j721e-esm";
+		reg = <0x0 0x700000 0x0 0x1000>;
+		ti,esm-pins = <344>, <345>;
+	};

+ 19 - 0
doc/device-tree-bindings/misc/esm-pmic.txt

@@ -0,0 +1,19 @@
+PMIC ESM Binding
+======================
+
+Certain Power Management ICs contain safety handling logic within them,
+allowing automatic reset of the board in case a safety error is signaled.
+For this purpose, ESM (Error Signal Monitor) is implemented within
+the PMIC running its own state machine.
+
+Required properties :
+- compatible	: "ti,tps659413-esm"
+
+Example
+=======
+
+&tps659413a {
+	esm: esm {
+		compatible = "ti,tps659413-esm";
+	};
+};

+ 66 - 0
doc/device-tree-bindings/video/tilcdc/panel.txt

@@ -0,0 +1,66 @@
+Device-Tree bindings for tilcdc DRM generic panel output driver
+
+Required properties:
+ - compatible: value should be "ti,tilcdc,panel".
+ - panel-info: configuration info to configure LCDC correctly for the panel
+   - ac-bias: AC Bias Pin Frequency
+   - ac-bias-intrpt: AC Bias Pin Transitions per Interrupt
+   - dma-burst-sz: DMA burst size
+   - bpp: Bits per pixel
+   - fdd: FIFO DMA Request Delay
+   - sync-edge: Horizontal and Vertical Sync Edge: 0=rising 1=falling
+   - sync-ctrl: Horizontal and Vertical Sync: Control: 0=ignore
+   - raster-order: Raster Data Order Select: 1=Most-to-least 0=Least-to-most
+   - fifo-th: DMA FIFO threshold
+ - display-timings: typical videomode of lcd panel.  Multiple video modes
+   can be listed if the panel supports multiple timings, but the 'native-mode'
+   should be the preferred/default resolution.  Refer to
+   Documentation/devicetree/bindings/display/panel/display-timing.txt for display
+   timing binding details.
+
+Optional properties:
+- backlight: phandle of the backlight device attached to the panel
+- enable-gpios: GPIO pin to enable or disable the panel
+
+Recommended properties:
+ - pinctrl-names, pinctrl-0: the pincontrol settings to configure
+   muxing properly for pins that connect to TFP410 device
+
+Example:
+
+	/* Settings for CDTech_S035Q01 / LCD3 cape: */
+	lcd3 {
+		compatible = "ti,tilcdc,panel";
+		pinctrl-names = "default";
+		pinctrl-0 = <&bone_lcd3_cape_lcd_pins>;
+		backlight = <&backlight>;
+		enable-gpios = <&gpio3 19 0>;
+
+		panel-info {
+			ac-bias           = <255>;
+			ac-bias-intrpt    = <0>;
+			dma-burst-sz      = <16>;
+			bpp               = <16>;
+			fdd               = <0x80>;
+			sync-edge         = <0>;
+			sync-ctrl         = <1>;
+			raster-order      = <0>;
+			fifo-th           = <0>;
+		};
+		display-timings {
+			native-mode = <&timing0>;
+			timing0: 320x240 {
+				hactive         = <320>;
+				vactive         = <240>;
+				hback-porch     = <21>;
+				hfront-porch    = <58>;
+				hsync-len       = <47>;
+				vback-porch     = <11>;
+				vfront-porch    = <23>;
+				vsync-len       = <2>;
+				clock-frequency = <8000000>;
+				hsync-active    = <0>;
+				vsync-active    = <0>;
+			};
+		};
+	};

+ 82 - 0
doc/device-tree-bindings/video/tilcdc/tilcdc.txt

@@ -0,0 +1,82 @@
+Device-Tree bindings for tilcdc DRM driver
+
+Required properties:
+ - compatible: value should be one of the following:
+    - "ti,am33xx-tilcdc" for AM335x based boards
+    - "ti,da850-tilcdc" for DA850/AM18x/OMAP-L138 based boards
+ - interrupts: the interrupt number
+ - reg: base address and size of the LCDC device
+
+Recommended properties:
+ - ti,hwmods: Name of the hwmod associated to the LCDC
+
+Optional properties:
+ - max-bandwidth: The maximum pixels per second that the memory
+   interface / lcd controller combination can sustain
+ - max-width: The maximum horizontal pixel width supported by
+   the lcd controller.
+ - max-pixelclock: The maximum pixel clock that can be supported
+   by the lcd controller in KHz.
+ - blue-and-red-wiring: Recognized values "straight" or "crossed".
+   This property deals with the LCDC revision 2 (found on AM335x)
+   color errata [1].
+    - "straight" indicates normal wiring that supports RGB565,
+      BGR888, and XBGR8888 color formats.
+    - "crossed" indicates wiring that has blue and red wires
+      crossed. This setup supports BGR565, RGB888 and XRGB8888
+      formats.
+    - If the property is not present or its value is not recognized
+      the legacy mode is assumed. This configuration supports RGB565,
+      RGB888 and XRGB8888 formats. However, depending on wiring, the red
+      and blue colors are swapped in either 16 or 24-bit color modes.
+
+Optional nodes:
+
+ - port/ports: to describe a connection to an external encoder. The
+   binding follows Documentation/devicetree/bindings/graph.txt and
+   supports a single port with a single endpoint.
+
+ - See also Documentation/devicetree/bindings/display/tilcdc/panel.txt and
+   Documentation/devicetree/bindings/display/tilcdc/tfp410.txt for connecting
+   tfp410 DVI encoder or lcd panel to lcdc
+
+[1] There is an errata about AM335x color wiring. For 16-bit color mode
+    the wires work as they should (LCD_DATA[0:4] is for Blue[3:7]),
+    but for 24 bit color modes the wiring of blue and red components is
+    crossed and LCD_DATA[0:4] is for Red[3:7] and LCD_DATA[11:15] is
+    for Blue[3-7]. For more details see section 3.1.1 in AM335x
+    Silicon Errata:
+    http://www.ti.com/general/docs/lit/getliterature.tsp?baseLiteratureNumber=sprz360
+
+Example:
+
+	fb: fb@4830e000 {
+		compatible = "ti,am33xx-tilcdc", "ti,da850-tilcdc";
+		reg = <0x4830e000 0x1000>;
+		interrupt-parent = <&intc>;
+		interrupts = <36>;
+		ti,hwmods = "lcdc";
+
+		blue-and-red-wiring = "crossed";
+
+		port {
+			lcdc_0: endpoint@0 {
+				remote-endpoint = <&hdmi_0>;
+			};
+		};
+	};
+
+	tda19988: tda19988 {
+		compatible = "nxp,tda998x";
+		reg = <0x70>;
+
+		pinctrl-names = "default", "off";
+		pinctrl-0 = <&nxp_hdmi_bonelt_pins>;
+		pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>;
+
+		port {
+			hdmi_0: endpoint@0 {
+				remote-endpoint = <&lcdc_0>;
+			};
+		};
+	};

+ 2 - 1
drivers/Makefile

@@ -107,7 +107,6 @@ obj-y += reset/
 obj-y += input/
 # SOC specific infrastructure drivers.
 obj-y += smem/
-obj-y += soc/
 obj-y += thermal/
 obj-$(CONFIG_TEE) += tee/
 obj-y += axi/
@@ -119,3 +118,5 @@ obj-$(CONFIG_MACH_PIC32) += ddr/microchip/
 obj-$(CONFIG_DM_HWSPINLOCK) += hwspinlock/
 obj-$(CONFIG_DM_RNG) += rng/
 endif
+
+obj-y += soc/

+ 3 - 4
drivers/dma/ti/k3-udma.c

@@ -938,7 +938,9 @@ static int udma_alloc_rchan_sci_req(struct udma_chan *uc)
 
 	req.valid_params = TI_SCI_MSG_VALUE_RM_UDMAP_CH_FETCH_SIZE_VALID |
 			TI_SCI_MSG_VALUE_RM_UDMAP_CH_CQ_QNUM_VALID |
-			TI_SCI_MSG_VALUE_RM_UDMAP_CH_CHAN_TYPE_VALID;
+			TI_SCI_MSG_VALUE_RM_UDMAP_CH_CHAN_TYPE_VALID |
+			TI_SCI_MSG_VALUE_RM_UDMAP_CH_RX_FLOWID_START_VALID |
+			TI_SCI_MSG_VALUE_RM_UDMAP_CH_RX_FLOWID_CNT_VALID;
 	req.nav_id = tisci_rm->tisci_dev_id;
 	req.index = uc->rchan->id;
 	req.rx_chan_type = mode;
@@ -954,9 +956,6 @@ static int udma_alloc_rchan_sci_req(struct udma_chan *uc)
 	if (uc->rflow->id != uc->rchan->id && uc->dir != DMA_MEM_TO_MEM) {
 		req.flowid_start = uc->rflow->id;
 		req.flowid_cnt = 1;
-		req.valid_params |=
-			TI_SCI_MSG_VALUE_RM_UDMAP_CH_RX_FLOWID_START_VALID |
-			TI_SCI_MSG_VALUE_RM_UDMAP_CH_RX_FLOWID_CNT_VALID;
 	}
 
 	ret = tisci_rm->tisci_udmap_ops->rx_ch_cfg(tisci_rm->tisci, &req);

+ 0 - 77
drivers/firmware/ti_sci.c

@@ -2364,82 +2364,6 @@ fail:
 	return ret;
 }
 
-/**
- * ti_sci_cmd_ring_get_config() - get RA ring configuration
- * @handle:	pointer to TI SCI handle
- * @nav_id: Device ID of Navigator Subsystem from which the ring is allocated
- * @index: Ring index.
- * @addr_lo: returns ring's base address lo 32 bits
- * @addr_hi: returns ring's base address hi 32 bits
- * @count: returns number of ring elements.
- * @mode: returns mode of the ring
- * @size: returns ring element size.
- * @order_id: returns ring's bus order ID.
- *
- * Return: 0 if all went well, else returns appropriate error value.
- *
- * See @ti_sci_msg_rm_ring_get_cfg_req for more info.
- */
-static int ti_sci_cmd_ring_get_config(const struct ti_sci_handle *handle,
-				      u32 nav_id, u32 index, u8 *mode,
-				      u32 *addr_lo, u32 *addr_hi,
-				      u32 *count, u8 *size, u8 *order_id)
-{
-	struct ti_sci_msg_rm_ring_get_cfg_resp *resp;
-	struct ti_sci_msg_rm_ring_get_cfg_req req;
-	struct ti_sci_xfer *xfer;
-	struct ti_sci_info *info;
-	int ret = 0;
-
-	if (IS_ERR(handle))
-		return PTR_ERR(handle);
-	if (!handle)
-		return -EINVAL;
-
-	info = handle_to_ti_sci_info(handle);
-
-	xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_RM_RING_GET_CFG,
-				     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
-				     (u32 *)&req, sizeof(req), sizeof(*resp));
-	if (IS_ERR(xfer)) {
-		ret = PTR_ERR(xfer);
-		dev_err(info->dev,
-			"RM_RA:Message get config failed(%d)\n", ret);
-		return ret;
-	}
-	req.nav_id = nav_id;
-	req.index = index;
-
-	ret = ti_sci_do_xfer(info, xfer);
-	if (ret) {
-		dev_err(info->dev, "RM_RA:Mbox get config send fail %d\n", ret);
-		goto fail;
-	}
-
-	resp = (struct ti_sci_msg_rm_ring_get_cfg_resp *)xfer->tx_message.buf;
-
-	if (!ti_sci_is_response_ack(resp)) {
-		ret = -ENODEV;
-	} else {
-		if (mode)
-			*mode = resp->mode;
-		if (addr_lo)
-			*addr_lo = resp->addr_lo;
-		if (addr_hi)
-			*addr_hi = resp->addr_hi;
-		if (count)
-			*count = resp->count;
-		if (size)
-			*size = resp->size;
-		if (order_id)
-			*order_id = resp->order_id;
-	};
-
-fail:
-	dev_dbg(info->dev, "RM_RA:get config ring %u ret:%d\n", index, ret);
-	return ret;
-}
-
 static int ti_sci_cmd_rm_psil_pair(const struct ti_sci_handle *handle,
 				   u32 nav_id, u32 src_thread, u32 dst_thread)
 {
@@ -2948,7 +2872,6 @@ static void ti_sci_setup_ops(struct ti_sci_info *info)
 	pops->proc_shutdown_no_wait = ti_sci_cmd_proc_shutdown_no_wait;
 
 	rops->config = ti_sci_cmd_ring_config;
-	rops->get_config = ti_sci_cmd_ring_get_config;
 
 	psilops->pair = ti_sci_cmd_rm_psil_pair;
 	psilops->unpair = ti_sci_cmd_rm_psil_unpair;

+ 0 - 5
drivers/firmware/ti_sci.h

@@ -58,7 +58,6 @@
 /* NAVSS resource management */
 /* Ringacc requests */
 #define TI_SCI_MSG_RM_RING_CFG			0x1110
-#define TI_SCI_MSG_RM_RING_GET_CFG		0x1111
 
 /* PSI-L requests */
 #define TI_SCI_MSG_RM_PSIL_PAIR			0x1280
@@ -72,13 +71,9 @@
 #define TI_SCI_MSG_RM_UDMAP_OPT_FLOW_CFG	0x1221
 
 #define TISCI_MSG_RM_UDMAP_TX_CH_CFG		0x1205
-#define TISCI_MSG_RM_UDMAP_TX_CH_GET_CFG	0x1206
 #define TISCI_MSG_RM_UDMAP_RX_CH_CFG		0x1215
-#define TISCI_MSG_RM_UDMAP_RX_CH_GET_CFG	0x1216
 #define TISCI_MSG_RM_UDMAP_FLOW_CFG		0x1230
 #define TISCI_MSG_RM_UDMAP_FLOW_SIZE_THRESH_CFG	0x1231
-#define TISCI_MSG_RM_UDMAP_FLOW_GET_CFG		0x1232
-#define TISCI_MSG_RM_UDMAP_FLOW_SIZE_THRESH_GET_CFG	0x1233
 
 #define TISCI_MSG_FWL_SET		0x9000
 #define TISCI_MSG_FWL_GET		0x9001

+ 12 - 0
drivers/misc/Kconfig

@@ -462,6 +462,11 @@ config IHS_FPGA
 	  gdsys devices, which supply the majority of the functionality offered
 	  by the devices. This driver supports both CON and CPU variants of the
 	  devices, depending on the device tree entry.
+config ESM_K3
+	bool "Enable K3 ESM driver"
+	depends on ARCH_K3
+	help
+	  Support ESM (Error Signaling Module) on TI K3 SoCs.
 
 config MICROCHIP_FLEXCOM
 	bool "Enable Microchip Flexcom driver"
@@ -481,4 +486,11 @@ config K3_AVS0
 	  optimized voltage from the efuse, so that it can be programmed
 	  to the PMIC on board.
 
+config ESM_PMIC
+	bool "Enable PMIC ESM driver"
+	depends on DM_PMIC
+	help
+	  Support ESM (Error Signal Monitor) on PMIC devices. ESM is used
+	  typically to reboot the board in error condition.
+
 endmenu

+ 2 - 0
drivers/misc/Makefile

@@ -72,3 +72,5 @@ obj-$(CONFIG_WINBOND_W83627) += winbond_w83627.o
 obj-$(CONFIG_JZ4780_EFUSE) += jz4780_efuse.o
 obj-$(CONFIG_MICROCHIP_FLEXCOM) += microchip_flexcom.o
 obj-$(CONFIG_K3_AVS0) += k3_avs.o
+obj-$(CONFIG_ESM_K3) += k3_esm.o
+obj-$(CONFIG_ESM_PMIC) += esm_pmic.o

+ 69 - 0
drivers/misc/esm_pmic.c

@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * PMIC Error Signal Monitor driver
+ *
+ * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
+ *      Tero Kristo <t-kristo@ti.com>
+ *
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <power/pmic.h>
+#include <dm/device_compat.h>
+
+#define INT_ESM_REG		0x6c
+#define INT_ESM_MASK		0x3f
+
+#define ESM_MCU_START_REG	0x8f
+
+#define ESM_MCU_START		BIT(0)
+
+#define ESM_MCU_MODE_CFG_REG	0x92
+
+#define ESM_MCU_EN		BIT(6)
+#define ESM_MCU_ENDRV		BIT(5)
+
+/**
+ * pmic_esm_probe: configures and enables PMIC ESM functionality
+ *
+ * Configures ESM PMIC support and enables it.
+ */
+static int pmic_esm_probe(struct udevice *dev)
+{
+	int ret;
+
+	ret = pmic_reg_write(dev->parent, INT_ESM_REG, INT_ESM_MASK);
+	if (ret) {
+		dev_err(dev, "clearing ESM irqs failed: %d\n", ret);
+		return ret;
+	}
+
+	ret = pmic_reg_write(dev->parent, ESM_MCU_MODE_CFG_REG,
+			     ESM_MCU_EN | ESM_MCU_ENDRV);
+	if (ret) {
+		dev_err(dev, "setting ESM mode failed: %d\n", ret);
+		return ret;
+	}
+
+	ret = pmic_reg_write(dev->parent, ESM_MCU_START_REG, ESM_MCU_START);
+	if (ret) {
+		dev_err(dev, "starting ESM failed: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct udevice_id pmic_esm_ids[] = {
+	{ .compatible = "ti,tps659413-esm" },
+	{}
+};
+
+U_BOOT_DRIVER(pmic_esm) = {
+	.name = "esm_pmic",
+	.of_match = pmic_esm_ids,
+	.id = UCLASS_MISC,
+	.probe = pmic_esm_probe,
+};

+ 6 - 6
drivers/misc/k3_avs.c

@@ -316,15 +316,15 @@ static struct vd_data am654_vd_data[] = {
 		.opp = AM6_OPP_NOM,
 		.opps = {
 			[AM6_OPP_NOM] = {
-				.volt = 1000000,
+				.volt = 1100000,
 				.freq = 800000000,
 			},
 			[AM6_OPP_OD] = {
-				.volt = 1100000,
+				.volt = 1200000,
 				.freq = 1000000000,
 			},
 			[AM6_OPP_TURBO] = {
-				.volt = 1220000,
+				.volt = 1240000,
 				.freq = 1100000000,
 			},
 		},
@@ -336,15 +336,15 @@ static struct vd_data am654_vd_data[] = {
 		.clk_id = 0, /* ARM clock */
 		.opps = {
 			[AM6_OPP_NOM] = {
-				.volt = 1000000,
+				.volt = 1100000,
 				.freq = 800000000,
 			},
 			[AM6_OPP_OD] = {
-				.volt = 1100000,
+				.volt = 1200000,
 				.freq = 1000000000,
 			},
 			[AM6_OPP_TURBO] = {
-				.volt = 1220000,
+				.volt = 1240000,
 				.freq = 1100000000,
 			},
 		},

+ 87 - 0
drivers/misc/k3_esm.c

@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Texas Instruments' K3 Error Signalling Module driver
+ *
+ * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
+ *      Tero Kristo <t-kristo@ti.com>
+ *
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <dm/device_compat.h>
+
+#define ESM_SFT_RST			0x0c
+#define ESM_SFT_RST_KEY			0x0f
+
+#define ESM_STS(i)			(0x404 + (i) / 32 * 0x20)
+#define ESM_PIN_EN_SET_OFFSET(i)	(0x414 + (i) / 32 * 0x20)
+#define ESM_PIN_MASK(i)			BIT((i) & 0x1f)
+
+static void esm_pin_enable(void __iomem *base, int pin)
+{
+	/* Enable event */
+	writel(ESM_PIN_MASK(pin), base + ESM_PIN_EN_SET_OFFSET(pin));
+}
+
+/**
+ * k3_esm_probe: configures ESM based on DT data
+ *
+ * Parses ESM info from device tree, and configures the module accordingly.
+ */
+static int k3_esm_probe(struct udevice *dev)
+{
+	int ret;
+	void __iomem *base;
+	int num_pins;
+	u32 *pins;
+	int i;
+
+	base = dev_remap_addr_index(dev, 0);
+	if (!base)
+		return -ENODEV;
+
+	num_pins = dev_read_size(dev, "ti,esm-pins");
+	if (num_pins < 0) {
+		dev_err(dev, "ti,esm-pins property missing or invalid: %d\n",
+			num_pins);
+		return num_pins;
+	}
+
+	num_pins /= sizeof(u32);
+
+	pins = kmalloc(num_pins * sizeof(u32), __GFP_ZERO);
+	if (!pins)
+		return -ENOMEM;
+
+	ret = dev_read_u32_array(dev, "ti,esm-pins", pins, num_pins);
+	if (ret < 0) {
+		dev_err(dev, "failed to read ti,esm-pins property: %d\n",
+			ret);
+		goto free_pins;
+	}
+
+	/* Clear any pending events */
+	writel(ESM_SFT_RST_KEY, base + ESM_SFT_RST);
+
+	for (i = 0; i < num_pins; i++)
+		esm_pin_enable(base, pins[i]);
+
+free_pins:
+	kfree(pins);
+	return ret;
+}
+
+static const struct udevice_id k3_esm_ids[] = {
+	{ .compatible = "ti,j721e-esm" },
+	{}
+};
+
+U_BOOT_DRIVER(k3_esm) = {
+	.name = "k3_esm",
+	.of_match = k3_esm_ids,
+	.id = UCLASS_MISC,
+	.probe = k3_esm_probe,
+};

+ 2 - 2
drivers/power/pmic/tps65941.c

@@ -59,8 +59,8 @@ static int tps65941_bind(struct udevice *dev)
 	if (!children)
 		printf("%s: %s - no child found\n", __func__, dev->name);
 
-	/* Always return success for this device */
-	return 0;
+	/* Probe all the child devices */
+	return dm_scan_fdt_dev(dev);
 }
 
 static struct dm_pmic_ops tps65941_ops = {

+ 115 - 13
drivers/remoteproc/ti_k3_dsp_rproc.c

@@ -2,9 +2,9 @@
 /*
  * Texas Instruments' K3 DSP Remoteproc driver
  *
- * Copyright (C) 2018-2019 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2018-2020 Texas Instruments Incorporated - http://www.ti.com/
  *	Lokesh Vutla <lokeshvutla@ti.com>
- *
+ *	Suman Anna <s-anna@ti.com>
  */
 
 #include <common.h>
@@ -18,6 +18,7 @@
 #include <power-domain.h>
 #include <dm/device_compat.h>
 #include <linux/err.h>
+#include <linux/sizes.h>
 #include <linux/soc/ti/ti_sci_protocol.h>
 #include "ti_sci_proc.h"
 
@@ -37,20 +38,80 @@ struct k3_dsp_mem {
 	size_t size;
 };
 
+/**
+ * struct k3_dsp_boot_data - internal data structure used for boot
+ * @boot_align_addr: Boot vector address alignment granularity
+ * @uses_lreset: Flag to denote the need for local reset management
+ */
+struct k3_dsp_boot_data {
+	u32 boot_align_addr;
+	bool uses_lreset;
+};
+
 /**
  * struct k3_dsp_privdata - Structure representing Remote processor data.
  * @rproc_rst:		rproc reset control data
  * @tsp:		Pointer to TISCI proc contrl handle
+ * @data:		Pointer to DSP specific boot data structure
  * @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_boot_data *data;
 	struct k3_dsp_mem *mem;
 	int num_mems;
 };
 
+/*
+ * The C66x DSP cores have a local reset that affects only the CPU, and a
+ * generic module reset that powers on the device and allows the DSP internal
+ * memories to be accessed while the local reset is asserted. This function is
+ * used to release the global reset on C66x DSPs to allow loading into the DSP
+ * internal RAMs. This helper function is invoked in k3_dsp_load() before any
+ * actual firmware loading and is undone only in k3_dsp_stop(). The local reset
+ * on C71x cores is a no-op and the global reset cannot be released on C71x
+ * cores until after the firmware images are loaded, so this function does
+ * nothing for C71x cores.
+ */
+static int k3_dsp_prepare(struct udevice *dev)
+{
+	struct k3_dsp_privdata *dsp = dev_get_priv(dev);
+	struct k3_dsp_boot_data *data = dsp->data;
+	int ret;
+
+	/* local reset is no-op on C71x processors */
+	if (!data->uses_lreset)
+		return 0;
+
+	ret = ti_sci_proc_power_domain_on(&dsp->tsp);
+	if (ret)
+		dev_err(dev, "cannot enable internal RAM loading, ret = %d\n",
+			ret);
+
+	return ret;
+}
+
+/*
+ * This function is the counterpart to k3_dsp_prepare() and is used to assert
+ * the global reset on C66x DSP cores (no-op for C71x DSP cores). This completes
+ * the second step of powering down the C66x DSP cores. The cores themselves
+ * are halted through the local reset in first step. This function is invoked
+ * in k3_dsp_stop() after the local reset is asserted.
+ */
+static int k3_dsp_unprepare(struct udevice *dev)
+{
+	struct k3_dsp_privdata *dsp = dev_get_priv(dev);
+	struct k3_dsp_boot_data *data = dsp->data;
+
+	/* local reset is no-op on C71x processors */
+	if (!data->uses_lreset)
+		return 0;
+
+	return ti_sci_proc_power_domain_off(&dsp->tsp);
+}
+
 /**
  * k3_dsp_load() - Load up the Remote processor image
  * @dev:	rproc device pointer
@@ -62,6 +123,7 @@ struct k3_dsp_privdata {
 static int k3_dsp_load(struct udevice *dev, ulong addr, ulong size)
 {
 	struct k3_dsp_privdata *dsp = dev_get_priv(dev);
+	struct k3_dsp_boot_data *data = dsp->data;
 	u32 boot_vector;
 	int ret;
 
@@ -70,17 +132,33 @@ static int k3_dsp_load(struct udevice *dev, ulong addr, ulong size)
 	if (ret)
 		return ret;
 
+	ret = k3_dsp_prepare(dev);
+	if (ret) {
+		dev_err(dev, "DSP prepare failed for core %d\n",
+			dsp->tsp.proc_id);
+		goto proc_release;
+	}
+
 	ret = rproc_elf_load_image(dev, addr, size);
 	if (ret < 0) {
 		dev_err(dev, "Loading elf failed %d\n", ret);
-		goto proc_release;
+		goto unprepare;
 	}
 
 	boot_vector = rproc_elf_get_boot_addr(dev, addr);
+	if (boot_vector & (data->boot_align_addr - 1)) {
+		ret = -EINVAL;
+		dev_err(dev, "Boot vector 0x%x not aligned on 0x%x boundary\n",
+			boot_vector, data->boot_align_addr);
+		goto proc_release;
+	}
 
 	dev_dbg(dev, "%s: Boot vector = 0x%x\n", __func__, boot_vector);
 
 	ret = ti_sci_proc_set_config(&dsp->tsp, boot_vector, 0, 0);
+unprepare:
+	if (ret)
+		k3_dsp_unprepare(dev);
 proc_release:
 	ti_sci_proc_release(&dsp->tsp);
 	return ret;
@@ -95,6 +173,7 @@ proc_release:
 static int k3_dsp_start(struct udevice *dev)
 {
 	struct k3_dsp_privdata *dsp = dev_get_priv(dev);
+	struct k3_dsp_boot_data *data = dsp->data;
 	int ret;
 
 	dev_dbg(dev, "%s\n", __func__);
@@ -102,16 +181,18 @@ static int k3_dsp_start(struct udevice *dev)
 	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;
+
+	if (!data->uses_lreset) {
+		ret = ti_sci_proc_power_domain_on(&dsp->tsp);
+		if (ret)
+			goto proc_release;
+	}
 
 	ret = reset_deassert(&dsp->dsp_rst);
+	if (ret) {
+		if (!data->uses_lreset)
+			ti_sci_proc_power_domain_off(&dsp->tsp);
+	}
 
 proc_release:
 	ti_sci_proc_release(&dsp->tsp);
@@ -302,6 +383,8 @@ static int k3_dsp_of_to_priv(struct udevice *dev, struct k3_dsp_privdata *dsp)
 	if (ret)
 		return ret;
 
+	dsp->data = (struct k3_dsp_boot_data *)dev_get_driver_data(dev);
+
 	return 0;
 }
 
@@ -326,6 +409,15 @@ static int k3_dsp_probe(struct udevice *dev)
 		return ret;
 	}
 
+	/*
+	 * The DSP local resets are deasserted by default on Power-On-Reset.
+	 * Assert the local resets to ensure the DSPs don't execute bogus code
+	 * in .load() callback when the module reset is released to support
+	 * internal memory loading. This is needed for C66x DSPs, and is a
+	 * no-op on C71x DSPs.
+	 */
+	reset_assert(&dsp->dsp_rst);
+
 	dev_dbg(dev, "Remoteproc successfully probed\n");
 
 	return 0;
@@ -340,9 +432,19 @@ static int k3_dsp_remove(struct udevice *dev)
 	return 0;
 }
 
+static const struct k3_dsp_boot_data c66_data = {
+	.boot_align_addr = SZ_1K,
+	.uses_lreset = true,
+};
+
+static const struct k3_dsp_boot_data c71_data = {
+	.boot_align_addr = SZ_2M,
+	.uses_lreset = false,
+};
+
 static const struct udevice_id k3_dsp_ids[] = {
-	{ .compatible = "ti,j721e-c66-dsp"},
-	{ .compatible = "ti,j721e-c71-dsp"},
+	{ .compatible = "ti,j721e-c66-dsp", .data = (ulong)&c66_data, },
+	{ .compatible = "ti,j721e-c71-dsp", .data = (ulong)&c71_data, },
 	{}
 };
 

+ 6 - 3
drivers/remoteproc/ti_k3_r5f_rproc.c

@@ -543,6 +543,7 @@ 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;
+	bool lockstep_permitted;
 	u64 boot_vec = 0;
 	int ret;
 
@@ -560,8 +561,9 @@ static int k3_r5f_rproc_configure(struct k3_r5f_core *core)
 		goto out;
 
 	/* Sanity check for Lockstep mode */
-	if (cluster->mode && is_primary_core(core) &&
-	    !(sts & PROC_BOOT_STATUS_FLAG_R5_LOCKSTEP_PERMITTED)) {
+	lockstep_permitted = !!(sts &
+				PROC_BOOT_STATUS_FLAG_R5_LOCKSTEP_PERMITTED);
+	if (cluster->mode && is_primary_core(core) && !lockstep_permitted) {
 		dev_err(core->dev, "LockStep mode not permitted on this device\n");
 		ret = -EINVAL;
 		goto out;
@@ -573,7 +575,7 @@ static int k3_r5f_rproc_configure(struct k3_r5f_core *core)
 		clr_cfg |= PROC_BOOT_CFG_FLAG_R5_TEINIT;
 		if (cluster->mode == CLUSTER_MODE_LOCKSTEP)
 			set_cfg |= PROC_BOOT_CFG_FLAG_R5_LOCKSTEP;
-		else
+		else if (lockstep_permitted)
 			clr_cfg |= PROC_BOOT_CFG_FLAG_R5_LOCKSTEP;
 	}
 
@@ -816,4 +818,5 @@ U_BOOT_DRIVER(k3_r5fss) = {
 	.id = UCLASS_MISC,
 	.probe = k3_r5f_cluster_probe,
 	.priv_auto_alloc_size = sizeof(struct k3_r5f_cluster),
+	.flags = DM_FLAG_DEFAULT_PD_CTRL_OFF,
 };

+ 6 - 0
drivers/video/Kconfig

@@ -473,6 +473,12 @@ config ATMEL_HLCD
 	help
 	   HLCDC supports video output to an attached LCD panel.
 
+config AM335X_LCD
+	bool "Enable AM335x video support"
+	depends on DM_VIDEO
+	help
+	   Supports video output to an attached LCD panel.
+
 config LOGICORE_DP_TX
 	bool "Enable Logicore DP TX driver"
 	depends on DISPLAY

+ 475 - 92
drivers/video/am335x-fb.c

@@ -2,6 +2,7 @@
 /*
  * Copyright (C) 2013-2018 Hannes Schmelzer <oe5hpm@oevsv.at>
  * B&R Industrial Automation GmbH - http://www.br-automation.com
+ * Copyright (C) 2020 Dario Binacchi <dariobin@libero.it>
  *
  * minimal framebuffer driver for TI's AM335x SoC to be compatible with
  * Wolfgang Denk's LCD-Framework (CONFIG_LCD, common/lcd.c)
@@ -11,61 +12,69 @@
  * - starts output DMA from gd->fb_base buffer
  */
 #include <common.h>
+#include <dm.h>
 #include <asm/io.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/omap.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/sys_proto.h>
+#include <asm/utils.h>
+#include <linux/err.h>
 #include <lcd.h>
+#include <video.h>
 #include "am335x-fb.h"
 
-#if !defined(LCD_CNTL_BASE)
-#error "hw-base address of LCD-Controller (LCD_CNTL_BASE) not defined!"
-#endif
-
 #define LCDC_FMAX				200000000
 
 /* LCD Control Register */
-#define LCD_CLK_DIVISOR(x)			((x) << 8)
-#define LCD_RASTER_MODE				0x01
+#define LCDC_CTRL_CLK_DIVISOR_MASK		GENMASK(15, 8)
+#define LCDC_CTRL_RASTER_MODE			BIT(0)
+#define LCDC_CTRL_CLK_DIVISOR(x)		(((x) & GENMASK(7, 0)) << 8)
 /* LCD Clock Enable Register */
-#define LCD_CORECLKEN				(0x01 << 0)
-#define LCD_LIDDCLKEN				(0x01 << 1)
-#define LCD_DMACLKEN				(0x01 << 2)
+#define LCDC_CLKC_ENABLE_CORECLKEN		BIT(0)
+#define LCDC_CLKC_ENABLE_LIDDCLKEN		BIT(1)
+#define LCDC_CLKC_ENABLE_DMACLKEN		BIT(2)
 /* LCD DMA Control Register */
-#define LCD_DMA_BURST_SIZE(x)			((x) << 4)
-#define LCD_DMA_BURST_1				0x0
-#define LCD_DMA_BURST_2				0x1
-#define LCD_DMA_BURST_4				0x2
-#define LCD_DMA_BURST_8				0x3
-#define LCD_DMA_BURST_16			0x4
+#define LCDC_DMA_CTRL_BURST_SIZE(x)		(((x) & GENMASK(2, 0)) << 4)
+#define LCDC_DMA_CTRL_BURST_1			0x0
+#define LCDC_DMA_CTRL_BURST_2			0x1
+#define LCDC_DMA_CTRL_BURST_4			0x2
+#define LCDC_DMA_CTRL_BURST_8			0x3
+#define LCDC_DMA_CTRL_BURST_16			0x4
+#define LCDC_DMA_CTRL_FIFO_TH(x)		(((x) & GENMASK(2, 0)) << 8)
 /* LCD Timing_0 Register */
-#define LCD_HBPLSB(x)				((((x)-1) & 0xFF) << 24)
-#define LCD_HFPLSB(x)				((((x)-1) & 0xFF) << 16)
-#define LCD_HSWLSB(x)				((((x)-1) & 0x3F) << 10)
-#define LCD_HORLSB(x)				(((((x) >> 4)-1) & 0x3F) << 4)
-#define LCD_HORMSB(x)				(((((x) >> 4)-1) & 0x40) >> 4)
+#define LCDC_RASTER_TIMING_0_HORMSB(x)	((((x) - 1) & BIT(10)) >> 7)
+#define LCDC_RASTER_TIMING_0_HORLSB(x) (((((x) >> 4) - 1) & GENMASK(5, 0)) << 4)
+#define LCDC_RASTER_TIMING_0_HSWLSB(x)	((((x) - 1) & GENMASK(5, 0)) << 10)
+#define LCDC_RASTER_TIMING_0_HFPLSB(x)	((((x) - 1) & GENMASK(7, 0)) << 16)
+#define LCDC_RASTER_TIMING_0_HBPLSB(x)	((((x) - 1) & GENMASK(7, 0)) << 24)
 /* LCD Timing_1 Register */
-#define LCD_VBP(x)				((x) << 24)
-#define LCD_VFP(x)				((x) << 16)
-#define LCD_VSW(x)				(((x)-1) << 10)
-#define LCD_VERLSB(x)				(((x)-1) & 0x3FF)
+#define LCDC_RASTER_TIMING_1_VERLSB(x)		(((x) - 1) & GENMASK(9, 0))
+#define LCDC_RASTER_TIMING_1_VSW(x)	((((x) - 1) & GENMASK(5, 0)) << 10)
+#define LCDC_RASTER_TIMING_1_VFP(x)		(((x) & GENMASK(7, 0)) << 16)
+#define LCDC_RASTER_TIMING_1_VBP(x)		(((x) & GENMASK(7, 0)) << 24)
 /* LCD Timing_2 Register */
-#define LCD_HSWMSB(x)				((((x)-1) & 0x3C0) << 21)
-#define LCD_VERMSB(x)				((((x)-1) & 0x400) << 16)
-#define LCD_HBPMSB(x)				((((x)-1) & 0x300) >> 4)
-#define LCD_HFPMSB(x)				((((x)-1) & 0x300) >> 8)
-#define LCD_INVMASK(x)				((x) & 0x3F00000)
+#define LCDC_RASTER_TIMING_2_HFPMSB(x)	((((x) - 1) & GENMASK(9, 8)) >> 8)
+#define LCDC_RASTER_TIMING_2_HBPMSB(x)	((((x) - 1) & GENMASK(9, 8)) >> 4)
+#define LCDC_RASTER_TIMING_2_ACB(x)		(((x) & GENMASK(7, 0)) << 8)
+#define LCDC_RASTER_TIMING_2_ACBI(x)		(((x) & GENMASK(3, 0)) << 16)
+#define LCDC_RASTER_TIMING_2_VSYNC_INVERT	BIT(20)
+#define LCDC_RASTER_TIMING_2_HSYNC_INVERT	BIT(21)
+#define LCDC_RASTER_TIMING_2_PXCLK_INVERT	BIT(22)
+#define LCDC_RASTER_TIMING_2_DE_INVERT		BIT(23)
+#define LCDC_RASTER_TIMING_2_HSVS_RISEFALL	BIT(24)
+#define LCDC_RASTER_TIMING_2_HSVS_CONTROL	BIT(25)
+#define LCDC_RASTER_TIMING_2_VERMSB(x)		((((x) - 1) & BIT(10)) << 16)
+#define LCDC_RASTER_TIMING_2_HSWMSB(x)	((((x) - 1) & GENMASK(9, 6)) << 21)
 /* LCD Raster Ctrl Register */
-#define LCD_TFT_24BPP_MODE			(1 << 25)
-#define LCD_TFT_24BPP_UNPACK			(1 << 26)
-#define LCD_PALMODE_RAWDATA			(0x02 << 20)
-#define LCD_TFT_MODE				(0x01 << 7)
-#define LCD_RASTER_ENABLE			(0x01 << 0)
-
-
-/* Macro definitions */
-#define FBSIZE(x)	((x->hactive * x->vactive * x->bpp) >> 3)
+#define LCDC_RASTER_CTRL_ENABLE			BIT(0)
+#define LCDC_RASTER_CTRL_TFT_MODE		BIT(7)
+#define LCDC_RASTER_CTRL_DATA_ORDER		BIT(8)
+#define LCDC_RASTER_CTRL_REQDLY(x)		(((x) & GENMASK(7, 0)) << 12)
+#define LCDC_RASTER_CTRL_PALMODE_RAWDATA	(0x02 << 20)
+#define LCDC_RASTER_CTRL_TFT_ALT_ENABLE		BIT(23)
+#define LCDC_RASTER_CTRL_TFT_24BPP_MODE		BIT(25)
+#define LCDC_RASTER_CTRL_TFT_24BPP_UNPACK	BIT(26)
 
 struct am335x_lcdhw {
 	unsigned int		pid;			/* 0x00 */
@@ -99,10 +108,106 @@ struct am335x_lcdhw {
 	unsigned int		clkc_reset;		/* 0x70 */
 };
 
-static struct am335x_lcdhw *lcdhw = (void *)LCD_CNTL_BASE;
+struct dpll_data {
+	unsigned long rounded_rate;
+	u16 rounded_m;
+	u8 rounded_n;
+	u8 rounded_div;
+};
 
 DECLARE_GLOBAL_DATA_PTR;
 
+/**
+ * am335x_dpll_round_rate() - Round a target rate for an OMAP DPLL
+ *
+ * @dpll_data: struct dpll_data pointer for the DPLL
+ * @rate:      New DPLL clock rate
+ * @return rounded rate and the computed m, n and div values in the dpll_data
+ *         structure, or -ve error code.
+ */
+static ulong am335x_dpll_round_rate(struct dpll_data *dd, ulong rate)
+{
+	unsigned int m, n, d;
+	unsigned long rounded_rate;
+	int err, err_r;
+
+	dd->rounded_rate = -EFAULT;
+	err = rate;
+	err_r = err;
+
+	for (d = 2; err && d < 255; d++) {
+		for (m = 2; m < 2047; m++) {
+			if ((V_OSCK * m) < (rate * d))
+				continue;
+
+			n = (V_OSCK * m) / (rate * d);
+			if (n > 127)
+				break;
+
+			if (((V_OSCK * m) / n) > LCDC_FMAX)
+				break;
+
+			rounded_rate = (V_OSCK * m) / n / d;
+			err = abs(rounded_rate - rate);
+			if (err < err_r) {
+				err_r = err;
+				dd->rounded_rate = rounded_rate;
+				dd->rounded_m = m;
+				dd->rounded_n = n;
+				dd->rounded_div = d;
+				if (err == 0)
+					break;
+			}
+		}
+	}
+
+	debug("DPLL display: best error %d Hz (M %d, N %d, DIV %d)\n",
+	      err_r, dd->rounded_m, dd->rounded_n, dd->rounded_div);
+
+	return dd->rounded_rate;
+}
+
+/**
+ * am335x_fb_set_pixel_clk_rate() - Set pixel clock rate.
+ *
+ * @am335x_lcdhw: Base address of the LCD controller registers.
+ * @rate:         New clock rate in Hz.
+ * @return new rate, or -ve error code.
+ */
+static ulong am335x_fb_set_pixel_clk_rate(struct am335x_lcdhw *regs, ulong rate)
+{
+	struct dpll_params dpll_disp = { 1, 0, 1, -1, -1, -1, -1 };
+	struct dpll_data dd;
+	ulong round_rate;
+	u32 reg;
+
+	round_rate = am335x_dpll_round_rate(&dd, rate);
+	if (IS_ERR_VALUE(round_rate))
+		return round_rate;
+
+	dpll_disp.m = dd.rounded_m;
+	dpll_disp.n = dd.rounded_n;
+	do_setup_dpll(&dpll_disp_regs, &dpll_disp);
+
+	reg = readl(&regs->ctrl) & ~LCDC_CTRL_CLK_DIVISOR_MASK;
+	reg |= LCDC_CTRL_CLK_DIVISOR(dd.rounded_div);
+	writel(reg, &regs->ctrl);
+	return round_rate;
+}
+
+#if !CONFIG_IS_ENABLED(DM_VIDEO)
+
+#if !defined(LCD_CNTL_BASE)
+#error "hw-base address of LCD-Controller (LCD_CNTL_BASE) not defined!"
+#endif
+
+/* Macro definitions */
+#define FBSIZE(x)	(((x)->hactive * (x)->vactive * (x)->bpp) >> 3)
+
+#define LCDC_RASTER_TIMING_2_INVMASK(x)		((x) & GENMASK(25, 20))
+
+static struct am335x_lcdhw *lcdhw = (void *)LCD_CNTL_BASE;
+
 int lcd_get_size(int *line_length)
 {
 	*line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8;
@@ -112,11 +217,9 @@ int lcd_get_size(int *line_length)
 int am335xfb_init(struct am335x_lcdpanel *panel)
 {
 	u32 raster_ctrl = 0;
-
 	struct cm_dpll *const cmdpll = (struct cm_dpll *)CM_DPLL;
-	struct dpll_params dpll_disp = { 1, 0, 1, -1, -1, -1, -1 };
-	unsigned int m, n, d, best_d = 2;
-	int err = 0, err_r = 0;
+	ulong rate;
+	u32 reg;
 
 	if (gd->fb_base == 0) {
 		printf("ERROR: no valid fb_base stored in GLOBAL_DATA_PTR!\n");
@@ -132,10 +235,10 @@ int am335xfb_init(struct am335x_lcdpanel *panel)
 	case 16:
 		break;
 	case 32:
-		raster_ctrl |= LCD_TFT_24BPP_UNPACK;
+		raster_ctrl |= LCDC_RASTER_CTRL_TFT_24BPP_UNPACK;
 		/* fallthrough */
 	case 24:
-		raster_ctrl |= LCD_TFT_24BPP_MODE;
+		raster_ctrl |= LCDC_RASTER_CTRL_TFT_24BPP_MODE;
 		break;
 	default:
 		pr_err("am335x-fb: invalid bpp value: %d\n", panel->bpp);
@@ -157,32 +260,9 @@ int am335xfb_init(struct am335x_lcdpanel *panel)
 	debug("using frambuffer at 0x%08x with size %d.\n",
 	      (unsigned int)gd->fb_base, FBSIZE(panel));
 
-	/* setup display pll for requested clock frequency */
-	err = panel->pxl_clk;
-	err_r = err;
-
-	for (d = 2; d < 255; d++) {
-		for (m = 2; m < 2047; m++) {
-			if ((V_OSCK * m) < (panel->pxl_clk * d))
-				continue;
-			n = (V_OSCK * m) / (panel->pxl_clk * d);
-			if (n > 127)
-				break;
-			if (((V_OSCK * m) / n) > LCDC_FMAX)
-				break;
-
-			err = abs((V_OSCK * m) / n / d - panel->pxl_clk);
-			if (err < err_r) {
-				err_r = err;
-				dpll_disp.m = m;
-				dpll_disp.n = n;
-				best_d = d;
-			}
-		}
-	}
-	debug("%s: PLL: best error %d Hz (M %d, N %d, DISP %d)\n",
-	      __func__, err_r, dpll_disp.m, dpll_disp.n, best_d);
-	do_setup_dpll(&dpll_disp_regs, &dpll_disp);
+	rate = am335x_fb_set_pixel_clk_rate(lcdhw, panel->pxl_clk);
+	if (IS_ERR_VALUE(rate))
+		return rate;
 
 	/* clock source for LCDC from dispPLL M2 */
 	writel(0x0, &cmdpll->clklcdcpixelclk);
@@ -199,37 +279,340 @@ int am335xfb_init(struct am335x_lcdpanel *panel)
 
 	debug("am335x-fb: wait for stable power ...\n");
 	mdelay(panel->pup_delay);
-	lcdhw->clkc_enable = LCD_CORECLKEN | LCD_LIDDCLKEN | LCD_DMACLKEN;
+	lcdhw->clkc_enable = LCDC_CLKC_ENABLE_CORECLKEN |
+		LCDC_CLKC_ENABLE_LIDDCLKEN | LCDC_CLKC_ENABLE_DMACLKEN;
 	lcdhw->raster_ctrl = 0;
-	lcdhw->ctrl = LCD_CLK_DIVISOR(best_d) | LCD_RASTER_MODE;
+
+	reg = lcdhw->ctrl & LCDC_CTRL_CLK_DIVISOR_MASK;
+	reg |= LCDC_CTRL_RASTER_MODE;
+	lcdhw->ctrl = reg;
+
 	lcdhw->lcddma_fb0_base = gd->fb_base;
 	lcdhw->lcddma_fb0_ceiling = gd->fb_base + FBSIZE(panel);
 	lcdhw->lcddma_fb1_base = gd->fb_base;
 	lcdhw->lcddma_fb1_ceiling = gd->fb_base + FBSIZE(panel);
-	lcdhw->lcddma_ctrl = LCD_DMA_BURST_SIZE(LCD_DMA_BURST_16);
-
-	lcdhw->raster_timing0 = LCD_HORLSB(panel->hactive) |
-				LCD_HORMSB(panel->hactive) |
-				LCD_HFPLSB(panel->hfp) |
-				LCD_HBPLSB(panel->hbp) |
-				LCD_HSWLSB(panel->hsw);
-	lcdhw->raster_timing1 = LCD_VBP(panel->vbp) |
-				LCD_VFP(panel->vfp) |
-				LCD_VSW(panel->vsw) |
-				LCD_VERLSB(panel->vactive);
-	lcdhw->raster_timing2 = LCD_HSWMSB(panel->hsw) |
-				LCD_VERMSB(panel->vactive) |
-				LCD_INVMASK(panel->pol) |
-				LCD_HBPMSB(panel->hbp) |
-				LCD_HFPMSB(panel->hfp) |
+	lcdhw->lcddma_ctrl = LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_16);
+
+	lcdhw->raster_timing0 = LCDC_RASTER_TIMING_0_HORLSB(panel->hactive) |
+				LCDC_RASTER_TIMING_0_HORMSB(panel->hactive) |
+				LCDC_RASTER_TIMING_0_HFPLSB(panel->hfp) |
+				LCDC_RASTER_TIMING_0_HBPLSB(panel->hbp) |
+				LCDC_RASTER_TIMING_0_HSWLSB(panel->hsw);
+	lcdhw->raster_timing1 = LCDC_RASTER_TIMING_1_VBP(panel->vbp) |
+				LCDC_RASTER_TIMING_1_VFP(panel->vfp) |
+				LCDC_RASTER_TIMING_1_VSW(panel->vsw) |
+				LCDC_RASTER_TIMING_1_VERLSB(panel->vactive);
+	lcdhw->raster_timing2 = LCDC_RASTER_TIMING_2_HSWMSB(panel->hsw) |
+				LCDC_RASTER_TIMING_2_VERMSB(panel->vactive) |
+				LCDC_RASTER_TIMING_2_INVMASK(panel->pol) |
+				LCDC_RASTER_TIMING_2_HBPMSB(panel->hbp) |
+				LCDC_RASTER_TIMING_2_HFPMSB(panel->hfp) |
 				0x0000FF00;	/* clk cycles for ac-bias */
 	lcdhw->raster_ctrl =	raster_ctrl |
-				LCD_PALMODE_RAWDATA |
-				LCD_TFT_MODE |
-				LCD_RASTER_ENABLE;
+				LCDC_RASTER_CTRL_PALMODE_RAWDATA |
+				LCDC_RASTER_CTRL_TFT_MODE |
+				LCDC_RASTER_CTRL_ENABLE;
 
 	debug("am335x-fb: waiting picture to be stable.\n.");
 	mdelay(panel->pon_delay);
 
 	return 0;
 }
+
+#else /* CONFIG_DM_VIDEO */
+
+#define FBSIZE(t, p)	(((t)->hactive.typ * (t)->vactive.typ * (p)->bpp) >> 3)
+
+enum {
+	LCD_MAX_WIDTH		= 2048,
+	LCD_MAX_HEIGHT		= 2048,
+	LCD_MAX_LOG2_BPP	= VIDEO_BPP32,
+};
+
+/**
+ * tilcdc_panel_info: Panel parameters
+ *
+ * @ac_bias: AC Bias Pin Frequency
+ * @ac_bias_intrpt: AC Bias Pin Transitions per Interrupt
+ * @dma_burst_sz: DMA burst size
+ * @bpp: Bits per pixel
+ * @fdd: FIFO DMA Request Delay
+ * @tft_alt_mode: TFT Alternative Signal Mapping (Only for active)
+ * @invert_pxl_clk: Invert pixel clock
+ * @sync_edge: Horizontal and Vertical Sync Edge: 0=rising 1=falling
+ * @sync_ctrl: Horizontal and Vertical Sync: Control: 0=ignore
+ * @raster_order: Raster Data Order Select: 1=Most-to-least 0=Least-to-most
+ * @fifo_th: DMA FIFO threshold
+ */
+struct tilcdc_panel_info {
+	u32 ac_bias;
+	u32 ac_bias_intrpt;
+	u32 dma_burst_sz;
+	u32 bpp;
+	u32 fdd;
+	bool tft_alt_mode;
+	bool invert_pxl_clk;
+	u32 sync_edge;
+	u32 sync_ctrl;
+	u32 raster_order;
+	u32 fifo_th;
+};
+
+struct am335x_fb_priv {
+	struct am335x_lcdhw *regs;
+	struct tilcdc_panel_info panel;
+	struct display_timing timing;
+};
+
+static int am335x_fb_remove(struct udevice *dev)
+{
+	struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
+
+	uc_plat->base -= 0x20;
+	uc_plat->size += 0x20;
+	return 0;
+}
+
+static int am335x_fb_probe(struct udevice *dev)
+{
+	struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
+	struct video_priv *uc_priv = dev_get_uclass_priv(dev);
+	struct am335x_fb_priv *priv = dev_get_priv(dev);
+	struct am335x_lcdhw *regs = priv->regs;
+	struct tilcdc_panel_info *panel = &priv->panel;
+	struct display_timing *timing = &priv->timing;
+	struct cm_dpll *const cmdpll = (struct cm_dpll *)CM_DPLL;
+	u32 reg;
+
+	/* Before relocation we don't need to do anything */
+	if (!(gd->flags & GD_FLG_RELOC))
+		return 0;
+
+	am335x_fb_set_pixel_clk_rate(regs, timing->pixelclock.typ);
+
+	/* clock source for LCDC from dispPLL M2 */
+	writel(0, &cmdpll->clklcdcpixelclk);
+
+	/* palette default entry */
+	memset((void *)uc_plat->base, 0, 0x20);
+	*(unsigned int *)uc_plat->base = 0x4000;
+	/* point fb behind palette */
+	uc_plat->base += 0x20;
+	uc_plat->size -= 0x20;
+
+	writel(LCDC_CLKC_ENABLE_CORECLKEN | LCDC_CLKC_ENABLE_LIDDCLKEN |
+	       LCDC_CLKC_ENABLE_DMACLKEN, &regs->clkc_enable);
+	writel(0, &regs->raster_ctrl);
+
+	reg = readl(&regs->ctrl) & LCDC_CTRL_CLK_DIVISOR_MASK;
+	reg |= LCDC_CTRL_RASTER_MODE;
+	writel(reg, &regs->ctrl);
+
+	writel(uc_plat->base, &regs->lcddma_fb0_base);
+	writel(uc_plat->base + FBSIZE(timing, panel),
+	       &regs->lcddma_fb0_ceiling);
+	writel(uc_plat->base, &regs->lcddma_fb1_base);
+	writel(uc_plat->base + FBSIZE(timing, panel),
+	       &regs->lcddma_fb1_ceiling);
+
+	reg = LCDC_DMA_CTRL_FIFO_TH(panel->fifo_th);
+	switch (panel->dma_burst_sz) {
+	case 1:
+		reg |= LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_1);
+		break;
+	case 2:
+		reg |= LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_2);
+		break;
+	case 4:
+		reg |= LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_4);
+		break;
+	case 8:
+		reg |= LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_8);
+		break;
+	case 16:
+		reg |= LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_16);
+		break;
+	}
+
+	writel(reg, &regs->lcddma_ctrl);
+
+	writel(LCDC_RASTER_TIMING_0_HORLSB(timing->hactive.typ) |
+	       LCDC_RASTER_TIMING_0_HORMSB(timing->hactive.typ) |
+	       LCDC_RASTER_TIMING_0_HFPLSB(timing->hfront_porch.typ) |
+	       LCDC_RASTER_TIMING_0_HBPLSB(timing->hback_porch.typ) |
+	       LCDC_RASTER_TIMING_0_HSWLSB(timing->hsync_len.typ),
+	       &regs->raster_timing0);
+
+	writel(LCDC_RASTER_TIMING_1_VBP(timing->vback_porch.typ) |
+	       LCDC_RASTER_TIMING_1_VFP(timing->vfront_porch.typ) |
+	       LCDC_RASTER_TIMING_1_VSW(timing->vsync_len.typ) |
+	       LCDC_RASTER_TIMING_1_VERLSB(timing->vactive.typ),
+	       &regs->raster_timing1);
+
+	reg = LCDC_RASTER_TIMING_2_ACB(panel->ac_bias) |
+		LCDC_RASTER_TIMING_2_ACBI(panel->ac_bias_intrpt) |
+		LCDC_RASTER_TIMING_2_HSWMSB(timing->hsync_len.typ) |
+		LCDC_RASTER_TIMING_2_VERMSB(timing->vactive.typ) |
+		LCDC_RASTER_TIMING_2_HBPMSB(timing->hback_porch.typ) |
+		LCDC_RASTER_TIMING_2_HFPMSB(timing->hfront_porch.typ);
+
+	if (timing->flags & DISPLAY_FLAGS_VSYNC_LOW)
+		reg |= LCDC_RASTER_TIMING_2_VSYNC_INVERT;
+
+	if (timing->flags & DISPLAY_FLAGS_HSYNC_LOW)
+		reg |= LCDC_RASTER_TIMING_2_HSYNC_INVERT;
+
+	if (panel->invert_pxl_clk)
+		reg |= LCDC_RASTER_TIMING_2_PXCLK_INVERT;
+
+	if (panel->sync_edge)
+		reg |= LCDC_RASTER_TIMING_2_HSVS_RISEFALL;
+
+	if (panel->sync_ctrl)
+		reg |= LCDC_RASTER_TIMING_2_HSVS_CONTROL;
+
+	writel(reg, &regs->raster_timing2);
+
+	reg = LCDC_RASTER_CTRL_PALMODE_RAWDATA | LCDC_RASTER_CTRL_TFT_MODE |
+		LCDC_RASTER_CTRL_ENABLE | LCDC_RASTER_CTRL_REQDLY(panel->fdd);
+
+	if (panel->tft_alt_mode)
+		reg |= LCDC_RASTER_CTRL_TFT_ALT_ENABLE;
+
+	if (panel->bpp == 24)
+		reg |= LCDC_RASTER_CTRL_TFT_24BPP_MODE;
+	else if (panel->bpp == 32)
+		reg |= LCDC_RASTER_CTRL_TFT_24BPP_MODE |
+			LCDC_RASTER_CTRL_TFT_24BPP_UNPACK;
+
+	if (panel->raster_order)
+		reg |= LCDC_RASTER_CTRL_DATA_ORDER;
+
+	writel(reg, &regs->raster_ctrl);
+
+	uc_priv->xsize = timing->hactive.typ;
+	uc_priv->ysize = timing->vactive.typ;
+	uc_priv->bpix = log_2_n_round_up(panel->bpp);
+	return 0;
+}
+
+static int am335x_fb_ofdata_to_platdata(struct udevice *dev)
+{
+	struct am335x_fb_priv *priv = dev_get_priv(dev);
+	struct tilcdc_panel_info *panel = &priv->panel;
+	struct display_timing *timing = &priv->timing;
+	ofnode node;
+	int err;
+
+	node = ofnode_by_compatible(ofnode_null(), "ti,am33xx-tilcdc");
+	if (!ofnode_valid(node)) {
+		dev_err(dev, "missing 'ti,am33xx-tilcdc' node\n");
+		return -ENXIO;
+	}
+
+	priv->regs = (struct am335x_lcdhw *)ofnode_get_addr(node);
+	dev_dbg(dev, "LCD: base address=0x%x\n", (unsigned int)priv->regs);
+
+	err = ofnode_decode_display_timing(dev_ofnode(dev), 0, timing);
+	if (err) {
+		dev_err(dev, "failed to get display timing\n");
+		return err;
+	}
+
+	if (timing->pixelclock.typ > (LCDC_FMAX / 2)) {
+		dev_err(dev, "invalid display clock-frequency: %d Hz\n",
+			timing->pixelclock.typ);
+		return -EINVAL;
+	}
+
+	if (timing->hactive.typ > LCD_MAX_WIDTH)
+		timing->hactive.typ = LCD_MAX_WIDTH;
+
+	if (timing->vactive.typ > LCD_MAX_HEIGHT)
+		timing->vactive.typ = LCD_MAX_HEIGHT;
+
+	node = ofnode_find_subnode(dev_ofnode(dev), "panel-info");
+	if (!ofnode_valid(node)) {
+		dev_err(dev, "missing 'panel-info' node\n");
+		return -ENXIO;
+	}
+
+	err |= ofnode_read_u32(node, "ac-bias", &panel->ac_bias);
+	err |= ofnode_read_u32(node, "ac-bias-intrpt", &panel->ac_bias_intrpt);
+	err |= ofnode_read_u32(node, "dma-burst-sz", &panel->dma_burst_sz);
+	err |= ofnode_read_u32(node, "bpp", &panel->bpp);
+	err |= ofnode_read_u32(node, "fdd", &panel->fdd);
+	err |= ofnode_read_u32(node, "sync-edge", &panel->sync_edge);
+	err |= ofnode_read_u32(node, "sync-ctrl", &panel->sync_ctrl);
+	err |= ofnode_read_u32(node, "raster-order", &panel->raster_order);
+	err |= ofnode_read_u32(node, "fifo-th", &panel->fifo_th);
+	if (err) {
+		dev_err(dev, "failed to get panel info\n");
+		return err;
+	}
+
+	switch (panel->bpp) {
+	case 16:
+	case 24:
+	case 32:
+		break;
+	default:
+		dev_err(dev, "invalid seting, bpp: %d\n", panel->bpp);
+		return -EINVAL;
+	}
+
+	switch (panel->dma_burst_sz) {
+	case 1:
+	case 2:
+	case 4:
+	case 8:
+	case 16:
+		break;
+	default:
+		dev_err(dev, "invalid setting, dma-burst-sz: %d\n",
+			panel->dma_burst_sz);
+		return -EINVAL;
+	}
+
+	/* optional */
+	panel->tft_alt_mode = ofnode_read_bool(node, "tft-alt-mode");
+	panel->invert_pxl_clk = ofnode_read_bool(node, "invert-pxl-clk");
+
+	dev_dbg(dev, "LCD: %dx%d, bpp=%d, clk=%d Hz\n", timing->hactive.typ,
+		timing->vactive.typ, panel->bpp, timing->pixelclock.typ);
+	dev_dbg(dev, "     hbp=%d, hfp=%d, hsw=%d\n", timing->hback_porch.typ,
+		timing->hfront_porch.typ, timing->hsync_len.typ);
+	dev_dbg(dev, "     vbp=%d, vfp=%d, vsw=%d\n", timing->vback_porch.typ,
+		timing->vfront_porch.typ, timing->vsync_len.typ);
+
+	return 0;
+}
+
+static int am335x_fb_bind(struct udevice *dev)
+{
+	struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
+
+	uc_plat->size = ((LCD_MAX_WIDTH * LCD_MAX_HEIGHT *
+			  (1 << LCD_MAX_LOG2_BPP)) >> 3) + 0x20;
+
+	dev_dbg(dev, "frame buffer size 0x%x\n", uc_plat->size);
+	return 0;
+}
+
+static const struct udevice_id am335x_fb_ids[] = {
+	{ .compatible = "ti,tilcdc,panel" },
+	{ }
+};
+
+U_BOOT_DRIVER(am335x_fb) = {
+	.name = "am335x_fb",
+	.id = UCLASS_VIDEO,
+	.of_match = am335x_fb_ids,
+	.bind = am335x_fb_bind,
+	.ofdata_to_platdata = am335x_fb_ofdata_to_platdata,
+	.probe = am335x_fb_probe,
+	.remove = am335x_fb_remove,
+	.priv_auto_alloc_size = sizeof(struct am335x_fb_priv),
+};
+
+#endif /* CONFIG_DM_VIDEO */

+ 10 - 6
drivers/video/am335x-fb.h

@@ -7,7 +7,9 @@
 #ifndef AM335X_FB_H
 #define AM335X_FB_H
 
-#define HSVS_CONTROL	(0x01 << 25)	/*
+#if !CONFIG_IS_ENABLED(DM_VIDEO)
+
+#define HSVS_CONTROL		BIT(25)	/*
 					 * 0 = lcd_lp and lcd_fp are driven on
 					 * opposite edges of pixel clock than
 					 * the lcd_pixel_o
@@ -17,7 +19,7 @@
 					 * Matrix displays the edge timing is
 					 * fixed
 					 */
-#define HSVS_RISEFALL	(0x01 << 24)	/*
+#define HSVS_RISEFALL		BIT(24)	/*
 					 * 0 = lcd_lp and lcd_fp are driven on
 					 * the rising edge of pixel clock (bit
 					 * 25 must be set to 1)
@@ -25,19 +27,19 @@
 					 * the falling edge of pixel clock (bit
 					 * 25 must be set to 1)
 					 */
-#define DE_INVERT	(0x01 << 23)	/*
+#define DE_INVERT		BIT(23)	/*
 					 * 0 = DE is low-active
 					 * 1 = DE is high-active
 					 */
-#define PXCLK_INVERT	(0x01 << 22)	/*
+#define PXCLK_INVERT		BIT(22)	/*
 					 * 0 = pix-clk is high-active
 					 * 1 = pic-clk is low-active
 					 */
-#define HSYNC_INVERT	(0x01 << 21)	/*
+#define HSYNC_INVERT		BIT(21)	/*
 					 * 0 = HSYNC is active high
 					 * 1 = HSYNC is avtive low
 					 */
-#define VSYNC_INVERT	(0x01 << 20)	/*
+#define VSYNC_INVERT		BIT(20)	/*
 					 * 0 = VSYNC is active high
 					 * 1 = VSYNC is active low
 					 */
@@ -68,4 +70,6 @@ struct am335x_lcdpanel {
 
 int am335xfb_init(struct am335x_lcdpanel *panel);
 
+#endif  /* CONFIG_DM_VIDEO */
+
 #endif  /* AM335X_FB_H */

+ 20 - 1
include/configs/am65x_evm.h

@@ -73,7 +73,8 @@
 	"name_kern=Image\0"						\
 	"console=ttyS2,115200n8\0"					\
 	"stdin=serial,usbkbd\0"						\
-	"args_all=setenv optargs earlycon=ns16550a,mmio32,0x02800000\0" \
+	"args_all=setenv optargs earlycon=ns16550a,mmio32,0x02800000 "  \
+		"${mtdparts}\0"						\
 	"run_kern=booti ${loadaddr} ${rd_spec} ${fdtaddr}\0"		\
 
 /* U-Boot MMC-specific configuration */
@@ -106,6 +107,22 @@
 		"0 /lib/firmware/am65x-mcu-r5f0_0-fw "			\
 		"1 /lib/firmware/am65x-mcu-r5f0_1-fw "
 
+#ifdef CONFIG_TARGET_AM654_A53_EVM
+#define EXTRA_ENV_AM65X_BOARD_SETTINGS_MTD				\
+	"mtdids=" CONFIG_MTDIDS_DEFAULT "\0"				\
+	"mtdparts=" CONFIG_MTDPARTS_DEFAULT "\0"
+#else
+#define EXTRA_ENV_AM65X_BOARD_SETTINGS_MTD
+#endif
+
+#define EXTRA_ENV_AM65X_BOARD_SETTINGS_UBI				\
+	"init_ubi=run args_all args_ubi; sf probe; "			\
+		"ubi part ospi.rootfs; ubifsmount ubi:rootfs;\0"	\
+	"get_kern_ubi=ubifsload ${loadaddr} ${bootdir}/${name_kern}\0"	\
+	"get_fdt_ubi=ubifsload ${fdtaddr} ${bootdir}/${name_fdt}\0"	\
+	"args_ubi=setenv bootargs console=${console} ${optargs} "	\
+		"rootfstype=ubifs root=ubi0:rootfs rw ubi.mtd=ospi.rootfs\0"
+
 #define EXTRA_ENV_DFUARGS						\
 	"dfu_bufsiz=0x20000\0"						\
 	DFU_ALT_INFO_MMC						\
@@ -118,6 +135,8 @@
 	DEFAULT_FIT_TI_ARGS						\
 	EXTRA_ENV_AM65X_BOARD_SETTINGS					\
 	EXTRA_ENV_AM65X_BOARD_SETTINGS_MMC				\
+	EXTRA_ENV_AM65X_BOARD_SETTINGS_MTD				\
+	EXTRA_ENV_AM65X_BOARD_SETTINGS_UBI				\
 	EXTRA_ENV_RPROC_SETTINGS					\
 	EXTRA_ENV_DFUARGS
 

+ 2 - 0
include/configs/brxre1.h

@@ -14,7 +14,9 @@
 #include <configs/bur_cfg_common.h>
 #include <configs/bur_am335x_common.h>
 /* ------------------------------------------------------------------------- */
+#if !defined(CONFIG_AM335X_LCD)
 #define CONFIG_AM335X_LCD
+#endif
 #define LCD_BPP				LCD_COLOR32
 
 /* memory */

+ 16 - 2
include/configs/j721e_evm.h

@@ -74,7 +74,8 @@
 	"overlayaddr=0x83000000\0"					\
 	"name_kern=Image\0"						\
 	"console=ttyS2,115200n8\0"					\
-	"args_all=setenv optargs earlycon=ns16550a,mmio32,0x02800000\0" \
+	"args_all=setenv optargs earlycon=ns16550a,mmio32,0x02800000 "	\
+		"${mtdparts}\0"						\
 	"run_kern=booti ${loadaddr} ${rd_spec} ${fdtaddr}\0"
 
 #define PARTS_DEFAULT \
@@ -88,6 +89,10 @@
 	"mmcdev=1\0"							\
 	"bootpart=1:2\0"						\
 	"bootdir=/boot\0"						\
+	"addr_mainr5f0_0load=88000000\0"					\
+	"name_mainr5f0_0fw=/lib/firmware/j7-main-r5f0_0-fw\0"		\
+	"addr_mcur5f0_0load=89000000\0"					\
+	"name_mcur5f0_0fw=/lib/firmware/j7-mcu-r5f0_0-fw\0"		\
 	"rd_spec=-\0"							\
 	"init_mmc=run args_all args_mmc\0"				\
 	"get_fdt_mmc=load mmc ${bootpart} ${fdtaddr} ${bootdir}/${name_fdt}\0" \
@@ -124,6 +129,14 @@
 	DFU_ALT_INFO_RAM \
 	DFU_ALT_INFO_OSPI
 
+#ifdef CONFIG_TARGET_J721E_A72_EVM
+#define EXTRA_ENV_J721E_BOARD_SETTINGS_MTD				\
+	"mtdids=" CONFIG_MTDIDS_DEFAULT "\0"				\
+	"mtdparts=" CONFIG_MTDPARTS_DEFAULT "\0"
+#else
+#define EXTRA_ENV_J721E_BOARD_SETTINGS_MTD
+#endif
+
 /* Incorporate settings into the U-Boot environment */
 #define CONFIG_EXTRA_ENV_SETTINGS					\
 	DEFAULT_MMC_TI_ARGS						\
@@ -132,7 +145,8 @@
 	EXTRA_ENV_J721E_BOARD_SETTINGS_MMC				\
 	EXTRA_ENV_RPROC_SETTINGS					\
 	EXTRA_ENV_DFUARGS						\
-	DEFAULT_UFS_TI_ARGS
+	DEFAULT_UFS_TI_ARGS						\
+	EXTRA_ENV_J721E_BOARD_SETTINGS_MTD
 
 /* Now for the remaining common defines */
 #include <configs/ti_armv7_common.h>

+ 4 - 0
include/elf.h

@@ -692,6 +692,10 @@ unsigned long elf_hash(const unsigned char *name);
 
 #ifndef __ASSEMBLER__
 int valid_elf_image(unsigned long addr);
+unsigned long load_elf64_image_phdr(unsigned long addr);
+unsigned long load_elf64_image_shdr(unsigned long addr);
+unsigned long load_elf_image_phdr(unsigned long addr);
+unsigned long load_elf_image_shdr(unsigned long addr);
 #endif
 
 #endif /* _ELF_H */

+ 4 - 4
include/environment/ti/boot.h

@@ -103,18 +103,18 @@
 		"echo \"  Reading DTB for AM57x EVM RevA3...\"; " \
 		"abootimg get dtb --index=0 dtb_start dtb_size; " \
 		"cp.b $dtb_start $fdtaddr $dtb_size; " \
-		"fdt addr $fdtaddr; " \
+		"fdt addr $fdtaddr 0x80000; " \
 		"echo \"  Applying DTBOs for AM57x EVM RevA3...\"; " \
 		"adtimg addr $dtboaddr; " \
-		"adtimg get dt --index=0 dtbo0_addr; " \
+		"adtimg get dt --index=0 dtbo0_addr dtbo0_size; " \
 		"fdt apply $dtbo0_addr; " \
-		"adtimg get dt --index=1 dtbo1_addr; " \
+		"adtimg get dt --index=1 dtbo1_addr dtbo1_size; " \
 		"fdt apply $dtbo1_addr; " \
 	"elif test $board_name = beagle_x15_revc; then " \
 		"echo \"  Reading DTB for Beagle X15 RevC...\"; " \
 		"abootimg get dtb --index=0 dtb_start dtb_size; " \
 		"cp.b $dtb_start $fdtaddr $dtb_size; " \
-		"fdt addr $fdtaddr; " \
+		"fdt addr $fdtaddr 0x80000; " \
 	"else " \
 		"echo Error: Android boot is not supported for $board_name; " \
 		"exit; " \

+ 0 - 6
include/linux/soc/ti/ti_sci_protocol.h

@@ -327,8 +327,6 @@ struct ti_sci_proc_ops {
 /**
  * struct ti_sci_rm_ringacc_ops - Ring Accelerator Management operations
  * @config: configure the SoC Navigator Subsystem Ring Accelerator ring
- * @get_config: get the SoC Navigator Subsystem Ring Accelerator ring
- *		configuration
  */
 struct ti_sci_rm_ringacc_ops {
 	int (*config)(const struct ti_sci_handle *handle,
@@ -336,10 +334,6 @@ struct ti_sci_rm_ringacc_ops {
 		      u32 addr_lo, u32 addr_hi, u32 count, u8 mode,
 		      u8 size, u8 order_id
 	);
-	int (*get_config)(const struct ti_sci_handle *handle,
-			  u32 nav_id, u32 index, u8 *mode,
-			  u32 *addr_lo, u32 *addr_hi, u32 *count,
-			  u8 *size, u8 *order_id);
 };
 
 /**

+ 6 - 0
lib/Kconfig

@@ -602,4 +602,10 @@ config TEST_FDTDEC
 config LIB_DATE
 	bool
 
+config LIB_ELF
+	bool
+	help
+	  Supoort basic elf loading/validating functions.
+	  This supports fir 32 bit and 64 bit versions.
+
 endmenu

+ 1 - 0
lib/Makefile

@@ -122,6 +122,7 @@ obj-y += vsprintf.o strto.o
 endif
 
 obj-y += date.o
+obj-$(CONFIG_LIB_ELF) += elf.o
 
 #
 # Build a fast OID lookup registry from include/linux/oid_registry.h

+ 246 - 0
lib/elf.c

@@ -0,0 +1,246 @@
+// SPDX-License-Identifier: BSD-2-Clause
+/*
+   Copyright (c) 2001 William L. Pitts
+*/
+
+#include <common.h>
+#include <command.h>
+#include <cpu_func.h>
+#include <elf.h>
+#include <env.h>
+#include <net.h>
+#include <vxworks.h>
+#ifdef CONFIG_X86
+#include <vbe.h>
+#include <asm/e820.h>
+#include <linux/linkage.h>
+#endif
+
+/*
+ * A very simple ELF64 loader, assumes the image is valid, returns the
+ * entry point address.
+ *
+ * Note if U-Boot is 32-bit, the loader assumes the to segment's
+ * physical address and size is within the lower 32-bit address space.
+ */
+unsigned long load_elf64_image_phdr(unsigned long addr)
+{
+	Elf64_Ehdr *ehdr; /* Elf header structure pointer */
+	Elf64_Phdr *phdr; /* Program header structure pointer */
+	int i;
+
+	ehdr = (Elf64_Ehdr *)addr;
+	phdr = (Elf64_Phdr *)(addr + (ulong)ehdr->e_phoff);
+
+	/* Load each program header */
+	for (i = 0; i < ehdr->e_phnum; ++i) {
+		void *dst = (void *)(ulong)phdr->p_paddr;
+		void *src = (void *)addr + phdr->p_offset;
+
+		debug("Loading phdr %i to 0x%p (%lu bytes)\n",
+		      i, dst, (ulong)phdr->p_filesz);
+		if (phdr->p_filesz)
+			memcpy(dst, src, phdr->p_filesz);
+		if (phdr->p_filesz != phdr->p_memsz)
+			memset(dst + phdr->p_filesz, 0x00,
+			       phdr->p_memsz - phdr->p_filesz);
+		flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
+			    roundup(phdr->p_memsz, ARCH_DMA_MINALIGN));
+		++phdr;
+	}
+
+	if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags &
+					    EF_PPC64_ELFV1_ABI)) {
+		/*
+		 * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function
+		 * descriptor pointer with the first double word being the
+		 * address of the entry point of the function.
+		 */
+		uintptr_t addr = ehdr->e_entry;
+
+		return *(Elf64_Addr *)addr;
+	}
+
+	return ehdr->e_entry;
+}
+
+unsigned long load_elf64_image_shdr(unsigned long addr)
+{
+	Elf64_Ehdr *ehdr; /* Elf header structure pointer */
+	Elf64_Shdr *shdr; /* Section header structure pointer */
+	unsigned char *strtab = 0; /* String table pointer */
+	unsigned char *image; /* Binary image pointer */
+	int i; /* Loop counter */
+
+	ehdr = (Elf64_Ehdr *)addr;
+
+	/* Find the section header string table for output info */
+	shdr = (Elf64_Shdr *)(addr + (ulong)ehdr->e_shoff +
+			     (ehdr->e_shstrndx * sizeof(Elf64_Shdr)));
+
+	if (shdr->sh_type == SHT_STRTAB)
+		strtab = (unsigned char *)(addr + (ulong)shdr->sh_offset);
+
+	/* Load each appropriate section */
+	for (i = 0; i < ehdr->e_shnum; ++i) {
+		shdr = (Elf64_Shdr *)(addr + (ulong)ehdr->e_shoff +
+				     (i * sizeof(Elf64_Shdr)));
+
+		if (!(shdr->sh_flags & SHF_ALLOC) ||
+		    shdr->sh_addr == 0 || shdr->sh_size == 0) {
+			continue;
+		}
+
+		if (strtab) {
+			debug("%sing %s @ 0x%08lx (%ld bytes)\n",
+			      (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load",
+			       &strtab[shdr->sh_name],
+			       (unsigned long)shdr->sh_addr,
+			       (long)shdr->sh_size);
+		}
+
+		if (shdr->sh_type == SHT_NOBITS) {
+			memset((void *)(uintptr_t)shdr->sh_addr, 0,
+			       shdr->sh_size);
+		} else {
+			image = (unsigned char *)addr + (ulong)shdr->sh_offset;
+			memcpy((void *)(uintptr_t)shdr->sh_addr,
+			       (const void *)image, shdr->sh_size);
+		}
+		flush_cache(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
+			    roundup((shdr->sh_addr + shdr->sh_size),
+				     ARCH_DMA_MINALIGN) -
+				rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
+	}
+
+	if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags &
+					    EF_PPC64_ELFV1_ABI)) {
+		/*
+		 * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function
+		 * descriptor pointer with the first double word being the
+		 * address of the entry point of the function.
+		 */
+		uintptr_t addr = ehdr->e_entry;
+
+		return *(Elf64_Addr *)addr;
+	}
+
+	return ehdr->e_entry;
+}
+
+/*
+ * A very simple ELF loader, assumes the image is valid, returns the
+ * entry point address.
+ *
+ * The loader firstly reads the EFI class to see if it's a 64-bit image.
+ * If yes, call the ELF64 loader. Otherwise continue with the ELF32 loader.
+ */
+unsigned long load_elf_image_phdr(unsigned long addr)
+{
+	Elf32_Ehdr *ehdr; /* Elf header structure pointer */
+	Elf32_Phdr *phdr; /* Program header structure pointer */
+	int i;
+
+	ehdr = (Elf32_Ehdr *)addr;
+	if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
+		return load_elf64_image_phdr(addr);
+
+	phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff);
+
+	/* Load each program header */
+	for (i = 0; i < ehdr->e_phnum; ++i) {
+		void *dst = (void *)(uintptr_t)phdr->p_paddr;
+		void *src = (void *)addr + phdr->p_offset;
+
+		debug("Loading phdr %i to 0x%p (%i bytes)\n",
+		      i, dst, phdr->p_filesz);
+		if (phdr->p_filesz)
+			memcpy(dst, src, phdr->p_filesz);
+		if (phdr->p_filesz != phdr->p_memsz)
+			memset(dst + phdr->p_filesz, 0x00,
+			       phdr->p_memsz - phdr->p_filesz);
+		flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
+			    roundup(phdr->p_memsz, ARCH_DMA_MINALIGN));
+		++phdr;
+	}
+
+	return ehdr->e_entry;
+}
+
+unsigned long load_elf_image_shdr(unsigned long addr)
+{
+	Elf32_Ehdr *ehdr; /* Elf header structure pointer */
+	Elf32_Shdr *shdr; /* Section header structure pointer */
+	unsigned char *strtab = 0; /* String table pointer */
+	unsigned char *image; /* Binary image pointer */
+	int i; /* Loop counter */
+
+	ehdr = (Elf32_Ehdr *)addr;
+	if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
+		return load_elf64_image_shdr(addr);
+
+	/* Find the section header string table for output info */
+	shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
+			     (ehdr->e_shstrndx * sizeof(Elf32_Shdr)));
+
+	if (shdr->sh_type == SHT_STRTAB)
+		strtab = (unsigned char *)(addr + shdr->sh_offset);
+
+	/* Load each appropriate section */
+	for (i = 0; i < ehdr->e_shnum; ++i) {
+		shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
+				     (i * sizeof(Elf32_Shdr)));
+
+		if (!(shdr->sh_flags & SHF_ALLOC) ||
+		    shdr->sh_addr == 0 || shdr->sh_size == 0) {
+			continue;
+		}
+
+		if (strtab) {
+			debug("%sing %s @ 0x%08lx (%ld bytes)\n",
+			      (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load",
+			       &strtab[shdr->sh_name],
+			       (unsigned long)shdr->sh_addr,
+			       (long)shdr->sh_size);
+		}
+
+		if (shdr->sh_type == SHT_NOBITS) {
+			memset((void *)(uintptr_t)shdr->sh_addr, 0,
+			       shdr->sh_size);
+		} else {
+			image = (unsigned char *)addr + shdr->sh_offset;
+			memcpy((void *)(uintptr_t)shdr->sh_addr,
+			       (const void *)image, shdr->sh_size);
+		}
+		flush_cache(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
+			    roundup((shdr->sh_addr + shdr->sh_size),
+				    ARCH_DMA_MINALIGN) -
+			    rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
+	}
+
+	return ehdr->e_entry;
+}
+
+/*
+ * Determine if a valid ELF image exists at the given memory location.
+ * First look at the ELF header magic field, then make sure that it is
+ * executable.
+ */
+int valid_elf_image(unsigned long addr)
+{
+	Elf32_Ehdr *ehdr; /* Elf header structure pointer */
+
+	ehdr = (Elf32_Ehdr *)addr;
+
+	if (!IS_ELF(*ehdr)) {
+		printf("## No elf image at address 0x%08lx\n", addr);
+		return 0;
+	}
+
+	if (ehdr->e_type != ET_EXEC) {
+		printf("## Not a 32-bit elf image at address 0x%08lx\n", addr);
+		return 0;
+	}
+
+	return 1;
+}