diff options
Diffstat (limited to 'drivers/ddr')
-rw-r--r-- | drivers/ddr/marvell/a38x/ddr3_init.c | 5 | ||||
-rw-r--r-- | drivers/ddr/marvell/a38x/ddr3_training.c | 5 | ||||
-rw-r--r-- | drivers/ddr/marvell/a38x/ddr3_training_db.c | 3 | ||||
-rw-r--r-- | drivers/ddr/marvell/a38x/ddr3_training_ip_def.h | 2 | ||||
-rw-r--r-- | drivers/ddr/marvell/a38x/ddr3_training_ip_engine.c | 5 | ||||
-rw-r--r-- | drivers/ddr/marvell/a38x/ddr_topology_def.h | 23 | ||||
-rw-r--r-- | drivers/ddr/marvell/a38x/mv_ddr_build_message.c | 2 | ||||
-rw-r--r-- | drivers/ddr/marvell/a38x/mv_ddr_plat.c | 9 | ||||
-rw-r--r-- | drivers/ddr/marvell/a38x/mv_ddr_topology.c | 14 | ||||
-rw-r--r-- | drivers/ddr/marvell/a38x/mv_ddr_topology.h | 2 | ||||
-rw-r--r-- | drivers/ddr/marvell/a38x/xor.c | 6 |
11 files changed, 64 insertions, 12 deletions
diff --git a/drivers/ddr/marvell/a38x/ddr3_init.c b/drivers/ddr/marvell/a38x/ddr3_init.c index a971cc155a0..7488770268c 100644 --- a/drivers/ddr/marvell/a38x/ddr3_init.c +++ b/drivers/ddr/marvell/a38x/ddr3_init.c @@ -104,6 +104,7 @@ int ddr3_init(void) static int mv_ddr_training_params_set(u8 dev_num) { struct tune_train_params params; + struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); int status; u32 cs_num; int ck_delay; @@ -136,6 +137,10 @@ static int mv_ddr_training_params_set(u8 dev_num) if (ck_delay > 0) params.ck_delay = ck_delay; + /* Use platform specific override ODT value */ + if (tm->odt_config) + params.g_odt_config = tm->odt_config; + status = ddr3_tip_tune_training_params(dev_num, ¶ms); if (MV_OK != status) { printf("%s Training Sequence - FAILED\n", ddr_type); diff --git a/drivers/ddr/marvell/a38x/ddr3_training.c b/drivers/ddr/marvell/a38x/ddr3_training.c index 34cc1709103..2b3af23202b 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training.c +++ b/drivers/ddr/marvell/a38x/ddr3_training.c @@ -143,6 +143,7 @@ static struct reg_data odpg_default_value[] = { {0x15a4, 0x0, MASK_ALL_BITS}, {0x15a8, 0x0, MASK_ALL_BITS}, {0x15ac, 0x0, MASK_ALL_BITS}, + {0x1600, 0x0, MASK_ALL_BITS}, {0x1604, 0x0, MASK_ALL_BITS}, {0x1608, 0x0, MASK_ALL_BITS}, {0x160c, 0x0, MASK_ALL_BITS}, @@ -218,7 +219,7 @@ static int ddr3_tip_pad_inv(void) DDR_PHY_CONTROL, PHY_CTRL_PHY_REG, data, data); -#else /* !CONFIG_ARMADA_38X && !CONFIG_ARMADA_39X && !A70X0 && !A80X0 && !A3900 */ +#else /* !CONFIG_ARMADA_38X && !CONFIG_ARMADA_39X */ #pragma message "unknown platform to configure ddr clock swap" #endif } @@ -1569,6 +1570,8 @@ int ddr3_tip_freq_set(u32 dev_num, enum hws_access_type access_type, val = ((cl_mask_table[cl_value] & 0x1) << 2) | ((cl_mask_table[cl_value] & 0xe) << 3); + cs_mask[0] = 0xc; + CHECK_STATUS(ddr3_tip_write_mrs_cmd(dev_num, cs_mask, MR_CMD0, val, (0x7 << 4) | (0x1 << 2))); diff --git a/drivers/ddr/marvell/a38x/ddr3_training_db.c b/drivers/ddr/marvell/a38x/ddr3_training_db.c index b2f11a83996..6aa7b6069e8 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training_db.c +++ b/drivers/ddr/marvell/a38x/ddr3_training_db.c @@ -833,6 +833,9 @@ u32 pattern_table_get_word(u32 dev_num, enum hws_pattern type, u8 index) pattern = pattern_table_get_isi_word16(index); break; default: + if (((int)type == 29) || ((int)type == 30)) + break; + printf("error: %s: unsupported pattern type [%d] found\n", __func__, (int)type); pattern = 0; diff --git a/drivers/ddr/marvell/a38x/ddr3_training_ip_def.h b/drivers/ddr/marvell/a38x/ddr3_training_ip_def.h index 2a68669f36c..8765df7cfbb 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training_ip_def.h +++ b/drivers/ddr/marvell/a38x/ddr3_training_ip_def.h @@ -80,6 +80,8 @@ #define ADDR_SIZE_2GB 0x10000000 #define ADDR_SIZE_4GB 0x20000000 #define ADDR_SIZE_8GB 0x40000000 +#define ADDR_SIZE_16GB 0x80000000 + enum hws_edge_compare { EDGE_PF, diff --git a/drivers/ddr/marvell/a38x/ddr3_training_ip_engine.c b/drivers/ddr/marvell/a38x/ddr3_training_ip_engine.c index 979f3530b79..5fd9a052fa0 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training_ip_engine.c +++ b/drivers/ddr/marvell/a38x/ddr3_training_ip_engine.c @@ -864,8 +864,11 @@ int ddr3_tip_load_all_pattern_to_mem(u32 dev_num) DUAL_DUNIT_CFG_REG, (1 << 3), (1 << 3))); } - for (pattern = 0; pattern < PATTERN_LAST; pattern++) + for (pattern = 0; pattern < PATTERN_LAST; pattern++) { + if (pattern == PATTERN_TEST) + continue; ddr3_tip_load_pattern_to_mem(dev_num, pattern); + } return MV_OK; } diff --git a/drivers/ddr/marvell/a38x/ddr_topology_def.h b/drivers/ddr/marvell/a38x/ddr_topology_def.h index 34196b16628..7f2317edfac 100644 --- a/drivers/ddr/marvell/a38x/ddr_topology_def.h +++ b/drivers/ddr/marvell/a38x/ddr_topology_def.h @@ -14,6 +14,11 @@ #define MV_DDR_MAX_BUS_NUM 9 #define MV_DDR_MAX_IFACE_NUM 1 +enum mv_ddr_twin_die { + NOT_COMBINED, + COMBINED, +}; + struct bus_params { /* Chip Select (CS) bitmask (bits 0-CS0, bit 1- CS1 ...) */ u8 cs_bitmask; @@ -113,6 +118,9 @@ struct mv_ddr_topology_map { /* source of ddr configuration data */ enum mv_ddr_cfg_src cfg_src; + /* ddr twin-die */ + enum mv_ddr_twin_die twin_die_combined; + /* raw spd data */ union mv_ddr_spd_data spd_data; @@ -125,6 +133,9 @@ struct mv_ddr_topology_map { /* electrical parameters */ unsigned int electrical_data[MV_DDR_EDATA_LAST]; + /* ODT configuration */ + u32 odt_config; + /* Clock enable mask */ u32 clk_enable; @@ -148,7 +159,13 @@ enum mv_ddr_validation { MV_DDR_VAL_DIS, MV_DDR_VAL_RX, MV_DDR_VAL_TX, - MV_DDR_VAL_RX_TX + MV_DDR_VAL_RX_TX, + MV_DDR_MEMORY_CHECK +}; + +enum mv_ddr_sscg { + SSCG_EN, + SSCG_DIS, }; struct mv_ddr_iface { @@ -179,8 +196,12 @@ struct mv_ddr_iface { /* ddr interface validation mode */ enum mv_ddr_validation validation; + /* ddr interface validation mode */ + enum mv_ddr_sscg sscg; + /* ddr interface topology map */ struct mv_ddr_topology_map tm; + }; struct mv_ddr_iface *mv_ddr_iface_get(void); diff --git a/drivers/ddr/marvell/a38x/mv_ddr_build_message.c b/drivers/ddr/marvell/a38x/mv_ddr_build_message.c index cc6234fd406..a2bb8a96a65 100644 --- a/drivers/ddr/marvell/a38x/mv_ddr_build_message.c +++ b/drivers/ddr/marvell/a38x/mv_ddr_build_message.c @@ -1,3 +1,3 @@ // SPDX-License-Identifier: GPL-2.0 const char mv_ddr_build_message[] = ""; -const char mv_ddr_version_string[] = "mv_ddr: mv_ddr-armada-18.09.2"; +const char mv_ddr_version_string[] = "mv_ddr: 14.0.0"; diff --git a/drivers/ddr/marvell/a38x/mv_ddr_plat.c b/drivers/ddr/marvell/a38x/mv_ddr_plat.c index 72f0dfbbbb1..0d1df189e82 100644 --- a/drivers/ddr/marvell/a38x/mv_ddr_plat.c +++ b/drivers/ddr/marvell/a38x/mv_ddr_plat.c @@ -4,6 +4,7 @@ */ #include "ddr3_init.h" +#include "mv_ddr_common.h" #include "mv_ddr_training_db.h" #include "mv_ddr_regs.h" #include "mv_ddr_sys_env_lib.h" @@ -1016,7 +1017,7 @@ int ddr3_calc_mem_cs_size(u32 cs, uint64_t *cs_size) return MV_BAD_VALUE; } - *cs_size = cs_mem_size << 20; /* write cs size in bytes */ + *cs_size = cs_mem_size; return MV_OK; } @@ -1025,9 +1026,11 @@ static int ddr3_fast_path_dynamic_cs_size_config(u32 cs_ena) { u32 reg, cs; uint64_t mem_total_size = 0; + uint64_t cs_mem_size_mb = 0; uint64_t cs_mem_size = 0; uint64_t mem_total_size_c, cs_mem_size_c; + #ifdef DEVICE_MAX_DRAM_ADDRESS_SIZE u32 physical_mem_size; u32 max_mem_size = DEVICE_MAX_DRAM_ADDRESS_SIZE; @@ -1038,8 +1041,9 @@ static int ddr3_fast_path_dynamic_cs_size_config(u32 cs_ena) for (cs = 0; cs < MAX_CS_NUM; cs++) { if (cs_ena & (1 << cs)) { /* get CS size */ - if (ddr3_calc_mem_cs_size(cs, &cs_mem_size) != MV_OK) + if (ddr3_calc_mem_cs_size(cs, &cs_mem_size_mb) != MV_OK) return MV_FAIL; + cs_mem_size = cs_mem_size_mb * _1M; #ifdef DEVICE_MAX_DRAM_ADDRESS_SIZE /* @@ -1088,6 +1092,7 @@ static int ddr3_fast_path_dynamic_cs_size_config(u32 cs_ena) */ mem_total_size_c = (mem_total_size >> 16) & 0xffffffffffff; cs_mem_size_c = (cs_mem_size >> 16) & 0xffffffffffff; + /* if the sum less than 2 G - calculate the value */ if (mem_total_size_c + cs_mem_size_c < 0x10000) mem_total_size += cs_mem_size; diff --git a/drivers/ddr/marvell/a38x/mv_ddr_topology.c b/drivers/ddr/marvell/a38x/mv_ddr_topology.c index 09840b1e70f..2db6283c238 100644 --- a/drivers/ddr/marvell/a38x/mv_ddr_topology.c +++ b/drivers/ddr/marvell/a38x/mv_ddr_topology.c @@ -127,6 +127,11 @@ int mv_ddr_topology_map_update(void) speed_bin_index = iface_params->speed_bin_index; freq = iface_params->memory_freq; + if (tm->twin_die_combined == COMBINED) { + iface_params->bus_width = MV_DDR_DEV_WIDTH_8BIT; + iface_params->memory_size -= 1; + } + if (iface_params->cas_l == 0) iface_params->cas_l = mv_ddr_cl_val_get(speed_bin_index, freq); @@ -144,6 +149,9 @@ unsigned short mv_ddr_bus_bit_mask_get(void) unsigned int octets_per_if_num = ddr3_tip_dev_attr_get(0, MV_ATTR_OCTET_PER_INTERFACE); if (tm->cfg_src == MV_DDR_CFG_SPD) { + if (tm->bus_act_mask == MV_DDR_32BIT_ECC_PUP8_BUS_MASK) + tm->spd_data.byte_fields.byte_13.bit_fields.primary_bus_width = MV_DDR_PRI_BUS_WIDTH_32; + enum mv_ddr_pri_bus_width pri_bus_width = mv_ddr_spd_pri_bus_width_get(&tm->spd_data); enum mv_ddr_bus_width_ext bus_width_ext = mv_ddr_spd_bus_width_ext_get(&tm->spd_data); @@ -151,7 +159,7 @@ unsigned short mv_ddr_bus_bit_mask_get(void) case MV_DDR_PRI_BUS_WIDTH_16: pri_and_ext_bus_width = BUS_MASK_16BIT; break; - case MV_DDR_PRI_BUS_WIDTH_32: + case MV_DDR_PRI_BUS_WIDTH_32: /*each bit represents byte, so 0xf-is means 4 bytes-32 bit*/ pri_and_ext_bus_width = BUS_MASK_32BIT; break; case MV_DDR_PRI_BUS_WIDTH_64: @@ -245,7 +253,8 @@ static unsigned int mem_size[] = { ADDR_SIZE_1GB, ADDR_SIZE_2GB, ADDR_SIZE_4GB, - ADDR_SIZE_8GB + ADDR_SIZE_8GB, + ADDR_SIZE_16GB /* TODO: add capacity up to 256GB */ }; @@ -277,7 +286,6 @@ unsigned long long mv_ddr_mem_sz_per_cs_get(void) mem_sz_per_cs = (unsigned long long)mem_size[iface_params->memory_size] * (unsigned long long)sphys / (unsigned long long)sphys_per_dunit; - return mem_sz_per_cs; } diff --git a/drivers/ddr/marvell/a38x/mv_ddr_topology.h b/drivers/ddr/marvell/a38x/mv_ddr_topology.h index 4fca47689f1..1cb69ad0855 100644 --- a/drivers/ddr/marvell/a38x/mv_ddr_topology.h +++ b/drivers/ddr/marvell/a38x/mv_ddr_topology.h @@ -179,7 +179,9 @@ enum mv_ddr_dic_evalue { /* phy electrical configuration values */ enum mv_ddr_ohm_evalue { + MV_DDR_OHM_20 = 20,/*relevant for Synopsys C/A Drive strength only*/ MV_DDR_OHM_30 = 30, + MV_DDR_OHM_40 = 40,/*relevant for Synopsys C/A Drive strength only*/ MV_DDR_OHM_48 = 48, MV_DDR_OHM_60 = 60, MV_DDR_OHM_80 = 80, diff --git a/drivers/ddr/marvell/a38x/xor.c b/drivers/ddr/marvell/a38x/xor.c index 5fb9e216d38..98fb39eaf0f 100644 --- a/drivers/ddr/marvell/a38x/xor.c +++ b/drivers/ddr/marvell/a38x/xor.c @@ -340,7 +340,7 @@ void ddr3_new_tip_ecc_scrub(void) { u32 cs_c, max_cs; u32 cs_ena = 0; - uint64_t total_mem_size, cs_mem_size = 0; + uint64_t total_mem_size, cs_mem_size_mb = 0, cs_mem_size = 0; printf("DDR Training Sequence - Start scrubbing\n"); max_cs = mv_ddr_cs_num_get(); @@ -349,9 +349,9 @@ void ddr3_new_tip_ecc_scrub(void) #if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ARMADA_39X) /* all chip-selects are of same size */ - ddr3_calc_mem_cs_size(0, &cs_mem_size); + ddr3_calc_mem_cs_size(0, &cs_mem_size_mb); #endif - + cs_mem_size = cs_mem_size_mb * _1M; mv_sys_xor_init(max_cs, cs_ena, cs_mem_size, 0); total_mem_size = max_cs * cs_mem_size; mv_xor_mem_init(0, 0, total_mem_size, 0xdeadbeef, 0xdeadbeef); |