YhLu's patch from January 18th.
hypertransport specific updates Signed-off-by: Yinghai Lu <yinghai.lu@amd.com> Signed-off-by: Ed Swierk <eswierk@arastra.com> Signed-off-by: Stefan Reinauer <stepan@coresystems.de> Acked-by: Ward Vandewege <ward@gnu.org> Acked-by: Stefan Reinauer <stepan@coresystems.de> git-svn-id: svn://svn.coreboot.org/coreboot/trunk@2596 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
parent
da38d60a70
commit
00a018f511
@ -1,10 +1,3 @@
|
|||||||
#if USE_DCACHE_RAM
|
|
||||||
|
|
||||||
#include "coherent_ht_car.c"
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
|
|
||||||
/* coherent hypertransport initialization for AMD64
|
/* coherent hypertransport initialization for AMD64
|
||||||
*
|
*
|
||||||
* written by Stefan Reinauer <stepan@openbios.org>
|
* written by Stefan Reinauer <stepan@openbios.org>
|
||||||
@ -74,6 +67,7 @@
|
|||||||
#include <device/pci_ids.h>
|
#include <device/pci_ids.h>
|
||||||
#include <device/hypertransport_def.h>
|
#include <device/hypertransport_def.h>
|
||||||
#include "arch/romcc_io.h"
|
#include "arch/romcc_io.h"
|
||||||
|
|
||||||
#include "amdk8.h"
|
#include "amdk8.h"
|
||||||
|
|
||||||
#define enable_bsp_routing() enable_routing(0)
|
#define enable_bsp_routing() enable_routing(0)
|
||||||
@ -84,8 +78,6 @@
|
|||||||
|
|
||||||
#define DEFAULT 0x00010101 /* default row entry */
|
#define DEFAULT 0x00010101 /* default row entry */
|
||||||
|
|
||||||
typedef uint8_t u8;
|
|
||||||
typedef uint32_t u32;
|
|
||||||
|
|
||||||
#ifndef CROSS_BAR_47_56
|
#ifndef CROSS_BAR_47_56
|
||||||
#define CROSS_BAR_47_56 0
|
#define CROSS_BAR_47_56 0
|
||||||
@ -111,11 +103,15 @@ typedef uint32_t u32;
|
|||||||
#define CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED 0
|
#define CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef ENABLE_APIC_EXT_ID
|
||||||
|
#define ENABLE_APIC_EXT_ID 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static inline void print_linkn (const char *strval, uint8_t byteval)
|
static inline void print_linkn (const char *strval, uint8_t byteval)
|
||||||
{
|
{
|
||||||
#if 1
|
#if 1
|
||||||
#if CONFIG_USE_INIT
|
#if CONFIG_USE_PRINTK_IN_CAR
|
||||||
printk_debug("%s%02x\r\n", strval, byteval);
|
printk_debug("%s%02x\r\n", strval, byteval);
|
||||||
#else
|
#else
|
||||||
print_debug(strval); print_debug_hex8(byteval); print_debug("\r\n");
|
print_debug(strval); print_debug_hex8(byteval); print_debug("\r\n");
|
||||||
@ -162,6 +158,19 @@ static void disable_probes(void)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void enable_apic_ext_id(u8 node)
|
||||||
|
{
|
||||||
|
#if ENABLE_APIC_EXT_ID==1
|
||||||
|
#warning "FIXME Is the right place to enable apic ext id here?"
|
||||||
|
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
val = pci_read_config32(NODE_HT(node), 0x68);
|
||||||
|
val |= (HTTC_APIC_EXT_SPUR | HTTC_APIC_EXT_ID | HTTC_APIC_EXT_BRD_CST);
|
||||||
|
pci_write_config32(NODE_HT(node), 0x68, val);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static void enable_routing(u8 node)
|
static void enable_routing(u8 node)
|
||||||
{
|
{
|
||||||
u32 val;
|
u32 val;
|
||||||
@ -199,17 +208,6 @@ static void enable_routing(u8 node)
|
|||||||
print_spew(" done.\r\n");
|
print_spew(" done.\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void enable_apic_ext_id(u8 node)
|
|
||||||
{
|
|
||||||
|
|
||||||
u32 val;
|
|
||||||
|
|
||||||
val = pci_read_config32(NODE_HT(node), 0x68);
|
|
||||||
val |= (HTTC_APIC_EXT_SPUR | HTTC_APIC_EXT_ID | HTTC_APIC_EXT_BRD_CST);
|
|
||||||
pci_write_config32(NODE_HT(node), 0x68, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void fill_row(u8 node, u8 row, u32 value)
|
static void fill_row(u8 node, u8 row, u32 value)
|
||||||
{
|
{
|
||||||
pci_write_config32(NODE_HT(node), 0x40+(row<<2), value);
|
pci_write_config32(NODE_HT(node), 0x40+(row<<2), value);
|
||||||
@ -259,23 +257,6 @@ static void rename_temp_node(u8 node)
|
|||||||
|
|
||||||
print_spew(" done.\r\n");
|
print_spew(" done.\r\n");
|
||||||
}
|
}
|
||||||
#if K8_HT_CHECK_PENDING_LINK == 1
|
|
||||||
static void wait_ht_stable(uint8_t node)
|
|
||||||
{
|
|
||||||
uint8_t linkn;
|
|
||||||
for(linkn = 0; linkn<3; linkn++) {
|
|
||||||
uint8_t regpos;
|
|
||||||
uint16_t i;
|
|
||||||
uint32_t reg;
|
|
||||||
regpos = 0x98 + 0x20 * linkn;
|
|
||||||
for(i = 0; i < 0xff; i++) { //wait to make sure it is done
|
|
||||||
reg = pci_read_config32(NODE_HT(node), regpos);
|
|
||||||
if ((reg & 0x10) == 0) break; // init complete
|
|
||||||
udelay(10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int verify_connection(u8 dest)
|
static int verify_connection(u8 dest)
|
||||||
{
|
{
|
||||||
@ -293,18 +274,23 @@ static int verify_connection(u8 dest)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned read_freq_cap(device_t dev, unsigned pos)
|
static uint16_t read_freq_cap(device_t dev, uint8_t pos)
|
||||||
{
|
{
|
||||||
/* Handle bugs in valid hypertransport frequency reporting */
|
/* Handle bugs in valid hypertransport frequency reporting */
|
||||||
unsigned freq_cap;
|
uint16_t freq_cap;
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
|
|
||||||
freq_cap = pci_read_config16(dev, pos);
|
freq_cap = pci_read_config16(dev, pos);
|
||||||
freq_cap &= ~(1 << HT_FREQ_VENDOR); /* Ignore Vendor HT frequencies */
|
freq_cap &= ~(1 << HT_FREQ_VENDOR); /* Ignore Vendor HT frequencies */
|
||||||
|
|
||||||
if (!is_cpu_pre_e0()) {
|
#if K8_HT_FREQ_1G_SUPPORT == 1
|
||||||
|
#if K8_REV_F_SUPPORT == 0
|
||||||
|
if (!is_cpu_pre_e0())
|
||||||
|
#endif
|
||||||
|
{
|
||||||
return freq_cap;
|
return freq_cap;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
id = pci_read_config32(dev, 0);
|
id = pci_read_config32(dev, 0);
|
||||||
|
|
||||||
@ -320,8 +306,8 @@ static int optimize_connection(device_t node1, uint8_t link1, device_t node2, ui
|
|||||||
{
|
{
|
||||||
static const uint8_t link_width_to_pow2[]= { 3, 4, 0, 5, 1, 2, 0, 0 };
|
static const uint8_t link_width_to_pow2[]= { 3, 4, 0, 5, 1, 2, 0, 0 };
|
||||||
static const uint8_t pow2_to_link_width[] = { 0x7, 4, 5, 0, 1, 3 };
|
static const uint8_t pow2_to_link_width[] = { 0x7, 4, 5, 0, 1, 3 };
|
||||||
uint16_t freq_cap1, freq_cap2, freq_cap, freq_mask;
|
uint16_t freq_cap1, freq_cap2;
|
||||||
uint8_t width_cap1, width_cap2, width_cap, width, old_width, ln_width1, ln_width2;
|
uint8_t width_cap1, width_cap2, width, old_width, ln_width1, ln_width2;
|
||||||
uint8_t freq, old_freq;
|
uint8_t freq, old_freq;
|
||||||
int needs_reset;
|
int needs_reset;
|
||||||
/* Set link width and frequency */
|
/* Set link width and frequency */
|
||||||
@ -369,6 +355,7 @@ static int optimize_connection(device_t node1, uint8_t link1, device_t node2, ui
|
|||||||
|
|
||||||
/* See if I am changing node1's width */
|
/* See if I am changing node1's width */
|
||||||
old_width = pci_read_config8(node1, link1 + PCI_HT_CAP_HOST_WIDTH + 1);
|
old_width = pci_read_config8(node1, link1 + PCI_HT_CAP_HOST_WIDTH + 1);
|
||||||
|
old_width &= 0x77;
|
||||||
needs_reset |= old_width != width;
|
needs_reset |= old_width != width;
|
||||||
|
|
||||||
/* Set node1's widths */
|
/* Set node1's widths */
|
||||||
@ -379,10 +366,12 @@ static int optimize_connection(device_t node1, uint8_t link1, device_t node2, ui
|
|||||||
|
|
||||||
/* See if I am changing node2's width */
|
/* See if I am changing node2's width */
|
||||||
old_width = pci_read_config8(node2, link2 + PCI_HT_CAP_HOST_WIDTH + 1);
|
old_width = pci_read_config8(node2, link2 + PCI_HT_CAP_HOST_WIDTH + 1);
|
||||||
|
old_width &= 0x77;
|
||||||
needs_reset |= old_width != width;
|
needs_reset |= old_width != width;
|
||||||
|
|
||||||
/* Set node2's widths */
|
/* Set node2's widths */
|
||||||
pci_write_config8(node2, link2 + PCI_HT_CAP_HOST_WIDTH + 1, width);
|
pci_write_config8(node2, link2 + PCI_HT_CAP_HOST_WIDTH + 1, width);
|
||||||
|
|
||||||
return needs_reset;
|
return needs_reset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -676,11 +665,6 @@ static void setup_uniprocessor(void)
|
|||||||
disable_probes();
|
disable_probes();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct setup_smp_result {
|
|
||||||
int nodes;
|
|
||||||
int needs_reset;
|
|
||||||
};
|
|
||||||
|
|
||||||
#if CONFIG_MAX_PHYSICAL_CPUS > 2
|
#if CONFIG_MAX_PHYSICAL_CPUS > 2
|
||||||
static int optimize_connection_group(const u8 *opt_conn, int num) {
|
static int optimize_connection_group(const u8 *opt_conn, int num) {
|
||||||
int needs_reset = 0;
|
int needs_reset = 0;
|
||||||
@ -695,21 +679,20 @@ static int optimize_connection_group(const u8 *opt_conn, int num) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CONFIG_MAX_PHYSICAL_CPUS > 1
|
#if CONFIG_MAX_PHYSICAL_CPUS > 1
|
||||||
static struct setup_smp_result setup_smp2(void)
|
static unsigned setup_smp2(void)
|
||||||
{
|
{
|
||||||
struct setup_smp_result result;
|
unsigned nodes;
|
||||||
u8 byte;
|
u8 byte;
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
result.nodes = 2;
|
nodes = 2;
|
||||||
result.needs_reset = 0;
|
|
||||||
|
|
||||||
setup_row_local(0, 0); /* it will update the broadcast RT*/
|
setup_row_local(0, 0); /* it will update the broadcast RT*/
|
||||||
|
|
||||||
val = get_row(0,0);
|
val = get_row(0,0);
|
||||||
byte = (val>>16) & 0xfe;
|
byte = (val>>16) & 0xfe;
|
||||||
if(byte<0x2) { /* no coherent connection so get out.*/
|
if(byte<0x2) { /* no coherent connection so get out.*/
|
||||||
result.nodes = 1;
|
nodes = 1;
|
||||||
return result;
|
return nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup and check a temporary connection to node 1 */
|
/* Setup and check a temporary connection to node 1 */
|
||||||
@ -766,24 +749,19 @@ static struct setup_smp_result setup_smp2(void)
|
|||||||
clear_temp_row(0);
|
clear_temp_row(0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
result.needs_reset |= optimize_connection(
|
return nodes;
|
||||||
NODE_HT(0), 0x80 + link_to_register(link_connection(0,1)),
|
|
||||||
NODE_HT(1), 0x80 + link_to_register(link_connection(1,0)) );
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
#endif /*CONFIG_MAX_PHYSICAL_CPUS > 1 */
|
#endif /*CONFIG_MAX_PHYSICAL_CPUS > 1 */
|
||||||
|
|
||||||
#if CONFIG_MAX_PHYSICAL_CPUS > 2
|
#if CONFIG_MAX_PHYSICAL_CPUS > 2
|
||||||
|
|
||||||
static struct setup_smp_result setup_smp4(int needs_reset)
|
static unsigned setup_smp4(void)
|
||||||
{
|
{
|
||||||
struct setup_smp_result result;
|
unsigned nodes;
|
||||||
u8 byte;
|
u8 byte;
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
|
|
||||||
result.nodes=4;
|
nodes=4;
|
||||||
result.needs_reset = needs_reset;
|
|
||||||
|
|
||||||
/* Setup and check temporary connection from Node 0 to Node 2 */
|
/* Setup and check temporary connection from Node 0 to Node 2 */
|
||||||
val = get_row(0,0);
|
val = get_row(0,0);
|
||||||
@ -791,8 +769,8 @@ static struct setup_smp_result setup_smp4(int needs_reset)
|
|||||||
byte = get_linkn_last_count(byte);
|
byte = get_linkn_last_count(byte);
|
||||||
|
|
||||||
if((byte>>2)==0) { /* We should have two coherent for 4p and above*/
|
if((byte>>2)==0) { /* We should have two coherent for 4p and above*/
|
||||||
result.nodes = 2;
|
nodes = 2;
|
||||||
return result;
|
return nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte &= 3; /* bit [3,2] is count-1*/
|
byte &= 3; /* bit [3,2] is count-1*/
|
||||||
@ -940,16 +918,7 @@ static struct setup_smp_result setup_smp4(int needs_reset)
|
|||||||
clear_temp_row(1);
|
clear_temp_row(1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* optimize physical connections - by LYH */
|
return nodes;
|
||||||
static const u8 opt_conn4[] = {
|
|
||||||
0,2,
|
|
||||||
1,3,
|
|
||||||
2,3,
|
|
||||||
};
|
|
||||||
|
|
||||||
result.needs_reset |= optimize_connection_group(opt_conn4, sizeof(opt_conn4)/sizeof(opt_conn4[0]));
|
|
||||||
|
|
||||||
return result;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -957,14 +926,13 @@ static struct setup_smp_result setup_smp4(int needs_reset)
|
|||||||
|
|
||||||
#if CONFIG_MAX_PHYSICAL_CPUS > 4
|
#if CONFIG_MAX_PHYSICAL_CPUS > 4
|
||||||
|
|
||||||
static struct setup_smp_result setup_smp6(int needs_reset)
|
static unsigned setup_smp6(void)
|
||||||
{
|
{
|
||||||
struct setup_smp_result result;
|
unsigned nodes;
|
||||||
u8 byte;
|
u8 byte;
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
|
|
||||||
result.nodes=6;
|
nodes=6;
|
||||||
result.needs_reset = needs_reset;
|
|
||||||
|
|
||||||
/* Setup and check temporary connection from Node 0 to Node 4 through 2*/
|
/* Setup and check temporary connection from Node 0 to Node 4 through 2*/
|
||||||
val = get_row(2,2);
|
val = get_row(2,2);
|
||||||
@ -972,8 +940,8 @@ static struct setup_smp_result setup_smp6(int needs_reset)
|
|||||||
byte = get_linkn_last_count(byte);
|
byte = get_linkn_last_count(byte);
|
||||||
|
|
||||||
if((byte>>2)==0) { /* We should have three coherent link on node 2 for 6p and above*/
|
if((byte>>2)==0) { /* We should have three coherent link on node 2 for 6p and above*/
|
||||||
result.nodes = 4;
|
nodes = 4;
|
||||||
return result;
|
return nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup and check temporary connection from Node 0 to Node 5 through 1, 3*/
|
/* Setup and check temporary connection from Node 0 to Node 5 through 1, 3*/
|
||||||
@ -982,8 +950,8 @@ static struct setup_smp_result setup_smp6(int needs_reset)
|
|||||||
byte = ((val>>16) & 0xfe) - link_connection(3,2) - link_connection(3,1);
|
byte = ((val>>16) & 0xfe) - link_connection(3,2) - link_connection(3,1);
|
||||||
byte = get_linkn_last_count(byte);
|
byte = get_linkn_last_count(byte);
|
||||||
if((byte>>2)==0) { /* We should have three coherent links on node 3 for 6p and above*/
|
if((byte>>2)==0) { /* We should have three coherent links on node 3 for 6p and above*/
|
||||||
result.nodes = 4;
|
nodes = 4;
|
||||||
return result;
|
return nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We found 6 nodes so far. Now setup all nodes for 6p */
|
/* We found 6 nodes so far. Now setup all nodes for 6p */
|
||||||
@ -1153,17 +1121,7 @@ static struct setup_smp_result setup_smp6(int needs_reset)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* optimize physical connections - by LYH */
|
return nodes;
|
||||||
static const uint8_t opt_conn6[] ={
|
|
||||||
2, 4,
|
|
||||||
3, 5,
|
|
||||||
#if !CROSS_BAR_47_56
|
|
||||||
4, 5,
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
result.needs_reset |= optimize_connection_group(opt_conn6, sizeof(opt_conn6)/sizeof(opt_conn6[0]));
|
|
||||||
|
|
||||||
return result;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1171,14 +1129,13 @@ static struct setup_smp_result setup_smp6(int needs_reset)
|
|||||||
|
|
||||||
#if CONFIG_MAX_PHYSICAL_CPUS > 6
|
#if CONFIG_MAX_PHYSICAL_CPUS > 6
|
||||||
|
|
||||||
static struct setup_smp_result setup_smp8(int needs_reset)
|
static unsigned setup_smp8(void)
|
||||||
{
|
{
|
||||||
struct setup_smp_result result;
|
unsigned nodes;
|
||||||
u8 byte;
|
u8 byte;
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
|
|
||||||
result.nodes=8;
|
nodes=8;
|
||||||
result.needs_reset = needs_reset;
|
|
||||||
|
|
||||||
/* Setup and check temporary connection from Node 0 to Node 6 via 2 and 4 to 7 */
|
/* Setup and check temporary connection from Node 0 to Node 6 via 2 and 4 to 7 */
|
||||||
val = get_row(4,4);
|
val = get_row(4,4);
|
||||||
@ -1188,16 +1145,16 @@ static struct setup_smp_result setup_smp8(int needs_reset)
|
|||||||
byte = ((val>>16) & 0xfe) - link_connection(4,5) - link_connection(4,2);
|
byte = ((val>>16) & 0xfe) - link_connection(4,5) - link_connection(4,2);
|
||||||
byte = get_linkn_last_count(byte); /* Max link to 6*/
|
byte = get_linkn_last_count(byte); /* Max link to 6*/
|
||||||
if((byte>>2)==0) { /* We should have two or three coherent links on node 4 for 8p*/
|
if((byte>>2)==0) { /* We should have two or three coherent links on node 4 for 8p*/
|
||||||
result.nodes = 6;
|
nodes = 6;
|
||||||
return result;
|
return nodes;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CROSS_BAR_47_56
|
#if CROSS_BAR_47_56
|
||||||
byte = get_linkn_last_count(byte); /* Max link to 6*/
|
byte = get_linkn_last_count(byte); /* Max link to 6*/
|
||||||
if((byte>>2)<2) { /* We should have two or three coherent links on node 4 for 8p*/
|
if((byte>>2)<2) { /* We should have two or three coherent links on node 4 for 8p*/
|
||||||
result.nodes = 6;
|
nodes = 6;
|
||||||
return result;
|
return nodes;
|
||||||
}
|
}
|
||||||
#if TRY_HIGH_FIRST == 1
|
#if TRY_HIGH_FIRST == 1
|
||||||
byte = ((val>>16) & 0xfe) - link_connection(4,2);
|
byte = ((val>>16) & 0xfe) - link_connection(4,2);
|
||||||
@ -1215,8 +1172,8 @@ static struct setup_smp_result setup_smp8(int needs_reset)
|
|||||||
byte = ((val>>16) & 0xfe) - link_connection(5,4) - link_connection(5,3);
|
byte = ((val>>16) & 0xfe) - link_connection(5,4) - link_connection(5,3);
|
||||||
byte = get_linkn_last_count(byte);
|
byte = get_linkn_last_count(byte);
|
||||||
if((byte>>2)==0) { /* We should have three coherent links on node 5 for 6p and above*/
|
if((byte>>2)==0) { /* We should have three coherent links on node 5 for 6p and above*/
|
||||||
result.nodes = 6;
|
nodes = 6;
|
||||||
return result;
|
return nodes;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1232,6 +1189,7 @@ static struct setup_smp_result setup_smp8(int needs_reset)
|
|||||||
3, 6,
|
3, 6,
|
||||||
/*3, 7,*/
|
/*3, 7,*/
|
||||||
/*4, 7,*/
|
/*4, 7,*/
|
||||||
|
5, 6,
|
||||||
#else
|
#else
|
||||||
0, 6, 2, 0,
|
0, 6, 2, 0,
|
||||||
/*0, 7, 2, 0,*/
|
/*0, 7, 2, 0,*/
|
||||||
@ -1513,19 +1471,7 @@ static struct setup_smp_result setup_smp8(int needs_reset)
|
|||||||
/* ready to enable RT for Node 7 */
|
/* ready to enable RT for Node 7 */
|
||||||
enable_routing(7); /* enable routing on node 7 (temp.) */
|
enable_routing(7); /* enable routing on node 7 (temp.) */
|
||||||
|
|
||||||
static const uint8_t opt_conn8[] ={
|
return nodes;
|
||||||
4, 6,
|
|
||||||
#if CROSS_BAR_47_56
|
|
||||||
4, 7,
|
|
||||||
5, 6,
|
|
||||||
#endif
|
|
||||||
5, 7,
|
|
||||||
6, 7,
|
|
||||||
};
|
|
||||||
/* optimize physical connections - by LYH */
|
|
||||||
result.needs_reset |= optimize_connection_group(opt_conn8, sizeof(opt_conn8)/sizeof(opt_conn8[0]));
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_MAX_PHYSICAL_CPUS > 6 */
|
#endif /* CONFIG_MAX_PHYSICAL_CPUS > 6 */
|
||||||
@ -1533,36 +1479,36 @@ static struct setup_smp_result setup_smp8(int needs_reset)
|
|||||||
|
|
||||||
#if CONFIG_MAX_PHYSICAL_CPUS > 1
|
#if CONFIG_MAX_PHYSICAL_CPUS > 1
|
||||||
|
|
||||||
static struct setup_smp_result setup_smp(void)
|
static unsigned setup_smp(void)
|
||||||
{
|
{
|
||||||
struct setup_smp_result result;
|
unsigned nodes;
|
||||||
|
|
||||||
print_spew("Enabling SMP settings\r\n");
|
print_spew("Enabling SMP settings\r\n");
|
||||||
|
|
||||||
result = setup_smp2();
|
nodes = setup_smp2();
|
||||||
#if CONFIG_MAX_PHYSICAL_CPUS > 2
|
#if CONFIG_MAX_PHYSICAL_CPUS > 2
|
||||||
if(result.nodes == 2)
|
if(nodes == 2)
|
||||||
result = setup_smp4(result.needs_reset);
|
nodes = setup_smp4();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CONFIG_MAX_PHYSICAL_CPUS > 4
|
#if CONFIG_MAX_PHYSICAL_CPUS > 4
|
||||||
if(result.nodes == 4)
|
if(nodes == 4)
|
||||||
result = setup_smp6(result.needs_reset);
|
nodes = setup_smp6();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CONFIG_MAX_PHYSICAL_CPUS > 6
|
#if CONFIG_MAX_PHYSICAL_CPUS > 6
|
||||||
if(result.nodes == 6)
|
if(nodes == 6)
|
||||||
result = setup_smp8(result.needs_reset);
|
nodes = setup_smp8();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CONFIG_USE_INIT
|
#if CONFIG_USE_PRINTK_IN_CAR
|
||||||
printk_debug("%02x nodes initialized.\r\n", result.nodes);
|
printk_debug("%02x nodes initialized.\r\n", nodes);
|
||||||
#else
|
#else
|
||||||
print_debug_hex8(result.nodes);
|
print_debug_hex8(nodes);
|
||||||
print_debug(" nodes initialized.\r\n");
|
print_debug(" nodes initialized.\r\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return result;
|
return nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned verify_mp_capabilities(unsigned nodes)
|
static unsigned verify_mp_capabilities(unsigned nodes)
|
||||||
@ -1601,7 +1547,7 @@ static void clear_dead_routes(unsigned nodes)
|
|||||||
{
|
{
|
||||||
int last_row;
|
int last_row;
|
||||||
int node, row;
|
int node, row;
|
||||||
#if CONFIG_MAX_PHYSICAL_CPUS > 6
|
#if CONFIG_MAX_PHYSICAL_CPUS == 8
|
||||||
if(nodes==8) return;/* don't touch (7,7)*/
|
if(nodes==8) return;/* don't touch (7,7)*/
|
||||||
#endif
|
#endif
|
||||||
last_row = nodes;
|
last_row = nodes;
|
||||||
@ -1625,9 +1571,9 @@ static void clear_dead_routes(unsigned nodes)
|
|||||||
}
|
}
|
||||||
#endif /* CONFIG_MAX_PHYSICAL_CPUS > 1 */
|
#endif /* CONFIG_MAX_PHYSICAL_CPUS > 1 */
|
||||||
|
|
||||||
static unsigned count_cpus(unsigned nodes)
|
|
||||||
{
|
|
||||||
#if CONFIG_LOGICAL_CPUS==1
|
#if CONFIG_LOGICAL_CPUS==1
|
||||||
|
static unsigned verify_dualcore(unsigned nodes)
|
||||||
|
{
|
||||||
unsigned node, totalcpus, tmp;
|
unsigned node, totalcpus, tmp;
|
||||||
|
|
||||||
totalcpus = 0;
|
totalcpus = 0;
|
||||||
@ -1637,24 +1583,26 @@ static unsigned count_cpus(unsigned nodes)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return totalcpus;
|
return totalcpus;
|
||||||
#else
|
|
||||||
return nodes;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
static inline unsigned get_nodes(void)
|
#endif
|
||||||
{
|
|
||||||
return ((pci_read_config32(PCI_DEV(0, 0x18, 0), 0x60)>>4) & 7) + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void coherent_ht_finalize(unsigned nodes)
|
static void coherent_ht_finalize(unsigned nodes)
|
||||||
{
|
{
|
||||||
unsigned total_cpus;
|
|
||||||
unsigned cpu_node_count;
|
|
||||||
unsigned node;
|
unsigned node;
|
||||||
|
#if K8_REV_F_SUPPORT == 0
|
||||||
int rev_a0;
|
int rev_a0;
|
||||||
total_cpus = count_cpus(nodes);
|
#endif
|
||||||
cpu_node_count = ((total_cpus -1)<<16)|((nodes - 1) << 4);
|
#if CONFIG_LOGICAL_CPUS==1
|
||||||
|
unsigned total_cpus;
|
||||||
|
|
||||||
|
if(read_option(CMOS_VSTART_dual_core, CMOS_VLEN_dual_core, 0) == 0) { /* dual_core */
|
||||||
|
total_cpus = verify_dualcore(nodes);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
total_cpus = nodes;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* set up cpu count and node count and enable Limit
|
/* set up cpu count and node count and enable Limit
|
||||||
* Config Space Range for all available CPUs.
|
* Config Space Range for all available CPUs.
|
||||||
@ -1663,7 +1611,9 @@ static void coherent_ht_finalize(unsigned nodes)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
print_spew("coherent_ht_finalize\r\n");
|
print_spew("coherent_ht_finalize\r\n");
|
||||||
|
#if K8_REV_F_SUPPORT == 0
|
||||||
rev_a0 = is_cpu_rev_a0();
|
rev_a0 = is_cpu_rev_a0();
|
||||||
|
#endif
|
||||||
for (node = 0; node < nodes; node++) {
|
for (node = 0; node < nodes; node++) {
|
||||||
device_t dev;
|
device_t dev;
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
@ -1672,7 +1622,11 @@ static void coherent_ht_finalize(unsigned nodes)
|
|||||||
/* Set the Total CPU and Node count in the system */
|
/* Set the Total CPU and Node count in the system */
|
||||||
val = pci_read_config32(dev, 0x60);
|
val = pci_read_config32(dev, 0x60);
|
||||||
val &= (~0x000F0070);
|
val &= (~0x000F0070);
|
||||||
val |= cpu_node_count;
|
#if CONFIG_LOGICAL_CPUS==1
|
||||||
|
val |= ((total_cpus-1)<<16)|((nodes-1)<<4);
|
||||||
|
#else
|
||||||
|
val |= ((nodes-1)<<16)|((nodes-1)<<4);
|
||||||
|
#endif
|
||||||
pci_write_config32(dev, 0x60, val);
|
pci_write_config32(dev, 0x60, val);
|
||||||
|
|
||||||
/* Only respond to real cpu pci configuration cycles
|
/* Only respond to real cpu pci configuration cycles
|
||||||
@ -1688,23 +1642,27 @@ static void coherent_ht_finalize(unsigned nodes)
|
|||||||
(3 << HTTC_HI_PRI_BYP_CNT_SHIFT);
|
(3 << HTTC_HI_PRI_BYP_CNT_SHIFT);
|
||||||
pci_write_config32(dev, HT_TRANSACTION_CONTROL, val);
|
pci_write_config32(dev, HT_TRANSACTION_CONTROL, val);
|
||||||
|
|
||||||
|
#if K8_REV_F_SUPPORT == 0
|
||||||
if (rev_a0) {
|
if (rev_a0) {
|
||||||
pci_write_config32(dev, 0x94, 0);
|
pci_write_config32(dev, 0x94, 0);
|
||||||
pci_write_config32(dev, 0xb4, 0);
|
pci_write_config32(dev, 0xb4, 0);
|
||||||
pci_write_config32(dev, 0xd4, 0);
|
pci_write_config32(dev, 0xd4, 0);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
print_spew("done\r\n");
|
print_spew("done\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int apply_cpu_errata_fixes(unsigned nodes, int needs_reset)
|
static int apply_cpu_errata_fixes(unsigned nodes)
|
||||||
{
|
{
|
||||||
unsigned node;
|
unsigned node;
|
||||||
|
int needs_reset = 0;
|
||||||
for(node = 0; node < nodes; node++) {
|
for(node = 0; node < nodes; node++) {
|
||||||
device_t dev;
|
device_t dev;
|
||||||
uint32_t cmd;
|
uint32_t cmd;
|
||||||
dev = NODE_MC(node);
|
dev = NODE_MC(node);
|
||||||
|
#if K8_REV_F_SUPPORT == 0
|
||||||
if (is_cpu_pre_c0()) {
|
if (is_cpu_pre_c0()) {
|
||||||
|
|
||||||
/* Errata 66
|
/* Errata 66
|
||||||
@ -1746,13 +1704,15 @@ static int apply_cpu_errata_fixes(unsigned nodes, int needs_reset)
|
|||||||
needs_reset = 1; /* Needed? */
|
needs_reset = 1; /* Needed? */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return needs_reset;
|
return needs_reset;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int optimize_link_read_pointers(unsigned nodes, int needs_reset)
|
static int optimize_link_read_pointers(unsigned nodes)
|
||||||
{
|
{
|
||||||
unsigned node;
|
unsigned node;
|
||||||
|
int needs_reset = 0;
|
||||||
for(node = 0; node < nodes; node++) {
|
for(node = 0; node < nodes; node++) {
|
||||||
device_t f0_dev, f3_dev;
|
device_t f0_dev, f3_dev;
|
||||||
uint32_t cmd_ref, cmd;
|
uint32_t cmd_ref, cmd;
|
||||||
@ -1782,58 +1742,98 @@ static int optimize_link_read_pointers(unsigned nodes, int needs_reset)
|
|||||||
return needs_reset;
|
return needs_reset;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void startup_other_cores(unsigned nodes)
|
static inline unsigned get_nodes(void)
|
||||||
{
|
{
|
||||||
unsigned node;
|
return ((pci_read_config32(PCI_DEV(0, 0x18, 0), 0x60)>>4) & 7) + 1;
|
||||||
for(node = 0; node < nodes; node++) {
|
|
||||||
device_t dev;
|
|
||||||
unsigned siblings;
|
|
||||||
dev = NODE_MC(node);
|
|
||||||
siblings = (pci_read_config32(dev, 0xe8) >> 12) & 0x3;
|
|
||||||
|
|
||||||
if (siblings) {
|
|
||||||
device_t dev_f0;
|
|
||||||
unsigned val;
|
|
||||||
/* Redirect all MC4 accesses and error logging to core0 */
|
|
||||||
val = pci_read_config32(dev, 0x44);
|
|
||||||
val |= (1 << 27); //NbMcaToMstCpuEn bit
|
|
||||||
pci_write_config32(dev, 0x44, val);
|
|
||||||
|
|
||||||
/* Enable the second core */
|
|
||||||
dev_f0 = NODE_HT(node);
|
|
||||||
val = pci_read_config32(dev_f0, 0x68);
|
|
||||||
val |= ( 1 << 5);
|
|
||||||
pci_write_config32(dev_f0, 0x68, val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int optimize_link_coherent_ht(void)
|
||||||
static int setup_coherent_ht_domain(void)
|
|
||||||
{
|
{
|
||||||
struct setup_smp_result result;
|
int needs_reset = 0;
|
||||||
result.nodes = 1;
|
|
||||||
result.needs_reset = 0;
|
|
||||||
|
|
||||||
#if K8_HT_CHECK_PENDING_LINK == 1
|
unsigned nodes;
|
||||||
//needed?
|
|
||||||
wait_ht_stable(0);
|
nodes = get_nodes();
|
||||||
|
|
||||||
|
#if CONFIG_MAX_PHYSICAL_CPUS > 1
|
||||||
|
if(nodes>1) {
|
||||||
|
needs_reset |= optimize_connection(
|
||||||
|
NODE_HT(0), 0x80 + link_to_register(link_connection(0,1)),
|
||||||
|
NODE_HT(1), 0x80 + link_to_register(link_connection(1,0)) );
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CONFIG_MAX_PHYSICAL_CPUS > 2
|
||||||
|
if(nodes>2) {
|
||||||
|
/* optimize physical connections - by LYH */
|
||||||
|
static const u8 opt_conn4[] = {
|
||||||
|
0,2,
|
||||||
|
1,3,
|
||||||
|
2,3,
|
||||||
|
};
|
||||||
|
needs_reset |= optimize_connection_group(opt_conn4, sizeof(opt_conn4)/sizeof(opt_conn4[0]));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_MAX_PHYSICAL_CPUS > 4
|
||||||
|
if(nodes>4) {
|
||||||
|
static const uint8_t opt_conn6[] ={
|
||||||
|
2, 4,
|
||||||
|
3, 5,
|
||||||
|
#if !CROSS_BAR_47_56
|
||||||
|
4, 5,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
needs_reset |= optimize_connection_group(opt_conn6, sizeof(opt_conn6)/sizeof(opt_conn6[0]));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_MAX_PHYSICAL_CPUS > 6
|
||||||
|
if(nodes>6) {
|
||||||
|
static const uint8_t opt_conn8[] ={
|
||||||
|
4, 6,
|
||||||
|
#if CROSS_BAR_47_56
|
||||||
|
4, 7,
|
||||||
|
5, 6,
|
||||||
|
#endif
|
||||||
|
5, 7,
|
||||||
|
6, 7,
|
||||||
|
};
|
||||||
|
needs_reset |= optimize_connection_group(opt_conn8, sizeof(opt_conn8)/sizeof(opt_conn8[0]));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
needs_reset |= apply_cpu_errata_fixes(nodes);
|
||||||
|
needs_reset |= optimize_link_read_pointers(nodes);
|
||||||
|
|
||||||
|
return needs_reset;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if RAMINIT_SYSINFO == 1
|
||||||
|
static void setup_coherent_ht_domain(void)
|
||||||
|
#else
|
||||||
|
static int setup_coherent_ht_domain(void)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
unsigned nodes;
|
||||||
|
nodes = 1;
|
||||||
|
|
||||||
enable_bsp_routing();
|
enable_bsp_routing();
|
||||||
|
|
||||||
#if CONFIG_MAX_PHYSICAL_CPUS > 1
|
#if CONFIG_MAX_PHYSICAL_CPUS > 1
|
||||||
result = setup_smp();
|
nodes = setup_smp();
|
||||||
result.nodes = verify_mp_capabilities(result.nodes);
|
nodes = verify_mp_capabilities(nodes);
|
||||||
clear_dead_routes(result.nodes);
|
clear_dead_routes(nodes);
|
||||||
#endif
|
#endif
|
||||||
if (result.nodes == 1) {
|
|
||||||
|
if (nodes == 1) {
|
||||||
setup_uniprocessor();
|
setup_uniprocessor();
|
||||||
}
|
}
|
||||||
coherent_ht_finalize(result.nodes);
|
coherent_ht_finalize(nodes);
|
||||||
startup_other_cores(result.nodes);
|
|
||||||
result.needs_reset = apply_cpu_errata_fixes(result.nodes, result.needs_reset);
|
#if RAMINIT_SYSINFO == 0
|
||||||
result.needs_reset = optimize_link_read_pointers(result.nodes, result.needs_reset);
|
return optimize_link_coherent_ht();
|
||||||
return result.needs_reset;
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
@ -13,6 +13,8 @@ static void enumerate_ht_chain(void)
|
|||||||
* links needs to be programed to point at bus 0.
|
* links needs to be programed to point at bus 0.
|
||||||
*/
|
*/
|
||||||
unsigned next_unitid, last_unitid;
|
unsigned next_unitid, last_unitid;
|
||||||
|
unsigned temp_unitid;
|
||||||
|
unsigned not_use_count;
|
||||||
#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE
|
#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE
|
||||||
//let't record the device of last ht device, So we can set the Unitid to HT_CHAIN_END_UNITID_BASE
|
//let't record the device of last ht device, So we can set the Unitid to HT_CHAIN_END_UNITID_BASE
|
||||||
unsigned real_last_unitid;
|
unsigned real_last_unitid;
|
||||||
@ -60,13 +62,20 @@ static void enumerate_ht_chain(void)
|
|||||||
unsigned ctrl, ctrl_off;
|
unsigned ctrl, ctrl_off;
|
||||||
|
|
||||||
flags &= ~0x1f;
|
flags &= ~0x1f;
|
||||||
flags |= next_unitid & 0x1f;
|
|
||||||
count = (flags >> 5) & 0x1f;
|
count = (flags >> 5) & 0x1f;
|
||||||
|
not_use_count = 0;
|
||||||
|
temp_unitid = next_unitid;
|
||||||
#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE
|
#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE
|
||||||
real_last_unitid = next_unitid;
|
if ( (count + next_unitid) >= 0x20) {
|
||||||
|
temp_unitid = HT_CHAIN_END_UNITID_BASE;
|
||||||
|
not_use_count = 1;
|
||||||
|
}
|
||||||
|
real_last_unitid = temp_unitid;
|
||||||
real_last_pos = pos;
|
real_last_pos = pos;
|
||||||
ht_dev_num++;
|
ht_dev_num++;
|
||||||
#endif
|
#endif
|
||||||
|
flags |= temp_unitid & 0x1f;
|
||||||
|
if(!not_use_count)
|
||||||
next_unitid += count;
|
next_unitid += count;
|
||||||
|
|
||||||
/* Test for end of chain */
|
/* Test for end of chain */
|
||||||
@ -87,8 +96,9 @@ static void enumerate_ht_chain(void)
|
|||||||
pos = pci_read_config8(PCI_DEV(0, 0, 0), pos + PCI_CAP_LIST_NEXT);
|
pos = pci_read_config8(PCI_DEV(0, 0, 0), pos + PCI_CAP_LIST_NEXT);
|
||||||
}
|
}
|
||||||
} while((last_unitid != next_unitid) && (next_unitid <= 0x1f));
|
} while((last_unitid != next_unitid) && (next_unitid <= 0x1f));
|
||||||
|
|
||||||
#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE
|
#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE
|
||||||
if(ht_dev_num>0) {
|
if((ht_dev_num>1) && (real_last_unitid != HT_CHAIN_END_UNITID_BASE)) {
|
||||||
uint16_t flags;
|
uint16_t flags;
|
||||||
flags = pci_read_config16(PCI_DEV(0,real_last_unitid,0), real_last_pos + PCI_CAP_FLAGS);
|
flags = pci_read_config16(PCI_DEV(0,real_last_unitid,0), real_last_pos + PCI_CAP_FLAGS);
|
||||||
flags &= ~0x1f;
|
flags &= ~0x1f;
|
||||||
|
@ -162,6 +162,24 @@ static uint16_t ht_read_freq_cap(device_t dev, uint8_t pos)
|
|||||||
|
|
||||||
return freq_cap;
|
return freq_cap;
|
||||||
}
|
}
|
||||||
|
static uint8_t ht_read_width_cap(device_t dev, uint8_t pos)
|
||||||
|
{
|
||||||
|
uint8_t width_cap = pci_read_config8(dev, pos);
|
||||||
|
|
||||||
|
uint32_t id;
|
||||||
|
|
||||||
|
id = pci_read_config32(dev, 0);
|
||||||
|
|
||||||
|
/* netlogic micro cap doesn't support 16 bit yet */
|
||||||
|
if (id == (0x184e | (0x0001 << 16))) {
|
||||||
|
if((width_cap & 0x77) == 0x11) {
|
||||||
|
width_cap &= 0x88;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return width_cap;
|
||||||
|
|
||||||
|
}
|
||||||
#define LINK_OFFS(CTRL, WIDTH,FREQ,FREQ_CAP) \
|
#define LINK_OFFS(CTRL, WIDTH,FREQ,FREQ_CAP) \
|
||||||
(((CTRL & 0xff) << 24) | ((WIDTH & 0xff) << 16) | ((FREQ & 0xff) << 8) | (FREQ_CAP & 0xFF))
|
(((CTRL & 0xff) << 24) | ((WIDTH & 0xff) << 16) | ((FREQ & 0xff) << 8) | (FREQ_CAP & 0xFF))
|
||||||
|
|
||||||
@ -223,8 +241,8 @@ static int ht_optimize_link(
|
|||||||
pci_write_config8(dev2, pos2 + LINK_FREQ(offs2), freq);
|
pci_write_config8(dev2, pos2 + LINK_FREQ(offs2), freq);
|
||||||
|
|
||||||
/* Get the width capabilities */
|
/* Get the width capabilities */
|
||||||
width_cap1 = pci_read_config8(dev1, pos1 + LINK_WIDTH(offs1));
|
width_cap1 = ht_read_width_cap(dev1, pos1 + LINK_WIDTH(offs1));
|
||||||
width_cap2 = pci_read_config8(dev2, pos2 + LINK_WIDTH(offs2));
|
width_cap2 = ht_read_width_cap(dev2, pos2 + LINK_WIDTH(offs2));
|
||||||
|
|
||||||
/* Calculate dev1's input width */
|
/* Calculate dev1's input width */
|
||||||
ln_width1 = link_width_to_pow2[width_cap1 & 7];
|
ln_width1 = link_width_to_pow2[width_cap1 & 7];
|
||||||
@ -402,6 +420,8 @@ static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned of
|
|||||||
|
|
||||||
uint8_t next_unitid, last_unitid;
|
uint8_t next_unitid, last_unitid;
|
||||||
unsigned uoffs;
|
unsigned uoffs;
|
||||||
|
uint8_t temp_unitid;
|
||||||
|
unsigned not_use_count;
|
||||||
|
|
||||||
#if RAMINIT_SYSINFO == 0
|
#if RAMINIT_SYSINFO == 0
|
||||||
int reset_needed = 0;
|
int reset_needed = 0;
|
||||||
@ -473,25 +493,35 @@ static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned of
|
|||||||
|
|
||||||
/* Update the Unitid of the current device */
|
/* Update the Unitid of the current device */
|
||||||
flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
|
flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
|
||||||
flags &= ~0x1f; /* mask out the bse Unit ID */
|
|
||||||
flags |= next_unitid & 0x1f;
|
|
||||||
pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
|
|
||||||
|
|
||||||
/* Note the change in device number */
|
|
||||||
dev = PCI_DEV(bus, next_unitid, 0);
|
|
||||||
|
|
||||||
/* Compute the number of unitids consumed */
|
/* Compute the number of unitids consumed */
|
||||||
count = (flags >> 5) & 0x1f;
|
count = (flags >> 5) & 0x1f;
|
||||||
|
flags &= ~0x1f; /* mask out the base Unit ID */
|
||||||
|
|
||||||
|
not_use_count = 0;
|
||||||
|
temp_unitid = next_unitid;
|
||||||
#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE
|
#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE
|
||||||
if(offset_unitid) {
|
if(offset_unitid) {
|
||||||
real_last_unitid = next_unitid;
|
if( (next_unitid + count) >= 0x20) {
|
||||||
|
temp_unitid = HT_CHAIN_END_UNITID_BASE;
|
||||||
|
// keep to use the old next_unitid
|
||||||
|
not_use_count = 1;
|
||||||
|
}
|
||||||
real_last_pos = pos;
|
real_last_pos = pos;
|
||||||
|
real_last_unitid = temp_unitid;
|
||||||
ht_dev_num++;
|
ht_dev_num++;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
flags |= temp_unitid & 0x1f;
|
||||||
|
pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
|
||||||
|
|
||||||
|
/* Note the change in device number */
|
||||||
|
dev = PCI_DEV(bus, temp_unitid, 0);
|
||||||
|
|
||||||
|
if(!not_use_count)
|
||||||
next_unitid += count;
|
next_unitid += count;
|
||||||
|
|
||||||
|
|
||||||
/* Find which side of the ht link we are on,
|
/* Find which side of the ht link we are on,
|
||||||
* by reading which direction our last write to PCI_CAP_FLAGS
|
* by reading which direction our last write to PCI_CAP_FLAGS
|
||||||
* came from.
|
* came from.
|
||||||
@ -525,7 +555,7 @@ static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned of
|
|||||||
end_of_chain: ;
|
end_of_chain: ;
|
||||||
|
|
||||||
#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE
|
#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE
|
||||||
if(offset_unitid && (ht_dev_num>0) ) {
|
if(offset_unitid && (ht_dev_num>1) && (real_last_unitid != HT_CHAIN_END_UNITID_BASE) ) {
|
||||||
uint16_t flags;
|
uint16_t flags;
|
||||||
int i;
|
int i;
|
||||||
flags = pci_read_config16(PCI_DEV(bus,real_last_unitid,0), real_last_pos + PCI_CAP_FLAGS);
|
flags = pci_read_config16(PCI_DEV(bus,real_last_unitid,0), real_last_pos + PCI_CAP_FLAGS);
|
||||||
@ -690,14 +720,7 @@ static int set_ht_link_buffer_counts_chain(uint8_t ht_c_num, unsigned vendorid,
|
|||||||
uint32_t reg;
|
uint32_t reg;
|
||||||
uint8_t nodeid, linkn;
|
uint8_t nodeid, linkn;
|
||||||
uint8_t busn;
|
uint8_t busn;
|
||||||
unsigned devn = 1;
|
unsigned devn;
|
||||||
|
|
||||||
#if HT_CHAIN_UNITID_BASE != 1
|
|
||||||
#if SB_HT_CHAIN_UNITID_OFFSET_ONLY == 1
|
|
||||||
if(i==0) // to check if it is sb ht chain
|
|
||||||
#endif
|
|
||||||
devn = HT_CHAIN_UNITID_BASE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
reg = pci_read_config32(PCI_DEV(0,0x18,1), 0xe0 + i * 4);
|
reg = pci_read_config32(PCI_DEV(0,0x18,1), 0xe0 + i * 4);
|
||||||
if((reg & 3) != 3) continue; // not enabled
|
if((reg & 3) != 3) continue; // not enabled
|
||||||
@ -706,9 +729,12 @@ static int set_ht_link_buffer_counts_chain(uint8_t ht_c_num, unsigned vendorid,
|
|||||||
linkn = ((reg & 0xf00)>>8); // link n
|
linkn = ((reg & 0xf00)>>8); // link n
|
||||||
busn = (reg & 0xff0000)>>16; //busn
|
busn = (reg & 0xff0000)>>16; //busn
|
||||||
|
|
||||||
|
for(devn = 0; devn < 0x20; devn++) {
|
||||||
reg = pci_read_config32( PCI_DEV(busn, devn, 0), PCI_VENDOR_ID); //1?
|
reg = pci_read_config32( PCI_DEV(busn, devn, 0), PCI_VENDOR_ID); //1?
|
||||||
if ( (reg & 0xffff) == vendorid ) {
|
if ( (reg & 0xffff) == vendorid ) {
|
||||||
reset_needed |= set_ht_link_buffer_count(nodeid, linkn, 0x07,val);
|
reset_needed |= set_ht_link_buffer_count(nodeid, linkn, 0x07,val);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user