summaryrefslogtreecommitdiff
path: root/drivers/ddr
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ddr')
-rw-r--r--drivers/ddr/marvell/a38x/ddr3_init.c5
-rw-r--r--drivers/ddr/marvell/a38x/ddr3_training.c5
-rw-r--r--drivers/ddr/marvell/a38x/ddr3_training_db.c3
-rw-r--r--drivers/ddr/marvell/a38x/ddr3_training_ip_def.h2
-rw-r--r--drivers/ddr/marvell/a38x/ddr3_training_ip_engine.c5
-rw-r--r--drivers/ddr/marvell/a38x/ddr_topology_def.h23
-rw-r--r--drivers/ddr/marvell/a38x/mv_ddr_build_message.c2
-rw-r--r--drivers/ddr/marvell/a38x/mv_ddr_plat.c9
-rw-r--r--drivers/ddr/marvell/a38x/mv_ddr_topology.c14
-rw-r--r--drivers/ddr/marvell/a38x/mv_ddr_topology.h2
-rw-r--r--drivers/ddr/marvell/a38x/xor.c6
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, &params);
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);