/*
 * linux/drivers/ide/pci/sc1200.c		Version 0.91	28-Jan-2003
 *
 * Copyright (C) 2000-2002		Mark Lord <mlord@pobox.com>
 * May be copied or modified under the terms of the GNU General Public License
 *
 * Development of this chipset driver was funded
 * by the nice folks at National Semiconductor.
 *
 * Documentation:
 *	Available from National Semiconductor
 */

#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/timer.h>
#include <linux/mm.h>
#include <linux/ioport.h>
#include <linux/blkdev.h>
#include <linux/hdreg.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/ide.h>
#include <linux/pm.h>
#include <asm/io.h>
#include <asm/irq.h>

#define SC1200_REV_A	0x00
#define SC1200_REV_B1	0x01
#define SC1200_REV_B3	0x02
#define SC1200_REV_C1	0x03
#define SC1200_REV_D1	0x04

#define PCI_CLK_33	0x00
#define PCI_CLK_48	0x01
#define PCI_CLK_66	0x02
#define PCI_CLK_33A	0x03

static unsigned short sc1200_get_pci_clock (void)
{
	unsigned char chip_id, silicon_revision;
	unsigned int pci_clock;
	/*
	 * Check the silicon revision, as not all versions of the chip
	 * have the register with the fast PCI bus timings.
	 */
	chip_id = inb (0x903c);
	silicon_revision = inb (0x903d);

	// Read the fast pci clock frequency
	if (chip_id == 0x04 && silicon_revision < SC1200_REV_B1) {
		pci_clock = PCI_CLK_33;
	} else {
		// check clock generator configuration (cfcc)
		// the clock is in bits 8 and 9 of this word

		pci_clock = inw (0x901e);
		pci_clock >>= 8;
		pci_clock &= 0x03;
		if (pci_clock == PCI_CLK_33A)
			pci_clock = PCI_CLK_33;
	}
	return pci_clock;
}

extern char *ide_xfer_verbose (byte xfer_rate);

/*
 * Set a new transfer mode at the drive
 */
static int sc1200_set_xfer_mode (ide_drive_t *drive, byte mode)
{
	printk("%s: sc1200_set_xfer_mode(%s)\n", drive->name, ide_xfer_verbose(mode));
	return ide_config_drive_speed(drive, mode);
}

/*
 * Here are the standard PIO mode 0-4 timings for each "format".
 * Format-0 uses fast data reg timings, with slower command reg timings.
 * Format-1 uses fast timings for all registers, but won't work with all drives.
 */
static const unsigned int sc1200_pio_timings[4][5] =
	{{0x00009172, 0x00012171, 0x00020080, 0x00032010, 0x00040010},	// format0  33Mhz
	 {0xd1329172, 0x71212171, 0x30200080, 0x20102010, 0x00100010},	// format1, 33Mhz
	 {0xfaa3f4f3, 0xc23232b2, 0x513101c1, 0x31213121, 0x10211021},	// format1, 48Mhz
	 {0xfff4fff4, 0xf35353d3, 0x814102f1, 0x42314231, 0x11311131}};	// format1, 66Mhz

/*
 * After chip reset, the PIO timings are set to 0x00009172, which is not valid.
 */
//#define SC1200_BAD_PIO(timings) (((timings)&~0x80000000)==0x00009172)

static int sc1200_autoselect_dma_mode (ide_drive_t *drive)
{
	int			udma_ok = 1, mode = 0;
	ide_hwif_t		*hwif = HWIF(drive);
	int			unit = drive->select.b.unit;
	ide_drive_t		*mate = &hwif->drives[unit^1];
	struct hd_driveid	*id = drive->id;

	/*
	 * The SC1200 specifies that two drives sharing a cable cannot
	 * mix UDMA/MDMA.  It has to be one or the other, for the pair,
	 * though different timings can still be chosen for each drive.
	 * We could set the appropriate timing bits on the fly,
	 * but that might be a bit confusing.  So, for now we statically
	 * handle this requirement by looking at our mate drive to see
	 * what it is capable of, before choosing a mode for our own drive.
	 */
	if (mate->present) {
		struct hd_driveid *mateid = mate->id;
		if (mateid && (mateid->capability & 1) && !__ide_dma_bad_drive(mate)) {
			if ((mateid->field_valid & 4) && (mateid->dma_ultra & 7))
				udma_ok = 1;
			else if ((mateid->field_valid & 2) && (mateid->dma_mword & 7))
				udma_ok = 0;
			else
				udma_ok = 1;
		}
	}
	/*
	 * Now see what the current drive is capable of,
	 * selecting UDMA only if the mate said it was ok.
	 */
	if (id && (id->capability & 1) && hwif->autodma && !__ide_dma_bad_drive(drive)) {
		if (udma_ok && (id->field_valid & 4) && (id->dma_ultra & 7)) {
			if      (id->dma_ultra & 4)
				mode = XFER_UDMA_2;
			else if (id->dma_ultra & 2)
				mode = XFER_UDMA_1;
			else if (id->dma_ultra & 1)
				mode = XFER_UDMA_0;
		}
		if (!mode && (id->field_valid & 2) && (id->dma_mword & 7)) {
			if      (id->dma_mword & 4)
				mode = XFER_MW_DMA_2;
			else if (id->dma_mword & 2)
				mode = XFER_MW_DMA_1;
			else if (id->dma_mword & 1)
				mode = XFER_MW_DMA_0;
		}
	}
	return mode;
}

