uboot/board/tqc/tqm8xx/tqm8xx.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2000-2008
   3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   4 *
   5 * SPDX-License-Identifier:     GPL-2.0+
   6 */
   7
   8#include <common.h>
   9#include <hwconfig.h>
  10#include <mpc8xx.h>
  11#ifdef CONFIG_PS2MULT
  12#include <ps2mult.h>
  13#endif
  14
  15#if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT)
  16#include <libfdt.h>
  17#endif
  18
  19extern flash_info_t flash_info[];       /* FLASH chips info */
  20
  21DECLARE_GLOBAL_DATA_PTR;
  22
  23static long int dram_size (long int, long int *, long int);
  24
  25#define _NOT_USED_      0xFFFFFFFF
  26
  27/* UPM initialization table for SDRAM: 40, 50, 66 MHz CLKOUT @ CAS latency 2, tWR=2 */
  28const uint sdram_table[] =
  29{
  30        /*
  31         * Single Read. (Offset 0 in UPMA RAM)
  32         */
  33        0x1F0DFC04, 0xEEAFBC04, 0x11AF7C04, 0xEFBAFC00,
  34        0x1FF5FC47, /* last */
  35        /*
  36         * SDRAM Initialization (offset 5 in UPMA RAM)
  37         *
  38         * This is no UPM entry point. The following definition uses
  39         * the remaining space to establish an initialization
  40         * sequence, which is executed by a RUN command.
  41         *
  42         */
  43                    0x1FF5FC34, 0xEFEABC34, 0x1FB57C35, /* last */
  44        /*
  45         * Burst Read. (Offset 8 in UPMA RAM)
  46         */
  47        0x1F0DFC04, 0xEEAFBC04, 0x10AF7C04, 0xF0AFFC00,
  48        0xF0AFFC00, 0xF1AFFC00, 0xEFBAFC00, 0x1FF5FC47, /* last */
  49        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
  50        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
  51        /*
  52         * Single Write. (Offset 18 in UPMA RAM)
  53         */
  54        0x1F0DFC04, 0xEEABBC00, 0x11B77C04, 0xEFFAFC44,
  55        0x1FF5FC47, /* last */
  56                    _NOT_USED_, _NOT_USED_, _NOT_USED_,
  57        /*
  58         * Burst Write. (Offset 20 in UPMA RAM)
  59         */
  60        0x1F0DFC04, 0xEEABBC00, 0x10A77C00, 0xF0AFFC00,
  61        0xF0AFFC00, 0xF0AFFC04, 0xE1BAFC44, 0x1FF5FC47, /* last */
  62        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
  63        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
  64        /*
  65         * Refresh  (Offset 30 in UPMA RAM)
  66         */
  67        0x1FFD7C84, 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC04,
  68        0xFFFFFC84, 0xFFFFFC07, /* last */
  69                                _NOT_USED_, _NOT_USED_,
  70        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
  71        /*
  72         * Exception. (Offset 3c in UPMA RAM)
  73         */
  74        0xFFFFFC07, /* last */
  75                    _NOT_USED_, _NOT_USED_, _NOT_USED_,
  76};
  77
  78/* ------------------------------------------------------------------------- */
  79
  80
  81/*
  82 * Check Board Identity:
  83 *
  84 * Test TQ ID string (TQM8xx...)
  85 * If present, check for "L" type (no second DRAM bank),
  86 * otherwise "L" type is assumed as default.
  87 *
  88 * Set board_type to 'L' for "L" type, 'M' for "M" type, 0 else.
  89 */
  90
  91int checkboard (void)
  92{
  93        char buf[64];
  94        int i;
  95        int l = getenv_f("serial#", buf, sizeof(buf));
  96
  97        puts ("Board: ");
  98
  99        if (l < 0 || strncmp(buf, "TQM8", 4)) {
 100                puts ("### No HW ID - assuming TQM8xxL\n");
 101                return (0);
 102        }
 103
 104        if ((buf[6] == 'L')) {  /* a TQM8xxL type */
 105                gd->board_type = 'L';
 106        }
 107
 108        if ((buf[6] == 'M')) {  /* a TQM8xxM type */
 109                gd->board_type = 'M';
 110        }
 111
 112        if ((buf[6] == 'D')) {  /* a TQM885D type */
 113                gd->board_type = 'D';
 114        }
 115
 116        for (i = 0; i < l; ++i) {
 117                if (buf[i] == ' ')
 118                        break;
 119                putc (buf[i]);
 120        }
 121
 122        putc ('\n');
 123
 124        return (0);
 125}
 126
 127/* ------------------------------------------------------------------------- */
 128
 129phys_size_t initdram (int board_type)
 130{
 131        volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
 132        volatile memctl8xx_t *memctl = &immap->im_memctl;
 133        long int size8, size9, size10;
 134        long int size_b0 = 0;
 135        long int size_b1 = 0;
 136
 137        upmconfig (UPMA, (uint *) sdram_table,
 138                           sizeof (sdram_table) / sizeof (uint));
 139
 140        /*
 141         * Preliminary prescaler for refresh (depends on number of
 142         * banks): This value is selected for four cycles every 62.4 us
 143         * with two SDRAM banks or four cycles every 31.2 us with one
 144         * bank. It will be adjusted after memory sizing.
 145         */
 146        memctl->memc_mptpr = CONFIG_SYS_MPTPR_2BK_8K;
 147
 148        /*
 149         * The following value is used as an address (i.e. opcode) for
 150         * the LOAD MODE REGISTER COMMAND during SDRAM initialisation. If
 151         * the port size is 32bit the SDRAM does NOT "see" the lower two
 152         * address lines, i.e. mar=0x00000088 -> opcode=0x00000022 for
 153         * MICRON SDRAMs:
 154         * ->    0 00 010 0 010
 155         *       |  |   | |   +- Burst Length = 4
 156         *       |  |   | +----- Burst Type   = Sequential
 157         *       |  |   +------- CAS Latency  = 2
 158         *       |  +----------- Operating Mode = Standard
 159         *       +-------------- Write Burst Mode = Programmed Burst Length
 160         */
 161        memctl->memc_mar = 0x00000088;
 162
 163        /*
 164         * Map controller banks 2 and 3 to the SDRAM banks 2 and 3 at
 165         * preliminary addresses - these have to be modified after the
 166         * SDRAM size has been determined.
 167         */
 168        memctl->memc_or2 = CONFIG_SYS_OR2_PRELIM;
 169        memctl->memc_br2 = CONFIG_SYS_BR2_PRELIM;
 170
 171#ifndef CONFIG_CAN_DRIVER
 172        if ((board_type != 'L') &&
 173            (board_type != 'M') &&
 174            (board_type != 'D') ) {     /* only one SDRAM bank on L, M and D modules */
 175                memctl->memc_or3 = CONFIG_SYS_OR3_PRELIM;
 176                memctl->memc_br3 = CONFIG_SYS_BR3_PRELIM;
 177        }
 178#endif                                                  /* CONFIG_CAN_DRIVER */
 179
 180        memctl->memc_mamr = CONFIG_SYS_MAMR_8COL & (~(MAMR_PTAE));      /* no refresh yet */
 181
 182        udelay (200);
 183
 184        /* perform SDRAM initializsation sequence */
 185
 186        memctl->memc_mcr = 0x80004105;  /* SDRAM bank 0 */
 187        udelay (1);
 188        memctl->memc_mcr = 0x80004230;  /* SDRAM bank 0 - execute twice */
 189        udelay (1);
 190
 191#ifndef CONFIG_CAN_DRIVER
 192        if ((board_type != 'L') &&
 193            (board_type != 'M') &&
 194            (board_type != 'D') ) {     /* only one SDRAM bank on L, M and D modules */
 195                memctl->memc_mcr = 0x80006105;  /* SDRAM bank 1 */
 196                udelay (1);
 197                memctl->memc_mcr = 0x80006230;  /* SDRAM bank 1 - execute twice */
 198                udelay (1);
 199        }
 200#endif                                                  /* CONFIG_CAN_DRIVER */
 201
 202        memctl->memc_mamr |= MAMR_PTAE; /* enable refresh */
 203
 204        udelay (1000);
 205
 206        /*
 207         * Check Bank 0 Memory Size for re-configuration
 208         *
 209         * try 8 column mode
 210         */
 211        size8 = dram_size (CONFIG_SYS_MAMR_8COL, SDRAM_BASE2_PRELIM, SDRAM_MAX_SIZE);
 212        debug ("SDRAM Bank 0 in 8 column mode: %ld MB\n", size8 >> 20);
 213
 214        udelay (1000);
 215
 216        /*
 217         * try 9 column mode
 218         */
 219        size9 = dram_size (CONFIG_SYS_MAMR_9COL, SDRAM_BASE2_PRELIM, SDRAM_MAX_SIZE);
 220        debug ("SDRAM Bank 0 in 9 column mode: %ld MB\n", size9 >> 20);
 221
 222        udelay(1000);
 223
 224#if defined(CONFIG_SYS_MAMR_10COL)
 225        /*
 226         * try 10 column mode
 227         */
 228        size10 = dram_size (CONFIG_SYS_MAMR_10COL, SDRAM_BASE2_PRELIM, SDRAM_MAX_SIZE);
 229        debug ("SDRAM Bank 0 in 10 column mode: %ld MB\n", size10 >> 20);
 230#else
 231        size10 = 0;
 232#endif /* CONFIG_SYS_MAMR_10COL */
 233
 234        if ((size8 < size10) && (size9 < size10)) {
 235                size_b0 = size10;
 236        } else if ((size8 < size9) && (size10 < size9)) {
 237                size_b0 = size9;
 238                memctl->memc_mamr = CONFIG_SYS_MAMR_9COL;
 239                udelay (500);
 240        } else {
 241                size_b0 = size8;
 242                memctl->memc_mamr = CONFIG_SYS_MAMR_8COL;
 243                udelay (500);
 244        }
 245        debug ("SDRAM Bank 0: %ld MB\n", size_b0 >> 20);
 246
 247#ifndef CONFIG_CAN_DRIVER
 248        if ((board_type != 'L') &&
 249            (board_type != 'M') &&
 250            (board_type != 'D') ) {     /* only one SDRAM bank on L, M and D modules */
 251                /*
 252                 * Check Bank 1 Memory Size
 253                 * use current column settings
 254                 * [9 column SDRAM may also be used in 8 column mode,
 255                 *  but then only half the real size will be used.]
 256                 */
 257                size_b1 = dram_size (memctl->memc_mamr, (long int *)SDRAM_BASE3_PRELIM,
 258                                     SDRAM_MAX_SIZE);
 259                debug ("SDRAM Bank 1: %ld MB\n", size_b1 >> 20);
 260        } else {
 261                size_b1 = 0;
 262        }
 263#endif  /* CONFIG_CAN_DRIVER */
 264
 265        udelay (1000);
 266
 267        /*
 268         * Adjust refresh rate depending on SDRAM type, both banks
 269         * For types > 128 MBit leave it at the current (fast) rate
 270         */
 271        if ((size_b0 < 0x02000000) && (size_b1 < 0x02000000)) {
 272                /* reduce to 15.6 us (62.4 us / quad) */
 273                memctl->memc_mptpr = CONFIG_SYS_MPTPR_2BK_4K;
 274                udelay (1000);
 275        }
 276
 277        /*
 278         * Final mapping: map bigger bank first
 279         */
 280        if (size_b1 > size_b0) {        /* SDRAM Bank 1 is bigger - map first   */
 281
 282                memctl->memc_or3 = ((-size_b1) & 0xFFFF0000) | CONFIG_SYS_OR_TIMING_SDRAM;
 283                memctl->memc_br3 = (CONFIG_SYS_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V;
 284
 285                if (size_b0 > 0) {
 286                        /*
 287                         * Position Bank 0 immediately above Bank 1
 288                         */
 289                        memctl->memc_or2 = ((-size_b0) & 0xFFFF0000) | CONFIG_SYS_OR_TIMING_SDRAM;
 290                        memctl->memc_br2 = ((CONFIG_SYS_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V)
 291                                           + size_b1;
 292                } else {
 293                        unsigned long reg;
 294
 295                        /*
 296                         * No bank 0
 297                         *
 298                         * invalidate bank
 299                         */
 300                        memctl->memc_br2 = 0;
 301
 302                        /* adjust refresh rate depending on SDRAM type, one bank */
 303                        reg = memctl->memc_mptpr;
 304                        reg >>= 1;                      /* reduce to CONFIG_SYS_MPTPR_1BK_8K / _4K */
 305                        memctl->memc_mptpr = reg;
 306                }
 307
 308        } else {                                        /* SDRAM Bank 0 is bigger - map first   */
 309
 310                memctl->memc_or2 = ((-size_b0) & 0xFFFF0000) | CONFIG_SYS_OR_TIMING_SDRAM;
 311                memctl->memc_br2 =
 312                                (CONFIG_SYS_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V;
 313
 314                if (size_b1 > 0) {
 315                        /*
 316                         * Position Bank 1 immediately above Bank 0
 317                         */
 318                        memctl->memc_or3 =
 319                                        ((-size_b1) & 0xFFFF0000) | CONFIG_SYS_OR_TIMING_SDRAM;
 320                        memctl->memc_br3 =
 321                                        ((CONFIG_SYS_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V)
 322                                        + size_b0;
 323                } else {
 324                        unsigned long reg;
 325
 326#ifndef CONFIG_CAN_DRIVER
 327                        /*
 328                         * No bank 1
 329                         *
 330                         * invalidate bank
 331                         */
 332                        memctl->memc_br3 = 0;
 333#endif                                                  /* CONFIG_CAN_DRIVER */
 334
 335                        /* adjust refresh rate depending on SDRAM type, one bank */
 336                        reg = memctl->memc_mptpr;
 337                        reg >>= 1;                      /* reduce to CONFIG_SYS_MPTPR_1BK_8K / _4K */
 338                        memctl->memc_mptpr = reg;
 339                }
 340        }
 341
 342        udelay (10000);
 343
 344#ifdef  CONFIG_CAN_DRIVER
 345        /* UPM initialization for CAN @ CLKOUT <= 66 MHz */
 346
 347        /* Initialize OR3 / BR3 */
 348        memctl->memc_or3 = CONFIG_SYS_OR3_CAN;
 349        memctl->memc_br3 = CONFIG_SYS_BR3_CAN;
 350
 351        /* Initialize MBMR */
 352        memctl->memc_mbmr = MBMR_GPL_B4DIS;     /* GPL_B4 ouput line Disable */
 353
 354        /* Initialize UPMB for CAN: single read */
 355        memctl->memc_mdr = 0xFFFFCC04;
 356        memctl->memc_mcr = 0x0100 | UPMB;
 357
 358        memctl->memc_mdr = 0x0FFFD004;
 359        memctl->memc_mcr = 0x0101 | UPMB;
 360
 361        memctl->memc_mdr = 0x0FFFC000;
 362        memctl->memc_mcr = 0x0102 | UPMB;
 363
 364        memctl->memc_mdr = 0x3FFFC004;
 365        memctl->memc_mcr = 0x0103 | UPMB;
 366
 367        memctl->memc_mdr = 0xFFFFDC07;
 368        memctl->memc_mcr = 0x0104 | UPMB;
 369
 370        /* Initialize UPMB for CAN: single write */
 371        memctl->memc_mdr = 0xFFFCCC04;
 372        memctl->memc_mcr = 0x0118 | UPMB;
 373
 374        memctl->memc_mdr = 0xCFFCDC04;
 375        memctl->memc_mcr = 0x0119 | UPMB;
 376
 377        memctl->memc_mdr = 0x3FFCC000;
 378        memctl->memc_mcr = 0x011A | UPMB;
 379
 380        memctl->memc_mdr = 0xFFFCC004;
 381        memctl->memc_mcr = 0x011B | UPMB;
 382
 383        memctl->memc_mdr = 0xFFFDC405;
 384        memctl->memc_mcr = 0x011C | UPMB;
 385#endif                                                  /* CONFIG_CAN_DRIVER */
 386
 387#ifdef  CONFIG_ISP1362_USB
 388        /* Initialize OR5 / BR5 */
 389        memctl->memc_or5 = CONFIG_SYS_OR5_ISP1362;
 390        memctl->memc_br5 = CONFIG_SYS_BR5_ISP1362;
 391#endif                                                  /* CONFIG_ISP1362_USB */
 392        return (size_b0 + size_b1);
 393}
 394
 395/* ------------------------------------------------------------------------- */
 396
 397/*
 398 * Check memory range for valid RAM. A simple memory test determines
 399 * the actually available RAM size between addresses `base' and
 400 * `base + maxsize'. Some (not all) hardware errors are detected:
 401 * - short between address lines
 402 * - short between data lines
 403 */
 404
 405static long int dram_size (long int mamr_value, long int *base, long int maxsize)
 406{
 407        volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
 408        volatile memctl8xx_t *memctl = &immap->im_memctl;
 409
 410        memctl->memc_mamr = mamr_value;
 411
 412        return (get_ram_size(base, maxsize));
 413}
 414
 415/* ------------------------------------------------------------------------- */
 416
 417#ifdef CONFIG_MISC_INIT_R
 418extern void load_sernum_ethaddr(void);
 419int misc_init_r (void)
 420{
 421        volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
 422        volatile memctl8xx_t *memctl = &immap->im_memctl;
 423
 424        load_sernum_ethaddr();
 425
 426#ifdef  CONFIG_SYS_OR_TIMING_FLASH_AT_50MHZ
 427        int scy, trlx, flash_or_timing, clk_diff;
 428
 429        scy = (CONFIG_SYS_OR_TIMING_FLASH_AT_50MHZ & OR_SCY_MSK) >> 4;
 430        if (CONFIG_SYS_OR_TIMING_FLASH_AT_50MHZ & OR_TRLX) {
 431                trlx = OR_TRLX;
 432                scy *= 2;
 433        } else {
 434                trlx = 0;
 435        }
 436
 437        /*
 438         * We assume that each 10MHz of bus clock require 1-clk SCY
 439         * adjustment.
 440         */
 441        clk_diff = (gd->bus_clk / 1000000) - 50;
 442
 443        /*
 444         * We need proper rounding here. This is what the "+5" and "-5"
 445         * are here for.
 446         */
 447        if (clk_diff >= 0)
 448                scy += (clk_diff + 5) / 10;
 449        else
 450                scy += (clk_diff - 5) / 10;
 451
 452        /*
 453         * For bus frequencies above 50MHz, we want to use relaxed timing
 454         * (OR_TRLX).
 455         */
 456        if (gd->bus_clk >= 50000000)
 457                trlx = OR_TRLX;
 458        else
 459                trlx = 0;
 460
 461        if (trlx)
 462                scy /= 2;
 463
 464        if (scy > 0xf)
 465                scy = 0xf;
 466        if (scy < 1)
 467                scy = 1;
 468
 469        flash_or_timing = (scy << 4) | trlx |
 470                (CONFIG_SYS_OR_TIMING_FLASH_AT_50MHZ & ~(OR_TRLX | OR_SCY_MSK));
 471
 472        memctl->memc_or0 =
 473                flash_or_timing | (-flash_info[0].size & OR_AM_MSK);
 474#else
 475        memctl->memc_or0 =
 476                CONFIG_SYS_OR_TIMING_FLASH | (-flash_info[0].size & OR_AM_MSK);
 477#endif
 478        memctl->memc_br0 = (CONFIG_SYS_FLASH_BASE & BR_BA_MSK) | BR_MS_GPCM | BR_V;
 479
 480        debug ("## BR0: 0x%08x    OR0: 0x%08x\n",
 481               memctl->memc_br0, memctl->memc_or0);
 482
 483        if (flash_info[1].size) {
 484#ifdef  CONFIG_SYS_OR_TIMING_FLASH_AT_50MHZ
 485                memctl->memc_or1 = flash_or_timing |
 486                        (-flash_info[1].size & 0xFFFF8000);
 487#else
 488                memctl->memc_or1 = CONFIG_SYS_OR_TIMING_FLASH |
 489                        (-flash_info[1].size & 0xFFFF8000);
 490#endif
 491                memctl->memc_br1 =
 492                        ((CONFIG_SYS_FLASH_BASE +
 493                          flash_info[0].
 494                          size) & BR_BA_MSK) | BR_MS_GPCM | BR_V;
 495
 496                debug ("## BR1: 0x%08x    OR1: 0x%08x\n",
 497                       memctl->memc_br1, memctl->memc_or1);
 498        } else {
 499                memctl->memc_br1 = 0;   /* invalidate bank */
 500
 501                debug ("## DISABLE BR1: 0x%08x    OR1: 0x%08x\n",
 502                       memctl->memc_br1, memctl->memc_or1);
 503        }
 504
 505# ifdef CONFIG_IDE_LED
 506        /* Configure PA15 as output port */
 507        immap->im_ioport.iop_padir |= 0x0001;
 508        immap->im_ioport.iop_paodr |= 0x0001;
 509        immap->im_ioport.iop_papar &= ~0x0001;
 510        immap->im_ioport.iop_padat &= ~0x0001;  /* turn it off */
 511# endif
 512
 513        return (0);
 514}
 515#endif  /* CONFIG_MISC_INIT_R */
 516
 517
 518# ifdef CONFIG_IDE_LED
 519void ide_led (uchar led, uchar status)
 520{
 521        volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
 522
 523        /* We have one led for both pcmcia slots */
 524        if (status) {                           /* led on */
 525                immap->im_ioport.iop_padat |= 0x0001;
 526        } else {
 527                immap->im_ioport.iop_padat &= ~0x0001;
 528        }
 529}
 530# endif
 531
 532#ifdef CONFIG_LCD_INFO
 533#include <lcd.h>
 534#include <version.h>
 535#include <timestamp.h>
 536
 537void lcd_show_board_info(void)
 538{
 539        char temp[32];
 540
 541        lcd_printf ("%s (%s - %s)\n", U_BOOT_VERSION, U_BOOT_DATE, U_BOOT_TIME);
 542        lcd_printf ("(C) 2008 DENX Software Engineering GmbH\n");
 543        lcd_printf ("    Wolfgang DENK, wd@denx.de\n");
 544#ifdef CONFIG_LCD_INFO_BELOW_LOGO
 545        lcd_printf ("MPC823 CPU at %s MHz\n",
 546                strmhz(temp, gd->cpu_clk));
 547        lcd_printf ("  %ld MB RAM, %ld MB Flash\n",
 548                gd->ram_size >> 20,
 549                gd->bd->bi_flashsize >> 20 );
 550#else
 551        /* leave one blank line */
 552        lcd_printf ("\nMPC823 CPU at %s MHz, %ld MB RAM, %ld MB Flash\n",
 553                strmhz(temp, gd->cpu_clk),
 554                gd->ram_size >> 20,
 555                gd->bd->bi_flashsize >> 20 );
 556#endif /* CONFIG_LCD_INFO_BELOW_LOGO */
 557}
 558#endif /* CONFIG_LCD_INFO */
 559
 560/*
 561 * Device Tree Support
 562 */
 563#if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT)
 564int fdt_set_node_and_value (void *blob,
 565                                char *nodename,
 566                                char *regname,
 567                                void *var,
 568                                int size)
 569{
 570        int ret = 0;
 571        int nodeoffset = 0;
 572
 573        nodeoffset = fdt_path_offset (blob, nodename);
 574        if (nodeoffset >= 0) {
 575                ret = fdt_setprop (blob, nodeoffset, regname, var,
 576                                        size);
 577                if (ret < 0) {
 578                        printf("ft_blob_update(): "
 579                                "cannot set %s/%s property; err: %s\n",
 580                                nodename, regname, fdt_strerror (ret));
 581                }
 582        } else {
 583                printf("ft_blob_update(): "
 584                        "cannot find %s node err:%s\n",
 585                        nodename, fdt_strerror (nodeoffset));
 586        }
 587        return ret;
 588}
 589
 590int fdt_del_node_name (void *blob, char *nodename)
 591{
 592        int ret = 0;
 593        int nodeoffset = 0;
 594
 595        nodeoffset = fdt_path_offset (blob, nodename);
 596        if (nodeoffset >= 0) {
 597                ret = fdt_del_node (blob, nodeoffset);
 598                if (ret < 0) {
 599                        printf("%s: cannot delete %s; err: %s\n",
 600                                __func__, nodename, fdt_strerror (ret));
 601                }
 602        } else {
 603                printf("%s: cannot find %s node err:%s\n",
 604                        __func__, nodename, fdt_strerror (nodeoffset));
 605        }
 606        return ret;
 607}
 608
 609int fdt_del_prop_name (void *blob, char *nodename, char *propname)
 610{
 611        int ret = 0;
 612        int nodeoffset = 0;
 613
 614        nodeoffset = fdt_path_offset (blob, nodename);
 615        if (nodeoffset >= 0) {
 616                ret = fdt_delprop (blob, nodeoffset, propname);
 617                if (ret < 0) {
 618                        printf("%s: cannot delete %s %s; err: %s\n",
 619                                __func__, nodename, propname,
 620                                fdt_strerror (ret));
 621                }
 622        } else {
 623                printf("%s: cannot find %s node err:%s\n",
 624                        __func__, nodename, fdt_strerror (nodeoffset));
 625        }
 626        return ret;
 627}
 628
 629/*
 630 * update "brg" property in the blob
 631 */
 632void ft_blob_update (void *blob, bd_t *bd)
 633{
 634        uchar enetaddr[6];
 635        ulong brg_data = 0;
 636
 637        /* BRG */
 638        brg_data = cpu_to_be32(bd->bi_busfreq);
 639        fdt_set_node_and_value(blob,
 640                                "/soc/cpm", "brg-frequency",
 641                                &brg_data, sizeof(brg_data));
 642
 643        /* MAC addr */
 644        if (eth_getenv_enetaddr("ethaddr", enetaddr)) {
 645                fdt_set_node_and_value(blob,
 646                                        "ethernet0", "local-mac-address",
 647                                        enetaddr, sizeof(u8) * 6);
 648        }
 649
 650        if (hwconfig_arg_cmp("fec", "off")) {
 651                /* no FEC on this plattform, delete DTS nodes */
 652                fdt_del_node_name (blob, "ethernet1");
 653                fdt_del_node_name (blob, "mdio1");
 654                /* also the aliases entries */
 655                fdt_del_prop_name (blob, "/aliases", "ethernet1");
 656                fdt_del_prop_name (blob, "/aliases", "mdio1");
 657        } else {
 658                /* adjust local-mac-address for FEC ethernet */
 659                if (eth_getenv_enetaddr("eth1addr", enetaddr)) {
 660                        fdt_set_node_and_value(blob,
 661                                        "ethernet1", "local-mac-address",
 662                                        enetaddr, sizeof(u8) * 6);
 663                }
 664        }
 665}
 666
 667int ft_board_setup(void *blob, bd_t *bd)
 668{
 669        ft_cpu_setup(blob, bd);
 670        ft_blob_update(blob, bd);
 671
 672        return 0;
 673}
 674#endif /* defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT) */
 675