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