Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/mips/sgi-ip27/ip27-xtalk.c
10818 views
1
/*
2
* Copyright (C) 1999, 2000 Ralf Baechle ([email protected])
3
* Copyright (C) 1999, 2000 Silcon Graphics, Inc.
4
* Copyright (C) 2004 Christoph Hellwig.
5
* Released under GPL v2.
6
*
7
* Generic XTALK initialization code
8
*/
9
10
#include <linux/init.h>
11
#include <linux/kernel.h>
12
#include <linux/smp.h>
13
#include <asm/sn/types.h>
14
#include <asm/sn/klconfig.h>
15
#include <asm/sn/hub.h>
16
#include <asm/pci/bridge.h>
17
#include <asm/xtalk/xtalk.h>
18
19
20
#define XBOW_WIDGET_PART_NUM 0x0
21
#define XXBOW_WIDGET_PART_NUM 0xd000 /* Xbow in Xbridge */
22
#define BASE_XBOW_PORT 8 /* Lowest external port */
23
24
extern int bridge_probe(nasid_t nasid, int widget, int masterwid);
25
26
static int __cpuinit probe_one_port(nasid_t nasid, int widget, int masterwid)
27
{
28
widgetreg_t widget_id;
29
xwidget_part_num_t partnum;
30
31
widget_id = *(volatile widgetreg_t *)
32
(RAW_NODE_SWIN_BASE(nasid, widget) + WIDGET_ID);
33
partnum = XWIDGET_PART_NUM(widget_id);
34
35
printk(KERN_INFO "Cpu %d, Nasid 0x%x, widget 0x%x (partnum 0x%x) is ",
36
smp_processor_id(), nasid, widget, partnum);
37
38
switch (partnum) {
39
case BRIDGE_WIDGET_PART_NUM:
40
case XBRIDGE_WIDGET_PART_NUM:
41
bridge_probe(nasid, widget, masterwid);
42
break;
43
default:
44
break;
45
}
46
47
return 0;
48
}
49
50
static int __cpuinit xbow_probe(nasid_t nasid)
51
{
52
lboard_t *brd;
53
klxbow_t *xbow_p;
54
unsigned masterwid, i;
55
56
printk("is xbow\n");
57
58
/*
59
* found xbow, so may have multiple bridges
60
* need to probe xbow
61
*/
62
brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_MIDPLANE8);
63
if (!brd)
64
return -ENODEV;
65
66
xbow_p = (klxbow_t *)find_component(brd, NULL, KLSTRUCT_XBOW);
67
if (!xbow_p)
68
return -ENODEV;
69
70
/*
71
* Okay, here's a xbow. Lets arbitrate and find
72
* out if we should initialize it. Set enabled
73
* hub connected at highest or lowest widget as
74
* master.
75
*/
76
#ifdef WIDGET_A
77
i = HUB_WIDGET_ID_MAX + 1;
78
do {
79
i--;
80
} while ((!XBOW_PORT_TYPE_HUB(xbow_p, i)) ||
81
(!XBOW_PORT_IS_ENABLED(xbow_p, i)));
82
#else
83
i = HUB_WIDGET_ID_MIN - 1;
84
do {
85
i++;
86
} while ((!XBOW_PORT_TYPE_HUB(xbow_p, i)) ||
87
(!XBOW_PORT_IS_ENABLED(xbow_p, i)));
88
#endif
89
90
masterwid = i;
91
if (nasid != XBOW_PORT_NASID(xbow_p, i))
92
return 1;
93
94
for (i = HUB_WIDGET_ID_MIN; i <= HUB_WIDGET_ID_MAX; i++) {
95
if (XBOW_PORT_IS_ENABLED(xbow_p, i) &&
96
XBOW_PORT_TYPE_IO(xbow_p, i))
97
probe_one_port(nasid, i, masterwid);
98
}
99
100
return 0;
101
}
102
103
void __cpuinit xtalk_probe_node(cnodeid_t nid)
104
{
105
volatile u64 hubreg;
106
nasid_t nasid;
107
xwidget_part_num_t partnum;
108
widgetreg_t widget_id;
109
110
nasid = COMPACT_TO_NASID_NODEID(nid);
111
hubreg = REMOTE_HUB_L(nasid, IIO_LLP_CSR);
112
113
/* check whether the link is up */
114
if (!(hubreg & IIO_LLP_CSR_IS_UP))
115
return;
116
117
widget_id = *(volatile widgetreg_t *)
118
(RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID);
119
partnum = XWIDGET_PART_NUM(widget_id);
120
121
printk(KERN_INFO "Cpu %d, Nasid 0x%x: partnum 0x%x is ",
122
smp_processor_id(), nasid, partnum);
123
124
switch (partnum) {
125
case BRIDGE_WIDGET_PART_NUM:
126
bridge_probe(nasid, 0x8, 0xa);
127
break;
128
case XBOW_WIDGET_PART_NUM:
129
case XXBOW_WIDGET_PART_NUM:
130
xbow_probe(nasid);
131
break;
132
default:
133
printk(" unknown widget??\n");
134
break;
135
}
136
}
137
138