Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/ia64/sn/pci/pcibr/pcibr_reg.c
15133 views
1
/*
2
* This file is subject to the terms and conditions of the GNU General Public
3
* License. See the file "COPYING" in the main directory of this archive
4
* for more details.
5
*
6
* Copyright (C) 2004 Silicon Graphics, Inc. All rights reserved.
7
*/
8
9
#include <linux/interrupt.h>
10
#include <linux/types.h>
11
#include <asm/sn/io.h>
12
#include <asm/sn/pcibr_provider.h>
13
#include <asm/sn/pcibus_provider_defs.h>
14
#include <asm/sn/pcidev.h>
15
#include <asm/sn/pic.h>
16
#include <asm/sn/tiocp.h>
17
18
union br_ptr {
19
struct tiocp tio;
20
struct pic pic;
21
};
22
23
/*
24
* Control Register Access -- Read/Write 0000_0020
25
*/
26
void pcireg_control_bit_clr(struct pcibus_info *pcibus_info, u64 bits)
27
{
28
union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
29
30
if (pcibus_info) {
31
switch (pcibus_info->pbi_bridge_type) {
32
case PCIBR_BRIDGETYPE_TIOCP:
33
__sn_clrq_relaxed(&ptr->tio.cp_control, bits);
34
break;
35
case PCIBR_BRIDGETYPE_PIC:
36
__sn_clrq_relaxed(&ptr->pic.p_wid_control, bits);
37
break;
38
default:
39
panic
40
("pcireg_control_bit_clr: unknown bridgetype bridge 0x%p",
41
ptr);
42
}
43
}
44
}
45
46
void pcireg_control_bit_set(struct pcibus_info *pcibus_info, u64 bits)
47
{
48
union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
49
50
if (pcibus_info) {
51
switch (pcibus_info->pbi_bridge_type) {
52
case PCIBR_BRIDGETYPE_TIOCP:
53
__sn_setq_relaxed(&ptr->tio.cp_control, bits);
54
break;
55
case PCIBR_BRIDGETYPE_PIC:
56
__sn_setq_relaxed(&ptr->pic.p_wid_control, bits);
57
break;
58
default:
59
panic
60
("pcireg_control_bit_set: unknown bridgetype bridge 0x%p",
61
ptr);
62
}
63
}
64
}
65
66
/*
67
* PCI/PCIX Target Flush Register Access -- Read Only 0000_0050
68
*/
69
u64 pcireg_tflush_get(struct pcibus_info *pcibus_info)
70
{
71
union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
72
u64 ret = 0;
73
74
if (pcibus_info) {
75
switch (pcibus_info->pbi_bridge_type) {
76
case PCIBR_BRIDGETYPE_TIOCP:
77
ret = __sn_readq_relaxed(&ptr->tio.cp_tflush);
78
break;
79
case PCIBR_BRIDGETYPE_PIC:
80
ret = __sn_readq_relaxed(&ptr->pic.p_wid_tflush);
81
break;
82
default:
83
panic
84
("pcireg_tflush_get: unknown bridgetype bridge 0x%p",
85
ptr);
86
}
87
}
88
89
/* Read of the Target Flush should always return zero */
90
if (ret != 0)
91
panic("pcireg_tflush_get:Target Flush failed\n");
92
93
return ret;
94
}
95
96
/*
97
* Interrupt Status Register Access -- Read Only 0000_0100
98
*/
99
u64 pcireg_intr_status_get(struct pcibus_info * pcibus_info)
100
{
101
union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
102
u64 ret = 0;
103
104
if (pcibus_info) {
105
switch (pcibus_info->pbi_bridge_type) {
106
case PCIBR_BRIDGETYPE_TIOCP:
107
ret = __sn_readq_relaxed(&ptr->tio.cp_int_status);
108
break;
109
case PCIBR_BRIDGETYPE_PIC:
110
ret = __sn_readq_relaxed(&ptr->pic.p_int_status);
111
break;
112
default:
113
panic
114
("pcireg_intr_status_get: unknown bridgetype bridge 0x%p",
115
ptr);
116
}
117
}
118
return ret;
119
}
120
121
/*
122
* Interrupt Enable Register Access -- Read/Write 0000_0108
123
*/
124
void pcireg_intr_enable_bit_clr(struct pcibus_info *pcibus_info, u64 bits)
125
{
126
union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
127
128
if (pcibus_info) {
129
switch (pcibus_info->pbi_bridge_type) {
130
case PCIBR_BRIDGETYPE_TIOCP:
131
__sn_clrq_relaxed(&ptr->tio.cp_int_enable, bits);
132
break;
133
case PCIBR_BRIDGETYPE_PIC:
134
__sn_clrq_relaxed(&ptr->pic.p_int_enable, bits);
135
break;
136
default:
137
panic
138
("pcireg_intr_enable_bit_clr: unknown bridgetype bridge 0x%p",
139
ptr);
140
}
141
}
142
}
143
144
void pcireg_intr_enable_bit_set(struct pcibus_info *pcibus_info, u64 bits)
145
{
146
union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
147
148
if (pcibus_info) {
149
switch (pcibus_info->pbi_bridge_type) {
150
case PCIBR_BRIDGETYPE_TIOCP:
151
__sn_setq_relaxed(&ptr->tio.cp_int_enable, bits);
152
break;
153
case PCIBR_BRIDGETYPE_PIC:
154
__sn_setq_relaxed(&ptr->pic.p_int_enable, bits);
155
break;
156
default:
157
panic
158
("pcireg_intr_enable_bit_set: unknown bridgetype bridge 0x%p",
159
ptr);
160
}
161
}
162
}
163
164
/*
165
* Intr Host Address Register (int_addr) -- Read/Write 0000_0130 - 0000_0168
166
*/
167
void pcireg_intr_addr_addr_set(struct pcibus_info *pcibus_info, int int_n,
168
u64 addr)
169
{
170
union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
171
172
if (pcibus_info) {
173
switch (pcibus_info->pbi_bridge_type) {
174
case PCIBR_BRIDGETYPE_TIOCP:
175
__sn_clrq_relaxed(&ptr->tio.cp_int_addr[int_n],
176
TIOCP_HOST_INTR_ADDR);
177
__sn_setq_relaxed(&ptr->tio.cp_int_addr[int_n],
178
(addr & TIOCP_HOST_INTR_ADDR));
179
break;
180
case PCIBR_BRIDGETYPE_PIC:
181
__sn_clrq_relaxed(&ptr->pic.p_int_addr[int_n],
182
PIC_HOST_INTR_ADDR);
183
__sn_setq_relaxed(&ptr->pic.p_int_addr[int_n],
184
(addr & PIC_HOST_INTR_ADDR));
185
break;
186
default:
187
panic
188
("pcireg_intr_addr_addr_get: unknown bridgetype bridge 0x%p",
189
ptr);
190
}
191
}
192
}
193
194
/*
195
* Force Interrupt Register Access -- Write Only 0000_01C0 - 0000_01F8
196
*/
197
void pcireg_force_intr_set(struct pcibus_info *pcibus_info, int int_n)
198
{
199
union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
200
201
if (pcibus_info) {
202
switch (pcibus_info->pbi_bridge_type) {
203
case PCIBR_BRIDGETYPE_TIOCP:
204
writeq(1, &ptr->tio.cp_force_pin[int_n]);
205
break;
206
case PCIBR_BRIDGETYPE_PIC:
207
writeq(1, &ptr->pic.p_force_pin[int_n]);
208
break;
209
default:
210
panic
211
("pcireg_force_intr_set: unknown bridgetype bridge 0x%p",
212
ptr);
213
}
214
}
215
}
216
217
/*
218
* Device(x) Write Buffer Flush Reg Access -- Read Only 0000_0240 - 0000_0258
219
*/
220
u64 pcireg_wrb_flush_get(struct pcibus_info *pcibus_info, int device)
221
{
222
union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
223
u64 ret = 0;
224
225
if (pcibus_info) {
226
switch (pcibus_info->pbi_bridge_type) {
227
case PCIBR_BRIDGETYPE_TIOCP:
228
ret =
229
__sn_readq_relaxed(&ptr->tio.cp_wr_req_buf[device]);
230
break;
231
case PCIBR_BRIDGETYPE_PIC:
232
ret =
233
__sn_readq_relaxed(&ptr->pic.p_wr_req_buf[device]);
234
break;
235
default:
236
panic("pcireg_wrb_flush_get: unknown bridgetype bridge 0x%p", ptr);
237
}
238
239
}
240
/* Read of the Write Buffer Flush should always return zero */
241
return ret;
242
}
243
244
void pcireg_int_ate_set(struct pcibus_info *pcibus_info, int ate_index,
245
u64 val)
246
{
247
union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
248
249
if (pcibus_info) {
250
switch (pcibus_info->pbi_bridge_type) {
251
case PCIBR_BRIDGETYPE_TIOCP:
252
writeq(val, &ptr->tio.cp_int_ate_ram[ate_index]);
253
break;
254
case PCIBR_BRIDGETYPE_PIC:
255
writeq(val, &ptr->pic.p_int_ate_ram[ate_index]);
256
break;
257
default:
258
panic
259
("pcireg_int_ate_set: unknown bridgetype bridge 0x%p",
260
ptr);
261
}
262
}
263
}
264
265
u64 __iomem *pcireg_int_ate_addr(struct pcibus_info *pcibus_info, int ate_index)
266
{
267
union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
268
u64 __iomem *ret = NULL;
269
270
if (pcibus_info) {
271
switch (pcibus_info->pbi_bridge_type) {
272
case PCIBR_BRIDGETYPE_TIOCP:
273
ret = &ptr->tio.cp_int_ate_ram[ate_index];
274
break;
275
case PCIBR_BRIDGETYPE_PIC:
276
ret = &ptr->pic.p_int_ate_ram[ate_index];
277
break;
278
default:
279
panic
280
("pcireg_int_ate_addr: unknown bridgetype bridge 0x%p",
281
ptr);
282
}
283
}
284
return ret;
285
}
286
287