source: SVN/rincon/u-boot/board/prodrive/p3mx/sdram_init.c @ 55

Last change on this file since 55 was 55, checked in by Tim Harvey, 2 years ago

rincon: added latest u-boot source

restored form server backup

Signed-off-by: Tim Harvey <tharvey@…>

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