xref: /rk3399_rockchip-uboot/board/freescale/t4rdb/ddr.c (revision 0b2e13d9ccbe56e32dc674cf896b2fb55684368c)
1*0b2e13d9SChunhe Lan /*
2*0b2e13d9SChunhe Lan  * Copyright 2014 Freescale Semiconductor, Inc.
3*0b2e13d9SChunhe Lan  *
4*0b2e13d9SChunhe Lan  * SPDX-License-Identifier:	GPL-2.0+
5*0b2e13d9SChunhe Lan  */
6*0b2e13d9SChunhe Lan 
7*0b2e13d9SChunhe Lan #include <common.h>
8*0b2e13d9SChunhe Lan #include <i2c.h>
9*0b2e13d9SChunhe Lan #include <hwconfig.h>
10*0b2e13d9SChunhe Lan #include <asm/mmu.h>
11*0b2e13d9SChunhe Lan #include <fsl_ddr_sdram.h>
12*0b2e13d9SChunhe Lan #include <fsl_ddr_dimm_params.h>
13*0b2e13d9SChunhe Lan #include <asm/fsl_law.h>
14*0b2e13d9SChunhe Lan #include "ddr.h"
15*0b2e13d9SChunhe Lan 
16*0b2e13d9SChunhe Lan DECLARE_GLOBAL_DATA_PTR;
17*0b2e13d9SChunhe Lan 
18*0b2e13d9SChunhe Lan void fsl_ddr_board_options(memctl_options_t *popts,
19*0b2e13d9SChunhe Lan 				dimm_params_t *pdimm,
20*0b2e13d9SChunhe Lan 				unsigned int ctrl_num)
21*0b2e13d9SChunhe Lan {
22*0b2e13d9SChunhe Lan 	const struct board_specific_parameters *pbsp, *pbsp_highest = NULL;
23*0b2e13d9SChunhe Lan 	ulong ddr_freq;
24*0b2e13d9SChunhe Lan 
25*0b2e13d9SChunhe Lan 	if (ctrl_num > 2) {
26*0b2e13d9SChunhe Lan 		printf("Not supported controller number %d\n", ctrl_num);
27*0b2e13d9SChunhe Lan 		return;
28*0b2e13d9SChunhe Lan 	}
29*0b2e13d9SChunhe Lan 	if (!pdimm->n_ranks)
30*0b2e13d9SChunhe Lan 		return;
31*0b2e13d9SChunhe Lan 
32*0b2e13d9SChunhe Lan 	/*
33*0b2e13d9SChunhe Lan 	 * we use identical timing for all slots. If needed, change the code
34*0b2e13d9SChunhe Lan 	 * to  pbsp = rdimms[ctrl_num] or pbsp = udimms[ctrl_num];
35*0b2e13d9SChunhe Lan 	 */
36*0b2e13d9SChunhe Lan 	if (popts->registered_dimm_en)
37*0b2e13d9SChunhe Lan 		pbsp = rdimms[0];
38*0b2e13d9SChunhe Lan 	else
39*0b2e13d9SChunhe Lan 		pbsp = udimms[0];
40*0b2e13d9SChunhe Lan 
41*0b2e13d9SChunhe Lan 
42*0b2e13d9SChunhe Lan 	/* Get clk_adjust, cpo, write_data_delay,2T, according to the board ddr
43*0b2e13d9SChunhe Lan 	 * freqency and n_banks specified in board_specific_parameters table.
44*0b2e13d9SChunhe Lan 	 */
45*0b2e13d9SChunhe Lan 	ddr_freq = get_ddr_freq(0) / 1000000;
46*0b2e13d9SChunhe Lan 	while (pbsp->datarate_mhz_high) {
47*0b2e13d9SChunhe Lan 		if (pbsp->n_ranks == pdimm->n_ranks &&
48*0b2e13d9SChunhe Lan 		    (pdimm->rank_density >> 30) >= pbsp->rank_gb) {
49*0b2e13d9SChunhe Lan 			if (ddr_freq <= pbsp->datarate_mhz_high) {
50*0b2e13d9SChunhe Lan 				popts->clk_adjust = pbsp->clk_adjust;
51*0b2e13d9SChunhe Lan 				popts->wrlvl_start = pbsp->wrlvl_start;
52*0b2e13d9SChunhe Lan 				popts->wrlvl_ctl_2 = pbsp->wrlvl_ctl_2;
53*0b2e13d9SChunhe Lan 				popts->wrlvl_ctl_3 = pbsp->wrlvl_ctl_3;
54*0b2e13d9SChunhe Lan 				goto found;
55*0b2e13d9SChunhe Lan 			}
56*0b2e13d9SChunhe Lan 			pbsp_highest = pbsp;
57*0b2e13d9SChunhe Lan 		}
58*0b2e13d9SChunhe Lan 		pbsp++;
59*0b2e13d9SChunhe Lan 	}
60*0b2e13d9SChunhe Lan 
61*0b2e13d9SChunhe Lan 	if (pbsp_highest) {
62*0b2e13d9SChunhe Lan 		printf("Error: board specific timing not found for data\n"
63*0b2e13d9SChunhe Lan 			"rate %lu MT/s\n"
64*0b2e13d9SChunhe Lan 			"Trying to use the highest speed (%u) parameters\n",
65*0b2e13d9SChunhe Lan 			ddr_freq, pbsp_highest->datarate_mhz_high);
66*0b2e13d9SChunhe Lan 		popts->clk_adjust = pbsp_highest->clk_adjust;
67*0b2e13d9SChunhe Lan 		popts->wrlvl_start = pbsp_highest->wrlvl_start;
68*0b2e13d9SChunhe Lan 		popts->wrlvl_ctl_2 = pbsp->wrlvl_ctl_2;
69*0b2e13d9SChunhe Lan 		popts->wrlvl_ctl_3 = pbsp->wrlvl_ctl_3;
70*0b2e13d9SChunhe Lan 	} else {
71*0b2e13d9SChunhe Lan 		panic("DIMM is not supported by this board");
72*0b2e13d9SChunhe Lan 	}
73*0b2e13d9SChunhe Lan found:
74*0b2e13d9SChunhe Lan 	debug("Found timing match: n_ranks %d, data rate %d, rank_gb %d\n"
75*0b2e13d9SChunhe Lan 		"\tclk_adjust %d, wrlvl_start %d, wrlvl_ctrl_2 0x%x,\n"
76*0b2e13d9SChunhe Lan 		"wrlvl_ctrl_3 0x%x\n",
77*0b2e13d9SChunhe Lan 		pbsp->n_ranks, pbsp->datarate_mhz_high, pbsp->rank_gb,
78*0b2e13d9SChunhe Lan 		pbsp->clk_adjust, pbsp->wrlvl_start, pbsp->wrlvl_ctl_2,
79*0b2e13d9SChunhe Lan 		pbsp->wrlvl_ctl_3);
80*0b2e13d9SChunhe Lan 
81*0b2e13d9SChunhe Lan 	/*
82*0b2e13d9SChunhe Lan 	 * Factors to consider for half-strength driver enable:
83*0b2e13d9SChunhe Lan 	 *	- number of DIMMs installed
84*0b2e13d9SChunhe Lan 	 */
85*0b2e13d9SChunhe Lan 	popts->half_strength_driver_enable = 0;
86*0b2e13d9SChunhe Lan 	/*
87*0b2e13d9SChunhe Lan 	 * Write leveling override
88*0b2e13d9SChunhe Lan 	 */
89*0b2e13d9SChunhe Lan 	popts->wrlvl_override = 1;
90*0b2e13d9SChunhe Lan 	popts->wrlvl_sample = 0xf;
91*0b2e13d9SChunhe Lan 
92*0b2e13d9SChunhe Lan 	/*
93*0b2e13d9SChunhe Lan 	 * Rtt and Rtt_WR override
94*0b2e13d9SChunhe Lan 	 */
95*0b2e13d9SChunhe Lan 	popts->rtt_override = 0;
96*0b2e13d9SChunhe Lan 
97*0b2e13d9SChunhe Lan 	/* Enable ZQ calibration */
98*0b2e13d9SChunhe Lan 	popts->zq_en = 1;
99*0b2e13d9SChunhe Lan 
100*0b2e13d9SChunhe Lan 	/* DHC_EN =1, ODT = 75 Ohm */
101*0b2e13d9SChunhe Lan 	popts->ddr_cdr1 = DDR_CDR1_DHC_EN | DDR_CDR1_ODT(DDR_CDR_ODT_75ohm);
102*0b2e13d9SChunhe Lan 	popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_75ohm);
103*0b2e13d9SChunhe Lan }
104*0b2e13d9SChunhe Lan 
105*0b2e13d9SChunhe Lan phys_size_t initdram(int board_type)
106*0b2e13d9SChunhe Lan {
107*0b2e13d9SChunhe Lan 	phys_size_t dram_size;
108*0b2e13d9SChunhe Lan 
109*0b2e13d9SChunhe Lan 	puts("Initializing....using SPD\n");
110*0b2e13d9SChunhe Lan 
111*0b2e13d9SChunhe Lan 	dram_size = fsl_ddr_sdram();
112*0b2e13d9SChunhe Lan 
113*0b2e13d9SChunhe Lan 	dram_size = setup_ddr_tlbs(dram_size / 0x100000);
114*0b2e13d9SChunhe Lan 	dram_size *= 0x100000;
115*0b2e13d9SChunhe Lan 
116*0b2e13d9SChunhe Lan 	puts("    DDR: ");
117*0b2e13d9SChunhe Lan 	return dram_size;
118*0b2e13d9SChunhe Lan }
119