/*
 * linux/drivers/ide/pci/sl82c105.c
 *
 * SL82C105/Winbond 553 IDE driver
 *
 * Maintainer unknown.
 *
 * Drive tuning added from Rebel.com's kernel sources
 *  -- Russell King (15/11/98) linux@arm.linux.org.uk
 * 
 * Merge in Russell's HW workarounds, fix various problems
 * with the timing registers setup.
 *  -- Benjamin Herrenschmidt (01/11/03) benh@kernel.crashing.org
 */

#include <linux/config.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/timer.h>
#include <linux/mm.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/blkdev.h>
#include <linux/hdreg.h>
#include <linux/pci.h>
#include <linux/ide.h>

#include <asm/io.h>
#include <asm/dma.h>

#undef DEBUG

#ifdef DEBUG
#define DBG(arg) printk arg
#else
#define DBG(fmt,...)
#endif
/*
 * SL82C105 PCI config register 0x40 bits.
 */
#define CTRL_IDE_IRQB   (1 << 30)
#define CTRL_IDE_IRQA   (1 << 28)
#define CTRL_LEGIRQ     (1 << 11)
#define CTRL_P1F16      (1 << 5)
#define CTRL_P1EN       (1 << 4)
#define CTRL_P0F16      (1 << 1)
#define CTRL_P0EN       (1 << 0)

/*
 * Convert a PIO mode and cycle time to the required on/off
 * times for the interface.  This has protection against run-away
 * timings.
 */
static unsigned int get_timing_sl82c105(ide_pio_data_t *p)
{
	unsigned int cmd_on;
	unsigned int cmd_off;

	cmd_on = (ide_pio_timings[p->pio_mode].active_time + 29) / 30;
	cmd_off = (p->cycle_time - 30 * cmd_on + 29) / 30;

	if (cmd_on > 32)
		cmd_on = 32;
	if (cmd_on == 0)
		cmd_on = 1;

	if (cmd_off > 32)
		cmd_off = 32;
	if (cmd_off == 0)
		cmd_off = 1;

	return (cmd_on - 1) << 8 | (cmd_off - 1) | (p->use_iordy ? 0x40 : 0x00);
}

/*
 * Configure the drive and chipset for PIO
 */
static void config_for_pio(ide_drive_t *drive, int pio, int report, int chipset_only)
{
	ide_hwif_t *hwif = HWIF(drive);
	struct pci_dev *dev = hwif->pci_dev;
	ide_pio_data_t p;
	u16 drv_ctrl = 0x909;
	unsigned int xfer_mode, reg;

	DBG(("config_for_pio(drive:%s, pio:%d, report:%d, chipset_only:%d)\n",
		drive->name, pio, report, chipset_only));
		
	reg = (hwif->channel ? 0x4c : 0x44) + (drive->select.b.unit ? 4 : 0);

	pio = ide_get_best_pio_mode(drive, pio, 5, &p);

	xfer_mode = XFER_PIO_0 + pio;

	if (chipset_only || ide_config_drive_speed(drive, xfer_mode) == 0) {
		drv_ctrl = get_timing_sl82c105(&p);
		drive->pio_speed = xfer_mode;
	} else
		drive->pio_speed = XFER_PIO_0;

	if (drive->using_dma == 0) {
		/*
		 * If we are actually using MW DMA, then we can not
		 * reprogram the interface drive control register.
		 */
		pci_write_config_word(dev, reg, drv_ctrl);
		pci_read_config_word(dev, reg, &drv_ctrl);

		if (report) {
			printk("%s: selected %s (%dns) (%04X)\n", drive->name,
			       ide_xfer_verbose(xfer_mode), p.cycle_time, drv_ctrl);
		}
	}
}

/*
 * Configure the drive and the chipset for DMA
 */
static int config_for_dma (ide_drive_t *drive)
{
	ide_hwif_t *hwif = HWIF(drive);
	struct pci_dev *dev = hwif->pci_dev;
	unsigned int reg;

	DBG(("config_for_dma(drive:%s)\n", drive->name));

	reg = (hwif->channel ? 0x4c : 0x44) + (drive->select.b.unit ? 4 : 0);

	if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0)
		return 1;

	pci_write_config_word(dev, reg, 0x0240);

	return 0;
}

