uboot/board/keymile/km82xx/km82xx.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2007 - 2008
   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 <mpc8260.h>
  26#include <ioports.h>
  27#include <malloc.h>
  28#include <asm/io.h>
  29
  30#if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT)
  31#include <libfdt.h>
  32#endif
  33
  34#include <i2c.h>
  35#include "../common/common.h"
  36
  37/*
  38 * I/O Port configuration table
  39 *
  40 * if conf is 1, then that port pin will be configured at boot time
  41 * according to the five values podr/pdir/ppar/psor/pdat for that entry
  42 */
  43const iop_conf_t iop_conf_tab[4][32] = {
  44
  45        /* Port A */
  46        {       /*            conf      ppar psor pdir podr pdat */
  47                { 0,             0,   0,   0,   0,   0 }, /* PA31            */
  48                { 0,             0,   0,   0,   0,   0 }, /* PA30            */
  49                { 0,             0,   0,   0,   0,   0 }, /* PA29            */
  50                { 0,             0,   0,   0,   0,   0 }, /* PA28            */
  51                { 0,             0,   0,   0,   0,   0 }, /* PA27            */
  52                { 0,             0,   0,   0,   0,   0 }, /* PA26            */
  53                { 0,             0,   0,   0,   0,   0 }, /* PA25            */
  54                { 0,             0,   0,   0,   0,   0 }, /* PA24            */
  55                { 0,             0,   0,   0,   0,   0 }, /* PA23            */
  56                { 0,             0,   0,   0,   0,   0 }, /* PA22            */
  57                { 0,             0,   0,   0,   0,   0 }, /* PA21            */
  58                { 0,             0,   0,   0,   0,   0 }, /* PA20            */
  59                { 0,             0,   0,   0,   0,   0 }, /* PA19            */
  60                { 0,             0,   0,   0,   0,   0 }, /* PA18            */
  61                { 0,             0,   0,   0,   0,   0 }, /* PA17            */
  62                { 0,             0,   0,   0,   0,   0 }, /* PA16            */
  63                { 0,             0,   0,   0,   0,   0 }, /* PA15            */
  64                { 0,             0,   0,   0,   0,   0 }, /* PA14            */
  65                { 0,             0,   0,   0,   0,   0 }, /* PA13            */
  66                { 0,             0,   0,   0,   0,   0 }, /* PA12            */
  67                { 0,             0,   0,   0,   0,   0 }, /* PA11            */
  68                { 0,             0,   0,   0,   0,   0 }, /* PA10            */
  69                { 1,             1,   0,   1,   0,   0 }, /* PA9 SMC2 TxD    */
  70                { 1,             1,   0,   0,   0,   0 }, /* PA8 SMC2 RxD    */
  71                { 0,             0,   0,   0,   0,   0 }, /* PA7             */
  72                { 0,             0,   0,   0,   0,   0 }, /* PA6             */
  73                { 0,             0,   0,   0,   0,   0 }, /* PA5             */
  74                { 0,             0,   0,   0,   0,   0 }, /* PA4             */
  75                { 0,             0,   0,   0,   0,   0 }, /* PA3             */
  76                { 0,             0,   0,   0,   0,   0 }, /* PA2             */
  77                { 0,             0,   0,   0,   0,   0 }, /* PA1             */
  78                { 0,             0,   0,   0,   0,   0 }  /* PA0             */
  79        },
  80
  81        /* Port B */
  82        {       /*            conf      ppar psor pdir podr pdat */
  83                { 0,             0,   0,   0,   0,   0 }, /* PB31            */
  84                { 0,             0,   0,   0,   0,   0 }, /* PB30            */
  85                { 0,             0,   0,   0,   0,   0 }, /* PB29            */
  86                { 0,             0,   0,   0,   0,   0 }, /* PB28            */
  87                { 0,             0,   0,   0,   0,   0 }, /* PB27            */
  88                { 0,             0,   0,   0,   0,   0 }, /* PB26            */
  89                { 0,             0,   0,   0,   0,   0 }, /* PB25            */
  90                { 0,             0,   0,   0,   0,   0 }, /* PB24            */
  91                { 0,             0,   0,   0,   0,   0 }, /* PB23            */
  92                { 0,             0,   0,   0,   0,   0 }, /* PB22            */
  93                { 0,             0,   0,   0,   0,   0 }, /* PB21            */
  94                { 0,             0,   0,   0,   0,   0 }, /* PB20            */
  95                { 0,             0,   0,   0,   0,   0 }, /* PB19            */
  96                { 0,             0,   0,   0,   0,   0 }, /* PB18            */
  97                { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
  98                { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
  99                { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
 100                { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
 101                { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
 102                { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
 103                { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
 104                { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
 105                { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
 106                { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
 107                { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
 108                { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
 109                { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
 110                { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
 111                { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
 112                { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
 113                { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
 114                { 0,             0,   0,   0,   0,   0 }  /* non-existent    */
 115        },
 116
 117        /* Port C */
 118        {       /*            conf      ppar psor pdir podr pdat */
 119                { 0,             0,   0,   0,   0,   0 }, /* PC31            */
 120                { 0,             0,   0,   0,   0,   0 }, /* PC30            */
 121                { 0,             0,   0,   0,   0,   0 }, /* PC29            */
 122                { 0,             0,   0,   0,   0,   0 }, /* PC28            */
 123                { 0,             0,   0,   0,   0,   0 }, /* PC27            */
 124                { 0,             0,   0,   0,   0,   0 }, /* PC26            */
 125                { 1,             1,   0,   0,   0,   0 }, /* PC25 RxClk      */
 126                { 1,             1,   0,   0,   0,   0 }, /* PC24 TxClk      */
 127                { 0,             0,   0,   0,   0,   0 }, /* PC23            */
 128                { 0,             0,   0,   0,   0,   0 }, /* PC22            */
 129                { 0,             0,   0,   0,   0,   0 }, /* PC21            */
 130                { 0,             0,   0,   0,   0,   0 }, /* PC20            */
 131                { 0,             0,   0,   0,   0,   0 }, /* PC19            */
 132                { 0,             0,   0,   0,   0,   0 }, /* PC18            */
 133                { 0,             0,   0,   0,   0,   0 }, /* PC17            */
 134                { 0,             0,   0,   0,   0,   0 }, /* PC16            */
 135                { 0,             0,   0,   0,   0,   0 }, /* PC15            */
 136                { 0,             0,   0,   0,   0,   0 }, /* PC14            */
 137                { 0,             0,   0,   0,   0,   0 }, /* PC13            */
 138                { 0,             0,   0,   0,   0,   0 }, /* PC12            */
 139                { 0,             0,   0,   0,   0,   0 }, /* PC11            */
 140                { 0,             0,   0,   0,   0,   0 }, /* PC10            */
 141                { 1,             1,   0,   0,   0,   0 }, /* PC9  SCC4: CTS  */
 142                { 1,             1,   0,   0,   0,   0 }, /* PC8  SCC4: CD   */
 143                { 0,             0,   0,   0,   0,   0 }, /* PC7             */
 144                { 0,             0,   0,   0,   0,   0 }, /* PC6             */
 145                { 0,             0,   0,   0,   0,   0 }, /* PC5             */
 146                { 0,             0,   0,   0,   0,   0 }, /* PC4             */
 147                { 0,             0,   0,   0,   0,   0 }, /* PC3             */
 148                { 0,             0,   0,   0,   0,   0 }, /* PC2             */
 149                { 0,             0,   0,   0,   0,   0 }, /* PC1             */
 150                { 0,             0,   0,   0,   0,   0 }, /* PC0             */
 151        },
 152
 153        /* Port D */
 154        {       /*            conf      ppar psor pdir podr pdat */
 155                { 0,             0,   0,   0,   0,   0 }, /* PD31            */
 156                { 0,             0,   0,   0,   0,   0 }, /* PD30            */
 157                { 0,             0,   0,   0,   0,   0 }, /* PD29            */
 158                { 0,             0,   0,   0,   0,   0 }, /* PD28            */
 159                { 0,             0,   0,   0,   0,   0 }, /* PD27            */
 160                { 0,             0,   0,   0,   0,   0 }, /* PD26            */
 161                { 0,             0,   0,   0,   0,   0 }, /* PD25            */
 162                { 0,             0,   0,   0,   0,   0 }, /* PD24            */
 163                { 0,             0,   0,   0,   0,   0 }, /* PD23            */
 164                { 1,             1,   0,   0,   0,   0 }, /* PD22 SCC4: RXD  */
 165                { 1,             1,   0,   1,   0,   0 }, /* PD21 SCC4: TXD  */
 166                { 1,             1,   0,   1,   0,   0 }, /* PD20 SCC4: RTS  */
 167                { 0,             0,   0,   0,   0,   0 }, /* PD19            */
 168                { 0,             0,   0,   0,   0,   0 }, /* PD18            */
 169                { 0,             0,   0,   0,   0,   0 }, /* PD17            */
 170                { 0,             0,   0,   0,   0,   0 }, /* PD16            */
 171#if defined(CONFIG_HARD_I2C)
 172                { 1,             1,   1,   0,   1,   0 }, /* PD15 I2C SDA    */
 173                { 1,             1,   1,   0,   1,   0 }, /* PD14 I2C SCL    */
 174#else
 175                { 1,             0,   0,   0,   1,   1 }, /* PD15            */
 176                { 1,             0,   0,   1,   1,   1 }, /* PD14            */
 177#endif
 178                { 0,             0,   0,   0,   0,   0 }, /* PD13            */
 179                { 0,             0,   0,   0,   0,   0 }, /* PD12            */
 180                { 0,             0,   0,   0,   0,   0 }, /* PD11            */
 181                { 0,             0,   0,   0,   0,   0 }, /* PD10            */
 182                { 0,             0,   0,   0,   0,   0 }, /* PD9             */
 183                { 0,             0,   0,   0,   0,   0 }, /* PD8             */
 184                { 0,             0,   0,   0,   0,   0 }, /* PD7             */
 185                { 0,             0,   0,   0,   0,   0 }, /* PD6             */
 186                { 0,             0,   0,   0,   0,   0 }, /* PD5             */
 187                { 0,             0,   0,   0,   0,   0 }, /* PD4             */
 188                { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
 189                { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
 190                { 0,             0,   0,   0,   0,   0 }, /* non-existent    */
 191                { 0,             0,   0,   0,   0,   0 }  /* non-existent    */
 192        }
 193};
 194
 195/*
 196 * Try SDRAM initialization with P/LSDMR=sdmr and ORx=orx
 197 *
 198 * This routine performs standard 8260 initialization sequence
 199 * and calculates the available memory size. It may be called
 200 * several times to try different SDRAM configurations on both
 201 * 60x and local buses.
 202 */
 203static long int try_init(memctl8260_t *memctl, ulong sdmr,
 204                                  ulong orx, uchar *base)
 205{
 206        uchar c = 0xff;
 207        ulong maxsize, size;
 208        int i;
 209
 210        /*
 211         * We must be able to test a location outsize the maximum legal size
 212         * to find out THAT we are outside; but this address still has to be
 213         * mapped by the controller. That means, that the initial mapping has
 214         * to be (at least) twice as large as the maximum expected size.
 215         */
 216        maxsize = (1 + (~orx | 0x7fff))/* / 2*/;
 217
 218        out_be32(&memctl->memc_or1, orx);
 219
 220        /*
 221         * Quote from 8260 UM (10.4.2 SDRAM Power-On Initialization, 10-35):
 222         *
 223         * "At system reset, initialization software must set up the
 224         *  programmable parameters in the memory controller banks registers
 225         *  (ORx, BRx, P/LSDMR). After all memory parameters are configured,
 226         *  system software should execute the following initialization sequence
 227         *  for each SDRAM device.
 228         *
 229         *  1. Issue a PRECHARGE-ALL-BANKS command
 230         *  2. Issue eight CBR REFRESH commands
 231         *  3. Issue a MODE-SET command to initialize the mode register
 232         *
 233         *  The initial commands are executed by setting P/LSDMR[OP] and
 234         *  accessing the SDRAM with a single-byte transaction."
 235         *
 236         * The appropriate BRx/ORx registers have already been set when we
 237         * get here. The SDRAM can be accessed at the address
 238         * CONFIG_SYS_SDRAM_BASE.
 239         */
 240
 241        out_be32(&memctl->memc_psdmr, sdmr | PSDMR_OP_PREA);
 242        out_8(base, c);
 243
 244        out_be32(&memctl->memc_psdmr, sdmr | PSDMR_OP_CBRR);
 245        for (i = 0; i < 8; i++)
 246                out_8(base, c);
 247
 248        out_be32(&memctl->memc_psdmr, sdmr | PSDMR_OP_MRW);
 249        /* setting MR on address lines */
 250        out_8((uchar *)(base + CONFIG_SYS_MRS_OFFS), c);
 251
 252        out_be32(&memctl->memc_psdmr, sdmr | PSDMR_OP_NORM | PSDMR_RFEN);
 253        out_8(base, c);
 254
 255        size = get_ram_size((long *)base, maxsize);
 256        out_be32(&memctl->memc_or1, orx | ~(size - 1));
 257
 258        return size;
 259}
 260
 261#ifdef CONFIG_SYS_SDRAM_LIST
 262
 263/*
 264 * If CONFIG_SYS_SDRAM_LIST is defined, we cycle through all SDRAM
 265 * configurations therein (should be from high to lower) to find the
 266 * one actually matching the current configuration.
 267 * CONFIG_SYS_PSDMR and CONFIG_SYS_OR1 will contain the base values which are
 268 * common among all possible configurations; values in CONFIG_SYS_SDRAM_LIST
 269 * (defined as the initialization value for the array of struct sdram_conf_s)
 270 * will then be ORed with such base values.
 271 */
 272
 273struct sdram_conf_s {
 274        ulong size;
 275        int or1;
 276        int psdmr;
 277};
 278
 279static struct sdram_conf_s sdram_conf[] = CONFIG_SYS_SDRAM_LIST;
 280
 281static long probe_sdram(memctl8260_t *memctl)
 282{
 283        int n = 0;
 284        long psize = 0;
 285
 286        for (n = 0; n < ARRAY_SIZE(sdram_conf); psize = 0, n++) {
 287                psize = try_init(memctl,
 288                        CONFIG_SYS_PSDMR | sdram_conf[n].psdmr,
 289                        CONFIG_SYS_OR1 | sdram_conf[n].or1,
 290                        (uchar *) CONFIG_SYS_SDRAM_BASE);
 291                debug("Probing %ld bytes returned %ld\n",
 292                        sdram_conf[n].size, psize);
 293                if (psize == sdram_conf[n].size)
 294                        break;
 295        }
 296        return psize;
 297}
 298
 299#else /* CONFIG_SYS_SDRAM_LIST */
 300
 301static long probe_sdram(memctl8260_t *memctl)
 302{
 303        return try_init(memctl, CONFIG_SYS_PSDMR, CONFIG_SYS_OR1,
 304                                        (uchar *) CONFIG_SYS_SDRAM_BASE);
 305}
 306#endif /* CONFIG_SYS_SDRAM_LIST */
 307
 308
 309phys_size_t initdram(int board_type)
 310{
 311        immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
 312        memctl8260_t *memctl = &immap->im_memctl;
 313
 314        long psize;
 315
 316        out_8(&memctl->memc_psrt, CONFIG_SYS_PSRT);
 317        out_be16(&memctl->memc_mptpr, CONFIG_SYS_MPTPR);
 318
 319#ifndef CONFIG_SYS_RAMBOOT
 320        /* 60x SDRAM setup:
 321         */
 322        psize = probe_sdram(memctl);
 323#endif /* CONFIG_SYS_RAMBOOT */
 324
 325        icache_enable();
 326
 327        return psize;
 328}
 329
 330int checkboard(void)
 331{
 332#if defined(CONFIG_MGCOGE)
 333        puts("Board: Keymile mgcoge");
 334#else
 335        puts("Board: Keymile mgcoge3ne");
 336#endif
 337        if (ethernet_present())
 338                puts(" with PIGGY.");
 339        puts("\n");
 340        return 0;
 341}
 342
 343int last_stage_init(void)
 344{
 345        struct bfticu_iomap *base =
 346                (struct bfticu_iomap *)CONFIG_SYS_FPGA_BASE;
 347        u8 dip_switch;
 348
 349        dip_switch = in_8(&base->mswitch);
 350        dip_switch &= BFTICU_DIPSWITCH_MASK;
 351        /* dip switch 'full reset' or 'db erase' */
 352        if (dip_switch & 0x1 || dip_switch & 0x2) {
 353                /* start bootloader */
 354                puts("DIP:   Enabled\n");
 355                setenv("actual_bank", "0");
 356        }
 357        set_km_env();
 358        return 0;
 359}
 360
 361#ifdef CONFIG_MGCOGE3NE
 362static void set_pin(int state, unsigned long mask);
 363
 364/*
 365 * For mgcoge3ne boards, the mgcoge3un control is controlled from
 366 * a GPIO line on the PPC CPU. If bobcatreset is set the line
 367 * will toggle once what forces the mgocge3un part to restart
 368 * immediately.
 369 */
 370static void handle_mgcoge3un_reset(void)
 371{
 372        char *bobcatreset = getenv("bobcatreset");
 373        if (bobcatreset) {
 374                if (strcmp(bobcatreset, "true") == 0) {
 375                        puts("Forcing bobcat reset\n");
 376                        set_pin(0, 0x00000004); /* clear PD29 to reset arm */
 377                        udelay(1000);
 378                        set_pin(1, 0x00000004);
 379                } else
 380                        set_pin(1, 0x00000004); /* set PD29 to not reset arm */
 381        }
 382}
 383#endif
 384
 385int ethernet_present(void)
 386{
 387        struct km_bec_fpga *base =
 388                (struct km_bec_fpga *)CONFIG_SYS_KMBEC_FPGA_BASE;
 389
 390        return in_8(&base->bprth) & PIGGY_PRESENT;
 391}
 392
 393/*
 394 * Early board initalization.
 395 */
 396int board_early_init_r(void)
 397{
 398        struct km_bec_fpga *base =
 399                (struct km_bec_fpga *)CONFIG_SYS_KMBEC_FPGA_BASE;
 400
 401        /* setup the UPIOx */
 402        /* General Unit Reset disabled, Flash Bank enabled, UnitLed on */
 403        out_8(&base->oprth, (WRG_RESET | H_OPORTS_14 | WRG_LED));
 404        /* SCC4 enable, halfduplex, FCC1 powerdown */
 405        out_8(&base->oprtl, (H_OPORTS_SCC4_ENA | H_OPORTS_SCC4_FD_ENA |
 406                H_OPORTS_FCC1_PW_DWN));
 407
 408#ifdef CONFIG_MGCOGE3NE
 409        handle_mgcoge3un_reset();
 410#endif
 411        return 0;
 412}
 413
 414int hush_init_var(void)
 415{
 416        ivm_read_eeprom();
 417        return 0;
 418}
 419
 420#define SDA_MASK        0x00010000
 421#define SCL_MASK        0x00020000
 422
 423static void set_pin(int state, unsigned long mask)
 424{
 425        ioport_t *iop = ioport_addr((immap_t *)CONFIG_SYS_IMMR, 3);
 426
 427        if (state)
 428                setbits_be32(&iop->pdat, mask);
 429        else
 430                clrbits_be32(&iop->pdat, mask);
 431
 432        setbits_be32(&iop->pdir, mask);
 433}
 434
 435static int get_pin(unsigned long mask)
 436{
 437        ioport_t *iop = ioport_addr((immap_t *)CONFIG_SYS_IMMR, 3);
 438
 439        clrbits_be32(&iop->pdir, mask);
 440        return 0 != (in_be32(&iop->pdat) & mask);
 441}
 442
 443void set_sda(int state)
 444{
 445        set_pin(state, SDA_MASK);
 446}
 447
 448void set_scl(int state)
 449{
 450        set_pin(state, SCL_MASK);
 451}
 452
 453int get_sda(void)
 454{
 455        return get_pin(SDA_MASK);
 456}
 457
 458int get_scl(void)
 459{
 460        return get_pin(SCL_MASK);
 461}
 462
 463#if defined(CONFIG_HARD_I2C)
 464static void setports(int gpio)
 465{
 466        ioport_t *iop = ioport_addr((immap_t *)CONFIG_SYS_IMMR, 3);
 467
 468        if (gpio) {
 469                clrbits_be32(&iop->ppar, (SDA_MASK | SCL_MASK));
 470                clrbits_be32(&iop->podr, (SDA_MASK | SCL_MASK));
 471        } else {
 472                setbits_be32(&iop->ppar, (SDA_MASK | SCL_MASK));
 473                clrbits_be32(&iop->pdir, (SDA_MASK | SCL_MASK));
 474                setbits_be32(&iop->podr, (SDA_MASK | SCL_MASK));
 475        }
 476}
 477#endif
 478#if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT)
 479void ft_board_setup(void *blob, bd_t *bd)
 480{
 481        ft_cpu_setup(blob, bd);
 482}
 483#endif /* defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT) */
 484