linkb_to_host and addon display card override onboard card.

git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1880 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
Yinghai Lu 2005-01-17 21:37:12 +00:00
parent c507e4de73
commit 1f1085b433
3 changed files with 65 additions and 45 deletions

View File

@ -363,35 +363,44 @@ void compute_allocate_resource(
} }
#if CONFIG_CONSOLE_VGA == 1 #if CONFIG_CONSOLE_VGA == 1
device_t vga_pri = 0;
static void allocate_vga_resource(void) static void allocate_vga_resource(void)
{ {
#warning "FIXME modify allocate_vga_resource so it is less pci centric!" #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." #warning "This function knows to much about PCI stuff, it should be just a ietrator/visitor."
/* FIXME handle the VGA pallette snooping */ /* FIXME handle the VGA pallette snooping */
struct device *dev, *vga; struct device *dev, *vga, *vga_onboard;
struct bus *bus; struct bus *bus;
bus = 0; bus = 0;
vga = 0; vga = 0;
vga_onboard = 0;
for (dev = all_devices; dev; dev = dev->next) { for (dev = all_devices; dev; dev = dev->next) {
if ( !dev->enabled ) continue;
if (((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) && if (((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) &&
((dev->class >> 8) != PCI_CLASS_DISPLAY_OTHER)) { ((dev->class >> 8) != PCI_CLASS_DISPLAY_OTHER)) {
if (!vga) { if (!vga) {
printk_debug("Allocating VGA resource %s\n", dev_path(dev)); if (dev->on_mainboard) {
vga = dev; vga_onboard = dev;
} }
if (vga == dev) { else {
/* All legacy VGA cards have MEM & I/O space registers */ vga = dev;
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);
} }
/* 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; bus = vga->bus;
} }
/* Now walk up the bridges setting the VGA enable */ /* 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; bus = (bus == bus->dev->bus)? 0 : bus->dev->bus;
} }
} }
#endif #endif
/** /**
* @brief Assign the computed resources to the devices on the bus. * @brief Assign the computed resources to the devices on the bus.
* *
@ -603,28 +614,27 @@ void dev_initialize(void)
printk_info("Initializing devices...\n"); printk_info("Initializing devices...\n");
#if CONFIG_CONSOLE_VGA == 1 #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) { for (dev = all_devices; dev; dev = dev->next) {
if (dev->enabled && !dev->initialized && if (dev->enabled && !dev->initialized &&
dev->ops && dev->ops->init) 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)); printk_debug("%s init\n", dev_path(dev));
dev->initialized = 1; dev->initialized = 1;
dev->ops->init(dev); 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"); printk_info("Devices initialized\n");
} }

View File

@ -67,15 +67,17 @@ static int ht_setup_link(struct prev_link *prev, device_t dev, unsigned pos)
unsigned freq, old_freq; unsigned freq, old_freq;
unsigned present_width, upstream_width, old_width; unsigned present_width, upstream_width, old_width;
int reset_needed; int reset_needed;
int linkb_to_host;
/* Set the hypertransport link width and frequency */ /* Set the hypertransport link width and frequency */
reset_needed = 0; reset_needed = 0;
linkb_to_host = pci_read_config16(dev, pos + PCI_CAP_FLAGS) & (1<<10);
/* Read the capabilities */ /* 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); 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); 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); upstream_width_cap = pci_read_config8(prev->dev, prev->pos + prev->config_off);
/* Calculate the highest useable frequency */ /* Calculate the highest useable frequency */
freq = log2(present_freq_cap & upstream_freq_cap); 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]; present_width |= pow2_to_link_width[ln_upstream_width_out];
/* Set the current device */ /* 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) { 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; reset_needed = 1;
printk_spew("HyperT FreqP old %x new %x\n",old_freq,freq); 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) { 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; reset_needed = 1;
printk_spew("HyperT widthP old %x new %x\n",old_width, present_width); 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 */ /* Remember the current link as the previous link */
prev->dev = dev; prev->dev = dev;
prev->pos = pos; prev->pos = pos;
prev->config_off = PCI_HT_CAP_SLAVE_WIDTH1; if(linkb_to_host) {
prev->freq_off = PCI_HT_CAP_SLAVE_FREQ1; prev->config_off = PCI_HT_CAP_SLAVE_WIDTH0;
prev->freq_cap_off = PCI_HT_CAP_SLAVE_FREQ_CAP1; 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; return reset_needed;
@ -175,7 +184,7 @@ static void ht_collapse_early_enumeration(struct bus *bus)
/* Spin through the devices and collapse any early /* Spin through the devices and collapse any early
* hypertransport enumeration. * hypertransport enumeration.
*/ */
for(devfn = 0; devfn <= 0xff; devfn += 8) { for(devfn = PCI_DEVFN(1, 0); devfn <= 0xff; devfn += 8) {
struct device dummy; struct device dummy;
uint32_t id; uint32_t id;
unsigned pos, flags; unsigned pos, flags;
@ -187,6 +196,7 @@ static void ht_collapse_early_enumeration(struct bus *bus)
id == 0x0000ffff || id == 0xffff0000) { id == 0x0000ffff || id == 0xffff0000) {
continue; continue;
} }
dummy.vendor = id & 0xffff; dummy.vendor = id & 0xffff;
dummy.device = (id >> 16) & 0xffff; dummy.device = (id >> 16) & 0xffff;
dummy.hdr_type = pci_read_config8(&dummy, PCI_HEADER_TYPE); 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 */ /* Now read the vendor and device id */
id = pci_read_config32(dev, PCI_VENDOR_ID); id = pci_read_config32(dev, PCI_VENDOR_ID);
/* If the chain is fully enumerated quit */ /* If the chain is fully enumerated quit */
if (id == 0xffffffff || id == 0x00000000 || if (id == 0xffffffff || id == 0x00000000 ||
id == 0x0000ffff || id == 0xffff0000) id == 0x0000ffff || id == 0xffff0000) {
{ if (dev->enabled) {
if (dev->enabled) { printk_info("Disabling static device: %s\n",
printk_info("Disabling static device: %s\n", dev_path(dev));
dev_path(dev)); dev->enabled = 0;
dev->enabled = 0; }
}
break; break;
} }
} }
@ -305,6 +313,7 @@ unsigned int hypertransport_scan_chain(struct bus *bus, unsigned int max)
break; break;
} }
/* Update the Unitid of the current device */ /* Update the Unitid of the current device */
flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS); flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
flags &= ~0x1f; /* mask out base Unit ID */ flags &= ~0x1f; /* mask out base Unit ID */

View File

@ -57,6 +57,7 @@ static void *pci_ram_image_start = PCI_RAM_IMAGE_START;
#if CONFIG_CONSOLE_VGA == 1 #if CONFIG_CONSOLE_VGA == 1
int vga_inited = 0; // it will be used by vga_console int vga_inited = 0; // it will be used by vga_console
extern device_t vga_pri; // The only VGA
#endif #endif
struct rom_header *pci_rom_load(struct device *dev, struct rom_header *rom_header) 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 (PCI_CLASS_DISPLAY_VGA == (rom_data->class_hi << 16 | rom_data->class_lo)) {
#if CONFIG_CONSOLE_VGA == 1 #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", printk_spew("%s, copying VGA ROM Image from %x to %x, %x bytes\n",
__func__, rom_header, PCI_VGA_RAM_IMAGE_START, rom_size); __func__, rom_header, PCI_VGA_RAM_IMAGE_START, rom_size);
memcpy(PCI_VGA_RAM_IMAGE_START, rom_header, rom_size); memcpy(PCI_VGA_RAM_IMAGE_START, rom_header, rom_size);