Merge https://gitlab.denx.de/u-boot/custodians/u-boot-marvell

CI: https://dev.azure.com/sr0718/u-boot/_build/results?buildId=374&view=results

- Turris Omnia DDR speed change with reset button (Marek)
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index 4a83287..c1a1a33 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -149,6 +149,7 @@
 	select SPL_SYS_MALLOC_SIMPLE
 	select SYS_I2C_MVTWSI
 	select ATSHA204A
+	select I2C_EEPROM
 	select ARMADA_38X_SUPPORT_OLD_DDR3_TRAINING
 
 config TARGET_TURRIS_MOX
diff --git a/board/CZ.NIC/turris_omnia/turris_omnia.c b/board/CZ.NIC/turris_omnia/turris_omnia.c
index 2f29d26..eb88ee7 100644
--- a/board/CZ.NIC/turris_omnia/turris_omnia.c
+++ b/board/CZ.NIC/turris_omnia/turris_omnia.c
@@ -23,6 +23,7 @@
 #include <dt-bindings/gpio/gpio.h>
 #include <fdt_support.h>
 #include <hexdump.h>
+#include <i2c_eeprom.h>
 #include <time.h>
 #include <turris-omnia-mcu-interface.h>
 #include <linux/bitops.h>
@@ -46,6 +47,9 @@
 #define OMNIA_I2C_EEPROM_CHIP_LEN	2
 #define OMNIA_I2C_EEPROM_MAGIC		0x0341a034
 
+#define OMNIA_RESET_TO_LOWER_DDR_SPEED	9
+#define OMNIA_LOWER_DDR_SPEED		"1333H"
+
 #define A385_SYS_RSTOUT_MASK		MVEBU_REGISTER(0x18260)
 #define   A385_SYS_RSTOUT_MASK_WD	BIT(10)
 
@@ -205,6 +209,20 @@
 	return ~bitrev32(crc);
 }
 
+static int omnia_mcu_get_reset(void)
+{
+	u8 reset_status;
+	int ret;
+
+	ret = omnia_mcu_read(CMD_GET_RESET, &reset_status, 1);
+	if (ret) {
+		printf("omnia_mcu_read failed: %i, reset status unknown!\n", ret);
+		return ret;
+	}
+
+	return reset_status;
+}
+
 /* Can only be called after relocation, since it needs cleared BSS */
 static int omnia_mcu_board_info(char *serial, u8 *mac, char *version)
 {
@@ -462,20 +480,27 @@
 	return true;
 }
 
+static struct udevice *omnia_get_eeprom(void)
+{
+	return omnia_get_i2c_chip("EEPROM", OMNIA_I2C_EEPROM_CHIP_ADDR,
+				  OMNIA_I2C_EEPROM_CHIP_LEN);
+}
+
 static bool omnia_read_eeprom(struct omnia_eeprom *oep)
 {
-	struct udevice *chip;
+	struct udevice *eeprom = omnia_get_eeprom();
 	int ret;
 
-	chip = omnia_get_i2c_chip("EEPROM", OMNIA_I2C_EEPROM_CHIP_ADDR,
-				  OMNIA_I2C_EEPROM_CHIP_LEN);
-
-	if (!chip)
+	if (!eeprom)
 		return false;
 
-	ret = dm_i2c_read(chip, 0, (void *)oep, sizeof(*oep));
+	if (IS_ENABLED(CONFIG_SPL_BUILD))
+		ret = dm_i2c_read(eeprom, 0, (void *)oep, sizeof(*oep));
+	else
+		ret = i2c_eeprom_read(eeprom, 0, (void *)oep, sizeof(*oep));
+
 	if (ret) {
-		printf("dm_i2c_read failed: %i, cannot read EEPROM\n", ret);
+		printf("cannot read EEPROM: %d\n", ret);
 		return false;
 	}
 
@@ -497,6 +522,35 @@
 	return true;
 }
 
