linkb_to_host and addon display card override onboard card.
authorYinghai Lu <yinghailu@gmail.com>
Mon, 17 Jan 2005 21:37:12 +0000 (21:37 +0000)
committerYinghai Lu <yinghailu@gmail.com>
Mon, 17 Jan 2005 21:37:12 +0000 (21:37 +0000)
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1880 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1

src/devices/device.c
src/devices/hypertransport.c
src/devices/pci_rom.c

index 40d3f5cf2ddecdcfa133ce3fc0d04c2da536373a..e4e8f24344d002873e9107ea65d2ad84edc874ac 100644 (file)
@@ -363,35 +363,44 @@ void compute_allocate_resource(
 
 
 }
-
 #if CONFIG_CONSOLE_VGA == 1
+device_t vga_pri = 0;
 static void allocate_vga_resource(void)
 {
 #warning "FIXME modify allocate_vga_resource so it is less pci centric!"
 #warning "This function knows to much about PCI stuff, it should be just a ietrator/visitor."
 
        /* FIXME handle the VGA pallette snooping */
-       struct device *dev, *vga;
+       struct device *dev, *vga, *vga_onboard;
        struct bus *bus;
        bus = 0;
        vga = 0;
+       vga_onboard = 0;
        for (dev = all_devices; dev; dev = dev->next) {
+               if ( !dev->enabled ) continue;
                if (((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) &&
                    ((dev->class >> 8) != PCI_CLASS_DISPLAY_OTHER)) {
                        if (!vga) {
-                                printk_debug("Allocating VGA resource %s\n", dev_path(dev));
-                               vga = dev;
-                       }
-                       if (vga == dev) {
-                               /* All legacy VGA cards have MEM & I/O space registers */
-                               dev->command |= PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
-                       } else {
-                               /* It isn't safe to enable other VGA cards */
-                               dev->command &= ~(PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
+                               if (dev->on_mainboard) {
+                                       vga_onboard = dev;
+                               } 
+                               else {
+                                       vga = dev;
+                               }
                        }
+                       /* It isn't safe to enable other VGA cards */
+                       dev->command &= ~(PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
                }
        }
-       if (vga) {
+       
+       if (!vga) {
+               vga = vga_onboard;
+       }
+       
+       if (vga) { // vga is first add on card or the only onboard vga
+               printk_debug("Allocating VGA resource %s\n", dev_path(vga));
+               vga->command |= (PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
+               vga_pri = vga;
                bus = vga->bus;
        }
        /* Now walk up the bridges setting the VGA enable */
@@ -402,8 +411,10 @@ static void allocate_vga_resource(void)
                bus = (bus == bus->dev->bus)? 0 : bus->dev->bus;
        } 
 }
+
 #endif
 
+
 /**
  * @brief  Assign the computed resources to the devices on the bus.
  *
@@ -603,28 +614,27 @@ void dev_initialize(void)
 
        printk_info("Initializing devices...\n");
 #if CONFIG_CONSOLE_VGA == 1
-        for (dev = all_devices; dev; dev = dev->next) {
-               if ( !dev->enabled ) continue;
-                if (dev->enabled && !dev->initialized &&
-                        dev->ops && dev->ops->init)
-                {
-                       if( !dev->on_mainboard ) continue;  // process addon card in second run
-                       else if( dev->rom_address!=0 ) continue; // onboard and it is assigned via MB Config.lb, process it later
-                        printk_debug("%s init\n", dev_path(dev));
-                        dev->initialized = 1;
-                        dev->ops->init(dev);
-                }
-        }
-#endif
        for (dev = all_devices; dev; dev = dev->next) {
                if (dev->enabled && !dev->initialized && 
                        dev->ops && dev->ops->init) 
                {
+                       if( !dev->on_mainboard ) continue;  // process addon card in second run
+                       else if( dev->rom_address!=0 ) continue; // onboard and it is assigned via MB Config.lb, process it later
                        printk_debug("%s init\n", dev_path(dev));
                        dev->initialized = 1;
                        dev->ops->init(dev);
                }
        }
+#endif
+        for (dev = all_devices; dev; dev = dev->next) {
+                if (dev->enabled && !dev->initialized &&
+                        dev->ops && dev->ops->init)
+                {
+                        printk_debug("%s init\n", dev_path(dev));
+                        dev->initialized = 1;
+                        dev->ops->init(dev);
+                }
+        }
        printk_info("Devices initialized\n");
 }
 
index e8cf432cb1ea781d6d1f95329ebcbc3b22cb2c2f..a75550cdae80bf309f632954f658cb4781b1b85a 100644 (file)
@@ -67,15 +67,17 @@ static int ht_setup_link(struct prev_link *prev, device_t dev, unsigned pos)
        unsigned freq, old_freq;
        unsigned present_width, upstream_width, old_width;
        int reset_needed;
+       int linkb_to_host;
 
        /* Set the hypertransport link width and frequency */
        reset_needed = 0;
+       linkb_to_host = pci_read_config16(dev, pos + PCI_CAP_FLAGS) & (1<<10);
 
        /* Read the capabilities */
-       present_freq_cap   = ht_read_freq_cap(dev, pos + PCI_HT_CAP_SLAVE_FREQ_CAP0);
+       present_freq_cap   = ht_read_freq_cap(dev, pos + (linkb_to_host ? PCI_HT_CAP_SLAVE_FREQ_CAP1: PCI_HT_CAP_SLAVE_FREQ_CAP0));
        upstream_freq_cap  = ht_read_freq_cap(prev->dev, prev->pos + prev->freq_cap_off);
-       present_width_cap  = pci_read_config8(dev, pos + PCI_HT_CAP_SLAVE_WIDTH0);
-       upstream_width_cap = pci_read_config8(prev->dev, prev->pos + prev->config_off);
+       present_width_cap  = pci_read_config8(dev, pos + (linkb_to_host ? PCI_HT_CAP_SLAVE_WIDTH1: PCI_HT_CAP_SLAVE_WIDTH0));
+        upstream_width_cap = pci_read_config8(prev->dev, prev->pos + prev->config_off);
        
        /* Calculate the highest useable frequency */
        freq = log2(present_freq_cap & upstream_freq_cap);
@@ -98,15 +100,15 @@ static int ht_setup_link(struct prev_link *prev, device_t dev, unsigned pos)
        present_width  |= pow2_to_link_width[ln_upstream_width_out];
 
        /* Set the current device */
-       old_freq = pci_read_config8(dev, pos + PCI_HT_CAP_SLAVE_FREQ0);
+       old_freq = pci_read_config8(dev, pos + (linkb_to_host ? PCI_HT_CAP_SLAVE_FREQ1:PCI_HT_CAP_SLAVE_FREQ0));
        if (freq != old_freq) {
-               pci_write_config8(dev, pos + PCI_HT_CAP_SLAVE_FREQ0, freq);
+               pci_write_config8(dev, pos + (linkb_to_host ? PCI_HT_CAP_SLAVE_FREQ1:PCI_HT_CAP_SLAVE_FREQ0), freq);
                reset_needed = 1;
                printk_spew("HyperT FreqP old %x new %x\n",old_freq,freq);
        }
-       old_width = pci_read_config8(dev, pos + PCI_HT_CAP_SLAVE_WIDTH0 + 1);
+       old_width = pci_read_config8(dev, pos + (linkb_to_host ? PCI_HT_CAP_SLAVE_WIDTH1: PCI_HT_CAP_SLAVE_WIDTH0) + 1);
        if (present_width != old_width) {
-               pci_write_config8(dev, pos + PCI_HT_CAP_SLAVE_WIDTH0 + 1, present_width);
+               pci_write_config8(dev, pos + (linkb_to_host ? PCI_HT_CAP_SLAVE_WIDTH1: PCI_HT_CAP_SLAVE_WIDTH0) + 1, present_width);
                reset_needed = 1;
                printk_spew("HyperT widthP old %x new %x\n",old_width, present_width);
        }
@@ -129,9 +131,16 @@ static int ht_setup_link(struct prev_link *prev, device_t dev, unsigned pos)
        /* Remember the current link as the previous link */
        prev->dev = dev;
        prev->pos = pos;
-       prev->config_off   = PCI_HT_CAP_SLAVE_WIDTH1;
-       prev->freq_off     = PCI_HT_CAP_SLAVE_FREQ1;
-       prev->freq_cap_off = PCI_HT_CAP_SLAVE_FREQ_CAP1;
+        if(linkb_to_host) {
+               prev->config_off   = PCI_HT_CAP_SLAVE_WIDTH0;
+               prev->freq_off     = PCI_HT_CAP_SLAVE_FREQ0;
+               prev->freq_cap_off = PCI_HT_CAP_SLAVE_FREQ_CAP0;
+        }
+        else {
+               prev->config_off   = PCI_HT_CAP_SLAVE_WIDTH1;
+               prev->freq_off     = PCI_HT_CAP_SLAVE_FREQ1;
+               prev->freq_cap_off = PCI_HT_CAP_SLAVE_FREQ_CAP1;
+        }
 
        return reset_needed;
                
@@ -175,7 +184,7 @@ static void ht_collapse_early_enumeration(struct bus *bus)
        /* Spin through the devices and collapse any early
         * hypertransport enumeration.
         */
-       for(devfn = 0; devfn <= 0xff; devfn += 8) {
+       for(devfn = PCI_DEVFN(1, 0); devfn <= 0xff; devfn += 8) {
                struct device dummy;
                uint32_t id;
                unsigned pos, flags;
@@ -187,6 +196,7 @@ static void ht_collapse_early_enumeration(struct bus *bus)
                        id == 0x0000ffff || id == 0xffff0000) {
                        continue;
                }
+
                dummy.vendor = id & 0xffff;
                dummy.device = (id >> 16) & 0xffff;
                dummy.hdr_type = pci_read_config8(&dummy, PCI_HEADER_TYPE);
@@ -268,16 +278,14 @@ unsigned int hypertransport_scan_chain(struct bus *bus, unsigned int max)
                        /* Now read the vendor and device id */
                        id = pci_read_config32(dev, PCI_VENDOR_ID);
 
-                       
                        /* If the chain is fully enumerated quit */
                        if (id == 0xffffffff || id == 0x00000000 ||
-                               id == 0x0000ffff || id == 0xffff0000) 
-                       {
-                               if (dev->enabled) {
-                                       printk_info("Disabling static device: %s\n",
-                                               dev_path(dev));
-                                       dev->enabled = 0;
-                               }
+                               id == 0x0000ffff || id == 0xffff0000) {
+                                      if (dev->enabled) {
+                                              printk_info("Disabling static device: %s\n",
+                                                      dev_path(dev));
+                                              dev->enabled = 0;
+                                       }
                                break;
                        }
                }
@@ -305,6 +313,7 @@ unsigned int hypertransport_scan_chain(struct bus *bus, unsigned int max)
                        break;
                }
                
+
                /* Update the Unitid of the current device */
                flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
                flags &= ~0x1f; /* mask out base Unit ID */
index 310c00f00c740eebbdd4baef6e019705f885a6a8..92f0b0980f8b8a359a533346058e56bf49cb7175 100644 (file)
@@ -57,6 +57,7 @@ static void *pci_ram_image_start = PCI_RAM_IMAGE_START;
 
 #if CONFIG_CONSOLE_VGA == 1
 int vga_inited = 0; // it will be used by vga_console 
+extern device_t vga_pri; // The only VGA
 #endif
 
 struct rom_header *pci_rom_load(struct device *dev, struct rom_header *rom_header)
@@ -71,7 +72,7 @@ struct rom_header *pci_rom_load(struct device *dev, struct rom_header *rom_heade
 
        if (PCI_CLASS_DISPLAY_VGA == (rom_data->class_hi << 16 | rom_data->class_lo)) {
 #if CONFIG_CONSOLE_VGA == 1
-               if(vga_inited) return NULL; // only one VGA supported
+               if (dev != vga_pri) return NULL; // only one VGA supported
                printk_spew("%s, copying VGA ROM Image from %x to %x, %x bytes\n",
                            __func__, rom_header, PCI_VGA_RAM_IMAGE_START, rom_size);
                memcpy(PCI_VGA_RAM_IMAGE_START, rom_header, rom_size);