]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
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 | ||
1da177e4 | 9 | #include <linux/interrupt.h> |
c13cf371 | 10 | #include <linux/types.h> |
1fa92957 | 11 | #include <asm/sn/io.h> |
c13cf371 | 12 | #include <asm/sn/pcibr_provider.h> |
9b08ebd1 MM |
13 | #include <asm/sn/pcibus_provider_defs.h> |
14 | #include <asm/sn/pcidev.h> | |
c13cf371 PB |
15 | #include <asm/sn/pic.h> |
16 | #include <asm/sn/tiocp.h> | |
1da177e4 LT |
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 | */ | |
53493dcf | 26 | void pcireg_control_bit_clr(struct pcibus_info *pcibus_info, u64 bits) |
1da177e4 | 27 | { |
b3e5b5b2 | 28 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; |
1da177e4 LT |
29 | |
30 | if (pcibus_info) { | |
31 | switch (pcibus_info->pbi_bridge_type) { | |
32 | case PCIBR_BRIDGETYPE_TIOCP: | |
5fbcf9a5 | 33 | __sn_clrq_relaxed(&ptr->tio.cp_control, bits); |
1da177e4 LT |
34 | break; |
35 | case PCIBR_BRIDGETYPE_PIC: | |
5fbcf9a5 | 36 | __sn_clrq_relaxed(&ptr->pic.p_wid_control, bits); |
1da177e4 LT |
37 | break; |
38 | default: | |
39 | panic | |
40 | ("pcireg_control_bit_clr: unknown bridgetype bridge 0x%p", | |
b3e5b5b2 | 41 | ptr); |
1da177e4 LT |
42 | } |
43 | } | |
44 | } | |
45 | ||
53493dcf | 46 | void pcireg_control_bit_set(struct pcibus_info *pcibus_info, u64 bits) |
1da177e4 | 47 | { |
b3e5b5b2 | 48 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; |
1da177e4 LT |
49 | |
50 | if (pcibus_info) { | |
51 | switch (pcibus_info->pbi_bridge_type) { | |
52 | case PCIBR_BRIDGETYPE_TIOCP: | |
5fbcf9a5 | 53 | __sn_setq_relaxed(&ptr->tio.cp_control, bits); |
1da177e4 LT |
54 | break; |
55 | case PCIBR_BRIDGETYPE_PIC: | |
5fbcf9a5 | 56 | __sn_setq_relaxed(&ptr->pic.p_wid_control, bits); |
1da177e4 LT |
57 | break; |
58 | default: | |
59 | panic | |
60 | ("pcireg_control_bit_set: unknown bridgetype bridge 0x%p", | |
b3e5b5b2 | 61 | ptr); |
1da177e4 LT |
62 | } |
63 | } | |
64 | } | |
65 | ||
66 | /* | |
67 | * PCI/PCIX Target Flush Register Access -- Read Only 0000_0050 | |
68 | */ | |
53493dcf | 69 | u64 pcireg_tflush_get(struct pcibus_info *pcibus_info) |
1da177e4 | 70 | { |
b3e5b5b2 | 71 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; |
53493dcf | 72 | u64 ret = 0; |
1da177e4 LT |
73 | |
74 | if (pcibus_info) { | |
75 | switch (pcibus_info->pbi_bridge_type) { | |
76 | case PCIBR_BRIDGETYPE_TIOCP: | |
5fbcf9a5 | 77 | ret = __sn_readq_relaxed(&ptr->tio.cp_tflush); |
1da177e4 LT |
78 | break; |
79 | case PCIBR_BRIDGETYPE_PIC: | |
5fbcf9a5 | 80 | ret = __sn_readq_relaxed(&ptr->pic.p_wid_tflush); |
1da177e4 LT |
81 | break; |
82 | default: | |
83 | panic | |
84 | ("pcireg_tflush_get: unknown bridgetype bridge 0x%p", | |
b3e5b5b2 | 85 | ptr); |
1da177e4 LT |
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 | */ | |
53493dcf | 99 | u64 pcireg_intr_status_get(struct pcibus_info * pcibus_info) |
1da177e4 | 100 | { |
b3e5b5b2 | 101 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; |
53493dcf | 102 | u64 ret = 0; |
1da177e4 LT |
103 | |
104 | if (pcibus_info) { | |
105 | switch (pcibus_info->pbi_bridge_type) { | |
106 | case PCIBR_BRIDGETYPE_TIOCP: | |
5fbcf9a5 | 107 | ret = __sn_readq_relaxed(&ptr->tio.cp_int_status); |
1da177e4 LT |
108 | break; |
109 | case PCIBR_BRIDGETYPE_PIC: | |
5fbcf9a5 | 110 | ret = __sn_readq_relaxed(&ptr->pic.p_int_status); |
1da177e4 LT |
111 | break; |
112 | default: | |
113 | panic | |
114 | ("pcireg_intr_status_get: unknown bridgetype bridge 0x%p", | |
b3e5b5b2 | 115 | ptr); |
1da177e4 LT |
116 | } |
117 | } | |
118 | return ret; | |
119 | } | |
120 | ||
121 | /* | |
122 | * Interrupt Enable Register Access -- Read/Write 0000_0108 | |
123 | */ | |
53493dcf | 124 | void pcireg_intr_enable_bit_clr(struct pcibus_info *pcibus_info, u64 bits) |
1da177e4 | 125 | { |
b3e5b5b2 | 126 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; |
1da177e4 LT |
127 | |
128 | if (pcibus_info) { | |
129 | switch (pcibus_info->pbi_bridge_type) { | |
130 | case PCIBR_BRIDGETYPE_TIOCP: | |
5fbcf9a5 | 131 | __sn_clrq_relaxed(&ptr->tio.cp_int_enable, bits); |
1da177e4 LT |
132 | break; |
133 | case PCIBR_BRIDGETYPE_PIC: | |
6fb93a92 | 134 | __sn_clrq_relaxed(&ptr->pic.p_int_enable, bits); |
1da177e4 LT |
135 | break; |
136 | default: | |
137 | panic | |
138 | ("pcireg_intr_enable_bit_clr: unknown bridgetype bridge 0x%p", | |
b3e5b5b2 | 139 | ptr); |
1da177e4 LT |
140 | } |
141 | } | |
142 | } | |
143 | ||
53493dcf | 144 | void pcireg_intr_enable_bit_set(struct pcibus_info *pcibus_info, u64 bits) |
1da177e4 | 145 | { |
b3e5b5b2 | 146 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; |
1da177e4 LT |
147 | |
148 | if (pcibus_info) { | |
149 | switch (pcibus_info->pbi_bridge_type) { | |
150 | case PCIBR_BRIDGETYPE_TIOCP: | |
5fbcf9a5 | 151 | __sn_setq_relaxed(&ptr->tio.cp_int_enable, bits); |
1da177e4 LT |
152 | break; |
153 | case PCIBR_BRIDGETYPE_PIC: | |
5fbcf9a5 | 154 | __sn_setq_relaxed(&ptr->pic.p_int_enable, bits); |
1da177e4 LT |
155 | break; |
156 | default: | |
157 | panic | |
158 | ("pcireg_intr_enable_bit_set: unknown bridgetype bridge 0x%p", | |
b3e5b5b2 | 159 | ptr); |
1da177e4 LT |
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, | |
53493dcf | 168 | u64 addr) |
1da177e4 | 169 | { |
b3e5b5b2 | 170 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; |
1da177e4 LT |
171 | |
172 | if (pcibus_info) { | |
173 | switch (pcibus_info->pbi_bridge_type) { | |
174 | case PCIBR_BRIDGETYPE_TIOCP: | |
5fbcf9a5 MM |
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)); | |
1da177e4 LT |
179 | break; |
180 | case PCIBR_BRIDGETYPE_PIC: | |
5fbcf9a5 MM |
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)); | |
1da177e4 LT |
185 | break; |
186 | default: | |
187 | panic | |
188 | ("pcireg_intr_addr_addr_get: unknown bridgetype bridge 0x%p", | |
b3e5b5b2 | 189 | ptr); |
1da177e4 LT |
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 | { | |
b3e5b5b2 | 199 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; |
1da177e4 LT |
200 | |
201 | if (pcibus_info) { | |
202 | switch (pcibus_info->pbi_bridge_type) { | |
203 | case PCIBR_BRIDGETYPE_TIOCP: | |
5fbcf9a5 | 204 | writeq(1, &ptr->tio.cp_force_pin[int_n]); |
1da177e4 LT |
205 | break; |
206 | case PCIBR_BRIDGETYPE_PIC: | |
5fbcf9a5 | 207 | writeq(1, &ptr->pic.p_force_pin[int_n]); |
1da177e4 LT |
208 | break; |
209 | default: | |
210 | panic | |
211 | ("pcireg_force_intr_set: unknown bridgetype bridge 0x%p", | |
b3e5b5b2 | 212 | ptr); |
1da177e4 LT |
213 | } |
214 | } | |
215 | } | |
216 | ||
217 | /* | |
218 | * Device(x) Write Buffer Flush Reg Access -- Read Only 0000_0240 - 0000_0258 | |
219 | */ | |
53493dcf | 220 | u64 pcireg_wrb_flush_get(struct pcibus_info *pcibus_info, int device) |
1da177e4 | 221 | { |
b3e5b5b2 | 222 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; |
53493dcf | 223 | u64 ret = 0; |
1da177e4 LT |
224 | |
225 | if (pcibus_info) { | |
226 | switch (pcibus_info->pbi_bridge_type) { | |
227 | case PCIBR_BRIDGETYPE_TIOCP: | |
5fbcf9a5 MM |
228 | ret = |
229 | __sn_readq_relaxed(&ptr->tio.cp_wr_req_buf[device]); | |
1da177e4 LT |
230 | break; |
231 | case PCIBR_BRIDGETYPE_PIC: | |
5fbcf9a5 MM |
232 | ret = |
233 | __sn_readq_relaxed(&ptr->pic.p_wr_req_buf[device]); | |
1da177e4 LT |
234 | break; |
235 | default: | |
b3e5b5b2 | 236 | panic("pcireg_wrb_flush_get: unknown bridgetype bridge 0x%p", ptr); |
1da177e4 LT |
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, | |
53493dcf | 245 | u64 val) |
1da177e4 | 246 | { |
b3e5b5b2 | 247 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; |
1da177e4 LT |
248 | |
249 | if (pcibus_info) { | |
250 | switch (pcibus_info->pbi_bridge_type) { | |
251 | case PCIBR_BRIDGETYPE_TIOCP: | |
5fbcf9a5 | 252 | writeq(val, &ptr->tio.cp_int_ate_ram[ate_index]); |
1da177e4 LT |
253 | break; |
254 | case PCIBR_BRIDGETYPE_PIC: | |
5fbcf9a5 | 255 | writeq(val, &ptr->pic.p_int_ate_ram[ate_index]); |
1da177e4 LT |
256 | break; |
257 | default: | |
258 | panic | |
259 | ("pcireg_int_ate_set: unknown bridgetype bridge 0x%p", | |
b3e5b5b2 | 260 | ptr); |
1da177e4 LT |
261 | } |
262 | } | |
263 | } | |
264 | ||
53493dcf | 265 | u64 __iomem *pcireg_int_ate_addr(struct pcibus_info *pcibus_info, int ate_index) |
1da177e4 | 266 | { |
b3e5b5b2 | 267 | union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; |
53493dcf | 268 | u64 __iomem *ret = NULL; |
1da177e4 LT |
269 | |
270 | if (pcibus_info) { | |
271 | switch (pcibus_info->pbi_bridge_type) { | |
272 | case PCIBR_BRIDGETYPE_TIOCP: | |
5fbcf9a5 | 273 | ret = &ptr->tio.cp_int_ate_ram[ate_index]; |
1da177e4 LT |
274 | break; |
275 | case PCIBR_BRIDGETYPE_PIC: | |
5fbcf9a5 | 276 | ret = &ptr->pic.p_int_ate_ram[ate_index]; |
1da177e4 LT |
277 | break; |
278 | default: | |
279 | panic | |
280 | ("pcireg_int_ate_addr: unknown bridgetype bridge 0x%p", | |
b3e5b5b2 | 281 | ptr); |
1da177e4 LT |
282 | } |
283 | } | |
284 | return ret; | |
285 | } |