aboutsummaryrefslogtreecommitdiff
path: root/src/northbridge/amd/amdk8/northbridge.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/northbridge/amd/amdk8/northbridge.c')
-rw-r--r--src/northbridge/amd/amdk8/northbridge.c260
1 files changed, 141 insertions, 119 deletions
diff --git a/src/northbridge/amd/amdk8/northbridge.c b/src/northbridge/amd/amdk8/northbridge.c
index 89602f37a6..e45aff8242 100644
--- a/src/northbridge/amd/amdk8/northbridge.c
+++ b/src/northbridge/amd/amdk8/northbridge.c
@@ -40,7 +40,7 @@ static device_t __f1_dev[FX_DEVS];
static void debug_fx_devs(void)
{
int i;
- for (i = 0; i < FX_DEVS; i++) {
+ for(i = 0; i < FX_DEVS; i++) {
device_t dev;
dev = __f0_dev[i];
if (dev) {
@@ -62,7 +62,7 @@ static void get_fx_devs(void)
if (__f1_dev[0]) {
return;
}
- for (i = 0; i < FX_DEVS; i++) {
+ for(i = 0; i < FX_DEVS; i++) {
__f0_dev[i] = dev_find_slot(0, PCI_DEVFN(0x18 + i, 0));
__f1_dev[i] = dev_find_slot(0, PCI_DEVFN(0x18 + i, 1));
}
@@ -81,7 +81,7 @@ static void f1_write_config32(unsigned reg, uint32_t value)
{
int i;
get_fx_devs();
- for (i = 0; i < FX_DEVS; i++) {
+ for(i = 0; i < FX_DEVS; i++) {
device_t dev;
dev = __f1_dev[i];
if (dev && dev->enabled) {
@@ -102,9 +102,9 @@ static unsigned int amdk8_scan_chains(device_t dev, unsigned int max)
nodeid = amdk8_nodeid(dev);
#if 0
printk_debug("%s amdk8_scan_chains max: %d starting...\n",
- dev_path(dev), max);
+ dev_path(dev), max);
#endif
- for (link = 0; link < dev->links; link++) {
+ for(link = 0; link < dev->links; link++) {
uint32_t link_type;
uint32_t busses, config_busses;
unsigned free_reg, config_reg;
@@ -122,9 +122,10 @@ static unsigned int amdk8_scan_chains(device_t dev, unsigned int max)
continue;
}
/* See if there is an available configuration space mapping
- * register in function 1. */
+ * register in function 1.
+ */
free_reg = 0;
- for (config_reg = 0xe0; config_reg <= 0xec; config_reg += 4) {
+ for(config_reg = 0xe0; config_reg <= 0xec; config_reg += 4) {
uint32_t config;
config = f1_read_config32(config_reg);
if (!free_reg && ((config & 3) == 0)) {
@@ -132,8 +133,8 @@ static unsigned int amdk8_scan_chains(device_t dev, unsigned int max)
continue;
}
if (((config & 3) == 3) &&
- (((config >> 4) & 7) == nodeid) &&
- (((config >> 8) & 3) == link)) {
+ (((config >> 4) & 7) == nodeid) &&
+ (((config >> 8) & 3) == link)) {
break;
}
}
@@ -141,7 +142,8 @@ static unsigned int amdk8_scan_chains(device_t dev, unsigned int max)
config_reg = free_reg;
}
/* If we can't find an available configuration space mapping
- * register skip this bus */
+ * register skip this bus
+ */
if (config_reg > 0xec) {
continue;
}
@@ -158,15 +160,15 @@ static unsigned int amdk8_scan_chains(device_t dev, unsigned int max)
*/
busses = pci_read_config32(dev, dev->link[link].cap + 0x14);
config_busses = f1_read_config32(config_reg);
-
+
/* Configure the bus numbers for this bridge: the configuration
* transactions will not be propagates by the bridge if it is
* not correctly configured
*/
busses &= 0xff000000;
busses |= (((unsigned int)(dev->bus->secondary) << 0) |
- ((unsigned int)(dev->link[link].secondary) << 8) |
- ((unsigned int)(dev->link[link].subordinate) << 16));
+ ((unsigned int)(dev->link[link].secondary) << 8) |
+ ((unsigned int)(dev->link[link].subordinate) << 16));
pci_write_config32(dev, dev->link[link].cap + 0x14, busses);
config_busses &= 0x000fc88;
@@ -183,13 +185,14 @@ static unsigned int amdk8_scan_chains(device_t dev, unsigned int max)
dev_path(dev), link, max);
#endif
/* Now we can scan all of the subordinate busses i.e. the
- * chain on the hypertranport link */
- max = hypertransport_scan_chain(&dev->link[link], max);
+ * chain on the hypertranport link
+ */
+ max = hypertransport_scan_chain(&dev->link[link], 0, 0xbf, max);
#if 0
printk_debug("%s Hyper transport scan link: %d new max: %d\n",
dev_path(dev), link, max);
-#endif
+#endif
/* We know the number of busses behind this bridge. Set the
* subordinate bus number to it's real value
@@ -202,6 +205,7 @@ static unsigned int amdk8_scan_chains(device_t dev, unsigned int max)
config_busses = (config_busses & 0x00ffffff) |
(dev->link[link].subordinate << 24);
f1_write_config32(config_reg, config_busses);
+
#if 0
printk_debug("%s Hypertransport scan link: %d done\n",
dev_path(dev), link);
@@ -214,32 +218,34 @@ static unsigned int amdk8_scan_chains(device_t dev, unsigned int max)
return max;
}
-static int reg_useable(unsigned reg, device_t goal_dev, unsigned goal_nodeid,
- unsigned goal_link)
+static int reg_useable(unsigned reg,
+ device_t goal_dev, unsigned goal_nodeid, unsigned goal_link)
{
struct resource *res;
unsigned nodeid, link;
int result;
res = 0;
- for (nodeid = 0; !res && (nodeid < 8); nodeid++) {
+ for(nodeid = 0; !res && (nodeid < 8); nodeid++) {
device_t dev;
dev = __f0_dev[nodeid];
- for (link = 0; !res && (link < 3); link++) {
+ for(link = 0; !res && (link < 3); link++) {
res = probe_resource(dev, 0x100 + (reg | link));
}
}
result = 2;
if (res) {
result = 0;
- if ((goal_link == (link - 1)) &&
- (goal_nodeid == (nodeid - 1)) &&
- (res->flags <= 1)) {
+ if ( (goal_link == (link - 1)) &&
+ (goal_nodeid == (nodeid - 1)) &&
+ (res->flags <= 1)) {
result = 1;
}
}
#if 0
printk_debug("reg: %02x result: %d gnodeid: %u glink: %u nodeid: %u link: %u\n",
- reg, result, goal_nodeid, goal_link, nodeid, link);
+ reg, result,
+ goal_nodeid, goal_link,
+ nodeid, link);
#endif
return result;
}
@@ -250,7 +256,7 @@ static struct resource *amdk8_find_iopair(device_t dev, unsigned nodeid, unsigne
unsigned free_reg, reg;
resource = 0;
free_reg = 0;
- for (reg = 0xc0; reg <= 0xd8; reg += 0x8) {
+ for(reg = 0xc0; reg <= 0xd8; reg += 0x8) {
int result;
result = reg_useable(reg, dev, nodeid, link);
if (result == 1) {
@@ -277,7 +283,7 @@ static struct resource *amdk8_find_mempair(device_t dev, unsigned nodeid, unsign
unsigned free_reg, reg;
resource = 0;
free_reg = 0;
- for (reg = 0x80; reg <= 0xb8; reg += 0x8) {
+ for(reg = 0x80; reg <= 0xb8; reg += 0x8) {
int result;
result = reg_useable(reg, dev, nodeid, link);
if (result == 1) {
@@ -348,7 +354,7 @@ static void amdk8_read_resources(device_t dev)
{
unsigned nodeid, link;
nodeid = amdk8_nodeid(dev);
- for (link = 0; link < dev->links; link++) {
+ for(link = 0; link < dev->links; link++) {
if (dev->link[link].children) {
amdk8_link_read_bases(dev, nodeid, link);
}
@@ -499,11 +505,11 @@ static void amdk8_set_resources(device_t dev)
amdk8_create_vga_resource(dev, nodeid);
/* Set each resource we have found */
- for (i = 0; i < dev->resources; i++) {
+ for(i = 0; i < dev->resources; i++) {
amdk8_set_resource(dev, &dev->resource[i], nodeid);
}
- for (link = 0; link < dev->links; link++) {
+ for(link = 0; link < dev->links; link++) {
struct bus *bus;
bus = &dev->link[link];
if (bus->children) {
@@ -520,26 +526,9 @@ static void amdk8_enable_resources(device_t dev)
static void mcf0_control_init(struct device *dev)
{
- uint32_t cmd;
-
#if 0
printk_debug("NB: Function 0 Misc Control.. ");
#endif
-#if 1
- /* improve latency and bandwith on HT */
- cmd = pci_read_config32(dev, 0x68);
- cmd &= 0xffff80ff;
- cmd |= 0x00004800;
- pci_write_config32(dev, 0x68, cmd );
-#endif
-
-#if 0
- /* over drive the ht port to 1000 Mhz */
- cmd = pci_read_config32(dev, 0xa8);
- cmd &= 0xfffff0ff;
- cmd |= 0x00000600;
- pci_write_config32(dev, 0xdc, cmd );
-#endif
#if 0
printk_debug("done.\n");
#endif
@@ -578,7 +567,7 @@ static void pci_domain_read_resources(device_t dev)
/* Find the already assigned resource pairs */
get_fx_devs();
- for (reg = 0x80; reg <= 0xd8; reg+= 0x08) {
+ for(reg = 0x80; reg <= 0xd8; reg+= 0x08) {
uint32_t base, limit;
base = f1_read_config32(reg);
limit = f1_read_config32(reg + 0x04);
@@ -612,8 +601,8 @@ static void pci_domain_read_resources(device_t dev)
resource->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
}
-static void ram_resource(device_t dev, unsigned long index,
- unsigned long basek, unsigned long sizek)
+static void ram_resource(device_t dev, unsigned long index,
+ unsigned long basek, unsigned long sizek)
{
struct resource *resource;
@@ -691,7 +680,7 @@ static void pci_domain_set_resources(device_t dev)
#endif
idx = 10;
- for (i = 0; i < 8; i++) {
+ for(i = 0; i < 8; i++) {
uint32_t base, limit;
unsigned basek, limitk, sizek;
base = f1_read_config32(0x40 + (i << 3));
@@ -737,11 +726,35 @@ static void pci_domain_set_resources(device_t dev)
static unsigned int pci_domain_scan_bus(device_t dev, unsigned int max)
{
unsigned reg;
+ int i;
/* Unmap all of the HT chains */
- for (reg = 0xe0; reg <= 0xec; reg += 4) {
+ for(reg = 0xe0; reg <= 0xec; reg += 4) {
f1_write_config32(reg, 0);
}
max = pci_scan_bus(&dev->link[0], PCI_DEVFN(0x18, 0), 0xff, max);
+
+ /* Tune the hypertransport transaction for best performance.
+ * Including enabling relaxed ordering if it is safe.
+ */
+ get_fx_devs();
+ for(i = 0; i < FX_DEVS; i++) {
+ device_t f0_dev;
+ f0_dev = __f0_dev[i];
+ if (f0_dev && f0_dev->enabled) {
+ uint32_t httc;
+ int j;
+ httc = pci_read_config32(f0_dev, HT_TRANSACTION_CONTROL);
+ httc &= ~HTTC_RSP_PASS_PW;
+ if (!dev->link[0].disable_relaxed_ordering) {
+ httc |= HTTC_RSP_PASS_PW;
+ }
+ printk_spew("%s passpw: %s\n",
+ dev_path(dev),
+ (!dev->link[0].disable_relaxed_ordering)?
+ "enabled":"disabled");
+ pci_write_config32(f0_dev, HT_TRANSACTION_CONTROL, httc);
+ }
+ }
return max;
}
@@ -755,20 +768,34 @@ static struct device_operations pci_domain_ops = {
};
#define APIC_ID_OFFSET 0x10
+
static unsigned int cpu_bus_scan(device_t dev, unsigned int max)
{
struct bus *cpu_bus;
device_t dev_mc;
+ int bsp_apic_id;
+ int apic_id_offset;
int i,j;
- unsigned nb_cfg_54 = 0;
- unsigned siblings = 0;
- int enable_apic_ext_id = 0;
- int bsp_apic_id = lapicid(); // bsp apicid
- int apic_id_offset = bsp_apic_id;
+ unsigned nb_cfg_54;
+ int enable_apic_ext_id;
+ unsigned siblings;
+#if CONFIG_LOGICAL_CPUS == 1
+ int e0_later_single_core;
+ int disable_siblings;
+#endif
-#if CONFIG_LOGICAL_CPUS==1
- int e0_later_single_core;
- int disable_siblings = !CONFIG_LOGICAL_CPUS;
+ nb_cfg_54 = 0;
+ enable_apic_ext_id = 0;
+ siblings = 0;
+
+ /* Find the bootstrap processors apicid */
+ bsp_apic_id = lapicid();
+
+ /* See if I will enable extended ids' */
+ apic_id_offset = bsp_apic_id;
+
+#if CONFIG_LOGICAL_CPUS == 1
+ disable_siblings = !CONFIG_LOGICAL_CPUS;
get_option(&disable_siblings, "dual_core");
// for pre_e0, nb_cfg_54 can not be set, ( even set, when you read it still be 0)
@@ -776,45 +803,42 @@ static unsigned int cpu_bus_scan(device_t dev, unsigned int max)
nb_cfg_54 = read_nb_cfg_54();
#endif
-
dev_mc = dev_find_slot(0, PCI_DEVFN(0x18, 0));
- if(pci_read_config32(dev_mc, 0x68) & ( HTTC_APIC_EXT_ID | HTTC_APIC_EXT_BRD_CST)) {
+ if (!dev_mc) {
+ die("0:18.0 not found?");
+ }
+ if (pci_read_config32(dev_mc, 0x68) & (HTTC_APIC_EXT_ID|HTTC_APIC_EXT_BRD_CST))
+ {
enable_apic_ext_id = 1;
- if(apic_id_offset==0) { //bsp apic id is not changed
+ if (apic_id_offset == 0) {
+ /* bsp apic id is not changed */
apic_id_offset = APIC_ID_OFFSET;
}
}
-
/* Find which cpus are present */
cpu_bus = &dev->link[0];
- for (i = 0; i < 8; i++) {
+ for(i = 0; i < 8; i++) {
device_t dev, cpu;
struct device_path cpu_path;
- /* Find the cpu's memory controller */
+ /* Find the cpu's pci device */
dev = dev_find_slot(0, PCI_DEVFN(0x18 + i, 3));
- if(!dev) { // in case we move apic cluser before pci_domain and not set that for second CPU
- for(j=0; j<4; j++) {
- struct device dummy;
- uint32_t id;
- dummy.bus = dev_mc->bus;
- dummy.path.type = DEVICE_PATH_PCI;
- dummy.path.u.pci.devfn = PCI_DEVFN(0x18 + i, j);
- id = pci_read_config32(&dummy, PCI_VENDOR_ID);
- if (id != 0xffffffff && id != 0x00000000 &&
- id != 0x0000ffff && id != 0xffff0000) {
- //create that for it
- dev = alloc_dev(dev_mc->bus, &dummy.path);
- }
+ if (!dev) {
+ /* If I am probing things in a weird order
+ * ensure all of the cpu's pci devices are found.
+ */
+ int j;
+ for(j = 0; j <= 3; j++) {
+ dev = pci_probe_dev(NULL, dev_mc->bus,
+ PCI_DEVFN(0x18 + i, j));
}
}
-#if CONFIG_LOGICAL_CPUS==1
+#if CONFIG_LOGICAL_CPUS == 1
e0_later_single_core = 0;
- if((!disable_siblings) && dev && dev->enabled) {
- j = (pci_read_config32(dev, 0xe8) >> 12) & 3; //dev is func 3
-
+ if ((!disable_siblings) && dev && dev->enabled) {
+ j = (pci_read_config32(dev, 0xe8) >> 12) & 3; // dev is func 3
printk_debug(" %s siblings=%d\r\n", dev_path(dev), j);
if(nb_cfg_54) {
@@ -843,51 +867,49 @@ static unsigned int cpu_bus_scan(device_t dev, unsigned int max)
}
} else {
siblings = j;
- }
+ }
}
#endif
-
#if CONFIG_LOGICAL_CPUS==1
for (j = 0; j <= (e0_later_single_core?0:siblings); j++ ) {
#else
- for (j = 0; j <= siblings; j++ ) {
+ for (j = 0; j <= siblings; j++ ) {
#endif
- /* Build the cpu device path */
- cpu_path.type = DEVICE_PATH_APIC;
- cpu_path.u.apic.apic_id = i * (nb_cfg_54?(siblings+1):1) + j * (nb_cfg_54?1:8);
-
- /* See if I can find the cpu */
- cpu = find_dev_path(cpu_bus, &cpu_path);
-
- /* Enable the cpu if I have the processor */
- if (dev && dev->enabled) {
- if (!cpu) {
- cpu = alloc_dev(cpu_bus, &cpu_path);
- }
- if (cpu) {
- cpu->enabled = 1;
- }
- }
-
- /* Disable the cpu if I don't have the processor */
- if (cpu && (!dev || !dev->enabled)) {
- cpu->enabled = 0;
- }
-
- /* Report what I have done */
- if (cpu) {
- if(enable_apic_ext_id) {
- if(cpu->path.u.apic.apic_id<apic_id_offset) { //all add offset except bsp core0
- if( (cpu->path.u.apic.apic_id > siblings) || (bsp_apic_id!=0) )
- cpu->path.u.apic.apic_id += apic_id_offset;
- }
+ /* Build the cpu device path */
+ cpu_path.type = DEVICE_PATH_APIC;
+ cpu_path.u.apic.apic_id = i * (nb_cfg_54?(siblings+1):1) + j * (nb_cfg_54?1:8);
+
+ /* See if I can find the cpu */
+ cpu = find_dev_path(cpu_bus, &cpu_path);
+
+ /* Enable the cpu if I have the processor */
+ if (dev && dev->enabled) {
+ if (!cpu) {
+ cpu = alloc_dev(cpu_bus, &cpu_path);
}
- printk_debug("CPU: %s %s\n",
- dev_path(cpu), cpu->enabled?"enabled":"disabled");
- }
- } //j
+ if (cpu) {
+ cpu->enabled = 1;
+ }
+ }
+
+ /* Disable the cpu if I don't have the processor */
+ if (cpu && (!dev || !dev->enabled)) {
+ cpu->enabled = 0;
+ }
+
+ /* Report what I have done */
+ if (cpu) {
+ if(enable_apic_ext_id) {
+ if(cpu->path.u.apic.apic_id<apic_id_offset) { //all add offset except bsp core0
+ if( (cpu->path.u.apic.apic_id > siblings) || (bsp_apic_id!=0) )
+ cpu->path.u.apic.apic_id += apic_id_offset;
+ }
+ }
+ printk_debug("CPU: %s %s\n",
+ dev_path(cpu), cpu->enabled?"enabled":"disabled");
+ }
+ } //j
}
-
return max;
}