]>
Commit | Line | Data |
---|---|---|
cae377b5 VH |
1 | /* |
2 | * Functions related to OMAP3 SDRC. | |
3 | * | |
4 | * This file has been created after exctracting and consolidating | |
5 | * the SDRC related content from mem.c and board.c, also created | |
6 | * generic init function (mem_init). | |
7 | * | |
8 | * Copyright (C) 2004-2010 | |
9 | * Texas Instruments Incorporated - http://www.ti.com/ | |
10 | * | |
b88e4256 SS |
11 | * Copyright (C) 2011 |
12 | * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.de> | |
13 | * | |
cae377b5 VH |
14 | * Author : |
15 | * Vaibhav Hiremath <hvaibhav@ti.com> | |
16 | * | |
17 | * Original implementation by (mem.c, board.c) : | |
18 | * Sunil Kumar <sunilsaini05@gmail.com> | |
19 | * Shashi Ranjan <shashiranjanmca05@gmail.com> | |
20 | * Manikandan Pillai <mani.pillai@ti.com> | |
21 | * | |
22 | * This program is free software; you can redistribute it and/or | |
23 | * modify it under the terms of the GNU General Public License as | |
24 | * published by the Free Software Foundation; either version 2 of | |
25 | * the License, or (at your option) any later version. | |
26 | * | |
27 | * This program is distributed in the hope that it will be useful, | |
28 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
29 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
30 | * GNU General Public License for more details. | |
31 | * | |
32 | * You should have received a copy of the GNU General Public License | |
33 | * along with this program; if not, write to the Free Software | |
34 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
35 | * MA 02111-1307 USA | |
36 | */ | |
37 | ||
38 | #include <common.h> | |
39 | #include <asm/io.h> | |
40 | #include <asm/arch/mem.h> | |
41 | #include <asm/arch/sys_proto.h> | |
42 | ||
ee3894c6 | 43 | DECLARE_GLOBAL_DATA_PTR; |
cae377b5 VH |
44 | extern omap3_sysinfo sysinfo; |
45 | ||
46 | static struct sdrc *sdrc_base = (struct sdrc *)OMAP34XX_SDRC_BASE; | |
47 | ||
48 | /* | |
49 | * is_mem_sdr - | |
50 | * - Return 1 if mem type in use is SDR | |
51 | */ | |
52 | u32 is_mem_sdr(void) | |
53 | { | |
54 | if (readl(&sdrc_base->cs[CS0].mr) == SDRC_MR_0_SDR) | |
55 | return 1; | |
56 | return 0; | |
57 | } | |
58 | ||
59 | /* | |
60 | * make_cs1_contiguous - | |
5f862b71 TR |
61 | * - When we have CS1 populated we want to have it mapped after cs0 to allow |
62 | * command line mem=xyz use all memory with out discontinuous support | |
63 | * compiled in. We could do it in the ATAG, but there really is two banks... | |
cae377b5 VH |
64 | */ |
65 | void make_cs1_contiguous(void) | |
66 | { | |
67 | u32 size, a_add_low, a_add_high; | |
68 | ||
69 | size = get_sdr_cs_size(CS0); | |
70 | size >>= 25; /* divide by 32 MiB to find size to offset CS1 */ | |
71 | a_add_high = (size & 3) << 8; /* set up low field */ | |
72 | a_add_low = (size & 0x3C) >> 2; /* set up high field */ | |
73 | writel((a_add_high | a_add_low), &sdrc_base->cs_cfg); | |
74 | ||
75 | } | |
76 | ||
77 | ||
78 | /* | |
79 | * get_sdr_cs_size - | |
80 | * - Get size of chip select 0/1 | |
81 | */ | |
82 | u32 get_sdr_cs_size(u32 cs) | |
83 | { | |
84 | u32 size; | |
85 | ||
86 | /* get ram size field */ | |
87 | size = readl(&sdrc_base->cs[cs].mcfg) >> 8; | |
88 | size &= 0x3FF; /* remove unwanted bits */ | |
89 | size <<= 21; /* multiply by 2 MiB to find size in MB */ | |
90 | return size; | |
91 | } | |
92 | ||
93 | /* | |
94 | * get_sdr_cs_offset - | |
95 | * - Get offset of cs from cs0 start | |
96 | */ | |
97 | u32 get_sdr_cs_offset(u32 cs) | |
98 | { | |
99 | u32 offset; | |
100 | ||
101 | if (!cs) | |
102 | return 0; | |
103 | ||
104 | offset = readl(&sdrc_base->cs_cfg); | |
136c69ad | 105 | offset = (offset & 15) << 27 | (offset & 0x30) << 17; |
cae377b5 VH |
106 | |
107 | return offset; | |
108 | } | |
109 | ||
2a04e858 TR |
110 | /* |
111 | * write_sdrc_timings - | |
112 | * - Takes CS and associated timings and initalize SDRAM | |
113 | * - Test CS to make sure it's OK for use | |
114 | */ | |
115 | static void write_sdrc_timings(u32 cs, struct sdrc_actim *sdrc_actim_base, | |
116 | u32 mcfg, u32 ctrla, u32 ctrlb, u32 rfr_ctrl, u32 mr) | |
117 | { | |
118 | /* Setup timings we got from the board. */ | |
119 | writel(mcfg, &sdrc_base->cs[cs].mcfg); | |
120 | writel(ctrla, &sdrc_actim_base->ctrla); | |
121 | writel(ctrlb, &sdrc_actim_base->ctrlb); | |
122 | writel(rfr_ctrl, &sdrc_base->cs[cs].rfr_ctrl); | |
123 | writel(CMD_NOP, &sdrc_base->cs[cs].manual); | |
124 | writel(CMD_PRECHARGE, &sdrc_base->cs[cs].manual); | |
125 | writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual); | |
126 | writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual); | |
127 | writel(mr, &sdrc_base->cs[cs].mr); | |
128 | ||
129 | /* | |
130 | * Test ram in this bank | |
131 | * Disable if bad or not present | |
132 | */ | |
133 | if (!mem_ok(cs)) | |
134 | writel(0, &sdrc_base->cs[cs].mcfg); | |
135 | } | |
136 | ||
cae377b5 VH |
137 | /* |
138 | * do_sdrc_init - | |
2a04e858 TR |
139 | * - Code called once in C-Stack only context for CS0 and with early being |
140 | * true and a possible 2nd time depending on memory configuration from | |
141 | * stack+global context. | |
cae377b5 VH |
142 | */ |
143 | void do_sdrc_init(u32 cs, u32 early) | |
144 | { | |
3667cbee | 145 | struct sdrc_actim *sdrc_actim_base0, *sdrc_actim_base1; |
2a04e858 TR |
146 | u32 mcfg, ctrla, ctrlb, rfr_ctrl, mr; |
147 | ||
148 | sdrc_actim_base0 = (struct sdrc_actim *)SDRC_ACTIM_CTRL0_BASE; | |
149 | sdrc_actim_base1 = (struct sdrc_actim *)SDRC_ACTIM_CTRL1_BASE; | |
cae377b5 VH |
150 | |
151 | if (early) { | |
152 | /* reset sdrc controller */ | |
153 | writel(SOFTRESET, &sdrc_base->sysconfig); | |
154 | wait_on_value(RESETDONE, RESETDONE, &sdrc_base->status, | |
155 | 12000000); | |
156 | writel(0, &sdrc_base->sysconfig); | |
157 | ||
158 | /* setup sdrc to ball mux */ | |
159 | writel(SDRC_SHARING, &sdrc_base->sharing); | |
160 | ||
2a04e858 | 161 | /* Disable Power Down of CKE because of 1 CKE on combo part */ |
cae377b5 VH |
162 | writel(WAKEUPPROC | SRFRONRESET | PAGEPOLICY_HIGH, |
163 | &sdrc_base->power); | |
164 | ||
165 | writel(ENADLL | DLLPHASE_90, &sdrc_base->dlla_ctrl); | |
166 | sdelay(0x20000); | |
b88e4256 SS |
167 | /* As long as V_MCFG and V_RFR_CTRL is not defined for all OMAP3 boards we need |
168 | * to prevent this to be build in non-SPL build */ | |
169 | #ifdef CONFIG_SPL_BUILD | |
2a04e858 TR |
170 | /* |
171 | * If we use a SPL there is no x-loader nor config header so | |
172 | * we have to do the job ourselfs | |
173 | */ | |
174 | ||
175 | mcfg = V_MCFG; | |
176 | ctrla = V_ACTIMA_165; | |
177 | ctrlb = V_ACTIMB_165; | |
178 | rfr_ctrl = V_RFR_CTRL; | |
179 | mr = V_MR; | |
180 | ||
181 | write_sdrc_timings(CS0, sdrc_actim_base0, mcfg, ctrla, ctrlb, | |
182 | rfr_ctrl, mr); | |
183 | #endif | |
b88e4256 | 184 | |
b88e4256 | 185 | } |
b88e4256 | 186 | |
cae377b5 | 187 | /* |
2a04e858 TR |
188 | * If we aren't using SPL we have been loaded by some |
189 | * other means which may not have correctly initialized | |
190 | * both CS0 and CS1 (such as some older versions of x-loader) | |
191 | * so we may be asked now to setup CS1. | |
cae377b5 | 192 | */ |
b88e4256 | 193 | if (cs == CS1) { |
2a04e858 TR |
194 | mcfg = readl(&sdrc_base->cs[CS0].mcfg), |
195 | rfr_ctrl = readl(&sdrc_base->cs[CS0].rfr_ctrl); | |
196 | ctrla = readl(&sdrc_actim_base0->ctrla), | |
197 | ctrlb = readl(&sdrc_actim_base0->ctrlb); | |
198 | mr = readl(&sdrc_base->cs[CS0].mr); | |
199 | write_sdrc_timings(cs, sdrc_actim_base1, mcfg, ctrla, ctrlb, | |
200 | rfr_ctrl, mr); | |
cae377b5 | 201 | |
2a04e858 | 202 | } |
cae377b5 VH |
203 | } |
204 | ||
205 | /* | |
206 | * dram_init - | |
207 | * - Sets uboots idea of sdram size | |
208 | */ | |
561142af HS |
209 | int dram_init(void) |
210 | { | |
561142af HS |
211 | unsigned int size0 = 0, size1 = 0; |
212 | ||
213 | size0 = get_sdr_cs_size(CS0); | |
214 | /* | |
5f862b71 TR |
215 | * We always need to have cs_cfg point at where the second |
216 | * bank would be, if present. Failure to do so can lead to | |
217 | * strange situations where memory isn't detected and | |
218 | * configured correctly. CS0 will already have been setup | |
219 | * at this point. | |
561142af | 220 | */ |
5f862b71 TR |
221 | make_cs1_contiguous(); |
222 | do_sdrc_init(CS1, NOT_EARLY); | |
223 | size1 = get_sdr_cs_size(CS1); | |
561142af | 224 | |
561142af HS |
225 | gd->ram_size = size0 + size1; |
226 | ||
227 | return 0; | |
228 | } | |
229 | ||
230 | void dram_init_banksize (void) | |
231 | { | |
561142af HS |
232 | unsigned int size0 = 0, size1 = 0; |
233 | ||
234 | size0 = get_sdr_cs_size(CS0); | |
235 | size1 = get_sdr_cs_size(CS1); | |
236 | ||
237 | gd->bd->bi_dram[0].start = PHYS_SDRAM_1; | |
238 | gd->bd->bi_dram[0].size = size0; | |
239 | gd->bd->bi_dram[1].start = PHYS_SDRAM_1 + get_sdr_cs_offset(CS1); | |
240 | gd->bd->bi_dram[1].size = size1; | |
241 | } | |
cae377b5 VH |
242 | |
243 | /* | |
244 | * mem_init - | |
245 | * - Init the sdrc chip, | |
246 | * - Selects CS0 and CS1, | |
247 | */ | |
248 | void mem_init(void) | |
249 | { | |
250 | /* only init up first bank here */ | |
251 | do_sdrc_init(CS0, EARLY_INIT); | |
252 | } |