diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/sh/boards/se |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'arch/sh/boards/se')
-rw-r--r-- | arch/sh/boards/se/7300/Makefile | 7 | ||||
-rw-r--r-- | arch/sh/boards/se/7300/io.c | 265 | ||||
-rw-r--r-- | arch/sh/boards/se/7300/irq.c | 37 | ||||
-rw-r--r-- | arch/sh/boards/se/7300/led.c | 69 | ||||
-rw-r--r-- | arch/sh/boards/se/7300/setup.c | 66 | ||||
-rw-r--r-- | arch/sh/boards/se/73180/Makefile | 7 | ||||
-rw-r--r-- | arch/sh/boards/se/73180/io.c | 265 | ||||
-rw-r--r-- | arch/sh/boards/se/73180/irq.c | 137 | ||||
-rw-r--r-- | arch/sh/boards/se/73180/led.c | 67 | ||||
-rw-r--r-- | arch/sh/boards/se/73180/setup.c | 68 | ||||
-rw-r--r-- | arch/sh/boards/se/770x/Makefile | 6 | ||||
-rw-r--r-- | arch/sh/boards/se/770x/io.c | 226 | ||||
-rw-r--r-- | arch/sh/boards/se/770x/irq.c | 80 | ||||
-rw-r--r-- | arch/sh/boards/se/770x/led.c | 68 | ||||
-rw-r--r-- | arch/sh/boards/se/770x/mach.c | 68 | ||||
-rw-r--r-- | arch/sh/boards/se/770x/setup.c | 85 | ||||
-rw-r--r-- | arch/sh/boards/se/7751/Makefile | 8 | ||||
-rw-r--r-- | arch/sh/boards/se/7751/io.c | 244 | ||||
-rw-r--r-- | arch/sh/boards/se/7751/irq.c | 67 | ||||
-rw-r--r-- | arch/sh/boards/se/7751/led.c | 68 | ||||
-rw-r--r-- | arch/sh/boards/se/7751/mach.c | 55 | ||||
-rw-r--r-- | arch/sh/boards/se/7751/pci.c | 148 | ||||
-rw-r--r-- | arch/sh/boards/se/7751/setup.c | 228 |
23 files changed, 2339 insertions, 0 deletions
diff --git a/arch/sh/boards/se/7300/Makefile b/arch/sh/boards/se/7300/Makefile new file mode 100644 index 000000000000..0fbd4f47815c --- /dev/null +++ b/arch/sh/boards/se/7300/Makefile | |||
@@ -0,0 +1,7 @@ | |||
1 | # | ||
2 | # Makefile for the 7300 SolutionEngine specific parts of the kernel | ||
3 | # | ||
4 | |||
5 | obj-y := setup.o io.o irq.o | ||
6 | |||
7 | obj-$(CONFIG_HEARTBEAT) += led.o | ||
diff --git a/arch/sh/boards/se/7300/io.c b/arch/sh/boards/se/7300/io.c new file mode 100644 index 000000000000..3c89def46480 --- /dev/null +++ b/arch/sh/boards/se/7300/io.c | |||
@@ -0,0 +1,265 @@ | |||
1 | /* | ||
2 | * arch/sh/boards/se/7300/io.c | ||
3 | * | ||
4 | * Copyright (C) 2003 YOSHII Takashi <yoshii-takashi@hitachi-ul.co.jp> | ||
5 | * Based on arch/sh/kernel/io_shmse.c | ||
6 | * | ||
7 | * I/O routine for SH-Mobile3 73180 SolutionEngine. | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <linux/config.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <asm/mach/se7300.h> | ||
14 | #include <asm/io.h> | ||
15 | |||
16 | #define badio(fn, a) panic("bad i/o operation %s for %08lx.", #fn, a) | ||
17 | |||
18 | struct iop { | ||
19 | unsigned long start, end; | ||
20 | unsigned long base; | ||
21 | struct iop *(*check) (struct iop * p, unsigned long port); | ||
22 | unsigned char (*inb) (struct iop * p, unsigned long port); | ||
23 | unsigned short (*inw) (struct iop * p, unsigned long port); | ||
24 | void (*outb) (struct iop * p, unsigned char value, unsigned long port); | ||
25 | void (*outw) (struct iop * p, unsigned short value, unsigned long port); | ||
26 | }; | ||
27 | |||
28 | struct iop * | ||
29 | simple_check(struct iop *p, unsigned long port) | ||
30 | { | ||
31 | if ((p->start <= port) && (port <= p->end)) | ||
32 | return p; | ||
33 | else | ||
34 | badio(check, port); | ||
35 | } | ||
36 | |||
37 | struct iop * | ||
38 | ide_check(struct iop *p, unsigned long port) | ||
39 | { | ||
40 | if (((0x1f0 <= port) && (port <= 0x1f7)) || (port == 0x3f7)) | ||
41 | return p; | ||
42 | return NULL; | ||
43 | } | ||
44 | |||
45 | unsigned char | ||
46 | simple_inb(struct iop *p, unsigned long port) | ||
47 | { | ||
48 | return *(unsigned char *) (p->base + port); | ||
49 | } | ||
50 | |||
51 | unsigned short | ||
52 | simple_inw(struct iop *p, unsigned long port) | ||
53 | { | ||
54 | return *(unsigned short *) (p->base + port); | ||
55 | } | ||
56 | |||
57 | void | ||
58 | simple_outb(struct iop *p, unsigned char value, unsigned long port) | ||
59 | { | ||
60 | *(unsigned char *) (p->base + port) = value; | ||
61 | } | ||
62 | |||
63 | void | ||
64 | simple_outw(struct iop *p, unsigned short value, unsigned long port) | ||
65 | { | ||
66 | *(unsigned short *) (p->base + port) = value; | ||
67 | } | ||
68 | |||
69 | unsigned char | ||
70 | pcc_inb(struct iop *p, unsigned long port) | ||
71 | { | ||
72 | unsigned long addr = p->base + port + 0x40000; | ||
73 | unsigned long v; | ||
74 | |||
75 | if (port & 1) | ||
76 | addr += 0x00400000; | ||
77 | v = *(volatile unsigned char *) addr; | ||
78 | return v; | ||
79 | } | ||
80 | |||
81 | void | ||
82 | pcc_outb(struct iop *p, unsigned char value, unsigned long port) | ||
83 | { | ||
84 | unsigned long addr = p->base + port + 0x40000; | ||
85 | |||
86 | if (port & 1) | ||
87 | addr += 0x00400000; | ||
88 | *(volatile unsigned char *) addr = value; | ||
89 | } | ||
90 | |||
91 | unsigned char | ||
92 | bad_inb(struct iop *p, unsigned long port) | ||
93 | { | ||
94 | badio(inb, port); | ||
95 | } | ||
96 | |||
97 | void | ||
98 | bad_outb(struct iop *p, unsigned char value, unsigned long port) | ||
99 | { | ||
100 | badio(inw, port); | ||
101 | } | ||
102 | |||
103 | /* MSTLANEX01 LAN at 0xb400:0000 */ | ||
104 | static struct iop laniop = { | ||
105 | .start = 0x300, | ||
106 | .end = 0x30f, | ||
107 | .base = 0xb4000000, | ||
108 | .check = simple_check, | ||
109 | .inb = simple_inb, | ||
110 | .inw = simple_inw, | ||
111 | .outb = simple_outb, | ||
112 | .outw = simple_outw, | ||
113 | }; | ||
114 | |||
115 | /* NE2000 pc card NIC */ | ||
116 | static struct iop neiop = { | ||
117 | .start = 0x280, | ||
118 | .end = 0x29f, | ||
119 | .base = 0xb0600000 + 0x80, /* soft 0x280 -> hard 0x300 */ | ||
120 | .check = simple_check, | ||
121 | .inb = pcc_inb, | ||
122 | .inw = simple_inw, | ||
123 | .outb = pcc_outb, | ||
124 | .outw = simple_outw, | ||
125 | }; | ||
126 | |||
127 | /* CF in CF slot */ | ||
128 | static struct iop cfiop = { | ||
129 | .base = 0xb0600000, | ||
130 | .check = ide_check, | ||
131 | .inb = pcc_inb, | ||
132 | .inw = simple_inw, | ||
133 | .outb = pcc_outb, | ||
134 | .outw = simple_outw, | ||
135 | }; | ||
136 | |||
137 | static __inline__ struct iop * | ||
138 | port2iop(unsigned long port) | ||
139 | { | ||
140 | if (0) ; | ||
141 | #if defined(CONFIG_SMC91111) | ||
142 | else if (laniop.check(&laniop, port)) | ||
143 | return &laniop; | ||
144 | #endif | ||
145 | #if defined(CONFIG_NE2000) | ||
146 | else if (neiop.check(&neiop, port)) | ||
147 | return &neiop; | ||
148 | #endif | ||
149 | #if defined(CONFIG_IDE) | ||
150 | else if (cfiop.check(&cfiop, port)) | ||
151 | return &cfiop; | ||
152 | #endif | ||
153 | else | ||
154 | return &neiop; /* fallback */ | ||
155 | } | ||
156 | |||
157 | static inline void | ||
158 | delay(void) | ||
159 | { | ||
160 | ctrl_inw(0xac000000); | ||
161 | ctrl_inw(0xac000000); | ||
162 | } | ||
163 | |||
164 | unsigned char | ||
165 | sh7300se_inb(unsigned long port) | ||
166 | { | ||
167 | struct iop *p = port2iop(port); | ||
168 | return (p->inb) (p, port); | ||
169 | } | ||
170 | |||
171 | unsigned char | ||
172 | sh7300se_inb_p(unsigned long port) | ||
173 | { | ||
174 | unsigned char v = sh7300se_inb(port); | ||
175 | delay(); | ||
176 | return v; | ||
177 | } | ||
178 | |||
179 | unsigned short | ||
180 | sh7300se_inw(unsigned long port) | ||
181 | { | ||
182 | struct iop *p = port2iop(port); | ||
183 | return (p->inw) (p, port); | ||
184 | } | ||
185 | |||
186 | unsigned int | ||
187 | sh7300se_inl(unsigned long port) | ||
188 | { | ||
189 | badio(inl, port); | ||
190 | } | ||
191 | |||
192 | void | ||
193 | sh7300se_outb(unsigned char value, unsigned long port) | ||
194 | { | ||
195 | struct iop *p = port2iop(port); | ||
196 | (p->outb) (p, value, port); | ||
197 | } | ||
198 | |||
199 | void | ||
200 | sh7300se_outb_p(unsigned char value, unsigned long port) | ||
201 | { | ||
202 | sh7300se_outb(value, port); | ||
203 | delay(); | ||
204 | } | ||
205 | |||
206 | void | ||
207 | sh7300se_outw(unsigned short value, unsigned long port) | ||
208 | { | ||
209 | struct iop *p = port2iop(port); | ||
210 | (p->outw) (p, value, port); | ||
211 | } | ||
212 | |||
213 | void | ||
214 | sh7300se_outl(unsigned int value, unsigned long port) | ||
215 | { | ||
216 | badio(outl, port); | ||
217 | } | ||
218 | |||
219 | void | ||
220 | sh7300se_insb(unsigned long port, void *addr, unsigned long count) | ||
221 | { | ||
222 | unsigned char *a = addr; | ||
223 | struct iop *p = port2iop(port); | ||
224 | while (count--) | ||
225 | *a++ = (p->inb) (p, port); | ||
226 | } | ||
227 | |||
228 | void | ||
229 | sh7300se_insw(unsigned long port, void *addr, unsigned long count) | ||
230 | { | ||
231 | unsigned short *a = addr; | ||
232 | struct iop *p = port2iop(port); | ||
233 | while (count--) | ||
234 | *a++ = (p->inw) (p, port); | ||
235 | } | ||
236 | |||
237 | void | ||
238 | sh7300se_insl(unsigned long port, void *addr, unsigned long count) | ||
239 | { | ||
240 | badio(insl, port); | ||
241 | } | ||
242 | |||
243 | void | ||
244 | sh7300se_outsb(unsigned long port, const void *addr, unsigned long count) | ||
245 | { | ||
246 | unsigned char *a = (unsigned char *) addr; | ||
247 | struct iop *p = port2iop(port); | ||
248 | while (count--) | ||
249 | (p->outb) (p, *a++, port); | ||
250 | } | ||
251 | |||
252 | void | ||
253 | sh7300se_outsw(unsigned long port, const void *addr, unsigned long count) | ||
254 | { | ||
255 | unsigned short *a = (unsigned short *) addr; | ||
256 | struct iop *p = port2iop(port); | ||
257 | while (count--) | ||
258 | (p->outw) (p, *a++, port); | ||
259 | } | ||
260 | |||
261 | void | ||
262 | sh7300se_outsl(unsigned long port, const void *addr, unsigned long count) | ||
263 | { | ||
264 | badio(outsw, port); | ||
265 | } | ||
diff --git a/arch/sh/boards/se/7300/irq.c b/arch/sh/boards/se/7300/irq.c new file mode 100644 index 000000000000..96c8c23d6c93 --- /dev/null +++ b/arch/sh/boards/se/7300/irq.c | |||
@@ -0,0 +1,37 @@ | |||
1 | /* | ||
2 | * linux/arch/sh/boards/se/7300/irq.c | ||
3 | * | ||
4 | * Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp> | ||
5 | * | ||
6 | * SH-Mobile SolutionEngine 7300 Support. | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | #include <linux/config.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/irq.h> | ||
13 | #include <asm/irq.h> | ||
14 | #include <asm/io.h> | ||
15 | #include <asm/mach/se7300.h> | ||
16 | |||
17 | /* | ||
18 | * Initialize IRQ setting | ||
19 | */ | ||
20 | void __init | ||
21 | init_7300se_IRQ(void) | ||
22 | { | ||
23 | ctrl_outw(0x0028, PA_EPLD_MODESET); /* mode set IRQ0,1 active low. */ | ||
24 | ctrl_outw(0xa000, INTC_ICR1); /* IRQ mode; IRQ0,1 enable. */ | ||
25 | ctrl_outw(0x0000, PORT_PFCR); /* use F for IRQ[3:0] and SIU. */ | ||
26 | |||
27 | /* PC_IRQ[0-3] -> IRQ0 (32) */ | ||
28 | make_ipr_irq(IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, 0x0f - IRQ0_IRQ); | ||
29 | /* A_IRQ[0-3] -> IRQ1 (33) */ | ||
30 | make_ipr_irq(IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, 0x0f - IRQ1_IRQ); | ||
31 | make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY); | ||
32 | make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); | ||
33 | make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); | ||
34 | make_ipr_irq(VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY); | ||
35 | |||
36 | ctrl_outw(0x2000, PA_MRSHPC + 0x0c); /* mrshpc irq enable */ | ||
37 | } | ||
diff --git a/arch/sh/boards/se/7300/led.c b/arch/sh/boards/se/7300/led.c new file mode 100644 index 000000000000..02c7f846c84c --- /dev/null +++ b/arch/sh/boards/se/7300/led.c | |||
@@ -0,0 +1,69 @@ | |||
1 | /* | ||
2 | * linux/arch/sh/boards/se/7300/led.c | ||
3 | * | ||
4 | * Derived from linux/arch/sh/boards/se/770x/led.c | ||
5 | * | ||
6 | * Copyright (C) 2000 Stuart Menefy <stuart.menefy@st.com> | ||
7 | * | ||
8 | * May be copied or modified under the terms of the GNU General Public | ||
9 | * License. See linux/COPYING for more information. | ||
10 | * | ||
11 | * This file contains Solution Engine specific LED code. | ||
12 | */ | ||
13 | |||
14 | #include <linux/config.h> | ||
15 | #include <linux/sched.h> | ||
16 | #include <asm/mach/se7300.h> | ||
17 | |||
18 | static void | ||
19 | mach_led(int position, int value) | ||
20 | { | ||
21 | volatile unsigned short *p = (volatile unsigned short *) PA_LED; | ||
22 | |||
23 | if (value) { | ||
24 | *p |= (1 << 8); | ||
25 | } else { | ||
26 | *p &= ~(1 << 8); | ||
27 | } | ||
28 | } | ||
29 | |||
30 | |||
31 | /* Cycle the LED's in the clasic Knightrider/Sun pattern */ | ||
32 | void | ||
33 | heartbeat_7300se(void) | ||
34 | { | ||
35 | static unsigned int cnt = 0, period = 0; | ||
36 | volatile unsigned short *p = (volatile unsigned short *) PA_LED; | ||
37 | static unsigned bit = 0, up = 1; | ||
38 | |||
39 | cnt += 1; | ||
40 | if (cnt < period) { | ||
41 | return; | ||
42 | } | ||
43 | |||
44 | cnt = 0; | ||
45 | |||
46 | /* Go through the points (roughly!): | ||
47 | * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110 | ||
48 | */ | ||
49 | period = 110 - ((300 << FSHIFT) / ((avenrun[0] / 5) + (3 << FSHIFT))); | ||
50 | |||
51 | if (up) { | ||
52 | if (bit == 7) { | ||
53 | bit--; | ||
54 | up = 0; | ||
55 | } else { | ||
56 | bit++; | ||
57 | } | ||
58 | } else { | ||
59 | if (bit == 0) { | ||
60 | bit++; | ||
61 | up = 1; | ||
62 | } else { | ||
63 | bit--; | ||
64 | } | ||
65 | } | ||
66 | *p = 1 << (bit + 8); | ||
67 | |||
68 | } | ||
69 | |||
diff --git a/arch/sh/boards/se/7300/setup.c b/arch/sh/boards/se/7300/setup.c new file mode 100644 index 000000000000..08536bc224dc --- /dev/null +++ b/arch/sh/boards/se/7300/setup.c | |||
@@ -0,0 +1,66 @@ | |||
1 | /* | ||
2 | * linux/arch/sh/boards/se/7300/setup.c | ||
3 | * | ||
4 | * Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp> | ||
5 | * | ||
6 | * SH-Mobile SolutionEngine 7300 Support. | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | #include <linux/config.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <asm/machvec.h> | ||
13 | #include <asm/machvec_init.h> | ||
14 | #include <asm/mach/io.h> | ||
15 | |||
16 | void heartbeat_7300se(void); | ||
17 | void init_7300se_IRQ(void); | ||
18 | |||
19 | const char * | ||
20 | get_system_type(void) | ||
21 | { | ||
22 | return "SolutionEngine 7300"; | ||
23 | } | ||
24 | |||
25 | /* | ||
26 | * The Machine Vector | ||
27 | */ | ||
28 | |||
29 | struct sh_machine_vector mv_7300se __initmv = { | ||
30 | .mv_nr_irqs = 109, | ||
31 | .mv_inb = sh7300se_inb, | ||
32 | .mv_inw = sh7300se_inw, | ||
33 | .mv_inl = sh7300se_inl, | ||
34 | .mv_outb = sh7300se_outb, | ||
35 | .mv_outw = sh7300se_outw, | ||
36 | .mv_outl = sh7300se_outl, | ||
37 | |||
38 | .mv_inb_p = sh7300se_inb_p, | ||
39 | .mv_inw_p = sh7300se_inw, | ||
40 | .mv_inl_p = sh7300se_inl, | ||
41 | .mv_outb_p = sh7300se_outb_p, | ||
42 | .mv_outw_p = sh7300se_outw, | ||
43 | .mv_outl_p = sh7300se_outl, | ||
44 | |||
45 | .mv_insb = sh7300se_insb, | ||
46 | .mv_insw = sh7300se_insw, | ||
47 | .mv_insl = sh7300se_insl, | ||
48 | .mv_outsb = sh7300se_outsb, | ||
49 | .mv_outsw = sh7300se_outsw, | ||
50 | .mv_outsl = sh7300se_outsl, | ||
51 | |||
52 | .mv_init_irq = init_7300se_IRQ, | ||
53 | #ifdef CONFIG_HEARTBEAT | ||
54 | .mv_heartbeat = heartbeat_7300se, | ||
55 | #endif | ||
56 | }; | ||
57 | |||
58 | ALIAS_MV(7300se) | ||
59 | /* | ||
60 | * Initialize the board | ||
61 | */ | ||
62 | void __init | ||
63 | platform_setup(void) | ||
64 | { | ||
65 | |||
66 | } | ||
diff --git a/arch/sh/boards/se/73180/Makefile b/arch/sh/boards/se/73180/Makefile new file mode 100644 index 000000000000..8f63886a0f3f --- /dev/null +++ b/arch/sh/boards/se/73180/Makefile | |||
@@ -0,0 +1,7 @@ | |||
1 | # | ||
2 | # Makefile for the 73180 SolutionEngine specific parts of the kernel | ||
3 | # | ||
4 | |||
5 | obj-y := setup.o io.o irq.o | ||
6 | |||
7 | obj-$(CONFIG_HEARTBEAT) += led.o | ||
diff --git a/arch/sh/boards/se/73180/io.c b/arch/sh/boards/se/73180/io.c new file mode 100644 index 000000000000..73648cbe3678 --- /dev/null +++ b/arch/sh/boards/se/73180/io.c | |||
@@ -0,0 +1,265 @@ | |||
1 | /* | ||
2 | * arch/sh/boards/se/73180/io.c | ||
3 | * | ||
4 | * Copyright (C) 2003 YOSHII Takashi <yoshii-takashi@hitachi-ul.co.jp> | ||
5 | * Based on arch/sh/boards/se/7300/io.c | ||
6 | * | ||
7 | * I/O routine for SH-Mobile3 73180 SolutionEngine. | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <linux/config.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <asm/mach/se73180.h> | ||
14 | #include <asm/io.h> | ||
15 | |||
16 | #define badio(fn, a) panic("bad i/o operation %s for %08lx.", #fn, a) | ||
17 | |||
18 | struct iop { | ||
19 | unsigned long start, end; | ||
20 | unsigned long base; | ||
21 | struct iop *(*check) (struct iop * p, unsigned long port); | ||
22 | unsigned char (*inb) (struct iop * p, unsigned long port); | ||
23 | unsigned short (*inw) (struct iop * p, unsigned long port); | ||
24 | void (*outb) (struct iop * p, unsigned char value, unsigned long port); | ||
25 | void (*outw) (struct iop * p, unsigned short value, unsigned long port); | ||
26 | }; | ||
27 | |||
28 | struct iop * | ||
29 | simple_check(struct iop *p, unsigned long port) | ||
30 | { | ||
31 | if ((p->start <= port) && (port <= p->end)) | ||
32 | return p; | ||
33 | else | ||
34 | badio(check, port); | ||
35 | } | ||
36 | |||
37 | struct iop * | ||
38 | ide_check(struct iop *p, unsigned long port) | ||
39 | { | ||
40 | if (((0x1f0 <= port) && (port <= 0x1f7)) || (port == 0x3f7)) | ||
41 | return p; | ||
42 | return NULL; | ||
43 | } | ||
44 | |||
45 | unsigned char | ||
46 | simple_inb(struct iop *p, unsigned long port) | ||
47 | { | ||
48 | return *(unsigned char *) (p->base + port); | ||
49 | } | ||
50 | |||
51 | unsigned short | ||
52 | simple_inw(struct iop *p, unsigned long port) | ||
53 | { | ||
54 | return *(unsigned short *) (p->base + port); | ||
55 | } | ||
56 | |||
57 | void | ||
58 | simple_outb(struct iop *p, unsigned char value, unsigned long port) | ||
59 | { | ||
60 | *(unsigned char *) (p->base + port) = value; | ||
61 | } | ||
62 | |||
63 | void | ||
64 | simple_outw(struct iop *p, unsigned short value, unsigned long port) | ||
65 | { | ||
66 | *(unsigned short *) (p->base + port) = value; | ||
67 | } | ||
68 | |||
69 | unsigned char | ||
70 | pcc_inb(struct iop *p, unsigned long port) | ||
71 | { | ||
72 | unsigned long addr = p->base + port + 0x40000; | ||
73 | unsigned long v; | ||
74 | |||
75 | if (port & 1) | ||
76 | addr += 0x00400000; | ||
77 | v = *(volatile unsigned char *) addr; | ||
78 | return v; | ||
79 | } | ||
80 | |||
81 | void | ||
82 | pcc_outb(struct iop *p, unsigned char value, unsigned long port) | ||
83 | { | ||
84 | unsigned long addr = p->base + port + 0x40000; | ||
85 | |||
86 | if (port & 1) | ||
87 | addr += 0x00400000; | ||
88 | *(volatile unsigned char *) addr = value; | ||
89 | } | ||
90 | |||
91 | unsigned char | ||
92 | bad_inb(struct iop *p, unsigned long port) | ||
93 | { | ||
94 | badio(inb, port); | ||
95 | } | ||
96 | |||
97 | void | ||
98 | bad_outb(struct iop *p, unsigned char value, unsigned long port) | ||
99 | { | ||
100 | badio(inw, port); | ||
101 | } | ||
102 | |||
103 | /* MSTLANEX01 LAN at 0xb400:0000 */ | ||
104 | static struct iop laniop = { | ||
105 | .start = 0x300, | ||
106 | .end = 0x30f, | ||
107 | .base = 0xb4000000, | ||
108 | .check = simple_check, | ||
109 | .inb = simple_inb, | ||
110 | .inw = simple_inw, | ||
111 | .outb = simple_outb, | ||
112 | .outw = simple_outw, | ||
113 | }; | ||
114 | |||
115 | /* NE2000 pc card NIC */ | ||
116 | static struct iop neiop = { | ||
117 | .start = 0x280, | ||
118 | .end = 0x29f, | ||
119 | .base = 0xb0600000 + 0x80, /* soft 0x280 -> hard 0x300 */ | ||
120 | .check = simple_check, | ||
121 | .inb = pcc_inb, | ||
122 | .inw = simple_inw, | ||
123 | .outb = pcc_outb, | ||
124 | .outw = simple_outw, | ||
125 | }; | ||
126 | |||
127 | /* CF in CF slot */ | ||
128 | static struct iop cfiop = { | ||
129 | .base = 0xb0600000, | ||
130 | .check = ide_check, | ||
131 | .inb = pcc_inb, | ||
132 | .inw = simple_inw, | ||
133 | .outb = pcc_outb, | ||
134 | .outw = simple_outw, | ||
135 | }; | ||
136 | |||
137 | static __inline__ struct iop * | ||
138 | port2iop(unsigned long port) | ||
139 | { | ||
140 | if (0) ; | ||
141 | #if defined(CONFIG_SMC91111) | ||
142 | else if (laniop.check(&laniop, port)) | ||
143 | return &laniop; | ||
144 | #endif | ||
145 | #if defined(CONFIG_NE2000) | ||
146 | else if (neiop.check(&neiop, port)) | ||
147 | return &neiop; | ||
148 | #endif | ||
149 | #if defined(CONFIG_IDE) | ||
150 | else if (cfiop.check(&cfiop, port)) | ||
151 | return &cfiop; | ||
152 | #endif | ||
153 | else | ||
154 | return &neiop; /* fallback */ | ||
155 | } | ||
156 | |||
157 | static inline void | ||
158 | delay(void) | ||
159 | { | ||
160 | ctrl_inw(0xac000000); | ||
161 | ctrl_inw(0xac000000); | ||
162 | } | ||
163 | |||
164 | unsigned char | ||
165 | sh73180se_inb(unsigned long port) | ||
166 | { | ||
167 | struct iop *p = port2iop(port); | ||
168 | return (p->inb) (p, port); | ||
169 | } | ||
170 | |||
171 | unsigned char | ||
172 | sh73180se_inb_p(unsigned long port) | ||
173 | { | ||
174 | unsigned char v = sh73180se_inb(port); | ||
175 | delay(); | ||
176 | return v; | ||
177 | } | ||
178 | |||
179 | unsigned short | ||
180 | sh73180se_inw(unsigned long port) | ||
181 | { | ||
182 | struct iop *p = port2iop(port); | ||
183 | return (p->inw) (p, port); | ||
184 | } | ||
185 | |||
186 | unsigned int | ||
187 | sh73180se_inl(unsigned long port) | ||
188 | { | ||
189 | badio(inl, port); | ||
190 | } | ||
191 | |||
192 | void | ||
193 | sh73180se_outb(unsigned char value, unsigned long port) | ||
194 | { | ||
195 | struct iop *p = port2iop(port); | ||
196 | (p->outb) (p, value, port); | ||
197 | } | ||
198 | |||
199 | void | ||
200 | sh73180se_outb_p(unsigned char value, unsigned long port) | ||
201 | { | ||
202 | sh73180se_outb(value, port); | ||
203 | delay(); | ||
204 | } | ||
205 | |||
206 | void | ||
207 | sh73180se_outw(unsigned short value, unsigned long port) | ||
208 | { | ||
209 | struct iop *p = port2iop(port); | ||
210 | (p->outw) (p, value, port); | ||
211 | } | ||
212 | |||
213 | void | ||
214 | sh73180se_outl(unsigned int value, unsigned long port) | ||
215 | { | ||
216 | badio(outl, port); | ||
217 | } | ||
218 | |||
219 | void | ||
220 | sh73180se_insb(unsigned long port, void *addr, unsigned long count) | ||
221 | { | ||
222 | unsigned char *a = addr; | ||
223 | struct iop *p = port2iop(port); | ||
224 | while (count--) | ||
225 | *a++ = (p->inb) (p, port); | ||
226 | } | ||
227 | |||
228 | void | ||
229 | sh73180se_insw(unsigned long port, void *addr, unsigned long count) | ||
230 | { | ||
231 | unsigned short *a = addr; | ||
232 | struct iop *p = port2iop(port); | ||
233 | while (count--) | ||
234 | *a++ = (p->inw) (p, port); | ||
235 | } | ||
236 | |||
237 | void | ||
238 | sh73180se_insl(unsigned long port, void *addr, unsigned long count) | ||
239 | { | ||
240 | badio(insl, port); | ||
241 | } | ||
242 | |||
243 | void | ||
244 | sh73180se_outsb(unsigned long port, const void *addr, unsigned long count) | ||
245 | { | ||
246 | unsigned char *a = (unsigned char *) addr; | ||
247 | struct iop *p = port2iop(port); | ||
248 | while (count--) | ||
249 | (p->outb) (p, *a++, port); | ||
250 | } | ||
251 | |||
252 | void | ||
253 | sh73180se_outsw(unsigned long port, const void *addr, unsigned long count) | ||
254 | { | ||
255 | unsigned short *a = (unsigned short *) addr; | ||
256 | struct iop *p = port2iop(port); | ||
257 | while (count--) | ||
258 | (p->outw) (p, *a++, port); | ||
259 | } | ||
260 | |||
261 | void | ||
262 | sh73180se_outsl(unsigned long port, const void *addr, unsigned long count) | ||
263 | { | ||
264 | badio(outsw, port); | ||
265 | } | ||
diff --git a/arch/sh/boards/se/73180/irq.c b/arch/sh/boards/se/73180/irq.c new file mode 100644 index 000000000000..70f04caad9a4 --- /dev/null +++ b/arch/sh/boards/se/73180/irq.c | |||
@@ -0,0 +1,137 @@ | |||
1 | /* | ||
2 | * arch/sh/boards/se/73180/irq.c | ||
3 | * | ||
4 | * Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp> | ||
5 | * Based on arch/sh/boards/se/7300/irq.c | ||
6 | * | ||
7 | * Modified for SH-Mobile SolutionEngine 73180 Support | ||
8 | * by YOSHII Takashi <yoshii-takashi@hitachi-ul.co.jp> | ||
9 | * | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | #include <linux/config.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/irq.h> | ||
16 | #include <asm/irq.h> | ||
17 | #include <asm/io.h> | ||
18 | #include <asm/mach/se73180.h> | ||
19 | |||
20 | static int | ||
21 | intreq2irq(int i) | ||
22 | { | ||
23 | if (i == 5) | ||
24 | return 10; | ||
25 | return 32 + 7 - i; | ||
26 | } | ||
27 | |||
28 | static int | ||
29 | irq2intreq(int irq) | ||
30 | { | ||
31 | if (irq == 10) | ||
32 | return 5; | ||
33 | return 7 - (irq - 32); | ||
34 | } | ||
35 | |||
36 | static void | ||
37 | disable_intreq_irq(unsigned int irq) | ||
38 | { | ||
39 | ctrl_outb(1 << (7 - irq2intreq(irq)), INTMSK0); | ||
40 | } | ||
41 | |||
42 | static void | ||
43 | enable_intreq_irq(unsigned int irq) | ||
44 | { | ||
45 | ctrl_outb(1 << (7 - irq2intreq(irq)), INTMSKCLR0); | ||
46 | } | ||
47 | |||
48 | static void | ||
49 | mask_and_ack_intreq_irq(unsigned int irq) | ||
50 | { | ||
51 | disable_intreq_irq(irq); | ||
52 | } | ||
53 | |||
54 | static unsigned int | ||
55 | startup_intreq_irq(unsigned int irq) | ||
56 | { | ||
57 | enable_intreq_irq(irq); | ||
58 | return 0; | ||
59 | } | ||
60 | |||
61 | static void | ||
62 | shutdown_intreq_irq(unsigned int irq) | ||
63 | { | ||
64 | disable_intreq_irq(irq); | ||
65 | } | ||
66 | |||
67 | static void | ||
68 | end_intreq_irq(unsigned int irq) | ||
69 | { | ||
70 | if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) | ||
71 | enable_intreq_irq(irq); | ||
72 | } | ||
73 | |||
74 | static struct hw_interrupt_type intreq_irq_type = { | ||
75 | .typename = "intreq", | ||
76 | .startup = startup_intreq_irq, | ||
77 | .shutdown = shutdown_intreq_irq, | ||
78 | .enable = enable_intreq_irq, | ||
79 | .disable = disable_intreq_irq, | ||
80 | .ack = mask_and_ack_intreq_irq, | ||
81 | .end = end_intreq_irq | ||
82 | }; | ||
83 | |||
84 | void | ||
85 | make_intreq_irq(unsigned int irq) | ||
86 | { | ||
87 | disable_irq_nosync(irq); | ||
88 | irq_desc[irq].handler = &intreq_irq_type; | ||
89 | disable_intreq_irq(irq); | ||
90 | } | ||
91 | |||
92 | int | ||
93 | shmse_irq_demux(int irq) | ||
94 | { | ||
95 | if (irq == IRQ5_IRQ) | ||
96 | return 10; | ||
97 | return irq; | ||
98 | } | ||
99 | |||
100 | /* | ||
101 | * Initialize IRQ setting | ||
102 | */ | ||
103 | void __init | ||
104 | init_73180se_IRQ(void) | ||
105 | { | ||
106 | make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY); | ||
107 | |||
108 | ctrl_outw(0x2000, 0xb03fffec); /* mrshpc irq enable */ | ||
109 | ctrl_outw(0x2000, 0xb07fffec); /* mrshpc irq enable */ | ||
110 | ctrl_outl(3 << ((7 - 5) * 4), INTC_INTPRI0); /* irq5 pri=3 */ | ||
111 | ctrl_outw(2 << ((7 - 5) * 2), INTC_ICR1); /* low-level irq */ | ||
112 | make_intreq_irq(10); | ||
113 | |||
114 | make_ipr_irq(VPU_IRQ, VPU_IPR_ADDR, VPU_IPR_POS, 8); | ||
115 | |||
116 | ctrl_outb(0x0f, INTC_IMCR5); /* enable SCIF IRQ */ | ||
117 | |||
118 | make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); | ||
119 | make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); | ||
120 | make_ipr_irq(DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY); | ||
121 | make_ipr_irq(IIC0_ALI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY); | ||
122 | make_ipr_irq(IIC0_TACKI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, | ||
123 | IIC0_PRIORITY); | ||
124 | make_ipr_irq(IIC0_WAITI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, | ||
125 | IIC0_PRIORITY); | ||
126 | make_ipr_irq(IIC0_DTEI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY); | ||
127 | make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY); | ||
128 | make_ipr_irq(SIU_IRQ, SIU_IPR_ADDR, SIU_IPR_POS, SIU_PRIORITY); | ||
129 | |||
130 | /* VIO interrupt */ | ||
131 | make_ipr_irq(CEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY); | ||
132 | make_ipr_irq(BEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY); | ||
133 | make_ipr_irq(VEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY); | ||
134 | |||
135 | make_ipr_irq(LCDC_IRQ, LCDC_IPR_ADDR, LCDC_IPR_POS, LCDC_PRIORITY); | ||
136 | ctrl_outw(0x2000, PA_MRSHPC + 0x0c); /* mrshpc irq enable */ | ||
137 | } | ||
diff --git a/arch/sh/boards/se/73180/led.c b/arch/sh/boards/se/73180/led.c new file mode 100644 index 000000000000..1e8f1cf3e10f --- /dev/null +++ b/arch/sh/boards/se/73180/led.c | |||
@@ -0,0 +1,67 @@ | |||
1 | /* | ||
2 | * arch/sh/boards/se/73180/led.c | ||
3 | * | ||
4 | * Derived from arch/sh/boards/se/770x/led.c | ||
5 | * | ||
6 | * Copyright (C) 2000 Stuart Menefy <stuart.menefy@st.com> | ||
7 | * | ||
8 | * May be copied or modified under the terms of the GNU General Public | ||
9 | * License. See linux/COPYING for more information. | ||
10 | * | ||
11 | * This file contains Solution Engine specific LED code. | ||
12 | */ | ||
13 | |||
14 | #include <linux/config.h> | ||
15 | #include <linux/sched.h> | ||
16 | #include <asm/mach/se73180.h> | ||
17 | |||
18 | static void | ||
19 | mach_led(int position, int value) | ||
20 | { | ||
21 | volatile unsigned short *p = (volatile unsigned short *) PA_LED; | ||
22 | |||
23 | if (value) { | ||
24 | *p |= (1 << LED_SHIFT); | ||
25 | } else { | ||
26 | *p &= ~(1 << LED_SHIFT); | ||
27 | } | ||
28 | } | ||
29 | |||
30 | /* Cycle the LED's in the clasic Knightrider/Sun pattern */ | ||
31 | void | ||
32 | heartbeat_73180se(void) | ||
33 | { | ||
34 | static unsigned int cnt = 0, period = 0; | ||
35 | volatile unsigned short *p = (volatile unsigned short *) PA_LED; | ||
36 | static unsigned bit = 0, up = 1; | ||
37 | |||
38 | cnt += 1; | ||
39 | if (cnt < period) { | ||
40 | return; | ||
41 | } | ||
42 | |||
43 | cnt = 0; | ||
44 | |||
45 | /* Go through the points (roughly!): | ||
46 | * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110 | ||
47 | */ | ||
48 | period = 110 - ((300 << FSHIFT) / ((avenrun[0] / 5) + (3 << FSHIFT))); | ||
49 | |||
50 | if (up) { | ||
51 | if (bit == 7) { | ||
52 | bit--; | ||
53 | up = 0; | ||
54 | } else { | ||
55 | bit++; | ||
56 | } | ||
57 | } else { | ||
58 | if (bit == 0) { | ||
59 | bit++; | ||
60 | up = 1; | ||
61 | } else { | ||
62 | bit--; | ||
63 | } | ||
64 | } | ||
65 | *p = 1 << (bit + LED_SHIFT); | ||
66 | |||
67 | } | ||
diff --git a/arch/sh/boards/se/73180/setup.c b/arch/sh/boards/se/73180/setup.c new file mode 100644 index 000000000000..07fa90c38a06 --- /dev/null +++ b/arch/sh/boards/se/73180/setup.c | |||
@@ -0,0 +1,68 @@ | |||
1 | /* | ||
2 | * arch/sh/boards/se/73180/setup.c | ||
3 | * | ||
4 | * Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp> | ||
5 | * Based on arch/sh/setup_shmse.c | ||
6 | * | ||
7 | * Modified for 73180 SolutionEngine | ||
8 | * by YOSHII Takashi <yoshii-takashi@hitachi-ul.co.jp> | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/config.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <asm/machvec.h> | ||
15 | #include <asm/machvec_init.h> | ||
16 | #include <asm/mach/io.h> | ||
17 | |||
18 | void heartbeat_73180se(void); | ||
19 | void init_73180se_IRQ(void); | ||
20 | |||
21 | const char * | ||
22 | get_system_type(void) | ||
23 | { | ||
24 | return "SolutionEngine 73180"; | ||
25 | } | ||
26 | |||
27 | /* | ||
28 | * The Machine Vector | ||
29 | */ | ||
30 | |||
31 | struct sh_machine_vector mv_73180se __initmv = { | ||
32 | .mv_nr_irqs = 108, | ||
33 | .mv_inb = sh73180se_inb, | ||
34 | .mv_inw = sh73180se_inw, | ||
35 | .mv_inl = sh73180se_inl, | ||
36 | .mv_outb = sh73180se_outb, | ||
37 | .mv_outw = sh73180se_outw, | ||
38 | .mv_outl = sh73180se_outl, | ||
39 | |||
40 | .mv_inb_p = sh73180se_inb_p, | ||
41 | .mv_inw_p = sh73180se_inw, | ||
42 | .mv_inl_p = sh73180se_inl, | ||
43 | .mv_outb_p = sh73180se_outb_p, | ||
44 | .mv_outw_p = sh73180se_outw, | ||
45 | .mv_outl_p = sh73180se_outl, | ||
46 | |||
47 | .mv_insb = sh73180se_insb, | ||
48 | .mv_insw = sh73180se_insw, | ||
49 | .mv_insl = sh73180se_insl, | ||
50 | .mv_outsb = sh73180se_outsb, | ||
51 | .mv_outsw = sh73180se_outsw, | ||
52 | .mv_outsl = sh73180se_outsl, | ||
53 | |||
54 | .mv_init_irq = init_73180se_IRQ, | ||
55 | #ifdef CONFIG_HEARTBEAT | ||
56 | .mv_heartbeat = heartbeat_73180se, | ||
57 | #endif | ||
58 | }; | ||
59 | |||
60 | ALIAS_MV(73180se) | ||
61 | /* | ||
62 | * Initialize the board | ||
63 | */ | ||
64 | void __init | ||
65 | platform_setup(void) | ||
66 | { | ||
67 | |||
68 | } | ||
diff --git a/arch/sh/boards/se/770x/Makefile b/arch/sh/boards/se/770x/Makefile new file mode 100644 index 000000000000..be89a73cc418 --- /dev/null +++ b/arch/sh/boards/se/770x/Makefile | |||
@@ -0,0 +1,6 @@ | |||
1 | # | ||
2 | # Makefile for the 770x SolutionEngine specific parts of the kernel | ||
3 | # | ||
4 | |||
5 | obj-y := mach.o setup.o io.o irq.o led.o | ||
6 | |||
diff --git a/arch/sh/boards/se/770x/io.c b/arch/sh/boards/se/770x/io.c new file mode 100644 index 000000000000..9a39ee963143 --- /dev/null +++ b/arch/sh/boards/se/770x/io.c | |||
@@ -0,0 +1,226 @@ | |||
1 | /* $Id: io.c,v 1.5 2004/02/22 23:08:43 kkojima Exp $ | ||
2 | * | ||
3 | * linux/arch/sh/kernel/io_se.c | ||
4 | * | ||
5 | * Copyright (C) 2000 Kazumoto Kojima | ||
6 | * | ||
7 | * I/O routine for Hitachi SolutionEngine. | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/types.h> | ||
13 | #include <asm/io.h> | ||
14 | #include <asm/se/se.h> | ||
15 | |||
16 | /* SH pcmcia io window base, start and end. */ | ||
17 | int sh_pcic_io_wbase = 0xb8400000; | ||
18 | int sh_pcic_io_start; | ||
19 | int sh_pcic_io_stop; | ||
20 | int sh_pcic_io_type; | ||
21 | int sh_pcic_io_dummy; | ||
22 | |||
23 | static inline void delay(void) | ||
24 | { | ||
25 | ctrl_inw(0xa0000000); | ||
26 | } | ||
27 | |||
28 | /* MS7750 requires special versions of in*, out* routines, since | ||
29 | PC-like io ports are located at upper half byte of 16-bit word which | ||
30 | can be accessed only with 16-bit wide. */ | ||
31 | |||
32 | static inline volatile __u16 * | ||
33 | port2adr(unsigned int port) | ||
34 | { | ||
35 | if (port >= 0x2000) | ||
36 | return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000)); | ||
37 | else if (port >= 0x1000) | ||
38 | return (volatile __u16 *) (PA_83902 + (port << 1)); | ||
39 | else if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) | ||
40 | return (volatile __u16 *) (sh_pcic_io_wbase + (port &~ 1)); | ||
41 | else | ||
42 | return (volatile __u16 *) (PA_SUPERIO + (port << 1)); | ||
43 | } | ||
44 | |||
45 | static inline int | ||
46 | shifted_port(unsigned long port) | ||
47 | { | ||
48 | /* For IDE registers, value is not shifted */ | ||
49 | if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) | ||
50 | return 0; | ||
51 | else | ||
52 | return 1; | ||
53 | } | ||
54 | |||
55 | #define maybebadio(name,port) \ | ||
56 | printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \ | ||
57 | #name, (port), (__u32) __builtin_return_address(0)) | ||
58 | |||
59 | unsigned char se_inb(unsigned long port) | ||
60 | { | ||
61 | if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) | ||
62 | return *(__u8 *) (sh_pcic_io_wbase + 0x40000 + port); | ||
63 | else if (shifted_port(port)) | ||
64 | return (*port2adr(port) >> 8); | ||
65 | else | ||
66 | return (*port2adr(port))&0xff; | ||
67 | } | ||
68 | |||
69 | unsigned char se_inb_p(unsigned long port) | ||
70 | { | ||
71 | unsigned long v; | ||
72 | |||
73 | if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) | ||
74 | v = *(__u8 *) (sh_pcic_io_wbase + 0x40000 + port); | ||
75 | else if (shifted_port(port)) | ||
76 | v = (*port2adr(port) >> 8); | ||
77 | else | ||
78 | v = (*port2adr(port))&0xff; | ||
79 | delay(); | ||
80 | return v; | ||
81 | } | ||
82 | |||
83 | unsigned short se_inw(unsigned long port) | ||
84 | { | ||
85 | if (port >= 0x2000 || | ||
86 | (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)) | ||
87 | return *port2adr(port); | ||
88 | else | ||
89 | maybebadio(inw, port); | ||
90 | return 0; | ||
91 | } | ||
92 | |||
93 | unsigned int se_inl(unsigned long port) | ||
94 | { | ||
95 | maybebadio(inl, port); | ||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | void se_outb(unsigned char value, unsigned long port) | ||
100 | { | ||
101 | if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) | ||
102 | *(__u8 *)(sh_pcic_io_wbase + port) = value; | ||
103 | else if (shifted_port(port)) | ||
104 | *(port2adr(port)) = value << 8; | ||
105 | else | ||
106 | *(port2adr(port)) = value; | ||
107 | } | ||
108 | |||
109 | void se_outb_p(unsigned char value, unsigned long port) | ||
110 | { | ||
111 | if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) | ||
112 | *(__u8 *)(sh_pcic_io_wbase + port) = value; | ||
113 | else if (shifted_port(port)) | ||
114 | *(port2adr(port)) = value << 8; | ||
115 | else | ||
116 | *(port2adr(port)) = value; | ||
117 | delay(); | ||
118 | } | ||
119 | |||
120 | void se_outw(unsigned short value, unsigned long port) | ||
121 | { | ||
122 | if (port >= 0x2000 || | ||
123 | (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)) | ||
124 | *port2adr(port) = value; | ||
125 | else | ||
126 | maybebadio(outw, port); | ||
127 | } | ||
128 | |||
129 | void se_outl(unsigned int value, unsigned long port) | ||
130 | { | ||
131 | maybebadio(outl, port); | ||
132 | } | ||
133 | |||
134 | void se_insb(unsigned long port, void *addr, unsigned long count) | ||
135 | { | ||
136 | volatile __u16 *p = port2adr(port); | ||
137 | __u8 *ap = addr; | ||
138 | |||
139 | if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) { | ||
140 | volatile __u8 *bp = (__u8 *) (sh_pcic_io_wbase + 0x40000 + port); | ||
141 | while (count--) | ||
142 | *ap++ = *bp; | ||
143 | } else if (shifted_port(port)) { | ||
144 | while (count--) | ||
145 | *ap++ = *p >> 8; | ||
146 | } else { | ||
147 | while (count--) | ||
148 | *ap++ = *p; | ||
149 | } | ||
150 | } | ||
151 | |||
152 | void se_insw(unsigned long port, void *addr, unsigned long count) | ||
153 | { | ||
154 | volatile __u16 *p = port2adr(port); | ||
155 | __u16 *ap = addr; | ||
156 | while (count--) | ||
157 | *ap++ = *p; | ||
158 | } | ||
159 | |||
160 | void se_insl(unsigned long port, void *addr, unsigned long count) | ||
161 | { | ||
162 | maybebadio(insl, port); | ||
163 | } | ||
164 | |||
165 | void se_outsb(unsigned long port, const void *addr, unsigned long count) | ||
166 | { | ||
167 | volatile __u16 *p = port2adr(port); | ||
168 | const __u8 *ap = addr; | ||
169 | |||
170 | if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) { | ||
171 | volatile __u8 *bp = (__u8 *) (sh_pcic_io_wbase + port); | ||
172 | while (count--) | ||
173 | *bp = *ap++; | ||
174 | } else if (shifted_port(port)) { | ||
175 | while (count--) | ||
176 | *p = *ap++ << 8; | ||
177 | } else { | ||
178 | while (count--) | ||
179 | *p = *ap++; | ||
180 | } | ||
181 | } | ||
182 | |||
183 | void se_outsw(unsigned long port, const void *addr, unsigned long count) | ||
184 | { | ||
185 | volatile __u16 *p = port2adr(port); | ||
186 | const __u16 *ap = addr; | ||
187 | while (count--) | ||
188 | *p = *ap++; | ||
189 | } | ||
190 | |||
191 | void se_outsl(unsigned long port, const void *addr, unsigned long count) | ||
192 | { | ||
193 | maybebadio(outsw, port); | ||
194 | } | ||
195 | |||
196 | /* Map ISA bus address to the real address. Only for PCMCIA. */ | ||
197 | |||
198 | /* ISA page descriptor. */ | ||
199 | static __u32 sh_isa_memmap[256]; | ||
200 | |||
201 | static int | ||
202 | sh_isa_mmap(__u32 start, __u32 length, __u32 offset) | ||
203 | { | ||
204 | int idx; | ||
205 | |||
206 | if (start >= 0x100000 || (start & 0xfff) || (length != 0x1000)) | ||
207 | return -1; | ||
208 | |||
209 | idx = start >> 12; | ||
210 | sh_isa_memmap[idx] = 0xb8000000 + (offset &~ 0xfff); | ||
211 | #if 0 | ||
212 | printk("sh_isa_mmap: start %x len %x offset %x (idx %x paddr %x)\n", | ||
213 | start, length, offset, idx, sh_isa_memmap[idx]); | ||
214 | #endif | ||
215 | return 0; | ||
216 | } | ||
217 | |||
218 | unsigned long | ||
219 | se_isa_port2addr(unsigned long offset) | ||
220 | { | ||
221 | int idx; | ||
222 | |||
223 | idx = (offset >> 12) & 0xff; | ||
224 | offset &= 0xfff; | ||
225 | return sh_isa_memmap[idx] + offset; | ||
226 | } | ||
diff --git a/arch/sh/boards/se/770x/irq.c b/arch/sh/boards/se/770x/irq.c new file mode 100644 index 000000000000..210897b315f4 --- /dev/null +++ b/arch/sh/boards/se/770x/irq.c | |||
@@ -0,0 +1,80 @@ | |||
1 | /* | ||
2 | * linux/arch/sh/boards/se/770x/irq.c | ||
3 | * | ||
4 | * Copyright (C) 2000 Kazumoto Kojima | ||
5 | * | ||
6 | * Hitachi SolutionEngine Support. | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | #include <linux/config.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/irq.h> | ||
13 | #include <asm/irq.h> | ||
14 | #include <asm/io.h> | ||
15 | #include <asm/se/se.h> | ||
16 | |||
17 | /* | ||
18 | * Initialize IRQ setting | ||
19 | */ | ||
20 | void __init init_se_IRQ(void) | ||
21 | { | ||
22 | /* | ||
23 | * Super I/O (Just mimic PC): | ||
24 | * 1: keyboard | ||
25 | * 3: serial 0 | ||
26 | * 4: serial 1 | ||
27 | * 5: printer | ||
28 | * 6: floppy | ||
29 | * 8: rtc | ||
30 | * 12: mouse | ||
31 | * 14: ide0 | ||
32 | */ | ||
33 | #if defined(CONFIG_CPU_SUBTYPE_SH7705) | ||
34 | /* Disable all interrupts */ | ||
35 | ctrl_outw(0, BCR_ILCRA); | ||
36 | ctrl_outw(0, BCR_ILCRB); | ||
37 | ctrl_outw(0, BCR_ILCRC); | ||
38 | ctrl_outw(0, BCR_ILCRD); | ||
39 | ctrl_outw(0, BCR_ILCRE); | ||
40 | ctrl_outw(0, BCR_ILCRF); | ||
41 | ctrl_outw(0, BCR_ILCRG); | ||
42 | /* This is default value */ | ||
43 | make_ipr_irq(0xf-0x2, BCR_ILCRA, 2, 0x2); | ||
44 | make_ipr_irq(0xf-0xa, BCR_ILCRA, 1, 0xa); | ||
45 | make_ipr_irq(0xf-0x5, BCR_ILCRB, 0, 0x5); | ||
46 | make_ipr_irq(0xf-0x8, BCR_ILCRC, 1, 0x8); | ||
47 | make_ipr_irq(0xf-0xc, BCR_ILCRC, 0, 0xc); | ||
48 | make_ipr_irq(0xf-0xe, BCR_ILCRD, 3, 0xe); | ||
49 | make_ipr_irq(0xf-0x3, BCR_ILCRD, 1, 0x3); /* LAN */ | ||
50 | make_ipr_irq(0xf-0xd, BCR_ILCRE, 2, 0xd); | ||
51 | make_ipr_irq(0xf-0x9, BCR_ILCRE, 1, 0x9); | ||
52 | make_ipr_irq(0xf-0x1, BCR_ILCRE, 0, 0x1); | ||
53 | make_ipr_irq(0xf-0xf, BCR_ILCRF, 3, 0xf); | ||
54 | make_ipr_irq(0xf-0xb, BCR_ILCRF, 1, 0xb); | ||
55 | make_ipr_irq(0xf-0x7, BCR_ILCRG, 3, 0x7); | ||
56 | make_ipr_irq(0xf-0x6, BCR_ILCRG, 2, 0x6); | ||
57 | make_ipr_irq(0xf-0x4, BCR_ILCRG, 1, 0x4); | ||
58 | #else | ||
59 | make_ipr_irq(14, BCR_ILCRA, 2, 0x0f-14); | ||
60 | make_ipr_irq(12, BCR_ILCRA, 1, 0x0f-12); | ||
61 | make_ipr_irq( 8, BCR_ILCRB, 1, 0x0f- 8); | ||
62 | make_ipr_irq( 6, BCR_ILCRC, 3, 0x0f- 6); | ||
63 | make_ipr_irq( 5, BCR_ILCRC, 2, 0x0f- 5); | ||
64 | make_ipr_irq( 4, BCR_ILCRC, 1, 0x0f- 4); | ||
65 | make_ipr_irq( 3, BCR_ILCRC, 0, 0x0f- 3); | ||
66 | make_ipr_irq( 1, BCR_ILCRD, 3, 0x0f- 1); | ||
67 | |||
68 | make_ipr_irq(10, BCR_ILCRD, 1, 0x0f-10); /* LAN */ | ||
69 | |||
70 | make_ipr_irq( 0, BCR_ILCRE, 3, 0x0f- 0); /* PCIRQ3 */ | ||
71 | make_ipr_irq(11, BCR_ILCRE, 2, 0x0f-11); /* PCIRQ2 */ | ||
72 | make_ipr_irq( 9, BCR_ILCRE, 1, 0x0f- 9); /* PCIRQ1 */ | ||
73 | make_ipr_irq( 7, BCR_ILCRE, 0, 0x0f- 7); /* PCIRQ0 */ | ||
74 | |||
75 | /* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */ | ||
76 | /* NOTE: #2 and #13 are not used on PC */ | ||
77 | make_ipr_irq(13, BCR_ILCRG, 1, 0x0f-13); /* SLOTIRQ2 */ | ||
78 | make_ipr_irq( 2, BCR_ILCRG, 0, 0x0f- 2); /* SLOTIRQ1 */ | ||
79 | #endif | ||
80 | } | ||
diff --git a/arch/sh/boards/se/770x/led.c b/arch/sh/boards/se/770x/led.c new file mode 100644 index 000000000000..5c64e8ab2cfb --- /dev/null +++ b/arch/sh/boards/se/770x/led.c | |||
@@ -0,0 +1,68 @@ | |||
1 | /* | ||
2 | * linux/arch/sh/kernel/led_se.c | ||
3 | * | ||
4 | * Copyright (C) 2000 Stuart Menefy <stuart.menefy@st.com> | ||
5 | * | ||
6 | * May be copied or modified under the terms of the GNU General Public | ||
7 | * License. See linux/COPYING for more information. | ||
8 | * | ||
9 | * This file contains Solution Engine specific LED code. | ||
10 | */ | ||
11 | |||
12 | #include <linux/config.h> | ||
13 | #include <asm/se/se.h> | ||
14 | |||
15 | static void mach_led(int position, int value) | ||
16 | { | ||
17 | volatile unsigned short* p = (volatile unsigned short*)PA_LED; | ||
18 | |||
19 | if (value) { | ||
20 | *p |= (1<<8); | ||
21 | } else { | ||
22 | *p &= ~(1<<8); | ||
23 | } | ||
24 | } | ||
25 | |||
26 | #ifdef CONFIG_HEARTBEAT | ||
27 | |||
28 | #include <linux/sched.h> | ||
29 | |||
30 | /* Cycle the LED's in the clasic Knightrider/Sun pattern */ | ||
31 | void heartbeat_se(void) | ||
32 | { | ||
33 | static unsigned int cnt = 0, period = 0; | ||
34 | volatile unsigned short* p = (volatile unsigned short*)PA_LED; | ||
35 | static unsigned bit = 0, up = 1; | ||
36 | |||
37 | cnt += 1; | ||
38 | if (cnt < period) { | ||
39 | return; | ||
40 | } | ||
41 | |||
42 | cnt = 0; | ||
43 | |||
44 | /* Go through the points (roughly!): | ||
45 | * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110 | ||
46 | */ | ||
47 | period = 110 - ( (300<<FSHIFT)/ | ||
48 | ((avenrun[0]/5) + (3<<FSHIFT)) ); | ||
49 | |||
50 | if (up) { | ||
51 | if (bit == 7) { | ||
52 | bit--; | ||
53 | up=0; | ||
54 | } else { | ||
55 | bit ++; | ||
56 | } | ||
57 | } else { | ||
58 | if (bit == 0) { | ||
59 | bit++; | ||
60 | up=1; | ||
61 | } else { | ||
62 | bit--; | ||
63 | } | ||
64 | } | ||
65 | *p = 1<<(bit+8); | ||
66 | |||
67 | } | ||
68 | #endif /* CONFIG_HEARTBEAT */ | ||
diff --git a/arch/sh/boards/se/770x/mach.c b/arch/sh/boards/se/770x/mach.c new file mode 100644 index 000000000000..f9b4c56cc47e --- /dev/null +++ b/arch/sh/boards/se/770x/mach.c | |||
@@ -0,0 +1,68 @@ | |||
1 | /* | ||
2 | * linux/arch/sh/kernel/mach_se.c | ||
3 | * | ||
4 | * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com) | ||
5 | * | ||
6 | * May be copied or modified under the terms of the GNU General Public | ||
7 | * License. See linux/COPYING for more information. | ||
8 | * | ||
9 | * Machine vector for the Hitachi SolutionEngine | ||
10 | */ | ||
11 | |||
12 | #include <linux/config.h> | ||
13 | #include <linux/init.h> | ||
14 | |||
15 | #include <asm/machvec.h> | ||
16 | #include <asm/rtc.h> | ||
17 | #include <asm/machvec_init.h> | ||
18 | |||
19 | #include <asm/se/io.h> | ||
20 | |||
21 | void heartbeat_se(void); | ||
22 | void setup_se(void); | ||
23 | void init_se_IRQ(void); | ||
24 | |||
25 | /* | ||
26 | * The Machine Vector | ||
27 | */ | ||
28 | |||
29 | struct sh_machine_vector mv_se __initmv = { | ||
30 | #if defined(CONFIG_CPU_SH4) | ||
31 | .mv_nr_irqs = 48, | ||
32 | #elif defined(CONFIG_CPU_SUBTYPE_SH7708) | ||
33 | .mv_nr_irqs = 32, | ||
34 | #elif defined(CONFIG_CPU_SUBTYPE_SH7709) | ||
35 | .mv_nr_irqs = 61, | ||
36 | #elif defined(CONFIG_CPU_SUBTYPE_SH7705) | ||
37 | .mv_nr_irqs = 86, | ||
38 | #endif | ||
39 | |||
40 | .mv_inb = se_inb, | ||
41 | .mv_inw = se_inw, | ||
42 | .mv_inl = se_inl, | ||
43 | .mv_outb = se_outb, | ||
44 | .mv_outw = se_outw, | ||
45 | .mv_outl = se_outl, | ||
46 | |||
47 | .mv_inb_p = se_inb_p, | ||
48 | .mv_inw_p = se_inw, | ||
49 | .mv_inl_p = se_inl, | ||
50 | .mv_outb_p = se_outb_p, | ||
51 | .mv_outw_p = se_outw, | ||
52 | .mv_outl_p = se_outl, | ||
53 | |||
54 | .mv_insb = se_insb, | ||
55 | .mv_insw = se_insw, | ||
56 | .mv_insl = se_insl, | ||
57 | .mv_outsb = se_outsb, | ||
58 | .mv_outsw = se_outsw, | ||
59 | .mv_outsl = se_outsl, | ||
60 | |||
61 | .mv_isa_port2addr = se_isa_port2addr, | ||
62 | |||
63 | .mv_init_irq = init_se_IRQ, | ||
64 | #ifdef CONFIG_HEARTBEAT | ||
65 | .mv_heartbeat = heartbeat_se, | ||
66 | #endif | ||
67 | }; | ||
68 | ALIAS_MV(se) | ||
diff --git a/arch/sh/boards/se/770x/setup.c b/arch/sh/boards/se/770x/setup.c new file mode 100644 index 000000000000..2bed46fb607d --- /dev/null +++ b/arch/sh/boards/se/770x/setup.c | |||
@@ -0,0 +1,85 @@ | |||
1 | /* $Id: setup.c,v 1.1.2.4 2002/03/02 21:57:07 lethal Exp $ | ||
2 | * | ||
3 | * linux/arch/sh/boards/se/770x/setup.c | ||
4 | * | ||
5 | * Copyright (C) 2000 Kazumoto Kojima | ||
6 | * | ||
7 | * Hitachi SolutionEngine Support. | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <linux/config.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/irq.h> | ||
14 | |||
15 | #include <linux/hdreg.h> | ||
16 | #include <linux/ide.h> | ||
17 | #include <asm/io.h> | ||
18 | #include <asm/se/se.h> | ||
19 | #include <asm/se/smc37c93x.h> | ||
20 | |||
21 | /* | ||
22 | * Configure the Super I/O chip | ||
23 | */ | ||
24 | static void __init smsc_config(int index, int data) | ||
25 | { | ||
26 | outb_p(index, INDEX_PORT); | ||
27 | outb_p(data, DATA_PORT); | ||
28 | } | ||
29 | |||
30 | static void __init init_smsc(void) | ||
31 | { | ||
32 | outb_p(CONFIG_ENTER, CONFIG_PORT); | ||
33 | outb_p(CONFIG_ENTER, CONFIG_PORT); | ||
34 | |||
35 | /* FDC */ | ||
36 | smsc_config(CURRENT_LDN_INDEX, LDN_FDC); | ||
37 | smsc_config(ACTIVATE_INDEX, 0x01); | ||
38 | smsc_config(IRQ_SELECT_INDEX, 6); /* IRQ6 */ | ||
39 | |||
40 | /* IDE1 */ | ||
41 | smsc_config(CURRENT_LDN_INDEX, LDN_IDE1); | ||
42 | smsc_config(ACTIVATE_INDEX, 0x01); | ||
43 | smsc_config(IRQ_SELECT_INDEX, 14); /* IRQ14 */ | ||
44 | |||
45 | /* AUXIO (GPIO): to use IDE1 */ | ||
46 | smsc_config(CURRENT_LDN_INDEX, LDN_AUXIO); | ||
47 | smsc_config(GPIO46_INDEX, 0x00); /* nIOROP */ | ||
48 | smsc_config(GPIO47_INDEX, 0x00); /* nIOWOP */ | ||
49 | |||
50 | /* COM1 */ | ||
51 | smsc_config(CURRENT_LDN_INDEX, LDN_COM1); | ||
52 | smsc_config(ACTIVATE_INDEX, 0x01); | ||
53 | smsc_config(IO_BASE_HI_INDEX, 0x03); | ||
54 | smsc_config(IO_BASE_LO_INDEX, 0xf8); | ||
55 | smsc_config(IRQ_SELECT_INDEX, 4); /* IRQ4 */ | ||
56 | |||
57 | /* COM2 */ | ||
58 | smsc_config(CURRENT_LDN_INDEX, LDN_COM2); | ||
59 | smsc_config(ACTIVATE_INDEX, 0x01); | ||
60 | smsc_config(IO_BASE_HI_INDEX, 0x02); | ||
61 | smsc_config(IO_BASE_LO_INDEX, 0xf8); | ||
62 | smsc_config(IRQ_SELECT_INDEX, 3); /* IRQ3 */ | ||
63 | |||
64 | /* RTC */ | ||
65 | smsc_config(CURRENT_LDN_INDEX, LDN_RTC); | ||
66 | smsc_config(ACTIVATE_INDEX, 0x01); | ||
67 | smsc_config(IRQ_SELECT_INDEX, 8); /* IRQ8 */ | ||
68 | |||
69 | /* XXX: PARPORT, KBD, and MOUSE will come here... */ | ||
70 | outb_p(CONFIG_EXIT, CONFIG_PORT); | ||
71 | } | ||
72 | |||
73 | const char *get_system_type(void) | ||
74 | { | ||
75 | return "SolutionEngine"; | ||
76 | } | ||
77 | |||
78 | /* | ||
79 | * Initialize the board | ||
80 | */ | ||
81 | void __init platform_setup(void) | ||
82 | { | ||
83 | init_smsc(); | ||
84 | /* XXX: RTC setting comes here */ | ||
85 | } | ||
diff --git a/arch/sh/boards/se/7751/Makefile b/arch/sh/boards/se/7751/Makefile new file mode 100644 index 000000000000..ce7ca247f84d --- /dev/null +++ b/arch/sh/boards/se/7751/Makefile | |||
@@ -0,0 +1,8 @@ | |||
1 | # | ||
2 | # Makefile for the 7751 SolutionEngine specific parts of the kernel | ||
3 | # | ||
4 | |||
5 | obj-y := mach.o setup.o io.o irq.o led.o | ||
6 | |||
7 | obj-$(CONFIG_PCI) += pci.o | ||
8 | |||
diff --git a/arch/sh/boards/se/7751/io.c b/arch/sh/boards/se/7751/io.c new file mode 100644 index 000000000000..99041b269261 --- /dev/null +++ b/arch/sh/boards/se/7751/io.c | |||
@@ -0,0 +1,244 @@ | |||
1 | /* | ||
2 | * linux/arch/sh/kernel/io_7751se.c | ||
3 | * | ||
4 | * Copyright (C) 2001 Ian da Silva, Jeremy Siegel | ||
5 | * Based largely on io_se.c. | ||
6 | * | ||
7 | * I/O routine for Hitachi 7751 SolutionEngine. | ||
8 | * | ||
9 | * Initial version only to support LAN access; some | ||
10 | * placeholder code from io_se.c left in with the | ||
11 | * expectation of later SuperIO and PCMCIA access. | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/types.h> | ||
16 | #include <asm/io.h> | ||
17 | #include <asm/se7751/se7751.h> | ||
18 | #include <asm/addrspace.h> | ||
19 | |||
20 | #include <linux/pci.h> | ||
21 | #include "../../../drivers/pci/pci-sh7751.h" | ||
22 | |||
23 | #if 0 | ||
24 | /****************************************************************** | ||
25 | * Variables from io_se.c, related to PCMCIA (not PCI); we're not | ||
26 | * compiling them in, and have removed references from functions | ||
27 | * which follow. [Many checked for IO ports in the range bounded | ||
28 | * by sh_pcic_io_start/stop, and used sh_pcic_io_wbase as offset. | ||
29 | * As start/stop are uninitialized, only port 0x0 would match?] | ||
30 | * When used, remember to adjust names to avoid clash with io_se? | ||
31 | *****************************************************************/ | ||
32 | /* SH pcmcia io window base, start and end. */ | ||
33 | int sh_pcic_io_wbase = 0xb8400000; | ||
34 | int sh_pcic_io_start; | ||
35 | int sh_pcic_io_stop; | ||
36 | int sh_pcic_io_type; | ||
37 | int sh_pcic_io_dummy; | ||
38 | /*************************************************************/ | ||
39 | #endif | ||
40 | |||
41 | /* | ||
42 | * The 7751 Solution Engine uses the built-in PCI controller (PCIC) | ||
43 | * of the 7751 processor, and has a SuperIO accessible via the PCI. | ||
44 | * The board also includes a PCMCIA controller on its memory bus, | ||
45 | * like the other Solution Engine boards. | ||
46 | */ | ||
47 | |||
48 | #define PCIIOBR (volatile long *)PCI_REG(SH7751_PCIIOBR) | ||
49 | #define PCIMBR (volatile long *)PCI_REG(SH7751_PCIMBR) | ||
50 | #define PCI_IO_AREA SH7751_PCI_IO_BASE | ||
51 | #define PCI_MEM_AREA SH7751_PCI_CONFIG_BASE | ||
52 | |||
53 | #define PCI_IOMAP(adr) (PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK)) | ||
54 | |||
55 | #define maybebadio(name,port) \ | ||
56 | printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \ | ||
57 | #name, (port), (__u32) __builtin_return_address(0)) | ||
58 | |||
59 | static inline void delay(void) | ||
60 | { | ||
61 | ctrl_inw(0xa0000000); | ||
62 | } | ||
63 | |||
64 | static inline volatile __u16 * | ||
65 | port2adr(unsigned int port) | ||
66 | { | ||
67 | if (port >= 0x2000) | ||
68 | return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000)); | ||
69 | #if 0 | ||
70 | else | ||
71 | return (volatile __u16 *) (PA_SUPERIO + (port << 1)); | ||
72 | #endif | ||
73 | maybebadio(name,(unsigned long)port); | ||
74 | return (volatile __u16*)port; | ||
75 | } | ||
76 | |||
77 | #if 0 | ||
78 | /* The 7751 Solution Engine seems to have everything hooked */ | ||
79 | /* up pretty normally (nothing on high-bytes only...) so this */ | ||
80 | /* shouldn't be needed */ | ||
81 | static inline int | ||
82 | shifted_port(unsigned long port) | ||
83 | { | ||
84 | /* For IDE registers, value is not shifted */ | ||
85 | if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) | ||
86 | return 0; | ||
87 | else | ||
88 | return 1; | ||
89 | } | ||
90 | #endif | ||
91 | |||
92 | /* In case someone configures the kernel w/o PCI support: in that */ | ||
93 | /* scenario, don't ever bother to check for PCI-window addresses */ | ||
94 | |||
95 | /* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */ | ||
96 | #if defined(CONFIG_PCI) | ||
97 | #define CHECK_SH7751_PCIIO(port) \ | ||
98 | ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE))) | ||
99 | #else | ||
100 | #define CHECK_SH7751_PCIIO(port) (0) | ||
101 | #endif | ||
102 | |||
103 | /* | ||
104 | * General outline: remap really low stuff [eventually] to SuperIO, | ||
105 | * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO) | ||
106 | * is mapped through the PCI IO window. Stuff with high bits (PXSEG) | ||
107 | * should be way beyond the window, and is used w/o translation for | ||
108 | * compatibility. | ||
109 | */ | ||
110 | unsigned char sh7751se_inb(unsigned long port) | ||
111 | { | ||
112 | if (PXSEG(port)) | ||
113 | return *(volatile unsigned char *)port; | ||
114 | else if (CHECK_SH7751_PCIIO(port)) | ||
115 | return *(volatile unsigned char *)PCI_IOMAP(port); | ||
116 | else | ||
117 | return (*port2adr(port))&0xff; | ||
118 | } | ||
119 | |||
120 | unsigned char sh7751se_inb_p(unsigned long port) | ||
121 | { | ||
122 | unsigned char v; | ||
123 | |||
124 | if (PXSEG(port)) | ||
125 | v = *(volatile unsigned char *)port; | ||
126 | else if (CHECK_SH7751_PCIIO(port)) | ||
127 | v = *(volatile unsigned char *)PCI_IOMAP(port); | ||
128 | else | ||
129 | v = (*port2adr(port))&0xff; | ||
130 | delay(); | ||
131 | return v; | ||
132 | } | ||
133 | |||
134 | unsigned short sh7751se_inw(unsigned long port) | ||
135 | { | ||
136 | if (PXSEG(port)) | ||
137 | return *(volatile unsigned short *)port; | ||
138 | else if (CHECK_SH7751_PCIIO(port)) | ||
139 | return *(volatile unsigned short *)PCI_IOMAP(port); | ||
140 | else if (port >= 0x2000) | ||
141 | return *port2adr(port); | ||
142 | else | ||
143 | maybebadio(inw, port); | ||
144 | return 0; | ||
145 | } | ||
146 | |||
147 | unsigned int sh7751se_inl(unsigned long port) | ||
148 | { | ||
149 | if (PXSEG(port)) | ||
150 | return *(volatile unsigned long *)port; | ||
151 | else if (CHECK_SH7751_PCIIO(port)) | ||
152 | return *(volatile unsigned int *)PCI_IOMAP(port); | ||
153 | else if (port >= 0x2000) | ||
154 | return *port2adr(port); | ||
155 | else | ||
156 | maybebadio(inl, port); | ||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | void sh7751se_outb(unsigned char value, unsigned long port) | ||
161 | { | ||
162 | |||
163 | if (PXSEG(port)) | ||
164 | *(volatile unsigned char *)port = value; | ||
165 | else if (CHECK_SH7751_PCIIO(port)) | ||
166 | *((unsigned char*)PCI_IOMAP(port)) = value; | ||
167 | else | ||
168 | *(port2adr(port)) = value; | ||
169 | } | ||
170 | |||
171 | void sh7751se_outb_p(unsigned char value, unsigned long port) | ||
172 | { | ||
173 | if (PXSEG(port)) | ||
174 | *(volatile unsigned char *)port = value; | ||
175 | else if (CHECK_SH7751_PCIIO(port)) | ||
176 | *((unsigned char*)PCI_IOMAP(port)) = value; | ||
177 | else | ||
178 | *(port2adr(port)) = value; | ||
179 | delay(); | ||
180 | } | ||
181 | |||
182 | void sh7751se_outw(unsigned short value, unsigned long port) | ||
183 | { | ||
184 | if (PXSEG(port)) | ||
185 | *(volatile unsigned short *)port = value; | ||
186 | else if (CHECK_SH7751_PCIIO(port)) | ||
187 | *((unsigned short *)PCI_IOMAP(port)) = value; | ||
188 | else if (port >= 0x2000) | ||
189 | *port2adr(port) = value; | ||
190 | else | ||
191 | maybebadio(outw, port); | ||
192 | } | ||
193 | |||
194 | void sh7751se_outl(unsigned int value, unsigned long port) | ||
195 | { | ||
196 | if (PXSEG(port)) | ||
197 | *(volatile unsigned long *)port = value; | ||
198 | else if (CHECK_SH7751_PCIIO(port)) | ||
199 | *((unsigned long*)PCI_IOMAP(port)) = value; | ||
200 | else | ||
201 | maybebadio(outl, port); | ||
202 | } | ||
203 | |||
204 | void sh7751se_insl(unsigned long port, void *addr, unsigned long count) | ||
205 | { | ||
206 | maybebadio(insl, port); | ||
207 | } | ||
208 | |||
209 | void sh7751se_outsl(unsigned long port, const void *addr, unsigned long count) | ||
210 | { | ||
211 | maybebadio(outsw, port); | ||
212 | } | ||
213 | |||
214 | /* Map ISA bus address to the real address. Only for PCMCIA. */ | ||
215 | |||
216 | /* ISA page descriptor. */ | ||
217 | static __u32 sh_isa_memmap[256]; | ||
218 | |||
219 | #if 0 | ||
220 | static int | ||
221 | sh_isa_mmap(__u32 start, __u32 length, __u32 offset) | ||
222 | { | ||
223 | int idx; | ||
224 | |||
225 | if (start >= 0x100000 || (start & 0xfff) || (length != 0x1000)) | ||
226 | return -1; | ||
227 | |||
228 | idx = start >> 12; | ||
229 | sh_isa_memmap[idx] = 0xb8000000 + (offset &~ 0xfff); | ||
230 | printk("sh_isa_mmap: start %x len %x offset %x (idx %x paddr %x)\n", | ||
231 | start, length, offset, idx, sh_isa_memmap[idx]); | ||
232 | return 0; | ||
233 | } | ||
234 | #endif | ||
235 | |||
236 | unsigned long | ||
237 | sh7751se_isa_port2addr(unsigned long offset) | ||
238 | { | ||
239 | int idx; | ||
240 | |||
241 | idx = (offset >> 12) & 0xff; | ||
242 | offset &= 0xfff; | ||
243 | return sh_isa_memmap[idx] + offset; | ||
244 | } | ||
diff --git a/arch/sh/boards/se/7751/irq.c b/arch/sh/boards/se/7751/irq.c new file mode 100644 index 000000000000..ad71f3e66c11 --- /dev/null +++ b/arch/sh/boards/se/7751/irq.c | |||
@@ -0,0 +1,67 @@ | |||
1 | /* | ||
2 | * linux/arch/sh/boards/se/7751/irq.c | ||
3 | * | ||
4 | * Copyright (C) 2000 Kazumoto Kojima | ||
5 | * | ||
6 | * Hitachi SolutionEngine Support. | ||
7 | * | ||
8 | * Modified for 7751 Solution Engine by | ||
9 | * Ian da Silva and Jeremy Siegel, 2001. | ||
10 | */ | ||
11 | |||
12 | #include <linux/config.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/irq.h> | ||
15 | #include <asm/irq.h> | ||
16 | #include <asm/se7751/se7751.h> | ||
17 | |||
18 | /* | ||
19 | * Initialize IRQ setting | ||
20 | */ | ||
21 | void __init init_7751se_IRQ(void) | ||
22 | { | ||
23 | |||
24 | /* Leave old Solution Engine code in for reference. */ | ||
25 | #if defined(CONFIG_SH_SOLUTION_ENGINE) | ||
26 | /* | ||
27 | * Super I/O (Just mimic PC): | ||
28 | * 1: keyboard | ||
29 | * 3: serial 0 | ||
30 | * 4: serial 1 | ||
31 | * 5: printer | ||
32 | * 6: floppy | ||
33 | * 8: rtc | ||
34 | * 12: mouse | ||
35 | * 14: ide0 | ||
36 | */ | ||
37 | make_ipr_irq(14, BCR_ILCRA, 2, 0x0f-14); | ||
38 | make_ipr_irq(12, BCR_ILCRA, 1, 0x0f-12); | ||
39 | make_ipr_irq( 8, BCR_ILCRB, 1, 0x0f- 8); | ||
40 | make_ipr_irq( 6, BCR_ILCRC, 3, 0x0f- 6); | ||
41 | make_ipr_irq( 5, BCR_ILCRC, 2, 0x0f- 5); | ||
42 | make_ipr_irq( 4, BCR_ILCRC, 1, 0x0f- 4); | ||
43 | make_ipr_irq( 3, BCR_ILCRC, 0, 0x0f- 3); | ||
44 | make_ipr_irq( 1, BCR_ILCRD, 3, 0x0f- 1); | ||
45 | |||
46 | make_ipr_irq(10, BCR_ILCRD, 1, 0x0f-10); /* LAN */ | ||
47 | |||
48 | make_ipr_irq( 0, BCR_ILCRE, 3, 0x0f- 0); /* PCIRQ3 */ | ||
49 | make_ipr_irq(11, BCR_ILCRE, 2, 0x0f-11); /* PCIRQ2 */ | ||
50 | make_ipr_irq( 9, BCR_ILCRE, 1, 0x0f- 9); /* PCIRQ1 */ | ||
51 | make_ipr_irq( 7, BCR_ILCRE, 0, 0x0f- 7); /* PCIRQ0 */ | ||
52 | |||
53 | /* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */ | ||
54 | /* NOTE: #2 and #13 are not used on PC */ | ||
55 | make_ipr_irq(13, BCR_ILCRG, 1, 0x0f-13); /* SLOTIRQ2 */ | ||
56 | make_ipr_irq( 2, BCR_ILCRG, 0, 0x0f- 2); /* SLOTIRQ1 */ | ||
57 | |||
58 | #elif defined(CONFIG_SH_7751_SOLUTION_ENGINE) | ||
59 | |||
60 | make_ipr_irq(13, BCR_ILCRD, 3, 2); | ||
61 | |||
62 | /* Add additional calls to make_ipr_irq() as drivers are added | ||
63 | * and tested. | ||
64 | */ | ||
65 | #endif | ||
66 | |||
67 | } | ||
diff --git a/arch/sh/boards/se/7751/led.c b/arch/sh/boards/se/7751/led.c new file mode 100644 index 000000000000..0c788230cf8f --- /dev/null +++ b/arch/sh/boards/se/7751/led.c | |||
@@ -0,0 +1,68 @@ | |||
1 | /* | ||
2 | * linux/arch/sh/kernel/led_se.c | ||
3 | * | ||
4 | * Copyright (C) 2000 Stuart Menefy <stuart.menefy@st.com> | ||
5 | * | ||
6 | * May be copied or modified under the terms of the GNU General Public | ||
7 | * License. See linux/COPYING for more information. | ||
8 | * | ||
9 | * This file contains Solution Engine specific LED code. | ||
10 | */ | ||
11 | |||
12 | #include <linux/config.h> | ||
13 | #include <asm/se7751/se7751.h> | ||
14 | |||
15 | static void mach_led(int position, int value) | ||
16 | { | ||
17 | volatile unsigned short* p = (volatile unsigned short*)PA_LED; | ||
18 | |||
19 | if (value) { | ||
20 | *p |= (1<<8); | ||
21 | } else { | ||
22 | *p &= ~(1<<8); | ||
23 | } | ||
24 | } | ||
25 | |||
26 | #ifdef CONFIG_HEARTBEAT | ||
27 | |||
28 | #include <linux/sched.h> | ||
29 | |||
30 | /* Cycle the LED's in the clasic Knightrider/Sun pattern */ | ||
31 | void heartbeat_7751se(void) | ||
32 | { | ||
33 | static unsigned int cnt = 0, period = 0; | ||
34 | volatile unsigned short* p = (volatile unsigned short*)PA_LED; | ||
35 | static unsigned bit = 0, up = 1; | ||
36 | |||
37 | cnt += 1; | ||
38 | if (cnt < period) { | ||
39 | return; | ||
40 | } | ||
41 | |||
42 | cnt = 0; | ||
43 | |||
44 | /* Go through the points (roughly!): | ||
45 | * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110 | ||
46 | */ | ||
47 | period = 110 - ( (300<<FSHIFT)/ | ||
48 | ((avenrun[0]/5) + (3<<FSHIFT)) ); | ||
49 | |||
50 | if (up) { | ||
51 | if (bit == 7) { | ||
52 | bit--; | ||
53 | up=0; | ||
54 | } else { | ||
55 | bit ++; | ||
56 | } | ||
57 | } else { | ||
58 | if (bit == 0) { | ||
59 | bit++; | ||
60 | up=1; | ||
61 | } else { | ||
62 | bit--; | ||
63 | } | ||
64 | } | ||
65 | *p = 1<<(bit+8); | ||
66 | |||
67 | } | ||
68 | #endif /* CONFIG_HEARTBEAT */ | ||
diff --git a/arch/sh/boards/se/7751/mach.c b/arch/sh/boards/se/7751/mach.c new file mode 100644 index 000000000000..16d386b7e3bf --- /dev/null +++ b/arch/sh/boards/se/7751/mach.c | |||
@@ -0,0 +1,55 @@ | |||
1 | /* | ||
2 | * linux/arch/sh/kernel/mach_7751se.c | ||
3 | * | ||
4 | * Minor tweak of mach_se.c file to reference 7751se-specific items. | ||
5 | * | ||
6 | * May be copied or modified under the terms of the GNU General Public | ||
7 | * License. See linux/COPYING for more information. | ||
8 | * | ||
9 | * Machine vector for the Hitachi 7751 SolutionEngine | ||
10 | */ | ||
11 | |||
12 | #include <linux/config.h> | ||
13 | #include <linux/init.h> | ||
14 | |||
15 | #include <asm/machvec.h> | ||
16 | #include <asm/rtc.h> | ||
17 | #include <asm/machvec_init.h> | ||
18 | |||
19 | #include <asm/se7751/io.h> | ||
20 | |||
21 | void heartbeat_7751se(void); | ||
22 | void init_7751se_IRQ(void); | ||
23 | |||
24 | /* | ||
25 | * The Machine Vector | ||
26 | */ | ||
27 | |||
28 | struct sh_machine_vector mv_7751se __initmv = { | ||
29 | .mv_nr_irqs = 72, | ||
30 | |||
31 | .mv_inb = sh7751se_inb, | ||
32 | .mv_inw = sh7751se_inw, | ||
33 | .mv_inl = sh7751se_inl, | ||
34 | .mv_outb = sh7751se_outb, | ||
35 | .mv_outw = sh7751se_outw, | ||
36 | .mv_outl = sh7751se_outl, | ||
37 | |||
38 | .mv_inb_p = sh7751se_inb_p, | ||
39 | .mv_inw_p = sh7751se_inw, | ||
40 | .mv_inl_p = sh7751se_inl, | ||
41 | .mv_outb_p = sh7751se_outb_p, | ||
42 | .mv_outw_p = sh7751se_outw, | ||
43 | .mv_outl_p = sh7751se_outl, | ||
44 | |||
45 | .mv_insl = sh7751se_insl, | ||
46 | .mv_outsl = sh7751se_outsl, | ||
47 | |||
48 | .mv_isa_port2addr = sh7751se_isa_port2addr, | ||
49 | |||
50 | .mv_init_irq = init_7751se_IRQ, | ||
51 | #ifdef CONFIG_HEARTBEAT | ||
52 | .mv_heartbeat = heartbeat_7751se, | ||
53 | #endif | ||
54 | }; | ||
55 | ALIAS_MV(7751se) | ||
diff --git a/arch/sh/boards/se/7751/pci.c b/arch/sh/boards/se/7751/pci.c new file mode 100644 index 000000000000..1f273efd2cf5 --- /dev/null +++ b/arch/sh/boards/se/7751/pci.c | |||
@@ -0,0 +1,148 @@ | |||
1 | /* | ||
2 | * linux/arch/sh/kernel/pci-7751se.c | ||
3 | * | ||
4 | * Author: Ian DaSilva (idasilva@mvista.com) | ||
5 | * | ||
6 | * Highly leveraged from pci-bigsur.c, written by Dustin McIntire. | ||
7 | * | ||
8 | * May be copied or modified under the terms of the GNU General Public | ||
9 | * License. See linux/COPYING for more information. | ||
10 | * | ||
11 | * PCI initialization for the Hitachi SH7751 Solution Engine board (MS7751SE01) | ||
12 | */ | ||
13 | |||
14 | #include <linux/config.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/types.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/delay.h> | ||
19 | #include <linux/pci.h> | ||
20 | |||
21 | #include <asm/io.h> | ||
22 | #include "../../../drivers/pci/pci-sh7751.h" | ||
23 | |||
24 | #define PCIMCR_MRSET_OFF 0xBFFFFFFF | ||
25 | #define PCIMCR_RFSH_OFF 0xFFFFFFFB | ||
26 | |||
27 | /* | ||
28 | * Only long word accesses of the PCIC's internal local registers and the | ||
29 | * configuration registers from the CPU is supported. | ||
30 | */ | ||
31 | #define PCIC_WRITE(x,v) writel((v), PCI_REG(x)) | ||
32 | #define PCIC_READ(x) readl(PCI_REG(x)) | ||
33 | |||
34 | /* | ||
35 | * Description: This function sets up and initializes the pcic, sets | ||
36 | * up the BARS, maps the DRAM into the address space etc, etc. | ||
37 | */ | ||
38 | int __init pcibios_init_platform(void) | ||
39 | { | ||
40 | unsigned long bcr1, wcr1, wcr2, wcr3, mcr; | ||
41 | unsigned short bcr2; | ||
42 | |||
43 | /* | ||
44 | * Initialize the slave bus controller on the pcic. The values used | ||
45 | * here should not be hardcoded, but they should be taken from the bsc | ||
46 | * on the processor, to make this function as generic as possible. | ||
47 | * (i.e. Another sbc may usr different SDRAM timing settings -- in order | ||
48 | * for the pcic to work, its settings need to be exactly the same.) | ||
49 | */ | ||
50 | bcr1 = (*(volatile unsigned long*)(SH7751_BCR1)); | ||
51 | bcr2 = (*(volatile unsigned short*)(SH7751_BCR2)); | ||
52 | wcr1 = (*(volatile unsigned long*)(SH7751_WCR1)); | ||
53 | wcr2 = (*(volatile unsigned long*)(SH7751_WCR2)); | ||
54 | wcr3 = (*(volatile unsigned long*)(SH7751_WCR3)); | ||
55 | mcr = (*(volatile unsigned long*)(SH7751_MCR)); | ||
56 | |||
57 | bcr1 = bcr1 | 0x00080000; /* Enable Bit 19, BREQEN */ | ||
58 | (*(volatile unsigned long*)(SH7751_BCR1)) = bcr1; | ||
59 | |||
60 | bcr1 = bcr1 | 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */ | ||
61 | PCIC_WRITE(SH7751_PCIBCR1, bcr1); /* PCIC BCR1 */ | ||
62 | PCIC_WRITE(SH7751_PCIBCR2, bcr2); /* PCIC BCR2 */ | ||
63 | PCIC_WRITE(SH7751_PCIWCR1, wcr1); /* PCIC WCR1 */ | ||
64 | PCIC_WRITE(SH7751_PCIWCR2, wcr2); /* PCIC WCR2 */ | ||
65 | PCIC_WRITE(SH7751_PCIWCR3, wcr3); /* PCIC WCR3 */ | ||
66 | mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF; | ||
67 | PCIC_WRITE(SH7751_PCIMCR, mcr); /* PCIC MCR */ | ||
68 | |||
69 | |||
70 | /* Enable all interrupts, so we know what to fix */ | ||
71 | PCIC_WRITE(SH7751_PCIINTM, 0x0000c3ff); | ||
72 | PCIC_WRITE(SH7751_PCIAINTM, 0x0000380f); | ||
73 | |||
74 | /* Set up standard PCI config registers */ | ||
75 | PCIC_WRITE(SH7751_PCICONF1, 0xF39000C7); /* Bus Master, Mem & I/O access */ | ||
76 | PCIC_WRITE(SH7751_PCICONF2, 0x00000000); /* PCI Class code & Revision ID */ | ||
77 | PCIC_WRITE(SH7751_PCICONF4, 0xab000001); /* PCI I/O address (local regs) */ | ||
78 | PCIC_WRITE(SH7751_PCICONF5, 0x0c000000); /* PCI MEM address (local RAM) */ | ||
79 | PCIC_WRITE(SH7751_PCICONF6, 0xd0000000); /* PCI MEM address (unused) */ | ||
80 | PCIC_WRITE(SH7751_PCICONF11, 0x35051054); /* PCI Subsystem ID & Vendor ID */ | ||
81 | PCIC_WRITE(SH7751_PCILSR0, 0x03f00000); /* MEM (full 64M exposed) */ | ||
82 | PCIC_WRITE(SH7751_PCILSR1, 0x00000000); /* MEM (unused) */ | ||
83 | PCIC_WRITE(SH7751_PCILAR0, 0x0c000000); /* MEM (direct map from PCI) */ | ||
84 | PCIC_WRITE(SH7751_PCILAR1, 0x00000000); /* MEM (unused) */ | ||
85 | |||
86 | /* Now turn it on... */ | ||
87 | PCIC_WRITE(SH7751_PCICR, 0xa5000001); | ||
88 | |||
89 | /* | ||
90 | * Set PCIMBR and PCIIOBR here, assuming a single window | ||
91 | * (16M MEM, 256K IO) is enough. If a larger space is | ||
92 | * needed, the readx/writex and inx/outx functions will | ||
93 | * have to do more (e.g. setting registers for each call). | ||
94 | */ | ||
95 | |||
96 | /* | ||
97 | * Set the MBR so PCI address is one-to-one with window, | ||
98 | * meaning all calls go straight through... use BUG_ON to | ||
99 | * catch erroneous assumption. | ||
100 | */ | ||
101 | BUG_ON(PCIBIOS_MIN_MEM != SH7751_PCI_MEMORY_BASE); | ||
102 | |||
103 | PCIC_WRITE(SH7751_PCIMBR, PCIBIOS_MIN_MEM); | ||
104 | |||
105 | /* Set IOBR for window containing area specified in pci.h */ | ||
106 | PCIC_WRITE(SH7751_PCIIOBR, (PCIBIOS_MIN_IO & SH7751_PCIIOBR_MASK)); | ||
107 | |||
108 | /* All done, may as well say so... */ | ||
109 | printk("SH7751 PCI: Finished initialization of the PCI controller\n"); | ||
110 | |||
111 | return 1; | ||
112 | } | ||
113 | |||
114 | int __init pcibios_map_platform_irq(u8 slot, u8 pin) | ||
115 | { | ||
116 | switch (slot) { | ||
117 | case 0: return 13; | ||
118 | case 1: return 13; /* AMD Ethernet controller */ | ||
119 | case 2: return -1; | ||
120 | case 3: return -1; | ||
121 | case 4: return -1; | ||
122 | default: | ||
123 | printk("PCI: Bad IRQ mapping request for slot %d\n", slot); | ||
124 | return -1; | ||
125 | } | ||
126 | } | ||
127 | |||
128 | static struct resource sh7751_io_resource = { | ||
129 | .name = "SH7751 IO", | ||
130 | .start = SH7751_PCI_IO_BASE, | ||
131 | .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1, | ||
132 | .flags = IORESOURCE_IO | ||
133 | }; | ||
134 | |||
135 | static struct resource sh7751_mem_resource = { | ||
136 | .name = "SH7751 mem", | ||
137 | .start = SH7751_PCI_MEMORY_BASE, | ||
138 | .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1, | ||
139 | .flags = IORESOURCE_MEM | ||
140 | }; | ||
141 | |||
142 | extern struct pci_ops sh7751_pci_ops; | ||
143 | |||
144 | struct pci_channel board_pci_channels[] = { | ||
145 | { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, | ||
146 | { NULL, NULL, NULL, 0, 0 }, | ||
147 | }; | ||
148 | |||
diff --git a/arch/sh/boards/se/7751/setup.c b/arch/sh/boards/se/7751/setup.c new file mode 100644 index 000000000000..9d111bb884f9 --- /dev/null +++ b/arch/sh/boards/se/7751/setup.c | |||
@@ -0,0 +1,228 @@ | |||
1 | /* | ||
2 | * linux/arch/sh/kernel/setup_7751se.c | ||
3 | * | ||
4 | * Copyright (C) 2000 Kazumoto Kojima | ||
5 | * | ||
6 | * Hitachi SolutionEngine Support. | ||
7 | * | ||
8 | * Modified for 7751 Solution Engine by | ||
9 | * Ian da Silva and Jeremy Siegel, 2001. | ||
10 | */ | ||
11 | |||
12 | #include <linux/config.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/irq.h> | ||
15 | |||
16 | #include <linux/hdreg.h> | ||
17 | #include <linux/ide.h> | ||
18 | #include <asm/io.h> | ||
19 | #include <asm/se7751/se7751.h> | ||
20 | |||
21 | #ifdef CONFIG_SH_KGDB | ||
22 | #include <asm/kgdb.h> | ||
23 | #endif | ||
24 | |||
25 | /* | ||
26 | * Configure the Super I/O chip | ||
27 | */ | ||
28 | #if 0 | ||
29 | /* Leftover code from regular Solution Engine, for reference. */ | ||
30 | /* The SH7751 Solution Engine has a different SuperIO. */ | ||
31 | static void __init smsc_config(int index, int data) | ||
32 | { | ||
33 | outb_p(index, INDEX_PORT); | ||
34 | outb_p(data, DATA_PORT); | ||
35 | } | ||
36 | |||
37 | static void __init init_smsc(void) | ||
38 | { | ||
39 | outb_p(CONFIG_ENTER, CONFIG_PORT); | ||
40 | outb_p(CONFIG_ENTER, CONFIG_PORT); | ||
41 | |||
42 | /* FDC */ | ||
43 | smsc_config(CURRENT_LDN_INDEX, LDN_FDC); | ||
44 | smsc_config(ACTIVATE_INDEX, 0x01); | ||
45 | smsc_config(IRQ_SELECT_INDEX, 6); /* IRQ6 */ | ||
46 | |||
47 | /* IDE1 */ | ||
48 | smsc_config(CURRENT_LDN_INDEX, LDN_IDE1); | ||
49 | smsc_config(ACTIVATE_INDEX, 0x01); | ||
50 | smsc_config(IRQ_SELECT_INDEX, 14); /* IRQ14 */ | ||
51 | |||
52 | /* AUXIO (GPIO): to use IDE1 */ | ||
53 | smsc_config(CURRENT_LDN_INDEX, LDN_AUXIO); | ||
54 | smsc_config(GPIO46_INDEX, 0x00); /* nIOROP */ | ||
55 | smsc_config(GPIO47_INDEX, 0x00); /* nIOWOP */ | ||
56 | |||
57 | /* COM1 */ | ||
58 | smsc_config(CURRENT_LDN_INDEX, LDN_COM1); | ||
59 | smsc_config(ACTIVATE_INDEX, 0x01); | ||
60 | smsc_config(IO_BASE_HI_INDEX, 0x03); | ||
61 | smsc_config(IO_BASE_LO_INDEX, 0xf8); | ||
62 | smsc_config(IRQ_SELECT_INDEX, 4); /* IRQ4 */ | ||
63 | |||
64 | /* COM2 */ | ||
65 | smsc_config(CURRENT_LDN_INDEX, LDN_COM2); | ||
66 | smsc_config(ACTIVATE_INDEX, 0x01); | ||
67 | smsc_config(IO_BASE_HI_INDEX, 0x02); | ||
68 | smsc_config(IO_BASE_LO_INDEX, 0xf8); | ||
69 | smsc_config(IRQ_SELECT_INDEX, 3); /* IRQ3 */ | ||
70 | |||
71 | /* RTC */ | ||
72 | smsc_config(CURRENT_LDN_INDEX, LDN_RTC); | ||
73 | smsc_config(ACTIVATE_INDEX, 0x01); | ||
74 | smsc_config(IRQ_SELECT_INDEX, 8); /* IRQ8 */ | ||
75 | |||
76 | /* XXX: PARPORT, KBD, and MOUSE will come here... */ | ||
77 | outb_p(CONFIG_EXIT, CONFIG_PORT); | ||
78 | } | ||
79 | #endif | ||
80 | |||
81 | const char *get_system_type(void) | ||
82 | { | ||
83 | return "7751 SolutionEngine"; | ||
84 | } | ||
85 | |||
86 | #ifdef CONFIG_SH_KGDB | ||
87 | static int kgdb_uart_setup(void); | ||
88 | static struct kgdb_sermap kgdb_uart_sermap = | ||
89 | { "ttyS", 0, kgdb_uart_setup, NULL }; | ||
90 | #endif | ||
91 | |||
92 | /* | ||
93 | * Initialize the board | ||
94 | */ | ||
95 | void __init platform_setup(void) | ||
96 | { | ||
97 | /* Call init_smsc() replacement to set up SuperIO. */ | ||
98 | /* XXX: RTC setting comes here */ | ||
99 | #ifdef CONFIG_SH_KGDB | ||
100 | kgdb_register_sermap(&kgdb_uart_sermap); | ||
101 | #endif | ||
102 | } | ||
103 | |||
104 | /********************************************************************* | ||
105 | * Currently a hack (e.g. does not interact well w/serial.c, lots of * | ||
106 | * hardcoded stuff) but may be useful if SCI/F needs debugging. * | ||
107 | * Mostly copied from x86 code (see files asm-i386/kgdb_local.h and * | ||
108 | * arch/i386/lib/kgdb_serial.c). * | ||
109 | *********************************************************************/ | ||
110 | |||
111 | #ifdef CONFIG_SH_KGDB | ||
112 | #include <linux/types.h> | ||
113 | #include <linux/serial.h> | ||
114 | #include <linux/serialP.h> | ||
115 | #include <linux/serial_reg.h> | ||
116 | |||
117 | #define COM1_PORT 0x3f8 /* Base I/O address */ | ||
118 | #define COM1_IRQ 4 /* IRQ not used yet */ | ||
119 | #define COM2_PORT 0x2f8 /* Base I/O address */ | ||
120 | #define COM2_IRQ 3 /* IRQ not used yet */ | ||
121 | |||
122 | #define SB_CLOCK 1843200 /* Serial baud clock */ | ||
123 | #define SB_BASE (SB_CLOCK/16) | ||
124 | #define SB_MCR UART_MCR_OUT2 | UART_MCR_DTR | UART_MCR_RTS | ||
125 | |||
126 | struct uart_port { | ||
127 | int base; | ||
128 | }; | ||
129 | #define UART_NPORTS 2 | ||
130 | struct uart_port uart_ports[] = { | ||
131 | { COM1_PORT }, | ||
132 | { COM2_PORT }, | ||
133 | }; | ||
134 | struct uart_port *kgdb_uart_port; | ||
135 | |||
136 | #define UART_IN(reg) inb_p(kgdb_uart_port->base + reg) | ||
137 | #define UART_OUT(reg,v) outb_p((v), kgdb_uart_port->base + reg) | ||
138 | |||
139 | /* Basic read/write functions for the UART */ | ||
140 | #define UART_LSR_RXCERR (UART_LSR_BI | UART_LSR_FE | UART_LSR_PE) | ||
141 | static int kgdb_uart_getchar(void) | ||
142 | { | ||
143 | int lsr; | ||
144 | int c = -1; | ||
145 | |||
146 | while (c == -1) { | ||
147 | lsr = UART_IN(UART_LSR); | ||
148 | if (lsr & UART_LSR_DR) | ||
149 | c = UART_IN(UART_RX); | ||
150 | if ((lsr & UART_LSR_RXCERR)) | ||
151 | c = -1; | ||
152 | } | ||
153 | return c; | ||
154 | } | ||
155 | |||
156 | static void kgdb_uart_putchar(int c) | ||
157 | { | ||
158 | while ((UART_IN(UART_LSR) & UART_LSR_THRE) == 0) | ||
159 | ; | ||
160 | UART_OUT(UART_TX, c); | ||
161 | } | ||
162 | |||
163 | /* | ||
164 | * Initialize UART to configured/requested values. | ||
165 | * (But we don't interrupts yet, or interact w/serial.c) | ||
166 | */ | ||
167 | static int kgdb_uart_setup(void) | ||
168 | { | ||
169 | int port; | ||
170 | int lcr = 0; | ||
171 | int bdiv = 0; | ||
172 | |||
173 | if (kgdb_portnum >= UART_NPORTS) { | ||
174 | KGDB_PRINTK("uart port %d invalid.\n", kgdb_portnum); | ||
175 | return -1; | ||
176 | } | ||
177 | |||
178 | kgdb_uart_port = &uart_ports[kgdb_portnum]; | ||
179 | |||
180 | /* Init sequence from gdb_hook_interrupt */ | ||
181 | UART_IN(UART_RX); | ||
182 | UART_OUT(UART_IER, 0); | ||
183 | |||
184 | UART_IN(UART_RX); /* Serial driver comments say */ | ||
185 | UART_IN(UART_IIR); /* this clears interrupt regs */ | ||
186 | UART_IN(UART_MSR); | ||
187 | |||
188 | /* Figure basic LCR values */ | ||
189 | switch (kgdb_bits) { | ||
190 | case '7': | ||
191 | lcr |= UART_LCR_WLEN7; | ||
192 | break; | ||
193 | default: case '8': | ||
194 | lcr |= UART_LCR_WLEN8; | ||
195 | break; | ||
196 | } | ||
197 | switch (kgdb_parity) { | ||
198 | case 'O': | ||
199 | lcr |= UART_LCR_PARITY; | ||
200 | break; | ||
201 | case 'E': | ||
202 | lcr |= (UART_LCR_PARITY | UART_LCR_EPAR); | ||
203 | break; | ||
204 | default: break; | ||
205 | } | ||
206 | |||
207 | /* Figure the baud rate divisor */ | ||
208 | bdiv = (SB_BASE/kgdb_baud); | ||
209 | |||
210 | /* Set the baud rate and LCR values */ | ||
211 | UART_OUT(UART_LCR, (lcr | UART_LCR_DLAB)); | ||
212 | UART_OUT(UART_DLL, (bdiv & 0xff)); | ||
213 | UART_OUT(UART_DLM, ((bdiv >> 8) & 0xff)); | ||
214 | UART_OUT(UART_LCR, lcr); | ||
215 | |||
216 | /* Set the MCR */ | ||
217 | UART_OUT(UART_MCR, SB_MCR); | ||
218 | |||
219 | /* Turn off FIFOs for now */ | ||
220 | UART_OUT(UART_FCR, 0); | ||
221 | |||
222 | /* Setup complete: initialize function pointers */ | ||
223 | kgdb_getchar = kgdb_uart_getchar; | ||
224 | kgdb_putchar = kgdb_uart_putchar; | ||
225 | |||
226 | return 0; | ||
227 | } | ||
228 | #endif /* CONFIG_SH_KGDB */ | ||