/*
 * linux/arch/sh/board/mpc1211/setup.c
 *
 * Copyright (C) 2002  Saito.K & Jeanne,  Fujii.Y
 *
 */

#include <linux/config.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/hdreg.h>
#include <linux/ide.h>
#include <linux/interrupt.h>

#include <asm/io.h>
#include <asm/machvec.h>
#include <asm/mpc1211/mpc1211.h>
#include <asm/mpc1211/pci.h>
#include <asm/mpc1211/m1543c.h>


/* ALI15X3 SMBus address offsets */
#define SMBHSTSTS   (0 + 0x3100)
#define SMBHSTCNT   (1 + 0x3100)
#define SMBHSTSTART (2 + 0x3100)
#define SMBHSTCMD   (7 + 0x3100)
#define SMBHSTADD   (3 + 0x3100)
#define SMBHSTDAT0  (4 + 0x3100)
#define SMBHSTDAT1  (5 + 0x3100)
#define SMBBLKDAT   (6 + 0x3100)

/* Other settings */
#define MAX_TIMEOUT 500		/* times 1/100 sec */

/* ALI15X3 command constants */
#define ALI15X3_ABORT      0x04
#define ALI15X3_T_OUT      0x08
#define ALI15X3_QUICK      0x00
#define ALI15X3_BYTE       0x10
#define ALI15X3_BYTE_DATA  0x20
#define ALI15X3_WORD_DATA  0x30
#define ALI15X3_BLOCK_DATA 0x40
#define ALI15X3_BLOCK_CLR  0x80

/* ALI15X3 status register bits */
#define ALI15X3_STS_IDLE	0x04
#define ALI15X3_STS_BUSY	0x08
#define ALI15X3_STS_DONE	0x10
#define ALI15X3_STS_DEV		0x20	/* device error */
#define ALI15X3_STS_COLL	0x40	/* collision or no response */
#define ALI15X3_STS_TERM	0x80	/* terminated by abort */
#define ALI15X3_STS_ERR		0xE0	/* all the bad error bits */

const char *get_system_type(void)
{
	return "Interface MPC-1211(CTP/PCI/MPC-SH02)";
}

static void __init pci_write_config(unsigned long busNo,
				    unsigned long devNo,
				    unsigned long fncNo,
				    unsigned long cnfAdd,
				    unsigned long cnfData)
{
	ctrl_outl((0x80000000 
                + ((busNo & 0xff) << 16) 
                + ((devNo & 0x1f) << 11) 
                + ((fncNo & 0x07) <<  8) 
		+ (cnfAdd & 0xfc)), PCIPAR);

        ctrl_outl(cnfData, PCIPDR);
}

/*
  Initialize IRQ setting
*/

static unsigned char m_irq_mask = 0xfb;
static unsigned char s_irq_mask = 0xff;
volatile unsigned long irq_err_count;

static void disable_mpc1211_irq(unsigned int irq)
{
	unsigned long flags;

	save_and_cli(flags);
	if( irq < 8) {
		m_irq_mask |= (1 << irq);
		outb(m_irq_mask,I8259_M_MR);
	} else {
		s_irq_mask |= (1 << (irq - 8));
		outb(s_irq_mask,I8259_S_MR);
	}
	restore_flags(flags);

}

static void enable_mpc1211_irq(unsigned int irq)
{
	unsigned long flags;

	save_and_cli(flags);

	if( irq < 8) {
		m_irq_mask &= ~(1 << irq);
		outb(m_irq_mask,I8259_M_MR);
	} else {
		s_irq_mask &= ~(1 << (irq - 8));
		outb(s_irq_mask,I8259_S_MR);
	}
	restore_flags(flags);
}

static inline int mpc1211_irq_real(unsigned int irq)
{
	int value;
	int irqmask;

	if ( irq < 8) {
		irqmask = 1<<irq;
		outb(0x0b,I8259_M_CR);		/* ISR register */
		value = inb(I8259_M_CR) & irqmask;
		outb(0x0a,I8259_M_CR);		/* back ro the IPR reg */
		return value;
	}
	irqmask = 1<<(irq - 8);
	outb(0x0b,I8259_S_CR);		/* ISR register */
	value = inb(I8259_S_CR) & irqmask;
	outb(0x0a,I8259_S_CR);		/* back ro the IPR reg */
	return value;
}

static void mask_and_ack_mpc1211(unsigned int irq)
{
	unsigned long flags;

	save_and_cli(flags);

	if(irq < 8) {
		if(m_irq_mask & (1<<irq)){
		  if(!mpc1211_irq_real(irq)){
		    irq_err_count++;
		    printk("spurious 8259A interrupt: IRQ %x\n",irq);
		   }
		} else {
			m_irq_mask |= (1<<irq);
		}
		inb(I8259_M_MR);		/* DUMMY */
		outb(m_irq_mask,I8259_M_MR);	/* disable */
		outb(0x60+irq,I8259_M_CR);	/* EOI */
		
	} else {
		if(s_irq_mask & (1<<(irq - 8))){
		  if(!mpc1211_irq_real(irq)){
		    irq_err_count++;
		    printk("spurious 8259A interrupt: IRQ %x\n",irq);
		  }
		} else {
			s_irq_mask |= (1<<(irq - 8));
		}
		inb(I8259_S_MR);		/* DUMMY */
		outb(s_irq_mask,I8259_S_MR);	/* disable */
		outb(0x60+(irq-8),I8259_S_CR); 	/* EOI */
		outb(0x60+2,I8259_M_CR);
	}
	restore_flags(flags);
}

static void end_mpc1211_irq(unsigned int irq)
{
	enable_mpc1211_irq(irq);
}

