Remove obsolete #include <linux/config.h>
[linux-2.6/verdex.git] / arch / sh / boards / mpc1211 / setup.c
blob2bfb221cc35cbfd75890d0ceaae3f9e0a3a7409d
1 /*
2 * linux/arch/sh/board/mpc1211/setup.c
4 * Copyright (C) 2002 Saito.K & Jeanne, Fujii.Y
6 */
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>
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>
21 /* ALI15X3 SMBus address offsets */
22 #define SMBHSTSTS (0 + 0x3100)
23 #define SMBHSTCNT (1 + 0x3100)
24 #define SMBHSTSTART (2 + 0x3100)
25 #define SMBHSTCMD (7 + 0x3100)
26 #define SMBHSTADD (3 + 0x3100)
27 #define SMBHSTDAT0 (4 + 0x3100)
28 #define SMBHSTDAT1 (5 + 0x3100)
29 #define SMBBLKDAT (6 + 0x3100)
31 /* Other settings */
32 #define MAX_TIMEOUT 500 /* times 1/100 sec */
34 /* ALI15X3 command constants */
35 #define ALI15X3_ABORT 0x04
36 #define ALI15X3_T_OUT 0x08
37 #define ALI15X3_QUICK 0x00
38 #define ALI15X3_BYTE 0x10
39 #define ALI15X3_BYTE_DATA 0x20
40 #define ALI15X3_WORD_DATA 0x30
41 #define ALI15X3_BLOCK_DATA 0x40
42 #define ALI15X3_BLOCK_CLR 0x80
44 /* ALI15X3 status register bits */
45 #define ALI15X3_STS_IDLE 0x04
46 #define ALI15X3_STS_BUSY 0x08
47 #define ALI15X3_STS_DONE 0x10
48 #define ALI15X3_STS_DEV 0x20 /* device error */
49 #define ALI15X3_STS_COLL 0x40 /* collision or no response */
50 #define ALI15X3_STS_TERM 0x80 /* terminated by abort */
51 #define ALI15X3_STS_ERR 0xE0 /* all the bad error bits */
53 const char *get_system_type(void)
55 return "Interface MPC-1211(CTP/PCI/MPC-SH02)";
58 static void __init pci_write_config(unsigned long busNo,
59 unsigned long devNo,
60 unsigned long fncNo,
61 unsigned long cnfAdd,
62 unsigned long cnfData)
64 ctrl_outl((0x80000000
65 + ((busNo & 0xff) << 16)
66 + ((devNo & 0x1f) << 11)
67 + ((fncNo & 0x07) << 8)
68 + (cnfAdd & 0xfc)), PCIPAR);
70 ctrl_outl(cnfData, PCIPDR);
74 Initialize IRQ setting
77 static unsigned char m_irq_mask = 0xfb;
78 static unsigned char s_irq_mask = 0xff;
79 volatile unsigned long irq_err_count;
81 static void disable_mpc1211_irq(unsigned int irq)
83 unsigned long flags;
85 save_and_cli(flags);
86 if( irq < 8) {
87 m_irq_mask |= (1 << irq);
88 outb(m_irq_mask,I8259_M_MR);
89 } else {
90 s_irq_mask |= (1 << (irq - 8));
91 outb(s_irq_mask,I8259_S_MR);
93 restore_flags(flags);
97 static void enable_mpc1211_irq(unsigned int irq)
99 unsigned long flags;
101 save_and_cli(flags);
103 if( irq < 8) {
104 m_irq_mask &= ~(1 << irq);
105 outb(m_irq_mask,I8259_M_MR);
106 } else {
107 s_irq_mask &= ~(1 << (irq - 8));
108 outb(s_irq_mask,I8259_S_MR);
110 restore_flags(flags);
113 static inline int mpc1211_irq_real(unsigned int irq)
115 int value;
116 int irqmask;
118 if ( irq < 8) {
119 irqmask = 1<<irq;
120 outb(0x0b,I8259_M_CR); /* ISR register */
121 value = inb(I8259_M_CR) & irqmask;
122 outb(0x0a,I8259_M_CR); /* back ro the IPR reg */
123 return value;
125 irqmask = 1<<(irq - 8);
126 outb(0x0b,I8259_S_CR); /* ISR register */
127 value = inb(I8259_S_CR) & irqmask;
128 outb(0x0a,I8259_S_CR); /* back ro the IPR reg */
129 return value;
132 static void mask_and_ack_mpc1211(unsigned int irq)
134 unsigned long flags;
136 save_and_cli(flags);
138 if(irq < 8) {
139 if(m_irq_mask & (1<<irq)){
140 if(!mpc1211_irq_real(irq)){
141 irq_err_count++;
142 printk("spurious 8259A interrupt: IRQ %x\n",irq);
144 } else {
145 m_irq_mask |= (1<<irq);
147 inb(I8259_M_MR); /* DUMMY */
148 outb(m_irq_mask,I8259_M_MR); /* disable */
149 outb(0x60+irq,I8259_M_CR); /* EOI */
151 } else {
152 if(s_irq_mask & (1<<(irq - 8))){
153 if(!mpc1211_irq_real(irq)){
154 irq_err_count++;
155 printk("spurious 8259A interrupt: IRQ %x\n",irq);
157 } else {
158 s_irq_mask |= (1<<(irq - 8));
160 inb(I8259_S_MR); /* DUMMY */
161 outb(s_irq_mask,I8259_S_MR); /* disable */
162 outb(0x60+(irq-8),I8259_S_CR); /* EOI */
163 outb(0x60+2,I8259_M_CR);
165 restore_flags(flags);
168 static void end_mpc1211_irq(unsigned int irq)
170 enable_mpc1211_irq(irq);
173 static unsigned int startup_mpc1211_irq(unsigned int irq)
175 enable_mpc1211_irq(irq);
176 return 0;
179 static void shutdown_mpc1211_irq(unsigned int irq)
181 disable_mpc1211_irq(irq);
184 static struct hw_interrupt_type mpc1211_irq_type = {
185 .typename = "MPC1211-IRQ",
186 .startup = startup_mpc1211_irq,
187 .shutdown = shutdown_mpc1211_irq,
188 .enable = enable_mpc1211_irq,
189 .disable = disable_mpc1211_irq,
190 .ack = mask_and_ack_mpc1211,
191 .end = end_mpc1211_irq
194 static void make_mpc1211_irq(unsigned int irq)
196 irq_desc[irq].chip = &mpc1211_irq_type;
197 irq_desc[irq].status = IRQ_DISABLED;
198 irq_desc[irq].action = 0;
199 irq_desc[irq].depth = 1;
200 disable_mpc1211_irq(irq);
203 int mpc1211_irq_demux(int irq)
205 unsigned int poll;
207 if( irq == 2 ) {
208 outb(0x0c,I8259_M_CR);
209 poll = inb(I8259_M_CR);
210 if(poll & 0x80) {
211 irq = (poll & 0x07);
213 if( irq == 2) {
214 outb(0x0c,I8259_S_CR);
215 poll = inb(I8259_S_CR);
216 irq = (poll & 0x07) + 8;
219 return irq;
222 void __init init_mpc1211_IRQ(void)
224 int i;
226 * Super I/O (Just mimic PC):
227 * 1: keyboard
228 * 3: serial 1
229 * 4: serial 0
230 * 5: printer
231 * 6: floppy
232 * 8: rtc
233 * 10: lan
234 * 12: mouse
235 * 14: ide0
236 * 15: ide1
239 pci_write_config(0,0,0,0x54, 0xb0b0002d);
240 outb(0x11, I8259_M_CR); /* mater icw1 edge trigger */
241 outb(0x11, I8259_S_CR); /* slave icw1 edge trigger */
242 outb(0x20, I8259_M_MR); /* m icw2 base vec 0x08 */
243 outb(0x28, I8259_S_MR); /* s icw2 base vec 0x70 */
244 outb(0x04, I8259_M_MR); /* m icw3 slave irq2 */
245 outb(0x02, I8259_S_MR); /* s icw3 slave id */
246 outb(0x01, I8259_M_MR); /* m icw4 non buf normal eoi*/
247 outb(0x01, I8259_S_MR); /* s icw4 non buf normal eo1*/
248 outb(0xfb, I8259_M_MR); /* disable irq0--irq7 */
249 outb(0xff, I8259_S_MR); /* disable irq8--irq15 */
251 for ( i=0; i < 16; i++) {
252 if(i != 2) {
253 make_mpc1211_irq(i);
259 Initialize the board
263 static void delay (void)
265 volatile unsigned short tmp;
266 tmp = *(volatile unsigned short *) 0xa0000000;
269 static void delay1000 (void)
271 int i;
273 for (i=0; i<1000; i++)
274 delay ();
277 static int put_smb_blk(unsigned char *p, int address, int command, int no)
279 int temp;
280 int timeout;
281 int i;
283 outb(0xff, SMBHSTSTS);
284 temp = inb(SMBHSTSTS);
285 for (timeout = 0; (timeout < MAX_TIMEOUT) && !(temp & ALI15X3_STS_IDLE); timeout++) {
286 delay1000();
287 temp = inb(SMBHSTSTS);
289 if (timeout >= MAX_TIMEOUT){
290 return -1;
293 outb(((address & 0x7f) << 1), SMBHSTADD);
294 outb(0xc0, SMBHSTCNT);
295 outb(command & 0xff, SMBHSTCMD);
296 outb(no & 0x1f, SMBHSTDAT0);
298 for(i = 1; i <= no; i++) {
299 outb(*p++, SMBBLKDAT);
301 outb(0xff, SMBHSTSTART);
303 temp = inb(SMBHSTSTS);
304 for (timeout = 0; (timeout < MAX_TIMEOUT) && !(temp & (ALI15X3_STS_ERR | ALI15X3_STS_DONE)); timeout++) {
305 delay1000();
306 temp = inb(SMBHSTSTS);
308 if (timeout >= MAX_TIMEOUT) {
309 return -2;
311 if ( temp & ALI15X3_STS_ERR ){
312 return -3;
314 return 0;
318 * The Machine Vector
321 struct sh_machine_vector mv_mpc1211 __initmv = {
322 .mv_nr_irqs = 48,
323 .mv_irq_demux = mpc1211_irq_demux,
324 .mv_init_irq = init_mpc1211_IRQ,
326 #ifdef CONFIG_HEARTBEAT
327 .mv_heartbeat = heartbeat_mpc1211,
328 #endif
331 ALIAS_MV(mpc1211)
333 /* arch/sh/boards/mpc1211/rtc.c */
334 void mpc1211_time_init(void);
336 int __init platform_setup(void)
338 unsigned char spd_buf[128];
340 __set_io_port_base(PA_PCI_IO);
342 pci_write_config(0,0,0,0x54, 0xb0b00000);
344 do {
345 outb(ALI15X3_ABORT, SMBHSTCNT);
346 spd_buf[0] = 0x0c;
347 spd_buf[1] = 0x43;
348 spd_buf[2] = 0x7f;
349 spd_buf[3] = 0x03;
350 spd_buf[4] = 0x00;
351 spd_buf[5] = 0x03;
352 spd_buf[6] = 0x00;
353 } while (put_smb_blk(spd_buf, 0x69, 0, 7) < 0);
355 board_time_init = mpc1211_time_init;
357 return 0;