uboot/board/svm_sc8xx/flash.c
<<
>>
Prefs
   1/*
   2 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   3 *
   4 * See file CREDITS for list of people who contributed to this
   5 * project.
   6 *
   7 * This program is free software; you can redistribute it and/or
   8 * modify it under the terms of the GNU General Public License as
   9 * published by the Free Software Foundation; either version 2 of
  10 * the License, or (at your option) any later version.
  11 *
  12 * This program is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU General Public License
  18 * along with this program; if not, write to the Free Software
  19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  20 * MA 02111-1307 USA
  21 */
  22
  23#include <common.h>
  24#include <mpc8xx.h>
  25
  26#ifndef CONFIG_ENV_ADDR
  27#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + CONFIG_ENV_OFFSET)
  28#endif
  29
  30flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
  31
  32/*-----------------------------------------------------------------------
  33 * Functions
  34 */
  35static int write_word(flash_info_t *info, ulong dest, ulong data);
  36
  37#ifdef CONFIG_BOOT_8B
  38static int my_in_8(unsigned char *addr);
  39static void my_out_8(unsigned char *addr, int val);
  40#endif
  41#ifdef CONFIG_BOOT_16B
  42static int my_in_be16(unsigned short *addr);
  43static void my_out_be16(unsigned short *addr, int val);
  44#endif
  45#ifdef CONFIG_BOOT_32B
  46static unsigned my_in_be32(unsigned *addr);
  47static void my_out_be32(unsigned *addr, int val);
  48#endif
  49/*-----------------------------------------------------------------------
  50 */
  51
  52unsigned long flash_init(void)
  53{
  54        volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
  55        volatile memctl8xx_t *memctl = &immap->im_memctl;
  56        unsigned long size_b0, size_b1;
  57        int i;
  58
  59        size_b0 = 0;
  60        size_b1 = 0;
  61        /* Init: no FLASHes known */
  62        for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i)
  63                flash_info[i].flash_id = FLASH_UNKNOWN;
  64
  65#ifdef CONFIG_SYS_DOC_BASE
  66#ifndef CONFIG_FEL8xx_AT
  67        /* 32k bytes */
  68        memctl->memc_or5 = (0xffff8000 | CONFIG_SYS_OR_TIMING_DOC);
  69        memctl->memc_br5 = CONFIG_SYS_DOC_BASE | 0x401;
  70#else
  71        /* 32k bytes */
  72        memctl->memc_or3 = (0xffff8000 | CONFIG_SYS_OR_TIMING_DOC);
  73        memctl->memc_br3 = CONFIG_SYS_DOC_BASE | 0x401;
  74#endif
  75#endif
  76#if defined(CONFIG_BOOT_8B)
  77        size_b0 = 0x80000;      /* 512 K */
  78
  79        flash_info[0].flash_id = FLASH_MAN_AMD | FLASH_AM040;
  80        flash_info[0].sector_count = 8;
  81        flash_info[0].size = 0x00080000;
  82
  83        /* set up sector start address table */
  84        for (i = 0; i < flash_info[0].sector_count; i++)
  85                flash_info[0].start[i] = 0x40000000 + (i * 0x10000);
  86
  87        /* protect all sectors */
  88        for (i = 0; i < flash_info[0].sector_count; i++)
  89                flash_info[0].protect[i] = 0x1;
  90
  91#elif defined(CONFIG_BOOT_16B)
  92        size_b0 = 0x400000;     /* 4MB , assume AMD29LV320B */
  93
  94        flash_info[0].flash_id = FLASH_MAN_AMD | FLASH_AM320B;
  95        flash_info[0].sector_count = 67;
  96        flash_info[0].size = 0x00400000;
  97
  98        /* set up sector start address table */
  99        flash_info[0].start[0] = 0x40000000;
 100        flash_info[0].start[1] = 0x40000000 + 0x4000;
 101        flash_info[0].start[2] = 0x40000000 + 0x6000;
 102        flash_info[0].start[3] = 0x40000000 + 0x8000;
 103
 104        for (i = 4; i < flash_info[0].sector_count; i++) {
 105                flash_info[0].start[i] =
 106                        0x40000000 + 0x10000 + ((i - 4) * 0x10000);
 107        }
 108
 109        /* protect all sectors */
 110        for (i = 0; i < flash_info[0].sector_count; i++)
 111                flash_info[0].protect[i] = 0x1;
 112#endif
 113
 114#ifdef CONFIG_BOOT_32B
 115
 116        /* Static FLASH Bank configuration here - FIXME XXX */
 117        size_b0 = flash_get_size((vu_long *) FLASH_BASE0_PRELIM,
 118                               &flash_info[0]);
 119
 120        if (flash_info[0].flash_id == FLASH_UNKNOWN) {
 121                printf("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
 122                        size_b0, size_b0 << 20);
 123        }
 124
 125        size_b1 = flash_get_size((vu_long *) FLASH_BASE1_PRELIM,
 126                               &flash_info[1]);
 127
 128        if (size_b1 > size_b0) {
 129                printf("## ERROR: "
 130                        "Bank 1 (0x%08lx = %ld MB) > Bank 0 (0x%08lx = %ld MB)\n",
 131                        size_b1, size_b1 << 20, size_b0, size_b0 << 20);
 132                flash_info[0].flash_id = FLASH_UNKNOWN;
 133                flash_info[1].flash_id = FLASH_UNKNOWN;
 134                flash_info[0].sector_count = -1;
 135                flash_info[1].sector_count = -1;
 136                flash_info[0].size = 0;
 137                flash_info[1].size = 0;
 138
 139                return 0;
 140        }
 141
 142        /* Remap FLASH according to real size */
 143        memctl->memc_or0 = CONFIG_SYS_OR_TIMING_FLASH |
 144                                (-size_b0 & OR_AM_MSK);
 145        memctl->memc_br0 = (CONFIG_SYS_FLASH_BASE & BR_BA_MSK) |
 146                                BR_MS_GPCM | BR_V;
 147
 148        /* Re-do sizing to get full correct info */
 149        size_b0 = flash_get_size((vu_long *) CONFIG_SYS_FLASH_BASE,
 150                                &flash_info[0]);
 151
 152        flash_get_offsets(CONFIG_SYS_FLASH_BASE, &flash_info[0]);
 153
 154#if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
 155        /* monitor protection ON by default */
 156        flash_protect(FLAG_PROTECT_SET,
 157                CONFIG_SYS_MONITOR_BASE,
 158                CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1,
 159                &flash_info[0]);
 160#endif
 161
 162#ifdef  CONFIG_ENV_IS_IN_FLASH
 163        /* ENV protection ON by default */
 164        flash_protect(FLAG_PROTECT_SET,
 165                CONFIG_ENV_ADDR,
 166                CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1, &flash_info[0]);
 167#endif
 168
 169        if (size_b1) {
 170                memctl->memc_or1 = CONFIG_SYS_OR_TIMING_FLASH |
 171                        (-size_b1 & 0xFFFF8000);
 172                memctl->memc_br1 = ((CONFIG_SYS_FLASH_BASE +
 173                        size_b0) & BR_BA_MSK) | BR_MS_GPCM | BR_V;
 174
 175                /* Re-do sizing to get full correct info */
 176                size_b1 = flash_get_size((vu_long *)(CONFIG_SYS_FLASH_BASE +
 177                                        size_b0), &flash_info[1]);
 178
 179                flash_get_offsets(CONFIG_SYS_FLASH_BASE + size_b0,
 180                                  &flash_info[1]);
 181
 182#if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
 183                /* monitor protection ON by default */
 184                flash_protect(FLAG_PROTECT_SET,
 185                              CONFIG_SYS_MONITOR_BASE,
 186                              CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1,
 187                              &flash_info[1]);
 188#endif
 189
 190#ifdef  CONFIG_ENV_IS_IN_FLASH
 191                /* ENV protection ON by default */
 192                flash_protect(FLAG_PROTECT_SET,
 193                              CONFIG_ENV_ADDR,
 194                              CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1,
 195                              &flash_info[1]);
 196#endif
 197        } else {
 198                memctl->memc_br1 = 0;   /* invalidate bank */
 199
 200                flash_info[1].flash_id = FLASH_UNKNOWN;
 201                flash_info[1].sector_count = -1;
 202        }
 203
 204        flash_info[0].size = size_b0;
 205        flash_info[1].size = size_b1;
 206
 207
 208#endif /* CONFIG_BOOT_32B */
 209
 210        return size_b0 + size_b1;
 211}
 212
 213
 214void flash_print_info(flash_info_t *info)
 215{
 216        int i;
 217
 218        if (info->flash_id == FLASH_UNKNOWN) {
 219                printf("missing or unknown FLASH type\n");
 220                return;
 221        }
 222
 223        switch (info->flash_id & FLASH_VENDMASK) {
 224        case FLASH_MAN_AMD:
 225                printf("AMD ");
 226                break;
 227        case FLASH_MAN_FUJ:
 228                printf("FUJITSU ");
 229                break;
 230        default:
 231                printf("Unknown Vendor ");
 232                break;
 233        }
 234
 235        switch (info->flash_id & FLASH_TYPEMASK) {
 236        case FLASH_AM400B:
 237                printf("AM29LV400B (4 Mbit, bottom boot sect)\n");
 238                break;
 239        case FLASH_AM400T:
 240                printf("AM29LV400T (4 Mbit, top boot sector)\n");
 241                break;
 242        case FLASH_AM800B:
 243                printf("AM29LV800B (8 Mbit, bottom boot sect)\n");
 244                break;
 245        case FLASH_AM800T:
 246                printf("AM29LV800T (8 Mbit, top boot sector)\n");
 247                break;
 248        case FLASH_AM160B:
 249                printf("AM29LV160B (16 Mbit, bottom boot sect)\n");
 250                break;
 251        case FLASH_AM160T:
 252                printf("AM29LV160T (16 Mbit, top boot sector)\n");
 253                break;
 254        case FLASH_AM320B:
 255                printf("AM29LV320B (32 Mbit, bottom boot sect)\n");
 256                break;
 257        case FLASH_AM320T:
 258                printf("AM29LV320T (32 Mbit, top boot sector)\n");
 259                break;
 260        default:
 261                printf("Unknown Chip Type\n");
 262                break;
 263        }
 264
 265        printf("  Size: %ld MB in %d Sectors\n",
 266                info->size >> 20, info->sector_count);
 267
 268        printf("  Sector Start Addresses:");
 269        for (i = 0; i < info->sector_count; ++i) {
 270                if ((i % 5) == 0)
 271                        printf("\n   ");
 272                printf(" %08lX%s",
 273                       info->start[i], info->protect[i] ? " (RO)" : "     ");
 274        }
 275        printf("\n");
 276        return;
 277}
 278
 279/*
 280 * The following code cannot be run from FLASH!
 281 */
 282
 283int flash_erase(flash_info_t *info, int s_first, int s_last)
 284{
 285        vu_long *addr = (vu_long *) (info->start[0]);
 286        int flag, prot, sect, l_sect, in_mid, in_did;
 287        ulong start, now, last;
 288
 289        if ((s_first < 0) || (s_first > s_last)) {
 290                if (info->flash_id == FLASH_UNKNOWN)
 291                        printf("- missing\n");
 292                else
 293                        printf("- no sectors to erase\n");
 294
 295                return 1;
 296        }
 297
 298        if ((info->flash_id == FLASH_UNKNOWN) ||
 299            (info->flash_id > FLASH_AMD_COMP)) {
 300                printf("Can't erase unknown flash type %08lx - aborted\n",
 301                       info->flash_id);
 302                return 1;
 303        }
 304
 305        prot = 0;
 306        for (sect = s_first; sect <= s_last; ++sect) {
 307                if (info->protect[sect])
 308                        prot++;
 309        }
 310
 311        if (prot) {
 312                printf("- Warning: %d protected sectors will not be erased!\n",
 313                        prot);
 314        } else {
 315                printf("\n");
 316        }
 317
 318        l_sect = -1;
 319
 320        /* Disable interrupts which might cause a timeout here */
 321        flag = disable_interrupts();
 322
 323#if defined(CONFIG_BOOT_8B)
 324        my_out_8((unsigned char *)((ulong)addr + 0x555), 0xaa);
 325        my_out_8((unsigned char *)((ulong)addr + 0x2aa), 0x55);
 326        my_out_8((unsigned char *)((ulong)addr + 0x555), 0x90);
 327
 328        in_mid = my_in_8((unsigned char *)addr);
 329        in_did = my_in_8((unsigned char *)((ulong)addr + 1));
 330
 331        printf(" man ID=0x%x, dev ID=0x%x.\n", in_mid, in_did);
 332
 333        my_out_8((unsigned char *)addr, 0xf0);
 334        udelay(1);
 335
 336        my_out_8((unsigned char *)((ulong)addr + 0x555), 0xaa);
 337        my_out_8((unsigned char *)((ulong)addr + 0x2aa), 0x55);
 338        my_out_8((unsigned char *)((ulong)addr + 0x555), 0x80);
 339        my_out_8((unsigned char *)((ulong)addr + 0x555), 0xaa);
 340        my_out_8((unsigned char *)((ulong)addr + 0x2aa), 0x55);
 341
 342        /* Start erase on unprotected sectors */
 343        for (sect = s_first; sect <= s_last; sect++) {
 344                if (info->protect[sect] == 0) { /* not protected */
 345                        addr = (vu_long *) (info->start[sect]);
 346                        /*addr[0] = 0x00300030; */
 347                        my_out_8((unsigned char *)((ulong)addr), 0x30);
 348                        l_sect = sect;
 349                }
 350        }
 351#elif defined(CONFIG_BOOT_16B)
 352        my_out_be16((unsigned short *)((ulong)addr + (0xaaa)), 0xaa);
 353        my_out_be16((unsigned short *)((ulong)addr + (0x554)), 0x55);
 354        my_out_be16((unsigned short *)((ulong)addr + (0xaaa)), 0x90);
 355        in_mid = my_in_be16((unsigned short *)addr);
 356        in_did = my_in_be16((unsigned short *)((ulong)addr + 2));
 357        printf(" man ID=0x%x, dev ID=0x%x.\n", in_mid, in_did);
 358        my_out_be16((unsigned short *)addr, 0xf0);
 359        udelay(1);
 360        my_out_be16((unsigned short *)((ulong)addr + 0xaaa), 0xaa);
 361        my_out_be16((unsigned short *)((ulong)addr + 0x554), 0x55);
 362        my_out_be16((unsigned short *)((ulong)addr + 0xaaa), 0x80);
 363        my_out_be16((unsigned short *)((ulong)addr + 0xaaa), 0xaa);
 364        my_out_be16((unsigned short *)((ulong)addr + 0x554), 0x55);
 365        /* Start erase on unprotected sectors */
 366        for (sect = s_first; sect <= s_last; sect++) {
 367                if (info->protect[sect] == 0) { /* not protected */
 368                        addr = (vu_long *) (info->start[sect]);
 369                        my_out_be16((unsigned short *)((ulong)addr), 0x30);
 370                        l_sect = sect;
 371                }
 372        }
 373
 374#elif defined(CONFIG_BOOT_32B)
 375        my_out_be32((unsigned *)((ulong)addr + 0x1554), 0xaa);
 376        my_out_be32((unsigned *)((ulong)addr + 0xaa8), 0x55);
 377        my_out_be32((unsigned *)((ulong)addr + 0x1554), 0x90);
 378
 379        in_mid = my_in_be32((unsigned *)addr);
 380        in_did = my_in_be32((unsigned *)((ulong)addr + 4));
 381
 382        printf(" man ID=0x%x, dev ID=0x%x.\n", in_mid, in_did);
 383
 384        my_out_be32((unsigned *) addr, 0xf0);
 385        udelay(1);
 386
 387        my_out_be32((unsigned *)((ulong)addr + 0x1554), 0xaa);
 388        my_out_be32((unsigned *)((ulong)addr + 0xaa8), 0x55);
 389        my_out_be32((unsigned *)((ulong)addr + 0x1554), 0x80);
 390        my_out_be32((unsigned *)((ulong)addr + 0x1554), 0xaa);
 391        my_out_be32((unsigned *)((ulong)addr + 0xaa8), 0x55);
 392
 393        /* Start erase on unprotected sectors */
 394        for (sect = s_first; sect <= s_last; sect++) {
 395                if (info->protect[sect] == 0) { /* not protected */
 396                        addr = (vu_long *) (info->start[sect]);
 397                        my_out_be32((unsigned *)((ulong)addr), 0x00300030);
 398                        l_sect = sect;
 399                }
 400        }
 401
 402#else
 403#error CONFIG_BOOT_(size)B missing.
 404#endif
 405        /* re-enable interrupts if necessary */
 406        if (flag)
 407                enable_interrupts();
 408
 409        /* wait at least 80us - let's wait 1 ms */
 410        udelay(1000);
 411
 412        /*
 413         * We wait for the last triggered sector
 414         */
 415        if (l_sect < 0)
 416                goto DONE;
 417
 418        start = get_timer(0);
 419        last = start;
 420        addr = (vu_long *) (info->start[l_sect]);
 421#if defined(CONFIG_BOOT_8B)
 422        while ((my_in_8((unsigned char *) addr) & 0x80) != 0x80)
 423#elif defined(CONFIG_BOOT_16B)
 424        while ((my_in_be16((unsigned short *) addr) & 0x0080) != 0x0080)
 425#elif defined(CONFIG_BOOT_32B)
 426        while ((my_in_be32((unsigned *) addr) & 0x00800080) != 0x00800080)
 427#else
 428#error CONFIG_BOOT_(size)B missing.
 429#endif
 430        {
 431                now = get_timer(start);
 432                if (now > CONFIG_SYS_FLASH_ERASE_TOUT) {
 433                        printf("Timeout\n");
 434                        return 1;
 435                }
 436                /* show that we're waiting */
 437                if ((now - last) > 1000) {      /* every second */
 438                        putc('.');
 439                        last = now;
 440                }
 441        }
 442DONE:
 443        /* reset to read mode */
 444        addr = (volatile unsigned long *) info->start[0];
 445
 446#if defined(CONFIG_BOOT_8B)
 447        my_out_8((unsigned char *) addr, 0xf0);
 448#elif defined(CONFIG_BOOT_16B)
 449        my_out_be16((unsigned short *) addr, 0x00f0);
 450#elif defined(CONFIG_BOOT_32B)
 451        my_out_be32((unsigned *) addr, 0x00F000F0);     /* reset bank */
 452#else
 453#error CONFIG_BOOT_(size)B missing.
 454#endif
 455        printf(" done\n");
 456        return 0;
 457}
 458
 459/*
 460 * Copy memory to flash, returns:
 461 * 0 - OK
 462 * 1 - write timeout
 463 * 2 - Flash not erased
 464 */
 465
 466int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
 467{
 468        ulong cp, wp, data;
 469        int i, l, rc;
 470
 471        wp = (addr & ~3);       /* get lower word aligned address */
 472
 473        /*
 474         * handle unaligned start bytes
 475         */
 476        l = addr - wp;
 477
 478        if (l != 0) {
 479                data = 0;
 480                for (i = 0, cp = wp; i < l; ++i, ++cp)
 481                        data = (data << 8) | (*(uchar *) cp);
 482
 483                for (; i < 4 && cnt > 0; ++i) {
 484                        data = (data << 8) | *src++;
 485                        --cnt;
 486                        ++cp;
 487                }
 488                for (; cnt == 0 && i < 4; ++i, ++cp)
 489                        data = (data << 8) | (*(uchar *) cp);
 490
 491                rc = write_word(info, wp, data);
 492
 493                if (rc != 0)
 494                        return rc;
 495
 496                wp += 4;
 497        }
 498
 499        /*
 500         * handle word aligned part
 501         */
 502        while (cnt >= 4) {
 503                data = 0;
 504                for (i = 0; i < 4; ++i)
 505                        data = (data << 8) | *src++;
 506
 507                rc = write_word(info, wp, data);
 508
 509                if (rc != 0)
 510                        return rc;
 511
 512                wp += 4;
 513                cnt -= 4;
 514        }
 515
 516        if (cnt == 0)
 517                return 0;
 518
 519        /*
 520         * handle unaligned tail bytes
 521         */
 522        data = 0;
 523        for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) {
 524                data = (data << 8) | *src++;
 525                --cnt;
 526        }
 527        for (; i < 4; ++i, ++cp)
 528                data = (data << 8) | (*(uchar *) cp);
 529
 530        return write_word(info, wp, data);
 531}
 532
 533/*
 534 * Write a word to Flash, returns:
 535 * 0 - OK
 536 * 1 - write timeout
 537 * 2 - Flash not erased
 538 */
 539static int write_word(flash_info_t *info, ulong dest, ulong data)
 540{
 541        ulong addr = (ulong) (info->start[0]);
 542        ulong start;
 543        int flag;
 544        ulong i;
 545        int data_short[2];
 546
 547        /* Check if Flash is (sufficiently) erased */
 548        if (((ulong)*(ulong *)dest & data) != data)
 549                return 2;
 550
 551        /* Disable interrupts which might cause a timeout here */
 552        flag = disable_interrupts();
 553#if defined(CONFIG_BOOT_8B)
 554#ifdef DEBUG
 555        {
 556                int in_mid, in_did;
 557
 558                my_out_8((unsigned char *) (addr + 0x555), 0xaa);
 559                my_out_8((unsigned char *) (addr + 0x2aa), 0x55);
 560                my_out_8((unsigned char *) (addr + 0x555), 0x90);
 561
 562                in_mid = my_in_8((unsigned char *) addr);
 563                in_did = my_in_8((unsigned char *) (addr + 1));
 564
 565                printf(" man ID=0x%x, dev ID=0x%x.\n", in_mid, in_did);
 566
 567                my_out_8((unsigned char *) addr, 0xf0);
 568                udelay(1);
 569        }
 570#endif
 571        {
 572                int data_ch[4];
 573
 574                data_ch[0] = (int) ((data >> 24) & 0xff);
 575                data_ch[1] = (int) ((data >> 16) & 0xff);
 576                data_ch[2] = (int) ((data >> 8) & 0xff);
 577                data_ch[3] = (int) (data & 0xff);
 578
 579                for (i = 0; i < 4; i++) {
 580                        my_out_8((unsigned char *) (addr + 0x555), 0xaa);
 581                        my_out_8((unsigned char *) (addr + 0x2aa), 0x55);
 582                        my_out_8((unsigned char *) (addr + 0x555), 0xa0);
 583                        my_out_8((unsigned char *) (dest + i), data_ch[i]);
 584
 585                        /* re-enable interrupts if necessary */
 586                        if (flag)
 587                                enable_interrupts();
 588
 589                        start = get_timer(0);
 590                        while ((my_in_8((unsigned char *)(dest + i))) !=
 591                               (data_ch[i])) {
 592                                if (get_timer(start) >
 593                                    CONFIG_SYS_FLASH_WRITE_TOUT) {
 594                                        return 1;
 595                                }
 596                        }
 597                }               /* for */
 598        }
 599#elif defined(CONFIG_BOOT_16B)
 600        data_short[0] = (int) (data >> 16) & 0xffff;
 601        data_short[1] = (int) data & 0xffff;
 602        for (i = 0; i < 2; i++) {
 603                my_out_be16((unsigned short *)((ulong)addr + 0xaaa), 0xaa);
 604                my_out_be16((unsigned short *)((ulong)addr + 0x554), 0x55);
 605                my_out_be16((unsigned short *)((ulong)addr + 0xaaa), 0xa0);
 606                my_out_be16((unsigned short *)(dest + (i * 2)),
 607                            data_short[i]);
 608
 609                /* re-enable interrupts if necessary */
 610                if (flag)
 611                        enable_interrupts();
 612
 613                start = get_timer(0);
 614                while ((my_in_be16((unsigned short *)(dest + (i * 2)))) !=
 615                                                        (data_short[i])) {
 616                        if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT)
 617                                return 1;
 618                }
 619        }
 620#elif defined(CONFIG_BOOT_32B)
 621        addr[0x0555] = 0x00AA00AA;
 622        addr[0x02AA] = 0x00550055;
 623        addr[0x0555] = 0x00A000A0;
 624
 625        *((vu_long *)dest) = data;
 626
 627        /* re-enable interrupts if necessary */
 628        if (flag)
 629                enable_interrupts();
 630
 631        /* data polling for D7 */
 632        start = get_timer(0);
 633        while ((*((vu_long *)dest) & 0x00800080) != (data & 0x00800080)) {
 634                if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT)
 635                        return 1;
 636        }
 637#endif
 638        return 0;
 639}
 640
 641#ifdef CONFIG_BOOT_8B
 642static int my_in_8(unsigned char *addr)
 643{
 644        int ret;
 645        __asm__ __volatile__("lbz%U1%X1 %0,%1; eieio":"=r"(ret):"m"(*addr));
 646
 647        return ret;
 648}
 649
 650static void my_out_8(unsigned char *addr, int val)
 651{
 652        __asm__ __volatile__("stb%U0%X0 %1,%0; eieio":"=m"(*addr):"r"(val));
 653}
 654#endif
 655#ifdef CONFIG_BOOT_16B
 656static int my_in_be16(unsigned short *addr)
 657{
 658        int ret;
 659        __asm__ __volatile__("lhz%U1%X1 %0,%1; eieio":"=r"(ret):"m"(*addr));
 660
 661        return ret;
 662}
 663
 664static void my_out_be16(unsigned short *addr, int val)
 665{
 666        __asm__ __volatile__("sth%U0%X0 %1,%0; eieio":"=m"(*addr):"r"(val));
 667}
 668#endif
 669#ifdef CONFIG_BOOT_32B
 670static unsigned my_in_be32(unsigned *addr)
 671{
 672        unsigned ret;
 673        __asm__ __volatile__("lwz%U1%X1 %0,%1; eieio":"=r"(ret):"m"(*addr));
 674
 675        return ret;
 676}
 677
 678static void my_out_be32(unsigned *addr, int val)
 679{
 680        __asm__ __volatile__("stw%U0%X0 %1,%0; eieio":"=m"(*addr):"r"(val));
 681}
 682#endif
 683