/*
 * sc1200_config_dma2() handles selection/setting of DMA/UDMA modes
 * for both the chipset and drive.
 */
static int sc1200_config_dma2 (ide_drive_t *drive, int mode)
{
	ide_hwif_t		*hwif = HWIF(drive);
	int			unit = drive->select.b.unit;
	unsigned int		reg, timings;
	unsigned short		pci_clock;
	unsigned int		basereg = hwif->channel ? 0x50 : 0x40;

	/*
	 * Default to DMA-off in case we run into trouble here.
	 */
	hwif->ide_dma_off_quietly(drive);			/* turn off DMA while we fiddle */
	outb(inb(hwif->dma_base+2)&~(unit?0x40:0x20), hwif->dma_base+2); /* clear DMA_capable bit */

	/*
	 * Tell the drive to switch to the new mode; abort on failure.
	 */
	if (!mode || sc1200_set_xfer_mode(drive, mode)) {
		printk("SC1200: set xfer mode failure\n");
		return 1;	/* failure */
	}

	pci_clock = sc1200_get_pci_clock();

	/*
	 * Now tune the chipset to match the drive:
	 *
	 * Note that each DMA mode has several timings associated with it.
	 * The correct timing depends on the fast PCI clock freq.
	 */
	timings = 0;
	switch (mode) {
		case XFER_UDMA_0:
			switch (pci_clock) {
				case PCI_CLK_33:	timings = 0x00921250;	break;
				case PCI_CLK_48:	timings = 0x00932470;	break;
				case PCI_CLK_66:	timings = 0x009436a1;	break;
			}
			break;
		case XFER_UDMA_1:
			switch (pci_clock) {
				case PCI_CLK_33:	timings = 0x00911140;	break;
				case PCI_CLK_48:	timings = 0x00922260;	break;
				case PCI_CLK_66:	timings = 0x00933481;	break;
			}
			break;
		case XFER_UDMA_2:
			switch (pci_clock) {
				case PCI_CLK_33:	timings = 0x00911030;	break;
				case PCI_CLK_48:	timings = 0x00922140;	break;
				case PCI_CLK_66:	timings = 0x00923261;	break;
			}
			break;
		case XFER_MW_DMA_0:
			switch (pci_clock) {
				case PCI_CLK_33:	timings = 0x00077771;	break;
				case PCI_CLK_48:	timings = 0x000bbbb2;	break;
				case PCI_CLK_66:	timings = 0x000ffff3;	break;
			}
			break;
		case XFER_MW_DMA_1:
			switch (pci_clock) {
				case PCI_CLK_33:	timings = 0x00012121;	break;
				case PCI_CLK_48:	timings = 0x00024241;	break;
				case PCI_CLK_66:	timings = 0x00035352;	break;
			}
			break;
		case XFER_MW_DMA_2:
			switch (pci_clock) {
				case PCI_CLK_33:	timings = 0x00002020;	break;
				case PCI_CLK_48:	timings = 0x00013131;	break;
				case PCI_CLK_66:	timings = 0x00015151;	break;
			}
			break;
	}

	if (timings == 0) {
		printk("%s: sc1200_config_dma: huh? mode=%02x clk=%x \n", drive->name, mode, pci_clock);
		return 1;	/* failure */
	}

	if (unit == 0) {			/* are we configuring drive0? */
		pci_read_config_dword(hwif->pci_dev, basereg+4, &reg);
		timings |= reg & 0x80000000;	/* preserve PIO format bit */
		pci_write_config_dword(hwif->pci_dev, basereg+4, timings);
	} else {
		pci_write_config_dword(hwif->pci_dev, basereg+12, timings);
	}

	outb(inb(hwif->dma_base+2)|(unit?0x40:0x20), hwif->dma_base+2);	/* set DMA_capable bit */

	/*
	 * Finally, turn DMA on in software, and exit.
	 */
	return hwif->ide_dma_on(drive);	/* success */
}

