uboot/board/esd/pf5200/pf5200.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2003
   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/*
  12 * pf5200.c - main board support/init for the esd pf5200.
  13 */
  14
  15#include <common.h>
  16#include <mpc5xxx.h>
  17#include <pci.h>
  18#include <command.h>
  19#include <netdev.h>
  20
  21#include "mt46v16m16-75.h"
  22
  23void init_power_switch(void);
  24
  25static void sdram_start(int hi_addr)
  26{
  27        long hi_addr_bit = hi_addr ? 0x01000000 : 0;
  28
  29        /* unlock mode register */
  30        *(vu_long *) MPC5XXX_SDRAM_CTRL =
  31            SDRAM_CONTROL | 0x80000000 | hi_addr_bit;
  32        __asm__ volatile ("sync");
  33
  34        /* precharge all banks */
  35        *(vu_long *) MPC5XXX_SDRAM_CTRL =
  36            SDRAM_CONTROL | 0x80000002 | hi_addr_bit;
  37        __asm__ volatile ("sync");
  38
  39        /* set mode register: extended mode */
  40        *(vu_long *) MPC5XXX_SDRAM_MODE = SDRAM_EMODE;
  41        __asm__ volatile ("sync");
  42
  43        /* set mode register: reset DLL */
  44        *(vu_long *) MPC5XXX_SDRAM_MODE = SDRAM_MODE | 0x04000000;
  45        __asm__ volatile ("sync");
  46
  47        /* precharge all banks */
  48        *(vu_long *) MPC5XXX_SDRAM_CTRL =
  49            SDRAM_CONTROL | 0x80000002 | hi_addr_bit;
  50        __asm__ volatile ("sync");
  51
  52        /* auto refresh */
  53        *(vu_long *) MPC5XXX_SDRAM_CTRL =
  54            SDRAM_CONTROL | 0x80000004 | hi_addr_bit;
  55        __asm__ volatile ("sync");
  56
  57        /* set mode register */
  58        *(vu_long *) MPC5XXX_SDRAM_MODE = SDRAM_MODE;
  59        __asm__ volatile ("sync");
  60
  61        /* normal operation */
  62        *(vu_long *) MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | hi_addr_bit;
  63        __asm__ volatile ("sync");
  64}
  65
  66/*
  67 * ATTENTION: Although partially referenced initdram does NOT make real use
  68 *            use of CONFIG_SYS_SDRAM_BASE. The code does not work if CONFIG_SYS_SDRAM_BASE
  69 *            is something else than 0x00000000.
  70 */
  71
  72phys_size_t initdram(int board_type)
  73{
  74        ulong dramsize = 0;
  75        ulong test1, test2;
  76
  77        /* setup SDRAM chip selects */
  78        *(vu_long *) MPC5XXX_SDRAM_CS0CFG = 0x0000001e; /* 2G at 0x0 */
  79        *(vu_long *) MPC5XXX_SDRAM_CS1CFG = 0x80000000; /* disabled */
  80        __asm__ volatile ("sync");
  81
  82        /* setup config registers */
  83        *(vu_long *) MPC5XXX_SDRAM_CONFIG1 = SDRAM_CONFIG1;
  84        *(vu_long *) MPC5XXX_SDRAM_CONFIG2 = SDRAM_CONFIG2;
  85        __asm__ volatile ("sync");
  86
  87        /* set tap delay */
  88        *(vu_long *) MPC5XXX_CDM_PORCFG = SDRAM_TAPDELAY;
  89        __asm__ volatile ("sync");
  90
  91        /* find RAM size using SDRAM CS0 only */
  92        sdram_start(0);
  93        test1 = get_ram_size((long *) CONFIG_SYS_SDRAM_BASE, 0x80000000);
  94        sdram_start(1);
  95        test2 = get_ram_size((long *) CONFIG_SYS_SDRAM_BASE, 0x80000000);
  96
  97        if (test1 > test2) {
  98                sdram_start(0);
  99                dramsize = test1;
 100        } else {
 101                dramsize = test2;
 102        }
 103
 104        /* memory smaller than 1MB is impossible */
 105        if (dramsize < (1 << 20)) {
 106                dramsize = 0;
 107        }
 108
 109        /* set SDRAM CS0 size according to the amount of RAM found */
 110        if (dramsize > 0) {
 111                *(vu_long *) MPC5XXX_SDRAM_CS0CFG =
 112                    0x13 + __builtin_ffs(dramsize >> 20) - 1;
 113                /* let SDRAM CS1 start right after CS0 */
 114                *(vu_long *) MPC5XXX_SDRAM_CS1CFG = dramsize + 0x0000001e;      /* 2G */
 115        } else {
 116#if 0
 117                *(vu_long *) MPC5XXX_SDRAM_CS0CFG = 0;  /* disabled */
 118                /* let SDRAM CS1 start right after CS0 */
 119                *(vu_long *) MPC5XXX_SDRAM_CS1CFG = dramsize + 0x0000001e;      /* 2G */
 120#else
 121                *(vu_long *) MPC5XXX_SDRAM_CS0CFG =
 122                    0x13 + __builtin_ffs(0x08000000 >> 20) - 1;
 123                /* let SDRAM CS1 start right after CS0 */
 124                *(vu_long *) MPC5XXX_SDRAM_CS1CFG = 0x08000000 + 0x0000001e;    /* 2G */
 125#endif
 126        }
 127
 128#if 0
 129        /* find RAM size using SDRAM CS1 only */
 130        sdram_start(0);
 131        get_ram_size((ulong *) (CONFIG_SYS_SDRAM_BASE + dramsize), 0x80000000);
 132        sdram_start(1);
 133        get_ram_size((ulong *) (CONFIG_SYS_SDRAM_BASE + dramsize), 0x80000000);
 134        sdram_start(0);
 135#endif
 136        /* set SDRAM CS1 size according to the amount of RAM found */
 137
 138        *(vu_long *) MPC5XXX_SDRAM_CS1CFG = dramsize;   /* disabled */
 139
 140        init_power_switch();
 141        return (dramsize);
 142}
 143
 144int checkboard(void)
 145{
 146        puts("Board: esd ParaFinder (pf5200)\n");
 147        return 0;
 148}
 149
 150void flash_preinit(void)
 151{
 152        /*
 153         * Now, when we are in RAM, enable flash write
 154         * access for detection process.
 155         * Note that CS_BOOT cannot be cleared when
 156         * executing in flash.
 157         */
 158        *(vu_long *) MPC5XXX_BOOTCS_CFG &= ~0x1;        /* clear RO */
 159}
 160
 161void flash_afterinit(ulong size)
 162{
 163        if (size == 0x02000000) {
 164                /* adjust mapping */
 165                *(vu_long *) MPC5XXX_BOOTCS_START =
 166                    *(vu_long *) MPC5XXX_CS0_START =
 167                    START_REG(CONFIG_SYS_BOOTCS_START | size);
 168                *(vu_long *) MPC5XXX_BOOTCS_STOP =
 169                    *(vu_long *) MPC5XXX_CS0_STOP =
 170                    STOP_REG(CONFIG_SYS_BOOTCS_START | size, size);
 171        }
 172}
 173
 174#ifdef  CONFIG_PCI
 175static struct pci_controller hose;
 176
 177extern void pci_mpc5xxx_init(struct pci_controller *);
 178
 179void pci_init_board(void) {
 180        pci_mpc5xxx_init(&hose);
 181}
 182#endif
 183
 184#if defined(CONFIG_CMD_IDE) && defined(CONFIG_IDE_RESET)
 185
 186void init_ide_reset(void)
 187{
 188        debug("init_ide_reset\n");
 189
 190        /* Configure PSC1_4 as GPIO output for ATA reset */
 191        *(vu_long *) MPC5XXX_WU_GPIO_ENABLE |= GPIO_PSC1_4;
 192        *(vu_long *) MPC5XXX_WU_GPIO_DIR |= GPIO_PSC1_4;
 193}
 194
 195void ide_set_reset(int idereset)
 196{
 197        debug("ide_reset(%d)\n", idereset);
 198
 199        if (idereset) {
 200                *(vu_long *) MPC5XXX_WU_GPIO_DATA_O &= ~GPIO_PSC1_4;
 201        } else {
 202                *(vu_long *) MPC5XXX_WU_GPIO_DATA_O |= GPIO_PSC1_4;
 203        }
 204}
 205#endif
 206
 207#define MPC5XXX_SIMPLEIO_GPIO_ENABLE       (MPC5XXX_GPIO + 0x0004)
 208#define MPC5XXX_SIMPLEIO_GPIO_DIR          (MPC5XXX_GPIO + 0x000C)
 209#define MPC5XXX_SIMPLEIO_GPIO_DATA_OUTPUT  (MPC5XXX_GPIO + 0x0010)
 210#define MPC5XXX_SIMPLEIO_GPIO_DATA_INPUT   (MPC5XXX_GPIO + 0x0014)
 211
 212#define MPC5XXX_INTERRUPT_GPIO_ENABLE      (MPC5XXX_GPIO + 0x0020)
 213#define MPC5XXX_INTERRUPT_GPIO_DIR         (MPC5XXX_GPIO + 0x0028)
 214#define MPC5XXX_INTERRUPT_GPIO_DATA_OUTPUT (MPC5XXX_GPIO + 0x002C)
 215#define MPC5XXX_INTERRUPT_GPIO_STATUS      (MPC5XXX_GPIO + 0x003C)
 216
 217#define GPIO_WU6        0x40000000UL
 218#define GPIO_USB0       0x00010000UL
 219#define GPIO_USB9       0x08000000UL
 220#define GPIO_USB9S      0x00080000UL
 221
 222void init_power_switch(void)
 223{
 224        debug("init_power_switch\n");
 225
 226        /* Configure GPIO_WU6 as GPIO output for ATA reset */
 227        *(vu_long *) MPC5XXX_WU_GPIO_DATA_O |= GPIO_WU6;
 228        *(vu_long *) MPC5XXX_WU_GPIO_ENABLE |= GPIO_WU6;
 229        *(vu_long *) MPC5XXX_WU_GPIO_DIR |= GPIO_WU6;
 230        __asm__ volatile ("sync");
 231
 232        *(vu_long *) MPC5XXX_SIMPLEIO_GPIO_DATA_OUTPUT &= ~GPIO_USB0;
 233        *(vu_long *) MPC5XXX_SIMPLEIO_GPIO_ENABLE |= GPIO_USB0;
 234        *(vu_long *) MPC5XXX_SIMPLEIO_GPIO_DIR |= GPIO_USB0;
 235        __asm__ volatile ("sync");
 236
 237        *(vu_long *) MPC5XXX_INTERRUPT_GPIO_DATA_OUTPUT &= ~GPIO_USB9;
 238        *(vu_long *) MPC5XXX_INTERRUPT_GPIO_ENABLE &= ~GPIO_USB9;
 239        __asm__ volatile ("sync");
 240
 241        if ((*(vu_long *) MPC5XXX_INTERRUPT_GPIO_STATUS & GPIO_USB9S) == 0) {
 242                *(vu_long *) MPC5XXX_SIMPLEIO_GPIO_DATA_OUTPUT |= GPIO_USB0;
 243                __asm__ volatile ("sync");
 244        }
 245        *(vu_char *) CONFIG_SYS_CS1_START = 0x02;       /* Red Power LED on */
 246        __asm__ volatile ("sync");
 247
 248        *(vu_char *) (CONFIG_SYS_CS1_START + 1) = 0x02; /* Disable driver for KB11 */
 249        __asm__ volatile ("sync");
 250}
 251
 252int board_eth_init(bd_t *bis)
 253{
 254        return pci_eth_init(bis);
 255}
 256
 257void power_set_reset(int power)
 258{
 259        debug("ide_set_reset(%d)\n", power);
 260
 261        if (power) {
 262                *(vu_long *) MPC5XXX_WU_GPIO_DATA_O &= ~GPIO_WU6;
 263                *(vu_long *) MPC5XXX_INTERRUPT_GPIO_DATA_OUTPUT &= ~GPIO_USB9;
 264        } else {
 265                *(vu_long *) MPC5XXX_WU_GPIO_DATA_O |= GPIO_WU6;
 266                if ((*(vu_long *) MPC5XXX_INTERRUPT_GPIO_STATUS & GPIO_USB9S) ==
 267                    0) {
 268                        *(vu_long *) MPC5XXX_SIMPLEIO_GPIO_DATA_OUTPUT |=
 269                            GPIO_USB0;
 270                }
 271
 272        }
 273}
 274
 275int do_poweroff(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 276{
 277        power_set_reset(1);
 278        return (0);
 279}
 280
 281U_BOOT_CMD(poweroff, 1, 1, do_poweroff, "Switch off power", "");
 282
 283int phypower(int flag)
 284{
 285        u32 addr;
 286        vu_long *reg;
 287        int status;
 288        pci_dev_t dev;
 289
 290        dev = PCI_BDF(0, 0x18, 0);
 291        status = pci_read_config_dword(dev, PCI_BASE_ADDRESS_1, &addr);
 292        if (status == 0) {
 293                reg = (vu_long *) (addr + 0x00000040);
 294                *reg |= 0x40000000;
 295                __asm__ volatile ("sync");
 296
 297                reg = (vu_long *) (addr + 0x001000c);
 298                *reg |= 0x20000000;
 299                __asm__ volatile ("sync");
 300
 301                reg = (vu_long *) (addr + 0x0010004);
 302                if (flag != 0) {
 303                        *reg &= ~0x20000000;
 304                } else {
 305                        *reg |= 0x20000000;
 306                }
 307                __asm__ volatile ("sync");
 308        }
 309        return (status);
 310}
 311
 312int do_phypower(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 313{
 314        if (argv[1][0] == '0')
 315                (void)phypower(0);
 316        else
 317                (void)phypower(1);
 318
 319        return (0);
 320}
 321
 322U_BOOT_CMD(phypower, 2, 2, do_phypower,
 323           "Switch power of ethernet phy", "");
 324
 325int do_writepci(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 326{
 327        unsigned int addr;
 328        unsigned int size;
 329        int i;
 330        volatile unsigned long *ptr;
 331
 332        addr = simple_strtol(argv[1], NULL, 16);
 333        size = simple_strtol(argv[2], NULL, 16);
 334
 335        printf("\nWriting at addr %08x, size %08x.\n", addr, size);
 336
 337        while (1) {
 338                ptr = (volatile unsigned long *)addr;
 339                for (i = 0; i < (size >> 2); i++) {
 340                        *ptr++ = i;
 341                }
 342
 343                /* Abort if ctrl-c was pressed */
 344                if (ctrlc()) {
 345                        puts("\nAbort\n");
 346                        return 0;
 347                }
 348                putc('.');
 349        }
 350        return 0;
 351}
 352
 353U_BOOT_CMD(writepci, 3, 1, do_writepci,
 354        "Write some data to pcibus",
 355        "<addr> <size>\n"
 356        ""
 357);
 358