diff options
Diffstat (limited to 'arch/sh/boards/overdrive')
-rw-r--r-- | arch/sh/boards/overdrive/Makefile | 8 | ||||
-rw-r--r-- | arch/sh/boards/overdrive/fpga.c | 133 | ||||
-rw-r--r-- | arch/sh/boards/overdrive/galileo.c | 587 | ||||
-rw-r--r-- | arch/sh/boards/overdrive/io.c | 172 | ||||
-rw-r--r-- | arch/sh/boards/overdrive/irq.c | 191 | ||||
-rw-r--r-- | arch/sh/boards/overdrive/led.c | 58 | ||||
-rw-r--r-- | arch/sh/boards/overdrive/mach.c | 62 | ||||
-rw-r--r-- | arch/sh/boards/overdrive/pcidma.c | 46 | ||||
-rw-r--r-- | arch/sh/boards/overdrive/setup.c | 36 |
9 files changed, 0 insertions, 1293 deletions
diff --git a/arch/sh/boards/overdrive/Makefile b/arch/sh/boards/overdrive/Makefile deleted file mode 100644 index 245f03baf762..000000000000 --- a/arch/sh/boards/overdrive/Makefile +++ /dev/null | |||
@@ -1,8 +0,0 @@ | |||
1 | # | ||
2 | # Makefile for the STMicroelectronics Overdrive 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) += fpga.o galileo.o pcidma.o | ||
8 | |||
diff --git a/arch/sh/boards/overdrive/fpga.c b/arch/sh/boards/overdrive/fpga.c deleted file mode 100644 index 956c23901228..000000000000 --- a/arch/sh/boards/overdrive/fpga.c +++ /dev/null | |||
@@ -1,133 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000 David J. Mckay (david.mckay@st.com) | ||
3 | * | ||
4 | * May be copied or modified under the terms of the GNU General Public | ||
5 | * License. See linux/COPYING for more information. | ||
6 | * | ||
7 | * This file handles programming up the Altera Flex10K that interfaces to | ||
8 | * the Galileo, and does the PS/2 keyboard and mouse | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | |||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/smp.h> | ||
15 | #include <linux/smp_lock.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/errno.h> | ||
18 | #include <linux/pci.h> | ||
19 | #include <linux/delay.h> | ||
20 | |||
21 | |||
22 | #include <asm/overdriver/gt64111.h> | ||
23 | #include <asm/overdrive/overdrive.h> | ||
24 | #include <asm/overdrive/fpga.h> | ||
25 | |||
26 | #define FPGA_NotConfigHigh() (*FPGA_ControlReg) = (*FPGA_ControlReg) | ENABLE_FPGA_BIT | ||
27 | #define FPGA_NotConfigLow() (*FPGA_ControlReg) = (*FPGA_ControlReg) & RESET_FPGA_MASK | ||
28 | |||
29 | /* I need to find out what (if any) the real delay factor here is */ | ||
30 | /* The delay is definately not critical */ | ||
31 | #define long_delay() {int i;for(i=0;i<10000;i++);} | ||
32 | #define short_delay() {int i;for(i=0;i<100;i++);} | ||
33 | |||
34 | static void __init program_overdrive_fpga(const unsigned char *fpgacode, | ||
35 | int size) | ||
36 | { | ||
37 | int timeout = 0; | ||
38 | int i, j; | ||
39 | unsigned char b; | ||
40 | static volatile unsigned char *FPGA_ControlReg = | ||
41 | (volatile unsigned char *) (OVERDRIVE_CTRL); | ||
42 | static volatile unsigned char *FPGA_ProgramReg = | ||
43 | (volatile unsigned char *) (FPGA_DCLK_ADDRESS); | ||
44 | |||
45 | printk("FPGA: Commencing FPGA Programming\n"); | ||
46 | |||
47 | /* The PCI reset but MUST be low when programming the FPGA !!! */ | ||
48 | b = (*FPGA_ControlReg) & RESET_PCI_MASK; | ||
49 | |||
50 | (*FPGA_ControlReg) = b; | ||
51 | |||
52 | /* Prepare FPGA to program */ | ||
53 | |||
54 | FPGA_NotConfigHigh(); | ||
55 | long_delay(); | ||
56 | |||
57 | FPGA_NotConfigLow(); | ||
58 | short_delay(); | ||
59 | |||
60 | while ((*FPGA_ProgramReg & FPGA_NOT_STATUS) != 0) { | ||
61 | printk("FPGA: Waiting for NotStatus to go Low ... \n"); | ||
62 | } | ||
63 | |||
64 | FPGA_NotConfigHigh(); | ||
65 | |||
66 | /* Wait for FPGA "ready to be programmed" signal */ | ||
67 | printk("FPGA: Waiting for NotStatus to go high (FPGA ready)... \n"); | ||
68 | |||
69 | for (timeout = 0; | ||
70 | (((*FPGA_ProgramReg & FPGA_NOT_STATUS) == 0) | ||
71 | && (timeout < FPGA_TIMEOUT)); timeout++); | ||
72 | |||
73 | /* Check if timeout condition occured - i.e. an error */ | ||
74 | |||
75 | if (timeout == FPGA_TIMEOUT) { | ||
76 | printk | ||
77 | ("FPGA: Failed to program - Timeout waiting for notSTATUS to go high\n"); | ||
78 | return; | ||
79 | } | ||
80 | |||
81 | printk("FPGA: Copying data to FPGA ... %d bytes\n", size); | ||
82 | |||
83 | /* Copy array to FPGA - bit at a time */ | ||
84 | |||
85 | for (i = 0; i < size; i++) { | ||
86 | volatile unsigned w = 0; | ||
87 | |||
88 | for (j = 0; j < 8; j++) { | ||
89 | *FPGA_ProgramReg = (fpgacode[i] >> j) & 0x01; | ||
90 | short_delay(); | ||
91 | } | ||
92 | if ((i & 0x3ff) == 0) { | ||
93 | printk("."); | ||
94 | } | ||
95 | } | ||
96 | |||
97 | /* Waiting for CONFDONE to go high - means the program is complete */ | ||
98 | |||
99 | for (timeout = 0; | ||
100 | (((*FPGA_ProgramReg & FPGA_CONFDONE) == 0) | ||
101 | && (timeout < FPGA_TIMEOUT)); timeout++) { | ||
102 | |||
103 | *FPGA_ProgramReg = 0x0; | ||
104 | long_delay(); | ||
105 | } | ||
106 | |||
107 | if (timeout == FPGA_TIMEOUT) { | ||
108 | printk | ||
109 | ("FPGA: Failed to program - Timeout waiting for CONFDONE to go high\n"); | ||
110 | return; | ||
111 | } else { /* Clock another 10 times - gets the device into a working state */ | ||
112 | for (i = 0; i < 10; i++) { | ||
113 | *FPGA_ProgramReg = 0x0; | ||
114 | short_delay(); | ||
115 | } | ||
116 | } | ||
117 | |||
118 | printk("FPGA: Programming complete\n"); | ||
119 | } | ||
120 | |||
121 | |||
122 | static const unsigned char __init fpgacode[] = { | ||
123 | #include "./overdrive.ttf" /* Code from maxplus2 compiler */ | ||
124 | , 0, 0 | ||
125 | }; | ||
126 | |||
127 | |||
128 | int __init init_overdrive_fpga(void) | ||
129 | { | ||
130 | program_overdrive_fpga(fpgacode, sizeof(fpgacode)); | ||
131 | |||
132 | return 0; | ||
133 | } | ||
diff --git a/arch/sh/boards/overdrive/galileo.c b/arch/sh/boards/overdrive/galileo.c deleted file mode 100644 index 29e48971bba0..000000000000 --- a/arch/sh/boards/overdrive/galileo.c +++ /dev/null | |||
@@ -1,587 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000 David J. Mckay (david.mckay@st.com) | ||
3 | * | ||
4 | * May be copied or modified under the terms of the GNU General Public | ||
5 | * License. See linux/COPYING for more information. | ||
6 | * | ||
7 | * This file contains the PCI routines required for the Galileo GT6411 | ||
8 | * PCI bridge as used on the Orion and Overdrive boards. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/smp.h> | ||
14 | #include <linux/smp_lock.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/errno.h> | ||
17 | #include <linux/pci.h> | ||
18 | #include <linux/delay.h> | ||
19 | #include <linux/types.h> | ||
20 | #include <linux/ioport.h> | ||
21 | |||
22 | #include <asm/overdrive/overdrive.h> | ||
23 | #include <asm/overdrive/gt64111.h> | ||
24 | |||
25 | |||
26 | /* After boot, we shift the Galileo registers so that they appear | ||
27 | * in BANK6, along with IO space. This means we can have one contingous | ||
28 | * lump of PCI address space without these registers appearing in the | ||
29 | * middle of them | ||
30 | */ | ||
31 | |||
32 | #define GT64111_BASE_ADDRESS 0xbb000000 | ||
33 | #define GT64111_IO_BASE_ADDRESS 0x1000 | ||
34 | /* The GT64111 registers appear at this address to the SH4 after reset */ | ||
35 | #define RESET_GT64111_BASE_ADDRESS 0xb4000000 | ||
36 | |||
37 | /* Macros used to access the Galileo registers */ | ||
38 | #define RESET_GT64111_REG(x) (RESET_GT64111_BASE_ADDRESS+x) | ||
39 | #define GT64111_REG(x) (GT64111_BASE_ADDRESS+x) | ||
40 | |||
41 | #define RESET_GT_WRITE(x,v) writel((v),RESET_GT64111_REG(x)) | ||
42 | |||
43 | #define RESET_GT_READ(x) readl(RESET_GT64111_REG(x)) | ||
44 | |||
45 | #define GT_WRITE(x,v) writel((v),GT64111_REG(x)) | ||
46 | #define GT_WRITE_BYTE(x,v) writeb((v),GT64111_REG(x)) | ||
47 | #define GT_WRITE_SHORT(x,v) writew((v),GT64111_REG(x)) | ||
48 | |||
49 | #define GT_READ(x) readl(GT64111_REG(x)) | ||
50 | #define GT_READ_BYTE(x) readb(GT64111_REG(x)) | ||
51 | #define GT_READ_SHORT(x) readw(GT64111_REG(x)) | ||
52 | |||
53 | |||
54 | /* Where the various SH banks start at */ | ||
55 | #define SH_BANK4_ADR 0xb0000000 | ||
56 | #define SH_BANK5_ADR 0xb4000000 | ||
57 | #define SH_BANK6_ADR 0xb8000000 | ||
58 | |||
59 | /* Masks out everything but lines 28,27,26 */ | ||
60 | #define BANK_SELECT_MASK 0x1c000000 | ||
61 | |||
62 | #define SH4_TO_BANK(x) ( (x) & BANK_SELECT_MASK) | ||
63 | |||
64 | /* | ||
65 | * Masks used for address conversaion. Bank 6 is used for IO and | ||
66 | * has all the address bits zeroed by the FPGA. Special case this | ||
67 | */ | ||
68 | #define MEMORY_BANK_MASK 0x1fffffff | ||
69 | #define IO_BANK_MASK 0x03ffffff | ||
70 | |||
71 | /* Mark bank 6 as the bank used for IO. You can change this in the FPGA code | ||
72 | * if you want | ||
73 | */ | ||
74 | #define IO_BANK_ADR PCI_GTIO_BASE | ||
75 | |||
76 | /* Will select the correct mask to apply depending on the SH$ address */ | ||
77 | #define SELECT_BANK_MASK(x) \ | ||
78 | ( (SH4_TO_BANK(x)==SH4_TO_BANK(IO_BANK_ADR)) ? IO_BANK_MASK : MEMORY_BANK_MASK) | ||
79 | |||
80 | /* Converts between PCI space and P2 region */ | ||
81 | #define SH4_TO_PCI(x) ((x)&SELECT_BANK_MASK(x)) | ||
82 | |||
83 | /* Various macros for figuring out what to stick in the Galileo registers. | ||
84 | * You *really* don't want to figure this stuff out by hand, you always get | ||
85 | * it wrong | ||
86 | */ | ||
87 | #define GT_MEM_LO_ADR(x) ((((unsigned)((x)&SELECT_BANK_MASK(x)))>>21)&0x7ff) | ||
88 | #define GT_MEM_HI_ADR(x) ((((unsigned)((x)&SELECT_BANK_MASK(x)))>>21)&0x7f) | ||
89 | #define GT_MEM_SUB_ADR(x) ((((unsigned)((x)&SELECT_BANK_MASK(x)))>>20)&0xff) | ||
90 | |||
91 | #define PROGRAM_HI_LO(block,a,s) \ | ||
92 | GT_WRITE(block##_LO_DEC_ADR,GT_MEM_LO_ADR(a));\ | ||
93 | GT_WRITE(block##_HI_DEC_ADR,GT_MEM_HI_ADR(a+s-1)) | ||
94 | |||
95 | #define PROGRAM_SUB_HI_LO(block,a,s) \ | ||
96 | GT_WRITE(block##_LO_DEC_ADR,GT_MEM_SUB_ADR(a));\ | ||
97 | GT_WRITE(block##_HI_DEC_ADR,GT_MEM_SUB_ADR(a+s-1)) | ||
98 | |||
99 | /* We need to set the size, and the offset register */ | ||
100 | |||
101 | #define GT_BAR_MASK(x) ((x)&~0xfff) | ||
102 | |||
103 | /* Macro to set up the BAR in the Galileo. Essentially used for the DRAM */ | ||
104 | #define PROGRAM_GT_BAR(block,a,s) \ | ||
105 | GT_WRITE(PCI_##block##_BANK_SIZE,GT_BAR_MASK((s-1)));\ | ||
106 | write_config_to_galileo(PCI_CONFIG_##block##_BASE_ADR,\ | ||
107 | GT_BAR_MASK(a)) | ||
108 | |||
109 | #define DISABLE_GT_BAR(block) \ | ||
110 | GT_WRITE(PCI_##block##_BANK_SIZE,0),\ | ||
111 | GT_CONFIG_WRITE(PCI_CONFIG_##block##_BASE_ADR,\ | ||
112 | 0x80000000) | ||
113 | |||
114 | /* Macros to disable things we are not going to use */ | ||
115 | #define DISABLE_DECODE(x) GT_WRITE(x##_LO_DEC_ADR,0x7ff);\ | ||
116 | GT_WRITE(x##_HI_DEC_ADR,0x00) | ||
117 | |||
118 | #define DISABLE_SUB_DECODE(x) GT_WRITE(x##_LO_DEC_ADR,0xff);\ | ||
119 | GT_WRITE(x##_HI_DEC_ADR,0x00) | ||
120 | |||
121 | static void __init reset_pci(void) | ||
122 | { | ||
123 | /* Set RESET_PCI bit high */ | ||
124 | writeb(readb(OVERDRIVE_CTRL) | ENABLE_PCI_BIT, OVERDRIVE_CTRL); | ||
125 | udelay(250); | ||
126 | |||
127 | /* Set RESET_PCI bit low */ | ||
128 | writeb(readb(OVERDRIVE_CTRL) & RESET_PCI_MASK, OVERDRIVE_CTRL); | ||
129 | udelay(250); | ||
130 | |||
131 | writeb(readb(OVERDRIVE_CTRL) | ENABLE_PCI_BIT, OVERDRIVE_CTRL); | ||
132 | udelay(250); | ||
133 | } | ||
134 | |||
135 | static int write_config_to_galileo(int where, u32 val); | ||
136 | #define GT_CONFIG_WRITE(where,val) write_config_to_galileo(where,val) | ||
137 | |||
138 | #define ENABLE_PCI_DRAM | ||
139 | |||
140 | |||
141 | #ifdef TEST_DRAM | ||
142 | /* Test function to check out if the PCI DRAM is working OK */ | ||
143 | static int /* __init */ test_dram(unsigned *base, unsigned size) | ||
144 | { | ||
145 | unsigned *p = base; | ||
146 | unsigned *end = (unsigned *) (((unsigned) base) + size); | ||
147 | unsigned w; | ||
148 | |||
149 | for (p = base; p < end; p++) { | ||
150 | *p = 0xffffffff; | ||
151 | if (*p != 0xffffffff) { | ||
152 | printk("AAARGH -write failed!!! at %p is %x\n", p, | ||
153 | *p); | ||
154 | return 0; | ||
155 | } | ||
156 | *p = 0x0; | ||
157 | if (*p != 0x0) { | ||
158 | printk("AAARGH -write failed!!!\n"); | ||
159 | return 0; | ||
160 | } | ||
161 | } | ||
162 | |||
163 | for (p = base; p < end; p++) { | ||
164 | *p = (unsigned) p; | ||
165 | if (*p != (unsigned) p) { | ||
166 | printk("Failed at 0x%p, actually is 0x%x\n", p, | ||
167 | *p); | ||
168 | return 0; | ||
169 | } | ||
170 | } | ||
171 | |||
172 | for (p = base; p < end; p++) { | ||
173 | w = ((unsigned) p & 0xffff0000); | ||
174 | *p = w | (w >> 16); | ||
175 | } | ||
176 | |||
177 | for (p = base; p < end; p++) { | ||
178 | w = ((unsigned) p & 0xffff0000); | ||
179 | w |= (w >> 16); | ||
180 | if (*p != w) { | ||
181 | printk | ||
182 | ("Failed at 0x%p, should be 0x%x actually is 0x%x\n", | ||
183 | p, w, *p); | ||
184 | return 0; | ||
185 | } | ||
186 | } | ||
187 | |||
188 | return 1; | ||
189 | } | ||
190 | #endif | ||
191 | |||
192 | |||
193 | /* Function to set up and initialise the galileo. This sets up the BARS, | ||
194 | * maps the DRAM into the address space etc,etc | ||
195 | */ | ||
196 | int __init galileo_init(void) | ||
197 | { | ||
198 | reset_pci(); | ||
199 | |||
200 | /* Now shift the galileo regs into this block */ | ||
201 | RESET_GT_WRITE(INTERNAL_SPACE_DEC, | ||
202 | GT_MEM_LO_ADR(GT64111_BASE_ADDRESS)); | ||
203 | |||
204 | /* Should have a sanity check here, that you can read back at the new | ||
205 | * address what you just wrote | ||
206 | */ | ||
207 | |||
208 | /* Disable decode for all regions */ | ||
209 | DISABLE_DECODE(RAS10); | ||
210 | DISABLE_DECODE(RAS32); | ||
211 | DISABLE_DECODE(CS20); | ||
212 | DISABLE_DECODE(CS3); | ||
213 | DISABLE_DECODE(PCI_IO); | ||
214 | DISABLE_DECODE(PCI_MEM0); | ||
215 | DISABLE_DECODE(PCI_MEM1); | ||
216 | |||
217 | /* Disable all BARS */ | ||
218 | GT_WRITE(BAR_ENABLE_ADR, 0x1ff); | ||
219 | DISABLE_GT_BAR(RAS10); | ||
220 | DISABLE_GT_BAR(RAS32); | ||
221 | DISABLE_GT_BAR(CS20); | ||
222 | DISABLE_GT_BAR(CS3); | ||
223 | |||
224 | /* Tell the BAR where the IO registers now are */ | ||
225 | GT_CONFIG_WRITE(PCI_CONFIG_INT_REG_IO_ADR,GT_BAR_MASK( | ||
226 | (GT64111_IO_BASE_ADDRESS & | ||
227 | IO_BANK_MASK))); | ||
228 | /* set up a 112 Mb decode */ | ||
229 | PROGRAM_HI_LO(PCI_MEM0, SH_BANK4_ADR, 112 * 1024 * 1024); | ||
230 | |||
231 | /* Set up a 32 MB io space decode */ | ||
232 | PROGRAM_HI_LO(PCI_IO, IO_BANK_ADR, 32 * 1024 * 1024); | ||
233 | |||
234 | #ifdef ENABLE_PCI_DRAM | ||
235 | /* Program up the DRAM configuration - there is DRAM only in bank 0 */ | ||
236 | /* Now set up the DRAM decode */ | ||
237 | PROGRAM_HI_LO(RAS10, PCI_DRAM_BASE, PCI_DRAM_SIZE); | ||
238 | /* And the sub decode */ | ||
239 | PROGRAM_SUB_HI_LO(RAS0, PCI_DRAM_BASE, PCI_DRAM_SIZE); | ||
240 | |||
241 | DISABLE_SUB_DECODE(RAS1); | ||
242 | |||
243 | /* Set refresh rate */ | ||
244 | GT_WRITE(DRAM_BANK0_PARMS, 0x3f); | ||
245 | GT_WRITE(DRAM_CFG, 0x100); | ||
246 | |||
247 | /* we have to lob off the top bits rememeber!! */ | ||
248 | PROGRAM_GT_BAR(RAS10, SH4_TO_PCI(PCI_DRAM_BASE), PCI_DRAM_SIZE); | ||
249 | |||
250 | #endif | ||
251 | |||
252 | /* We are only interested in decoding RAS10 and the Galileo's internal | ||
253 | * registers (as IO) on the PCI bus | ||
254 | */ | ||
255 | #ifdef ENABLE_PCI_DRAM | ||
256 | GT_WRITE(BAR_ENABLE_ADR, (~((1 << 8) | (1 << 3))) & 0x1ff); | ||
257 | #else | ||
258 | GT_WRITE(BAR_ENABLE_ADR, (~(1 << 3)) & 0x1ff); | ||
259 | #endif | ||
260 | |||
261 | /* Change the class code to host bridge, it actually powers up | ||
262 | * as a memory controller | ||
263 | */ | ||
264 | GT_CONFIG_WRITE(8, 0x06000011); | ||
265 | |||
266 | /* Allow the galileo to master the PCI bus */ | ||
267 | GT_CONFIG_WRITE(PCI_COMMAND, | ||
268 | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | | ||
269 | PCI_COMMAND_IO); | ||
270 | |||
271 | |||
272 | #if 0 | ||
273 | printk("Testing PCI DRAM - "); | ||
274 | if(test_dram(PCI_DRAM_BASE,PCI_DRAM_SIZE)) { | ||
275 | printk("Passed\n"); | ||
276 | }else { | ||
277 | printk("FAILED\n"); | ||
278 | } | ||
279 | #endif | ||
280 | return 0; | ||
281 | |||
282 | } | ||
283 | |||
284 | |||
285 | #define SET_CONFIG_BITS(bus,devfn,where)\ | ||
286 | ((1<<31) | ((bus) << 16) | ((devfn) << 8) | ((where) & ~3)) | ||
287 | |||
288 | #define CONFIG_CMD(dev, where) SET_CONFIG_BITS((dev)->bus->number,(dev)->devfn,where) | ||
289 | |||
290 | /* This write to the galileo config registers, unlike the functions below, can | ||
291 | * be used before the PCI subsystem has started up | ||
292 | */ | ||
293 | static int __init write_config_to_galileo(int where, u32 val) | ||
294 | { | ||
295 | GT_WRITE(PCI_CFG_ADR, SET_CONFIG_BITS(0, 0, where)); | ||
296 | |||
297 | GT_WRITE(PCI_CFG_DATA, val); | ||
298 | return 0; | ||
299 | } | ||
300 | |||
301 | /* We exclude the galileo and slot 31, the galileo because I don't know how to stop | ||
302 | * the setup code shagging up the setup I have done on it, and 31 because the whole | ||
303 | * thing locks up if you try to access that slot (which doesn't exist of course anyway | ||
304 | */ | ||
305 | |||
306 | #define EXCLUDED_DEV(dev) ((dev->bus->number==0) && ((PCI_SLOT(dev->devfn)==0) || (PCI_SLOT(dev->devfn) == 31))) | ||
307 | |||
308 | static int galileo_read_config_byte(struct pci_dev *dev, int where, | ||
309 | u8 * val) | ||
310 | { | ||
311 | |||
312 | |||
313 | /* I suspect this doesn't work because this drives a special cycle ? */ | ||
314 | if (EXCLUDED_DEV(dev)) { | ||
315 | *val = 0xff; | ||
316 | return PCIBIOS_SUCCESSFUL; | ||
317 | } | ||
318 | /* Start the config cycle */ | ||
319 | GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where)); | ||
320 | /* Read back the result */ | ||
321 | *val = GT_READ_BYTE(PCI_CFG_DATA + (where & 3)); | ||
322 | |||
323 | return PCIBIOS_SUCCESSFUL; | ||
324 | } | ||
325 | |||
326 | |||
327 | static int galileo_read_config_word(struct pci_dev *dev, int where, | ||
328 | u16 * val) | ||
329 | { | ||
330 | |||
331 | if (EXCLUDED_DEV(dev)) { | ||
332 | *val = 0xffff; | ||
333 | return PCIBIOS_SUCCESSFUL; | ||
334 | } | ||
335 | |||
336 | GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where)); | ||
337 | *val = GT_READ_SHORT(PCI_CFG_DATA + (where & 2)); | ||
338 | |||
339 | return PCIBIOS_SUCCESSFUL; | ||
340 | } | ||
341 | |||
342 | |||
343 | static int galileo_read_config_dword(struct pci_dev *dev, int where, | ||
344 | u32 * val) | ||
345 | { | ||
346 | if (EXCLUDED_DEV(dev)) { | ||
347 | *val = 0xffffffff; | ||
348 | return PCIBIOS_SUCCESSFUL; | ||
349 | } | ||
350 | |||
351 | GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where)); | ||
352 | *val = GT_READ(PCI_CFG_DATA); | ||
353 | |||
354 | return PCIBIOS_SUCCESSFUL; | ||
355 | } | ||
356 | |||
357 | static int galileo_write_config_byte(struct pci_dev *dev, int where, | ||
358 | u8 val) | ||
359 | { | ||
360 | GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where)); | ||
361 | |||
362 | GT_WRITE_BYTE(PCI_CFG_DATA + (where & 3), val); | ||
363 | |||
364 | return PCIBIOS_SUCCESSFUL; | ||
365 | } | ||
366 | |||
367 | |||
368 | static int galileo_write_config_word(struct pci_dev *dev, int where, | ||
369 | u16 val) | ||
370 | { | ||
371 | GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where)); | ||
372 | |||
373 | GT_WRITE_SHORT(PCI_CFG_DATA + (where & 2), val); | ||
374 | |||
375 | return PCIBIOS_SUCCESSFUL; | ||
376 | } | ||
377 | |||
378 | static int galileo_write_config_dword(struct pci_dev *dev, int where, | ||
379 | u32 val) | ||
380 | { | ||
381 | GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where)); | ||
382 | |||
383 | GT_WRITE(PCI_CFG_DATA, val); | ||
384 | |||
385 | return PCIBIOS_SUCCESSFUL; | ||
386 | } | ||
387 | |||
388 | static struct pci_ops pci_config_ops = { | ||
389 | galileo_read_config_byte, | ||
390 | galileo_read_config_word, | ||
391 | galileo_read_config_dword, | ||
392 | galileo_write_config_byte, | ||
393 | galileo_write_config_word, | ||
394 | galileo_write_config_dword | ||
395 | }; | ||
396 | |||
397 | |||
398 | /* Everything hangs off this */ | ||
399 | static struct pci_bus *pci_root_bus; | ||
400 | |||
401 | |||
402 | static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin) | ||
403 | { | ||
404 | return PCI_SLOT(dev->devfn); | ||
405 | } | ||
406 | |||
407 | static int __init map_od_irq(struct pci_dev *dev, u8 slot, u8 pin) | ||
408 | { | ||
409 | /* Slot 1: Galileo | ||
410 | * Slot 2: PCI Slot 1 | ||
411 | * Slot 3: PCI Slot 2 | ||
412 | * Slot 4: ESS | ||
413 | */ | ||
414 | switch (slot) { | ||
415 | case 2: | ||
416 | return OVERDRIVE_PCI_IRQ1; | ||
417 | case 3: | ||
418 | /* Note this assumes you have a hacked card in slot 2 */ | ||
419 | return OVERDRIVE_PCI_IRQ2; | ||
420 | case 4: | ||
421 | return OVERDRIVE_ESS_IRQ; | ||
422 | default: | ||
423 | /* printk("PCI: Unexpected IRQ mapping request for slot %d\n", slot); */ | ||
424 | return -1; | ||
425 | } | ||
426 | } | ||
427 | |||
428 | |||
429 | |||
430 | void __init | ||
431 | pcibios_fixup_pbus_ranges(struct pci_bus *bus, struct pbus_set_ranges_data *ranges) | ||
432 | { | ||
433 | ranges->io_start -= bus->resource[0]->start; | ||
434 | ranges->io_end -= bus->resource[0]->start; | ||
435 | ranges->mem_start -= bus->resource[1]->start; | ||
436 | ranges->mem_end -= bus->resource[1]->start; | ||
437 | } | ||
438 | |||
439 | static void __init pci_fixup_ide_bases(struct pci_dev *d) | ||
440 | { | ||
441 | int i; | ||
442 | |||
443 | /* | ||
444 | * PCI IDE controllers use non-standard I/O port decoding, respect it. | ||
445 | */ | ||
446 | if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE) | ||
447 | return; | ||
448 | printk("PCI: IDE base address fixup for %s\n", pci_name(d)); | ||
449 | for(i=0; i<4; i++) { | ||
450 | struct resource *r = &d->resource[i]; | ||
451 | if ((r->start & ~0x80) == 0x374) { | ||
452 | r->start |= 2; | ||
453 | r->end = r->start; | ||
454 | } | ||
455 | } | ||
456 | } | ||
457 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases); | ||
458 | |||
459 | void __init pcibios_init(void) | ||
460 | { | ||
461 | static struct resource galio,galmem; | ||
462 | |||
463 | /* Allocate the registers used by the Galileo */ | ||
464 | galio.flags = IORESOURCE_IO; | ||
465 | galio.name = "Galileo GT64011"; | ||
466 | galmem.flags = IORESOURCE_MEM|IORESOURCE_PREFETCH; | ||
467 | galmem.name = "Galileo GT64011 DRAM"; | ||
468 | |||
469 | allocate_resource(&ioport_resource, &galio, 256, | ||
470 | GT64111_IO_BASE_ADDRESS,GT64111_IO_BASE_ADDRESS+256, 256, NULL, NULL); | ||
471 | allocate_resource(&iomem_resource, &galmem,PCI_DRAM_SIZE, | ||
472 | PHYSADDR(PCI_DRAM_BASE), PHYSADDR(PCI_DRAM_BASE)+PCI_DRAM_SIZE, | ||
473 | PCI_DRAM_SIZE, NULL, NULL); | ||
474 | |||
475 | /* ok, do the scan man */ | ||
476 | pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL); | ||
477 | |||
478 | pci_assign_unassigned_resources(); | ||
479 | pci_fixup_irqs(no_swizzle, map_od_irq); | ||
480 | |||
481 | #ifdef TEST_DRAM | ||
482 | printk("Testing PCI DRAM - "); | ||
483 | if(test_dram(PCI_DRAM_BASE,PCI_DRAM_SIZE)) { | ||
484 | printk("Passed\n"); | ||
485 | }else { | ||
486 | printk("FAILED\n"); | ||
487 | } | ||
488 | #endif | ||
489 | |||
490 | } | ||
491 | |||
492 | char * __init pcibios_setup(char *str) | ||
493 | { | ||
494 | return str; | ||
495 | } | ||
496 | |||
497 | |||
498 | |||
499 | int pcibios_enable_device(struct pci_dev *dev) | ||
500 | { | ||
501 | |||
502 | u16 cmd, old_cmd; | ||
503 | int idx; | ||
504 | struct resource *r; | ||
505 | |||
506 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | ||
507 | old_cmd = cmd; | ||
508 | for (idx = 0; idx < 6; idx++) { | ||
509 | r = dev->resource + idx; | ||
510 | if (!r->start && r->end) { | ||
511 | printk(KERN_ERR | ||
512 | "PCI: Device %s not available because" | ||
513 | " of resource collisions\n", | ||
514 | pci_name(dev)); | ||
515 | return -EINVAL; | ||
516 | } | ||
517 | if (r->flags & IORESOURCE_IO) | ||
518 | cmd |= PCI_COMMAND_IO; | ||
519 | if (r->flags & IORESOURCE_MEM) | ||
520 | cmd |= PCI_COMMAND_MEMORY; | ||
521 | } | ||
522 | if (cmd != old_cmd) { | ||
523 | printk("PCI: enabling device %s (%04x -> %04x)\n", | ||
524 | pci_name(dev), old_cmd, cmd); | ||
525 | pci_write_config_word(dev, PCI_COMMAND, cmd); | ||
526 | } | ||
527 | return 0; | ||
528 | |||
529 | } | ||
530 | |||
531 | /* We should do some optimisation work here I think. Ok for now though */ | ||
532 | void __init pcibios_fixup_bus(struct pci_bus *bus) | ||
533 | { | ||
534 | |||
535 | } | ||
536 | |||
537 | void pcibios_align_resource(void *data, struct resource *res, | ||
538 | resource_size_t size) | ||
539 | { | ||
540 | } | ||
541 | |||
542 | void __init pcibios_update_resource(struct pci_dev *dev, struct resource *root, | ||
543 | struct resource *res, int resource) | ||
544 | { | ||
545 | |||
546 | unsigned long where, size; | ||
547 | u32 reg; | ||
548 | |||
549 | |||
550 | printk("PCI: Assigning %3s %08lx to %s\n", | ||
551 | res->flags & IORESOURCE_IO ? "IO" : "MEM", | ||
552 | res->start, dev->name); | ||
553 | |||
554 | where = PCI_BASE_ADDRESS_0 + resource * 4; | ||
555 | size = res->end - res->start; | ||
556 | |||
557 | pci_read_config_dword(dev, where, ®); | ||
558 | reg = (reg & size) | (((u32) (res->start - root->start)) & ~size); | ||
559 | pci_write_config_dword(dev, where, reg); | ||
560 | } | ||
561 | |||
562 | |||
563 | void __init pcibios_update_irq(struct pci_dev *dev, int irq) | ||
564 | { | ||
565 | printk("PCI: Assigning IRQ %02d to %s\n", irq, dev->name); | ||
566 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); | ||
567 | } | ||
568 | |||
569 | /* | ||
570 | * If we set up a device for bus mastering, we need to check the latency | ||
571 | * timer as certain crappy BIOSes forget to set it properly. | ||
572 | */ | ||
573 | unsigned int pcibios_max_latency = 255; | ||
574 | |||
575 | void pcibios_set_master(struct pci_dev *dev) | ||
576 | { | ||
577 | u8 lat; | ||
578 | pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); | ||
579 | if (lat < 16) | ||
580 | lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency; | ||
581 | else if (lat > pcibios_max_latency) | ||
582 | lat = pcibios_max_latency; | ||
583 | else | ||
584 | return; | ||
585 | printk("PCI: Setting latency timer of device %s to %d\n", pci_name(dev), lat); | ||
586 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); | ||
587 | } | ||
diff --git a/arch/sh/boards/overdrive/io.c b/arch/sh/boards/overdrive/io.c deleted file mode 100644 index 4671b6b047bb..000000000000 --- a/arch/sh/boards/overdrive/io.c +++ /dev/null | |||
@@ -1,172 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000 David J. Mckay (david.mckay@st.com) | ||
3 | * | ||
4 | * May be copied or modified under the terms of the GNU General Public | ||
5 | * License. See linux/COPYING for more information. | ||
6 | * | ||
7 | * This file contains the I/O routines for use on the overdrive board | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <linux/types.h> | ||
12 | #include <linux/delay.h> | ||
13 | #include <asm/processor.h> | ||
14 | #include <asm/io.h> | ||
15 | #include <asm/addrspace.h> | ||
16 | |||
17 | #include <asm/overdrive/overdrive.h> | ||
18 | |||
19 | /* | ||
20 | * readX/writeX() are used to access memory mapped devices. On some | ||
21 | * architectures the memory mapped IO stuff needs to be accessed | ||
22 | * differently. On the SuperH architecture, we just read/write the | ||
23 | * memory location directly. | ||
24 | */ | ||
25 | |||
26 | #define dprintk(x...) | ||
27 | |||
28 | /* Translates an IO address to where it is mapped in memory */ | ||
29 | |||
30 | #define io_addr(x) (((unsigned)(x))|PCI_GTIO_BASE) | ||
31 | |||
32 | unsigned char od_inb(unsigned long port) | ||
33 | { | ||
34 | dprintk("od_inb(%x)\n", port); | ||
35 | return readb(io_addr(port)) & 0xff; | ||
36 | } | ||
37 | |||
38 | |||
39 | unsigned short od_inw(unsigned long port) | ||
40 | { | ||
41 | dprintk("od_inw(%x)\n", port); | ||
42 | return readw(io_addr(port)) & 0xffff; | ||
43 | } | ||
44 | |||
45 | unsigned int od_inl(unsigned long port) | ||
46 | { | ||
47 | dprintk("od_inl(%x)\n", port); | ||
48 | return readl(io_addr(port)); | ||
49 | } | ||
50 | |||
51 | void od_outb(unsigned char value, unsigned long port) | ||
52 | { | ||
53 | dprintk("od_outb(%x, %x)\n", value, port); | ||
54 | writeb(value, io_addr(port)); | ||
55 | } | ||
56 | |||
57 | void od_outw(unsigned short value, unsigned long port) | ||
58 | { | ||
59 | dprintk("od_outw(%x, %x)\n", value, port); | ||
60 | writew(value, io_addr(port)); | ||
61 | } | ||
62 | |||
63 | void od_outl(unsigned int value, unsigned long port) | ||
64 | { | ||
65 | dprintk("od_outl(%x, %x)\n", value, port); | ||
66 | writel(value, io_addr(port)); | ||
67 | } | ||
68 | |||
69 | /* This is horrible at the moment - needs more work to do something sensible */ | ||
70 | #define IO_DELAY() udelay(10) | ||
71 | |||
72 | #define OUT_DELAY(x,type) \ | ||
73 | void od_out##x##_p(unsigned type value,unsigned long port){out##x(value,port);IO_DELAY();} | ||
74 | |||
75 | #define IN_DELAY(x,type) \ | ||
76 | unsigned type od_in##x##_p(unsigned long port) {unsigned type tmp=in##x(port);IO_DELAY();return tmp;} | ||
77 | |||
78 | |||
79 | OUT_DELAY(b,char) | ||
80 | OUT_DELAY(w,short) | ||
81 | OUT_DELAY(l,int) | ||
82 | |||
83 | IN_DELAY(b,char) | ||
84 | IN_DELAY(w,short) | ||
85 | IN_DELAY(l,int) | ||
86 | |||
87 | |||
88 | /* Now for the string version of these functions */ | ||
89 | void od_outsb(unsigned long port, const void *addr, unsigned long count) | ||
90 | { | ||
91 | int i; | ||
92 | unsigned char *p = (unsigned char *) addr; | ||
93 | |||
94 | for (i = 0; i < count; i++, p++) { | ||
95 | outb(*p, port); | ||
96 | } | ||
97 | } | ||
98 | |||
99 | |||
100 | void od_insb(unsigned long port, void *addr, unsigned long count) | ||
101 | { | ||
102 | int i; | ||
103 | unsigned char *p = (unsigned char *) addr; | ||
104 | |||
105 | for (i = 0; i < count; i++, p++) { | ||
106 | *p = inb(port); | ||
107 | } | ||
108 | } | ||
109 | |||
110 | /* For the 16 and 32 bit string functions, we have to worry about alignment. | ||
111 | * The SH does not do unaligned accesses, so we have to read as bytes and | ||
112 | * then write as a word or dword. | ||
113 | * This can be optimised a lot more, especially in the case where the data | ||
114 | * is aligned | ||
115 | */ | ||
116 | |||
117 | void od_outsw(unsigned long port, const void *addr, unsigned long count) | ||
118 | { | ||
119 | int i; | ||
120 | unsigned short tmp; | ||
121 | unsigned char *p = (unsigned char *) addr; | ||
122 | |||
123 | for (i = 0; i < count; i++, p += 2) { | ||
124 | tmp = (*p) | ((*(p + 1)) << 8); | ||
125 | outw(tmp, port); | ||
126 | } | ||
127 | } | ||
128 | |||
129 | |||
130 | void od_insw(unsigned long port, void *addr, unsigned long count) | ||
131 | { | ||
132 | int i; | ||
133 | unsigned short tmp; | ||
134 | unsigned char *p = (unsigned char *) addr; | ||
135 | |||
136 | for (i = 0; i < count; i++, p += 2) { | ||
137 | tmp = inw(port); | ||
138 | p[0] = tmp & 0xff; | ||
139 | p[1] = (tmp >> 8) & 0xff; | ||
140 | } | ||
141 | } | ||
142 | |||
143 | |||
144 | void od_outsl(unsigned long port, const void *addr, unsigned long count) | ||
145 | { | ||
146 | int i; | ||
147 | unsigned tmp; | ||
148 | unsigned char *p = (unsigned char *) addr; | ||
149 | |||
150 | for (i = 0; i < count; i++, p += 4) { | ||
151 | tmp = (*p) | ((*(p + 1)) << 8) | ((*(p + 2)) << 16) | | ||
152 | ((*(p + 3)) << 24); | ||
153 | outl(tmp, port); | ||
154 | } | ||
155 | } | ||
156 | |||
157 | |||
158 | void od_insl(unsigned long port, void *addr, unsigned long count) | ||
159 | { | ||
160 | int i; | ||
161 | unsigned tmp; | ||
162 | unsigned char *p = (unsigned char *) addr; | ||
163 | |||
164 | for (i = 0; i < count; i++, p += 4) { | ||
165 | tmp = inl(port); | ||
166 | p[0] = tmp & 0xff; | ||
167 | p[1] = (tmp >> 8) & 0xff; | ||
168 | p[2] = (tmp >> 16) & 0xff; | ||
169 | p[3] = (tmp >> 24) & 0xff; | ||
170 | |||
171 | } | ||
172 | } | ||
diff --git a/arch/sh/boards/overdrive/irq.c b/arch/sh/boards/overdrive/irq.c deleted file mode 100644 index 5d730c70389e..000000000000 --- a/arch/sh/boards/overdrive/irq.c +++ /dev/null | |||
@@ -1,191 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000 David J. Mckay (david.mckay@st.com) | ||
3 | * | ||
4 | * May be copied or modified under the terms of the GNU General Public | ||
5 | * License. See linux/COPYING for more information. | ||
6 | * | ||
7 | * Looks after interrupts on the overdrive board. | ||
8 | * | ||
9 | * Bases on the IPR irq system | ||
10 | */ | ||
11 | |||
12 | #include <linux/init.h> | ||
13 | #include <linux/irq.h> | ||
14 | |||
15 | #include <asm/system.h> | ||
16 | #include <asm/io.h> | ||
17 | |||
18 | #include <asm/overdrive/overdrive.h> | ||
19 | |||
20 | struct od_data { | ||
21 | int overdrive_irq; | ||
22 | int irq_mask; | ||
23 | }; | ||
24 | |||
25 | #define NUM_EXTERNAL_IRQS 16 | ||
26 | #define EXTERNAL_IRQ_NOT_IN_USE (-1) | ||
27 | #define EXTERNAL_IRQ_NOT_ASSIGNED (-1) | ||
28 | |||
29 | /* | ||
30 | * This table is used to determine what to program into the FPGA's CT register | ||
31 | * for the specified Linux IRQ. | ||
32 | * | ||
33 | * The irq_mask gives the interrupt number from the PCI board (PCI_Int(6:0)) | ||
34 | * but is one greater than that because the because the FPGA treats 0 | ||
35 | * as disabled, a value of 1 asserts PCI_Int0, and so on. | ||
36 | * | ||
37 | * The overdrive_irq specifies which of the eight interrupt sources generates | ||
38 | * that interrupt, and but is multiplied by four to give the bit offset into | ||
39 | * the CT register. | ||
40 | * | ||
41 | * The seven interrupts levels (SH4 IRL's) we have available here is hardwired | ||
42 | * by the EPLD. The assignments here of which PCI interrupt generates each | ||
43 | * level is arbitary. | ||
44 | */ | ||
45 | static struct od_data od_data_table[NUM_EXTERNAL_IRQS] = { | ||
46 | /* overdrive_irq , irq_mask */ | ||
47 | {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 0 */ | ||
48 | {EXTERNAL_IRQ_NOT_ASSIGNED, 7}, /* 1 */ | ||
49 | {EXTERNAL_IRQ_NOT_ASSIGNED, 6}, /* 2 */ | ||
50 | {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 3 */ | ||
51 | {EXTERNAL_IRQ_NOT_ASSIGNED, 5}, /* 4 */ | ||
52 | {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 5 */ | ||
53 | {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 6 */ | ||
54 | {EXTERNAL_IRQ_NOT_ASSIGNED, 4}, /* 7 */ | ||
55 | {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 8 */ | ||
56 | {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 9 */ | ||
57 | {EXTERNAL_IRQ_NOT_ASSIGNED, 3}, /* 10 */ | ||
58 | {EXTERNAL_IRQ_NOT_ASSIGNED, 2}, /* 11 */ | ||
59 | {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 12 */ | ||
60 | {EXTERNAL_IRQ_NOT_ASSIGNED, 1}, /* 13 */ | ||
61 | {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 14 */ | ||
62 | {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE} /* 15 */ | ||
63 | }; | ||
64 | |||
65 | static void set_od_data(int overdrive_irq, int irq) | ||
66 | { | ||
67 | if (irq >= NUM_EXTERNAL_IRQS || irq < 0) | ||
68 | return; | ||
69 | od_data_table[irq].overdrive_irq = overdrive_irq << 2; | ||
70 | } | ||
71 | |||
72 | static void enable_od_irq(unsigned int irq); | ||
73 | void disable_od_irq(unsigned int irq); | ||
74 | |||
75 | /* shutdown is same as "disable" */ | ||
76 | #define shutdown_od_irq disable_od_irq | ||
77 | |||
78 | static void mask_and_ack_od(unsigned int); | ||
79 | static void end_od_irq(unsigned int irq); | ||
80 | |||
81 | static unsigned int startup_od_irq(unsigned int irq) | ||
82 | { | ||
83 | enable_od_irq(irq); | ||
84 | return 0; /* never anything pending */ | ||
85 | } | ||
86 | |||
87 | static struct hw_interrupt_type od_irq_type = { | ||
88 | .typename = "Overdrive-IRQ", | ||
89 | .startup = startup_od_irq, | ||
90 | .shutdown = shutdown_od_irq, | ||
91 | .enable = enable_od_irq, | ||
92 | .disable = disable_od_irq, | ||
93 | .ack = mask_and_ack_od, | ||
94 | .end = end_od_irq | ||
95 | }; | ||
96 | |||
97 | static void disable_od_irq(unsigned int irq) | ||
98 | { | ||
99 | unsigned val, flags; | ||
100 | int overdrive_irq; | ||
101 | unsigned mask; | ||
102 | |||
103 | /* Not a valid interrupt */ | ||
104 | if (irq < 0 || irq >= NUM_EXTERNAL_IRQS) | ||
105 | return; | ||
106 | |||
107 | /* Is is necessary to use a cli here? Would a spinlock not be | ||
108 | * mroe efficient? | ||
109 | */ | ||
110 | local_irq_save(flags); | ||
111 | overdrive_irq = od_data_table[irq].overdrive_irq; | ||
112 | if (overdrive_irq != EXTERNAL_IRQ_NOT_ASSIGNED) { | ||
113 | mask = ~(0x7 << overdrive_irq); | ||
114 | val = ctrl_inl(OVERDRIVE_INT_CT); | ||
115 | val &= mask; | ||
116 | ctrl_outl(val, OVERDRIVE_INT_CT); | ||
117 | } | ||
118 | local_irq_restore(flags); | ||
119 | } | ||
120 | |||
121 | static void enable_od_irq(unsigned int irq) | ||
122 | { | ||
123 | unsigned val, flags; | ||
124 | int overdrive_irq; | ||
125 | unsigned mask; | ||
126 | |||
127 | /* Not a valid interrupt */ | ||
128 | if (irq < 0 || irq >= NUM_EXTERNAL_IRQS) | ||
129 | return; | ||
130 | |||
131 | /* Set priority in OD back to original value */ | ||
132 | local_irq_save(flags); | ||
133 | /* This one is not in use currently */ | ||
134 | overdrive_irq = od_data_table[irq].overdrive_irq; | ||
135 | if (overdrive_irq != EXTERNAL_IRQ_NOT_ASSIGNED) { | ||
136 | val = ctrl_inl(OVERDRIVE_INT_CT); | ||
137 | mask = ~(0x7 << overdrive_irq); | ||
138 | val &= mask; | ||
139 | mask = od_data_table[irq].irq_mask << overdrive_irq; | ||
140 | val |= mask; | ||
141 | ctrl_outl(val, OVERDRIVE_INT_CT); | ||
142 | } | ||
143 | local_irq_restore(flags); | ||
144 | } | ||
145 | |||
146 | |||
147 | |||
148 | /* this functions sets the desired irq handler to be an overdrive type */ | ||
149 | static void __init make_od_irq(unsigned int irq) | ||
150 | { | ||
151 | disable_irq_nosync(irq); | ||
152 | irq_desc[irq].chip = &od_irq_type; | ||
153 | disable_od_irq(irq); | ||
154 | } | ||
155 | |||
156 | |||
157 | static void mask_and_ack_od(unsigned int irq) | ||
158 | { | ||
159 | disable_od_irq(irq); | ||
160 | } | ||
161 | |||
162 | static void end_od_irq(unsigned int irq) | ||
163 | { | ||
164 | enable_od_irq(irq); | ||
165 | } | ||
166 | |||
167 | void __init init_overdrive_irq(void) | ||
168 | { | ||
169 | int i; | ||
170 | |||
171 | /* Disable all interrupts */ | ||
172 | ctrl_outl(0, OVERDRIVE_INT_CT); | ||
173 | |||
174 | /* Update interrupt pin mode to use encoded interrupts */ | ||
175 | i = ctrl_inw(INTC_ICR); | ||
176 | i &= ~INTC_ICR_IRLM; | ||
177 | ctrl_outw(i, INTC_ICR); | ||
178 | |||
179 | for (i = 0; i < NUM_EXTERNAL_IRQS; i++) { | ||
180 | if (od_data_table[i].irq_mask != EXTERNAL_IRQ_NOT_IN_USE) { | ||
181 | make_od_irq(i); | ||
182 | } else if (i != 15) { // Cannot use imask on level 15 | ||
183 | make_imask_irq(i); | ||
184 | } | ||
185 | } | ||
186 | |||
187 | /* Set up the interrupts */ | ||
188 | set_od_data(OVERDRIVE_PCI_INTA, OVERDRIVE_PCI_IRQ1); | ||
189 | set_od_data(OVERDRIVE_PCI_INTB, OVERDRIVE_PCI_IRQ2); | ||
190 | set_od_data(OVERDRIVE_AUDIO_INT, OVERDRIVE_ESS_IRQ); | ||
191 | } | ||
diff --git a/arch/sh/boards/overdrive/led.c b/arch/sh/boards/overdrive/led.c deleted file mode 100644 index 860d7f204a4e..000000000000 --- a/arch/sh/boards/overdrive/led.c +++ /dev/null | |||
@@ -1,58 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/sh/overdrive/led.c | ||
3 | * | ||
4 | * Copyright (C) 1999 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 an Overdrive specific LED feature. | ||
10 | */ | ||
11 | |||
12 | #include <asm/system.h> | ||
13 | #include <asm/io.h> | ||
14 | #include <asm/overdrive/overdrive.h> | ||
15 | |||
16 | static void mach_led(int position, int value) | ||
17 | { | ||
18 | unsigned long flags; | ||
19 | unsigned long reg; | ||
20 | |||
21 | local_irq_save(flags); | ||
22 | |||
23 | reg = readl(OVERDRIVE_CTRL); | ||
24 | if (value) { | ||
25 | reg |= (1<<3); | ||
26 | } else { | ||
27 | reg &= ~(1<<3); | ||
28 | } | ||
29 | writel(reg, OVERDRIVE_CTRL); | ||
30 | |||
31 | local_irq_restore(flags); | ||
32 | } | ||
33 | |||
34 | #ifdef CONFIG_HEARTBEAT | ||
35 | |||
36 | #include <linux/sched.h> | ||
37 | |||
38 | /* acts like an actual heart beat -- ie thump-thump-pause... */ | ||
39 | void heartbeat_od(void) | ||
40 | { | ||
41 | static unsigned cnt = 0, period = 0, dist = 0; | ||
42 | |||
43 | if (cnt == 0 || cnt == dist) | ||
44 | mach_led( -1, 1); | ||
45 | else if (cnt == 7 || cnt == dist+7) | ||
46 | mach_led( -1, 0); | ||
47 | |||
48 | if (++cnt > period) { | ||
49 | cnt = 0; | ||
50 | /* The hyperbolic function below modifies the heartbeat period | ||
51 | * length in dependency of the current (5min) load. It goes | ||
52 | * through the points f(0)=126, f(1)=86, f(5)=51, | ||
53 | * f(inf)->30. */ | ||
54 | period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30; | ||
55 | dist = period / 4; | ||
56 | } | ||
57 | } | ||
58 | #endif /* CONFIG_HEARTBEAT */ | ||
diff --git a/arch/sh/boards/overdrive/mach.c b/arch/sh/boards/overdrive/mach.c deleted file mode 100644 index 2834a03ae477..000000000000 --- a/arch/sh/boards/overdrive/mach.c +++ /dev/null | |||
@@ -1,62 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/sh/overdrive/mach.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 STMicroelectronics Overdrive | ||
10 | */ | ||
11 | |||
12 | #include <linux/init.h> | ||
13 | |||
14 | #include <asm/machvec.h> | ||
15 | #include <asm/rtc.h> | ||
16 | #include <asm/machvec_init.h> | ||
17 | |||
18 | #include <asm/io_unknown.h> | ||
19 | #include <asm/io_generic.h> | ||
20 | #include <asm/overdrive/io.h> | ||
21 | |||
22 | void heartbeat_od(void); | ||
23 | void init_overdrive_irq(void); | ||
24 | void galileo_pcibios_init(void); | ||
25 | |||
26 | /* | ||
27 | * The Machine Vector | ||
28 | */ | ||
29 | |||
30 | struct sh_machine_vector mv_od __initmv = { | ||
31 | .mv_nr_irqs = 48, | ||
32 | |||
33 | .mv_inb = od_inb, | ||
34 | .mv_inw = od_inw, | ||
35 | .mv_inl = od_inl, | ||
36 | .mv_outb = od_outb, | ||
37 | .mv_outw = od_outw, | ||
38 | .mv_outl = od_outl, | ||
39 | |||
40 | .mv_inb_p = od_inb_p, | ||
41 | .mv_inw_p = od_inw_p, | ||
42 | .mv_inl_p = od_inl_p, | ||
43 | .mv_outb_p = od_outb_p, | ||
44 | .mv_outw_p = od_outw_p, | ||
45 | .mv_outl_p = od_outl_p, | ||
46 | |||
47 | .mv_insb = od_insb, | ||
48 | .mv_insw = od_insw, | ||
49 | .mv_insl = od_insl, | ||
50 | .mv_outsb = od_outsb, | ||
51 | .mv_outsw = od_outsw, | ||
52 | .mv_outsl = od_outsl, | ||
53 | |||
54 | #ifdef CONFIG_PCI | ||
55 | .mv_init_irq = init_overdrive_irq, | ||
56 | #endif | ||
57 | #ifdef CONFIG_HEARTBEAT | ||
58 | .mv_heartbeat = heartbeat_od, | ||
59 | #endif | ||
60 | }; | ||
61 | |||
62 | ALIAS_MV(od) | ||
diff --git a/arch/sh/boards/overdrive/pcidma.c b/arch/sh/boards/overdrive/pcidma.c deleted file mode 100644 index 1c9bfeda00b7..000000000000 --- a/arch/sh/boards/overdrive/pcidma.c +++ /dev/null | |||
@@ -1,46 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000 David J. Mckay (david.mckay@st.com) | ||
3 | * | ||
4 | * May be copied or modified under the terms of the GNU General Public | ||
5 | * License. See linux/COPYING for more information. | ||
6 | * | ||
7 | * Dynamic DMA mapping support. | ||
8 | * | ||
9 | * On the overdrive, we can only DMA from memory behind the PCI bus! | ||
10 | * this means that all DMA'able memory must come from there. | ||
11 | * this restriction will not apply to later boards. | ||
12 | */ | ||
13 | |||
14 | #include <linux/types.h> | ||
15 | #include <linux/mm.h> | ||
16 | #include <linux/string.h> | ||
17 | #include <linux/pci.h> | ||
18 | #include <asm/io.h> | ||
19 | |||
20 | void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, | ||
21 | dma_addr_t * dma_handle) | ||
22 | { | ||
23 | void *ret; | ||
24 | int gfp = GFP_ATOMIC; | ||
25 | |||
26 | printk("BUG: pci_alloc_consistent() called - not yet supported\n"); | ||
27 | /* We ALWAYS need DMA memory on the overdrive hardware, | ||
28 | * due to it's extreme weirdness | ||
29 | * Need to flush the cache here as well, since the memory | ||
30 | * can still be seen through the cache! | ||
31 | */ | ||
32 | gfp |= GFP_DMA; | ||
33 | ret = (void *) __get_free_pages(gfp, get_order(size)); | ||
34 | |||
35 | if (ret != NULL) { | ||
36 | memset(ret, 0, size); | ||
37 | *dma_handle = virt_to_bus(ret); | ||
38 | } | ||
39 | return ret; | ||
40 | } | ||
41 | |||
42 | void pci_free_consistent(struct pci_dev *hwdev, size_t size, | ||
43 | void *vaddr, dma_addr_t dma_handle) | ||
44 | { | ||
45 | free_pages((unsigned long) vaddr, get_order(size)); | ||
46 | } | ||
diff --git a/arch/sh/boards/overdrive/setup.c b/arch/sh/boards/overdrive/setup.c deleted file mode 100644 index a3a7744c2047..000000000000 --- a/arch/sh/boards/overdrive/setup.c +++ /dev/null | |||
@@ -1,36 +0,0 @@ | |||
1 | /* | ||
2 | * arch/sh/overdrive/setup.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 | * STMicroelectronics Overdrive Support. | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <asm/io.h> | ||
15 | |||
16 | #include <asm/overdrive/overdrive.h> | ||
17 | #include <asm/overdrive/fpga.h> | ||
18 | |||
19 | const char *get_system_type(void) | ||
20 | { | ||
21 | return "SH7750 Overdrive"; | ||
22 | } | ||
23 | |||
24 | /* | ||
25 | * Initialize the board | ||
26 | */ | ||
27 | int __init platform_setup(void) | ||
28 | { | ||
29 | #ifdef CONFIG_PCI | ||
30 | init_overdrive_fpga(); | ||
31 | galileo_init(); | ||
32 | #endif | ||
33 | |||
34 | /* Enable RS232 receive buffers */ | ||
35 | writel(0x1e, OVERDRIVE_CTRL); | ||
36 | } | ||