uboot/board/prodrive/p3mx/sdram_init.c
<<
>>
Prefs
   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
  28DECLARE_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
  39int set_dfcdlInit (void);       /* setup delay line of Mv64460 */
  40int mvDmaIsChannelActive (int);
  41int mvDmaSetMemorySpace (ulong, ulong, ulong, ulong, ulong);
  42int 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
  49int 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 */
  97long 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
 147phys_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
 262void 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 */
 296int 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 */
 322int 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 */
 360int 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 ***************************************************************************************/
 391int 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}
 419