]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
* Patch by Yuli Barcohen, 26 Jan 2004:
authorwdenk <wdenk>
Sun, 8 Feb 2004 22:55:38 +0000 (22:55 +0000)
committerwdenk <wdenk>
Sun, 8 Feb 2004 22:55:38 +0000 (22:55 +0000)
  Allow bzip2 compression for small memory footprint boards

* Patch by Brad Kemp, 21 Jan 2004:
  Add support for CFI flash driver for both the Intel and the AMD
  command sets.

* Patch by Travis Sawyer, 20 Jan 2004:
  Fix pci bridge auto enumeration of sibling p2p bridges.

* Patch by Tolunay Orkun, 12 Jan 2004:
  Add some delays as needed for Intel LXT971A PHY support

* Patches by Stephan Linz, 09 Jan 2004:
  - avoid warning: unused variable `piop' in board/altera/common/sevenseg.c
  - make DK1C20 board configuration related to ASMI conform to
    documentation

CHANGELOG
README
board/altera/common/sevenseg.c
common/cmd_bootm.c
common/miiphyutil.c
cpu/ppc4xx/miiphy.c
drivers/Makefile
drivers/cfi_flash.c [new file with mode: 0644]
drivers/pci_auto.c
include/configs/DK1C20.h
include/flash.h

index 202dd47ee8726d79454201ebff0ff2125b1f5dd6..2359b482089e0b34588846227a4bac19c6bf7d33 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,24 @@
 Changes since U-Boot 1.0.1:
 ======================================================================
 
+* Patch by Yuli Barcohen, 26 Jan 2004:
+  Allow bzip2 compression for small memory footprint boards
+
+* Patch by Brad Kemp, 21 Jan 2004:
+  Add support for CFI flash driver for both the Intel and the AMD
+  command sets.
+
+* Patch by Travis Sawyer, 20 Jan 2004:
+  Fix pci bridge auto enumeration of sibling p2p bridges.
+
+* Patch by Tolunay Orkun, 12 Jan 2004:
+  Add some delays as needed for Intel LXT971A PHY support
+
+* Patches by Stephan Linz, 09 Jan 2004:
+  - avoid warning: unused variable `piop' in board/altera/common/sevenseg.c
+  - make DK1C20 board configuration related to ASMI conform to
+    documentation
+
 * Patch by Anders Larsen, 09 Jan 2004:
 
   ARM memory layout fixes: the abort-stack is now set up in the
diff --git a/README b/README
index 46171bf11c8c8ef2268b26fa553d772d8dfb2ee3..ac5b921b4dead3b962a6a88adc03a568eb131105 100644 (file)
--- a/README
+++ b/README
@@ -1643,7 +1643,11 @@ Configuration Settings:
 
 - CFG_FLASH_CFI:
                Define if the flash driver uses extra elements in the
-               common flash structure for storing flash geometry
+               common flash structure for storing flash geometry.
+
+- CFG_FLASH_CFI_DRIVER
+               This option also enables the building of the cfi_flash driver
+               in the drivers directory
 
 - CFG_RX_ETH_BUFFER:
                Defines the number of ethernet receive buffers. On some
