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