uboot/board/tqc/tqm8272/tqm8272.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2006
   3 * Heiko Schocher, DENX Software Engineering, hs@denx.de.
   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 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 * MA 02111-1307 USA
  22 */
  23
  24#include <common.h>
  25#include <ioports.h>
  26#include <mpc8260.h>
  27
  28#include <command.h>
  29#include <netdev.h>
  30#ifdef CONFIG_PCI
  31#include <pci.h>
  32#include <asm/m8260_pci.h>
  33#endif
  34#include "tqm8272.h"
  35
  36#if 0
  37#define deb_printf(fmt,arg...) \
  38        printf ("TQM8272 %s %s: " fmt,__FILE__, __FUNCTION__, ##arg)
  39#else
  40#define deb_printf(fmt,arg...) \
  41        do { } while (0)
  42#endif
  43
  44#if defined(CONFIG_BOARD_GET_CPU_CLK_F)
  45unsigned long board_get_cpu_clk_f (void);
  46#endif
  47
  48/*
  49 * I/O Port configuration table
  50 *
  51 * if conf is 1, then that port pin will be configured at boot time
  52 * according to the five values podr/pdir/ppar/psor/pdat for that entry
  53 */
  54
  55const iop_conf_t iop_conf_tab[4][32] = {
  56
  57    /* Port A configuration */
  58    {   /*            conf ppar psor pdir podr pdat */
  59        /* PA31 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 *ATMTXEN */
  60        /* PA30 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMTCA   */
  61        /* PA29 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMTSOC  */
  62        /* PA28 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 *ATMRXEN */
  63        /* PA27 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMRSOC */
  64        /* PA26 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMRCA */
  65        /* PA25 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMTXD[0] */
  66        /* PA24 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMTXD[1] */
  67        /* PA23 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMTXD[2] */
  68        /* PA22 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMTXD[3] */
  69        /* PA21 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMTXD[4] */
  70        /* PA20 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMTXD[5] */
  71        /* PA19 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMTXD[6] */
  72        /* PA18 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMTXD[7] */
  73        /* PA17 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMRXD[7] */
  74        /* PA16 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMRXD[6] */
  75        /* PA15 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMRXD[5] */
  76        /* PA14 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMRXD[4] */
  77        /* PA13 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMRXD[3] */
  78        /* PA12 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMRXD[2] */
  79        /* PA11 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMRXD[1] */
  80        /* PA10 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMRXD[0] */
  81        /* PA9  */ {   1,   1,   0,   1,   0,   0   }, /* SMC2 TXD */
  82        /* PA8  */ {   1,   1,   0,   0,   0,   0   }, /* SMC2 RXD */
  83        /* PA7  */ {   0,   0,   0,   1,   0,   0   }, /* PA7 */
  84        /* PA6  */ {   0,   0,   0,   1,   0,   0   }, /* PA6 */
  85        /* PA5  */ {   0,   0,   0,   1,   0,   0   }, /* PA5 */
  86        /* PA4  */ {   0,   0,   0,   1,   0,   0   }, /* PA4 */
  87        /* PA3  */ {   0,   0,   0,   1,   0,   0   }, /* PA3 */
  88        /* PA2  */ {   0,   0,   0,   1,   0,   0   }, /* PA2 */
  89        /* PA1  */ {   0,   0,   0,   1,   0,   0   }, /* PA1 */
  90        /* PA0  */ {   0,   0,   0,   1,   0,   0   }  /* PA0 */
  91    },
  92
  93    /* Port B configuration */
  94    {   /*            conf ppar psor pdir podr pdat */
  95        /* PB31 */ {   1,   1,   0,   1,   0,   0   }, /* FCC2 MII TX_ER */
  96        /* PB30 */ {   1,   1,   0,   0,   0,   0   }, /* FCC2 MII RX_DV */
  97        /* PB29 */ {   1,   1,   1,   1,   0,   0   }, /* FCC2 MII TX_EN */
  98        /* PB28 */ {   1,   1,   0,   0,   0,   0   }, /* FCC2 MII RX_ER */
  99        /* PB27 */ {   1,   1,   0,   0,   0,   0   }, /* FCC2 MII COL */
 100        /* PB26 */ {   1,   1,   0,   0,   0,   0   }, /* FCC2 MII CRS */
 101        /* PB25 */ {   1,   1,   0,   1,   0,   0   }, /* FCC2 MII TxD[3] */
 102        /* PB24 */ {   1,   1,   0,   1,   0,   0   }, /* FCC2 MII TxD[2] */
 103        /* PB23 */ {   1,   1,   0,   1,   0,   0   }, /* FCC2 MII TxD[1] */
 104        /* PB22 */ {   1,   1,   0,   1,   0,   0   }, /* FCC2 MII TxD[0] */
 105        /* PB21 */ {   1,   1,   0,   0,   0,   0   }, /* FCC2 MII RxD[0] */
 106        /* PB20 */ {   1,   1,   0,   0,   0,   0   }, /* FCC2 MII RxD[1] */
 107        /* PB19 */ {   1,   1,   0,   0,   0,   0   }, /* FCC2 MII RxD[2] */
 108        /* PB18 */ {   1,   1,   0,   0,   0,   0   }, /* FCC2 MII RxD[3] */
 109        /* PB17 */ {   0,   0,   0,   0,   0,   0   }, /* PB17 */
 110        /* PB16 */ {   0,   0,   0,   0,   0,   0   }, /* PB16 */
 111        /* PB15 */ {   0,   0,   0,   0,   0,   0   }, /* PB15 */
 112        /* PB14 */ {   0,   0,   0,   0,   0,   0   }, /* PB14 */
 113        /* PB13 */ {   0,   0,   0,   0,   0,   0   }, /* PB13 */
 114        /* PB12 */ {   0,   0,   0,   0,   0,   0   }, /* PB12 */
 115        /* PB11 */ {   0,   0,   0,   0,   0,   0   }, /* PB11 */
 116        /* PB10 */ {   0,   0,   0,   0,   0,   0   }, /* PB10 */
 117        /* PB9  */ {   0,   0,   0,   0,   0,   0   }, /* PB9 */
 118        /* PB8  */ {   0,   0,   0,   0,   0,   0   }, /* PB8 */
 119        /* PB7  */ {   0,   0,   0,   0,   0,   0   }, /* PB7 */
 120        /* PB6  */ {   0,   0,   0,   0,   0,   0   }, /* PB6 */
 121        /* PB5  */ {   0,   0,   0,   0,   0,   0   }, /* PB5 */
 122        /* PB4  */ {   0,   0,   0,   0,   0,   0   }, /* PB4 */
 123        /* PB3  */ {   0,   0,   0,   0,   0,   0   }, /* pin doesn't exist */
 124        /* PB2  */ {   0,   0,   0,   0,   0,   0   }, /* pin doesn't exist */
 125        /* PB1  */ {   0,   0,   0,   0,   0,   0   }, /* pin doesn't exist */
 126        /* PB0  */ {   0,   0,   0,   0,   0,   0   }  /* pin doesn't exist */
 127    },
 128
 129    /* Port C */
 130    {   /*            conf ppar psor pdir podr pdat */
 131        /* PC31 */ {   0,   0,   0,   1,   0,   0   }, /* PC31 */
 132        /* PC30 */ {   0,   0,   0,   0,   0,   0   }, /* PC30 */
 133        /* PC29 */ {   1,   1,   1,   0,   0,   0   }, /* SCC1 EN *CLSN */
 134        /* PC28 */ {   0,   0,   0,   1,   0,   0   }, /* PC28 */
 135        /* PC27 */ {   0,   0,   0,   1,   0,   0   }, /* PC27 */
 136        /* PC26 */ {   0,   0,   0,   1,   0,   0   }, /* PC26 */
 137        /* PC25 */ {   0,   0,   0,   1,   0,   0   }, /* PC25 */
 138        /* PC24 */ {   0,   0,   0,   1,   0,   0   }, /* PC24 */
 139        /* PC23 */ {   0,   1,   0,   1,   0,   0   }, /* ATMTFCLK */
 140        /* PC22 */ {   0,   1,   0,   0,   0,   0   }, /* ATMRFCLK */
 141        /* PC21 */ {   1,   1,   0,   0,   0,   0   }, /* SCC1 EN RXCLK */
 142        /* PC20 */ {   1,   1,   0,   0,   0,   0   }, /* SCC1 EN TXCLK */
 143        /* PC19 */ {   1,   1,   0,   0,   0,   0   }, /* FCC2 MII RX_CLK */
 144        /* PC18 */ {   1,   1,   0,   0,   0,   0   }, /* FCC2 MII TX_CLK */
 145        /* PC17 */ {   1,   0,   0,   1,   0,   0   }, /* PC17 MDC */
 146        /* PC16 */ {   1,   0,   0,   0,   0,   0   }, /* PC16 MDIO*/
 147        /* PC15 */ {   0,   0,   0,   1,   0,   0   }, /* PC15 */
 148        /* PC14 */ {   1,   1,   0,   0,   0,   0   }, /* SCC1 EN *CD */
 149        /* PC13 */ {   0,   0,   0,   1,   0,   0   }, /* PC13 */
 150        /* PC12 */ {   0,   0,   0,   1,   0,   0   }, /* PC12 */
 151        /* PC11 */ {   0,   0,   0,   1,   0,   0   }, /* PC11 */
 152        /* PC10 */ {   0,   0,   0,   1,   0,   0   }, /* PC10 */
 153        /* PC9  */ {   0,   0,   0,   1,   0,   0   }, /* PC9 */
 154        /* PC8  */ {   0,   0,   0,   1,   0,   0   }, /* PC8 */
 155        /* PC7  */ {   0,   0,   0,   1,   0,   0   }, /* PC7 */
 156        /* PC6  */ {   0,   0,   0,   1,   0,   0   }, /* PC6 */
 157        /* PC5  */ {   1,   1,   0,   1,   0,   0   }, /* PC5 SMC1 TXD */
 158        /* PC4  */ {   1,   1,   0,   0,   0,   0   }, /* PC4 SMC1 RXD */
 159        /* PC3  */ {   0,   0,   0,   1,   0,   0   }, /* PC3 */
 160        /* PC2  */ {   0,   0,   0,   1,   0,   1   }, /* ENET FDE */
 161        /* PC1  */ {   0,   0,   0,   1,   0,   0   }, /* ENET DSQE */
 162        /* PC0  */ {   0,   0,   0,   1,   0,   0   }, /* ENET LBK */
 163    },
 164
 165    /* Port D */
 166    {   /*            conf ppar psor pdir podr pdat */
 167        /* PD31 */ {   1,   1,   0,   0,   0,   0   }, /* SCC1 EN RxD */
 168        /* PD30 */ {   1,   1,   1,   1,   0,   0   }, /* SCC1 EN TxD */
 169        /* PD29 */ {   1,   1,   0,   1,   0,   0   }, /* SCC1 EN TENA */
 170        /* PD28 */ {   0,   0,   0,   1,   0,   0   }, /* PD28 */
 171        /* PD27 */ {   0,   0,   0,   1,   0,   0   }, /* PD27 */
 172        /* PD26 */ {   0,   0,   0,   1,   0,   0   }, /* PD26 */
 173        /* PD25 */ {   0,   0,   0,   1,   0,   0   }, /* PD25 */
 174        /* PD24 */ {   0,   0,   0,   1,   0,   0   }, /* PD24 */
 175        /* PD23 */ {   0,   0,   0,   1,   0,   0   }, /* PD23 */
 176        /* PD22 */ {   0,   0,   0,   1,   0,   0   }, /* PD22 */
 177        /* PD21 */ {   0,   0,   0,   1,   0,   0   }, /* PD21 */
 178        /* PD20 */ {   0,   0,   0,   1,   0,   0   }, /* PD20 */
 179        /* PD19 */ {   0,   0,   0,   1,   0,   0   }, /* PD19 */
 180        /* PD18 */ {   0,   0,   0,   1,   0,   0   }, /* PD19 */
 181        /* PD17 */ {   0,   1,   0,   0,   0,   0   }, /* FCC1 ATMRXPRTY */
 182        /* PD16 */ {   0,   1,   0,   1,   0,   0   }, /* FCC1 ATMTXPRTY */
 183#if defined(CONFIG_SOFT_I2C)
 184        /* PD15 */ {   1,   0,   0,   1,   1,   1   }, /* I2C SDA */
 185        /* PD14 */ {   1,   0,   0,   1,   1,   1   }, /* I2C SCL */
 186#else
 187#if defined(CONFIG_HARD_I2C)
 188        /* PD15 */ {   1,   1,   1,   0,   1,   0   }, /* I2C SDA */
 189        /* PD14 */ {   1,   1,   1,   0,   1,   0   }, /* I2C SCL */
 190#else /* normal I/O port pins */
 191        /* PD15 */ {   0,   1,   1,   0,   1,   0   }, /* I2C SDA */
 192        /* PD14 */ {   0,   1,   1,   0,   1,   0   }, /* I2C SCL */
 193#endif
 194#endif
 195        /* PD13 */ {   0,   0,   0,   0,   0,   0   }, /* PD13 */
 196        /* PD12 */ {   0,   0,   0,   0,   0,   0   }, /* PD12 */
 197        /* PD11 */ {   0,   0,   0,   0,   0,   0   }, /* PD11 */
 198        /* PD10 */ {   0,   0,   0,   0,   0,   0   }, /* PD10 */
 199        /* PD9  */ {   1,   1,   0,   1,   0,   0   }, /* SMC1 TXD */
 200        /* PD8  */ {   1,   1,   0,   0,   0,   0   }, /* SMC1 RXD */
 201        /* PD7  */ {   0,   0,   0,   1,   0,   1   }, /* PD7 */
 202        /* PD6  */ {   0,   0,   0,   1,   0,   1   }, /* PD6 */
 203        /* PD5  */ {   0,   0,   0,   1,   0,   0   }, /* PD5 */
 204        /* PD4  */ {   0,   0,   0,   1,   0,   1   }, /* PD4 */
 205        /* PD3  */ {   0,   0,   0,   0,   0,   0   }, /* pin doesn't exist */
 206        /* PD2  */ {   0,   0,   0,   0,   0,   0   }, /* pin doesn't exist */
 207        /* PD1  */ {   0,   0,   0,   0,   0,   0   }, /* pin doesn't exist */
 208        /* PD0  */ {   0,   0,   0,   0,   0,   0   }  /* pin doesn't exist */
 209    }
 210};
 211
 212/* UPM pattern for slow init */
 213static const uint upmTableSlow[] =
 214{
 215    /* Offset   UPM Read Single RAM array entry */
 216    /* 0x00 */  0xffffee00, 0x00ffcc80, 0x00ffcf00, 0x00ffdc00,
 217    /* 0x04 */  0x00ffce80, 0x00ffcc00, 0x00ffee00, 0x3fffcc07,
 218
 219                /* UPM Read Burst RAM array entry -> unused */
 220    /* 0x08 */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 221    /* 0x0C */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 222
 223                /* UPM Read Burst RAM array entry -> unused */
 224    /* 0x10 */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 225    /* 0x14 */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 226
 227                /* UPM Write Single RAM array entry */
 228    /* 0x18 */  0xffffee00, 0x00ffec80, 0x00ffef00, 0x00fffc80,
 229    /* 0x1C */  0x00fffe00, 0x00ffec00, 0x0fffef00, 0x3fffec05,
 230
 231                /* UPM Write Burst RAM array entry -> unused */
 232    /* 0x20 */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 233    /* 0x24 */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 234    /* 0x28 */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 235    /* 0x2C */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
 236
 237                /* UPM Refresh Timer RAM array entry -> unused */
 238    /* 0x30 */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 239    /* 0x34 */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 240    /* 0x38 */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
 241
 242                /* UPM Exception RAM array entry -> unused */
 243    /* 0x3C */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
 244};
 245
 246/* UPM pattern for fast init */
 247static const uint upmTableFast[] =
 248{
 249    /* Offset   UPM Read Single RAM array entry */
 250    /* 0x00 */  0xffffee00, 0x00ffcc80, 0x00ffcd80, 0x00ffdc00,
 251    /* 0x04 */  0x00ffdc00, 0x00ffcf00, 0x00ffec00, 0x3fffcc07,
 252
 253                /* UPM Read Burst RAM array entry -> unused */
 254    /* 0x08 */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 255    /* 0x0C */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 256
 257                /* UPM Read Burst RAM array entry -> unused */
 258    /* 0x10 */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 259    /* 0x14 */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 260
 261                /* UPM Write Single RAM array entry */
 262    /* 0x18 */  0xffffee00, 0x00ffec80, 0x00ffee80, 0x00fffc00,
 263    /* 0x1C */  0x00fffc00, 0x00ffec00, 0x0fffef00, 0x3fffec05,
 264
 265                /* UPM Write Burst RAM array entry -> unused */
 266    /* 0x20 */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 267    /* 0x24 */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 268    /* 0x28 */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 269    /* 0x2C */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
 270
 271                /* UPM Refresh Timer RAM array entry -> unused */
 272    /* 0x30 */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 273    /* 0x34 */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
 274    /* 0x38 */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
 275
 276                /* UPM Exception RAM array entry -> unused */
 277    /* 0x3C */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
 278};
 279
 280
 281/* ------------------------------------------------------------------------- */
 282
 283/* Check Board Identity:
 284 */
 285int checkboard (void)
 286{
 287        char *p = (char *) HWIB_INFO_START_ADDR;
 288
 289        puts ("Board: ");
 290        if (*((unsigned long *)p) == (unsigned long)CONFIG_SYS_HWINFO_MAGIC) {
 291                puts (p);
 292        } else {
 293                puts ("No HWIB assuming TQM8272");
 294        }
 295        putc ('\n');
 296
 297        return 0;
 298}
 299
 300/* ------------------------------------------------------------------------- */
 301#if defined(CONFIG_BOARD_GET_CPU_CLK_F)
 302static int get_cas_latency (void)
 303{
 304        /* get it from the option -ts in CIB */
 305        /* default is 3 */
 306        int     ret = 3;
 307        int     pos = 0;
 308        char    *p = (char *) CIB_INFO_START_ADDR;
 309
 310        while ((*p != '\0') && (pos < CIB_INFO_LEN)) {
 311                if (*p < ' ' || *p > '~') { /* ASCII strings! */
 312                        return ret;
 313                }
 314                if (*p == '-') {
 315                        if ((p[1] == 't') && (p[2] == 's')) {
 316                                return (p[4] - '0');
 317                        }
 318                }
 319                p++;
 320                pos++;
 321        }
 322        return ret;
 323}
 324#endif
 325
 326static ulong set_sdram_timing (volatile uint *sdmr_ptr, ulong sdmr, int col)
 327{
 328#if defined(CONFIG_BOARD_GET_CPU_CLK_F)
 329        int     clk = board_get_cpu_clk_f ();
 330        volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
 331        int     busmode = (immr->im_siu_conf.sc_bcr & BCR_EBM ? 1 : 0);
 332        int     cas;
 333
 334        sdmr = sdmr & ~(PSDMR_RFRC_MSK | PSDMR_PRETOACT_MSK | PSDMR_WRC_MSK | \
 335                         PSDMR_BUFCMD);
 336        if (busmode) {
 337                switch (clk) {
 338                        case 66666666:
 339                                sdmr |= (PSDMR_RFRC_66MHZ_60X | \
 340                                        PSDMR_PRETOACT_66MHZ_60X | \
 341                                        PSDMR_WRC_66MHZ_60X | \
 342                                        PSDMR_BUFCMD_66MHZ_60X);
 343                                break;
 344                        case 100000000:
 345                                sdmr |= (PSDMR_RFRC_100MHZ_60X | \
 346                                        PSDMR_PRETOACT_100MHZ_60X | \
 347                                        PSDMR_WRC_100MHZ_60X | \
 348                                        PSDMR_BUFCMD_100MHZ_60X);
 349                                break;
 350
 351                }
 352        } else {
 353                switch (clk) {
 354                        case 66666666:
 355                                sdmr |= (PSDMR_RFRC_66MHZ_SINGLE | \
 356                                        PSDMR_PRETOACT_66MHZ_SINGLE | \
 357                                        PSDMR_WRC_66MHZ_SINGLE | \
 358                                        PSDMR_BUFCMD_66MHZ_SINGLE);
 359                                break;
 360                        case 100000000:
 361                                sdmr |= (PSDMR_RFRC_100MHZ_SINGLE | \
 362                                        PSDMR_PRETOACT_100MHZ_SINGLE | \
 363                                        PSDMR_WRC_100MHZ_SINGLE | \
 364                                        PSDMR_BUFCMD_100MHZ_SINGLE);
 365                                break;
 366                        case 133333333:
 367                                sdmr |= (PSDMR_RFRC_133MHZ_SINGLE | \
 368                                        PSDMR_PRETOACT_133MHZ_SINGLE | \
 369                                        PSDMR_WRC_133MHZ_SINGLE | \
 370                                        PSDMR_BUFCMD_133MHZ_SINGLE);
 371                                break;
 372                }
 373        }
 374        cas = get_cas_latency();
 375        sdmr &=~ (PSDMR_CL_MSK | PSDMR_LDOTOPRE_MSK);
 376        sdmr |= cas;
 377        sdmr |= ((cas - 1) << 6);
 378        return sdmr;
 379#else
 380        return sdmr;
 381#endif
 382}
 383
 384/* Try SDRAM initialization with P/LSDMR=sdmr and ORx=orx
 385 *
 386 * This routine performs standard 8260 initialization sequence
 387 * and calculates the available memory size. It may be called
 388 * several times to try different SDRAM configurations on both
 389 * 60x and local buses.
 390 */
 391static long int try_init (volatile memctl8260_t * memctl, ulong sdmr,
 392                                                  ulong orx, volatile uchar * base, int col)
 393{
 394        volatile uchar c = 0xff;
 395        volatile uint *sdmr_ptr;
 396        volatile uint *orx_ptr;
 397        ulong maxsize, size;
 398        int i;
 399
 400        /* We must be able to test a location outsize the maximum legal size
 401         * to find out THAT we are outside; but this address still has to be
 402         * mapped by the controller. That means, that the initial mapping has
 403         * to be (at least) twice as large as the maximum expected size.
 404         */
 405        maxsize = (1 + (~orx | 0x7fff)) / 2;
 406
 407        /* Since CONFIG_SYS_SDRAM_BASE is always 0 (??), we assume that
 408         * we are configuring CS1 if base != 0
 409         */
 410        sdmr_ptr = base ? &memctl->memc_lsdmr : &memctl->memc_psdmr;
 411        orx_ptr = base ? &memctl->memc_or2 : &memctl->memc_or1;
 412
 413        *orx_ptr = orx;
 414        sdmr = set_sdram_timing (sdmr_ptr, sdmr, col);
 415        /*
 416         * Quote from 8260 UM (10.4.2 SDRAM Power-On Initialization, 10-35):
 417         *
 418         * "At system reset, initialization software must set up the
 419         *  programmable parameters in the memory controller banks registers
 420         *  (ORx, BRx, P/LSDMR). After all memory parameters are configured,
 421         *  system software should execute the following initialization sequence
 422         *  for each SDRAM device.
 423         *
 424         *  1. Issue a PRECHARGE-ALL-BANKS command
 425         *  2. Issue eight CBR REFRESH commands
 426         *  3. Issue a MODE-SET command to initialize the mode register
 427         *
 428         *  The initial commands are executed by setting P/LSDMR[OP] and
 429         *  accessing the SDRAM with a single-byte transaction."
 430         *
 431         * The appropriate BRx/ORx registers have already been set when we
 432         * get here. The SDRAM can be accessed at the address CONFIG_SYS_SDRAM_BASE.
 433         */
 434
 435        *sdmr_ptr = sdmr | PSDMR_OP_PREA;
 436        *base = c;
 437
 438        *sdmr_ptr = sdmr | PSDMR_OP_CBRR;
 439        for (i = 0; i < 8; i++)
 440                *base = c;
 441
 442        *sdmr_ptr = sdmr | PSDMR_OP_MRW;
 443        *(base + CONFIG_SYS_MRS_OFFS) = c;      /* setting MR on address lines */
 444
 445        *sdmr_ptr = sdmr | PSDMR_OP_NORM | PSDMR_RFEN;
 446        *base = c;
 447
 448        size = get_ram_size((long *)base, maxsize);
 449        *orx_ptr = orx | ~(size - 1);
 450
 451        return (size);
 452}
 453
 454phys_size_t initdram (int board_type)
 455{
 456        volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
 457        volatile memctl8260_t *memctl = &immap->im_memctl;
 458
 459#ifndef CONFIG_SYS_RAMBOOT
 460        long size8, size9;
 461#endif
 462        long psize;
 463
 464        psize = 16 * 1024 * 1024;
 465
 466        memctl->memc_psrt = CONFIG_SYS_PSRT;
 467        memctl->memc_mptpr = CONFIG_SYS_MPTPR;
 468
 469#ifndef CONFIG_SYS_RAMBOOT
 470        /* 60x SDRAM setup:
 471         */
 472        size8 = try_init (memctl, CONFIG_SYS_PSDMR_8COL, CONFIG_SYS_OR1_8COL,
 473                                          (uchar *) CONFIG_SYS_SDRAM_BASE, 8);
 474        size9 = try_init (memctl, CONFIG_SYS_PSDMR_9COL, CONFIG_SYS_OR1_9COL,
 475                                          (uchar *) CONFIG_SYS_SDRAM_BASE, 9);
 476
 477        if (size8 < size9) {
 478                psize = size9;
 479                printf ("(60x:9COL - %ld MB, ", psize >> 20);
 480        } else {
 481                psize = try_init (memctl, CONFIG_SYS_PSDMR_8COL, CONFIG_SYS_OR1_8COL,
 482                                                  (uchar *) CONFIG_SYS_SDRAM_BASE, 8);
 483                printf ("(60x:8COL - %ld MB, ", psize >> 20);
 484        }
 485
 486#endif /* CONFIG_SYS_RAMBOOT */
 487
 488        icache_enable ();
 489
 490        return (psize);
 491}
 492
 493
 494static inline int scanChar (char *p, int len, unsigned long *number)
 495{
 496        int     akt = 0;
 497
 498        *number = 0;
 499        while (akt < len) {
 500                if ((*p >= '0') && (*p <= '9')) {
 501                        *number *= 10;
 502                        *number += *p - '0';
 503                        p += 1;
 504                } else {
 505                        if (*p == '-')  return akt;
 506                        return -1;
 507                }
 508                akt ++;
 509        }
 510        return akt;
 511}
 512
 513static int dump_hwib(void)
 514{
 515        HWIB_INFO       *hw = &hwinf;
 516        char buf[64];
 517        int i = getenv_f("serial#", buf, sizeof(buf));
 518        volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
 519
 520        if (i < 0)
 521                buf[0] = '\0';
 522
 523        if (hw->OK) {
 524                printf ("HWIB on %x\n", HWIB_INFO_START_ADDR);
 525                printf ("serial : %s\n", buf);
 526                printf ("ethaddr: %s\n", hw->ethaddr);
 527                printf ("FLASH  : %x nr:%d\n", hw->flash, hw->flash_nr);
 528                printf ("RAM    : %x cs:%d\n", hw->ram, hw->ram_cs);
 529                printf ("CPU    : %lu\n", hw->cpunr);
 530                printf ("CAN    : %d\n", hw->can);
 531                if (hw->eeprom) printf ("EEprom : %x\n", hw->eeprom);
 532                else printf ("No EEprom\n");
 533                if (hw->nand) {
 534                        printf ("NAND   : %x\n", hw->nand);
 535                        printf ("NAND CS: %d\n", hw->nand_cs);
 536                } else { printf ("No NAND\n");}
 537                printf ("Bus %s mode.\n", (hw->Bus ? "60x" : "Single PQII"));
 538                printf ("  real : %s\n", (immr->im_siu_conf.sc_bcr & BCR_EBM ? \
 539                                 "60x" : "Single PQII"));
 540                printf ("Option : %lx\n", hw->option);
 541                printf ("%s Security Engine\n", (hw->SecEng ? "with" : "no"));
 542                printf ("CPM Clk: %d\n", hw->cpmcl);
 543                printf ("CPU Clk: %d\n", hw->cpucl);
 544                printf ("Bus Clk: %d\n", hw->buscl);
 545                if (hw->busclk_real_ok) {
 546                        printf ("  real Clk: %d\n", hw->busclk_real);
 547                }
 548                printf ("CAS    : %d\n", get_cas_latency());
 549        } else {
 550                printf("HWIB @%x not OK\n", HWIB_INFO_START_ADDR);
 551        }
 552        return 0;
 553}
 554
 555static inline int search_real_busclk (int *clk)
 556{
 557        int     part = 0, pos = 0;
 558        char *p = (char *) CIB_INFO_START_ADDR;
 559        int     ok = 0;
 560
 561        while ((*p != '\0') && (pos < CIB_INFO_LEN)) {
 562                if (*p < ' ' || *p > '~') { /* ASCII strings! */
 563                        return 0;
 564                }
 565                switch (part) {
 566                default:
 567                        if (*p == '-') {
 568                                ++part;
 569                        }
 570                        break;
 571                case 3:
 572                        if (*p == '-') {
 573                                ++part;
 574                                break;
 575                        }
 576                        if (*p == 'b') {
 577                                ok = 1;
 578                                p++;
 579                                break;
 580                        }
 581                        if (ok) {
 582                                switch (*p) {
 583                                case '6':
 584                                        *clk = 66666666;
 585                                        return 1;
 586                                        break;
 587                                case '1':
 588                                        if (p[1] == '3') {
 589                                                *clk = 133333333;
 590                                        } else {
 591                                                *clk = 100000000;
 592                                        }
 593                                        return 1;
 594                                        break;
 595                                }
 596                        }
 597                        break;
 598                }
 599                p++;
 600        }
 601        return 0;
 602}
 603
 604int analyse_hwib (void)
 605{
 606        char    *p = (char *) HWIB_INFO_START_ADDR;
 607        int     anz;
 608        int     part = 1, i = 0, pos = 0;
 609        HWIB_INFO       *hw = &hwinf;
 610
 611        deb_printf(" %s pointer: %p\n", __FUNCTION__, p);
 612        /* Head = TQM */
 613        if (*((unsigned long *)p) != (unsigned long)CONFIG_SYS_HWINFO_MAGIC) {
 614                deb_printf("No HWIB\n");
 615                return -1;
 616        }
 617        p += 3;
 618        if (scanChar (p, 4, &hw->cpunr) < 0) {
 619                deb_printf("No CPU\n");
 620                return -2;
 621        }
 622        p +=4;
 623
 624        hw->flash = 0x200000 << (*p - 'A');
 625        p++;
 626        hw->flash_nr = *p - '0';
 627        p++;
 628
 629        hw->ram = 0x2000000 << (*p - 'A');
 630        p++;
 631        if (*p == '2') {
 632                hw->ram_cs = 2;
 633                p++;
 634        }
 635
 636        if (*p == 'A') hw->can = 1;
 637        if (*p == 'B') hw->can = 2;
 638        p +=1;
 639        p +=1;  /* connector */
 640        if (*p != '0') {
 641                hw->eeprom = 0x1000 << (*p - 'A');
 642        }
 643        p++;
 644
 645        if ((*p < '0') || (*p > '9')) {
 646                /* NAND before z-option */
 647                hw->nand = 0x8000000 << (*p - 'A');
 648                p++;
 649                hw->nand_cs = *p - '0';
 650                p += 2;
 651        }
 652        /* z-option */
 653        anz = scanChar (p, 4, &hw->option);
 654        if (anz < 0) {
 655                deb_printf("No option\n");
 656                return -3;
 657        }
 658        if (hw->option & 0x8) hw->Bus = 1;
 659        p += anz;
 660        if (*p != '-') {
 661                deb_printf("No -\n");
 662                return -4;
 663        }
 664        p++;
 665        /* C option */
 666        if (*p == 'E') {
 667                hw->SecEng = 1;
 668                p++;
 669        }
 670        switch (*p) {
 671                case 'M': hw->cpucl = 266666666;
 672                        break;
 673                case 'P': hw->cpucl = 300000000;
 674                        break;
 675                case 'T': hw->cpucl = 400000000;
 676                        break;
 677                default:
 678                        deb_printf("No CPU Clk: %c\n", *p);
 679                        return -5;
 680                        break;
 681        }
 682        p++;
 683        switch (*p) {
 684                case 'I': hw->cpmcl = 200000000;
 685                        break;
 686                case 'M': hw->cpmcl = 300000000;
 687                        break;
 688                default:
 689                        deb_printf("No CPM Clk\n");
 690                        return -6;
 691                        break;
 692        }
 693        p++;
 694        switch (*p) {
 695                case 'B': hw->buscl = 66666666;
 696                        break;
 697                case 'E': hw->buscl = 100000000;
 698                        break;
 699                case 'F': hw->buscl = 133333333;
 700                        break;
 701                default:
 702                        deb_printf("No BUS Clk\n");
 703                        return -7;
 704                        break;
 705        }
 706        p++;
 707
 708        hw->OK = 1;
 709        /* search MAC Address */
 710        while ((*p != '\0') && (pos < CONFIG_SYS_HWINFO_SIZE)) {
 711                if (*p < ' ' || *p > '~') { /* ASCII strings! */
 712                        return 0;
 713                }
 714                switch (part) {
 715                default:
 716                        if (*p == ' ') {
 717                                ++part;
 718                                i = 0;
 719                        }
 720                        break;
 721                case 3:                 /* Copy MAC address */
 722                        if (*p == ' ') {
 723                                ++part;
 724                                i = 0;
 725                                break;
 726                        }
 727                        hw->ethaddr[i++] = *p;
 728                        if ((i % 3) == 2)
 729                                hw->ethaddr[i++] = ':';
 730                        break;
 731
 732                }
 733                p++;
 734        }
 735
 736        hw->busclk_real_ok = search_real_busclk (&hw->busclk_real);
 737        return 0;
 738}
 739
 740#if defined(CONFIG_GET_CPU_STR_F)
 741/* !! This routine runs from Flash */
 742char get_cpu_str_f (char *buf)
 743{
 744        char *p = (char *) HWIB_INFO_START_ADDR;
 745        int     i = 0;
 746
 747        buf[i++] = 'M';
 748        buf[i++] = 'P';
 749        buf[i++] = 'C';
 750        if (*((unsigned long *)p) == (unsigned long)CONFIG_SYS_HWINFO_MAGIC) {
 751                buf[i++] = *&p[3];
 752                buf[i++] = *&p[4];
 753                buf[i++] = *&p[5];
 754                buf[i++] = *&p[6];
 755        } else {
 756                buf[i++] = '8';
 757                buf[i++] = '2';
 758                buf[i++] = '7';
 759                buf[i++] = 'x';
 760        }
 761        buf[i++] = 0;
 762        return 0;
 763}
 764#endif
 765
 766#if defined(CONFIG_BOARD_GET_CPU_CLK_F)
 767/* !! This routine runs from Flash */
 768unsigned long board_get_cpu_clk_f (void)
 769{
 770        char *p = (char *) HWIB_INFO_START_ADDR;
 771        int i = 0;
 772
 773        if (*((unsigned long *)p) == (unsigned long)CONFIG_SYS_HWINFO_MAGIC) {
 774                if (search_real_busclk (&i))
 775                        return i;
 776        }
 777        return CONFIG_8260_CLKIN;
 778}
 779#endif
 780
 781#if CONFIG_BOARD_EARLY_INIT_R
 782
 783static int can_test (unsigned long off)
 784{
 785        volatile unsigned char  *base   = (unsigned char *) (CONFIG_SYS_CAN_BASE + off);
 786
 787        *(base + 0x17) = 'T';
 788        *(base + 0x18) = 'Q';
 789        *(base + 0x19) = 'M';
 790        if ((*(base + 0x17) != 'T') ||
 791            (*(base + 0x18) != 'Q') ||
 792            (*(base + 0x19) != 'M')) {
 793                return 0;
 794        }
 795        return 1;
 796}
 797
 798static int can_config_one (unsigned long off)
 799{
 800        volatile unsigned char  *ctrl   = (unsigned char *) (CONFIG_SYS_CAN_BASE + off);
 801        volatile unsigned char  *cpu_if = (unsigned char *) (CONFIG_SYS_CAN_BASE + off + 0x02);
 802        volatile unsigned char  *clkout = (unsigned char *) (CONFIG_SYS_CAN_BASE + off + 0x1f);
 803        unsigned char temp;
 804
 805        *cpu_if = 0x45;
 806        temp = *ctrl;
 807        temp |= 0x40;
 808        *ctrl   = temp;
 809        *clkout = 0x20;
 810        temp = *ctrl;
 811        temp &= ~0x40;
 812        *ctrl   = temp;
 813        return 0;
 814}
 815
 816static int can_config (void)
 817{
 818        int     ret = 0;
 819        can_config_one (0);
 820        if (hwinf.can == 2) {
 821                can_config_one (0x100);
 822        }
 823        /* make Test if they really there */
 824        ret += can_test (0);
 825        ret += can_test (0x100);
 826        return ret;
 827}
 828
 829static int init_can (void)
 830{
 831        volatile immap_t * immr = (immap_t *)CONFIG_SYS_IMMR;
 832        volatile memctl8260_t *memctl = &immr->im_memctl;
 833        int     count = 0;
 834
 835        if ((hwinf.OK) && (hwinf.can)) {
 836                memctl->memc_or4 = CONFIG_SYS_CAN_OR;
 837                memctl->memc_br4 = CONFIG_SYS_CAN_BR;
 838                /* upm Init */
 839                upmconfig (UPMC, (uint *) upmTableFast,
 840                           sizeof (upmTableFast) / sizeof (uint));
 841                memctl->memc_mcmr =     (MxMR_DSx_3_CYCL |
 842                                        MxMR_GPL_x4DIS |
 843                                        MxMR_RLFx_2X |
 844                                        MxMR_WLFx_2X |
 845                                        MxMR_OP_NORM);
 846                /* can configure */
 847                count = can_config ();
 848                printf ("CAN:   %d @ %x\n", count, CONFIG_SYS_CAN_BASE);
 849                if (hwinf.can != count) printf("!!! difference to HWIB\n");
 850        } else {
 851                printf ("CAN:   No\n");
 852        }
 853        return 0;
 854}
 855
 856int board_early_init_r(void)
 857{
 858        analyse_hwib ();
 859        init_can ();
 860        return 0;
 861}
 862#endif
 863
 864int do_hwib_dump (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 865{
 866        dump_hwib ();
 867        return 0;
 868}
 869
 870U_BOOT_CMD(
 871          hwib, 1,      1,      do_hwib_dump,
 872          "dump HWIB'",
 873          ""
 874);
 875
 876#ifdef CONFIG_SYS_UPDATE_FLASH_SIZE
 877static int get_flash_timing (void)
 878{
 879        /* get it from the option -tf in CIB */
 880        /* default is 0x00000c84 */
 881        int     ret = 0x00000c84;
 882        int     pos = 0;
 883        int     nr = 0;
 884        char    *p = (char *) CIB_INFO_START_ADDR;
 885
 886        while ((*p != '\0') && (pos < CIB_INFO_LEN)) {
 887                if (*p < ' ' || *p > '~') { /* ASCII strings! */
 888                        return ret;
 889                }
 890                if (*p == '-') {
 891                        if ((p[1] == 't') && (p[2] == 'f')) {
 892                                p += 6;
 893                                ret = 0;
 894                                while (nr < 8) {
 895                                if ((*p >= '0') && (*p <= '9')) {
 896                                        ret *= 0x10;
 897                                        ret += *p - '0';
 898                                        p += 1;
 899                                        nr ++;
 900                                } else if ((*p >= 'A') && (*p <= 'F')) {
 901                                        ret *= 10;
 902                                        ret += *p - '7';
 903                                        p += 1;
 904                                        nr ++;
 905                                } else {
 906                                        if (nr < 8) return 0x00000c84;
 907                                        return ret;
 908                                }
 909                                }
 910                        }
 911                }
 912                p++;
 913                pos++;
 914        }
 915        return ret;
 916}
 917
 918/* Update the Flash_Size and the Flash Timing */
 919int update_flash_size (int flash_size)
 920{
 921        volatile immap_t * immr = (immap_t *)CONFIG_SYS_IMMR;
 922        volatile memctl8260_t *memctl = &immr->im_memctl;
 923        unsigned long reg;
 924        unsigned long tim;
 925
 926        /* I must use reg, otherwise the board hang */
 927        reg = memctl->memc_or0;
 928        reg &= ~ORxU_AM_MSK;
 929        reg |= MEG_TO_AM(flash_size >> 20);
 930        tim = get_flash_timing ();
 931        reg &= ~0xfff;
 932        reg |= (tim & 0xfff);
 933        memctl->memc_or0 = reg;
 934        return 0;
 935}
 936#endif
 937
 938#ifdef CONFIG_PCI
 939struct pci_controller hose;
 940
 941int board_early_init_f (void)
 942{
 943        volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
 944
 945        immap->im_clkrst.car_sccr |= M826X_SCCR_PCI_MODE_EN;
 946        return 0;
 947}
 948
 949extern void pci_mpc8250_init(struct pci_controller *);
 950
 951void pci_init_board(void)
 952{
 953        pci_mpc8250_init(&hose);
 954}
 955#endif
 956
 957int board_eth_init(bd_t *bis)
 958{
 959        return pci_eth_init(bis);
 960}
 961