]>
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 | ||
110 | /* | |
111 | * do_sdrc_init - | |
112 | * - Initialize the SDRAM for use. | |
cae377b5 VH |
113 | * - code called once in C-Stack only context for CS0 and a possible 2nd |
114 | * time depending on memory configuration from stack+global context | |
115 | */ | |
116 | void do_sdrc_init(u32 cs, u32 early) | |
117 | { | |
3667cbee | 118 | struct sdrc_actim *sdrc_actim_base0, *sdrc_actim_base1; |
cae377b5 VH |
119 | |
120 | if (early) { | |
121 | /* reset sdrc controller */ | |
122 | writel(SOFTRESET, &sdrc_base->sysconfig); | |
123 | wait_on_value(RESETDONE, RESETDONE, &sdrc_base->status, | |
124 | 12000000); | |
125 | writel(0, &sdrc_base->sysconfig); | |
126 | ||
127 | /* setup sdrc to ball mux */ | |
128 | writel(SDRC_SHARING, &sdrc_base->sharing); | |
129 | ||
130 | /* Disable Power Down of CKE cuz of 1 CKE on combo part */ | |
131 | writel(WAKEUPPROC | SRFRONRESET | PAGEPOLICY_HIGH, | |
132 | &sdrc_base->power); | |
133 | ||
134 | writel(ENADLL | DLLPHASE_90, &sdrc_base->dlla_ctrl); | |
135 | sdelay(0x20000); | |
136 | } | |
137 | ||
b88e4256 SS |
138 | /* As long as V_MCFG and V_RFR_CTRL is not defined for all OMAP3 boards we need |
139 | * to prevent this to be build in non-SPL build */ | |
140 | #ifdef CONFIG_SPL_BUILD | |
141 | /* If we use a SPL there is no x-loader nor config header so we have | |
142 | * to do the job ourselfs | |
143 | */ | |
144 | if (cs == CS0) { | |
145 | sdrc_actim_base0 = (struct sdrc_actim *)SDRC_ACTIM_CTRL0_BASE; | |
146 | ||
147 | /* General SDRC config */ | |
148 | writel(V_MCFG, &sdrc_base->cs[cs].mcfg); | |
149 | writel(V_RFR_CTRL, &sdrc_base->cs[cs].rfr_ctrl); | |
150 | ||
151 | /* AC timings */ | |
152 | writel(V_ACTIMA_165, &sdrc_actim_base0->ctrla); | |
153 | writel(V_ACTIMB_165, &sdrc_actim_base0->ctrlb); | |
154 | ||
155 | /* Initialize */ | |
156 | writel(CMD_NOP, &sdrc_base->cs[cs].manual); | |
157 | writel(CMD_PRECHARGE, &sdrc_base->cs[cs].manual); | |
158 | writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual); | |
159 | writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual); | |
160 | ||
161 | writel(V_MR, &sdrc_base->cs[cs].mr); | |
162 | } | |
163 | #endif | |
164 | ||
cae377b5 | 165 | /* |
3667cbee SS |
166 | * SDRC timings are set up by x-load or config header |
167 | * We don't need to redo them here. | |
168 | * Older x-loads configure only CS0 | |
169 | * configure CS1 to handle this ommission | |
cae377b5 | 170 | */ |
b88e4256 | 171 | if (cs == CS1) { |
3667cbee SS |
172 | sdrc_actim_base0 = (struct sdrc_actim *)SDRC_ACTIM_CTRL0_BASE; |
173 | sdrc_actim_base1 = (struct sdrc_actim *)SDRC_ACTIM_CTRL1_BASE; | |
174 | writel(readl(&sdrc_base->cs[CS0].mcfg), | |
175 | &sdrc_base->cs[CS1].mcfg); | |
176 | writel(readl(&sdrc_base->cs[CS0].rfr_ctrl), | |
177 | &sdrc_base->cs[CS1].rfr_ctrl); | |
178 | writel(readl(&sdrc_actim_base0->ctrla), | |
179 | &sdrc_actim_base1->ctrla); | |
180 | writel(readl(&sdrc_actim_base0->ctrlb), | |
181 | &sdrc_actim_base1->ctrlb); | |
0fc43a41 HS |
182 | |
183 | writel(CMD_NOP, &sdrc_base->cs[cs].manual); | |
184 | writel(CMD_PRECHARGE, &sdrc_base->cs[cs].manual); | |
185 | writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual); | |
186 | writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual); | |
187 | writel(readl(&sdrc_base->cs[CS0].mr), | |
188 | &sdrc_base->cs[CS1].mr); | |
3667cbee | 189 | } |
cae377b5 | 190 | |
3667cbee SS |
191 | /* |
192 | * Test ram in this bank | |
193 | * Disable if bad or not present | |
194 | */ | |
cae377b5 VH |
195 | if (!mem_ok(cs)) |
196 | writel(0, &sdrc_base->cs[cs].mcfg); | |
197 | } | |
198 | ||
199 | /* | |
200 | * dram_init - | |
201 | * - Sets uboots idea of sdram size | |
202 | */ | |
561142af HS |
203 | int dram_init(void) |
204 | { | |
561142af HS |
205 | unsigned int size0 = 0, size1 = 0; |
206 | ||
207 | size0 = get_sdr_cs_size(CS0); | |
208 | /* | |
5f862b71 TR |
209 | * We always need to have cs_cfg point at where the second |
210 | * bank would be, if present. Failure to do so can lead to | |
211 | * strange situations where memory isn't detected and | |
212 | * configured correctly. CS0 will already have been setup | |
213 | * at this point. | |
561142af | 214 | */ |
5f862b71 TR |
215 | make_cs1_contiguous(); |
216 | do_sdrc_init(CS1, NOT_EARLY); | |
217 | size1 = get_sdr_cs_size(CS1); | |
561142af | 218 | |
561142af HS |
219 | gd->ram_size = size0 + size1; |
220 | ||
221 | return 0; | |
222 | } | |
223 | ||
224 | void dram_init_banksize (void) | |
225 | { | |
561142af HS |
226 | unsigned int size0 = 0, size1 = 0; |
227 | ||
228 | size0 = get_sdr_cs_size(CS0); | |
229 | size1 = get_sdr_cs_size(CS1); | |
230 | ||
231 | gd->bd->bi_dram[0].start = PHYS_SDRAM_1; | |
232 | gd->bd->bi_dram[0].size = size0; | |
233 | gd->bd->bi_dram[1].start = PHYS_SDRAM_1 + get_sdr_cs_offset(CS1); | |
234 | gd->bd->bi_dram[1].size = size1; | |
235 | } | |
cae377b5 VH |
236 | |
237 | /* | |
238 | * mem_init - | |
239 | * - Init the sdrc chip, | |
240 | * - Selects CS0 and CS1, | |
241 | */ | |
242 | void mem_init(void) | |
243 | { | |
244 | /* only init up first bank here */ | |
245 | do_sdrc_init(CS0, EARLY_INIT); | |
246 | } |