uboot/board/bc3450/bc3450.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2003-2004
   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 * (C) Copyright 2004-2005
   9 * Martin Krause, TQ-Systems GmbH, martin.krause@tqs.de
  10 *
  11 * (C) Copyright 2006
  12 * Stefan Strobl, GERSYS GmbH, stefan.strobl@gersys.de
  13 *
  14 * See file CREDITS for list of people who contributed to this
  15 * project.
  16 *
  17 * This program is free software; you can redistribute it and/or
  18 * modify it under the terms of the GNU General Public License as
  19 * published by the Free Software Foundation; either version 2 of
  20 * the License, or (at your option) any later version.
  21 *
  22 * This program is distributed in the hope that it will be useful,
  23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  25 * GNU General Public License for more details.
  26 *
  27 * You should have received a copy of the GNU General Public License
  28 * along with this program; if not, write to the Free Software
  29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  30 * MA 02111-1307 USA
  31 */
  32
  33#include <common.h>
  34#include <mpc5xxx.h>
  35#include <pci.h>
  36#include <netdev.h>
  37
  38#ifdef CONFIG_VIDEO_SM501
  39#include <sm501.h>
  40#endif
  41
  42#if defined(CONFIG_MPC5200_DDR)
  43#include "mt46v16m16-75.h"
  44#else
  45#include "mt48lc16m16a2-75.h"
  46#endif
  47
  48#ifdef CONFIG_RTC_MPC5200
  49#include <rtc.h>
  50#endif
  51
  52#ifdef CONFIG_PS2MULT
  53void ps2mult_early_init(void);
  54#endif
  55
  56#ifndef CONFIG_SYS_RAMBOOT
  57static void sdram_start (int hi_addr)
  58{
  59        long hi_addr_bit = hi_addr ? 0x01000000 : 0;
  60
  61        /* unlock mode register */
  62        *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000000 |
  63                hi_addr_bit;
  64        __asm__ volatile ("sync");
  65
  66        /* precharge all banks */
  67        *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000002 |
  68                hi_addr_bit;
  69        __asm__ volatile ("sync");
  70
  71#if SDRAM_DDR
  72        /* set mode register: extended mode */
  73        *(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_EMODE;
  74        __asm__ volatile ("sync");
  75
  76        /* set mode register: reset DLL */
  77        *(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_MODE | 0x04000000;
  78        __asm__ volatile ("sync");
  79#endif
  80
  81        /* precharge all banks */
  82        *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000002 |
  83                hi_addr_bit;
  84        __asm__ volatile ("sync");
  85
  86        /* auto refresh */
  87        *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000004 |
  88                hi_addr_bit;
  89        __asm__ volatile ("sync");
  90
  91        /* set mode register */
  92        *(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_MODE;
  93        __asm__ volatile ("sync");
  94
  95        /* normal operation */
  96        *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | hi_addr_bit;
  97        __asm__ volatile ("sync");
  98}
  99#endif
 100
 101/*
 102 * ATTENTION: Although partially referenced initdram does NOT make real use
 103 *            use of CONFIG_SYS_SDRAM_BASE. The code does not work if CONFIG_SYS_SDRAM_BASE
 104 *            is something else than 0x00000000.
 105 */
 106
 107phys_size_t initdram (int board_type)
 108{
 109        ulong dramsize = 0;
 110        ulong dramsize2 = 0;
 111#ifndef CONFIG_SYS_RAMBOOT
 112        ulong test1, test2;
 113
 114        /* setup SDRAM chip selects */
 115        *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x0000001c; /* 512MB at 0x0 */
 116        *(vu_long *)MPC5XXX_SDRAM_CS1CFG = 0x40000000; /* disabled */
 117        __asm__ volatile ("sync");
 118
 119        /* setup config registers */
 120        *(vu_long *)MPC5XXX_SDRAM_CONFIG1 = SDRAM_CONFIG1;
 121        *(vu_long *)MPC5XXX_SDRAM_CONFIG2 = SDRAM_CONFIG2;
 122        __asm__ volatile ("sync");
 123
 124#if SDRAM_DDR
 125        /* set tap delay */
 126        *(vu_long *)MPC5XXX_CDM_PORCFG = SDRAM_TAPDELAY;
 127        __asm__ volatile ("sync");
 128#endif
 129
 130        /* find RAM size using SDRAM CS0 only */
 131        sdram_start(0);
 132        test1 = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE, 0x20000000);
 133        sdram_start(1);
 134        test2 = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE, 0x20000000);
 135        if (test1 > test2) {
 136                sdram_start(0);
 137                dramsize = test1;
 138        } else {
 139                dramsize = test2;
 140        }
 141
 142        /* memory smaller than 1MB is impossible */
 143        if (dramsize < (1 << 20)) {
 144                dramsize = 0;
 145        }
 146
 147        /* set SDRAM CS0 size according to the amount of RAM found */
 148        if (dramsize > 0) {
 149                *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x13 +
 150                        __builtin_ffs(dramsize >> 20) - 1;
 151        } else {
 152                *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0; /* disabled */
 153        }
 154
 155        /* let SDRAM CS1 start right after CS0 */
 156        *(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize + 0x0000001c; /* 512MB */
 157
 158        /* find RAM size using SDRAM CS1 only */
 159        sdram_start(0);
 160        test1 = get_ram_size((long *)(CONFIG_SYS_SDRAM_BASE + dramsize), 0x20000000);
 161        sdram_start(1);
 162        test2 = get_ram_size((long *)(CONFIG_SYS_SDRAM_BASE + dramsize), 0x20000000);
 163        if (test1 > test2) {
 164                sdram_start(0);
 165                dramsize2 = test1;
 166        } else {
 167                dramsize2 = test2;
 168        }
 169
 170        /* memory smaller than 1MB is impossible */
 171        if (dramsize2 < (1 << 20)) {
 172                dramsize2 = 0;
 173        }
 174
 175        /* set SDRAM CS1 size according to the amount of RAM found */
 176        if (dramsize2 > 0) {
 177                *(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize
 178                        | (0x13 + __builtin_ffs(dramsize2 >> 20) - 1);
 179        } else {
 180                *(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize; /* disabled */
 181        }
 182
 183#else /* CONFIG_SYS_RAMBOOT */
 184
 185        /* retrieve size of memory connected to SDRAM CS0 */
 186        dramsize = *(vu_long *)MPC5XXX_SDRAM_CS0CFG & 0xFF;
 187        if (dramsize >= 0x13) {
 188                dramsize = (1 << (dramsize - 0x13)) << 20;
 189        } else {
 190                dramsize = 0;
 191        }
 192
 193        /* retrieve size of memory connected to SDRAM CS1 */
 194        dramsize2 = *(vu_long *)MPC5XXX_SDRAM_CS1CFG & 0xFF;
 195        if (dramsize2 >= 0x13) {
 196                dramsize2 = (1 << (dramsize2 - 0x13)) << 20;
 197        } else {
 198                dramsize2 = 0;
 199        }
 200
 201#endif /* CONFIG_SYS_RAMBOOT */
 202
 203        return dramsize;
 204}
 205
 206int checkboard (void)
 207{
 208#if defined (CONFIG_TQM5200)
 209        puts ("Board: TQM5200 (TQ-Components GmbH)\n");
 210#endif
 211
 212#if defined (CONFIG_BC3450)
 213        puts ("Dev:   GERSYS BC3450\n");
 214#endif
 215
 216        return 0;
 217}
 218
 219void flash_preinit(void)
 220{
 221        /*
 222         * Now, when we are in RAM, enable flash write
 223         * access for detection process.
 224         * Note that CS_BOOT cannot be cleared when
 225         * executing in flash.
 226         */
 227        *(vu_long *)MPC5XXX_BOOTCS_CFG &= ~0x1;         /* clear RO        */
 228}
 229
 230
 231#ifdef  CONFIG_PCI
 232static struct pci_controller hose;
 233
 234extern void pci_mpc5xxx_init(struct pci_controller *);
 235
 236void pci_init_board(void)
 237{
 238        pci_mpc5xxx_init(&hose);
 239}
 240#endif
 241
 242#if defined(CONFIG_CMD_IDE) && defined(CONFIG_IDE_RESET)
 243
 244void init_ide_reset (void)
 245{
 246        debug ("init_ide_reset\n");
 247
 248        /* Configure PSC1_4 as GPIO output for ATA reset */
 249        *(vu_long *) MPC5XXX_WU_GPIO_ENABLE |= GPIO_PSC1_4;
 250        *(vu_long *) MPC5XXX_WU_GPIO_DIR    |= GPIO_PSC1_4;
 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        } else {
 260                *(vu_long *) MPC5XXX_WU_GPIO_DATA_O |=  GPIO_PSC1_4;
 261        }
 262}
 263#endif
 264
 265#ifdef CONFIG_POST
 266/*
 267 * Reads GPIO pin PSC6_3. A keypress is reported, if PSC6_3 is low. If PSC6_3
 268 * is left open, no keypress is detected.
 269 */
 270int post_hotkeys_pressed(void)
 271{
 272        struct mpc5xxx_gpio *gpio;
 273
 274        gpio = (struct mpc5xxx_gpio*) MPC5XXX_GPIO;
 275
 276        /*
 277         * Configure PSC6_1 and PSC6_3 as GPIO. PSC6 then couldn't be used in
 278         * CODEC or UART mode. Consumer IrDA should still be possible.
 279         */
 280        gpio->port_config &= ~(0x07000000);
 281        gpio->port_config |=   0x03000000;
 282
 283        /* Enable GPIO for GPIO_IRDA_1 (IR_USB_CLK pin) = PSC6_3 */
 284        gpio->simple_gpioe |= 0x20000000;
 285
 286        /* Configure GPIO_IRDA_1 as input */
 287        gpio->simple_ddr &= ~(0x20000000);
 288
 289        return ((gpio->simple_ival & 0x20000000) ? 0 : 1);
 290}
 291#endif
 292
 293#ifdef CONFIG_BOARD_EARLY_INIT_R
 294int board_early_init_r (void)
 295{
 296#ifdef CONFIG_RTC_MPC5200
 297        struct rtc_time t;
 298
 299        /* set to Wed Dec 31 19:00:00 1969 */
 300        t.tm_sec = t.tm_min = 0;
 301        t.tm_hour = 19;
 302        t.tm_mday = 31;
 303        t.tm_mon = 12;
 304        t.tm_year = 1969;
 305        t.tm_wday = 3;
 306
 307        rtc_set(&t);
 308#endif /* CONFIG_RTC_MPC5200 */
 309
 310#ifdef CONFIG_PS2MULT
 311        ps2mult_early_init();
 312#endif /* CONFIG_PS2MULT */
 313        return (0);
 314}
 315#endif /* CONFIG_BOARD_EARLY_INIT_R */
 316
 317
 318int last_stage_init (void)
 319{
 320        /*
 321         * auto scan for really existing devices and re-set chip select
 322         * configuration.
 323         */
 324        u16 save, tmp;
 325        int restore;
 326
 327        /*
 328         * Check for SRAM and SRAM size
 329         */
 330
 331        /* save original SRAM content  */
 332        save = *(volatile u16 *)CONFIG_SYS_CS2_START;
 333        restore = 1;
 334
 335        /* write test pattern to SRAM */
 336        *(volatile u16 *)CONFIG_SYS_CS2_START = 0xA5A5;
 337        __asm__ volatile ("sync");
 338        /*
 339         * Put a different pattern on the data lines: otherwise they may float
 340         * long enough to read back what we wrote.
 341         */
 342        tmp = *(volatile u16 *)CONFIG_SYS_FLASH_BASE;
 343        if (tmp == 0xA5A5)
 344                puts ("!! possible error in SRAM detection\n");
 345
 346        if (*(volatile u16 *)CONFIG_SYS_CS2_START != 0xA5A5) {
 347                /* no SRAM at all, disable cs */
 348                *(vu_long *)MPC5XXX_ADDECR &= ~(1 << 18);
 349                *(vu_long *)MPC5XXX_CS2_START = 0x0000FFFF;
 350                *(vu_long *)MPC5XXX_CS2_STOP = 0x0000FFFF;
 351                restore = 0;
 352                __asm__ volatile ("sync");
 353        } else if (*(volatile u16 *)(CONFIG_SYS_CS2_START + (1<<19)) == 0xA5A5) {
 354                /* make sure that we access a mirrored address */
 355                *(volatile u16 *)CONFIG_SYS_CS2_START = 0x1111;
 356                __asm__ volatile ("sync");
 357                if (*(volatile u16 *)(CONFIG_SYS_CS2_START + (1<<19)) == 0x1111) {
 358                        /* SRAM size = 512 kByte */
 359                        *(vu_long *)MPC5XXX_CS2_STOP = STOP_REG(CONFIG_SYS_CS2_START,
 360                                                                0x80000);
 361                        __asm__ volatile ("sync");
 362                        puts ("SRAM:  512 kB\n");
 363                }
 364                else
 365                        puts ("!! possible error in SRAM detection\n");
 366        } else {
 367                puts ("SRAM:  1 MB\n");
 368        }
 369        /* restore origianl SRAM content  */
 370        if (restore) {
 371                *(volatile u16 *)CONFIG_SYS_CS2_START = save;
 372                __asm__ volatile ("sync");
 373        }
 374
 375        /*
 376         * Check for Grafic Controller
 377         */
 378
 379        /* save origianl FB content  */
 380        save = *(volatile u16 *)CONFIG_SYS_CS1_START;
 381        restore = 1;
 382
 383        /* write test pattern to FB memory */
 384        *(volatile u16 *)CONFIG_SYS_CS1_START = 0xA5A5;
 385        __asm__ volatile ("sync");
 386        /*
 387         * Put a different pattern on the data lines: otherwise they may float
 388         * long enough to read back what we wrote.
 389         */
 390        tmp = *(volatile u16 *)CONFIG_SYS_FLASH_BASE;
 391        if (tmp == 0xA5A5)
 392                puts ("!! possible error in grafic controller detection\n");
 393
 394        if (*(volatile u16 *)CONFIG_SYS_CS1_START != 0xA5A5) {
 395                /* no grafic controller at all, disable cs */
 396                *(vu_long *)MPC5XXX_ADDECR &= ~(1 << 17);
 397                *(vu_long *)MPC5XXX_CS1_START = 0x0000FFFF;
 398                *(vu_long *)MPC5XXX_CS1_STOP = 0x0000FFFF;
 399                restore = 0;
 400                __asm__ volatile ("sync");
 401        } else {
 402                puts ("VGA:   SMI501 (Voyager) with 8 MB\n");
 403        }
 404        /* restore origianl FB content  */
 405        if (restore) {
 406                *(volatile u16 *)CONFIG_SYS_CS1_START = save;
 407                __asm__ volatile ("sync");
 408        }
 409
 410        return 0;
 411}
 412
 413#ifdef CONFIG_VIDEO_SM501
 414
 415#define DISPLAY_WIDTH   640
 416#define DISPLAY_HEIGHT  480
 417
 418#ifdef CONFIG_VIDEO_SM501_8BPP
 419#error CONFIG_VIDEO_SM501_8BPP not supported.
 420#endif /* CONFIG_VIDEO_SM501_8BPP */
 421
 422#ifdef CONFIG_VIDEO_SM501_16BPP
 423#error CONFIG_VIDEO_SM501_16BPP not supported.
 424#endif /* CONFIG_VIDEO_SM501_16BPP */
 425
 426#ifdef CONFIG_VIDEO_SM501_32BPP
 427static const SMI_REGS init_regs [] =
 428{
 429#if defined (CONFIG_BC3450_FP) && !defined (CONFIG_BC3450_CRT)
 430        /* FP only */
 431        {0x00004, 0x0},
 432        {0x00048, 0x00021807},
 433        {0x0004C, 0x091a0a01},
 434        {0x00054, 0x1},
 435        {0x00040, 0x00021807},
 436        {0x00044, 0x091a0a01},
 437        {0x00054, 0x0},
 438        {0x80000, 0x01013106},
 439        {0x80004, 0xc428bb17},
 440        {0x80000, 0x03013106},
 441        {0x8000C, 0x00000000},
 442        {0x80010, 0x0a000a00},
 443        {0x80014, 0x02800000},
 444        {0x80018, 0x01e00000},
 445        {0x8001C, 0x00000000},
 446        {0x80020, 0x01e00280},
 447        {0x80024, 0x02fa027f},
 448        {0x80028, 0x004a028b},
 449        {0x8002C, 0x020c01df},
 450        {0x80030, 0x000201e9},
 451        {0x80200, 0x00010200},
 452        {0x80000, 0x0f013106},
 453#elif defined (CONFIG_BC3450_CRT) && !defined (CONFIG_BC3450_FP)
 454        /* CRT only */
 455        {0x00004, 0x0},
 456        {0x00048, 0x00021807},
 457        {0x0004C, 0x10090a01},
 458        {0x00054, 0x1},
 459        {0x00040, 0x00021807},
 460        {0x00044, 0x10090a01},
 461        {0x00054, 0x0},
 462        {0x80200, 0x00010000},
 463        {0x80204, 0x0},
 464        {0x80208, 0x0A000A00},
 465        {0x8020C, 0x02fa027f},
 466        {0x80210, 0x004a028b},
 467        {0x80214, 0x020c01df},
 468        {0x80218, 0x000201e9},
 469        {0x80200, 0x00013306},
 470#else   /* panel + CRT */
 471        {0x00004, 0x0},
 472        {0x00048, 0x00021807},
 473        {0x0004C, 0x091a0a01},
 474        {0x00054, 0x1},
 475        {0x00040, 0x00021807},
 476        {0x00044, 0x091a0a01},
 477        {0x00054, 0x0},
 478        {0x80000, 0x0f013106},
 479        {0x80004, 0xc428bb17},
 480        {0x8000C, 0x00000000},
 481        {0x80010, 0x0a000a00},
 482        {0x80014, 0x02800000},
 483        {0x80018, 0x01e00000},
 484        {0x8001C, 0x00000000},
 485        {0x80020, 0x01e00280},
 486        {0x80024, 0x02fa027f},
 487        {0x80028, 0x004a028b},
 488        {0x8002C, 0x020c01df},
 489        {0x80030, 0x000201e9},
 490        {0x80200, 0x00010000},
 491#endif
 492        {0, 0}
 493};
 494#endif /* CONFIG_VIDEO_SM501_32BPP */
 495
 496#ifdef CONFIG_CONSOLE_EXTRA_INFO
 497/*
 498 * Return text to be printed besides the logo.
 499 */
 500void video_get_info_str (int line_number, char *info)
 501{
 502        if (line_number == 1) {
 503#if defined (CONFIG_TQM5200)
 504            strcpy (info, " Board: TQM5200 (TQ-Components GmbH)");
 505#else
 506#error No supported board selected
 507#endif /* CONFIG_TQM5200 */
 508
 509#if defined (CONFIG_BC3450)
 510        } else if (line_number == 2) {
 511            strcpy (info, " Dev:   GERSYS BC3450");
 512#endif /* CONFIG_BC3450 */
 513        }
 514        else {
 515                info [0] = '\0';
 516        }
 517}
 518#endif
 519
 520/*
 521 * Returns SM501 register base address. First thing called in the
 522 * driver. Checks if SM501 is physically present.
 523 */
 524unsigned int board_video_init (void)
 525{
 526        u16 save, tmp;
 527        int restore, ret;
 528
 529        /*
 530         * Check for Grafic Controller
 531         */
 532
 533        /* save origianl FB content  */
 534        save = *(volatile u16 *)CONFIG_SYS_CS1_START;
 535        restore = 1;
 536
 537        /* write test pattern to FB memory */
 538        *(volatile u16 *)CONFIG_SYS_CS1_START = 0xA5A5;
 539        __asm__ volatile ("sync");
 540        /*
 541         * Put a different pattern on the data lines: otherwise they may float
 542         * long enough to read back what we wrote.
 543         */
 544        tmp = *(volatile u16 *)CONFIG_SYS_FLASH_BASE;
 545        if (tmp == 0xA5A5)
 546                puts ("!! possible error in grafic controller detection\n");
 547
 548        if (*(volatile u16 *)CONFIG_SYS_CS1_START != 0xA5A5) {
 549                /* no grafic controller found */
 550                restore = 0;
 551                ret = 0;
 552        } else {
 553            ret = SM501_MMIO_BASE;
 554        }
 555
 556        if (restore) {
 557                *(volatile u16 *)CONFIG_SYS_CS1_START = save;
 558                __asm__ volatile ("sync");
 559        }
 560        return ret;
 561}
 562
 563/*
 564 * Returns SM501 framebuffer address
 565 */
 566unsigned int board_video_get_fb (void)
 567{
 568        return SM501_FB_BASE;
 569}
 570
 571/*
 572 * Called after initializing the SM501 and before clearing the screen.
 573 */
 574void board_validate_screen (unsigned int base)
 575{
 576}
 577
 578/*
 579 * Return a pointer to the initialization sequence.
 580 */
 581const SMI_REGS *board_get_regs (void)
 582{
 583        return init_regs;
 584}
 585
 586int board_get_width (void)
 587{
 588        return DISPLAY_WIDTH;
 589}
 590
 591int board_get_height (void)
 592{
 593        return DISPLAY_HEIGHT;
 594}
 595
 596#endif /* CONFIG_VIDEO_SM501 */
 597
 598int board_eth_init(bd_t *bis)
 599{
 600        cpu_eth_init(bis); /* Built in FEC comes first */
 601        return pci_eth_init(bis);
 602}
 603