2 * linux/arch/sh/boards/mpc1211/setup.c
4 * Copyright (C) 2002 Saito.K & Jeanne, Fujii.Y
8 #include <linux/init.h>
10 #include <linux/hdreg.h>
11 #include <linux/ide.h>
12 #include <linux/interrupt.h>
13 #include <linux/platform_device.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)
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
,
56 unsigned long cnfData
)
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
)
77 m_irq_mask
|= (1 << irq
);
78 outb(m_irq_mask
,I8259_M_MR
);
80 s_irq_mask
|= (1 << (irq
- 8));
81 outb(s_irq_mask
,I8259_S_MR
);
86 static void enable_mpc1211_irq(unsigned int irq
)
89 m_irq_mask
&= ~(1 << irq
);
90 outb(m_irq_mask
,I8259_M_MR
);
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
)
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 */
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 */
116 static void mask_and_ack_mpc1211(unsigned int irq
)
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
);
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 */
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
);
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
);
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
)
187 outb(0x0c,I8259_M_CR
);
188 poll
= inb(I8259_M_CR
);
193 outb(0x0c,I8259_S_CR
);
194 poll
= inb(I8259_S_CR
);
195 irq
= (poll
& 0x07) + 8;
201 static void __init
init_mpc1211_IRQ(void)
205 * Super I/O (Just mimic PC):
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
++) {
237 static void delay1000(void)
241 for (i
=0; i
<1000; i
++)
245 static int put_smb_blk(unsigned char *p
, int address
, int command
, int no
)
251 outb(0xff, SMBHSTSTS
);
252 temp
= inb(SMBHSTSTS
);
253 for (timeout
= 0; (timeout
< MAX_TIMEOUT
) && !(temp
& ALI15X3_STS_IDLE
); timeout
++) {
255 temp
= inb(SMBHSTSTS
);
257 if (timeout
>= MAX_TIMEOUT
){
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
++) {
274 temp
= inb(SMBHSTSTS
);
276 if (timeout
>= MAX_TIMEOUT
) {
279 if ( temp
& ALI15X3_STS_ERR
){
285 static struct resource heartbeat_resources
[] = {
289 .flags
= IORESOURCE_MEM
,
293 static struct platform_device heartbeat_device
= {
296 .num_resources
= ARRAY_SIZE(heartbeat_resources
),
297 .resource
= heartbeat_resources
,
300 static struct platform_device
*mpc1211_devices
[] __initdata
= {
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);
323 outb(ALI15X3_ABORT
, SMBHSTCNT
);
331 } while (put_smb_blk(spd_buf
, 0x69, 0, 7) < 0);
333 board_time_init
= mpc1211_time_init
;
341 static struct sh_machine_vector mv_mpc1211 __initmv
= {
342 .mv_name
= "Interface MPC-1211(CTP/PCI/MPC-SH02)",
343 .mv_setup
= mpc1211_setup
,
345 .mv_irq_demux
= mpc1211_irq_demux
,
346 .mv_init_irq
= init_mpc1211_IRQ
,