summaryrefslogtreecommitdiffstats
path: root/board/freescale/ls2085a/ddr.c
diff options
context:
space:
mode:
authorYork Sun <yorksun@freescale.com>2014-06-23 15:15:56 -0700
committerAlbert ARIBAUD <albert.u.boot@aribaud.net>2014-07-04 19:48:41 +0200
commitf749db3a75ec483692d7bb6d46a1fbecb65c38ba (patch)
tree20033069fbaa0a0539bc72620bafcc143a42b963 /board/freescale/ls2085a/ddr.c
parentb940ca64b22ba8980fd4ec8dda028f6b1a2ed79d (diff)
downloadu-boot-f749db3a75ec483692d7bb6d46a1fbecb65c38ba.tar.gz
u-boot-f749db3a75ec483692d7bb6d46a1fbecb65c38ba.tar.xz
u-boot-f749db3a75ec483692d7bb6d46a1fbecb65c38ba.zip
ARMv8/ls2085a_emu: Add LS2085A emulator and simulator board support
LS2085A is an ARMv8 implementation. This adds board support for emulator and simulator: Two DDR controllers UART2 is used as the console IFC timing is tightened for speedy booting Support DDR3 and DDR4 as separated targets Management Complex (MC) is enabled Support for GIC 500 (based on GICv3 arch) Signed-off-by: York Sun <yorksun@freescale.com> Signed-off-by: Arnab Basu <arnab.basu@freescale.com> Signed-off-by: J. German Rivera <German.Rivera@freescale.com> Signed-off-by: Bhupesh Sharma <bhupesh.sharma@freescale.com>
Diffstat (limited to 'board/freescale/ls2085a/ddr.c')
-rw-r--r--board/freescale/ls2085a/ddr.c175
1 files changed, 175 insertions, 0 deletions
diff --git a/board/freescale/ls2085a/ddr.c b/board/freescale/ls2085a/ddr.c
new file mode 100644
index 0000000000..257bc162d0
--- /dev/null
+++ b/board/freescale/ls2085a/ddr.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2014 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <fsl_ddr_sdram.h>
+#include <fsl_ddr_dimm_params.h>
+#include "ddr.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void fsl_ddr_board_options(memctl_options_t *popts,
+ dimm_params_t *pdimm,
+ unsigned int ctrl_num)
+{
+ const struct board_specific_parameters *pbsp, *pbsp_highest = NULL;
+ ulong ddr_freq;
+
+ if (ctrl_num > 3) {
+ printf("Not supported controller number %d\n", ctrl_num);
+ return;
+ }
+ if (!pdimm->n_ranks)
+ return;
+
+ /*
+ * we use identical timing for all slots. If needed, change the code
+ * to pbsp = rdimms[ctrl_num] or pbsp = udimms[ctrl_num];
+ */
+ 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.
+ */
+ ddr_freq = get_ddr_freq(0) / 1000000;
+ while (pbsp->datarate_mhz_high) {
+ if (pbsp->n_ranks == pdimm->n_ranks &&
+ (pdimm->rank_density >> 30) >= pbsp->rank_gb) {
+ if (ddr_freq <= pbsp->datarate_mhz_high) {
+ popts->clk_adjust = pbsp->clk_adjust;
+ popts->wrlvl_start = pbsp->wrlvl_start;
+ popts->wrlvl_ctl_2 = pbsp->wrlvl_ctl_2;
+ popts->wrlvl_ctl_3 = pbsp->wrlvl_ctl_3;
+ goto found;
+ }
+ pbsp_highest = pbsp;
+ }
+ pbsp++;
+ }
+
+ if (pbsp_highest) {
+ printf("Error: board specific timing not found for data rate %lu MT/s\n"
+ "Trying to use the highest speed (%u) parameters\n",
+ ddr_freq, pbsp_highest->datarate_mhz_high);
+ popts->clk_adjust = pbsp_highest->clk_adjust;
+ popts->wrlvl_start = pbsp_highest->wrlvl_start;
+ popts->wrlvl_ctl_2 = pbsp->wrlvl_ctl_2;
+ popts->wrlvl_ctl_3 = pbsp->wrlvl_ctl_3;
+ } else {
+ panic("DIMM is not supported by this board");
+ }
+found:
+ debug("Found timing match: n_ranks %d, data rate %d, rank_gb %d\n"
+ "\tclk_adjust %d, wrlvl_start %d, wrlvl_ctrl_2 0x%x, wrlvl_ctrl_3 0x%x\n",
+ pbsp->n_ranks, pbsp->datarate_mhz_high, pbsp->rank_gb,
+ pbsp->clk_adjust, pbsp->wrlvl_start, pbsp->wrlvl_ctl_2,
+ pbsp->wrlvl_ctl_3);
+
+ /*
+ * Factors to consider for half-strength driver enable:
+ * - number of DIMMs installed
+ */
+ popts->half_strength_driver_enable = 1;
+ /*
+ * Write leveling override
+ */
+ popts->wrlvl_override = 1;
+ popts->wrlvl_sample = 0xf;
+
+ /*
+ * Rtt and Rtt_WR override
+ */
+ popts->rtt_override = 0;
+
+ /* Enable ZQ calibration */
+ popts->zq_en = 1;
+
+#ifdef CONFIG_SYS_FSL_DDR4
+ popts->ddr_cdr1 = DDR_CDR1_DHC_EN | DDR_CDR1_ODT(DDR_CDR_ODT_80ohm);
+ popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_80ohm) |
+ DDR_CDR2_VREF_OVRD(70); /* Vref = 70% */
+#else
+ /* DHC_EN =1, ODT = 75 Ohm */
+ popts->ddr_cdr1 = DDR_CDR1_DHC_EN | DDR_CDR1_ODT(DDR_CDR_ODT_75ohm);
+ popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_75ohm);
+#endif
+}
+
+#ifdef CONFIG_SYS_DDR_RAW_TIMING
+dimm_params_t ddr_raw_timing = {
+ .n_ranks = 2,
+ .rank_density = 1073741824u,
+ .capacity = 2147483648,
+ .primary_sdram_width = 64,
+ .ec_sdram_width = 0,
+ .registered_dimm = 0,
+ .mirrored_dimm = 0,
+ .n_row_addr = 14,
+ .n_col_addr = 10,
+ .n_banks_per_sdram_device = 8,
+ .edc_config = 0,
+ .burst_lengths_bitmask = 0x0c,
+
+ .tckmin_x_ps = 937,
+ .caslat_x = 0x6FC << 4, /* 14,13,11,10,9,8,7,6 */
+ .taa_ps = 13090,
+ .twr_ps = 15000,
+ .trcd_ps = 13090,
+ .trrd_ps = 5000,
+ .trp_ps = 13090,
+ .tras_ps = 33000,
+ .trc_ps = 46090,
+ .trfc_ps = 160000,
+ .twtr_ps = 7500,
+ .trtp_ps = 7500,
+ .refresh_rate_ps = 7800000,
+ .tfaw_ps = 25000,
+};
+
+int fsl_ddr_get_dimm_params(dimm_params_t *pdimm,
+ unsigned int controller_number,
+ unsigned int dimm_number)
+{
+ const char dimm_model[] = "Fixed DDR on board";
+
+ if (((controller_number == 0) && (dimm_number == 0)) ||
+ ((controller_number == 1) && (dimm_number == 0))) {
+ memcpy(pdimm, &ddr_raw_timing, sizeof(dimm_params_t));
+ memset(pdimm->mpart, 0, sizeof(pdimm->mpart));
+ memcpy(pdimm->mpart, dimm_model, sizeof(dimm_model) - 1);
+ }
+
+ return 0;
+}
+#endif
+phys_size_t initdram(int board_type)
+{
+ phys_size_t dram_size;
+
+ puts("Initializing DDR....");
+
+ puts("using SPD\n");
+ dram_size = fsl_ddr_sdram();
+
+ return dram_size;
+}
+
+void dram_init_banksize(void)
+{
+ gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
+ if (gd->ram_size > CONFIG_SYS_LS2_DDR_BLOCK1_SIZE) {
+ gd->bd->bi_dram[0].size = CONFIG_SYS_LS2_DDR_BLOCK1_SIZE;
+ gd->bd->bi_dram[1].start = CONFIG_SYS_DDR_BLOCK2_BASE;
+ gd->bd->bi_dram[1].size = gd->ram_size -
+ CONFIG_SYS_LS2_DDR_BLOCK1_SIZE;
+ } else {
+ gd->bd->bi_dram[0].size = gd->ram_size;
+ }
+}