uboot/board/freescale/mpc8360emds/mpc8360emds.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2006 Freescale Semiconductor, Inc.
   3 * Dave Liu <daveliu@freescale.com>
   4 *
   5 * See file CREDITS for list of people who contributed to this
   6 * project.
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License as
  10 * published by the Free Software Foundation; either version 2 of
  11 * the License, or (at your option) any later version.
  12 */
  13
  14#include <common.h>
  15#include <ioports.h>
  16#include <mpc83xx.h>
  17#include <i2c.h>
  18#include <miiphy.h>
  19#if defined(CONFIG_PCI)
  20#include <pci.h>
  21#endif
  22#include <spd_sdram.h>
  23#include <asm/mmu.h>
  24#include <asm/io.h>
  25#if defined(CONFIG_OF_LIBFDT)
  26#include <libfdt.h>
  27#endif
  28#include <hwconfig.h>
  29#include <fdt_support.h>
  30#if defined(CONFIG_PQ_MDS_PIB)
  31#include "../common/pq-mds-pib.h"
  32#endif
  33#include "../../../drivers/qe/uec.h"
  34
  35const qe_iop_conf_t qe_iop_conf_tab[] = {
  36        /* GETH1 */
  37        {0,  3, 1, 0, 1}, /* TxD0 */
  38        {0,  4, 1, 0, 1}, /* TxD1 */
  39        {0,  5, 1, 0, 1}, /* TxD2 */
  40        {0,  6, 1, 0, 1}, /* TxD3 */
  41        {1,  6, 1, 0, 3}, /* TxD4 */
  42        {1,  7, 1, 0, 1}, /* TxD5 */
  43        {1,  9, 1, 0, 2}, /* TxD6 */
  44        {1, 10, 1, 0, 2}, /* TxD7 */
  45        {0,  9, 2, 0, 1}, /* RxD0 */
  46        {0, 10, 2, 0, 1}, /* RxD1 */
  47        {0, 11, 2, 0, 1}, /* RxD2 */
  48        {0, 12, 2, 0, 1}, /* RxD3 */
  49        {0, 13, 2, 0, 1}, /* RxD4 */
  50        {1,  1, 2, 0, 2}, /* RxD5 */
  51        {1,  0, 2, 0, 2}, /* RxD6 */
  52        {1,  4, 2, 0, 2}, /* RxD7 */
  53        {0,  7, 1, 0, 1}, /* TX_EN */
  54        {0,  8, 1, 0, 1}, /* TX_ER */
  55        {0, 15, 2, 0, 1}, /* RX_DV */
  56        {0, 16, 2, 0, 1}, /* RX_ER */
  57        {0,  0, 2, 0, 1}, /* RX_CLK */
  58        {2,  9, 1, 0, 3}, /* GTX_CLK - CLK10 */
  59        {2,  8, 2, 0, 1}, /* GTX125 - CLK9 */
  60        /* GETH2 */
  61        {0, 17, 1, 0, 1}, /* TxD0 */
  62        {0, 18, 1, 0, 1}, /* TxD1 */
  63        {0, 19, 1, 0, 1}, /* TxD2 */
  64        {0, 20, 1, 0, 1}, /* TxD3 */
  65        {1,  2, 1, 0, 1}, /* TxD4 */
  66        {1,  3, 1, 0, 2}, /* TxD5 */
  67        {1,  5, 1, 0, 3}, /* TxD6 */
  68        {1,  8, 1, 0, 3}, /* TxD7 */
  69        {0, 23, 2, 0, 1}, /* RxD0 */
  70        {0, 24, 2, 0, 1}, /* RxD1 */
  71        {0, 25, 2, 0, 1}, /* RxD2 */
  72        {0, 26, 2, 0, 1}, /* RxD3 */
  73        {0, 27, 2, 0, 1}, /* RxD4 */
  74        {1, 12, 2, 0, 2}, /* RxD5 */
  75        {1, 13, 2, 0, 3}, /* RxD6 */
  76        {1, 11, 2, 0, 2}, /* RxD7 */
  77        {0, 21, 1, 0, 1}, /* TX_EN */
  78        {0, 22, 1, 0, 1}, /* TX_ER */
  79        {0, 29, 2, 0, 1}, /* RX_DV */
  80        {0, 30, 2, 0, 1}, /* RX_ER */
  81        {0, 31, 2, 0, 1}, /* RX_CLK */
  82        {2,  2, 1, 0, 2}, /* GTX_CLK = CLK10 */
  83        {2,  3, 2, 0, 1}, /* GTX125 - CLK4 */
  84
  85        {0,  1, 3, 0, 2}, /* MDIO */
  86        {0,  2, 1, 0, 1}, /* MDC */
  87
  88        {5,  0, 1, 0, 2}, /* UART2_SOUT */
  89        {5,  1, 2, 0, 3}, /* UART2_CTS */
  90        {5,  2, 1, 0, 1}, /* UART2_RTS */
  91        {5,  3, 2, 0, 2}, /* UART2_SIN */
  92
  93        {0,  0, 0, 0, QE_IOP_TAB_END}, /* END of table */
  94};
  95
  96/* Handle "mpc8360ea rev.2.1 erratum 2: RGMII Timing"? */
  97static int board_handle_erratum2(void)
  98{
  99        const immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
 100
 101        return REVID_MAJOR(immr->sysconf.spridr) == 2 &&
 102               REVID_MINOR(immr->sysconf.spridr) == 1;
 103}
 104
 105int board_early_init_f(void)
 106{
 107        const immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
 108        u8 *bcsr = (u8 *)CONFIG_SYS_BCSR;
 109
 110        /* Enable flash write */
 111        bcsr[0xa] &= ~0x04;
 112
 113        /* Disable G1TXCLK, G2TXCLK h/w buffers (rev.2.x h/w bug workaround) */
 114        if (REVID_MAJOR(immr->sysconf.spridr) == 2)
 115                bcsr[0xe] = 0x30;
 116
 117        /* Enable second UART */
 118        bcsr[0x9] &= ~0x01;
 119
 120        if (board_handle_erratum2()) {
 121                void *immap = (immap_t *)(CONFIG_SYS_IMMR + 0x14a8);
 122
 123                /*
 124                 * IMMR + 0x14A8[4:5] = 11 (clk delay for UCC 2)
 125                 * IMMR + 0x14A8[18:19] = 11 (clk delay for UCC 1)
 126                 */
 127                setbits_be32(immap, 0x0c003000);
 128
 129                /*
 130                 * IMMR + 0x14AC[20:27] = 10101010
 131                 * (data delay for both UCC's)
 132                 */
 133                clrsetbits_be32(immap + 4, 0xff0, 0xaa0);
 134        }
 135        return 0;
 136}
 137
 138int board_early_init_r(void)
 139{
 140#ifdef CONFIG_PQ_MDS_PIB
 141        pib_init();
 142#endif
 143        return 0;
 144}
 145
 146#ifdef CONFIG_UEC_ETH
 147static uec_info_t uec_info[] = {
 148#ifdef CONFIG_UEC_ETH1
 149        STD_UEC_INFO(1),
 150#endif
 151#ifdef CONFIG_UEC_ETH2
 152        STD_UEC_INFO(2),
 153#endif
 154};
 155
 156int board_eth_init(bd_t *bd)
 157{
 158        if (board_handle_erratum2()) {
 159                int i;
 160
 161                for (i = 0; i < ARRAY_SIZE(uec_info); i++)
 162                        uec_info[i].enet_interface = ENET_1000_RGMII_RXID;
 163        }
 164        return uec_eth_init(bd, uec_info, ARRAY_SIZE(uec_info));
 165}
 166#endif /* CONFIG_UEC_ETH */
 167
 168#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
 169extern void ddr_enable_ecc(unsigned int dram_size);
 170#endif
 171int fixed_sdram(void);
 172static int sdram_init(unsigned int base);
 173
 174phys_size_t initdram(int board_type)
 175{
 176        volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
 177        u32 msize = 0;
 178        u32 lbc_sdram_size;
 179
 180        if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32) im)
 181                return -1;
 182
 183        /* DDR SDRAM - Main SODIMM */
 184        im->sysconf.ddrlaw[0].bar = CONFIG_SYS_DDR_BASE & LAWBAR_BAR;
 185#if defined(CONFIG_SPD_EEPROM)
 186        msize = spd_sdram();
 187#else
 188        msize = fixed_sdram();
 189#endif
 190
 191#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
 192        /*
 193         * Initialize DDR ECC byte
 194         */
 195        ddr_enable_ecc(msize * 1024 * 1024);
 196#endif
 197        /*
 198         * Initialize SDRAM if it is on local bus.
 199         */
 200        lbc_sdram_size = sdram_init(msize * 1024 * 1024);
 201        if (!msize)
 202                msize = lbc_sdram_size;
 203
 204        /* return total bus SDRAM size(bytes)  -- DDR */
 205        return (msize * 1024 * 1024);
 206}
 207
 208#if !defined(CONFIG_SPD_EEPROM)
 209/*************************************************************************
 210 *  fixed sdram init -- doesn't use serial presence detect.
 211 ************************************************************************/
 212int fixed_sdram(void)
 213{
 214        volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
 215        u32 msize = 0;
 216        u32 ddr_size;
 217        u32 ddr_size_log2;
 218
 219        msize = CONFIG_SYS_DDR_SIZE;
 220        for (ddr_size = msize << 20, ddr_size_log2 = 0;
 221             (ddr_size > 1); ddr_size = ddr_size >> 1, ddr_size_log2++) {
 222                if (ddr_size & 1) {
 223                        return -1;
 224                }
 225        }
 226        im->sysconf.ddrlaw[0].ar =
 227            LAWAR_EN | ((ddr_size_log2 - 1) & LAWAR_SIZE);
 228#if (CONFIG_SYS_DDR_SIZE != 256)
 229#warning Currenly any ddr size other than 256 is not supported
 230#endif
 231#ifdef CONFIG_DDR_II
 232        im->ddr.csbnds[0].csbnds = CONFIG_SYS_DDR_CS0_BNDS;
 233        im->ddr.cs_config[0] = CONFIG_SYS_DDR_CS0_CONFIG;
 234        im->ddr.timing_cfg_0 = CONFIG_SYS_DDR_TIMING_0;
 235        im->ddr.timing_cfg_1 = CONFIG_SYS_DDR_TIMING_1;
 236        im->ddr.timing_cfg_2 = CONFIG_SYS_DDR_TIMING_2;
 237        im->ddr.timing_cfg_3 = CONFIG_SYS_DDR_TIMING_3;
 238        im->ddr.sdram_cfg = CONFIG_SYS_DDR_SDRAM_CFG;
 239        im->ddr.sdram_cfg2 = CONFIG_SYS_DDR_SDRAM_CFG2;
 240        im->ddr.sdram_mode = CONFIG_SYS_DDR_MODE;
 241        im->ddr.sdram_mode2 = CONFIG_SYS_DDR_MODE2;
 242        im->ddr.sdram_interval = CONFIG_SYS_DDR_INTERVAL;
 243        im->ddr.sdram_clk_cntl = CONFIG_SYS_DDR_CLK_CNTL;
 244#else
 245        im->ddr.csbnds[0].csbnds = 0x00000007;
 246        im->ddr.csbnds[1].csbnds = 0x0008000f;
 247
 248        im->ddr.cs_config[0] = CONFIG_SYS_DDR_CONFIG;
 249        im->ddr.cs_config[1] = CONFIG_SYS_DDR_CONFIG;
 250
 251        im->ddr.timing_cfg_1 = CONFIG_SYS_DDR_TIMING_1;
 252        im->ddr.timing_cfg_2 = CONFIG_SYS_DDR_TIMING_2;
 253        im->ddr.sdram_cfg = CONFIG_SYS_DDR_CONTROL;
 254
 255        im->ddr.sdram_mode = CONFIG_SYS_DDR_MODE;
 256        im->ddr.sdram_interval = CONFIG_SYS_DDR_INTERVAL;
 257#endif
 258        udelay(200);
 259        im->ddr.sdram_cfg |= SDRAM_CFG_MEM_EN;
 260
 261        return msize;
 262}
 263#endif                          /*!CONFIG_SYS_SPD_EEPROM */
 264
 265int checkboard(void)
 266{
 267        puts("Board: Freescale MPC8360EMDS\n");
 268        return 0;
 269}
 270
 271/*
 272 * if MPC8360EMDS is soldered with SDRAM
 273 */
 274#ifdef CONFIG_SYS_LB_SDRAM
 275/*
 276 * Initialize SDRAM memory on the Local Bus.
 277 */
 278
 279static int sdram_init(unsigned int base)
 280{
 281        volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
 282        volatile fsl_lbus_t *lbc = &immap->lbus;
 283        const int sdram_size = CONFIG_SYS_LBC_SDRAM_SIZE * 1024 * 1024;
 284        int rem = base % sdram_size;
 285        uint *sdram_addr;
 286
 287        /* window base address should be aligned to the window size */
 288        if (rem)
 289                base = base - rem + sdram_size;
 290
 291        sdram_addr = (uint *)base;
 292        /*
 293         * Setup SDRAM Base and Option Registers
 294         */
 295        immap->lbus.bank[2].br = base | CONFIG_SYS_BR2;
 296        immap->lbus.bank[2].or = CONFIG_SYS_OR2;
 297        immap->sysconf.lblaw[2].bar = base;
 298        immap->sysconf.lblaw[2].ar = CONFIG_SYS_LBLAWAR2;
 299
 300        /*setup mtrpt, lsrt and lbcr for LB bus */
 301        lbc->lbcr = CONFIG_SYS_LBC_LBCR;
 302        lbc->mrtpr = CONFIG_SYS_LBC_MRTPR;
 303        lbc->lsrt = CONFIG_SYS_LBC_LSRT;
 304        asm("sync");
 305
 306        /*
 307         * Configure the SDRAM controller Machine Mode Register.
 308         */
 309        lbc->lsdmr = CONFIG_SYS_LBC_LSDMR_5;    /* Normal Operation */
 310        lbc->lsdmr = CONFIG_SYS_LBC_LSDMR_1;    /* Precharge All Banks */
 311        asm("sync");
 312        *sdram_addr = 0xff;
 313        udelay(100);
 314
 315        /*
 316         * We need do 8 times auto refresh operation.
 317         */
 318        lbc->lsdmr = CONFIG_SYS_LBC_LSDMR_2;
 319        asm("sync");
 320        *sdram_addr = 0xff;     /* 1 times */
 321        udelay(100);
 322        *sdram_addr = 0xff;     /* 2 times */
 323        udelay(100);
 324        *sdram_addr = 0xff;     /* 3 times */
 325        udelay(100);
 326        *sdram_addr = 0xff;     /* 4 times */
 327        udelay(100);
 328        *sdram_addr = 0xff;     /* 5 times */
 329        udelay(100);
 330        *sdram_addr = 0xff;     /* 6 times */
 331        udelay(100);
 332        *sdram_addr = 0xff;     /* 7 times */
 333        udelay(100);
 334        *sdram_addr = 0xff;     /* 8 times */
 335        udelay(100);
 336
 337        /* Mode register write operation */
 338        lbc->lsdmr = CONFIG_SYS_LBC_LSDMR_4;
 339        asm("sync");
 340        *(sdram_addr + 0xcc) = 0xff;
 341        udelay(100);
 342
 343        /* Normal operation */
 344        lbc->lsdmr = CONFIG_SYS_LBC_LSDMR_5 | 0x40000000;
 345        asm("sync");
 346        *sdram_addr = 0xff;
 347        udelay(100);
 348
 349        /*
 350         * In non-aligned case we don't [normally] use that memory because
 351         * there is a hole.
 352         */
 353        if (rem)
 354                return 0;
 355        return CONFIG_SYS_LBC_SDRAM_SIZE;
 356}
 357#else
 358static int sdram_init(unsigned int base) { return 0; }
 359#endif
 360
 361#if defined(CONFIG_OF_BOARD_SETUP)
 362static void ft_board_fixup_qe_usb(void *blob, bd_t *bd)
 363{
 364        if (!hwconfig_subarg_cmp("qe_usb", "mode", "peripheral"))
 365                return;
 366
 367        do_fixup_by_compat(blob, "fsl,mpc8323-qe-usb", "mode",
 368                           "peripheral", sizeof("peripheral"), 1);
 369}
 370
 371void ft_board_setup(void *blob, bd_t *bd)
 372{
 373        ft_cpu_setup(blob, bd);
 374#ifdef CONFIG_PCI
 375        ft_pci_setup(blob, bd);
 376#endif
 377        ft_board_fixup_qe_usb(blob, bd);
 378        /*
 379         * mpc8360ea pb mds errata 2: RGMII timing
 380         * if on mpc8360ea rev. 2.1,
 381         * change both ucc phy-connection-types from rgmii-id to rgmii-rxid
 382         */
 383        if (board_handle_erratum2()) {
 384                int nodeoffset;
 385                const char *prop;
 386                int path;
 387
 388                nodeoffset = fdt_path_offset(blob, "/aliases");
 389                if (nodeoffset >= 0) {
 390#if defined(CONFIG_HAS_ETH0)
 391                        /* fixup UCC 1 if using rgmii-id mode */
 392                        prop = fdt_getprop(blob, nodeoffset, "ethernet0", NULL);
 393                        if (prop) {
 394                                path = fdt_path_offset(blob, prop);
 395                                prop = fdt_getprop(blob, path,
 396                                                   "phy-connection-type", 0);
 397                                if (prop && (strcmp(prop, "rgmii-id") == 0))
 398                                        fdt_setprop(blob, path,
 399                                                    "phy-connection-type",
 400                                                    "rgmii-rxid",
 401                                                    sizeof("rgmii-rxid"));
 402                        }
 403#endif
 404#if defined(CONFIG_HAS_ETH1)
 405                        /* fixup UCC 2 if using rgmii-id mode */
 406                        prop = fdt_getprop(blob, nodeoffset, "ethernet1", NULL);
 407                        if (prop) {
 408                                path = fdt_path_offset(blob, prop);
 409                                prop = fdt_getprop(blob, path,
 410                                                   "phy-connection-type", 0);
 411                                if (prop && (strcmp(prop, "rgmii-id") == 0))
 412                                        fdt_setprop(blob, path,
 413                                                    "phy-connection-type",
 414                                                    "rgmii-rxid",
 415                                                    sizeof("rgmii-rxid"));
 416                        }
 417#endif
 418                }
 419        }
 420}
 421#endif
 422