xref: /openbmc/u-boot/board/freescale/p1022ds/ddr.c (revision 5df4b0ad0dff3cef1bd6660bcc8cba028c80adcb)
1 /*
2  * Copyright 2010 Freescale Semiconductor, Inc.
3  * Authors: Srikanth Srinivasan <srikanth.srinivasan@freescale.com>
4  *          Timur Tabi <timur@freescale.com>
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the Free
8  * Software Foundation; either version 2 of the License, or (at your option)
9  * any later version.
10  */
11 
12 #include <common.h>
13 #include <i2c.h>
14 
15 #include <asm/fsl_ddr_sdram.h>
16 #include <asm/fsl_ddr_dimm_params.h>
17 
18 void fsl_ddr_get_spd(ddr3_spd_eeprom_t *ctrl_dimms_spd, unsigned int ctrl_num)
19 {
20 	int ret;
21 
22 	/*
23 	 * The P1022 has only one DDR controller, and the board has only one
24 	 * DIMM slot.
25 	 */
26 	ret = i2c_read(SPD_EEPROM_ADDRESS1, 0, 1, (u8 *)ctrl_dimms_spd,
27 		       sizeof(ddr3_spd_eeprom_t));
28 	if (ret) {
29 		debug("DDR: failed to read SPD from address %u\n",
30 		      SPD_EEPROM_ADDRESS1);
31 		memset(ctrl_dimms_spd, 0, sizeof(ddr3_spd_eeprom_t));
32 	}
33 }
34 
35 typedef struct {
36 	u32 datarate_mhz_low;
37 	u32 datarate_mhz_high;
38 	u32 n_ranks;
39 	u32 clk_adjust;		/* Range: 0-8 */
40 	u32 cpo;		/* Range: 2-31 */
41 	u32 write_data_delay;	/* Range: 0-6 */
42 	u32 force_2T;
43 } board_specific_parameters_t;
44 
45 static const board_specific_parameters_t bsp[] = {
46 /*
47  *        lo|  hi|  num|  clk| cpo|wrdata|2T
48  *       mhz| mhz|ranks|adjst|    | delay|
49  */
50 	{  0, 333,    1,    5,  31,     3, 0},
51 	{334, 400,    1,    5,  31,     3, 0},
52 	{401, 549,    1,    5,  31,     3, 0},
53 	{550, 680,    1,    5,  31,     5, 0},
54 	{681, 850,    1,    5,  31,     5, 0},
55 	{  0, 333,    2,    5,  31,     3, 0},
56 	{334, 400,    2,    5,  31,     3, 0},
57 	{401, 549,    2,    5,  31,     3, 0},
58 	{550, 680,    2,    5,  31,     5, 0},
59 	{681, 850,    2,    5,  31,     5, 0},
60 };
61 
62 void fsl_ddr_board_options(memctl_options_t *popts, dimm_params_t *pdimm,
63 			   unsigned int ctrl_num)
64 {
65 	unsigned long ddr_freq;
66 	unsigned int i;
67 
68 	/* set odt_rd_cfg and odt_wr_cfg. */
69 	for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
70 		popts->cs_local_opts[i].odt_rd_cfg = 0;
71 		popts->cs_local_opts[i].odt_wr_cfg = 1;
72 	}
73 
74 	/*
75 	 * Get clk_adjust, cpo, write_data_delay,2T, according to the board ddr
76 	 * freqency and n_banks specified in board_specific_parameters table.
77 	 */
78 	ddr_freq = get_ddr_freq(0) / 1000000;
79 	for (i = 0; i < ARRAY_SIZE(bsp); i++) {
80 		if (ddr_freq >= bsp[i].datarate_mhz_low &&
81 		    ddr_freq <= bsp[i].datarate_mhz_high &&
82 		    pdimm->n_ranks == bsp[i].n_ranks) {
83 			popts->clk_adjust = bsp[i].clk_adjust;
84 			popts->cpo_override = bsp[i].cpo;
85 			popts->write_data_delay = bsp[i].write_data_delay;
86 			popts->twoT_en = bsp[i].force_2T;
87 			break;
88 		}
89 	}
90 
91 	popts->half_strength_driver_enable = 1;
92 
93 	/* Per AN4039, enable ZQ calibration. */
94 	popts->zq_en = 1;
95 
96 	/*
97 	 * For wake-up on ARP, we need auto self refresh enabled
98 	 */
99 	popts->auto_self_refresh_en = 1;
100 	popts->sr_it = 0xb;
101 }
102