/home/lenb/src/to-akpm branch 'acpi-2.6.12'
[sfrench/cifs-2.6.git] / arch / ia64 / sn / pci / pcibr / pcibr_reg.c
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/pcibr_provider.h>
12 #include <asm/sn/pcibus_provider_defs.h>
13 #include <asm/sn/pcidev.h>
14 #include <asm/sn/pic.h>
15 #include <asm/sn/tiocp.h>
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 }