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, lsize;
 463
 464        psize = 16 * 1024 * 1024;
 465        lsize = 0;
 466
 467        memctl->memc_psrt = CONFIG_SYS_PSRT;
 468        memctl->memc_mptpr = CONFIG_SYS_MPTPR;
 469
 470#ifndef CONFIG_SYS_RAMBOOT
 471        /* 60x SDRAM setup:
 472         */
 473        size8 = try_init (memctl, CONFIG_SYS_PSDMR_8COL, CONFIG_SYS_OR1_8COL,
 474                                          (uchar *) CONFIG_SYS_SDRAM_BASE, 8);
 475        size9 = try_init (memctl, CONFIG_SYS_PSDMR_9COL, CONFIG_SYS_OR1_9COL,
 476                                          (uchar *) CONFIG_SYS_SDRAM_BASE, 9);
 477
 478        if (size8 < size9) {
 479                psize = size9;
 480                printf ("(60x:9COL - %ld MB, ", psize >> 20);
 481        } else {
 482                psize = try_init (memctl, CONFIG_SYS_PSDMR_8COL, CONFIG_SYS_OR1_8COL,
 483                                                  (uchar *) CONFIG_SYS_SDRAM_BASE, 8);
 484                printf ("(60x:8COL - %ld MB, ", psize >> 20);
 485        }
 486
 487#endif /* CONFIG_SYS_RAMBOOT */
 488
 489        icache_enable ();
 490
 491        return (psize);
 492}
 493
 494
 495static inline int scanChar (char *p, int len, unsigned long *number)
 496{
 497        int     akt = 0;
 498
 499        *number = 0;
 500        while (akt < len) {
 501                if ((*p >= '0') && (*p <= '9')) {
 502                        *number *= 10;
 503                        *number += *p - '0';
 504                        p += 1;
 505                } else {
 506                        if (*p == '-')  return akt;
 507                        return -1;
 508                }
 509                akt ++;
 510        }
 511        return akt;
 512}
 513
 514static int dump_hwib(void)
 515{
 516        HWIB_INFO       *hw = &hwinf;
 517        volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
 518        char *s = getenv("serial#");
 519
 520        if (hw->OK) {
 521                printf ("HWIB on %x\n", HWIB_INFO_START_ADDR);
 522                printf ("serial : %s\n", s);
 523                printf ("ethaddr: %s\n", hw->ethaddr);
 524                printf ("FLASH  : %x nr:%d\n", hw->flash, hw->flash_nr);
 525                printf ("RAM    : %x cs:%d\n", hw->ram, hw->ram_cs);
 526                printf ("CPU    : %lu\n", hw->cpunr);
 527                printf ("CAN    : %d\n", hw->can);
 528                if (hw->eeprom) printf ("EEprom : %x\n", hw->eeprom);
 529                else printf ("No EEprom\n");
 530                if (hw->nand) {
 531                        printf ("NAND   : %x\n", hw->nand);
 532                        printf ("NAND CS: %d\n", hw->nand_cs);
 533                } else { printf ("No NAND\n");}
 534                printf ("Bus %s mode.\n", (hw->Bus ? "60x" : "Single PQII"));
 535                printf ("  real : %s\n", (immr->im_siu_conf.sc_bcr & BCR_EBM ? \
 536                                 "60x" : "Single PQII"));
 537                printf ("Option : %lx\n", hw->option);
 538                printf ("%s Security Engine\n", (hw->SecEng ? "with" : "no"));
 539                printf ("CPM Clk: %d\n", hw->cpmcl);
 540                printf ("CPU Clk: %d\n", hw->cpucl);
 541                printf ("Bus Clk: %d\n", hw->buscl);
 542                if (hw->busclk_real_ok) {
 543                        printf ("  real Clk: %d\n", hw->busclk_real);
 544                }
 545                printf ("CAS    : %d\n", get_cas_latency());
 546        } else {
 547                printf("HWIB @%x not OK\n", HWIB_INFO_START_ADDR);
 548        }
 549        return 0;
 550}
 551
 552static inline int search_real_busclk (int *clk)
 553{
 554        int     part = 0, pos = 0;
 555        char *p = (char *) CIB_INFO_START_ADDR;
 556        int     ok = 0;
 557
 558        while ((*p != '\0') && (pos < CIB_INFO_LEN)) {
 559                if (*p < ' ' || *p > '~') { /* ASCII strings! */
 560                        return 0;
 561                }
 562                switch (part) {
 563                default:
 564                        if (*p == '-') {
 565                                ++part;
 566                        }
 567                        break;
 568                case 3:
 569                        if (*p == '-') {
 570                                ++part;
 571                                break;
 572                        }
 573                        if (*p == 'b') {
 574                                ok = 1;
 575                                p++;
 576                                break;
 577                        }
 578                        if (ok) {
 579                                switch (*p) {
 580                                case '6':
 581                                        *clk = 66666666;
 582                                        return 1;
 583                                        break;
 584                                case '1':
 585                                        if (p[1] == '3') {
 586                                                *clk = 133333333;
 587                                        } else {
 588                                                *clk = 100000000;
 589                                        }
 590                                        return 1;
 591                                        break;
 592                                }
 593                        }
 594                        break;
 595                }
 596                p++;
 597        }
 598        return 0;
 599}
 600
 601int analyse_hwib (void)
 602{
 603        char    *p = (char *) HWIB_INFO_START_ADDR;
 604        int     anz;
 605        int     part = 1, i = 0, pos = 0;
 606        HWIB_INFO       *hw = &hwinf;
 607
 608        deb_printf(" %s pointer: %p\n", __FUNCTION__, p);
 609        /* Head = TQM */
 610        if (*((unsigned long *)p) != (unsigned long)CONFIG_SYS_HWINFO_MAGIC) {
 611                deb_printf("No HWIB\n");
 612                return -1;
 613        }
 614        p += 3;
 615        if (scanChar (p, 4, &hw->cpunr) < 0) {
 616                deb_printf("No CPU\n");
 617                return -2;
 618        }
 619        p +=4;
 620
 621        hw->flash = 0x200000 << (*p - 'A');
 622        p++;
 623        hw->flash_nr = *p - '0';
 624        p++;
 625
 626        hw->ram = 0x2000000 << (*p - 'A');
 627        p++;
 628        if (*p == '2') {
 629                hw->ram_cs = 2;
 630                p++;
 631        }
 632
 633        if (*p == 'A') hw->can = 1;
 634        if (*p == 'B') hw->can = 2;
 635        p +=1;
 636        p +=1;  /* connector */
 637        if (*p != '0') {
 638                hw->eeprom = 0x1000 << (*p - 'A');
 639        }
 640        p++;
 641
 642        if ((*p < '0') || (*p > '9')) {
 643                /* NAND before z-option */
 644                hw->nand = 0x8000000 << (*p - 'A');
 645                p++;
 646                hw->nand_cs = *p - '0';
 647                p += 2;
 648        }
 649        /* z-option */
 650        anz = scanChar (p, 4, &hw->option);
 651        if (anz < 0) {
 652                deb_printf("No option\n");
 653                return -3;
 654        }
 655        if (hw->option & 0x8) hw->Bus = 1;
 656        p += anz;
 657        if (*p != '-') {
 658                deb_printf("No -\n");
 659                return -4;
 660        }
 661        p++;
 662        /* C option */
 663        if (*p == 'E') {
 664                hw->SecEng = 1;
 665                p++;
 666        }
 667        switch (*p) {
 668                case 'M': hw->cpucl = 266666666;
 669                        break;
 670                case 'P': hw->cpucl = 300000000;
 671                        break;
 672                case 'T': hw->cpucl = 400000000;
 673                        break;
 674                default:
 675                        deb_printf("No CPU Clk: %c\n", *p);
 676                        return -5;
 677                        break;
 678        }
 679        p++;
 680        switch (*p) {
 681                case 'I': hw->cpmcl = 200000000;
 682                        break;
 683                case 'M': hw->cpmcl = 300000000;
 684                        break;
 685                default:
 686                        deb_printf("No CPM Clk\n");
 687                        return -6;
 688                        break;
 689        }
 690        p++;
 691        switch (*p) {
 692                case 'B': hw->buscl = 66666666;
 693                        break;
 694                case 'E': hw->buscl = 100000000;
 695                        break;
 696                case 'F': hw->buscl = 133333333;
 697                        break;
 698                default:
 699                        deb_printf("No BUS Clk\n");
 700                        return -7;
 701                        break;
 702        }
 703        p++;
 704
 705        hw->OK = 1;
 706        /* search MAC Address */
 707        while ((*p != '\0') && (pos < CONFIG_SYS_HWINFO_SIZE)) {
 708                if (*p < ' ' || *p > '~') { /* ASCII strings! */
 709                        return 0;
 710                }
 711                switch (part) {
 712                default:
 713                        if (*p == ' ') {
 714                                ++part;
 715                                i = 0;
 716                        }
 717                        break;
 718                case 3:                 /* Copy MAC address */
 719                        if (*p == ' ') {
 720                                ++part;
 721                                i = 0;
 722                                break;
 723                        }
 724                        hw->ethaddr[i++] = *p;
 725                        if ((i % 3) == 2)
 726                                hw->ethaddr[i++] = ':';
 727                        break;
 728
 729                }
 730                p++;
 731        }
 732
 733        hw->busclk_real_ok = search_real_busclk (&hw->busclk_real);
 734        return 0;
 735}
 736
 737#if defined(CONFIG_GET_CPU_STR_F)
 738/* !! This routine runs from Flash */
 739char get_cpu_str_f (char *buf)
 740{
 741        char *p = (char *) HWIB_INFO_START_ADDR;
 742        int     i = 0;
 743
 744        buf[i++] = 'M';
 745        buf[i++] = 'P';
 746        buf[i++] = 'C';
 747        if (*((unsigned long *)p) == (unsigned long)CONFIG_SYS_HWINFO_MAGIC) {
 748                buf[i++] = *&p[3];
 749                buf[i++] = *&p[4];
 750                buf[i++] = *&p[5];
 751                buf[i++] = *&p[6];
 752        } else {
 753                buf[i++] = '8';
 754                buf[i++] = '2';
 755                buf[i++] = '7';
 756                buf[i++] = 'x';
 757        }
 758        buf[i++] = 0;
 759        return 0;
 760}
 761#endif
 762
 763#if defined(CONFIG_BOARD_GET_CPU_CLK_F)
 764/* !! This routine runs from Flash */
 765unsigned long board_get_cpu_clk_f (void)
 766{
 767        char *p = (char *) HWIB_INFO_START_ADDR;
 768        int i = 0;
 769
 770        if (*((unsigned long *)p) == (unsigned long)CONFIG_SYS_HWINFO_MAGIC) {
 771                if (search_real_busclk (&i))
 772                        return i;
 773        }
 774        return CONFIG_8260_CLKIN;
 775}
 776#endif
 777
 778#if CONFIG_BOARD_EARLY_INIT_R
 779
 780static int can_test (unsigned long off)
 781{
 782        volatile unsigned char  *base   = (unsigned char *) (CONFIG_SYS_CAN_BASE + off);
 783
 784        *(base + 0x17) = 'T';
 785        *(base + 0x18) = 'Q';
 786        *(base + 0x19) = 'M';
 787        if ((*(base + 0x17) != 'T') ||
 788            (*(base + 0x18) != 'Q') ||
 789            (*(base + 0x19) != 'M')) {
 790                return 0;
 791        }
 792        return 1;
 793}
 794
 795static int can_config_one (unsigned long off)
 796{
 797        volatile unsigned char  *ctrl   = (unsigned char *) (CONFIG_SYS_CAN_BASE + off);
 798        volatile unsigned char  *cpu_if = (unsigned char *) (CONFIG_SYS_CAN_BASE + off + 0x02);
 799        volatile unsigned char  *clkout = (unsigned char *) (CONFIG_SYS_CAN_BASE + off + 0x1f);
 800        unsigned char temp;
 801
 802        *cpu_if = 0x45;
 803        temp = *ctrl;
 804        temp |= 0x40;
 805        *ctrl   = temp;
 806        *clkout = 0x20;
 807        temp = *ctrl;
 808        temp &= ~0x40;
 809        *ctrl   = temp;
 810        return 0;
 811}
 812
 813static int can_config (void)
 814{
 815        int     ret = 0;
 816        can_config_one (0);
 817        if (hwinf.can == 2) {
 818                can_config_one (0x100);
 819        }
 820        /* make Test if they really there */
 821        ret += can_test (0);
 822        ret += can_test (0x100);
 823        return ret;
 824}
 825
 826static int init_can (void)
 827{
 828        volatile immap_t * immr = (immap_t *)CONFIG_SYS_IMMR;
 829        volatile memctl8260_t *memctl = &immr->im_memctl;
 830        int     count = 0;
 831
 832        if ((hwinf.OK) && (hwinf.can)) {
 833                memctl->memc_or4 = CONFIG_SYS_CAN_OR;
 834                memctl->memc_br4 = CONFIG_SYS_CAN_BR;
 835                /* upm Init */
 836                upmconfig (UPMC, (uint *) upmTableFast,
 837                           sizeof (upmTableFast) / sizeof (uint));
 838                memctl->memc_mcmr =     (MxMR_DSx_3_CYCL |
 839                                        MxMR_GPL_x4DIS |
 840                                        MxMR_RLFx_2X |
 841                                        MxMR_WLFx_2X |
 842                                        MxMR_OP_NORM);
 843                /* can configure */
 844                count = can_config ();
 845                printf ("CAN:   %d @ %x\n", count, CONFIG_SYS_CAN_BASE);
 846                if (hwinf.can != count) printf("!!! difference to HWIB\n");
 847        } else {
 848                printf ("CAN:   No\n");
 849        }
 850        return 0;
 851}
 852
 853int board_early_init_r(void)
 854{
 855        analyse_hwib ();
 856        init_can ();
 857        return 0;
 858}
 859#endif
 860
 861int do_hwib_dump (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 862{
 863        dump_hwib ();
 864        return 0;
 865}
 866
 867U_BOOT_CMD(
 868          hwib, 1,      1,      do_hwib_dump,
 869          "dump HWIB'",
 870          ""
 871);
 872
 873#ifdef CONFIG_SYS_UPDATE_FLASH_SIZE
 874static int get_flash_timing (void)
 875{
 876        /* get it from the option -tf in CIB */
 877        /* default is 0x00000c84 */
 878        int     ret = 0x00000c84;
 879        int     pos = 0;
 880        int     nr = 0;
 881        char    *p = (char *) CIB_INFO_START_ADDR;
 882
 883        while ((*p != '\0') && (pos < CIB_INFO_LEN)) {
 884                if (*p < ' ' || *p > '~') { /* ASCII strings! */
 885                        return ret;
 886                }
 887                if (*p == '-') {
 888                        if ((p[1] == 't') && (p[2] == 'f')) {
 889                                p += 6;
 890                                ret = 0;
 891                                while (nr < 8) {
 892                                if ((*p >= '0') && (*p <= '9')) {
 893                                        ret *= 0x10;
 894                                        ret += *p - '0';
 895                                        p += 1;
 896                                        nr ++;
 897                                } else if ((*p >= 'A') && (*p <= 'F')) {
 898                                        ret *= 10;
 899                                        ret += *p - '7';
 900                                        p += 1;
 901                                        nr ++;
 902                                } else {
 903                                        if (nr < 8) return 0x00000c84;
 904                                        return ret;
 905                                }
 906                                }
 907                        }
 908                }
 909                p++;
 910                pos++;
 911        }
 912        return ret;
 913}
 914
 915/* Update the Flash_Size and the Flash Timing */
 916int update_flash_size (int flash_size)
 917{
 918        volatile immap_t * immr = (immap_t *)CONFIG_SYS_IMMR;
 919        volatile memctl8260_t *memctl = &immr->im_memctl;
 920        unsigned long reg;
 921        unsigned long tim;
 922
 923        /* I must use reg, otherwise the board hang */
 924        reg = memctl->memc_or0;
 925        reg &= ~ORxU_AM_MSK;
 926        reg |= MEG_TO_AM(flash_size >> 20);
 927        tim = get_flash_timing ();
 928        reg &= ~0xfff;
 929        reg |= (tim & 0xfff);
 930        memctl->memc_or0 = reg;
 931        return 0;
 932}
 933#endif
 934
 935#ifdef CONFIG_PCI
 936struct pci_controller hose;
 937
 938int board_early_init_f (void)
 939{
 940        volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
 941
 942        immap->im_clkrst.car_sccr |= M826X_SCCR_PCI_MODE_EN;
 943        return 0;
 944}
 945
 946extern void pci_mpc8250_init(struct pci_controller *);
 947
 948void pci_init_board(void)
 949{
 950        pci_mpc8250_init(&hose);
 951}
 952#endif
 953
 954int board_eth_init(bd_t *bis)
 955{
 956        return pci_eth_init(bis);
 957}
 958