xref: /rk3399_rockchip-uboot/board/freescale/t1040qds/ddr.c (revision f1683aa73c31db0a025e0254e6ce1ee7e56aad3e)
17d436078SPrabhakar Kushwaha /*
2c60dee03SYork Sun  * Copyright 2013-2014 Freescale Semiconductor, Inc.
37d436078SPrabhakar Kushwaha  *
47d436078SPrabhakar Kushwaha  * SPDX-License-Identifier:	GPL-2.0+
57d436078SPrabhakar Kushwaha  */
67d436078SPrabhakar Kushwaha 
77d436078SPrabhakar Kushwaha #include <common.h>
87d436078SPrabhakar Kushwaha #include <i2c.h>
97d436078SPrabhakar Kushwaha #include <hwconfig.h>
107d436078SPrabhakar Kushwaha #include <asm/mmu.h>
115614e71bSYork Sun #include <fsl_ddr_sdram.h>
125614e71bSYork Sun #include <fsl_ddr_dimm_params.h>
137d436078SPrabhakar Kushwaha #include <asm/fsl_law.h>
147d0e97a2Stang yuantian #include <asm/mpc85xx_gpio.h>
157d436078SPrabhakar Kushwaha #include "ddr.h"
167d436078SPrabhakar Kushwaha 
177d436078SPrabhakar Kushwaha DECLARE_GLOBAL_DATA_PTR;
187d436078SPrabhakar Kushwaha 
fsl_ddr_board_options(memctl_options_t * popts,dimm_params_t * pdimm,unsigned int ctrl_num)197d436078SPrabhakar Kushwaha void fsl_ddr_board_options(memctl_options_t *popts,
207d436078SPrabhakar Kushwaha 				dimm_params_t *pdimm,
217d436078SPrabhakar Kushwaha 				unsigned int ctrl_num)
227d436078SPrabhakar Kushwaha {
237d436078SPrabhakar Kushwaha 	const struct board_specific_parameters *pbsp, *pbsp_highest = NULL;
247d436078SPrabhakar Kushwaha 	ulong ddr_freq;
257d436078SPrabhakar Kushwaha 
267d436078SPrabhakar Kushwaha 	if (ctrl_num > 2) {
277d436078SPrabhakar Kushwaha 		printf("Not supported controller number %d\n", ctrl_num);
287d436078SPrabhakar Kushwaha 		return;
297d436078SPrabhakar Kushwaha 	}
307d436078SPrabhakar Kushwaha 	if (!pdimm->n_ranks)
317d436078SPrabhakar Kushwaha 		return;
327d436078SPrabhakar Kushwaha 
337d436078SPrabhakar Kushwaha 	pbsp = udimms[0];
347d436078SPrabhakar Kushwaha 
357d436078SPrabhakar Kushwaha 	/* Get clk_adjust, cpo, write_data_delay,2t, according to the board ddr
367d436078SPrabhakar Kushwaha 	 * freqency and n_banks specified in board_specific_parameters table.
377d436078SPrabhakar Kushwaha 	 */
387d436078SPrabhakar Kushwaha 	ddr_freq = get_ddr_freq(0) / 1000000;
397d436078SPrabhakar Kushwaha 	while (pbsp->datarate_mhz_high) {
407d436078SPrabhakar Kushwaha 		if (pbsp->n_ranks == pdimm->n_ranks &&
417d436078SPrabhakar Kushwaha 		    (pdimm->rank_density >> 30) >= pbsp->rank_gb) {
427d436078SPrabhakar Kushwaha 			if (ddr_freq <= pbsp->datarate_mhz_high) {
437d436078SPrabhakar Kushwaha 				popts->clk_adjust = pbsp->clk_adjust;
447d436078SPrabhakar Kushwaha 				popts->wrlvl_start = pbsp->wrlvl_start;
457d436078SPrabhakar Kushwaha 				popts->wrlvl_ctl_2 = pbsp->wrlvl_ctl_2;
467d436078SPrabhakar Kushwaha 				popts->wrlvl_ctl_3 = pbsp->wrlvl_ctl_3;
477d436078SPrabhakar Kushwaha 				goto found;
487d436078SPrabhakar Kushwaha 			}
497d436078SPrabhakar Kushwaha 			pbsp_highest = pbsp;
507d436078SPrabhakar Kushwaha 		}
517d436078SPrabhakar Kushwaha 		pbsp++;
527d436078SPrabhakar Kushwaha 	}
537d436078SPrabhakar Kushwaha 
547d436078SPrabhakar Kushwaha 	if (pbsp_highest) {
557d436078SPrabhakar Kushwaha 		printf("Error: board specific timing not found\n");
567d436078SPrabhakar Kushwaha 		printf("for data rate %lu MT/s\n", ddr_freq);
577d436078SPrabhakar Kushwaha 		printf("Trying to use the highest speed (%u) parameters\n",
587d436078SPrabhakar Kushwaha 		       pbsp_highest->datarate_mhz_high);
597d436078SPrabhakar Kushwaha 		popts->clk_adjust = pbsp_highest->clk_adjust;
607d436078SPrabhakar Kushwaha 		popts->wrlvl_start = pbsp_highest->wrlvl_start;
617d436078SPrabhakar Kushwaha 		popts->wrlvl_ctl_2 = pbsp->wrlvl_ctl_2;
627d436078SPrabhakar Kushwaha 		popts->wrlvl_ctl_3 = pbsp->wrlvl_ctl_3;
637d436078SPrabhakar Kushwaha 	} else {
647d436078SPrabhakar Kushwaha 		panic("DIMM is not supported by this board");
657d436078SPrabhakar Kushwaha 	}
667d436078SPrabhakar Kushwaha found:
677d436078SPrabhakar Kushwaha 	debug("Found timing match: n_ranks %d, data rate %d, rank_gb %d\n"
687d436078SPrabhakar Kushwaha 		"\tclk_adjust %d, wrlvl_start %d, wrlvl_ctrl_2 0x%x, "
697d436078SPrabhakar Kushwaha 		"wrlvl_ctrl_3 0x%x\n",
707d436078SPrabhakar Kushwaha 		pbsp->n_ranks, pbsp->datarate_mhz_high, pbsp->rank_gb,
717d436078SPrabhakar Kushwaha 		pbsp->clk_adjust, pbsp->wrlvl_start, pbsp->wrlvl_ctl_2,
727d436078SPrabhakar Kushwaha 		pbsp->wrlvl_ctl_3);
737d436078SPrabhakar Kushwaha 
747d436078SPrabhakar Kushwaha 	/*
757d436078SPrabhakar Kushwaha 	 * Factors to consider for half-strength driver enable:
767d436078SPrabhakar Kushwaha 	 *	- number of DIMMs installed
777d436078SPrabhakar Kushwaha 	 */
78c60dee03SYork Sun 	popts->half_strength_driver_enable = 1;
797d436078SPrabhakar Kushwaha 	/*
807d436078SPrabhakar Kushwaha 	 * Write leveling override
817d436078SPrabhakar Kushwaha 	 */
827d436078SPrabhakar Kushwaha 	popts->wrlvl_override = 1;
837d436078SPrabhakar Kushwaha 	popts->wrlvl_sample = 0xf;
847d436078SPrabhakar Kushwaha 
857d436078SPrabhakar Kushwaha 	/*
867d436078SPrabhakar Kushwaha 	 * rtt and rtt_wr override
877d436078SPrabhakar Kushwaha 	 */
887d436078SPrabhakar Kushwaha 	popts->rtt_override = 0;
897d436078SPrabhakar Kushwaha 
907d436078SPrabhakar Kushwaha 	/* Enable ZQ calibration */
917d436078SPrabhakar Kushwaha 	popts->zq_en = 1;
927d436078SPrabhakar Kushwaha 
937d436078SPrabhakar Kushwaha 	/* DHC_EN =1, ODT = 75 Ohm */
94c60dee03SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
95c60dee03SYork Sun 	popts->ddr_cdr1 = DDR_CDR1_DHC_EN | DDR_CDR1_ODT(DDR_CDR_ODT_80ohm);
96c60dee03SYork Sun 	popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_80ohm) |
97c60dee03SYork Sun 			  DDR_CDR2_VREF_OVRD(70);	/* Vref = 70% */
9890101386SShengzhou Liu 
9990101386SShengzhou Liu 	/* optimize cpo for erratum A-009942 */
10090101386SShengzhou Liu 	popts->cpo_sample = 0x69;
101c60dee03SYork Sun #else
1027d436078SPrabhakar Kushwaha 	popts->ddr_cdr1 = DDR_CDR1_DHC_EN | DDR_CDR1_ODT(DDR_CDR_ODT_75ohm);
1037d436078SPrabhakar Kushwaha 	popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_75ohm);
104c60dee03SYork Sun #endif
1057d436078SPrabhakar Kushwaha }
1067d436078SPrabhakar Kushwaha 
1077d0e97a2Stang yuantian #if defined(CONFIG_DEEP_SLEEP)
board_mem_sleep_setup(void)1087d0e97a2Stang yuantian void board_mem_sleep_setup(void)
1097d0e97a2Stang yuantian {
1107d0e97a2Stang yuantian 	void __iomem *qixis_base = (void *)QIXIS_BASE;
1117d0e97a2Stang yuantian 
1127d0e97a2Stang yuantian 	/* does not provide HW signals for power management */
1137d0e97a2Stang yuantian 	clrbits_8(qixis_base + 0x21, 0x2);
1147d0e97a2Stang yuantian 	/* Disable MCKE isolation */
1157d0e97a2Stang yuantian 	gpio_set_value(2, 0);
1167d0e97a2Stang yuantian 	udelay(1);
1177d0e97a2Stang yuantian }
1187d0e97a2Stang yuantian #endif
1197d0e97a2Stang yuantian 
dram_init(void)120*f1683aa7SSimon Glass int dram_init(void)
1217d436078SPrabhakar Kushwaha {
1227d436078SPrabhakar Kushwaha 	phys_size_t dram_size;
1237d436078SPrabhakar Kushwaha 
1247d436078SPrabhakar Kushwaha 	puts("Initializing....using SPD\n");
1257d436078SPrabhakar Kushwaha 
1267d436078SPrabhakar Kushwaha 	dram_size = fsl_ddr_sdram();
1277d436078SPrabhakar Kushwaha 
1287d436078SPrabhakar Kushwaha 	dram_size = setup_ddr_tlbs(dram_size / 0x100000);
1297d436078SPrabhakar Kushwaha 	dram_size *= 0x100000;
1307d436078SPrabhakar Kushwaha 
1317d436078SPrabhakar Kushwaha 	puts("    DDR: ");
1327d0e97a2Stang yuantian 
1337d0e97a2Stang yuantian #if defined(CONFIG_DEEP_SLEEP) && !defined(CONFIG_SPL_BUILD)
1347d0e97a2Stang yuantian 	fsl_dp_resume();
1357d0e97a2Stang yuantian #endif
1367d0e97a2Stang yuantian 
137088454cdSSimon Glass 	gd->ram_size = dram_size;
138088454cdSSimon Glass 
139088454cdSSimon Glass 	return 0;
1407d436078SPrabhakar Kushwaha }
141