summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Kconfig2
-rw-r--r--arch/Kconfig1
-rw-r--r--arch/arm/Kconfig1
-rw-r--r--arch/arm/cpu/armv7/arch_timer.c3
-rw-r--r--arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi8
-rw-r--r--arch/arm/dts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi24
-rw-r--r--arch/arm/mach-stm32mp/Kconfig24
-rw-r--r--arch/arm/mach-stm32mp/bsec.c2
-rw-r--r--arch/arm/mach-stm32mp/include/mach/ddr.h9
-rw-r--r--arch/arm/mach-stm32mp/include/mach/stm32.h1
-rw-r--r--arch/arm/mach-stm32mp/psci.c22
-rw-r--r--arch/m68k/Kconfig33
-rw-r--r--arch/m68k/cpu/mcf5227x/Makefile2
-rw-r--r--arch/m68k/cpu/mcf5227x/cpu_init.c65
-rw-r--r--arch/m68k/cpu/mcf5227x/dspi.c43
-rw-r--r--arch/m68k/cpu/mcf5227x/start.S3
-rw-r--r--arch/m68k/cpu/mcf5445x/Makefile2
-rw-r--r--arch/m68k/cpu/mcf5445x/cpu_init.c142
-rw-r--r--arch/m68k/cpu/mcf5445x/dspi.c88
-rw-r--r--arch/m68k/cpu/mcf547x_8x/start.S6
-rw-r--r--arch/m68k/cpu/u-boot.lds6
-rw-r--r--arch/m68k/dts/M5208EVBE.dts22
-rw-r--r--arch/m68k/dts/M52277EVB.dts25
-rw-r--r--arch/m68k/dts/M52277EVB_stmicro.dts22
-rw-r--r--arch/m68k/dts/M5235EVB.dts22
-rw-r--r--arch/m68k/dts/M5235EVB_Flash32.dts22
-rw-r--r--arch/m68k/dts/M5249EVB.dts22
-rw-r--r--arch/m68k/dts/M5253DEMO.dts22
-rw-r--r--arch/m68k/dts/M5272C3.dts22
-rw-r--r--arch/m68k/dts/M5275EVB.dts22
-rw-r--r--arch/m68k/dts/M5282EVB.dts22
-rw-r--r--arch/m68k/dts/M53017EVB.dts22
-rw-r--r--arch/m68k/dts/M5329AFEE.dts22
-rw-r--r--arch/m68k/dts/M5329BFEE.dts22
-rw-r--r--arch/m68k/dts/M5373EVB.dts22
-rw-r--r--arch/m68k/dts/M54418TWR.dts25
-rw-r--r--arch/m68k/dts/M54418TWR_nand_mii.dts25
-rw-r--r--arch/m68k/dts/M54418TWR_nand_rmii.dts25
-rw-r--r--arch/m68k/dts/M54418TWR_nand_rmii_lowfreq.dts25
-rw-r--r--arch/m68k/dts/M54418TWR_serial_mii.dts25
-rw-r--r--arch/m68k/dts/M54418TWR_serial_rmii.dts25
-rw-r--r--arch/m68k/dts/M54451EVB.dts25
-rw-r--r--arch/m68k/dts/M54451EVB_stmicro.dts25
-rw-r--r--arch/m68k/dts/M54455EVB.dts25
-rw-r--r--arch/m68k/dts/M54455EVB_a66.dts25
-rw-r--r--arch/m68k/dts/M54455EVB_i66.dts25
-rw-r--r--arch/m68k/dts/M54455EVB_intel.dts26
-rw-r--r--arch/m68k/dts/M54455EVB_stm33.dts25
-rw-r--r--arch/m68k/dts/M5475AFE.dts13
-rw-r--r--arch/m68k/dts/M5475BFE.dts13
-rw-r--r--arch/m68k/dts/M5475CFE.dts13
-rw-r--r--arch/m68k/dts/M5475DFE.dts13
-rw-r--r--arch/m68k/dts/M5475EFE.dts13
-rw-r--r--arch/m68k/dts/M5475FFE.dts13
-rw-r--r--arch/m68k/dts/M5475GFE.dts13
-rw-r--r--arch/m68k/dts/M5485AFE.dts17
-rw-r--r--arch/m68k/dts/M5485BFE.dts17
-rw-r--r--arch/m68k/dts/M5485CFE.dts17
-rw-r--r--arch/m68k/dts/M5485DFE.dts17
-rw-r--r--arch/m68k/dts/M5485EFE.dts17
-rw-r--r--arch/m68k/dts/M5485FFE.dts17
-rw-r--r--arch/m68k/dts/M5485GFE.dts17
-rw-r--r--arch/m68k/dts/M5485HFE.dts17
-rw-r--r--arch/m68k/dts/Makefile59
-rw-r--r--arch/m68k/dts/amcore.dts22
-rw-r--r--arch/m68k/dts/astro_mcf5373l.dts22
-rw-r--r--arch/m68k/dts/cobra5272.dts22
-rw-r--r--arch/m68k/dts/eb_cpu5282.dts22
-rw-r--r--arch/m68k/dts/eb_cpu5282_internal.dts22
-rw-r--r--arch/m68k/dts/mcf5208.dtsi36
-rw-r--r--arch/m68k/dts/mcf5227x.dtsi48
-rw-r--r--arch/m68k/dts/mcf523x.dtsi44
-rw-r--r--arch/m68k/dts/mcf5249.dtsi38
-rw-r--r--arch/m68k/dts/mcf5253.dtsi44
-rw-r--r--arch/m68k/dts/mcf5271.dtsi44
-rw-r--r--arch/m68k/dts/mcf5272.dtsi38
-rw-r--r--arch/m68k/dts/mcf5275.dtsi44
-rw-r--r--arch/m68k/dts/mcf5282.dtsi44
-rw-r--r--arch/m68k/dts/mcf5301x.dtsi48
-rw-r--r--arch/m68k/dts/mcf5307.dtsi39
-rw-r--r--arch/m68k/dts/mcf5329.dtsi36
-rw-r--r--arch/m68k/dts/mcf537x.dtsi36
-rw-r--r--arch/m68k/dts/mcf5441x.dtsi87
-rw-r--r--arch/m68k/dts/mcf5445x.dtsi48
-rw-r--r--arch/m68k/dts/mcf54xx.dtsi40
-rw-r--r--arch/m68k/dts/stmark2.dts34
-rw-r--r--arch/m68k/include/asm/coldfire/dspi.h4
-rw-r--r--arch/mips/Kconfig2
-rw-r--r--arch/mips/mach-mtmips/cpu.c15
-rw-r--r--arch/powerpc/cpu/mpc85xx/Kconfig4
-rw-r--r--arch/powerpc/dts/t2080.dtsi45
-rw-r--r--board/st/stm32mp1/board.c171
-rw-r--r--common/Kconfig1
-rw-r--r--common/Makefile1
-rw-r--r--configs/M5208EVBE_defconfig1
-rw-r--r--configs/M52277EVB_defconfig2
-rw-r--r--configs/M52277EVB_stmicro_defconfig2
-rw-r--r--configs/M5235EVB_Flash32_defconfig1
-rw-r--r--configs/M5235EVB_defconfig1
-rw-r--r--configs/M5249EVB_defconfig1
-rw-r--r--configs/M5253DEMO_defconfig1
-rw-r--r--configs/M5272C3_defconfig1
-rw-r--r--configs/M5275EVB_defconfig1
-rw-r--r--configs/M5282EVB_defconfig1
-rw-r--r--configs/M53017EVB_defconfig1
-rw-r--r--configs/M5329AFEE_defconfig1
-rw-r--r--configs/M5329BFEE_defconfig1
-rw-r--r--configs/M5373EVB_defconfig1
-rw-r--r--configs/M54418TWR_defconfig2
-rw-r--r--configs/M54418TWR_nand_mii_defconfig2
-rw-r--r--configs/M54418TWR_nand_rmii_defconfig2
-rw-r--r--configs/M54418TWR_nand_rmii_lowfreq_defconfig2
-rw-r--r--configs/M54418TWR_serial_mii_defconfig2
-rw-r--r--configs/M54418TWR_serial_rmii_defconfig2
-rw-r--r--configs/M54451EVB_defconfig2
-rw-r--r--configs/M54451EVB_stmicro_defconfig2
-rw-r--r--configs/M54455EVB_a66_defconfig2
-rw-r--r--configs/M54455EVB_defconfig2
-rw-r--r--configs/M54455EVB_i66_defconfig2
-rw-r--r--configs/M54455EVB_intel_defconfig2
-rw-r--r--configs/M54455EVB_stm33_defconfig2
-rw-r--r--configs/M5475AFE_defconfig1
-rw-r--r--configs/M5475BFE_defconfig1
-rw-r--r--configs/M5475CFE_defconfig1
-rw-r--r--configs/M5475DFE_defconfig1
-rw-r--r--configs/M5475EFE_defconfig1
-rw-r--r--configs/M5475FFE_defconfig1
-rw-r--r--configs/M5475GFE_defconfig1
-rw-r--r--configs/M5485AFE_defconfig1
-rw-r--r--configs/M5485BFE_defconfig1
-rw-r--r--configs/M5485CFE_defconfig1
-rw-r--r--configs/M5485DFE_defconfig1
-rw-r--r--configs/M5485EFE_defconfig1
-rw-r--r--configs/M5485FFE_defconfig1
-rw-r--r--configs/M5485GFE_defconfig1
-rw-r--r--configs/M5485HFE_defconfig1
-rw-r--r--configs/T2080QDS_NAND_defconfig7
-rw-r--r--configs/T2080QDS_SDCARD_defconfig7
-rw-r--r--configs/T2080QDS_SECURE_BOOT_defconfig10
-rw-r--r--configs/T2080QDS_SPIFLASH_defconfig7
-rw-r--r--configs/T2080QDS_SRIO_PCIE_BOOT_defconfig11
-rw-r--r--configs/T2080QDS_defconfig7
-rw-r--r--configs/amcore_defconfig1
-rw-r--r--configs/astro_mcf5373l_defconfig1
-rw-r--r--configs/cobra5272_defconfig1
-rw-r--r--configs/eb_cpu5282_defconfig1
-rw-r--r--configs/eb_cpu5282_internal_defconfig1
-rw-r--r--configs/gardena-smart-gateway-mt7688-ram_defconfig2
-rw-r--r--configs/gardena-smart-gateway-mt7688_defconfig2
-rw-r--r--configs/stmark2_defconfig3
-rw-r--r--doc/device-tree-bindings/clock/st,stm32mp1.txt427
-rw-r--r--doc/device-tree-bindings/memory-controllers/st,stm32mp1-ddr.txt6
-rw-r--r--doc/device-tree-bindings/serial/mcf-uart.txt19
-rw-r--r--doc/device-tree-bindings/spi/spi-mcf-dspi.txt30
-rw-r--r--drivers/ata/Kconfig10
-rw-r--r--drivers/ata/Makefile1
-rw-r--r--drivers/ata/fsl_ahci.c1030
-rw-r--r--drivers/ata/fsl_sata.h1
-rw-r--r--drivers/clk/clk_stm32mp1.c83
-rw-r--r--drivers/i2c/stm32f7_i2c.c6
-rw-r--r--drivers/mmc/fsl_esdhc.c11
-rw-r--r--drivers/ram/stm32mp1/Kconfig37
-rw-r--r--drivers/ram/stm32mp1/Makefile8
-rw-r--r--drivers/ram/stm32mp1/stm32mp1_ddr.c368
-rw-r--r--drivers/ram/stm32mp1/stm32mp1_ddr.h4
-rw-r--r--drivers/ram/stm32mp1/stm32mp1_ddr_regs.h3
-rw-r--r--drivers/ram/stm32mp1/stm32mp1_interactive.c483
-rw-r--r--drivers/ram/stm32mp1/stm32mp1_ram.c18
-rw-r--r--drivers/ram/stm32mp1/stm32mp1_tests.c1426
-rw-r--r--drivers/ram/stm32mp1/stm32mp1_tests.h34
-rw-r--r--drivers/ram/stm32mp1/stm32mp1_tuning.c1380
-rw-r--r--drivers/serial/Kconfig8
-rw-r--r--drivers/serial/mcfuart.c106
-rw-r--r--drivers/serial/serial_stm32.c3
-rw-r--r--drivers/spi/Kconfig6
-rw-r--r--drivers/spi/cf_spi.c482
-rw-r--r--drivers/usb/host/ehci-fsl.c10
-rw-r--r--env/Kconfig2
-rw-r--r--env/common.c7
-rw-r--r--include/configs/M52277EVB.h11
-rw-r--r--include/configs/M54418TWR.h12
-rw-r--r--include/configs/M54451EVB.h12
-rw-r--r--include/configs/M54455EVB.h10
-rw-r--r--include/configs/stm32mp1.h12
-rw-r--r--include/configs/stmark2.h11
-rw-r--r--include/dm/platform_data/spi_coldfire.h29
-rw-r--r--tools/stm32image.c8
187 files changed, 7968 insertions, 775 deletions
diff --git a/Kconfig b/Kconfig
index 5f5c5ccfd6..fcde0c35e2 100644
--- a/Kconfig
+++ b/Kconfig
@@ -147,7 +147,7 @@ config SYS_MALLOC_F_LEN
config SYS_MALLOC_LEN
hex "Define memory for Dynamic allocation"
- depends on ARCH_ZYNQ || ARCH_VERSAL
+ depends on ARCH_ZYNQ || ARCH_VERSAL || ARCH_STM32MP
help
This defines memory to be allocated for Dynamic allocation
TODO: Use for other architectures
diff --git a/arch/Kconfig b/arch/Kconfig
index 239289b885..e574b0d441 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -28,6 +28,7 @@ config M68K
select HAVE_PRIVATE_LIBGCC
select SYS_BOOT_GET_CMDLINE
select SYS_BOOT_GET_KBD
+ select SUPPORT_OF_CONTROL
config MICROBLAZE
bool "MicroBlaze architecture"
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index efb9aab390..01ff57cf1b 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1488,6 +1488,7 @@ config ARCH_STM32MP
imply CMD_DM
imply CMD_POWEROFF
imply ENV_VARS_UBOOT_RUNTIME_CONFIG
+ imply USE_PREBOOT
help
Support for STM32MP SoC family developed by STMicroelectronics,
MPUs based on ARM cortex A core
diff --git a/arch/arm/cpu/armv7/arch_timer.c b/arch/arm/cpu/armv7/arch_timer.c
index 3db31c0209..5de63053d5 100644
--- a/arch/arm/cpu/armv7/arch_timer.c
+++ b/arch/arm/cpu/armv7/arch_timer.c
@@ -49,6 +49,9 @@ unsigned long long get_ticks(void)
ulong timer_get_boot_us(void)
{
+ if (!gd->arch.timer_rate_hz)
+ timer_init();
+
return lldiv(get_ticks(), gd->arch.timer_rate_hz / 1000000);
}
diff --git a/arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi b/arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi
index 7d9b95ccf1..dc30360b0a 100644
--- a/arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi
+++ b/arch/arm/dts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi
@@ -16,8 +16,8 @@
* address mapping : RBC
* Tc > + 85C : N
*/
-#define DDR_MEM_NAME "DDR3-1066/888 bin G 1x4Gb 533MHz v1.43"
-#define DDR_MEM_SPEED 533
+#define DDR_MEM_NAME "DDR3-1066/888 bin G 1x4Gb 533MHz v1.44"
+#define DDR_MEM_SPEED 533000
#define DDR_MEM_SIZE 0x20000000
#define DDR_MSTR 0x00041401
@@ -108,11 +108,11 @@
#define DDR_DX1DLLCR 0x40000000
#define DDR_DX1DQTR 0xFFFFFFFF
#define DDR_DX1DQSTR 0x3DB02000
-#define DDR_DX2GCR 0x0000CE81
+#define DDR_DX2GCR 0x0000CE80
#define DDR_DX2DLLCR 0x40000000
#define DDR_DX2DQTR 0xFFFFFFFF
#define DDR_DX2DQSTR 0x3DB02000
-#define DDR_DX3GCR 0x0000CE81
+#define DDR_DX3GCR 0x0000CE80
#define DDR_DX3DLLCR 0x40000000
#define DDR_DX3DQTR 0xFFFFFFFF
#define DDR_DX3DQSTR 0x3DB02000
diff --git a/arch/arm/dts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi b/arch/arm/dts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi
index 8a5a821ec4..8158a56f13 100644
--- a/arch/arm/dts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi
+++ b/arch/arm/dts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi
@@ -1,9 +1,8 @@
// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
/*
* Copyright (C) 2018, STMicroelectronics - All Rights Reserved
- */
-
-/* STM32MP157C ED1 and ED2 BOARD configuration
+ *
+ * STM32MP157C ED1 BOARD configuration
* 2x DDR3L 4Gb each, 16-bit, 533MHz, Single Die Package in flyby topology.
* Reference used NT5CC256M16DP-DI from NANYA
*
@@ -15,10 +14,11 @@
* timing mode optimized
* Scheduling/QoS options : type = 2
* address mapping : RBC
+ * Tc > + 85C : N
*/
-#define DDR_MEM_NAME "DDR3-1066 bin G 2x4Gb 533MHz v1.36"
-#define DDR_MEM_SPEED 533
+#define DDR_MEM_NAME "DDR3-1066/888 bin G 2x4Gb 533MHz v1.44"
+#define DDR_MEM_SPEED 533000
#define DDR_MEM_SIZE 0x40000000
#define DDR_MSTR 0x00040401
@@ -62,7 +62,7 @@
#define DDR_ADDRMAP11 0x00000000
#define DDR_ODTCFG 0x06000600
#define DDR_ODTMAP 0x00000001
-#define DDR_SCHED 0x00001201
+#define DDR_SCHED 0x00000C01
#define DDR_SCHED1 0x00000000
#define DDR_PERFHPR1 0x01000001
#define DDR_PERFLPR1 0x08000200
@@ -74,15 +74,15 @@
#define DDR_PCCFG 0x00000010
#define DDR_PCFGR_0 0x00010000
#define DDR_PCFGW_0 0x00000000
-#define DDR_PCFGQOS0_0 0x02100B03
+#define DDR_PCFGQOS0_0 0x02100C03
#define DDR_PCFGQOS1_0 0x00800100
-#define DDR_PCFGWQOS0_0 0x01100B03
+#define DDR_PCFGWQOS0_0 0x01100C03
#define DDR_PCFGWQOS1_0 0x01000200
#define DDR_PCFGR_1 0x00010000
#define DDR_PCFGW_1 0x00000000
-#define DDR_PCFGQOS0_1 0x02100B03
-#define DDR_PCFGQOS1_1 0x00800100
-#define DDR_PCFGWQOS0_1 0x01100B03
+#define DDR_PCFGQOS0_1 0x02100C03
+#define DDR_PCFGQOS1_1 0x00800040
+#define DDR_PCFGWQOS0_1 0x01100C03
#define DDR_PCFGWQOS1_1 0x01000200
#define DDR_PGCR 0x01442E02
#define DDR_PTR0 0x0022AA5B
@@ -100,7 +100,7 @@
#define DDR_MR2 0x00000208
#define DDR_MR3 0x00000000
#define DDR_ODTCR 0x00010000
-#define DDR_ZQ0CR1 0x0000005B
+#define DDR_ZQ0CR1 0x00000038
#define DDR_DX0GCR 0x0000CE81
#define DDR_DX0DLLCR 0x40000000
#define DDR_DX0DQTR 0xFFFFFFFF
diff --git a/arch/arm/mach-stm32mp/Kconfig b/arch/arm/mach-stm32mp/Kconfig
index 73aa382712..77f66c65c0 100644
--- a/arch/arm/mach-stm32mp/Kconfig
+++ b/arch/arm/mach-stm32mp/Kconfig
@@ -17,12 +17,20 @@ config SPL
select SPL_DM_RESET
select SPL_SERIAL_SUPPORT
select SPL_SYSCON
+ imply BOOTSTAGE_STASH if SPL_BOOTSTAGE
+ imply SPL_BOOTSTAGE if BOOTSTAGE
imply SPL_DISPLAY_PRINT
imply SPL_LIBDISK_SUPPORT
config SYS_SOC
default "stm32mp"
+config SYS_MALLOC_LEN
+ default 0x2000000
+
+config ENV_SIZE
+ default 0x1000
+
config TARGET_STM32MP1
bool "Support stm32mp1xx"
select ARCH_SUPPORT_PSCI if !STM32MP1_TRUSTED
@@ -33,6 +41,10 @@ config TARGET_STM32MP1
select STM32_RCC
select STM32_RESET
select SYS_ARCH_TIMER
+ imply BOOTCOUNT_LIMIT
+ imply BOOTSTAGE
+ imply CMD_BOOTCOUNT
+ imply CMD_BOOTSTAGE
imply SYSRESET_PSCI if STM32MP1_TRUSTED
imply SYSRESET_SYSCON if !STM32MP1_TRUSTED
help
@@ -70,6 +82,18 @@ config SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION_MMC2
Partition on the second MMC to load U-Boot from when the MMC is being
used in raw mode
+config BOOTSTAGE_STASH_ADDR
+ default 0xC3000000
+
+if BOOTCOUNT_LIMIT
+config SYS_BOOTCOUNT_SINGLEWORD
+ default y
+
+# TAMP_BOOTCOUNT = TAMP_BACKUP_REGISTER(21)
+config SYS_BOOTCOUNT_ADDR
+ default 0x5C00A154
+endif
+
if DEBUG_UART
config DEBUG_UART_BOARD_INIT
diff --git a/arch/arm/mach-stm32mp/bsec.c b/arch/arm/mach-stm32mp/bsec.c
index 9ed8d8c56c..0166649685 100644
--- a/arch/arm/mach-stm32mp/bsec.c
+++ b/arch/arm/mach-stm32mp/bsec.c
@@ -7,9 +7,9 @@
#include <dm.h>
#include <misc.h>
#include <asm/io.h>
-#include <linux/iopoll.h>
#include <asm/arch/stm32mp1_smc.h>
#include <linux/arm-smccc.h>
+#include <linux/iopoll.h>
#define BSEC_OTP_MAX_VALUE 95
diff --git a/arch/arm/mach-stm32mp/include/mach/ddr.h b/arch/arm/mach-stm32mp/include/mach/ddr.h
index 18575842ba..b8a17cfbdd 100644
--- a/arch/arm/mach-stm32mp/include/mach/ddr.h
+++ b/arch/arm/mach-stm32mp/include/mach/ddr.h
@@ -6,6 +6,13 @@
#ifndef __MACH_STM32MP_DDR_H_
#define __MACH_STM32MP_DDR_H_
-int board_ddr_power_init(void);
+/* DDR power initializations */
+enum ddr_type {
+ STM32MP_DDR3,
+ STM32MP_LPDDR2,
+ STM32MP_LPDDR3,
+};
+
+int board_ddr_power_init(enum ddr_type ddr_type);
#endif
diff --git a/arch/arm/mach-stm32mp/include/mach/stm32.h b/arch/arm/mach-stm32mp/include/mach/stm32.h
index c526c88e3e..6795352044 100644
--- a/arch/arm/mach-stm32mp/include/mach/stm32.h
+++ b/arch/arm/mach-stm32mp/include/mach/stm32.h
@@ -88,6 +88,7 @@ enum boot_device {
#define TAMP_BACKUP_MAGIC_NUMBER TAMP_BACKUP_REGISTER(4)
#define TAMP_BACKUP_BRANCH_ADDRESS TAMP_BACKUP_REGISTER(5)
#define TAMP_BOOT_CONTEXT TAMP_BACKUP_REGISTER(20)
+#define TAMP_BOOTCOUNT TAMP_BACKUP_REGISTER(21)
#define TAMP_BOOT_MODE_MASK GENMASK(15, 8)
#define TAMP_BOOT_MODE_SHIFT 8
diff --git a/arch/arm/mach-stm32mp/psci.c b/arch/arm/mach-stm32mp/psci.c
index c2dff38c36..139bb09292 100644
--- a/arch/arm/mach-stm32mp/psci.c
+++ b/arch/arm/mach-stm32mp/psci.c
@@ -47,14 +47,14 @@ static u32 __secure stm32mp_get_gicd_base_address(void)
return (periphbase & CBAR_MASK) + GIC_DIST_OFFSET;
}
-static void __secure stm32mp_smp_kick_all_cpus(void)
+static void __secure stm32mp_raise_sgi0(int cpu)
{
u32 gic_dist_addr;
gic_dist_addr = stm32mp_get_gicd_base_address();
- /* kick all CPUs (except this one) by writing to GICD_SGIR */
- writel(1U << 24, gic_dist_addr + GICD_SGIR);
+ /* ask cpu with SGI0 */
+ writel((BIT(cpu) << 16), gic_dist_addr + GICD_SGIR);
}
void __secure psci_arch_cpu_entry(void)
@@ -62,6 +62,9 @@ void __secure psci_arch_cpu_entry(void)
u32 cpu = psci_get_cpu_id();
psci_set_state(cpu, PSCI_AFFINITY_LEVEL_ON);
+
+ /* reset magic in TAMP register */
+ writel(0xFFFFFFFF, TAMP_BACKUP_MAGIC_NUMBER);
}
int __secure psci_features(u32 function_id, u32 psci_fid)
@@ -127,6 +130,16 @@ int __secure psci_cpu_on(u32 function_id, u32 target_cpu, u32 pc,
if (psci_state[cpu] == PSCI_AFFINITY_LEVEL_ON)
return ARM_PSCI_RET_ALREADY_ON;
+ /* reset magic in TAMP register */
+ if (readl(TAMP_BACKUP_MAGIC_NUMBER))
+ writel(0xFFFFFFFF, TAMP_BACKUP_MAGIC_NUMBER);
+ /*
+ * ROM code need a first SGI0 after core reset
+ * core is ready when magic is set to 0 in ROM code
+ */
+ while (readl(TAMP_BACKUP_MAGIC_NUMBER))
+ stm32mp_raise_sgi0(cpu);
+
/* store target PC and context id*/
psci_save(cpu, pc, context_id);
@@ -142,7 +155,8 @@ int __secure psci_cpu_on(u32 function_id, u32 target_cpu, u32 pc,
writel(BOOT_API_A7_CORE0_MAGIC_NUMBER,
TAMP_BACKUP_MAGIC_NUMBER);
- stm32mp_smp_kick_all_cpus();
+ /* Generate an IT to start the core */
+ stm32mp_raise_sgi0(cpu);
return ARM_PSCI_RET_SUCCESS;
}
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 1f6df5c870..fef108105b 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -6,36 +6,69 @@ config SYS_ARCH
# processor family
config MCF520x
+ select OF_CONTROL
+ select DM
+ select DM_SERIAL
bool
config MCF52x2
+ select OF_CONTROL
+ select DM
+ select DM_SERIAL
bool
config MCF523x
+ select OF_CONTROL
+ select DM
+ select DM_SERIAL
bool
config MCF530x
+ select OF_CONTROL
+ select DM
+ select DM_SERIAL
bool
config MCF5301x
+ select OF_CONTROL
+ select DM
+ select DM_SERIAL
bool
config MCF532x
+ select OF_CONTROL
+ select DM
+ select DM_SERIAL
bool
config MCF537x
+ select OF_CONTROL
+ select DM
+ select DM_SERIAL
bool
config MCF5441x
+ select OF_CONTROL
+ select DM
+ select DM_SERIAL
bool
config MCF5445x
+ select OF_CONTROL
+ select DM
+ select DM_SERIAL
bool
config MCF5227x
+ select OF_CONTROL
+ select DM
+ select DM_SERIAL
bool
config MCF547x_8x
+ select OF_CONTROL
+ select DM
+ select DM_SERIAL
bool
# processor type
diff --git a/arch/m68k/cpu/mcf5227x/Makefile b/arch/m68k/cpu/mcf5227x/Makefile
index ef43893c51..6a38c4838e 100644
--- a/arch/m68k/cpu/mcf5227x/Makefile
+++ b/arch/m68k/cpu/mcf5227x/Makefile
@@ -6,4 +6,4 @@
# ccflags-y += -DET_DEBUG
extra-y = start.o
-obj-y = cpu.o speed.o cpu_init.o interrupts.o
+obj-y = cpu.o speed.o cpu_init.o interrupts.o dspi.o
diff --git a/arch/m68k/cpu/mcf5227x/cpu_init.c b/arch/m68k/cpu/mcf5227x/cpu_init.c
index 0d6a484a45..3bbc42f508 100644
--- a/arch/m68k/cpu/mcf5227x/cpu_init.c
+++ b/arch/m68k/cpu/mcf5227x/cpu_init.c
@@ -16,6 +16,15 @@
#include <asm/rtc.h>
#include <linux/compiler.h>
+void cfspi_port_conf(void)
+{
+ gpio_t *gpio = (gpio_t *)MMAP_GPIO;
+
+ out_8(&gpio->par_dspi,
+ GPIO_PAR_DSPI_SIN_SIN | GPIO_PAR_DSPI_SOUT_SOUT |
+ GPIO_PAR_DSPI_SCK_SCK);
+}
+
/*
* Breath some life into the CPU...
*
@@ -93,6 +102,8 @@ void cpu_init_f(void)
#endif
icache_enable();
+
+ cfspi_port_conf();
}
/*
@@ -137,57 +148,3 @@ void uart_port_conf(int port)
break;
}
}
-
-#ifdef CONFIG_CF_DSPI
-void cfspi_port_conf(void)
-{
- gpio_t *gpio = (gpio_t *) MMAP_GPIO;
-
- out_8(&gpio->par_dspi,
- GPIO_PAR_DSPI_SIN_SIN | GPIO_PAR_DSPI_SOUT_SOUT |
- GPIO_PAR_DSPI_SCK_SCK);
-}
-
-int cfspi_claim_bus(uint bus, uint cs)
-{
- dspi_t *dspi = (dspi_t *) MMAP_DSPI;
- gpio_t *gpio = (gpio_t *) MMAP_GPIO;
-
- if ((in_be32(&dspi->sr) & DSPI_SR_TXRXS) != DSPI_SR_TXRXS)
- return -1;
-
- /* Clear FIFO and resume transfer */
- clrbits_be32(&dspi->mcr, DSPI_MCR_CTXF | DSPI_MCR_CRXF);
-
- switch (cs) {
- case 0:
- clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS0_UNMASK);
- setbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS0_PCS0);
- break;
- case 2:
- clrbits_8(&gpio->par_timer, ~GPIO_PAR_TIMER_T2IN_UNMASK);
- setbits_8(&gpio->par_timer, GPIO_PAR_TIMER_T2IN_DSPIPCS2);
- break;
- }
-
- return 0;
-}
-
-void cfspi_release_bus(uint bus, uint cs)
-{
- dspi_t *dspi = (dspi_t *) MMAP_DSPI;
- gpio_t *gpio = (gpio_t *) MMAP_GPIO;
-
- /* Clear FIFO */
- clrbits_be32(&dspi->mcr, DSPI_MCR_CTXF | DSPI_MCR_CRXF);
-
- switch (cs) {
- case 0:
- clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS0_PCS0);
- break;
- case 2:
- clrbits_8(&gpio->par_timer, ~GPIO_PAR_TIMER_T2IN_UNMASK);
- break;
- }
-}
-#endif
diff --git a/arch/m68k/cpu/mcf5227x/dspi.c b/arch/m68k/cpu/mcf5227x/dspi.c
new file mode 100644
index 0000000000..8fc4da271e
--- /dev/null
+++ b/arch/m68k/cpu/mcf5227x/dspi.c
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019
+ * Angelo Dureghello <angleo@sysam.it>
+ *
+ * CPU specific dspi routines
+ */
+
+#include <common.h>
+#include <asm/immap.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_CF_DSPI
+void dspi_chip_select(int cs)
+{
+ struct gpio *gpio = (struct gpio *)MMAP_GPIO;
+
+ switch (cs) {
+ case 0:
+ clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS0_UNMASK);
+ setbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS0_PCS0);
+ break;
+ case 2:
+ clrbits_8(&gpio->par_timer, ~GPIO_PAR_TIMER_T2IN_UNMASK);
+ setbits_8(&gpio->par_timer, GPIO_PAR_TIMER_T2IN_DSPIPCS2);
+ break;
+ }
+}
+
+void dspi_chip_unselect(int cs)
+{
+ struct gpio *gpio = (struct gpio *)MMAP_GPIO;
+
+ switch (cs) {
+ case 0:
+ clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS0_PCS0);
+ break;
+ case 2:
+ clrbits_8(&gpio->par_timer, ~GPIO_PAR_TIMER_T2IN_UNMASK);
+ break;
+ }
+}
+#endif /* CONFIG_CF_DSPI */
diff --git a/arch/m68k/cpu/mcf5227x/start.S b/arch/m68k/cpu/mcf5227x/start.S
index e1b6c35133..61f9c6859c 100644
--- a/arch/m68k/cpu/mcf5227x/start.S
+++ b/arch/m68k/cpu/mcf5227x/start.S
@@ -378,7 +378,8 @@ _start:
clr.l %sp@-
/* run low-level board init code (from flash) */
- bsr board_init_f
+ move.l #board_init_f, %a1
+ jsr (%a1)
/* board_init_f() does not return */
diff --git a/arch/m68k/cpu/mcf5445x/Makefile b/arch/m68k/cpu/mcf5445x/Makefile
index be2cb2a6fb..ba90fc3c34 100644
--- a/arch/m68k/cpu/mcf5445x/Makefile
+++ b/arch/m68k/cpu/mcf5445x/Makefile
@@ -6,4 +6,4 @@
# ccflags-y += -DET_DEBUG
extra-y = start.o
-obj-y = cpu.o speed.o cpu_init.o interrupts.o pci.o
+obj-y = cpu.o speed.o cpu_init.o interrupts.o pci.o dspi.o
diff --git a/arch/m68k/cpu/mcf5445x/cpu_init.c b/arch/m68k/cpu/mcf5445x/cpu_init.c
index 7632d9262c..8f4991c1cb 100644
--- a/arch/m68k/cpu/mcf5445x/cpu_init.c
+++ b/arch/m68k/cpu/mcf5445x/cpu_init.c
@@ -66,6 +66,32 @@ void init_fbcs(void)
#endif
}
+#ifdef CONFIG_CF_DSPI
+void cfspi_port_conf(void)
+{
+ gpio_t *gpio = (gpio_t *)MMAP_GPIO;
+
+#ifdef CONFIG_MCF5445x
+ out_8(&gpio->par_dspi,
+ GPIO_PAR_DSPI_SIN_SIN |
+ GPIO_PAR_DSPI_SOUT_SOUT |
+ GPIO_PAR_DSPI_SCK_SCK);
+#endif
+
+#ifdef CONFIG_MCF5441x
+ pm_t *pm = (pm_t *)MMAP_PM;
+
+ out_8(&gpio->par_dspi0,
+ GPIO_PAR_DSPI0_SIN_DSPI0SIN | GPIO_PAR_DSPI0_SOUT_DSPI0SOUT |
+ GPIO_PAR_DSPI0_SCK_DSPI0SCK);
+ out_8(&gpio->srcr_dspiow, 3);
+
+ /* DSPI0 */
+ out_8(&pm->pmcr0, 23);
+#endif
+}
+#endif
+
/*
* Breath some life into the CPU...
*
@@ -204,6 +230,10 @@ void cpu_init_f(void)
GPIO_PAR_FBCTL_OE | GPIO_PAR_FBCTL_TA_TA |
GPIO_PAR_FBCTL_RW_RW | GPIO_PAR_FBCTL_TS_TS);
+#ifdef CONFIG_CF_SPI
+ cfspi_port_conf();
+#endif
+
#ifdef CONFIG_SYS_FSL_I2C
out_be16(&gpio->par_feci2c,
GPIO_PAR_FECI2C_SCL_SCL | GPIO_PAR_FECI2C_SDA_SDA);
@@ -433,115 +463,3 @@ int fecpin_setclear(struct eth_device *dev, int setclear)
}
#endif
-#ifdef CONFIG_CF_DSPI
-void cfspi_port_conf(void)
-{
- gpio_t *gpio = (gpio_t *) MMAP_GPIO;
-
-#ifdef CONFIG_MCF5445x
- out_8(&gpio->par_dspi,
- GPIO_PAR_DSPI_SIN_SIN |
- GPIO_PAR_DSPI_SOUT_SOUT |
- GPIO_PAR_DSPI_SCK_SCK);
-#endif
-
-#ifdef CONFIG_MCF5441x
- pm_t *pm = (pm_t *) MMAP_PM;
-
- out_8(&gpio->par_dspi0,
- GPIO_PAR_DSPI0_SIN_DSPI0SIN | GPIO_PAR_DSPI0_SOUT_DSPI0SOUT |
- GPIO_PAR_DSPI0_SCK_DSPI0SCK);
- out_8(&gpio->srcr_dspiow, 3);
-
- /* DSPI0 */
- out_8(&pm->pmcr0, 23);
-#endif
-}
-
-int cfspi_claim_bus(uint bus, uint cs)
-{
- dspi_t *dspi = (dspi_t *) MMAP_DSPI;
- gpio_t *gpio = (gpio_t *) MMAP_GPIO;
-
- if ((in_be32(&dspi->sr) & DSPI_SR_TXRXS) != DSPI_SR_TXRXS)
- return -1;
-
- /* Clear FIFO and resume transfer */
- clrbits_be32(&dspi->mcr, DSPI_MCR_CTXF | DSPI_MCR_CRXF);
-
-#ifdef CONFIG_MCF5445x
- switch (cs) {
- case 0:
- clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS0_PCS0);
- setbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS0_PCS0);
- break;
- case 1:
- clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS1_PCS1);
- setbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS1_PCS1);
- break;
- case 2:
- clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS2_PCS2);
- setbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS2_PCS2);
- break;
- case 3:
- clrbits_8(&gpio->par_dma, ~GPIO_PAR_DMA_DACK0_UNMASK);
- setbits_8(&gpio->par_dma, GPIO_PAR_DMA_DACK0_PCS3);
- break;
- case 5:
- clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS5_PCS5);
- setbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS5_PCS5);
- break;
- }
-#endif
-
-#ifdef CONFIG_MCF5441x
- switch (cs) {
- case 0:
- clrbits_8(&gpio->par_dspi0, ~GPIO_PAR_DSPI0_PCS0_MASK);
- setbits_8(&gpio->par_dspi0, GPIO_PAR_DSPI0_PCS0_DSPI0PCS0);
- break;
- case 1:
- clrbits_8(&gpio->par_dspiow, GPIO_PAR_DSPIOW_DSPI0PSC1);
- setbits_8(&gpio->par_dspiow, GPIO_PAR_DSPIOW_DSPI0PSC1);
- break;
- }
-#endif
-
- return 0;
-}
-
-void cfspi_release_bus(uint bus, uint cs)
-{
- dspi_t *dspi = (dspi_t *) MMAP_DSPI;
- gpio_t *gpio = (gpio_t *) MMAP_GPIO;
-
- /* Clear FIFO */
- clrbits_be32(&dspi->mcr, DSPI_MCR_CTXF | DSPI_MCR_CRXF);
-
-#ifdef CONFIG_MCF5445x
- switch (cs) {
- case 0:
- clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS0_PCS0);
- break;
- case 1:
- clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS1_PCS1);
- break;
- case 2:
- clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS2_PCS2);
- break;
- case 3:
- clrbits_8(&gpio->par_dma, ~GPIO_PAR_DMA_DACK0_UNMASK);
- break;
- case 5:
- clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS5_PCS5);
- break;
- }
-#endif
-
-#ifdef CONFIG_MCF5441x
- if (cs == 1)
- clrbits_8(&gpio->par_dspiow, GPIO_PAR_DSPIOW_DSPI0PSC1);
-#endif
-}
-
-#endif
diff --git a/arch/m68k/cpu/mcf5445x/dspi.c b/arch/m68k/cpu/mcf5445x/dspi.c
new file mode 100644
index 0000000000..b0e2f2cb01
--- /dev/null
+++ b/arch/m68k/cpu/mcf5445x/dspi.c
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019
+ * Angelo Dureghello <angleo@sysam.it>
+ *
+ * CPU specific dspi routines
+ */
+
+#include <common.h>
+#include <asm/immap.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_CF_DSPI
+void dspi_chip_select(int cs)
+{
+ struct gpio *gpio = (struct gpio *)MMAP_GPIO;
+
+#ifdef CONFIG_MCF5445x
+ switch (cs) {
+ case 0:
+ clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS0_PCS0);
+ setbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS0_PCS0);
+ break;
+ case 1:
+ clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS1_PCS1);
+ setbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS1_PCS1);
+ break;
+ case 2:
+ clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS2_PCS2);
+ setbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS2_PCS2);
+ break;
+ case 3:
+ clrbits_8(&gpio->par_dma, ~GPIO_PAR_DMA_DACK0_UNMASK);
+ setbits_8(&gpio->par_dma, GPIO_PAR_DMA_DACK0_PCS3);
+ break;
+ case 5:
+ clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS5_PCS5);
+ setbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS5_PCS5);
+ break;
+ }
+#endif
+#ifdef CONFIG_MCF5441x
+ switch (cs) {
+ case 0:
+ clrbits_8(&gpio->par_dspi0,
+ ~GPIO_PAR_DSPI0_PCS0_MASK);
+ setbits_8(&gpio->par_dspi0,
+ GPIO_PAR_DSPI0_PCS0_DSPI0PCS0);
+ break;
+ case 1:
+ clrbits_8(&gpio->par_dspiow,
+ GPIO_PAR_DSPIOW_DSPI0PSC1);
+ setbits_8(&gpio->par_dspiow,
+ GPIO_PAR_DSPIOW_DSPI0PSC1);
+ break;
+ }
+#endif
+}
+
+void dspi_chip_unselect(int cs)
+{
+ struct gpio *gpio = (struct gpio *)MMAP_GPIO;
+
+#ifdef CONFIG_MCF5445x
+ switch (cs) {
+ case 0:
+ clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS0_PCS0);
+ break;
+ case 1:
+ clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS1_PCS1);
+ break;
+ case 2:
+ clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS2_PCS2);
+ break;
+ case 3:
+ clrbits_8(&gpio->par_dma, ~GPIO_PAR_DMA_DACK0_UNMASK);
+ break;
+ case 5:
+ clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS5_PCS5);
+ break;
+ }
+#endif
+#ifdef CONFIG_MCF5441x
+ if (cs == 1)
+ clrbits_8(&gpio->par_dspiow, GPIO_PAR_DSPIOW_DSPI0PSC1);
+#endif
+}
+#endif /* CONFIG_CF_DSPI */
diff --git a/arch/m68k/cpu/mcf547x_8x/start.S b/arch/m68k/cpu/mcf547x_8x/start.S
index 7cb5db7ff0..4dd57bf39c 100644
--- a/arch/m68k/cpu/mcf547x_8x/start.S
+++ b/arch/m68k/cpu/mcf547x_8x/start.S
@@ -131,7 +131,8 @@ _start:
* then (and always) gd struct space will be reserved
*/
move.l %sp, -(%sp)
- bsr board_init_f_alloc_reserve
+ move.l #board_init_f_alloc_reserve, %a1
+ jsr (%a1)
/* update stack and frame-pointers */
move.l %d0, %sp
@@ -139,7 +140,8 @@ _start:
/* initialize reserved area */
move.l %d0, -(%sp)
- bsr board_init_f_init_reserve
+ move.l #board_init_f_init_reserve, %a1
+ jsr (%a1)
/* run low-level CPU init code (from flash) */
jbsr cpu_init_f
diff --git a/arch/m68k/cpu/u-boot.lds b/arch/m68k/cpu/u-boot.lds
index 96451208e5..64cf2ff5ef 100644
--- a/arch/m68k/cpu/u-boot.lds
+++ b/arch/m68k/cpu/u-boot.lds
@@ -68,13 +68,15 @@ SECTIONS
__ex_table : { *(__ex_table) }
__stop___ex_table = .;
- . = ALIGN(256);
+ . = ALIGN(4);
__init_begin = .;
.text.init : { *(.text.init) }
.data.init : { *(.data.init) }
- . = ALIGN(256);
+ . = ALIGN(4);
__init_end = .;
+ _end = .;
+
__bss_start = .;
.bss (NOLOAD) :
{
diff --git a/arch/m68k/dts/M5208EVBE.dts b/arch/m68k/dts/M5208EVBE.dts
new file mode 100644
index 0000000000..e78513f3b8
--- /dev/null
+++ b/arch/m68k/dts/M5208EVBE.dts
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf5208.dtsi"
+
+/ {
+ model = "Freescale M5208EVBE";
+ compatible = "fsl,M5208EVBE";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
+
diff --git a/arch/m68k/dts/M52277EVB.dts b/arch/m68k/dts/M52277EVB.dts
new file mode 100644
index 0000000000..a2210c8811
--- /dev/null
+++ b/arch/m68k/dts/M52277EVB.dts
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf5227x.dtsi"
+
+/ {
+ model = "Freescale M52277EVB";
+ compatible = "fsl,M52277EVB";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
+
+&dspi0 {
+ status = "okay";
+};
diff --git a/arch/m68k/dts/M52277EVB_stmicro.dts b/arch/m68k/dts/M52277EVB_stmicro.dts
new file mode 100644
index 0000000000..5fd3ca5efd
--- /dev/null
+++ b/arch/m68k/dts/M52277EVB_stmicro.dts
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf5227x.dtsi"
+
+/ {
+ model = "Freescale M52277_stmicro";
+ compatible = "fsl,M52277_stmicro";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
+
diff --git a/arch/m68k/dts/M5235EVB.dts b/arch/m68k/dts/M5235EVB.dts
new file mode 100644
index 0000000000..1a32539323
--- /dev/null
+++ b/arch/m68k/dts/M5235EVB.dts
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf523x.dtsi"
+
+/ {
+ model = "Freescale M5235EVB";
+ compatible = "fsl,M5235EVB";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
+
diff --git a/arch/m68k/dts/M5235EVB_Flash32.dts b/arch/m68k/dts/M5235EVB_Flash32.dts
new file mode 100644
index 0000000000..fcbffb23f5
--- /dev/null
+++ b/arch/m68k/dts/M5235EVB_Flash32.dts
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf523x.dtsi"
+
+/ {
+ model = "Freescale M5235EVB_Flash32";
+ compatible = "fsl,M5235EVB_Flash32";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
+
diff --git a/arch/m68k/dts/M5249EVB.dts b/arch/m68k/dts/M5249EVB.dts
new file mode 100644
index 0000000000..b2a1be9090
--- /dev/null
+++ b/arch/m68k/dts/M5249EVB.dts
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf5249.dtsi"
+
+/ {
+ model = "Freescale M5249EVB";
+ compatible = "fsl,M5249EVB";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
+
diff --git a/arch/m68k/dts/M5253DEMO.dts b/arch/m68k/dts/M5253DEMO.dts
new file mode 100644
index 0000000000..7ebaa9a2e0
--- /dev/null
+++ b/arch/m68k/dts/M5253DEMO.dts
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf5253.dtsi"
+
+/ {
+ model = "Freescale M5253DEMO";
+ compatible = "fsl,M5253DEMO";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
+
diff --git a/arch/m68k/dts/M5272C3.dts b/arch/m68k/dts/M5272C3.dts
new file mode 100644
index 0000000000..6efb8a4cc5
--- /dev/null
+++ b/arch/m68k/dts/M5272C3.dts
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf5272.dtsi"
+
+/ {
+ model = "Freescale M5272C3";
+ compatible = "fsl,M5272C3";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
+
diff --git a/arch/m68k/dts/M5275EVB.dts b/arch/m68k/dts/M5275EVB.dts
new file mode 100644
index 0000000000..cd9eb7d145
--- /dev/null
+++ b/arch/m68k/dts/M5275EVB.dts
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf5275.dtsi"
+
+/ {
+ model = "Freescale M5275EVB";
+ compatible = "fsl,M5275EVB";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
+
diff --git a/arch/m68k/dts/M5282EVB.dts b/arch/m68k/dts/M5282EVB.dts
new file mode 100644
index 0000000000..9527caafc2
--- /dev/null
+++ b/arch/m68k/dts/M5282EVB.dts
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf5282.dtsi"
+
+/ {
+ model = "Freescale M5282EVB";
+ compatible = "fsl,M5282EVB";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
+
diff --git a/arch/m68k/dts/M53017EVB.dts b/arch/m68k/dts/M53017EVB.dts
new file mode 100644
index 0000000000..b267488e0f
--- /dev/null
+++ b/arch/m68k/dts/M53017EVB.dts
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf5301x.dtsi"
+
+/ {
+ model = "Freescale M53017EVB";
+ compatible = "fsl,M53017EVB";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
+
diff --git a/arch/m68k/dts/M5329AFEE.dts b/arch/m68k/dts/M5329AFEE.dts
new file mode 100644
index 0000000000..7d121d68e7
--- /dev/null
+++ b/arch/m68k/dts/M5329AFEE.dts
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf5329.dtsi"
+
+/ {
+ model = "Freescale M5329AFEE";
+ compatible = "fsl,M5329AFEE";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
+
diff --git a/arch/m68k/dts/M5329BFEE.dts b/arch/m68k/dts/M5329BFEE.dts
new file mode 100644
index 0000000000..cd087b6ea6
--- /dev/null
+++ b/arch/m68k/dts/M5329BFEE.dts
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf5329.dtsi"
+
+/ {
+ model = "Freescale M5329BFEE";
+ compatible = "fsl,M5329BFEE";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
+
diff --git a/arch/m68k/dts/M5373EVB.dts b/arch/m68k/dts/M5373EVB.dts
new file mode 100644
index 0000000000..930f911d4a
--- /dev/null
+++ b/arch/m68k/dts/M5373EVB.dts
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf537x.dtsi"
+
+/ {
+ model = "Freescale M5373EVB";
+ compatible = "fsl,M5373EVB";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
+
diff --git a/arch/m68k/dts/M54418TWR.dts b/arch/m68k/dts/M54418TWR.dts
new file mode 100644
index 0000000000..7765c7abbb
--- /dev/null
+++ b/arch/m68k/dts/M54418TWR.dts
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf5441x.dtsi"
+
+/ {
+ model = "Freescale M54418TWR";
+ compatible = "fsl,M54418TWR";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
+
+&dspi0 {
+ status = "okay";
+};
diff --git a/arch/m68k/dts/M54418TWR_nand_mii.dts b/arch/m68k/dts/M54418TWR_nand_mii.dts
new file mode 100644
index 0000000000..9b1cb85325
--- /dev/null
+++ b/arch/m68k/dts/M54418TWR_nand_mii.dts
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf5441x.dtsi"
+
+/ {
+ model = "Freescale M54418TWR_nand_mii";
+ compatible = "fsl,M54418TWR_nand_mii";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
+
+&dspi0 {
+ status = "okay";
+};
diff --git a/arch/m68k/dts/M54418TWR_nand_rmii.dts b/arch/m68k/dts/M54418TWR_nand_rmii.dts
new file mode 100644
index 0000000000..824a66af48
--- /dev/null
+++ b/arch/m68k/dts/M54418TWR_nand_rmii.dts
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf5441x.dtsi"
+
+/ {
+ model = "Freescale M54418TWR_nand_rmii";
+ compatible = "fsl,M54418TWR_nand_rmii";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
+
+&dspi0 {
+ status = "okay";
+};
diff --git a/arch/m68k/dts/M54418TWR_nand_rmii_lowfreq.dts b/arch/m68k/dts/M54418TWR_nand_rmii_lowfreq.dts
new file mode 100644
index 0000000000..74fa197ea9
--- /dev/null
+++ b/arch/m68k/dts/M54418TWR_nand_rmii_lowfreq.dts
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf5441x.dtsi"
+
+/ {
+ model = "Freescale M54418TWR_nand_rmii_lowfreq";
+ compatible = "fsl,M54418TWR_nand_rmii_lowfreq";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
+
+&dspi0 {
+ status = "okay";
+};
diff --git a/arch/m68k/dts/M54418TWR_serial_mii.dts b/arch/m68k/dts/M54418TWR_serial_mii.dts
new file mode 100644
index 0000000000..22f27b5612
--- /dev/null
+++ b/arch/m68k/dts/M54418TWR_serial_mii.dts
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf5441x.dtsi"
+
+/ {
+ model = "Freescale M54418TWR_serial_mii";
+ compatible = "fsl,M54418TWR_serial_mii";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
+
+&dspi0 {
+ status = "okay";
+};
diff --git a/arch/m68k/dts/M54418TWR_serial_rmii.dts b/arch/m68k/dts/M54418TWR_serial_rmii.dts
new file mode 100644
index 0000000000..0ddefd9da2
--- /dev/null
+++ b/arch/m68k/dts/M54418TWR_serial_rmii.dts
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf5441x.dtsi"
+
+/ {
+ model = "Freescale M54418TWR_serial_rmii";
+ compatible = "fsl,M54418TWR_serial_rmii";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
+
+&dspi0 {
+ status = "okay";
+};
diff --git a/arch/m68k/dts/M54451EVB.dts b/arch/m68k/dts/M54451EVB.dts
new file mode 100644
index 0000000000..b57bfea2cb
--- /dev/null
+++ b/arch/m68k/dts/M54451EVB.dts
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf5445x.dtsi"
+
+/ {
+ model = "Freescale M54451EVB";
+ compatible = "fsl,M54451EVB";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
+
+&dspi0 {
+ status = "okay";
+};
diff --git a/arch/m68k/dts/M54451EVB_stmicro.dts b/arch/m68k/dts/M54451EVB_stmicro.dts
new file mode 100644
index 0000000000..9a088e16d0
--- /dev/null
+++ b/arch/m68k/dts/M54451EVB_stmicro.dts
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf5445x.dtsi"
+
+/ {
+ model = "Freescale M54451EVB_stmicro";
+ compatible = "fsl,M54451EVB";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
+
+&dspi0 {
+ status = "okay";
+};
diff --git a/arch/m68k/dts/M54455EVB.dts b/arch/m68k/dts/M54455EVB.dts
new file mode 100644
index 0000000000..dd11181033
--- /dev/null
+++ b/arch/m68k/dts/M54455EVB.dts
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf5445x.dtsi"
+
+/ {
+ model = "Freescale M54455EVB";
+ compatible = "fsl,M54455EVB";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
+
+&dspi0 {
+ status = "okay";
+};
diff --git a/arch/m68k/dts/M54455EVB_a66.dts b/arch/m68k/dts/M54455EVB_a66.dts
new file mode 100644
index 0000000000..70d544b72d
--- /dev/null
+++ b/arch/m68k/dts/M54455EVB_a66.dts
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf5445x.dtsi"
+
+/ {
+ model = "Freescale M54455EVB_a66";
+ compatible = "fsl,M54455EVB_a66";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
+
+&dspi0 {
+ status = "okay";
+};
diff --git a/arch/m68k/dts/M54455EVB_i66.dts b/arch/m68k/dts/M54455EVB_i66.dts
new file mode 100644
index 0000000000..b37a87213f
--- /dev/null
+++ b/arch/m68k/dts/M54455EVB_i66.dts
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf5445x.dtsi"
+
+/ {
+ model = "Freescale M54455EVB_i66";
+ compatible = "fsl,M54455EVB_i66";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
+
+&dspi0 {
+ status = "okay";
+};
diff --git a/arch/m68k/dts/M54455EVB_intel.dts b/arch/m68k/dts/M54455EVB_intel.dts
new file mode 100644
index 0000000000..c92228fc8b
--- /dev/null
+++ b/arch/m68k/dts/M54455EVB_intel.dts
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf5445x.dtsi"
+
+/ {
+ model = "Freescale M54455EVB_intel";
+ compatible = "fsl,M5275EVB_intel";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
+
+&dspi0 {
+ status = "okay";
+};
+
diff --git a/arch/m68k/dts/M54455EVB_stm33.dts b/arch/m68k/dts/M54455EVB_stm33.dts
new file mode 100644
index 0000000000..9e467f94a1
--- /dev/null
+++ b/arch/m68k/dts/M54455EVB_stm33.dts
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf5445x.dtsi"
+
+/ {
+ model = "Freescale M54455EVB_stm33";
+ compatible = "fsl,M5275EVB_stm33";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
+
+&dspi0 {
+ status = "okay";
+};
diff --git a/arch/m68k/dts/M5475AFE.dts b/arch/m68k/dts/M5475AFE.dts
new file mode 100644
index 0000000000..0c0a79befa
--- /dev/null
+++ b/arch/m68k/dts/M5475AFE.dts
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf54xx.dtsi"
+
+/ {
+ model = "Freescale M5475AFE";
+ compatible = "fsl,M5475AFE";
+};
+
diff --git a/arch/m68k/dts/M5475BFE.dts b/arch/m68k/dts/M5475BFE.dts
new file mode 100644
index 0000000000..c4d14097cd
--- /dev/null
+++ b/arch/m68k/dts/M5475BFE.dts
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf54xx.dtsi"
+
+/ {
+ model = "Freescale M5475BFE";
+ compatible = "fsl,M5475BFE";
+};
+
diff --git a/arch/m68k/dts/M5475CFE.dts b/arch/m68k/dts/M5475CFE.dts
new file mode 100644
index 0000000000..4c92c332ba
--- /dev/null
+++ b/arch/m68k/dts/M5475CFE.dts
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf54xx.dtsi"
+
+/ {
+ model = "Freescale M5475CFE";
+ compatible = "fsl,M5475CFE";
+};
+
diff --git a/arch/m68k/dts/M5475DFE.dts b/arch/m68k/dts/M5475DFE.dts
new file mode 100644
index 0000000000..c41c1b3c12
--- /dev/null
+++ b/arch/m68k/dts/M5475DFE.dts
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf54xx.dtsi"
+
+/ {
+ model = "Freescale M5475DFE";
+ compatible = "fsl,M5475DFE";
+};
+
diff --git a/arch/m68k/dts/M5475EFE.dts b/arch/m68k/dts/M5475EFE.dts
new file mode 100644
index 0000000000..5a920b241a
--- /dev/null
+++ b/arch/m68k/dts/M5475EFE.dts
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf54xx.dtsi"
+
+/ {
+ model = "Freescale M5475EFE";
+ compatible = "fsl,M5475EFE";
+};
+
diff --git a/arch/m68k/dts/M5475FFE.dts b/arch/m68k/dts/M5475FFE.dts
new file mode 100644
index 0000000000..d312a6ae8d
--- /dev/null
+++ b/arch/m68k/dts/M5475FFE.dts
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf54xx.dtsi"
+
+/ {
+ model = "Freescale M5475FFE";
+ compatible = "fsl,M5475FFE";
+};
+
diff --git a/arch/m68k/dts/M5475GFE.dts b/arch/m68k/dts/M5475GFE.dts
new file mode 100644
index 0000000000..9e794dafa6
--- /dev/null
+++ b/arch/m68k/dts/M5475GFE.dts
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf54xx.dtsi"
+
+/ {
+ model = "Freescale M5475GFE";
+ compatible = "fsl,M5475GFE";
+};
+
diff --git a/arch/m68k/dts/M5485AFE.dts b/arch/m68k/dts/M5485AFE.dts
new file mode 100644
index 0000000000..3466751174
--- /dev/null
+++ b/arch/m68k/dts/M5485AFE.dts
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf54xx.dtsi"
+
+/ {
+ model = "Freescale M5485AFE";
+ compatible = "fsl,M5485AFE";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
diff --git a/arch/m68k/dts/M5485BFE.dts b/arch/m68k/dts/M5485BFE.dts
new file mode 100644
index 0000000000..6d48795a4d
--- /dev/null
+++ b/arch/m68k/dts/M5485BFE.dts
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf54xx.dtsi"
+
+/ {
+ model = "Freescale M5485BFE";
+ compatible = "fsl,M5485BFE";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
diff --git a/arch/m68k/dts/M5485CFE.dts b/arch/m68k/dts/M5485CFE.dts
new file mode 100644
index 0000000000..d1a7d9d383
--- /dev/null
+++ b/arch/m68k/dts/M5485CFE.dts
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf54xx.dtsi"
+
+/ {
+ model = "Freescale M5485CFE";
+ compatible = "fsl,M5485CFE";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
diff --git a/arch/m68k/dts/M5485DFE.dts b/arch/m68k/dts/M5485DFE.dts
new file mode 100644
index 0000000000..7c362e26e5
--- /dev/null
+++ b/arch/m68k/dts/M5485DFE.dts
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf54xx.dtsi"
+
+/ {
+ model = "Freescale M5485DFE";
+ compatible = "fsl,M5485DFE";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
diff --git a/arch/m68k/dts/M5485EFE.dts b/arch/m68k/dts/M5485EFE.dts
new file mode 100644
index 0000000000..4c688dce2b
--- /dev/null
+++ b/arch/m68k/dts/M5485EFE.dts
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf54xx.dtsi"
+
+/ {
+ model = "Freescale M5485EFE";
+ compatible = "fsl,M5485EFE";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
diff --git a/arch/m68k/dts/M5485FFE.dts b/arch/m68k/dts/M5485FFE.dts
new file mode 100644
index 0000000000..87ec2c543d
--- /dev/null
+++ b/arch/m68k/dts/M5485FFE.dts
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf54xx.dtsi"
+
+/ {
+ model = "Freescale M5485FFE";
+ compatible = "fsl,M5485FFE";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
diff --git a/arch/m68k/dts/M5485GFE.dts b/arch/m68k/dts/M5485GFE.dts
new file mode 100644
index 0000000000..9f67e5516b
--- /dev/null
+++ b/arch/m68k/dts/M5485GFE.dts
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf54xx.dtsi"
+
+/ {
+ model = "Freescale M5485GFE";
+ compatible = "fsl,M5485GFE";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
diff --git a/arch/m68k/dts/M5485HFE.dts b/arch/m68k/dts/M5485HFE.dts
new file mode 100644
index 0000000000..2eb2213d78
--- /dev/null
+++ b/arch/m68k/dts/M5485HFE.dts
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf54xx.dtsi"
+
+/ {
+ model = "Freescale M5485HFE";
+ compatible = "fsl,M5485HFE";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
diff --git a/arch/m68k/dts/Makefile b/arch/m68k/dts/Makefile
new file mode 100644
index 0000000000..e059f23ccd
--- /dev/null
+++ b/arch/m68k/dts/Makefile
@@ -0,0 +1,59 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+dtb-$(CONFIG_TARGET_M52277EVB) += M52277EVB.dtb \
+ M52277EVB_stmicro.dtb
+dtb-$(CONFIG_TARGET_M5235EVB) += M5235EVB.dtb \
+ M5235EVB_Flash32.dtb
+dtb-$(CONFIG_TARGET_COBRA5272) += cobra5272.dtb
+dtb-$(CONFIG_TARGET_EB_CPU5282) += eb_cpu5282.dtb \
+ eb_cpu5282_internal.dtb
+dtb-$(CONFIG_TARGET_M5208EVBE) += M5208EVBE.dtb
+dtb-$(CONFIG_TARGET_M5249EVB) += M5249EVB.dtb
+dtb-$(CONFIG_TARGET_M5253DEMO) += M5253DEMO.dtb
+dtb-$(CONFIG_TARGET_M5272C3) += M5272C3.dtb
+dtb-$(CONFIG_TARGET_M5275EVB) += M5275EVB.dtb
+dtb-$(CONFIG_TARGET_M5282EVB) += M5282EVB.dtb
+dtb-$(CONFIG_TARGET_ASTRO_MCF5373L) += astro_mcf5373l.dtb
+dtb-$(CONFIG_TARGET_M53017EVB) += M53017EVB.dtb
+dtb-$(CONFIG_TARGET_M5329EVB) += M5329AFEE.dtb M5329BFEE.dtb
+dtb-$(CONFIG_TARGET_M5373EVB) += M5373EVB.dtb
+dtb-$(CONFIG_TARGET_M54418TWR) += M54418TWR.dtb \
+ M54418TWR_nand_mii.dtb \
+ M54418TWR_nand_rmii.dtb \
+ M54418TWR_serial_mii.dtb \
+ M54418TWR_serial_rmii.dtb \
+ M54418TWR_nand_rmii_lowfreq.dtb
+dtb-$(CONFIG_TARGET_M54451EVB) += M54451EVB.dtb \
+ M54451EVB_stmicro.dtb
+dtb-$(CONFIG_TARGET_M54455EVB) += M54455EVB.dtb \
+ M54455EVB_intel.dtb \
+ M54455EVB_stm33.dtb \
+ M54455EVB_a66.dtb \
+ M54455EVB_i66.dtb
+dtb-$(CONFIG_TARGET_AMCORE) += amcore.dtb
+dtb-$(CONFIG_TARGET_STMARK2) += stmark2.dtb
+dtb-$(CONFIG_TARGET_M5475EVB) += M5475AFE.dtb \
+ M5475BFE.dtb \
+ M5475CFE.dtb \
+ M5475DFE.dtb \
+ M5475EFE.dtb \
+ M5475FFE.dtb \
+ M5475GFE.dtb
+dtb-$(CONFIG_TARGET_M5485EVB) += M5485AFE.dtb \
+ M5485BFE.dtb \
+ M5485CFE.dtb \
+ M5485DFE.dtb \
+ M5485EFE.dtb \
+ M5485FFE.dtb \
+ M5485GFE.dtb \
+ M5485HFE.dtb
+
+targets += $(dtb-y)
+
+DTC_FLAGS += -R 4 -p 0x1000
+
+PHONY += dtbs
+dtbs: $(addprefix $(obj)/, $(dtb-y))
+ @:
+
+clean-files := *.dtb
diff --git a/arch/m68k/dts/amcore.dts b/arch/m68k/dts/amcore.dts
new file mode 100644
index 0000000000..c21fb8ff79
--- /dev/null
+++ b/arch/m68k/dts/amcore.dts
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf5307.dtsi"
+
+/ {
+ model = "Sysam AMCORE";
+ compatible = "sysam,AMCORE";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
+
diff --git a/arch/m68k/dts/astro_mcf5373l.dts b/arch/m68k/dts/astro_mcf5373l.dts
new file mode 100644
index 0000000000..1b1a46ac2d
--- /dev/null
+++ b/arch/m68k/dts/astro_mcf5373l.dts
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf537x.dtsi"
+
+/ {
+ model = "Astro mcf5373l";
+ compatible = "astro,mcf5373l";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
+
diff --git a/arch/m68k/dts/cobra5272.dts b/arch/m68k/dts/cobra5272.dts
new file mode 100644
index 0000000000..f3b74975de
--- /dev/null
+++ b/arch/m68k/dts/cobra5272.dts
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf5272.dtsi"
+
+/ {
+ model = "Cobra 5272";
+ compatible = "cobra,M5272";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
+
diff --git a/arch/m68k/dts/eb_cpu5282.dts b/arch/m68k/dts/eb_cpu5282.dts
new file mode 100644
index 0000000000..4641e9cb56
--- /dev/null
+++ b/arch/m68k/dts/eb_cpu5282.dts
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf5282.dtsi"
+
+/ {
+ model = "BuS eb_cpuM5282";
+ compatible = "bus,eb_cpuM5282";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
+
diff --git a/arch/m68k/dts/eb_cpu5282_internal.dts b/arch/m68k/dts/eb_cpu5282_internal.dts
new file mode 100644
index 0000000000..0acb7935f4
--- /dev/null
+++ b/arch/m68k/dts/eb_cpu5282_internal.dts
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf5282.dtsi"
+
+/ {
+ model = "BuS eb_cpu5282_internals";
+ compatible = "bus,eb_cpu5282_internals";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
+
diff --git a/arch/m68k/dts/mcf5208.dtsi b/arch/m68k/dts/mcf5208.dtsi
new file mode 100644
index 0000000000..558d8bf41a
--- /dev/null
+++ b/arch/m68k/dts/mcf5208.dtsi
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/ {
+ compatible = "fsl,mcf5208";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ uart0: uart@fc060000 {
+ compatible = "fsl,mcf-uart";
+ reg = <0xfc060000 0x40>;
+ status = "disabled";
+ };
+
+ uart1: uart@fc064000 {
+ compatible = "fsl,mcf-uart";
+ reg = <0xfc064000 0x40>;
+ status = "disabled";
+ };
+
+ uart2: uart@fc068000 {
+ compatible = "fsl,mcf-uart";
+ reg = <0xfc068000 0x40>;
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/m68k/dts/mcf5227x.dtsi b/arch/m68k/dts/mcf5227x.dtsi
new file mode 100644
index 0000000000..8c95edddb6
--- /dev/null
+++ b/arch/m68k/dts/mcf5227x.dtsi
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/ {
+ compatible = "fsl,mcf5227x";
+
+ aliases {
+ serial0 = &uart0;
+ spi0 = &dspi0;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ uart0: uart@fc060000 {
+ compatible = "fsl,mcf-uart";
+ reg = <0xfc060000 0x40>;
+ status = "disabled";
+ };
+
+ uart1: uart@fc064000 {
+ compatible = "fsl,mcf-uart";
+ reg = <0xfc064000 0x40>;
+ status = "disabled";
+ };
+
+ uart2: uart@fc068000 {
+ compatible = "fsl,mcf-uart";
+ reg = <0xfc068000 0x40>;
+ status = "disabled";
+ };
+
+ dspi0: dspi@fc05c000 {
+ compatible = "fsl,mcf-dspi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xfc05c000 0x100>;
+ spi-max-frequency = <50000000>;
+ num-cs = <4>;
+ spi-mode = <0>;
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/m68k/dts/mcf523x.dtsi b/arch/m68k/dts/mcf523x.dtsi
new file mode 100644
index 0000000000..9e79d472ec
--- /dev/null
+++ b/arch/m68k/dts/mcf523x.dtsi
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/ {
+ compatible = "fsl,mcf523x";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ ipsbar: ipsbar@4000000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x00000000 0x40000000 0x40000000>;
+ reg = <0x40000000 0x40000000>;
+
+ uart0: uart@200 {
+ compatible = "fsl,mcf-uart";
+ reg = <0x200 0x40>;
+ status = "disabled";
+ };
+
+ uart1: uart@240 {
+ compatible = "fsl,mcf-uart";
+ reg = <0x240 0x40>;
+ status = "disabled";
+ };
+
+ uart2: uart@280 {
+ compatible = "fsl,mcf-uart";
+ reg = <0x280 0x40>;
+ status = "disabled";
+ };
+ };
+ };
+};
diff --git a/arch/m68k/dts/mcf5249.dtsi b/arch/m68k/dts/mcf5249.dtsi
new file mode 100644
index 0000000000..248b3dc68b
--- /dev/null
+++ b/arch/m68k/dts/mcf5249.dtsi
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/ {
+ compatible = "fsl,mcf5249";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ mbar: mbar@10000000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x00000000 0x10000000 0x10000>;
+ reg = <0x10000000 0x10000>;
+
+ uart0: uart@1c0 {
+ compatible = "fsl,mcf-uart";
+ reg = <0x1c0 0x40>;
+ status = "disabled";
+ };
+
+ uart1: uart@200 {
+ compatible = "fsl,mcf-uart";
+ reg = <0x200 0x40>;
+ status = "disabled";
+ };
+ };
+ };
+};
diff --git a/arch/m68k/dts/mcf5253.dtsi b/arch/m68k/dts/mcf5253.dtsi
new file mode 100644
index 0000000000..3bde2d6202
--- /dev/null
+++ b/arch/m68k/dts/mcf5253.dtsi
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/ {
+ compatible = "fsl,mcf5253";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ mbar: mbar@10000000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x00000000 0x10000000 0x10000>;
+ reg = <0x10000000 0x10000>;
+
+ uart0: uart@1c0 {
+ compatible = "fsl,mcf-uart";
+ reg = <0x1c0 0x40>;
+ status = "disabled";
+ };
+
+ uart1: uart@200 {
+ compatible = "fsl,mcf-uart";
+ reg = <0x200 0x40>;
+ status = "disabled";
+ };
+
+ uart3: uart@c00 {
+ compatible = "fsl,mcf-uart";
+ reg = <0xc00 0x40>;
+ status = "disabled";
+ };
+ };
+ };
+};
diff --git a/arch/m68k/dts/mcf5271.dtsi b/arch/m68k/dts/mcf5271.dtsi
new file mode 100644
index 0000000000..29355528d0
--- /dev/null
+++ b/arch/m68k/dts/mcf5271.dtsi
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/ {
+ compatible = "fsl,mcf5271";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ ipsbar: ipsbar@4000000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x00000000 0x40000000 0x40000000>;
+ reg = <0x40000000 0x40000000>;
+
+ uart0: uart@200 {
+ compatible = "fsl,mcf-uart";
+ reg = <0x200 0x40>;
+ status = "disabled";
+ };
+
+ uart1: uart@240 {
+ compatible = "fsl,mcf-uart";
+ reg = <0x240 0x40>;
+ status = "disabled";
+ };
+
+ uart2: uart@280 {
+ compatible = "fsl,mcf-uart";
+ reg = <0x280 0x40>;
+ status = "disabled";
+ };
+ };
+ };
+};
diff --git a/arch/m68k/dts/mcf5272.dtsi b/arch/m68k/dts/mcf5272.dtsi
new file mode 100644
index 0000000000..a56117728b
--- /dev/null
+++ b/arch/m68k/dts/mcf5272.dtsi
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/ {
+ compatible = "fsl,mcf5272";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ mbar: mbar@10000000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x00000000 0x10000000 0x10000>;
+ reg = <0x10000000 0x10000>;
+
+ uart0: uart@100 {
+ compatible = "fsl,mcf-uart";
+ reg = <0x100 0x40>;
+ status = "disabled";
+ };
+
+ uart1: uart@140 {
+ compatible = "fsl,mcf-uart";
+ reg = <0x140 0x40>;
+ status = "disabled";
+ };
+ };
+ };
+};
diff --git a/arch/m68k/dts/mcf5275.dtsi b/arch/m68k/dts/mcf5275.dtsi
new file mode 100644
index 0000000000..b375609d4a
--- /dev/null
+++ b/arch/m68k/dts/mcf5275.dtsi
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/ {
+ compatible = "fsl,mcf5275";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ ipsbar: ipsbar@4000000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x00000000 0x40000000 0x40000000>;
+ reg = <0x40000000 0x40000000>;
+
+ uart0: uart@200 {
+ compatible = "fsl,mcf-uart";
+ reg = <0x200 0x40>;
+ status = "disabled";
+ };
+
+ uart1: uart@240 {
+ compatible = "fsl,mcf-uart";
+ reg = <0x240 0x40>;
+ status = "disabled";
+ };
+
+ uart2: uart@280 {
+ compatible = "fsl,mcf-uart";
+ reg = <0x280 0x40>;
+ status = "disabled";
+ };
+ };
+ };
+};
diff --git a/arch/m68k/dts/mcf5282.dtsi b/arch/m68k/dts/mcf5282.dtsi
new file mode 100644
index 0000000000..3ad1be7bb5
--- /dev/null
+++ b/arch/m68k/dts/mcf5282.dtsi
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/ {
+ compatible = "fsl,mcf5282";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ ipsbar: ipsbar@4000000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x00000000 0x40000000 0x40000000>;
+ reg = <0x40000000 0x40000000>;
+
+ uart0: uart@200 {
+ compatible = "fsl,mcf-uart";
+ reg = <0x200 0x40>;
+ status = "disabled";
+ };
+
+ uart1: uart@240 {
+ compatible = "fsl,mcf-uart";
+ reg = <0x240 0x40>;
+ status = "disabled";
+ };
+
+ uart2: uart@280 {
+ compatible = "fsl,mcf-uart";
+ reg = <0x280 0x40>;
+ status = "disabled";
+ };
+ };
+ };
+};
diff --git a/arch/m68k/dts/mcf5301x.dtsi b/arch/m68k/dts/mcf5301x.dtsi
new file mode 100644
index 0000000000..0891e4dfd5
--- /dev/null
+++ b/arch/m68k/dts/mcf5301x.dtsi
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/ {
+ compatible = "fsl,mcf5301x";
+
+ aliases {
+ serial0 = &uart0;
+ spi0 = &dspi0;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ uart0: uart@fc060000 {
+ compatible = "fsl,mcf-uart";
+ reg = <0xfc060000 0x40>;
+ status = "disabled";
+ };
+
+ uart1: uart@fc064000 {
+ compatible = "fsl,mcf-uart";
+ reg = <0xfc064000 0x40>;
+ status = "disabled";
+ };
+
+ uart2: uart@fc068000 {
+ compatible = "fsl,mcf-uart";
+ reg = <0xfc068000 0x40>;
+ status = "disabled";
+ };
+
+ dspi0: dspi@fc05c000 {
+ compatible = "fsl,mcf-dspi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xfc05c000 0x100>;
+ spi-max-frequency = <50000000>;
+ num-cs = <4>;
+ spi-mode = <0>;
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/m68k/dts/mcf5307.dtsi b/arch/m68k/dts/mcf5307.dtsi
new file mode 100644
index 0000000000..e199cf9991
--- /dev/null
+++ b/arch/m68k/dts/mcf5307.dtsi
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/ {
+ compatible = "fsl,mcf5307";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ /* MBAR */
+ mbar: mbar@10000000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x00000000 0x10000000 0x10000>;
+ reg = <0x10000000 0x10000>;
+
+ uart0: uart@1c0 {
+ compatible = "fsl,mcf-uart";
+ reg = <0x1c0 0x40>;
+ status = "disabled";
+ };
+
+ uart1: uart@200 {
+ compatible = "fsl,mcf-uart";
+ reg = <0x200 0x40>;
+ status = "disabled";
+ };
+ };
+ };
+};
diff --git a/arch/m68k/dts/mcf5329.dtsi b/arch/m68k/dts/mcf5329.dtsi
new file mode 100644
index 0000000000..aeaa6430af
--- /dev/null
+++ b/arch/m68k/dts/mcf5329.dtsi
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/ {
+ compatible = "fsl,mcf5329";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ uart0: uart@fc060000 {
+ compatible = "fsl,mcf-uart";
+ reg = <0xfc060000 0x40>;
+ status = "disabled";
+ };
+
+ uart1: uart@fc064000 {
+ compatible = "fsl,mcf-uart";
+ reg = <0xfc064000 0x40>;
+ status = "disabled";
+ };
+
+ uart2: uart@fc068000 {
+ compatible = "fsl,mcf-uart";
+ reg = <0xfc068000 0x40>;
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/m68k/dts/mcf537x.dtsi b/arch/m68k/dts/mcf537x.dtsi
new file mode 100644
index 0000000000..aeaa6430af
--- /dev/null
+++ b/arch/m68k/dts/mcf537x.dtsi
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/ {
+ compatible = "fsl,mcf5329";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ uart0: uart@fc060000 {
+ compatible = "fsl,mcf-uart";
+ reg = <0xfc060000 0x40>;
+ status = "disabled";
+ };
+
+ uart1: uart@fc064000 {
+ compatible = "fsl,mcf-uart";
+ reg = <0xfc064000 0x40>;
+ status = "disabled";
+ };
+
+ uart2: uart@fc068000 {
+ compatible = "fsl,mcf-uart";
+ reg = <0xfc068000 0x40>;
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/m68k/dts/mcf5441x.dtsi b/arch/m68k/dts/mcf5441x.dtsi
new file mode 100644
index 0000000000..71b392adc3
--- /dev/null
+++ b/arch/m68k/dts/mcf5441x.dtsi
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/ {
+ compatible = "fsl,mcf5441x";
+
+ aliases {
+ serial0 = &uart0;
+ spi0 = &dspi0;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ uart0: uart@fc060000 {
+ compatible = "fsl,mcf-uart";
+ reg = <0xfc060000 0x40>;
+ status = "disabled";
+ };
+
+ uart1: uart@fc064000 {
+ compatible = "fsl,mcf-uart";
+ reg = <0xfc064000 0x40>;
+ status = "disabled";
+ };
+
+ uart2: uart@fc068000 {
+ compatible = "fsl,mcf-uart";
+ reg = <0xfc068000 0x40>;
+ status = "disabled";
+ };
+
+ uart3: uart@fc06c000 {
+ compatible = "fsl,mcf-uart";
+ reg = <0xfc06c000 0x40>;
+ status = "disabled";
+ };
+
+ dspi0: dspi@fc05c000 {
+ compatible = "fsl,mcf-dspi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xfc05c000 0x100>;
+ spi-max-frequency = <50000000>;
+ num-cs = <4>;
+ spi-mode = <0>;
+ status = "disabled";
+ };
+
+ dspi1: dspi@fc03c000 {
+ compatible = "fsl,mcf-dspi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xfc03c000 0x100>;
+ spi-max-frequency = <50000000>;
+ num-cs = <4>;
+ spi-mode = <0>;
+ status = "disabled";
+ };
+
+ dspi2: dspi@ec038000 {
+ compatible = "fsl,mcf-dspi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xec038000 0x100>;
+ spi-max-frequency = <50000000>;
+ num-cs = <4>;
+ spi-mode = <0>;
+ status = "disabled";
+ };
+
+ dspi3: dspi@ec03c000 {
+ compatible = "fsl,mcf-dspi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xec03c00 0x100>;
+ spi-max-frequency = <50000000>;
+ num-cs = <4>;
+ spi-mode = <0>;
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/m68k/dts/mcf5445x.dtsi b/arch/m68k/dts/mcf5445x.dtsi
new file mode 100644
index 0000000000..ccbee29a6c
--- /dev/null
+++ b/arch/m68k/dts/mcf5445x.dtsi
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/ {
+ compatible = "fsl,mcf5445x";
+
+ aliases {
+ serial0 = &uart0;
+ spi0 = &dspi0;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ uart0: uart@fc060000 {
+ compatible = "fsl,mcf-uart";
+ reg = <0xfc060000 0x40>;
+ status = "disabled";
+ };
+
+ uart1: uart@fc064000 {
+ compatible = "fsl,mcf-uart";
+ reg = <0xfc064000 0x40>;
+ status = "disabled";
+ };
+
+ uart2: uart@fc068000 {
+ compatible = "fsl,mcf-uart";
+ reg = <0xfc068000 0x40>;
+ status = "disabled";
+ };
+
+ dspi0: dspi@fc05c000 {
+ compatible = "fsl,mcf-dspi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xfc05c000 0x100>;
+ spi-max-frequency = <50000000>;
+ num-cs = <4>;
+ spi-mode = <0>;
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/m68k/dts/mcf54xx.dtsi b/arch/m68k/dts/mcf54xx.dtsi
new file mode 100644
index 0000000000..537bb424f3
--- /dev/null
+++ b/arch/m68k/dts/mcf54xx.dtsi
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/ {
+ compatible = "fsl,mcf54x5";
+
+ aliases {
+ /* TO DO, clarify on serial, this SoC seems to have SPC and
+ * no UARTS.
+ */
+ spi0 = &dspi0;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ mbar: mbar@80000000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x00000000 0x80000000 0x10000>;
+ reg = <0x80000000 0x10000>;
+
+ dspi0: dspi@8a00 {
+ compatible = "fsl,mcf-dspi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x8a00 0x100>;
+ spi-max-frequency = <50000000>;
+ num-cs = <4>;
+ spi-mode = <0>;
+ status = "disabled";
+ };
+ };
+ };
+};
diff --git a/arch/m68k/dts/stmark2.dts b/arch/m68k/dts/stmark2.dts
new file mode 100644
index 0000000000..fd8ce4fa35
--- /dev/null
+++ b/arch/m68k/dts/stmark2.dts
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+/dts-v1/;
+/include/ "mcf5441x.dtsi"
+
+/ {
+ model = "Sysam stmark2";
+ compatible = "sysam,stmark2";
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
+
+&dspi0 {
+ spi-mode = <3>;
+ status = "okay";
+
+ flash: is25lp128@1 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spi-flash";
+ spi-max-frequency = <60000000>;
+ reg = <1>;
+ };
+};
diff --git a/arch/m68k/include/asm/coldfire/dspi.h b/arch/m68k/include/asm/coldfire/dspi.h
index afd5c79f35..ddd8f33805 100644
--- a/arch/m68k/include/asm/coldfire/dspi.h
+++ b/arch/m68k/include/asm/coldfire/dspi.h
@@ -138,4 +138,8 @@ typedef struct dspi {
/* Bit definitions and macros for DRFDR group */
#define DSPI_RFDR_RXDATA(x) (((x)&0x0000FFFF))
+/* Architecture-related operations */
+void dspi_chip_select(int cs);
+void dspi_chip_unselect(int cs);
+
#endif /* __DSPI_H__ */
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 9cf8e9800d..5cb9bdf2ee 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -84,13 +84,13 @@ config ARCH_MTMIPS
select DM_SERIAL
imply DM_SPI
imply DM_SPI_FLASH
- select ARCH_MISC_INIT
select MIPS_TUNE_24KC
select OF_CONTROL
select ROM_EXCEPTION_VECTORS
select SUPPORTS_CPU_MIPS32_R1
select SUPPORTS_CPU_MIPS32_R2
select SUPPORTS_LITTLE_ENDIAN
+ select SYS_MALLOC_CLEAR_ON_INIT
select SYSRESET
config ARCH_JZ47XX
diff --git a/arch/mips/mach-mtmips/cpu.c b/arch/mips/mach-mtmips/cpu.c
index fcd0484a6d..b0a6397d68 100644
--- a/arch/mips/mach-mtmips/cpu.c
+++ b/arch/mips/mach-mtmips/cpu.c
@@ -68,18 +68,3 @@ int print_cpuinfo(void)
return 0;
}
-
-int arch_misc_init(void)
-{
- /*
- * It has been noticed, that sometimes the d-cache is not in a
- * "clean-state" when U-Boot is running on MT7688. This was
- * detected when using the ethernet driver (which uses d-cache)
- * and a TFTP command does not complete. Flushing the complete
- * d-cache (again?) here seems to fix this issue.
- */
- flush_dcache_range(gd->bd->bi_memstart,
- gd->bd->bi_memstart + gd->ram_size - 1);
-
- return 0;
-}
diff --git a/arch/powerpc/cpu/mpc85xx/Kconfig b/arch/powerpc/cpu/mpc85xx/Kconfig
index 0057f195b3..aebf168a89 100644
--- a/arch/powerpc/cpu/mpc85xx/Kconfig
+++ b/arch/powerpc/cpu/mpc85xx/Kconfig
@@ -352,7 +352,6 @@ config TARGET_T2080QDS
select PHYS_64BIT
select FSL_DDR_FIRST_SLOT_QUAD_CAPABLE
select FSL_DDR_INTERACTIVE
- imply CMD_SATA
config TARGET_T2080RDB
bool "Support T2080RDB"
@@ -361,6 +360,7 @@ config TARGET_T2080RDB
select SUPPORT_SPL
select PHYS_64BIT
imply CMD_SATA
+ imply FSL_SATA
imply PANIC_HANG
config TARGET_T2081QDS
@@ -1081,10 +1081,8 @@ config ARCH_T2080
select SYS_FSL_SEC_COMPAT_4
select SYS_PPC64
select FSL_IFC
- imply CMD_SATA
imply CMD_NAND
imply CMD_REGINFO
- imply FSL_SATA
config ARCH_T2081
bool
diff --git a/arch/powerpc/dts/t2080.dtsi b/arch/powerpc/dts/t2080.dtsi
index db65ea5725..d2bebb08b6 100644
--- a/arch/powerpc/dts/t2080.dtsi
+++ b/arch/powerpc/dts/t2080.dtsi
@@ -58,5 +58,50 @@
device_type = "open-pic";
clock-frequency = <0x0>;
};
+
+ esdhc: esdhc@114000 {
+ compatible = "fsl,esdhc";
+ reg = <0x114000 0x1000>;
+ interrupts = <48 2 0 0>;
+ clock-frequency = <0>;
+ sdhci,auto-cmd12;
+ bus-width = <4>;
+ voltage-ranges = <1800 1800 3300 3300>;
+ };
+
+ usb0: usb@210000 {
+ compatible = "fsl-usb2-mph";
+ reg = <0x210000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <44 0x2 0 0>;
+ phy_type = "utmi";
+ };
+
+ usb1: usb@211000 {
+ compatible = "fsl-usb2-dr";
+ reg = <0x211000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <45 0x2 0 0>;
+ dr_mode = "host";
+ phy_type = "utmi";
+ };
+
+ sata0: sata@220000 {
+ compatible = "fsl,pq-sata-v2";
+ reg = <0x220000 0x1000>;
+ interrupts = <68 0x2 0 0>;
+ sata-number = <0x0>;
+ sata-fpdma = <0x0>;
+ };
+
+ sata1: sata@221000 {
+ compatible = "fsl,pq-sata-v2";
+ reg = <0x221000 0x1000>;
+ interrupts = <69 0x2 0 0>;
+ sata-number = <0x0>;
+ sata-fpdma = <0x0>;
+ };
};
};
diff --git a/board/st/stm32mp1/board.c b/board/st/stm32mp1/board.c
index 5c1acca20d..c3d832f584 100644
--- a/board/st/stm32mp1/board.c
+++ b/board/st/stm32mp1/board.c
@@ -38,9 +38,10 @@ void board_debug_uart_init(void)
#endif
#ifdef CONFIG_PMIC_STPMIC1
-int board_ddr_power_init(void)
+int board_ddr_power_init(enum ddr_type ddr_type)
{
struct udevice *dev;
+ bool buck3_at_1800000v = false;
int ret;
ret = uclass_get_device_by_driver(UCLASS_PMIC,
@@ -49,53 +50,127 @@ int board_ddr_power_init(void)
/* No PMIC on board */
return 0;
- /* VTT = Set LDO3 to sync mode */
- ret = pmic_reg_read(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3));
- if (ret < 0)
- return ret;
-
- ret &= ~STPMIC1_LDO3_MODE;
- ret &= ~STPMIC1_LDO12356_VOUT_MASK;
- ret |= STPMIC1_LDO_VOUT(STPMIC1_LDO3_DDR_SEL);
-
- ret = pmic_reg_write(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3),
- ret);
- if (ret < 0)
- return ret;
-
- /* VDD_DDR = Set BUCK2 to 1.35V */
- ret = pmic_clrsetbits(dev,
- STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2),
- STPMIC1_BUCK_VOUT_MASK,
- STPMIC1_BUCK2_1350000V);
- if (ret < 0)
- return ret;
-
- /* Enable VDD_DDR = BUCK2 */
- ret = pmic_clrsetbits(dev,
- STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2),
- STPMIC1_BUCK_ENA, STPMIC1_BUCK_ENA);
- if (ret < 0)
- return ret;
-
- mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
-
- /* Enable VREF */
- ret = pmic_clrsetbits(dev, STPMIC1_REFDDR_MAIN_CR,
- STPMIC1_VREF_ENA, STPMIC1_VREF_ENA);
- if (ret < 0)
- return ret;
-
- mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
-
- /* Enable LDO3 */
- ret = pmic_clrsetbits(dev,
- STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3),
- STPMIC1_LDO_ENA, STPMIC1_LDO_ENA);
- if (ret < 0)
- return ret;
-
- mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
+ switch (ddr_type) {
+ case STM32MP_DDR3:
+ /* VTT = Set LDO3 to sync mode */
+ ret = pmic_reg_read(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3));
+ if (ret < 0)
+ return ret;
+
+ ret &= ~STPMIC1_LDO3_MODE;
+ ret &= ~STPMIC1_LDO12356_VOUT_MASK;
+ ret |= STPMIC1_LDO_VOUT(STPMIC1_LDO3_DDR_SEL);
+
+ ret = pmic_reg_write(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3),
+ ret);
+ if (ret < 0)
+ return ret;
+
+ /* VDD_DDR = Set BUCK2 to 1.35V */
+ ret = pmic_clrsetbits(dev,
+ STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2),
+ STPMIC1_BUCK_VOUT_MASK,
+ STPMIC1_BUCK2_1350000V);
+ if (ret < 0)
+ return ret;
+
+ /* Enable VDD_DDR = BUCK2 */
+ ret = pmic_clrsetbits(dev,
+ STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2),
+ STPMIC1_BUCK_ENA, STPMIC1_BUCK_ENA);
+ if (ret < 0)
+ return ret;
+
+ mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
+
+ /* Enable VREF */
+ ret = pmic_clrsetbits(dev, STPMIC1_REFDDR_MAIN_CR,
+ STPMIC1_VREF_ENA, STPMIC1_VREF_ENA);
+ if (ret < 0)
+ return ret;
+
+ mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
+
+ /* Enable VTT = LDO3 */
+ ret = pmic_clrsetbits(dev,
+ STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3),
+ STPMIC1_LDO_ENA, STPMIC1_LDO_ENA);
+ if (ret < 0)
+ return ret;
+
+ mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
+
+ break;
+
+ case STM32MP_LPDDR2:
+ case STM32MP_LPDDR3:
+ /*
+ * configure VDD_DDR1 = LDO3
+ * Set LDO3 to 1.8V
+ * + bypass mode if BUCK3 = 1.8V
+ * + normal mode if BUCK3 != 1.8V
+ */
+ ret = pmic_reg_read(dev,
+ STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK3));
+ if (ret < 0)
+ return ret;
+
+ if ((ret & STPMIC1_BUCK3_1800000V) == STPMIC1_BUCK3_1800000V)
+ buck3_at_1800000v = true;
+
+ ret = pmic_reg_read(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3));
+ if (ret < 0)
+ return ret;
+
+ ret &= ~STPMIC1_LDO3_MODE;
+ ret &= ~STPMIC1_LDO12356_VOUT_MASK;
+ ret |= STPMIC1_LDO3_1800000;
+ if (buck3_at_1800000v)
+ ret |= STPMIC1_LDO3_MODE;
+
+ ret = pmic_reg_write(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3),
+ ret);
+ if (ret < 0)
+ return ret;
+
+ /* VDD_DDR2 : Set BUCK2 to 1.2V */
+ ret = pmic_clrsetbits(dev,
+ STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2),
+ STPMIC1_BUCK_VOUT_MASK,
+ STPMIC1_BUCK2_1200000V);
+ if (ret < 0)
+ return ret;
+
+ /* Enable VDD_DDR1 = LDO3 */
+ ret = pmic_clrsetbits(dev, STPMIC1_LDOX_MAIN_CR(STPMIC1_LDO3),
+ STPMIC1_LDO_ENA, STPMIC1_LDO_ENA);
+ if (ret < 0)
+ return ret;
+
+ mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
+
+ /* Enable VDD_DDR2 =BUCK2 */
+ ret = pmic_clrsetbits(dev,
+ STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2),
+ STPMIC1_BUCK_ENA, STPMIC1_BUCK_ENA);
+ if (ret < 0)
+ return ret;
+
+ mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
+
+ /* Enable VREF */
+ ret = pmic_clrsetbits(dev, STPMIC1_REFDDR_MAIN_CR,
+ STPMIC1_VREF_ENA, STPMIC1_VREF_ENA);
+ if (ret < 0)
+ return ret;
+
+ mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
+
+ break;
+
+ default:
+ break;
+ };
return 0;
}
diff --git a/common/Kconfig b/common/Kconfig
index 1a1951f874..c759952b80 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -247,6 +247,7 @@ config USE_PREBOOT
config PREBOOT
string "preboot default value"
depends on USE_PREBOOT
+ default ""
help
This is the default of "preboot" environment variable.
diff --git a/common/Makefile b/common/Makefile
index 8c92feb399..c7e41ef307 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -124,6 +124,7 @@ endif
obj-y += cli.o
obj-$(CONFIG_FSL_DDR_INTERACTIVE) += cli_simple.o cli_readline.o
+obj-$(CONFIG_STM32MP1_DDR_INTERACTIVE) += cli_simple.o cli_readline.o
obj-$(CONFIG_DFU_OVER_USB) += dfu.o
obj-y += command.o
obj-$(CONFIG_$(SPL_TPL_)LOG) += log.o
diff --git a/configs/M5208EVBE_defconfig b/configs/M5208EVBE_defconfig
index 934cda4aa6..01b2c97b66 100644
--- a/configs/M5208EVBE_defconfig
+++ b/configs/M5208EVBE_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0x0
CONFIG_TARGET_M5208EVBE=y
+CONFIG_DEFAULT_DEVICE_TREE="M5208EVBE"
CONFIG_BOOTDELAY=1
# CONFIG_DISPLAY_BOARDINFO is not set
# CONFIG_CMDLINE_EDITING is not set
diff --git a/configs/M52277EVB_defconfig b/configs/M52277EVB_defconfig
index efa5e7102b..bc7b051239 100644
--- a/configs/M52277EVB_defconfig
+++ b/configs/M52277EVB_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0x0
CONFIG_TARGET_M52277EVB=y
+CONFIG_DEFAULT_DEVICE_TREE="M52277EVB"
CONFIG_SYS_EXTRA_OPTIONS="SYS_SPANSION_BOOT"
CONFIG_BOOTDELAY=3
# CONFIG_DISPLAY_BOARDINFO is not set
@@ -25,4 +26,5 @@ CONFIG_SYS_FLASH_CFI=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_SPI=y
+CONFIG_DM_SPI=y
CONFIG_CF_SPI=y
diff --git a/configs/M52277EVB_stmicro_defconfig b/configs/M52277EVB_stmicro_defconfig
index cafc861167..d417be6ec3 100644
--- a/configs/M52277EVB_stmicro_defconfig
+++ b/configs/M52277EVB_stmicro_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0x43E00000
CONFIG_TARGET_M52277EVB=y
+CONFIG_DEFAULT_DEVICE_TREE="M52277EVB_stmicro"
CONFIG_SYS_EXTRA_OPTIONS="CF_SBF,SYS_STMICRO_BOOT"
CONFIG_BOOTDELAY=3
# CONFIG_DISPLAY_BOARDINFO is not set
@@ -26,4 +27,5 @@ CONFIG_SYS_FLASH_CFI=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_SPI=y
+CONFIG_DM_SPI=y
CONFIG_CF_SPI=y
diff --git a/configs/M5235EVB_Flash32_defconfig b/configs/M5235EVB_Flash32_defconfig
index fff57436c7..aef8281319 100644
--- a/configs/M5235EVB_Flash32_defconfig
+++ b/configs/M5235EVB_Flash32_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0xFFC00000
CONFIG_TARGET_M5235EVB=y
+CONFIG_DEFAULT_DEVICE_TREE="M5235EVB_Flash32"
CONFIG_SYS_EXTRA_OPTIONS="NORFLASH_PS32BIT"
CONFIG_BOOTDELAY=1
# CONFIG_DISPLAY_BOARDINFO is not set
diff --git a/configs/M5235EVB_defconfig b/configs/M5235EVB_defconfig
index 07e0f4f50b..efc03179c9 100644
--- a/configs/M5235EVB_defconfig
+++ b/configs/M5235EVB_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0xFFE00000
CONFIG_TARGET_M5235EVB=y
+CONFIG_DEFAULT_DEVICE_TREE="M5235EVB"
CONFIG_BOOTDELAY=1
# CONFIG_DISPLAY_BOARDINFO is not set
# CONFIG_CMDLINE_EDITING is not set
diff --git a/configs/M5249EVB_defconfig b/configs/M5249EVB_defconfig
index 908f6a1ab1..3f76665efd 100644
--- a/configs/M5249EVB_defconfig
+++ b/configs/M5249EVB_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0xFFE00000
CONFIG_TARGET_M5249EVB=y
+CONFIG_DEFAULT_DEVICE_TREE="M5249EVB"
CONFIG_SYS_CONSOLE_INFO_QUIET=y
# CONFIG_DISPLAY_BOARDINFO is not set
# CONFIG_CMDLINE_EDITING is not set
diff --git a/configs/M5253DEMO_defconfig b/configs/M5253DEMO_defconfig
index 4685c4eb83..2dbbd22f54 100644
--- a/configs/M5253DEMO_defconfig
+++ b/configs/M5253DEMO_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0xFF800000
CONFIG_TARGET_M5253DEMO=y
+CONFIG_DEFAULT_DEVICE_TREE="M5253DEMO"
CONFIG_BOOTDELAY=5
# CONFIG_DISPLAY_BOARDINFO is not set
# CONFIG_CMDLINE_EDITING is not set
diff --git a/configs/M5272C3_defconfig b/configs/M5272C3_defconfig
index 85283d40e4..dc4d045e36 100644
--- a/configs/M5272C3_defconfig
+++ b/configs/M5272C3_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0xFFE00000
CONFIG_TARGET_M5272C3=y
+CONFIG_DEFAULT_DEVICE_TREE="M5272C3"
CONFIG_BOOTDELAY=5
# CONFIG_DISPLAY_BOARDINFO is not set
# CONFIG_CMDLINE_EDITING is not set
diff --git a/configs/M5275EVB_defconfig b/configs/M5275EVB_defconfig
index 5ff262425c..2e1f60cf88 100644
--- a/configs/M5275EVB_defconfig
+++ b/configs/M5275EVB_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0xFFE00000
CONFIG_TARGET_M5275EVB=y
+CONFIG_DEFAULT_DEVICE_TREE="M5275EVB"
CONFIG_BOOTDELAY=5
# CONFIG_DISPLAY_BOARDINFO is not set
# CONFIG_CMDLINE_EDITING is not set
diff --git a/configs/M5282EVB_defconfig b/configs/M5282EVB_defconfig
index 289922ba33..f904d90012 100644
--- a/configs/M5282EVB_defconfig
+++ b/configs/M5282EVB_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0xFFE00000
CONFIG_TARGET_M5282EVB=y
+CONFIG_DEFAULT_DEVICE_TREE="M5282EVB"
CONFIG_BOOTDELAY=5
# CONFIG_DISPLAY_BOARDINFO is not set
# CONFIG_CMDLINE_EDITING is not set
diff --git a/configs/M53017EVB_defconfig b/configs/M53017EVB_defconfig
index 0b1073af61..9eef96df48 100644
--- a/configs/M53017EVB_defconfig
+++ b/configs/M53017EVB_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0x0
CONFIG_TARGET_M53017EVB=y
+CONFIG_DEFAULT_DEVICE_TREE="M53017EVB"
CONFIG_BOOTDELAY=1
CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="root=/dev/mtdblock3 rw rootfstype=jffs2"
diff --git a/configs/M5329AFEE_defconfig b/configs/M5329AFEE_defconfig
index c6dff0e27b..6899ac1c52 100644
--- a/configs/M5329AFEE_defconfig
+++ b/configs/M5329AFEE_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0x0
CONFIG_TARGET_M5329EVB=y
+CONFIG_DEFAULT_DEVICE_TREE="M5329AFEE"
CONFIG_SYS_EXTRA_OPTIONS="NANDFLASH_SIZE=0"
CONFIG_BOOTDELAY=1
# CONFIG_DISPLAY_BOARDINFO is not set
diff --git a/configs/M5329BFEE_defconfig b/configs/M5329BFEE_defconfig
index 56dba26f6f..16777c10eb 100644
--- a/configs/M5329BFEE_defconfig
+++ b/configs/M5329BFEE_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0x0
CONFIG_TARGET_M5329EVB=y
+CONFIG_DEFAULT_DEVICE_TREE="M5329BFEE"
CONFIG_SYS_EXTRA_OPTIONS="NANDFLASH_SIZE=16"
CONFIG_BOOTDELAY=1
# CONFIG_DISPLAY_BOARDINFO is not set
diff --git a/configs/M5373EVB_defconfig b/configs/M5373EVB_defconfig
index 39823200ee..95cf43a6f3 100644
--- a/configs/M5373EVB_defconfig
+++ b/configs/M5373EVB_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0x0
CONFIG_TARGET_M5373EVB=y
+CONFIG_DEFAULT_DEVICE_TREE="M5373EVB"
CONFIG_SYS_EXTRA_OPTIONS="NANDFLASH_SIZE=16"
CONFIG_BOOTDELAY=1
# CONFIG_DISPLAY_BOARDINFO is not set
diff --git a/configs/M54418TWR_defconfig b/configs/M54418TWR_defconfig
index a239f4a02f..da5feb5b29 100644
--- a/configs/M54418TWR_defconfig
+++ b/configs/M54418TWR_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0x47E00000
CONFIG_TARGET_M54418TWR=y
+CONFIG_DEFAULT_DEVICE_TREE="M54418TWR"
CONFIG_SYS_EXTRA_OPTIONS="CF_SBF,SYS_SERIAL_BOOT,SYS_INPUT_CLKSRC=50000000"
CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="root=/dev/nfs rw nfsroot=192.168.1.1:/tftpboot/192.168.1.2 ip=192.168.1.2:192.168.1.1:192.168.1.1: 255.255.255.0::eth0:off:rw console=ttyS0,115200"
@@ -27,3 +28,4 @@ CONFIG_SPI_FLASH_ATMEL=y
CONFIG_MII=y
CONFIG_SPI=y
CONFIG_CF_SPI=y
+CONFIG_DM_SPI=y
diff --git a/configs/M54418TWR_nand_mii_defconfig b/configs/M54418TWR_nand_mii_defconfig
index 04ca3a8114..1c2d337367 100644
--- a/configs/M54418TWR_nand_mii_defconfig
+++ b/configs/M54418TWR_nand_mii_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0x47E00000
CONFIG_TARGET_M54418TWR=y
+CONFIG_DEFAULT_DEVICE_TREE="M54418TWR_nand_mii"
CONFIG_SYS_EXTRA_OPTIONS="SYS_NAND_BOOT,SYS_INPUT_CLKSRC=25000000"
CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="root=/dev/mtdblock2 rw rootfstype=jffs2 mtdparts=NAND:1M(u-boot)ro,7M(kernel)ro,-(jffs2) console=ttyS0,115200"
@@ -23,4 +24,5 @@ CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_ATMEL=y
CONFIG_MII=y
CONFIG_SPI=y
+CONFIG_DM_SPI=y
CONFIG_CF_SPI=y
diff --git a/configs/M54418TWR_nand_rmii_defconfig b/configs/M54418TWR_nand_rmii_defconfig
index f6acf6019d..29d891b073 100644
--- a/configs/M54418TWR_nand_rmii_defconfig
+++ b/configs/M54418TWR_nand_rmii_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0x47E00000
CONFIG_TARGET_M54418TWR=y
+CONFIG_DEFAULT_DEVICE_TREE="M54418TWR_nand_rmii"
CONFIG_SYS_EXTRA_OPTIONS="SYS_NAND_BOOT,SYS_INPUT_CLKSRC=50000000"
CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="root=/dev/mtdblock2 rw rootfstype=jffs2 mtdparts=NAND:1M(u-boot)ro,7M(kernel)ro,-(jffs2) console=ttyS0,115200"
@@ -23,4 +24,5 @@ CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_ATMEL=y
CONFIG_MII=y
CONFIG_SPI=y
+CONFIG_DM_SPI=y
CONFIG_CF_SPI=y
diff --git a/configs/M54418TWR_nand_rmii_lowfreq_defconfig b/configs/M54418TWR_nand_rmii_lowfreq_defconfig
index 6b631d6d4b..4881076757 100644
--- a/configs/M54418TWR_nand_rmii_lowfreq_defconfig
+++ b/configs/M54418TWR_nand_rmii_lowfreq_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0x47E00000
CONFIG_TARGET_M54418TWR=y
+CONFIG_DEFAULT_DEVICE_TREE="M54418TWR_nand_rmii_lowfreq"
CONFIG_SYS_EXTRA_OPTIONS="SYS_NAND_BOOT,LOW_MCFCLK,SYS_INPUT_CLKSRC=50000000"
CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="root=/dev/mtdblock2 rw rootfstype=jffs2 mtdparts=NAND:1M(u-boot)ro,7M(kernel)ro,-(jffs2) console=ttyS0,115200"
@@ -23,4 +24,5 @@ CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_ATMEL=y
CONFIG_MII=y
CONFIG_SPI=y
+CONFIG_DM_SPI=y
CONFIG_CF_SPI=y
diff --git a/configs/M54418TWR_serial_mii_defconfig b/configs/M54418TWR_serial_mii_defconfig
index 8b72bd35d3..476e9ee1d2 100644
--- a/configs/M54418TWR_serial_mii_defconfig
+++ b/configs/M54418TWR_serial_mii_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0x47E00000
CONFIG_TARGET_M54418TWR=y
+CONFIG_DEFAULT_DEVICE_TREE="M54418TWR_serial_mii"
CONFIG_SYS_EXTRA_OPTIONS="CF_SBF,SYS_SERIAL_BOOT,SYS_INPUT_CLKSRC=25000000"
CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="root=/dev/nfs rw nfsroot=192.168.1.1:/tftpboot/192.168.1.2 ip=192.168.1.2:192.168.1.1:192.168.1.1: 255.255.255.0::eth0:off:rw console=ttyS0,115200"
@@ -26,4 +27,5 @@ CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_ATMEL=y
CONFIG_MII=y
CONFIG_SPI=y
+CONFIG_DM_SPI=y
CONFIG_CF_SPI=y
diff --git a/configs/M54418TWR_serial_rmii_defconfig b/configs/M54418TWR_serial_rmii_defconfig
index a239f4a02f..5209157bd5 100644
--- a/configs/M54418TWR_serial_rmii_defconfig
+++ b/configs/M54418TWR_serial_rmii_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0x47E00000
CONFIG_TARGET_M54418TWR=y
+CONFIG_DEFAULT_DEVICE_TREE="M54418TWR_serial_rmii"
CONFIG_SYS_EXTRA_OPTIONS="CF_SBF,SYS_SERIAL_BOOT,SYS_INPUT_CLKSRC=50000000"
CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="root=/dev/nfs rw nfsroot=192.168.1.1:/tftpboot/192.168.1.2 ip=192.168.1.2:192.168.1.1:192.168.1.1: 255.255.255.0::eth0:off:rw console=ttyS0,115200"
@@ -26,4 +27,5 @@ CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_ATMEL=y
CONFIG_MII=y
CONFIG_SPI=y
+CONFIG_DM_SPI=y
CONFIG_CF_SPI=y
diff --git a/configs/M54451EVB_defconfig b/configs/M54451EVB_defconfig
index 8448b6cfbf..c85b476089 100644
--- a/configs/M54451EVB_defconfig
+++ b/configs/M54451EVB_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0x0
CONFIG_TARGET_M54451EVB=y
+CONFIG_DEFAULT_DEVICE_TREE="M54451EVB"
CONFIG_SYS_EXTRA_OPTIONS="SYS_INPUT_CLKSRC=24000000"
CONFIG_BOOTDELAY=1
CONFIG_USE_BOOTARGS=y
@@ -30,4 +31,5 @@ CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_MII=y
CONFIG_SPI=y
+CONFIG_DM_SPI=y
CONFIG_CF_SPI=y
diff --git a/configs/M54451EVB_stmicro_defconfig b/configs/M54451EVB_stmicro_defconfig
index b614ca716d..a26e2d019f 100644
--- a/configs/M54451EVB_stmicro_defconfig
+++ b/configs/M54451EVB_stmicro_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0x47E00000
CONFIG_TARGET_M54451EVB=y
+CONFIG_DEFAULT_DEVICE_TREE="M54451EVB_stmicro"
CONFIG_SYS_EXTRA_OPTIONS="CF_SBF,SYS_STMICRO_BOOT,SYS_INPUT_CLKSRC=24000000"
CONFIG_BOOTDELAY=1
CONFIG_USE_BOOTARGS=y
@@ -31,4 +32,5 @@ CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_MII=y
CONFIG_SPI=y
+CONFIG_DM_SPI=y
CONFIG_CF_SPI=y
diff --git a/configs/M54455EVB_a66_defconfig b/configs/M54455EVB_a66_defconfig
index f9be1c3773..9cfd1f896c 100644
--- a/configs/M54455EVB_a66_defconfig
+++ b/configs/M54455EVB_a66_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0x4000000
CONFIG_TARGET_M54455EVB=y
+CONFIG_DEFAULT_DEVICE_TREE="M54455EVB_a66"
CONFIG_SYS_EXTRA_OPTIONS="SYS_ATMEL_BOOT,SYS_INPUT_CLKSRC=66666666"
CONFIG_BOOTDELAY=1
CONFIG_USE_BOOTARGS=y
@@ -34,4 +35,5 @@ CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_MII=y
CONFIG_SPI=y
+CONFIG_DM_SPI=y
CONFIG_CF_SPI=y
diff --git a/configs/M54455EVB_defconfig b/configs/M54455EVB_defconfig
index abb69a966a..8d0f9bf54f 100644
--- a/configs/M54455EVB_defconfig
+++ b/configs/M54455EVB_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0x4000000
CONFIG_TARGET_M54455EVB=y
+CONFIG_DEFAULT_DEVICE_TREE="M54455EVB"
CONFIG_SYS_EXTRA_OPTIONS="SYS_ATMEL_BOOT,SYS_INPUT_CLKSRC=33333333"
CONFIG_BOOTDELAY=1
CONFIG_USE_BOOTARGS=y
@@ -35,4 +36,5 @@ CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_MII=y
CONFIG_SPI=y
+CONFIG_DM_SPI=y
CONFIG_CF_SPI=y
diff --git a/configs/M54455EVB_i66_defconfig b/configs/M54455EVB_i66_defconfig
index 6050df5d51..d47a20a73a 100644
--- a/configs/M54455EVB_i66_defconfig
+++ b/configs/M54455EVB_i66_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0x0
CONFIG_TARGET_M54455EVB=y
+CONFIG_DEFAULT_DEVICE_TREE="M54455EVB_i66"
CONFIG_SYS_EXTRA_OPTIONS="SYS_INTEL_BOOT,SYS_INPUT_CLKSRC=66666666"
CONFIG_BOOTDELAY=1
CONFIG_USE_BOOTARGS=y
@@ -34,4 +35,5 @@ CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_MII=y
CONFIG_SPI=y
+CONFIG_DM_SPI=y
CONFIG_CF_SPI=y
diff --git a/configs/M54455EVB_intel_defconfig b/configs/M54455EVB_intel_defconfig
index 686c00e318..b90dad72c1 100644
--- a/configs/M54455EVB_intel_defconfig
+++ b/configs/M54455EVB_intel_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0x0
CONFIG_TARGET_M54455EVB=y
+CONFIG_DEFAULT_DEVICE_TREE="M54455EVB_intel"
CONFIG_SYS_EXTRA_OPTIONS="SYS_INTEL_BOOT,SYS_INPUT_CLKSRC=33333333"
CONFIG_BOOTDELAY=1
CONFIG_USE_BOOTARGS=y
@@ -34,4 +35,5 @@ CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_MII=y
CONFIG_SPI=y
+CONFIG_DM_SPI=y
CONFIG_CF_SPI=y
diff --git a/configs/M54455EVB_stm33_defconfig b/configs/M54455EVB_stm33_defconfig
index 467bfaee9a..a39fda6df8 100644
--- a/configs/M54455EVB_stm33_defconfig
+++ b/configs/M54455EVB_stm33_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0x4FE00000
CONFIG_TARGET_M54455EVB=y
+CONFIG_DEFAULT_DEVICE_TREE="M54455EVB_stm33"
CONFIG_SYS_EXTRA_OPTIONS="SYS_STMICRO_BOOT,CF_SBF,SYS_INPUT_CLKSRC=33333333"
CONFIG_BOOTDELAY=1
CONFIG_USE_BOOTARGS=y
@@ -36,4 +37,5 @@ CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_MII=y
CONFIG_SPI=y
+CONFIG_DM_SPI=y
CONFIG_CF_SPI=y
diff --git a/configs/M5475AFE_defconfig b/configs/M5475AFE_defconfig
index b0296acff0..71e78fdaf0 100644
--- a/configs/M5475AFE_defconfig
+++ b/configs/M5475AFE_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0xFF800000
CONFIG_TARGET_M5475EVB=y
+CONFIG_DEFAULT_DEVICE_TREE="M5475AFE"
CONFIG_SYS_EXTRA_OPTIONS="SYS_BUSCLK=133333333,SYS_BOOTSZ=2,SYS_DRAMSZ=64"
CONFIG_BOOTDELAY=1
# CONFIG_CMDLINE_EDITING is not set
diff --git a/configs/M5475BFE_defconfig b/configs/M5475BFE_defconfig
index 7fc61bd249..9db3d28e44 100644
--- a/configs/M5475BFE_defconfig
+++ b/configs/M5475BFE_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0xFF800000
CONFIG_TARGET_M5475EVB=y
+CONFIG_DEFAULT_DEVICE_TREE="M5475BFE"
CONFIG_SYS_EXTRA_OPTIONS="SYS_BUSCLK=133333333,SYS_BOOTSZ=2,SYS_DRAMSZ=64,SYS_NOR1SZ=16"
CONFIG_BOOTDELAY=1
# CONFIG_CMDLINE_EDITING is not set
diff --git a/configs/M5475CFE_defconfig b/configs/M5475CFE_defconfig
index 22d1074521..4069d59a52 100644
--- a/configs/M5475CFE_defconfig
+++ b/configs/M5475CFE_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0xFF800000
CONFIG_TARGET_M5475EVB=y
+CONFIG_DEFAULT_DEVICE_TREE="M5475CFE"
CONFIG_SYS_EXTRA_OPTIONS="SYS_BUSCLK=133333333,SYS_BOOTSZ=2,SYS_DRAMSZ=64,SYS_NOR1SZ=16,SYS_VIDEO,SYS_USBCTRL"
CONFIG_BOOTDELAY=1
# CONFIG_CMDLINE_EDITING is not set
diff --git a/configs/M5475DFE_defconfig b/configs/M5475DFE_defconfig
index ee8c2abfba..fb5ecbb2ca 100644
--- a/configs/M5475DFE_defconfig
+++ b/configs/M5475DFE_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0xFF800000
CONFIG_TARGET_M5475EVB=y
+CONFIG_DEFAULT_DEVICE_TREE="M5475DFE"
CONFIG_SYS_EXTRA_OPTIONS="SYS_BUSCLK=133333333,SYS_BOOTSZ=2,SYS_DRAMSZ=64,SYS_USBCTRL"
CONFIG_BOOTDELAY=1
# CONFIG_CMDLINE_EDITING is not set
diff --git a/configs/M5475EFE_defconfig b/configs/M5475EFE_defconfig
index 939e56b28e..45d6f233c2 100644
--- a/configs/M5475EFE_defconfig
+++ b/configs/M5475EFE_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0xFF800000
CONFIG_TARGET_M5475EVB=y
+CONFIG_DEFAULT_DEVICE_TREE="M5475EFE"
CONFIG_SYS_EXTRA_OPTIONS="SYS_BUSCLK=133333333,SYS_BOOTSZ=2,SYS_DRAMSZ=64,SYS_VIDEO,SYS_USBCTRL"
CONFIG_BOOTDELAY=1
# CONFIG_CMDLINE_EDITING is not set
diff --git a/configs/M5475FFE_defconfig b/configs/M5475FFE_defconfig
index 1fef8fffd6..43d5c964dc 100644
--- a/configs/M5475FFE_defconfig
+++ b/configs/M5475FFE_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0xFF800000
CONFIG_TARGET_M5475EVB=y
+CONFIG_DEFAULT_DEVICE_TREE="M5475FFE"
CONFIG_SYS_EXTRA_OPTIONS="SYS_BUSCLK=133333333,SYS_BOOTSZ=2,SYS_DRAMSZ=64,SYS_NOR1SZ=32,SYS_VIDEO,SYS_USBCTRL,SYS_DRAMSZ1=64"
CONFIG_BOOTDELAY=1
# CONFIG_CMDLINE_EDITING is not set
diff --git a/configs/M5475GFE_defconfig b/configs/M5475GFE_defconfig
index d78cafffed..11ea9cd454 100644
--- a/configs/M5475GFE_defconfig
+++ b/configs/M5475GFE_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0xFF800000
CONFIG_TARGET_M5475EVB=y
+CONFIG_DEFAULT_DEVICE_TREE="M5475GFE"
CONFIG_SYS_EXTRA_OPTIONS="SYS_BUSCLK=133333333,SYS_BOOTSZ=4,SYS_DRAMSZ=64"
CONFIG_BOOTDELAY=1
# CONFIG_CMDLINE_EDITING is not set
diff --git a/configs/M5485AFE_defconfig b/configs/M5485AFE_defconfig
index 5cda25a99a..8f9aaa9856 100644
--- a/configs/M5485AFE_defconfig
+++ b/configs/M5485AFE_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0xFF800000
CONFIG_TARGET_M5485EVB=y
+CONFIG_DEFAULT_DEVICE_TREE="M5485AFE"
CONFIG_SYS_EXTRA_OPTIONS="SYS_BUSCLK=100000000,SYS_BOOTSZ=2,SYS_DRAMSZ=64"
CONFIG_BOOTDELAY=1
# CONFIG_CMDLINE_EDITING is not set
diff --git a/configs/M5485BFE_defconfig b/configs/M5485BFE_defconfig
index 7cd4a5355b..ce26bed66b 100644
--- a/configs/M5485BFE_defconfig
+++ b/configs/M5485BFE_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0xFF800000
CONFIG_TARGET_M5485EVB=y
+CONFIG_DEFAULT_DEVICE_TREE="M5485BFE"
CONFIG_SYS_EXTRA_OPTIONS="SYS_BUSCLK=100000000,SYS_BOOTSZ=2,SYS_DRAMSZ=64,SYS_NOR1SZ=16"
CONFIG_BOOTDELAY=1
# CONFIG_CMDLINE_EDITING is not set
diff --git a/configs/M5485CFE_defconfig b/configs/M5485CFE_defconfig
index ff5e8ef043..47b27323bc 100644
--- a/configs/M5485CFE_defconfig
+++ b/configs/M5485CFE_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0xFF800000
CONFIG_TARGET_M5485EVB=y
+CONFIG_DEFAULT_DEVICE_TREE="M5485CFE"
CONFIG_SYS_EXTRA_OPTIONS="SYS_BUSCLK=100000000,SYS_BOOTSZ=2,SYS_DRAMSZ=64,SYS_NOR1SZ=16,SYS_VIDEO,SYS_USBCTRL"
CONFIG_BOOTDELAY=1
# CONFIG_CMDLINE_EDITING is not set
diff --git a/configs/M5485DFE_defconfig b/configs/M5485DFE_defconfig
index c4dd6c3ae9..eb0d19b7c2 100644
--- a/configs/M5485DFE_defconfig
+++ b/configs/M5485DFE_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0xFF800000
CONFIG_TARGET_M5485EVB=y
+CONFIG_DEFAULT_DEVICE_TREE="M5485DFE"
CONFIG_SYS_EXTRA_OPTIONS="SYS_BUSCLK=100000000,SYS_BOOTSZ=2,SYS_DRAMSZ=64,SYS_USBCTRL"
CONFIG_BOOTDELAY=1
# CONFIG_CMDLINE_EDITING is not set
diff --git a/configs/M5485EFE_defconfig b/configs/M5485EFE_defconfig
index 4e84828f48..9504b26090 100644
--- a/configs/M5485EFE_defconfig
+++ b/configs/M5485EFE_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0xFF800000
CONFIG_TARGET_M5485EVB=y
+CONFIG_DEFAULT_DEVICE_TREE="M5485EFE"
CONFIG_SYS_EXTRA_OPTIONS="SYS_BUSCLK=100000000,SYS_BOOTSZ=2,SYS_DRAMSZ=64,SYS_VIDEO,SYS_USBCTRL"
CONFIG_BOOTDELAY=1
# CONFIG_CMDLINE_EDITING is not set
diff --git a/configs/M5485FFE_defconfig b/configs/M5485FFE_defconfig
index f6264e8c5e..f2bc3a0cb0 100644
--- a/configs/M5485FFE_defconfig
+++ b/configs/M5485FFE_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0xFF800000
CONFIG_TARGET_M5485EVB=y
+CONFIG_DEFAULT_DEVICE_TREE="M5485FFE"
CONFIG_SYS_EXTRA_OPTIONS="SYS_BUSCLK=100000000,SYS_BOOTSZ=2,SYS_DRAMSZ=64,SYS_NOR1SZ=32,SYS_VIDEO,SYS_USBCTRL,SYS_DRAMSZ1=64"
CONFIG_BOOTDELAY=1
# CONFIG_CMDLINE_EDITING is not set
diff --git a/configs/M5485GFE_defconfig b/configs/M5485GFE_defconfig
index 9a589e0ae2..43ddd41b54 100644
--- a/configs/M5485GFE_defconfig
+++ b/configs/M5485GFE_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0xFF800000
CONFIG_TARGET_M5485EVB=y
+CONFIG_DEFAULT_DEVICE_TREE="M5485GFE"
CONFIG_SYS_EXTRA_OPTIONS="SYS_BUSCLK=100000000,SYS_BOOTSZ=4,SYS_DRAMSZ=64"
CONFIG_BOOTDELAY=1
# CONFIG_CMDLINE_EDITING is not set
diff --git a/configs/M5485HFE_defconfig b/configs/M5485HFE_defconfig
index edc50c8f53..820d5aadd5 100644
--- a/configs/M5485HFE_defconfig
+++ b/configs/M5485HFE_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0xFF800000
CONFIG_TARGET_M5485EVB=y
+CONFIG_DEFAULT_DEVICE_TREE="M5485HFE"
CONFIG_SYS_EXTRA_OPTIONS="SYS_BUSCLK=100000000,SYS_BOOTSZ=2,SYS_DRAMSZ=64,SYS_NOR1SZ=16,SYS_VIDEO"
CONFIG_BOOTDELAY=1
# CONFIG_CMDLINE_EDITING is not set
diff --git a/configs/T2080QDS_NAND_defconfig b/configs/T2080QDS_NAND_defconfig
index 4c39f66096..4a8ec11138 100644
--- a/configs/T2080QDS_NAND_defconfig
+++ b/configs/T2080QDS_NAND_defconfig
@@ -7,6 +7,7 @@ CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
CONFIG_SPL=y
CONFIG_MPC85xx=y
CONFIG_TARGET_T2080QDS=y
+CONFIG_AHCI=y
CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_OF_BOARD_SETUP=y
@@ -39,7 +40,10 @@ CONFIG_MTDPARTS_DEFAULT="mtdparts=fe8000000.nor:1m(uboot),5m(kernel),128k(dtb),9
CONFIG_OF_CONTROL=y
CONFIG_DEFAULT_DEVICE_TREE="t2080qds"
CONFIG_ENV_IS_IN_NAND=y
+CONFIG_DM=y
+CONFIG_FSL_AHCI=y
CONFIG_FSL_CAAM=y
+CONFIG_DM_MMC=y
CONFIG_FSL_ESDHC=y
CONFIG_MTD_NOR_FLASH=y
CONFIG_FLASH_CFI_DRIVER=y
@@ -57,8 +61,11 @@ CONFIG_PHYLIB=y
CONFIG_PHY_AQUANTIA=y
CONFIG_E1000=y
CONFIG_MII=y
+CONFIG_SCSI=y
+CONFIG_DM_SCSI=y
CONFIG_SYS_NS16550=y
CONFIG_SPI=y
CONFIG_FSL_ESPI=y
CONFIG_USB=y
+CONFIG_DM_USB=y
CONFIG_USB_STORAGE=y
diff --git a/configs/T2080QDS_SDCARD_defconfig b/configs/T2080QDS_SDCARD_defconfig
index 5fe12da409..d830b17789 100644
--- a/configs/T2080QDS_SDCARD_defconfig
+++ b/configs/T2080QDS_SDCARD_defconfig
@@ -8,6 +8,7 @@ CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
CONFIG_SPL=y
CONFIG_MPC85xx=y
CONFIG_TARGET_T2080QDS=y
+CONFIG_AHCI=y
CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_OF_BOARD_SETUP=y
@@ -39,7 +40,10 @@ CONFIG_MTDPARTS_DEFAULT="mtdparts=fe8000000.nor:1m(uboot),5m(kernel),128k(dtb),9
CONFIG_OF_CONTROL=y
CONFIG_DEFAULT_DEVICE_TREE="t2080qds"
CONFIG_ENV_IS_IN_MMC=y
+CONFIG_DM=y
+CONFIG_FSL_AHCI=y
CONFIG_FSL_CAAM=y
+CONFIG_DM_MMC=y
CONFIG_FSL_ESDHC=y
CONFIG_MTD_NOR_FLASH=y
CONFIG_FLASH_CFI_DRIVER=y
@@ -56,8 +60,11 @@ CONFIG_PHYLIB=y
CONFIG_PHY_AQUANTIA=y
CONFIG_E1000=y
CONFIG_MII=y
+CONFIG_SCSI=y
+CONFIG_DM_SCSI=y
CONFIG_SYS_NS16550=y
CONFIG_SPI=y
CONFIG_FSL_ESPI=y
CONFIG_USB=y
+CONFIG_DM_USB=y
CONFIG_USB_STORAGE=y
diff --git a/configs/T2080QDS_SECURE_BOOT_defconfig b/configs/T2080QDS_SECURE_BOOT_defconfig
index dd71811f34..f6284fede0 100644
--- a/configs/T2080QDS_SECURE_BOOT_defconfig
+++ b/configs/T2080QDS_SECURE_BOOT_defconfig
@@ -3,6 +3,8 @@ CONFIG_SYS_TEXT_BASE=0xEFF40000
CONFIG_SECURE_BOOT=y
CONFIG_MPC85xx=y
CONFIG_TARGET_T2080QDS=y
+CONFIG_MPC85XX_HAVE_RESET_VECTOR=y
+CONFIG_AHCI=y
# CONFIG_SYS_MALLOC_F is not set
CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
@@ -26,7 +28,11 @@ CONFIG_CMD_FAT=y
CONFIG_CMD_MTDPARTS=y
CONFIG_MTDIDS_DEFAULT="nor0=fe8000000.nor,nand0=fff800000.flash,spi0=spife110000.0"
CONFIG_MTDPARTS_DEFAULT="mtdparts=fe8000000.nor:1m(uboot),5m(kernel),128k(dtb),96m(fs),-(user);fff800000.flash:1m(uboot),5m(kernel),128k(dtb),96m(fs),-(user);spife110000.0:1m(uboot),5m(kernel),128k(dtb),-(user)"
+CONFIG_OF_CONTROL=y
+CONFIG_DEFAULT_DEVICE_TREE="t2080qds"
CONFIG_DM=y
+CONFIG_FSL_AHCI=y
+CONFIG_DM_MMC=y
CONFIG_FSL_ESDHC=y
CONFIG_MTD_NOR_FLASH=y
CONFIG_FLASH_CFI_DRIVER=y
@@ -43,12 +49,14 @@ CONFIG_PHYLIB=y
CONFIG_PHY_AQUANTIA=y
CONFIG_E1000=y
CONFIG_MII=y
+CONFIG_SCSI=y
+CONFIG_DM_SCSI=y
CONFIG_SYS_NS16550=y
CONFIG_SPI=y
CONFIG_FSL_ESPI=y
CONFIG_USB=y
+CONFIG_DM_USB=y
CONFIG_USB_STORAGE=y
CONFIG_RSA=y
CONFIG_SPL_RSA=y
CONFIG_RSA_SOFTWARE_EXP=y
-CONFIG_OF_LIBFDT=y
diff --git a/configs/T2080QDS_SPIFLASH_defconfig b/configs/T2080QDS_SPIFLASH_defconfig
index 899f61c8a8..812a1b1c2c 100644
--- a/configs/T2080QDS_SPIFLASH_defconfig
+++ b/configs/T2080QDS_SPIFLASH_defconfig
@@ -9,6 +9,7 @@ CONFIG_SPL_SPI_FLASH_SUPPORT=y
CONFIG_SPL_SPI_SUPPORT=y
CONFIG_MPC85xx=y
CONFIG_TARGET_T2080QDS=y
+CONFIG_AHCI=y
CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_OF_BOARD_SETUP=y
@@ -40,7 +41,10 @@ CONFIG_MTDPARTS_DEFAULT="mtdparts=fe8000000.nor:1m(uboot),5m(kernel),128k(dtb),9
CONFIG_OF_CONTROL=y
CONFIG_DEFAULT_DEVICE_TREE="t2080qds"
CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_DM=y
+CONFIG_FSL_AHCI=y
CONFIG_FSL_CAAM=y
+CONFIG_DM_MMC=y
CONFIG_FSL_ESDHC=y
CONFIG_MTD_NOR_FLASH=y
CONFIG_FLASH_CFI_DRIVER=y
@@ -57,8 +61,11 @@ CONFIG_PHYLIB=y
CONFIG_PHY_AQUANTIA=y
CONFIG_E1000=y
CONFIG_MII=y
+CONFIG_SCSI=y
+CONFIG_DM_SCSI=y
CONFIG_SYS_NS16550=y
CONFIG_SPI=y
CONFIG_FSL_ESPI=y
CONFIG_USB=y
+CONFIG_DM_USB=y
CONFIG_USB_STORAGE=y
diff --git a/configs/T2080QDS_SRIO_PCIE_BOOT_defconfig b/configs/T2080QDS_SRIO_PCIE_BOOT_defconfig
index 133dc7d15c..f18759f9fd 100644
--- a/configs/T2080QDS_SRIO_PCIE_BOOT_defconfig
+++ b/configs/T2080QDS_SRIO_PCIE_BOOT_defconfig
@@ -2,6 +2,8 @@ CONFIG_PPC=y
CONFIG_SYS_TEXT_BASE=0xFFF40000
CONFIG_MPC85xx=y
CONFIG_TARGET_T2080QDS=y
+CONFIG_MPC85XX_HAVE_RESET_VECTOR=y
+CONFIG_AHCI=y
CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_OF_BOARD_SETUP=y
@@ -22,8 +24,13 @@ CONFIG_CMD_PING=y
CONFIG_MP=y
CONFIG_CMD_EXT2=y
CONFIG_CMD_FAT=y
+CONFIG_OF_CONTROL=y
+CONFIG_DEFAULT_DEVICE_TREE="t2080qds"
CONFIG_ENV_IS_IN_REMOTE=y
+CONFIG_DM=y
+CONFIG_FSL_AHCI=y
CONFIG_FSL_CAAM=y
+CONFIG_DM_MMC=y
CONFIG_FSL_ESDHC=y
CONFIG_SPI_FLASH=y
CONFIG_SF_DEFAULT_MODE=0
@@ -35,9 +42,11 @@ CONFIG_PHYLIB=y
CONFIG_PHY_AQUANTIA=y
CONFIG_E1000=y
CONFIG_MII=y
+CONFIG_SCSI=y
+CONFIG_DM_SCSI=y
CONFIG_SYS_NS16550=y
CONFIG_SPI=y
CONFIG_FSL_ESPI=y
CONFIG_USB=y
+CONFIG_DM_USB=y
CONFIG_USB_STORAGE=y
-CONFIG_OF_LIBFDT=y
diff --git a/configs/T2080QDS_defconfig b/configs/T2080QDS_defconfig
index 7f5a26fa76..8166c13b17 100644
--- a/configs/T2080QDS_defconfig
+++ b/configs/T2080QDS_defconfig
@@ -3,6 +3,7 @@ CONFIG_SYS_TEXT_BASE=0xEFF40000
CONFIG_MPC85xx=y
CONFIG_TARGET_T2080QDS=y
CONFIG_MPC85XX_HAVE_RESET_VECTOR=y
+CONFIG_AHCI=y
CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_OF_BOARD_SETUP=y
@@ -28,7 +29,10 @@ CONFIG_MTDPARTS_DEFAULT="mtdparts=fe8000000.nor:1m(uboot),5m(kernel),128k(dtb),9
CONFIG_OF_CONTROL=y
CONFIG_DEFAULT_DEVICE_TREE="t2080qds"
CONFIG_ENV_IS_IN_FLASH=y
+CONFIG_DM=y
+CONFIG_FSL_AHCI=y
CONFIG_FSL_CAAM=y
+CONFIG_DM_MMC=y
CONFIG_FSL_ESDHC=y
CONFIG_MTD_NOR_FLASH=y
CONFIG_FLASH_CFI_DRIVER=y
@@ -45,8 +49,11 @@ CONFIG_PHYLIB=y
CONFIG_PHY_AQUANTIA=y
CONFIG_E1000=y
CONFIG_MII=y
+CONFIG_SCSI=y
+CONFIG_DM_SCSI=y
CONFIG_SYS_NS16550=y
CONFIG_SPI=y
CONFIG_FSL_ESPI=y
CONFIG_USB=y
+CONFIG_DM_USB=y
CONFIG_USB_STORAGE=y
diff --git a/configs/amcore_defconfig b/configs/amcore_defconfig
index 43e71cd6c2..de56175e17 100644
--- a/configs/amcore_defconfig
+++ b/configs/amcore_defconfig
@@ -2,6 +2,7 @@ CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0xFFC00000
CONFIG_SYS_MALLOC_F_LEN=0x800
CONFIG_TARGET_AMCORE=y
+CONFIG_DEFAULT_DEVICE_TREE="amcore"
CONFIG_BOOTDELAY=1
CONFIG_SYS_CONSOLE_INFO_QUIET=y
# CONFIG_DISPLAY_BOARDINFO is not set
diff --git a/configs/astro_mcf5373l_defconfig b/configs/astro_mcf5373l_defconfig
index 230c4cb921..6d72beca7c 100644
--- a/configs/astro_mcf5373l_defconfig
+++ b/configs/astro_mcf5373l_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0x00000000
CONFIG_TARGET_ASTRO_MCF5373L=y
+CONFIG_DEFAULT_DEVICE_TREE="astro_mcf5373l"
CONFIG_BOOTDELAY=1
CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS=" console=ttyS2,115200 rootfstype=romfs loaderversion=$loaderversion"
diff --git a/configs/cobra5272_defconfig b/configs/cobra5272_defconfig
index fc295af114..7b9c6c6608 100644
--- a/configs/cobra5272_defconfig
+++ b/configs/cobra5272_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0xFFE00000
CONFIG_TARGET_COBRA5272=y
+CONFIG_DEFAULT_DEVICE_TREE="cobra5272"
CONFIG_BOOTDELAY=5
# CONFIG_DISPLAY_BOARDINFO is not set
# CONFIG_CMDLINE_EDITING is not set
diff --git a/configs/eb_cpu5282_defconfig b/configs/eb_cpu5282_defconfig
index 3632706f33..8d3106edcc 100644
--- a/configs/eb_cpu5282_defconfig
+++ b/configs/eb_cpu5282_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0xFF000000
CONFIG_TARGET_EB_CPU5282=y
+CONFIG_DEFAULT_DEVICE_TREE="eb_cpu5282"
CONFIG_SYS_EXTRA_OPTIONS="SYS_MONITOR_BASE=0xFF000400"
CONFIG_BOOTDELAY=5
# CONFIG_CONSOLE_MUX is not set
diff --git a/configs/eb_cpu5282_internal_defconfig b/configs/eb_cpu5282_internal_defconfig
index 73c6744e7f..e3240c1f82 100644
--- a/configs/eb_cpu5282_internal_defconfig
+++ b/configs/eb_cpu5282_internal_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0xF0000000
CONFIG_TARGET_EB_CPU5282=y
+CONFIG_DEFAULT_DEVICE_TREE="eb_cpu5282_internal"
CONFIG_SYS_EXTRA_OPTIONS="SYS_MONITOR_BASE=0xF0000418"
CONFIG_BOOTDELAY=5
# CONFIG_CONSOLE_MUX is not set
diff --git a/configs/gardena-smart-gateway-mt7688-ram_defconfig b/configs/gardena-smart-gateway-mt7688-ram_defconfig
index e09950637f..cb0d33e944 100644
--- a/configs/gardena-smart-gateway-mt7688-ram_defconfig
+++ b/configs/gardena-smart-gateway-mt7688-ram_defconfig
@@ -12,6 +12,7 @@ CONFIG_IMAGE_FORMAT_LEGACY=y
CONFIG_OF_STDOUT_VIA_ALIAS=y
CONFIG_USE_BOOTCOMMAND=y
CONFIG_BOOTCOMMAND="cp.b 83000000 84000000 10000 && dhcp uEnv.txt && env import -t ${fileaddr} ${filesize} && run do_u_boot_init; reset"
+CONFIG_USE_PREBOOT=y
CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_VERSION_VARIABLE=y
CONFIG_BOARD_EARLY_INIT_F=y
@@ -26,6 +27,7 @@ CONFIG_CMD_GPIO=y
CONFIG_CMD_MTD=y
CONFIG_CMD_SF=y
CONFIG_CMD_SPI=y
+CONFIG_CMD_WDT=y
CONFIG_CMD_DHCP=y
CONFIG_CMD_MII=y
CONFIG_CMD_PING=y
diff --git a/configs/gardena-smart-gateway-mt7688_defconfig b/configs/gardena-smart-gateway-mt7688_defconfig
index ad0db2e723..ad2fbd07f7 100644
--- a/configs/gardena-smart-gateway-mt7688_defconfig
+++ b/configs/gardena-smart-gateway-mt7688_defconfig
@@ -15,6 +15,7 @@ CONFIG_IMAGE_FORMAT_LEGACY=y
CONFIG_OF_STDOUT_VIA_ALIAS=y
CONFIG_USE_BOOTCOMMAND=y
CONFIG_BOOTCOMMAND="cp.b 83000000 84000000 10000 && dhcp uEnv.txt && env import -t ${fileaddr} ${filesize} && run do_u_boot_init; reset"
+CONFIG_USE_PREBOOT=y
CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_VERSION_VARIABLE=y
CONFIG_BOARD_EARLY_INIT_F=y
@@ -29,6 +30,7 @@ CONFIG_CMD_GPIO=y
CONFIG_CMD_MTD=y
CONFIG_CMD_SF=y
CONFIG_CMD_SPI=y
+CONFIG_CMD_WDT=y
CONFIG_CMD_DHCP=y
CONFIG_CMD_MII=y
CONFIG_CMD_PING=y
diff --git a/configs/stmark2_defconfig b/configs/stmark2_defconfig
index 630b01c233..40769a86a0 100644
--- a/configs/stmark2_defconfig
+++ b/configs/stmark2_defconfig
@@ -1,6 +1,7 @@
CONFIG_M68K=y
CONFIG_SYS_TEXT_BASE=0x47E00000
CONFIG_TARGET_STMARK2=y
+CONFIG_DEFAULT_DEVICE_TREE="stmark2"
CONFIG_SYS_EXTRA_OPTIONS="CF_SBF,SYS_SERIAL_BOOT,SYS_INPUT_CLKSRC=30000000"
# CONFIG_DISPLAY_BOARDINFO is not set
CONFIG_HUSH_PARSER=y
@@ -29,5 +30,7 @@ CONFIG_SF_DEFAULT_SPEED=50000000
CONFIG_SPI_FLASH_ISSI=y
CONFIG_SPI_FLASH_MTD=y
CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_DM_SPI_FLASH=y
CONFIG_CF_SPI=y
CONFIG_REGEX=y
diff --git a/doc/device-tree-bindings/clock/st,stm32mp1.txt b/doc/device-tree-bindings/clock/st,stm32mp1.txt
index ffcf8cd31d..02e14609bb 100644
--- a/doc/device-tree-bindings/clock/st,stm32mp1.txt
+++ b/doc/device-tree-bindings/clock/st,stm32mp1.txt
@@ -1,185 +1,186 @@
STMicroelectronics STM32MP1 clock tree initialization
=====================================================
-The STM32MP clock tree initialization is based on device tree information
-for RCC IP and on fixed clocks.
+The STM32MP1 clock tree initialization is based on device tree information
+for RCC IP node (st,stm32mp1-rcc) and on fixed-clock nodes.
--------------------------------
-RCC CLOCK = st,stm32mp1-rcc-clk
--------------------------------
+RCC IP = st,stm32mp1-rcc
+========================
The RCC IP is both a reset and a clock controller but this documentation only
describes the fields added for clock tree initialization which are not present
-in Linux binding.
+in Linux binding for compatible "st,stm32mp1-rcc" defined in st,stm32mp1-rcc.txt
+file.
-Please refer to ../mfd/st,stm32-rcc.txt for all the other properties common
-with Linux.
+The added properties for clock tree initialization are:
Required properties:
+- st,clksrc : The clock sources configuration array in a platform specific
+ order.
-- compatible: Should be "st,stm32mp1-rcc-clk"
+ For the STM32MP15x family there are 9 clock sources selector which are
+ configured in the following order:
+ MPU AXI MCU PLL12 PLL3 PLL4 RTC MCO1 MCO2
-- st,clksrc : The clock source in this order
+ Clock source configuration values are defined by macros CLK_<NAME>_<SOURCE>
+ from dt-bindings/clock/stm32mp1-clksrc.h.
- for STM32MP15x: 9 clock sources are requested
- MPU AXI MCU PLL12 PLL3 PLL4 RTC MCO1 MCO2
-
- with value equals to RCC clock specifier as defined in
- dt-bindings/clock/stm32mp1-clksrc.h: CLK_<NAME>_<SOURCE>
-
-- st,clkdiv : The div parameters in this order
- for STM32MP15x: 11 dividers value are requested
+ Example:
+ st,clksrc = <
+ CLK_MPU_PLL1P
+ CLK_AXI_PLL2P
+ CLK_MCU_PLL3P
+ CLK_PLL12_HSE
+ CLK_PLL3_HSE
+ CLK_PLL4_HSE
+ CLK_RTC_LSE
+ CLK_MCO1_DISABLED
+ CLK_MCO2_DISABLED
+ >;
+
+- st,clkdiv : The clock main dividers value specified in an array
+ in a platform specific order.
+
+ When used, it shall describe the whole clock dividers tree.
+
+ For the STM32MP15x family there are 11 dividers values expected.
+ They shall be configured in the following order:
MPU AXI MCU APB1 APB2 APB3 APB4 APB5 RTC MCO1 MCO2
- with DIV coding defined in RCC associated register RCC_xxxDIVR
-
- most the case, it is:
+ The each divider value uses the DIV coding defined in RCC associated
+ register RCC_xxxDIVR. In most the case, it is:
0x0: not divided
0x1: division by 2
0x2: division by 4
0x3: division by 8
...
- but for RTC MCO1 MCO2, the coding is different:
+ Note that for RTC MCO1 MCO2, the coding is different:
0x0: not divided
0x1: division by 2
0x2: division by 3
0x3: division by 4
...
-Optional Properties:
-- st,pll
- PLL children node for PLL1 to PLL4 : (see ref manual for details)
- with associated index 0 to 3 (st,pll@0 to st,pll@4)
- PLLx is off when the associated node is absent
+ Example:
+ st,clkdiv = <
+ 1 /*MPU*/
+ 0 /*AXI*/
+ 0 /*MCU*/
+ 1 /*APB1*/
+ 1 /*APB2*/
+ 1 /*APB3*/
+ 1 /*APB4*/
+ 2 /*APB5*/
+ 23 /*RTC*/
+ 0 /*MCO1*/
+ 0 /*MCO2*/
+ >;
- - Sub-nodes:
+Optional Properties:
+- st,pll : A specific PLL configuration, including frequency.
- - cfg: The parameters for PLL configuration in this order:
- DIVM DIVN DIVP DIVQ DIVR Output
+ PLL children nodes for PLL1 to PLL4 (see ref manual for details)
+ are listed with associated index 0 to 3 (st,pll@0 to st,pll@3).
+ PLLx is off when the associated node is absent.
- with DIV value as defined in RCC spec:
- 0x0: bypass (division by 1)
- 0x1: division by 2
- 0x2: division by 3
- 0x3: division by 4
- ...
+ Here are the available properties for each PLL node:
- and Output = bitfield for each output value = 1:ON/0:OFF
- BIT(0) => output P : DIVPEN
- BIT(1) => output Q : DIVQEN
- BIT(2) => output R : DIVREN
- NB : macro PQR(p,q,r) can be used to build this value
- with p,p,r = 0 or 1
+ - cfg: The parameters for PLL configuration in the following order:
+ DIVM DIVN DIVP DIVQ DIVR Output.
- - frac : Fractional part of the multiplication factor
- (optional, PLL is in integer mode when absent)
+ DIVx values are defined as in RCC spec:
+ 0x0: bypass (division by 1)
+ 0x1: division by 2
+ 0x2: division by 3
+ 0x3: division by 4
+ ...
- - csg : Clock Spreading Generator (optional)
- with parameters in this order:
- MOD_PER INC_STEP SSCG_MODE
+ Output contains a bitfield for each output value (1:ON/0:OFF)
+ BIT(0) => output P : DIVPEN
+ BIT(1) => output Q : DIVQEN
+ BIT(2) => output R : DIVREN
+ NB: macro PQR(p,q,r) can be used to build this value
+ with p,q,r = 0 or 1.
+
+ - frac : Fractional part of the multiplication factor
+ (optional, PLL is in integer mode when absent).
+
+ - csg : Clock Spreading Generator (optional) with parameters in the
+ following order: MOD_PER INC_STEP SSCG_MODE.
+
+ MOD_PER: Modulation Period Adjustment
+ INC_STEP: Modulation Depth Adjustment
+ SSCG_MODE: Spread spectrum clock generator mode, with associated
+ defined from stm32mp1-clksrc.h:
+ - SSCG_MODE_CENTER_SPREAD = 0
+ - SSCG_MODE_DOWN_SPREAD = 1
+
+ Example:
+ st,pll@0 {
+ cfg = < 1 53 0 0 0 1 >;
+ frac = < 0x810 >;
+ };
+ st,pll@1 {
+ cfg = < 1 43 1 0 0 PQR(0,1,1) >;
+ csg = < 10 20 1 >;
+ };
+ st,pll@2 {
+ cfg = < 2 85 3 13 3 0 >;
+ csg = < 10 20 SSCG_MODE_CENTER_SPREAD >;
+ };
+ st,pll@3 {
+ cfg = < 2 78 4 7 9 3 >;
+ };
- * MOD_PER: Modulation Period Adjustment
- * INC_STEP: Modulation Depth Adjustment
- * SSCG_MODE: Spread spectrum clock generator mode
- you can use associated defines from stm32mp1-clksrc.h
- * SSCG_MODE_CENTER_SPREAD = 0
- * SSCG_MODE_DOWN_SPREAD = 1
+- st,pkcs : used to configure the peripherals kernel clock selection.
+ The property is a list of peripheral kernel clock source identifiers defined
+ by macros CLK_<KERNEL-CLOCK>_<PARENT-CLOCK> as defined by header file
+ dt-bindings/clock/stm32mp1-clksrc.h.
-- st,pkcs : used to configure the peripherals kernel clock selection
- containing a list of peripheral kernel clock source identifier as defined
- in the file dt-bindings/clock/stm32mp1-clksrc.h
+ st,pkcs may not list all the kernel clocks and has no ordering requirements.
Example:
+ st,pkcs = <
+ CLK_STGEN_HSE
+ CLK_CKPER_HSI
+ CLK_USBPHY_PLL2P
+ CLK_DSI_PLL2Q
+ CLK_I2C46_HSI
+ CLK_UART1_HSI
+ CLK_UART24_HSI
+ >;
- rcc: rcc@50000000 {
- compatible = "syscon", "simple-mfd";
-
- reg = <0x50000000 0x1000>;
-
- rcc_clk: rcc-clk@50000000 {
- #clock-cells = <1>;
- compatible = "st,stm32mp1-rcc-clk";
-
- st,clksrc = < CLK_MPU_PLL1P
- CLK_AXI_PLL2P
- CLK_MCU_HSI
- CLK_PLL12_HSE
- CLK_PLL3_HSE
- CLK_PLL4_HSE
- CLK_RTC_HSE
- CLK_MCO1_DISABLED
- CLK_MCO2_DISABLED
- >;
-
- st,clkdiv = <
- 1 /*MPU*/
- 0 /*AXI*/
- 0 /*MCU*/
- 1 /*APB1*/
- 1 /*APB2*/
- 1 /*APB3*/
- 1 /*APB4*/
- 5 /*APB5*/
- 23 /*RTC*/
- 0 /*MCO1*/
- 0 /*MCO2*/
- >;
-
- st,pll@0 {
- cfg = < 1 53 0 0 0 1 >;
- frac = < 0x810 >;
- };
- st,pll@1 {
- cfg = < 1 43 1 0 0 PQR(0,1,1) >;
- csg = < 10 20 1 >;
- };
- st,pll@2 {
- cfg = < 2 85 3 13 3 0 >;
- csg = < 10 20 SSCG_MODE_CENTER_SPREAD >;
- };
- st,pll@3 {
- cfg = < 2 78 4 7 9 3 >;
- };
- st,pkcs = <
- CLK_STGEN_HSE
- CLK_CKPER_HSI
- CLK_USBPHY_PLL2P
- CLK_DSI_PLL2Q
- >;
- };
- };
-
---------------------------
other clocks = fixed-clock
---------------------------
+==========================
+
The clock tree is also based on 5 fixed-clock in clocks node
used to define the state of associated ST32MP1 oscillators:
-- clk-lsi
-- clk-lse
-- clk-hsi
-- clk-hse
-- clk-csi
+ - clk-lsi
+ - clk-lse
+ - clk-hsi
+ - clk-hse
+ - clk-csi
At boot the clock tree initialization will
-- enable the oscillator present in device tree
-- disable HSI oscillator if the node is absent (always activated by bootrom)
+ - enable oscillators present in device tree
+ - disable HSI oscillator if the node is absent (always activated by bootrom)
Optional properties :
a) for external oscillator: "clk-lse", "clk-hse"
- 4 optional fields are managed
- - "st,bypass" Configure the oscillator bypass mode (HSEBYP, LSEBYP)
- - "st,digbypass" Configure the bypass mode as full-swing digital signal
- (DIGBYP)
- - "st,css" Activate the clock security system (HSECSSON, LSECSSON)
- - "st,drive" (only for LSE) value of the drive for the oscillator
- (see LSEDRV_ define in the file dt-bindings/clock/stm32mp1-clksrc.h)
-
- Example board file:
+ 4 optional fields are managed
+ - "st,bypass" configures the oscillator bypass mode (HSEBYP, LSEBYP)
+ - "st,digbypass" configures the bypass mode as full-swing digital
+ signal (DIGBYP)
+ - "st,css" activates the clock security system (HSECSSON, LSECSSON)
+ - "st,drive" (only for LSE) contains the value of the drive for the
+ oscillator (see LSEDRV_ defined in the file
+ dt-bindings/clock/stm32mp1-clksrc.h)
+ Example board file:
/ {
clocks {
clk_hse: clk-hse {
@@ -200,13 +201,12 @@ a) for external oscillator: "clk-lse", "clk-hse"
b) for internal oscillator: "clk-hsi"
- internally HSI clock is fixed to 64MHz for STM32MP157 soc
- in device tree clk-hsi is the clock after HSIDIV (ck_hsi in RCC doc)
- So this clock frequency is used to compute the expected HSI_DIV
- for the clock tree initialisation
-
- ex: for HSIDIV = /1
+ Internally HSI clock is fixed to 64MHz for STM32MP157 SoC.
+ In device tree, clk-hsi is the clock after HSIDIV (clk_hsi in RCC
+ doc). So this clock frequency is used to compute the expected HSI_DIV
+ for the clock tree initialization.
+ Example with HSIDIV = /1:
/ {
clocks {
clk_hsi: clk-hsi {
@@ -216,8 +216,7 @@ b) for internal oscillator: "clk-hsi"
};
};
- ex: for HSIDIV = /2
-
+ Example with HSIDIV = /2
/ {
clocks {
clk_hsi: clk-hsi {
@@ -226,3 +225,151 @@ b) for internal oscillator: "clk-hsi"
clock-frequency = <32000000>;
};
};
+
+Example of clock tree initialization
+====================================
+
+/ {
+ clocks {
+ u-boot,dm-pre-reloc;
+ clk_hse: clk-hse {
+ u-boot,dm-pre-reloc;
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ st,digbypass;
+ };
+
+ clk_hsi: clk-hsi {
+ u-boot,dm-pre-reloc;
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <64000000>;
+ };
+
+ clk_lse: clk-lse {
+ u-boot,dm-pre-reloc;
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ };
+
+ clk_lsi: clk-lsi {
+ u-boot,dm-pre-reloc;
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32000>;
+ };
+
+ clk_csi: clk-csi {
+ u-boot,dm-pre-reloc;
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <4000000>;
+ };
+ };
+
+ soc {
+
+ rcc: rcc@50000000 {
+ u-boot,dm-pre-reloc;
+ compatible = "st,stm32mp1-rcc", "syscon";
+ reg = <0x50000000 0x1000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+
+ st,clksrc = <
+ CLK_MPU_PLL1P
+ CLK_AXI_PLL2P
+ CLK_MCU_PLL3P
+ CLK_PLL12_HSE
+ CLK_PLL3_HSE
+ CLK_PLL4_HSE
+ CLK_RTC_LSE
+ CLK_MCO1_DISABLED
+ CLK_MCO2_DISABLED
+ >;
+
+ st,clkdiv = <
+ 1 /*MPU*/
+ 0 /*AXI*/
+ 0 /*MCU*/
+ 1 /*APB1*/
+ 1 /*APB2*/
+ 1 /*APB3*/
+ 1 /*APB4*/
+ 2 /*APB5*/
+ 23 /*RTC*/
+ 0 /*MCO1*/
+ 0 /*MCO2*/
+ >;
+
+ st,pkcs = <
+ CLK_CKPER_HSE
+ CLK_FMC_ACLK
+ CLK_QSPI_ACLK
+ CLK_ETH_DISABLED
+ CLK_SDMMC12_PLL4P
+ CLK_DSI_DSIPLL
+ CLK_STGEN_HSE
+ CLK_USBPHY_HSE
+ CLK_SPI2S1_PLL3Q
+ CLK_SPI2S23_PLL3Q
+ CLK_SPI45_HSI
+ CLK_SPI6_HSI
+ CLK_I2C46_HSI
+ CLK_SDMMC3_PLL4P
+ CLK_USBO_USBPHY
+ CLK_ADC_CKPER
+ CLK_CEC_LSE
+ CLK_I2C12_HSI
+ CLK_I2C35_HSI
+ CLK_UART1_HSI
+ CLK_UART24_HSI
+ CLK_UART35_HSI
+ CLK_UART6_HSI
+ CLK_UART78_HSI
+ CLK_SPDIF_PLL4P
+ CLK_FDCAN_PLL4Q
+ CLK_SAI1_PLL3Q
+ CLK_SAI2_PLL3Q
+ CLK_SAI3_PLL3Q
+ CLK_SAI4_PLL3Q
+ CLK_RNG1_LSI
+ CLK_RNG2_LSI
+ CLK_LPTIM1_PCLK1
+ CLK_LPTIM23_PCLK3
+ CLK_LPTIM45_LSE
+ >;
+
+ /* VCO = 1300.0 MHz => P = 650 (CPU) */
+ pll1: st,pll@0 {
+ cfg = < 2 80 0 0 0 PQR(1,0,0) >;
+ frac = < 0x800 >;
+ u-boot,dm-pre-reloc;
+ };
+
+ /* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU),
+ R = 533 (DDR) */
+ pll2: st,pll@1 {
+ cfg = < 2 65 1 0 0 PQR(1,1,1) >;
+ frac = < 0x1400 >;
+ u-boot,dm-pre-reloc;
+ };
+
+ /* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */
+ pll3: st,pll@2 {
+ cfg = < 1 33 1 16 36 PQR(1,1,1) >;
+ frac = < 0x1a04 >;
+ u-boot,dm-pre-reloc;
+ };
+
+ /* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */
+ pll4: st,pll@3 {
+ cfg = < 3 98 5 7 7 PQR(1,1,1) >;
+ u-boot,dm-pre-reloc;
+ };
+ };
+ };
+};
diff --git a/doc/device-tree-bindings/memory-controllers/st,stm32mp1-ddr.txt b/doc/device-tree-bindings/memory-controllers/st,stm32mp1-ddr.txt
index 3028636c45..ee708ce92c 100644
--- a/doc/device-tree-bindings/memory-controllers/st,stm32mp1-ddr.txt
+++ b/doc/device-tree-bindings/memory-controllers/st,stm32mp1-ddr.txt
@@ -16,7 +16,7 @@ included in STM32 Cube tool
info attributes:
----------------
- st,mem-name : name for DDR configuration, simple string for information
-- st,mem-speed : DDR expected speed for the setting in MHz
+- st,mem-speed : DDR expected speed for the setting in kHz
- st,mem-size : DDR mem size in byte
@@ -102,7 +102,7 @@ controlleur attributes:
phyc attributes:
----------------
- st,phy-reg : phy values depending of the DDR type (DDR3/LPDDR2/LPDDR3)
- for STM32MP15x: 10 values are requested in this order
+ for STM32MP15x: 11 values are requested in this order
PGCR
ACIOCR
DXCCR
@@ -173,7 +173,7 @@ Example:
"ddrphycapb";
st,mem-name = "DDR3 2x4Gb 533MHz";
- st,mem-speed = <533>;
+ st,mem-speed = <533000>;
st,mem-size = <0x40000000>;
st,ctl-reg = <
diff --git a/doc/device-tree-bindings/serial/mcf-uart.txt b/doc/device-tree-bindings/serial/mcf-uart.txt
new file mode 100644
index 0000000000..d73f764c01
--- /dev/null
+++ b/doc/device-tree-bindings/serial/mcf-uart.txt
@@ -0,0 +1,19 @@
+Freescale ColdFire UART
+
+Required properties:
+- compatible : should be "fsl,mcf-uart"
+- reg: start address and size of the registers
+
+Example:
+
+soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ uart0: uart@fc060000 {
+ compatible = "fsl,mcf-uart";
+ reg = <0xfc060000 0x40>;
+ status = "disabled";
+ };
+};
diff --git a/doc/device-tree-bindings/spi/spi-mcf-dspi.txt b/doc/device-tree-bindings/spi/spi-mcf-dspi.txt
new file mode 100644
index 0000000000..860eb8ac85
--- /dev/null
+++ b/doc/device-tree-bindings/spi/spi-mcf-dspi.txt
@@ -0,0 +1,30 @@
+Freescale ColdFire DSPI controller
+
+Required properties:
+- compatible : "fsl,mcf-dspi"
+- #address-cells: <1>, as required by generic SPI binding
+- #size-cells: <0>, also as required by generic SPI binding
+- reg : offset and length of the register set for the device
+
+Optional properties:
+- spi-max-frequency : max supported spi frequency
+- num-cs : the number of the chipselect signals
+- spi-mode: spi motorola mode, 0 to 3
+- ctar-params: CTAR0 to 7 register configuration, as an array
+ of 8 integer fields for each register, where each register
+ is defined as: <fmsz, pcssck, pasc, pdt, cssck, asc, dt, br>.
+
+Example:
+
+dspi0: dspi@fc05c000 {
+ compatible = "fsl,mcf-dspi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xfc05c000 0x100>;
+ spi-max-frequency = <50000000>;
+ num-cs = <4>;
+ spi-mode = <0>;
+ ctar-fields = <7, 0, 0, 0, 0, 0, 1, 6>,
+ <7, 0, 0, 0, 0, 0, 1, 6>,
+ <7, 0, 0, 0, 0, 0, 1, 6>;
+};
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 4e95a68a2d..87636ae30f 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -59,6 +59,16 @@ config DWC_AHCI
Enable this driver to support Sata devices through
Synopsys DWC AHCI module.
+config FSL_AHCI
+ bool "Enable Freescale AHCI driver support"
+ select SCSI_AHCI
+ depends on AHCI
+ depends on DM_SCSI
+ help
+ Enable this driver to support Sata devices found in
+ some Freescale PowerPC SoCs.
+
+
config DWC_AHSATA
bool "Enable DWC AHSATA driver support"
select LIBATA
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index a69edb10f7..6e03384f81 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -4,6 +4,7 @@
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
obj-$(CONFIG_DWC_AHCI) += dwc_ahci.o
+obj-$(CONFIG_FSL_AHCI) += fsl_ahci.o
obj-$(CONFIG_AHCI) += ahci-uclass.o
obj-$(CONFIG_AHCI_PCI) += ahci-pci.o
obj-$(CONFIG_SCSI_AHCI) += ahci.o
diff --git a/drivers/ata/fsl_ahci.c b/drivers/ata/fsl_ahci.c
new file mode 100644
index 0000000000..d04cff3ee7
--- /dev/null
+++ b/drivers/ata/fsl_ahci.c
@@ -0,0 +1,1030 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * NXP PPC SATA platform driver
+ *
+ * (C) Copyright 2019 NXP, Inc.
+ *
+ */
+#include <common.h>
+#include <asm/fsl_serdes.h>
+#include <dm/lists.h>
+#include <dm.h>
+#include <ahci.h>
+#include <scsi.h>
+#include <libata.h>
+#include <sata.h>
+#include <malloc.h>
+#include <memalign.h>
+#include <fis.h>
+
+#include "fsl_sata.h"
+
+struct fsl_ahci_priv {
+ u32 base;
+ u32 flag;
+ u32 number;
+ fsl_sata_t *fsl_sata;
+};
+
+static int fsl_ahci_bind(struct udevice *dev)
+{
+ return device_bind_driver(dev, "fsl_ahci_scsi", "fsl_ahci_scsi", NULL);
+}
+
+static int fsl_ahci_ofdata_to_platdata(struct udevice *dev)
+{
+ struct fsl_ahci_priv *priv = dev_get_priv(dev);
+
+ priv->number = dev_read_u32_default(dev, "sata-number", -1);
+ priv->flag = dev_read_u32_default(dev, "sata-fpdma", -1);
+
+ priv->base = dev_read_addr(dev);
+ if (priv->base == FDT_ADDR_T_NONE)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int ata_wait_register(unsigned __iomem *addr, u32 mask,
+ u32 val, u32 timeout_msec)
+{
+ int i;
+
+ for (i = 0; ((in_le32(addr) & mask) != val) && i < timeout_msec; i++)
+ mdelay(1);
+
+ return (i < timeout_msec) ? 0 : -1;
+}
+
+static void fsl_sata_dump_sfis(struct sata_fis_d2h *s)
+{
+ printf("Status FIS dump:\n\r");
+ printf("fis_type: %02x\n\r", s->fis_type);
+ printf("pm_port_i: %02x\n\r", s->pm_port_i);
+ printf("status: %02x\n\r", s->status);
+ printf("error: %02x\n\r", s->error);
+ printf("lba_low: %02x\n\r", s->lba_low);
+ printf("lba_mid: %02x\n\r", s->lba_mid);
+ printf("lba_high: %02x\n\r", s->lba_high);
+ printf("device: %02x\n\r", s->device);
+ printf("lba_low_exp: %02x\n\r", s->lba_low_exp);
+ printf("lba_mid_exp: %02x\n\r", s->lba_mid_exp);
+ printf("lba_high_exp: %02x\n\r", s->lba_high_exp);
+ printf("res1: %02x\n\r", s->res1);
+ printf("sector_count: %02x\n\r", s->sector_count);
+ printf("sector_count_exp: %02x\n\r", s->sector_count_exp);
+}
+
+static void fsl_sata_dump_regs(fsl_sata_reg_t __iomem *reg)
+{
+ printf("\n\rSATA: %08x\n\r", (u32)reg);
+ printf("CQR: %08x\n\r", in_le32(&reg->cqr));
+ printf("CAR: %08x\n\r", in_le32(&reg->car));
+ printf("CCR: %08x\n\r", in_le32(&reg->ccr));
+ printf("CER: %08x\n\r", in_le32(&reg->cer));
+ printf("CQR: %08x\n\r", in_le32(&reg->cqr));
+ printf("DER: %08x\n\r", in_le32(&reg->der));
+ printf("CHBA: %08x\n\r", in_le32(&reg->chba));
+ printf("HStatus: %08x\n\r", in_le32(&reg->hstatus));
+ printf("HControl: %08x\n\r", in_le32(&reg->hcontrol));
+ printf("CQPMP: %08x\n\r", in_le32(&reg->cqpmp));
+ printf("SIG: %08x\n\r", in_le32(&reg->sig));
+ printf("ICC: %08x\n\r", in_le32(&reg->icc));
+ printf("SStatus: %08x\n\r", in_le32(&reg->sstatus));
+ printf("SError: %08x\n\r", in_le32(&reg->serror));
+ printf("SControl: %08x\n\r", in_le32(&reg->scontrol));
+ printf("SNotification: %08x\n\r", in_le32(&reg->snotification));
+ printf("TransCfg: %08x\n\r", in_le32(&reg->transcfg));
+ printf("TransStatus: %08x\n\r", in_le32(&reg->transstatus));
+ printf("LinkCfg: %08x\n\r", in_le32(&reg->linkcfg));
+ printf("LinkCfg1: %08x\n\r", in_le32(&reg->linkcfg1));
+ printf("LinkCfg2: %08x\n\r", in_le32(&reg->linkcfg2));
+ printf("LinkStatus: %08x\n\r", in_le32(&reg->linkstatus));
+ printf("LinkStatus1: %08x\n\r", in_le32(&reg->linkstatus1));
+ printf("PhyCtrlCfg: %08x\n\r", in_le32(&reg->phyctrlcfg));
+ printf("SYSPR: %08x\n\r", in_be32(&reg->syspr));
+}
+
+static int init_sata(struct fsl_ahci_priv *priv)
+{
+ int i;
+ u32 cda;
+ u32 val32;
+ u32 sig;
+ fsl_sata_t *sata;
+ u32 length, align;
+ cmd_hdr_tbl_t *cmd_hdr;
+ fsl_sata_reg_t __iomem *reg;
+
+ int dev = priv->number;
+
+ if (dev < 0 || dev > (CONFIG_SYS_SATA_MAX_DEVICE - 1)) {
+ printf("the sata index %d is out of ranges\n\r", dev);
+ return -EINVAL;
+ }
+
+#ifdef CONFIG_MPC85xx
+ if (dev == 0 && (!is_serdes_configured(SATA1))) {
+ printf("SATA%d [dev = %d] is not enabled\n", dev + 1, dev);
+ return -EINVAL;
+ }
+ if (dev == 1 && (!is_serdes_configured(SATA2))) {
+ printf("SATA%d [dev = %d] is not enabled\n", dev + 1, dev);
+ return -EINVAL;
+ }
+#endif
+
+ /* Allocate SATA device driver struct */
+ sata = (fsl_sata_t *)malloc(sizeof(fsl_sata_t));
+ if (!sata) {
+ printf("alloc the sata device struct failed\n\r");
+ return -ENOMEM;
+ }
+ /* Zero all of the device driver struct */
+ memset((void *)sata, 0, sizeof(fsl_sata_t));
+
+ sata->dma_flag = priv->flag;
+ snprintf(sata->name, 12, "SATA%d", dev);
+
+ /* Set the controller register base address to device struct */
+ reg = (fsl_sata_reg_t *)priv->base;
+ sata->reg_base = reg;
+
+ /* Allocate the command header table, 4 bytes aligned */
+ length = sizeof(struct cmd_hdr_tbl);
+ align = SATA_HC_CMD_HDR_TBL_ALIGN;
+ sata->cmd_hdr_tbl_offset = (void *)malloc(length + align);
+ if (!sata->cmd_hdr_tbl_offset) {
+ printf("alloc the command header failed\n\r");
+ return -ENOMEM;
+ }
+
+ cmd_hdr = (cmd_hdr_tbl_t *)(((u32)sata->cmd_hdr_tbl_offset + align)
+ & ~(align - 1));
+ sata->cmd_hdr = cmd_hdr;
+
+ /* Zero all of the command header table */
+ memset((void *)sata->cmd_hdr_tbl_offset, 0, length + align);
+
+ /* Allocate command descriptor for all command */
+ length = sizeof(struct cmd_desc) * SATA_HC_MAX_CMD;
+ align = SATA_HC_CMD_DESC_ALIGN;
+ sata->cmd_desc_offset = (void *)malloc(length + align);
+ if (!sata->cmd_desc_offset) {
+ printf("alloc the command descriptor failed\n\r");
+ return -ENOMEM;
+ }
+ sata->cmd_desc = (cmd_desc_t *)(((u32)sata->cmd_desc_offset + align)
+ & ~(align - 1));
+ /* Zero all of command descriptor */
+ memset((void *)sata->cmd_desc_offset, 0, length + align);
+
+ /* Link the command descriptor to command header */
+ for (i = 0; i < SATA_HC_MAX_CMD; i++) {
+ cda = ((u32)sata->cmd_desc + SATA_HC_CMD_DESC_SIZE * i)
+ & ~(CMD_HDR_CDA_ALIGN - 1);
+ cmd_hdr->cmd_slot[i].cda = cpu_to_le32(cda);
+ }
+
+ /* To have safe state, force the controller offline */
+ val32 = in_le32(&reg->hcontrol);
+ val32 &= ~HCONTROL_ONOFF;
+ val32 |= HCONTROL_FORCE_OFFLINE;
+ out_le32(&reg->hcontrol, val32);
+
+ /* Wait the controller offline */
+ ata_wait_register(&reg->hstatus, HSTATUS_ONOFF, 0, 1000);
+
+ /* Set the command header base address to CHBA register to tell DMA */
+ out_le32(&reg->chba, (u32)cmd_hdr & ~0x3);
+
+ /* Snoop for the command header */
+ val32 = in_le32(&reg->hcontrol);
+ val32 |= HCONTROL_HDR_SNOOP;
+ out_le32(&reg->hcontrol, val32);
+
+ /* Disable all of interrupts */
+ val32 = in_le32(&reg->hcontrol);
+ val32 &= ~HCONTROL_INT_EN_ALL;
+ out_le32(&reg->hcontrol, val32);
+
+ /* Clear all of interrupts */
+ val32 = in_le32(&reg->hstatus);
+ out_le32(&reg->hstatus, val32);
+
+ /* Set the ICC, no interrupt coalescing */
+ out_le32(&reg->icc, 0x01000000);
+
+ /* No PM attatched, the SATA device direct connect */
+ out_le32(&reg->cqpmp, 0);
+
+ /* Clear SError register */
+ val32 = in_le32(&reg->serror);
+ out_le32(&reg->serror, val32);
+
+ /* Clear CER register */
+ val32 = in_le32(&reg->cer);
+ out_le32(&reg->cer, val32);
+
+ /* Clear DER register */
+ val32 = in_le32(&reg->der);
+ out_le32(&reg->der, val32);
+
+ /* No device detection or initialization action requested */
+ out_le32(&reg->scontrol, 0x00000300);
+
+ /* Configure the transport layer, default value */
+ out_le32(&reg->transcfg, 0x08000016);
+
+ /* Configure the link layer, default value */
+ out_le32(&reg->linkcfg, 0x0000ff34);
+
+ /* Bring the controller online */
+ val32 = in_le32(&reg->hcontrol);
+ val32 |= HCONTROL_ONOFF;
+ out_le32(&reg->hcontrol, val32);
+
+ mdelay(100);
+
+ /* print sata device name */
+ printf("%s ", sata->name);
+
+ /* Wait PHY RDY signal changed for 500ms */
+ ata_wait_register(&reg->hstatus, HSTATUS_PHY_RDY,
+ HSTATUS_PHY_RDY, 500);
+
+ /* Check PHYRDY */
+ val32 = in_le32(&reg->hstatus);
+ if (val32 & HSTATUS_PHY_RDY) {
+ sata->link = 1;
+ } else {
+ sata->link = 0;
+ printf("(No RDY)\n\r");
+ return -EINVAL;
+ }
+
+ /* Wait for signature updated, which is 1st D2H */
+ ata_wait_register(&reg->hstatus, HSTATUS_SIGNATURE,
+ HSTATUS_SIGNATURE, 10000);
+
+ if (val32 & HSTATUS_SIGNATURE) {
+ sig = in_le32(&reg->sig);
+ debug("Signature updated, the sig =%08x\n\r", sig);
+ sata->ata_device_type = ata_dev_classify(sig);
+ }
+
+ /* Check the speed */
+ val32 = in_le32(&reg->sstatus);
+ if ((val32 & SSTATUS_SPD_MASK) == SSTATUS_SPD_GEN1)
+ printf("(1.5 Gbps)\n\r");
+ else if ((val32 & SSTATUS_SPD_MASK) == SSTATUS_SPD_GEN2)
+ printf("(3 Gbps)\n\r");
+
+ priv->fsl_sata = sata;
+
+ return 0;
+}
+
+static int fsl_ata_exec_ata_cmd(struct fsl_sata *sata,
+ struct sata_fis_h2d *cfis,
+ int is_ncq, int tag,
+ u8 *buffer, u32 len)
+{
+ cmd_hdr_entry_t *cmd_hdr;
+ cmd_desc_t *cmd_desc;
+ sata_fis_h2d_t *h2d;
+ prd_entry_t *prde;
+ u32 ext_c_ddc;
+ u32 prde_count;
+ u32 val32;
+ u32 ttl;
+ u32 der;
+ int i;
+
+ fsl_sata_reg_t *reg = sata->reg_base;
+
+ /* Check xfer length */
+ if (len > SATA_HC_MAX_XFER_LEN) {
+ printf("max transfer length is 64MB\n\r");
+ return 0;
+ }
+
+ /* Setup the command descriptor */
+ cmd_desc = sata->cmd_desc + tag;
+
+ /* Get the pointer cfis of command descriptor */
+ h2d = (sata_fis_h2d_t *)cmd_desc->cfis;
+
+ /* Zero the cfis of command descriptor */
+ memset((void *)h2d, 0, SATA_HC_CMD_DESC_CFIS_SIZE);
+
+ /* Copy the cfis from user to command descriptor */
+ h2d->fis_type = cfis->fis_type;
+ h2d->pm_port_c = cfis->pm_port_c;
+ h2d->command = cfis->command;
+
+ h2d->features = cfis->features;
+ h2d->features_exp = cfis->features_exp;
+
+ h2d->lba_low = cfis->lba_low;
+ h2d->lba_mid = cfis->lba_mid;
+ h2d->lba_high = cfis->lba_high;
+ h2d->lba_low_exp = cfis->lba_low_exp;
+ h2d->lba_mid_exp = cfis->lba_mid_exp;
+ h2d->lba_high_exp = cfis->lba_high_exp;
+
+ if (!is_ncq) {
+ h2d->sector_count = cfis->sector_count;
+ h2d->sector_count_exp = cfis->sector_count_exp;
+ } else { /* NCQ */
+ h2d->sector_count = (u8)(tag << 3);
+ }
+
+ h2d->device = cfis->device;
+ h2d->control = cfis->control;
+
+ /* Setup the PRD table */
+ prde = (prd_entry_t *)cmd_desc->prdt;
+ memset((void *)prde, 0, sizeof(struct prdt));
+
+ prde_count = 0;
+ ttl = len;
+ for (i = 0; i < SATA_HC_MAX_PRD_DIRECT; i++) {
+ if (!len)
+ break;
+ prde->dba = cpu_to_le32((u32)buffer & ~0x3);
+ debug("dba = %08x\n\r", (u32)buffer);
+
+ if (len < PRD_ENTRY_MAX_XFER_SZ) {
+ ext_c_ddc = PRD_ENTRY_DATA_SNOOP | len;
+ debug("ext_c_ddc1 = %08x, len = %08x\n\r",
+ ext_c_ddc, len);
+ prde->ext_c_ddc = cpu_to_le32(ext_c_ddc);
+ prde_count++;
+ prde++;
+ } else {
+ ext_c_ddc = PRD_ENTRY_DATA_SNOOP; /* 4M bytes */
+ debug("ext_c_ddc2 = %08x, len = %08x\n\r",
+ ext_c_ddc, len);
+ prde->ext_c_ddc = cpu_to_le32(ext_c_ddc);
+ buffer += PRD_ENTRY_MAX_XFER_SZ;
+ len -= PRD_ENTRY_MAX_XFER_SZ;
+ prde_count++;
+ prde++;
+ }
+ }
+
+ /* Setup the command slot of cmd hdr */
+ cmd_hdr = (cmd_hdr_entry_t *)&sata->cmd_hdr->cmd_slot[tag];
+
+ cmd_hdr->cda = cpu_to_le32((u32)cmd_desc & ~0x3);
+
+ val32 = prde_count << CMD_HDR_PRD_ENTRY_SHIFT;
+ val32 |= sizeof(sata_fis_h2d_t);
+ cmd_hdr->prde_fis_len = cpu_to_le32(val32);
+
+ cmd_hdr->ttl = cpu_to_le32(ttl);
+
+ if (!is_ncq)
+ val32 = CMD_HDR_ATTR_RES | CMD_HDR_ATTR_SNOOP;
+ else
+ val32 = CMD_HDR_ATTR_RES | CMD_HDR_ATTR_SNOOP |
+ CMD_HDR_ATTR_FPDMA;
+
+ tag &= CMD_HDR_ATTR_TAG;
+ val32 |= tag;
+
+ debug("attribute = %08x\n\r", val32);
+ cmd_hdr->attribute = cpu_to_le32(val32);
+
+ /* Make sure cmd desc and cmd slot valid before command issue */
+ sync();
+
+ /* PMP*/
+ val32 = (u32)(h2d->pm_port_c & 0x0f);
+ out_le32(&reg->cqpmp, val32);
+
+ /* Wait no active */
+ if (ata_wait_register(&reg->car, (1 << tag), 0, 10000))
+ printf("Wait no active time out\n\r");
+
+ /* Issue command */
+ if (!(in_le32(&reg->cqr) & (1 << tag))) {
+ val32 = 1 << tag;
+ out_le32(&reg->cqr, val32);
+ }
+
+ /* Wait command completed for 10s */
+ if (ata_wait_register(&reg->ccr, (1 << tag), (1 << tag), 10000)) {
+ if (!is_ncq)
+ printf("Non-NCQ command time out\n\r");
+ else
+ printf("NCQ command time out\n\r");
+ }
+
+ val32 = in_le32(&reg->cer);
+
+ if (val32) {
+ fsl_sata_dump_sfis((struct sata_fis_d2h *)cmd_desc->sfis);
+ printf("CE at device\n\r");
+ fsl_sata_dump_regs(reg);
+ der = in_le32(&reg->der);
+ out_le32(&reg->cer, val32);
+ out_le32(&reg->der, der);
+ }
+
+ /* Clear complete flags */
+ val32 = in_le32(&reg->ccr);
+ out_le32(&reg->ccr, val32);
+
+ return len;
+}
+
+static int fsl_sata_exec_cmd(struct fsl_sata *sata, struct sata_fis_h2d *cfis,
+ enum cmd_type command_type, int tag, u8 *buffer,
+ u32 len)
+{
+ int rc;
+
+ if (tag > SATA_HC_MAX_CMD || tag < 0) {
+ printf("tag is out of range, tag=%d\n\r", tag);
+ return -1;
+ }
+
+ switch (command_type) {
+ case CMD_ATA:
+ rc = fsl_ata_exec_ata_cmd(sata, cfis, 0, tag, buffer, len);
+ return rc;
+ case CMD_NCQ:
+ rc = fsl_ata_exec_ata_cmd(sata, cfis, 1, tag, buffer, len);
+ return rc;
+ case CMD_ATAPI:
+ case CMD_VENDOR_BIST:
+ case CMD_BIST:
+ printf("not support now\n\r");
+ return -1;
+ default:
+ break;
+ }
+
+ return -1;
+}
+
+static void fsl_sata_identify(fsl_sata_t *sata, u16 *id)
+{
+ struct sata_fis_h2d h2d, *cfis = &h2d;
+
+ memset(cfis, 0, sizeof(struct sata_fis_h2d));
+
+ cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+ cfis->pm_port_c = 0x80; /* is command */
+ cfis->command = ATA_CMD_ID_ATA;
+
+ fsl_sata_exec_cmd(sata, cfis, CMD_ATA, 0, (u8 *)id, ATA_ID_WORDS * 2);
+ ata_swap_buf_le16(id, ATA_ID_WORDS);
+}
+
+static void fsl_sata_xfer_mode(fsl_sata_t *sata, u16 *id)
+{
+ sata->pio = id[ATA_ID_PIO_MODES];
+ sata->mwdma = id[ATA_ID_MWDMA_MODES];
+ sata->udma = id[ATA_ID_UDMA_MODES];
+ debug("pio %04x, mwdma %04x, udma %04x\n\r", sata->pio,
+ sata->mwdma, sata->udma);
+}
+
+static void fsl_sata_init_wcache(fsl_sata_t *sata, u16 *id)
+{
+ if (ata_id_has_wcache(id) && ata_id_wcache_enabled(id))
+ sata->wcache = 1;
+ if (ata_id_has_flush(id))
+ sata->flush = 1;
+ if (ata_id_has_flush_ext(id))
+ sata->flush_ext = 1;
+}
+
+static void fsl_sata_set_features(fsl_sata_t *sata)
+{
+ struct sata_fis_h2d h2d, *cfis = &h2d;
+ u8 udma_cap;
+
+ memset(cfis, 0, sizeof(struct sata_fis_h2d));
+
+ cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+ cfis->pm_port_c = 0x80; /* is command */
+ cfis->command = ATA_CMD_SET_FEATURES;
+ cfis->features = SETFEATURES_XFER;
+
+ /* First check the device capablity */
+ udma_cap = (u8)(sata->udma & 0xff);
+ debug("udma_cap %02x\n\r", udma_cap);
+
+ if (udma_cap == ATA_UDMA6)
+ cfis->sector_count = XFER_UDMA_6;
+ if (udma_cap == ATA_UDMA5)
+ cfis->sector_count = XFER_UDMA_5;
+ if (udma_cap == ATA_UDMA4)
+ cfis->sector_count = XFER_UDMA_4;
+ if (udma_cap == ATA_UDMA3)
+ cfis->sector_count = XFER_UDMA_3;
+
+ fsl_sata_exec_cmd(sata, cfis, CMD_ATA, 0, NULL, 0);
+}
+
+static u32 fsl_sata_rw_cmd(fsl_sata_t *sata, u32 start, u32 blkcnt,
+ u8 *buffer, int is_write)
+{
+ struct sata_fis_h2d h2d, *cfis = &h2d;
+ u32 block;
+
+ block = start;
+
+ memset(cfis, 0, sizeof(struct sata_fis_h2d));
+
+ cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+ cfis->pm_port_c = 0x80; /* is command */
+ cfis->command = (is_write) ? ATA_CMD_WRITE : ATA_CMD_READ;
+ cfis->device = ATA_LBA;
+
+ cfis->device |= (block >> 24) & 0xf;
+ cfis->lba_high = (block >> 16) & 0xff;
+ cfis->lba_mid = (block >> 8) & 0xff;
+ cfis->lba_low = block & 0xff;
+ cfis->sector_count = (u8)(blkcnt & 0xff);
+
+ fsl_sata_exec_cmd(sata, cfis, CMD_ATA, 0, buffer,
+ ATA_SECT_SIZE * blkcnt);
+ return blkcnt;
+}
+
+static void fsl_sata_flush_cache(fsl_sata_t *sata)
+{
+ struct sata_fis_h2d h2d, *cfis = &h2d;
+
+ memset(cfis, 0, sizeof(struct sata_fis_h2d));
+
+ cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+ cfis->pm_port_c = 0x80; /* is command */
+ cfis->command = ATA_CMD_FLUSH;
+
+ fsl_sata_exec_cmd(sata, cfis, CMD_ATA, 0, NULL, 0);
+}
+
+static u32 fsl_sata_rw_cmd_ext(fsl_sata_t *sata, u32 start,
+ u32 blkcnt, u8 *buffer, int is_write)
+{
+ struct sata_fis_h2d h2d, *cfis = &h2d;
+ u64 block;
+
+ block = (u64)start;
+
+ memset(cfis, 0, sizeof(struct sata_fis_h2d));
+
+ cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+ cfis->pm_port_c = 0x80; /* is command */
+
+ cfis->command = (is_write) ? ATA_CMD_WRITE_EXT
+ : ATA_CMD_READ_EXT;
+
+ cfis->lba_high_exp = (block >> 40) & 0xff;
+ cfis->lba_mid_exp = (block >> 32) & 0xff;
+ cfis->lba_low_exp = (block >> 24) & 0xff;
+ cfis->lba_high = (block >> 16) & 0xff;
+ cfis->lba_mid = (block >> 8) & 0xff;
+ cfis->lba_low = block & 0xff;
+ cfis->device = ATA_LBA;
+ cfis->sector_count_exp = (blkcnt >> 8) & 0xff;
+ cfis->sector_count = blkcnt & 0xff;
+
+ fsl_sata_exec_cmd(sata, cfis, CMD_ATA, 0, buffer,
+ ATA_SECT_SIZE * blkcnt);
+ return blkcnt;
+}
+
+static u32 fsl_sata_rw_ncq_cmd(fsl_sata_t *sata, u32 start, u32 blkcnt,
+ u8 *buffer,
+ int is_write)
+{
+ struct sata_fis_h2d h2d, *cfis = &h2d;
+ int ncq_channel;
+ u64 block;
+
+ if (sata->lba48 != 1) {
+ printf("execute FPDMA command on non-LBA48 hard disk\n\r");
+ return -1;
+ }
+
+ block = (u64)start;
+
+ memset(cfis, 0, sizeof(struct sata_fis_h2d));
+
+ cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+ cfis->pm_port_c = 0x80; /* is command */
+
+ cfis->command = (is_write) ? ATA_CMD_FPDMA_WRITE
+ : ATA_CMD_FPDMA_READ;
+
+ cfis->lba_high_exp = (block >> 40) & 0xff;
+ cfis->lba_mid_exp = (block >> 32) & 0xff;
+ cfis->lba_low_exp = (block >> 24) & 0xff;
+ cfis->lba_high = (block >> 16) & 0xff;
+ cfis->lba_mid = (block >> 8) & 0xff;
+ cfis->lba_low = block & 0xff;
+
+ cfis->device = ATA_LBA;
+ cfis->features_exp = (blkcnt >> 8) & 0xff;
+ cfis->features = blkcnt & 0xff;
+
+ if (sata->queue_depth >= SATA_HC_MAX_CMD)
+ ncq_channel = SATA_HC_MAX_CMD - 1;
+ else
+ ncq_channel = sata->queue_depth - 1;
+
+ /* Use the latest queue */
+ fsl_sata_exec_cmd(sata, cfis, CMD_NCQ, ncq_channel, buffer,
+ ATA_SECT_SIZE * blkcnt);
+ return blkcnt;
+}
+
+static void fsl_sata_flush_cache_ext(fsl_sata_t *sata)
+{
+ struct sata_fis_h2d h2d, *cfis = &h2d;
+
+ memset(cfis, 0, sizeof(struct sata_fis_h2d));
+
+ cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+ cfis->pm_port_c = 0x80; /* is command */
+ cfis->command = ATA_CMD_FLUSH_EXT;
+
+ fsl_sata_exec_cmd(sata, cfis, CMD_ATA, 0, NULL, 0);
+}
+
+static u32 ata_low_level_rw_lba48(fsl_sata_t *sata, u32 blknr, lbaint_t blkcnt,
+ const void *buffer, int is_write)
+{
+ u32 start, blks;
+ u8 *addr;
+ int max_blks;
+
+ start = blknr;
+ blks = blkcnt;
+ addr = (u8 *)buffer;
+
+ max_blks = ATA_MAX_SECTORS_LBA48;
+ do {
+ if (blks > max_blks) {
+ if (sata->dma_flag != FLAGS_FPDMA)
+ fsl_sata_rw_cmd_ext(sata, start, max_blks,
+ addr, is_write);
+ else
+ fsl_sata_rw_ncq_cmd(sata, start, max_blks,
+ addr, is_write);
+ start += max_blks;
+ blks -= max_blks;
+ addr += ATA_SECT_SIZE * max_blks;
+ } else {
+ if (sata->dma_flag != FLAGS_FPDMA)
+ fsl_sata_rw_cmd_ext(sata, start, blks,
+ addr, is_write);
+ else
+ fsl_sata_rw_ncq_cmd(sata, start, blks,
+ addr, is_write);
+ start += blks;
+ blks = 0;
+ addr += ATA_SECT_SIZE * blks;
+ }
+ } while (blks != 0);
+
+ return blks;
+}
+
+static u32 ata_low_level_rw_lba28(fsl_sata_t *sata, u32 blknr, u32 blkcnt,
+ const void *buffer, int is_write)
+{
+ u32 start, blks;
+ u8 *addr;
+ int max_blks;
+
+ start = blknr;
+ blks = blkcnt;
+ addr = (u8 *)buffer;
+
+ max_blks = ATA_MAX_SECTORS;
+ do {
+ if (blks > max_blks) {
+ fsl_sata_rw_cmd(sata, start, max_blks, addr, is_write);
+ start += max_blks;
+ blks -= max_blks;
+ addr += ATA_SECT_SIZE * max_blks;
+ } else {
+ fsl_sata_rw_cmd(sata, start, blks, addr, is_write);
+ start += blks;
+ blks = 0;
+ addr += ATA_SECT_SIZE * blks;
+ }
+ } while (blks != 0);
+
+ return blks;
+}
+
+/*
+ * SATA interface between low level driver and command layer
+ */
+static int sata_read(fsl_sata_t *sata, ulong blknr, lbaint_t blkcnt,
+ void *buffer)
+{
+ u32 rc;
+
+ if (sata->lba48)
+ rc = ata_low_level_rw_lba48(sata, blknr, blkcnt, buffer,
+ READ_CMD);
+ else
+ rc = ata_low_level_rw_lba28(sata, blknr, blkcnt, buffer,
+ READ_CMD);
+ return rc;
+}
+
+static int sata_write(fsl_sata_t *sata, ulong blknr, lbaint_t blkcnt,
+ const void *buffer)
+{
+ u32 rc;
+
+ if (sata->lba48) {
+ rc = ata_low_level_rw_lba48(sata, blknr, blkcnt, buffer,
+ WRITE_CMD);
+ if (sata->wcache && sata->flush_ext)
+ fsl_sata_flush_cache_ext(sata);
+ } else {
+ rc = ata_low_level_rw_lba28(sata, blknr, blkcnt, buffer,
+ WRITE_CMD);
+ if (sata->wcache && sata->flush)
+ fsl_sata_flush_cache(sata);
+ }
+
+ return rc;
+}
+
+int sata_getinfo(fsl_sata_t *sata, u16 *id)
+{
+ /* if no detected link */
+ if (!sata->link)
+ return -EINVAL;
+
+#ifdef CONFIG_LBA48
+ /* Check if support LBA48 */
+ if (ata_id_has_lba48(id)) {
+ sata->lba48 = 1;
+ debug("Device support LBA48\n\r");
+ } else {
+ debug("Device supports LBA28\n\r");
+ }
+#endif
+
+ /* Get the NCQ queue depth from device */
+ sata->queue_depth = ata_id_queue_depth(id);
+
+ /* Get the xfer mode from device */
+ fsl_sata_xfer_mode(sata, id);
+
+ /* Get the write cache status from device */
+ fsl_sata_init_wcache(sata, id);
+
+ /* Set the xfer mode to highest speed */
+ fsl_sata_set_features(sata);
+
+ return 0;
+}
+
+static int fsl_scsi_exec(fsl_sata_t *sata, struct scsi_cmd *pccb,
+ bool is_write)
+{
+ int ret;
+ u32 temp;
+ u16 blocks = 0;
+ lbaint_t start = 0;
+ u8 *buffer = pccb->pdata;
+
+ /* Retrieve the base LBA number from the ccb structure. */
+ if (pccb->cmd[0] == SCSI_READ16) {
+ memcpy(&start, pccb->cmd + 2, 8);
+ start = be64_to_cpu(start);
+ } else {
+ memcpy(&temp, pccb->cmd + 2, 4);
+ start = be32_to_cpu(temp);
+ }
+
+ if (pccb->cmd[0] == SCSI_READ16)
+ blocks = (((u16)pccb->cmd[13]) << 8) | ((u16)pccb->cmd[14]);
+ else
+ blocks = (((u16)pccb->cmd[7]) << 8) | ((u16)pccb->cmd[8]);
+
+ debug("scsi_ahci: %s %u blocks starting from lba 0x" LBAFU "\n",
+ is_write ? "write" : "read", blocks, start);
+
+ if (is_write)
+ ret = sata_write(sata, start, blocks, buffer);
+ else
+ ret = sata_read(sata, start, blocks, buffer);
+
+ return ret;
+}
+
+static char *fsl_ata_id_strcpy(u16 *target, u16 *src, int len)
+{
+ int i;
+
+ for (i = 0; i < len / 2; i++)
+ target[i] = src[i];
+
+ return (char *)target;
+}
+
+static int fsl_ata_scsiop_inquiry(struct ahci_uc_priv *uc_priv,
+ struct scsi_cmd *pccb,
+ fsl_sata_t *sata)
+{
+ u8 port;
+ u16 *idbuf;
+
+ ALLOC_CACHE_ALIGN_BUFFER(u16, tmpid, ATA_ID_WORDS);
+
+ /* Clean ccb data buffer */
+ memset(pccb->pdata, 0, pccb->datalen);
+
+ if (pccb->datalen <= 35)
+ return 0;
+
+ /* Read id from sata */
+ port = pccb->target;
+
+ fsl_sata_identify(sata, (u16 *)tmpid);
+
+ if (!uc_priv->ataid[port]) {
+ uc_priv->ataid[port] = malloc(ATA_ID_WORDS * 2);
+ if (!uc_priv->ataid[port]) {
+ printf("%s: No memory for ataid[port]\n", __func__);
+ return -ENOMEM;
+ }
+ }
+
+ idbuf = uc_priv->ataid[port];
+
+ memcpy(idbuf, tmpid, ATA_ID_WORDS * 2);
+
+ memcpy(&pccb->pdata[8], "ATA ", 8);
+ fsl_ata_id_strcpy((u16 *)&pccb->pdata[16], &idbuf[ATA_ID_PROD], 16);
+ fsl_ata_id_strcpy((u16 *)&pccb->pdata[32], &idbuf[ATA_ID_FW_REV], 4);
+
+ sata_getinfo(sata, (u16 *)idbuf);
+#ifdef DEBUG
+ ata_dump_id(idbuf);
+#endif
+ return 0;
+}
+
+/*
+ * SCSI READ CAPACITY10 command operation.
+ */
+static int fsl_ata_scsiop_read_capacity10(struct ahci_uc_priv *uc_priv,
+ struct scsi_cmd *pccb)
+{
+ u32 cap;
+ u64 cap64;
+ u32 block_size;
+
+ if (!uc_priv->ataid[pccb->target]) {
+ printf("scsi_ahci: SCSI READ CAPACITY10 command failure.");
+ printf("\tNo ATA info!\n");
+ printf("\tPlease run SCSI command INQUIRY first!\n");
+ return -EPERM;
+ }
+
+ cap64 = ata_id_n_sectors(uc_priv->ataid[pccb->target]);
+ if (cap64 > 0x100000000ULL)
+ cap64 = 0xffffffff;
+
+ cap = cpu_to_be32(cap64);
+ memcpy(pccb->pdata, &cap, sizeof(cap));
+
+ block_size = cpu_to_be32((u32)512);
+ memcpy(&pccb->pdata[4], &block_size, 4);
+
+ return 0;
+}
+
+/*
+ * SCSI READ CAPACITY16 command operation.
+ */
+static int fsl_ata_scsiop_read_capacity16(struct ahci_uc_priv *uc_priv,
+ struct scsi_cmd *pccb)
+{
+ u64 cap;
+ u64 block_size;
+
+ if (!uc_priv->ataid[pccb->target]) {
+ printf("scsi_ahci: SCSI READ CAPACITY16 command failure.");
+ printf("\tNo ATA info!\n");
+ printf("\tPlease run SCSI command INQUIRY first!\n");
+ return -EPERM;
+ }
+
+ cap = ata_id_n_sectors(uc_priv->ataid[pccb->target]);
+ cap = cpu_to_be64(cap);
+ memcpy(pccb->pdata, &cap, sizeof(cap));
+
+ block_size = cpu_to_be64((u64)512);
+ memcpy(&pccb->pdata[8], &block_size, 8);
+
+ return 0;
+}
+
+/*
+ * SCSI TEST UNIT READY command operation.
+ */
+static int fsl_ata_scsiop_test_unit_ready(struct ahci_uc_priv *uc_priv,
+ struct scsi_cmd *pccb)
+{
+ return (uc_priv->ataid[pccb->target]) ? 0 : -EPERM;
+}
+
+static int fsl_ahci_scsi_exec(struct udevice *dev, struct scsi_cmd *pccb)
+{
+ struct ahci_uc_priv *uc_priv = dev_get_uclass_priv(dev->parent);
+ struct fsl_ahci_priv *priv = dev_get_priv(dev->parent);
+ fsl_sata_t *sata = priv->fsl_sata;
+ int ret;
+
+ switch (pccb->cmd[0]) {
+ case SCSI_READ16:
+ case SCSI_READ10:
+ ret = fsl_scsi_exec(sata, pccb, 0);
+ break;
+ case SCSI_WRITE10:
+ ret = fsl_scsi_exec(sata, pccb, 1);
+ break;
+ case SCSI_RD_CAPAC10:
+ ret = fsl_ata_scsiop_read_capacity10(uc_priv, pccb);
+ break;
+ case SCSI_RD_CAPAC16:
+ ret = fsl_ata_scsiop_read_capacity16(uc_priv, pccb);
+ break;
+ case SCSI_TST_U_RDY:
+ ret = fsl_ata_scsiop_test_unit_ready(uc_priv, pccb);
+ break;
+ case SCSI_INQUIRY:
+ ret = fsl_ata_scsiop_inquiry(uc_priv, pccb, sata);
+ break;
+ default:
+ printf("Unsupport SCSI command 0x%02x\n", pccb->cmd[0]);
+ return -ENOTSUPP;
+ }
+
+ if (ret) {
+ debug("SCSI command 0x%02x ret errno %d\n", pccb->cmd[0], ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int fsl_ahci_probe(struct udevice *dev)
+{
+ struct fsl_ahci_priv *priv = dev_get_priv(dev);
+ struct udevice *child_dev;
+ struct scsi_platdata *uc_plat;
+
+ device_find_first_child(dev, &child_dev);
+ if (!child_dev)
+ return -ENODEV;
+ uc_plat = dev_get_uclass_platdata(child_dev);
+ uc_plat->base = priv->base;
+ uc_plat->max_lun = 1;
+ uc_plat->max_id = 1;
+
+ return init_sata(priv);
+}
+
+struct scsi_ops fsl_scsi_ops = {
+ .exec = fsl_ahci_scsi_exec,
+};
+
+static const struct udevice_id fsl_ahci_ids[] = {
+ { .compatible = "fsl,pq-sata-v2" },
+ { }
+};
+
+U_BOOT_DRIVER(fsl_ahci_scsi) = {
+ .name = "fsl_ahci_scsi",
+ .id = UCLASS_SCSI,
+ .ops = &fsl_scsi_ops,
+};
+
+U_BOOT_DRIVER(fsl_ahci) = {
+ .name = "fsl_ahci",
+ .id = UCLASS_AHCI,
+ .of_match = fsl_ahci_ids,
+ .bind = fsl_ahci_bind,
+ .ofdata_to_platdata = fsl_ahci_ofdata_to_platdata,
+ .probe = fsl_ahci_probe,
+ .priv_auto_alloc_size = sizeof(struct fsl_ahci_priv),
+};
diff --git a/drivers/ata/fsl_sata.h b/drivers/ata/fsl_sata.h
index 1e2da10b02..a4ee83d187 100644
--- a/drivers/ata/fsl_sata.h
+++ b/drivers/ata/fsl_sata.h
@@ -312,6 +312,7 @@ typedef struct fsl_sata {
int wcache;
int flush;
int flush_ext;
+ u32 dma_flag;
} fsl_sata_t;
#define READ_CMD 0
diff --git a/drivers/clk/clk_stm32mp1.c b/drivers/clk/clk_stm32mp1.c
index 24859fd054..6272b00b9e 100644
--- a/drivers/clk/clk_stm32mp1.c
+++ b/drivers/clk/clk_stm32mp1.c
@@ -1448,6 +1448,71 @@ static void pll_csg(struct stm32mp1_clk_priv *priv, int pll_id, u32 *csg)
setbits_le32(priv->base + pll[pll_id].pllxcr, RCC_PLLNCR_SSCG_CTRL);
}
+static __maybe_unused int pll_set_rate(struct udevice *dev,
+ int pll_id,
+ int div_id,
+ unsigned long clk_rate)
+{
+ struct stm32mp1_clk_priv *priv = dev_get_priv(dev);
+ unsigned int pllcfg[PLLCFG_NB];
+ ofnode plloff;
+ char name[12];
+ const struct stm32mp1_clk_pll *pll = priv->data->pll;
+ enum stm32mp1_plltype type = pll[pll_id].plltype;
+ int divm, divn, divy;
+ int ret;
+ ulong fck_ref;
+ u32 fracv;
+ u64 value;
+
+ if (div_id > _DIV_NB)
+ return -EINVAL;
+
+ sprintf(name, "st,pll@%d", pll_id);
+ plloff = dev_read_subnode(dev, name);
+ if (!ofnode_valid(plloff))
+ return -FDT_ERR_NOTFOUND;
+
+ ret = ofnode_read_u32_array(plloff, "cfg",
+ pllcfg, PLLCFG_NB);
+ if (ret < 0)
+ return -FDT_ERR_NOTFOUND;
+
+ fck_ref = pll_get_fref_ck(priv, pll_id);
+
+ divm = pllcfg[PLLCFG_M];
+ /* select output divider = 0: for _DIV_P, 1:_DIV_Q 2:_DIV_R */
+ divy = pllcfg[PLLCFG_P + div_id];
+
+ /* For: PLL1 & PLL2 => VCO is * 2 but ck_pll_y is also / 2
+ * So same final result than PLL2 et 4
+ * with FRACV
+ * Fck_pll_y = Fck_ref * ((DIVN + 1) + FRACV / 2^13)
+ * / (DIVy + 1) * (DIVM + 1)
+ * value = (DIVN + 1) * 2^13 + FRACV / 2^13
+ * = Fck_pll_y (DIVy + 1) * (DIVM + 1) * 2^13 / Fck_ref
+ */
+ value = ((u64)clk_rate * (divy + 1) * (divm + 1)) << 13;
+ value = lldiv(value, fck_ref);
+
+ divn = (value >> 13) - 1;
+ if (divn < DIVN_MIN ||
+ divn > stm32mp1_pll[type].divn_max) {
+ pr_err("divn invalid = %d", divn);
+ return -EINVAL;
+ }
+ fracv = value - ((divn + 1) << 13);
+ pllcfg[PLLCFG_N] = divn;
+
+ /* reconfigure PLL */
+ pll_stop(priv, pll_id);
+ pll_config(priv, pll_id, pllcfg, fracv);
+ pll_start(priv, pll_id);
+ pll_output(priv, pll_id, pllcfg[PLLCFG_O]);
+
+ return 0;
+}
+
static int set_clksrc(struct stm32mp1_clk_priv *priv, unsigned int clksrc)
{
u32 address = priv->base + (clksrc >> 4);
@@ -1820,6 +1885,11 @@ static ulong stm32mp1_clk_set_rate(struct clk *clk, unsigned long clk_rate)
int p;
switch (clk->id) {
+#if defined(STM32MP1_CLOCK_TREE_INIT) && \
+ defined(CONFIG_STM32MP1_DDR_INTERACTIVE)
+ case DDRPHYC:
+ break;
+#endif
case LTDC_PX:
case DSI_PX:
break;
@@ -1833,6 +1903,19 @@ static ulong stm32mp1_clk_set_rate(struct clk *clk, unsigned long clk_rate)
return -EINVAL;
switch (p) {
+#if defined(STM32MP1_CLOCK_TREE_INIT) && \
+ defined(CONFIG_STM32MP1_DDR_INTERACTIVE)
+ case _PLL2_R: /* DDRPHYC */
+ {
+ /* only for change DDR clock in interactive mode */
+ ulong result;
+
+ set_clksrc(priv, CLK_AXI_HSI);
+ result = pll_set_rate(clk->dev, _PLL2, _DIV_R, clk_rate);
+ set_clksrc(priv, CLK_AXI_PLL2P);
+ return result;
+ }
+#endif
case _PLL4_Q:
/* for LTDC_PX and DSI_PX case */
return pll_set_output_rate(clk->dev, _PLL4, _DIV_Q, clk_rate);
diff --git a/drivers/i2c/stm32f7_i2c.c b/drivers/i2c/stm32f7_i2c.c
index 3872364d6b..50c4fd0de2 100644
--- a/drivers/i2c/stm32f7_i2c.c
+++ b/drivers/i2c/stm32f7_i2c.c
@@ -500,7 +500,7 @@ static int stm32_i2c_compute_solutions(struct stm32_i2c_setup *setup,
af_delay_max = setup->analog_filter ?
STM32_I2C_ANALOG_FILTER_DELAY_MAX : 0;
- sdadel_min = setup->fall_time - i2c_specs[setup->speed].hddat_min -
+ sdadel_min = i2c_specs[setup->speed].hddat_min + setup->fall_time -
af_delay_min - (setup->dnf + 3) * i2cclk;
sdadel_max = i2c_specs[setup->speed].vddat_max - setup->rise_time -
@@ -540,8 +540,12 @@ static int stm32_i2c_compute_solutions(struct stm32_i2c_setup *setup,
p_prev = p;
list_add_tail(&v->node, solutions);
+ break;
}
}
+
+ if (p_prev == p)
+ break;
}
}
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index 377b2673a3..672691fa6a 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -1435,7 +1435,9 @@ void fdt_fixup_esdhc(void *blob, bd_t *bd)
#endif
#if CONFIG_IS_ENABLED(DM_MMC)
+#ifndef CONFIG_PPC
#include <asm/arch/clock.h>
+#endif
__weak void init_clk_usdhc(u32 index)
{
}
@@ -1460,8 +1462,11 @@ static int fsl_esdhc_probe(struct udevice *dev)
addr = dev_read_addr(dev);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
-
+#ifdef CONFIG_PPC
+ priv->esdhc_regs = (struct fsl_esdhc *)lower_32_bits(addr);
+#else
priv->esdhc_regs = (struct fsl_esdhc *)addr;
+#endif
priv->dev = dev;
priv->mode = -1;
if (data) {
@@ -1568,7 +1573,11 @@ static int fsl_esdhc_probe(struct udevice *dev)
priv->sdhc_clk = clk_get_rate(&priv->per_clk);
} else {
+#ifndef CONFIG_PPC
priv->sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK + dev->seq);
+#else
+ priv->sdhc_clk = gd->arch.sdhc_clk;
+#endif
if (priv->sdhc_clk <= 0) {
dev_err(dev, "Unable to get clk for %s\n", dev->name);
return -EINVAL;
diff --git a/drivers/ram/stm32mp1/Kconfig b/drivers/ram/stm32mp1/Kconfig
index b9c816662c..2fd8c7b7e3 100644
--- a/drivers/ram/stm32mp1/Kconfig
+++ b/drivers/ram/stm32mp1/Kconfig
@@ -10,3 +10,40 @@ config STM32MP1_DDR
family: support for LPDDR2, LPDDR3 and DDR3
the SDRAM parameters for controleur and phy need to be provided
in device tree (computed by DDR tuning tools)
+
+config STM32MP1_DDR_INTERACTIVE
+ bool "STM32MP1 DDR driver : interactive support"
+ depends on STM32MP1_DDR
+ help
+ activate interactive support in STM32MP1 DDR controller driver
+ used for DDR tuning tools
+ to enter in intercative mode type 'd' during SPL DDR driver
+ initialisation
+
+config STM32MP1_DDR_INTERACTIVE_FORCE
+ bool "STM32MP1 DDR driver : force interactive mode"
+ depends on STM32MP1_DDR_INTERACTIVE
+ default n
+ help
+ force interactive mode in STM32MP1 DDR controller driver
+ skip the polling of character 'd' in console
+ useful when SPL is loaded in sysram
+ directly by programmer
+
+config STM32MP1_DDR_TESTS
+ bool "STM32MP1 DDR driver : tests support"
+ depends on STM32MP1_DDR_INTERACTIVE
+ default y
+ help
+ activate test support for interactive support in
+ STM32MP1 DDR controller driver: command test
+
+config STM32MP1_DDR_TUNING
+ bool "STM32MP1 DDR driver : support of tuning"
+ depends on STM32MP1_DDR_INTERACTIVE
+ default y
+ help
+ activate tuning command in STM32MP1 DDR interactive mode
+ used for DDR tuning tools
+ - DQ Deskew algorithm
+ - DQS Trimming
diff --git a/drivers/ram/stm32mp1/Makefile b/drivers/ram/stm32mp1/Makefile
index 79eb028fab..e1e9135603 100644
--- a/drivers/ram/stm32mp1/Makefile
+++ b/drivers/ram/stm32mp1/Makefile
@@ -5,3 +5,11 @@
obj-y += stm32mp1_ram.o
obj-y += stm32mp1_ddr.o
+
+obj-$(CONFIG_STM32MP1_DDR_INTERACTIVE) += stm32mp1_interactive.o
+obj-$(CONFIG_STM32MP1_DDR_TESTS) += stm32mp1_tests.o
+obj-$(CONFIG_STM32MP1_DDR_TUNING) += stm32mp1_tuning.o
+
+ifneq ($(DDR_INTERACTIVE),)
+CFLAGS_stm32mp1_interactive.o += -DCONFIG_STM32MP1_DDR_INTERACTIVE_FORCE=y
+endif
diff --git a/drivers/ram/stm32mp1/stm32mp1_ddr.c b/drivers/ram/stm32mp1/stm32mp1_ddr.c
index c7c3ba70a4..d765a46f7c 100644
--- a/drivers/ram/stm32mp1/stm32mp1_ddr.c
+++ b/drivers/ram/stm32mp1/stm32mp1_ddr.c
@@ -41,8 +41,32 @@ struct reg_desc {
offsetof(struct stm32mp1_ddrphy, x),\
offsetof(struct y, x)}
+#define DDR_REG_DYN(x) \
+ {#x,\
+ offsetof(struct stm32mp1_ddrctl, x),\
+ INVALID_OFFSET}
+
+#define DDRPHY_REG_DYN(x) \
+ {#x,\
+ offsetof(struct stm32mp1_ddrphy, x),\
+ INVALID_OFFSET}
+
+/***********************************************************
+ * PARAMETERS: value get from device tree :
+ * size / order need to be aligned with binding
+ * modification NOT ALLOWED !!!
+ ***********************************************************/
+#define DDRCTL_REG_REG_SIZE 25 /* st,ctl-reg */
+#define DDRCTL_REG_TIMING_SIZE 12 /* st,ctl-timing */
+#define DDRCTL_REG_MAP_SIZE 9 /* st,ctl-map */
+#define DDRCTL_REG_PERF_SIZE 17 /* st,ctl-perf */
+
+#define DDRPHY_REG_REG_SIZE 11 /* st,phy-reg */
+#define DDRPHY_REG_TIMING_SIZE 10 /* st,phy-timing */
+#define DDRPHY_REG_CAL_SIZE 12 /* st,phy-cal */
+
#define DDRCTL_REG_REG(x) DDRCTL_REG(x, stm32mp1_ddrctrl_reg)
-static const struct reg_desc ddr_reg[] = {
+static const struct reg_desc ddr_reg[DDRCTL_REG_REG_SIZE] = {
DDRCTL_REG_REG(mstr),
DDRCTL_REG_REG(mrctrl0),
DDRCTL_REG_REG(mrctrl1),
@@ -71,7 +95,7 @@ static const struct reg_desc ddr_reg[] = {
};
#define DDRCTL_REG_TIMING(x) DDRCTL_REG(x, stm32mp1_ddrctrl_timing)
-static const struct reg_desc ddr_timing[] = {
+static const struct reg_desc ddr_timing[DDRCTL_REG_TIMING_SIZE] = {
DDRCTL_REG_TIMING(rfshtmg),
DDRCTL_REG_TIMING(dramtmg0),
DDRCTL_REG_TIMING(dramtmg1),
@@ -87,7 +111,7 @@ static const struct reg_desc ddr_timing[] = {
};
#define DDRCTL_REG_MAP(x) DDRCTL_REG(x, stm32mp1_ddrctrl_map)
-static const struct reg_desc ddr_map[] = {
+static const struct reg_desc ddr_map[DDRCTL_REG_MAP_SIZE] = {
DDRCTL_REG_MAP(addrmap1),
DDRCTL_REG_MAP(addrmap2),
DDRCTL_REG_MAP(addrmap3),
@@ -100,7 +124,7 @@ static const struct reg_desc ddr_map[] = {
};
#define DDRCTL_REG_PERF(x) DDRCTL_REG(x, stm32mp1_ddrctrl_perf)
-static const struct reg_desc ddr_perf[] = {
+static const struct reg_desc ddr_perf[DDRCTL_REG_PERF_SIZE] = {
DDRCTL_REG_PERF(sched),
DDRCTL_REG_PERF(sched1),
DDRCTL_REG_PERF(perfhpr1),
@@ -121,7 +145,7 @@ static const struct reg_desc ddr_perf[] = {
};
#define DDRPHY_REG_REG(x) DDRPHY_REG(x, stm32mp1_ddrphy_reg)
-static const struct reg_desc ddrphy_reg[] = {
+static const struct reg_desc ddrphy_reg[DDRPHY_REG_REG_SIZE] = {
DDRPHY_REG_REG(pgcr),
DDRPHY_REG_REG(aciocr),
DDRPHY_REG_REG(dxccr),
@@ -136,7 +160,7 @@ static const struct reg_desc ddrphy_reg[] = {
};
#define DDRPHY_REG_TIMING(x) DDRPHY_REG(x, stm32mp1_ddrphy_timing)
-static const struct reg_desc ddrphy_timing[] = {
+static const struct reg_desc ddrphy_timing[DDRPHY_REG_TIMING_SIZE] = {
DDRPHY_REG_TIMING(ptr0),
DDRPHY_REG_TIMING(ptr1),
DDRPHY_REG_TIMING(ptr2),
@@ -150,7 +174,7 @@ static const struct reg_desc ddrphy_timing[] = {
};
#define DDRPHY_REG_CAL(x) DDRPHY_REG(x, stm32mp1_ddrphy_cal)
-static const struct reg_desc ddrphy_cal[] = {
+static const struct reg_desc ddrphy_cal[DDRPHY_REG_CAL_SIZE] = {
DDRPHY_REG_CAL(dx0dllcr),
DDRPHY_REG_CAL(dx0dqtr),
DDRPHY_REG_CAL(dx0dqstr),
@@ -165,6 +189,45 @@ static const struct reg_desc ddrphy_cal[] = {
DDRPHY_REG_CAL(dx3dqstr),
};
+/**************************************************************
+ * DYNAMIC REGISTERS: only used for debug purpose (read/modify)
+ **************************************************************/
+#ifdef CONFIG_STM32MP1_DDR_INTERACTIVE
+static const struct reg_desc ddr_dyn[] = {
+ DDR_REG_DYN(stat),
+ DDR_REG_DYN(init0),
+ DDR_REG_DYN(dfimisc),
+ DDR_REG_DYN(dfistat),
+ DDR_REG_DYN(swctl),
+ DDR_REG_DYN(swstat),
+ DDR_REG_DYN(pctrl_0),
+ DDR_REG_DYN(pctrl_1),
+};
+
+#define DDR_REG_DYN_SIZE ARRAY_SIZE(ddr_dyn)
+
+static const struct reg_desc ddrphy_dyn[] = {
+ DDRPHY_REG_DYN(pir),
+ DDRPHY_REG_DYN(pgsr),
+ DDRPHY_REG_DYN(zq0sr0),
+ DDRPHY_REG_DYN(zq0sr1),
+ DDRPHY_REG_DYN(dx0gsr0),
+ DDRPHY_REG_DYN(dx0gsr1),
+ DDRPHY_REG_DYN(dx1gsr0),
+ DDRPHY_REG_DYN(dx1gsr1),
+ DDRPHY_REG_DYN(dx2gsr0),
+ DDRPHY_REG_DYN(dx2gsr1),
+ DDRPHY_REG_DYN(dx3gsr0),
+ DDRPHY_REG_DYN(dx3gsr1),
+};
+
+#define DDRPHY_REG_DYN_SIZE ARRAY_SIZE(ddrphy_dyn)
+
+#endif
+
+/*****************************************************************
+ * REGISTERS ARRAY: used to parse device tree and interactive mode
+ *****************************************************************/
enum reg_type {
REG_REG,
REG_TIMING,
@@ -173,6 +236,13 @@ enum reg_type {
REGPHY_REG,
REGPHY_TIMING,
REGPHY_CAL,
+#ifdef CONFIG_STM32MP1_DDR_INTERACTIVE
+/* dynamic registers => managed in driver or not changed,
+ * can be dumped in interactive mode
+ */
+ REG_DYN,
+ REGPHY_DYN,
+#endif
REG_TYPE_NB
};
@@ -193,19 +263,26 @@ struct ddr_reg_info {
const struct ddr_reg_info ddr_registers[REG_TYPE_NB] = {
[REG_REG] = {
- "static", ddr_reg, ARRAY_SIZE(ddr_reg), DDR_BASE},
+ "static", ddr_reg, DDRCTL_REG_REG_SIZE, DDR_BASE},
[REG_TIMING] = {
- "timing", ddr_timing, ARRAY_SIZE(ddr_timing), DDR_BASE},
+ "timing", ddr_timing, DDRCTL_REG_TIMING_SIZE, DDR_BASE},
[REG_PERF] = {
- "perf", ddr_perf, ARRAY_SIZE(ddr_perf), DDR_BASE},
+ "perf", ddr_perf, DDRCTL_REG_PERF_SIZE, DDR_BASE},
[REG_MAP] = {
- "map", ddr_map, ARRAY_SIZE(ddr_map), DDR_BASE},
+ "map", ddr_map, DDRCTL_REG_MAP_SIZE, DDR_BASE},
[REGPHY_REG] = {
- "static", ddrphy_reg, ARRAY_SIZE(ddrphy_reg), DDRPHY_BASE},
+ "static", ddrphy_reg, DDRPHY_REG_REG_SIZE, DDRPHY_BASE},
[REGPHY_TIMING] = {
- "timing", ddrphy_timing, ARRAY_SIZE(ddrphy_timing), DDRPHY_BASE},
+ "timing", ddrphy_timing, DDRPHY_REG_TIMING_SIZE, DDRPHY_BASE},
[REGPHY_CAL] = {
- "cal", ddrphy_cal, ARRAY_SIZE(ddrphy_cal), DDRPHY_BASE},
+ "cal", ddrphy_cal, DDRPHY_REG_CAL_SIZE, DDRPHY_BASE},
+#ifdef CONFIG_STM32MP1_DDR_INTERACTIVE
+[REG_DYN] = {
+ "dyn", ddr_dyn, DDR_REG_DYN_SIZE, DDR_BASE},
+[REGPHY_DYN] = {
+ "dyn", ddrphy_dyn, DDRPHY_REG_DYN_SIZE, DDRPHY_BASE},
+#endif
+
};
const char *base_name[] = {
@@ -246,6 +323,231 @@ static void set_reg(const struct ddr_info *priv,
}
}
+#ifdef CONFIG_STM32MP1_DDR_INTERACTIVE
+static void stm32mp1_dump_reg_desc(u32 base_addr, const struct reg_desc *desc)
+{
+ unsigned int *ptr;
+
+ ptr = (unsigned int *)(base_addr + desc->offset);
+ printf("%s= 0x%08x\n", desc->name, readl(ptr));
+}
+
+static void stm32mp1_dump_param_desc(u32 par_addr, const struct reg_desc *desc)
+{
+ unsigned int *ptr;
+
+ ptr = (unsigned int *)(par_addr + desc->par_offset);
+ printf("%s= 0x%08x\n", desc->name, readl(ptr));
+}
+
+static const struct reg_desc *found_reg(const char *name, enum reg_type *type)
+{
+ unsigned int i, j;
+ const struct reg_desc *desc;
+
+ for (i = 0; i < ARRAY_SIZE(ddr_registers); i++) {
+ desc = ddr_registers[i].desc;
+ for (j = 0; j < ddr_registers[i].size; j++) {
+ if (strcmp(name, desc[j].name) == 0) {
+ *type = i;
+ return &desc[j];
+ }
+ }
+ }
+ *type = REG_TYPE_NB;
+ return NULL;
+}
+
+int stm32mp1_dump_reg(const struct ddr_info *priv,
+ const char *name)
+{
+ unsigned int i, j;
+ const struct reg_desc *desc;
+ u32 base_addr;
+ enum base_type p_base;
+ enum reg_type type;
+ const char *p_name;
+ enum base_type filter = NONE_BASE;
+ int result = -1;
+
+ if (name) {
+ if (strcmp(name, base_name[DDR_BASE]) == 0)
+ filter = DDR_BASE;
+ else if (strcmp(name, base_name[DDRPHY_BASE]) == 0)
+ filter = DDRPHY_BASE;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(ddr_registers); i++) {
+ p_base = ddr_registers[i].base;
+ p_name = ddr_registers[i].name;
+ if (!name || (filter == p_base || !strcmp(name, p_name))) {
+ result = 0;
+ desc = ddr_registers[i].desc;
+ base_addr = get_base_addr(priv, p_base);
+ printf("==%s.%s==\n", base_name[p_base], p_name);
+ for (j = 0; j < ddr_registers[i].size; j++)
+ stm32mp1_dump_reg_desc(base_addr, &desc[j]);
+ }
+ }
+ if (result) {
+ desc = found_reg(name, &type);
+ if (desc) {
+ p_base = ddr_registers[type].base;
+ base_addr = get_base_addr(priv, p_base);
+ stm32mp1_dump_reg_desc(base_addr, desc);
+ result = 0;
+ }
+ }
+ return result;
+}
+
+void stm32mp1_edit_reg(const struct ddr_info *priv,
+ char *name, char *string)
+{
+ unsigned long *ptr, value;
+ enum reg_type type;
+ enum base_type base;
+ const struct reg_desc *desc;
+ u32 base_addr;
+
+ desc = found_reg(name, &type);
+
+ if (!desc) {
+ printf("%s not found\n", name);
+ return;
+ }
+ if (strict_strtoul(string, 16, &value) < 0) {
+ printf("invalid value %s\n", string);
+ return;
+ }
+ base = ddr_registers[type].base;
+ base_addr = get_base_addr(priv, base);
+ ptr = (unsigned long *)(base_addr + desc->offset);
+ writel(value, ptr);
+ printf("%s= 0x%08x\n", desc->name, readl(ptr));
+}
+
+static u32 get_par_addr(const struct stm32mp1_ddr_config *config,
+ enum reg_type type)
+{
+ u32 par_addr = 0x0;
+
+ switch (type) {
+ case REG_REG:
+ par_addr = (u32)&config->c_reg;
+ break;
+ case REG_TIMING:
+ par_addr = (u32)&config->c_timing;
+ break;
+ case REG_PERF:
+ par_addr = (u32)&config->c_perf;
+ break;
+ case REG_MAP:
+ par_addr = (u32)&config->c_map;
+ break;
+ case REGPHY_REG:
+ par_addr = (u32)&config->p_reg;
+ break;
+ case REGPHY_TIMING:
+ par_addr = (u32)&config->p_timing;
+ break;
+ case REGPHY_CAL:
+ par_addr = (u32)&config->p_cal;
+ break;
+ case REG_DYN:
+ case REGPHY_DYN:
+ case REG_TYPE_NB:
+ par_addr = (u32)NULL;
+ break;
+ }
+
+ return par_addr;
+}
+
+int stm32mp1_dump_param(const struct stm32mp1_ddr_config *config,
+ const char *name)
+{
+ unsigned int i, j;
+ const struct reg_desc *desc;
+ u32 par_addr;
+ enum base_type p_base;
+ enum reg_type type;
+ const char *p_name;
+ enum base_type filter = NONE_BASE;
+ int result = -EINVAL;
+
+ if (name) {
+ if (strcmp(name, base_name[DDR_BASE]) == 0)
+ filter = DDR_BASE;
+ else if (strcmp(name, base_name[DDRPHY_BASE]) == 0)
+ filter = DDRPHY_BASE;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(ddr_registers); i++) {
+ par_addr = get_par_addr(config, i);
+ if (!par_addr)
+ continue;
+ p_base = ddr_registers[i].base;
+ p_name = ddr_registers[i].name;
+ if (!name || (filter == p_base || !strcmp(name, p_name))) {
+ result = 0;
+ desc = ddr_registers[i].desc;
+ printf("==%s.%s==\n", base_name[p_base], p_name);
+ for (j = 0; j < ddr_registers[i].size; j++)
+ stm32mp1_dump_param_desc(par_addr, &desc[j]);
+ }
+ }
+ if (result) {
+ desc = found_reg(name, &type);
+ if (desc) {
+ par_addr = get_par_addr(config, type);
+ if (par_addr) {
+ stm32mp1_dump_param_desc(par_addr, desc);
+ result = 0;
+ }
+ }
+ }
+ return result;
+}
+
+void stm32mp1_edit_param(const struct stm32mp1_ddr_config *config,
+ char *name, char *string)
+{
+ unsigned long *ptr, value;
+ enum reg_type type;
+ const struct reg_desc *desc;
+ u32 par_addr;
+
+ desc = found_reg(name, &type);
+ if (!desc) {
+ printf("%s not found\n", name);
+ return;
+ }
+ if (strict_strtoul(string, 16, &value) < 0) {
+ printf("invalid value %s\n", string);
+ return;
+ }
+ par_addr = get_par_addr(config, type);
+ if (!par_addr) {
+ printf("no parameter %s\n", name);
+ return;
+ }
+ ptr = (unsigned long *)(par_addr + desc->par_offset);
+ writel(value, ptr);
+ printf("%s= 0x%08x\n", desc->name, readl(ptr));
+}
+#endif
+
+__weak bool stm32mp1_ddr_interactive(void *priv,
+ enum stm32mp1_ddr_interact_step step,
+ const struct stm32mp1_ddr_config *config)
+{
+ return false;
+}
+
+#define INTERACTIVE(step)\
+ stm32mp1_ddr_interactive(priv, step, config)
+
static void ddrphy_idone_wait(struct stm32mp1_ddrphy *phy)
{
u32 pgsr;
@@ -312,7 +614,7 @@ static void wait_operating_mode(struct ddr_info *priv, int mode)
/* self-refresh due to software => check also STAT.selfref_type */
if (mode == DDRCTRL_STAT_OPERATING_MODE_SR) {
mask |= DDRCTRL_STAT_SELFREF_TYPE_MASK;
- stat |= DDRCTRL_STAT_SELFREF_TYPE_SR;
+ val |= DDRCTRL_STAT_SELFREF_TYPE_SR;
} else if (mode == DDRCTRL_STAT_OPERATING_MODE_NORMAL) {
/* normal mode: handle also automatic self refresh */
mask2 = DDRCTRL_STAT_OPERATING_MODE_MASK |
@@ -355,7 +657,7 @@ void stm32mp1_refresh_restore(struct stm32mp1_ddrctl *ctl,
}
/* board-specific DDR power initializations. */
-__weak int board_ddr_power_init(void)
+__weak int board_ddr_power_init(enum ddr_type ddr_type)
{
return 0;
}
@@ -365,15 +667,21 @@ void stm32mp1_ddr_init(struct ddr_info *priv,
const struct stm32mp1_ddr_config *config)
{
u32 pir;
- int ret;
+ int ret = -EINVAL;
- ret = board_ddr_power_init();
+ if (config->c_reg.mstr & DDRCTRL_MSTR_DDR3)
+ ret = board_ddr_power_init(STM32MP_DDR3);
+ else if (config->c_reg.mstr & DDRCTRL_MSTR_LPDDR2)
+ ret = board_ddr_power_init(STM32MP_LPDDR2);
+ else if (config->c_reg.mstr & DDRCTRL_MSTR_LPDDR3)
+ ret = board_ddr_power_init(STM32MP_LPDDR3);
if (ret)
panic("ddr power init failed\n");
+start:
debug("name = %s\n", config->info.name);
- debug("speed = %d MHz\n", config->info.speed);
+ debug("speed = %d kHz\n", config->info.speed);
debug("size = 0x%x\n", config->info.size);
/*
* 1. Program the DWC_ddr_umctl2 registers
@@ -389,7 +697,7 @@ void stm32mp1_ddr_init(struct ddr_info *priv,
/* 1.2. start CLOCK */
if (stm32mp1_ddr_clk_enable(priv, config->info.speed))
- panic("invalid DRAM clock : %d MHz\n",
+ panic("invalid DRAM clock : %d kHz\n",
config->info.speed);
/* 1.3. deassert reset */
@@ -401,11 +709,12 @@ void stm32mp1_ddr_init(struct ddr_info *priv,
*/
clrbits_le32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DDRCAPBRST);
-/* 1.4. wait 4 cycles for synchronization */
- asm(" nop");
- asm(" nop");
- asm(" nop");
- asm(" nop");
+/* 1.4. wait 128 cycles to permit initialization of end logic */
+ udelay(2);
+ /* for PCLK = 133MHz => 1 us is enough, 2 to allow lower frequency */
+
+ if (INTERACTIVE(STEP_DDR_RESET))
+ goto start;
/* 1.5. initialize registers ddr_umctl2 */
/* Stop uMCTL2 before PHY is ready */
@@ -424,6 +733,9 @@ void stm32mp1_ddr_init(struct ddr_info *priv,
set_reg(priv, REG_PERF, &config->c_perf);
+ if (INTERACTIVE(STEP_CTL_INIT))
+ goto start;
+
/* 2. deassert reset signal core_ddrc_rstn, aresetn and presetn */
clrbits_le32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DDRCORERST);
clrbits_le32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DDRCAXIRST);
@@ -436,6 +748,9 @@ void stm32mp1_ddr_init(struct ddr_info *priv,
set_reg(priv, REGPHY_TIMING, &config->p_timing);
set_reg(priv, REGPHY_CAL, &config->p_cal);
+ if (INTERACTIVE(STEP_PHY_INIT))
+ goto start;
+
/* 4. Monitor PHY init status by polling PUBL register PGSR.IDONE
* Perform DDR PHY DRAM initialization and Gate Training Evaluation
*/
@@ -492,4 +807,7 @@ void stm32mp1_ddr_init(struct ddr_info *priv,
/* enable uMCTL2 AXI port 0 and 1 */
setbits_le32(&priv->ctl->pctrl_0, DDRCTRL_PCTRL_N_PORT_EN);
setbits_le32(&priv->ctl->pctrl_1, DDRCTRL_PCTRL_N_PORT_EN);
+
+ if (INTERACTIVE(STEP_DDR_READY))
+ goto start;
}
diff --git a/drivers/ram/stm32mp1/stm32mp1_ddr.h b/drivers/ram/stm32mp1/stm32mp1_ddr.h
index 3cd0161299..a8eed89e3c 100644
--- a/drivers/ram/stm32mp1/stm32mp1_ddr.h
+++ b/drivers/ram/stm32mp1/stm32mp1_ddr.h
@@ -157,7 +157,7 @@ struct stm32mp1_ddrphy_cal {
struct stm32mp1_ddr_info {
const char *name;
- u16 speed; /* in MHZ */
+ u32 speed; /* in kHZ */
u32 size; /* memory size in byte = col * row * width */
};
@@ -172,7 +172,7 @@ struct stm32mp1_ddr_config {
struct stm32mp1_ddrphy_cal p_cal;
};
-int stm32mp1_ddr_clk_enable(struct ddr_info *priv, u16 mem_speed);
+int stm32mp1_ddr_clk_enable(struct ddr_info *priv, u32 mem_speed);
void stm32mp1_ddrphy_init(struct stm32mp1_ddrphy *phy, u32 pir);
void stm32mp1_refresh_disable(struct stm32mp1_ddrctl *ctl);
void stm32mp1_refresh_restore(struct stm32mp1_ddrctl *ctl,
diff --git a/drivers/ram/stm32mp1/stm32mp1_ddr_regs.h b/drivers/ram/stm32mp1/stm32mp1_ddr_regs.h
index a606b2bcbe..9d33186b3a 100644
--- a/drivers/ram/stm32mp1/stm32mp1_ddr_regs.h
+++ b/drivers/ram/stm32mp1/stm32mp1_ddr_regs.h
@@ -234,6 +234,8 @@ struct stm32mp1_ddrphy {
/* DDRCTRL REGISTERS */
#define DDRCTRL_MSTR_DDR3 BIT(0)
+#define DDRCTRL_MSTR_LPDDR2 BIT(2)
+#define DDRCTRL_MSTR_LPDDR3 BIT(3)
#define DDRCTRL_MSTR_DATA_BUS_WIDTH_MASK GENMASK(13, 12)
#define DDRCTRL_MSTR_DATA_BUS_WIDTH_FULL (0 << 12)
#define DDRCTRL_MSTR_DATA_BUS_WIDTH_HALF (1 << 12)
@@ -330,6 +332,7 @@ struct stm32mp1_ddrphy {
#define DDRPHYC_DXNGCR_DXEN BIT(0)
+#define DDRPHYC_DXNDLLCR_DLLSRST BIT(30)
#define DDRPHYC_DXNDLLCR_DLLDIS BIT(31)
#define DDRPHYC_DXNDLLCR_SDPHASE_MASK GENMASK(17, 14)
#define DDRPHYC_DXNDLLCR_SDPHASE_SHIFT 14
diff --git a/drivers/ram/stm32mp1/stm32mp1_interactive.c b/drivers/ram/stm32mp1/stm32mp1_interactive.c
new file mode 100644
index 0000000000..cc9b2e7c96
--- /dev/null
+++ b/drivers/ram/stm32mp1/stm32mp1_interactive.c
@@ -0,0 +1,483 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2019, STMicroelectronics - All Rights Reserved
+ */
+
+#include <common.h>
+#include <console.h>
+#include <cli.h>
+#include <clk.h>
+#include <malloc.h>
+#include <ram.h>
+#include <reset.h>
+#include "stm32mp1_ddr.h"
+#include "stm32mp1_tests.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+enum ddr_command {
+ DDR_CMD_HELP,
+ DDR_CMD_INFO,
+ DDR_CMD_FREQ,
+ DDR_CMD_RESET,
+ DDR_CMD_PARAM,
+ DDR_CMD_PRINT,
+ DDR_CMD_EDIT,
+ DDR_CMD_STEP,
+ DDR_CMD_NEXT,
+ DDR_CMD_GO,
+ DDR_CMD_TEST,
+ DDR_CMD_TUNING,
+ DDR_CMD_UNKNOWN,
+};
+
+const char *step_str[] = {
+ [STEP_DDR_RESET] = "DDR_RESET",
+ [STEP_CTL_INIT] = "DDR_CTRL_INIT_DONE",
+ [STEP_PHY_INIT] = "DDR PHY_INIT_DONE",
+ [STEP_DDR_READY] = "DDR_READY",
+ [STEP_RUN] = "RUN"
+};
+
+enum ddr_command stm32mp1_get_command(char *cmd, int argc)
+{
+ const char *cmd_string[DDR_CMD_UNKNOWN] = {
+ [DDR_CMD_HELP] = "help",
+ [DDR_CMD_INFO] = "info",
+ [DDR_CMD_FREQ] = "freq",
+ [DDR_CMD_RESET] = "reset",
+ [DDR_CMD_PARAM] = "param",
+ [DDR_CMD_PRINT] = "print",
+ [DDR_CMD_EDIT] = "edit",
+ [DDR_CMD_STEP] = "step",
+ [DDR_CMD_NEXT] = "next",
+ [DDR_CMD_GO] = "go",
+#ifdef CONFIG_STM32MP1_DDR_TESTS
+ [DDR_CMD_TEST] = "test",
+#endif
+#ifdef CONFIG_STM32MP1_DDR_TUNING
+ [DDR_CMD_TUNING] = "tuning",
+#endif
+ };
+ /* min and max number of argument */
+ const char cmd_arg[DDR_CMD_UNKNOWN][2] = {
+ [DDR_CMD_HELP] = { 0, 0 },
+ [DDR_CMD_INFO] = { 0, 255 },
+ [DDR_CMD_FREQ] = { 0, 1 },
+ [DDR_CMD_RESET] = { 0, 0 },
+ [DDR_CMD_PARAM] = { 0, 2 },
+ [DDR_CMD_PRINT] = { 0, 1 },
+ [DDR_CMD_EDIT] = { 2, 2 },
+ [DDR_CMD_STEP] = { 0, 1 },
+ [DDR_CMD_NEXT] = { 0, 0 },
+ [DDR_CMD_GO] = { 0, 0 },
+#ifdef CONFIG_STM32MP1_DDR_TESTS
+ [DDR_CMD_TEST] = { 0, 255 },
+#endif
+#ifdef CONFIG_STM32MP1_DDR_TUNING
+ [DDR_CMD_TUNING] = { 0, 255 },
+#endif
+ };
+ int i;
+
+ for (i = 0; i < DDR_CMD_UNKNOWN; i++)
+ if (!strcmp(cmd, cmd_string[i])) {
+ if (argc - 1 < cmd_arg[i][0]) {
+ printf("no enought argument (min=%d)\n",
+ cmd_arg[i][0]);
+ return DDR_CMD_UNKNOWN;
+ } else if (argc - 1 > cmd_arg[i][1]) {
+ printf("too many argument (max=%d)\n",
+ cmd_arg[i][1]);
+ return DDR_CMD_UNKNOWN;
+ } else {
+ return i;
+ }
+ }
+
+ printf("unknown command %s\n", cmd);
+ return DDR_CMD_UNKNOWN;
+}
+
+static void stm32mp1_do_usage(void)
+{
+ const char *usage = {
+ "commands:\n\n"
+ "help displays help\n"
+ "info displays DDR information\n"
+ "info <param> <val> changes DDR information\n"
+ " with <param> = step, name, size or speed\n"
+ "freq displays the DDR PHY frequency in kHz\n"
+ "freq <freq> changes the DDR PHY frequency\n"
+ "param [type|reg] prints input parameters\n"
+ "param <reg> <val> edits parameters in step 0\n"
+ "print [type|reg] dumps registers\n"
+ "edit <reg> <val> modifies one register\n"
+ "step lists the available step\n"
+ "step <n> go to the step <n>\n"
+ "next goes to the next step\n"
+ "go continues the U-Boot SPL execution\n"
+ "reset reboots machine\n"
+#ifdef CONFIG_STM32MP1_DDR_TESTS
+ "test [help] | <n> [...] lists (with help) or executes test <n>\n"
+#endif
+#ifdef CONFIG_STM32MP1_DDR_TUNING
+ "tuning [help] | <n> [...] lists (with help) or execute tuning <n>\n"
+#endif
+ "\nwith for [type|reg]:\n"
+ " all registers if absent\n"
+ " <type> = ctl, phy\n"
+ " or one category (static, timing, map, perf, cal, dyn)\n"
+ " <reg> = name of the register\n"
+ };
+
+ puts(usage);
+}
+
+static bool stm32mp1_check_step(enum stm32mp1_ddr_interact_step step,
+ enum stm32mp1_ddr_interact_step expected)
+{
+ if (step != expected) {
+ printf("invalid step %d:%s expecting %d:%s\n",
+ step, step_str[step],
+ expected,
+ step_str[expected]);
+ return false;
+ }
+ return true;
+}
+
+static void stm32mp1_do_info(struct ddr_info *priv,
+ struct stm32mp1_ddr_config *config,
+ enum stm32mp1_ddr_interact_step step,
+ int argc, char * const argv[])
+{
+ unsigned long value;
+ static char *ddr_name;
+
+ if (argc == 1) {
+ printf("step = %d : %s\n", step, step_str[step]);
+ printf("name = %s\n", config->info.name);
+ printf("size = 0x%x\n", config->info.size);
+ printf("speed = %d kHz\n", config->info.speed);
+ return;
+ }
+
+ if (argc < 3) {
+ printf("no enought parameter\n");
+ return;
+ }
+ if (!strcmp(argv[1], "name")) {
+ u32 i, name_len = 0;
+
+ for (i = 2; i < argc; i++)
+ name_len += strlen(argv[i]) + 1;
+ if (ddr_name)
+ free(ddr_name);
+ ddr_name = malloc(name_len);
+ config->info.name = ddr_name;
+ if (!ddr_name) {
+ printf("alloc error, length %d\n", name_len);
+ return;
+ }
+ strcpy(ddr_name, argv[2]);
+ for (i = 3; i < argc; i++) {
+ strcat(ddr_name, " ");
+ strcat(ddr_name, argv[i]);
+ }
+ printf("name = %s\n", ddr_name);
+ return;
+ }
+ if (!strcmp(argv[1], "size")) {
+ if (strict_strtoul(argv[2], 16, &value) < 0) {
+ printf("invalid value %s\n", argv[2]);
+ } else {
+ config->info.size = value;
+ printf("size = 0x%x\n", config->info.size);
+ }
+ return;
+ }
+ if (!strcmp(argv[1], "speed")) {
+ if (strict_strtoul(argv[2], 10, &value) < 0) {
+ printf("invalid value %s\n", argv[2]);
+ } else {
+ config->info.speed = value;
+ printf("speed = %d kHz\n", config->info.speed);
+ value = clk_get_rate(&priv->clk);
+ printf("DDRPHY = %ld kHz\n", value / 1000);
+ }
+ return;
+ }
+ printf("argument %s invalid\n", argv[1]);
+}
+
+static bool stm32mp1_do_freq(struct ddr_info *priv,
+ int argc, char * const argv[])
+{
+ unsigned long ddrphy_clk;
+
+ if (argc == 2) {
+ if (strict_strtoul(argv[1], 0, &ddrphy_clk) < 0) {
+ printf("invalid argument %s", argv[1]);
+ return false;
+ }
+ if (clk_set_rate(&priv->clk, ddrphy_clk * 1000)) {
+ printf("ERROR: update failed!\n");
+ return false;
+ }
+ }
+ ddrphy_clk = clk_get_rate(&priv->clk);
+ printf("DDRPHY = %ld kHz\n", ddrphy_clk / 1000);
+ if (argc == 2)
+ return true;
+ return false;
+}
+
+static void stm32mp1_do_param(enum stm32mp1_ddr_interact_step step,
+ const struct stm32mp1_ddr_config *config,
+ int argc, char * const argv[])
+{
+ switch (argc) {
+ case 1:
+ stm32mp1_dump_param(config, NULL);
+ break;
+ case 2:
+ if (stm32mp1_dump_param(config, argv[1]))
+ printf("invalid argument %s\n",
+ argv[1]);
+ break;
+ case 3:
+ if (!stm32mp1_check_step(step, STEP_DDR_RESET))
+ return;
+ stm32mp1_edit_param(config, argv[1], argv[2]);
+ break;
+ }
+}
+
+static void stm32mp1_do_print(struct ddr_info *priv,
+ int argc, char * const argv[])
+{
+ switch (argc) {
+ case 1:
+ stm32mp1_dump_reg(priv, NULL);
+ break;
+ case 2:
+ if (stm32mp1_dump_reg(priv, argv[1]))
+ printf("invalid argument %s\n",
+ argv[1]);
+ break;
+ }
+}
+
+static int stm32mp1_do_step(enum stm32mp1_ddr_interact_step step,
+ int argc, char * const argv[])
+{
+ int i;
+ unsigned long value;
+
+ switch (argc) {
+ case 1:
+ for (i = 0; i < ARRAY_SIZE(step_str); i++)
+ printf("%d:%s\n", i, step_str[i]);
+ break;
+
+ case 2:
+ if ((strict_strtoul(argv[1], 0,
+ &value) < 0) ||
+ value >= ARRAY_SIZE(step_str)) {
+ printf("invalid argument %s\n",
+ argv[1]);
+ goto end;
+ }
+
+ if (value != STEP_DDR_RESET &&
+ value <= step) {
+ printf("invalid target %d:%s, current step is %d:%s\n",
+ (int)value, step_str[value],
+ step, step_str[step]);
+ goto end;
+ }
+ printf("step to %d:%s\n",
+ (int)value, step_str[value]);
+ return (int)value;
+ };
+
+end:
+ return step;
+}
+
+#if defined(CONFIG_STM32MP1_DDR_TESTS) || defined(CONFIG_STM32MP1_DDR_TUNING)
+static const char * const s_result[] = {
+ [TEST_PASSED] = "Pass",
+ [TEST_FAILED] = "Failed",
+ [TEST_ERROR] = "Error"
+};
+
+static void stm32mp1_ddr_subcmd(struct ddr_info *priv,
+ int argc, char *argv[],
+ const struct test_desc array[],
+ const int array_nb)
+{
+ int i;
+ unsigned long value;
+ int result;
+ char string[50] = "";
+
+ if (argc == 1) {
+ printf("%s:%d\n", argv[0], array_nb);
+ for (i = 0; i < array_nb; i++)
+ printf("%d:%s:%s\n",
+ i, array[i].name, array[i].usage);
+ return;
+ }
+ if (argc > 1 && !strcmp(argv[1], "help")) {
+ printf("%s:%d\n", argv[0], array_nb);
+ for (i = 0; i < array_nb; i++)
+ printf("%d:%s:%s:%s\n", i,
+ array[i].name, array[i].usage, array[i].help);
+ return;
+ }
+
+ if ((strict_strtoul(argv[1], 0, &value) < 0) ||
+ value >= array_nb) {
+ sprintf(string, "invalid argument %s",
+ argv[1]);
+ result = TEST_FAILED;
+ goto end;
+ }
+
+ if (argc > (array[value].max_args + 2)) {
+ sprintf(string, "invalid nb of args %d, max %d",
+ argc - 2, array[value].max_args);
+ result = TEST_FAILED;
+ goto end;
+ }
+
+ printf("execute %d:%s\n", (int)value, array[value].name);
+ clear_ctrlc();
+ result = array[value].fct(priv->ctl, priv->phy,
+ string, argc - 2, &argv[2]);
+
+end:
+ printf("Result: %s [%s]\n", s_result[result], string);
+}
+#endif
+
+bool stm32mp1_ddr_interactive(void *priv,
+ enum stm32mp1_ddr_interact_step step,
+ const struct stm32mp1_ddr_config *config)
+{
+ const char *prompt = "DDR>";
+ char buffer[CONFIG_SYS_CBSIZE];
+ char *argv[CONFIG_SYS_MAXARGS + 1]; /* NULL terminated */
+ int argc;
+ static int next_step = -1;
+
+ if (next_step < 0 && step == STEP_DDR_RESET) {
+#ifdef CONFIG_STM32MP1_DDR_INTERACTIVE_FORCE
+ gd->flags &= ~(GD_FLG_SILENT |
+ GD_FLG_DISABLE_CONSOLE);
+ next_step = STEP_DDR_RESET;
+#else
+ unsigned long start = get_timer(0);
+
+ while (1) {
+ if (tstc() && (getc() == 'd')) {
+ next_step = STEP_DDR_RESET;
+ break;
+ }
+ if (get_timer(start) > 100)
+ break;
+ }
+#endif
+ }
+
+ debug("** step %d ** %s / %d\n", step, step_str[step], next_step);
+
+ if (next_step < 0)
+ return false;
+
+ if (step < 0 || step > ARRAY_SIZE(step_str)) {
+ printf("** step %d ** INVALID\n", step);
+ return false;
+ }
+
+ printf("%d:%s\n", step, step_str[step]);
+ printf("%s\n", prompt);
+
+ if (next_step > step)
+ return false;
+
+ while (next_step == step) {
+ cli_readline_into_buffer(prompt, buffer, 0);
+ argc = cli_simple_parse_line(buffer, argv);
+ if (!argc)
+ continue;
+
+ switch (stm32mp1_get_command(argv[0], argc)) {
+ case DDR_CMD_HELP:
+ stm32mp1_do_usage();
+ break;
+
+ case DDR_CMD_INFO:
+ stm32mp1_do_info(priv,
+ (struct stm32mp1_ddr_config *)config,
+ step, argc, argv);
+ break;
+
+ case DDR_CMD_FREQ:
+ if (stm32mp1_do_freq(priv, argc, argv))
+ next_step = STEP_DDR_RESET;
+ break;
+
+ case DDR_CMD_RESET:
+ do_reset(NULL, 0, 0, NULL);
+ break;
+
+ case DDR_CMD_PARAM:
+ stm32mp1_do_param(step, config, argc, argv);
+ break;
+
+ case DDR_CMD_PRINT:
+ stm32mp1_do_print(priv, argc, argv);
+ break;
+
+ case DDR_CMD_EDIT:
+ stm32mp1_edit_reg(priv, argv[1], argv[2]);
+ break;
+
+ case DDR_CMD_GO:
+ next_step = STEP_RUN;
+ break;
+
+ case DDR_CMD_NEXT:
+ next_step = step + 1;
+ break;
+
+ case DDR_CMD_STEP:
+ next_step = stm32mp1_do_step(step, argc, argv);
+ break;
+
+#ifdef CONFIG_STM32MP1_DDR_TESTS
+ case DDR_CMD_TEST:
+ if (!stm32mp1_check_step(step, STEP_DDR_READY))
+ continue;
+ stm32mp1_ddr_subcmd(priv, argc, argv, test, test_nb);
+ break;
+#endif
+
+#ifdef CONFIG_STM32MP1_DDR_TUNING
+ case DDR_CMD_TUNING:
+ if (!stm32mp1_check_step(step, STEP_DDR_READY))
+ continue;
+ stm32mp1_ddr_subcmd(priv, argc, argv,
+ tuning, tuning_nb);
+ break;
+#endif
+
+ default:
+ break;
+ }
+ }
+ return next_step == STEP_DDR_RESET;
+}
diff --git a/drivers/ram/stm32mp1/stm32mp1_ram.c b/drivers/ram/stm32mp1/stm32mp1_ram.c
index e45a3b2658..84e39d093b 100644
--- a/drivers/ram/stm32mp1/stm32mp1_ram.c
+++ b/drivers/ram/stm32mp1/stm32mp1_ram.c
@@ -20,7 +20,7 @@ static const char *const clkname[] = {
"ddrphyc" /* LAST clock => used for get_rate() */
};
-int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint16_t mem_speed)
+int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint32_t mem_speed)
{
unsigned long ddrphy_clk;
unsigned long ddr_clk;
@@ -43,13 +43,13 @@ int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint16_t mem_speed)
priv->clk = clk;
ddrphy_clk = clk_get_rate(&priv->clk);
- debug("DDR: mem_speed (%d MHz), RCC %d MHz\n",
- mem_speed, (u32)(ddrphy_clk / 1000 / 1000));
+ debug("DDR: mem_speed (%d kHz), RCC %d kHz\n",
+ mem_speed, (u32)(ddrphy_clk / 1000));
/* max 10% frequency delta */
- ddr_clk = abs(ddrphy_clk - mem_speed * 1000 * 1000);
- if (ddr_clk > (mem_speed * 1000 * 100)) {
- pr_err("DDR expected freq %d MHz, current is %d MHz\n",
- mem_speed, (u32)(ddrphy_clk / 1000 / 1000));
+ ddr_clk = abs(ddrphy_clk - mem_speed * 1000);
+ if (ddr_clk > (mem_speed * 100)) {
+ pr_err("DDR expected freq %d kHz, current is %d kHz\n",
+ mem_speed, (u32)(ddrphy_clk / 1000));
return -EINVAL;
}
@@ -102,8 +102,8 @@ static __maybe_unused int stm32mp1_ddr_setup(struct udevice *dev)
debug("%s: %s[0x%x] = %d\n", __func__,
param[idx].name, param[idx].size, ret);
if (ret) {
- pr_err("%s: Cannot read %s\n",
- __func__, param[idx].name);
+ pr_err("%s: Cannot read %s, error=%d\n",
+ __func__, param[idx].name, ret);
return -EINVAL;
}
}
diff --git a/drivers/ram/stm32mp1/stm32mp1_tests.c b/drivers/ram/stm32mp1/stm32mp1_tests.c
new file mode 100644
index 0000000000..b6fb2a9c58
--- /dev/null
+++ b/drivers/ram/stm32mp1/stm32mp1_tests.c
@@ -0,0 +1,1426 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2019, STMicroelectronics - All Rights Reserved
+ */
+#include <common.h>
+#include <console.h>
+#include <asm/io.h>
+#include <linux/log2.h>
+#include "stm32mp1_tests.h"
+
+#define ADDR_INVALID 0xFFFFFFFF
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int get_bufsize(char *string, int argc, char *argv[], int arg_nb,
+ size_t *bufsize, size_t default_size)
+{
+ unsigned long value;
+
+ if (argc > arg_nb) {
+ if (strict_strtoul(argv[arg_nb], 0, &value) < 0) {
+ sprintf(string, "invalid %d parameter %s",
+ arg_nb, argv[arg_nb]);
+ return -1;
+ }
+ if (value > STM32_DDR_SIZE || value == 0) {
+ sprintf(string, "invalid size %s", argv[arg_nb]);
+ return -1;
+ }
+ if (value & 0x3) {
+ sprintf(string, "unaligned size %s",
+ argv[arg_nb]);
+ return -1;
+ }
+ *bufsize = value;
+ } else {
+ if (default_size != STM32_DDR_SIZE)
+ *bufsize = default_size;
+ else
+ *bufsize = get_ram_size((long *)STM32_DDR_BASE,
+ STM32_DDR_SIZE);
+ }
+ return 0;
+}
+
+static int get_nb_loop(char *string, int argc, char *argv[], int arg_nb,
+ u32 *nb_loop, u32 default_nb_loop)
+{
+ unsigned long value;
+
+ if (argc > arg_nb) {
+ if (strict_strtoul(argv[arg_nb], 0, &value) < 0) {
+ sprintf(string, "invalid %d parameter %s",
+ arg_nb, argv[arg_nb]);
+ return -1;
+ }
+ if (value == 0)
+ printf("WARNING: infinite loop requested\n");
+ *nb_loop = value;
+ } else {
+ *nb_loop = default_nb_loop;
+ }
+
+ return 0;
+}
+
+static int get_addr(char *string, int argc, char *argv[], int arg_nb,
+ u32 *addr)
+{
+ unsigned long value;
+
+ if (argc > arg_nb) {
+ if (strict_strtoul(argv[arg_nb], 16, &value) < 0) {
+ sprintf(string, "invalid %d parameter %s",
+ arg_nb, argv[arg_nb]);
+ return -1;
+ }
+ if (value < STM32_DDR_BASE) {
+ sprintf(string, "too low address %s", argv[arg_nb]);
+ return -1;
+ }
+ if (value & 0x3 && value != ADDR_INVALID) {
+ sprintf(string, "unaligned address %s",
+ argv[arg_nb]);
+ return -1;
+ }
+ *addr = value;
+ } else {
+ *addr = STM32_DDR_BASE;
+ }
+
+ return 0;
+}
+
+static int get_pattern(char *string, int argc, char *argv[], int arg_nb,
+ u32 *pattern, u32 default_pattern)
+{
+ unsigned long value;
+
+ if (argc > arg_nb) {
+ if (strict_strtoul(argv[arg_nb], 16, &value) < 0) {
+ sprintf(string, "invalid %d parameter %s",
+ arg_nb, argv[arg_nb]);
+ return -1;
+ }
+ *pattern = value;
+ } else {
+ *pattern = default_pattern;
+ }
+
+ return 0;
+}
+
+static u32 check_addr(u32 addr, u32 value)
+{
+ u32 data = readl(addr);
+
+ if (value != data) {
+ printf("0x%08x: 0x%08x <=> 0x%08x", addr, data, value);
+ data = readl(addr);
+ printf("(2nd read: 0x%08x)", data);
+ if (value == data)
+ printf("- read error");
+ else
+ printf("- write error");
+ printf("\n");
+ return -1;
+ }
+ return 0;
+}
+
+static int progress(u32 offset)
+{
+ if (!(offset & 0xFFFFFF)) {
+ putc('.');
+ if (ctrlc()) {
+ printf("\ntest interrupted!\n");
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int test_loop_end(u32 *loop, u32 nb_loop, u32 progress)
+{
+ (*loop)++;
+ if (nb_loop && *loop >= nb_loop)
+ return 1;
+ if ((*loop) % progress)
+ return 0;
+ /* allow to interrupt the test only for progress step */
+ if (ctrlc()) {
+ printf("test interrupted!\n");
+ return 1;
+ }
+ printf("loop #%d\n", *loop);
+ return 0;
+}
+
+/**********************************************************************
+ *
+ * Function: memTestDataBus()
+ *
+ * Description: Test the data bus wiring in a memory region by
+ * performing a walking 1's test at a fixed address
+ * within that region. The address is selected
+ * by the caller.
+ *
+ * Notes:
+ *
+ * Returns: 0 if the test succeeds.
+ * A non-zero result is the first pattern that failed.
+ *
+ **********************************************************************/
+static u32 databus(u32 *address)
+{
+ u32 pattern;
+ u32 read_value;
+
+ /* Perform a walking 1's test at the given address. */
+ for (pattern = 1; pattern != 0; pattern <<= 1) {
+ /* Write the test pattern. */
+ writel(pattern, address);
+
+ /* Read it back (immediately is okay for this test). */
+ read_value = readl(address);
+ debug("%x: %x <=> %x\n",
+ (u32)address, read_value, pattern);
+
+ if (read_value != pattern)
+ return pattern;
+ }
+
+ return 0;
+}
+
+/**********************************************************************
+ *
+ * Function: memTestAddressBus()
+ *
+ * Description: Test the address bus wiring in a memory region by
+ * performing a walking 1's test on the relevant bits
+ * of the address and checking for aliasing. This test
+ * will find single-bit address failures such as stuck
+ * -high, stuck-low, and shorted pins. The base address
+ * and size of the region are selected by the caller.
+ *
+ * Notes: For best results, the selected base address should
+ * have enough LSB 0's to guarantee single address bit
+ * changes. For example, to test a 64-Kbyte region,
+ * select a base address on a 64-Kbyte boundary. Also,
+ * select the region size as a power-of-two--if at all
+ * possible.
+ *
+ * Returns: NULL if the test succeeds.
+ * A non-zero result is the first address at which an
+ * aliasing problem was uncovered. By examining the
+ * contents of memory, it may be possible to gather
+ * additional information about the problem.
+ *
+ **********************************************************************/
+static u32 *addressbus(u32 *address, u32 nb_bytes)
+{
+ u32 mask = (nb_bytes / sizeof(u32) - 1);
+ u32 offset;
+ u32 test_offset;
+ u32 read_value;
+
+ u32 pattern = 0xAAAAAAAA;
+ u32 antipattern = 0x55555555;
+
+ /* Write the default pattern at each of the power-of-two offsets. */
+ for (offset = 1; (offset & mask) != 0; offset <<= 1)
+ writel(pattern, &address[offset]);
+
+ /* Check for address bits stuck high. */
+ test_offset = 0;
+ writel(antipattern, &address[test_offset]);
+
+ for (offset = 1; (offset & mask) != 0; offset <<= 1) {
+ read_value = readl(&address[offset]);
+ debug("%x: %x <=> %x\n",
+ (u32)&address[offset], read_value, pattern);
+ if (read_value != pattern)
+ return &address[offset];
+ }
+
+ writel(pattern, &address[test_offset]);
+
+ /* Check for address bits stuck low or shorted. */
+ for (test_offset = 1; (test_offset & mask) != 0; test_offset <<= 1) {
+ writel(antipattern, &address[test_offset]);
+ if (readl(&address[0]) != pattern)
+ return &address[test_offset];
+
+ for (offset = 1; (offset & mask) != 0; offset <<= 1) {
+ if (readl(&address[offset]) != pattern &&
+ offset != test_offset)
+ return &address[test_offset];
+ }
+ writel(pattern, &address[test_offset]);
+ }
+
+ return NULL;
+}
+
+/**********************************************************************
+ *
+ * Function: memTestDevice()
+ *
+ * Description: Test the integrity of a physical memory device by
+ * performing an increment/decrement test over the
+ * entire region. In the process every storage bit
+ * in the device is tested as a zero and a one. The
+ * base address and the size of the region are
+ * selected by the caller.
+ *
+ * Notes:
+ *
+ * Returns: NULL if the test succeeds.
+ *
+ * A non-zero result is the first address at which an
+ * incorrect value was read back. By examining the
+ * contents of memory, it may be possible to gather
+ * additional information about the problem.
+ *
+ **********************************************************************/
+static u32 *memdevice(u32 *address, u32 nb_bytes)
+{
+ u32 offset;
+ u32 nb_words = nb_bytes / sizeof(u32);
+
+ u32 pattern;
+ u32 antipattern;
+
+ puts("Fill with pattern");
+ /* Fill memory with a known pattern. */
+ for (pattern = 1, offset = 0; offset < nb_words; pattern++, offset++) {
+ writel(pattern, &address[offset]);
+ if (progress(offset))
+ return NULL;
+ }
+
+ puts("\nCheck and invert pattern");
+ /* Check each location and invert it for the second pass. */
+ for (pattern = 1, offset = 0; offset < nb_words; pattern++, offset++) {
+ if (readl(&address[offset]) != pattern)
+ return &address[offset];
+
+ antipattern = ~pattern;
+ writel(antipattern, &address[offset]);
+ if (progress(offset))
+ return NULL;
+ }
+
+ puts("\nCheck inverted pattern");
+ /* Check each location for the inverted pattern and zero it. */
+ for (pattern = 1, offset = 0; offset < nb_words; pattern++, offset++) {
+ antipattern = ~pattern;
+ if (readl(&address[offset]) != antipattern)
+ return &address[offset];
+ if (progress(offset))
+ return NULL;
+ }
+ printf("\n");
+
+ return NULL;
+}
+
+static enum test_result databuswalk0(struct stm32mp1_ddrctl *ctl,
+ struct stm32mp1_ddrphy *phy,
+ char *string, int argc, char *argv[])
+{
+ int i;
+ u32 loop = 0, nb_loop;
+ u32 addr;
+ u32 error = 0;
+ u32 data;
+
+ if (get_nb_loop(string, argc, argv, 0, &nb_loop, 100))
+ return TEST_ERROR;
+ if (get_addr(string, argc, argv, 1, &addr))
+ return TEST_ERROR;
+
+ printf("running %d loops at 0x%x\n", nb_loop, addr);
+ while (!error) {
+ for (i = 0; i < 32; i++)
+ writel(~(1 << i), addr + 4 * i);
+ for (i = 0; i < 32; i++) {
+ data = readl(addr + 4 * i);
+ if (~(1 << i) != data) {
+ error |= 1 << i;
+ debug("%x: error %x expected %x => error:%x\n",
+ addr + 4 * i, data, ~(1 << i), error);
+ }
+ }
+ if (test_loop_end(&loop, nb_loop, 1000))
+ break;
+ for (i = 0; i < 32; i++)
+ writel(0, addr + 4 * i);
+ }
+ if (error) {
+ sprintf(string, "loop %d: error for bits 0x%x",
+ loop, error);
+ return TEST_FAILED;
+ }
+ sprintf(string, "no error for %d loops", loop);
+ return TEST_PASSED;
+}
+
+static enum test_result databuswalk1(struct stm32mp1_ddrctl *ctl,
+ struct stm32mp1_ddrphy *phy,
+ char *string, int argc, char *argv[])
+{
+ int i;
+ u32 loop = 0, nb_loop;
+ u32 addr;
+ u32 error = 0;
+ u32 data;
+
+ if (get_nb_loop(string, argc, argv, 0, &nb_loop, 100))
+ return TEST_ERROR;
+ if (get_addr(string, argc, argv, 1, &addr))
+ return TEST_ERROR;
+ printf("running %d loops at 0x%x\n", nb_loop, addr);
+ while (!error) {
+ for (i = 0; i < 32; i++)
+ writel(1 << i, addr + 4 * i);
+ for (i = 0; i < 32; i++) {
+ data = readl(addr + 4 * i);
+ if ((1 << i) != data) {
+ error |= 1 << i;
+ debug("%x: error %x expected %x => error:%x\n",
+ addr + 4 * i, data, (1 << i), error);
+ }
+ }
+ if (test_loop_end(&loop, nb_loop, 1000))
+ break;
+ for (i = 0; i < 32; i++)
+ writel(0, addr + 4 * i);
+ }
+ if (error) {
+ sprintf(string, "loop %d: error for bits 0x%x",
+ loop, error);
+ return TEST_FAILED;
+ }
+ sprintf(string, "no error for %d loops", loop);
+ return TEST_PASSED;
+}
+
+static enum test_result test_databus(struct stm32mp1_ddrctl *ctl,
+ struct stm32mp1_ddrphy *phy,
+ char *string, int argc, char *argv[])
+{
+ u32 addr;
+ u32 error;
+
+ if (get_addr(string, argc, argv, 0, &addr))
+ return TEST_ERROR;
+ error = databus((u32 *)addr);
+ if (error) {
+ sprintf(string, "0x%x: error for bits 0x%x",
+ addr, error);
+ return TEST_FAILED;
+ }
+ sprintf(string, "address 0x%x", addr);
+ return TEST_PASSED;
+}
+
+static enum test_result test_addressbus(struct stm32mp1_ddrctl *ctl,
+ struct stm32mp1_ddrphy *phy,
+ char *string, int argc, char *argv[])
+{
+ u32 addr;
+ u32 bufsize;
+ u32 error;
+
+ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
+ return TEST_ERROR;
+ if (!is_power_of_2(bufsize)) {
+ sprintf(string, "size 0x%x is not a power of 2",
+ (u32)bufsize);
+ return TEST_ERROR;
+ }
+ if (get_addr(string, argc, argv, 1, &addr))
+ return TEST_ERROR;
+
+ error = (u32)addressbus((u32 *)addr, bufsize);
+ if (error) {
+ sprintf(string, "0x%x: error for address 0x%x",
+ addr, error);
+ return TEST_FAILED;
+ }
+ sprintf(string, "address 0x%x, size 0x%x",
+ addr, bufsize);
+ return TEST_PASSED;
+}
+
+static enum test_result test_memdevice(struct stm32mp1_ddrctl *ctl,
+ struct stm32mp1_ddrphy *phy,
+ char *string, int argc, char *argv[])
+{
+ u32 addr;
+ size_t bufsize;
+ u32 error;
+
+ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
+ return TEST_ERROR;
+ if (get_addr(string, argc, argv, 1, &addr))
+ return TEST_ERROR;
+ error = (u32)memdevice((u32 *)addr, (unsigned long)bufsize);
+ if (error) {
+ sprintf(string, "0x%x: error for address 0x%x",
+ addr, error);
+ return TEST_FAILED;
+ }
+ sprintf(string, "address 0x%x, size 0x%x",
+ addr, bufsize);
+ return TEST_PASSED;
+}
+
+/**********************************************************************
+ *
+ * Function: sso
+ *
+ * Description: Test the Simultaneous Switching Output.
+ * Verifies succes sive reads and writes to the same memory word,
+ * holding one bit constant while toggling all other data bits
+ * simultaneously
+ * => stress the data bus over an address range
+ *
+ * The CPU writes to each address in the given range.
+ * For each bit, first the CPU holds the bit at 1 while
+ * toggling the other bits, and then the CPU holds the bit at 0
+ * while toggling the other bits.
+ * After each write, the CPU reads the address that was written
+ * to verify that it contains the correct data
+ *
+ **********************************************************************/
+static enum test_result test_sso(struct stm32mp1_ddrctl *ctl,
+ struct stm32mp1_ddrphy *phy,
+ char *string, int argc, char *argv[])
+{
+ int i, j;
+ u32 addr, bufsize, remaining, offset;
+ u32 error = 0;
+ u32 data;
+
+ if (get_bufsize(string, argc, argv, 0, &bufsize, 4))
+ return TEST_ERROR;
+ if (get_addr(string, argc, argv, 1, &addr))
+ return TEST_ERROR;
+
+ printf("running sso at 0x%x length 0x%x", addr, bufsize);
+ offset = addr;
+ remaining = bufsize;
+ while (remaining) {
+ for (i = 0; i < 32; i++) {
+ /* write pattern. */
+ for (j = 0; j < 6; j++) {
+ switch (j) {
+ case 0:
+ case 2:
+ data = 1 << i;
+ break;
+ case 3:
+ case 5:
+ data = ~(1 << i);
+ break;
+ case 1:
+ data = ~0x0;
+ break;
+ case 4:
+ data = 0x0;
+ break;
+ }
+
+ writel(data, offset);
+ error = check_addr(offset, data);
+ if (error)
+ goto end;
+ }
+ }
+ offset += 4;
+ remaining -= 4;
+ if (progress(offset << 7))
+ goto end;
+ }
+ puts("\n");
+
+end:
+ if (error) {
+ sprintf(string, "error for pattern 0x%x @0x%x",
+ data, offset);
+ return TEST_FAILED;
+ }
+ sprintf(string, "no error for sso at 0x%x length 0x%x", addr, bufsize);
+ return TEST_PASSED;
+}
+
+/**********************************************************************
+ *
+ * Function: Random
+ *
+ * Description: Verifies r/w with pseudo-ramdom value on one region
+ * + write the region (individual access)
+ * + memcopy to the 2nd region (try to use burst)
+ * + verify the 2 regions
+ *
+ **********************************************************************/
+static enum test_result test_random(struct stm32mp1_ddrctl *ctl,
+ struct stm32mp1_ddrphy *phy,
+ char *string, int argc, char *argv[])
+{
+ u32 addr, offset, value = 0;
+ size_t bufsize;
+ u32 loop = 0, nb_loop;
+ u32 error = 0;
+ unsigned int seed;
+
+ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
+ return TEST_ERROR;
+ if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
+ return TEST_ERROR;
+ if (get_addr(string, argc, argv, 2, &addr))
+ return TEST_ERROR;
+
+ printf("running %d loops at 0x%x\n", nb_loop, addr);
+ while (!error) {
+ seed = rand();
+ for (offset = addr; offset < addr + bufsize; offset += 4)
+ writel(rand(), offset);
+
+ memcpy((void *)addr + bufsize, (void *)addr, bufsize);
+
+ srand(seed);
+ for (offset = addr; offset < addr + 2 * bufsize; offset += 4) {
+ if (offset == (addr + bufsize))
+ srand(seed);
+ value = rand();
+ error = check_addr(offset, value);
+ if (error)
+ break;
+ if (progress(offset))
+ return TEST_FAILED;
+ }
+ if (test_loop_end(&loop, nb_loop, 100))
+ break;
+ }
+
+ if (error) {
+ sprintf(string,
+ "loop %d: error for address 0x%x: 0x%x expected 0x%x",
+ loop, offset, readl(offset), value);
+ return TEST_FAILED;
+ }
+ sprintf(string, "no error for %d loops, size 0x%x",
+ loop, bufsize);
+ return TEST_PASSED;
+}
+
+/**********************************************************************
+ *
+ * Function: noise
+ *
+ * Description: Verifies r/w while forcing switching of all data bus lines.
+ * optimised 4 iteration write/read/write/read cycles...
+ * for pattern and inversed pattern
+ *
+ **********************************************************************/
+void do_noise(u32 addr, u32 pattern, u32 *result)
+{
+ __asm__("push {R0-R11}");
+ __asm__("mov r0, %0" : : "r" (addr));
+ __asm__("mov r1, %0" : : "r" (pattern));
+ __asm__("mov r11, %0" : : "r" (result));
+
+ __asm__("mvn r2, r1");
+
+ __asm__("str r1, [r0]");
+ __asm__("ldr r3, [r0]");
+ __asm__("str r2, [r0]");
+ __asm__("ldr r4, [r0]");
+
+ __asm__("str r1, [r0]");
+ __asm__("ldr r5, [r0]");
+ __asm__("str r2, [r0]");
+ __asm__("ldr r6, [r0]");
+
+ __asm__("str r1, [r0]");
+ __asm__("ldr r7, [r0]");
+ __asm__("str r2, [r0]");
+ __asm__("ldr r8, [r0]");
+
+ __asm__("str r1, [r0]");
+ __asm__("ldr r9, [r0]");
+ __asm__("str r2, [r0]");
+ __asm__("ldr r10, [r0]");
+
+ __asm__("stmia R11!, {R3-R10}");
+
+ __asm__("pop {R0-R11}");
+}
+
+static enum test_result test_noise(struct stm32mp1_ddrctl *ctl,
+ struct stm32mp1_ddrphy *phy,
+ char *string, int argc, char *argv[])
+{
+ u32 addr, pattern;
+ u32 result[8];
+ int i;
+ enum test_result res = TEST_PASSED;
+
+ if (get_pattern(string, argc, argv, 0, &pattern, 0xFFFFFFFF))
+ return TEST_ERROR;
+ if (get_addr(string, argc, argv, 1, &addr))
+ return TEST_ERROR;
+
+ printf("running noise for 0x%x at 0x%x\n", pattern, addr);
+
+ do_noise(addr, pattern, result);
+
+ for (i = 0; i < 0x8;) {
+ if (check_addr((u32)&result[i++], pattern))
+ res = TEST_FAILED;
+ if (check_addr((u32)&result[i++], ~pattern))
+ res = TEST_FAILED;
+ }
+
+ return res;
+}
+
+/**********************************************************************
+ *
+ * Function: noise_burst
+ *
+ * Description: Verifies r/w while forcing switching of all data bus lines.
+ * optimised write loop witrh store multiple to use burst
+ * for pattern and inversed pattern
+ *
+ **********************************************************************/
+void do_noise_burst(u32 addr, u32 pattern, size_t bufsize)
+{
+ __asm__("push {R0-R9}");
+ __asm__("mov r0, %0" : : "r" (addr));
+ __asm__("mov r1, %0" : : "r" (pattern));
+ __asm__("mov r9, %0" : : "r" (bufsize));
+
+ __asm__("mvn r2, r1");
+ __asm__("mov r3, r1");
+ __asm__("mov r4, r2");
+ __asm__("mov r5, r1");
+ __asm__("mov r6, r2");
+ __asm__("mov r7, r1");
+ __asm__("mov r8, r2");
+
+ __asm__("loop1:");
+ __asm__("stmia R0!, {R1-R8}");
+ __asm__("stmia R0!, {R1-R8}");
+ __asm__("stmia R0!, {R1-R8}");
+ __asm__("stmia R0!, {R1-R8}");
+ __asm__("subs r9, r9, #128");
+ __asm__("bge loop1");
+ __asm__("pop {R0-R9}");
+}
+
+/* chunk size enough to allow interruption with Ctrl-C*/
+#define CHUNK_SIZE 0x8000000
+static enum test_result test_noise_burst(struct stm32mp1_ddrctl *ctl,
+ struct stm32mp1_ddrphy *phy,
+ char *string, int argc, char *argv[])
+{
+ u32 addr, offset, pattern;
+ size_t bufsize, remaining, size;
+ int i;
+ enum test_result res = TEST_PASSED;
+
+ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
+ return TEST_ERROR;
+ if (get_pattern(string, argc, argv, 1, &pattern, 0xFFFFFFFF))
+ return TEST_ERROR;
+ if (get_addr(string, argc, argv, 2, &addr))
+ return TEST_ERROR;
+
+ printf("running noise burst for 0x%x at 0x%x + 0x%x",
+ pattern, addr, bufsize);
+
+ offset = addr;
+ remaining = bufsize;
+ size = CHUNK_SIZE;
+ while (remaining) {
+ if (remaining < size)
+ size = remaining;
+ do_noise_burst(offset, pattern, size);
+ remaining -= size;
+ offset += size;
+ if (progress(offset)) {
+ res = TEST_FAILED;
+ goto end;
+ }
+ }
+ puts("\ncheck buffer");
+ for (i = 0; i < bufsize;) {
+ if (check_addr(addr + i, pattern))
+ res = TEST_FAILED;
+ i += 4;
+ if (check_addr(addr + i, ~pattern))
+ res = TEST_FAILED;
+ i += 4;
+ if (progress(i)) {
+ res = TEST_FAILED;
+ goto end;
+ }
+ }
+end:
+ puts("\n");
+ return res;
+}
+
+/**********************************************************************
+ *
+ * Function: pattern test
+ *
+ * Description: optimized loop for read/write pattern (array of 8 u32)
+ *
+ **********************************************************************/
+#define PATTERN_SIZE 8
+static enum test_result test_loop(const u32 *pattern, u32 *address,
+ const u32 bufsize)
+{
+ int i;
+ int j;
+ enum test_result res = TEST_PASSED;
+ u32 *offset, testsize, remaining;
+
+ offset = address;
+ remaining = bufsize;
+ while (remaining) {
+ testsize = bufsize > 0x1000000 ? 0x1000000 : bufsize;
+
+ __asm__("push {R0-R10}");
+ __asm__("mov r0, %0" : : "r" (pattern));
+ __asm__("mov r1, %0" : : "r" (offset));
+ __asm__("mov r2, %0" : : "r" (testsize));
+ __asm__("ldmia r0!, {R3-R10}");
+
+ __asm__("loop2:");
+ __asm__("stmia r1!, {R3-R10}");
+ __asm__("stmia r1!, {R3-R10}");
+ __asm__("stmia r1!, {R3-R10}");
+ __asm__("stmia r1!, {R3-R10}");
+ __asm__("subs r2, r2, #8");
+ __asm__("bge loop2");
+ __asm__("pop {R0-R10}");
+
+ offset += testsize;
+ remaining -= testsize;
+ if (progress((u32)offset)) {
+ res = TEST_FAILED;
+ goto end;
+ }
+ }
+
+ puts("\ncheck buffer");
+ for (i = 0; i < bufsize; i += PATTERN_SIZE * 4) {
+ for (j = 0; j < PATTERN_SIZE; j++, address++)
+ if (check_addr((u32)address, pattern[j])) {
+ res = TEST_FAILED;
+ goto end;
+ }
+ if (progress(i)) {
+ res = TEST_FAILED;
+ goto end;
+ }
+ }
+
+end:
+ puts("\n");
+ return res;
+}
+
+const u32 pattern_div1_x16[PATTERN_SIZE] = {
+ 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF,
+ 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF
+};
+
+const u32 pattern_div2_x16[PATTERN_SIZE] = {
+ 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000,
+ 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000
+};
+
+const u32 pattern_div4_x16[PATTERN_SIZE] = {
+ 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000
+};
+
+const u32 pattern_div4_x32[PATTERN_SIZE] = {
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000
+};
+
+const u32 pattern_mostly_zero_x16[PATTERN_SIZE] = {
+ 0x00000000, 0x00000000, 0x00000000, 0x0000FFFF,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000
+};
+
+const u32 pattern_mostly_zero_x32[PATTERN_SIZE] = {
+ 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000
+};
+
+const u32 pattern_mostly_one_x16[PATTERN_SIZE] = {
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000FFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
+};
+
+const u32 pattern_mostly_one_x32[PATTERN_SIZE] = {
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
+};
+
+#define NB_PATTERN 5
+static enum test_result test_freq_pattern(struct stm32mp1_ddrctl *ctl,
+ struct stm32mp1_ddrphy *phy,
+ char *string, int argc, char *argv[])
+{
+ const u32 * const patterns_x16[NB_PATTERN] = {
+ pattern_div1_x16,
+ pattern_div2_x16,
+ pattern_div4_x16,
+ pattern_mostly_zero_x16,
+ pattern_mostly_one_x16,
+ };
+ const u32 * const patterns_x32[NB_PATTERN] = {
+ pattern_div2_x16,
+ pattern_div4_x16,
+ pattern_div4_x32,
+ pattern_mostly_zero_x32,
+ pattern_mostly_one_x32
+ };
+ const char *patterns_comments[NB_PATTERN] = {
+ "switching at frequency F/1",
+ "switching at frequency F/2",
+ "switching at frequency F/4",
+ "mostly zero",
+ "mostly one"
+ };
+
+ enum test_result res = TEST_PASSED, pattern_res;
+ int i, bus_width;
+ const u32 **patterns;
+ u32 bufsize;
+
+ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
+ return TEST_ERROR;
+
+ switch (readl(&ctl->mstr) & DDRCTRL_MSTR_DATA_BUS_WIDTH_MASK) {
+ case DDRCTRL_MSTR_DATA_BUS_WIDTH_HALF:
+ case DDRCTRL_MSTR_DATA_BUS_WIDTH_QUARTER:
+ bus_width = 16;
+ break;
+ default:
+ bus_width = 32;
+ break;
+ }
+
+ printf("running test pattern at 0x%08x length 0x%x width = %d\n",
+ STM32_DDR_BASE, bufsize, bus_width);
+
+ patterns =
+ (const u32 **)(bus_width == 16 ? patterns_x16 : patterns_x32);
+
+ for (i = 0; i < NB_PATTERN; i++) {
+ printf("test data pattern %s:", patterns_comments[i]);
+ pattern_res = test_loop(patterns[i], (u32 *)STM32_DDR_BASE,
+ bufsize);
+ if (pattern_res != TEST_PASSED) {
+ printf("Failed\n");
+ return pattern_res;
+ }
+ printf("Passed\n");
+ }
+
+ return res;
+}
+
+/**********************************************************************
+ *
+ * Function: pattern test with size
+ *
+ * Description: loop for write pattern
+ *
+ **********************************************************************/
+
+static enum test_result test_loop_size(const u32 *pattern, u32 size,
+ u32 *address,
+ const u32 bufsize)
+{
+ int i, j;
+ enum test_result res = TEST_PASSED;
+ u32 *p = address;
+
+ for (i = 0; i < bufsize; i += size * 4) {
+ for (j = 0; j < size ; j++, p++)
+ *p = pattern[j];
+ if (progress(i)) {
+ res = TEST_FAILED;
+ goto end;
+ }
+ }
+
+ puts("\ncheck buffer");
+ p = address;
+ for (i = 0; i < bufsize; i += size * 4) {
+ for (j = 0; j < size; j++, p++)
+ if (check_addr((u32)p, pattern[j])) {
+ res = TEST_FAILED;
+ goto end;
+ }
+ if (progress(i)) {
+ res = TEST_FAILED;
+ goto end;
+ }
+ }
+
+end:
+ puts("\n");
+ return res;
+}
+
+static enum test_result test_checkboard(struct stm32mp1_ddrctl *ctl,
+ struct stm32mp1_ddrphy *phy,
+ char *string, int argc, char *argv[])
+{
+ enum test_result res = TEST_PASSED;
+ u32 bufsize, nb_loop, loop = 0, addr;
+ int i;
+
+ u32 checkboard[2] = {0x55555555, 0xAAAAAAAA};
+
+ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
+ return TEST_ERROR;
+ if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
+ return TEST_ERROR;
+ if (get_addr(string, argc, argv, 2, &addr))
+ return TEST_ERROR;
+
+ printf("running %d loops at 0x%08x length 0x%x\n",
+ nb_loop, addr, bufsize);
+ while (1) {
+ for (i = 0; i < 2; i++) {
+ res = test_loop_size(checkboard, 2, (u32 *)addr,
+ bufsize);
+ if (res)
+ return res;
+ checkboard[0] = ~checkboard[0];
+ checkboard[1] = ~checkboard[1];
+ }
+ if (test_loop_end(&loop, nb_loop, 1))
+ break;
+ }
+ sprintf(string, "no error for %d loops at 0x%08x length 0x%x",
+ loop, addr, bufsize);
+
+ return res;
+}
+
+static enum test_result test_blockseq(struct stm32mp1_ddrctl *ctl,
+ struct stm32mp1_ddrphy *phy,
+ char *string, int argc, char *argv[])
+{
+ enum test_result res = TEST_PASSED;
+ u32 bufsize, nb_loop, loop = 0, addr, value;
+ int i;
+
+ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
+ return TEST_ERROR;
+ if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
+ return TEST_ERROR;
+ if (get_addr(string, argc, argv, 2, &addr))
+ return TEST_ERROR;
+
+ printf("running %d loops at 0x%08x length 0x%x\n",
+ nb_loop, addr, bufsize);
+ while (1) {
+ for (i = 0; i < 256; i++) {
+ value = i | i << 8 | i << 16 | i << 24;
+ printf("pattern = %08x", value);
+ res = test_loop_size(&value, 1, (u32 *)addr, bufsize);
+ if (res != TEST_PASSED)
+ return res;
+ }
+ if (test_loop_end(&loop, nb_loop, 1))
+ break;
+ }
+ sprintf(string, "no error for %d loops at 0x%08x length 0x%x",
+ loop, addr, bufsize);
+
+ return res;
+}
+
+static enum test_result test_walkbit0(struct stm32mp1_ddrctl *ctl,
+ struct stm32mp1_ddrphy *phy,
+ char *string, int argc, char *argv[])
+{
+ enum test_result res = TEST_PASSED;
+ u32 bufsize, nb_loop, loop = 0, addr, value;
+ int i;
+
+ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
+ return TEST_ERROR;
+ if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
+ return TEST_ERROR;
+ if (get_addr(string, argc, argv, 2, &addr))
+ return TEST_ERROR;
+
+ printf("running %d loops at 0x%08x length 0x%x\n",
+ nb_loop, addr, bufsize);
+ while (1) {
+ for (i = 0; i < 64; i++) {
+ if (i < 32)
+ value = 1 << i;
+ else
+ value = 1 << (63 - i);
+
+ printf("pattern = %08x", value);
+ res = test_loop_size(&value, 1, (u32 *)addr, bufsize);
+ if (res != TEST_PASSED)
+ return res;
+ }
+ if (test_loop_end(&loop, nb_loop, 1))
+ break;
+ }
+ sprintf(string, "no error for %d loops at 0x%08x length 0x%x",
+ loop, addr, bufsize);
+
+ return res;
+}
+
+static enum test_result test_walkbit1(struct stm32mp1_ddrctl *ctl,
+ struct stm32mp1_ddrphy *phy,
+ char *string, int argc, char *argv[])
+{
+ enum test_result res = TEST_PASSED;
+ u32 bufsize, nb_loop, loop = 0, addr, value;
+ int i;
+
+ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
+ return TEST_ERROR;
+ if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
+ return TEST_ERROR;
+ if (get_addr(string, argc, argv, 2, &addr))
+ return TEST_ERROR;
+
+ printf("running %d loops at 0x%08x length 0x%x\n",
+ nb_loop, addr, bufsize);
+ while (1) {
+ for (i = 0; i < 64; i++) {
+ if (i < 32)
+ value = ~(1 << i);
+ else
+ value = ~(1 << (63 - i));
+
+ printf("pattern = %08x", value);
+ res = test_loop_size(&value, 1, (u32 *)addr, bufsize);
+ if (res != TEST_PASSED)
+ return res;
+ }
+ if (test_loop_end(&loop, nb_loop, 1))
+ break;
+ }
+ sprintf(string, "no error for %d loops at 0x%08x length 0x%x",
+ loop, addr, bufsize);
+
+ return res;
+}
+
+/*
+ * try to catch bad bits which are dependent on the current values of
+ * surrounding bits in either the same word32
+ */
+static enum test_result test_bitspread(struct stm32mp1_ddrctl *ctl,
+ struct stm32mp1_ddrphy *phy,
+ char *string, int argc, char *argv[])
+{
+ enum test_result res = TEST_PASSED;
+ u32 bufsize, nb_loop, loop = 0, addr, bitspread[4];
+ int i, j;
+
+ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
+ return TEST_ERROR;
+ if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
+ return TEST_ERROR;
+ if (get_addr(string, argc, argv, 2, &addr))
+ return TEST_ERROR;
+
+ printf("running %d loops at 0x%08x length 0x%x\n",
+ nb_loop, addr, bufsize);
+ while (1) {
+ for (i = 1; i < 32; i++) {
+ for (j = 0; j < i; j++) {
+ if (i < 32)
+ bitspread[0] = (1 << i) | (1 << j);
+ else
+ bitspread[0] = (1 << (63 - i)) |
+ (1 << (63 - j));
+ bitspread[1] = bitspread[0];
+ bitspread[2] = ~bitspread[0];
+ bitspread[3] = ~bitspread[0];
+ printf("pattern = %08x", bitspread[0]);
+
+ res = test_loop_size(bitspread, 4, (u32 *)addr,
+ bufsize);
+ if (res != TEST_PASSED)
+ return res;
+ }
+ }
+ if (test_loop_end(&loop, nb_loop, 1))
+ break;
+ }
+ sprintf(string, "no error for %d loops at 0x%08x length 0x%x",
+ loop, addr, bufsize);
+
+ return res;
+}
+
+static enum test_result test_bitflip(struct stm32mp1_ddrctl *ctl,
+ struct stm32mp1_ddrphy *phy,
+ char *string, int argc, char *argv[])
+{
+ enum test_result res = TEST_PASSED;
+ u32 bufsize, nb_loop, loop = 0, addr;
+ int i;
+
+ u32 bitflip[4];
+
+ if (get_bufsize(string, argc, argv, 0, &bufsize, 4 * 1024))
+ return TEST_ERROR;
+ if (get_nb_loop(string, argc, argv, 1, &nb_loop, 1))
+ return TEST_ERROR;
+ if (get_addr(string, argc, argv, 2, &addr))
+ return TEST_ERROR;
+
+ printf("running %d loops at 0x%08x length 0x%x\n",
+ nb_loop, addr, bufsize);
+ while (1) {
+ for (i = 0; i < 32; i++) {
+ bitflip[0] = 1 << i;
+ bitflip[1] = bitflip[0];
+ bitflip[2] = ~bitflip[0];
+ bitflip[3] = bitflip[2];
+ printf("pattern = %08x", bitflip[0]);
+
+ res = test_loop_size(bitflip, 4, (u32 *)addr, bufsize);
+ if (res != TEST_PASSED)
+ return res;
+ }
+ if (test_loop_end(&loop, nb_loop, 1))
+ break;
+ }
+ sprintf(string, "no error for %d loops at 0x%08x length 0x%x",
+ loop, addr, bufsize);
+
+ return res;
+}
+
+/**********************************************************************
+ *
+ * Function: infinite read access to DDR
+ *
+ * Description: continuous read the same pattern at the same address
+ *
+ **********************************************************************/
+static enum test_result test_read(struct stm32mp1_ddrctl *ctl,
+ struct stm32mp1_ddrphy *phy,
+ char *string, int argc, char *argv[])
+{
+ u32 *addr;
+ u32 data;
+ u32 loop = 0;
+ bool random = false;
+
+ if (get_addr(string, argc, argv, 0, (u32 *)&addr))
+ return TEST_ERROR;
+
+ if ((u32)addr == ADDR_INVALID) {
+ printf("random ");
+ random = true;
+ }
+
+ printf("running at 0x%08x\n", (u32)addr);
+
+ while (1) {
+ if (random)
+ addr = (u32 *)(STM32_DDR_BASE +
+ (rand() & (STM32_DDR_SIZE - 1) & ~0x3));
+ data = readl(addr);
+ if (test_loop_end(&loop, 0, 1000))
+ break;
+ }
+ sprintf(string, "0x%x: %x", (u32)addr, data);
+
+ return TEST_PASSED;
+}
+
+/**********************************************************************
+ *
+ * Function: infinite write access to DDR
+ *
+ * Description: continuous write the same pattern at the same address
+ *
+ **********************************************************************/
+static enum test_result test_write(struct stm32mp1_ddrctl *ctl,
+ struct stm32mp1_ddrphy *phy,
+ char *string, int argc, char *argv[])
+{
+ u32 *addr;
+ u32 data = 0xA5A5AA55;
+ u32 loop = 0;
+ bool random = false;
+
+ if (get_addr(string, argc, argv, 0, (u32 *)&addr))
+ return TEST_ERROR;
+
+ if ((u32)addr == ADDR_INVALID) {
+ printf("random ");
+ random = true;
+ }
+
+ printf("running at 0x%08x\n", (u32)addr);
+
+ while (1) {
+ if (random) {
+ addr = (u32 *)(STM32_DDR_BASE +
+ (rand() & (STM32_DDR_SIZE - 1) & ~0x3));
+ data = rand();
+ }
+ writel(data, addr);
+ if (test_loop_end(&loop, 0, 1000))
+ break;
+ }
+ sprintf(string, "0x%x: %x", (u32)addr, data);
+
+ return TEST_PASSED;
+}
+
+#define NB_TEST_INFINITE 2
+static enum test_result test_all(struct stm32mp1_ddrctl *ctl,
+ struct stm32mp1_ddrphy *phy,
+ char *string, int argc, char *argv[])
+{
+ enum test_result res = TEST_PASSED, result;
+ int i, nb_error = 0;
+ u32 loop = 0, nb_loop;
+
+ if (get_nb_loop(string, argc, argv, 0, &nb_loop, 1))
+ return TEST_ERROR;
+
+ while (!nb_error) {
+ /* execute all the test except the lasts which are infinite */
+ for (i = 1; i < test_nb - NB_TEST_INFINITE; i++) {
+ printf("execute %d:%s\n", (int)i, test[i].name);
+ result = test[i].fct(ctl, phy, string, 0, NULL);
+ printf("result %d:%s = ", (int)i, test[i].name);
+ if (result != TEST_PASSED) {
+ nb_error++;
+ res = TEST_FAILED;
+ puts("Failed");
+ } else {
+ puts("Passed");
+ }
+ puts("\n\n");
+ }
+ printf("loop %d: %d/%d test failed\n\n\n",
+ loop + 1, nb_error, test_nb - NB_TEST_INFINITE);
+ if (test_loop_end(&loop, nb_loop, 1))
+ break;
+ }
+ if (res != TEST_PASSED) {
+ sprintf(string, "loop %d: %d/%d test failed", loop, nb_error,
+ test_nb - NB_TEST_INFINITE);
+ } else {
+ sprintf(string, "loop %d: %d tests passed", loop,
+ test_nb - NB_TEST_INFINITE);
+ }
+ return res;
+}
+
+/****************************************************************
+ * TEST Description
+ ****************************************************************/
+
+const struct test_desc test[] = {
+ {test_all, "All", "[loop]", "Execute all tests", 1 },
+ {test_databus, "Simple DataBus", "[addr]",
+ "Verifies each data line by walking 1 on fixed address",
+ 1
+ },
+ {databuswalk0, "DataBusWalking0", "[loop] [addr]",
+ "Verifies each data bus signal can be driven low (32 word burst)",
+ 2
+ },
+ {databuswalk1, "DataBusWalking1", "[loop] [addr]",
+ "Verifies each data bus signal can be driven high (32 word burst)",
+ 2
+ },
+ {test_addressbus, "AddressBus", "[size] [addr]",
+ "Verifies each relevant bits of the address and checking for aliasing",
+ 2
+ },
+ {test_memdevice, "MemDevice", "[size] [addr]",
+ "Test the integrity of a physical memory (test every storage bit in the region)",
+ 2
+ },
+ {test_sso, "SimultaneousSwitchingOutput", "[size] [addr] ",
+ "Stress the data bus over an address range",
+ 2
+ },
+ {test_noise, "Noise", "[pattern] [addr]",
+ "Verifies r/w while forcing switching of all data bus lines.",
+ 3
+ },
+ {test_noise_burst, "NoiseBurst", "[size] [pattern] [addr]",
+ "burst transfers while forcing switching of the data bus lines",
+ 3
+ },
+ {test_random, "Random", "[size] [loop] [addr]",
+ "Verifies r/w and memcopy(burst for pseudo random value.",
+ 3
+ },
+ {test_freq_pattern, "FrequencySelectivePattern ", "[size]",
+ "write & test patterns: Mostly Zero, Mostly One and F/n",
+ 1
+ },
+ {test_blockseq, "BlockSequential", "[size] [loop] [addr]",
+ "test incremental pattern",
+ 3
+ },
+ {test_checkboard, "Checkerboard", "[size] [loop] [addr]",
+ "test checker pattern",
+ 3
+ },
+ {test_bitspread, "BitSpread", "[size] [loop] [addr]",
+ "test Bit Spread pattern",
+ 3
+ },
+ {test_bitflip, "BitFlip", "[size] [loop] [addr]",
+ "test Bit Flip pattern",
+ 3
+ },
+ {test_walkbit0, "WalkingOnes", "[size] [loop] [addr]",
+ "test Walking Ones pattern",
+ 3
+ },
+ {test_walkbit1, "WalkingZeroes", "[size] [loop] [addr]",
+ "test Walking Zeroes pattern",
+ 3
+ },
+ /* need to the the 2 last one (infinite) : skipped for test all */
+ {test_read, "infinite read", "[addr]",
+ "basic test : infinite read access", 1},
+ {test_write, "infinite write", "[addr]",
+ "basic test : infinite write access", 1},
+};
+
+const int test_nb = ARRAY_SIZE(test);
diff --git a/drivers/ram/stm32mp1/stm32mp1_tests.h b/drivers/ram/stm32mp1/stm32mp1_tests.h
new file mode 100644
index 0000000000..55f5d6d93b
--- /dev/null
+++ b/drivers/ram/stm32mp1/stm32mp1_tests.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
+/*
+ * Copyright (C) 2019, STMicroelectronics - All Rights Reserved
+ */
+
+#ifndef _RAM_STM32MP1_TESTS_H_
+#define _RAM_STM32MP1_TESTS_H_
+
+#include "stm32mp1_ddr_regs.h"
+
+enum test_result {
+ TEST_PASSED,
+ TEST_FAILED,
+ TEST_ERROR
+};
+
+struct test_desc {
+ enum test_result (*fct)(struct stm32mp1_ddrctl *ctl,
+ struct stm32mp1_ddrphy *phy,
+ char *string,
+ int argc, char *argv[]);
+ const char *name;
+ const char *usage;
+ const char *help;
+ u8 max_args;
+};
+
+extern const struct test_desc test[];
+extern const int test_nb;
+
+extern const struct test_desc tuning[];
+extern const int tuning_nb;
+
+#endif
diff --git a/drivers/ram/stm32mp1/stm32mp1_tuning.c b/drivers/ram/stm32mp1/stm32mp1_tuning.c
new file mode 100644
index 0000000000..4e1c1fab54
--- /dev/null
+++ b/drivers/ram/stm32mp1/stm32mp1_tuning.c
@@ -0,0 +1,1380 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2019, STMicroelectronics - All Rights Reserved
+ */
+#include <common.h>
+#include <console.h>
+#include <clk.h>
+#include <ram.h>
+#include <reset.h>
+#include <asm/io.h>
+
+#include "stm32mp1_ddr_regs.h"
+#include "stm32mp1_ddr.h"
+#include "stm32mp1_tests.h"
+
+#define MAX_DQS_PHASE_IDX _144deg
+#define MAX_DQS_UNIT_IDX 7
+#define MAX_GSL_IDX 5
+#define MAX_GPS_IDX 3
+
+/* Number of bytes used in this SW. ( min 1--> max 4). */
+#define NUM_BYTES 4
+
+enum dqs_phase_enum {
+ _36deg = 0,
+ _54deg = 1,
+ _72deg = 2,
+ _90deg = 3,
+ _108deg = 4,
+ _126deg = 5,
+ _144deg = 6
+};
+
+/* BIST Result struct */
+struct BIST_result {
+ /* Overall test result:
+ * 0 Fail (any bit failed) ,
+ * 1 Success (All bits success)
+ */
+ bool test_result;
+ /* 1: true, all fail / 0: False, not all bits fail */
+ bool all_bits_fail;
+ bool bit_i_test_result[8]; /* 0 fail / 1 success */
+};
+
+/* a struct that defines tuning parameters of a byte. */
+struct tuning_position {
+ u8 phase; /* DQS phase */
+ u8 unit; /* DQS unit delay */
+ u32 bits_delay; /* Bits deskew in this byte */
+};
+
+/* 36deg, 54deg, 72deg, 90deg, 108deg, 126deg, 144deg */
+const u8 dx_dll_phase[7] = {3, 2, 1, 0, 14, 13, 12};
+
+static u8 BIST_error_max = 1;
+static u32 BIST_seed = 0x1234ABCD;
+
+static u8 get_nb_bytes(struct stm32mp1_ddrctl *ctl)
+{
+ u32 data_bus = readl(&ctl->mstr) & DDRCTRL_MSTR_DATA_BUS_WIDTH_MASK;
+ u8 nb_bytes = NUM_BYTES;
+
+ switch (data_bus) {
+ case DDRCTRL_MSTR_DATA_BUS_WIDTH_HALF:
+ nb_bytes /= 2;
+ break;
+ case DDRCTRL_MSTR_DATA_BUS_WIDTH_QUARTER:
+ nb_bytes /= 4;
+ break;
+ default:
+ break;
+ }
+
+ return nb_bytes;
+}
+
+static void itm_soft_reset(struct stm32mp1_ddrphy *phy)
+{
+ stm32mp1_ddrphy_init(phy, DDRPHYC_PIR_ITMSRST);
+}
+
+/* Read DQ unit delay register and provides the retrieved value for DQS
+ * We are assuming that we have the same delay when clocking
+ * by DQS and when clocking by DQSN
+ */
+static u8 DQ_unit_index(struct stm32mp1_ddrphy *phy, u8 byte, u8 bit)
+{
+ u32 index;
+ u32 addr = DXNDQTR(phy, byte);
+
+ /* We are assuming that we have the same delay when clocking by DQS
+ * and when clocking by DQSN : use only the low bits
+ */
+ index = (readl(addr) >> DDRPHYC_DXNDQTR_DQDLY_SHIFT(bit))
+ & DDRPHYC_DXNDQTR_DQDLY_LOW_MASK;
+
+ pr_debug("%s: [%x]: %x => DQ unit index = %x\n",
+ __func__, addr, readl(addr), index);
+
+ return index;
+}
+
+/* Sets the DQS phase delay for a byte lane.
+ *phase delay is specified by giving the index of the desired delay
+ * in the dx_dll_phase array.
+ */
+static void DQS_phase_delay(struct stm32mp1_ddrphy *phy, u8 byte, u8 phase_idx)
+{
+ u8 sdphase_val = 0;
+
+ /* Write DXNDLLCR.SDPHASE = dx_dll_phase(phase_index); */
+ sdphase_val = dx_dll_phase[phase_idx];
+ clrsetbits_le32(DXNDLLCR(phy, byte),
+ DDRPHYC_DXNDLLCR_SDPHASE_MASK,
+ sdphase_val << DDRPHYC_DXNDLLCR_SDPHASE_SHIFT);
+}
+
+/* Sets the DQS unit delay for a byte lane.
+ * unit delay is specified by giving the index of the desired delay
+ * for dgsdly and dqsndly (same value).
+ */
+static void DQS_unit_delay(struct stm32mp1_ddrphy *phy,
+ u8 byte, u8 unit_dly_idx)
+{
+ /* Write the same value in DXNDQSTR.DQSDLY and DXNDQSTR.DQSNDLY */
+ clrsetbits_le32(DXNDQSTR(phy, byte),
+ DDRPHYC_DXNDQSTR_DQSDLY_MASK |
+ DDRPHYC_DXNDQSTR_DQSNDLY_MASK,
+ (unit_dly_idx << DDRPHYC_DXNDQSTR_DQSDLY_SHIFT) |
+ (unit_dly_idx << DDRPHYC_DXNDQSTR_DQSNDLY_SHIFT));
+
+ /* After changing this value, an ITM soft reset (PIR.ITMSRST=1,
+ * plus PIR.INIT=1) must be issued.
+ */
+ stm32mp1_ddrphy_init(phy, DDRPHYC_PIR_ITMSRST);
+}
+
+/* Sets the DQ unit delay for a bit line in particular byte lane.
+ * unit delay is specified by giving the desired delay
+ */
+static void set_DQ_unit_delay(struct stm32mp1_ddrphy *phy,
+ u8 byte, u8 bit,
+ u8 dq_delay_index)
+{
+ u8 dq_bit_delay_val = dq_delay_index | (dq_delay_index << 2);
+
+ /* same value on delay for clock DQ an DQS_b */
+ clrsetbits_le32(DXNDQTR(phy, byte),
+ DDRPHYC_DXNDQTR_DQDLY_MASK
+ << DDRPHYC_DXNDQTR_DQDLY_SHIFT(bit),
+ dq_bit_delay_val << DDRPHYC_DXNDQTR_DQDLY_SHIFT(bit));
+}
+
+static void set_r0dgsl_delay(struct stm32mp1_ddrphy *phy,
+ u8 byte, u8 r0dgsl_idx)
+{
+ clrsetbits_le32(DXNDQSTR(phy, byte),
+ DDRPHYC_DXNDQSTR_R0DGSL_MASK,
+ r0dgsl_idx << DDRPHYC_DXNDQSTR_R0DGSL_SHIFT);
+}
+
+static void set_r0dgps_delay(struct stm32mp1_ddrphy *phy,
+ u8 byte, u8 r0dgps_idx)
+{
+ clrsetbits_le32(DXNDQSTR(phy, byte),
+ DDRPHYC_DXNDQSTR_R0DGPS_MASK,
+ r0dgps_idx << DDRPHYC_DXNDQSTR_R0DGPS_SHIFT);
+}
+
+/* Basic BIST configuration for data lane tests. */
+static void config_BIST(struct stm32mp1_ddrphy *phy)
+{
+ /* Selects the SDRAM bank address to be used during BIST. */
+ u32 bbank = 0;
+ /* Selects the SDRAM row address to be used during BIST. */
+ u32 brow = 0;
+ /* Selects the SDRAM column address to be used during BIST. */
+ u32 bcol = 0;
+ /* Selects the value by which the SDRAM address is incremented
+ * for each write/read access.
+ */
+ u32 bainc = 0x00000008;
+ /* Specifies the maximum SDRAM rank to be used during BIST.
+ * The default value is set to maximum ranks minus 1.
+ * must be 0 with single rank
+ */
+ u32 bmrank = 0;
+ /* Selects the SDRAM rank to be used during BIST.
+ * must be 0 with single rank
+ */
+ u32 brank = 0;
+ /* Specifies the maximum SDRAM bank address to be used during
+ * BIST before the address & increments to the next rank.
+ */
+ u32 bmbank = 1;
+ /* Specifies the maximum SDRAM row address to be used during
+ * BIST before the address & increments to the next bank.
+ */
+ u32 bmrow = 0x7FFF; /* To check */
+ /* Specifies the maximum SDRAM column address to be used during
+ * BIST before the address & increments to the next row.
+ */
+ u32 bmcol = 0x3FF; /* To check */
+ u32 bmode_conf = 0x00000001; /* DRam mode */
+ u32 bdxen_conf = 0x00000001; /* BIST on Data byte */
+ u32 bdpat_conf = 0x00000002; /* Select LFSR pattern */
+
+ /*Setup BIST for DRAM mode, and LFSR-random data pattern.*/
+ /*Write BISTRR.BMODE = 1?b1;*/
+ /*Write BISTRR.BDXEN = 1?b1;*/
+ /*Write BISTRR.BDPAT = 2?b10;*/
+
+ /* reset BIST */
+ writel(0x3, &phy->bistrr);
+
+ writel((bmode_conf << 3) | (bdxen_conf << 14) | (bdpat_conf << 17),
+ &phy->bistrr);
+
+ /*Setup BIST Word Count*/
+ /*Write BISTWCR.BWCNT = 16?b0008;*/
+ writel(0x00000200, &phy->bistwcr); /* A multiple of BL/2 */
+
+ writel(bcol | (brow << 12) | (bbank << 28), &phy->bistar0);
+ writel(brank | (bmrank << 2) | (bainc << 4), &phy->bistar1);
+
+ /* To check this line : */
+ writel(bmcol | (bmrow << 12) | (bmbank << 28), &phy->bistar2);
+}
+
+/* Select the Byte lane to be tested by BIST. */
+static void BIST_datx8_sel(struct stm32mp1_ddrphy *phy, u8 datx8)
+{
+ clrsetbits_le32(&phy->bistrr,
+ DDRPHYC_BISTRR_BDXSEL_MASK,
+ datx8 << DDRPHYC_BISTRR_BDXSEL_SHIFT);
+
+ /*(For example, selecting Byte Lane 3, BISTRR.BDXSEL = 4?b0011)*/
+ /* Write BISTRR.BDXSEL = datx8; */
+}
+
+/* Perform BIST Write_Read test on a byte lane and return test result. */
+static void BIST_test(struct stm32mp1_ddrphy *phy, u8 byte,
+ struct BIST_result *bist)
+{
+ bool result = true; /* BIST_SUCCESS */
+ u32 cnt = 0;
+ u32 error = 0;
+
+ bist->test_result = true;
+
+run:
+ itm_soft_reset(phy);
+
+ /*Perform BIST Reset*/
+ /* Write BISTRR.BINST = 3?b011; */
+ clrsetbits_le32(&phy->bistrr,
+ 0x00000007,
+ 0x00000003);
+
+ /*Re-seed LFSR*/
+ /* Write BISTLSR.SEED = 32'h1234ABCD; */
+ if (BIST_seed)
+ writel(BIST_seed, &phy->bistlsr);
+ else
+ writel(rand(), &phy->bistlsr);
+
+ /* some delay to reset BIST */
+ mdelay(1);
+
+ /*Perform BIST Run*/
+ clrsetbits_le32(&phy->bistrr,
+ 0x00000007,
+ 0x00000001);
+ /* Write BISTRR.BINST = 3?b001; */
+
+ /* Wait for a number of CTL clocks before reading BIST register*/
+ /* Wait 300 ctl_clk cycles; ... IS it really needed?? */
+ /* Perform BIST Instruction Stop*/
+ /* Write BISTRR.BINST = 3?b010;*/
+
+ /* poll on BISTGSR.BDONE. If 0, wait. ++TODO Add timeout */
+ while (!(readl(&phy->bistgsr) & DDRPHYC_BISTGSR_BDDONE))
+ ;
+
+ /*Check if received correct number of words*/
+ /* if (Read BISTWCSR.DXWCNT = Read BISTWCR.BWCNT) */
+ if (((readl(&phy->bistwcsr)) >> DDRPHYC_BISTWCSR_DXWCNT_SHIFT) ==
+ readl(&phy->bistwcr)) {
+ /*Determine if there is a data comparison error*/
+ /* if (Read BISTGSR.BDXERR = 1?b0) */
+ if (readl(&phy->bistgsr) & DDRPHYC_BISTGSR_BDXERR)
+ result = false; /* BIST_FAIL; */
+ else
+ result = true; /* BIST_SUCCESS; */
+ } else {
+ result = false; /* BIST_FAIL; */
+ }
+
+ /* loop while success */
+ cnt++;
+ if (result && cnt != 1000)
+ goto run;
+
+ if (!result)
+ error++;
+
+ if (error < BIST_error_max) {
+ if (cnt != 1000)
+ goto run;
+ bist->test_result = true;
+ } else {
+ bist->test_result = false;
+ }
+}
+
+/* After running the deskew algo, this function applies the new DQ delays
+ * by reading them from the array "deskew_delay"and writing in PHY registers.
+ * The bits that are not deskewed parfectly (too much skew on them,
+ * or data eye very wide) are marked in the array deskew_non_converge.
+ */
+static void apply_deskew_results(struct stm32mp1_ddrphy *phy, u8 byte,
+ u8 deskew_delay[NUM_BYTES][8],
+ u8 deskew_non_converge[NUM_BYTES][8])
+{
+ u8 bit_i;
+ u8 index;
+
+ for (bit_i = 0; bit_i < 8; bit_i++) {
+ set_DQ_unit_delay(phy, byte, bit_i, deskew_delay[byte][bit_i]);
+ index = DQ_unit_index(phy, byte, bit_i);
+ pr_debug("Byte %d ; bit %d : The new DQ delay (%d) index=%d [delta=%d, 3 is the default]",
+ byte, bit_i, deskew_delay[byte][bit_i],
+ index, index - 3);
+ printf("Byte %d, bit %d, DQ delay = %d",
+ byte, bit_i, deskew_delay[byte][bit_i]);
+ if (deskew_non_converge[byte][bit_i] == 1)
+ pr_debug(" - not converged : still more skew");
+ printf("\n");
+ }
+}
+
+/* DQ Bit de-skew algorithm.
+ * Deskews data lines as much as possible.
+ * 1. Add delay to DQS line until finding the failure
+ * (normally a hold time violation)
+ * 2. Reduce DQS line by small steps until finding the very first time
+ * we go back to "Pass" condition.
+ * 3. For each DQ line, Reduce DQ delay until finding the very first failure
+ * (normally a hold time fail)
+ * 4. When all bits are at their first failure delay, we can consider them
+ * aligned.
+ * Handle conrer situation (Can't find Pass-fail, or fail-pass transitions
+ * at any step)
+ * TODO Provide a return Status. Improve doc
+ */
+static enum test_result bit_deskew(struct stm32mp1_ddrctl *ctl,
+ struct stm32mp1_ddrphy *phy, char *string)
+{
+ /* New DQ delay value (index), set during Deskew algo */
+ u8 deskew_delay[NUM_BYTES][8];
+ /*If there is still skew on a bit, mark this bit. */
+ u8 deskew_non_converge[NUM_BYTES][8];
+ struct BIST_result result;
+ s8 dqs_unit_delay_index = 0;
+ u8 datx8 = 0;
+ u8 bit_i = 0;
+ s8 phase_idx = 0;
+ s8 bit_i_delay_index = 0;
+ u8 success = 0;
+ struct tuning_position last_right_ok;
+ u8 force_stop = 0;
+ u8 fail_found;
+ u8 error = 0;
+ u8 nb_bytes = get_nb_bytes(ctl);
+ /* u8 last_pass_dqs_unit = 0; */
+
+ memset(deskew_delay, 0, sizeof(deskew_delay));
+ memset(deskew_non_converge, 0, sizeof(deskew_non_converge));
+
+ /*Disable DQS Drift Compensation*/
+ clrbits_le32(&phy->pgcr, DDRPHYC_PGCR_DFTCMP);
+ /*Disable all bytes*/
+ /* Disable automatic power down of DLL and IOs when disabling
+ * a byte (To avoid having to add programming and delay
+ * for a DLL re-lock when later re-enabling a disabled Byte Lane)
+ */
+ clrbits_le32(&phy->pgcr, DDRPHYC_PGCR_PDDISDX);
+
+ /* Disable all data bytes */
+ clrbits_le32(&phy->dx0gcr, DDRPHYC_DXNGCR_DXEN);
+ clrbits_le32(&phy->dx1gcr, DDRPHYC_DXNGCR_DXEN);
+ clrbits_le32(&phy->dx2gcr, DDRPHYC_DXNGCR_DXEN);
+ clrbits_le32(&phy->dx3gcr, DDRPHYC_DXNGCR_DXEN);
+
+ /* Config the BIST block */
+ config_BIST(phy);
+ pr_debug("BIST Config done.\n");
+
+ /* Train each byte */
+ for (datx8 = 0; datx8 < nb_bytes; datx8++) {
+ if (ctrlc()) {
+ sprintf(string, "interrupted at byte %d/%d, error=%d",
+ datx8 + 1, nb_bytes, error);
+ return TEST_FAILED;
+ }
+ pr_debug("\n======================\n");
+ pr_debug("Start deskew byte %d .\n", datx8);
+ pr_debug("======================\n");
+ /* Enable Byte (DXNGCR, bit DXEN) */
+ setbits_le32(DXNGCR(phy, datx8), DDRPHYC_DXNGCR_DXEN);
+
+ /* Select the byte lane for comparison of read data */
+ BIST_datx8_sel(phy, datx8);
+
+ /* Set all DQDLYn to maximum value. All bits within the byte
+ * will be delayed with DQSTR = 2 instead of max = 3
+ * to avoid inter bits fail influence
+ */
+ writel(0xAAAAAAAA, DXNDQTR(phy, datx8));
+
+ /* Set the DQS phase delay to 90 DEG (default).
+ * What is defined here is the index of the desired config
+ * in the PHASE array.
+ */
+ phase_idx = _90deg;
+
+ /* Set DQS unit delay to the max value. */
+ dqs_unit_delay_index = MAX_DQS_UNIT_IDX;
+ DQS_unit_delay(phy, datx8, dqs_unit_delay_index);
+ DQS_phase_delay(phy, datx8, phase_idx);
+
+ /* Issue a DLL soft reset */
+ clrbits_le32(DXNDLLCR(phy, datx8), DDRPHYC_DXNDLLCR_DLLSRST);
+ setbits_le32(DXNDLLCR(phy, datx8), DDRPHYC_DXNDLLCR_DLLSRST);
+
+ /* Test this typical init condition */
+ BIST_test(phy, datx8, &result);
+ success = result.test_result;
+
+ /* If the test pass in this typical condition,
+ * start the algo with it.
+ * Else, look for Pass init condition
+ */
+ if (!success) {
+ pr_debug("Fail at init condtion. Let's look for a good init condition.\n");
+ success = 0; /* init */
+ /* Make sure we start with a PASS condition before
+ * looking for a fail condition.
+ * Find the first PASS PHASE condition
+ */
+
+ /* escape if we find a PASS */
+ pr_debug("increase Phase idx\n");
+ while (!success && (phase_idx <= MAX_DQS_PHASE_IDX)) {
+ DQS_phase_delay(phy, datx8, phase_idx);
+ BIST_test(phy, datx8, &result);
+ success = result.test_result;
+ phase_idx++;
+ }
+ /* if ended with success
+ * ==>> Restore the fist success condition
+ */
+ if (success)
+ phase_idx--; /* because it ended with ++ */
+ }
+ if (ctrlc()) {
+ sprintf(string, "interrupted at byte %d/%d, error=%d",
+ datx8 + 1, nb_bytes, error);
+ return TEST_FAILED;
+ }
+ /* We couldn't find a successful condition, its seems
+ * we have hold violation, lets try reduce DQS_unit Delay
+ */
+ if (!success) {
+ /* We couldn't find a successful condition, its seems
+ * we have hold violation, lets try reduce DQS_unit
+ * Delay
+ */
+ pr_debug("Still fail. Try decrease DQS Unit delay\n");
+
+ phase_idx = 0;
+ dqs_unit_delay_index = 0;
+ DQS_phase_delay(phy, datx8, phase_idx);
+
+ /* escape if we find a PASS */
+ while (!success &&
+ (dqs_unit_delay_index <=
+ MAX_DQS_UNIT_IDX)) {
+ DQS_unit_delay(phy, datx8,
+ dqs_unit_delay_index);
+ BIST_test(phy, datx8, &result);
+ success = result.test_result;
+ dqs_unit_delay_index++;
+ }
+ if (success) {
+ /* Restore the first success condition*/
+ dqs_unit_delay_index--;
+ /* last_pass_dqs_unit = dqs_unit_delay_index;*/
+ DQS_unit_delay(phy, datx8,
+ dqs_unit_delay_index);
+ } else {
+ /* No need to continue,
+ * there is no pass region.
+ */
+ force_stop = 1;
+ }
+ }
+
+ /* There is an initial PASS condition
+ * Look for the first failing condition by PHASE stepping.
+ * This part of the algo can finish without converging.
+ */
+ if (force_stop) {
+ printf("Result: Failed ");
+ printf("[Cannot Deskew lines, ");
+ printf("there is no PASS region]\n");
+ error++;
+ continue;
+ }
+ if (ctrlc()) {
+ sprintf(string, "interrupted at byte %d/%d, error=%d",
+ datx8 + 1, nb_bytes, error);
+ return TEST_FAILED;
+ }
+
+ pr_debug("there is a pass region for phase idx %d\n",
+ phase_idx);
+ pr_debug("Step1: Find the first failing condition\n");
+ /* Look for the first failing condition by PHASE stepping.
+ * This part of the algo can finish without converging.
+ */
+
+ /* escape if we find a fail (hold time violation)
+ * condition at any bit or if out of delay range.
+ */
+ while (success && (phase_idx <= MAX_DQS_PHASE_IDX)) {
+ DQS_phase_delay(phy, datx8, phase_idx);
+ BIST_test(phy, datx8, &result);
+ success = result.test_result;
+ phase_idx++;
+ }
+ if (ctrlc()) {
+ sprintf(string, "interrupted at byte %d/%d, error=%d",
+ datx8 + 1, nb_bytes, error);
+ return TEST_FAILED;
+ }
+
+ /* if the loop ended with a failing condition at any bit,
+ * lets look for the first previous success condition by unit
+ * stepping (minimal delay)
+ */
+ if (!success) {
+ pr_debug("Fail region (PHASE) found phase idx %d\n",
+ phase_idx);
+ pr_debug("Let's look for first success by DQS Unit steps\n");
+ /* This part, the algo always converge */
+ phase_idx--;
+
+ /* escape if we find a success condition
+ * or if out of delay range.
+ */
+ while (!success && dqs_unit_delay_index >= 0) {
+ DQS_unit_delay(phy, datx8,
+ dqs_unit_delay_index);
+ BIST_test(phy, datx8, &result);
+ success = result.test_result;
+ dqs_unit_delay_index--;
+ }
+ /* if the loop ended with a success condition,
+ * the last delay Right OK (before hold violation)
+ * condition is then defined as following:
+ */
+ if (success) {
+ /* Hold the dely parameters of the the last
+ * delay Right OK condition.
+ * -1 to get back to current condition
+ */
+ last_right_ok.phase = phase_idx;
+ /*+1 to get back to current condition */
+ last_right_ok.unit = dqs_unit_delay_index + 1;
+ last_right_ok.bits_delay = 0xFFFFFFFF;
+ pr_debug("Found %d\n", dqs_unit_delay_index);
+ } else {
+ /* the last OK condition is then with the
+ * previous phase_idx.
+ * -2 instead of -1 because at the last
+ * iteration of the while(),
+ * we incremented phase_idx
+ */
+ last_right_ok.phase = phase_idx - 1;
+ /* Nominal+1. Because we want the previous
+ * delay after reducing the phase delay.
+ */
+ last_right_ok.unit = 1;
+ last_right_ok.bits_delay = 0xFFFFFFFF;
+ pr_debug("Not Found : try previous phase %d\n",
+ phase_idx - 1);
+
+ DQS_phase_delay(phy, datx8, phase_idx - 1);
+ dqs_unit_delay_index = 0;
+ success = true;
+ while (success &&
+ (dqs_unit_delay_index <
+ MAX_DQS_UNIT_IDX)) {
+ DQS_unit_delay(phy, datx8,
+ dqs_unit_delay_index);
+ BIST_test(phy, datx8, &result);
+ success = result.test_result;
+ dqs_unit_delay_index++;
+ pr_debug("dqs_unit_delay_index = %d, result = %d\n",
+ dqs_unit_delay_index, success);
+ }
+
+ if (!success) {
+ last_right_ok.unit =
+ dqs_unit_delay_index - 1;
+ } else {
+ last_right_ok.unit = 0;
+ pr_debug("ERROR: failed region not FOUND");
+ }
+ }
+ } else {
+ /* we can't find a failing condition at all bits
+ * ==> Just hold the last test condition
+ * (the max DQS delay)
+ * which is the most likely,
+ * the closest to a hold violation
+ * If we can't find a Fail condition after
+ * the Pass region, stick at this position
+ * In order to have max chances to find a fail
+ * when reducing DQ delays.
+ */
+ last_right_ok.phase = MAX_DQS_PHASE_IDX;
+ last_right_ok.unit = MAX_DQS_UNIT_IDX;
+ last_right_ok.bits_delay = 0xFFFFFFFF;
+ pr_debug("Can't find the a fail condition\n");
+ }
+
+ /* step 2:
+ * if we arrive at this stage, it means that we found the last
+ * Right OK condition (by tweeking the DQS delay). Or we simply
+ * pushed DQS delay to the max
+ * This means that by reducing the delay on some DQ bits,
+ * we should find a failing condition.
+ */
+ printf("Byte %d, DQS unit = %d, phase = %d\n",
+ datx8, last_right_ok.unit, last_right_ok.phase);
+ pr_debug("Step2, unit = %d, phase = %d, bits delay=%x\n",
+ last_right_ok.unit, last_right_ok.phase,
+ last_right_ok.bits_delay);
+
+ /* Restore the last_right_ok condtion. */
+ DQS_unit_delay(phy, datx8, last_right_ok.unit);
+ DQS_phase_delay(phy, datx8, last_right_ok.phase);
+ writel(last_right_ok.bits_delay, DXNDQTR(phy, datx8));
+
+ /* train each bit
+ * reduce delay on each bit, and perform a write/read test
+ * and stop at the very first time it fails.
+ * the goal is the find the first failing condition
+ * for each bit.
+ * When we achieve this condition< for all the bits,
+ * we are sure they are aligned (+/- step resolution)
+ */
+ fail_found = 0;
+ for (bit_i = 0; bit_i < 8; bit_i++) {
+ if (ctrlc()) {
+ sprintf(string,
+ "interrupted at byte %d/%d, error=%d",
+ datx8 + 1, nb_bytes, error);
+ return error;
+ }
+ pr_debug("deskewing bit %d:\n", bit_i);
+ success = 1; /* init */
+ /* Set all DQDLYn to maximum value.
+ * Only bit_i will be down-delayed
+ * ==> if we have a fail, it will be definitely
+ * from bit_i
+ */
+ writel(0xFFFFFFFF, DXNDQTR(phy, datx8));
+ /* Arriving at this stage,
+ * we have a success condition with delay = 3;
+ */
+ bit_i_delay_index = 3;
+
+ /* escape if bit delay is out of range or
+ * if a fatil occurs
+ */
+ while ((bit_i_delay_index >= 0) && success) {
+ set_DQ_unit_delay(phy, datx8,
+ bit_i,
+ bit_i_delay_index);
+ BIST_test(phy, datx8, &result);
+ success = result.test_result;
+ bit_i_delay_index--;
+ }
+
+ /* if escape with a fail condition
+ * ==> save this position for bit_i
+ */
+ if (!success) {
+ /* save the delay position.
+ * Add 1 because the while loop ended with a --,
+ * and that we need to hold the last success
+ * delay
+ */
+ deskew_delay[datx8][bit_i] =
+ bit_i_delay_index + 2;
+ if (deskew_delay[datx8][bit_i] > 3)
+ deskew_delay[datx8][bit_i] = 3;
+
+ /* A flag that states we found at least a fail
+ * at one bit.
+ */
+ fail_found = 1;
+ pr_debug("Fail found on bit %d, for delay = %d => deskew[%d][%d] = %d\n",
+ bit_i, bit_i_delay_index + 1,
+ datx8, bit_i,
+ deskew_delay[datx8][bit_i]);
+ } else {
+ /* if we can find a success condition by
+ * back-delaying this bit, just set the delay
+ * to 0 (the best deskew
+ * possible) and mark the bit.
+ */
+ deskew_delay[datx8][bit_i] = 0;
+ /* set a flag that will be used later
+ * in the report.
+ */
+ deskew_non_converge[datx8][bit_i] = 1;
+ pr_debug("Fail not found on bit %d => deskew[%d][%d] = %d\n",
+ bit_i, datx8, bit_i,
+ deskew_delay[datx8][bit_i]);
+ }
+ }
+ pr_debug("**********byte %d tuning complete************\n",
+ datx8);
+ /* If we can't find any failure by back delaying DQ lines,
+ * hold the default values
+ */
+ if (!fail_found) {
+ for (bit_i = 0; bit_i < 8; bit_i++)
+ deskew_delay[datx8][bit_i] = 0;
+ pr_debug("The Deskew algorithm can't converge, there is too much margin in your design. Good job!\n");
+ }
+
+ apply_deskew_results(phy, datx8, deskew_delay,
+ deskew_non_converge);
+ /* Restore nominal value for DQS delay */
+ DQS_phase_delay(phy, datx8, 3);
+ DQS_unit_delay(phy, datx8, 3);
+ /* disable byte after byte bits deskew */
+ clrbits_le32(DXNGCR(phy, datx8), DDRPHYC_DXNGCR_DXEN);
+ } /* end of byte deskew */
+
+ /* re-enable all data bytes */
+ setbits_le32(&phy->dx0gcr, DDRPHYC_DXNGCR_DXEN);
+ setbits_le32(&phy->dx1gcr, DDRPHYC_DXNGCR_DXEN);
+ setbits_le32(&phy->dx2gcr, DDRPHYC_DXNGCR_DXEN);
+ setbits_le32(&phy->dx3gcr, DDRPHYC_DXNGCR_DXEN);
+
+ if (error) {
+ sprintf(string, "error = %d", error);
+ return TEST_FAILED;
+ }
+
+ return TEST_PASSED;
+} /* end function */
+
+/* Trim DQS timings and set it in the centre of data eye.
+ * Look for a PPPPF region, then look for a FPPP region and finally select
+ * the mid of the FPPPPPF region
+ */
+static enum test_result eye_training(struct stm32mp1_ddrctl *ctl,
+ struct stm32mp1_ddrphy *phy, char *string)
+{
+ /*Stores the DQS trim values (PHASE index, unit index) */
+ u8 eye_training_val[NUM_BYTES][2];
+ u8 byte = 0;
+ struct BIST_result result;
+ s8 dqs_unit_delay_index = 0;
+ s8 phase_idx = 0;
+ s8 dqs_unit_delay_index_pass = 0;
+ s8 phase_idx_pass = 0;
+ u8 success = 0;
+ u8 left_phase_bound_found, right_phase_bound_found;
+ u8 left_unit_bound_found, right_unit_bound_found;
+ u8 left_bound_found, right_bound_found;
+ struct tuning_position left_bound, right_bound;
+ u8 error = 0;
+ u8 nb_bytes = get_nb_bytes(ctl);
+
+ /*Disable DQS Drift Compensation*/
+ clrbits_le32(&phy->pgcr, DDRPHYC_PGCR_DFTCMP);
+ /*Disable all bytes*/
+ /* Disable automatic power down of DLL and IOs when disabling a byte
+ * (To avoid having to add programming and delay
+ * for a DLL re-lock when later re-enabling a disabled Byte Lane)
+ */
+ clrbits_le32(&phy->pgcr, DDRPHYC_PGCR_PDDISDX);
+
+ /*Disable all data bytes */
+ clrbits_le32(&phy->dx0gcr, DDRPHYC_DXNGCR_DXEN);
+ clrbits_le32(&phy->dx1gcr, DDRPHYC_DXNGCR_DXEN);
+ clrbits_le32(&phy->dx2gcr, DDRPHYC_DXNGCR_DXEN);
+ clrbits_le32(&phy->dx3gcr, DDRPHYC_DXNGCR_DXEN);
+
+ /* Config the BIST block */
+ config_BIST(phy);
+
+ for (byte = 0; byte < nb_bytes; byte++) {
+ if (ctrlc()) {
+ sprintf(string, "interrupted at byte %d/%d, error=%d",
+ byte + 1, nb_bytes, error);
+ return TEST_FAILED;
+ }
+ right_bound.phase = 0;
+ right_bound.unit = 0;
+
+ left_bound.phase = 0;
+ left_bound.unit = 0;
+
+ left_phase_bound_found = 0;
+ right_phase_bound_found = 0;
+
+ left_unit_bound_found = 0;
+ right_unit_bound_found = 0;
+
+ left_bound_found = 0;
+ right_bound_found = 0;
+
+ /* Enable Byte (DXNGCR, bit DXEN) */
+ setbits_le32(DXNGCR(phy, byte), DDRPHYC_DXNGCR_DXEN);
+
+ /* Select the byte lane for comparison of read data */
+ BIST_datx8_sel(phy, byte);
+
+ /* Set DQS phase delay to the nominal value. */
+ phase_idx = _90deg;
+ phase_idx_pass = phase_idx;
+
+ /* Set DQS unit delay to the nominal value. */
+ dqs_unit_delay_index = 3;
+ dqs_unit_delay_index_pass = dqs_unit_delay_index;
+ success = 0;
+
+ pr_debug("STEP0: Find Init delay\n");
+ /* STEP0: Find Init delay: a delay that put the system
+ * in a "Pass" condition then (TODO) update
+ * dqs_unit_delay_index_pass & phase_idx_pass
+ */
+ DQS_unit_delay(phy, byte, dqs_unit_delay_index);
+ DQS_phase_delay(phy, byte, phase_idx);
+ BIST_test(phy, byte, &result);
+ success = result.test_result;
+ /* If we have a fail in the nominal condition */
+ if (!success) {
+ /* Look at the left */
+ while (phase_idx >= 0 && !success) {
+ phase_idx--;
+ DQS_phase_delay(phy, byte, phase_idx);
+ BIST_test(phy, byte, &result);
+ success = result.test_result;
+ }
+ }
+ if (!success) {
+ /* if we can't find pass condition,
+ * then look at the right
+ */
+ phase_idx = _90deg;
+ while (phase_idx <= MAX_DQS_PHASE_IDX &&
+ !success) {
+ phase_idx++;
+ DQS_phase_delay(phy, byte,
+ phase_idx);
+ BIST_test(phy, byte, &result);
+ success = result.test_result;
+ }
+ }
+ /* save the pass condition */
+ if (success) {
+ phase_idx_pass = phase_idx;
+ } else {
+ printf("Result: Failed ");
+ printf("[Cannot DQS timings, ");
+ printf("there is no PASS region]\n");
+ error++;
+ continue;
+ }
+
+ if (ctrlc()) {
+ sprintf(string, "interrupted at byte %d/%d, error=%d",
+ byte + 1, nb_bytes, error);
+ return TEST_FAILED;
+ }
+ pr_debug("STEP1: Find LEFT PHASE DQS Bound\n");
+ /* STEP1: Find LEFT PHASE DQS Bound */
+ while ((phase_idx >= 0) &&
+ (phase_idx <= MAX_DQS_PHASE_IDX) &&
+ !left_phase_bound_found) {
+ DQS_unit_delay(phy, byte,
+ dqs_unit_delay_index);
+ DQS_phase_delay(phy, byte,
+ phase_idx);
+ BIST_test(phy, byte, &result);
+ success = result.test_result;
+
+ /*TODO: Manage the case were at the beginning
+ * there is already a fail
+ */
+ if (!success) {
+ /* the last pass condition */
+ left_bound.phase = ++phase_idx;
+ left_phase_bound_found = 1;
+ } else if (success) {
+ phase_idx--;
+ }
+ }
+ if (!left_phase_bound_found) {
+ left_bound.phase = 0;
+ phase_idx = 0;
+ }
+ /* If not found, lets take 0 */
+
+ if (ctrlc()) {
+ sprintf(string, "interrupted at byte %d/%d, error=%d",
+ byte + 1, nb_bytes, error);
+ return TEST_FAILED;
+ }
+ pr_debug("STEP2: Find UNIT left bound\n");
+ /* STEP2: Find UNIT left bound */
+ while ((dqs_unit_delay_index >= 0) &&
+ !left_unit_bound_found) {
+ DQS_unit_delay(phy, byte,
+ dqs_unit_delay_index);
+ DQS_phase_delay(phy, byte, phase_idx);
+ BIST_test(phy, byte, &result);
+ success = result.test_result;
+ if (!success) {
+ left_bound.unit =
+ ++dqs_unit_delay_index;
+ left_unit_bound_found = 1;
+ left_bound_found = 1;
+ } else if (success) {
+ dqs_unit_delay_index--;
+ }
+ }
+
+ /* If not found, lets take 0 */
+ if (!left_unit_bound_found)
+ left_bound.unit = 0;
+
+ if (ctrlc()) {
+ sprintf(string, "interrupted at byte %d/%d, error=%d",
+ byte + 1, nb_bytes, error);
+ return TEST_FAILED;
+ }
+ pr_debug("STEP3: Find PHase right bound\n");
+ /* STEP3: Find PHase right bound, start with "pass"
+ * condition
+ */
+
+ /* Set DQS phase delay to the pass value. */
+ phase_idx = phase_idx_pass;
+
+ /* Set DQS unit delay to the pass value. */
+ dqs_unit_delay_index = dqs_unit_delay_index_pass;
+
+ while ((phase_idx <= MAX_DQS_PHASE_IDX) &&
+ !right_phase_bound_found) {
+ DQS_unit_delay(phy, byte,
+ dqs_unit_delay_index);
+ DQS_phase_delay(phy, byte, phase_idx);
+ BIST_test(phy, byte, &result);
+ success = result.test_result;
+ if (!success) {
+ /* the last pass condition */
+ right_bound.phase = --phase_idx;
+ right_phase_bound_found = 1;
+ } else if (success) {
+ phase_idx++;
+ }
+ }
+
+ /* If not found, lets take the max value */
+ if (!right_phase_bound_found) {
+ right_bound.phase = MAX_DQS_PHASE_IDX;
+ phase_idx = MAX_DQS_PHASE_IDX;
+ }
+
+ if (ctrlc()) {
+ sprintf(string, "interrupted at byte %d/%d, error=%d",
+ byte + 1, nb_bytes, error);
+ return TEST_FAILED;
+ }
+ pr_debug("STEP4: Find UNIT right bound\n");
+ /* STEP4: Find UNIT right bound */
+ while ((dqs_unit_delay_index <= MAX_DQS_UNIT_IDX) &&
+ !right_unit_bound_found) {
+ DQS_unit_delay(phy, byte,
+ dqs_unit_delay_index);
+ DQS_phase_delay(phy, byte, phase_idx);
+ BIST_test(phy, byte, &result);
+ success = result.test_result;
+ if (!success) {
+ right_bound.unit =
+ --dqs_unit_delay_index;
+ right_unit_bound_found = 1;
+ right_bound_found = 1;
+ } else if (success) {
+ dqs_unit_delay_index++;
+ }
+ }
+ /* If not found, lets take the max value */
+ if (!right_unit_bound_found)
+ right_bound.unit = MAX_DQS_UNIT_IDX;
+
+ /* If we found a regular FAil Pass FAil pattern
+ * FFPPPPPPFF
+ * OR PPPPPFF Or FFPPPPP
+ */
+
+ if (left_bound_found || right_bound_found) {
+ eye_training_val[byte][0] = (right_bound.phase +
+ left_bound.phase) / 2;
+ eye_training_val[byte][1] = (right_bound.unit +
+ left_bound.unit) / 2;
+
+ /* If we already lost 1/2PHASE Tuning,
+ * let's try to recover by ++ on unit
+ */
+ if (((right_bound.phase + left_bound.phase) % 2 == 1) &&
+ eye_training_val[byte][1] != MAX_DQS_UNIT_IDX)
+ eye_training_val[byte][1]++;
+ pr_debug("** found phase : %d - %d & unit %d - %d\n",
+ right_bound.phase, left_bound.phase,
+ right_bound.unit, left_bound.unit);
+ pr_debug("** calculating mid region: phase: %d unit: %d (nominal is 3)\n",
+ eye_training_val[byte][0],
+ eye_training_val[byte][1]);
+ } else {
+ /* PPPPPPPPPP, we're already good.
+ * Set nominal values.
+ */
+ eye_training_val[byte][0] = 3;
+ eye_training_val[byte][1] = 3;
+ }
+ DQS_phase_delay(phy, byte, eye_training_val[byte][0]);
+ DQS_unit_delay(phy, byte, eye_training_val[byte][1]);
+
+ printf("Byte %d, DQS unit = %d, phase = %d\n",
+ byte,
+ eye_training_val[byte][1],
+ eye_training_val[byte][0]);
+ }
+
+ if (error) {
+ sprintf(string, "error = %d", error);
+ return TEST_FAILED;
+ }
+
+ return TEST_PASSED;
+}
+
+static void display_reg_results(struct stm32mp1_ddrphy *phy, u8 byte)
+{
+ u8 i = 0;
+
+ printf("Byte %d Dekew result, bit0 delay, bit1 delay...bit8 delay\n ",
+ byte);
+
+ for (i = 0; i < 8; i++)
+ printf("%d ", DQ_unit_index(phy, byte, i));
+ printf("\n");
+
+ printf("dxndllcr: [%08x] val:%08x\n",
+ DXNDLLCR(phy, byte),
+ readl(DXNDLLCR(phy, byte)));
+ printf("dxnqdstr: [%08x] val:%08x\n",
+ DXNDQSTR(phy, byte),
+ readl(DXNDQSTR(phy, byte)));
+ printf("dxndqtr: [%08x] val:%08x\n",
+ DXNDQTR(phy, byte),
+ readl(DXNDQTR(phy, byte)));
+}
+
+/* analyse the dgs gating log table, and determine the midpoint.*/
+static u8 set_midpoint_read_dqs_gating(struct stm32mp1_ddrphy *phy, u8 byte,
+ u8 dqs_gating[NUM_BYTES]
+ [MAX_GSL_IDX + 1]
+ [MAX_GPS_IDX + 1])
+{
+ /* stores the dqs gate values (gsl index, gps index) */
+ u8 dqs_gate_values[NUM_BYTES][2];
+ u8 gsl_idx, gps_idx = 0;
+ u8 left_bound_idx[2] = {0, 0};
+ u8 right_bound_idx[2] = {0, 0};
+ u8 left_bound_found = 0;
+ u8 right_bound_found = 0;
+ u8 intermittent = 0;
+ u8 value;
+
+ for (gsl_idx = 0; gsl_idx <= MAX_GSL_IDX; gsl_idx++) {
+ for (gps_idx = 0; gps_idx <= MAX_GPS_IDX; gps_idx++) {
+ value = dqs_gating[byte][gsl_idx][gps_idx];
+ if (value == 1 && left_bound_found == 0) {
+ left_bound_idx[0] = gsl_idx;
+ left_bound_idx[1] = gps_idx;
+ left_bound_found = 1;
+ } else if (value == 0 &&
+ left_bound_found == 1 &&
+ !right_bound_found) {
+ if (gps_idx == 0) {
+ right_bound_idx[0] = gsl_idx - 1;
+ right_bound_idx[1] = MAX_GPS_IDX;
+ } else {
+ right_bound_idx[0] = gsl_idx;
+ right_bound_idx[1] = gps_idx - 1;
+ }
+ right_bound_found = 1;
+ } else if (value == 1 &&
+ right_bound_found == 1) {
+ intermittent = 1;
+ }
+ }
+ }
+
+ /* if only ppppppp is found, there is no mid region. */
+ if (left_bound_idx[0] == 0 && left_bound_idx[1] == 0 &&
+ right_bound_idx[0] == 0 && right_bound_idx[1] == 0)
+ intermittent = 1;
+
+ /*if we found a regular fail pass fail pattern ffppppppff
+ * or pppppff or ffppppp
+ */
+ if (!intermittent) {
+ /*if we found a regular fail pass fail pattern ffppppppff
+ * or pppppff or ffppppp
+ */
+ if (left_bound_found || right_bound_found) {
+ pr_debug("idx0(%d): %d %d idx1(%d) : %d %d\n",
+ left_bound_found,
+ right_bound_idx[0], left_bound_idx[0],
+ right_bound_found,
+ right_bound_idx[1], left_bound_idx[1]);
+ dqs_gate_values[byte][0] =
+ (right_bound_idx[0] + left_bound_idx[0]) / 2;
+ dqs_gate_values[byte][1] =
+ (right_bound_idx[1] + left_bound_idx[1]) / 2;
+ /* if we already lost 1/2gsl tuning,
+ * let's try to recover by ++ on gps
+ */
+ if (((right_bound_idx[0] +
+ left_bound_idx[0]) % 2 == 1) &&
+ dqs_gate_values[byte][1] != MAX_GPS_IDX)
+ dqs_gate_values[byte][1]++;
+ /* if we already lost 1/2gsl tuning and gps is on max*/
+ else if (((right_bound_idx[0] +
+ left_bound_idx[0]) % 2 == 1) &&
+ dqs_gate_values[byte][1] == MAX_GPS_IDX) {
+ dqs_gate_values[byte][1] = 0;
+ dqs_gate_values[byte][0]++;
+ }
+ /* if we have gsl left and write limit too close
+ * (difference=1)
+ */
+ if (((right_bound_idx[0] - left_bound_idx[0]) == 1)) {
+ dqs_gate_values[byte][1] = (left_bound_idx[1] +
+ right_bound_idx[1] +
+ 4) / 2;
+ if (dqs_gate_values[byte][1] >= 4) {
+ dqs_gate_values[byte][0] =
+ right_bound_idx[0];
+ dqs_gate_values[byte][1] -= 4;
+ } else {
+ dqs_gate_values[byte][0] =
+ left_bound_idx[0];
+ }
+ }
+ pr_debug("*******calculating mid region: system latency: %d phase: %d********\n",
+ dqs_gate_values[byte][0],
+ dqs_gate_values[byte][1]);
+ pr_debug("*******the nominal values were system latency: 0 phase: 2*******\n");
+ set_r0dgsl_delay(phy, byte, dqs_gate_values[byte][0]);
+ set_r0dgps_delay(phy, byte, dqs_gate_values[byte][1]);
+ }
+ } else {
+ /* if intermitant, restore defaut values */
+ pr_debug("dqs gating:no regular fail/pass/fail found. defaults values restored.\n");
+ set_r0dgsl_delay(phy, byte, 0);
+ set_r0dgps_delay(phy, byte, 2);
+ }
+
+ /* return 0 if intermittent or if both left_bound
+ * and right_bound are not found
+ */
+ return !(intermittent || (left_bound_found && right_bound_found));
+}
+
+static enum test_result read_dqs_gating(struct stm32mp1_ddrctl *ctl,
+ struct stm32mp1_ddrphy *phy,
+ char *string)
+{
+ /* stores the log of pass/fail */
+ u8 dqs_gating[NUM_BYTES][MAX_GSL_IDX + 1][MAX_GPS_IDX + 1];
+ u8 byte, gsl_idx, gps_idx = 0;
+ struct BIST_result result;
+ u8 success = 0;
+ u8 nb_bytes = get_nb_bytes(ctl);
+
+ memset(dqs_gating, 0x0, sizeof(dqs_gating));
+
+ /*disable dqs drift compensation*/
+ clrbits_le32(&phy->pgcr, DDRPHYC_PGCR_DFTCMP);
+ /*disable all bytes*/
+ /* disable automatic power down of dll and ios when disabling a byte
+ * (to avoid having to add programming and delay
+ * for a dll re-lock when later re-enabling a disabled byte lane)
+ */
+ clrbits_le32(&phy->pgcr, DDRPHYC_PGCR_PDDISDX);
+
+ /* disable all data bytes */
+ clrbits_le32(&phy->dx0gcr, DDRPHYC_DXNGCR_DXEN);
+ clrbits_le32(&phy->dx1gcr, DDRPHYC_DXNGCR_DXEN);
+ clrbits_le32(&phy->dx2gcr, DDRPHYC_DXNGCR_DXEN);
+ clrbits_le32(&phy->dx3gcr, DDRPHYC_DXNGCR_DXEN);
+
+ /* config the bist block */
+ config_BIST(phy);
+
+ for (byte = 0; byte < nb_bytes; byte++) {
+ if (ctrlc()) {
+ sprintf(string, "interrupted at byte %d/%d",
+ byte + 1, nb_bytes);
+ return TEST_FAILED;
+ }
+ /* enable byte x (dxngcr, bit dxen) */
+ setbits_le32(DXNGCR(phy, byte), DDRPHYC_DXNGCR_DXEN);
+
+ /* select the byte lane for comparison of read data */
+ BIST_datx8_sel(phy, byte);
+ for (gsl_idx = 0; gsl_idx <= MAX_GSL_IDX; gsl_idx++) {
+ for (gps_idx = 0; gps_idx <= MAX_GPS_IDX; gps_idx++) {
+ if (ctrlc()) {
+ sprintf(string,
+ "interrupted at byte %d/%d",
+ byte + 1, nb_bytes);
+ return TEST_FAILED;
+ }
+ /* write cfg to dxndqstr */
+ set_r0dgsl_delay(phy, byte, gsl_idx);
+ set_r0dgps_delay(phy, byte, gps_idx);
+
+ BIST_test(phy, byte, &result);
+ success = result.test_result;
+ if (success)
+ dqs_gating[byte][gsl_idx][gps_idx] = 1;
+ itm_soft_reset(phy);
+ }
+ }
+ set_midpoint_read_dqs_gating(phy, byte, dqs_gating);
+ /* dummy reads */
+ readl(0xc0000000);
+ readl(0xc0000000);
+ }
+
+ /* re-enable drift compensation */
+ /* setbits_le32(&phy->pgcr, DDRPHYC_PGCR_DFTCMP); */
+ return TEST_PASSED;
+}
+
+/****************************************************************
+ * TEST
+ ****************************************************************
+ */
+static enum test_result do_read_dqs_gating(struct stm32mp1_ddrctl *ctl,
+ struct stm32mp1_ddrphy *phy,
+ char *string, int argc,
+ char *argv[])
+{
+ u32 rfshctl3 = readl(&ctl->rfshctl3);
+ u32 pwrctl = readl(&ctl->pwrctl);
+ enum test_result res;
+
+ stm32mp1_refresh_disable(ctl);
+ res = read_dqs_gating(ctl, phy, string);
+ stm32mp1_refresh_restore(ctl, rfshctl3, pwrctl);
+
+ return res;
+}
+
+static enum test_result do_bit_deskew(struct stm32mp1_ddrctl *ctl,
+ struct stm32mp1_ddrphy *phy,
+ char *string, int argc, char *argv[])
+{
+ u32 rfshctl3 = readl(&ctl->rfshctl3);
+ u32 pwrctl = readl(&ctl->pwrctl);
+ enum test_result res;
+
+ stm32mp1_refresh_disable(ctl);
+ res = bit_deskew(ctl, phy, string);
+ stm32mp1_refresh_restore(ctl, rfshctl3, pwrctl);
+
+ return res;
+}
+
+static enum test_result do_eye_training(struct stm32mp1_ddrctl *ctl,
+ struct stm32mp1_ddrphy *phy,
+ char *string, int argc, char *argv[])
+{
+ u32 rfshctl3 = readl(&ctl->rfshctl3);
+ u32 pwrctl = readl(&ctl->pwrctl);
+ enum test_result res;
+
+ stm32mp1_refresh_disable(ctl);
+ res = eye_training(ctl, phy, string);
+ stm32mp1_refresh_restore(ctl, rfshctl3, pwrctl);
+
+ return res;
+}
+
+static enum test_result do_display(struct stm32mp1_ddrctl *ctl,
+ struct stm32mp1_ddrphy *phy,
+ char *string, int argc, char *argv[])
+{
+ int byte;
+ u8 nb_bytes = get_nb_bytes(ctl);
+
+ for (byte = 0; byte < nb_bytes; byte++)
+ display_reg_results(phy, byte);
+
+ return TEST_PASSED;
+}
+
+static enum test_result do_bist_config(struct stm32mp1_ddrctl *ctl,
+ struct stm32mp1_ddrphy *phy,
+ char *string, int argc, char *argv[])
+{
+ unsigned long value;
+
+ if (argc > 0) {
+ if (strict_strtoul(argv[0], 0, &value) < 0) {
+ sprintf(string, "invalid nbErr %s", argv[0]);
+ return TEST_FAILED;
+ }
+ BIST_error_max = value;
+ }
+ if (argc > 1) {
+ if (strict_strtoul(argv[1], 0, &value) < 0) {
+ sprintf(string, "invalid Seed %s", argv[1]);
+ return TEST_FAILED;
+ }
+ BIST_seed = value;
+ }
+ printf("Bist.nbErr = %d\n", BIST_error_max);
+ if (BIST_seed)
+ printf("Bist.Seed = 0x%x\n", BIST_seed);
+ else
+ printf("Bist.Seed = random\n");
+
+ return TEST_PASSED;
+}
+
+/****************************************************************
+ * TEST Description
+ ****************************************************************
+ */
+
+const struct test_desc tuning[] = {
+ {do_read_dqs_gating, "Read DQS gating",
+ "software read DQS Gating", "", 0 },
+ {do_bit_deskew, "Bit de-skew", "", "", 0 },
+ {do_eye_training, "Eye Training", "or DQS training", "", 0 },
+ {do_display, "Display registers", "", "", 0 },
+ {do_bist_config, "Bist config", "[nbErr] [seed]",
+ "configure Bist test", 2},
+};
+
+const int tuning_nb = ARRAY_SIZE(tuning);
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index fcbb0a81ed..8a447fd6e3 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -559,6 +559,14 @@ config MVEBU_A3700_UART
Choose this option to add support for UART driver on the Marvell
Armada 3700 SoC. The base address is configured via DT.
+config MCFUART
+ bool "Freescale ColdFire UART support"
+ help
+ Choose this option to add support for UART driver on the ColdFire
+ SoC's family. The serial communication channel provides a full-duplex
+ asynchronous/synchronous receiver and transmitter deriving an
+ operating frequency from the internal bus clock or an external clock.
+
config MXC_UART
bool "IMX serial port support"
depends on MX5 || MX6
diff --git a/drivers/serial/mcfuart.c b/drivers/serial/mcfuart.c
index 1371049de2..066e5a18d8 100644
--- a/drivers/serial/mcfuart.c
+++ b/drivers/serial/mcfuart.c
@@ -5,6 +5,9 @@
*
* Modified to add device model (DM) support
* (C) Copyright 2015 Angelo Dureghello <angelo@sysam.it>
+ *
+ * Modified to add DM and fdt support, removed non DM code
+ * (C) Copyright 2018 Angelo Dureghello <angelo@sysam.it>
*/
/*
@@ -78,83 +81,6 @@ static void mcf_serial_setbrg_common(uart_t *uart, int baudrate)
writeb(UART_UCR_RX_ENABLED | UART_UCR_TX_ENABLED, &uart->ucr);
}
-#ifndef CONFIG_DM_SERIAL
-
-static int mcf_serial_init(void)
-{
- uart_t *uart_base;
- int port_idx;
-
- uart_base = (uart_t *)CONFIG_SYS_UART_BASE;
- port_idx = CONFIG_SYS_UART_PORT;
-
- return mcf_serial_init_common(uart_base, port_idx, gd->baudrate);
-}
-
-static void mcf_serial_putc(const char c)
-{
- uart_t *uart = (uart_t *)CONFIG_SYS_UART_BASE;
-
- if (c == '\n')
- serial_putc('\r');
-
- /* Wait for last character to go. */
- while (!(readb(&uart->usr) & UART_USR_TXRDY))
- ;
-
- writeb(c, &uart->utb);
-}
-
-static int mcf_serial_getc(void)
-{
- uart_t *uart = (uart_t *)CONFIG_SYS_UART_BASE;
-
- /* Wait for a character to arrive. */
- while (!(readb(&uart->usr) & UART_USR_RXRDY))
- ;
-
- return readb(&uart->urb);
-}
-
-static void mcf_serial_setbrg(void)
-{
- uart_t *uart = (uart_t *)CONFIG_SYS_UART_BASE;
-
- mcf_serial_setbrg_common(uart, gd->baudrate);
-}
-
-static int mcf_serial_tstc(void)
-{
- uart_t *uart = (uart_t *)CONFIG_SYS_UART_BASE;
-
- return readb(&uart->usr) & UART_USR_RXRDY;
-}
-
-static struct serial_device mcf_serial_drv = {
- .name = "mcf_serial",
- .start = mcf_serial_init,
- .stop = NULL,
- .setbrg = mcf_serial_setbrg,
- .putc = mcf_serial_putc,
- .puts = default_serial_puts,
- .getc = mcf_serial_getc,
- .tstc = mcf_serial_tstc,
-};
-
-void mcf_serial_initialize(void)
-{
- serial_register(&mcf_serial_drv);
-}
-
-__weak struct serial_device *default_serial_console(void)
-{
- return &mcf_serial_drv;
-}
-
-#endif
-
-#ifdef CONFIG_DM_SERIAL
-
static int coldfire_serial_probe(struct udevice *dev)
{
struct coldfire_serial_platdata *plat = dev->platdata;
@@ -212,6 +138,23 @@ static int coldfire_serial_pending(struct udevice *dev, bool input)
return 0;
}
+static int coldfire_ofdata_to_platdata(struct udevice *dev)
+{
+ struct coldfire_serial_platdata *plat = dev_get_platdata(dev);
+ fdt_addr_t addr_base;
+
+ addr_base = devfdt_get_addr(dev);
+ if (addr_base == FDT_ADDR_T_NONE)
+ return -ENODEV;
+
+ plat->base = (uint32_t)addr_base;
+
+ plat->port = dev->seq;
+ plat->baudrate = gd->baudrate;
+
+ return 0;
+}
+
static const struct dm_serial_ops coldfire_serial_ops = {
.putc = coldfire_serial_putc,
.pending = coldfire_serial_pending,
@@ -219,11 +162,18 @@ static const struct dm_serial_ops coldfire_serial_ops = {
.setbrg = coldfire_serial_setbrg,
};
+static const struct udevice_id coldfire_serial_ids[] = {
+ { .compatible = "fsl,mcf-uart" },
+ { }
+};
+
U_BOOT_DRIVER(serial_coldfire) = {
.name = "serial_coldfire",
.id = UCLASS_SERIAL,
+ .of_match = coldfire_serial_ids,
+ .ofdata_to_platdata = coldfire_ofdata_to_platdata,
+ .platdata_auto_alloc_size = sizeof(struct coldfire_serial_platdata),
.probe = coldfire_serial_probe,
.ops = &coldfire_serial_ops,
.flags = DM_FLAG_PRE_RELOC,
};
-#endif
diff --git a/drivers/serial/serial_stm32.c b/drivers/serial/serial_stm32.c
index e31c87b9ac..cca8b707ac 100644
--- a/drivers/serial/serial_stm32.c
+++ b/drivers/serial/serial_stm32.c
@@ -269,7 +269,6 @@ static inline void _debug_uart_init(void)
_stm32_serial_setbrg(base, uart_info,
CONFIG_DEBUG_UART_CLOCK,
CONFIG_BAUDRATE);
- printf("DEBUG done\n");
}
static inline void _debug_uart_putc(int c)
@@ -278,7 +277,7 @@ static inline void _debug_uart_putc(int c)
struct stm32_uart_info *uart_info = _debug_uart_info();
while (_stm32_serial_putc(base, uart_info, c) == -EAGAIN)
- WATCHDOG_RESET();
+ ;
}
DEBUG_UART_FUNCS
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index c3a829deae..7044da35d6 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -87,6 +87,12 @@ config CADENCE_QSPI
used to access the SPI NOR flash on platforms embedding this
Cadence IP core.
+config CF_SPI
+ bool "ColdFire SPI driver"
+ help
+ Enable the ColdFire SPI driver. This driver can be used on
+ some m68k SoCs.
+
config DESIGNWARE_SPI
bool "Designware SPI driver"
help
diff --git a/drivers/spi/cf_spi.c b/drivers/spi/cf_spi.c
index 522631cbbf..923ff6f311 100644
--- a/drivers/spi/cf_spi.c
+++ b/drivers/spi/cf_spi.c
@@ -6,23 +6,28 @@
*
* Copyright (C) 2004-2009 Freescale Semiconductor, Inc.
* TsiChung Liew (Tsi-Chung.Liew@freescale.com)
+ *
+ * Support for DM and DT, non-DM code removed.
+ * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it>
+ *
+ * TODO: fsl_dspi.c should work as a driver for the DSPI module.
*/
#include <common.h>
+#include <dm.h>
+#include <dm/platform_data/spi_coldfire.h>
#include <spi.h>
#include <malloc.h>
-#include <asm/immap.h>
+#include <asm/coldfire/dspi.h>
+#include <asm/io.h>
-struct cf_spi_slave {
- struct spi_slave slave;
+struct coldfire_spi_priv {
+ struct dspi *regs;
uint baudrate;
+ int mode;
int charbit;
};
-extern void cfspi_port_conf(void);
-extern int cfspi_claim_bus(uint bus, uint cs);
-extern void cfspi_release_bus(uint bus, uint cs);
-
DECLARE_GLOBAL_DATA_PTR;
#ifndef CONFIG_SPI_IDLE_VAL
@@ -33,163 +38,193 @@ DECLARE_GLOBAL_DATA_PTR;
#endif
#endif
-#if defined(CONFIG_CF_DSPI)
-/* DSPI specific mode */
-#define SPI_MODE_MOD 0x00200000
-#define SPI_DBLRATE 0x00100000
-
-static inline struct cf_spi_slave *to_cf_spi_slave(struct spi_slave *slave)
+/*
+ * DSPI specific mode
+ *
+ * bit 31 - 28: Transfer size 3 to 16 bits
+ * 27 - 26: PCS to SCK delay prescaler
+ * 25 - 24: After SCK delay prescaler
+ * 23 - 22: Delay after transfer prescaler
+ * 21 : Allow overwrite for bit 31-22 and bit 20-8
+ * 20 : Double baud rate
+ * 19 - 16: PCS to SCK delay scaler
+ * 15 - 12: After SCK delay scaler
+ * 11 - 8: Delay after transfer scaler
+ * 7 - 0: SPI_CPHA, SPI_CPOL, SPI_LSB_FIRST
+ */
+#define SPI_MODE_MOD 0x00200000
+#define SPI_MODE_DBLRATE 0x00100000
+
+#define SPI_MODE_XFER_SZ_MASK 0xf0000000
+#define SPI_MODE_DLY_PRE_MASK 0x0fc00000
+#define SPI_MODE_DLY_SCA_MASK 0x000fff00
+
+#define MCF_FRM_SZ_16BIT DSPI_CTAR_TRSZ(0xf)
+#define MCF_DSPI_SPEED_BESTMATCH 0x7FFFFFFF
+#define MCF_DSPI_MAX_CTAR_REGS 8
+
+/* Default values */
+#define MCF_DSPI_DEFAULT_SCK_FREQ 10000000
+#define MCF_DSPI_DEFAULT_MAX_CS 4
+#define MCF_DSPI_DEFAULT_MODE 0
+
+#define MCF_DSPI_DEFAULT_CTAR (DSPI_CTAR_TRSZ(7) | \
+ DSPI_CTAR_PCSSCK_1CLK | \
+ DSPI_CTAR_PASC(0) | \
+ DSPI_CTAR_PDT(0) | \
+ DSPI_CTAR_CSSCK(0) | \
+ DSPI_CTAR_ASC(0) | \
+ DSPI_CTAR_DT(1) | \
+ DSPI_CTAR_BR(6))
+
+#define MCF_CTAR_MODE_MASK (MCF_FRM_SZ_16BIT | \
+ DSPI_CTAR_PCSSCK(3) | \
+ DSPI_CTAR_PASC_7CLK | \
+ DSPI_CTAR_PDT(3) | \
+ DSPI_CTAR_CSSCK(0x0f) | \
+ DSPI_CTAR_ASC(0x0f) | \
+ DSPI_CTAR_DT(0x0f))
+
+#define setup_ctrl(ctrl, cs) ((ctrl & 0xFF000000) | ((1 << cs) << 16))
+
+static inline void cfspi_tx(struct coldfire_spi_priv *cfspi,
+ u32 ctrl, u16 data)
{
- return container_of(slave, struct cf_spi_slave, slave);
+ /*
+ * Need to check fifo level here
+ */
+ while ((readl(&cfspi->regs->sr) & 0x0000F000) >= 0x4000)
+ ;
+
+ writel(ctrl | data, &cfspi->regs->tfr);
}
-static void cfspi_init(void)
+static inline u16 cfspi_rx(struct coldfire_spi_priv *cfspi)
{
- volatile dspi_t *dspi = (dspi_t *) MMAP_DSPI;
- cfspi_port_conf(); /* port configuration */
-
- dspi->mcr = DSPI_MCR_MSTR | DSPI_MCR_CSIS7 | DSPI_MCR_CSIS6 |
- DSPI_MCR_CSIS5 | DSPI_MCR_CSIS4 | DSPI_MCR_CSIS3 |
- DSPI_MCR_CSIS2 | DSPI_MCR_CSIS1 | DSPI_MCR_CSIS0 |
- DSPI_MCR_CRXF | DSPI_MCR_CTXF;
+ while ((readl(&cfspi->regs->sr) & 0x000000F0) == 0)
+ ;
- /* Default setting in platform configuration */
-#ifdef CONFIG_SYS_DSPI_CTAR0
- dspi->ctar[0] = CONFIG_SYS_DSPI_CTAR0;
-#endif
-#ifdef CONFIG_SYS_DSPI_CTAR1
- dspi->ctar[1] = CONFIG_SYS_DSPI_CTAR1;
-#endif
-#ifdef CONFIG_SYS_DSPI_CTAR2
- dspi->ctar[2] = CONFIG_SYS_DSPI_CTAR2;
-#endif
-#ifdef CONFIG_SYS_DSPI_CTAR3
- dspi->ctar[3] = CONFIG_SYS_DSPI_CTAR3;
-#endif
-#ifdef CONFIG_SYS_DSPI_CTAR4
- dspi->ctar[4] = CONFIG_SYS_DSPI_CTAR4;
-#endif
-#ifdef CONFIG_SYS_DSPI_CTAR5
- dspi->ctar[5] = CONFIG_SYS_DSPI_CTAR5;
-#endif
-#ifdef CONFIG_SYS_DSPI_CTAR6
- dspi->ctar[6] = CONFIG_SYS_DSPI_CTAR6;
-#endif
-#ifdef CONFIG_SYS_DSPI_CTAR7
- dspi->ctar[7] = CONFIG_SYS_DSPI_CTAR7;
-#endif
+ return readw(&cfspi->regs->rfr);
}
-static void cfspi_tx(u32 ctrl, u16 data)
+static int coldfire_spi_claim_bus(struct udevice *dev)
{
- volatile dspi_t *dspi = (dspi_t *) MMAP_DSPI;
+ struct udevice *bus = dev->parent;
+ struct coldfire_spi_priv *cfspi = dev_get_priv(bus);
+ struct dspi *dspi = cfspi->regs;
+ struct dm_spi_slave_platdata *slave_plat =
+ dev_get_parent_platdata(dev);
- while ((dspi->sr & 0x0000F000) >= 4) ;
+ if ((in_be32(&dspi->sr) & DSPI_SR_TXRXS) != DSPI_SR_TXRXS)
+ return -1;
- dspi->tfr = (ctrl | data);
+ /* Clear FIFO and resume transfer */
+ clrbits_be32(&dspi->mcr, DSPI_MCR_CTXF | DSPI_MCR_CRXF);
+
+ dspi_chip_select(slave_plat->cs);
+
+ return 0;
}
-static u16 cfspi_rx(void)
+static int coldfire_spi_release_bus(struct udevice *dev)
{
- volatile dspi_t *dspi = (dspi_t *) MMAP_DSPI;
+ struct udevice *bus = dev->parent;
+ struct coldfire_spi_priv *cfspi = dev_get_priv(bus);
+ struct dspi *dspi = cfspi->regs;
+ struct dm_spi_slave_platdata *slave_plat =
+ dev_get_parent_platdata(dev);
- while ((dspi->sr & 0x000000F0) == 0) ;
+ /* Clear FIFO */
+ clrbits_be32(&dspi->mcr, DSPI_MCR_CTXF | DSPI_MCR_CRXF);
- return (dspi->rfr & 0xFFFF);
+ dspi_chip_unselect(slave_plat->cs);
+
+ return 0;
}
-static int cfspi_xfer(struct spi_slave *slave, uint bitlen, const void *dout,
- void *din, ulong flags)
+static int coldfire_spi_xfer(struct udevice *dev, unsigned int bitlen,
+ const void *dout, void *din,
+ unsigned long flags)
{
- struct cf_spi_slave *cfslave = to_cf_spi_slave(slave);
+ struct udevice *bus = dev_get_parent(dev);
+ struct coldfire_spi_priv *cfspi = dev_get_priv(bus);
+ struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
u16 *spi_rd16 = NULL, *spi_wr16 = NULL;
u8 *spi_rd = NULL, *spi_wr = NULL;
- static u32 ctrl = 0;
+ static u32 ctrl;
uint len = bitlen >> 3;
- if (cfslave->charbit == 16) {
+ if (cfspi->charbit == 16) {
bitlen >>= 1;
- spi_wr16 = (u16 *) dout;
- spi_rd16 = (u16 *) din;
+ spi_wr16 = (u16 *)dout;
+ spi_rd16 = (u16 *)din;
} else {
- spi_wr = (u8 *) dout;
- spi_rd = (u8 *) din;
+ spi_wr = (u8 *)dout;
+ spi_rd = (u8 *)din;
}
if ((flags & SPI_XFER_BEGIN) == SPI_XFER_BEGIN)
ctrl |= DSPI_TFR_CONT;
- ctrl = (ctrl & 0xFF000000) | ((1 << slave->cs) << 16);
+ ctrl = setup_ctrl(ctrl, slave_plat->cs);
if (len > 1) {
int tmp_len = len - 1;
+
while (tmp_len--) {
- if (dout != NULL) {
- if (cfslave->charbit == 16)
- cfspi_tx(ctrl, *spi_wr16++);
+ if (dout) {
+ if (cfspi->charbit == 16)
+ cfspi_tx(cfspi, ctrl, *spi_wr16++);
else
- cfspi_tx(ctrl, *spi_wr++);
- cfspi_rx();
+ cfspi_tx(cfspi, ctrl, *spi_wr++);
+ cfspi_rx(cfspi);
}
- if (din != NULL) {
- cfspi_tx(ctrl, CONFIG_SPI_IDLE_VAL);
- if (cfslave->charbit == 16)
- *spi_rd16++ = cfspi_rx();
+ if (din) {
+ cfspi_tx(cfspi, ctrl, CONFIG_SPI_IDLE_VAL);
+ if (cfspi->charbit == 16)
+ *spi_rd16++ = cfspi_rx(cfspi);
else
- *spi_rd++ = cfspi_rx();
+ *spi_rd++ = cfspi_rx(cfspi);
}
}
len = 1; /* remaining byte */
}
- if ((flags & SPI_XFER_END) == SPI_XFER_END)
+ if (flags & SPI_XFER_END)
ctrl &= ~DSPI_TFR_CONT;
if (len) {
- if (dout != NULL) {
- if (cfslave->charbit == 16)
- cfspi_tx(ctrl, *spi_wr16);
+ if (dout) {
+ if (cfspi->charbit == 16)
+ cfspi_tx(cfspi, ctrl, *spi_wr16);
else
- cfspi_tx(ctrl, *spi_wr);
- cfspi_rx();
+ cfspi_tx(cfspi, ctrl, *spi_wr);
+ cfspi_rx(cfspi);
}
- if (din != NULL) {
- cfspi_tx(ctrl, CONFIG_SPI_IDLE_VAL);
- if (cfslave->charbit == 16)
- *spi_rd16 = cfspi_rx();
+ if (din) {
+ cfspi_tx(cfspi, ctrl, CONFIG_SPI_IDLE_VAL);
+ if (cfspi->charbit == 16)
+ *spi_rd16 = cfspi_rx(cfspi);
else
- *spi_rd = cfspi_rx();
+ *spi_rd = cfspi_rx(cfspi);
}
} else {
/* dummy read */
- cfspi_tx(ctrl, CONFIG_SPI_IDLE_VAL);
- cfspi_rx();
+ cfspi_tx(cfspi, ctrl, CONFIG_SPI_IDLE_VAL);
+ cfspi_rx(cfspi);
}
return 0;
}
-static struct spi_slave *cfspi_setup_slave(struct cf_spi_slave *cfslave,
- uint mode)
+static int coldfire_spi_set_speed(struct udevice *bus, uint max_hz)
{
- /*
- * bit definition for mode:
- * bit 31 - 28: Transfer size 3 to 16 bits
- * 27 - 26: PCS to SCK delay prescaler
- * 25 - 24: After SCK delay prescaler
- * 23 - 22: Delay after transfer prescaler
- * 21 : Allow overwrite for bit 31-22 and bit 20-8
- * 20 : Double baud rate
- * 19 - 16: PCS to SCK delay scaler
- * 15 - 12: After SCK delay scaler
- * 11 - 8: Delay after transfer scaler
- * 7 - 0: SPI_CPHA, SPI_CPOL, SPI_LSB_FIRST
- */
- volatile dspi_t *dspi = (dspi_t *) MMAP_DSPI;
+ struct coldfire_spi_priv *cfspi = dev_get_priv(bus);
+ struct dspi *dspi = cfspi->regs;
int prescaler[] = { 2, 3, 5, 7 };
int scaler[] = {
2, 4, 6, 8,
@@ -198,57 +233,41 @@ static struct spi_slave *cfspi_setup_slave(struct cf_spi_slave *cfslave,
4096, 8192, 16384, 32768
};
int i, j, pbrcnt, brcnt, diff, tmp, dbr = 0;
- int best_i, best_j, bestmatch = 0x7FFFFFFF, baud_speed;
- u32 bus_setup = 0;
+ int best_i, best_j, bestmatch = MCF_DSPI_SPEED_BESTMATCH, baud_speed;
+ u32 bus_setup;
+
+ cfspi->baudrate = max_hz;
+
+ /* Read current setup */
+ bus_setup = readl(&dspi->ctar[bus->seq]);
tmp = (prescaler[3] * scaler[15]);
/* Maximum and minimum baudrate it can handle */
- if ((cfslave->baudrate > (gd->bus_clk >> 1)) ||
- (cfslave->baudrate < (gd->bus_clk / tmp))) {
+ if ((cfspi->baudrate > (gd->bus_clk >> 1)) ||
+ (cfspi->baudrate < (gd->bus_clk / tmp))) {
printf("Exceed baudrate limitation: Max %d - Min %d\n",
(int)(gd->bus_clk >> 1), (int)(gd->bus_clk / tmp));
- return NULL;
+ return -1;
}
/* Activate Double Baud when it exceed 1/4 the bus clk */
- if ((CONFIG_SYS_DSPI_CTAR0 & DSPI_CTAR_DBR) ||
- (cfslave->baudrate > (gd->bus_clk / (prescaler[0] * scaler[0])))) {
+ if ((bus_setup & DSPI_CTAR_DBR) ||
+ (cfspi->baudrate > (gd->bus_clk / (prescaler[0] * scaler[0])))) {
bus_setup |= DSPI_CTAR_DBR;
dbr = 1;
}
- if (mode & SPI_CPOL)
- bus_setup |= DSPI_CTAR_CPOL;
- if (mode & SPI_CPHA)
- bus_setup |= DSPI_CTAR_CPHA;
- if (mode & SPI_LSB_FIRST)
- bus_setup |= DSPI_CTAR_LSBFE;
-
/* Overwrite default value set in platform configuration file */
- if (mode & SPI_MODE_MOD) {
-
- if ((mode & 0xF0000000) == 0)
- bus_setup |=
- dspi->ctar[cfslave->slave.bus] & 0x78000000;
- else
- bus_setup |= ((mode & 0xF0000000) >> 1);
-
+ if (cfspi->mode & SPI_MODE_MOD) {
/*
* Check to see if it is enabled by default in platform
* config, or manual setting passed by mode parameter
*/
- if (mode & SPI_DBLRATE) {
+ if (cfspi->mode & SPI_MODE_DBLRATE) {
bus_setup |= DSPI_CTAR_DBR;
dbr = 1;
}
- bus_setup |= (mode & 0x0FC00000) >> 4; /* PSCSCK, PASC, PDT */
- bus_setup |= (mode & 0x000FFF00) >> 4; /* CSSCK, ASC, DT */
- } else
- bus_setup |= (dspi->ctar[cfslave->slave.bus] & 0x78FCFFF0);
-
- cfslave->charbit =
- ((dspi->ctar[cfslave->slave.bus] & 0x78000000) ==
- 0x78000000) ? 16 : 8;
+ }
pbrcnt = sizeof(prescaler) / sizeof(int);
brcnt = sizeof(scaler) / sizeof(int);
@@ -259,10 +278,10 @@ static struct spi_slave *cfspi_setup_slave(struct cf_spi_slave *cfslave,
for (j = 0; j < brcnt; j++) {
tmp = (baud_speed / scaler[j]) * (1 + dbr);
- if (tmp > cfslave->baudrate)
- diff = tmp - cfslave->baudrate;
+ if (tmp > cfspi->baudrate)
+ diff = tmp - cfspi->baudrate;
else
- diff = cfslave->baudrate - tmp;
+ diff = cfspi->baudrate - tmp;
if (diff < bestmatch) {
bestmatch = diff;
@@ -271,65 +290,174 @@ static struct spi_slave *cfspi_setup_slave(struct cf_spi_slave *cfslave,
}
}
}
+
+ bus_setup &= ~(DSPI_CTAR_PBR(0x03) | DSPI_CTAR_BR(0x0f));
bus_setup |= (DSPI_CTAR_PBR(best_i) | DSPI_CTAR_BR(best_j));
- dspi->ctar[cfslave->slave.bus] = bus_setup;
+ writel(bus_setup, &dspi->ctar[bus->seq]);
- return &cfslave->slave;
+ return 0;
}
-#endif /* CONFIG_CF_DSPI */
-#ifdef CONFIG_CMD_SPI
-int spi_cs_is_valid(unsigned int bus, unsigned int cs)
+static int coldfire_spi_set_mode(struct udevice *bus, uint mode)
{
- if (((cs >= 0) && (cs < 8)) && ((bus >= 0) && (bus < 8)))
- return 1;
- else
- return 0;
-}
+ struct coldfire_spi_priv *cfspi = dev_get_priv(bus);
+ struct dspi *dspi = cfspi->regs;
+ u32 bus_setup = 0;
-void spi_init(void)
-{
- cfspi_init();
-}
+ cfspi->mode = mode;
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
- unsigned int max_hz, unsigned int mode)
-{
- struct cf_spi_slave *cfslave;
+ if (cfspi->mode & SPI_CPOL)
+ bus_setup |= DSPI_CTAR_CPOL;
+ if (cfspi->mode & SPI_CPHA)
+ bus_setup |= DSPI_CTAR_CPHA;
+ if (cfspi->mode & SPI_LSB_FIRST)
+ bus_setup |= DSPI_CTAR_LSBFE;
- if (!spi_cs_is_valid(bus, cs))
- return NULL;
+ /* Overwrite default value set in platform configuration file */
+ if (cfspi->mode & SPI_MODE_MOD) {
+ if ((cfspi->mode & SPI_MODE_XFER_SZ_MASK) == 0)
+ bus_setup |=
+ readl(&dspi->ctar[bus->seq]) & MCF_FRM_SZ_16BIT;
+ else
+ bus_setup |=
+ ((cfspi->mode & SPI_MODE_XFER_SZ_MASK) >> 1);
- cfslave = spi_alloc_slave(struct cf_spi_slave, bus, cs);
- if (!cfslave)
- return NULL;
+ /* PSCSCK, PASC, PDT */
+ bus_setup |= (cfspi->mode & SPI_MODE_DLY_PRE_MASK) >> 4;
+ /* CSSCK, ASC, DT */
+ bus_setup |= (cfspi->mode & SPI_MODE_DLY_SCA_MASK) >> 4;
+ } else {
+ bus_setup |=
+ (readl(&dspi->ctar[bus->seq]) & MCF_CTAR_MODE_MASK);
+ }
+
+ cfspi->charbit =
+ ((readl(&dspi->ctar[bus->seq]) & MCF_FRM_SZ_16BIT) ==
+ MCF_FRM_SZ_16BIT) ? 16 : 8;
- cfslave->baudrate = max_hz;
+ setbits_be32(&dspi->ctar[bus->seq], bus_setup);
- /* specific setup */
- return cfspi_setup_slave(cfslave, mode);
+ return 0;
}
-void spi_free_slave(struct spi_slave *slave)
+static int coldfire_spi_probe(struct udevice *bus)
{
- struct cf_spi_slave *cfslave = to_cf_spi_slave(slave);
+ struct coldfire_spi_platdata *plat = dev_get_platdata(bus);
+ struct coldfire_spi_priv *cfspi = dev_get_priv(bus);
+ struct dspi *dspi = cfspi->regs;
+ int i;
- free(cfslave);
-}
+ cfspi->regs = (struct dspi *)plat->regs_addr;
-int spi_claim_bus(struct spi_slave *slave)
-{
- return cfspi_claim_bus(slave->bus, slave->cs);
+ cfspi->baudrate = plat->speed_hz;
+ cfspi->mode = plat->mode;
+
+ for (i = 0; i < MCF_DSPI_MAX_CTAR_REGS; i++) {
+ unsigned int ctar = 0;
+
+ if (plat->ctar[i][0] == 0)
+ break;
+
+ ctar = DSPI_CTAR_TRSZ(plat->ctar[i][0]) |
+ DSPI_CTAR_PCSSCK(plat->ctar[i][1]) |
+ DSPI_CTAR_PASC(plat->ctar[i][2]) |
+ DSPI_CTAR_PDT(plat->ctar[i][3]) |
+ DSPI_CTAR_CSSCK(plat->ctar[i][4]) |
+ DSPI_CTAR_ASC(plat->ctar[i][5]) |
+ DSPI_CTAR_DT(plat->ctar[i][6]) |
+ DSPI_CTAR_BR(plat->ctar[i][7]);
+
+ writel(ctar, &cfspi->regs->ctar[i]);
+ }
+
+ /* Default CTARs */
+ for (i = 0; i < MCF_DSPI_MAX_CTAR_REGS; i++)
+ writel(MCF_DSPI_DEFAULT_CTAR, &dspi->ctar[i]);
+
+ dspi->mcr = DSPI_MCR_MSTR | DSPI_MCR_CSIS7 | DSPI_MCR_CSIS6 |
+ DSPI_MCR_CSIS5 | DSPI_MCR_CSIS4 | DSPI_MCR_CSIS3 |
+ DSPI_MCR_CSIS2 | DSPI_MCR_CSIS1 | DSPI_MCR_CSIS0 |
+ DSPI_MCR_CRXF | DSPI_MCR_CTXF;
+
+ return 0;
}
-void spi_release_bus(struct spi_slave *slave)
+void spi_init(void)
{
- cfspi_release_bus(slave->bus, slave->cs);
}
-int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
- void *din, unsigned long flags)
+#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
+static int coldfire_dspi_ofdata_to_platdata(struct udevice *bus)
{
- return cfspi_xfer(slave, bitlen, dout, din, flags);
+ fdt_addr_t addr;
+ struct coldfire_spi_platdata *plat = bus->platdata;
+ const void *blob = gd->fdt_blob;
+ int node = dev_of_offset(bus);
+ int *ctar, len;
+
+ addr = devfdt_get_addr(bus);
+ if (addr == FDT_ADDR_T_NONE)
+ return -ENOMEM;
+
+ plat->regs_addr = addr;
+
+ plat->num_cs = fdtdec_get_int(blob, node, "num-cs",
+ MCF_DSPI_DEFAULT_MAX_CS);
+
+ plat->speed_hz = fdtdec_get_int(blob, node, "spi-max-frequency",
+ MCF_DSPI_DEFAULT_SCK_FREQ);
+
+ plat->mode = fdtdec_get_int(blob, node, "spi-mode",
+ MCF_DSPI_DEFAULT_MODE);
+
+ memset(plat->ctar, 0, sizeof(plat->ctar));
+
+ ctar = (int *)fdt_getprop(blob, node, "ctar-params", &len);
+
+ if (ctar && len) {
+ int i, q, ctar_regs;
+
+ ctar_regs = len / sizeof(unsigned int) / MAX_CTAR_FIELDS;
+
+ if (ctar_regs > MAX_CTAR_REGS)
+ ctar_regs = MAX_CTAR_REGS;
+
+ for (i = 0; i < ctar_regs; i++) {
+ for (q = 0; q < MAX_CTAR_FIELDS; q++)
+ plat->ctar[i][q] = *ctar++;
+ }
+ }
+
+ debug("DSPI: regs=%pa, max-frequency=%d, num-cs=%d, mode=%d\n",
+ (void *)plat->regs_addr,
+ plat->speed_hz, plat->num_cs, plat->mode);
+
+ return 0;
}
-#endif /* CONFIG_CMD_SPI */
+
+static const struct udevice_id coldfire_spi_ids[] = {
+ { .compatible = "fsl,mcf-dspi" },
+ { }
+};
+#endif
+
+static const struct dm_spi_ops coldfire_spi_ops = {
+ .claim_bus = coldfire_spi_claim_bus,
+ .release_bus = coldfire_spi_release_bus,
+ .xfer = coldfire_spi_xfer,
+ .set_speed = coldfire_spi_set_speed,
+ .set_mode = coldfire_spi_set_mode,
+};
+
+U_BOOT_DRIVER(coldfire_spi) = {
+ .name = "spi_coldfire",
+ .id = UCLASS_SPI,
+#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
+ .of_match = coldfire_spi_ids,
+ .ofdata_to_platdata = coldfire_dspi_ofdata_to_platdata,
+ .platdata_auto_alloc_size = sizeof(struct coldfire_spi_platdata),
+#endif
+ .probe = coldfire_spi_probe,
+ .ops = &coldfire_spi_ops,
+ .priv_auto_alloc_size = sizeof(struct coldfire_spi_priv),
+};
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index 23e7e7125f..b8f8e7a794 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -75,8 +75,12 @@ static int ehci_fsl_init_after_reset(struct ehci_ctrl *ctrl)
struct usb_ehci *ehci = NULL;
struct ehci_fsl_priv *priv = container_of(ctrl, struct ehci_fsl_priv,
ehci);
-
+#ifdef CONFIG_PPC
+ ehci = (struct usb_ehci *)lower_32_bits(priv->hcd_base);
+#else
ehci = (struct usb_ehci *)priv->hcd_base;
+#endif
+
if (ehci_fsl_init(priv, ehci, priv->ehci.hccr, priv->ehci.hcor) < 0)
return -ENXIO;
@@ -103,7 +107,11 @@ static int ehci_fsl_probe(struct udevice *dev)
debug("Can't get the EHCI register base address\n");
return -ENXIO;
}
+#ifdef CONFIG_PPC
+ ehci = (struct usb_ehci *)lower_32_bits(priv->hcd_base);
+#else
ehci = (struct usb_ehci *)priv->hcd_base;
+#endif
hccr = (struct ehci_hccr *)(&ehci->caplength);
hcor = (struct ehci_hcor *)
((void *)hccr + HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
diff --git a/env/Kconfig b/env/Kconfig
index 70858d3b40..1e10c7a4c4 100644
--- a/env/Kconfig
+++ b/env/Kconfig
@@ -470,7 +470,7 @@ config ENV_EXT4_FILE
It's a string of the EXT4 file name. This file use to store the
environment (explicit path to the file)
-if ARCH_ROCKCHIP || ARCH_SUNXI || ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_VERSAL || ARC
+if ARCH_ROCKCHIP || ARCH_SUNXI || ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_VERSAL || ARC || ARCH_STM32MP
config ENV_OFFSET
hex "Environment Offset"
diff --git a/env/common.c b/env/common.c
index 324502ed82..bd340fe9d5 100644
--- a/env/common.c
+++ b/env/common.c
@@ -23,7 +23,10 @@ DECLARE_GLOBAL_DATA_PTR;
#include <env_default.h>
struct hsearch_data env_htab = {
+#if CONFIG_IS_ENABLED(ENV_SUPPORT)
+ /* defined in flags.c, only compile with ENV_SUPPORT */
.change_ok = env_flags_validate,
+#endif
};
/*
@@ -225,7 +228,9 @@ void env_relocate(void)
#if defined(CONFIG_NEEDS_MANUAL_RELOC)
env_reloc();
env_fix_drivers();
- env_htab.change_ok += gd->reloc_off;
+
+ if (env_htab.change_ok)
+ env_htab.change_ok += gd->reloc_off;
#endif
if (gd->env_valid == ENV_INVALID) {
#if defined(CONFIG_ENV_IS_NOWHERE) || defined(CONFIG_SPL_BUILD)
diff --git a/include/configs/M52277EVB.h b/include/configs/M52277EVB.h
index 514733eef7..a9c260d5cf 100644
--- a/include/configs/M52277EVB.h
+++ b/include/configs/M52277EVB.h
@@ -103,17 +103,6 @@
/* DSPI and Serial Flash */
#define CONFIG_CF_DSPI
#define CONFIG_SYS_SBFHDR_SIZE 0x7
-#ifdef CONFIG_CMD_SPI
-# define CONFIG_SYS_DSPI_CS2
-
-# define CONFIG_SYS_DSPI_CTAR0 (DSPI_CTAR_TRSZ(7) | \
- DSPI_CTAR_PCSSCK_1CLK | \
- DSPI_CTAR_PASC(0) | \
- DSPI_CTAR_PDT(0) | \
- DSPI_CTAR_CSSCK(0) | \
- DSPI_CTAR_ASC(0) | \
- DSPI_CTAR_DT(1))
-#endif
/* Input, PCI, Flexbus, and VCO */
#define CONFIG_EXTRA_CLOCK
diff --git a/include/configs/M54418TWR.h b/include/configs/M54418TWR.h
index f7b0669fc5..e07684d820 100644
--- a/include/configs/M54418TWR.h
+++ b/include/configs/M54418TWR.h
@@ -152,18 +152,6 @@
#define CONFIG_CF_DSPI
#define CONFIG_SERIAL_FLASH
#define CONFIG_SYS_SBFHDR_SIZE 0x7
-#ifdef CONFIG_CMD_SPI
-
-# define CONFIG_SYS_DSPI_CTAR0 (DSPI_CTAR_TRSZ(7) | \
- DSPI_CTAR_PCSSCK_1CLK | \
- DSPI_CTAR_PASC(0) | \
- DSPI_CTAR_PDT(0) | \
- DSPI_CTAR_CSSCK(0) | \
- DSPI_CTAR_ASC(0) | \
- DSPI_CTAR_DT(1))
-# define CONFIG_SYS_DSPI_CTAR1 (CONFIG_SYS_DSPI_CTAR0)
-# define CONFIG_SYS_DSPI_CTAR2 (CONFIG_SYS_DSPI_CTAR0)
-#endif
/* Input, PCI, Flexbus, and VCO */
#define CONFIG_EXTRA_CLOCK
diff --git a/include/configs/M54451EVB.h b/include/configs/M54451EVB.h
index 57c8572aba..2bd0e62231 100644
--- a/include/configs/M54451EVB.h
+++ b/include/configs/M54451EVB.h
@@ -117,18 +117,6 @@
#define CONFIG_CF_DSPI
#define CONFIG_SERIAL_FLASH
#define CONFIG_SYS_SBFHDR_SIZE 0x7
-#ifdef CONFIG_CMD_SPI
-
-# define CONFIG_SYS_DSPI_CTAR0 (DSPI_CTAR_TRSZ(7) | \
- DSPI_CTAR_PCSSCK_1CLK | \
- DSPI_CTAR_PASC(0) | \
- DSPI_CTAR_PDT(0) | \
- DSPI_CTAR_CSSCK(0) | \
- DSPI_CTAR_ASC(0) | \
- DSPI_CTAR_DT(1))
-# define CONFIG_SYS_DSPI_CTAR1 (CONFIG_SYS_DSPI_CTAR0)
-# define CONFIG_SYS_DSPI_CTAR2 (CONFIG_SYS_DSPI_CTAR0)
-#endif
/* Input, PCI, Flexbus, and VCO */
#define CONFIG_EXTRA_CLOCK
diff --git a/include/configs/M54455EVB.h b/include/configs/M54455EVB.h
index 448dfc98a9..d73101f96c 100644
--- a/include/configs/M54455EVB.h
+++ b/include/configs/M54455EVB.h
@@ -143,16 +143,6 @@
/* DSPI and Serial Flash */
#define CONFIG_CF_DSPI
#define CONFIG_SYS_SBFHDR_SIZE 0x13
-#ifdef CONFIG_CMD_SPI
-
-# define CONFIG_SYS_DSPI_CTAR0 (DSPI_CTAR_TRSZ(7) | \
- DSPI_CTAR_PCSSCK_1CLK | \
- DSPI_CTAR_PASC(0) | \
- DSPI_CTAR_PDT(0) | \
- DSPI_CTAR_CSSCK(0) | \
- DSPI_CTAR_ASC(0) | \
- DSPI_CTAR_DT(1))
-#endif
/* PCI */
#ifdef CONFIG_CMD_PCI
diff --git a/include/configs/stm32mp1.h b/include/configs/stm32mp1.h
index fd6c97a0c6..e8be51a155 100644
--- a/include/configs/stm32mp1.h
+++ b/include/configs/stm32mp1.h
@@ -23,11 +23,6 @@
#endif
/*
- * malloc() pool size
- */
-#define CONFIG_SYS_MALLOC_LEN SZ_32M
-
-/*
* Configuration of the external SRAM memory used by U-Boot
*/
#define CONFIG_SYS_SDRAM_BASE STM32_DDR_BASE
@@ -43,11 +38,6 @@
*/
#define CONFIG_SYS_LOAD_ADDR STM32_DDR_BASE
-/*
- * Env parameters
- */
-#define CONFIG_ENV_SIZE SZ_4K
-
/* ATAGs */
#define CONFIG_CMDLINE_TAG
#define CONFIG_SETUP_MEMORY_TAGS
@@ -95,8 +85,6 @@
* for nand boot, boot with on ubifs partition on nand
* for nor boot, use the default order
*/
-#define CONFIG_PREBOOT
-
#define STM32MP_BOOTCMD "bootcmd_stm32mp=" \
"echo \"Boot over ${boot_device}${boot_instance}!\";" \
"if test ${boot_device} = serial || test ${boot_device} = usb;" \
diff --git a/include/configs/stmark2.h b/include/configs/stmark2.h
index 17f92d89c9..35966580a9 100644
--- a/include/configs/stmark2.h
+++ b/include/configs/stmark2.h
@@ -68,17 +68,6 @@
#define CONFIG_SYS_SBFHDR_SIZE 0x7
-#define CONFIG_SYS_DSPI_CTAR0 (DSPI_CTAR_TRSZ(7) | \
- DSPI_CTAR_PCSSCK_1CLK | \
- DSPI_CTAR_PASC(0) | \
- DSPI_CTAR_PDT(0) | \
- DSPI_CTAR_CSSCK(0) | \
- DSPI_CTAR_ASC(0) | \
- DSPI_CTAR_DT(1) | \
- DSPI_CTAR_BR(6))
-#define CONFIG_SYS_DSPI_CTAR1 (CONFIG_SYS_DSPI_CTAR0)
-#define CONFIG_SYS_DSPI_CTAR2 (CONFIG_SYS_DSPI_CTAR0)
-
/* Input, PCI, Flexbus, and VCO */
#define CONFIG_EXTRA_CLOCK
diff --git a/include/dm/platform_data/spi_coldfire.h b/include/dm/platform_data/spi_coldfire.h
new file mode 100644
index 0000000000..8ad8eaedfd
--- /dev/null
+++ b/include/dm/platform_data/spi_coldfire.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2018 Angelo Dureghello <angelo@sysam.it>
+ */
+
+#ifndef __spi_coldfire_h
+#define __spi_coldfire_h
+
+#define MAX_CTAR_REGS 8
+#define MAX_CTAR_FIELDS 8
+
+/*
+ * struct coldfire_spi_platdata - information about a coldfire spi module
+ *
+ * @regs_addr: base address for module registers
+ * @speed_hz: default SCK frequency
+ * @mode: default SPI mode
+ * @num_cs: number of DSPI chipselect signals
+ */
+struct coldfire_spi_platdata {
+ fdt_addr_t regs_addr;
+ uint speed_hz;
+ uint mode;
+ uint num_cs;
+ uint ctar[MAX_CTAR_REGS][MAX_CTAR_FIELDS];
+};
+
+#endif /* __spi_coldfire_h */
+
diff --git a/tools/stm32image.c b/tools/stm32image.c
index 08b32ba87d..ff3ec5f3f2 100644
--- a/tools/stm32image.c
+++ b/tools/stm32image.c
@@ -14,6 +14,8 @@
#define HEADER_VERSION_V1 0x1
/* default option : bit0 => no signature */
#define HEADER_DEFAULT_OPTION (cpu_to_le32(0x00000001))
+/* default binary type for U-Boot */
+#define HEADER_TYPE_UBOOT (cpu_to_le32(0x00000000))
struct stm32_header {
uint32_t magic_number;
@@ -29,7 +31,8 @@ struct stm32_header {
uint32_t option_flags;
uint32_t ecdsa_algorithm;
uint32_t ecdsa_public_key[64 / 4];
- uint32_t padding[84 / 4];
+ uint32_t padding[83 / 4];
+ uint32_t binary_type;
};
static struct stm32_header stm32image_header;
@@ -43,6 +46,7 @@ static void stm32image_default_header(struct stm32_header *ptr)
ptr->header_version[VER_MAJOR_IDX] = HEADER_VERSION_V1;
ptr->option_flags = HEADER_DEFAULT_OPTION;
ptr->ecdsa_algorithm = 1;
+ ptr->binary_type = HEADER_TYPE_UBOOT;
}
static uint32_t stm32image_checksum(void *start, uint32_t len)
@@ -112,6 +116,8 @@ static void stm32image_print_header(const void *ptr)
le32_to_cpu(stm32hdr->image_checksum));
printf("Option : 0x%08x\n",
le32_to_cpu(stm32hdr->option_flags));
+ printf("BinaryType : 0x%08x\n",
+ le32_to_cpu(stm32hdr->binary_type));
}
static void stm32image_set_header(void *ptr, struct stat *sbuf, int ifd,