From 20968c9220b6de6a403c807edb19babc8c3a2eac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ky=C3=B6sti=20M=C3=A4lkki?= Date: Mon, 23 Feb 2015 12:05:33 +0200 Subject: AMD K8 fam10: Add ht_route_link() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I41aeb80121f120641b65759c8502150ce89caa30 Signed-off-by: Kyösti Mälkki Reviewed-on: http://review.coreboot.org/8556 Tested-by: build bot (Jenkins) Reviewed-by: Edward O'Callaghan Reviewed-by: Timothy Pearson --- src/northbridge/amd/amdfam10/northbridge.c | 50 +++++++++++++++++-------- src/northbridge/amd/amdk8/northbridge.c | 60 +++++++++++++++++++----------- 2 files changed, 73 insertions(+), 37 deletions(-) diff --git a/src/northbridge/amd/amdfam10/northbridge.c b/src/northbridge/amd/amdfam10/northbridge.c index 424ecd7dcbc3..ff5dc31a0366 100644 --- a/src/northbridge/amd/amdfam10/northbridge.c +++ b/src/northbridge/amd/amdfam10/northbridge.c @@ -158,6 +158,37 @@ static bool is_non_coherent_link(struct device *dev, struct bus *link) return !!(link_type & NonCoherent); } +typedef enum { + HT_ROUTE_CLOSE, + HT_ROUTE_SCAN, + HT_ROUTE_FINAL, +} scan_state; + +static void ht_route_link(struct bus *link, scan_state mode) +{ + struct bus *parent = link->dev->bus; + u32 busses; + + /* Configure the bus numbers for this bridge: the configuration + * transactions will not be propagated by the bridge if it is + * not correctly configured + */ + busses = pci_read_config32(link->dev, link->cap + 0x14); + busses &= 0xff000000; + busses |= parent->secondary & 0xff; + if (mode == HT_ROUTE_CLOSE) { + busses |= 0xfeff << 8; + } else if (mode == HT_ROUTE_SCAN) { + busses |= ((u32) link->secondary & 0xff) << 8; + busses |= 0xfc << 16; + } else if (mode == HT_ROUTE_FINAL) { + busses |= ((u32) link->secondary & 0xff) << 8; + busses |= ((u32) link->subordinate & 0xff) << 16; + } + pci_write_config32(link->dev, link->cap + 0x14, busses); + +} + static u32 amdfam10_scan_chain(device_t dev, u32 nodeid, struct bus *link, bool is_sblink, u32 max) { @@ -170,7 +201,6 @@ static u32 amdfam10_scan_chain(device_t dev, u32 nodeid, struct bus *link, bool u32 ht_unitid_base[4]; // here assume only 4 HT device on chain u32 max_bus; u32 min_bus; - u32 busses; #if CONFIG_SB_HT_CHAIN_ON_BUS0 > 1 u32 busn = max&0xff; #endif @@ -219,23 +249,11 @@ static u32 amdfam10_scan_chain(device_t dev, u32 nodeid, struct bus *link, bool link->secondary = min_bus; link->subordinate = link->secondary; - /* Read the existing primary/secondary/subordinate bus - * number configuration. - */ - busses = pci_read_config32(dev, link->cap + 0x14); - - /* Configure the bus numbers for this bridge: the configuration - * transactions will not be propagates by the bridge if it is - * not correctly configured - */ - busses &= 0xffff00ff; - busses |= ((u32)(link->secondary) << 8); - pci_write_config32(dev, link->cap + 0x14, busses); - + ht_route_link(link, HT_ROUTE_SCAN); /* set the config map space */ - set_config_map_reg(nodeid, link->link_num, ht_c_index, link->secondary, max_bus, sysconf.segbit, sysconf.nodes); + set_config_map_reg(nodeid, link->link_num, ht_c_index, link->secondary, link->subordinate, sysconf.segbit, sysconf.nodes); /* Now we can scan all of the subordinate busses i.e. the * chain on the hypertranport link @@ -255,6 +273,8 @@ static u32 amdfam10_scan_chain(device_t dev, u32 nodeid, struct bus *link, bool /* Now that nothing is overlapping it is safe to scan the children. */ pci_scan_bus(link, 0x00, ((next_unitid - 1) << 3) | 7); + ht_route_link(link, HT_ROUTE_FINAL); + /* We know the number of busses behind this bridge. Set the * subordinate bus number to it's real value */ diff --git a/src/northbridge/amd/amdk8/northbridge.c b/src/northbridge/amd/amdk8/northbridge.c index 45cff9e71a32..018b68a8d620 100644 --- a/src/northbridge/amd/amdk8/northbridge.c +++ b/src/northbridge/amd/amdk8/northbridge.c @@ -96,6 +96,38 @@ static bool is_non_coherent_link(struct device *dev, struct bus *link) return !!(link_type & NonCoherent); } +typedef enum { + HT_ROUTE_CLOSE, + HT_ROUTE_SCAN, + HT_ROUTE_FINAL, +} scan_state; + +static void ht_route_link(struct bus *link, scan_state mode) +{ + struct device *dev = link->dev; + struct bus *parent = dev->bus; + u32 busses; + + /* Configure the bus numbers for this bridge: the configuration + * transactions will not be propagated by the bridge if it is + * not correctly configured + */ + busses = pci_read_config32(link->dev, link->cap + 0x14); + busses &= 0xff000000; + busses |= parent->secondary & 0xff; + if (mode == HT_ROUTE_CLOSE) { + busses |= 0xfeff << 8; + } else if (mode == HT_ROUTE_SCAN) { + busses |= ((u32) link->secondary & 0xff) << 8; + busses |= 0xff << 16; + } else if (mode == HT_ROUTE_FINAL) { + busses |= ((u32) link->secondary & 0xff) << 8; + busses |= ((u32) link->subordinate & 0xff) << 16; + } + pci_write_config32(link->dev, link->cap + 0x14, busses); + +} + static u32 amdk8_nodeid(device_t dev) { return (dev->path.pci.devfn >> 3) - 0x18; @@ -106,10 +138,9 @@ static u32 amdk8_scan_chain(device_t dev, u32 nodeid, struct bus *link, bool is_ { int i; unsigned int next_unitid; - u32 busses, config_busses; + u32 config_busses; u32 free_reg, config_reg; u32 ht_unitid_base[4]; // here assume only 4 HT device on chain - u32 max_bus; u32 min_bus; u32 max_devfn; @@ -168,34 +199,20 @@ static u32 amdk8_scan_chain(device_t dev, u32 nodeid, struct bus *link, bool is_ #else min_bus = ++max; #endif - max_bus = 0xff; link->secondary = min_bus; link->subordinate = link->secondary; - /* Read the existing primary/secondary/subordinate bus - * number configuration. - */ - busses = pci_read_config32(dev, 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)(link->secondary) << 8) | - (max_bus << 16)); - pci_write_config32(dev, link->cap + 0x14, busses); + ht_route_link(link, HT_ROUTE_SCAN); + config_busses = f1_read_config32(config_reg); config_busses &= 0x000fc88; config_busses |= (3 << 0) | /* rw enable, no device compare */ (( nodeid & 7) << 4) | ((link->link_num & 3) << 8) | ((link->secondary) << 16) | - (max_bus << 24); + (0xff << 24); f1_write_config32(config_reg, config_busses); /* Now we can scan all of the subordinate busses i.e. the @@ -218,9 +235,8 @@ static u32 amdk8_scan_chain(device_t dev, u32 nodeid, struct bus *link, bool is_ /* We know the number of busses behind this bridge. Set the * subordinate bus number to it's real value */ - busses = (busses & 0xff00ffff) | - ((unsigned int) (link->subordinate) << 16); - pci_write_config32(dev, link->cap + 0x14, busses); + + ht_route_link(link, HT_ROUTE_FINAL); config_busses = (config_busses & 0x00ffffff) | (link->subordinate << 24); -- cgit v1.2.3