/*
 * sc1200_config_dma() handles selection/setting of DMA/UDMA modes
 * for both the chipset and drive.
 */
static int sc1200_config_dma (ide_drive_t *drive)
{
	return sc1200_config_dma2(drive, sc1200_autoselect_dma_mode(drive));
}


/*  Replacement for the standard ide_dma_end action in
 *  dma_proc.
 *
 *  returns 1 on error, 0 otherwise
 */
static int sc1200_ide_dma_end (ide_drive_t *drive)
{
	ide_hwif_t *hwif = HWIF(drive);
	unsigned long dma_base = hwif->dma_base;
	byte dma_stat;

	dma_stat = inb(dma_base+2);		/* get DMA status */

	if (!(dma_stat & 4))
		printk(" ide_dma_end dma_stat=%0x err=%x newerr=%x\n",
		  dma_stat, ((dma_stat&7)!=4), ((dma_stat&2)==2));

	outb(dma_stat|0x1b, dma_base+2);	/* clear the INTR & ERROR bits */
	outb(inb(dma_base)&~1, dma_base);	/* !! DO THIS HERE !! stop DMA */

	drive->waiting_for_dma = 0;
	ide_destroy_dmatable(drive);		/* purge DMA mappings */

	return (dma_stat & 7) != 4;		/* verify good DMA status */
}

/*
 * sc1200_tuneproc() handles selection/setting of PIO modes
 * for both the chipset and drive.
 *
 * All existing BIOSs for this chipset guarantee that all drives
 * will have valid default PIO timings set up before we get here.
 */
static void sc1200_tuneproc (ide_drive_t *drive, byte pio)	/* mode=255 means "autotune" */
{
	ide_hwif_t	*hwif = HWIF(drive);
	unsigned int	format;
	static byte	modes[5] = {XFER_PIO_0, XFER_PIO_1, XFER_PIO_2, XFER_PIO_3, XFER_PIO_4};
	int		mode = -1;

	switch (pio) {
		case 200: mode = XFER_UDMA_0;	break;
		case 201: mode = XFER_UDMA_1;	break;
		case 202: mode = XFER_UDMA_2;	break;
		case 100: mode = XFER_MW_DMA_0;	break;
		case 101: mode = XFER_MW_DMA_1;	break;
		case 102: mode = XFER_MW_DMA_2;	break;
	}
	if (mode != -1) {
		printk("SC1200: %s: changing (U)DMA mode\n", drive->name);
		(void)sc1200_config_dma2(drive, mode);
		return;
	}

	pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
	printk("SC1200: %s: setting PIO mode%d\n", drive->name, pio);
	if (!sc1200_set_xfer_mode(drive, modes[pio])) {
		unsigned int basereg = hwif->channel ? 0x50 : 0x40;
		pci_read_config_dword (hwif->pci_dev, basereg+4, &format);
		format = (format >> 31) & 1;
		if (format)
			format += sc1200_get_pci_clock();
		pci_write_config_dword(hwif->pci_dev, basereg + (drive->select.b.unit << 3), sc1200_pio_timings[format][pio]);
 	}
}

static ide_hwif_t *lookup_pci_dev (ide_hwif_t *prev, struct pci_dev *dev)
{
	int	h;

	for (h = 0; h < MAX_HWIFS; h++) {
		ide_hwif_t *hwif = &ide_hwifs[h];
		if (prev) {
			if (hwif == prev)
				prev = NULL;	// found previous, now look for next match
		} else {
			if (hwif && hwif->pci_dev == dev)
				return hwif;	// found next match
		}
	}
	return NULL;	// not found
}

typedef struct sc1200_saved_state_s {
	__u32		regs[4];
} sc1200_saved_state_t;


static int sc1200_suspend (struct pci_dev *dev, pm_message_t state)
{
	ide_hwif_t		*hwif = NULL;

	printk("SC1200: suspend(%u)\n", state.event);

	if (state.event == PM_EVENT_ON) {
		// we only save state when going from full power to less

		//
		// Loop over all interfaces that are part of this PCI device:
		//
		while ((hwif = lookup_pci_dev(hwif, dev)) != NULL) {
			sc1200_saved_state_t	*ss;
			unsigned int		basereg, r;
			//
			// allocate a permanent save area, if not already allocated
			//
			ss = (sc1200_saved_state_t *)hwif->config_data;
			if (ss == NULL) {
				ss = kmalloc(sizeof(sc1200_saved_state_t), GFP_KERNEL);
				if (ss == NULL)
					return -ENOMEM;
				hwif->config_data = (unsigned long)ss;
			}
			ss = (sc1200_saved_state_t *)hwif->config_data;
			//
			// Save timing registers:  this may be unnecessary if 
			// BIOS also does it
			//
			basereg = hwif->channel ? 0x50 : 0x40;
			for (r = 0; r < 4; ++r) {
				pci_read_config_dword (hwif->pci_dev, basereg + (r<<2), &ss->regs[r]);
			}
		}
	}

	/* You don't need to iterate over disks -- sysfs should have done that for you already */ 

	pci_disable_device(dev);
	pci_set_power_state(dev, pci_choose_state(dev, state));
	dev->current_state = state.event;
	return 0;
}

static int sc1200_resume (struct pci_dev *dev)
{
	ide_hwif_t	*hwif = NULL;

	pci_set_power_state(dev, PCI_D0);	// bring chip back from sleep state
	dev->current_state = PM_EVENT_ON;
	pci_enable_device(dev);
	//
	// loop over all interfaces that are part of this pci device:
	//
	while ((hwif = lookup_pci_dev(hwif, dev)) != NULL) {
		unsigned int		basereg, r, d, format;
		sc1200_saved_state_t	*ss = (sc1200_saved_state_t *)hwif->config_data;

		//
		// Restore timing registers:  this may be unnecessary if BIOS also does it
		//
		basereg = hwif->channel ? 0x50 : 0x40;
		if (ss != NULL) {
			for (r = 0; r < 4; ++r) {
				pci_write_config_dword(hwif->pci_dev, basereg + (r<<2), ss->regs[r]);
			}
		}
		//
		// Re-program drive PIO modes
		//
		pci_read_config_dword(hwif->pci_dev, basereg+4, &format);
		format = (format >> 31) & 1;
		if (format)
			format += sc1200_get_pci_clock();
		for (d = 0; d < 2; ++d) {
			ide_drive_t *drive = &(hwif->drives[d]);
			if (drive->present) {
				unsigned int pio, timings;
				pci_read_config_dword(hwif->pci_dev, basereg+(drive->select.b.unit << 3), &timings);
				for (pio = 0; pio <= 4; ++pio) {
					if (sc1200_pio_timings[format][pio] == timings)
						break;
				}
				if (pio > 4)
					pio = 255; /* autotune */
				(void)sc1200_tuneproc(drive, pio);
			}
		}
		//
		// Re-program drive DMA modes
		//
		for (d = 0; d < MAX_DRIVES; ++d) {
			ide_drive_t *drive = &(hwif->drives[d]);
			if (drive->present && !__ide_dma_bad_drive(drive)) {
				int was_using_dma = drive->using_dma;
				hwif->ide_dma_off_quietly(drive);
				sc1200_config_dma(drive);
				if (!was_using_dma && drive->using_dma) {
					hwif->ide_dma_off_quietly(drive);
				}
			}
		}
	}
	return 0;
}

/*
 * This gets invoked by the IDE driver once for each channel,
 * and performs channel-specific pre-initialization before drive probing.
 */
static void __devinit init_hwif_sc1200 (ide_hwif_t *hwif)
{
	if (hwif->mate)
		hwif->serialized = hwif->mate->serialized = 1;
	hwif->autodma = 0;
	if (hwif->dma_base) {
		hwif->ide_dma_check = &sc1200_config_dma;
		hwif->ide_dma_end   = &sc1200_ide_dma_end;
        	if (!noautodma)
                	hwif->autodma = 1;
		hwif->tuneproc = &sc1200_tuneproc;
	}
        hwif->atapi_dma = 1;
        hwif->ultra_mask = 0x07;
        hwif->mwdma_mask = 0x07;

        hwif->drives[0].autodma = hwif->autodma;
        hwif->drives[1].autodma = hwif->autodma;
}

static ide_pci_device_t sc1200_chipset __devinitdata = {
	.name		= "SC1200",
	.init_hwif	= init_hwif_sc1200,
	.channels	= 2,
	.autodma	= AUTODMA,
	.bootable	= ON_BOARD,
};

static int __devinit sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
	return ide_setup_pci_device(dev, &sc1200_chipset);
}

static struct pci_device_id sc1200_pci_tbl[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_IDE), 0},
	{ 0, },
};
MODULE_DEVICE_TABLE(pci, sc1200_pci_tbl);

static struct pci_driver driver = {
	.name		= "SC1200_IDE",
	.id_table	= sc1200_pci_tbl,
	.probe		= sc1200_init_one,
	.suspend	= sc1200_suspend,
	.resume		= sc1200_resume,
};

static int sc1200_ide_init(void)
{
	return ide_pci_register_driver(&driver);
}

module_init(sc1200_ide_init);

MODULE_AUTHOR("Mark Lord");
MODULE_DESCRIPTION("PCI driver module for NS SC1200 IDE");
MODULE_LICENSE("GPL");
