AMD K8 fam10: Refactor HT link connection test
Change-Id: I1e935a6b848a59f7f2e58779bceea599032de9e3 Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com> Reviewed-on: http://review.coreboot.org/8562 Tested-by: build bot (Jenkins) Reviewed-by: Edward O'Callaghan <edward.ocallaghan@koparo.com> Reviewed-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
This commit is contained in:
parent
3690727955
commit
0a3d4e4b03
|
@ -507,6 +507,23 @@ void ht_scan_bridge(struct device *dev)
|
||||||
do_pci_scan_bridge(dev, hypertransport_scan_chain_x);
|
do_pci_scan_bridge(dev, hypertransport_scan_chain_x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ht_is_non_coherent_link(struct bus *link)
|
||||||
|
{
|
||||||
|
u32 link_type;
|
||||||
|
do {
|
||||||
|
link_type = pci_read_config32(link->dev, link->cap + 0x18);
|
||||||
|
} while (link_type & ConnectionPending);
|
||||||
|
|
||||||
|
if (!(link_type & LinkConnected))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
do {
|
||||||
|
link_type = pci_read_config32(link->dev, link->cap + 0x18);
|
||||||
|
} while (!(link_type & InitComplete));
|
||||||
|
|
||||||
|
return !!(link_type & NonCoherent);
|
||||||
|
}
|
||||||
|
|
||||||
/** Default device operations for hypertransport bridges */
|
/** Default device operations for hypertransport bridges */
|
||||||
static struct pci_operations ht_bus_ops_pci = {
|
static struct pci_operations ht_bus_ops_pci = {
|
||||||
.set_subsystem = 0,
|
.set_subsystem = 0,
|
||||||
|
|
|
@ -90,6 +90,7 @@ struct bus {
|
||||||
|
|
||||||
unsigned reset_needed : 1;
|
unsigned reset_needed : 1;
|
||||||
unsigned disable_relaxed_ordering : 1;
|
unsigned disable_relaxed_ordering : 1;
|
||||||
|
unsigned ht_link_up : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -3,6 +3,13 @@
|
||||||
|
|
||||||
#include <device/hypertransport_def.h>
|
#include <device/hypertransport_def.h>
|
||||||
|
|
||||||
|
/* TODO: Check HT specs for better names for these. */
|
||||||
|
#define LinkConnected (1 << 0)
|
||||||
|
#define InitComplete (1 << 1)
|
||||||
|
#define NonCoherent (1 << 2)
|
||||||
|
#define ConnectionPending (1 << 4)
|
||||||
|
bool ht_is_non_coherent_link(struct bus *link);
|
||||||
|
|
||||||
unsigned int hypertransport_scan_chain(struct bus *bus,
|
unsigned int hypertransport_scan_chain(struct bus *bus,
|
||||||
unsigned min_devfn, unsigned max_devfn, unsigned *ht_unit_base, unsigned offset_unitid);
|
unsigned min_devfn, unsigned max_devfn, unsigned *ht_unit_base, unsigned offset_unitid);
|
||||||
void ht_scan_bridge(struct device *dev);
|
void ht_scan_bridge(struct device *dev);
|
||||||
|
|
|
@ -141,23 +141,6 @@ static void set_vga_enable_reg(u32 nodeid, u32 linkn)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool is_non_coherent_link(struct device *dev, struct bus *link)
|
|
||||||
{
|
|
||||||
u32 link_type;
|
|
||||||
do {
|
|
||||||
link_type = pci_read_config32(dev, link->cap + 0x18);
|
|
||||||
} while (link_type & ConnectionPending);
|
|
||||||
|
|
||||||
if (!(link_type & LinkConnected))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
do {
|
|
||||||
link_type = pci_read_config32(dev, link->cap + 0x18);
|
|
||||||
} while (!(link_type & InitComplete));
|
|
||||||
|
|
||||||
return !!(link_type & NonCoherent);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
HT_ROUTE_CLOSE,
|
HT_ROUTE_CLOSE,
|
||||||
HT_ROUTE_SCAN,
|
HT_ROUTE_SCAN,
|
||||||
|
@ -200,11 +183,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 ht_unitid_base[4]; // here assume only 4 HT device on chain
|
||||||
u32 max_devfn;
|
u32 max_devfn;
|
||||||
|
|
||||||
/* Check for connected link. */
|
|
||||||
link->cap = 0x80 + (link->link_num * 0x20);
|
|
||||||
if (!is_non_coherent_link(dev, link))
|
|
||||||
return max;
|
|
||||||
|
|
||||||
/* See if there is an available configuration space mapping
|
/* See if there is an available configuration space mapping
|
||||||
* register in function 1.
|
* register in function 1.
|
||||||
*/
|
*/
|
||||||
|
@ -298,6 +276,17 @@ static void relocate_sb_ht_chain(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void trim_ht_chain(struct device *dev)
|
||||||
|
{
|
||||||
|
struct bus *link;
|
||||||
|
|
||||||
|
/* Check for connected link. */
|
||||||
|
for (link = dev->link_list; link; link = link->next) {
|
||||||
|
link->cap = 0x80 + (link->link_num * 0x20);
|
||||||
|
link->ht_link_up = ht_is_non_coherent_link(link);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void amdfam10_scan_chains(device_t dev)
|
static void amdfam10_scan_chains(device_t dev)
|
||||||
{
|
{
|
||||||
unsigned nodeid;
|
unsigned nodeid;
|
||||||
|
@ -308,8 +297,11 @@ static void amdfam10_scan_chains(device_t dev)
|
||||||
nodeid = amdfam10_nodeid(dev);
|
nodeid = amdfam10_nodeid(dev);
|
||||||
|
|
||||||
/* Do sb ht chain at first, in case s2885 put sb chain (8131/8111) on link2, but put 8151 on link0 */
|
/* Do sb ht chain at first, in case s2885 put sb chain (8131/8111) on link2, but put 8151 on link0 */
|
||||||
|
trim_ht_chain(dev);
|
||||||
|
|
||||||
for (link = dev->link_list; link; link = link->next) {
|
for (link = dev->link_list; link; link = link->next) {
|
||||||
bool is_sblink = (nodeid == 0) && (link->link_num == sblink);
|
bool is_sblink = (nodeid == 0) && (link->link_num == sblink);
|
||||||
|
if (link->ht_link_up)
|
||||||
max = amdfam10_scan_chain(dev, nodeid, link, is_sblink, max);
|
max = amdfam10_scan_chain(dev, nodeid, link, is_sblink, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,23 +79,6 @@ static void f1_write_config32(unsigned reg, u32 value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool is_non_coherent_link(struct device *dev, struct bus *link)
|
|
||||||
{
|
|
||||||
u32 link_type;
|
|
||||||
do {
|
|
||||||
link_type = pci_read_config32(dev, link->cap + 0x18);
|
|
||||||
} while (link_type & ConnectionPending);
|
|
||||||
|
|
||||||
if (!(link_type & LinkConnected))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
do {
|
|
||||||
link_type = pci_read_config32(dev, link->cap + 0x18);
|
|
||||||
} while (!(link_type & InitComplete));
|
|
||||||
|
|
||||||
return !!(link_type & NonCoherent);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
HT_ROUTE_CLOSE,
|
HT_ROUTE_CLOSE,
|
||||||
HT_ROUTE_SCAN,
|
HT_ROUTE_SCAN,
|
||||||
|
@ -143,10 +126,6 @@ static u32 amdk8_scan_chain(device_t dev, u32 nodeid, struct bus *link, bool is_
|
||||||
u32 ht_unitid_base[4]; // here assume only 4 HT device on chain
|
u32 ht_unitid_base[4]; // here assume only 4 HT device on chain
|
||||||
u32 max_devfn;
|
u32 max_devfn;
|
||||||
|
|
||||||
link->cap = 0x80 + (link->link_num * 0x20);
|
|
||||||
if (!is_non_coherent_link(dev, link))
|
|
||||||
return max;
|
|
||||||
|
|
||||||
/* See if there is an available configuration space mapping
|
/* See if there is an available configuration space mapping
|
||||||
* register in function 1.
|
* register in function 1.
|
||||||
*/
|
*/
|
||||||
|
@ -267,6 +246,17 @@ static void relocate_sb_ht_chain(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void trim_ht_chain(struct device *dev)
|
||||||
|
{
|
||||||
|
struct bus *link;
|
||||||
|
|
||||||
|
/* Check for connected links. */
|
||||||
|
for (link = dev->link_list; link; link = link->next) {
|
||||||
|
link->cap = 0x80 + (link->link_num * 0x20);
|
||||||
|
link->ht_link_up = ht_is_non_coherent_link(link);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void amdk8_scan_chains(device_t dev)
|
static void amdk8_scan_chains(device_t dev)
|
||||||
{
|
{
|
||||||
unsigned nodeid;
|
unsigned nodeid;
|
||||||
|
@ -278,8 +268,11 @@ static void amdk8_scan_chains(device_t dev)
|
||||||
if (nodeid == 0)
|
if (nodeid == 0)
|
||||||
sblink = (pci_read_config32(dev, 0x64)>>8) & 3;
|
sblink = (pci_read_config32(dev, 0x64)>>8) & 3;
|
||||||
|
|
||||||
|
trim_ht_chain(dev);
|
||||||
|
|
||||||
for (link = dev->link_list; link; link = link->next) {
|
for (link = dev->link_list; link; link = link->next) {
|
||||||
bool is_sblink = (nodeid == 0) && (link->link_num == sblink);
|
bool is_sblink = (nodeid == 0) && (link->link_num == sblink);
|
||||||
|
if (link->ht_link_up)
|
||||||
max = amdk8_scan_chain(dev, nodeid, link, is_sblink, max);
|
max = amdk8_scan_chain(dev, nodeid, link, is_sblink, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue