diff options
Diffstat (limited to 'arch/sh/boards/mpc1211/setup.c')
-rw-r--r-- | arch/sh/boards/mpc1211/setup.c | 347 |
1 files changed, 0 insertions, 347 deletions
diff --git a/arch/sh/boards/mpc1211/setup.c b/arch/sh/boards/mpc1211/setup.c deleted file mode 100644 index fede36361dc7..000000000000 --- a/arch/sh/boards/mpc1211/setup.c +++ /dev/null | |||
@@ -1,347 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/sh/boards/mpc1211/setup.c | ||
3 | * | ||
4 | * Copyright (C) 2002 Saito.K & Jeanne, Fujii.Y | ||
5 | * | ||
6 | */ | ||
7 | |||
8 | #include <linux/init.h> | ||
9 | #include <linux/irq.h> | ||
10 | #include <linux/hdreg.h> | ||
11 | #include <linux/ide.h> | ||
12 | #include <linux/interrupt.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | #include <asm/io.h> | ||
15 | #include <asm/machvec.h> | ||
16 | #include <asm/mpc1211/mpc1211.h> | ||
17 | #include <asm/mpc1211/pci.h> | ||
18 | #include <asm/mpc1211/m1543c.h> | ||
19 | |||
20 | /* ALI15X3 SMBus address offsets */ | ||
21 | #define SMBHSTSTS (0 + 0x3100) | ||
22 | #define SMBHSTCNT (1 + 0x3100) | ||
23 | #define SMBHSTSTART (2 + 0x3100) | ||
24 | #define SMBHSTCMD (7 + 0x3100) | ||
25 | #define SMBHSTADD (3 + 0x3100) | ||
26 | #define SMBHSTDAT0 (4 + 0x3100) | ||
27 | #define SMBHSTDAT1 (5 + 0x3100) | ||
28 | #define SMBBLKDAT (6 + 0x3100) | ||
29 | |||
30 | /* Other settings */ | ||
31 | #define MAX_TIMEOUT 500 /* times 1/100 sec */ | ||
32 | |||
33 | /* ALI15X3 command constants */ | ||
34 | #define ALI15X3_ABORT 0x04 | ||
35 | #define ALI15X3_T_OUT 0x08 | ||
36 | #define ALI15X3_QUICK 0x00 | ||
37 | #define ALI15X3_BYTE 0x10 | ||
38 | #define ALI15X3_BYTE_DATA 0x20 | ||
39 | #define ALI15X3_WORD_DATA 0x30 | ||
40 | #define ALI15X3_BLOCK_DATA 0x40 | ||
41 | #define ALI15X3_BLOCK_CLR 0x80 | ||
42 | |||
43 | /* ALI15X3 status register bits */ | ||
44 | #define ALI15X3_STS_IDLE 0x04 | ||
45 | #define ALI15X3_STS_BUSY 0x08 | ||
46 | #define ALI15X3_STS_DONE 0x10 | ||
47 | #define ALI15X3_STS_DEV 0x20 /* device error */ | ||
48 | #define ALI15X3_STS_COLL 0x40 /* collision or no response */ | ||
49 | #define ALI15X3_STS_TERM 0x80 /* terminated by abort */ | ||
50 | #define ALI15X3_STS_ERR 0xE0 /* all the bad error bits */ | ||
51 | |||
52 | static void __init pci_write_config(unsigned long busNo, | ||
53 | unsigned long devNo, | ||
54 | unsigned long fncNo, | ||
55 | unsigned long cnfAdd, | ||
56 | unsigned long cnfData) | ||
57 | { | ||
58 | ctrl_outl((0x80000000 | ||
59 | + ((busNo & 0xff) << 16) | ||
60 | + ((devNo & 0x1f) << 11) | ||
61 | + ((fncNo & 0x07) << 8) | ||
62 | + (cnfAdd & 0xfc)), PCIPAR); | ||
63 | |||
64 | ctrl_outl(cnfData, PCIPDR); | ||
65 | } | ||
66 | |||
67 | /* | ||
68 | Initialize IRQ setting | ||
69 | */ | ||
70 | |||
71 | static unsigned char m_irq_mask = 0xfb; | ||
72 | static unsigned char s_irq_mask = 0xff; | ||
73 | |||
74 | static void disable_mpc1211_irq(unsigned int irq) | ||
75 | { | ||
76 | if( irq < 8) { | ||
77 | m_irq_mask |= (1 << irq); | ||
78 | outb(m_irq_mask,I8259_M_MR); | ||
79 | } else { | ||
80 | s_irq_mask |= (1 << (irq - 8)); | ||
81 | outb(s_irq_mask,I8259_S_MR); | ||
82 | } | ||
83 | |||
84 | } | ||
85 | |||
86 | static void enable_mpc1211_irq(unsigned int irq) | ||
87 | { | ||
88 | if( irq < 8) { | ||
89 | m_irq_mask &= ~(1 << irq); | ||
90 | outb(m_irq_mask,I8259_M_MR); | ||
91 | } else { | ||
92 | s_irq_mask &= ~(1 << (irq - 8)); | ||
93 | outb(s_irq_mask,I8259_S_MR); | ||
94 | } | ||
95 | } | ||
96 | |||
97 | static inline int mpc1211_irq_real(unsigned int irq) | ||
98 | { | ||
99 | int value; | ||
100 | int irqmask; | ||
101 | |||
102 | if ( irq < 8) { | ||
103 | irqmask = 1<<irq; | ||
104 | outb(0x0b,I8259_M_CR); /* ISR register */ | ||
105 | value = inb(I8259_M_CR) & irqmask; | ||
106 | outb(0x0a,I8259_M_CR); /* back ro the IPR reg */ | ||
107 | return value; | ||
108 | } | ||
109 | irqmask = 1<<(irq - 8); | ||
110 | outb(0x0b,I8259_S_CR); /* ISR register */ | ||
111 | value = inb(I8259_S_CR) & irqmask; | ||
112 | outb(0x0a,I8259_S_CR); /* back ro the IPR reg */ | ||
113 | return value; | ||
114 | } | ||
115 | |||
116 | static void mask_and_ack_mpc1211(unsigned int irq) | ||
117 | { | ||
118 | if(irq < 8) { | ||
119 | if(m_irq_mask & (1<<irq)){ | ||
120 | if(!mpc1211_irq_real(irq)){ | ||
121 | atomic_inc(&irq_err_count) | ||
122 | printk("spurious 8259A interrupt: IRQ %x\n",irq); | ||
123 | } | ||
124 | } else { | ||
125 | m_irq_mask |= (1<<irq); | ||
126 | } | ||
127 | inb(I8259_M_MR); /* DUMMY */ | ||
128 | outb(m_irq_mask,I8259_M_MR); /* disable */ | ||
129 | outb(0x60+irq,I8259_M_CR); /* EOI */ | ||
130 | |||
131 | } else { | ||
132 | if(s_irq_mask & (1<<(irq - 8))){ | ||
133 | if(!mpc1211_irq_real(irq)){ | ||
134 | atomic_inc(&irq_err_count); | ||
135 | printk("spurious 8259A interrupt: IRQ %x\n",irq); | ||
136 | } | ||
137 | } else { | ||
138 | s_irq_mask |= (1<<(irq - 8)); | ||
139 | } | ||
140 | inb(I8259_S_MR); /* DUMMY */ | ||
141 | outb(s_irq_mask,I8259_S_MR); /* disable */ | ||
142 | outb(0x60+(irq-8),I8259_S_CR); /* EOI */ | ||
143 | outb(0x60+2,I8259_M_CR); | ||
144 | } | ||
145 | } | ||
146 | |||
147 | static void end_mpc1211_irq(unsigned int irq) | ||
148 | { | ||
149 | enable_mpc1211_irq(irq); | ||
150 | } | ||
151 | |||
152 | static unsigned int startup_mpc1211_irq(unsigned int irq) | ||
153 | { | ||
154 | enable_mpc1211_irq(irq); | ||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | static void shutdown_mpc1211_irq(unsigned int irq) | ||
159 | { | ||
160 | disable_mpc1211_irq(irq); | ||
161 | } | ||
162 | |||
163 | static struct hw_interrupt_type mpc1211_irq_type = { | ||
164 | .typename = "MPC1211-IRQ", | ||
165 | .startup = startup_mpc1211_irq, | ||
166 | .shutdown = shutdown_mpc1211_irq, | ||
167 | .enable = enable_mpc1211_irq, | ||
168 | .disable = disable_mpc1211_irq, | ||
169 | .ack = mask_and_ack_mpc1211, | ||
170 | .end = end_mpc1211_irq | ||
171 | }; | ||
172 | |||
173 | static void make_mpc1211_irq(unsigned int irq) | ||
174 | { | ||
175 | irq_desc[irq].chip = &mpc1211_irq_type; | ||
176 | irq_desc[irq].status = IRQ_DISABLED; | ||
177 | irq_desc[irq].action = 0; | ||
178 | irq_desc[irq].depth = 1; | ||
179 | disable_mpc1211_irq(irq); | ||
180 | } | ||
181 | |||
182 | int mpc1211_irq_demux(int irq) | ||
183 | { | ||
184 | unsigned int poll; | ||
185 | |||
186 | if( irq == 2 ) { | ||
187 | outb(0x0c,I8259_M_CR); | ||
188 | poll = inb(I8259_M_CR); | ||
189 | if(poll & 0x80) { | ||
190 | irq = (poll & 0x07); | ||
191 | } | ||
192 | if( irq == 2) { | ||
193 | outb(0x0c,I8259_S_CR); | ||
194 | poll = inb(I8259_S_CR); | ||
195 | irq = (poll & 0x07) + 8; | ||
196 | } | ||
197 | } | ||
198 | return irq; | ||
199 | } | ||
200 | |||
201 | static void __init init_mpc1211_IRQ(void) | ||
202 | { | ||
203 | int i; | ||
204 | /* | ||
205 | * Super I/O (Just mimic PC): | ||
206 | * 1: keyboard | ||
207 | * 3: serial 1 | ||
208 | * 4: serial 0 | ||
209 | * 5: printer | ||
210 | * 6: floppy | ||
211 | * 8: rtc | ||
212 | * 10: lan | ||
213 | * 12: mouse | ||
214 | * 14: ide0 | ||
215 | * 15: ide1 | ||
216 | */ | ||
217 | |||
218 | pci_write_config(0,0,0,0x54, 0xb0b0002d); | ||
219 | outb(0x11, I8259_M_CR); /* mater icw1 edge trigger */ | ||
220 | outb(0x11, I8259_S_CR); /* slave icw1 edge trigger */ | ||
221 | outb(0x20, I8259_M_MR); /* m icw2 base vec 0x08 */ | ||
222 | outb(0x28, I8259_S_MR); /* s icw2 base vec 0x70 */ | ||
223 | outb(0x04, I8259_M_MR); /* m icw3 slave irq2 */ | ||
224 | outb(0x02, I8259_S_MR); /* s icw3 slave id */ | ||
225 | outb(0x01, I8259_M_MR); /* m icw4 non buf normal eoi*/ | ||
226 | outb(0x01, I8259_S_MR); /* s icw4 non buf normal eo1*/ | ||
227 | outb(0xfb, I8259_M_MR); /* disable irq0--irq7 */ | ||
228 | outb(0xff, I8259_S_MR); /* disable irq8--irq15 */ | ||
229 | |||
230 | for ( i=0; i < 16; i++) { | ||
231 | if(i != 2) { | ||
232 | make_mpc1211_irq(i); | ||
233 | } | ||
234 | } | ||
235 | } | ||
236 | |||
237 | static void delay1000(void) | ||
238 | { | ||
239 | int i; | ||
240 | |||
241 | for (i=0; i<1000; i++) | ||
242 | ctrl_delay(); | ||
243 | } | ||
244 | |||
245 | static int put_smb_blk(unsigned char *p, int address, int command, int no) | ||
246 | { | ||
247 | int temp; | ||
248 | int timeout; | ||
249 | int i; | ||
250 | |||
251 | outb(0xff, SMBHSTSTS); | ||
252 | temp = inb(SMBHSTSTS); | ||
253 | for (timeout = 0; (timeout < MAX_TIMEOUT) && !(temp & ALI15X3_STS_IDLE); timeout++) { | ||
254 | delay1000(); | ||
255 | temp = inb(SMBHSTSTS); | ||
256 | } | ||
257 | if (timeout >= MAX_TIMEOUT){ | ||
258 | return -1; | ||
259 | } | ||
260 | |||
261 | outb(((address & 0x7f) << 1), SMBHSTADD); | ||
262 | outb(0xc0, SMBHSTCNT); | ||
263 | outb(command & 0xff, SMBHSTCMD); | ||
264 | outb(no & 0x1f, SMBHSTDAT0); | ||
265 | |||
266 | for(i = 1; i <= no; i++) { | ||
267 | outb(*p++, SMBBLKDAT); | ||
268 | } | ||
269 | outb(0xff, SMBHSTSTART); | ||
270 | |||
271 | temp = inb(SMBHSTSTS); | ||
272 | for (timeout = 0; (timeout < MAX_TIMEOUT) && !(temp & (ALI15X3_STS_ERR | ALI15X3_STS_DONE)); timeout++) { | ||
273 | delay1000(); | ||
274 | temp = inb(SMBHSTSTS); | ||
275 | } | ||
276 | if (timeout >= MAX_TIMEOUT) { | ||
277 | return -2; | ||
278 | } | ||
279 | if ( temp & ALI15X3_STS_ERR ){ | ||
280 | return -3; | ||
281 | } | ||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | static struct resource heartbeat_resources[] = { | ||
286 | [0] = { | ||
287 | .start = 0xa2000000, | ||
288 | .end = 0xa2000000, | ||
289 | .flags = IORESOURCE_MEM, | ||
290 | }, | ||
291 | }; | ||
292 | |||
293 | static struct platform_device heartbeat_device = { | ||
294 | .name = "heartbeat", | ||
295 | .id = -1, | ||
296 | .num_resources = ARRAY_SIZE(heartbeat_resources), | ||
297 | .resource = heartbeat_resources, | ||
298 | }; | ||
299 | |||
300 | static struct platform_device *mpc1211_devices[] __initdata = { | ||
301 | &heartbeat_device, | ||
302 | }; | ||
303 | |||
304 | static int __init mpc1211_devices_setup(void) | ||
305 | { | ||
306 | return platform_add_devices(mpc1211_devices, | ||
307 | ARRAY_SIZE(mpc1211_devices)); | ||
308 | } | ||
309 | __initcall(mpc1211_devices_setup); | ||
310 | |||
311 | /* arch/sh/boards/mpc1211/rtc.c */ | ||
312 | void mpc1211_time_init(void); | ||
313 | |||
314 | static void __init mpc1211_setup(char **cmdline_p) | ||
315 | { | ||
316 | unsigned char spd_buf[128]; | ||
317 | |||
318 | __set_io_port_base(PA_PCI_IO); | ||
319 | |||
320 | pci_write_config(0,0,0,0x54, 0xb0b00000); | ||
321 | |||
322 | do { | ||
323 | outb(ALI15X3_ABORT, SMBHSTCNT); | ||
324 | spd_buf[0] = 0x0c; | ||
325 | spd_buf[1] = 0x43; | ||
326 | spd_buf[2] = 0x7f; | ||
327 | spd_buf[3] = 0x03; | ||
328 | spd_buf[4] = 0x00; | ||
329 | spd_buf[5] = 0x03; | ||
330 | spd_buf[6] = 0x00; | ||
331 | } while (put_smb_blk(spd_buf, 0x69, 0, 7) < 0); | ||
332 | |||
333 | board_time_init = mpc1211_time_init; | ||
334 | |||
335 | return 0; | ||
336 | } | ||
337 | |||
338 | /* | ||
339 | * The Machine Vector | ||
340 | */ | ||
341 | static struct sh_machine_vector mv_mpc1211 __initmv = { | ||
342 | .mv_name = "Interface MPC-1211(CTP/PCI/MPC-SH02)", | ||
343 | .mv_setup = mpc1211_setup, | ||
344 | .mv_nr_irqs = 48, | ||
345 | .mv_irq_demux = mpc1211_irq_demux, | ||
346 | .mv_init_irq = init_mpc1211_IRQ, | ||
347 | }; | ||