]>
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 | * | |
11 | * Author : | |
12 | * Vaibhav Hiremath <hvaibhav@ti.com> | |
13 | * | |
14 | * Original implementation by (mem.c, board.c) : | |
15 | * Sunil Kumar <sunilsaini05@gmail.com> | |
16 | * Shashi Ranjan <shashiranjanmca05@gmail.com> | |
17 | * Manikandan Pillai <mani.pillai@ti.com> | |
18 | * | |
19 | * This program is free software; you can redistribute it and/or | |
20 | * modify it under the terms of the GNU General Public License as | |
21 | * published by the Free Software Foundation; either version 2 of | |
22 | * the License, or (at your option) any later version. | |
23 | * | |
24 | * This program is distributed in the hope that it will be useful, | |
25 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
26 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
27 | * GNU General Public License for more details. | |
28 | * | |
29 | * You should have received a copy of the GNU General Public License | |
30 | * along with this program; if not, write to the Free Software | |
31 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
32 | * MA 02111-1307 USA | |
33 | */ | |
34 | ||
35 | #include <common.h> | |
36 | #include <asm/io.h> | |
37 | #include <asm/arch/mem.h> | |
38 | #include <asm/arch/sys_proto.h> | |
39 | ||
40 | extern omap3_sysinfo sysinfo; | |
41 | ||
42 | static struct sdrc *sdrc_base = (struct sdrc *)OMAP34XX_SDRC_BASE; | |
43 | ||
44 | /* | |
45 | * is_mem_sdr - | |
46 | * - Return 1 if mem type in use is SDR | |
47 | */ | |
48 | u32 is_mem_sdr(void) | |
49 | { | |
50 | if (readl(&sdrc_base->cs[CS0].mr) == SDRC_MR_0_SDR) | |
51 | return 1; | |
52 | return 0; | |
53 | } | |
54 | ||
55 | /* | |
56 | * make_cs1_contiguous - | |
57 | * - For es2 and above remap cs1 behind cs0 to allow command line | |
58 | * mem=xyz use all memory with out discontinuous support compiled in. | |
59 | * Could do it at the ATAG, but there really is two banks... | |
60 | * - Called as part of 2nd phase DDR init. | |
61 | */ | |
62 | void make_cs1_contiguous(void) | |
63 | { | |
64 | u32 size, a_add_low, a_add_high; | |
65 | ||
66 | size = get_sdr_cs_size(CS0); | |
67 | size >>= 25; /* divide by 32 MiB to find size to offset CS1 */ | |
68 | a_add_high = (size & 3) << 8; /* set up low field */ | |
69 | a_add_low = (size & 0x3C) >> 2; /* set up high field */ | |
70 | writel((a_add_high | a_add_low), &sdrc_base->cs_cfg); | |
71 | ||
72 | } | |
73 | ||
74 | ||
75 | /* | |
76 | * get_sdr_cs_size - | |
77 | * - Get size of chip select 0/1 | |
78 | */ | |
79 | u32 get_sdr_cs_size(u32 cs) | |
80 | { | |
81 | u32 size; | |
82 | ||
83 | /* get ram size field */ | |
84 | size = readl(&sdrc_base->cs[cs].mcfg) >> 8; | |
85 | size &= 0x3FF; /* remove unwanted bits */ | |
86 | size <<= 21; /* multiply by 2 MiB to find size in MB */ | |
87 | return size; | |
88 | } | |
89 | ||
90 | /* | |
91 | * get_sdr_cs_offset - | |
92 | * - Get offset of cs from cs0 start | |
93 | */ | |
94 | u32 get_sdr_cs_offset(u32 cs) | |
95 | { | |
96 | u32 offset; | |
97 | ||
98 | if (!cs) | |
99 | return 0; | |
100 | ||
101 | offset = readl(&sdrc_base->cs_cfg); | |
102 | offset = (offset & 15) << 27 | (offset & 0x30) >> 17; | |
103 | ||
104 | return offset; | |
105 | } | |
106 | ||
107 | /* | |
108 | * do_sdrc_init - | |
109 | * - Initialize the SDRAM for use. | |
110 | * - Sets up SDRC timings for CS0 | |
111 | * - code called once in C-Stack only context for CS0 and a possible 2nd | |
112 | * time depending on memory configuration from stack+global context | |
113 | */ | |
114 | void do_sdrc_init(u32 cs, u32 early) | |
115 | { | |
116 | struct sdrc_actim *sdrc_actim_base; | |
117 | ||
118 | if (cs) | |
119 | sdrc_actim_base = (struct sdrc_actim *)SDRC_ACTIM_CTRL1_BASE; | |
120 | else | |
121 | sdrc_actim_base = (struct sdrc_actim *)SDRC_ACTIM_CTRL0_BASE; | |
122 | ||
123 | if (early) { | |
124 | /* reset sdrc controller */ | |
125 | writel(SOFTRESET, &sdrc_base->sysconfig); | |
126 | wait_on_value(RESETDONE, RESETDONE, &sdrc_base->status, | |
127 | 12000000); | |
128 | writel(0, &sdrc_base->sysconfig); | |
129 | ||
130 | /* setup sdrc to ball mux */ | |
131 | writel(SDRC_SHARING, &sdrc_base->sharing); | |
132 | ||
133 | /* Disable Power Down of CKE cuz of 1 CKE on combo part */ | |
134 | writel(WAKEUPPROC | SRFRONRESET | PAGEPOLICY_HIGH, | |
135 | &sdrc_base->power); | |
136 | ||
137 | writel(ENADLL | DLLPHASE_90, &sdrc_base->dlla_ctrl); | |
138 | sdelay(0x20000); | |
139 | } | |
140 | ||
141 | writel(RASWIDTH_13BITS | CASWIDTH_10BITS | ADDRMUXLEGACY | | |
142 | RAMSIZE_128 | BANKALLOCATION | B32NOT16 | B32NOT16 | | |
143 | DEEPPD | DDR_SDRAM, &sdrc_base->cs[cs].mcfg); | |
144 | writel(ARCV | ARE_ARCV_1, &sdrc_base->cs[cs].rfr_ctrl); | |
145 | writel(V_ACTIMA_165, &sdrc_actim_base->ctrla); | |
146 | writel(V_ACTIMB_165, &sdrc_actim_base->ctrlb); | |
147 | ||
148 | writel(CMD_NOP, &sdrc_base->cs[cs].manual); | |
149 | writel(CMD_PRECHARGE, &sdrc_base->cs[cs].manual); | |
150 | writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual); | |
151 | writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual); | |
152 | ||
153 | /* | |
154 | * CAS latency 3, Write Burst = Read Burst, Serial Mode, | |
155 | * Burst length = 4 | |
156 | */ | |
157 | writel(CASL3 | BURSTLENGTH4, &sdrc_base->cs[cs].mr); | |
158 | ||
159 | if (!mem_ok(cs)) | |
160 | writel(0, &sdrc_base->cs[cs].mcfg); | |
161 | } | |
162 | ||
163 | /* | |
164 | * dram_init - | |
165 | * - Sets uboots idea of sdram size | |
166 | */ | |
167 | int dram_init(void) | |
168 | { | |
169 | DECLARE_GLOBAL_DATA_PTR; | |
170 | unsigned int size0 = 0, size1 = 0; | |
171 | ||
172 | size0 = get_sdr_cs_size(CS0); | |
173 | /* | |
174 | * If a second bank of DDR is attached to CS1 this is | |
175 | * where it can be started. Early init code will init | |
176 | * memory on CS0. | |
177 | */ | |
178 | if ((sysinfo.mtype == DDR_COMBO) || (sysinfo.mtype == DDR_STACKED)) { | |
179 | do_sdrc_init(CS1, NOT_EARLY); | |
180 | make_cs1_contiguous(); | |
181 | ||
182 | size1 = get_sdr_cs_size(CS1); | |
183 | } | |
184 | ||
185 | gd->bd->bi_dram[0].start = PHYS_SDRAM_1; | |
186 | gd->bd->bi_dram[0].size = size0; | |
187 | gd->bd->bi_dram[1].start = PHYS_SDRAM_1 + get_sdr_cs_offset(CS1); | |
188 | gd->bd->bi_dram[1].size = size1; | |
189 | ||
190 | return 0; | |
191 | } | |
192 | ||
193 | /* | |
194 | * mem_init - | |
195 | * - Init the sdrc chip, | |
196 | * - Selects CS0 and CS1, | |
197 | */ | |
198 | void mem_init(void) | |
199 | { | |
200 | /* only init up first bank here */ | |
201 | do_sdrc_init(CS0, EARLY_INIT); | |
202 | } |