diff options
author | Tom Rini <trini@konsulko.com> | 2024-09-04 10:34:54 -0600 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2024-09-04 10:34:54 -0600 |
commit | 1630ff26cc960439b5949b80cfc604a2c8aa47dd (patch) | |
tree | d6fb9b9418accf492f669bbf257487ccffed2fe8 | |
parent | 1312faac5f52d27cfb45dfe1a5a93a2944ca5c21 (diff) | |
parent | bc8664c9f31195a0249dd4eb0794f4a8625ad864 (diff) |
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)
-rw-r--r-- | arch/arm/mach-mvebu/Kconfig | 1 | ||||
-rw-r--r-- | board/CZ.NIC/turris_omnia/turris_omnia.c | 101 | ||||
-rw-r--r-- | configs/turris_omnia_defconfig | 1 |
3 files changed, 86 insertions, 17 deletions
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index 4a8328760eb..c1a1a333e6c 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig @@ -149,6 +149,7 @@ config TARGET_TURRIS_OMNIA 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 2f29d26edf8..eb88ee7f1ed 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 @@ DECLARE_GLOBAL_DATA_PTR; #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 @@ static u32 omnia_mcu_crc32(const void *p, size_t len) 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 @@ static bool check_eeprom_crc(const void *buf, size_t size, u32 expected, 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 @@ static bool omnia_read_eeprom(struct omnia_eeprom *oep) 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 @@ bool board_use_old_ddr3_training(void) { 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 @@ static void fixup_speed_in_ddr_topology(struct mv_ddr_topology_map *topology) 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 @@ static void fixup_speed_in_ddr_topology(struct mv_ddr_topology_map *topology) 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 int set_regdomain(void) 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 @@ static void handle_reset_button(void) */ 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 c8756a3a788..93f0bc53f9e 100644 --- a/configs/turris_omnia_defconfig +++ b/configs/turris_omnia_defconfig @@ -92,7 +92,6 @@ CONFIG_SPL_OF_TRANSLATE=y 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 |