diff options
-rw-r--r-- | src/devices/pci_device.c | 87 | ||||
-rw-r--r-- | src/devices/smbus_ops.c | 15 | ||||
-rw-r--r-- | src/northbridge/amd/amdk8/northbridge.c | 23 |
3 files changed, 97 insertions, 28 deletions
diff --git a/src/devices/pci_device.c b/src/devices/pci_device.c index b16e922a33..6062fa6387 100644 --- a/src/devices/pci_device.c +++ b/src/devices/pci_device.c @@ -37,6 +37,7 @@ static uint8_t pci_moving_config8(struct device *dev, unsigned reg) return ones ^ zeroes; } + static uint16_t pci_moving_config16(struct device *dev, unsigned reg) { uint16_t value, ones, zeroes; @@ -81,7 +82,7 @@ unsigned pci_find_capability(device_t dev, unsigned cap) if (pos > PCI_CAP_LIST_NEXT) { pos = pci_read_config8(dev, pos); } - while(pos != 0) { /* loop through the linked list */ + while (pos != 0) { /* loop through the linked list */ int this_cap; this_cap = pci_read_config8(dev, pos + PCI_CAP_LIST_ID); if (this_cap == cap) { @@ -111,7 +112,7 @@ struct resource *pci_get_resource(struct device *dev, unsigned long index) /* See which bits move */ moving = pci_moving_config32(dev, index); - + /* Initialize attr to the bits that do not move */ attr = value & ~moving; @@ -153,9 +154,8 @@ struct resource *pci_get_resource(struct device *dev, unsigned long index) */ if (moving == 0) { if (value != 0) { - printk_debug( - "%s register %02x(%08x), read-only ignoring it\n", - dev_path(dev), index, value); + printk_debug("%s register %02x(%08x), read-only ignoring it\n", + dev_path(dev), index, value); } resource->flags = 0; } @@ -199,9 +199,9 @@ struct resource *pci_get_resource(struct device *dev, unsigned long index) #if 0 if (resource->flags) { printk_debug("%s %02x ->", - dev_path(dev), resource->index); + dev_path(dev), resource->index); printk_debug(" value: 0x%08Lx zeroes: 0x%08Lx ones: 0x%08Lx attr: %08lx\n", - value, zeroes, ones, attr); + value, zeroes, ones, attr); printk_debug( "%s %02x -> size: 0x%08Lx max: 0x%08Lx %s%s\n ", dev_path(dev), @@ -225,7 +225,7 @@ static void pci_read_bases(struct device *dev, unsigned int howmany) { unsigned long index; - for(index = PCI_BASE_ADDRESS_0; (index < PCI_BASE_ADDRESS_0 + (howmany << 2)); ) { + for (index = PCI_BASE_ADDRESS_0; (index < PCI_BASE_ADDRESS_0 + (howmany << 2)); ) { struct resource *resource; resource = pci_get_resource(dev, index); index += (resource->flags & IORESOURCE_PCI64)?8:4; @@ -233,11 +233,63 @@ static void pci_read_bases(struct device *dev, unsigned int howmany) compact_resources(dev); } +static void pci_read_rom_resource(struct device *dev, unsigned long index) +{ + struct resource *resource; + unsigned long value, attr; + resource_t moving, limit; + + /* Initialize the resources to nothing */ + resource = new_resource(dev, index); + + /* Get the initial value */ + value = pci_read_config32(dev, index); + + /* See which bits move */ + moving = pci_moving_config32(dev, index); + /* clear the Enable bit */ + moving = moving & 0xffffffffe; + + /* Find the resource constraints. + * + * Start by finding the bits that move. From there: + * - Size is the least significant bit of the bits that move. + * - Limit is all of the bits that move plus all of the lower bits. + * See PCI Spec 6.2.5.1 ... + */ + limit = 0; + + if (moving) { + resource->size = 1; + resource->align = resource->gran = 0; + while(!(moving & resource->size)) { + resource->size <<= 1; + resource->align += 1; + resource->gran += 1; + } + resource->limit = limit = moving | (resource->size - 1); + printk_debug("%s, rom size: %x, limit: %x\n", + dev_path(dev), resource->size, limit); + } + + if (moving == 0) { + if (value != 0) { + printk_debug("%s register %02x(%08x), read-only ignoring it\n", + dev_path(dev), index, value); + } + resource->flags = 0; + } else { + resource->flags |= IORESOURCE_MEM | IORESOURCE_READONLY; + } + compact_resources(dev); + +} + static void pci_set_resource(struct device *dev, struct resource *resource); -static void pci_record_bridge_resource( - struct device *dev, resource_t moving, - unsigned index, unsigned long mask, unsigned long type) +static void pci_record_bridge_resource( struct device *dev, resource_t moving, + unsigned index, unsigned long mask, + unsigned long type) { /* Initiliaze the constraints on the current bus */ struct resource *resource; @@ -272,7 +324,6 @@ static void pci_record_bridge_resource( return; } - static void pci_bridge_read_bases(struct device *dev) { resource_t moving_base, moving_limit, moving; @@ -329,8 +380,7 @@ void pci_dev_read_resources(struct device *dev) pci_read_bases(dev, 6); - addr = pci_read_config32(dev, PCI_ROM_ADDRESS); - dev->rom_address = (addr == 0xffffffff)? 0 : addr; + pci_read_rom_resource(dev, PCI_ROM_ADDRESS); } void pci_bus_read_resources(struct device *dev) @@ -339,9 +389,8 @@ void pci_bus_read_resources(struct device *dev) pci_bridge_read_bases(dev); pci_read_bases(dev, 2); - - addr = pci_read_config32(dev, PCI_ROM_ADDRESS1); - dev->rom_address = (addr == 0xffffffff)? 0 : addr; + + pci_read_rom_resource(dev, PCI_ROM_ADDRESS1); } static void pci_set_resource(struct device *dev, struct resource *resource) @@ -450,10 +499,10 @@ void pci_dev_set_resources(struct device *dev) last = &dev->resource[dev->resources]; - for(resource = &dev->resource[0]; resource < last; resource++) { + for (resource = &dev->resource[0]; resource < last; resource++) { pci_set_resource(dev, resource); } - for(link = 0; link < dev->links; link++) { + for (link = 0; link < dev->links; link++) { struct bus *bus; bus = &dev->link[link]; if (bus->children) { diff --git a/src/devices/smbus_ops.c b/src/devices/smbus_ops.c index e721bfbfb3..8d32a66b8f 100644 --- a/src/devices/smbus_ops.c +++ b/src/devices/smbus_ops.c @@ -7,7 +7,7 @@ struct bus *get_pbus_smbus(device_t dev) { struct bus *pbus = dev->bus; - while(pbus && pbus->dev && !ops_smbus_bus(pbus)) { + while (pbus && pbus->dev && !ops_smbus_bus(pbus)) { pbus = pbus->dev->bus; } if (!pbus || !pbus->dev || !pbus->dev->ops || !pbus->dev->ops->ops_smbus_bus) { @@ -18,9 +18,10 @@ struct bus *get_pbus_smbus(device_t dev) return pbus; } - /*multi level i2c MUX??? may need to find the first i2c device and then set link down to current dev - 1 store get_pbus_smbus list link - 2 reverse the link and call set link */ +/*multi level i2c MUX??? may need to find the first i2c device and then set link + * down to current dev + 1 store get_pbus_smbus list link + 2 reverse the link and call set link */ int smbus_set_link(device_t dev) { @@ -33,10 +34,10 @@ int smbus_set_link(device_t dev) pbus = pbus->dev->bus; } // printk_info("smbus_set_link: "); - for(i=pbus_num-1; i>=0; i--) { + for (i=pbus_num-1; i>=0; i--) { // printk_info(" %s[%d] -> ", dev_path(pbus_a[i]->dev), pbus_a[i]->link); - if(ops_smbus_bus(get_pbus_smbus(pbus_a[i]->dev))) { - if(pbus_a[i]->dev->ops && pbus_a[i]->dev->ops->set_link) + if (ops_smbus_bus(get_pbus_smbus(pbus_a[i]->dev))) { + if (pbus_a[i]->dev->ops && pbus_a[i]->dev->ops->set_link) pbus_a[i]->dev->ops->set_link(pbus_a[i]->dev, pbus_a[i]->link); } } diff --git a/src/northbridge/amd/amdk8/northbridge.c b/src/northbridge/amd/amdk8/northbridge.c index 788d698bac..7612d398ae 100644 --- a/src/northbridge/amd/amdk8/northbridge.c +++ b/src/northbridge/amd/amdk8/northbridge.c @@ -424,6 +424,8 @@ static void amdk8_create_vga_resource(device_t dev, unsigned nodeid) { struct resource *resource; unsigned link; + uint32_t base, limit; + unsigned reg; for (link = 0; link < dev->links; link++) { if (dev->link[link].bridge_ctrl & PCI_BRIDGE_CTL_VGA) { printk_info("%s: bridge on link %d has VGA device\n", @@ -433,12 +435,29 @@ static void amdk8_create_vga_resource(device_t dev, unsigned nodeid) resource = amdk8_find_mempair(dev, nodeid, link); printk_info("MEM pair register %x\n", resource->index - 0x100); resource->base = 0xa0000; - resource->size = 0x00000; + resource->size = 0x20000; resource->gran = 16; resource->align = 16; - resource->flags = IORESOURCE_PREFETCH | IORESOURCE_MEM | IORESOURCE_FIXED | IORESOURCE_ASSIGNED; + resource->flags = IORESOURCE_MEM | IORESOURCE_FIXED | IORESOURCE_ASSIGNED; } } +#if 1 + reg = resource->index & 0xfc; + base = f1_read_config32(reg); + limit = f1_read_config32(reg + 0x4); + base &= 0x000000f0; + base |= (resource->base >> 8) & 0xffffff00; + base |= 3; + limit &= 0x00000048; + limit |= ((resource->base + resource->size) >> 8) & 0xffffff00; + limit |= (resource->index & 3) << 4; + limit |= (nodeid & 7); + f1_write_config32(reg + 0x4, limit); + f1_write_config32(reg, base); + + /* release the resource */ + resource->flags = 0; +#endif } static void amdk8_set_resources(device_t dev) { |