return 0;
}
+static void eeprom_field_print_bool(const struct eeprom_field *field)
+{
+ unsigned char val = field->buf[0];
+
+ printf(PRINT_FIELD_SEGMENT, field->name);
+
+ if (val == 0xff)
+ puts("(empty, defaults to 0)\n");
+ else
+ printf("%u\n", val);
+}
+
+static int eeprom_field_update_bool(struct eeprom_field *field, char *value)
+{
+ unsigned char *val = &field->buf[0];
+
+ if (value[0] == '\0') {
+ /* setting default value */
+ *val = 0xff;
+
+ return 0;
+ }
+
+ if (value[1] != '\0')
+ return -1;
+
+ if (value[0] == '1' || value[0] == '0')
+ *val = value[0] - '0';
+ else
+ return -1;
+
+ return 0;
+}
+
static struct eeprom_field omnia_layout[] = {
_DEF_FIELD("Magic constant", 4, bin),
_DEF_FIELD("RAM size in GB", 4, ramsz),
_DEF_FIELD("Wi-Fi Region", 4, region),
_DEF_FIELD("CRC32 checksum", 4, bin),
_DEF_FIELD("DDR speed", 5, ddr_speed),
- _DEF_FIELD("Extended reserved fields", 39, reserved),
+ _DEF_FIELD("Use old DDR training", 1, bool),
+ _DEF_FIELD("Extended reserved fields", 38, reserved),
_DEF_FIELD("Extended CRC32 checksum", 4, bin),
};
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2024 Marek Behún <kabel@kernel.org>
+ */
+
+#include <asm/arch/soc.h>
+#include <asm/io.h>
+
+#include "../drivers/ddr/marvell/a38x/old/ddr3_init.h"
+
+static struct hws_topology_map board_topology_map_1g = {
+ 0x1, /* active interfaces */
+ /* cs_mask, mirror, dqs_swap, ck_swap X PUPs */
+ { { { {0x1, 0, 0, 0},
+ {0x1, 0, 0, 0},
+ {0x1, 0, 0, 0},
+ {0x1, 0, 0, 0},
+ {0x1, 0, 0, 0} },
+ SPEED_BIN_DDR_1600K, /* speed_bin */
+ BUS_WIDTH_16, /* memory_width */
+ MEM_4G, /* mem_size */
+ DDR_FREQ_800, /* frequency */
+ 0, 0, /* cas_l cas_wl */
+ HWS_TEMP_NORMAL, /* temperature */
+ HWS_TIM_2T} }, /* timing (force 2t) */
+ 5, /* Num Of Bus Per Interface*/
+ BUS_MASK_32BIT /* Busses mask */
+};
+
+static struct hws_topology_map board_topology_map_2g = {
+ 0x1, /* active interfaces */
+ /* cs_mask, mirror, dqs_swap, ck_swap X PUPs */
+ { { { {0x1, 0, 0, 0},
+ {0x1, 0, 0, 0},
+ {0x1, 0, 0, 0},
+ {0x1, 0, 0, 0},
+ {0x1, 0, 0, 0} },
+ SPEED_BIN_DDR_1600K, /* speed_bin */
+ BUS_WIDTH_16, /* memory_width */
+ MEM_8G, /* mem_size */
+ DDR_FREQ_800, /* frequency */
+ 0, 0, /* cas_l cas_wl */
+ HWS_TEMP_NORMAL, /* temperature */
+ HWS_TIM_2T} }, /* timing (force 2t) */
+ 5, /* Num Of Bus Per Interface*/
+ BUS_MASK_32BIT /* Busses mask */
+};
+
+/* defined in turris_omnia.c */
+extern int omnia_get_ram_size_gb(void);
+
+struct hws_topology_map *ddr3_get_topology_map(void)
+{
+ if (omnia_get_ram_size_gb() == 2)
+ return &board_topology_map_2g;
+ else
+ return &board_topology_map_1g;
+}
+
+__weak u32 sys_env_get_topology_update_info(struct topology_update_info *tui)
+{
+ return MV_OK;
+}
/* second part (only considered if crc2 is not all-ones) */
char ddr_speed[5];
- u8 reserved[39];
+ u8 old_ddr_training;
+ u8 reserved[38];
u32 crc2;
};
return true;
}
-static int omnia_get_ram_size_gb(void)
+int omnia_get_ram_size_gb(void)
{
static int ram_size;
struct omnia_eeprom oep;
return ram_size;
}
+bool board_use_old_ddr3_training(void)
+{
+ struct omnia_eeprom oep;
+
+ if (!omnia_read_eeprom(&oep))
+ return false;
+
+ if (!is_omnia_eeprom_second_part_valid(&oep))
+ return false;
+
+ return oep.old_ddr_training == 1;
+}
+
static const char *omnia_get_ddr_speed(void)
{
struct omnia_eeprom oep;