Author: uwe
Date: 2009-05-16 23:39:19 +0200 (Sat, 16 May 2009)
New Revision: 520

Modified:
   trunk/flash.h
   trunk/flashchips.c
   trunk/nic3com.c
   trunk/pcidev.c
Log:
Add proper workaround for 3COM 3C90xB cards, which need special fixups
(the 3C90xC ones don't). This is tested on hardware.

Also, add initial support for the Atmel AT29C010A chip (which I inserted
in a 3COM 3C90xB card for testing). It can be detected, read works, erase
works, but write will need some additional code (will post in another
patch later).

Signed-off-by: Uwe Hermann <[email protected]>
Acked-by: Carl-Daniel Hailfinger <[email protected]>



Modified: trunk/flash.h
===================================================================
--- trunk/flash.h       2009-05-16 21:22:56 UTC (rev 519)
+++ trunk/flash.h       2009-05-16 21:39:19 UTC (rev 520)
@@ -193,6 +193,7 @@
 #define TEST_OK_ERASE  (1<<2)
 #define TEST_OK_WRITE  (1<<3)
 #define TEST_OK_PR     (TEST_OK_PROBE|TEST_OK_READ)
+#define TEST_OK_PRE    (TEST_OK_PROBE|TEST_OK_READ|TEST_OK_ERASE)
 #define TEST_OK_PREW   (TEST_OK_PROBE|TEST_OK_READ|TEST_OK_ERASE|TEST_OK_WRITE)
 #define TEST_OK_MASK   0x0f
 
@@ -258,6 +259,7 @@
 #define AT_26DF321             0x4700  /* also 25DF321 */
 #define AT_26F004              0x0400
 #define AT_29C040A             0xA4
+#define AT_29C010A             0xD5    
 #define AT_29C020              0xDA
 #define AT_45BR3214B           /* No ID available */
 #define AT_45CS1282            0x2920
@@ -559,6 +561,7 @@
 extern uint32_t io_base_addr;
 extern struct pci_access *pacc;
 extern struct pci_filter filter;
+extern struct pci_dev *pcidev_dev;
 struct pcidev_status {
        uint16_t vendor_id;
        uint16_t device_id;

Modified: trunk/flashchips.c
===================================================================
--- trunk/flashchips.c  2009-05-16 21:22:56 UTC (rev 519)
+++ trunk/flashchips.c  2009-05-16 21:39:19 UTC (rev 520)
@@ -376,6 +376,20 @@
 
        {
                .vendor         = "Atmel",
+               .name           = "AT29C010A",
+               .manufacture_id = ATMEL_ID,
+               .model_id       = AT_29C010A,
+               .total_size     = 128,
+               .page_size      = 128,
+               .tested         = TEST_OK_PRE,
+               .probe          = probe_jedec,
+               .erase          = erase_chip_jedec,
+               .write          = write_jedec,  /* FIXME */
+               .read           = read_memmapped,
+       },
+
+       {
+               .vendor         = "Atmel",
                .name           = "AT29C020",
                .manufacture_id = ATMEL_ID,
                .model_id       = AT_29C020,

Modified: trunk/nic3com.c
===================================================================
--- trunk/nic3com.c     2009-05-16 21:22:56 UTC (rev 519)
+++ trunk/nic3com.c     2009-05-16 21:39:19 UTC (rev 520)
@@ -29,13 +29,17 @@
 #define BIOS_ROM_ADDR          0x04
 #define BIOS_ROM_DATA          0x08
 #define INT_STATUS             0x0e
+#define INTERNAL_CONFIG                0x00
 #define SELECT_REG_WINDOW      0x800
 
 #define PCI_VENDOR_ID_3COM     0x10b7
 
+uint32_t internal_conf;
+uint16_t id;
+
 struct pcidev_status nics_3com[] = {
        /* 3C90xB */
-       {0x10b7, 0x9055, PCI_NT, "3COM", "3C90xB: PCI 10/100 Mbps; shared 
10BASE-T/100BASE-TX"},
+       {0x10b7, 0x9055, PCI_OK, "3COM", "3C90xB: PCI 10/100 Mbps; shared 
10BASE-T/100BASE-TX"},
        {0x10b7, 0x9001, PCI_NT, "3COM", "3C90xB: PCI 10/100 Mbps; shared 
10BASE-T/100BASE-T4" },
        {0x10b7, 0x9004, PCI_NT, "3COM", "3C90xB: PCI 10BASE-T (TPO)" },
        {0x10b7, 0x9005, PCI_NT, "3COM", "3C90xB: PCI 10BASE-T/10BASE2/AUI 
(COMBO)" },
@@ -57,7 +61,19 @@
        get_io_perms();
 
        io_base_addr = pcidev_init(PCI_VENDOR_ID_3COM, nics_3com);
+       id = pcidev_dev->device_id;
 
+       /* 3COM 3C90xB cards need a special fixup. */
+       if (id == 0x9055 || id == 0x9001 || id == 0x9004 || id == 0x9005
+           || id == 0x9006 || id == 0x900a || id == 0x905a) {
+               /* Select register window 3 and save the receiver status. */
+               OUTW(SELECT_REG_WINDOW + 3, io_base_addr + INT_STATUS);
+               internal_conf = INL(io_base_addr + INTERNAL_CONFIG);
+
+               /* Set receiver type to MII for full BIOS ROM access. */
+               OUTL((internal_conf & 0xf00fffff) | 0x00600000, io_base_addr);
+       }
+
        /*
         * The lowest 16 bytes of the I/O mapped register space of (most) 3COM
         * cards form a 'register window' into one of multiple (usually 8)
@@ -70,6 +86,14 @@
 
 int nic3com_shutdown(void)
 {
+       /* 3COM 3C90xB cards need a special fixup. */
+       if (id == 0x9055 || id == 0x9001 || id == 0x9004 || id == 0x9005
+           || id == 0x9006 || id == 0x900a || id == 0x905a) {
+               /* Select register window 3 and restore the receiver status. */
+               OUTW(SELECT_REG_WINDOW + 3, io_base_addr + INT_STATUS);
+               OUTL(internal_conf, io_base_addr + INTERNAL_CONFIG);
+       }
+
        free(pcidev_bdf);
        pci_cleanup(pacc);
 #if defined(__FreeBSD__) || defined(__DragonFly__)

Modified: trunk/pcidev.c
===================================================================
--- trunk/pcidev.c      2009-05-16 21:22:56 UTC (rev 519)
+++ trunk/pcidev.c      2009-05-16 21:39:19 UTC (rev 520)
@@ -32,6 +32,7 @@
 struct pci_access *pacc;
 struct pci_filter filter;
 char *pcidev_bdf = NULL;
+struct pci_dev *pcidev_dev = NULL;
 
 uint32_t pcidev_validate(struct pci_dev *dev, struct pcidev_status *devs)
 {
@@ -67,7 +68,7 @@
        struct pci_dev *dev;
        char *msg = NULL;
        int found = 0;
-       uint32_t addr = 0;
+       uint32_t addr = 0, curaddr = 0;
 
        pacc = pci_alloc();     /* Get the pci_access structure */
        pci_init(pacc);         /* Initialize the PCI library */
@@ -85,8 +86,11 @@
 
        for (dev = pacc->devices; dev; dev = dev->next) {
                if (pci_filter_match(&filter, dev)) {
-                       if ((addr = pcidev_validate(dev, devs)) != 0)
+                       if ((addr = pcidev_validate(dev, devs)) != 0) {
+                               curaddr = addr;
+                               pcidev_dev = dev;
                                found++;
+                       }
                }
        }
 
@@ -102,7 +106,7 @@
                exit(1);
        }
 
-       return addr;
+       return curaddr;
 }
 
 void print_supported_pcidevs(struct pcidev_status *devs)


-- 
coreboot mailing list: [email protected]
http://www.coreboot.org/mailman/listinfo/coreboot

Reply via email to