183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
244937214SPrabhakar Kushwaha /*
344937214SPrabhakar Kushwaha * Copyright 2015 Freescale Semiconductor, Inc.
444937214SPrabhakar Kushwaha */
544937214SPrabhakar Kushwaha
644937214SPrabhakar Kushwaha #include <common.h>
744937214SPrabhakar Kushwaha #include <fsl_ddr_sdram.h>
844937214SPrabhakar Kushwaha #include <fsl_ddr_dimm_params.h>
93c1d218aSYork Sun #include <asm/arch/soc.h>
106e2941d7SSimon Glass #include <asm/arch/clock.h>
1144937214SPrabhakar Kushwaha #include "ddr.h"
1244937214SPrabhakar Kushwaha
1344937214SPrabhakar Kushwaha DECLARE_GLOBAL_DATA_PTR;
1444937214SPrabhakar Kushwaha
fsl_ddr_board_options(memctl_options_t * popts,dimm_params_t * pdimm,unsigned int ctrl_num)1544937214SPrabhakar Kushwaha void fsl_ddr_board_options(memctl_options_t *popts,
1644937214SPrabhakar Kushwaha dimm_params_t *pdimm,
1744937214SPrabhakar Kushwaha unsigned int ctrl_num)
1844937214SPrabhakar Kushwaha {
1944937214SPrabhakar Kushwaha #ifdef CONFIG_SYS_FSL_HAS_DP_DDR
2044937214SPrabhakar Kushwaha u8 dq_mapping_0, dq_mapping_2, dq_mapping_3;
2144937214SPrabhakar Kushwaha #endif
2244937214SPrabhakar Kushwaha const struct board_specific_parameters *pbsp, *pbsp_highest = NULL;
2344937214SPrabhakar Kushwaha ulong ddr_freq;
2444937214SPrabhakar Kushwaha int slot;
2544937214SPrabhakar Kushwaha
2644937214SPrabhakar Kushwaha if (ctrl_num > 2) {
2744937214SPrabhakar Kushwaha printf("Not supported controller number %d\n", ctrl_num);
2844937214SPrabhakar Kushwaha return;
2944937214SPrabhakar Kushwaha }
3044937214SPrabhakar Kushwaha
3144937214SPrabhakar Kushwaha for (slot = 0; slot < CONFIG_DIMM_SLOTS_PER_CTLR; slot++) {
3244937214SPrabhakar Kushwaha if (pdimm[slot].n_ranks)
3344937214SPrabhakar Kushwaha break;
3444937214SPrabhakar Kushwaha }
3544937214SPrabhakar Kushwaha
3644937214SPrabhakar Kushwaha if (slot >= CONFIG_DIMM_SLOTS_PER_CTLR)
3744937214SPrabhakar Kushwaha return;
3844937214SPrabhakar Kushwaha
3944937214SPrabhakar Kushwaha /*
4044937214SPrabhakar Kushwaha * we use identical timing for all slots. If needed, change the code
4144937214SPrabhakar Kushwaha * to pbsp = rdimms[ctrl_num] or pbsp = udimms[ctrl_num];
4244937214SPrabhakar Kushwaha */
4344937214SPrabhakar Kushwaha if (popts->registered_dimm_en)
4444937214SPrabhakar Kushwaha pbsp = rdimms[ctrl_num];
4544937214SPrabhakar Kushwaha else
4644937214SPrabhakar Kushwaha pbsp = udimms[ctrl_num];
4744937214SPrabhakar Kushwaha
4844937214SPrabhakar Kushwaha
4944937214SPrabhakar Kushwaha /* Get clk_adjust, wrlvl_start, wrlvl_ctl, according to the board ddr
5044937214SPrabhakar Kushwaha * freqency and n_banks specified in board_specific_parameters table.
5144937214SPrabhakar Kushwaha */
5244937214SPrabhakar Kushwaha ddr_freq = get_ddr_freq(ctrl_num) / 1000000;
5344937214SPrabhakar Kushwaha while (pbsp->datarate_mhz_high) {
5444937214SPrabhakar Kushwaha if (pbsp->n_ranks == pdimm[slot].n_ranks &&
5544937214SPrabhakar Kushwaha (pdimm[slot].rank_density >> 30) >= pbsp->rank_gb) {
5644937214SPrabhakar Kushwaha if (ddr_freq <= pbsp->datarate_mhz_high) {
5744937214SPrabhakar Kushwaha popts->clk_adjust = pbsp->clk_adjust;
5844937214SPrabhakar Kushwaha popts->wrlvl_start = pbsp->wrlvl_start;
5944937214SPrabhakar Kushwaha popts->wrlvl_ctl_2 = pbsp->wrlvl_ctl_2;
6044937214SPrabhakar Kushwaha popts->wrlvl_ctl_3 = pbsp->wrlvl_ctl_3;
6144937214SPrabhakar Kushwaha goto found;
6244937214SPrabhakar Kushwaha }
6344937214SPrabhakar Kushwaha pbsp_highest = pbsp;
6444937214SPrabhakar Kushwaha }
6544937214SPrabhakar Kushwaha pbsp++;
6644937214SPrabhakar Kushwaha }
6744937214SPrabhakar Kushwaha
6844937214SPrabhakar Kushwaha if (pbsp_highest) {
6944937214SPrabhakar Kushwaha printf("Error: board specific timing not found for data rate %lu MT/s\n"
7044937214SPrabhakar Kushwaha "Trying to use the highest speed (%u) parameters\n",
7144937214SPrabhakar Kushwaha ddr_freq, pbsp_highest->datarate_mhz_high);
7244937214SPrabhakar Kushwaha popts->clk_adjust = pbsp_highest->clk_adjust;
7344937214SPrabhakar Kushwaha popts->wrlvl_start = pbsp_highest->wrlvl_start;
7444937214SPrabhakar Kushwaha popts->wrlvl_ctl_2 = pbsp->wrlvl_ctl_2;
7544937214SPrabhakar Kushwaha popts->wrlvl_ctl_3 = pbsp->wrlvl_ctl_3;
7644937214SPrabhakar Kushwaha } else {
7744937214SPrabhakar Kushwaha panic("DIMM is not supported by this board");
7844937214SPrabhakar Kushwaha }
7944937214SPrabhakar Kushwaha found:
8044937214SPrabhakar Kushwaha debug("Found timing match: n_ranks %d, data rate %d, rank_gb %d\n"
8144937214SPrabhakar Kushwaha "\tclk_adjust %d, wrlvl_start %d, wrlvl_ctrl_2 0x%x, wrlvl_ctrl_3 0x%x\n",
8244937214SPrabhakar Kushwaha pbsp->n_ranks, pbsp->datarate_mhz_high, pbsp->rank_gb,
8344937214SPrabhakar Kushwaha pbsp->clk_adjust, pbsp->wrlvl_start, pbsp->wrlvl_ctl_2,
8444937214SPrabhakar Kushwaha pbsp->wrlvl_ctl_3);
8544937214SPrabhakar Kushwaha #ifdef CONFIG_SYS_FSL_HAS_DP_DDR
8644937214SPrabhakar Kushwaha if (ctrl_num == CONFIG_DP_DDR_CTRL) {
8744937214SPrabhakar Kushwaha /* force DDR bus width to 32 bits */
8844937214SPrabhakar Kushwaha popts->data_bus_width = 1;
8944937214SPrabhakar Kushwaha popts->otf_burst_chop_en = 0;
9044937214SPrabhakar Kushwaha popts->burst_length = DDR_BL8;
9144937214SPrabhakar Kushwaha popts->bstopre = 0; /* enable auto precharge */
9244937214SPrabhakar Kushwaha /*
9344937214SPrabhakar Kushwaha * Layout optimization results byte mapping
9444937214SPrabhakar Kushwaha * Byte 0 -> Byte ECC
9544937214SPrabhakar Kushwaha * Byte 1 -> Byte 3
9644937214SPrabhakar Kushwaha * Byte 2 -> Byte 2
9744937214SPrabhakar Kushwaha * Byte 3 -> Byte 1
9844937214SPrabhakar Kushwaha * Byte ECC -> Byte 0
9944937214SPrabhakar Kushwaha */
10044937214SPrabhakar Kushwaha dq_mapping_0 = pdimm[slot].dq_mapping[0];
10144937214SPrabhakar Kushwaha dq_mapping_2 = pdimm[slot].dq_mapping[2];
10244937214SPrabhakar Kushwaha dq_mapping_3 = pdimm[slot].dq_mapping[3];
10344937214SPrabhakar Kushwaha pdimm[slot].dq_mapping[0] = pdimm[slot].dq_mapping[8];
10444937214SPrabhakar Kushwaha pdimm[slot].dq_mapping[1] = pdimm[slot].dq_mapping[9];
10544937214SPrabhakar Kushwaha pdimm[slot].dq_mapping[2] = pdimm[slot].dq_mapping[6];
10644937214SPrabhakar Kushwaha pdimm[slot].dq_mapping[3] = pdimm[slot].dq_mapping[7];
10744937214SPrabhakar Kushwaha pdimm[slot].dq_mapping[6] = dq_mapping_2;
10844937214SPrabhakar Kushwaha pdimm[slot].dq_mapping[7] = dq_mapping_3;
10944937214SPrabhakar Kushwaha pdimm[slot].dq_mapping[8] = dq_mapping_0;
11044937214SPrabhakar Kushwaha pdimm[slot].dq_mapping[9] = 0;
11144937214SPrabhakar Kushwaha pdimm[slot].dq_mapping[10] = 0;
11244937214SPrabhakar Kushwaha pdimm[slot].dq_mapping[11] = 0;
11344937214SPrabhakar Kushwaha pdimm[slot].dq_mapping[12] = 0;
11444937214SPrabhakar Kushwaha pdimm[slot].dq_mapping[13] = 0;
11544937214SPrabhakar Kushwaha pdimm[slot].dq_mapping[14] = 0;
11644937214SPrabhakar Kushwaha pdimm[slot].dq_mapping[15] = 0;
11744937214SPrabhakar Kushwaha pdimm[slot].dq_mapping[16] = 0;
11844937214SPrabhakar Kushwaha pdimm[slot].dq_mapping[17] = 0;
11944937214SPrabhakar Kushwaha }
12044937214SPrabhakar Kushwaha #endif
12144937214SPrabhakar Kushwaha /* To work at higher than 1333MT/s */
12244937214SPrabhakar Kushwaha popts->half_strength_driver_enable = 0;
12344937214SPrabhakar Kushwaha /*
12444937214SPrabhakar Kushwaha * Write leveling override
12544937214SPrabhakar Kushwaha */
12644937214SPrabhakar Kushwaha popts->wrlvl_override = 1;
12744937214SPrabhakar Kushwaha popts->wrlvl_sample = 0x0; /* 32 clocks */
12844937214SPrabhakar Kushwaha
12944937214SPrabhakar Kushwaha /*
13044937214SPrabhakar Kushwaha * Rtt and Rtt_WR override
13144937214SPrabhakar Kushwaha */
13244937214SPrabhakar Kushwaha popts->rtt_override = 0;
13344937214SPrabhakar Kushwaha
13444937214SPrabhakar Kushwaha /* Enable ZQ calibration */
13544937214SPrabhakar Kushwaha popts->zq_en = 1;
13644937214SPrabhakar Kushwaha
13744937214SPrabhakar Kushwaha if (ddr_freq < 2350) {
138c4243ac9SYork Sun if (pdimm[0].n_ranks == 2 && pdimm[1].n_ranks == 2) {
139c4243ac9SYork Sun /* four chip-selects */
140c4243ac9SYork Sun popts->ddr_cdr1 = DDR_CDR1_DHC_EN |
141c4243ac9SYork Sun DDR_CDR1_ODT(DDR_CDR_ODT_80ohm);
142c4243ac9SYork Sun popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_80ohm);
143c4243ac9SYork Sun popts->twot_en = 1; /* enable 2T timing */
144c4243ac9SYork Sun } else {
14544937214SPrabhakar Kushwaha popts->ddr_cdr1 = DDR_CDR1_DHC_EN |
14644937214SPrabhakar Kushwaha DDR_CDR1_ODT(DDR_CDR_ODT_60ohm);
14744937214SPrabhakar Kushwaha popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_60ohm) |
14844937214SPrabhakar Kushwaha DDR_CDR2_VREF_RANGE_2;
149c4243ac9SYork Sun }
15044937214SPrabhakar Kushwaha } else {
15144937214SPrabhakar Kushwaha popts->ddr_cdr1 = DDR_CDR1_DHC_EN |
15244937214SPrabhakar Kushwaha DDR_CDR1_ODT(DDR_CDR_ODT_100ohm);
15344937214SPrabhakar Kushwaha popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_100ohm) |
15444937214SPrabhakar Kushwaha DDR_CDR2_VREF_RANGE_2;
15544937214SPrabhakar Kushwaha }
15644937214SPrabhakar Kushwaha }
15744937214SPrabhakar Kushwaha
158*1908201cSRajesh Bhagat #ifdef CONFIG_TFABOOT
fsl_initdram(void)159*1908201cSRajesh Bhagat int fsl_initdram(void)
160*1908201cSRajesh Bhagat {
161*1908201cSRajesh Bhagat gd->ram_size = tfa_get_dram_size();
162*1908201cSRajesh Bhagat
163*1908201cSRajesh Bhagat if (!gd->ram_size)
164*1908201cSRajesh Bhagat gd->ram_size = fsl_ddr_sdram_size();
165*1908201cSRajesh Bhagat
166*1908201cSRajesh Bhagat return 0;
167*1908201cSRajesh Bhagat }
168*1908201cSRajesh Bhagat #else
fsl_initdram(void)1693eace37eSSimon Glass int fsl_initdram(void)
17044937214SPrabhakar Kushwaha {
17144937214SPrabhakar Kushwaha #if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD)
172088454cdSSimon Glass gd->ram_size = fsl_ddr_sdram_size();
17344937214SPrabhakar Kushwaha #else
17444937214SPrabhakar Kushwaha puts("Initializing DDR....using SPD\n");
17544937214SPrabhakar Kushwaha
176088454cdSSimon Glass gd->ram_size = fsl_ddr_sdram();
17744937214SPrabhakar Kushwaha #endif
17844937214SPrabhakar Kushwaha
179088454cdSSimon Glass return 0;
18044937214SPrabhakar Kushwaha }
181*1908201cSRajesh Bhagat #endif /* CONFIG_TFABOOT */
182