uboot/board/v38b/v38b.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2003-2006
   3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   4 *
   5 * (C) Copyright 2004
   6 * Mark Jonas, Freescale Semiconductor, mark.jonas@motorola.com.
   7 *
   8 * See file CREDITS for list of people who contributed to this
   9 * project.
  10 *
  11 * This program is free software; you can redistribute it and/or
  12 * modify it under the terms of the GNU General Public License as
  13 * published by the Free Software Foundation; either version 2 of
  14 * the License, or (at your option) any later version.
  15 *
  16 * This program is distributed in the hope that it will be useful,
  17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19 * GNU General Public License for more details.
  20 *
  21 * You should have received a copy of the GNU General Public License
  22 * along with this program; if not, write to the Free Software
  23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  24 * MA 02111-1307 USA
  25 */
  26
  27#include <common.h>
  28#include <mpc5xxx.h>
  29#include <net.h>
  30#include <asm/processor.h>
  31
  32
  33#ifndef CONFIG_SYS_RAMBOOT
  34static void sdram_start(int hi_addr)
  35{
  36        long hi_addr_bit = hi_addr ? 0x01000000 : 0;
  37
  38        /* unlock mode register */
  39        *(vu_long *) MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000000 | hi_addr_bit;
  40        __asm__ volatile ("sync");
  41
  42        /* precharge all banks */
  43        *(vu_long *) MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000002 | hi_addr_bit;
  44        __asm__ volatile ("sync");
  45
  46#if SDRAM_DDR
  47        /* set mode register: extended mode */
  48        *(vu_long *) MPC5XXX_SDRAM_MODE = SDRAM_EMODE;
  49        __asm__ volatile ("sync");
  50
  51        /* set mode register: reset DLL */
  52        *(vu_long *) MPC5XXX_SDRAM_MODE = SDRAM_MODE | 0x04000000;
  53        __asm__ volatile ("sync");
  54#endif /* SDRAM_DDR */
  55
  56        /* precharge all banks */
  57        *(vu_long *) MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000002 | hi_addr_bit;
  58        __asm__ volatile ("sync");
  59
  60        /* auto refresh */
  61        *(vu_long *) MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000004 | hi_addr_bit;
  62        __asm__ volatile ("sync");
  63
  64        /* set mode register */
  65        *(vu_long *) MPC5XXX_SDRAM_MODE = SDRAM_MODE;
  66        __asm__ volatile ("sync");
  67
  68        /* normal operation */
  69        *(vu_long *) MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | hi_addr_bit;
  70        __asm__ volatile ("sync");
  71}
  72#endif /* !CONFIG_SYS_RAMBOOT */
  73
  74
  75phys_size_t initdram(int board_type)
  76{
  77        ulong dramsize = 0;
  78        ulong dramsize2 = 0;
  79        uint svr, pvr;
  80
  81#ifndef CONFIG_SYS_RAMBOOT
  82        ulong test1, test2;
  83
  84        /* setup SDRAM chip selects */
  85        *(vu_long *) MPC5XXX_SDRAM_CS0CFG = 0x0000001e; /* 2G at 0x0 */
  86        *(vu_long *) MPC5XXX_SDRAM_CS1CFG = 0x80000000; /* disabled */
  87        __asm__ volatile ("sync");
  88
  89        /* setup config registers */
  90        *(vu_long *) MPC5XXX_SDRAM_CONFIG1 = SDRAM_CONFIG1;
  91        *(vu_long *) MPC5XXX_SDRAM_CONFIG2 = SDRAM_CONFIG2;
  92        __asm__ volatile ("sync");
  93
  94#if SDRAM_DDR
  95        /* set tap delay */
  96        *(vu_long *) MPC5XXX_CDM_PORCFG = SDRAM_TAPDELAY;
  97        __asm__ volatile ("sync");
  98#endif /* SDRAM_DDR */
  99
 100        /* find RAM size using SDRAM CS0 only */
 101        sdram_start(0);
 102        test1 = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE, 0x80000000);
 103        sdram_start(1);
 104        test2 = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE, 0x80000000);
 105        if (test1 > test2) {
 106                sdram_start(0);
 107                dramsize = test1;
 108        } else
 109                dramsize = test2;
 110
 111        /* memory smaller than 1MB is impossible */
 112        if (dramsize < (1 << 20))
 113                dramsize = 0;
 114
 115        /* set SDRAM CS0 size according to the amount of RAM found */
 116        if (dramsize > 0)
 117                *(vu_long *) MPC5XXX_SDRAM_CS0CFG = 0x13 + __builtin_ffs(dramsize >> 20) - 1;
 118        else
 119                *(vu_long *) MPC5XXX_SDRAM_CS0CFG = 0; /* disabled */
 120
 121        /* let SDRAM CS1 start right after CS0 */
 122        *(vu_long *) MPC5XXX_SDRAM_CS1CFG = dramsize + 0x0000001e;/* 2G */
 123
 124        /* find RAM size using SDRAM CS1 only */
 125        if (!dramsize)
 126                sdram_start(0);
 127        test2 = test1 = get_ram_size((long *) (CONFIG_SYS_SDRAM_BASE + dramsize), 0x80000000);
 128        if (!dramsize) {
 129                sdram_start(1);
 130                test2 = get_ram_size((long *) (CONFIG_SYS_SDRAM_BASE + dramsize), 0x80000000);
 131        }
 132        if (test1 > test2) {
 133                sdram_start(0);
 134                dramsize2 = test1;
 135        } else
 136                dramsize2 = test2;
 137
 138        /* memory smaller than 1MB is impossible */
 139        if (dramsize2 < (1 << 20))
 140                dramsize2 = 0;
 141
 142        /* set SDRAM CS1 size according to the amount of RAM found */
 143        if (dramsize2 > 0)
 144                *(vu_long *) MPC5XXX_SDRAM_CS1CFG = dramsize
 145                        | (0x13 + __builtin_ffs(dramsize2 >> 20) - 1);
 146        else
 147                *(vu_long *) MPC5XXX_SDRAM_CS1CFG = dramsize; /* disabled */
 148
 149#else /* CONFIG_SYS_RAMBOOT */
 150
 151        /* retrieve size of memory connected to SDRAM CS0 */
 152        dramsize = *(vu_long *) MPC5XXX_SDRAM_CS0CFG & 0xFF;
 153        if (dramsize >= 0x13)
 154                dramsize = (1 << (dramsize - 0x13)) << 20;
 155        else
 156                dramsize = 0;
 157
 158        /* retrieve size of memory connected to SDRAM CS1 */
 159        dramsize2 = *(vu_long *) MPC5XXX_SDRAM_CS1CFG & 0xFF;
 160        if (dramsize2 >= 0x13)
 161                dramsize2 = (1 << (dramsize2 - 0x13)) << 20;
 162        else
 163                dramsize2 = 0;
 164
 165#endif /* CONFIG_SYS_RAMBOOT */
 166
 167        /*
 168         * On MPC5200B we need to set the special configuration delay in the
 169         * DDR controller. Please refer to Freescale's AN3221 "MPC5200B SDRAM
 170         * Initialization and Configuration", 3.3.1 SDelay--MBAR + 0x0190:
 171         *
 172         * "The SDelay should be written to a value of 0x00000004. It is
 173         * required to account for changes caused by normal wafer processing
 174         * parameters."
 175         */
 176        svr = get_svr();
 177        pvr = get_pvr();
 178        if ((SVR_MJREV(svr) >= 2) &&
 179                (PVR_MAJ(pvr) == 1) && (PVR_MIN(pvr) == 4)) {
 180
 181                *(vu_long *) MPC5XXX_SDRAM_SDELAY = 0x04;
 182                __asm__ volatile ("sync");
 183        }
 184
 185        return dramsize + dramsize2;
 186}
 187
 188
 189int checkboard (void)
 190{
 191        puts("Board: MarelV38B\n");
 192        return 0;
 193}
 194
 195int board_early_init_f(void)
 196{
 197#ifdef CONFIG_HW_WATCHDOG
 198        /*
 199         * Enable and configure the direction (output) of PSC3_9 - watchdog
 200         * reset input. Refer to 7.3.2.2.[1,3,4] of the MPC5200B User's
 201         * Manual.
 202         */
 203        *(vu_long *) MPC5XXX_WU_GPIO_ENABLE |= GPIO_PSC3_9;
 204        *(vu_long *) MPC5XXX_WU_GPIO_DIR |= GPIO_PSC3_9;
 205#endif /* CONFIG_HW_WATCHDOG */
 206        return 0;
 207}
 208
 209int board_early_init_r(void)
 210{
 211        /*
 212         * Now, when we are in RAM, enable flash write access for the
 213         * detection process.  Note that CS_BOOT cannot be cleared when
 214         * executing in flash.
 215         */
 216        *(vu_long *) MPC5XXX_BOOTCS_CFG &= ~0x1; /* clear RO */
 217
 218        /*
 219         * Enable GPIO_WKUP_7 to "read the status of the actual power
 220         * situation". Default direction is input, so no need to set it
 221         * explicitly.
 222         */
 223        *(vu_long *) MPC5XXX_WU_GPIO_ENABLE |= GPIO_WKUP_7;
 224        return 0;
 225}
 226
 227extern void board_get_enetaddr(uchar *enetaddr);
 228int misc_init_r(void)
 229{
 230        uchar enetaddr[6];
 231
 232        if (!eth_getenv_enetaddr("ethaddr", enetaddr)) {
 233                board_get_enetaddr(enetaddr);
 234                eth_setenv_enetaddr("ethaddr", enetaddr);
 235        }
 236
 237        return 0;
 238}
 239
 240#if defined(CONFIG_CMD_IDE) && defined(CONFIG_IDE_RESET)
 241void init_ide_reset(void)
 242{
 243        debug("init_ide_reset\n");
 244
 245        /* Configure PSC1_4 as GPIO output for ATA reset */
 246        *(vu_long *) MPC5XXX_WU_GPIO_ENABLE |= GPIO_PSC1_4;
 247        *(vu_long *) MPC5XXX_WU_GPIO_DIR |= GPIO_PSC1_4;
 248        /* Deassert reset */
 249        *(vu_long *) MPC5XXX_WU_GPIO_DATA_O |= GPIO_PSC1_4;
 250}
 251
 252
 253void ide_set_reset(int idereset)
 254{
 255        debug("ide_reset(%d)\n", idereset);
 256
 257        if (idereset) {
 258                *(vu_long *) MPC5XXX_WU_GPIO_DATA_O &= ~GPIO_PSC1_4;
 259                /* Make a delay. MPC5200 spec says 25 usec min */
 260                udelay(500000);
 261        } else
 262                *(vu_long *) MPC5XXX_WU_GPIO_DATA_O |=  GPIO_PSC1_4;
 263}
 264#endif
 265
 266
 267#ifdef CONFIG_HW_WATCHDOG
 268void hw_watchdog_reset(void)
 269{
 270        /*
 271         * MarelV38B has a TPS3705 watchdog. Spec says that to kick the dog
 272         * we need a positive or negative transition on WDI i.e., our PSC3_9.
 273         */
 274        *(vu_long *) MPC5XXX_WU_GPIO_DATA_O ^= GPIO_PSC3_9;
 275}
 276#endif /* CONFIG_HW_WATCHDOG */
 277