]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/xes/xpedite517x/ddr.c
53cb156fd558a806de47686ad12254d376313a5d
[karo-tx-uboot.git] / board / xes / xpedite517x / ddr.c
1 /*
2  * Copyright 2009 Extreme Engineering Solutions, Inc.
3  * Copyright 2007-2008 Freescale Semiconductor, Inc.
4  *
5  * SPDX-License-Identifier:     GPL-2.0+ 
6  */
7
8 #include <common.h>
9 #include <i2c.h>
10 #include <asm/fsl_ddr_sdram.h>
11 #include <asm/fsl_ddr_dimm_params.h>
12
13 void get_spd(ddr2_spd_eeprom_t *spd, u8 i2c_address)
14 {
15         i2c_read(i2c_address, SPD_EEPROM_OFFSET, 2, (uchar *)spd,
16                 sizeof(ddr2_spd_eeprom_t));
17 }
18
19 /*
20  * There are four board-specific SDRAM timing parameters which must be
21  * calculated based on the particular PCB artwork.  These are:
22  *   1.) CPO (Read Capture Delay)
23  *           - TIMING_CFG_2 register
24  *           Source: Calculation based on board trace lengths and
25  *                   chip-specific internal delays.
26  *   2.) WR_DATA_DELAY (Write Command to Data Strobe Delay)
27  *           - TIMING_CFG_2 register
28  *           Source: Calculation based on board trace lengths.
29  *                   Unless clock and DQ lanes are very different
30  *                   lengths (>2"), this should be set to the nominal value
31  *                   of 1/2 clock delay.
32  *   3.) CLK_ADJUST (Clock and Addr/Cmd alignment control)
33  *           - DDR_SDRAM_CLK_CNTL register
34  *           Source: Signal Integrity Simulations
35  *   4.) 2T Timing on Addr/Ctl
36  *           - TIMING_CFG_2 register
37  *           Source: Signal Integrity Simulations
38  *           Usually only needed with heavy load/very high speed (>DDR2-800)
39  *
40  *     PCB routing on the XPedite5170 is nearly identical to the XPedite5370
41  *     so we use the XPedite5370 settings as a basis for the XPedite5170.
42  */
43
44 typedef struct board_memctl_options {
45         uint16_t datarate_mhz_low;
46         uint16_t datarate_mhz_high;
47         uint8_t clk_adjust;
48         uint8_t cpo_override;
49         uint8_t write_data_delay;
50 } board_memctl_options_t;
51
52 static struct board_memctl_options bopts_ctrl[][2] = {
53         {
54                 /* Controller 0 */
55                 {
56                         /* DDR2 600/667 */
57                         .datarate_mhz_low       = 500,
58                         .datarate_mhz_high      = 750,
59                         .clk_adjust             = 5,
60                         .cpo_override           = 8,
61                         .write_data_delay       = 2,
62                 },
63                 {
64                         /* DDR2 800 */
65                         .datarate_mhz_low       = 750,
66                         .datarate_mhz_high      = 850,
67                         .clk_adjust             = 5,
68                         .cpo_override           = 9,
69                         .write_data_delay       = 2,
70                 },
71         },
72         {
73                 /* Controller 1 */
74                 {
75                         /* DDR2 600/667 */
76                         .datarate_mhz_low       = 500,
77                         .datarate_mhz_high      = 750,
78                         .clk_adjust             = 5,
79                         .cpo_override           = 7,
80                         .write_data_delay       = 2,
81                 },
82                 {
83                         /* DDR2 800 */
84                         .datarate_mhz_low       = 750,
85                         .datarate_mhz_high      = 850,
86                         .clk_adjust             = 5,
87                         .cpo_override           = 8,
88                         .write_data_delay       = 2,
89                 },
90         },
91 };
92
93 void fsl_ddr_board_options(memctl_options_t *popts,
94                         dimm_params_t *pdimm,
95                         unsigned int ctrl_num)
96 {
97         struct board_memctl_options *bopts = bopts_ctrl[ctrl_num];
98         sys_info_t sysinfo;
99         int i;
100         unsigned int datarate;
101
102         get_sys_info(&sysinfo);
103         datarate = get_ddr_freq(0) / 1000000;
104
105         for (i = 0; i < ARRAY_SIZE(bopts_ctrl[ctrl_num]); i++) {
106                 if ((bopts[i].datarate_mhz_low <= datarate) &&
107                     (bopts[i].datarate_mhz_high >= datarate)) {
108                         debug("controller %d:\n", ctrl_num);
109                         debug(" clk_adjust = %d\n", bopts[i].clk_adjust);
110                         debug(" cpo = %d\n", bopts[i].cpo_override);
111                         debug(" write_data_delay = %d\n",
112                                 bopts[i].write_data_delay);
113                         popts->clk_adjust = bopts[i].clk_adjust;
114                         popts->cpo_override = bopts[i].cpo_override;
115                         popts->write_data_delay = bopts[i].write_data_delay;
116                 }
117         }
118
119         /*
120          * Factors to consider for half-strength driver enable:
121          *      - number of DIMMs installed
122          */
123         popts->half_strength_driver_enable = 0;
124 }