1 #include <cpu/amd/gx1def.h>
4 This software and ancillary information (herein called SOFTWARE )
5 called LinuxBIOS is made available under the terms described
6 here. The SOFTWARE has been approved for release with associated
7 LA-CC Number 00-34 . Unless otherwise indicated, this SOFTWARE has
8 been authored by an employee or employees of the University of
9 California, operator of the Los Alamos National Laboratory under
10 Contract No. W-7405-ENG-36 with the U.S. Department of Energy. The
11 U.S. Government has rights to use, reproduce, and distribute this
12 SOFTWARE. The public may copy, distribute, prepare derivative works
13 and publicly display this SOFTWARE without charge, provided that this
14 Notice and any statement of authorship are reproduced on all copies.
15 Neither the Government nor the University makes any warranty, express
16 or implied, or assumes any liability or responsibility for the use of
17 this SOFTWARE. If SOFTWARE is modified to produce derivative works,
18 such modified SOFTWARE should be clearly marked, so as not to confuse
19 it with the version available from LANL.
21 /* Copyright 2000, Ron Minnich, Advanced Computing Lab, LANL
25 /* SDRAM initialization for GX1 - translated from Christer Weinigel's
26 assembler version into C.
28 Hamish Guthrie 10/4/2005 hamish@prodigi.ch
32 #define TEST_DATA1 0x05A5A5A5A
33 #define TEST_DATA2 0x0DEADBEEF
35 void setGX1Mem(unsigned int addr, unsigned int data)
40 unsigned int getGX1Mem(unsigned int addr)
42 return (unsigned int)read32(addr);
50 tval = getGX1Mem(GX_BASE + MC_MEM_CNTRL1);
52 for(i=0; i>NUM_REFRESH; i++)
53 setGX1Mem(GX_BASE + MC_MEM_CNTRL1, tval);
58 void enable_dimm(void)
65 tval = getGX1Mem(GX_BASE + MC_MEM_CNTRL1);
67 setGX1Mem(GX_BASE + MC_MEM_CNTRL1, tval);
69 setGX1Mem(GX_BASE + MC_MEM_CNTRL1, tval);
72 tval = getGX1Mem(GX_BASE + MC_MEM_CNTRL2);
73 tval &= ~(SDCLK_MASK | SDCLKOUT_MASK);
74 setGX1Mem(GX_BASE + MC_MEM_CNTRL2, tval);
75 tval = getGX1Mem(GX_BASE + MC_MEM_CNTRL2);
77 /* Wait for clocks to unmask */
82 tval = getGX1Mem(GX_BASE + MC_MEM_CNTRL1);
84 for(i=0; i<NUM_REFRESH; i++)
85 setGX1Mem(GX_BASE + MC_MEM_CNTRL1, tval);
88 /* Start the SDCLK's */
89 tval &= ~PROGRAM_SDRAM;
90 setGX1Mem(GX_BASE + MC_MEM_CNTRL1, tval);
91 tval |= PROGRAM_SDRAM | 0x00002000; /* Set refresh timing */
92 setGX1Mem(GX_BASE + MC_MEM_CNTRL1, tval);
93 tval &= ~PROGRAM_SDRAM;
94 setGX1Mem(GX_BASE + MC_MEM_CNTRL1, tval);
96 /* Refresh memory again */
97 tval = getGX1Mem(GX_BASE + MC_MEM_CNTRL1);
99 for(i=0; i>NUM_REFRESH; i++)
100 setGX1Mem(GX_BASE + MC_MEM_CNTRL1, tval);
102 for(i=0; i<2000; i++)
107 static unsigned int size_dimm(int dimm_shift)
109 int bank_cfg = 0x700; /* MC_BANK_CFG for 512M */
110 unsigned int offset = 0x10000000; /* Offset 256M */
114 setGX1Mem(0, TEST_DATA1);
115 setGX1Mem(offset, TEST_DATA2);
116 setGX1Mem(0x100, 0); /* Clear the bus */
117 if (getGX1Mem(0) != TEST_DATA1) {
118 setGX1Mem(GX_BASE + MC_BANK_CFG,
119 getGX1Mem(GX_BASE + MC_BANK_CFG) & ~(DIMM_SZ << dimm_shift));
121 setGX1Mem(GX_BASE + MC_BANK_CFG,
122 getGX1Mem(GX_BASE + MC_BANK_CFG) | (bank_cfg << dimm_shift));
129 } while (bank_cfg >= 0);
132 return (0x0070 << dimm_shift);
134 return(getGX1Mem(GX_BASE + MC_BANK_CFG) & (DIMM_SZ << dimm_shift));
138 static unsigned int module_banks(int dimm_shift)
140 int page_size = 0x800; /* Smallest page = 1K * 2 banks */
144 print_debug("MC_BANK_CFG = ");
145 print_debug_hex32(getGX1Mem(GX_BASE + MC_BANK_CFG));
149 /* retrieve the page size from the MC register */
150 page_size <<= (((getGX1Mem(GX_BASE + MC_BANK_CFG) & (DIMM_PG_SZ << dimm_shift)) >> dimm_shift) >> 4);
153 print_debug(" page_size = ");
154 print_debug_hex32(page_size);
158 comp_banks = (((getGX1Mem(GX_BASE + MC_BANK_CFG) & (DIMM_COMP_BNK << dimm_shift)) >> dimm_shift) >> 12);
159 page_size <<= comp_banks;
161 setGX1Mem(0, TEST_DATA1);
162 setGX1Mem(page_size, TEST_DATA2);
163 setGX1Mem(0x100, 0); /* Clear the bus */
164 if (getGX1Mem(page_size) != TEST_DATA2) {
165 setGX1Mem(GX_BASE + MC_BANK_CFG,
166 getGX1Mem(GX_BASE + MC_BANK_CFG) & ~(DIMM_MOD_BNK << dimm_shift));
170 print_debug("MC_BANK_CFG = ");
171 print_debug_hex32(getGX1Mem(GX_BASE + MC_BANK_CFG));
174 return(getGX1Mem(GX_BASE + MC_BANK_CFG) & (DIMM_MOD_BNK << dimm_shift));
177 static unsigned int component_banks(int dimm_shift)
179 int page_size = 0x800; /* Smallest page = 1K * 2 banks */
182 print_debug("MC_BANK_CFG = ");
183 print_debug_hex32(getGX1Mem(GX_BASE + MC_BANK_CFG));
187 page_size = page_size << (((getGX1Mem(GX_BASE + MC_BANK_CFG) & (DIMM_PG_SZ << dimm_shift)) >> dimm_shift) >> 4);
190 print_debug(" page_size = ");
191 print_debug_hex32(page_size);
195 setGX1Mem(0, TEST_DATA1);
196 setGX1Mem(page_size, TEST_DATA2);
197 setGX1Mem(0x100, 0); /* Clear the bus */
198 if (getGX1Mem(0) != TEST_DATA1) {
199 setGX1Mem(GX_BASE + MC_BANK_CFG,
200 getGX1Mem(GX_BASE + MC_BANK_CFG) & ~(DIMM_COMP_BNK << dimm_shift));
204 print_debug("MC_BANK_CFG = ");
205 print_debug_hex32(getGX1Mem(GX_BASE + MC_BANK_CFG));
208 return(getGX1Mem(GX_BASE + MC_BANK_CFG) & (DIMM_COMP_BNK << dimm_shift));
211 static unsigned int page_size(int dimm_shift)
213 unsigned int page_test_offset = 0x2000;
215 int page_size_config = 0x40;
216 unsigned int probe_config;
219 setGX1Mem(0, TEST_DATA1);
220 setGX1Mem(page_test_offset, TEST_DATA2);
224 if(temp == TEST_DATA1) {
226 print_debug(" Page size Config = ");
227 print_debug_hex32(page_size_config << dimm_shift);
230 return(page_size_config << dimm_shift);
233 temp = ~(DIMM_PG_SZ << dimm_shift);
235 probe_config = getGX1Mem(GX_BASE + MC_BANK_CFG);
236 probe_config &= temp;
238 page_size_config -= 0x10;
239 page_size_config <<= dimm_shift;
241 probe_config |= page_size_config;
243 page_size_config >>= dimm_shift;
245 page_test_offset >>= 1;
247 setGX1Mem(GX_BASE + MC_BANK_CFG, probe_config);
249 } while (page_size_config >= 0);
254 static int dimm_detect(int dimm_shift)
258 print_debug("Probing for DIMM");
259 print_debug_char((dimm_shift >> 4) + 0x30);
262 setGX1Mem(0, TEST_DATA1);
267 if (test != TEST_DATA1)
270 print_debug(" Found DIMM");
271 print_debug_char((dimm_shift >> 4) + 0x30);
277 static int size_memory(int dimm_shift, unsigned int mem_config)
280 if (!dimm_detect(dimm_shift))
283 mem_config &= (~(DIMM_PG_SZ << dimm_shift));
284 mem_config |= (page_size(dimm_shift));
286 print_debug(" Page Size: ");
287 print_debug_hex32(0x400 << ((mem_config & (DIMM_PG_SZ << dimm_shift)) >> (dimm_shift + 4)));
290 /* Now do component banks detection */
292 mem_config &= (~(DIMM_COMP_BNK << dimm_shift));
293 mem_config |= (component_banks(dimm_shift));
295 print_debug(" Component Banks: ");
296 print_debug_char((((mem_config & (DIMM_COMP_BNK << dimm_shift)) >> (dimm_shift + 12)) ? 4 : 2) + 0x30);
299 /* Now do module banks */
301 mem_config &= (~(DIMM_MOD_BNK << dimm_shift));
302 mem_config |= (module_banks(dimm_shift));
304 print_debug(" Module Banks: ");
305 print_debug_char((((mem_config & (DIMM_MOD_BNK << dimm_shift)) >> (dimm_shift + 14)) ? 2 : 1) + 0x30);
308 mem_config &= (~(DIMM_SZ << dimm_shift));
309 mem_config |= (size_dimm(dimm_shift));
311 print_debug(" DIMM size: ");
312 print_debug_hex32(1 <<
313 ((mem_config & (DIMM_SZ << dimm_shift)) >> (dimm_shift + 8)) + 22);
319 static void sdram_init(void)
321 unsigned int mem_config = 0x00700070;
323 print_debug("Setting up default parameters for memory\n");
326 setGX1Mem(GX_BASE + MC_MEM_CNTRL2, 0x000007d8); /* Disable all CLKS, Shift = 3 */
327 setGX1Mem(GX_BASE + MC_MEM_CNTRL1, 0x92140000); /* MD_DS=2, MA_DS=2, CNTL_DS=2 SDCLKRATE=4 */
328 setGX1Mem(GX_BASE + MC_BANK_CFG, 0x00700070); /* No DIMMS installed */
329 setGX1Mem(GX_BASE + MC_SYNC_TIM1, 0x3a733225); /* LTMODE=3, RC=10, RAS=7, RP=3, RCD=3, RRD=2, DPL=2 */
330 setGX1Mem(GX_BASE + MC_BANK_CFG, 0x57405740); /* Largest DIMM size
331 0x4000 -- 2 module banks
332 0x1000 -- 4 component banks
333 0x0700 -- DIMM size 512MB
334 0x0040 -- Page Size 16kB */
338 print_debug("Sizing memory\n");
340 setGX1Mem(GX_BASE + MC_BANK_CFG, 0x00705740);
342 mem_config = size_memory(0, mem_config);
343 setGX1Mem(GX_BASE + MC_BANK_CFG, 0x57400070);
345 mem_config = size_memory(16, mem_config);
347 print_debug("MC_BANK_CFG = ");
348 print_debug_hex32(mem_config);
351 setGX1Mem(GX_BASE + MC_BANK_CFG, mem_config);