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