allow coexistance of N build and AC build.
[tomato.git] / release / src-rt-6.x / linux / linux-2.6 / arch / sh / boards / mpc1211 / setup.c
blob1a0604b23ce0f4bac86f65fa1e783d8e372cdb04
1 /*
2 * linux/arch/sh/boards/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>
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>
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)
30 /* Other settings */
31 #define MAX_TIMEOUT 500 /* times 1/100 sec */
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
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 */
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)
58 ctrl_outl((0x80000000
59 + ((busNo & 0xff) << 16)
60 + ((devNo & 0x1f) << 11)
61 + ((fncNo & 0x07) << 8)
62 + (cnfAdd & 0xfc)), PCIPAR);
64 ctrl_outl(cnfData, PCIPDR);
68 Initialize IRQ setting
71 static unsigned char m_irq_mask = 0xfb;
72 static unsigned char s_irq_mask = 0xff;
74 static void disable_mpc1211_irq(unsigned int irq)
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);
86 static void enable_mpc1211_irq(unsigned int irq)
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);
97 static inline int mpc1211_irq_real(unsigned int irq)
99 int value;
100 int irqmask;
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;
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;
116 static void mask_and_ack_mpc1211(unsigned int irq)
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);
124 } else {
125 m_irq_mask |= (1<<irq);
127 inb(I8259_M_MR); /* DUMMY */
128 outb(m_irq_mask,I8259_M_MR); /* disable */
129 outb(0x60+irq,I8259_M_CR); /* EOI */
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);
137 } else {
138 s_irq_mask |= (1<<(irq - 8));
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);
147 static void end_mpc1211_irq(unsigned int irq)
149 enable_mpc1211_irq(irq);
152 static unsigned int startup_mpc1211_irq(unsigned int irq)
154 enable_mpc1211_irq(irq);
155 return 0;
158 static void shutdown_mpc1211_irq(unsigned int irq)
160 disable_mpc1211_irq(irq);
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
173 static void make_mpc1211_irq(unsigned int irq)
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);
182 int mpc1211_irq_demux(int irq)
184 unsigned int poll;
186 if( irq == 2 ) {
187 outb(0x0c,I8259_M_CR);
188 poll = inb(I8259_M_CR);
189 if(poll & 0x80) {
190 irq = (poll & 0x07);
192 if( irq == 2) {
193 outb(0x0c,I8259_S_CR);
194 poll = inb(I8259_S_CR);
195 irq = (poll & 0x07) + 8;
198 return irq;
201 static void __init init_mpc1211_IRQ(void)
203 int i;
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
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 */
230 for ( i=0; i < 16; i++) {
231 if(i != 2) {
232 make_mpc1211_irq(i);
237 static void delay1000(void)
239 int i;
241 for (i=0; i<1000; i++)
242 ctrl_delay();
245 static int put_smb_blk(unsigned char *p, int address, int command, int no)
247 int temp;
248 int timeout;
249 int i;
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);
257 if (timeout >= MAX_TIMEOUT){
258 return -1;
261 outb(((address & 0x7f) << 1), SMBHSTADD);
262 outb(0xc0, SMBHSTCNT);
263 outb(command & 0xff, SMBHSTCMD);
264 outb(no & 0x1f, SMBHSTDAT0);
266 for(i = 1; i <= no; i++) {
267 outb(*p++, SMBBLKDAT);
269 outb(0xff, SMBHSTSTART);
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);
276 if (timeout >= MAX_TIMEOUT) {
277 return -2;
279 if ( temp & ALI15X3_STS_ERR ){
280 return -3;
282 return 0;
285 static struct resource heartbeat_resources[] = {
286 [0] = {
287 .start = 0xa2000000,
288 .end = 0xa2000000 + 8 - 1,
289 .flags = IORESOURCE_MEM,
293 static struct platform_device heartbeat_device = {
294 .name = "heartbeat",
295 .id = -1,
296 .num_resources = ARRAY_SIZE(heartbeat_resources),
297 .resource = heartbeat_resources,
300 static struct platform_device *mpc1211_devices[] __initdata = {
301 &heartbeat_device,
304 static int __init mpc1211_devices_setup(void)
306 return platform_add_devices(mpc1211_devices,
307 ARRAY_SIZE(mpc1211_devices));
309 __initcall(mpc1211_devices_setup);
311 /* arch/sh/boards/mpc1211/rtc.c */
312 void mpc1211_time_init(void);
314 static void __init mpc1211_setup(char **cmdline_p)
316 unsigned char spd_buf[128];
318 __set_io_port_base(PA_PCI_IO);
320 pci_write_config(0,0,0,0x54, 0xb0b00000);
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);
333 board_time_init = mpc1211_time_init;
335 return 0;
339 * The Machine Vector
341 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,
348 ALIAS_MV(mpc1211)