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/7751 |
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/7751')
-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 |
7 files changed, 818 insertions, 0 deletions
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 */ | ||