static unsigned int startup_mpc1211_irq(unsigned int irq)
{
	enable_mpc1211_irq(irq);
	return 0;
}

static void shutdown_mpc1211_irq(unsigned int irq)
{
	disable_mpc1211_irq(irq);
}

static struct hw_interrupt_type mpc1211_irq_type = {
	.typename	= "MPC1211-IRQ",
	.startup	= startup_mpc1211_irq,
	.shutdown	= shutdown_mpc1211_irq,
	.enable		= enable_mpc1211_irq,
	.disable	= disable_mpc1211_irq,
	.ack		= mask_and_ack_mpc1211,
	.end		= end_mpc1211_irq
};

static void make_mpc1211_irq(unsigned int irq)
{
	irq_desc[irq].handler = &mpc1211_irq_type;
	irq_desc[irq].status  = IRQ_DISABLED;
	irq_desc[irq].action  = 0;
	irq_desc[irq].depth   = 1;
	disable_mpc1211_irq(irq);
}

int mpc1211_irq_demux(int irq)
{
	unsigned int poll;

	if( irq == 2 ) {
		outb(0x0c,I8259_M_CR);
		poll = inb(I8259_M_CR);
		if(poll & 0x80) {
			irq = (poll & 0x07);
		}
		if( irq == 2) {
			outb(0x0c,I8259_S_CR);
			poll = inb(I8259_S_CR);
			irq = (poll & 0x07) + 8;
		}
	}
	return irq;
}

void __init init_mpc1211_IRQ(void)
{
	int i;
	/*
	 * Super I/O (Just mimic PC):
	 *  1: keyboard
	 *  3: serial 1
	 *  4: serial 0
	 *  5: printer
	 *  6: floppy
	 *  8: rtc
	 * 10: lan
	 * 12: mouse
	 * 14: ide0
	 * 15: ide1
	 */

	pci_write_config(0,0,0,0x54, 0xb0b0002d);
	outb(0x11, I8259_M_CR); 	/* mater icw1 edge trigger  */
	outb(0x11, I8259_S_CR);		/* slave icw1 edge trigger  */
	outb(0x20, I8259_M_MR); 	/* m icw2 base vec 0x08	    */
	outb(0x28, I8259_S_MR);		/* s icw2 base vec 0x70	    */
	outb(0x04, I8259_M_MR);		/* m icw3 slave irq2	    */
	outb(0x02, I8259_S_MR);		/* s icw3 slave id	    */
	outb(0x01, I8259_M_MR);		/* m icw4 non buf normal eoi*/
	outb(0x01, I8259_S_MR);		/* s icw4 non buf normal eo1*/
	outb(0xfb, I8259_M_MR);		/* disable irq0--irq7  */
	outb(0xff, I8259_S_MR);		/* disable irq8--irq15 */

	for ( i=0; i < 16; i++) {
		if(i != 2) {
			make_mpc1211_irq(i);
		}
	}
}

/*
  Initialize the board
*/


static void delay (void)
{
	volatile unsigned short tmp;
	tmp = *(volatile unsigned short *) 0xa0000000;
}

static void delay1000 (void)
{
	int i;

	for (i=0; i<1000; i++)
		delay ();
}

static int put_smb_blk(unsigned char *p, int address, int command, int no)
{
	int temp;
	int timeout;
	int i;

	outb(0xff, SMBHSTSTS);
	temp = inb(SMBHSTSTS);
	for (timeout = 0; (timeout < MAX_TIMEOUT) && !(temp & ALI15X3_STS_IDLE); timeout++) {
		delay1000();
		temp = inb(SMBHSTSTS);
	}
	if (timeout >= MAX_TIMEOUT){
		return -1;
	}

	outb(((address & 0x7f) << 1), SMBHSTADD);
	outb(0xc0, SMBHSTCNT);
	outb(command & 0xff, SMBHSTCMD);
	outb(no & 0x1f, SMBHSTDAT0);

	for(i = 1; i <= no; i++) {
		outb(*p++, SMBBLKDAT);
	}
	outb(0xff, SMBHSTSTART);

	temp = inb(SMBHSTSTS);
	for (timeout = 0; (timeout < MAX_TIMEOUT) && !(temp & (ALI15X3_STS_ERR | ALI15X3_STS_DONE)); timeout++) {
		delay1000();
		temp = inb(SMBHSTSTS);
	}
	if (timeout >= MAX_TIMEOUT) {
		return -2;
	}
	if ( temp & ALI15X3_STS_ERR ){
		return -3;
	}
	return 0;
}

/*
 * The Machine Vector
 */

struct sh_machine_vector mv_mpc1211 __initmv = {
	.mv_nr_irqs		= 48,
	.mv_irq_demux		= mpc1211_irq_demux,
	.mv_init_irq		= init_mpc1211_IRQ,

#ifdef CONFIG_HEARTBEAT
	.mv_heartbeat		= heartbeat_mpc1211,
#endif
};

ALIAS_MV(mpc1211)

/* arch/sh/boards/mpc1211/rtc.c */
void mpc1211_time_init(void);

int __init platform_setup(void)
{
	unsigned char spd_buf[128];

	__set_io_port_base(PA_PCI_IO);

	pci_write_config(0,0,0,0x54, 0xb0b00000);

	do {
		outb(ALI15X3_ABORT, SMBHSTCNT);
		spd_buf[0] = 0x0c;
		spd_buf[1] = 0x43;
		spd_buf[2] = 0x7f;
		spd_buf[3] = 0x03;
		spd_buf[4] = 0x00;
		spd_buf[5] = 0x03;
		spd_buf[6] = 0x00;
	} while (put_smb_blk(spd_buf, 0x69, 0, 7) < 0);

	board_time_init = mpc1211_time_init;

	return 0;
}

