From 426230a65f2dd62c3b6c1509e9775d5500db20d3 Mon Sep 17 00:00:00 2001 From: York Sun Date: Mon, 29 Jan 2018 09:44:33 -0800 Subject: drivers/ddr/fsl: Fix DDR4 RDIMM support For DDR4, command/address delay in mode registers and parity latency in timing config register are only needed for UDIMMs, but not RDIMMs. Add additional register rcw_3 for DDR4 RDIMM. Fix mirrored bit for dual rank RDIMMs. Set sdram_cfg_3[DIS_MRS_PAR] for RDIMMs. Fix calculation of timing config registers. Use hexadecimal format for printing RCW (register control word) registers. Signed-off-by: York Sun --- drivers/ddr/fsl/ddr4_dimm_params.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/ddr/fsl/ddr4_dimm_params.c') diff --git a/drivers/ddr/fsl/ddr4_dimm_params.c b/drivers/ddr/fsl/ddr4_dimm_params.c index 42834ca7b21..6e26ba88a5d 100644 --- a/drivers/ddr/fsl/ddr4_dimm_params.c +++ b/drivers/ddr/fsl/ddr4_dimm_params.c @@ -179,6 +179,8 @@ unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num, case DDR4_SPD_MODULETYPE_RDIMM: /* Registered/buffered DIMMs */ pdimm->registered_dimm = 1; + if (spd->mod_section.registered.reg_map & 0x1) + pdimm->mirrored_dimm = 1; break; case DDR4_SPD_MODULETYPE_UDIMM: -- cgit v1.2.3 From c0c32af0b2f037e3e167c7ac82e7110ebae48fb5 Mon Sep 17 00:00:00 2001 From: York Sun Date: Mon, 29 Jan 2018 09:44:35 -0800 Subject: drivers/ddr/fsl: Add 3DS RDIMM support On top of RDIMM support, add new register calculation to support 3DS RDIMMs. Only symmetrical 3DS is supported at this time. Signed-off-by: York Sun --- drivers/ddr/fsl/ddr4_dimm_params.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'drivers/ddr/fsl/ddr4_dimm_params.c') diff --git a/drivers/ddr/fsl/ddr4_dimm_params.c b/drivers/ddr/fsl/ddr4_dimm_params.c index 6e26ba88a5d..1f1d9b897a4 100644 --- a/drivers/ddr/fsl/ddr4_dimm_params.c +++ b/drivers/ddr/fsl/ddr4_dimm_params.c @@ -1,5 +1,8 @@ /* - * Copyright 2014 Freescale Semiconductor, Inc. + * Copyright 2014-2016 Freescale Semiconductor, Inc. + * Copyright 2017-2018 NXP Semiconductor + * + * SPDX-License-Identifier: GPL-2.0+ * * calculate the organization and timing parameter * from ddr3 spd, please refer to the spec @@ -98,6 +101,10 @@ compute_ranksize(const struct ddr4_spd_eeprom_s *spd) if ((spd->organization & 0x7) < 4) nbit_sdram_width = (spd->organization & 0x7) + 2; package_3ds = (spd->package_type & 0x3) == 0x2; + if ((spd->package_type & 0x80) && !package_3ds) { /* other than 3DS */ + printf("Warning: not supported SDRAM package type\n"); + return 0; + } if (package_3ds) die_count = (spd->package_type >> 4) & 0x7; @@ -105,7 +112,7 @@ compute_ranksize(const struct ddr4_spd_eeprom_s *spd) nbit_primary_bus_width - nbit_sdram_width + die_count); - debug("DDR: DDR III rank density = 0x%16llx\n", bsize); + debug("DDR: DDR rank density = 0x%16llx\n", bsize); return bsize; } @@ -163,6 +170,7 @@ unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num, pdimm->n_ranks = ((spd->organization >> 3) & 0x7) + 1; pdimm->rank_density = compute_ranksize(spd); pdimm->capacity = pdimm->n_ranks * pdimm->rank_density; + pdimm->die_density = spd->density_banks & 0xf; pdimm->primary_sdram_width = 1 << (3 + (spd->bus_width & 0x7)); if ((spd->bus_width >> 3) & 0x3) pdimm->ec_sdram_width = 8; @@ -171,6 +179,8 @@ unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num, pdimm->data_width = pdimm->primary_sdram_width + pdimm->ec_sdram_width; pdimm->device_width = 1 << ((spd->organization & 0x7) + 2); + pdimm->package_3ds = (spd->package_type & 0x3) == 0x2 ? + (spd->package_type >> 4) & 0x7 : 0; /* These are the types defined by the JEDEC SPD spec */ pdimm->mirrored_dimm = 0; @@ -310,6 +320,17 @@ unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num, /* min CAS to CAS Delay Time (tCCD_Lmin), same bank group */ pdimm->tccdl_ps = spd_to_ps(spd->tccdl_min, spd->fine_tccdl_min); + if (pdimm->package_3ds) { + if (pdimm->die_density <= 0x4) { + pdimm->trfc_slr_ps = 260000; + } else if (pdimm->die_density <= 0x5) { + pdimm->trfc_slr_ps = 350000; + } else { + printf("WARN: Unsupported logical rank density 0x%x\n", + pdimm->die_density); + } + } + /* * Average periodic refresh interval * tREFI = 7.8 us at normal temperature range -- cgit v1.2.3 From 564e9383e53b567114bd3403246c0759a6d69c50 Mon Sep 17 00:00:00 2001 From: York Sun Date: Mon, 29 Jan 2018 10:24:08 -0800 Subject: drivers/ddr/fsl: Add calculation of register control words DDR4 RDIMM has some information in SPD to be used to calculate the control words for register chip. The rest can be found from JEDEC spec DDR4RCD02. Signed-off-by: York Sun --- drivers/ddr/fsl/ddr4_dimm_params.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'drivers/ddr/fsl/ddr4_dimm_params.c') diff --git a/drivers/ddr/fsl/ddr4_dimm_params.c b/drivers/ddr/fsl/ddr4_dimm_params.c index 1f1d9b897a4..5c8fc8804d4 100644 --- a/drivers/ddr/fsl/ddr4_dimm_params.c +++ b/drivers/ddr/fsl/ddr4_dimm_params.c @@ -139,6 +139,7 @@ unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num, }; int spd_error = 0; u8 *ptr; + u8 val; if (spd->mem_type) { if (spd->mem_type != SPD_MEMTYPE_DDR4) { @@ -191,6 +192,26 @@ unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num, pdimm->registered_dimm = 1; if (spd->mod_section.registered.reg_map & 0x1) pdimm->mirrored_dimm = 1; + val = spd->mod_section.registered.ca_stren; + pdimm->rcw[3] = val >> 4; + pdimm->rcw[4] = ((val & 0x3) << 2) | ((val & 0xc) >> 2); + val = spd->mod_section.registered.clk_stren; + pdimm->rcw[5] = ((val & 0x3) << 2) | ((val & 0xc) >> 2); + /* Not all in SPD. For convience only. Boards may overwrite. */ + pdimm->rcw[6] = 0xf; + /* + * A17 only used for 16Gb and above devices. + * C[2:0] only used for 3DS. + */ + pdimm->rcw[8] = pdimm->die_density >= 0x6 ? 0x0 : 0x8 | + (pdimm->package_3ds > 0x3 ? 0x0 : + (pdimm->package_3ds > 0x1 ? 0x1 : + (pdimm->package_3ds > 0 ? 0x2 : 0x3))); + if (pdimm->package_3ds || pdimm->n_ranks != 4) + pdimm->rcw[13] = 0xc; + else + pdimm->rcw[13] = 0xd; /* Fix encoded by board */ + break; case DDR4_SPD_MODULETYPE_UDIMM: -- cgit v1.2.3 From 140ad2d8991ca31d0e84af5119c74fc6e2c5a2d4 Mon Sep 17 00:00:00 2001 From: York Sun Date: Mon, 29 Jan 2018 09:44:38 -0800 Subject: drivers/ddr/fsl: Cleanup unused variable Variable "row_density" is no longer used. Drop it from DIMM structure. Signed-off-by: York Sun --- drivers/ddr/fsl/ddr4_dimm_params.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/ddr/fsl/ddr4_dimm_params.c') diff --git a/drivers/ddr/fsl/ddr4_dimm_params.c b/drivers/ddr/fsl/ddr4_dimm_params.c index 5c8fc8804d4..4867fbc932b 100644 --- a/drivers/ddr/fsl/ddr4_dimm_params.c +++ b/drivers/ddr/fsl/ddr4_dimm_params.c @@ -264,7 +264,6 @@ unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num, * BL8 -bit3, BC4 -bit2 */ pdimm->burst_lengths_bitmask = 0x0c; - pdimm->row_density = __ilog2(pdimm->rank_density); /* MTB - medium timebase * The MTB in the SPD spec is 125ps, -- cgit v1.2.3