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) 2000-2004 Silicon Graphics, Inc. All rights reserved. 7 */ 8 9#ifndef _ASM_SN_IO_H 10#define _ASM_SN_IO_H 11#include <linux/compiler.h> 12#include <asm/intrinsics.h> 13 14extern void * sn_io_addr(unsigned long port) __attribute_const__; /* Forward definition */ 15extern void __sn_mmiowb(void); /* Forward definition */ 16 17extern int num_cnodes; 18 19#define __sn_mf_a() ia64_mfa() 20 21extern void sn_dma_flush(unsigned long); 22 23#define __sn_inb ___sn_inb 24#define __sn_inw ___sn_inw 25#define __sn_inl ___sn_inl 26#define __sn_outb ___sn_outb 27#define __sn_outw ___sn_outw 28#define __sn_outl ___sn_outl 29#define __sn_readb ___sn_readb 30#define __sn_readw ___sn_readw 31#define __sn_readl ___sn_readl 32#define __sn_readq ___sn_readq 33#define __sn_readb_relaxed ___sn_readb_relaxed 34#define __sn_readw_relaxed ___sn_readw_relaxed 35#define __sn_readl_relaxed ___sn_readl_relaxed 36#define __sn_readq_relaxed ___sn_readq_relaxed 37 38/* 39 * Convenience macros for setting/clearing bits using the above accessors 40 */ 41 42#define __sn_setq_relaxed(addr, val) \ 43 writeq((__sn_readq_relaxed(addr) | (val)), (addr)) 44#define __sn_clrq_relaxed(addr, val) \ 45 writeq((__sn_readq_relaxed(addr) & ~(val)), (addr)) 46 47/* 48 * The following routines are SN Platform specific, called when 49 * a reference is made to inX/outX set macros. SN Platform 50 * inX set of macros ensures that Posted DMA writes on the 51 * Bridge is flushed. 52 * 53 * The routines should be self explainatory. 54 */ 55 56static inline unsigned int 57___sn_inb (unsigned long port) 58{ 59 volatile unsigned char *addr; 60 unsigned char ret = -1; 61 62 if ((addr = sn_io_addr(port))) { 63 ret = *addr; 64 __sn_mf_a(); 65 sn_dma_flush((unsigned long)addr); 66 } 67 return ret; 68} 69 70static inline unsigned int 71___sn_inw (unsigned long port) 72{ 73 volatile unsigned short *addr; 74 unsigned short ret = -1; 75 76 if ((addr = sn_io_addr(port))) { 77 ret = *addr; 78 __sn_mf_a(); 79 sn_dma_flush((unsigned long)addr); 80 } 81 return ret; 82} 83 84static inline unsigned int 85___sn_inl (unsigned long port) 86{ 87 volatile unsigned int *addr; 88 unsigned int ret = -1; 89 90 if ((addr = sn_io_addr(port))) { 91 ret = *addr; 92 __sn_mf_a(); 93 sn_dma_flush((unsigned long)addr); 94 } 95 return ret; 96} 97 98static inline void 99___sn_outb (unsigned char val, unsigned long port) 100{ 101 volatile unsigned char *addr; 102 103 if ((addr = sn_io_addr(port))) { 104 *addr = val; 105 __sn_mmiowb(); 106 } 107} 108 109static inline void 110___sn_outw (unsigned short val, unsigned long port) 111{ 112 volatile unsigned short *addr; 113 114 if ((addr = sn_io_addr(port))) { 115 *addr = val; 116 __sn_mmiowb(); 117 } 118} 119 120static inline void 121___sn_outl (unsigned int val, unsigned long port) 122{ 123 volatile unsigned int *addr; 124 125 if ((addr = sn_io_addr(port))) { 126 *addr = val; 127 __sn_mmiowb(); 128 } 129} 130 131/* 132 * The following routines are SN Platform specific, called when 133 * a reference is made to readX/writeX set macros. SN Platform 134 * readX set of macros ensures that Posted DMA writes on the 135 * Bridge is flushed. 136 * 137 * The routines should be self explainatory. 138 */ 139 140static inline unsigned char 141___sn_readb (const volatile void __iomem *addr) 142{ 143 unsigned char val; 144 145 val = *(volatile unsigned char __force *)addr; 146 __sn_mf_a(); 147 sn_dma_flush((unsigned long)addr); 148 return val; 149} 150 151static inline unsigned short 152___sn_readw (const volatile void __iomem *addr) 153{ 154 unsigned short val; 155 156 val = *(volatile unsigned short __force *)addr; 157 __sn_mf_a(); 158 sn_dma_flush((unsigned long)addr); 159 return val; 160} 161 162static inline unsigned int 163___sn_readl (const volatile void __iomem *addr) 164{ 165 unsigned int val; 166 167 val = *(volatile unsigned int __force *)addr; 168 __sn_mf_a(); 169 sn_dma_flush((unsigned long)addr); 170 return val; 171} 172 173static inline unsigned long 174___sn_readq (const volatile void __iomem *addr) 175{ 176 unsigned long val; 177 178 val = *(volatile unsigned long __force *)addr; 179 __sn_mf_a(); 180 sn_dma_flush((unsigned long)addr); 181 return val; 182} 183 184/* 185 * For generic and SN2 kernels, we have a set of fast access 186 * PIO macros. These macros are provided on SN Platform 187 * because the normal inX and readX macros perform an 188 * additional task of flushing Post DMA request on the Bridge. 189 * 190 * These routines should be self explainatory. 191 */ 192 193static inline unsigned int 194sn_inb_fast (unsigned long port) 195{ 196 volatile unsigned char *addr = (unsigned char *)port; 197 unsigned char ret; 198 199 ret = *addr; 200 __sn_mf_a(); 201 return ret; 202} 203 204static inline unsigned int 205sn_inw_fast (unsigned long port) 206{ 207 volatile unsigned short *addr = (unsigned short *)port; 208 unsigned short ret; 209 210 ret = *addr; 211 __sn_mf_a(); 212 return ret; 213} 214 215static inline unsigned int 216sn_inl_fast (unsigned long port) 217{ 218 volatile unsigned int *addr = (unsigned int *)port; 219 unsigned int ret; 220 221 ret = *addr; 222 __sn_mf_a(); 223 return ret; 224} 225 226static inline unsigned char 227___sn_readb_relaxed (const volatile void __iomem *addr) 228{ 229 return *(volatile unsigned char __force *)addr; 230} 231 232static inline unsigned short 233___sn_readw_relaxed (const volatile void __iomem *addr) 234{ 235 return *(volatile unsigned short __force *)addr; 236} 237 238static inline unsigned int 239___sn_readl_relaxed (const volatile void __iomem *addr) 240{ 241 return *(volatile unsigned int __force *) addr; 242} 243 244static inline unsigned long 245___sn_readq_relaxed (const volatile void __iomem *addr) 246{ 247 return *(volatile unsigned long __force *) addr; 248} 249 250struct pci_dev; 251 252static inline int 253sn_pci_set_vchan(struct pci_dev *pci_dev, unsigned long *addr, int vchan) 254{ 255 256 if (vchan > 1) { 257 return -1; 258 } 259 260 if (!(*addr >> 32)) /* Using a mask here would be cleaner */ 261 return 0; /* but this generates better code */ 262 263 if (vchan == 1) { 264 /* Set Bit 57 */ 265 *addr |= (1UL << 57); 266 } else { 267 /* Clear Bit 57 */ 268 *addr &= ~(1UL << 57); 269 } 270 271 return 0; 272} 273 274#endif /* _ASM_SN_IO_H */ 275