/*
 * Check to see if the drive and
 * chipset is capable of DMA mode
 */

static int sl82c105_check_drive (ide_drive_t *drive)
{
	ide_hwif_t *hwif	= HWIF(drive);

	DBG(("sl82c105_check_drive(drive:%s)\n", drive->name));

	do {
		struct hd_driveid *id = drive->id;

		if (!drive->autodma)
			break;

		if (!id || !(id->capability & 1))
			break;

		/* Consult the list of known "bad" drives */
		if (__ide_dma_bad_drive(drive))
			break;

		if (id->field_valid & 2) {
			if ((id->dma_mword & hwif->mwdma_mask) ||
			    (id->dma_1word & hwif->swdma_mask))
				return hwif->ide_dma_on(drive);
		}

		if (__ide_dma_good_drive(drive))
			return hwif->ide_dma_on(drive);
	} while (0);

	return hwif->ide_dma_off_quietly(drive);
}

/*
 * The SL82C105 holds off all IDE interrupts while in DMA mode until
 * all DMA activity is completed.  Sometimes this causes problems (eg,
 * when the drive wants to report an error condition).
 *
 * 0x7e is a "chip testing" register.  Bit 2 resets the DMA controller
 * state machine.  We need to kick this to work around various bugs.
 */
static inline void sl82c105_reset_host(struct pci_dev *dev)
{
	u16 val;

	pci_read_config_word(dev, 0x7e, &val);
	pci_write_config_word(dev, 0x7e, val | (1 << 2));
	pci_write_config_word(dev, 0x7e, val & ~(1 << 2));
}

/*
 * If we get an IRQ timeout, it might be that the DMA state machine
 * got confused.  Fix from Todd Inglett.  Details from Winbond.
 *
 * This function is called when the IDE timer expires, the drive
 * indicates that it is READY, and we were waiting for DMA to complete.
 */
static int sl82c105_ide_dma_lost_irq(ide_drive_t *drive)
{
	ide_hwif_t *hwif = HWIF(drive);
	struct pci_dev *dev = hwif->pci_dev;
	u32 val, mask = hwif->channel ? CTRL_IDE_IRQB : CTRL_IDE_IRQA;
	unsigned long dma_base = hwif->dma_base;

	printk("sl82c105: lost IRQ: resetting host\n");

	/*
	 * Check the raw interrupt from the drive.
	 */
	pci_read_config_dword(dev, 0x40, &val);
	if (val & mask)
		printk("sl82c105: drive was requesting IRQ, but host lost it\n");

	/*
	 * Was DMA enabled?  If so, disable it - we're resetting the
	 * host.  The IDE layer will be handling the drive for us.
	 */
	val = hwif->INB(dma_base);
	if (val & 1) {
		outb(val & ~1, dma_base);
		printk("sl82c105: DMA was enabled\n");
	}

	sl82c105_reset_host(dev);

	/* ide_dmaproc would return 1, so we do as well */
	return 1;
}

/*
 * ATAPI devices can cause the SL82C105 DMA state machine to go gaga.
 * Winbond recommend that the DMA state machine is reset prior to
 * setting the bus master DMA enable bit.
 *
 * The generic IDE core will have disabled the BMEN bit before this
 * function is called.
 */
static void sl82c105_ide_dma_start(ide_drive_t *drive)
{
	ide_hwif_t *hwif = HWIF(drive);
	struct pci_dev *dev = hwif->pci_dev;

	sl82c105_reset_host(dev);
	ide_dma_start(drive);
}

static int sl82c105_ide_dma_timeout(ide_drive_t *drive)
{
	ide_hwif_t *hwif = HWIF(drive);
	struct pci_dev *dev = hwif->pci_dev;

	DBG(("sl82c105_ide_dma_timeout(drive:%s)\n", drive->name));

	sl82c105_reset_host(dev);
	return __ide_dma_timeout(drive);
}

