From f9747a5a5d34d39843f8007b4230a86bcb852461 Mon Sep 17 00:00:00 2001 From: Yogesh Gaur Date: Tue, 16 Jan 2018 10:08:24 +0530 Subject: driver: fsl-mc: Perform fsl-mc fdt fixup for lazyapply dpl For for case of lazyapply method, API fdt_fixup_board_enet() gets invoked before DPL being deployed. This leads to an issue that fsl-mc fdt fixup status marked as fail and dprc driver didn't get registered in linux boot. Fixes this issue by calling fdt_fixup_board_enet() for case when DPL is deployed successfully in lazyapply method. Signed-off-by: Yogesh Gaur Reviewed-by: York Sun --- drivers/net/fsl-mc/mc.c | 4 +++- include/fdt_support.h | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/fsl-mc/mc.c b/drivers/net/fsl-mc/mc.c index f36fe06269..760a12488a 100644 --- a/drivers/net/fsl-mc/mc.c +++ b/drivers/net/fsl-mc/mc.c @@ -1415,7 +1415,9 @@ int fsl_mc_ldpaa_exit(bd_t *bd) bool mc_boot_status = false; if (bd && mc_lazy_dpl_addr && !fsl_mc_ldpaa_exit(NULL)) { - mc_apply_dpl(mc_lazy_dpl_addr); + err = mc_apply_dpl(mc_lazy_dpl_addr); + if (!err) + fdt_fixup_board_enet(working_fdt); mc_lazy_dpl_addr = 0; } diff --git a/include/fdt_support.h b/include/fdt_support.h index f00fadcddb..46bf83f671 100644 --- a/include/fdt_support.h +++ b/include/fdt_support.h @@ -293,4 +293,7 @@ int fdtdec_get_int(const void *blob, int node, const char *prop_name, #ifdef CONFIG_FMAN_ENET int fdt_update_ethernet_dt(void *blob); #endif +#ifdef CONFIG_FSL_MC_ENET +void fdt_fixup_board_enet(void *blob); +#endif #endif /* ifndef __FDT_SUPPORT_H */ -- cgit From a9b1c2164a45e0c1af59b8e7a1c92f2f53babe92 Mon Sep 17 00:00:00 2001 From: Ashish Kumar Date: Mon, 29 Jan 2018 12:11:20 +0530 Subject: armv8: ls1088a: Add CONFIG_SPI_FLASH_SPANSION to sdcard defconfigs Signed-off-by: Ashish Kumar Reviewed-by: York Sun --- configs/ls1088aqds_sdcard_qspi_defconfig | 1 + configs/ls1088ardb_sdcard_qspi_SECURE_BOOT_defconfig | 1 + configs/ls1088ardb_sdcard_qspi_defconfig | 1 + 3 files changed, 3 insertions(+) diff --git a/configs/ls1088aqds_sdcard_qspi_defconfig b/configs/ls1088aqds_sdcard_qspi_defconfig index 659bc4fbf9..b6de10c5b6 100644 --- a/configs/ls1088aqds_sdcard_qspi_defconfig +++ b/configs/ls1088aqds_sdcard_qspi_defconfig @@ -34,6 +34,7 @@ CONFIG_DM=y CONFIG_SCSI_AHCI=y CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_SPANSION=y CONFIG_NETDEVICES=y CONFIG_E1000=y CONFIG_PCI=y diff --git a/configs/ls1088ardb_sdcard_qspi_SECURE_BOOT_defconfig b/configs/ls1088ardb_sdcard_qspi_SECURE_BOOT_defconfig index a7466f11c6..a4afbb5180 100644 --- a/configs/ls1088ardb_sdcard_qspi_SECURE_BOOT_defconfig +++ b/configs/ls1088ardb_sdcard_qspi_SECURE_BOOT_defconfig @@ -35,6 +35,7 @@ CONFIG_SPL_DM=y CONFIG_SCSI_AHCI=y CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_SPANSION=y CONFIG_NETDEVICES=y CONFIG_E1000=y CONFIG_SYS_NS16550=y diff --git a/configs/ls1088ardb_sdcard_qspi_defconfig b/configs/ls1088ardb_sdcard_qspi_defconfig index 2e3c287c5f..2f8c097337 100644 --- a/configs/ls1088ardb_sdcard_qspi_defconfig +++ b/configs/ls1088ardb_sdcard_qspi_defconfig @@ -33,6 +33,7 @@ CONFIG_DM=y CONFIG_SCSI_AHCI=y CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_SPANSION=y CONFIG_NETDEVICES=y CONFIG_E1000=y CONFIG_PCI=y -- cgit 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/ctrl_regs.c | 51 +++++++++++++++++++++++--------------- drivers/ddr/fsl/ddr4_dimm_params.c | 2 ++ drivers/ddr/fsl/interactive.c | 9 +++++-- include/fsl_ddr_sdram.h | 1 + 4 files changed, 41 insertions(+), 22 deletions(-) diff --git a/drivers/ddr/fsl/ctrl_regs.c b/drivers/ddr/fsl/ctrl_regs.c index c0ee858a02..33adfb1f06 100644 --- a/drivers/ddr/fsl/ctrl_regs.c +++ b/drivers/ddr/fsl/ctrl_regs.c @@ -732,6 +732,7 @@ static void set_ddr_sdram_rcw(fsl_ddr_cfg_regs_t *ddr, if (popts->rcw_override) { ddr->ddr_sdram_rcw_1 = popts->rcw_1; ddr->ddr_sdram_rcw_2 = popts->rcw_2; + ddr->ddr_sdram_rcw_3 = popts->rcw_3; } else { ddr->ddr_sdram_rcw_1 = common_dimm->rcw[0] << 28 | \ @@ -752,8 +753,12 @@ static void set_ddr_sdram_rcw(fsl_ddr_cfg_regs_t *ddr, common_dimm->rcw[14] << 4 | \ common_dimm->rcw[15]; } - debug("FSLDDR: ddr_sdram_rcw_1 = 0x%08x\n", ddr->ddr_sdram_rcw_1); - debug("FSLDDR: ddr_sdram_rcw_2 = 0x%08x\n", ddr->ddr_sdram_rcw_2); + debug("FSLDDR: ddr_sdram_rcw_1 = 0x%08x\n", + ddr->ddr_sdram_rcw_1); + debug("FSLDDR: ddr_sdram_rcw_2 = 0x%08x\n", + ddr->ddr_sdram_rcw_2); + debug("FSLDDR: ddr_sdram_rcw_3 = 0x%08x\n", + ddr->ddr_sdram_rcw_3); } } @@ -1159,8 +1164,14 @@ static void set_ddr_sdram_mode_9(fsl_ddr_cfg_regs_t *ddr, esdmode5 = 0x00000400; /* Data mask enabled */ } - /* set command/address parity latency */ - if (ddr->ddr_sdram_cfg_2 & SDRAM_CFG2_AP_EN) { + /* + * For DDR3, set C/A latency if address parity is enabled. + * For DDR4, set C/A latency for UDIMM only. For RDIMM the delay is + * handled by register chip and RCW settings. + */ + if ((ddr->ddr_sdram_cfg_2 & SDRAM_CFG2_AP_EN) && + ((CONFIG_FSL_SDRAM_TYPE != SDRAM_TYPE_DDR4) || + !popts->registered_dimm_en)) { if (mclk_ps >= 935) { /* for DDR4-1600/1866/2133 */ esdmode5 |= DDR_MR5_CA_PARITY_LAT_4_CLK; @@ -1193,7 +1204,9 @@ static void set_ddr_sdram_mode_9(fsl_ddr_cfg_regs_t *ddr, esdmode5 = 0x00000400; } - if (ddr->ddr_sdram_cfg_2 & SDRAM_CFG2_AP_EN) { + if ((ddr->ddr_sdram_cfg_2 & SDRAM_CFG2_AP_EN) && + ((CONFIG_FSL_SDRAM_TYPE != SDRAM_TYPE_DDR4) || + !popts->registered_dimm_en)) { if (mclk_ps >= 935) { /* for DDR4-1600/1866/2133 */ esdmode5 |= DDR_MR5_CA_PARITY_LAT_4_CLK; @@ -1965,6 +1978,7 @@ static void set_timing_cfg_6(fsl_ddr_cfg_regs_t *ddr) static void set_timing_cfg_7(const unsigned int ctrl_num, fsl_ddr_cfg_regs_t *ddr, + const memctl_options_t *popts, const common_timing_params_t *common_dimm) { unsigned int txpr, tcksre, tcksrx; @@ -1975,16 +1989,11 @@ static void set_timing_cfg_7(const unsigned int ctrl_num, tcksre = max(5U, picos_to_mclk(ctrl_num, 10000)); tcksrx = max(5U, picos_to_mclk(ctrl_num, 10000)); - if (ddr->ddr_sdram_cfg_2 & SDRAM_CFG2_AP_EN) { - if (mclk_ps >= 935) { - /* parity latency 4 clocks in case of 1600/1866/2133 */ - par_lat = 4; - } else if (mclk_ps >= 833) { - /* parity latency 5 clocks for DDR4-2400 */ - par_lat = 5; - } else { - printf("parity: mclk_ps = %d not supported\n", mclk_ps); - } + if (ddr->ddr_sdram_cfg_2 & SDRAM_CFG2_AP_EN && + CONFIG_FSL_SDRAM_TYPE == SDRAM_TYPE_DDR4) { + /* for DDR4 only */ + par_lat = (popts->rcw_2 & 0xf) + 1; + debug("PAR_LAT = %u for mclk_ps = %d\n", par_lat, mclk_ps); } cs_to_cmd = 0; @@ -2024,11 +2033,11 @@ static void set_timing_cfg_8(const unsigned int ctrl_num, const common_timing_params_t *common_dimm, unsigned int cas_latency) { - unsigned int rwt_bg, wrt_bg, rrt_bg, wwt_bg; + int rwt_bg, wrt_bg, rrt_bg, wwt_bg; unsigned int acttoact_bg, wrtord_bg, pre_all_rec; - unsigned int tccdl = picos_to_mclk(ctrl_num, common_dimm->tccdl_ps); - unsigned int wr_lat = ((ddr->timing_cfg_2 & 0x00780000) >> 19) + - ((ddr->timing_cfg_2 & 0x00040000) >> 14); + int tccdl = picos_to_mclk(ctrl_num, common_dimm->tccdl_ps); + int wr_lat = ((ddr->timing_cfg_2 & 0x00780000) >> 19) + + ((ddr->timing_cfg_2 & 0x00040000) >> 14); rwt_bg = cas_latency + 2 + 4 - wr_lat; if (rwt_bg < tccdl) @@ -2130,6 +2139,8 @@ static void set_ddr_sdram_cfg_3(fsl_ddr_cfg_regs_t *ddr, rd_pre = popts->quad_rank_present ? 1 : 0; ddr->ddr_sdram_cfg_3 = (rd_pre & 0x1) << 16; + /* Disable MRS on parity error for RDIMMs */ + ddr->ddr_sdram_cfg_3 |= popts->registered_dimm_en ? 1 : 0; debug("FSLDDR: ddr_sdram_cfg_3 = 0x%08x\n", ddr->ddr_sdram_cfg_3); } @@ -2535,7 +2546,7 @@ compute_fsl_memctl_config_regs(const unsigned int ctrl_num, #ifdef CONFIG_SYS_FSL_DDR4 set_ddr_sdram_cfg_3(ddr, popts); set_timing_cfg_6(ddr); - set_timing_cfg_7(ctrl_num, ddr, common_dimm); + set_timing_cfg_7(ctrl_num, ddr, popts, common_dimm); set_timing_cfg_8(ctrl_num, ddr, popts, common_dimm, cas_latency); set_timing_cfg_9(ddr); set_ddr_dq_mapping(ddr, dimm_params); diff --git a/drivers/ddr/fsl/ddr4_dimm_params.c b/drivers/ddr/fsl/ddr4_dimm_params.c index 42834ca7b2..6e26ba88a5 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: diff --git a/drivers/ddr/fsl/interactive.c b/drivers/ddr/fsl/interactive.c index c99bd2fb6d..660060d7eb 100644 --- a/drivers/ddr/fsl/interactive.c +++ b/drivers/ddr/fsl/interactive.c @@ -558,6 +558,7 @@ static void fsl_ddr_options_edit(fsl_ddr_info_t *pinfo, */ CTRL_OPTIONS(twot_en), CTRL_OPTIONS(threet_en), + CTRL_OPTIONS(mirrored_dimm), CTRL_OPTIONS(ap_en), CTRL_OPTIONS(x4_en), CTRL_OPTIONS(bstopre), @@ -568,6 +569,7 @@ static void fsl_ddr_options_edit(fsl_ddr_info_t *pinfo, CTRL_OPTIONS(rcw_override), CTRL_OPTIONS(rcw_1), CTRL_OPTIONS(rcw_2), + CTRL_OPTIONS(rcw_3), CTRL_OPTIONS(ddr_cdr1), CTRL_OPTIONS(ddr_cdr2), CTRL_OPTIONS(tfaw_window_four_activates_ps), @@ -660,6 +662,7 @@ static void print_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr) CFG_REGS(ddr_sr_cntr), CFG_REGS(ddr_sdram_rcw_1), CFG_REGS(ddr_sdram_rcw_2), + CFG_REGS(ddr_sdram_rcw_3), CFG_REGS(ddr_cdr1), CFG_REGS(ddr_cdr2), CFG_REGS(dq_map_0), @@ -750,6 +753,7 @@ static void fsl_ddr_regs_edit(fsl_ddr_info_t *pinfo, CFG_REGS(ddr_sr_cntr), CFG_REGS(ddr_sdram_rcw_1), CFG_REGS(ddr_sdram_rcw_2), + CFG_REGS(ddr_sdram_rcw_3), CFG_REGS(ddr_cdr1), CFG_REGS(ddr_cdr2), CFG_REGS(dq_map_0), @@ -857,8 +861,9 @@ static void print_memctl_options(const memctl_options_t *popts) CTRL_OPTIONS(wrlvl_start), CTRL_OPTIONS_HEX(cswl_override), CTRL_OPTIONS(rcw_override), - CTRL_OPTIONS(rcw_1), - CTRL_OPTIONS(rcw_2), + CTRL_OPTIONS_HEX(rcw_1), + CTRL_OPTIONS_HEX(rcw_2), + CTRL_OPTIONS_HEX(rcw_3), CTRL_OPTIONS_HEX(ddr_cdr1), CTRL_OPTIONS_HEX(ddr_cdr2), CTRL_OPTIONS(tfaw_window_four_activates_ps), diff --git a/include/fsl_ddr_sdram.h b/include/fsl_ddr_sdram.h index 6a1f04b81a..de7ef9b53f 100644 --- a/include/fsl_ddr_sdram.h +++ b/include/fsl_ddr_sdram.h @@ -408,6 +408,7 @@ typedef struct memctl_options_s { unsigned int rcw_override; unsigned int rcw_1; unsigned int rcw_2; + unsigned int rcw_3; /* control register 1 */ unsigned int ddr_cdr1; unsigned int ddr_cdr2; -- cgit From d46ec0bbaf1a38711b493266f49bb26ac9157d8a Mon Sep 17 00:00:00 2001 From: York Sun Date: Mon, 29 Jan 2018 09:44:34 -0800 Subject: drivers/ddr/fsl: Fix workaround for A009803 Wrong field was masked in this workaround due to wrong endianness. The impacted SoCs have big-endian. Signed-off-by: York Sun --- drivers/ddr/fsl/fsl_ddr_gen4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ddr/fsl/fsl_ddr_gen4.c b/drivers/ddr/fsl/fsl_ddr_gen4.c index b3a27ec5a8..7df9178415 100644 --- a/drivers/ddr/fsl/fsl_ddr_gen4.c +++ b/drivers/ddr/fsl/fsl_ddr_gen4.c @@ -210,7 +210,7 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, if (regs->ddr_sdram_cfg_2 & SDRAM_CFG2_AP_EN) { if (regs->ddr_sdram_cfg & SDRAM_CFG_RD_EN) { /* for RDIMM */ ddr_out32(&ddr->ddr_sdram_rcw_2, - regs->ddr_sdram_rcw_2 & ~0x0f000000); + regs->ddr_sdram_rcw_2 & ~0xf0); } ddr_out32(&ddr->err_disable, regs->err_disable | DDR_ERR_DISABLE_APED); -- cgit 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/ctrl_regs.c | 43 ++++++++++++++++++++++++++------- drivers/ddr/fsl/ddr4_dimm_params.c | 25 +++++++++++++++++-- drivers/ddr/fsl/interactive.c | 13 +++++++++- drivers/ddr/fsl/lc_common_dimm_params.c | 8 +++++- drivers/ddr/fsl/options.c | 5 +++- include/common_timing_params.h | 1 + include/fsl_ddr_dimm_params.h | 6 ++++- include/fsl_ddr_sdram.h | 4 ++- 8 files changed, 89 insertions(+), 16 deletions(-) diff --git a/drivers/ddr/fsl/ctrl_regs.c b/drivers/ddr/fsl/ctrl_regs.c index 33adfb1f06..bcab9046ad 100644 --- a/drivers/ddr/fsl/ctrl_regs.c +++ b/drivers/ddr/fsl/ctrl_regs.c @@ -1,5 +1,6 @@ /* - * Copyright 2008-2014 Freescale Semiconductor, Inc. + * Copyright 2008-2016 Freescale Semiconductor, Inc. + * Copyright 2017-2018 NXP Semiconductor * * SPDX-License-Identifier: GPL-2.0+ */ @@ -492,7 +493,7 @@ static void set_timing_cfg_3(const unsigned int ctrl_num, | ((ext_pretoact & 0x1) << 28) | ((ext_acttopre & 0x3) << 24) | ((ext_acttorw & 0x1) << 22) - | ((ext_refrec & 0x1F) << 16) + | ((ext_refrec & 0x3F) << 16) | ((ext_caslat & 0x3) << 12) | ((ext_add_lat & 0x1) << 10) | ((ext_wrrec & 0x1) << 8) @@ -885,7 +886,7 @@ static void set_ddr_sdram_cfg_2(const unsigned int ctrl_num, } } sr_ie = popts->self_refresh_interrupt_en; - num_pr = 1; /* Make this configurable */ + num_pr = popts->package_3ds + 1; /* * 8572 manual says @@ -1193,7 +1194,7 @@ static void set_ddr_sdram_mode_9(fsl_ddr_cfg_regs_t *ddr, * need 0x500 to park. */ - debug("FSLDDR: ddr_sdram_mode_9) = 0x%08x\n", ddr->ddr_sdram_mode_9); + 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++) { if (!rtt_park && @@ -1270,7 +1271,7 @@ static void set_ddr_sdram_mode_10(const unsigned int ctrl_num, | ((esdmode6 & 0xffff) << 16) | ((esdmode7 & 0xffff) << 0) ); - debug("FSLDDR: ddr_sdram_mode_10) = 0x%08x\n", ddr->ddr_sdram_mode_10); + debug("FSLDDR: ddr_sdram_mode_10 = 0x%08x\n", ddr->ddr_sdram_mode_10); if (unq_mrs_en) { /* unique mode registers are supported */ for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { switch (i) { @@ -1992,7 +1993,7 @@ static void set_timing_cfg_7(const unsigned int ctrl_num, if (ddr->ddr_sdram_cfg_2 & SDRAM_CFG2_AP_EN && CONFIG_FSL_SDRAM_TYPE == SDRAM_TYPE_DDR4) { /* for DDR4 only */ - par_lat = (popts->rcw_2 & 0xf) + 1; + par_lat = (ddr->ddr_sdram_rcw_2 & 0xf) + 1; debug("PAR_LAT = %u for mclk_ps = %d\n", par_lat, mclk_ps); } @@ -2079,9 +2080,23 @@ static void set_timing_cfg_8(const unsigned int ctrl_num, debug("FSLDDR: timing_cfg_8 = 0x%08x\n", ddr->timing_cfg_8); } -static void set_timing_cfg_9(fsl_ddr_cfg_regs_t *ddr) +static void set_timing_cfg_9(const unsigned int ctrl_num, + fsl_ddr_cfg_regs_t *ddr, + const memctl_options_t *popts, + const common_timing_params_t *common_dimm) { - ddr->timing_cfg_9 = 0; + unsigned int refrec_cid_mclk = 0; + unsigned int acttoact_cid_mclk = 0; + + if (popts->package_3ds) { + refrec_cid_mclk = + picos_to_mclk(ctrl_num, common_dimm->trfc_slr_ps); + acttoact_cid_mclk = 4U; /* tRRDS_slr */ + } + + ddr->timing_cfg_9 = (refrec_cid_mclk & 0x3ff) << 16 | + (acttoact_cid_mclk & 0xf) << 8; + debug("FSLDDR: timing_cfg_9 = 0x%08x\n", ddr->timing_cfg_9); } @@ -2142,6 +2157,16 @@ static void set_ddr_sdram_cfg_3(fsl_ddr_cfg_regs_t *ddr, /* Disable MRS on parity error for RDIMMs */ ddr->ddr_sdram_cfg_3 |= popts->registered_dimm_en ? 1 : 0; + if (popts->package_3ds) { /* only 2,4,8 are supported */ + if ((popts->package_3ds + 1) & 0x1) { + printf("Error: Unsupported 3DS DIMM with %d die\n", + popts->package_3ds + 1); + } else { + ddr->ddr_sdram_cfg_3 |= ((popts->package_3ds + 1) >> 1) + << 4; + } + } + debug("FSLDDR: ddr_sdram_cfg_3 = 0x%08x\n", ddr->ddr_sdram_cfg_3); } #endif /* CONFIG_SYS_FSL_DDR4 */ @@ -2548,7 +2573,7 @@ compute_fsl_memctl_config_regs(const unsigned int ctrl_num, set_timing_cfg_6(ddr); set_timing_cfg_7(ctrl_num, ddr, popts, common_dimm); set_timing_cfg_8(ctrl_num, ddr, popts, common_dimm, cas_latency); - set_timing_cfg_9(ddr); + set_timing_cfg_9(ctrl_num, ddr, popts, common_dimm); set_ddr_dq_mapping(ddr, dimm_params); #endif diff --git a/drivers/ddr/fsl/ddr4_dimm_params.c b/drivers/ddr/fsl/ddr4_dimm_params.c index 6e26ba88a5..1f1d9b897a 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 diff --git a/drivers/ddr/fsl/interactive.c b/drivers/ddr/fsl/interactive.c index 660060d7eb..78ca03bcb2 100644 --- a/drivers/ddr/fsl/interactive.c +++ b/drivers/ddr/fsl/interactive.c @@ -1,5 +1,6 @@ /* - * Copyright 2010-2014 Freescale Semiconductor, Inc. + * Copyright 2010-2016 Freescale Semiconductor, Inc. + * Copyright 2017-2018 NXP Semiconductor * * SPDX-License-Identifier: GPL-2.0+ */ @@ -168,6 +169,7 @@ static void lowest_common_dimm_parameters_edit(fsl_ddr_info_t *pinfo, COMMON_TIMING(trrds_ps), COMMON_TIMING(trrdl_ps), COMMON_TIMING(tccdl_ps), + COMMON_TIMING(trfc_slr_ps), #else COMMON_TIMING(twtr_ps), COMMON_TIMING(trfc_ps), @@ -223,6 +225,7 @@ static void fsl_ddr_dimm_parameters_edit(fsl_ddr_info_t *pinfo, DIMM_PARM(data_width), DIMM_PARM(primary_sdram_width), DIMM_PARM(ec_sdram_width), + DIMM_PARM(package_3ds), DIMM_PARM(registered_dimm), DIMM_PARM(mirrored_dimm), DIMM_PARM(device_width), @@ -233,6 +236,7 @@ static void fsl_ddr_dimm_parameters_edit(fsl_ddr_info_t *pinfo, #ifdef CONFIG_SYS_FSL_DDR4 DIMM_PARM(bank_addr_bits), DIMM_PARM(bank_group_bits), + DIMM_PARM_HEX(die_density), #else DIMM_PARM(n_banks_per_sdram_device), #endif @@ -260,6 +264,7 @@ static void fsl_ddr_dimm_parameters_edit(fsl_ddr_info_t *pinfo, DIMM_PARM(trrds_ps), DIMM_PARM(trrdl_ps), DIMM_PARM(tccdl_ps), + DIMM_PARM(trfc_slr_ps), #else DIMM_PARM(twr_ps), DIMM_PARM(twtr_ps), @@ -320,6 +325,7 @@ static void print_dimm_parameters(const dimm_params_t *pdimm) DIMM_PARM(data_width), DIMM_PARM(primary_sdram_width), DIMM_PARM(ec_sdram_width), + DIMM_PARM(package_3ds), DIMM_PARM(registered_dimm), DIMM_PARM(mirrored_dimm), DIMM_PARM(device_width), @@ -330,6 +336,7 @@ static void print_dimm_parameters(const dimm_params_t *pdimm) #ifdef CONFIG_SYS_FSL_DDR4 DIMM_PARM(bank_addr_bits), DIMM_PARM(bank_group_bits), + DIMM_PARM_HEX(die_density), #else DIMM_PARM(n_banks_per_sdram_device), #endif @@ -359,6 +366,7 @@ static void print_dimm_parameters(const dimm_params_t *pdimm) DIMM_PARM(trrds_ps), DIMM_PARM(trrdl_ps), DIMM_PARM(tccdl_ps), + DIMM_PARM(trfc_slr_ps), #else DIMM_PARM(twr_ps), DIMM_PARM(twtr_ps), @@ -437,6 +445,7 @@ static void print_lowest_common_dimm_parameters( COMMON_TIMING(trrds_ps), COMMON_TIMING(trrdl_ps), COMMON_TIMING(tccdl_ps), + COMMON_TIMING(trfc_slr_ps), #else COMMON_TIMING(twtr_ps), COMMON_TIMING(trfc_ps), @@ -561,6 +570,7 @@ static void fsl_ddr_options_edit(fsl_ddr_info_t *pinfo, CTRL_OPTIONS(mirrored_dimm), CTRL_OPTIONS(ap_en), CTRL_OPTIONS(x4_en), + CTRL_OPTIONS(package_3ds), CTRL_OPTIONS(bstopre), CTRL_OPTIONS(wrlvl_override), CTRL_OPTIONS(wrlvl_sample), @@ -855,6 +865,7 @@ static void print_memctl_options(const memctl_options_t *popts) CTRL_OPTIONS(mirrored_dimm), CTRL_OPTIONS(ap_en), CTRL_OPTIONS(x4_en), + CTRL_OPTIONS(package_3ds), CTRL_OPTIONS(bstopre), CTRL_OPTIONS(wrlvl_override), CTRL_OPTIONS(wrlvl_sample), diff --git a/drivers/ddr/fsl/lc_common_dimm_params.c b/drivers/ddr/fsl/lc_common_dimm_params.c index 850c8f6c43..6599901893 100644 --- a/drivers/ddr/fsl/lc_common_dimm_params.c +++ b/drivers/ddr/fsl/lc_common_dimm_params.c @@ -1,5 +1,6 @@ /* - * Copyright 2008-2014 Freescale Semiconductor, Inc. + * Copyright 2008-2016 Freescale Semiconductor, Inc. + * Copyright 2017-2018 NXP Semiconductor * * SPDX-License-Identifier: GPL-2.0 */ @@ -234,6 +235,7 @@ compute_lowest_common_dimm_parameters(const unsigned int ctrl_num, unsigned int trrds_ps = 0; unsigned int trrdl_ps = 0; unsigned int tccdl_ps = 0; + unsigned int trfc_slr_ps = 0; #else unsigned int twr_ps = 0; unsigned int twtr_ps = 0; @@ -313,6 +315,8 @@ compute_lowest_common_dimm_parameters(const unsigned int ctrl_num, (unsigned int)dimm_params[i].trrdl_ps); tccdl_ps = max(tccdl_ps, (unsigned int)dimm_params[i].tccdl_ps); + trfc_slr_ps = max(trfc_slr_ps, + (unsigned int)dimm_params[i].trfc_slr_ps); #else twr_ps = max(twr_ps, (unsigned int)dimm_params[i].twr_ps); twtr_ps = max(twtr_ps, (unsigned int)dimm_params[i].twtr_ps); @@ -365,6 +369,7 @@ compute_lowest_common_dimm_parameters(const unsigned int ctrl_num, outpdimm->trrds_ps = trrds_ps; outpdimm->trrdl_ps = trrdl_ps; outpdimm->tccdl_ps = tccdl_ps; + outpdimm->trfc_slr_ps = trfc_slr_ps; #else outpdimm->twtr_ps = twtr_ps; outpdimm->trfc_ps = trfc_ps; @@ -567,6 +572,7 @@ compute_lowest_common_dimm_parameters(const unsigned int ctrl_num, debug("trrds_ps = %u\n", trrds_ps); debug("trrdl_ps = %u\n", trrdl_ps); debug("tccdl_ps = %u\n", tccdl_ps); + debug("trfc_slr_ps = %u\n", trfc_slr_ps); #else debug("twtr_ps = %u\n", outpdimm->twtr_ps); debug("trfc_ps = %u\n", outpdimm->trfc_ps); diff --git a/drivers/ddr/fsl/options.c b/drivers/ddr/fsl/options.c index a7eaed1bd7..5158ea2089 100644 --- a/drivers/ddr/fsl/options.c +++ b/drivers/ddr/fsl/options.c @@ -1,5 +1,6 @@ /* - * Copyright 2008, 2010-2014 Freescale Semiconductor, Inc. + * Copyright 2008, 2010-2016 Freescale Semiconductor, Inc. + * Copyright 2017-2018 NXP Semiconductor * * SPDX-License-Identifier: GPL-2.0+ */ @@ -1292,6 +1293,8 @@ done: if (pdimm[0].n_ranks == 4) popts->quad_rank_present = 1; + popts->package_3ds = pdimm->package_3ds; + ddr_freq = get_ddr_freq(ctrl_num) / 1000000; if (popts->registered_dimm_en) { popts->rcw_override = 1; diff --git a/include/common_timing_params.h b/include/common_timing_params.h index b97147db41..070010728b 100644 --- a/include/common_timing_params.h +++ b/include/common_timing_params.h @@ -26,6 +26,7 @@ typedef struct { unsigned int trrds_ps; unsigned int trrdl_ps; unsigned int tccdl_ps; + unsigned int trfc_slr_ps; #else unsigned int twtr_ps; /* maximum = 63750 ps */ unsigned int trfc_ps; /* maximum = 255 ns + 256 ns + .75 ns diff --git a/include/fsl_ddr_dimm_params.h b/include/fsl_ddr_dimm_params.h index 12a1944106..c6c819ea0a 100644 --- a/include/fsl_ddr_dimm_params.h +++ b/include/fsl_ddr_dimm_params.h @@ -1,5 +1,6 @@ /* - * Copyright 2008-2014 Freescale Semiconductor, Inc. + * Copyright 2008-2016 Freescale Semiconductor, Inc. + * Copyright 2017-2018 NXP Semiconductor * * SPDX-License-Identifier: GPL-2.0 */ @@ -18,12 +19,14 @@ typedef struct dimm_params_s { char mpart[19]; /* guaranteed null terminated */ unsigned int n_ranks; + unsigned int die_density; unsigned long long rank_density; unsigned long long capacity; unsigned int data_width; unsigned int primary_sdram_width; unsigned int ec_sdram_width; unsigned int registered_dimm; + unsigned int package_3ds; /* number of dies in 3DS DIMM */ unsigned int device_width; /* x4, x8, x16 components */ /* SDRAM device parameters */ @@ -79,6 +82,7 @@ typedef struct dimm_params_s { int trrds_ps; int trrdl_ps; int tccdl_ps; + int trfc_slr_ps; #else int twr_ps; /* maximum = 63750 ps */ int trfc_ps; /* max = 255 ns + 256 ns + .75 ns diff --git a/include/fsl_ddr_sdram.h b/include/fsl_ddr_sdram.h index de7ef9b53f..d4275e694b 100644 --- a/include/fsl_ddr_sdram.h +++ b/include/fsl_ddr_sdram.h @@ -1,5 +1,6 @@ /* - * Copyright 2008-2014 Freescale Semiconductor, Inc. + * Copyright 2008-2016 Freescale Semiconductor, Inc. + * Copyright 2017-2018 NXP Semiconductor * * SPDX-License-Identifier: GPL-2.0 */ @@ -366,6 +367,7 @@ typedef struct memctl_options_s { unsigned int quad_rank_present; unsigned int ap_en; /* address parity enable for RDIMM/DDR4-UDIMM */ unsigned int x4_en; /* enable x4 devices */ + unsigned int package_3ds; /* Global Timing Parameters */ unsigned int cas_latency_override; -- cgit 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/ctrl_regs.c | 30 +++++++++++++++++++++++------- drivers/ddr/fsl/ddr4_dimm_params.c | 21 +++++++++++++++++++++ drivers/ddr/fsl/options.c | 4 ++++ include/ddr_spd.h | 8 +++++--- include/fsl_ddr_dimm_params.h | 2 +- 5 files changed, 54 insertions(+), 11 deletions(-) diff --git a/drivers/ddr/fsl/ctrl_regs.c b/drivers/ddr/fsl/ctrl_regs.c index bcab9046ad..8b8727116d 100644 --- a/drivers/ddr/fsl/ctrl_regs.c +++ b/drivers/ddr/fsl/ctrl_regs.c @@ -724,10 +724,14 @@ static void set_timing_cfg_2(const unsigned int ctrl_num, } /* DDR SDRAM Register Control Word */ -static void set_ddr_sdram_rcw(fsl_ddr_cfg_regs_t *ddr, - const memctl_options_t *popts, - const common_timing_params_t *common_dimm) +static void set_ddr_sdram_rcw(const unsigned int ctrl_num, + fsl_ddr_cfg_regs_t *ddr, + const memctl_options_t *popts, + const common_timing_params_t *common_dimm) { + unsigned int ddr_freq = get_ddr_freq(ctrl_num) / 1000000; + unsigned int rc0a, rc0f; + if (common_dimm->all_dimms_registered && !common_dimm->all_dimms_unbuffered) { if (popts->rcw_override) { @@ -735,6 +739,16 @@ static void set_ddr_sdram_rcw(fsl_ddr_cfg_regs_t *ddr, ddr->ddr_sdram_rcw_2 = popts->rcw_2; ddr->ddr_sdram_rcw_3 = popts->rcw_3; } else { + rc0a = ddr_freq > 3200 ? 0x7 : + (ddr_freq > 2933 ? 0x6 : + (ddr_freq > 2666 ? 0x5 : + (ddr_freq > 2400 ? 0x4 : + (ddr_freq > 2133 ? 0x3 : + (ddr_freq > 1866 ? 0x2 : + (ddr_freq > 1600 ? 1 : 0)))))); + rc0f = ddr_freq > 3200 ? 0x3 : + (ddr_freq > 2400 ? 0x2 : + (ddr_freq > 2133 ? 0x1 : 0)); ddr->ddr_sdram_rcw_1 = common_dimm->rcw[0] << 28 | \ common_dimm->rcw[1] << 24 | \ @@ -747,12 +761,14 @@ static void set_ddr_sdram_rcw(fsl_ddr_cfg_regs_t *ddr, ddr->ddr_sdram_rcw_2 = common_dimm->rcw[8] << 28 | \ common_dimm->rcw[9] << 24 | \ - common_dimm->rcw[10] << 20 | \ + rc0a << 20 | \ common_dimm->rcw[11] << 16 | \ common_dimm->rcw[12] << 12 | \ common_dimm->rcw[13] << 8 | \ common_dimm->rcw[14] << 4 | \ - common_dimm->rcw[15]; + rc0f; + ddr->ddr_sdram_rcw_3 = + ((ddr_freq - 1260 + 19) / 20) << 8; } debug("FSLDDR: ddr_sdram_rcw_1 = 0x%08x\n", ddr->ddr_sdram_rcw_1); @@ -2561,6 +2577,8 @@ compute_fsl_memctl_config_regs(const unsigned int ctrl_num, set_ddr_sdram_mode_9(ddr, popts, common_dimm, unq_mrs_en); set_ddr_sdram_mode_10(ctrl_num, ddr, popts, common_dimm, unq_mrs_en); #endif + set_ddr_sdram_rcw(ctrl_num, ddr, popts, common_dimm); + set_ddr_sdram_interval(ctrl_num, ddr, popts, common_dimm); set_ddr_data_init(ddr); set_ddr_sdram_clk_cntl(ddr, popts); @@ -2582,8 +2600,6 @@ compute_fsl_memctl_config_regs(const unsigned int ctrl_num, set_ddr_sr_cntr(ddr, sr_it); - set_ddr_sdram_rcw(ddr, popts, common_dimm); - #ifdef CONFIG_SYS_FSL_DDR_EMU /* disble DDR training for emulator */ ddr->debug[2] = 0x00000400; diff --git a/drivers/ddr/fsl/ddr4_dimm_params.c b/drivers/ddr/fsl/ddr4_dimm_params.c index 1f1d9b897a..5c8fc8804d 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: diff --git a/drivers/ddr/fsl/options.c b/drivers/ddr/fsl/options.c index 5158ea2089..85ec48c28e 100644 --- a/drivers/ddr/fsl/options.c +++ b/drivers/ddr/fsl/options.c @@ -750,7 +750,9 @@ unsigned int populate_memctl_options(const common_timing_params_t *common_dimm, defined(CONFIG_SYS_FSL_DDR4) const struct dynamic_odt *pdodt = odt_unknown; #endif +#if (CONFIG_FSL_SDRAM_TYPE != SDRAM_TYPE_DDR4) ulong ddr_freq; +#endif /* * Extract hwconfig from environment since we have not properly setup @@ -1295,6 +1297,7 @@ done: popts->package_3ds = pdimm->package_3ds; +#if (CONFIG_FSL_SDRAM_TYPE != SDRAM_TYPE_DDR4) ddr_freq = get_ddr_freq(ctrl_num) / 1000000; if (popts->registered_dimm_en) { popts->rcw_override = 1; @@ -1308,6 +1311,7 @@ done: else popts->rcw_2 = 0x00300000; } +#endif fsl_ddr_board_options(popts, pdimm, ctrl_num); diff --git a/include/ddr_spd.h b/include/ddr_spd.h index d71cd9ab3c..20dc9ea1a6 100644 --- a/include/ddr_spd.h +++ b/include/ddr_spd.h @@ -382,9 +382,11 @@ struct ddr4_spd_eeprom_s { /* 135 Register Revision Number */ uint8_t reg_rev; /* 136 Address mapping from register to DRAM */ - uint8_t reg_map; - /* 137~253 Reserved */ - uint8_t res_137[254-137]; + u8 reg_map; + u8 ca_stren; + u8 clk_stren; + /* 139~253 Reserved */ + u8 res_137[254 - 139]; /* 254~255 CRC */ uint8_t crc[2]; } registered; diff --git a/include/fsl_ddr_dimm_params.h b/include/fsl_ddr_dimm_params.h index c6c819ea0a..1f78ea2d86 100644 --- a/include/fsl_ddr_dimm_params.h +++ b/include/fsl_ddr_dimm_params.h @@ -106,7 +106,7 @@ typedef struct dimm_params_s { int tqhs_ps; /* byte 45, spd->tqhs */ #endif - /* DDR3 RDIMM */ + /* DDR3 & DDR4 RDIMM */ unsigned char rcw[16]; /* Register Control Word 0-15 */ #ifdef CONFIG_SYS_FSL_DDR4 unsigned int dq_mapping[18]; -- cgit From 944537c56e7bf51efef640408113d707cd0ad9f0 Mon Sep 17 00:00:00 2001 From: York Sun Date: Mon, 29 Jan 2018 09:44:37 -0800 Subject: drivers/ddr/fsl: Modify binding registers to save time on data init DDR controllers always use binding register to determine the memory space to perform data initialization. In case of controller interleaving, the space is doubled, resulting twice long wait. It wasn't too bad until the memory capacity increases. To reduce the wait time, reduce the binding space to half and restore it after data initialization. Three-way interleaving is no longer used and is removed. Signed-off-by: York Sun --- drivers/ddr/fsl/fsl_ddr_gen4.c | 60 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 49 insertions(+), 11 deletions(-) diff --git a/drivers/ddr/fsl/fsl_ddr_gen4.c b/drivers/ddr/fsl/fsl_ddr_gen4.c index 7df9178415..c225c8e723 100644 --- a/drivers/ddr/fsl/fsl_ddr_gen4.c +++ b/drivers/ddr/fsl/fsl_ddr_gen4.c @@ -16,6 +16,8 @@ #include #endif +#define CTLR_INTLV_MASK 0x20000000 + #if defined(CONFIG_SYS_FSL_ERRATUM_A008511) | \ defined(CONFIG_SYS_FSL_ERRATUM_A009803) static void set_wait_for_bits_clear(void *ptr, u32 value, u32 bits) @@ -54,6 +56,7 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, u32 temp32; u32 total_gb_size_per_controller; int timeout; + int mod_bnds = 0; #ifdef CONFIG_SYS_FSL_ERRATUM_A008511 u32 mr6; @@ -91,6 +94,7 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, printf("%s unexpected ctrl_num = %u\n", __func__, ctrl_num); return; } + mod_bnds = regs->cs[0].config & CTLR_INTLV_MASK; if (step == 2) goto step2; @@ -102,25 +106,48 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, ddr_out32(&ddr->eor, regs->ddr_eor); ddr_out32(&ddr->sdram_clk_cntl, regs->ddr_sdram_clk_cntl); - for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { if (i == 0) { - ddr_out32(&ddr->cs0_bnds, regs->cs[i].bnds); - ddr_out32(&ddr->cs0_config, regs->cs[i].config); + if (mod_bnds) { + debug("modified bnds\n"); + ddr_out32(&ddr->cs0_bnds, + (regs->cs[i].bnds & 0xfffefffe) >> 1); + ddr_out32(&ddr->cs0_config, + (regs->cs[i].config & + ~CTLR_INTLV_MASK)); + } else { + ddr_out32(&ddr->cs0_bnds, regs->cs[i].bnds); + ddr_out32(&ddr->cs0_config, regs->cs[i].config); + } ddr_out32(&ddr->cs0_config_2, regs->cs[i].config_2); } else if (i == 1) { - ddr_out32(&ddr->cs1_bnds, regs->cs[i].bnds); + if (mod_bnds) { + ddr_out32(&ddr->cs1_bnds, + (regs->cs[i].bnds & 0xfffefffe) >> 1); + } else { + ddr_out32(&ddr->cs1_bnds, regs->cs[i].bnds); + } ddr_out32(&ddr->cs1_config, regs->cs[i].config); ddr_out32(&ddr->cs1_config_2, regs->cs[i].config_2); } else if (i == 2) { - ddr_out32(&ddr->cs2_bnds, regs->cs[i].bnds); + if (mod_bnds) { + ddr_out32(&ddr->cs2_bnds, + (regs->cs[i].bnds & 0xfffefffe) >> 1); + } else { + ddr_out32(&ddr->cs2_bnds, regs->cs[i].bnds); + } ddr_out32(&ddr->cs2_config, regs->cs[i].config); ddr_out32(&ddr->cs2_config_2, regs->cs[i].config_2); } else if (i == 3) { - ddr_out32(&ddr->cs3_bnds, regs->cs[i].bnds); + if (mod_bnds) { + ddr_out32(&ddr->cs3_bnds, + (regs->cs[i].bnds & 0xfffefffe) >> 1); + } else { + ddr_out32(&ddr->cs3_bnds, regs->cs[i].bnds); + } ddr_out32(&ddr->cs3_config, regs->cs[i].config); ddr_out32(&ddr->cs3_config_2, regs->cs[i].config_2); } @@ -417,13 +444,10 @@ step2: ((regs->cs[i].config >> 8) & 0x7) + 12 + ((regs->cs[i].config >> 4) & 0x3) + 0 + ((regs->cs[i].config >> 0) & 0x7) + 8 + + ((regs->ddr_sdram_cfg_3 >> 4) & 0x3) + 3 - ((regs->ddr_sdram_cfg >> 19) & 0x3) - 26); /* minus 26 (count of 64M) */ } - if (fsl_ddr_get_intl3r() & 0x80000000) /* 3-way interleaving */ - total_gb_size_per_controller *= 3; - else if (regs->cs[0].config & 0x20000000) /* 2-way interleaving */ - total_gb_size_per_controller <<= 1; /* * total memory / bus width = transactions needed * transactions needed / data rate = seconds @@ -449,6 +473,21 @@ step2: if (timeout <= 0) printf("Waiting for D_INIT timeout. Memory may not work.\n"); + if (mod_bnds) { + debug("Reset to original bnds\n"); + ddr_out32(&ddr->cs0_bnds, regs->cs[0].bnds); +#if (CONFIG_CHIP_SELECTS_PER_CTRL > 1) + ddr_out32(&ddr->cs1_bnds, regs->cs[1].bnds); +#if (CONFIG_CHIP_SELECTS_PER_CTRL > 2) + ddr_out32(&ddr->cs2_bnds, regs->cs[2].bnds); +#if (CONFIG_CHIP_SELECTS_PER_CTRL > 3) + ddr_out32(&ddr->cs3_bnds, regs->cs[3].bnds); +#endif +#endif +#endif + ddr_out32(&ddr->cs0_config, regs->cs[0].config); + } + #ifdef CONFIG_SYS_FSL_ERRATUM_A009663 ddr_out32(&ddr->sdram_interval, regs->ddr_sdram_interval); #endif @@ -468,7 +507,6 @@ step2: #define BIST_CR 0x80010000 #define BIST_CR_EN 0x80000000 #define BIST_CR_STAT 0x00000001 -#define CTLR_INTLV_MASK 0x20000000 /* Perform build-in test on memory. Three-way interleaving is not yet * supported by this code. */ if (env_get_f("ddr_bist", buffer, CONFIG_SYS_CBSIZE) >= 0) { -- cgit 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/ddr1_dimm_params.c | 1 - drivers/ddr/fsl/ddr2_dimm_params.c | 1 - drivers/ddr/fsl/ddr3_dimm_params.c | 1 - drivers/ddr/fsl/ddr4_dimm_params.c | 1 - drivers/ddr/fsl/interactive.c | 1 - include/fsl_ddr_dimm_params.h | 1 - 6 files changed, 6 deletions(-) diff --git a/drivers/ddr/fsl/ddr1_dimm_params.c b/drivers/ddr/fsl/ddr1_dimm_params.c index 369b325ff2..c02725e611 100644 --- a/drivers/ddr/fsl/ddr1_dimm_params.c +++ b/drivers/ddr/fsl/ddr1_dimm_params.c @@ -270,7 +270,6 @@ unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num, pdimm->n_banks_per_sdram_device = spd->nbanks; pdimm->edc_config = spd->config; pdimm->burst_lengths_bitmask = spd->burstl; - pdimm->row_density = spd->bank_dens; /* * Calculate the Maximum Data Rate based on the Minimum Cycle time. diff --git a/drivers/ddr/fsl/ddr2_dimm_params.c b/drivers/ddr/fsl/ddr2_dimm_params.c index af752cc96c..062c849075 100644 --- a/drivers/ddr/fsl/ddr2_dimm_params.c +++ b/drivers/ddr/fsl/ddr2_dimm_params.c @@ -269,7 +269,6 @@ unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num, pdimm->n_banks_per_sdram_device = spd->nbanks; pdimm->edc_config = spd->config; pdimm->burst_lengths_bitmask = spd->burstl; - pdimm->row_density = spd->rank_dens; /* * Calculate the Maximum Data Rate based on the Minimum Cycle time. diff --git a/drivers/ddr/fsl/ddr3_dimm_params.c b/drivers/ddr/fsl/ddr3_dimm_params.c index 9944dbbf03..8a0587a646 100644 --- a/drivers/ddr/fsl/ddr3_dimm_params.c +++ b/drivers/ddr/fsl/ddr3_dimm_params.c @@ -186,7 +186,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 unit in the SPD spec is ns, diff --git a/drivers/ddr/fsl/ddr4_dimm_params.c b/drivers/ddr/fsl/ddr4_dimm_params.c index 5c8fc8804d..4867fbc932 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, diff --git a/drivers/ddr/fsl/interactive.c b/drivers/ddr/fsl/interactive.c index 78ca03bcb2..1fa35c3c42 100644 --- a/drivers/ddr/fsl/interactive.c +++ b/drivers/ddr/fsl/interactive.c @@ -241,7 +241,6 @@ static void fsl_ddr_dimm_parameters_edit(fsl_ddr_info_t *pinfo, DIMM_PARM(n_banks_per_sdram_device), #endif DIMM_PARM(burst_lengths_bitmask), - DIMM_PARM(row_density), DIMM_PARM(tckmin_x_ps), DIMM_PARM(tckmin_x_minus_1_ps), diff --git a/include/fsl_ddr_dimm_params.h b/include/fsl_ddr_dimm_params.h index 1f78ea2d86..1632a8fd36 100644 --- a/include/fsl_ddr_dimm_params.h +++ b/include/fsl_ddr_dimm_params.h @@ -40,7 +40,6 @@ typedef struct dimm_params_s { unsigned int n_banks_per_sdram_device; #endif unsigned int burst_lengths_bitmask; /* BL=4 bit 2, BL=8 = bit 3 */ - unsigned int row_density; /* used in computing base address of DIMMs */ unsigned long long base_address; -- cgit From f513de6c828ab4ccc677ab3c4812a3234833894a Mon Sep 17 00:00:00 2001 From: York Sun Date: Mon, 29 Jan 2018 09:44:39 -0800 Subject: armv8: ls1046ardb: Add RDIMM support This adds 2Rx8 RDIMM on LS1046ARDB board. Tested with RDIMM MTA18ASF2G72PDZ and MTA9ASF1G72PZ. Signed-off-by: York Sun --- board/freescale/ls1046ardb/ddr.c | 9 +++++---- board/freescale/ls1046ardb/ddr.h | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/board/freescale/ls1046ardb/ddr.c b/board/freescale/ls1046ardb/ddr.c index fb4f6abe0b..46ed7bd0cf 100644 --- a/board/freescale/ls1046ardb/ddr.c +++ b/board/freescale/ls1046ardb/ddr.c @@ -29,7 +29,10 @@ void fsl_ddr_board_options(memctl_options_t *popts, if (!pdimm->n_ranks) return; - pbsp = udimms[0]; + if (popts->registered_dimm_en) + pbsp = rdimms[0]; + else + pbsp = udimms[0]; /* Get clk_adjust, wrlvl_start, wrlvl_ctl, according to the board ddr * freqency and n_banks specified in board_specific_parameters table. @@ -66,8 +69,6 @@ found: pbsp->n_ranks, pbsp->datarate_mhz_high, pbsp->rank_gb); popts->data_bus_width = 0; /* 64-bit data bus */ - popts->otf_burst_chop_en = 0; - popts->burst_length = DDR_BL8; popts->bstopre = 0; /* enable auto precharge */ /* @@ -94,7 +95,7 @@ found: DDR_CDR2_VREF_TRAIN_EN | DDR_CDR2_VREF_RANGE_2; /* optimize cpo for erratum A-009942 */ - popts->cpo_sample = 0x70; + popts->cpo_sample = 0x61; } int fsl_initdram(void) diff --git a/board/freescale/ls1046ardb/ddr.h b/board/freescale/ls1046ardb/ddr.h index 9e440f67b4..04328f2555 100644 --- a/board/freescale/ls1046ardb/ddr.h +++ b/board/freescale/ls1046ardb/ddr.h @@ -41,4 +41,23 @@ static const struct board_specific_parameters *udimms[] = { udimm0, }; +static const struct board_specific_parameters rdimm0[] = { + /* + * memory controller 0 + * num| hi| rank| clk| wrlvl | wrlvl | wrlvl + * ranks| mhz| GB |adjst| start | ctl2 | ctl3 + */ + {2, 1666, 0, 0x8, 0x0D, 0x0C0B0A08, 0x0A0B0C08,}, + {2, 1900, 0, 0x8, 0x0E, 0x0D0C0B09, 0x0B0C0D09,}, + {2, 2300, 0, 0xa, 0x12, 0x100F0D0C, 0x0E0F100C,}, + {1, 1666, 0, 0x8, 0x0D, 0x0C0B0A08, 0x0A0B0C08,}, + {1, 1900, 0, 0x8, 0x0E, 0x0D0C0B09, 0x0B0C0D09,}, + {1, 2300, 0, 0xa, 0x12, 0x100F0D0C, 0x0E0F100C,}, + {} +}; + +static const struct board_specific_parameters *rdimms[] = { + rdimm0, +}; + #endif -- cgit From 58932ec68cdcd574c85620e285a7b95a49551603 Mon Sep 17 00:00:00 2001 From: York Sun Date: Mon, 29 Jan 2018 09:44:40 -0800 Subject: armv8: ls2088ardb: Add 3DS RDIMM support Tested with MTA72ASS8G72PSZ-2S6G1. This is 3DS RDIMM module with x4 DDR chips. LS2088ARDB needs to be modified to connect all DQS signals. Some of them are grounded by default for x8 chips. Tested with RDIMM MTA18ASF2G72PDZ on main memory controllers. DP-DDR doesn't support RDIMM. Dropped related timing table. Signed-off-by: York Sun --- board/freescale/ls2080ardb/ddr.c | 2 ++ board/freescale/ls2080ardb/ddr.h | 23 ++++------------------- 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/board/freescale/ls2080ardb/ddr.c b/board/freescale/ls2080ardb/ddr.c index 01f7d82fb6..b13a974b6e 100644 --- a/board/freescale/ls2080ardb/ddr.c +++ b/board/freescale/ls2080ardb/ddr.c @@ -85,6 +85,8 @@ found: pbsp->wrlvl_ctl_3); #ifdef CONFIG_SYS_FSL_HAS_DP_DDR if (ctrl_num == CONFIG_DP_DDR_CTRL) { + if (popts->registered_dimm_en) + printf("WARN: RDIMM not supported.\n"); /* force DDR bus width to 32 bits */ popts->data_bus_width = 1; popts->otf_burst_chop_en = 0; diff --git a/board/freescale/ls2080ardb/ddr.h b/board/freescale/ls2080ardb/ddr.h index 8d5a49061c..53c16f54f7 100644 --- a/board/freescale/ls2080ardb/ddr.h +++ b/board/freescale/ls2080ardb/ddr.h @@ -55,24 +55,9 @@ static const struct board_specific_parameters rdimm0[] = { * num| hi| rank| clk| wrlvl | wrlvl | wrlvl * ranks| mhz| GB |adjst| start | ctl2 | ctl3 */ - {2, 1350, 0, 8, 6, 0x0708090B, 0x0C0D0E09,}, - {2, 1666, 0, 8, 7, 0x08090A0C, 0x0D0F100B,}, - {2, 1900, 0, 8, 7, 0x09090B0D, 0x0E10120B,}, - {2, 2200, 0, 8, 8, 0x090A0C0F, 0x1012130C,}, - {} -}; - -/* DP-DDR DIMM */ -static const struct board_specific_parameters rdimm2[] = { - /* - * memory controller 2 - * num| hi| rank| clk| wrlvl | wrlvl | wrlvl - * ranks| mhz| GB |adjst| start | ctl2 | ctl3 - */ - {2, 1350, 0, 8, 6, 0x0708090B, 0x0C0D0E09,}, - {2, 1666, 0, 8, 7, 0x0B0A090C, 0x0D0F100B,}, - {2, 1900, 0, 8, 7, 0x09090B0D, 0x0E10120B,}, - {2, 2200, 0, 8, 8, 0x090A0C0F, 0x1012130C,}, + {2, 1666, 0, 8, 0x0F, 0x0D0C0A09, 0x0B0C0E08,}, + {2, 1900, 0, 8, 0x10, 0x0F0D0B0A, 0x0B0E0F09,}, + {2, 2200, 0, 8, 0x13, 0x120F0E0B, 0x0D10110B,}, {} }; @@ -85,7 +70,7 @@ static const struct board_specific_parameters *udimms[] = { static const struct board_specific_parameters *rdimms[] = { rdimm0, rdimm0, - rdimm2, + udimm2, /* DP-DDR doesn't support RDIMM */ }; -- cgit