index fecfbd388e578d95988620710c8c1b84a504890a..c53cec16e64feaaf7df2ad73c5fbbdb7b0d0b3ff 100644 (file)
@@ -44,7 +44,7 @@ static int sevenseg_init_done = 0;
 
 static inline void __sevenseg_set_masked (unsigned int mask, int value)
 {
-       nios_pio_t *piop = (nios_pio_t*)SEVENSEG_BASE;
+       nios_pio_t *piop __attribute__((unused)) = (nios_pio_t*)SEVENSEG_BASE;
 
 #ifdef SEVENSEG_WRONLY /* emulate read access */
 
@@ -97,7 +97,7 @@ static inline void __sevenseg_toggle_masked (unsigned int mask)
 
 static inline void __sevenseg_set (unsigned int value)
 {
-       nios_pio_t *piop = (nios_pio_t*)SEVENSEG_BASE;
+       nios_pio_t *piop __attribute__((unused)) = (nios_pio_t*)SEVENSEG_BASE;
 
 #ifdef SEVENSEG_WRONLY /* emulate read access */
 
@@ -126,7 +126,7 @@ static inline void __sevenseg_set (unsigned int value)
 
 static inline void __sevenseg_init (void)
 {
-       nios_pio_t *piop = (nios_pio_t*)SEVENSEG_BASE;
+       nios_pio_t *piop __attribute__((unused)) = (nios_pio_t*)SEVENSEG_BASE;
 
        __sevenseg_set(0);
 
index 34a74ce2c5a6fd0fcdfdb3acfc107b74f5ffdb08..ac9c32e7b8791a313e2835d66c33a6bdc395c3d8 100644 (file)
@@ -333,8 +333,14 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 #ifdef CONFIG_BZIP2
        case IH_COMP_BZIP2:
                printf ("   Uncompressing %s ... ", name);
+               /*
+                * If we've got less than 4 MB of malloc() space,
+                * use slower decompression algorithm which requires
+                * at most 2300 KB of memory.
+                */
                i = BZ2_bzBuffToBuffDecompress ((char*)ntohl(hdr->ih_load),
-                                               &unc_len, (char *)data, len, 0, 0);
+                                               &unc_len, (char *)data, len,
+                                               CFG_MALLOC_LEN < (4096 * 1024), 0);
                if (i != BZ_OK) {
                        printf ("BUNZIP2 ERROR %d - must RESET board to recover\n", i);
                        SHOW_BOOT_PROGRESS (-6);
index af8c7c7a310695dc45d0c7d9a805a353b97b5769..03964da81f685f444ee6ffbf4749ab6a1000422c 100644 (file)
@@ -99,7 +99,9 @@ int miiphy_reset (unsigned char addr)
 #endif
                return (-1);
        }
-
+#ifdef CONFIG_PHY_RESET_DELAY
+       udelay (CONFIG_PHY_RESET_DELAY);        /* Intel LXT971A needs this */
+#endif
        /*
         * Poll the control register for the reset bit to go to 0 (it is
         * auto-clearing).  This should happen within 0.5 seconds per the
index 5ca66815c5e0f4c1cc92e7b4512d80a5eabc8bcf..3d343ee881d34751958c3bf6b552831d147b0ebf 100644 (file)
@@ -113,6 +113,9 @@ int miiphy_read (unsigned char addr, unsigned char reg,
        printf ("a2: write: EMAC_STACR=0x%0x\n", sta_reg);      /* test-only */
 #endif
 
+#ifdef CONFIG_PHY_CMD_DELAY
+       udelay (CONFIG_PHY_CMD_DELAY);          /* Intel LXT971A needs this */
+#endif
        sta_reg = in32 (EMAC_STACR);
        i = 0;
        while ((sta_reg & EMAC_STACR_OC) == 0) {
@@ -173,6 +176,9 @@ int miiphy_write (unsigned char addr, unsigned char reg,
 
        out32 (EMAC_STACR, sta_reg);
 
+#ifdef CONFIG_PHY_CMD_DELAY
+       udelay (CONFIG_PHY_CMD_DELAY);          /* Intel LXT971A needs this */
+#endif
        /* wait for completion */
        i = 0;
        sta_reg = in32 (EMAC_STACR);
index 2bdabae8ec31091650aaaa671f78b907ba002c35..2999eb465a99e08eda57c25f4b38ecd3d719679e 100644 (file)
@@ -28,7 +28,7 @@ include $(TOPDIR)/config.mk
 LIB    = libdrivers.a
 
 OBJS   = 3c589.o 5701rls.o ali512x.o \
-         bcm570x.o bcm570x_autoneg.o cfb_console.o \
+         bcm570x.o bcm570x_autoneg.o cfb_console.o cfi_flash.o \
          cs8900.o ct69000.o dataflash.o dc2114x.o          \
          e1000.o eepro100.o \
          i8042.o i82365.o inca-ip_sw.o \
diff --git a/drivers/cfi_flash.c b/drivers/cfi_flash.c
new file mode 100644 (file)
index 0000000..fb76925
--- /dev/null
@@ -0,0 +1,1018 @@
+/*
+ * (C) Copyright 2002
+ * Brad Kemp, Seranoa Networks, Brad.Kemp@seranoa.com
+ *
+ * Copyright (C) 2003 Arabella Software Ltd.
+ * Yuli Barcohen <yuli@arabellasw.com>
+ * Modified to work with AMD flashes
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * History
+ * 01/20/2004 - combined variants of original driver.
+ *
+ * Tested Architectures
+ * Port Width  Chip Width    # of banks    Flash Chip  Board
+ * 32          16            1             23F128J3    seranoa/eagle
+ * 
+ */
+
+/* The DEBUG define must be before common to enable debugging */
+#undef  DEBUG 
+#include <common.h>
+#include <asm/processor.h>
+#ifdef  CFG_FLASH_CFI_DRIVER
+/*
+ * This file implements a Common Flash Interface (CFI) driver for U-Boot.
+ * The width of the port and the width of the chips are determined at initialization.
+ * These widths are used to calculate the address for access CFI data structures.
+ * It has been tested on an Intel Strataflash implementation and AMD 29F016D.
+ *
+ * References
+ * JEDEC Standard JESD68 - Common Flash Interface (CFI)
+ * JEDEC Standard JEP137-A Common Flash Interface (CFI) ID Codes
+ * Intel Application Note 646 Common Flash Interface (CFI) and Command Sets
+ * Intel 290667-008 3 Volt Intel StrataFlash Memory datasheet
+ *
+ * TODO
+ *
+ * Use Primary Extended Query table (PRI) and Alternate Algorithm Query
+ * Table (ALT) to determine if protection is available
+ *
+ * Add support for other command sets Use the PRI and ALT to determine command set
+ * Verify erase and program timeouts.
+ */
+
+#define FLASH_CMD_CFI                  0x98
+#define FLASH_CMD_READ_ID              0x90
+#define FLASH_CMD_RESET                        0xff
+#define FLASH_CMD_BLOCK_ERASE          0x20
+#define FLASH_CMD_ERASE_CONFIRM                0xD0
+#define FLASH_CMD_WRITE                        0x40
+#define FLASH_CMD_PROTECT              0x60
+#define FLASH_CMD_PROTECT_SET          0x01
+#define FLASH_CMD_PROTECT_CLEAR                0xD0
+#define FLASH_CMD_CLEAR_STATUS         0x50
+#define FLASH_CMD_WRITE_TO_BUFFER       0xE8
+#define FLASH_CMD_WRITE_BUFFER_CONFIRM  0xD0
+
+#define FLASH_STATUS_DONE              0x80
+#define FLASH_STATUS_ESS               0x40
+#define FLASH_STATUS_ECLBS             0x20
+#define FLASH_STATUS_PSLBS             0x10
+#define FLASH_STATUS_VPENS             0x08
+#define FLASH_STATUS_PSS               0x04
+#define FLASH_STATUS_DPS               0x02
+#define FLASH_STATUS_R                 0x01
+#define FLASH_STATUS_PROTECT           0x01
+
+#define AMD_CMD_RESET                  0xF0
+#define AMD_CMD_WRITE                  0xA0
+#define AMD_CMD_ERASE_START            0x80
+#define AMD_CMD_ERASE_SECTOR           0x30
+
+#define AMD_STATUS_TOGGLE              0x40
+#define AMD_STATUS_ERROR               0x20
+
+#define FLASH_OFFSET_CFI               0x55
+#define FLASH_OFFSET_CFI_RESP          0x10
+#define FLASH_OFFSET_PRIMARY_VENDOR     0x13
+#define FLASH_OFFSET_WTOUT             0x1F
+#define FLASH_OFFSET_WBTOUT             0x20
+#define FLASH_OFFSET_ETOUT             0x21
+#define FLASH_OFFSET_CETOUT             0x22
+#define FLASH_OFFSET_WMAX_TOUT         0x23
+#define FLASH_OFFSET_WBMAX_TOUT         0x24
+#define FLASH_OFFSET_EMAX_TOUT         0x25
+#define FLASH_OFFSET_CEMAX_TOUT         0x26
+#define FLASH_OFFSET_SIZE              0x27
+#define FLASH_OFFSET_INTERFACE          0x28
+#define FLASH_OFFSET_BUFFER_SIZE        0x2A
+#define FLASH_OFFSET_NUM_ERASE_REGIONS 0x2C
+#define FLASH_OFFSET_ERASE_REGIONS     0x2D
+#define FLASH_OFFSET_PROTECT           0x02
+#define FLASH_OFFSET_USER_PROTECTION    0x85
+#define FLASH_OFFSET_INTEL_PROTECTION   0x81
+
+
+#define FLASH_MAN_CFI                  0x01000000
+
+#define CFI_CMDSET_NONE             0
+#define CFI_CMDSET_INTEL_EXTENDED   1
+#define CFI_CMDSET_AMD_STANDARD     2
+#define CFI_CMDSET_INTEL_STANDARD   3
+#define CFI_CMDSET_AMD_EXTENDED     4
+#define CFI_CMDSET_MITSU_STANDARD   256
+#define CFI_CMDSET_MITSU_EXTENDED   257
+#define CFI_CMDSET_SST              258
+
+
+typedef union {
+       unsigned char c;
+       unsigned short w;
+       unsigned long l;
+       unsigned long long ll;
+} cfiword_t;
+
+typedef union {
+       volatile unsigned char  *cp;
+       volatile unsigned short *wp;
+       volatile unsigned long  *lp;
+       volatile unsigned long long *llp;
+} cfiptr_t;
+
+#define NUM_ERASE_REGIONS 4
+
+static ulong bank_base[CFG_MAX_FLASH_BANKS] = CFG_FLASH_BANKS_LIST;
+
+flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips  */
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+
+typedef unsigned long flash_sect_t;
+
+static void flash_add_byte(flash_info_t *info, cfiword_t * cword, uchar c);
+static void flash_make_cmd(flash_info_t * info, uchar cmd, void * cmdbuf);
+static void flash_write_cmd(flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd);
+static void flash_unlock_seq(flash_info_t *info);
+static int flash_isequal(flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd);
+static int flash_isset(flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd);
+static int flash_toggle(flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd);
+static int flash_detect_cfi(flash_info_t * info);
+static ulong flash_get_size (ulong base, int banknum);
+static int flash_write_cfiword (flash_info_t *info, ulong dest, cfiword_t cword);
+static int flash_full_status_check(flash_info_t * info, flash_sect_t sector, ulong tout, char * prompt);
+#ifdef CFG_FLASH_USE_BUFFER_WRITE
+static int flash_write_cfibuffer(flash_info_t * info, ulong dest, uchar * cp, int len);
+#endif
+
+#ifdef DEBUG
+void print_longlong(char * str, unsigned long long data)
+{
+       int i;
+       char *cp;
+       cp = (unsigned char *)&data;
+       for(i=0;i<8; i++) 
+               sprintf(&str[i*2], "%2.2x", *cp++);  
+}
+#endif
+
+
+/*-----------------------------------------------------------------------
+ * create an address based on the offset and the port width
+ */
+inline uchar * flash_make_addr(flash_info_t * info, flash_sect_t sect, uint offset)
+{
+       return ((uchar *)(info->start[sect] + (offset * info->portwidth)));
+}
+/*-----------------------------------------------------------------------
+ * read a character at a port width address
+ */
+inline uchar flash_read_uchar(flash_info_t * info, uint offset)
+{
+       uchar *cp;
+       cp = flash_make_addr(info, 0, offset);
+       return (cp[info->portwidth - 1]);
+}
+
+/*-----------------------------------------------------------------------
+ * read a short word by swapping for ppc format.
+ */
+ushort flash_read_ushort(flash_info_t * info, flash_sect_t sect,  uint offset)
+{
+    uchar * addr;
+
+    addr = flash_make_addr(info, sect, offset);
+    return ((addr[(2*info->portwidth) - 1] << 8) | addr[info->portwidth - 1]);
+
+}
+
+/*-----------------------------------------------------------------------
+ * read a long word by picking the least significant byte of each maiximum
+ * port size word. Swap for ppc format.
+ */
+ulong flash_read_long(flash_info_t * info, flash_sect_t sect,  uint offset)
+{
+    uchar * addr;
+
+    addr = flash_make_addr(info, sect, offset);
+    return ( (addr[(2*info->portwidth) - 1] << 24 ) | (addr[(info->portwidth) -1] << 16) |
+           (addr[(4*info->portwidth) - 1] << 8) | addr[(3*info->portwidth) - 1]);
+
+}
+
+/*-----------------------------------------------------------------------
+ */
+unsigned long flash_init (void)
+{
+       unsigned long size = 0;
+       int i;
+
+       /* Init: no FLASHes known */
+       for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
+               flash_info[i].flash_id = FLASH_UNKNOWN;
+               size += flash_info[i].size = flash_get_size(bank_base[i], i);
+               if (flash_info[i].flash_id == FLASH_UNKNOWN) {
+                       printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n",
+                               i, flash_info[i].size, flash_info[i].size << 20);
+               }
+       }
+
+       /* Monitor protection ON by default */
+#if (CFG_MONITOR_BASE >= CFG_FLASH_BASE)
+       flash_protect(FLAG_PROTECT_SET,
+                     CFG_MONITOR_BASE,
+                     CFG_MONITOR_BASE + monitor_flash_len - 1,
+                     &flash_info[0]);
+#endif
+
+       return (size);
+}
+
+/*-----------------------------------------------------------------------
+ */
+int flash_erase (flash_info_t *info, int s_first, int s_last)
+{
+       int rcode = 0;
+       int prot;
+       flash_sect_t sect;
+
+       if( info->flash_id != FLASH_MAN_CFI) {
+               printf ("Can't erase unknown flash type - aborted\n");
+               return 1;
+       }
+       if ((s_first < 0) || (s_first > s_last)) {
+               printf ("- no sectors to erase\n");
+               return 1;
+       }
+
+       prot = 0;
+       for (sect=s_first; sect<=s_last; ++sect) {
+               if (info->protect[sect]) {
+                       prot++;
+               }
+       }
+       if (prot) {
+               printf ("- Warning: %d protected sectors will not be erased!\n",
+                       prot);
+       } else {
+               printf ("\n");
+       }
+
+
+       for (sect = s_first; sect<=s_last; sect++) {
+               if (info->protect[sect] == 0) { /* not protected */
+                       switch(info->vendor) {
+                       case CFI_CMDSET_INTEL_STANDARD:
+                       case CFI_CMDSET_INTEL_EXTENDED:
+                               flash_write_cmd(info, sect, 0, FLASH_CMD_CLEAR_STATUS);
+                               flash_write_cmd(info, sect, 0, FLASH_CMD_BLOCK_ERASE);
+                               flash_write_cmd(info, sect, 0, FLASH_CMD_ERASE_CONFIRM);
+                               break;
+                       case CFI_CMDSET_AMD_STANDARD:
+                       case CFI_CMDSET_AMD_EXTENDED:
+                               flash_unlock_seq(info);
+                               flash_write_cmd(info, sect, 0x555, AMD_CMD_ERASE_START);
+                               flash_unlock_seq(info);
+                               flash_write_cmd(info, sect, 0, AMD_CMD_ERASE_SECTOR);
+                               break;
+                       default:
+                               debug("Unkown flash vendor %d\n", info->vendor);
+                               break;
+                       }
+
+                       if(flash_full_status_check(info, sect, info->erase_blk_tout, "erase")) {
+                               rcode = 1;
+                       } else
+                               printf(".");
+               }
+       }
+       printf (" done\n");
+       return rcode;
+}
+
+/*-----------------------------------------------------------------------
+ */
+void flash_print_info  (flash_info_t *info)
+{
+       int i;
+
+       if (info->flash_id != FLASH_MAN_CFI) {
+               printf ("missing or unknown FLASH type\n");
+               return;
+       }
+
+       printf("CFI conformant FLASH (%d x %d)",
+              (info->portwidth  << 3 ), (info->chipwidth  << 3 ));
+       printf ("  Size: %ld MB in %d Sectors\n",
+               info->size >> 20, info->sector_count);
+       printf(" Erase timeout %ld ms, write timeout %ld ms, buffer write timeout %ld ms, buffer size %d\n",
+              info->erase_blk_tout, info->write_tout, info->buffer_write_tout, info->buffer_size);
+
+       printf ("  Sector Start Addresses:");
+       for (i=0; i<info->sector_count; ++i) {
+#ifdef CFG_FLASH_EMPTY_INFO
+               int k;
+               int size;
+               int erased;
+               volatile unsigned long *flash;
+
+               /*
+                * Check if whole sector is erased
+                */
+               if (i != (info->sector_count-1))
+                 size = info->start[i+1] - info->start[i];
+               else
+                 size = info->start[0] + info->size - info->start[i];
+               erased = 1;
+               flash = (volatile unsigned long *)info->start[i];
+               size = size >> 2;        /* divide by 4 for longword access */
+               for (k=0; k<size; k++)
+                 {
+                   if (*flash++ != 0xffffffff)
+                     {
+                       erased = 0;
+                       break;
+                     }
+                 }
+
+               if ((i % 5) == 0)
+                       printf ("\n");
+               /* print empty and read-only info */
+               printf (" %08lX%s%s",
+                       info->start[i],
+                       erased ? " E" : "  ",
+                       info->protect[i] ? "RO " : "   ");
+#else
+               if ((i % 5) == 0)
+                       printf ("\n   ");
+               printf (" %08lX%s",
+                       info->start[i],
+                       info->protect[i] ? " (RO)" : "     ");
+#endif
+       }
+       printf ("\n");
+       return;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+       ulong wp;
+       ulong cp;
+       int aln;
+       cfiword_t cword;
+       int i, rc;
+
+       /* get lower aligned address */
+       wp = (addr & ~(info->portwidth - 1));
+
+       /* handle unaligned start */
+       if((aln = addr - wp) != 0) {
+               cword.l = 0;
+               cp = wp;
+               for(i=0;i<aln; ++i, ++cp)
+                       flash_add_byte(info, &cword, (*(uchar *)cp));
+
+               for(; (i< info->portwidth) && (cnt > 0) ; i++) {
+                       flash_add_byte(info, &cword, *src++);
+                       cnt--;
+                       cp++;
+               }
+               for(; (cnt == 0) && (i < info->portwidth); ++i, ++cp)
+                       flash_add_byte(info, &cword, (*(uchar *)cp));
+               if((rc = flash_write_cfiword(info, wp, cword)) != 0)
+                       return rc;
+               wp = cp;
+       }
+
+#ifdef CFG_FLASH_USE_BUFFER_WRITE
+       while(cnt >= info->portwidth) {
+               i = info->buffer_size > cnt? cnt: info->buffer_size;
+               if((rc = flash_write_cfibuffer(info, wp, src,i)) != ERR_OK)
+                       return rc;
+               wp += i;
+               src += i;
+               cnt -=i;
+       }
+#else
+       /* handle the aligned part */
+       while(cnt >= info->portwidth) {
+               cword.l = 0;
+               for(i = 0; i < info->portwidth; i++) {
+                       flash_add_byte(info, &cword, *src++);
+               }
+               if((rc = flash_write_cfiword(info, wp, cword)) != 0)
+                       return rc;
+               wp += info->portwidth;
+               cnt -= info->portwidth;
+       }
+#endif /* CFG_FLASH_USE_BUFFER_WRITE */
+       if (cnt == 0) {
+               return (0);
+       }
+
+       /*
+        * handle unaligned tail bytes
+        */
+       cword.l = 0;
+       for (i=0, cp=wp; (i<info->portwidth) && (cnt>0); ++i, ++cp) {
+               flash_add_byte(info, &cword, *src++);
+               --cnt;
+       }
+       for (; i<info->portwidth; ++i, ++cp) {
+               flash_add_byte(info, & cword, (*(uchar *)cp));
+       }
+
+       return flash_write_cfiword(info, wp, cword);
+}
+
+/*-----------------------------------------------------------------------
+ */
+#ifdef CFG_FLASH_PROTECTION
+
+int flash_real_protect(flash_info_t *info, long sector, int prot)
+{
+       int retcode = 0;
+
+       flash_write_cmd(info, sector, 0, FLASH_CMD_CLEAR_STATUS);
+       flash_write_cmd(info, sector, 0, FLASH_CMD_PROTECT);
+       if(prot)
+               flash_write_cmd(info, sector, 0, FLASH_CMD_PROTECT_SET);
+       else
+               flash_write_cmd(info, sector, 0, FLASH_CMD_PROTECT_CLEAR);
+
+       if((retcode = flash_full_status_check(info, sector, info->erase_blk_tout,
+                                        prot?"protect":"unprotect")) == 0) {
+
+               info->protect[sector] = prot;
+               /* Intel's unprotect unprotects all locking */
+               if(prot == 0) {
+                       flash_sect_t i;
+                       for(i = 0 ; i<info->sector_count; i++) {
+                               if(info->protect[i])
+                                       flash_real_protect(info, i, 1);
+                       }
+               }
+       }
+
+       return retcode;
+ }
+/*-----------------------------------------------------------------------
+ * flash_read_user_serial - read the OneTimeProgramming cells
+ */
+void flash_read_user_serial(flash_info_t * info, void * buffer, int offset, int len)
+{
+       uchar * src;
+       uchar * dst;
+
+       dst = buffer;
+       src = flash_make_addr(info, 0, FLASH_OFFSET_USER_PROTECTION);
+       flash_write_cmd(info,0, 0, FLASH_CMD_READ_ID);
+       memcpy(dst,src + offset,len);
+       flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
+}
+/*
+ * flash_read_factory_serial - read the device Id from the protection area
+ */
+void flash_read_factory_serial(flash_info_t * info, void * buffer, int offset, int len)
+{
+       uchar * src;
+       
+       src = flash_make_addr(info, 0, FLASH_OFFSET_INTEL_PROTECTION);
+       flash_write_cmd(info,0, 0, FLASH_CMD_READ_ID);
+       memcpy(buffer,src + offset,len);
+       flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
+}
+
+#endif /* CFG_FLASH_PROTECTION */
+
+static int flash_poll_status(flash_info_t * info, flash_sect_t sect) 
+{
+       int retval;
+       switch(info->vendor) {
+       case CFI_CMDSET_INTEL_STANDARD:
+       case CFI_CMDSET_INTEL_EXTENDED:
+               retval = !flash_isset(info, sect, 0, FLASH_STATUS_DONE);
+               break;
+       case CFI_CMDSET_AMD_STANDARD:
+       case CFI_CMDSET_AMD_EXTENDED:
+               retval =  flash_toggle(info, sect, 0, AMD_STATUS_TOGGLE);
+               break;
+       default:
+               retval = 0;
+       }
+       return retval;
+}
+/*-----------------------------------------------------------------------
+ *  wait for XSR.7 to be set. Time out with an error if it does not.
+ *  This routine does not set the flash to read-array mode.
+ */
+static int flash_status_check(flash_info_t * info, flash_sect_t sector, ulong tout, char * prompt)
+{
+       ulong start;
+
+       /* Wait for command completion */
+       start = get_timer (0);
+       while (flash_poll_status(info, sector)) {
+               if (get_timer(start) > info->erase_blk_tout) {
+                       printf("Flash %s timeout at address %lx\n", prompt, info->start[sector]);
+                       flash_write_cmd(info, sector, 0, info->cmd_reset);
+                       return ERR_TIMOUT;
+               }
+       }
+       return ERR_OK;
+}
+/*-----------------------------------------------------------------------
+ * Wait for XSR.7 to be set, if it times out print an error, otherwise do a full status check.
+ * This routine sets the flash to read-array mode.
+ */
+static int flash_full_status_check(flash_info_t * info, flash_sect_t sector, ulong tout, char * prompt)
+{
+       int retcode;
+       retcode = flash_status_check(info, sector, tout, prompt);
+       switch(info->vendor) {
+       case CFI_CMDSET_INTEL_EXTENDED:
+       case CFI_CMDSET_INTEL_STANDARD:
+               if((retcode == ERR_OK) && !flash_isequal(info,sector, 0, FLASH_STATUS_DONE)) {
+                       retcode = ERR_INVAL;
+                       printf("Flash %s error at address %lx\n", prompt,info->start[sector]);
+                       if(flash_isset(info, sector, 0, FLASH_STATUS_ECLBS | FLASH_STATUS_PSLBS)){
+                               printf("Command Sequence Error.\n");
+                       } else if(flash_isset(info, sector, 0, FLASH_STATUS_ECLBS)){
+                               printf("Block Erase Error.\n");
+                               retcode = ERR_NOT_ERASED;
+                       } else if (flash_isset(info, sector, 0, FLASH_STATUS_PSLBS)) {
+                               printf("Locking Error\n");
+                       }
+               if(flash_isset(info, sector, 0, FLASH_STATUS_DPS)){
+                       printf("Block locked.\n");
+                       retcode = ERR_PROTECTED;
+               }
+               if(flash_isset(info, sector, 0, FLASH_STATUS_VPENS))
+                       printf("Vpp Low Error.\n");
+               }
+               flash_write_cmd(info, sector, 0, FLASH_CMD_RESET);
+               break;
+       default:
+               break;
+       }
+       return retcode;
+}
+/*-----------------------------------------------------------------------
+ */
+static void flash_add_byte(flash_info_t *info, cfiword_t * cword, uchar c)
+{
+       switch(info->portwidth) {
+       case FLASH_CFI_8BIT:
+               cword->c = c;
+               break;
+       case FLASH_CFI_16BIT:
+               cword->w = (cword->w << 8) | c;
+               break;
+       case FLASH_CFI_32BIT:
+               cword->l = (cword->l << 8) | c;
+               break;
+       case FLASH_CFI_64BIT:
+               cword->ll = (cword->ll << 8) | c;
+               break;
+       }
+}
+
+
+/*-----------------------------------------------------------------------
+ * make a proper sized command based on the port and chip widths
+ */
+static void flash_make_cmd(flash_info_t * info, uchar cmd, void * cmdbuf)
+{
+       int i;
+       uchar *cp = (uchar *)cmdbuf;
+       for(i=0; i< info->portwidth; i++)
+               *cp++ = ((i+1) % info->chipwidth) ? '\0':cmd;
+}
+
+/*
+ * Write a proper sized command to the correct address
+ */
+static void flash_write_cmd(flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd)
+{
+
+       volatile cfiptr_t addr;
+       cfiword_t cword;
+       addr.cp = flash_make_addr(info, sect, offset);
+       flash_make_cmd(info, cmd, &cword);
+       switch(info->portwidth) {
+       case FLASH_CFI_8BIT:
+               debug("fwc addr %p cmd %x %x 8bit x %d bit\n",addr.cp, cmd, cword.c, 
+                      info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
+               *addr.cp = cword.c;
+               break;
+       case FLASH_CFI_16BIT:
+               debug("fwc addr %p cmd %x %4.4x 16bit x %d bit\n",addr.wp, cmd, cword.w, 
+                      info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
+               *addr.wp = cword.w;
+               break;
+       case FLASH_CFI_32BIT:
+               debug("fwc addr %p cmd %x %8.8lx 32bit x %d bit\n",addr.lp, cmd, cword.l, 
+                      info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
+               *addr.lp = cword.l;
+               break;
+       case FLASH_CFI_64BIT:
+#ifdef DEBUG
+               { 
+                       char str[20];
+                       print_longlong(str, cword.ll);
+       
+                       printf("fwc addr %p cmd %x %s 64 bit x %d bit\n",addr.llp, cmd, str, 
+                              info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
+               }
+#endif
+               *addr.llp = cword.ll;
+               break;
+       }
+}
+
+static void flash_unlock_seq(flash_info_t *info)
+{
+       flash_write_cmd(info, 0, 0x555, 0xAA);
+       flash_write_cmd(info, 0, 0x2AA, 0x55);
+}
+/*-----------------------------------------------------------------------
+ */
+static int flash_isequal(flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd)
+{
+       cfiptr_t cptr;
+       cfiword_t cword;
+       int retval;
+       cptr.cp = flash_make_addr(info, sect, offset);
+       flash_make_cmd(info, cmd, &cword);
+
+       debug("is= cmd %x(%c) addr %p ", cmd,cmd, cptr.cp);
+       switch(info->portwidth) {
+       case FLASH_CFI_8BIT:
+               debug("is= %x %x\n", cptr.cp[0], cword.c);
+               retval = (cptr.cp[0] == cword.c);
+               break;
+       case FLASH_CFI_16BIT:
+               debug("is= %4.4x %4.4x\n", cptr.wp[0], cword.w);
+               retval = (cptr.wp[0] == cword.w);
+               break;
+       case FLASH_CFI_32BIT:
+               debug("is= %8.8lx %8.8lx\n", cptr.lp[0], cword.l);
+               retval = (cptr.lp[0] == cword.l);
+               break;
+       case FLASH_CFI_64BIT:
+#ifdef DEBUG           
+               {
+                       char str1[20];
+                       char str2[20];
+                       print_longlong(str1, cptr.llp[0]);
+                       print_longlong(str2, cword.ll);
+                       printf("is= %s %s\n", str1, str2);
+               }
+#endif
+               retval = (cptr.llp[0] == cword.ll);
+               break;
+       default:
+               retval = 0;
+               break;
+       }
+       return retval;
+}
+/*-----------------------------------------------------------------------
+ */
+static int flash_isset(flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd)
+{
+       cfiptr_t cptr;
+       cfiword_t cword;
+       int retval;
+       cptr.cp = flash_make_addr(info, sect, offset);
+       flash_make_cmd(info, cmd, &cword);
+       switch(info->portwidth) {
+       case FLASH_CFI_8BIT:
+               retval = ((cptr.cp[0] & cword.c) == cword.c);
+               break;
+       case FLASH_CFI_16BIT:
+               retval = ((cptr.wp[0] & cword.w) == cword.w);
+               break;
+       case FLASH_CFI_32BIT:
+               retval = ((cptr.lp[0] & cword.l) == cword.l);
+               break;
+       case FLASH_CFI_64BIT:
+               retval = ((cptr.llp[0] & cword.ll) == cword.ll);
+       default:
+               retval = 0;
+               break;
+       }
+       return retval;
+}
+
+/*-----------------------------------------------------------------------
+ */
+static int flash_toggle(flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd)
+{
+       cfiptr_t cptr;
+       cfiword_t cword;
+       int retval;
+       cptr.cp = flash_make_addr(info, sect, offset);
+       flash_make_cmd(info, cmd, &cword);
+       switch(info->portwidth) {
+       case FLASH_CFI_8BIT:
+               retval = ((cptr.cp[0] & cword.c) != (cptr.cp[0] & cword.c));
+               break;
+       case FLASH_CFI_16BIT:
+               retval = ((cptr.wp[0] & cword.w) != (cptr.wp[0] & cword.w));
+               break;
+       case FLASH_CFI_32BIT:
+               retval = ((cptr.lp[0] & cword.l) != (cptr.lp[0] & cword.l));
+               break;
+       case FLASH_CFI_64BIT:
+               retval = ((cptr.llp[0] & cword.ll) != (cptr.llp[0] & cword.ll));
+               break;
+       default:
+               retval = 0;
+               break;
+       }
+       return retval;
+}
+
+/*-----------------------------------------------------------------------
+ * detect if flash is compatible with the Common Flash Interface (CFI)
+ * http://www.jedec.org/download/search/jesd68.pdf
+ *
+*/
+static int flash_detect_cfi(flash_info_t * info)
+{
+
+    puts("flash detect cfi\n");
+
+       for(info->portwidth=FLASH_CFI_8BIT; info->portwidth <= FLASH_CFI_64BIT;
+           info->portwidth <<= 1) {
+         /*            for(info->chipwidth = info->portwidth;
+                       info->chipwidth > 0;
+                       info->chipwidth >>= 1) { */
+               for(info->chipwidth =FLASH_CFI_BY8;
+                   info->chipwidth <= info->portwidth;
+                   info->chipwidth <<= 1) { 
+                       flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
+                       flash_write_cmd(info, 0, FLASH_OFFSET_CFI, FLASH_CMD_CFI);
+                       if(flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP,'Q') &&
+                          flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP + 1, 'R') &&
+                          flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP + 2, 'Y')) {
+                               debug("found port %d chip %d ", info->portwidth, info->chipwidth);
+                               debug("port %d bits chip %d bits\n", info->portwidth << CFI_FLASH_SHIFT_WIDTH, 
+                                      info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
+                               return 1;
+                       }
+               }
+       }
+       puts("not found\n");
+       return 0;
+}
+/*
+ * The following code cannot be run from FLASH!
+ *
+ */
+static ulong flash_get_size (ulong base, int banknum)
+{
+       flash_info_t * info = &flash_info[banknum];
+       int i, j;
+       flash_sect_t sect_cnt;
+       unsigned long sector;
+       unsigned long tmp;
+       int size_ratio;
+       uchar num_erase_regions;
+       int  erase_region_size;
+       int  erase_region_count;
+
+       info->start[0] = base;
+
+       if(flash_detect_cfi(info)){
+               info->vendor = flash_read_ushort(info, 0, FLASH_OFFSET_PRIMARY_VENDOR);
+               switch(info->vendor) {
+               case CFI_CMDSET_INTEL_STANDARD:
+               case CFI_CMDSET_INTEL_EXTENDED:
+               default:
+                       info->cmd_reset = FLASH_CMD_RESET;
+                       break;
+               case CFI_CMDSET_AMD_STANDARD:
+               case CFI_CMDSET_AMD_EXTENDED:
+                       info->cmd_reset = AMD_CMD_RESET;
+                       break;
+               }
+                       
+               debug("manufacturer is %d\n", info->vendor);
+               size_ratio = info->portwidth / info->chipwidth;
+               num_erase_regions = flash_read_uchar(info, FLASH_OFFSET_NUM_ERASE_REGIONS);
+               debug("size_ration %d port %d bits chip %d bits\n", size_ratio, info->portwidth << CFI_FLASH_SHIFT_WIDTH, 
+                              info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
+               debug("found %d erase regions\n", num_erase_regions);
+               sect_cnt = 0;
+               sector = base;
+               for(i = 0 ; i < num_erase_regions; i++) {
+                       if(i > NUM_ERASE_REGIONS) {
+                               printf("%d erase regions found, only %d used\n",
+                                      num_erase_regions, NUM_ERASE_REGIONS);
+                               break;
+                       }
+                       tmp = flash_read_long(info, 0, FLASH_OFFSET_ERASE_REGIONS + i*4);
+                       erase_region_size = (tmp & 0xffff)? ((tmp & 0xffff) * 256): 128;
+                       tmp >>= 16;
+                       erase_region_count = (tmp & 0xffff) +1;
+                       for(j = 0; j< erase_region_count; j++) {
+                               info->start[sect_cnt] = sector;
+                               sector += (erase_region_size * size_ratio);
+                               info->protect[sect_cnt] = flash_isset(info, sect_cnt, FLASH_OFFSET_PROTECT, FLASH_STATUS_PROTECT);
+                               sect_cnt++;
+                       }
+               }
+
+               info->sector_count = sect_cnt;
+               /* multiply the size by the number of chips */
+               info->size = (1 << flash_read_uchar(info, FLASH_OFFSET_SIZE)) * size_ratio;
+               info->buffer_size = (1 << flash_read_ushort(info, 0, FLASH_OFFSET_BUFFER_SIZE));
+               tmp = 1 << flash_read_uchar(info, FLASH_OFFSET_ETOUT);
+               info->erase_blk_tout = (tmp * (1 << flash_read_uchar(info, FLASH_OFFSET_EMAX_TOUT)));
+               tmp = 1 << flash_read_uchar(info, FLASH_OFFSET_WBTOUT);
+               info->buffer_write_tout = (tmp * (1 << flash_read_uchar(info, FLASH_OFFSET_WBMAX_TOUT)));
+               tmp = 1 << flash_read_uchar(info, FLASH_OFFSET_WTOUT);
+               info->write_tout = (tmp * (1 << flash_read_uchar(info, FLASH_OFFSET_WMAX_TOUT)))/ 1000;
+               info->flash_id = FLASH_MAN_CFI;
+       }
+
+       flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
+       return(info->size);
+}
+
+
+/*-----------------------------------------------------------------------
+ */
+static int flash_write_cfiword (flash_info_t *info, ulong dest, cfiword_t cword)
+{
+
+       cfiptr_t ctladdr;
+       cfiptr_t cptr;
+       int flag;
+
+       ctladdr.cp = flash_make_addr(info, 0, 0);
+       cptr.cp = (uchar *)dest;
+
+
+       /* Check if Flash is (sufficiently) erased */
+       switch(info->portwidth) {
+       case FLASH_CFI_8BIT:
+               flag = ((cptr.cp[0] & cword.c) == cword.c);
+               break;
+       case FLASH_CFI_16BIT:
+               flag = ((cptr.wp[0] & cword.w) == cword.w);
+               break;
+       case FLASH_CFI_32BIT:
+               flag = ((cptr.lp[0] & cword.l)  == cword.l);
+               break;
+       case FLASH_CFI_64BIT:
+               flag = ((cptr.lp[0] & cword.ll) == cword.ll);
+               break;
+       default:
+               return 2;
+       }
+       if(!flag)
+               return 2;
+
+       /* Disable interrupts which might cause a timeout here */
+       flag = disable_interrupts();
+
+       switch(info->vendor) {
+       case CFI_CMDSET_INTEL_EXTENDED:
+       case CFI_CMDSET_INTEL_STANDARD:
+               flash_write_cmd(info, 0, 0, FLASH_CMD_CLEAR_STATUS);
+               flash_write_cmd(info, 0, 0, FLASH_CMD_WRITE);
+               break;
+       case CFI_CMDSET_AMD_EXTENDED:
+       case CFI_CMDSET_AMD_STANDARD:
+               flash_unlock_seq(info);
+               flash_write_cmd(info, 0, 0x555, AMD_CMD_WRITE);
+               break;
+       }
+
+       switch(info->portwidth) {
+       case FLASH_CFI_8BIT:
+               cptr.cp[0] = cword.c;
+               break;
+       case FLASH_CFI_16BIT:
+               cptr.wp[0] = cword.w;
+               break;
+       case FLASH_CFI_32BIT:
+               cptr.lp[0] = cword.l;
+               break;
+       case FLASH_CFI_64BIT:
+               cptr.llp[0] = cword.ll;
+               break;
+       }
+
+       /* re-enable interrupts if necessary */
+       if(flag)
+               enable_interrupts();
+
+       return flash_full_status_check(info, 0, info->write_tout, "write");
+}
+
+#ifdef CFG_FLASH_USE_BUFFER_WRITE
+
+/* loop through the sectors from the highest address
+ * when the passed address is greater or equal to the sector address
+ * we have a match
+ */
+static flash_sect_t find_sector(flash_info_t *info, ulong addr)
+{
+       flash_sect_t sector;
+       for(sector = info->sector_count - 1; sector >= 0; sector--) {
+               if(addr >= info->start[sector])
+                       break;
+       }
+       return sector;
+}
+
+static int flash_write_cfibuffer(flash_info_t * info, ulong dest, uchar * cp, int len)
+{
+       flash_sect_t sector;
+       int cnt;
+       int retcode;
+       volatile cfiptr_t src;
+       volatile cfiptr_t dst;
+
+       src.cp = cp;
+       dst.cp = (uchar *)dest;
+       sector = find_sector(info, dest);
+       flash_write_cmd(info, sector, 0, FLASH_CMD_CLEAR_STATUS);
+       flash_write_cmd(info, sector, 0, FLASH_CMD_WRITE_TO_BUFFER);
+       if((retcode = flash_status_check(info, sector, info->buffer_write_tout,
+                                        "write to buffer")) == ERR_OK) {
+               switch(info->portwidth) {
+               case FLASH_CFI_8BIT:
+                       cnt = len;
+                       break;
+               case FLASH_CFI_16BIT:
+                       cnt = len >> 1;
+                       break;
+               case FLASH_CFI_32BIT:
+                       cnt = len >> 2;
+                       break;
+               case FLASH_CFI_64BIT:
+                       cnt = len >> 3;
+                       break;
+               default:
+                       return ERR_INVAL;
+                       break;
+               }
+               flash_write_cmd(info, sector, 0, (uchar)cnt-1);
+               while(cnt-- > 0) {
+                       switch(info->portwidth) {
+                       case FLASH_CFI_8BIT:
+                               *dst.cp++ = *src.cp++;
+                               break;
+                       case FLASH_CFI_16BIT:
+                               *dst.wp++ = *src.wp++;
+                               break;
+                       case FLASH_CFI_32BIT:
+                               *dst.lp++ = *src.lp++;
+                               break;
+                       case FLASH_CFI_64BIT:
+                               *dst.llp++ = *src.llp++;
+                               break;
+                       default:
+                               return ERR_INVAL;
+                               break;
+                       }
+               }
+               flash_write_cmd(info, sector, 0, FLASH_CMD_WRITE_BUFFER_CONFIRM);
+               retcode = flash_full_status_check(info, sector, info->buffer_write_tout,
+                                            "buffer write");
+       }
+       flash_write_cmd(info, sector, 0, FLASH_CMD_CLEAR_STATUS);
+       return retcode;
+}
+#endif /* CFG_USE_FLASH_BUFFER_WRITE */
+#endif /* CFG_FLASH_CFI */
index 20acc0713ef9241c2ef08b78c2c9df2557e87ceb..39b7e8e33b255a0971e4183f4d817070b38a4041 100644 (file)
@@ -163,7 +163,8 @@ static void pciauto_prescan_setup_bridge(struct pci_controller *hose,
 
        /* Configure bus number registers */
        pci_hose_write_config_byte(hose, dev, PCI_PRIMARY_BUS, PCI_BUS(dev));
-       pci_hose_write_config_byte(hose, dev, PCI_SECONDARY_BUS, sub_bus + 1);
+       /* TBS: passed in sub_bus is correct, removed the +1 */
+       pci_hose_write_config_byte(hose, dev, PCI_SECONDARY_BUS, sub_bus);
        pci_hose_write_config_byte(hose, dev, PCI_SUBORDINATE_BUS, 0xff);
 
        if (pci_mem)
@@ -284,6 +285,7 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev)
        unsigned int sub_bus = PCI_BUS(dev);
        unsigned short class;
        unsigned char prg_iface;
+       int n;
 
        pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class);
 
@@ -294,11 +296,19 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev)
                pciauto_setup_device(hose, dev, 2, hose->pci_mem, hose->pci_io);
 
                DEBUGF("PCI Autoconfig: Found P2P bridge, device %d\n", PCI_DEV(dev));
-               pciauto_prescan_setup_bridge(hose, dev, sub_bus);
-
-               pci_hose_scan_bus(hose, hose->current_busno);
-
+               
+               /* TBS: Passing in current_busno allows for sibling P2P bridges */
+               pciauto_prescan_setup_bridge(hose, dev, hose->current_busno);
+               /* 
+                * TBS: need to figure out if this is a subordinate bridge on the bus 
+                * to be able to properly set the pri/sec/sub bridge registers.
+                */
+               n = pci_hose_scan_bus(hose, hose->current_busno);
+
+               /* TBS: figure out the deepest we've gone for this leg */
+               sub_bus = max(n, sub_bus);
                pciauto_postscan_setup_bridge(hose, dev, sub_bus);
+
                sub_bus = hose->current_busno;
                break;
 
index 92c8e517eb733a0a3264a5d3d1775fcf043fb42c..f3570512e2ad244e373ea406cd6a70b01c4b6e9a 100644 (file)
  * ASMI is for Cyclone devices only and only works when the configuration
  * is loaded via JTAG or ASMI. Please see doc/README.dk1c20 for details.
  *----------------------------------------------------------------------*/
-#define CONFIG_NIOS_ASMI                       /* Enable ASMI          */
-#define CFG_NIOS_ASMIBASE      0x00920b00      /* ASMI base address    */
+#define CONFIG_NIOS_ASMI                          /* Enable ASMI       */
+#define CFG_NIOS_ASMIBASE      CFG_NIOS_CPU_ASMI0 /* ASMI base address */
 
 /*------------------------------------------------------------------------
  * COMMANDS
index 8f20887e4b945a894ff58d7882aab5b2f986df80..0cfc76d32c610da2e0eeb5424ef77c7c58c29909 100644 (file)
@@ -42,7 +42,8 @@ typedef struct {
        ulong   erase_blk_tout;         /* maximum block erase timeout          */
        ulong   write_tout;             /* maximum write timeout                */
        ulong   buffer_write_tout;      /* maximum buffer write timeout         */
-
+       ushort  vendor;                 /* the primary vendor id                */
+       ushort  cmd_reset;              /* Vendor specific reset command        */
 #endif
 } flash_info_t;
 
@@ -61,6 +62,8 @@ typedef struct {
 #define FLASH_CFI_BY32         0x04
 #define FLASH_CFI_BY64         0x08
 
+/* convert between bit value and numeric value */
+#define CFI_FLASH_SHIFT_WIDTH      3
 /* Prototypes */
 
 extern unsigned long flash_init (void);
@@ -78,6 +81,8 @@ extern int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt);
 /* board/?/flash.c */
 #if defined(CFG_FLASH_PROTECTION)
 extern int flash_real_protect(flash_info_t *info, long sector, int prot);
+extern void flash_read_user_serial(flash_info_t * info, void * buffer, int offset, int len);
+extern void flash_read_factory_serial(flash_info_t * info, void * buffer, int offset, int len);
 #endif /* CFG_FLASH_PROTECTION */
 
 /*-----------------------------------------------------------------------