static int sl82c105_ide_dma_on (ide_drive_t *drive)
{
	DBG(("sl82c105_ide_dma_on(drive:%s)\n", drive->name));

	if (config_for_dma(drive)) {
		config_for_pio(drive, 4, 0, 0);
		return HWIF(drive)->ide_dma_off_quietly(drive);
	}
	printk(KERN_INFO "%s: DMA enabled\n", drive->name);
	return __ide_dma_on(drive);
}

static int sl82c105_ide_dma_off_quietly (ide_drive_t *drive)
{
	u8 speed = XFER_PIO_0;
	int rc;
	
	DBG(("sl82c105_ide_dma_off_quietly(drive:%s)\n", drive->name));

	rc = __ide_dma_off_quietly(drive);
	if (drive->pio_speed)
		speed = drive->pio_speed - XFER_PIO_0;
	config_for_pio(drive, speed, 0, 1);
	drive->current_speed = drive->pio_speed;

	return rc;
}

/*
 * Ok, that is nasty, but we must make sure the DMA timings
 * won't be used for a PIO access. The solution here is
 * to make sure the 16 bits mode is diabled on the channel
 * when DMA is enabled, thus causing the chip to use PIO0
 * timings for those operations.
 */
static void sl82c105_selectproc(ide_drive_t *drive)
{
	ide_hwif_t *hwif = HWIF(drive);
	struct pci_dev *dev = hwif->pci_dev;
	u32 val, old, mask;

	//DBG(("sl82c105_selectproc(drive:%s)\n", drive->name));

	mask = hwif->channel ? CTRL_P1F16 : CTRL_P0F16;
	old = val = *((u32 *)&hwif->hwif_data);
	if (drive->using_dma)
		val &= ~mask;
	else
		val |= mask;
	if (old != val) {
		pci_write_config_dword(dev, 0x40, val);	
		*((u32 *)&hwif->hwif_data) = val;
	}
}

/*
 * ATA reset will clear the 16 bits mode in the control
 * register, we need to update our cache
 */
static void sl82c105_resetproc(ide_drive_t *drive)
{
	ide_hwif_t *hwif = HWIF(drive);
	struct pci_dev *dev = hwif->pci_dev;
	u32 val;

	DBG(("sl82c105_resetproc(drive:%s)\n", drive->name));

	pci_read_config_dword(dev, 0x40, &val);
	*((u32 *)&hwif->hwif_data) = val;
}
	
/*
 * We only deal with PIO mode here - DMA mode 'using_dma' is not
 * initialised at the point that this function is called.
 */
static void tune_sl82c105(ide_drive_t *drive, u8 pio)
{
	DBG(("tune_sl82c105(drive:%s)\n", drive->name));

	config_for_pio(drive, pio, 1, 0);

	/*
	 * We support 32-bit I/O on this interface, and it
	 * doesn't have problems with interrupts.
	 */
	drive->io_32bit = 1;
	drive->unmask = 1;
}

/*
 * Return the revision of the Winbond bridge
 * which this function is part of.
 */
static unsigned int sl82c105_bridge_revision(struct pci_dev *dev)
{
	struct pci_dev *bridge;
	u8 rev;

	/*
	 * The bridge should be part of the same device, but function 0.
	 */
	bridge = pci_find_slot(dev->bus->number,
			       PCI_DEVFN(PCI_SLOT(dev->devfn), 0));
	if (!bridge)
		return -1;

	/*
	 * Make sure it is a Winbond 553 and is an ISA bridge.
	 */
	if (bridge->vendor != PCI_VENDOR_ID_WINBOND ||
	    bridge->device != PCI_DEVICE_ID_WINBOND_83C553 ||
	    bridge->class >> 8 != PCI_CLASS_BRIDGE_ISA)
		return -1;

	/*
	 * We need to find function 0's revision, not function 1
	 */
	pci_read_config_byte(bridge, PCI_REVISION_ID, &rev);

	return rev;
}

/*
 * Enable the PCI device
 * 
 * --BenH: It's arch fixup code that should enable channels that
 * have not been enabled by firmware. I decided we can still enable
 * channel 0 here at least, but channel 1 has to be enabled by
 * firmware or arch code. We still set both to 16 bits mode.
 */
