]>
Commit | Line | Data |
---|---|---|
48c6f328 SL |
1 | /* |
2 | * Copyright 2014 Freescale Semiconductor, Inc. | |
3 | * | |
4 | * SPDX-License-Identifier: GPL-2.0+ | |
5 | */ | |
6 | ||
7 | #include <common.h> | |
8 | #include <i2c.h> | |
9 | #include <hwconfig.h> | |
10 | #include <asm/mmu.h> | |
11 | #include <fsl_ddr_sdram.h> | |
12 | #include <fsl_ddr_dimm_params.h> | |
13 | #include <asm/fsl_law.h> | |
f49b8c1b | 14 | #include <asm/mpc85xx_gpio.h> |
48c6f328 SL |
15 | |
16 | DECLARE_GLOBAL_DATA_PTR; | |
17 | ||
18 | struct board_specific_parameters { | |
19 | u32 n_ranks; | |
20 | u32 datarate_mhz_high; | |
21 | u32 rank_gb; | |
22 | u32 clk_adjust; | |
23 | u32 wrlvl_start; | |
24 | u32 wrlvl_ctl_2; | |
25 | u32 wrlvl_ctl_3; | |
26 | }; | |
27 | ||
28 | /* | |
29 | * datarate_mhz_high values need to be in ascending order | |
30 | */ | |
31 | static const struct board_specific_parameters udimm0[] = { | |
32 | /* | |
33 | * memory controller 0 | |
34 | * num| hi| rank| clk| wrlvl | wrlvl | wrlvl | | |
35 | * ranks| mhz| GB |adjst| start | ctl2 | ctl3 | | |
36 | */ | |
e04f9d0c SL |
37 | {2, 833, 0, 8, 6, 0x06060607, 0x08080807,}, |
38 | {2, 1350, 0, 8, 7, 0x0708080A, 0x0A0B0C09,}, | |
39 | {2, 1666, 0, 8, 7, 0x0808090B, 0x0C0D0E0A,}, | |
40 | {1, 833, 0, 8, 6, 0x06060607, 0x08080807,}, | |
41 | {1, 1350, 0, 8, 7, 0x0708080A, 0x0A0B0C09,}, | |
42 | {1, 1666, 0, 8, 7, 0x0808090B, 0x0C0D0E0A,}, | |
48c6f328 SL |
43 | {} |
44 | }; | |
45 | ||
46 | static const struct board_specific_parameters *udimms[] = { | |
47 | udimm0, | |
48 | }; | |
49 | ||
50 | void fsl_ddr_board_options(memctl_options_t *popts, | |
51 | dimm_params_t *pdimm, | |
52 | unsigned int ctrl_num) | |
53 | { | |
54 | const struct board_specific_parameters *pbsp, *pbsp_highest = NULL; | |
55 | ulong ddr_freq; | |
56 | struct cpu_type *cpu = gd->arch.cpu; | |
57 | ||
58 | if (ctrl_num > 1) { | |
59 | printf("Not supported controller number %d\n", ctrl_num); | |
60 | return; | |
61 | } | |
62 | if (!pdimm->n_ranks) | |
63 | return; | |
64 | ||
65 | pbsp = udimms[0]; | |
66 | ||
67 | /* Get clk_adjust according to the board ddr freqency and n_banks | |
68 | * specified in board_specific_parameters table. | |
69 | */ | |
70 | ddr_freq = get_ddr_freq(0) / 1000000; | |
71 | while (pbsp->datarate_mhz_high) { | |
72 | if (pbsp->n_ranks == pdimm->n_ranks && | |
73 | (pdimm->rank_density >> 30) >= pbsp->rank_gb) { | |
74 | if (ddr_freq <= pbsp->datarate_mhz_high) { | |
75 | popts->clk_adjust = pbsp->clk_adjust; | |
76 | popts->wrlvl_start = pbsp->wrlvl_start; | |
77 | popts->wrlvl_ctl_2 = pbsp->wrlvl_ctl_2; | |
78 | popts->wrlvl_ctl_3 = pbsp->wrlvl_ctl_3; | |
79 | goto found; | |
80 | } | |
81 | pbsp_highest = pbsp; | |
82 | } | |
83 | pbsp++; | |
84 | } | |
85 | ||
86 | if (pbsp_highest) { | |
87 | printf("Error: board specific timing not found\n"); | |
88 | printf("for data rate %lu MT/s\n", ddr_freq); | |
89 | printf("Trying to use the highest speed (%u) parameters\n", | |
90 | pbsp_highest->datarate_mhz_high); | |
91 | popts->clk_adjust = pbsp_highest->clk_adjust; | |
92 | popts->wrlvl_start = pbsp_highest->wrlvl_start; | |
93 | popts->wrlvl_ctl_2 = pbsp->wrlvl_ctl_2; | |
94 | popts->wrlvl_ctl_3 = pbsp->wrlvl_ctl_3; | |
95 | } else { | |
96 | panic("DIMM is not supported by this board"); | |
97 | } | |
98 | found: | |
99 | debug("Found timing match: n_ranks %d, data rate %d, rank_gb %d\n", | |
100 | pbsp->n_ranks, pbsp->datarate_mhz_high, pbsp->rank_gb); | |
101 | debug("\tclk_adjust %d, wrlvl_start %d, wrlvl_ctrl_2 0x%x, ", | |
102 | pbsp->clk_adjust, pbsp->wrlvl_start, pbsp->wrlvl_ctl_2); | |
103 | debug("wrlvl_ctrl_3 0x%x\n", pbsp->wrlvl_ctl_3); | |
104 | ||
105 | /* | |
106 | * Factors to consider for half-strength driver enable: | |
107 | * - number of DIMMs installed | |
108 | */ | |
109 | popts->half_strength_driver_enable = 0; | |
110 | /* | |
111 | * Write leveling override | |
112 | */ | |
113 | popts->wrlvl_override = 1; | |
114 | popts->wrlvl_sample = 0xf; | |
115 | ||
116 | /* | |
117 | * rtt and rtt_wr override | |
118 | */ | |
119 | popts->rtt_override = 0; | |
120 | ||
121 | /* Enable ZQ calibration */ | |
122 | popts->zq_en = 1; | |
123 | ||
124 | /* DHC_EN =1, ODT = 75 Ohm */ | |
125 | popts->ddr_cdr1 = DDR_CDR1_DHC_EN | DDR_CDR1_ODT(DDR_CDR_ODT_OFF); | |
126 | popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_OFF); | |
127 | ||
128 | /* T1023 supports max DDR bus 32bit width, T1024 supports DDR 64bit, | |
129 | * force DDR bus width to 32bit for T1023 | |
130 | */ | |
131 | if (cpu->soc_ver == SVR_T1023) | |
132 | popts->data_bus_width = DDR_DATA_BUS_WIDTH_32; | |
133 | ||
134 | #ifdef CONFIG_FORCE_DDR_DATA_BUS_WIDTH_32 | |
135 | /* for DDR bus 32bit test on T1024 */ | |
136 | popts->data_bus_width = DDR_DATA_BUS_WIDTH_32; | |
137 | #endif | |
e8a7f1c3 | 138 | |
9082405d | 139 | #ifdef CONFIG_TARGET_T1023RDB |
e8a7f1c3 SL |
140 | popts->wrlvl_ctl_2 = 0x07070606; |
141 | popts->half_strength_driver_enable = 1; | |
90101386 | 142 | popts->cpo_sample = 0x43; |
960286b6 | 143 | #elif defined(CONFIG_TARGET_T1024RDB) |
90101386 SL |
144 | /* optimize cpo for erratum A-009942 */ |
145 | popts->cpo_sample = 0x52; | |
e8a7f1c3 | 146 | #endif |
48c6f328 SL |
147 | } |
148 | ||
e8a7f1c3 SL |
149 | #ifdef CONFIG_SYS_DDR_RAW_TIMING |
150 | /* 2GB discrete DDR4 MT40A512M8HX on T1023RDB */ | |
151 | dimm_params_t ddr_raw_timing = { | |
152 | .n_ranks = 1, | |
153 | .rank_density = 0x80000000, | |
154 | .capacity = 0x80000000, | |
155 | .primary_sdram_width = 32, | |
156 | .ec_sdram_width = 8, | |
157 | .registered_dimm = 0, | |
158 | .mirrored_dimm = 0, | |
159 | .n_row_addr = 15, | |
160 | .n_col_addr = 10, | |
161 | .bank_addr_bits = 2, | |
162 | .bank_group_bits = 2, | |
163 | .edc_config = 0, | |
164 | .burst_lengths_bitmask = 0x0c, | |
165 | .tckmin_x_ps = 938, | |
166 | .tckmax_ps = 1500, | |
167 | .caslat_x = 0x000DFA00, | |
168 | .taa_ps = 13500, | |
169 | .trcd_ps = 13500, | |
170 | .trp_ps = 13500, | |
171 | .tras_ps = 33000, | |
172 | .trc_ps = 46500, | |
173 | .trfc1_ps = 260000, | |
174 | .trfc2_ps = 160000, | |
175 | .trfc4_ps = 110000, | |
176 | .tfaw_ps = 25000, | |
177 | .trrds_ps = 3700, | |
178 | .trrdl_ps = 5300, | |
179 | .tccdl_ps = 5355, | |
180 | .refresh_rate_ps = 7800000, | |
181 | .dq_mapping[0] = 0x0, | |
182 | .dq_mapping[1] = 0x0, | |
183 | .dq_mapping[2] = 0x0, | |
184 | .dq_mapping[3] = 0x0, | |
185 | .dq_mapping[4] = 0x0, | |
186 | .dq_mapping[5] = 0x0, | |
187 | .dq_mapping[6] = 0x0, | |
188 | .dq_mapping[7] = 0x0, | |
189 | .dq_mapping[8] = 0x0, | |
190 | .dq_mapping[9] = 0x0, | |
191 | .dq_mapping[10] = 0x0, | |
192 | .dq_mapping[11] = 0x0, | |
193 | .dq_mapping[12] = 0x0, | |
194 | .dq_mapping[13] = 0x0, | |
195 | .dq_mapping[14] = 0x0, | |
196 | .dq_mapping[15] = 0x0, | |
197 | .dq_mapping[16] = 0x0, | |
198 | .dq_mapping[17] = 0x0, | |
199 | .dq_mapping_ors = 1, | |
200 | }; | |
201 | ||
202 | int fsl_ddr_get_dimm_params(dimm_params_t *pdimm, | |
203 | unsigned int controller_number, | |
204 | unsigned int dimm_number) | |
205 | { | |
206 | const char dimm_model[] = "Fixed DDR4 on board"; | |
207 | ||
208 | if (((controller_number == 0) && (dimm_number == 0)) || | |
209 | ((controller_number == 1) && (dimm_number == 0))) { | |
210 | memcpy(pdimm, &ddr_raw_timing, sizeof(dimm_params_t)); | |
211 | memset(pdimm->mpart, 0, sizeof(pdimm->mpart)); | |
212 | memcpy(pdimm->mpart, dimm_model, sizeof(dimm_model) - 1); | |
213 | } | |
214 | ||
215 | return 0; | |
216 | } | |
217 | #endif | |
218 | ||
f49b8c1b | 219 | #if defined(CONFIG_DEEP_SLEEP) |
220 | void board_mem_sleep_setup(void) | |
221 | { | |
222 | void __iomem *cpld_base = (void *)CONFIG_SYS_CPLD_BASE; | |
223 | ||
224 | /* does not provide HW signals for power management */ | |
225 | clrbits_8(cpld_base + 0x17, 0x40); | |
226 | /* Disable MCKE isolation */ | |
227 | gpio_set_value(2, 0); | |
228 | udelay(1); | |
229 | } | |
230 | #endif | |
231 | ||
48c6f328 SL |
232 | phys_size_t initdram(int board_type) |
233 | { | |
234 | phys_size_t dram_size; | |
235 | ||
236 | #if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_RAMBOOT_PBL) | |
e8a7f1c3 | 237 | #ifndef CONFIG_SYS_DDR_RAW_TIMING |
48c6f328 | 238 | puts("Initializing....using SPD\n"); |
e8a7f1c3 | 239 | #endif |
48c6f328 | 240 | dram_size = fsl_ddr_sdram(); |
48c6f328 SL |
241 | #else |
242 | /* DDR has been initialised by first stage boot loader */ | |
243 | dram_size = fsl_ddr_sdram_size(); | |
244 | #endif | |
53499282 SL |
245 | dram_size = setup_ddr_tlbs(dram_size / 0x100000); |
246 | dram_size *= 0x100000; | |
f49b8c1b | 247 | |
248 | #if defined(CONFIG_DEEP_SLEEP) && !defined(CONFIG_SPL_BUILD) | |
249 | fsl_dp_resume(); | |
250 | #endif | |
251 | ||
48c6f328 SL |
252 | return dram_size; |
253 | } |