blob: 8b8bbd51d43389f8a108d7599d9d98490a8e15f1 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
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
Linus Torvalds1da177e2005-04-16 15:20:36 -07009#include <linux/interrupt.h>
Prarit Bhargavac13cf372005-07-06 15:26:51 -070010#include <linux/types.h>
Tony Luck1fa92952005-09-09 11:41:12 -070011#include <asm/sn/io.h>
Prarit Bhargavac13cf372005-07-06 15:26:51 -070012#include <asm/sn/pcibr_provider.h>
Mark Maule9b08ebd2005-04-25 11:32:16 -070013#include <asm/sn/pcibus_provider_defs.h>
14#include <asm/sn/pcidev.h>
Prarit Bhargavac13cf372005-07-06 15:26:51 -070015#include <asm/sn/pic.h>
16#include <asm/sn/tiocp.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070017
18union br_ptr {
19 struct tiocp tio;
20 struct pic pic;
21};
22
23/*
24 * Control Register Access -- Read/Write 0000_0020
25 */
Prarit Bhargava53493dc2006-01-16 19:54:40 -080026void pcireg_control_bit_clr(struct pcibus_info *pcibus_info, u64 bits)
Linus Torvalds1da177e2005-04-16 15:20:36 -070027{
Al Virob3e5b5b2005-12-15 09:18:40 +000028 union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
Linus Torvalds1da177e2005-04-16 15:20:36 -070029
30 if (pcibus_info) {
31 switch (pcibus_info->pbi_bridge_type) {
32 case PCIBR_BRIDGETYPE_TIOCP:
Mark Maule5fbcf9a2005-09-06 13:03:51 -050033 __sn_clrq_relaxed(&ptr->tio.cp_control, bits);
Linus Torvalds1da177e2005-04-16 15:20:36 -070034 break;
35 case PCIBR_BRIDGETYPE_PIC:
Mark Maule5fbcf9a2005-09-06 13:03:51 -050036 __sn_clrq_relaxed(&ptr->pic.p_wid_control, bits);
Linus Torvalds1da177e2005-04-16 15:20:36 -070037 break;
38 default:
39 panic
40 ("pcireg_control_bit_clr: unknown bridgetype bridge 0x%p",
Al Virob3e5b5b2005-12-15 09:18:40 +000041 ptr);
Linus Torvalds1da177e2005-04-16 15:20:36 -070042 }
43 }
44}
45
Prarit Bhargava53493dc2006-01-16 19:54:40 -080046void pcireg_control_bit_set(struct pcibus_info *pcibus_info, u64 bits)
Linus Torvalds1da177e2005-04-16 15:20:36 -070047{
Al Virob3e5b5b2005-12-15 09:18:40 +000048 union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
Linus Torvalds1da177e2005-04-16 15:20:36 -070049
50 if (pcibus_info) {
51 switch (pcibus_info->pbi_bridge_type) {
52 case PCIBR_BRIDGETYPE_TIOCP:
Mark Maule5fbcf9a2005-09-06 13:03:51 -050053 __sn_setq_relaxed(&ptr->tio.cp_control, bits);
Linus Torvalds1da177e2005-04-16 15:20:36 -070054 break;
55 case PCIBR_BRIDGETYPE_PIC:
Mark Maule5fbcf9a2005-09-06 13:03:51 -050056 __sn_setq_relaxed(&ptr->pic.p_wid_control, bits);
Linus Torvalds1da177e2005-04-16 15:20:36 -070057 break;
58 default:
59 panic
60 ("pcireg_control_bit_set: unknown bridgetype bridge 0x%p",
Al Virob3e5b5b2005-12-15 09:18:40 +000061 ptr);
Linus Torvalds1da177e2005-04-16 15:20:36 -070062 }
63 }
64}
65
66/*
67 * PCI/PCIX Target Flush Register Access -- Read Only 0000_0050
68 */
Prarit Bhargava53493dc2006-01-16 19:54:40 -080069u64 pcireg_tflush_get(struct pcibus_info *pcibus_info)
Linus Torvalds1da177e2005-04-16 15:20:36 -070070{
Al Virob3e5b5b2005-12-15 09:18:40 +000071 union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
Prarit Bhargava53493dc2006-01-16 19:54:40 -080072 u64 ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -070073
74 if (pcibus_info) {
75 switch (pcibus_info->pbi_bridge_type) {
76 case PCIBR_BRIDGETYPE_TIOCP:
Mark Maule5fbcf9a2005-09-06 13:03:51 -050077 ret = __sn_readq_relaxed(&ptr->tio.cp_tflush);
Linus Torvalds1da177e2005-04-16 15:20:36 -070078 break;
79 case PCIBR_BRIDGETYPE_PIC:
Mark Maule5fbcf9a2005-09-06 13:03:51 -050080 ret = __sn_readq_relaxed(&ptr->pic.p_wid_tflush);
Linus Torvalds1da177e2005-04-16 15:20:36 -070081 break;
82 default:
83 panic
84 ("pcireg_tflush_get: unknown bridgetype bridge 0x%p",
Al Virob3e5b5b2005-12-15 09:18:40 +000085 ptr);
Linus Torvalds1da177e2005-04-16 15:20:36 -070086 }
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 */
Prarit Bhargava53493dc2006-01-16 19:54:40 -080099u64 pcireg_intr_status_get(struct pcibus_info * pcibus_info)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100{
Al Virob3e5b5b2005-12-15 09:18:40 +0000101 union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
Prarit Bhargava53493dc2006-01-16 19:54:40 -0800102 u64 ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103
104 if (pcibus_info) {
105 switch (pcibus_info->pbi_bridge_type) {
106 case PCIBR_BRIDGETYPE_TIOCP:
Mark Maule5fbcf9a2005-09-06 13:03:51 -0500107 ret = __sn_readq_relaxed(&ptr->tio.cp_int_status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108 break;
109 case PCIBR_BRIDGETYPE_PIC:
Mark Maule5fbcf9a2005-09-06 13:03:51 -0500110 ret = __sn_readq_relaxed(&ptr->pic.p_int_status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111 break;
112 default:
113 panic
114 ("pcireg_intr_status_get: unknown bridgetype bridge 0x%p",
Al Virob3e5b5b2005-12-15 09:18:40 +0000115 ptr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116 }
117 }
118 return ret;
119}
120
121/*
122 * Interrupt Enable Register Access -- Read/Write 0000_0108
123 */
Prarit Bhargava53493dc2006-01-16 19:54:40 -0800124void pcireg_intr_enable_bit_clr(struct pcibus_info *pcibus_info, u64 bits)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125{
Al Virob3e5b5b2005-12-15 09:18:40 +0000126 union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700127
128 if (pcibus_info) {
129 switch (pcibus_info->pbi_bridge_type) {
130 case PCIBR_BRIDGETYPE_TIOCP:
Mark Maule5fbcf9a2005-09-06 13:03:51 -0500131 __sn_clrq_relaxed(&ptr->tio.cp_int_enable, bits);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132 break;
133 case PCIBR_BRIDGETYPE_PIC:
Mark Maule6fb93a92005-11-07 15:48:50 -0600134 __sn_clrq_relaxed(&ptr->pic.p_int_enable, bits);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135 break;
136 default:
137 panic
138 ("pcireg_intr_enable_bit_clr: unknown bridgetype bridge 0x%p",
Al Virob3e5b5b2005-12-15 09:18:40 +0000139 ptr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140 }
141 }
142}
143
Prarit Bhargava53493dc2006-01-16 19:54:40 -0800144void pcireg_intr_enable_bit_set(struct pcibus_info *pcibus_info, u64 bits)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700145{
Al Virob3e5b5b2005-12-15 09:18:40 +0000146 union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700147
148 if (pcibus_info) {
149 switch (pcibus_info->pbi_bridge_type) {
150 case PCIBR_BRIDGETYPE_TIOCP:
Mark Maule5fbcf9a2005-09-06 13:03:51 -0500151 __sn_setq_relaxed(&ptr->tio.cp_int_enable, bits);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700152 break;
153 case PCIBR_BRIDGETYPE_PIC:
Mark Maule5fbcf9a2005-09-06 13:03:51 -0500154 __sn_setq_relaxed(&ptr->pic.p_int_enable, bits);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700155 break;
156 default:
157 panic
158 ("pcireg_intr_enable_bit_set: unknown bridgetype bridge 0x%p",
Al Virob3e5b5b2005-12-15 09:18:40 +0000159 ptr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700160 }
161 }
162}
163
164/*
165 * Intr Host Address Register (int_addr) -- Read/Write 0000_0130 - 0000_0168
166 */
167void pcireg_intr_addr_addr_set(struct pcibus_info *pcibus_info, int int_n,
Prarit Bhargava53493dc2006-01-16 19:54:40 -0800168 u64 addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700169{
Al Virob3e5b5b2005-12-15 09:18:40 +0000170 union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700171
172 if (pcibus_info) {
173 switch (pcibus_info->pbi_bridge_type) {
174 case PCIBR_BRIDGETYPE_TIOCP:
Mark Maule5fbcf9a2005-09-06 13:03:51 -0500175 __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));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700179 break;
180 case PCIBR_BRIDGETYPE_PIC:
Mark Maule5fbcf9a2005-09-06 13:03:51 -0500181 __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));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185 break;
186 default:
187 panic
188 ("pcireg_intr_addr_addr_get: unknown bridgetype bridge 0x%p",
Al Virob3e5b5b2005-12-15 09:18:40 +0000189 ptr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700190 }
191 }
192}
193
194/*
195 * Force Interrupt Register Access -- Write Only 0000_01C0 - 0000_01F8
196 */
197void pcireg_force_intr_set(struct pcibus_info *pcibus_info, int int_n)
198{
Al Virob3e5b5b2005-12-15 09:18:40 +0000199 union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700200
201 if (pcibus_info) {
202 switch (pcibus_info->pbi_bridge_type) {
203 case PCIBR_BRIDGETYPE_TIOCP:
Mark Maule5fbcf9a2005-09-06 13:03:51 -0500204 writeq(1, &ptr->tio.cp_force_pin[int_n]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205 break;
206 case PCIBR_BRIDGETYPE_PIC:
Mark Maule5fbcf9a2005-09-06 13:03:51 -0500207 writeq(1, &ptr->pic.p_force_pin[int_n]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208 break;
209 default:
210 panic
211 ("pcireg_force_intr_set: unknown bridgetype bridge 0x%p",
Al Virob3e5b5b2005-12-15 09:18:40 +0000212 ptr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213 }
214 }
215}
216
217/*
218 * Device(x) Write Buffer Flush Reg Access -- Read Only 0000_0240 - 0000_0258
219 */
Prarit Bhargava53493dc2006-01-16 19:54:40 -0800220u64 pcireg_wrb_flush_get(struct pcibus_info *pcibus_info, int device)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700221{
Al Virob3e5b5b2005-12-15 09:18:40 +0000222 union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
Prarit Bhargava53493dc2006-01-16 19:54:40 -0800223 u64 ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224
225 if (pcibus_info) {
226 switch (pcibus_info->pbi_bridge_type) {
227 case PCIBR_BRIDGETYPE_TIOCP:
Mark Maule5fbcf9a2005-09-06 13:03:51 -0500228 ret =
229 __sn_readq_relaxed(&ptr->tio.cp_wr_req_buf[device]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230 break;
231 case PCIBR_BRIDGETYPE_PIC:
Mark Maule5fbcf9a2005-09-06 13:03:51 -0500232 ret =
233 __sn_readq_relaxed(&ptr->pic.p_wr_req_buf[device]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700234 break;
235 default:
Al Virob3e5b5b2005-12-15 09:18:40 +0000236 panic("pcireg_wrb_flush_get: unknown bridgetype bridge 0x%p", ptr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237 }
238
239 }
240 /* Read of the Write Buffer Flush should always return zero */
241 return ret;
242}
243
244void pcireg_int_ate_set(struct pcibus_info *pcibus_info, int ate_index,
Prarit Bhargava53493dc2006-01-16 19:54:40 -0800245 u64 val)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700246{
Al Virob3e5b5b2005-12-15 09:18:40 +0000247 union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700248
249 if (pcibus_info) {
250 switch (pcibus_info->pbi_bridge_type) {
251 case PCIBR_BRIDGETYPE_TIOCP:
Mark Maule5fbcf9a2005-09-06 13:03:51 -0500252 writeq(val, &ptr->tio.cp_int_ate_ram[ate_index]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700253 break;
254 case PCIBR_BRIDGETYPE_PIC:
Mark Maule5fbcf9a2005-09-06 13:03:51 -0500255 writeq(val, &ptr->pic.p_int_ate_ram[ate_index]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700256 break;
257 default:
258 panic
259 ("pcireg_int_ate_set: unknown bridgetype bridge 0x%p",
Al Virob3e5b5b2005-12-15 09:18:40 +0000260 ptr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261 }
262 }
263}
264
Prarit Bhargava53493dc2006-01-16 19:54:40 -0800265u64 __iomem *pcireg_int_ate_addr(struct pcibus_info *pcibus_info, int ate_index)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700266{
Al Virob3e5b5b2005-12-15 09:18:40 +0000267 union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
Prarit Bhargava53493dc2006-01-16 19:54:40 -0800268 u64 __iomem *ret = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700269
270 if (pcibus_info) {
271 switch (pcibus_info->pbi_bridge_type) {
272 case PCIBR_BRIDGETYPE_TIOCP:
Mark Maule5fbcf9a2005-09-06 13:03:51 -0500273 ret = &ptr->tio.cp_int_ate_ram[ate_index];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700274 break;
275 case PCIBR_BRIDGETYPE_PIC:
Mark Maule5fbcf9a2005-09-06 13:03:51 -0500276 ret = &ptr->pic.p_int_ate_ram[ate_index];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277 break;
278 default:
279 panic
280 ("pcireg_int_ate_addr: unknown bridgetype bridge 0x%p",
Al Virob3e5b5b2005-12-15 09:18:40 +0000281 ptr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282 }
283 }
284 return ret;
285}