summaryrefslogtreecommitdiff
path: root/src/northbridge
diff options
context:
space:
mode:
Diffstat (limited to 'src/northbridge')
-rw-r--r--src/northbridge/amd/amdk8/northbridge.c1
-rw-r--r--src/northbridge/emulation/qemu-i386/northbridge.c135
-rw-r--r--src/northbridge/intel/e7501/northbridge.c4
-rw-r--r--src/northbridge/intel/i855pm/northbridge.c234
-rw-r--r--src/northbridge/motorola/mpc107/mpc107.c588
-rw-r--r--src/northbridge/transmeta/tm5800/northbridge.c230
-rw-r--r--src/northbridge/via/vt8601/northbridge.c252
-rw-r--r--src/northbridge/via/vt8623/northbridge.c356
8 files changed, 1053 insertions, 747 deletions
diff --git a/src/northbridge/amd/amdk8/northbridge.c b/src/northbridge/amd/amdk8/northbridge.c
index f3f6ba9818..200877cec2 100644
--- a/src/northbridge/amd/amdk8/northbridge.c
+++ b/src/northbridge/amd/amdk8/northbridge.c
@@ -1,7 +1,6 @@
#include <console/console.h>
#include <arch/io.h>
#include <stdint.h>
-#include <mem.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
diff --git a/src/northbridge/emulation/qemu-i386/northbridge.c b/src/northbridge/emulation/qemu-i386/northbridge.c
index 6122c2c940..cd06573067 100644
--- a/src/northbridge/emulation/qemu-i386/northbridge.c
+++ b/src/northbridge/emulation/qemu-i386/northbridge.c
@@ -1,8 +1,6 @@
#include <console/console.h>
#include <arch/io.h>
#include <stdint.h>
-#include <mem.h>
-#include <part/sizeram.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/hypertransport.h>
@@ -17,57 +15,102 @@ void hard_reset(void)
printk_err("Hard_RESET!!!\n");
}
-struct mem_range *sizeram(void)
+#define BRIDGE_IO_MASK (IORESOURCE_IO | IORESOURCE_MEM)
+
+static void pci_domain_read_resources(device_t dev)
{
- unsigned long mmio_basek;
- static struct mem_range mem[10];
- device_t dev;
- int i, idx;
- unsigned char rambits;
+ struct resource *resource;
+ unsigned reg;
+
+ /* Initialize the system wide io space constraints */
+ resource = new_resource(dev, 0);
+ resource->base = 0x400;
+ resource->limit = 0xffffUL;
+ resource->flags = IORESOURCE_IO;
+ compute_allocate_resource(&dev->link[0], resource,
+ IORESOURCE_IO, IORESOURCE_IO);
+
+ /* Initialize the system wide memory resources constraints */
+ resource = new_resource(dev, 1);
+ resource->limit = 0xffffffffULL;
+ resource->flags = IORESOURCE_MEM;
+ compute_allocate_resource(&dev->link[0], resource,
+ IORESOURCE_MEM, IORESOURCE_MEM);
+}
+
+static void pci_domain_set_resources(device_t dev)
+{
+ struct resource *resource, *last;
+ device_t mc_dev;
+ uint32_t pci_tolm;
+
+ pci_tolm = 0xffffffffUL;
+ last = &dev->resource[dev->resources];
+ for(resource = &dev->resource[0]; resource < last; resource++)
+ {
+ compute_allocate_resource(&dev->link[0], resource,
+ BRIDGE_IO_MASK, resource->flags & BRIDGE_IO_MASK);
+
+ resource->flags |= IORESOURCE_STORED;
+ report_resource_stored(dev, resource, "");
+
+ if ((resource->flags & IORESOURCE_MEM) &&
+ (pci_tolm > resource->base))
+ {
+ pci_tolm = resource->base;
+ }
+ }
- dev = dev_find_slot(0, 0);
- if (!dev) {
- printk_err("Cannot find PCI: 0:0\n");
- return 0;
- }
- mem[0].basek = 0;
- mem[0].sizek = 65536;
-#if 0
- idx = 1;
- while(idx < sizeof(mem)/sizeof(mem[0])) {
- mem[idx].basek = 0;
- mem[idx].sizek = 0;
- idx++;
- }
- for(rambits = 0, i = 0; i < sizeof(ramregs)/sizeof(ramregs[0]); i++) {
- unsigned char reg;
- reg = pci_read_config8(dev, ramregs[i]);
- /* these are ENDING addresses, not sizes.
- * if there is memory in this slot, then reg will be > rambits.
- * So we just take the max, that gives us total.
- * We take the highest one to cover for once and future linuxbios
- * bugs. We warn about bugs.
- */
- if (reg > rambits)
- rambits = reg;
- if (reg < rambits)
- printk_err("ERROR! register 0x%x is not set!\n",
- ramregs[i]);
- }
- printk_debug("I would set ram size to 0x%x Kbytes\n", (rambits)*8*1024);
- mem[0].sizek = rambits*8*1024;
-#endif
-#if 1
- for(i = 0; i < idx; i++) {
- printk_debug("mem[%d].basek = %08x mem[%d].sizek = %08x\n",
- i, mem[i].basek, i, mem[i].sizek);
+ mc_dev = dev->link[0].children;
+ if (mc_dev) {
+ unsigned long tomk, tolmk;
+ /* Hard code the Top of memory for now */
+ tomk = 65536;
+ /* Compute the top of Low memory */
+ tolmk = pci_tolm >> 10;
+ if (tolmk >= tomk) {
+ /* The PCI hole does not overlap memory.
+ */
+ tolmk = tomk;
+ }
+
+ /* Report the memory regions */
+ idx = 10;
+ ram_resource(dev, idx++, 0, 640);
+ ram_resource(dev, idx++, 768, tolmk - 768);
+ if (tomk > 4*1024*1024) {
+ ram_resource(dev, idx++, 4096*1024, tomk - 4*1024*1024);
+ }
}
-#endif
+ assign_resources(&dev->link[0]);
+}
+
+static unsigned int pci_domain_scan_bus(device_t dev, unsigned int max)
+{
+ max = pci_scan_bus(&dev->link[0], PCI_DEVFN(0, 0), 0xff, max);
+ return max;
+}
+
+static struct device_operations pci_domain_ops = {
+ .read_resources = pci_domain_read_resources,
+ .set_resources = pci_domain_set_resources,
+ .enable_resources = enable_childrens_resources,
+ .init = 0,
+ .scan_bus = pci_domain_scan_bus,
+};
+
+static void enable_dev(struct device *dev)
+{
+ struct device_path path;
- return mem;
+ /* Set the operations if it is a special bus type */
+ if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
+ dev->ops = &pci_domain_ops;
+ }
}
struct chip_operations northbridge_emulation_qemu_i386_control = {
.name = "QEMU Northbridge",
+ .enable_dev = enable_dev,
};
diff --git a/src/northbridge/intel/e7501/northbridge.c b/src/northbridge/intel/e7501/northbridge.c
index 098ad5312a..065ea54f8a 100644
--- a/src/northbridge/intel/e7501/northbridge.c
+++ b/src/northbridge/intel/e7501/northbridge.c
@@ -1,8 +1,6 @@
#include <console/console.h>
#include <arch/io.h>
#include <stdint.h>
-#include <mem.h>
-#include <part/sizeram.h>
#include <device/device.h>
#include <device/pci.h>
#include <stdlib.h>
@@ -172,7 +170,7 @@ static struct device_operations cpu_bus_ops = {
.set_resources = cpu_bus_noop,
.enable_resources = cpu_bus_noop,
.init = cpu_bus_init,
- .scan_bus = cpu_bus_noop,
+ .scan_bus = 0,
};
static void enable_dev(struct device *dev)
diff --git a/src/northbridge/intel/i855pm/northbridge.c b/src/northbridge/intel/i855pm/northbridge.c
index b43a853eee..38a0a4a196 100644
--- a/src/northbridge/intel/i855pm/northbridge.c
+++ b/src/northbridge/intel/i855pm/northbridge.c
@@ -1,8 +1,6 @@
#include <console/console.h>
#include <arch/io.h>
#include <stdint.h>
-#include <mem.h>
-#include <part/sizeram.h>
#include <device/device.h>
#include <device/pci.h>
#include <stdlib.h>
@@ -10,110 +8,152 @@
#include <bitops.h>
#include "chip.h"
-struct mem_range *sizeram(void)
+#define BRIDGE_IO_MASK (IORESOURCE_IO | IORESOURCE_MEM)
+
+static void pci_domain_read_resources(device_t dev)
+{
+ struct resource *resource;
+ unsigned reg;
+
+ /* Initialize the system wide io space constraints */
+ resource = new_resource(dev, 0);
+ resource->base = 0x400;
+ resource->limit = 0xffffUL;
+ resource->flags = IORESOURCE_IO;
+ compute_allocate_resource(&dev->link[0], resource,
+ IORESOURCE_IO, IORESOURCE_IO);
+
+ /* Initialize the system wide memory resources constraints */
+ resource = new_resource(dev, 1);
+ resource->limit = 0xffffffffULL;
+ resource->flags = IORESOURCE_MEM;
+ compute_allocate_resource(&dev->link[0], resource,
+ IORESOURCE_MEM, IORESOURCE_MEM);
+}
+
+static void ram_resource(device_t dev, unsigned long index,
+ unsigned long basek, unsigned long sizek)
+{
+ struct resource *resource;
+
+ if (!sizek) {
+ return;
+ }
+ resource = new_resource(dev, index);
+ resource->base = ((resource_t)basek) << 10;
+ resource->size = ((resource_t)sizek) << 10;
+ resource->flags = IORESOURCE_MEM | IORESOURCE_CACHEABLE | \
+ IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
+}
+
+static void pci_domain_set_resources(device_t dev)
{
- static struct mem_range mem[4];
- /* the units of tolm are 64 KB */
- /* the units of drb16 are 64 MB */
- uint16_t tolm, remapbase, remaplimit, drb16;
- uint16_t tolm_r, remapbase_r, remaplimit_r;
- uint8_t drb;
- int remap_high;
- device_t dev;
-
- dev = dev_find_slot(0, 0); // d0f0
- if (!dev) {
- printk_err("Cannot find PCI: 0:0\n");
- return 0;
+ struct resource *resource, *last;
+ device_t mc_dev;
+ uint32_t pci_tolm;
+
+ pci_tolm = 0xffffffffUL;
+ last = &dev->resource[dev->resources];
+ for(resource = &dev->resource[0]; resource < last; resource++)
+ {
+ compute_allocate_resource(&dev->link[0], resource,
+ BRIDGE_IO_MASK, resource->flags & BRIDGE_IO_MASK);
+
+ resource->flags |= IORESOURCE_STORED;
+ report_resource_stored(dev, resource, "");
+
+ if ((resource->flags & IORESOURCE_MEM) &&
+ (pci_tolm > resource->base))
+ {
+ pci_tolm = resource->base;
+ }
}
-
- /* Calculate and report the top of low memory and
- * any remapping.
- */
- /* Test if the remap memory high option is set */
- remap_high = 0;
-// if(get_option(&remap_high, "remap_memory_high")){
-// remap_high = 0;
-// }
- printk_debug("remap_high is %d\n", remap_high);
- /* get out the value of the highest DRB. This tells the end of
- * physical memory. The units are ticks of 64 MB i.e. 1 means
- * 64 MB.
- */
- drb = pci_read_config8(dev, 0x67);
- drb16 = (uint16_t)drb;
- if(remap_high && (drb16 > 0x08)) {
- /* We only come here if we have at least 512MB of memory,
- * so it is safe to hard code tolm.
- * 0x2000 means 512MB
+
+ mc_dev = dev->link[0].children;
+ if (mc_dev) {
+ /* Figure out which areas are/should be occupied by RAM.
+ * This is all computed in kilobytes and converted to/from
+ * the memory controller right at the edges.
+ * Having different variables in different units is
+ * too confusing to get right. Kilobytes are good up to
+ * 4 Terabytes of RAM...
*/
+ uint16_t tolm_r;
+ unsigned long tomk, tolmk;
+ int idx;
- tolm = 0x2000;
- /* i.e 0x40 * 0x40 is 0x1000 which is 4 GB */
- if(drb16 > 0x0040) {
- /* There is more than 4GB of memory put
- * the remap window at the end of ram.
+ /* Get the value of the highest DRB. This tells the end of
+ * the physical memory. The units are ticks of 32MB
+ * i.e. 1 means 32MB.
+ */
+ tomk = ((unsigned long)pci_read_config8(mc_dev, 0x63)) << 15;
+ /* Compute the top of Low memory */
+ tolmk = pci_tolm >> 10;
+ if (tolmk >= tomk) {
+ /* The PCI hole does does not overlap the memory.
*/
- remapbase = drb16;
- remaplimit = remapbase + 0x38;
- }
- else {
- remapbase = 0x0040;
- remaplimit = remapbase + (drb16-8);
- }
- }
- else {
- tolm = (uint16_t)((dev_root.resource[1].base >> 16)&0x0f800);
- if((tolm>>8) >= (drb16<<2)) {
- tolm = (drb16<<10);
- remapbase = 0x3ff;
- remaplimit = 0;
- }
- else {
- remapbase = drb16;
- remaplimit = remapbase + ((0x0040-(tolm>>10))-1);
+ tolmk = tomk;
}
- }
- /* Write the ram configruation registers,
- * preserving the reserved bits.
- */
- tolm_r = pci_read_config16(dev, 0xc4);
- tolm |= (tolm_r & 0x7ff);
- pci_write_config16(dev, 0xc4, tolm);
- remapbase_r = pci_read_config16(dev, 0xc6);
- remapbase |= (remapbase_r & 0xfc00);
- pci_write_config16(dev, 0xc6, remapbase);
- remaplimit_r = pci_read_config16(dev, 0xc8);
- remaplimit |= (remaplimit_r & 0xfc00);
- pci_write_config16(dev, 0xc8, remaplimit);
-
-#if 0
- printk_debug("mem info tolm = %x, drb = %x, pci_memory_base = %x, remap = %x-%x\n",tolm,drb,pci_memory_base,remapbase,remaplimit);
-#endif
-
- mem[0].basek = 0;
- mem[0].sizek = 640;
- mem[1].basek = 768;
- /* Convert size in 64K bytes to size in K bytes */
- mem[1].sizek = (tolm << 6) - mem[1].basek;
- mem[2].basek = 0;
- mem[2].sizek = 0;
- if ((drb << 16) > (tolm << 6)) {
- /* We don't need to consider the remap window
- * here because we put it immediately after the
- * rest of ram.
- * All we must do is calculate the amount
- * of unused memory and report it at 4GB.
+ /* Write the ram configuration registers,
+ * preserving the reserved bits.
*/
- mem[2].basek = 4096*1024;
- mem[2].sizek = (drb << 16) - (tolm << 6);
+ tolm_r = pci_read_config16(mc_dev, 0xc4);
+ tolm_r = ((tolmk >> 10) << 3) | (tolm_r & 0xf);
+ pci_write_config16(mc_dev, 0xc4, tolm_r);
+
+ /* Report the memory regions */
+ idx = 10;
+ ram_resource(dev, idx++, 0, 640);
+ ram_resource(dev, idx++, 768, tolmk - 768);
}
- mem[3].basek = 0;
- mem[3].sizek = 0;
-
- return mem;
+ assign_resources(&dev->link[0]);
+}
+
+static unsigned int pci_domain_scan_bus(device_t dev, unsigned int max)
+{
+ max = pci_scan_bus(&dev->link[0], PCI_DEVFN(0, 0), 0xff, max);
+ return max;
+}
+
+static struct device_operations pci_domain_ops = {
+ .read_resources = pci_domain_read_resources,
+ .set_resources = pci_domain_set_resources,
+ .enable_resources = enable_childrens_resources,
+ .init = 0,
+ .scan_bus = pci_domain_scan_bus,
+};
+
+static void cpu_bus_init(device_t dev)
+{
+ initialize_cpus(&dev->link[0]);
+}
+
+static void cpu_bus_noop(device_t dev)
+{
+}
+
+static struct device_operations cpu_bus_ops = {
+ .read_resources = cpu_bus_noop,
+ .set_resources = cpu_bus_noop,
+ .enable_resources = cpu_bus_noop,
+ .init = cpu_bus_init,
+ .scan_bus = 0,
+};
+
+static void enable_dev(struct device *dev)
+{
+ struct device_path path;
+
+ /* Set the operations if it is a special bus type */
+ if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
+ dev->ops = &pci_domain_ops;
+ }
+ else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) {
+ dev->ops = &cpu_bus_ops;
+ }
}
struct chip_operations northbridge_intel_i855pm_control = {
- .name = "intel i855pm Northbridge",
+ .name = "intel i855pm Northbridge",
+ .enable_dev = enable_dev,
};
diff --git a/src/northbridge/motorola/mpc107/mpc107.c b/src/northbridge/motorola/mpc107/mpc107.c
index 8fdc8a9c14..e7e75b9af5 100644
--- a/src/northbridge/motorola/mpc107/mpc107.c
+++ b/src/northbridge/motorola/mpc107/mpc107.c
@@ -314,272 +314,272 @@ mpc107_init(void)
unsigned long
mpc107_config_memory(int no_banks, sdram_bank_info * bank, int for_real)
{
- int i, j;
- char ignore[8];
- /* Convert bus clock to cycle time in 100ns units */
- unsigned cycle_time = 10 * (2500000000U / get_timer_freq());
- /* Approximate */
- unsigned access_time = cycle_time - 300;
- unsigned cas_latency = 0;
- unsigned rdlat;
- unsigned refint;
- unsigned refrec;
- unsigned acttorw, acttopre;
- unsigned pretoact, bstopre;
- enum sdram_error_detect error_detect;
- uint32_t mccr1;
- uint32_t mccr2;
- uint32_t mccr3;
- uint32_t mccr4;
- uint8_t bank_enable;
- uint32_t memstart1, memstart2;
- uint32_t extmemstart1, extmemstart2;
- uint32_t memend1, memend2;
- uint32_t extmemend1, extmemend2;
- uint32_t address;
-
- /* Set up the ignore mask */
- for(i = 0; i < no_banks; i++)
- ignore[i] = (bank[i].size == 0);
+ int i, j;
+ char ignore[8];
+ /* Convert bus clock to cycle time in 100ns units */
+ unsigned cycle_time = 10 * (2500000000U / get_timer_freq());
+ /* Approximate */
+ unsigned access_time = cycle_time - 300;
+ unsigned cas_latency = 0;
+ unsigned rdlat;
+ unsigned refint;
+ unsigned refrec;
+ unsigned acttorw, acttopre;
+ unsigned pretoact, bstopre;
+ enum sdram_error_detect error_detect;
+ uint32_t mccr1;
+ uint32_t mccr2;
+ uint32_t mccr3;
+ uint32_t mccr4;
+ uint8_t bank_enable;
+ uint32_t memstart1, memstart2;
+ uint32_t extmemstart1, extmemstart2;
+ uint32_t memend1, memend2;
+ uint32_t extmemend1, extmemend2;
+ uint32_t address;
+
+ /* Set up the ignore mask */
+ for(i = 0; i < no_banks; i++)
+ ignore[i] = (bank[i].size == 0);
- /* Pick best CAS latency possible */
- for (i = 0; i < no_banks; i++)
- {
- if (! ignore[i])
- {
- for (j = 0; j < 3; j++)
- {
- if (cycle_time >= bank[i].cycle_time[j] &&
- access_time >= bank[i].access_time[j])
+ /* Pick best CAS latency possible */
+ for (i = 0; i < no_banks; i++)
+ {
+ if (! ignore[i])
{
- cas_latency = bank[i].cas_latency[j];
- break;
+ for (j = 0; j < 3; j++)
+ {
+ if (cycle_time >= bank[i].cycle_time[j] &&
+ access_time >= bank[i].access_time[j])
+ {
+ cas_latency = bank[i].cas_latency[j];
+ break;
+ }
+ }
}
- }
}
- }
- if (!cas_latency)
- return 0;
+ if (!cas_latency)
+ return 0;
- /* For various parameters there is a risk of clashing between banks */
- error_detect = (for_real > 1) ? ERRORS_ECC : ERRORS_NONE;
- for (i = 0; i < no_banks; i++)
- {
- if (! ignore[i])
+ /* For various parameters there is a risk of clashing between banks */
+ error_detect = (for_real > 1) ? ERRORS_ECC : ERRORS_NONE;
+ for (i = 0; i < no_banks; i++)
{
- {
- for (j = 0; j < 3; j++)
- if (bank[i].cas_latency[j] == cas_latency)
- break;
- if (j == 3)
- {
- ignore[i] = 1;
- if (! for_real)
- printk_info("Disabling memory bank %d (cas latency)\n", i);
+ if (! ignore[i])
+ {
+ {
+ for (j = 0; j < 3; j++)
+ if (bank[i].cas_latency[j] == cas_latency)
+ break;
+ if (j == 3)
+ {
+ ignore[i] = 1;
+ if (! for_real)
+ printk_info("Disabling memory bank %d (cas latency)\n", i);
+ }
+ if (bank[i].error_detect < error_detect)
+ error_detect = bank[i].error_detect;
+ }
}
- if (bank[i].error_detect < error_detect)
- error_detect = bank[i].error_detect;
- }
- }
- }
-
- /* Read in configuration of port X */
- mccr1 = pci_ppc_read_config32(0, 0, 0xf0);
- mccr2 = pci_ppc_read_config32(0, 0, 0xf4);
- mccr4 = pci_ppc_read_config32(0, 0, 0xfc);
- mccr1 &= 0xfff00000;
- mccr2 &= 0xffe00000;
- mccr3 = 0;
- mccr4 &= 0x00230000;
-
- pretoact = 0;
- acttorw = 0;
- acttopre = 0;
- for (i = 0; i < no_banks; i++)
- if (! ignore[i])
- {
- int rowcode = -1;
- if (for_real)
- {
- bank[i].actual_detect = error_detect;
- bank[i].actual_cas = cas_latency;
}
+
+ /* Read in configuration of port X */
+ mccr1 = pci_ppc_read_config32(0, 0, 0xf0);
+ mccr2 = pci_ppc_read_config32(0, 0, 0xf4);
+ mccr4 = pci_ppc_read_config32(0, 0, 0xfc);
+ mccr1 &= 0xfff00000;
+ mccr2 &= 0xffe00000;
+ mccr3 = 0;
+ mccr4 &= 0x00230000;
+
+ pretoact = 0;
+ acttorw = 0;
+ acttopre = 0;
+ for (i = 0; i < no_banks; i++)
+ if (! ignore[i])
+ {
+ int rowcode = -1;
+ if (for_real)
+ {
+ bank[i].actual_detect = error_detect;
+ bank[i].actual_cas = cas_latency;
+ }
- switch (bank[i].row_bits) {
- case 13:
- if (bank[i].internal_banks == 4)
- rowcode = 2;
- else if (bank[i].internal_banks == 2)
- rowcode = 1;
- break;
- case 12:
- if (bank[i].internal_banks == 4)
- rowcode = 0;
- else if (bank[i].internal_banks == 2)
- rowcode = 1;
- break;
- case 11:
- if (bank[i].internal_banks == 4)
- rowcode = 0;
- else if (bank[i].internal_banks == 2)
- rowcode = 3;
- break;
+ switch (bank[i].row_bits) {
+ case 13:
+ if (bank[i].internal_banks == 4)
+ rowcode = 2;
+ else if (bank[i].internal_banks == 2)
+ rowcode = 1;
+ break;
+ case 12:
+ if (bank[i].internal_banks == 4)
+ rowcode = 0;
+ else if (bank[i].internal_banks == 2)
+ rowcode = 1;
+ break;
+ case 11:
+ if (bank[i].internal_banks == 4)
+ rowcode = 0;
+ else if (bank[i].internal_banks == 2)
+ rowcode = 3;
+ break;
+ }
+ if (rowcode == -1) {
+ ignore[i] = 1;
+ if (! for_real)
+ printk_info("Memory bank %d disabled: row bits %d and banks %d not supported\n", i, bank[i].row_bits, bank[i].internal_banks);
+ } else
+ mccr1 |= rowcode << (2 * i);
+
+ /* Update worst case settings */
+ if (! ignore[i]) {
+ if (bank[i].min_row_precharge > pretoact)
+ pretoact = bank[i].min_row_precharge;
+ if (bank[i].min_ras_to_cas > acttorw)
+ acttorw = bank[i].min_ras_to_cas;
+ if (bank[i].min_ras > acttopre)
+ acttopre = bank[i].min_ras;
+ }
+ }
+
+ /* Now convert to clock cycles, rounding up */
+ pretoact = (100 * pretoact + cycle_time - 1) / cycle_time;
+ acttopre = (100 * acttopre + cycle_time - 1) / cycle_time;
+ acttorw = (100 * acttorw + cycle_time - 1) / cycle_time;
+ refrec = acttopre;
+ bstopre = 0x240; /* Set conservative values, because we can't derive */
+ refint = 1000;
+
+ if (error_detect == ERRORS_ECC)
+ {
+ rdlat = cas_latency + 2;
+ mccr4 |= 0x00400000;
+ mccr2 |= 0x000c0001;
}
- if (rowcode == -1) {
- ignore[i] = 1;
- if (! for_real)
- printk_info("Memory bank %d disabled: row bits %d and banks %d not supported\n", i, bank[i].row_bits, bank[i].internal_banks);
- } else
- mccr1 |= rowcode << (2 * i);
-
- /* Update worst case settings */
- if (! ignore[i]) {
- if (bank[i].min_row_precharge > pretoact)
- pretoact = bank[i].min_row_precharge;
- if (bank[i].min_ras_to_cas > acttorw)
- acttorw = bank[i].min_ras_to_cas;
- if (bank[i].min_ras > acttopre)
- acttopre = bank[i].min_ras;
+ else
+ {
+ rdlat = cas_latency + 1;
+ mccr4 |= 0x00100000;
}
- }
-
- /* Now convert to clock cycles, rounding up */
- pretoact = (100 * pretoact + cycle_time - 1) / cycle_time;
- acttopre = (100 * acttopre + cycle_time - 1) / cycle_time;
- acttorw = (100 * acttorw + cycle_time - 1) / cycle_time;
- refrec = acttopre;
- bstopre = 0x240; /* Set conservative values, because we can't derive */
- refint = 1000;
-
- if (error_detect == ERRORS_ECC)
- {
- rdlat = cas_latency + 2;
- mccr4 |= 0x00400000;
- mccr2 |= 0x000c0001;
- }
- else
- {
- rdlat = cas_latency + 1;
- mccr4 |= 0x00100000;
- }
- if (pretoact > 16 || acttopre > 16 || acttorw > 16)
- if (! for_real)
- printk_info("Timings out of range\n");
- mccr4 |= ((pretoact & 0x0f) << 28) | ((acttopre & 0xf) << 24) |
- ((acttorw & 0x0f) << 4) |
- ((bstopre & 0x003) << 18) | ((bstopre & 0x3c0) >> 6) |
- (cas_latency << 12) | 0x00000200 /* burst length */ ;
- mccr3 |= ((bstopre & 0x03c) << 26) |
- ((refrec & 0x0f) << 24) | (rdlat << 20);
- mccr2 |= refint << 2;
- mccr1 |= 0x00080000; /* memgo */
-
- address = 0;
- memstart1 = memstart2 = 0;
- extmemstart1 = extmemstart2 = 0;
- memend1 = memend2 = 0;
- extmemend1 = extmemend2 = 0;
- bank_enable = 0;
- for (i = 0; i < no_banks; i++) {
- if (! ignore[i]) {
- uint32_t end = address + bank[i].size - 1;
- bank_enable |= 1 << i;
- if (i < 4) {
- memstart1 |= ((address >> 20) & 0xff) << (8 * i);
- extmemstart1 |= ((address >> 28) & 0x03) << (8 * i);
- memend1 |= ((end >> 20) & 0xff) << (8 * i);
- extmemend1 |= ((end >> 28) & 0x03) << (8 * i);
- } else {
- int k = i - 4;
- memstart2 |= ((address >> 20) & 0xff) << (8 * k);
- extmemstart2 |= ((address >> 28) & 0x03) << (8 * k);
- memend2 |= ((end >> 20) & 0xff) << (8 * k);
- extmemend2 |= ((end >> 28) & 0x03) << (8 * k);
- }
- address += bank[i].size;
+ if (pretoact > 16 || acttopre > 16 || acttorw > 16)
+ if (! for_real)
+ printk_info("Timings out of range\n");
+ mccr4 |= ((pretoact & 0x0f) << 28) | ((acttopre & 0xf) << 24) |
+ ((acttorw & 0x0f) << 4) |
+ ((bstopre & 0x003) << 18) | ((bstopre & 0x3c0) >> 6) |
+ (cas_latency << 12) | 0x00000200 /* burst length */ ;
+ mccr3 |= ((bstopre & 0x03c) << 26) |
+ ((refrec & 0x0f) << 24) | (rdlat << 20);
+ mccr2 |= refint << 2;
+ mccr1 |= 0x00080000; /* memgo */
+
+ address = 0;
+ memstart1 = memstart2 = 0;
+ extmemstart1 = extmemstart2 = 0;
+ memend1 = memend2 = 0;
+ extmemend1 = extmemend2 = 0;
+ bank_enable = 0;
+ for (i = 0; i < no_banks; i++) {
+ if (! ignore[i]) {
+ uint32_t end = address + bank[i].size - 1;
+ bank_enable |= 1 << i;
+ if (i < 4) {
+ memstart1 |= ((address >> 20) & 0xff) << (8 * i);
+ extmemstart1 |= ((address >> 28) & 0x03) << (8 * i);
+ memend1 |= ((end >> 20) & 0xff) << (8 * i);
+ extmemend1 |= ((end >> 28) & 0x03) << (8 * i);
+ } else {
+ int k = i - 4;
+ memstart2 |= ((address >> 20) & 0xff) << (8 * k);
+ extmemstart2 |= ((address >> 28) & 0x03) << (8 * k);
+ memend2 |= ((end >> 20) & 0xff) << (8 * k);
+ extmemend2 |= ((end >> 28) & 0x03) << (8 * k);
+ }
+ address += bank[i].size;
+ }
}
- }
-
- if (for_real)
- {
- /*
- * Mask MEMGO bit before setting MCCR1
- */
- mccr1 &= ~0x80000;
- printk_info("MCCR1 = 0x%08x\n", mccr1);
- pci_ppc_write_config32(0, 0, 0xf0, mccr1);
-
- printk_info("MBEN = 0x%02x\n", bank_enable);
- pci_ppc_write_config8(0, 0, 0xa0, bank_enable);
- printk_info("MSAR1 = 0x%08x\n", memstart1);
- pci_ppc_write_config32(0, 0, 0x80, memstart1);
- printk_info("MSAR2 = 0x%08x\n", memstart2);
- pci_ppc_write_config32(0, 0, 0x84, memstart2);
- printk_info("MSAR3 = 0x%08x\n", extmemstart1);
- pci_ppc_write_config32(0, 0, 0x88, extmemstart1);
- printk_info("MSAR4 = 0x%08x\n", extmemstart2);
- pci_ppc_write_config32(0, 0, 0x8c, extmemstart2);
- printk_info("MEAR1 = 0x%08x\n", memend1);
- pci_ppc_write_config32(0, 0, 0x90, memend1);
- printk_info("MEAR2 = 0x%08x\n", memend2);
- pci_ppc_write_config32(0, 0, 0x94, memend2);
- printk_info("MEAR3 = 0x%08x\n", extmemend1);
- pci_ppc_write_config32(0, 0, 0x98, extmemend1);
- printk_info("MEAR4 = 0x%08x\n", extmemend2);
- pci_ppc_write_config32(0, 0, 0x9c, extmemend2);
- printk_info("MCCR2 = 0x%08x\n", mccr2);
- pci_ppc_write_config32(0, 0, 0xf4, mccr2);
- printk_info("MCCR3 = 0x%08x\n", mccr3);
- pci_ppc_write_config32(0, 0, 0xf8, mccr3);
- printk_info("MCCR4 = 0x%08x\n", mccr4);
- pci_ppc_write_config32(0, 0, 0xfc, mccr4);
- udelay(200);
-
- /*
- * Set MEMGO bit
- */
- mccr1 |= 0x80000;
- printk_info("MCCR1 = 0x%08x\n", mccr1);
- pci_ppc_write_config32(0, 0, 0xf0, mccr1);
-
- udelay(10000);
- }
+ if (for_real)
+ {
+ /*
+ * Mask MEMGO bit before setting MCCR1
+ */
+ mccr1 &= ~0x80000;
+ printk_info("MCCR1 = 0x%08x\n", mccr1);
+ pci_ppc_write_config32(0, 0, 0xf0, mccr1);
+
+ printk_info("MBEN = 0x%02x\n", bank_enable);
+ pci_ppc_write_config8(0, 0, 0xa0, bank_enable);
+ printk_info("MSAR1 = 0x%08x\n", memstart1);
+ pci_ppc_write_config32(0, 0, 0x80, memstart1);
+ printk_info("MSAR2 = 0x%08x\n", memstart2);
+ pci_ppc_write_config32(0, 0, 0x84, memstart2);
+ printk_info("MSAR3 = 0x%08x\n", extmemstart1);
+ pci_ppc_write_config32(0, 0, 0x88, extmemstart1);
+ printk_info("MSAR4 = 0x%08x\n", extmemstart2);
+ pci_ppc_write_config32(0, 0, 0x8c, extmemstart2);
+ printk_info("MEAR1 = 0x%08x\n", memend1);
+ pci_ppc_write_config32(0, 0, 0x90, memend1);
+ printk_info("MEAR2 = 0x%08x\n", memend2);
+ pci_ppc_write_config32(0, 0, 0x94, memend2);
+ printk_info("MEAR3 = 0x%08x\n", extmemend1);
+ pci_ppc_write_config32(0, 0, 0x98, extmemend1);
+ printk_info("MEAR4 = 0x%08x\n", extmemend2);
+ pci_ppc_write_config32(0, 0, 0x9c, extmemend2);
+ printk_info("MCCR2 = 0x%08x\n", mccr2);
+ pci_ppc_write_config32(0, 0, 0xf4, mccr2);
+ printk_info("MCCR3 = 0x%08x\n", mccr3);
+ pci_ppc_write_config32(0, 0, 0xf8, mccr3);
+ printk_info("MCCR4 = 0x%08x\n", mccr4);
+ pci_ppc_write_config32(0, 0, 0xfc, mccr4);
+
+ udelay(200);
+
+ /*
+ * Set MEMGO bit
+ */
+ mccr1 |= 0x80000;
+ printk_info("MCCR1 = 0x%08x\n", mccr1);
+ pci_ppc_write_config32(0, 0, 0xf0, mccr1);
+
+ udelay(10000);
+ }
- return address;
+ return address;
}
static int
i2c_wait(unsigned timeout, int writing)
{
- uint32_t x;
- while (((x = readl(MPC107_BASE + MPC107_I2CSR)) & (MPC107_I2C_CSR_MCF | MPC107_I2C_CSR_MIF))
- != (MPC107_I2C_CSR_MCF | MPC107_I2C_CSR_MIF)) {
- if (ticks_since_boot() > timeout)
- return -1;
- }
-
- if (x & MPC107_I2C_CSR_MAL) {
- return -1;
- }
- if (writing && (x & MPC107_I2C_CSR_RXAK)) {
- printk_info("No RXAK\n");
- /* generate stop */
- writel(MPC107_I2C_CCR_MEN, MPC107_BASE + MPC107_I2CCR);
- return -1;
- }
- writel(0, MPC107_BASE + MPC107_I2CSR);
- return 0;
+ uint32_t x;
+ while (((x = readl(MPC107_BASE + MPC107_I2CSR)) & (MPC107_I2C_CSR_MCF | MPC107_I2C_CSR_MIF))
+ != (MPC107_I2C_CSR_MCF | MPC107_I2C_CSR_MIF)) {
+ if (ticks_since_boot() > timeout)
+ return -1;
+ }
+
+ if (x & MPC107_I2C_CSR_MAL) {
+ return -1;
+ }
+ if (writing && (x & MPC107_I2C_CSR_RXAK)) {
+ printk_info("No RXAK\n");
+ /* generate stop */
+ writel(MPC107_I2C_CCR_MEN, MPC107_BASE + MPC107_I2CCR);
+ return -1;
+ }
+ writel(0, MPC107_BASE + MPC107_I2CSR);
+ return 0;
}
static void
mpc107_i2c_start(struct i2c_bus *bus)
{
- /* Set clock */
- writel(0x1031, MPC107_BASE + MPC107_I2CFDR);
- /* Clear arbitration */
- writel(0, MPC107_BASE + MPC107_I2CSR);
+ /* Set clock */
+ writel(0x1031, MPC107_BASE + MPC107_I2CFDR);
+ /* Clear arbitration */
+ writel(0, MPC107_BASE + MPC107_I2CSR);
}
static void
@@ -680,27 +680,27 @@ mpc107_i2c_master_read(struct i2c_bus *bus, int target, int address,
count = 0;
while (count < length) {
- if (i2c_wait(timeout, 0) < 0)
- return -1;
-
- /* Generate txack on next to last byte */
- if (count == length - 2)
- writel(MPC107_I2C_CCR_MEN | MPC107_I2C_CCR_MSTA | MPC107_I2C_CCR_TXAK, MPC107_BASE + MPC107_I2CCR);
- /* Generate stop on last byte */
- if (count == length - 1)
- writel(MPC107_I2C_CCR_MEN | MPC107_I2C_CCR_TXAK, MPC107_BASE + MPC107_I2CCR);
- data[count] = readl(MPC107_BASE + MPC107_I2CDR);
- if (count == 0 && length == DIMM_LENGTH) {
- if (data[0] == 0xff) {
- printk_debug("I2C device not present\n");
- length = 3;
- } else {
- length = data[0];
- if (length < 3)
- length = 3;
+ if (i2c_wait(timeout, 0) < 0)
+ return -1;
+
+ /* Generate txack on next to last byte */
+ if (count == length - 2)
+ writel(MPC107_I2C_CCR_MEN | MPC107_I2C_CCR_MSTA | MPC107_I2C_CCR_TXAK, MPC107_BASE + MPC107_I2CCR);
+ /* Generate stop on last byte */
+ if (count == length - 1)
+ writel(MPC107_I2C_CCR_MEN | MPC107_I2C_CCR_TXAK, MPC107_BASE + MPC107_I2CCR);
+ data[count] = readl(MPC107_BASE + MPC107_I2CDR);
+ if (count == 0 && length == DIMM_LENGTH) {
+ if (data[0] == 0xff) {
+ printk_debug("I2C device not present\n");
+ length = 3;
+ } else {
+ length = data[0];
+ if (length < 3)
+ length = 3;
+ }
}
- }
- count++;
+ count++;
}
/* Finish with disable master */
@@ -709,8 +709,8 @@ mpc107_i2c_master_read(struct i2c_bus *bus, int target, int address,
}
i2c_fn mpc107_i2c_fn = {
- mpc107_i2c_start, mpc107_i2c_stop,
- mpc107_i2c_master_write, mpc107_i2c_master_read
+ mpc107_i2c_start, mpc107_i2c_stop,
+ mpc107_i2c_master_write, mpc107_i2c_master_read
};
/*
@@ -719,36 +719,36 @@ i2c_fn mpc107_i2c_fn = {
void
mpc107_probe_dimms(int no_dimms, sdram_dimm_info *dimms, sdram_bank_info * bank)
{
- unsigned char data[256];
- unsigned dimm;
-
- printk_debug("Probing DIMMS...\n");
-
- mpc107_i2c_start(NULL);
-
- for(dimm = 0; dimm < no_dimms; dimm++)
- {
- dimms[dimm].number = dimm;
- dimms[dimm].bank1 = bank + dimm*NUM_BANKS;
- dimms[dimm].bank2 = bank + dimm*NUM_BANKS + 1;
- bank[dimm*NUM_BANKS].size = 0;
- bank[dimm*NUM_BANKS+1].size = 0;
- bank[dimm*NUM_BANKS].number = 0;
- bank[dimm*NUM_BANKS+1].number = 1;
- }
-
-
- for (dimm = 0; dimm < no_dimms; dimm ++) {
- unsigned limit = mpc107_i2c_master_read(NULL, 0xa0 + 2*dimm, 0,
- data, DIMM_LENGTH);
-
- if (limit > 3) {
- sdram_dimm_to_bank_info(data, dimms + dimm, 1);
- memcpy(dimms[dimm].part_number, data + 73, 18);
- dimms[dimm].part_number[18] = 0;
- printk_debug("Part Number: %s\n", dimms[dimm].part_number);
+ unsigned char data[256];
+ unsigned dimm;
+
+ printk_debug("Probing DIMMS...\n");
+
+ mpc107_i2c_start(NULL);
+
+ for(dimm = 0; dimm < no_dimms; dimm++)
+ {
+ dimms[dimm].number = dimm;
+ dimms[dimm].bank1 = bank + dimm*NUM_BANKS;
+ dimms[dimm].bank2 = bank + dimm*NUM_BANKS + 1;
+ bank[dimm*NUM_BANKS].size = 0;
+ bank[dimm*NUM_BANKS+1].size = 0;
+ bank[dimm*NUM_BANKS].number = 0;
+ bank[dimm*NUM_BANKS+1].number = 1;
}
- }
-
- mpc107_i2c_stop(NULL);
+
+
+ for (dimm = 0; dimm < no_dimms; dimm ++) {
+ unsigned limit = mpc107_i2c_master_read(NULL, 0xa0 + 2*dimm, 0,
+ data, DIMM_LENGTH);
+
+ if (limit > 3) {
+ sdram_dimm_to_bank_info(data, dimms + dimm, 1);
+ memcpy(dimms[dimm].part_number, data + 73, 18);
+ dimms[dimm].part_number[18] = 0;
+ printk_debug("Part Number: %s\n", dimms[dimm].part_number);
+ }
+ }
+
+ mpc107_i2c_stop(NULL);
}
diff --git a/src/northbridge/transmeta/tm5800/northbridge.c b/src/northbridge/transmeta/tm5800/northbridge.c
index d3576a9143..107ebe2aed 100644
--- a/src/northbridge/transmeta/tm5800/northbridge.c
+++ b/src/northbridge/transmeta/tm5800/northbridge.c
@@ -1,8 +1,6 @@
#include <console/console.h>
#include <arch/io.h>
#include <stdint.h>
-#include <mem.h>
-#include <part/sizeram.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
@@ -13,111 +11,141 @@
#include "chip.h"
#include "northbridge.h"
-struct mem_range *sizeram(void)
+#define BRIDGE_IO_MASK (IORESOURCE_IO | IORESOURCE_MEM)
+
+static void pci_domain_read_resources(device_t dev)
{
- unsigned long mmio_basek;
- static struct mem_range mem[10];
- device_t dev;
- int i, idx;
-
-#warning "FIXME handle interleaved nodes"
- dev = dev_find_slot(0, PCI_DEVFN(0x18, 1));
- if (!dev) {
- printk_err("Cannot find PCI: 0:18.1\n");
- return 0;
- }
- mmio_basek = (dev_root.resource[1].base >> 10);
- /* Round mmio_basek to something the processor can support */
- mmio_basek &= ~((1 << 6) -1);
-
-#if 1
-#warning "FIXME improve mtrr.c so we don't use up all of the mtrrs with a 64M MMIO hole"
- /* Round the mmio hold to 256M */
- mmio_basek &= ~((256*1024) - 1);
-#endif
-
-#if 0
- printk_debug("mmio_base: %dKB\n", mmio_basek);
-#endif
-
- for (idx = i = 0; i < 8; i++) {
- uint32_t base, limit;
- unsigned basek, limitk, sizek;
- base = pci_read_config32(dev, 0x40 + (i<<3));
- limit = pci_read_config32(dev, 0x44 + (i<<3));
- if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
- continue;
- }
- basek = (base & 0xffff0000) >> 2;
- limitk = ((limit + 0x00010000) & 0xffff0000) >> 2;
- sizek = limitk - basek;
- if ((idx > 0) &&
- ((mem[idx - 1].basek + mem[idx - 1].sizek) == basek)) {
- mem[idx -1].sizek += sizek;
- } else {
- mem[idx].basek = basek;
- mem[idx].sizek = sizek;
- idx++;
- }
-
- /* see if we need a hole from 0xa0000 to 0xbffff */
- if ((mem[idx-1].basek < ((8*64)+(8*16))) /* 640 */ &&
- (mem[idx-1].sizek > ((8*64)+(16*16))) /* 768 */ ) {
-#warning "FIXME: this left 0xA0000 to 0xBFFFF undefined"
- mem[idx].basek = (8*64)+(16*16);
- mem[idx].sizek = mem[idx-1].sizek - ((8*64)+(16*16));
- mem[idx-1].sizek = ((8*64)+(8*16)) - mem[idx-1].basek;
- idx++;
- }
-
- /* See if I need to split the region to accomodate pci memory space */
- if ((mem[idx - 1].basek <= mmio_basek) &&
- ((mem[idx - 1].basek + mem[idx - 1].sizek) > mmio_basek)) {
- if (mem[idx - 1].basek < mmio_basek) {
- unsigned pre_sizek;
- pre_sizek = mmio_basek - mem[idx - 1].basek;
- mem[idx].basek = mmio_basek;
- mem[idx].sizek = mem[idx - 1].sizek - pre_sizek;
- mem[idx - 1].sizek = pre_sizek;
- idx++;
- }
- if ((mem[idx - 1].basek + mem[idx - 1].sizek) <= 4*1024*1024) {
- idx -= 1;
- } else {
- mem[idx - 1].basek = 4*1024*1024;
- mem[idx - 1].sizek -= (4*1024*1024 - mmio_basek);
- }
+ struct resource *resource;
+ unsigned reg;
+
+ /* Initialize the system wide io space constraints */
+ resource = new_resource(dev, 0);
+ resource->base = 0x400;
+ resource->limit = 0xffffUL;
+ resource->flags = IORESOURCE_IO;
+ compute_allocate_resource(&dev->link[0], resource,
+ IORESOURCE_IO, IORESOURCE_IO);
+
+ /* Initialize the system wide memory resources constraints */
+ resource = new_resource(dev, 1);
+ resource->limit = 0xffffffffULL;
+ resource->flags = IORESOURCE_MEM;
+ compute_allocate_resource(&dev->link[0], resource,
+ IORESOURCE_MEM, IORESOURCE_MEM);
+}
+
+static void ram_resource(device_t dev, unsigned long index,
+ unsigned long basek, unsigned long sizek)
+{
+ struct resource *resource;
+
+ if (!sizek) {
+ return;
+ }
+ resource = new_resource(dev, index);
+ resource->base = ((resource_t)basek) << 10;
+ resource->size = ((resource_t)sizek) << 10;
+ resource->flags = IORESOURCE_MEM | IORESOURCE_CACHEABLE | \
+ IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
+}
+
+static void pci_domain_set_resources(device_t dev)
+{
+ struct resource *resource, *last;
+ device_t mc_dev;
+ uint32_t pci_tolm;
+
+ pci_tolm = 0xffffffffUL;
+ last = &dev->resource[dev->resources];
+ for(resource = &dev->resource[0]; resource < last; resource++)
+ {
+ compute_allocate_resource(&dev->link[0], resource,
+ BRIDGE_IO_MASK, resource->flags & BRIDGE_IO_MASK);
+
+ resource->flags |= IORESOURCE_STORED;
+ report_resource_stored(dev, resource, "");
+
+ if ((resource->flags & IORESOURCE_MEM) &&
+ (pci_tolm > resource->base))
+ {
+ pci_tolm = resource->base;
+ }
+ }
+
+ mc_dev = dev->link[0].children;
+ if (mc_dev) {
+ /* Figure out which areas are/should be occupied by RAM.
+ * This is all computed in kilobytes and converted to/from
+ * the memory controller right at the edges.
+ * Having different variables in different units is
+ * too confusing to get right. Kilobytes are good up to
+ * 4 Terabytes of RAM...
+ */
+ unsigned long tomk, tolmk;
+ int idx;
+
+#warning "This is hardcoded to 1MiB of RAM for now"
+ tomk = 1024;
+ /* Compute the top of Low memory */
+ tolmk = pci_tolm >> 10;
+ if (tolmk >= tomk) {
+ /* The PCI hole does does not overlap the memory.
+ */
+ tolmk = tomk;
}
+ /* Report the memory regions */
+ idx = 10;
+ ram_resource(dev, idx++, 0, 640);
+ ram_resource(dev, idx++, 768, tolmk - 768);
}
-#if 1
- for (i = 0; i < idx; i++) {
- printk_debug("mem[%d].basek = %08x mem[%d].sizek = %08x\n",
- i, mem[i].basek, i, mem[i].sizek);
- }
-#endif
- while (idx < sizeof(mem)/sizeof(mem[0])) {
- mem[idx].basek = 0;
- mem[idx].sizek = 0;
- idx++;
- }
- return mem;
+ assign_resources(&dev->link[0]);
}
-static struct device_operations northbridge_operations = {
- .read_resources = tm5800_read_resources,
- .set_resources = tm5800_set_resources,
- .enable_resources = tm5800_enable_resources,
- .init = mcf0_control_init,
- .scan_bus = tm5800_scan_chains,
- .enable = 0,
-};
+static unsigned int pci_domain_scan_bus(device_t dev, unsigned int max)
+{
+ max = pci_scan_bus(&dev->link[0], PCI_DEVFN(0, 0), 0xff, max);
+ return max;
+}
+
+static struct device_operations pci_domain_ops = {
+ .read_resources = pci_domain_read_resources,
+ .set_resources = pci_domain_set_resources,
+ .enable_resources = enable_childrens_resources,
+ .init = 0,
+ .scan_bus = pci_domain_scan_bus,
+};
-static struct pci_driver mcf0_driver __pci_driver = {
- .ops = &northbridge_operations,
- .vendor = PCI_VENDOR_ID_AMD,
- .device = 0x1100,
+static void cpu_bus_init(device_t dev)
+{
+ initialize_cpus(&dev->link[0]);
+}
+
+static void cpu_bus_noop(device_t dev)
+{
+}
+
+static struct device_operations cpu_bus_ops = {
+ .read_resources = cpu_bus_noop,
+ .set_resources = cpu_bus_noop,
+ .enable_resources = cpu_bus_noop,
+ .init = cpu_bus_init,
+ .scan_bus = 0,
};
-struct chip_operations northbridge_amd_tm5800_control = {
- .name = "Transmeta tm5800 Northbridge",
+static void enable_dev(struct device *dev)
+{
+ struct device_path path;
+
+ /* Set the operations if it is a special bus type */
+ if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
+ dev->ops = &pci_domain_ops;
+ }
+ else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) {
+ dev->ops = &cpu_bus_ops;
+ }
+}
+
+struct chip_operations northbridge_transmeta_tm5800_control = {
+ .name = "Transmeta tm5800 Northbridge",
+ .enable_dev = enable_dev,
};
diff --git a/src/northbridge/via/vt8601/northbridge.c b/src/northbridge/via/vt8601/northbridge.c
index bd3018625e..fd6b6eb916 100644
--- a/src/northbridge/via/vt8601/northbridge.c
+++ b/src/northbridge/via/vt8601/northbridge.c
@@ -1,8 +1,6 @@
#include <console/console.h>
#include <arch/io.h>
#include <stdint.h>
-#include <mem.h>
-#include <part/sizeram.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/hypertransport.h>
@@ -12,103 +10,189 @@
#include "chip.h"
#include "northbridge.h"
+/*
+ * This fixup is based on capturing values from an Award bios. Without
+ * this fixup the DMA write performance is awful (i.e. hdparm -t /dev/hda is 20x
+ * slower than normal, ethernet drops packets).
+ * Apparently these registers govern some sort of bus master behavior.
+ */
+static void northbridge_init(device_t dev)
+{
+ printk_spew("VT8601 random fixup ...\n");
+ pci_write_config8(dev, 0x70, 0xc0);
+ pci_write_config8(dev, 0x71, 0x88);
+ pci_write_config8(dev, 0x72, 0xec);
+ pci_write_config8(dev, 0x73, 0x0c);
+ pci_write_config8(dev, 0x74, 0x0e);
+ pci_write_config8(dev, 0x75, 0x81);
+ pci_write_config8(dev, 0x76, 0x52);
+}
+
+
+
+static struct device_operations northbridge_operations = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = northbridge_init,
+ .enable = 0,
+ .ops_pci = 0,
+};
+
+static struct pci_driver northbridge_driver __pci_driver = {
+ .ops = &northbridge_operations,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = 0x0601, /* 0x8601 is the AGP bridge? */
+};
+
+
+
+#define BRIDGE_IO_MASK (IORESOURCE_IO | IORESOURCE_MEM)
+
+static void pci_domain_read_resources(device_t dev)
+{
+ struct resource *resource;
+ unsigned reg;
+
+ /* Initialize the system wide io space constraints */
+ resource = new_resource(dev, 0);
+ resource->base = 0x400;
+ resource->limit = 0xffffUL;
+ resource->flags = IORESOURCE_IO;
+ compute_allocate_resource(&dev->link[0], resource,
+ IORESOURCE_IO, IORESOURCE_IO);
+
+ /* Initialize the system wide memory resources constraints */
+ resource = new_resource(dev, 1);
+ resource->limit = 0xffffffffULL;
+ resource->flags = IORESOURCE_MEM;
+ compute_allocate_resource(&dev->link[0], resource,
+ IORESOURCE_MEM, IORESOURCE_MEM);
+}
+
+static void ram_resource(device_t dev, unsigned long index,
+ unsigned long basek, unsigned long sizek)
+{
+ struct resource *resource;
+
+ if (!sizek) {
+ return;
+ }
+ resource = new_resource(dev, index);
+ resource->base = ((resource_t)basek) << 10;
+ resource->size = ((resource_t)sizek) << 10;
+ resource->flags = IORESOURCE_MEM | IORESOURCE_CACHEABLE | \
+ IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
+}
+
static const uint8_t ramregs[] = {0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x56, 0x57};
-struct mem_range *sizeram(void)
+static void pci_domain_set_resources(device_t dev)
{
- unsigned long mmio_basek;
- static struct mem_range mem[10];
- device_t dev;
- int i, idx;
- unsigned char rambits;
-
- dev = dev_find_slot(0, 0);
- if (!dev) {
- printk_err("Cannot find PCI: 0:0\n");
- return 0;
- }
- mem[0].basek = 0;
- mem[0].sizek = 65536;
- idx = 1;
- while(idx < sizeof(mem)/sizeof(mem[0])) {
- mem[idx].basek = 0;
- mem[idx].sizek = 0;
- idx++;
- }
- for(rambits = 0, i = 0; i < sizeof(ramregs)/sizeof(ramregs[0]); i++) {
- unsigned char reg;
- reg = pci_read_config8(dev, ramregs[i]);
- /* these are ENDING addresses, not sizes.
- * if there is memory in this slot, then reg will be > rambits.
- * So we just take the max, that gives us total.
- * We take the highest one to cover for once and future linuxbios
- * bugs. We warn about bugs.
- */
- if (reg > rambits)
- rambits = reg;
- if (reg < rambits)
- printk_err("ERROR! register 0x%x is not set!\n",
- ramregs[i]);
- }
-
- printk_debug("I would set ram size to 0x%x Kbytes\n", (rambits)*8*1024);
- mem[0].sizek = rambits*8*1024;
-#if 1
- for(i = 0; i < idx; i++) {
- printk_debug("mem[%d].basek = %08x mem[%d].sizek = %08x\n",
- i, mem[i].basek, i, mem[i].sizek);
+ struct resource *resource, *last;
+ device_t mc_dev;
+ uint32_t pci_tolm;
+
+ pci_tolm = 0xffffffffUL;
+ last = &dev->resource[dev->resources];
+ for(resource = &dev->resource[0]; resource < last; resource++)
+ {
+ compute_allocate_resource(&dev->link[0], resource,
+ BRIDGE_IO_MASK, resource->flags & BRIDGE_IO_MASK);
+
+ resource->flags |= IORESOURCE_STORED;
+ report_resource_stored(dev, resource, "");
+
+ if ((resource->flags & IORESOURCE_MEM) &&
+ (pci_tolm > resource->base))
+ {
+ pci_tolm = resource->base;
+ }
+ }
+
+ mc_dev = dev->link[0].children;
+ if (mc_dev) {
+ unsigned long tomk, tolmk;
+ unsigned char rambits;
+ int i, idx;
+
+ for(rambits = 0, i = 0; i < sizeof(ramregs)/sizeof(ramregs[0]); i++) {
+ unsigned char reg;
+ reg = pci_read_config8(mc_dev, ramregs[i]);
+ /* these are ENDING addresses, not sizes.
+ * if there is memory in this slot, then reg will be > rambits.
+ * So we just take the max, that gives us total.
+ * We take the highest one to cover for once and future linuxbios
+ * bugs. We warn about bugs.
+ */
+ if (reg > rambits)
+ rambits = reg;
+ if (reg < rambits)
+ printk_err("ERROR! register 0x%x is not set!\n",
+ ramregs[i]);
+ }
+ printk_debug("I would set ram size to 0x%x Kbytes\n", (rambits)*8*1024);
+ tomk = ramreg*8*1024;
+ /* Compute the top of Low memory */
+ tolmk = pci_tolm >> 10;
+ if (tolmk >= tomk) {
+ /* The PCI hole does does not overlap the memory.
+ */
+ tolmk = tomk;
+ }
+ /* Report the memory regions */
+ idx = 10;
+ ram_resource(dev, idx++, 0, tolmk);
}
-#endif
+ assign_resources(&dev->link[0]);
+}
- return mem;
+static unsigned int pci_domain_scan_bus(device_t dev, unsigned int max)
+{
+ max = pci_scan_bus(&dev->link[0], PCI_DEVFN(0, 0), 0xff, max);
+ return max;
}
-/*
- * This fixup is based on capturing values from an Award bios. Without
- * this fixup the DMA write performance is awful (i.e. hdparm -t /dev/hda is 20x
- * slower than normal, ethernet drops packets).
- * Apparently these registers govern some sort of bus master behavior.
- */
-static void random_fixup() {
- device_t pcidev = dev_find_slot(0, 0);
+static struct device_operations pci_domain_ops = {
+ .read_resources = pci_domain_read_resources,
+ .set_resources = pci_domain_set_resources,
+ .enable_resources = enable_childrens_resources,
+ .init = 0,
+ .scan_bus = pci_domain_scan_bus,
+};
- printk_spew("VT8601 random fixup ...\n");
- if (pcidev) {
- pci_write_config8(pcidev, 0x70, 0xc0);
- pci_write_config8(pcidev, 0x71, 0x88);
- pci_write_config8(pcidev, 0x72, 0xec);
- pci_write_config8(pcidev, 0x73, 0x0c);
- pci_write_config8(pcidev, 0x74, 0x0e);
- pci_write_config8(pcidev, 0x75, 0x81);
- pci_write_config8(pcidev, 0x76, 0x52);
- }
+static void cpu_bus_init(device_t dev)
+{
+ initialize_cpus(&dev->link[0]);
}
-static void northbridge_init(struct chip *chip, enum chip_pass pass)
+static void cpu_bus_noop(device_t dev)
{
+}
- struct northbridge_via_vt8601_config *conf =
- (struct northbridge_via_vt8601_config *)chip->chip_info;
-
- switch (pass) {
- case CONF_PASS_PRE_PCI:
- break;
-
- case CONF_PASS_POST_PCI:
- break;
-
- case CONF_PASS_PRE_BOOT:
- random_fixup();
- break;
-
- default:
- /* nothing yet */
- break;
- }
+static struct device_operations cpu_bus_ops = {
+ .read_resources = cpu_bus_noop,
+ .set_resources = cpu_bus_noop,
+ .enable_resources = cpu_bus_noop,
+ .init = cpu_bus_init,
+ .scan_bus = 0,
+};
+
+static void enable_dev(struct device *dev)
+{
+ struct device_path path;
+
+ /* Set the operations if it is a special bus type */
+ if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
+ dev->ops = &pci_domain_ops;
+ }
+ else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) {
+ dev->ops = &cpu_bus_ops;
+ }
}
struct chip_operations northbridge_via_vt8601_control = {
- .enable = northbridge_init,
+ .enable_dev = enable_dev,
.name = "VIA vt8601 Northbridge",
};
diff --git a/src/northbridge/via/vt8623/northbridge.c b/src/northbridge/via/vt8623/northbridge.c
index 2d53f23353..6597da2729 100644
--- a/src/northbridge/via/vt8623/northbridge.c
+++ b/src/northbridge/via/vt8623/northbridge.c
@@ -1,8 +1,6 @@
#include <console/console.h>
#include <arch/io.h>
#include <stdint.h>
-#include <mem.h>
-#include <part/sizeram.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/hypertransport.h>
@@ -14,151 +12,267 @@
#include "chip.h"
#include "northbridge.h"
-static const uint8_t ramregs[] = {0x5a, 0x5b, 0x5c, 0x5d };
-
-struct mem_range *sizeram(void)
-{
- unsigned long mmio_basek;
- static struct mem_range mem[10];
- device_t dev;
- int i, idx;
- unsigned char rambits;
-
- dev = dev_find_slot(0, 0);
- if (!dev) {
- printk_err("Cannot find PCI: 0:0\n");
- return 0;
- }
- mem[0].basek = 0;
- mem[0].sizek = 0xa0000 >>10; // first 640k
- mem[1].basek = 0xc0000 >>10; // leave a hole for vga
- idx = 2;
- while(idx < sizeof(mem)/sizeof(mem[0])) {
- mem[idx].basek = 0;
- mem[idx].sizek = 0;
- idx++;
- }
- for(rambits = 0, i = 0; i < sizeof(ramregs)/sizeof(ramregs[0]); i++) {
- unsigned char reg;
- reg = pci_read_config8(dev, ramregs[i]);
- /* these are ENDING addresses, not sizes.
- * if there is memory in this slot, then reg will be > rambits.
- * So we just take the max, that gives us total.
- * We take the highest one to cover for once and future linuxbios
- * bugs. We warn about bugs.
- */
- if (reg > rambits)
- rambits = reg;
- if (reg < rambits)
- printk_err("ERROR! register 0x%x is not set!\n",
- ramregs[i]);
- }
-
- printk_debug("I would set ram size to 0x%x Kbytes\n", (rambits)*16*1024);
- mem[1].sizek = rambits*16*1024 - 32768 - (0xc0000 >> 10);
-#if 1
- for(i = 0; i < idx; i++) {
- printk_debug("mem[%d].basek = %08x mem[%d].sizek = %08x\n",
- i, mem[i].basek, i, mem[i].sizek);
- }
-#endif
-
- return mem;
-}
-
/*
* This fixup is based on capturing values from an Award bios. Without
* this fixup the DMA write performance is awful (i.e. hdparm -t /dev/hda is 20x
* slower than normal, ethernet drops packets).
* Apparently these registers govern some sort of bus master behavior.
*/
-static void random_fixup() {
- device_t pcidev0 = dev_find_slot(0, 0);
- device_t pcidev1,pcidev2;
+static void norhbrige_init(device_t dev)
+{
+ device_t fb_dev;
unsigned long fb;
unsigned char c;
printk_debug("VT8623 random fixup ...\n");
- if (pcidev0) {
- pci_write_config8(pcidev0, 0x0d, 0x08);
- pci_write_config8(pcidev0, 0x70, 0x82);
- pci_write_config8(pcidev0, 0x71, 0xc8);
- pci_write_config8(pcidev0, 0x72, 0x0);
- pci_write_config8(pcidev0, 0x73, 0x01);
- pci_write_config8(pcidev0, 0x74, 0x01);
- pci_write_config8(pcidev0, 0x75, 0x08);
- pci_write_config8(pcidev0, 0x76, 0x52);
- pci_write_config8(pcidev0, 0x13, 0xd0);
- pci_write_config8(pcidev0, 0x84, 0x80);
- pci_write_config16(pcidev0,0x80, 0x610f);
- pci_write_config32(pcidev0,0x88, 0x02);
+ pci_write_config8(dev, 0x0d, 0x08);
+ pci_write_config8(dev, 0x70, 0x82);
+ pci_write_config8(dev, 0x71, 0xc8);
+ pci_write_config8(dev, 0x72, 0x00);
+ pci_write_config8(dev, 0x73, 0x01);
+ pci_write_config8(dev, 0x74, 0x01);
+ pci_write_config8(dev, 0x75, 0x08);
+ pci_write_config8(dev, 0x76, 0x52);
+ pci_write_config8(dev, 0x13, 0xd0);
+ pci_write_config8(dev, 0x84, 0x80);
+ pci_write_config16(dev, 0x80, 0x610f);
+ pci_write_config32(dev, 0x88, 0x00000002);
+
+ fb_dev = dev_find_device(PCI_VENDOR_ID_VIA, 0x3122, 0);
+ if (fb_dev) {
+ /* Fixup GART and framebuffer addresses properly.
+ * First setup frame buffer properly.
+ */
+ fb = pci_read_config32(dev, 0x10); /* Base addres of framebuffer */
+ printk_debug("Frame buffer at %8x\n",fb);
+
+ c = pci_read_config8(dev, 0xe1) & 0xf0; /* size of vga */
+ c |= fb>>28; /* upper nibble of frame buffer address */
+ pci_write_config8(dev, 0xe1, c);
+ c = (fb>>20) | 1; /* enable framebuffer */
+ pci_write_config8(dev, 0xe0, c);
+ pci_write_config8(dev, 0xe2, 0x42); /* 'cos award does */
}
+}
+
+
+static struct device_operations northbridge_operations = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = northbridge_init,
+ .scan_bus = pci_scan_bridge,
+ .ops_pci = 0,
+};
+
+static struct pci_driver northbridge_driver __pci_driver = {
+ .ops = &northbridge_ops,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = 0x3123,
+};
+
+static void agp_init(device_t dev)
+{
printk_debug("VT8623 AGP random fixup ...\n");
- pcidev1 = dev_find_device(PCI_VENDOR_ID_VIA,0xb091,0);
- if( pcidev1) {
- pci_write_config8(pcidev1,0x3e,0x0c);
- pci_write_config8(pcidev1,0x40,0x83);
- pci_write_config8(pcidev1,0x41,0xc5);
- pci_write_config8(pcidev1,0x43,0x44);
- pci_write_config8(pcidev1,0x44,0x34);
- pci_write_config8(pcidev1,0x83,0x02);
- }
- printk_debug("VGA random fixup ...\n");
- pcidev2 = dev_find_device(PCI_VENDOR_ID_VIA,0x3122,0);
- if( pcidev2 ){
- pci_write_config8(pcidev2,0x04,0x07);
- pci_write_config8(pcidev2,0x0d,0x20);
- }
- // fixup GART and framebuffer addresses properly
- // first set up frame buffer properly
- fb = pci_read_config32(pcidev2,0x10); // base address of framebuffer
- printk_debug("Frame buffer at %8x\n",fb);
- c = pci_read_config8(pcidev0,0xe1) & 0xf0; // size of vga
- c |= fb>>28; // upper nibble of frame buffer address
- pci_write_config8(pcidev0,0xe1,c);
- c = (fb>>20) | 1; // enable framebuffer
- pci_write_config8(pcidev0,0xe0,c);
- pci_write_config8(pcidev0,0xe2,0x42); // 'cos award does
-
+ pci_write_config8(dev, 0x3e, 0x0c);
+ pci_write_config8(dev, 0x40, 0x83);
+ pci_write_config8(dev, 0x41, 0xc5);
+ pci_write_config8(dev, 0x43, 0x44);
+ pci_write_config8(dev, 0x44, 0x34);
+ pci_write_config8(dev, 0x83, 0x02);
}
-static void set_vga_mtrrs(void)
+
+static struct device_operations agp_operations = {
+ .read_resources = pci_bus_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_bus_enable_resources,
+ .init = agp_init,
+ .scan_bus = pci_scan_bridge,
+ .ops_pci = 0,
+};
+
+static struct pci_driver agp_driver __pci_driver = {
+ .ops = &agp_ops,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = 0xb091,
+};
+
+static void vga_init(device_t dev)
{
- device_t pcidev = dev_find_device(PCI_VENDOR_ID_VIA,0x3122,0);
unsigned long fb;
+ printk_debug("VGA random fixup ...\n");
+ pci_write_config8(dev, 0x04, 0x07);
+ pci_write_config8(dev, 0x0d, 0x20);
+
+ /* Set the vga mtrrs */
add_var_mtrr( 0xd0000000 >> 10, 0x08000000>>10, MTRR_TYPE_WRCOMB);
- fb = pci_read_config32(pcidev,0x10); // get the fb address
+ fb = pci_read_config32(dev,0x10); // get the fb address
add_var_mtrr( fb>>10, 8192, MTRR_TYPE_WRCOMB);
-
+}
+
+static struct device_operations vga_operations = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = vga_init,
+ .ops_pci = 0,
+};
+
+static struct pci_driver vga_driver __pci_driver = {
+ .ops = &vga_ops,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = 0x3122,
+};
+
+
+#define BRIDGE_IO_MASK (IORESOURCE_IO | IORESOURCE_MEM)
+
+static void pci_domain_read_resources(device_t dev)
+{
+ struct resource *resource;
+ unsigned reg;
+ /* Initialize the system wide io space constraints */
+ resource = new_resource(dev, 0);
+ resource->base = 0x400;
+ resource->limit = 0xffffUL;
+ resource->flags = IORESOURCE_IO;
+ compute_allocate_resource(&dev->link[0], resource,
+ IORESOURCE_IO, IORESOURCE_IO);
+
+ /* Initialize the system wide memory resources constraints */
+ resource = new_resource(dev, 1);
+ resource->limit = 0xffffffffULL;
+ resource->flags = IORESOURCE_MEM;
+ compute_allocate_resource(&dev->link[0], resource,
+ IORESOURCE_MEM, IORESOURCE_MEM);
}
-static void northbridge_init(struct chip *chip, enum chip_pass pass)
+static void ram_resource(device_t dev, unsigned long index,
+ unsigned long basek, unsigned long sizek)
{
+ struct resource *resource;
+
+ if (!sizek) {
+ return;
+ }
+ resource = new_resource(dev, index);
+ resource->base = ((resource_t)basek) << 10;
+ resource->size = ((resource_t)sizek) << 10;
+ resource->flags = IORESOURCE_MEM | IORESOURCE_CACHEABLE | \
+ IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
+}
+
+static const uint8_t ramregs[] = {0x5a, 0x5b, 0x5c, 0x5d };
+
+static void pci_domain_set_resources(device_t dev)
+{
+ struct resource *resource, *last;
+ device_t mc_dev;
+ uint32_t pci_tolm;
+
+ pci_tolm = 0xffffffffUL;
+ last = &dev->resource[dev->resources];
+ for(resource = &dev->resource[0]; resource < last; resource++)
+ {
+ compute_allocate_resource(&dev->link[0], resource,
+ BRIDGE_IO_MASK, resource->flags & BRIDGE_IO_MASK);
+
+ resource->flags |= IORESOURCE_STORED;
+ report_resource_stored(dev, resource, "");
- struct northbridge_via_vt8623_config *conf =
- (struct northbridge_via_vt8623_config *)chip->chip_info;
-
- switch (pass) {
- case CONF_PASS_PRE_PCI:
- break;
-
- case CONF_PASS_POST_PCI:
- random_fixup();
- break;
-
- case CONF_PASS_PRE_BOOT:
- set_vga_mtrrs();
- break;
-
- default:
- /* nothing yet */
- break;
+ if ((resource->flags & IORESOURCE_MEM) &&
+ (pci_tolm > resource->base))
+ {
+ pci_tolm = resource->base;
+ }
+ }
+
+ mc_dev = dev->link[0].children;
+ if (mc_dev) {
+ unsigned long tomk, tolmk;
+ unsigned char rambits;
+ int i, idx;
+
+ for(rambits = 0, i = 0; i < sizeof(ramregs)/sizeof(ramregs[0]); i++) {
+ unsigned char reg;
+ reg = pci_read_config8(mc_dev, ramregs[i]);
+ /* these are ENDING addresses, not sizes.
+ * if there is memory in this slot, then reg will be > rambits.
+ * So we just take the max, that gives us total.
+ * We take the highest one to cover for once and future linuxbios
+ * bugs. We warn about bugs.
+ */
+ if (reg > rambits)
+ rambits = reg;
+ if (reg < rambits)
+ printk_err("ERROR! register 0x%x is not set!\n",
+ ramregs[i]);
+ }
+ printk_debug("I would set ram size to 0x%x Kbytes\n", (rambits)*16*1024);
+ tomk = ramreg*16*1024 - 32768;
+ /* Compute the top of Low memory */
+ tolmk = pci_tolm >> 10;
+ if (tolmk >= tomk) {
+ /* The PCI hole does does not overlap the memory.
+ */
+ tolmk = tomk;
+ }
+ /* Report the memory regions */
+ idx = 10;
+ ram_resource(dev, idx++, 0, 640); /* first 640k */
+ ram_resource(dev, idx++, 768, tolmk - 768); /* leave a hole for vga */
}
+ assign_resources(&dev->link[0]);
+}
+
+static unsigned int pci_domain_scan_bus(device_t dev, unsigned int max)
+{
+ max = pci_scan_bus(&dev->link[0], PCI_DEVFN(0, 0), 0xff, max);
+ return max;
+}
+
+static struct device_operations pci_domain_ops = {
+ .read_resources = pci_domain_read_resources,
+ .set_resources = pci_domain_set_resources,
+ .enable_resources = enable_childrens_resources,
+ .init = 0,
+ .scan_bus = pci_domain_scan_bus,
+};
+
+static void cpu_bus_init(device_t dev)
+{
+ initialize_cpus(&dev->link[0]);
+}
+
+static void cpu_bus_noop(device_t dev)
+{
+}
+
+static struct device_operations cpu_bus_ops = {
+ .read_resources = cpu_bus_noop,
+ .set_resources = cpu_bus_noop,
+ .enable_resources = cpu_bus_noop,
+ .init = cpu_bus_init,
+ .scan_bus = 0,
+};
+
+static void enable_dev(struct device *dev)
+{
+ struct device_path path;
+
+ /* Set the operations if it is a special bus type */
+ if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
+ dev->ops = &pci_domain_ops;
+ }
+ else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) {
+ dev->ops = &cpu_bus_ops;
+ }
}
struct chip_operations northbridge_via_vt8623_control = {
- .enable = northbridge_init,
- .name = "VIA vt8623 Northbridge",
+ .enable_dev = enable_dev,
+ .name = "VIA vt8623 Northbridge",
};