static unsigned int __init init_chipset_sl82c105(struct pci_dev *dev, const char *msg)
{
	u32 val;

	DBG(("init_chipset_sl82c105()\n"));

	pci_read_config_dword(dev, 0x40, &val);
	val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16;
	pci_write_config_dword(dev, 0x40, val);

	return dev->irq;
}

static void __init init_dma_sl82c105(ide_hwif_t *hwif, unsigned long dma_base)
{
	unsigned int rev;
	u8 dma_state;

	DBG(("init_dma_sl82c105(hwif: ide%d, dma_base: 0x%08x)\n", hwif->index, dma_base));

	hwif->autodma = 0;

	if (!dma_base)
		return;

	dma_state = hwif->INB(dma_base + 2);
	rev = sl82c105_bridge_revision(hwif->pci_dev);
	if (rev <= 5) {
		printk("    %s: Winbond 553 bridge revision %d, BM-DMA disabled\n",
		       hwif->name, rev);
		dma_state &= ~0x60;
	} else {
		dma_state |= 0x60;
		if (!noautodma)
			hwif->autodma = 1;
	}
	hwif->OUTB(dma_state, dma_base + 2);

	ide_setup_dma(hwif, dma_base, 8);
}

/*
 * Initialise the chip
 */

static void __init init_hwif_sl82c105(ide_hwif_t *hwif)
{
	struct pci_dev *dev = hwif->pci_dev;
	u32 val;
	
	DBG(("init_hwif_sl82c105(hwif: ide%d)\n", hwif->index));

	hwif->tuneproc = tune_sl82c105;
	hwif->selectproc = sl82c105_selectproc;
	hwif->resetproc = sl82c105_resetproc;
	
	/* Default to PIO 0 for fallback unless tuned otherwise,
	 * we always autotune PIO, this is done before DMA is
	 * checked, so there is no risk of accidentally disabling
	 * DMA
	  */
	hwif->drives[0].pio_speed = XFER_PIO_0;
	hwif->drives[0].autotune = 1;
	hwif->drives[1].pio_speed = XFER_PIO_1;
	hwif->drives[1].autotune = 1;

	pci_read_config_dword(dev, 0x40, &val);
	*((u32 *)&hwif->hwif_data) = val;
	
	if (!hwif->dma_base)
		return;

	hwif->atapi_dma = 1;
	hwif->mwdma_mask = 0x07;
	hwif->swdma_mask = 0x07;

#ifdef CONFIG_BLK_DEV_IDEDMA
	hwif->ide_dma_check = &sl82c105_check_drive;
	hwif->ide_dma_on = &sl82c105_ide_dma_on;
	hwif->ide_dma_off_quietly = &sl82c105_ide_dma_off_quietly;
	hwif->ide_dma_lostirq = &sl82c105_ide_dma_lost_irq;
	hwif->dma_start = &sl82c105_ide_dma_start;
	hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout;

	if (!noautodma)
		hwif->autodma = 1;
	hwif->drives[0].autodma = hwif->autodma;
	hwif->drives[1].autodma = hwif->autodma;
#endif /* CONFIG_BLK_DEV_IDEDMA */
}

static ide_pci_device_t sl82c105_chipset __devinitdata = {
	.name		= "W82C105",
	.init_chipset	= init_chipset_sl82c105,
	.init_hwif	= init_hwif_sl82c105,
	.init_dma	= init_dma_sl82c105,
	.channels	= 2,
	.autodma	= NOAUTODMA,
	.enablebits	= {{0x40,0x01,0x01}, {0x40,0x10,0x10}},
	.bootable	= ON_BOARD,
};

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

static struct pci_device_id sl82c105_pci_tbl[] = {
	{ PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
	{ 0, },
};
MODULE_DEVICE_TABLE(pci, sl82c105_pci_tbl);

static struct pci_driver driver = {
	.name		= "W82C105_IDE",
	.id_table	= sl82c105_pci_tbl,
	.probe		= sl82c105_init_one,
};

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

module_init(sl82c105_ide_init);

MODULE_DESCRIPTION("PCI driver module for W82C105 IDE");
MODULE_LICENSE("GPL");
