io_64.h 12.3 KB
Newer Older
1 2 3 4 5 6 7 8 9
#ifndef __SPARC64_IO_H
#define __SPARC64_IO_H

#include <linux/kernel.h>
#include <linux/compiler.h>
#include <linux/types.h>

#include <asm/page.h>      /* IO address mapping routines need this */
#include <asm/asi.h>
10
#include <asm-generic/pci_iomap.h>
11 12 13 14

/* BIO layer definitions. */
extern unsigned long kern_base, kern_size;

15 16
#define inb inb
static inline u8 inb(unsigned long addr)
17 18 19 20 21 22 23 24 25 26 27
{
	u8 ret;

	__asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_inb */"
			     : "=r" (ret)
			     : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
			     : "memory");

	return ret;
}

28 29
#define inw inw
static inline u16 inw(unsigned long addr)
30 31 32 33 34 35 36 37 38 39 40
{
	u16 ret;

	__asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_inw */"
			     : "=r" (ret)
			     : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
			     : "memory");

	return ret;
}

41 42
#define inl inl
static inline u32 inl(unsigned long addr)
43 44 45 46 47 48 49 50 51 52 53
{
	u32 ret;

	__asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_inl */"
			     : "=r" (ret)
			     : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
			     : "memory");

	return ret;
}

54 55
#define outb outb
static inline void outb(u8 b, unsigned long addr)
56 57 58 59 60 61 62
{
	__asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_outb */"
			     : /* no outputs */
			     : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
			     : "memory");
}

63 64
#define outw outw
static inline void outw(u16 w, unsigned long addr)
65 66 67 68 69 70 71
{
	__asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_outw */"
			     : /* no outputs */
			     : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
			     : "memory");
}

72 73
#define outl outl
static inline void outl(u32 l, unsigned long addr)
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
{
	__asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_outl */"
			     : /* no outputs */
			     : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
			     : "memory");
}


#define inb_p(__addr) 		inb(__addr)
#define outb_p(__b, __addr)	outb(__b, __addr)
#define inw_p(__addr)		inw(__addr)
#define outw_p(__w, __addr)	outw(__w, __addr)
#define inl_p(__addr)		inl(__addr)
#define outl_p(__l, __addr)	outl(__l, __addr)

89 90 91 92 93 94
void outsb(unsigned long, const void *, unsigned long);
void outsw(unsigned long, const void *, unsigned long);
void outsl(unsigned long, const void *, unsigned long);
void insb(unsigned long, void *, unsigned long);
void insw(unsigned long, void *, unsigned long);
void insl(unsigned long, void *, unsigned long);
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125

static inline void ioread8_rep(void __iomem *port, void *buf, unsigned long count)
{
	insb((unsigned long __force)port, buf, count);
}
static inline void ioread16_rep(void __iomem *port, void *buf, unsigned long count)
{
	insw((unsigned long __force)port, buf, count);
}

static inline void ioread32_rep(void __iomem *port, void *buf, unsigned long count)
{
	insl((unsigned long __force)port, buf, count);
}

static inline void iowrite8_rep(void __iomem *port, const void *buf, unsigned long count)
{
	outsb((unsigned long __force)port, buf, count);
}

static inline void iowrite16_rep(void __iomem *port, const void *buf, unsigned long count)
{
	outsw((unsigned long __force)port, buf, count);
}

static inline void iowrite32_rep(void __iomem *port, const void *buf, unsigned long count)
{
	outsl((unsigned long __force)port, buf, count);
}

/* Memory functions, same as I/O accesses on Ultra. */
126 127
#define readb readb
static inline u8 readb(const volatile void __iomem *addr)
128 129 130 131 132 133 134 135 136
{	u8 ret;

	__asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_readb */"
			     : "=r" (ret)
			     : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
			     : "memory");
	return ret;
}

137 138
#define readw readw
static inline u16 readw(const volatile void __iomem *addr)
139 140 141 142 143 144 145 146 147 148
{	u16 ret;

	__asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_readw */"
			     : "=r" (ret)
			     : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
			     : "memory");

	return ret;
}

149 150
#define readl readl
static inline u32 readl(const volatile void __iomem *addr)
151 152 153 154 155 156 157 158 159 160
{	u32 ret;

	__asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_readl */"
			     : "=r" (ret)
			     : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
			     : "memory");

	return ret;
}

161 162
#define readq readq
static inline u64 readq(const volatile void __iomem *addr)
163 164 165 166 167 168 169 170 171 172
{	u64 ret;

	__asm__ __volatile__("ldxa\t[%1] %2, %0\t/* pci_readq */"
			     : "=r" (ret)
			     : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
			     : "memory");

	return ret;
}

173 174
#define writeb writeb
static inline void writeb(u8 b, volatile void __iomem *addr)
175 176 177 178 179 180 181
{
	__asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_writeb */"
			     : /* no outputs */
			     : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
			     : "memory");
}

