3 * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
5 * SPDX-License-Identifier: GPL-2.0+
8 /*************************************************************************
9 * adaption for the Marvell DB64460 Board
10 * Ingo Assmus (ingo.assmus@keymile.com)
11 *************************************************************************/
13 /* sdram_init.c - automatic memory sizing */
17 #include "../../Marvell/include/memory.h"
18 #include "../../Marvell/include/pci.h"
19 #include "../../Marvell/include/mv_gen_reg.h"
24 #include "../../Marvell/common/i2c.h"
28 DECLARE_GLOBAL_DATA_PTR;
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);
44 #define D_CACHE_FLUSH_LINE(addr, offset) \
46 __asm__ __volatile__ ("dcbf %0,%1" : : "r" (addr), "r" (offset)); \
49 int memory_map_bank (unsigned int bankNo,
50 unsigned int bankBase, unsigned int bankLength)
52 #if defined (MAP_PCI) && defined (CONFIG_PCI)
58 printf ("mapping bank %d at %08x - %08x\n",
59 bankNo, bankBase, bankBase + bankLength - 1);
61 printf ("unmapping bank %d\n", bankNo);
65 memoryMapBank (bankNo, bankBase, bankLength);
67 #if defined (MAP_PCI) && defined (CONFIG_PCI)
68 for (host = PCI_HOST0; host <= PCI_HOST1; host++) {
73 READ_LINE_AGGRESSIVE_PREFETCH |
74 READ_MULTI_AGGRESSIVE_PREFETCH |
75 MAX_BURST_4 | PCI_NO_SWAP;
77 pciMapMemoryBank (host, bankNo, bankBase, bankLength);
79 pciSetRegionSnoopMode (host, bankNo, PCI_SNOOP_WB, bankBase,
82 pciSetRegionFeatures (host, bankNo, features, bankBase,
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
97 long int dram_size (long int *base, long int maxsize)
99 volatile long int *addr, *b = base;
100 long int cnt, val, save1, save2;
102 #define STARTVAL (1<<20) /* start test at 1M */
103 for (cnt = STARTVAL / sizeof (long); cnt < maxsize / sizeof (long);
105 addr = base + cnt; /* pointer arith! */
107 save1 = *addr; /* save contents of addr */
108 save2 = *b; /* save contents of base */
110 *addr = cnt; /* write cnt to addr */
111 *b = 0; /* put null at base */
113 /* check at base address */
115 *addr = save1; /* restore *addr */
116 *b = save2; /* restore *b */
119 val = *addr; /* read *addr */
120 val = *addr; /* read *addr */
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))
132 return (cnt * sizeof (long));
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
147 phys_size_t initdram (int board_type)
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);
161 /* calibrate delay lines */
164 GT_REG_WRITE(MV64460_SDRAM_OPERATION, SDRAM_NOP); /* 0x1418 */
166 tmp = GTREGREAD(MV64460_SDRAM_OPERATION);
169 /* SDRAM controller configuration */
170 #ifdef CONFIG_MV64460_ECC
171 GT_REG_WRITE(MV64460_SDRAM_CONFIG, 0x58201400); /* 0x1400 */
173 GT_REG_WRITE(MV64460_SDRAM_CONFIG, 0x58200400); /* 0x1400 */
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 */
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 */
188 /* setup SDRAM device registers */
191 GT_REG_WRITE(MV64460_SDRAM_OPERATION, SDRAM_PRECHARGE_ALL); /* 0x1418 */
193 tmp = GTREGREAD(MV64460_SDRAM_OPERATION);
197 GT_REG_WRITE(MV64460_EXTENDED_DRAM_MODE, 0x00000000); /* 0x1420 */
198 GT_REG_WRITE(MV64460_SDRAM_OPERATION, SDRAM_XTEN_MODE_REG_SETUP); /* 0x1418 */
200 tmp = GTREGREAD(MV64460_SDRAM_OPERATION);
204 GT_REG_WRITE(MV64460_SDRAM_MODE, 0x00000132); /* 0x141C */
205 GT_REG_WRITE(MV64460_SDRAM_OPERATION, SDRAM_MODE_REG_SETUP); /* 0x1418 */
207 tmp = GTREGREAD(MV64460_SDRAM_OPERATION);
211 GT_REG_WRITE(MV64460_SDRAM_OPERATION, SDRAM_PRECHARGE_ALL); /* 0x1418 */
213 tmp = GTREGREAD(MV64460_SDRAM_OPERATION);
216 /* wait for 2 auto refresh commands */
220 GT_REG_WRITE(MV64460_SDRAM_MODE, 0x00000032); /* 0x141C */
221 GT_REG_WRITE(MV64460_SDRAM_OPERATION, SDRAM_MODE_REG_SETUP); /* 0x1418 */
223 tmp = GTREGREAD(MV64460_SDRAM_OPERATION);
226 /* wait 200 cycles */
227 udelay(2); /* FIXME make this dynamic for the system clock */
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));
235 /* DUNIT_MMASK: enable SnoopHitEn bit to avoid errata CPU-#4
237 tmp = GTREGREAD(MV64460_D_UNIT_MMASK); /* 0x14B0 */
238 GT_REG_WRITE(MV64460_D_UNIT_MMASK, tmp | 0x2);
243 #elif defined (CONFIG_P3M7448)
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));
262 void board_add_ram_info(int use_default)
267 switch ((GTREGREAD(MV64460_SDRAM_MODE) >> 4) & 0x7) {
282 val = GTREGREAD(MV64460_SDRAM_CONFIG);
285 if (val & 0x00001000)
288 puts("not enabled)");
292 * mvDmaIsChannelActive - Check if IDMA channel is active
294 * channel = IDMA channel number from 0 to 7
296 int mvDmaIsChannelActive (int channel)
300 data = GTREGREAD (MV64460_DMA_CHANNEL0_CONTROL + 4 * channel);
301 if (data & BIT14) /* activity status */
308 * mvDmaSetMemorySpace - Set a DMA memory window for the DMA's address decoding
311 * memSpace = IDMA memory window number from 0 to 7
312 * trg_if = Target interface:
315 * 0x2 Integrated SDRAM (or CPU bus 60x only)
318 * attr = IDMA attributes (see MV datasheet)
319 * base_addr = Sets up memory window for transfers
322 int mvDmaSetMemorySpace (ulong memSpace,
324 ulong attr, ulong base_addr, ulong size)
328 /* The base address must be aligned to the size. */
329 if (base_addr % size != 0)
332 if (size >= 0x10000) { /* 64K */
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)));
350 * mvDmaTransfer - Transfer data from src_addr to dst_addr on one of the 4
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
360 int mvDmaTransfer (int channel, ulong sourceAddr,
361 ulong destAddr, ulong size, ulong command)
363 ulong engOffReg = 0; /* Engine Offset Register */
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);
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);
380 /****************************************************************************************
382 * This procedure detect all Sdram types: 64, 128, 256, 512 Mbit, 1Gbit and 2Gb *
383 * This procedure fits only the Atlantis *
385 ***************************************************************************************/
387 /****************************************************************************************
388 * DFCDL initialize MV643xx Design Considerations *
390 ***************************************************************************************/
391 int set_dfcdlInit (void)
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 };
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 */