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