182 183
#define writew writew
static inline void writew(u16 w, volatile void __iomem *addr)
184 185 186 187 188 189 190
{
	__asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_writew */"
			     : /* no outputs */
			     : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
			     : "memory");
}

191 192
#define writel writel
static inline void writel(u32 l, volatile void __iomem *addr)
193 194 195 196 197 198 199
{
	__asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_writel */"
			     : /* no outputs */
			     : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
			     : "memory");
}

200 201
#define writeq writeq
static inline void writeq(u64 q, volatile void __iomem *addr)
202 203 204 205 206 207 208
{
	__asm__ __volatile__("stxa\t%r0, [%1] %2\t/* pci_writeq */"
			     : /* no outputs */
			     : "Jr" (q), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
			     : "memory");
}

209 210 211 212
#define readb_relaxed(__addr)	readb(__addr)
#define readw_relaxed(__addr)	readw(__addr)
#define readl_relaxed(__addr)	readl(__addr)
#define readq_relaxed(__addr)	readq(__addr)
213 214

/* Now versions without byte-swapping. */
215 216
#define __raw_readb __raw_readb
static inline u8 __raw_readb(const volatile void __iomem *addr)
217 218 219 220 221 222 223 224 225 226
{
	u8 ret;

	__asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_raw_readb */"
			     : "=r" (ret)
			     : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));

	return ret;
}

227 228
#define __raw_readw __raw_readw
static inline u16 __raw_readw(const volatile void __iomem *addr)
229 230 231 232 233 234 235 236 237 238
{
	u16 ret;

	__asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_raw_readw */"
			     : "=r" (ret)
			     : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));

	return ret;
}

239 240
#define __raw_readl __raw_readl
static inline u32 __raw_readl(const volatile void __iomem *addr)
241 242 243 244 245 246 247 248 249 250
{
	u32 ret;

	__asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_raw_readl */"
			     : "=r" (ret)
			     : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));

	return ret;
}

251 252
#define __raw_readq __raw_readq
static inline u64 __raw_readq(const volatile void __iomem *addr)
253 254 255 256 257 258 259 260 261 262
{
	u64 ret;

	__asm__ __volatile__("ldxa\t[%1] %2, %0\t/* pci_raw_readq */"
			     : "=r" (ret)
			     : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));

	return ret;
}

263 264
#define __raw_writeb __raw_writeb
static inline void __raw_writeb(u8 b, const volatile void __iomem *addr)
265 266 267 268 269 270
{
	__asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_raw_writeb */"
			     : /* no outputs */
			     : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
}

271 272
#define __raw_writew __raw_writew
static inline void __raw_writew(u16 w, const volatile void __iomem *addr)
273 274 275 276 277 278
{
	__asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_raw_writew */"
			     : /* no outputs */
			     : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
}

279 280
#define __raw_writel __raw_writel
static inline void __raw_writel(u32 l, const volatile void __iomem *addr)
281 282 283 284 285 286
{
	__asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_raw_writel */"
			     : /* no outputs */
			     : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
}

