]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/prodrive/p3mx/sdram_init.c
4a42fa35462ee622e0ae6d2f533c6d4d7d5a25f6
[karo-tx-uboot.git] / board / prodrive / p3mx / sdram_init.c
1 /*
2  * (C) Copyright 2001
3  * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
4  *
5  * SPDX-License-Identifier:     GPL-2.0+ 
6  */
7
8 /*************************************************************************
9  * adaption for the Marvell DB64460 Board
10  * Ingo Assmus (ingo.assmus@keymile.com)
11  *************************************************************************/
12
13 /* sdram_init.c - automatic memory sizing */
14
15 #include <common.h>
16 #include <74xx_7xx.h>
17 #include "../../Marvell/include/memory.h"
18 #include "../../Marvell/include/pci.h"
19 #include "../../Marvell/include/mv_gen_reg.h"
20 #include <net.h>
21
22 #include "eth.h"
23 #include "mpsc.h"
24 #include "../../Marvell/common/i2c.h"
25 #include "64460.h"
26 #include "mv_regs.h"
27
28 DECLARE_GLOBAL_DATA_PTR;
29
30 #undef  DEBUG
31 #define MAP_PCI
32
33 #ifdef DEBUG
34 #define DP(x) x
35 #else
36 #define DP(x)
37 #endif
38
39 int set_dfcdlInit (void);       /* setup delay line of Mv64460 */
40 int mvDmaIsChannelActive (int);
41 int mvDmaSetMemorySpace (ulong, ulong, ulong, ulong, ulong);
42 int mvDmaTransfer (int, ulong, ulong, ulong, ulong);
43
44 #define D_CACHE_FLUSH_LINE(addr, offset)                                \
45         {                                                               \
46                 __asm__ __volatile__ ("dcbf %0,%1" : : "r" (addr), "r" (offset)); \
47         }
48
49 int memory_map_bank (unsigned int bankNo,
50                      unsigned int bankBase, unsigned int bankLength)
51 {
52 #if defined (MAP_PCI) && defined (CONFIG_PCI)
53         PCI_HOST host;
54 #endif
55
56 #ifdef DEBUG
57         if (bankLength > 0) {
58                 printf ("mapping bank %d at %08x - %08x\n",
59                         bankNo, bankBase, bankBase + bankLength - 1);
60         } else {
61                 printf ("unmapping bank %d\n", bankNo);
62         }
63 #endif
64
65         memoryMapBank (bankNo, bankBase, bankLength);
66
67 #if defined (MAP_PCI) && defined (CONFIG_PCI)
68         for (host = PCI_HOST0; host <= PCI_HOST1; host++) {
69                 const int features =
70                         PREFETCH_ENABLE |
71                         DELAYED_READ_ENABLE |
72                         AGGRESSIVE_PREFETCH |
73                         READ_LINE_AGGRESSIVE_PREFETCH |
74                         READ_MULTI_AGGRESSIVE_PREFETCH |
75                         MAX_BURST_4 | PCI_NO_SWAP;
76
77                 pciMapMemoryBank (host, bankNo, bankBase, bankLength);
78
79                 pciSetRegionSnoopMode (host, bankNo, PCI_SNOOP_WB, bankBase,
80                                        bankLength);
81
82                 pciSetRegionFeatures (host, bankNo, features, bankBase,
83                                       bankLength);
84         }
85 #endif
86
87         return 0;
88 }
89
90 /*
91  * Check memory range for valid RAM. A simple memory test determines
92  * the actually available RAM size between addresses `base' and
93  * `base + maxsize'. Some (not all) hardware errors are detected:
94  * - short between address lines
95  * - short between data lines
96  */
97 long int dram_size (long int *base, long int maxsize)
98 {
99         volatile long int *addr, *b = base;
100         long int cnt, val, save1, save2;
101
102 #define STARTVAL (1<<20)        /* start test at 1M */
103         for (cnt = STARTVAL / sizeof (long); cnt < maxsize / sizeof (long);
104              cnt <<= 1) {
105                 addr = base + cnt;      /* pointer arith! */
106
107                 save1 = *addr;  /* save contents of addr */
108                 save2 = *b;     /* save contents of base */
109
110                 *addr = cnt;    /* write cnt to addr */
111                 *b = 0;         /* put null at base */
112
113                 /* check at base address */
114                 if ((*b) != 0) {
115                         *addr = save1;  /* restore *addr */
116                         *b = save2;     /* restore *b */
117                         return (0);
118                 }
119                 val = *addr;    /* read *addr */
120                 val = *addr;    /* read *addr */
121
122                 *addr = save1;
123                 *b = save2;
124
125                 if (val != cnt) {
126                         DP (printf
127                             ("Found %08x  at Address %08x (failure)\n",
128                              (unsigned int) val, (unsigned int) addr));
129                         /* fix boundary condition.. STARTVAL means zero */
130                         if (cnt == STARTVAL / sizeof (long))
131                                 cnt = 0;
132                         return (cnt * sizeof (long));
133                 }
134         }
135
136         return maxsize;
137 }
138
139 #define SDRAM_NORMAL                    0x0
140 #define SDRAM_PRECHARGE_ALL             0x1
141 #define SDRAM_REFRESH_ALL               0x2
142 #define SDRAM_MODE_REG_SETUP            0x3
143 #define SDRAM_XTEN_MODE_REG_SETUP       0x4
144 #define SDRAM_NOP                       0x5
145 #define SDRAM_SELF_REFRESH              0x7
146
147 phys_size_t initdram (int board_type)
148 {
149         int tmp;
150         int start;
151         ulong size;
152         ulong memSpaceAttr;
153         ulong dest;
154
155         /* first disable all banks */
156         memory_map_bank(0, 0, 0);
157         memory_map_bank(1, 0, 0);
158         memory_map_bank(2, 0, 0);
159         memory_map_bank(3, 0, 0);
160
161         /* calibrate delay lines */
162         set_dfcdlInit();
163
164         GT_REG_WRITE(MV64460_SDRAM_OPERATION, SDRAM_NOP);               /* 0x1418 */
165         do {
166                 tmp = GTREGREAD(MV64460_SDRAM_OPERATION);
167         } while(tmp != 0x0);
168
169         /* SDRAM controller configuration */
170 #ifdef CONFIG_MV64460_ECC
171         GT_REG_WRITE(MV64460_SDRAM_CONFIG,              0x58201400);    /* 0x1400 */
172 #else
173         GT_REG_WRITE(MV64460_SDRAM_CONFIG,              0x58200400);    /* 0x1400 */
174 #endif
175         GT_REG_WRITE(MV64460_D_UNIT_CONTROL_LOW,        0xC3000540);    /* 0x1404  */
176         GT_REG_WRITE(MV64460_D_UNIT_CONTROL_HIGH,       0x0300F777);    /* 0x1424 */
177         GT_REG_WRITE(MV64460_SDRAM_TIMING_CONTROL_LOW,  0x01712220);    /* 0x1408 */
178         GT_REG_WRITE(MV64460_SDRAM_TIMING_CONTROL_HIGH, 0x0000005D);    /* 0x140C */
179         GT_REG_WRITE(MV64460_SDRAM_ADDR_CONTROL,        0x00000012);    /* 0x1410 */
180         GT_REG_WRITE(MV64460_SDRAM_OPEN_PAGES_CONTROL,  0x00000001);    /* 0x1414 */
181
182         /* SDRAM drive strength */
183         GT_REG_WRITE(MV64460_SDRAM_ADDR_CTRL_PADS_CALIBRATION, 0x80000000); /* 0x14C0 */
184         GT_REG_WRITE(MV64460_SDRAM_ADDR_CTRL_PADS_CALIBRATION, 0x80000008); /* 0x14C0 */
185         GT_REG_WRITE(MV64460_SDRAM_DATA_PADS_CALIBRATION, 0x80000000);      /* 0x14C4 */
186         GT_REG_WRITE(MV64460_SDRAM_DATA_PADS_CALIBRATION, 0x80000008);      /* 0x14C4 */
187
188         /* setup SDRAM device registers */
189
190         /* precharge all */
191         GT_REG_WRITE(MV64460_SDRAM_OPERATION, SDRAM_PRECHARGE_ALL);     /* 0x1418 */
192         do {
193                 tmp = GTREGREAD(MV64460_SDRAM_OPERATION);
194         } while(tmp != 0x0);
195
196         /* enable DLL */
197         GT_REG_WRITE(MV64460_EXTENDED_DRAM_MODE, 0x00000000);                   /* 0x1420 */
198         GT_REG_WRITE(MV64460_SDRAM_OPERATION, SDRAM_XTEN_MODE_REG_SETUP);       /* 0x1418 */
199         do {
200                 tmp = GTREGREAD(MV64460_SDRAM_OPERATION);
201         } while(tmp != 0x0);
202
203         /* reset DLL */
204         GT_REG_WRITE(MV64460_SDRAM_MODE, 0x00000132);   /* 0x141C */
205         GT_REG_WRITE(MV64460_SDRAM_OPERATION, SDRAM_MODE_REG_SETUP);    /* 0x1418 */
206         do {
207                 tmp = GTREGREAD(MV64460_SDRAM_OPERATION);
208         } while(tmp != 0x0);
209
210         /* precharge all */
211         GT_REG_WRITE(MV64460_SDRAM_OPERATION, SDRAM_PRECHARGE_ALL);     /* 0x1418 */
212         do {
213                 tmp = GTREGREAD(MV64460_SDRAM_OPERATION);
214         } while(tmp != 0x0);
215
216         /* wait for 2 auto refresh commands */
217         udelay(20);
218
219         /* un-reset DLL */
220         GT_REG_WRITE(MV64460_SDRAM_MODE, 0x00000032);   /* 0x141C */
221         GT_REG_WRITE(MV64460_SDRAM_OPERATION, SDRAM_MODE_REG_SETUP);    /* 0x1418 */
222         do {
223                 tmp = GTREGREAD(MV64460_SDRAM_OPERATION);
224         } while(tmp != 0x0);
225
226         /* wait 200 cycles */
227         udelay(2);  /* FIXME  make this dynamic for the system clock */
228
229         /* SDRAM init done */
230         memory_map_bank(0, CONFIG_SYS_SDRAM_BASE,  (256 << 20));
231 #ifdef CONFIG_SYS_SDRAM1_BASE
232         memory_map_bank(1, CONFIG_SYS_SDRAM1_BASE, (256 << 20));
233 #endif
234
235         /* DUNIT_MMASK: enable SnoopHitEn bit to avoid errata CPU-#4
236          */
237         tmp = GTREGREAD(MV64460_D_UNIT_MMASK);                          /* 0x14B0 */
238         GT_REG_WRITE(MV64460_D_UNIT_MMASK, tmp | 0x2);
239
240         start = (0 << 20);
241 #ifdef CONFIG_P3M750
242         size = (512 << 20);
243 #elif defined (CONFIG_P3M7448)
244         size = (128 << 20);
245 #endif
246
247 #ifdef CONFIG_MV64460_ECC
248         memSpaceAttr = ((~(BIT0 << 0)) & 0xf) << 8;
249         mvDmaSetMemorySpace (0, 0, memSpaceAttr, start, size);
250         for (dest = start; dest < start + size; dest += _8M) {
251                 mvDmaTransfer (0, start, dest, _8M,
252                                BIT8 /*DMA_DTL_128BYTES */  |
253                                BIT3 /*DMA_HOLD_SOURCE_ADDR */ |
254                                BIT11 /*DMA_BLOCK_TRANSFER_MODE */ );
255                 while (mvDmaIsChannelActive (0));
256         }
257 #endif
258
259         return (size);
260 }
261
262 void board_add_ram_info(int use_default)
263 {
264         u32 val;
265
266         puts(" (CL=");
267         switch ((GTREGREAD(MV64460_SDRAM_MODE) >> 4) & 0x7) {
268         case 0x2:
269                 puts("2");
270                 break;
271         case 0x3:
272                 puts("3");
273                 break;
274         case 0x5:
275                 puts("1.5");
276                 break;
277         case 0x6:
278                 puts("2.5");
279                 break;
280         }
281
282         val = GTREGREAD(MV64460_SDRAM_CONFIG);
283
284         puts(", ECC ");
285         if (val & 0x00001000)
286                 puts("enabled)");
287         else
288                 puts("not enabled)");
289 }
290
291 /*
292  * mvDmaIsChannelActive - Check if IDMA channel is active
293  *
294  * channel      = IDMA channel number from 0 to 7
295  */
296 int mvDmaIsChannelActive (int channel)
297 {
298         ulong data;
299
300         data = GTREGREAD (MV64460_DMA_CHANNEL0_CONTROL + 4 * channel);
301         if (data & BIT14)       /* activity status */
302                 return 1;
303
304         return 0;
305 }
306
307 /*
308  * mvDmaSetMemorySpace - Set a DMA memory window for the DMA's address decoding
309  *                       map.
310  *
311  * memSpace     = IDMA memory window number from 0 to 7
312  * trg_if       = Target interface:
313  *                0x0 DRAM
314  *                0x1 Device Bus
315  *                0x2 Integrated SDRAM (or CPU bus 60x only)
316  *                0x3 PCI0
317  *                0x4 PCI1
318  * attr         = IDMA attributes (see MV datasheet)
319  * base_addr    = Sets up memory window for transfers
320  *
321  */
322 int mvDmaSetMemorySpace (ulong memSpace,
323                          ulong trg_if,
324                          ulong attr, ulong base_addr, ulong size)
325 {
326         ulong temp;
327
328         /* The base address must be aligned to the size.  */
329         if (base_addr % size != 0)
330                 return 0;
331
332         if (size >= 0x10000) {   /* 64K */
333                 size &= 0xffff0000;
334                 base_addr = (base_addr & 0xffff0000);
335                 /* Set the new attributes */
336                 GT_REG_WRITE (MV64460_DMA_BASE_ADDR_REG0 + memSpace * 8,
337                               (base_addr | trg_if | attr));
338                 GT_REG_WRITE ((MV64460_DMA_SIZE_REG0 + memSpace * 8),
339                               (size - 1) & 0xffff0000);
340                 temp = GTREGREAD (MV64460_DMA_BASE_ADDR_ENABLE_REG);
341                 GT_REG_WRITE (DMA_BASE_ADDR_ENABLE_REG,
342                               (temp & ~(BIT0 << memSpace)));
343                 return 1;
344         }
345
346         return 0;
347 }
348
349 /*
350  * mvDmaTransfer - Transfer data from src_addr to dst_addr on one of the 4
351  *                 DMA channels.
352  *
353  * channel      = IDMA channel number from 0 to 3
354  * destAddr     = Destination address
355  * sourceAddr   = Source address
356  * size         = Size in bytes
357  * command      = See MV datasheet
358  *
359  */
360 int mvDmaTransfer (int channel, ulong sourceAddr,
361                    ulong destAddr, ulong size, ulong command)
362 {
363         ulong engOffReg = 0;    /* Engine Offset Register */
364
365         if (size > 0xffff)
366                 command = command | BIT31;      /* DMA_16M_DESCRIPTOR_MODE */
367         command = command | ((command >> 6) & 0x7);
368         engOffReg = channel * 4;
369         GT_REG_WRITE (MV64460_DMA_CHANNEL0_BYTE_COUNT + engOffReg, size);
370         GT_REG_WRITE (MV64460_DMA_CHANNEL0_SOURCE_ADDR + engOffReg, sourceAddr);
371         GT_REG_WRITE (MV64460_DMA_CHANNEL0_DESTINATION_ADDR + engOffReg, destAddr);
372         command = command |
373                 BIT12   |                       /* DMA_CHANNEL_ENABLE */
374                 BIT9;                           /* DMA_NON_CHAIN_MODE */
375         /* Activate DMA channel By writting to mvDmaControlRegister */
376         GT_REG_WRITE (MV64460_DMA_CHANNEL0_CONTROL + engOffReg, command);
377         return 1;
378 }
379
380 /****************************************************************************************
381  *                             SDRAM INIT                                               *
382  *  This procedure detect all Sdram types: 64, 128, 256, 512 Mbit, 1Gbit and 2Gb        *
383  *               This procedure fits only the Atlantis                                  *
384  *                                                                                      *
385  ***************************************************************************************/
386
387 /****************************************************************************************
388  *                             DFCDL initialize MV643xx Design Considerations           *
389  *                                                                                      *
390  ***************************************************************************************/
391 int set_dfcdlInit (void)
392 {
393         int i;
394
395         /* Values from MV64460 User Manual */
396         unsigned int dfcdl_tbl[] = { 0x00000000, 0x00000001, 0x00000042, 0x00000083,
397                                      0x000000c4, 0x00000105, 0x00000146, 0x00000187,
398                                      0x000001c8, 0x00000209, 0x0000024a, 0x0000028b,
399                                      0x000002cc, 0x0000030d, 0x0000034e, 0x0000038f,
400                                      0x000003d0, 0x00000411, 0x00000452, 0x00000493,
401                                      0x000004d4, 0x00000515, 0x00000556, 0x00000597,
402                                      0x000005d8, 0x00000619, 0x0000065a, 0x0000069b,
403                                      0x000006dc, 0x0000071d, 0x0000075e, 0x0000079f,
404                                      0x000007e0, 0x00000821, 0x00000862, 0x000008a3,
405                                      0x000008e4, 0x00000925, 0x00000966, 0x000009a7,
406                                      0x000009e8, 0x00000a29, 0x00000a6a, 0x00000aab,
407                                      0x00000aec, 0x00000b2d, 0x00000b6e, 0x00000baf,
408                                      0x00000bf0, 0x00000c31, 0x00000c72, 0x00000cb3,
409                                      0x00000cf4, 0x00000d35, 0x00000d76, 0x00000db7,
410                                      0x00000df8, 0x00000e39, 0x00000e7a, 0x00000ebb,
411                                      0x00000efc, 0x00000f3d, 0x00000f7e, 0x00000fbf };
412
413         for (i = 0; i < 64; i++)
414                 GT_REG_WRITE (SRAM_DATA0, dfcdl_tbl[i]);
415         GT_REG_WRITE (DFCDL_CONFIG0, 0x00300000);       /* enable dynamic delay line updating */
416
417         return (0);
418 }