+static void omnia_eeprom_set_lower_ddr_speed(void)
+{
+	struct udevice *eeprom = omnia_get_eeprom();
+	struct omnia_eeprom oep;
+	int ret;
+
+	if (!eeprom || !omnia_read_eeprom(&oep))
+		return;
+
+	puts("Setting DDR speed to " OMNIA_LOWER_DDR_SPEED " in EEPROM as requested by reset button... ");
+
+	/* check if already set */
+	if (!strncmp(oep.ddr_speed, OMNIA_LOWER_DDR_SPEED, sizeof(oep.ddr_speed)) &&
+	    (oep.old_ddr_training == 0 || oep.old_ddr_training == 0xff)) {
+		puts("was already set\n");
+		return;
+	}
+
+	strncpy(oep.ddr_speed, OMNIA_LOWER_DDR_SPEED, sizeof(oep.ddr_speed));
+	oep.old_ddr_training = 0xff;
+	oep.crc2 = crc32(0, (const void *)&oep, offsetof(struct omnia_eeprom, crc2));
+
+	ret = i2c_eeprom_write(eeprom, 0, (const void *)&oep, sizeof(oep));
+	if (ret)
+		printf("cannot write EEPROM: %d\n", ret);
+	else
+		puts("done\n");
+}
+
 int omnia_get_ram_size_gb(void)
 {
 	static int ram_size;
@@ -526,6 +580,13 @@
 {
 	struct omnia_eeprom oep;
 
+	/*
+	 * If lower DDR speed is requested by reset button, we can't use old DDR
+	 * training algorithm.
+	 */
+	if (omnia_mcu_get_reset() == OMNIA_RESET_TO_LOWER_DDR_SPEED)
+		return false;
+
 	if (!omnia_read_eeprom(&oep))
 		return false;
 
@@ -706,13 +767,19 @@
 	const struct omnia_ddr_speed *setting;
 	const char *speed;
 	static bool done;
+	int reset_status;
 
 	if (done)
 		return;
 
 	done = true;
 
-	speed = omnia_get_ddr_speed();
+	reset_status = omnia_mcu_get_reset();
+	if (reset_status == OMNIA_RESET_TO_LOWER_DDR_SPEED)
+		speed = OMNIA_LOWER_DDR_SPEED;
+	else
+		speed = omnia_get_ddr_speed();
+
 	if (!speed)
 		return;
 
@@ -729,7 +796,10 @@
 	if (params->speed_bin_index == setting->speed_bin)
 		return;
 
-	printf("Fixing up DDR3 speed (EEPROM defines %s)\n", speed);
+	if (reset_status == OMNIA_RESET_TO_LOWER_DDR_SPEED)
+		printf("Fixing up DDR3 speed to %s as requested by reset button\n", speed);
+	else
+		printf("Fixing up DDR3 speed (EEPROM defines %s)\n", speed);
 
 	params->speed_bin_index = setting->speed_bin;
 	params->memory_freq = setting->freq;
@@ -766,8 +836,7 @@
 static void handle_reset_button(void)
 {
 	const char * const vars[1] = { "bootcmd_rescue", };
-	int ret;
-	u8 reset_status;
+	int reset_status;
 
 	/*
 	 * Ensure that bootcmd_rescue has always stock value, so that running
@@ -776,12 +845,12 @@
 	 */
 	env_set_default_vars(1, (char * const *)vars, 0);
 
-	ret = omnia_mcu_read(CMD_GET_RESET, &reset_status, 1);
-	if (ret) {
-		printf("omnia_mcu_read failed: %i, reset status unknown!\n",
-		       ret);
+	reset_status = omnia_mcu_get_reset();
+	if (reset_status < 0)
 		return;
-	}
+
+	if (reset_status == OMNIA_RESET_TO_LOWER_DDR_SPEED)
+		return omnia_eeprom_set_lower_ddr_speed();
 
 	env_set_ulong("omnia_reset", reset_status);
 
diff --git a/configs/turris_omnia_defconfig b/configs/turris_omnia_defconfig
index c8756a3..93f0bc5 100644
--- a/configs/turris_omnia_defconfig
+++ b/configs/turris_omnia_defconfig
@@ -92,7 +92,6 @@
 CONFIG_AHCI_PCI=y
 CONFIG_AHCI_MVEBU=y
 CONFIG_DM_PCA953X=y
-CONFIG_I2C_EEPROM=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_MV=y
 CONFIG_DM_MTD=y