287 288
#define __raw_writeq __raw_writeq
static inline void __raw_writeq(u64 q, const volatile void __iomem *addr)
289 290 291 292 293 294 295 296 297 298 299 300 301 302 303
{
	__asm__ __volatile__("stxa\t%r0, [%1] %2\t/* pci_raw_writeq */"
			     : /* no outputs */
			     : "Jr" (q), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
}


/* Valid I/O Space regions are anywhere, because each PCI bus supported
 * can live in an arbitrary area of the physical address range.
 */
#define IO_SPACE_LIMIT 0xffffffffffffffffUL

/* Now, SBUS variants, only difference from PCI is that we do
 * not use little-endian ASIs.
 */
304
static inline u8 sbus_readb(const volatile void __iomem *addr)
305 306 307 308 309 310 311 312 313 314 315
{
	u8 ret;

	__asm__ __volatile__("lduba\t[%1] %2, %0\t/* sbus_readb */"
			     : "=r" (ret)
			     : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
			     : "memory");

	return ret;
}

316
static inline u16 sbus_readw(const volatile void __iomem *addr)
317 318 319 320 321 322 323 324 325 326 327
{
	u16 ret;

	__asm__ __volatile__("lduha\t[%1] %2, %0\t/* sbus_readw */"
			     : "=r" (ret)
			     : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
			     : "memory");

	return ret;
}

328
static inline u32 sbus_readl(const volatile void __iomem *addr)
329 330 331 332 333 334 335 336 337 338 339
{
	u32 ret;

	__asm__ __volatile__("lduwa\t[%1] %2, %0\t/* sbus_readl */"
			     : "=r" (ret)
			     : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
			     : "memory");

	return ret;
}

340
static inline u64 sbus_readq(const volatile void __iomem *addr)
341 342 343 344 345 346 347 348 349 350 351
{
	u64 ret;

	__asm__ __volatile__("ldxa\t[%1] %2, %0\t/* sbus_readq */"
			     : "=r" (ret)
			     : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
			     : "memory");

	return ret;
}

352
static inline void sbus_writeb(u8 b, volatile void __iomem *addr)
353 354 355 356 357 358 359
{
	__asm__ __volatile__("stba\t%r0, [%1] %2\t/* sbus_writeb */"
			     : /* no outputs */
			     : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
			     : "memory");
}

360
static inline void sbus_writew(u16 w, volatile void __iomem *addr)
361 362 363 364 365 366 367
{
	__asm__ __volatile__("stha\t%r0, [%1] %2\t/* sbus_writew */"
			     : /* no outputs */
			     : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
			     : "memory");
}

368
static inline void sbus_writel(u32 l, volatile void __iomem *addr)
369 370 371 372 373 374 375
{
	__asm__ __volatile__("stwa\t%r0, [%1] %2\t/* sbus_writel */"
			     : /* no outputs */
			     : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
			     : "memory");
}

376
static inline void sbus_writeq(u64 l, volatile void __iomem *addr)
377 378 379 380 381 382 383
{
	__asm__ __volatile__("stxa\t%r0, [%1] %2\t/* sbus_writeq */"
			     : /* no outputs */
			     : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
			     : "memory");
}

384
static inline void sbus_memset_io(volatile void __iomem *dst, int c, __kernel_size_t n)
385 386 387 388 389 390 391
{
	while(n--) {
		sbus_writeb(c, dst);
		dst++;
	}
}

392
static inline void memset_io(volatile void __iomem *dst, int c, __kernel_size_t n)
393 394 395 396 397 398 399 400 401
{
	volatile void __iomem *d = dst;

	while (n--) {
		writeb(c, d);
		d++;
	}
}

402 403
static inline void sbus_memcpy_fromio(void *dst, const volatile void __iomem *src,
				      __kernel_size_t n)
404 405 406 407 408 409 410 411 412 413 414
{
	char *d = dst;

	while (n--) {
		char tmp = sbus_readb(src);
		*d++ = tmp;
		src++;
	}
}


415 416
static inline void memcpy_fromio(void *dst, const volatile void __iomem *src,
				 __kernel_size_t n)
417 418 419 420 421 422 423 424 425 426
{
	char *d = dst;

	while (n--) {
		char tmp = readb(src);
		*d++ = tmp;
		src++;
	}
}

427 428
static inline void sbus_memcpy_toio(volatile void __iomem *dst, const void *src,
				    __kernel_size_t n)
429 430 431 432 433 434 435 436 437 438 439
{
	const char *s = src;
	volatile void __iomem *d = dst;

	while (n--) {
		char tmp = *s++;
		sbus_writeb(tmp, d);
		d++;
	}
}

440 441
static inline void memcpy_toio(volatile void __iomem *dst, const void *src,
			       __kernel_size_t n)
442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465
{
	const char *s = src;
	volatile void __iomem *d = dst;

	while (n--) {
		char tmp = *s++;
		writeb(tmp, d);
		d++;
	}
}

#define mmiowb()

#ifdef __KERNEL__

/* On sparc64 we have the whole physical IO address space accessible
 * using physically addressed loads and stores, so this does nothing.
 */
static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
{
	return (void __iomem *)offset;
}

#define ioremap_nocache(X,Y)		ioremap((X),(Y))
466
#define ioremap_wc(X,Y)			ioremap((X),(Y))
467 468 469 470 471 472 473

static inline void iounmap(volatile void __iomem *addr)
{
}

#define ioread8(X)			readb(X)
#define ioread16(X)			readw(X)
474
#define ioread16be(X)			__raw_readw(X)
475
#define ioread32(X)			readl(X)
476
#define ioread32be(X)			__raw_readl(X)
477 478
#define iowrite8(val,X)			writeb(val,X)
#define iowrite16(val,X)		writew(val,X)
479
#define iowrite16be(val,X)		__raw_writew(val,X)
480
#define iowrite32(val,X)		writel(val,X)
481
#define iowrite32be(val,X)		__raw_writel(val,X)
482 483

/* Create a virtual mapping cookie for an IO port range */
484 485
void __iomem *ioport_map(unsigned long port, unsigned int nr);
void ioport_unmap(void __iomem *);
486 487 488

/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
struct pci_dev;
489
void pci_iounmap(struct pci_dev *dev, void __iomem *);
490

491 492 493 494 495 496 497 498 499
static inline int sbus_can_dma_64bit(void)
{
	return 1;
}
static inline int sbus_can_burst64(void)
{
	return 1;
}
struct device;
500
void sbus_set_sbus64(struct device *, int);
501

502 503 504 505 506 507 508 509 510 511 512 513 514 515
/*
 * Convert a physical pointer to a virtual kernel pointer for /dev/mem
 * access
 */
#define xlate_dev_mem_ptr(p)	__va(p)

/*
 * Convert a virtual cached pointer to an uncached pointer
 */
#define xlate_dev_kmem_ptr(p)	p

#endif

#endif /* !(__SPARC64_IO_H) */