xref: /rk3399_rockchip-uboot/board/freescale/t208xrdb/ddr.c (revision f1683aa73c31db0a025e0254e6ce1ee7e56aad3e)
18d67c368SShengzhou Liu /*
28d67c368SShengzhou Liu  * Copyright 2014 Freescale Semiconductor, Inc.
38d67c368SShengzhou Liu  *
45b8031ccSTom Rini  * SPDX-License-Identifier:	GPL-2.0
58d67c368SShengzhou Liu  */
68d67c368SShengzhou Liu 
78d67c368SShengzhou Liu #include <common.h>
88d67c368SShengzhou Liu #include <i2c.h>
98d67c368SShengzhou Liu #include <hwconfig.h>
108d67c368SShengzhou Liu #include <asm/mmu.h>
118d67c368SShengzhou Liu #include <fsl_ddr_sdram.h>
128d67c368SShengzhou Liu #include <fsl_ddr_dimm_params.h>
138d67c368SShengzhou Liu #include <asm/fsl_law.h>
148d67c368SShengzhou Liu #include "ddr.h"
158d67c368SShengzhou Liu 
168d67c368SShengzhou Liu DECLARE_GLOBAL_DATA_PTR;
178d67c368SShengzhou Liu 
fsl_ddr_board_options(memctl_options_t * popts,dimm_params_t * pdimm,unsigned int ctrl_num)188d67c368SShengzhou Liu void fsl_ddr_board_options(memctl_options_t *popts,
198d67c368SShengzhou Liu 				dimm_params_t *pdimm,
208d67c368SShengzhou Liu 				unsigned int ctrl_num)
218d67c368SShengzhou Liu {
228d67c368SShengzhou Liu 	const struct board_specific_parameters *pbsp, *pbsp_highest = NULL;
238d67c368SShengzhou Liu 	ulong ddr_freq;
248d67c368SShengzhou Liu 
258d67c368SShengzhou Liu 	if (ctrl_num > 1) {
268d67c368SShengzhou Liu 		printf("Not supported controller number %d\n", ctrl_num);
278d67c368SShengzhou Liu 		return;
288d67c368SShengzhou Liu 	}
298d67c368SShengzhou Liu 	if (!pdimm->n_ranks)
308d67c368SShengzhou Liu 		return;
318d67c368SShengzhou Liu 
328d67c368SShengzhou Liu 	pbsp = udimms[0];
338d67c368SShengzhou Liu 
348d67c368SShengzhou Liu 	/* Get clk_adjust, wrlvl_start, wrlvl_ctl, according to the board ddr
358d67c368SShengzhou Liu 	 * freqency and n_banks specified in board_specific_parameters table.
368d67c368SShengzhou Liu 	 */
378d67c368SShengzhou Liu 	ddr_freq = get_ddr_freq(0) / 1000000;
388d67c368SShengzhou Liu 	while (pbsp->datarate_mhz_high) {
398d67c368SShengzhou Liu 		if (pbsp->n_ranks == pdimm->n_ranks &&
408d67c368SShengzhou Liu 		    (pdimm->rank_density >> 30) >= pbsp->rank_gb) {
418d67c368SShengzhou Liu 			if (ddr_freq <= pbsp->datarate_mhz_high) {
428d67c368SShengzhou Liu 				popts->clk_adjust = pbsp->clk_adjust;
438d67c368SShengzhou Liu 				popts->wrlvl_start = pbsp->wrlvl_start;
448d67c368SShengzhou Liu 				popts->wrlvl_ctl_2 = pbsp->wrlvl_ctl_2;
458d67c368SShengzhou Liu 				popts->wrlvl_ctl_3 = pbsp->wrlvl_ctl_3;
468d67c368SShengzhou Liu 				goto found;
478d67c368SShengzhou Liu 			}
488d67c368SShengzhou Liu 			pbsp_highest = pbsp;
498d67c368SShengzhou Liu 		}
508d67c368SShengzhou Liu 		pbsp++;
518d67c368SShengzhou Liu 	}
528d67c368SShengzhou Liu 
538d67c368SShengzhou Liu 	if (pbsp_highest) {
548d67c368SShengzhou Liu 		printf("Error: board specific timing not found");
558d67c368SShengzhou Liu 		printf("for data rate %lu MT/s\n", ddr_freq);
568d67c368SShengzhou Liu 		printf("Trying to use the highest speed (%u) parameters\n",
578d67c368SShengzhou Liu 		       pbsp_highest->datarate_mhz_high);
588d67c368SShengzhou Liu 		popts->clk_adjust = pbsp_highest->clk_adjust;
598d67c368SShengzhou Liu 		popts->wrlvl_start = pbsp_highest->wrlvl_start;
608d67c368SShengzhou Liu 		popts->wrlvl_ctl_2 = pbsp->wrlvl_ctl_2;
618d67c368SShengzhou Liu 		popts->wrlvl_ctl_3 = pbsp->wrlvl_ctl_3;
628d67c368SShengzhou Liu 	} else {
638d67c368SShengzhou Liu 		panic("DIMM is not supported by this board");
648d67c368SShengzhou Liu 	}
658d67c368SShengzhou Liu found:
668d67c368SShengzhou Liu 	debug("Found timing match: n_ranks %d, data rate %d, rank_gb %d\n"
678d67c368SShengzhou Liu 		"\tclk_adjust %d, wrlvl_start %d, wrlvl_ctrl_2 0x%x, "
688d67c368SShengzhou Liu 		"wrlvl_ctrl_3 0x%x\n",
698d67c368SShengzhou Liu 		pbsp->n_ranks, pbsp->datarate_mhz_high, pbsp->rank_gb,
708d67c368SShengzhou Liu 		pbsp->clk_adjust, pbsp->wrlvl_start, pbsp->wrlvl_ctl_2,
718d67c368SShengzhou Liu 		pbsp->wrlvl_ctl_3);
728d67c368SShengzhou Liu 
738d67c368SShengzhou Liu 	/*
748d67c368SShengzhou Liu 	 * Factors to consider for half-strength driver enable:
758d67c368SShengzhou Liu 	 *	- number of DIMMs installed
768d67c368SShengzhou Liu 	 */
778d67c368SShengzhou Liu 	popts->half_strength_driver_enable = 0;
788d67c368SShengzhou Liu 	/*
798d67c368SShengzhou Liu 	 * Write leveling override
808d67c368SShengzhou Liu 	 */
818d67c368SShengzhou Liu 	popts->wrlvl_override = 1;
828d67c368SShengzhou Liu 	popts->wrlvl_sample = 0xf;
838d67c368SShengzhou Liu 
848d67c368SShengzhou Liu 	/*
858d67c368SShengzhou Liu 	 * Rtt and Rtt_WR override
868d67c368SShengzhou Liu 	 */
878d67c368SShengzhou Liu 	popts->rtt_override = 0;
888d67c368SShengzhou Liu 
898d67c368SShengzhou Liu 	/* Enable ZQ calibration */
908d67c368SShengzhou Liu 	popts->zq_en = 1;
918d67c368SShengzhou Liu 
928d67c368SShengzhou Liu 	/* DHC_EN =1, ODT = 75 Ohm */
938d67c368SShengzhou Liu 	popts->ddr_cdr1 = DDR_CDR1_DHC_EN | DDR_CDR1_ODT(DDR_CDR_ODT_75ohm);
948d67c368SShengzhou Liu 	popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_75ohm);
9590101386SShengzhou Liu 
9690101386SShengzhou Liu 	/* optimize cpo for erratum A-009942 */
9790101386SShengzhou Liu 	popts->cpo_sample = 0x54;
988d67c368SShengzhou Liu }
998d67c368SShengzhou Liu 
dram_init(void)100*f1683aa7SSimon Glass int dram_init(void)
1018d67c368SShengzhou Liu {
1028d67c368SShengzhou Liu 	phys_size_t dram_size;
1038d67c368SShengzhou Liu 
1044d666683SShengzhou Liu #if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_RAMBOOT_PBL)
1058d67c368SShengzhou Liu 	puts("Initializing....using SPD\n");
1068d67c368SShengzhou Liu 	dram_size = fsl_ddr_sdram();
1074d666683SShengzhou Liu #else
1084d666683SShengzhou Liu 	/* DDR has been initialised by first stage boot loader */
1094d666683SShengzhou Liu 	dram_size = fsl_ddr_sdram_size();
1104d666683SShengzhou Liu #endif
11153499282SShengzhou Liu 	dram_size = setup_ddr_tlbs(dram_size / 0x100000);
11253499282SShengzhou Liu 	dram_size *= 0x100000;
11353499282SShengzhou Liu 
114088454cdSSimon Glass 	gd->ram_size = dram_size;
115088454cdSSimon Glass 
116088454cdSSimon Glass 	return 0;
1178d67c368SShengzhou Liu }
118