Commit 66869f95 authored by York Sun's avatar York Sun
Browse files

drivers/ddr/fsl: Update DDR driver for DDR4



Add/update registers for DDR4, including DQ mappings. Allow raw timing
method used for all controllers. Update mode_9 register to 0x500 for
improved stability. Check DDR controller version number individually
in case a SoC has multiple DDR controllers of different versions.
Increase read-write turnaround for DDR4 high speeds.
Signed-off-by: default avatarYork Sun <yorksun@freescale.com>
parent f8cb101e
......@@ -313,7 +313,10 @@ static void set_timing_cfg_0(const unsigned int ctrl_num,
#ifdef CONFIG_SYS_FSL_DDR4
/* tXP=max(4nCK, 6ns) */
int txp = max((int)mclk_ps * 4, 6000); /* unit=ps */
trwt_mclk = 2;
unsigned int data_rate = get_ddr_freq(ctrl_num);
/* for faster clock, need more time for data setup */
trwt_mclk = (data_rate/1000000 > 1900) ? 3 : 2;
twrt_mclk = 1;
act_pd_exit_mclk = picos_to_mclk(ctrl_num, txp);
pre_pd_exit_mclk = act_pd_exit_mclk;
......@@ -338,7 +341,7 @@ static void set_timing_cfg_0(const unsigned int ctrl_num,
*/
txp = max((int)mclk_ps * 3, (mclk_ps > 1540 ? 7500 : 6000));
ip_rev = fsl_ddr_get_version();
ip_rev = fsl_ddr_get_version(ctrl_num);
if (ip_rev >= 0x40700) {
/*
* MRS_CYC = max(tMRD, tMOD)
......@@ -544,7 +547,7 @@ static void set_timing_cfg_1(const unsigned int ctrl_num,
* we need set extend bit for it at
* TIMING_CFG_3[EXT_CASLAT]
*/
if (fsl_ddr_get_version() <= 0x40400)
if (fsl_ddr_get_version(ctrl_num) <= 0x40400)
caslat_ctrl = 2 * cas_latency - 1;
else
caslat_ctrl = (cas_latency - 1) << 1;
......@@ -1114,12 +1117,16 @@ static void set_ddr_sdram_mode_9(fsl_ddr_cfg_regs_t *ddr,
unsigned short esdmode4 = 0; /* Extended SDRAM mode 4 */
unsigned short esdmode5; /* Extended SDRAM mode 5 */
esdmode5 = 0x00000400; /* Data mask enabled */
esdmode5 = 0x00000500; /* Data mask enabled */
ddr->ddr_sdram_mode_9 = (0
| ((esdmode4 & 0xffff) << 16)
| ((esdmode5 & 0xffff) << 0)
);
/* only mode_9 use 0x500, others use 0x400 */
esdmode5 = 0x00000400; /* Data mask enabled */
debug("FSLDDR: ddr_sdram_mode_9) = 0x%08x\n", ddr->ddr_sdram_mode_9);
if (unq_mrs_en) { /* unique mode registers are supported */
for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
......@@ -2357,7 +2364,7 @@ compute_fsl_memctl_config_regs(const unsigned int ctrl_num,
set_ddr_cdr1(ddr, popts);
set_ddr_cdr2(ddr, popts);
set_ddr_sdram_cfg(ddr, popts, common_dimm);
ip_rev = fsl_ddr_get_version();
ip_rev = fsl_ddr_get_version(ctrl_num);
if (ip_rev > 0x40400)
unq_mrs_en = 1;
......
......@@ -205,6 +205,8 @@ static void lowest_common_dimm_parameters_edit(fsl_ddr_info_t *pinfo,
#define DIMM_PARM(x) {#x, offsetof(dimm_params_t, x), \
sizeof((dimm_params_t *)0)->x, 0}
#define DIMM_PARM_HEX(x) {#x, offsetof(dimm_params_t, x), \
sizeof((dimm_params_t *)0)->x, 1}
static void fsl_ddr_dimm_parameters_edit(fsl_ddr_info_t *pinfo,
unsigned int ctrl_num,
......@@ -220,6 +222,7 @@ static void fsl_ddr_dimm_parameters_edit(fsl_ddr_info_t *pinfo,
DIMM_PARM(primary_sdram_width),
DIMM_PARM(ec_sdram_width),
DIMM_PARM(registered_dimm),
DIMM_PARM(mirrored_dimm),
DIMM_PARM(device_width),
DIMM_PARM(n_row_addr),
......@@ -274,7 +277,27 @@ static void fsl_ddr_dimm_parameters_edit(fsl_ddr_info_t *pinfo,
DIMM_PARM(tdqsq_max_ps),
DIMM_PARM(tqhs_ps),
#endif
#ifdef CONFIG_SYS_FSL_DDR4
DIMM_PARM_HEX(dq_mapping[0]),
DIMM_PARM_HEX(dq_mapping[1]),
DIMM_PARM_HEX(dq_mapping[2]),
DIMM_PARM_HEX(dq_mapping[3]),
DIMM_PARM_HEX(dq_mapping[4]),
DIMM_PARM_HEX(dq_mapping[5]),
DIMM_PARM_HEX(dq_mapping[6]),
DIMM_PARM_HEX(dq_mapping[7]),
DIMM_PARM_HEX(dq_mapping[8]),
DIMM_PARM_HEX(dq_mapping[9]),
DIMM_PARM_HEX(dq_mapping[10]),
DIMM_PARM_HEX(dq_mapping[11]),
DIMM_PARM_HEX(dq_mapping[12]),
DIMM_PARM_HEX(dq_mapping[13]),
DIMM_PARM_HEX(dq_mapping[14]),
DIMM_PARM_HEX(dq_mapping[15]),
DIMM_PARM_HEX(dq_mapping[16]),
DIMM_PARM_HEX(dq_mapping[17]),
DIMM_PARM(dq_mapping_ors),
#endif
DIMM_PARM(rank_density),
DIMM_PARM(capacity),
DIMM_PARM(base_address),
......@@ -296,6 +319,7 @@ static void print_dimm_parameters(const dimm_params_t *pdimm)
DIMM_PARM(primary_sdram_width),
DIMM_PARM(ec_sdram_width),
DIMM_PARM(registered_dimm),
DIMM_PARM(mirrored_dimm),
DIMM_PARM(device_width),
DIMM_PARM(n_row_addr),
......@@ -314,6 +338,7 @@ static void print_dimm_parameters(const dimm_params_t *pdimm)
DIMM_PARM(tckmax_ps),
DIMM_PARM(caslat_x),
DIMM_PARM_HEX(caslat_x),
DIMM_PARM(taa_ps),
DIMM_PARM(caslat_x_minus_1),
DIMM_PARM(caslat_x_minus_2),
......@@ -322,6 +347,9 @@ static void print_dimm_parameters(const dimm_params_t *pdimm)
DIMM_PARM(trcd_ps),
DIMM_PARM(trp_ps),
DIMM_PARM(tras_ps),
#if defined(CONFIG_SYS_FSL_DDR4) || defined(CONFIG_SYS_FSL_DDR3)
DIMM_PARM(tfaw_ps),
#endif
#ifdef CONFIG_SYS_FSL_DDR4
DIMM_PARM(trfc1_ps),
DIMM_PARM(trfc2_ps),
......@@ -346,6 +374,27 @@ static void print_dimm_parameters(const dimm_params_t *pdimm)
DIMM_PARM(tdh_ps),
DIMM_PARM(tdqsq_max_ps),
DIMM_PARM(tqhs_ps),
#endif
#ifdef CONFIG_SYS_FSL_DDR4
DIMM_PARM_HEX(dq_mapping[0]),
DIMM_PARM_HEX(dq_mapping[1]),
DIMM_PARM_HEX(dq_mapping[2]),
DIMM_PARM_HEX(dq_mapping[3]),
DIMM_PARM_HEX(dq_mapping[4]),
DIMM_PARM_HEX(dq_mapping[5]),
DIMM_PARM_HEX(dq_mapping[6]),
DIMM_PARM_HEX(dq_mapping[7]),
DIMM_PARM_HEX(dq_mapping[8]),
DIMM_PARM_HEX(dq_mapping[9]),
DIMM_PARM_HEX(dq_mapping[10]),
DIMM_PARM_HEX(dq_mapping[11]),
DIMM_PARM_HEX(dq_mapping[12]),
DIMM_PARM_HEX(dq_mapping[13]),
DIMM_PARM_HEX(dq_mapping[14]),
DIMM_PARM_HEX(dq_mapping[15]),
DIMM_PARM_HEX(dq_mapping[16]),
DIMM_PARM_HEX(dq_mapping[17]),
DIMM_PARM(dq_mapping_ors),
#endif
};
static const unsigned int n_opts = ARRAY_SIZE(options);
......
......@@ -453,7 +453,7 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,
retval = compute_dimm_parameters(
i, spd, pdimm, j);
#ifdef CONFIG_SYS_DDR_RAW_TIMING
if (!i && !j && retval) {
if (!j && retval) {
printf("SPD error on controller %d! "
"Trying fallback to raw timing "
"calculation\n", i);
......
......@@ -23,12 +23,34 @@
#define ULL_8FS 0xFFFFFFFFULL
u32 fsl_ddr_get_version(void)
u32 fsl_ddr_get_version(unsigned int ctrl_num)
{
struct ccsr_ddr __iomem *ddr;
u32 ver_major_minor_errata;
ddr = (void *)_DDR_ADDR;
switch (ctrl_num) {
case 0:
ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
break;
#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1)
case 1:
ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR;
break;
#endif
#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2)
case 2:
ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR;
break;
#endif
#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3)
case 3:
ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR;
break;
#endif
default:
printf("%s unexpected ctrl_num = %u\n", __func__, ctrl_num);
return 0;
}
ver_major_minor_errata = (ddr_in32(&ddr->ip_rev1) & 0xFFFF) << 8;
ver_major_minor_errata |= (ddr_in32(&ddr->ip_rev2) & 0xFF00) >> 8;
......@@ -212,7 +234,7 @@ void print_ddr_info(unsigned int start_ctrl)
/* Calculate CAS latency based on timing cfg values */
cas_lat = ((ddr_in32(&ddr->timing_cfg_1) >> 16) & 0xf);
if (fsl_ddr_get_version() <= 0x40400)
if (fsl_ddr_get_version(0) <= 0x40400)
cas_lat += 1;
else
cas_lat += 2;
......
......@@ -34,9 +34,7 @@
#define ddr_clrsetbits32(a, clear, set) clrsetbits_be32(a, clear, set)
#endif
#define _DDR_ADDR CONFIG_SYS_FSL_DDR_ADDR
u32 fsl_ddr_get_version(void);
u32 fsl_ddr_get_version(unsigned int ctrl_num);
#if defined(CONFIG_DDR_SPD) || defined(CONFIG_SPD_EEPROM)
/*
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment