| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  * include/asm-sh/io_bigsur.c | 
 | 3 |  * | 
 | 4 |  * By Dustin McIntire (dustin@sensoria.com) (c)2001 | 
 | 5 |  * Derived from io_hd64465.h, which bore the message: | 
 | 6 |  * By Greg Banks <gbanks@pocketpenguins.com> | 
 | 7 |  * (c) 2000 PocketPenguins Inc.  | 
 | 8 |  * and from io_hd64461.h, which bore the message: | 
 | 9 |  * Copyright 2000 Stuart Menefy (stuart.menefy@st.com) | 
 | 10 |  * | 
 | 11 |  * May be copied or modified under the terms of the GNU General Public | 
 | 12 |  * License.  See linux/COPYING for more information. | 
 | 13 |  * | 
 | 14 |  * IO functions for a Hitachi Big Sur Evaluation Board. | 
 | 15 |  */ | 
 | 16 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 17 | #include <linux/kernel.h> | 
 | 18 | #include <linux/module.h> | 
 | 19 | #include <asm/machvec.h> | 
 | 20 | #include <asm/io.h> | 
 | 21 | #include <asm/bigsur/bigsur.h> | 
 | 22 |  | 
 | 23 | /* Low iomap maps port 0-1K to addresses in 8byte chunks */ | 
 | 24 | #define BIGSUR_IOMAP_LO_THRESH 0x400 | 
 | 25 | #define BIGSUR_IOMAP_LO_SHIFT	3 | 
 | 26 | #define BIGSUR_IOMAP_LO_MASK	((1<<BIGSUR_IOMAP_LO_SHIFT)-1) | 
 | 27 | #define BIGSUR_IOMAP_LO_NMAP	(BIGSUR_IOMAP_LO_THRESH>>BIGSUR_IOMAP_LO_SHIFT) | 
 | 28 | static u32 bigsur_iomap_lo[BIGSUR_IOMAP_LO_NMAP]; | 
 | 29 | static u8 bigsur_iomap_lo_shift[BIGSUR_IOMAP_LO_NMAP]; | 
 | 30 |  | 
 | 31 | /* High iomap maps port 1K-64K to addresses in 1K chunks */ | 
 | 32 | #define BIGSUR_IOMAP_HI_THRESH 0x10000 | 
 | 33 | #define BIGSUR_IOMAP_HI_SHIFT	10 | 
 | 34 | #define BIGSUR_IOMAP_HI_MASK	((1<<BIGSUR_IOMAP_HI_SHIFT)-1) | 
 | 35 | #define BIGSUR_IOMAP_HI_NMAP	(BIGSUR_IOMAP_HI_THRESH>>BIGSUR_IOMAP_HI_SHIFT) | 
 | 36 | static u32 bigsur_iomap_hi[BIGSUR_IOMAP_HI_NMAP]; | 
 | 37 | static u8 bigsur_iomap_hi_shift[BIGSUR_IOMAP_HI_NMAP]; | 
 | 38 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 39 | void bigsur_port_map(u32 baseport, u32 nports, u32 addr, u8 shift) | 
 | 40 | { | 
 | 41 | 	u32 port, endport = baseport + nports; | 
 | 42 |  | 
 | 43 | 	pr_debug("bigsur_port_map(base=0x%0x, n=0x%0x, addr=0x%08x)\n", | 
 | 44 | 		 baseport, nports, addr); | 
 | 45 | 	     | 
 | 46 | 	for (port = baseport ; | 
 | 47 | 	     port < endport && port < BIGSUR_IOMAP_LO_THRESH ; | 
 | 48 | 	     port += (1<<BIGSUR_IOMAP_LO_SHIFT)) { | 
 | 49 | 	    	pr_debug("    maplo[0x%x] = 0x%08x\n", port, addr); | 
 | 50 |     	    bigsur_iomap_lo[port>>BIGSUR_IOMAP_LO_SHIFT] = addr; | 
 | 51 |     	    bigsur_iomap_lo_shift[port>>BIGSUR_IOMAP_LO_SHIFT] = shift; | 
 | 52 | 	    	addr += (1<<(BIGSUR_IOMAP_LO_SHIFT)); | 
 | 53 | 	} | 
 | 54 |  | 
| Michael Veeck | 0e8bbf5 | 2005-09-10 00:27:11 -0700 | [diff] [blame] | 55 | 	for (port = max_t(u32, baseport, BIGSUR_IOMAP_LO_THRESH); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 56 | 	     port < endport && port < BIGSUR_IOMAP_HI_THRESH ; | 
 | 57 | 	     port += (1<<BIGSUR_IOMAP_HI_SHIFT)) { | 
 | 58 | 	    	pr_debug("    maphi[0x%x] = 0x%08x\n", port, addr); | 
 | 59 |     	    bigsur_iomap_hi[port>>BIGSUR_IOMAP_HI_SHIFT] = addr; | 
 | 60 |     	    bigsur_iomap_hi_shift[port>>BIGSUR_IOMAP_HI_SHIFT] = shift; | 
 | 61 | 	    	addr += (1<<(BIGSUR_IOMAP_HI_SHIFT)); | 
 | 62 | 	} | 
 | 63 | } | 
 | 64 | EXPORT_SYMBOL(bigsur_port_map); | 
 | 65 |  | 
 | 66 | void bigsur_port_unmap(u32 baseport, u32 nports) | 
 | 67 | { | 
 | 68 | 	u32 port, endport = baseport + nports; | 
 | 69 | 	 | 
 | 70 | 	pr_debug("bigsur_port_unmap(base=0x%0x, n=0x%0x)\n", baseport, nports); | 
 | 71 |  | 
 | 72 | 	for (port = baseport ; | 
 | 73 | 	     port < endport && port < BIGSUR_IOMAP_LO_THRESH ; | 
 | 74 | 	     port += (1<<BIGSUR_IOMAP_LO_SHIFT)) { | 
 | 75 | 		bigsur_iomap_lo[port>>BIGSUR_IOMAP_LO_SHIFT] = 0; | 
 | 76 | 	} | 
 | 77 |  | 
| Michael Veeck | 0e8bbf5 | 2005-09-10 00:27:11 -0700 | [diff] [blame] | 78 | 	for (port = max_t(u32, baseport, BIGSUR_IOMAP_LO_THRESH); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 79 | 	     port < endport && port < BIGSUR_IOMAP_HI_THRESH ; | 
 | 80 | 	     port += (1<<BIGSUR_IOMAP_HI_SHIFT)) { | 
 | 81 | 		bigsur_iomap_hi[port>>BIGSUR_IOMAP_HI_SHIFT] = 0; | 
 | 82 | 	} | 
 | 83 | } | 
 | 84 | EXPORT_SYMBOL(bigsur_port_unmap); | 
 | 85 |  | 
 | 86 | unsigned long bigsur_isa_port2addr(unsigned long port) | 
 | 87 | { | 
 | 88 | 	unsigned long addr = 0; | 
 | 89 | 	unsigned char shift; | 
 | 90 |  | 
 | 91 | 	/* Physical address not in P0, do nothing */ | 
 | 92 | 	if (PXSEG(port)) { | 
 | 93 | 		addr = port; | 
 | 94 | 	/* physical address in P0, map to P2 */ | 
 | 95 | 	} else if (port >= 0x30000) { | 
 | 96 | 		addr = P2SEGADDR(port); | 
 | 97 | 	/* Big Sur I/O + HD64465 registers 0x10000-0x30000 */ | 
 | 98 | 	} else if (port >= BIGSUR_IOMAP_HI_THRESH) { | 
 | 99 | 		addr = BIGSUR_INTERNAL_BASE + (port - BIGSUR_IOMAP_HI_THRESH); | 
 | 100 | 	/* Handle remapping of high IO/PCI IO ports */ | 
 | 101 | 	} else if (port >= BIGSUR_IOMAP_LO_THRESH) { | 
 | 102 | 		addr = bigsur_iomap_hi[port >> BIGSUR_IOMAP_HI_SHIFT]; | 
 | 103 | 		shift = bigsur_iomap_hi_shift[port >> BIGSUR_IOMAP_HI_SHIFT]; | 
 | 104 |  | 
 | 105 | 		if (addr != 0) | 
 | 106 | 			addr += (port & BIGSUR_IOMAP_HI_MASK) << shift; | 
 | 107 | 	} else { | 
 | 108 | 		/* Handle remapping of low IO ports */ | 
 | 109 | 		addr = bigsur_iomap_lo[port >> BIGSUR_IOMAP_LO_SHIFT]; | 
 | 110 | 		shift = bigsur_iomap_lo_shift[port >> BIGSUR_IOMAP_LO_SHIFT]; | 
 | 111 |  | 
 | 112 | 		if (addr != 0) | 
 | 113 | 			addr += (port & BIGSUR_IOMAP_LO_MASK) << shift; | 
 | 114 | 	} | 
 | 115 |  | 
 | 116 | 	pr_debug("%s(0x%08lx) = 0x%08lx\n", __FUNCTION__, port, addr); | 
 | 117 |  | 
 | 118 | 	return addr; | 
 | 119 | } | 
 | 120 |  |