xref: /linux/arch/sparc/lib/PeeCeeI.c (revision b2441318)
1*b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
2478b8fecSSam Ravnborg /*
3478b8fecSSam Ravnborg  * PeeCeeI.c: The emerging standard...
4478b8fecSSam Ravnborg  *
5478b8fecSSam Ravnborg  * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
6478b8fecSSam Ravnborg  */
7478b8fecSSam Ravnborg 
8917c3660SSam Ravnborg #include <linux/module.h>
9917c3660SSam Ravnborg 
10478b8fecSSam Ravnborg #include <asm/io.h>
11478b8fecSSam Ravnborg #include <asm/byteorder.h>
12478b8fecSSam Ravnborg 
outsb(unsigned long __addr,const void * src,unsigned long count)13478b8fecSSam Ravnborg void outsb(unsigned long __addr, const void *src, unsigned long count)
14478b8fecSSam Ravnborg {
15478b8fecSSam Ravnborg 	void __iomem *addr = (void __iomem *) __addr;
16478b8fecSSam Ravnborg 	const u8 *p = src;
17478b8fecSSam Ravnborg 
18478b8fecSSam Ravnborg 	while (count--)
196b8b5507SSam Ravnborg 		__raw_writeb(*p++, addr);
20478b8fecSSam Ravnborg }
21917c3660SSam Ravnborg EXPORT_SYMBOL(outsb);
22478b8fecSSam Ravnborg 
outsw(unsigned long __addr,const void * src,unsigned long count)23478b8fecSSam Ravnborg void outsw(unsigned long __addr, const void *src, unsigned long count)
24478b8fecSSam Ravnborg {
25478b8fecSSam Ravnborg 	void __iomem *addr = (void __iomem *) __addr;
26478b8fecSSam Ravnborg 
27478b8fecSSam Ravnborg 	while (count--) {
28478b8fecSSam Ravnborg 		__raw_writew(*(u16 *)src, addr);
29478b8fecSSam Ravnborg 		src += sizeof(u16);
30478b8fecSSam Ravnborg 	}
31478b8fecSSam Ravnborg }
32917c3660SSam Ravnborg EXPORT_SYMBOL(outsw);
33478b8fecSSam Ravnborg 
outsl(unsigned long __addr,const void * src,unsigned long count)34478b8fecSSam Ravnborg void outsl(unsigned long __addr, const void *src, unsigned long count)
35478b8fecSSam Ravnborg {
36478b8fecSSam Ravnborg 	void __iomem *addr = (void __iomem *) __addr;
37478b8fecSSam Ravnborg 	u32 l, l2;
38478b8fecSSam Ravnborg 
39478b8fecSSam Ravnborg 	if (!count)
40478b8fecSSam Ravnborg 		return;
41478b8fecSSam Ravnborg 
42478b8fecSSam Ravnborg 	switch (((unsigned long)src) & 0x3) {
43478b8fecSSam Ravnborg 	case 0x0:
44478b8fecSSam Ravnborg 		/* src is naturally aligned */
45478b8fecSSam Ravnborg 		while (count--) {
46478b8fecSSam Ravnborg 			__raw_writel(*(u32 *)src, addr);
47478b8fecSSam Ravnborg 			src += sizeof(u32);
48478b8fecSSam Ravnborg 		}
49478b8fecSSam Ravnborg 		break;
50478b8fecSSam Ravnborg 	case 0x2:
51478b8fecSSam Ravnborg 		/* 2-byte alignment */
52478b8fecSSam Ravnborg 		while (count--) {
53478b8fecSSam Ravnborg 			l = (*(u16 *)src) << 16;
54478b8fecSSam Ravnborg 			l |= *(u16 *)(src + sizeof(u16));
55478b8fecSSam Ravnborg 			__raw_writel(l, addr);
56478b8fecSSam Ravnborg 			src += sizeof(u32);
57478b8fecSSam Ravnborg 		}
58478b8fecSSam Ravnborg 		break;
59478b8fecSSam Ravnborg 	case 0x1:
60478b8fecSSam Ravnborg 		/* Hold three bytes in l each time, grab a byte from l2 */
61478b8fecSSam Ravnborg 		l = (*(u8 *)src) << 24;
62478b8fecSSam Ravnborg 		l |= (*(u16 *)(src + sizeof(u8))) << 8;
63478b8fecSSam Ravnborg 		src += sizeof(u8) + sizeof(u16);
64478b8fecSSam Ravnborg 		while (count--) {
65478b8fecSSam Ravnborg 			l2 = *(u32 *)src;
66478b8fecSSam Ravnborg 			l |= (l2 >> 24);
67478b8fecSSam Ravnborg 			__raw_writel(l, addr);
68478b8fecSSam Ravnborg 			l = l2 << 8;
69478b8fecSSam Ravnborg 			src += sizeof(u32);
70478b8fecSSam Ravnborg 		}
71478b8fecSSam Ravnborg 		break;
72478b8fecSSam Ravnborg 	case 0x3:
73478b8fecSSam Ravnborg 		/* Hold a byte in l each time, grab 3 bytes from l2 */
74478b8fecSSam Ravnborg 		l = (*(u8 *)src) << 24;
75478b8fecSSam Ravnborg 		src += sizeof(u8);
76478b8fecSSam Ravnborg 		while (count--) {
77478b8fecSSam Ravnborg 			l2 = *(u32 *)src;
78478b8fecSSam Ravnborg 			l |= (l2 >> 8);
79478b8fecSSam Ravnborg 			__raw_writel(l, addr);
80478b8fecSSam Ravnborg 			l = l2 << 24;
81478b8fecSSam Ravnborg 			src += sizeof(u32);
82478b8fecSSam Ravnborg 		}
83478b8fecSSam Ravnborg 		break;
84478b8fecSSam Ravnborg 	}
85478b8fecSSam Ravnborg }
86917c3660SSam Ravnborg EXPORT_SYMBOL(outsl);
87478b8fecSSam Ravnborg 
insb(unsigned long __addr,void * dst,unsigned long count)88478b8fecSSam Ravnborg void insb(unsigned long __addr, void *dst, unsigned long count)
89478b8fecSSam Ravnborg {
90478b8fecSSam Ravnborg 	void __iomem *addr = (void __iomem *) __addr;
91478b8fecSSam Ravnborg 
92478b8fecSSam Ravnborg 	if (count) {
93478b8fecSSam Ravnborg 		u32 *pi;
94478b8fecSSam Ravnborg 		u8 *pb = dst;
95478b8fecSSam Ravnborg 
96478b8fecSSam Ravnborg 		while ((((unsigned long)pb) & 0x3) && count--)
976b8b5507SSam Ravnborg 			*pb++ = __raw_readb(addr);
98478b8fecSSam Ravnborg 		pi = (u32 *)pb;
99478b8fecSSam Ravnborg 		while (count >= 4) {
100478b8fecSSam Ravnborg 			u32 w;
101478b8fecSSam Ravnborg 
1026b8b5507SSam Ravnborg 			w  = (__raw_readb(addr) << 24);
1036b8b5507SSam Ravnborg 			w |= (__raw_readb(addr) << 16);
1046b8b5507SSam Ravnborg 			w |= (__raw_readb(addr) << 8);
1056b8b5507SSam Ravnborg 			w |= (__raw_readb(addr) << 0);
106478b8fecSSam Ravnborg 			*pi++ = w;
107478b8fecSSam Ravnborg 			count -= 4;
108478b8fecSSam Ravnborg 		}
109478b8fecSSam Ravnborg 		pb = (u8 *)pi;
110478b8fecSSam Ravnborg 		while (count--)
1116b8b5507SSam Ravnborg 			*pb++ = __raw_readb(addr);
112478b8fecSSam Ravnborg 	}
113478b8fecSSam Ravnborg }
114917c3660SSam Ravnborg EXPORT_SYMBOL(insb);
115478b8fecSSam Ravnborg 
insw(unsigned long __addr,void * dst,unsigned long count)116478b8fecSSam Ravnborg void insw(unsigned long __addr, void *dst, unsigned long count)
117478b8fecSSam Ravnborg {
118478b8fecSSam Ravnborg 	void __iomem *addr = (void __iomem *) __addr;
119478b8fecSSam Ravnborg 
120478b8fecSSam Ravnborg 	if (count) {
121478b8fecSSam Ravnborg 		u16 *ps = dst;
122478b8fecSSam Ravnborg 		u32 *pi;
123478b8fecSSam Ravnborg 
124478b8fecSSam Ravnborg 		if (((unsigned long)ps) & 0x2) {
1256b8b5507SSam Ravnborg 			*ps++ = __raw_readw(addr);
126478b8fecSSam Ravnborg 			count--;
127478b8fecSSam Ravnborg 		}
128478b8fecSSam Ravnborg 		pi = (u32 *)ps;
129478b8fecSSam Ravnborg 		while (count >= 2) {
130478b8fecSSam Ravnborg 			u32 w;
131478b8fecSSam Ravnborg 
1326b8b5507SSam Ravnborg 			w  = __raw_readw(addr) << 16;
1336b8b5507SSam Ravnborg 			w |= __raw_readw(addr) << 0;
134478b8fecSSam Ravnborg 			*pi++ = w;
135478b8fecSSam Ravnborg 			count -= 2;
136478b8fecSSam Ravnborg 		}
137478b8fecSSam Ravnborg 		ps = (u16 *)pi;
138478b8fecSSam Ravnborg 		if (count)
1396b8b5507SSam Ravnborg 			*ps = __raw_readw(addr);
140478b8fecSSam Ravnborg 	}
141478b8fecSSam Ravnborg }
142917c3660SSam Ravnborg EXPORT_SYMBOL(insw);
143478b8fecSSam Ravnborg 
insl(unsigned long __addr,void * dst,unsigned long count)144478b8fecSSam Ravnborg void insl(unsigned long __addr, void *dst, unsigned long count)
145478b8fecSSam Ravnborg {
146478b8fecSSam Ravnborg 	void __iomem *addr = (void __iomem *) __addr;
147478b8fecSSam Ravnborg 
148478b8fecSSam Ravnborg 	if (count) {
149478b8fecSSam Ravnborg 		if ((((unsigned long)dst) & 0x3) == 0) {
150478b8fecSSam Ravnborg 			u32 *pi = dst;
151478b8fecSSam Ravnborg 			while (count--)
1526b8b5507SSam Ravnborg 				*pi++ = __raw_readl(addr);
153478b8fecSSam Ravnborg 		} else {
154478b8fecSSam Ravnborg 			u32 l = 0, l2, *pi;
155478b8fecSSam Ravnborg 			u16 *ps;
156478b8fecSSam Ravnborg 			u8 *pb;
157478b8fecSSam Ravnborg 
158478b8fecSSam Ravnborg 			switch (((unsigned long)dst) & 3) {
159478b8fecSSam Ravnborg 			case 0x2:
160478b8fecSSam Ravnborg 				ps = dst;
161478b8fecSSam Ravnborg 				count -= 1;
1626b8b5507SSam Ravnborg 				l = __raw_readl(addr);
163478b8fecSSam Ravnborg 				*ps++ = l;
164478b8fecSSam Ravnborg 				pi = (u32 *)ps;
165478b8fecSSam Ravnborg 				while (count--) {
1666b8b5507SSam Ravnborg 					l2 = __raw_readl(addr);
167478b8fecSSam Ravnborg 					*pi++ = (l << 16) | (l2 >> 16);
168478b8fecSSam Ravnborg 					l = l2;
169478b8fecSSam Ravnborg 				}
170478b8fecSSam Ravnborg 				ps = (u16 *)pi;
171478b8fecSSam Ravnborg 				*ps = l;
172478b8fecSSam Ravnborg 				break;
173478b8fecSSam Ravnborg 
174478b8fecSSam Ravnborg 			case 0x1:
175478b8fecSSam Ravnborg 				pb = dst;
176478b8fecSSam Ravnborg 				count -= 1;
1776b8b5507SSam Ravnborg 				l = __raw_readl(addr);
178478b8fecSSam Ravnborg 				*pb++ = l >> 24;
179478b8fecSSam Ravnborg 				ps = (u16 *)pb;
180478b8fecSSam Ravnborg 				*ps++ = ((l >> 8) & 0xffff);
181478b8fecSSam Ravnborg 				pi = (u32 *)ps;
182478b8fecSSam Ravnborg 				while (count--) {
1836b8b5507SSam Ravnborg 					l2 = __raw_readl(addr);
184478b8fecSSam Ravnborg 					*pi++ = (l << 24) | (l2 >> 8);
185478b8fecSSam Ravnborg 					l = l2;
186478b8fecSSam Ravnborg 				}
187478b8fecSSam Ravnborg 				pb = (u8 *)pi;
188478b8fecSSam Ravnborg 				*pb = l;
189478b8fecSSam Ravnborg 				break;
190478b8fecSSam Ravnborg 
191478b8fecSSam Ravnborg 			case 0x3:
192478b8fecSSam Ravnborg 				pb = (u8 *)dst;
193478b8fecSSam Ravnborg 				count -= 1;
1946b8b5507SSam Ravnborg 				l = __raw_readl(addr);
195478b8fecSSam Ravnborg 				*pb++ = l >> 24;
196478b8fecSSam Ravnborg 				pi = (u32 *)pb;
197478b8fecSSam Ravnborg 				while (count--) {
1986b8b5507SSam Ravnborg 					l2 = __raw_readl(addr);
199478b8fecSSam Ravnborg 					*pi++ = (l << 8) | (l2 >> 24);
200478b8fecSSam Ravnborg 					l = l2;
201478b8fecSSam Ravnborg 				}
202478b8fecSSam Ravnborg 				ps = (u16 *)pi;
203478b8fecSSam Ravnborg 				*ps++ = ((l >> 8) & 0xffff);
204478b8fecSSam Ravnborg 				pb = (u8 *)ps;
205478b8fecSSam Ravnborg 				*pb = l;
206478b8fecSSam Ravnborg 				break;
207478b8fecSSam Ravnborg 			}
208478b8fecSSam Ravnborg 		}
209478b8fecSSam Ravnborg 	}
210478b8fecSSam Ravnborg }
211917c3660SSam Ravnborg EXPORT_SYMBOL(insl);
212478b8fecSSam Ravnborg 
213