Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pcibr_reg.c
Go to the documentation of this file.
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>
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  */
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) {
33  __sn_clrq_relaxed(&ptr->tio.cp_control, bits);
34  break;
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 
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) {
53  __sn_setq_relaxed(&ptr->tio.cp_control, bits);
54  break;
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  */
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) {
77  ret = __sn_readq_relaxed(&ptr->tio.cp_tflush);
78  break;
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  */
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) {
107  ret = __sn_readq_relaxed(&ptr->tio.cp_int_status);
108  break;
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  */
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) {
131  __sn_clrq_relaxed(&ptr->tio.cp_int_enable, bits);
132  break;
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 
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) {
151  __sn_setq_relaxed(&ptr->tio.cp_int_enable, bits);
152  break;
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  */
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) {
175  __sn_clrq_relaxed(&ptr->tio.cp_int_addr[int_n],
177  __sn_setq_relaxed(&ptr->tio.cp_int_addr[int_n],
178  (addr & TIOCP_HOST_INTR_ADDR));
179  break;
181  __sn_clrq_relaxed(&ptr->pic.p_int_addr[int_n],
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  */
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) {
204  writeq(1, &ptr->tio.cp_force_pin[int_n]);
205  break;
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  */
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) {
228  ret =
229  __sn_readq_relaxed(&ptr->tio.cp_wr_req_buf[device]);
230  break;
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) {
252  writeq(val, &ptr->tio.cp_int_ate_ram[ate_index]);
253  break;
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 
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) {
273  ret = &ptr->tio.cp_int_ate_ram[ate_index];
274  break;
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 }