/*
 * pata_serverworks.c 	- Serverworks PATA for new ATA layer
 *			  (C) 2005 Red Hat Inc
 *
 * based upon
 *
 * serverworks.c
 *
 * Copyright (C) 1998-2000 Michel Aubry
 * Copyright (C) 1998-2000 Andrzej Krzysztofowicz
 * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
 * Portions copyright (c) 2001 Sun Microsystems
 *
 *
 * RCC/ServerWorks IDE driver for Linux
 *
 *   OSB4: `Open South Bridge' IDE Interface (fn 1)
 *         supports UDMA mode 2 (33 MB/s)
 *
 *   CSB5: `Champion South Bridge' IDE Interface (fn 1)
 *         all revisions support UDMA mode 4 (66 MB/s)
 *         revision A2.0 and up support UDMA mode 5 (100 MB/s)
 *
 *         *** The CSB5 does not provide ANY register ***
 *         *** to detect 80-conductor cable presence. ***
 *
 *   CSB6: `Champion South Bridge' IDE Interface (optional: third channel)
 *
 * Documentation:
 *	Available under NDA only. Errata info very hard to get.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>

#define DRV_NAME "pata_serverworks"
#define DRV_VERSION "0.4.3"

#define SVWKS_CSB5_REVISION_NEW	0x92 /* min PCI_REVISION_ID for UDMA5 (A2.0) */
#define SVWKS_CSB6_REVISION	0xa0 /* min PCI_REVISION_ID for UDMA4 (A1.0) */

/* Seagate Barracuda ATA IV Family drives in UDMA mode 5
 * can overrun their FIFOs when used with the CSB5 */

static const char *csb_bad_ata100[] = {
	"ST320011A",
	"ST340016A",
	"ST360021A",
	"ST380021A",
	NULL
};

/**
 *	dell_cable	-	Dell serverworks cable detection
 *	@ap: ATA port to do cable detect
 *
 *	Dell hide the 40/80 pin select for their interfaces in the top two
 *	bits of the subsystem ID.
 */

static int dell_cable(struct ata_port *ap) {
	struct pci_dev *pdev = to_pci_dev(ap->host->dev);

	if (pdev->subsystem_device & (1 << (ap->port_no + 14)))
		return ATA_CBL_PATA80;
	return ATA_CBL_PATA40;
}

/**
 *	sun_cable	-	Sun Cobalt 'Alpine' cable detection
 *	@ap: ATA port to do cable select
 *
 *	Cobalt CSB5 IDE hides the 40/80pin in the top two bits of the
 *	subsystem ID the same as dell. We could use one function but we may
 *	need to extend the Dell one in future
 */

static int sun_cable(struct ata_port *ap) {
	struct pci_dev *pdev = to_pci_dev(ap->host->dev);

	if (pdev->subsystem_device & (1 << (ap->port_no + 14)))
		return ATA_CBL_PATA80;
	return ATA_CBL_PATA40;
}

/**
 *	osb4_cable	-	OSB4 cable detect
 *	@ap: ATA port to check
 *
 *	The OSB4 isn't UDMA66 capable so this is easy
 */

static int osb4_cable(struct ata_port *ap) {
	return ATA_CBL_PATA40;
}

/**
 *	csb_cable	-	CSB5/6 cable detect
 *	@ap: ATA port to check
 *
 *	Serverworks default arrangement is to use the drive side detection
 *	only.
 */

static int csb_cable(struct ata_port *ap) {
	return ATA_CBL_PATA_UNK;
}

struct sv_cable_table {
	int device;
	int subvendor;
	int (*cable_detect)(struct ata_port *ap);
};

/*
 *	Note that we don't copy the old serverworks code because the old
 *	code contains obvious mistakes
 */

static struct sv_cable_table cable_detect[] = {
	{ PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, PCI_VENDOR_ID_DELL, dell_cable },
	{ PCI_DEVICE_ID_SERVERWORKS_CSB6IDE, PCI_VENDOR_ID_DELL, dell_cable },
	{ PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, PCI_VENDOR_ID_SUN,  sun_cable },
	{ PCI_DEVICE_ID_SERVERWORKS_OSB4IDE, PCI_ANY_ID, osb4_cable },
	{ PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, PCI_ANY_ID, csb_cable },
	{ PCI_DEVICE_ID_SERVERWORKS_CSB6IDE, PCI_ANY_ID, csb_cable },
	{ PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2, PCI_ANY_ID, csb_cable },
	{ PCI_DEVICE_ID_SERVERWORKS_HT1000IDE, PCI_ANY_ID, csb_cable },
	{ }
};

/**
 *	serverworks_cable_detect	-	cable detection
 *	@ap: ATA port
 *	@deadline: deadline jiffies for the operation
 *
 *	Perform cable detection according to the device and subvendor
 *	identifications
 */

static int serverworks_cable_detect(struct ata_port *ap)
{
	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
	struct sv_cable_table *cb = cable_detect;

	while(cb->device) {
		if (cb->device == pdev->device &&
		    (cb->subvendor == pdev->subsystem_vendor ||
		      cb->subvendor == PCI_ANY_ID)) {
			return cb->cable_detect(ap);
		}
		cb++;
	}

	BUG();
	return -1;	/* kill compiler warning */
}

/**
 *	serverworks_is_csb	-	Check for CSB or OSB
 *	@pdev: PCI device to check
 *
 *	Returns true if the device being checked is known to be a CSB
 *	series device.
 */

static u8 serverworks_is_csb(struct pci_dev *pdev)
{
	switch (pdev->device) {
		case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE:
		case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE:
		case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2:
		case PCI_DEVICE_ID_SERVERWORKS_HT1000IDE:
			return 1;
		default:
			break;
	}
	return 0;
}

/**
 *	serverworks_osb4_filter	-	mode selection filter
 *	@adev: ATA device
 *	@mask: Mask of proposed modes
 *
 *	Filter the offered modes for the device to apply controller
 *	specific rules. OSB4 requires no UDMA for disks due to a FIFO
 *	bug we hit.
 */

static unsigned long serverworks_osb4_filter(struct ata_device *adev, unsigned long mask)
{
	if (adev->class == ATA_DEV_ATA)
		mask &= ~ATA_MASK_UDMA;
	return ata_bmdma_mode_filter(adev, mask);
}


/**
 *	serverworks_csb_filter	-	mode selection filter
 *	@adev: ATA device
 *	@mask: Mask of proposed modes
 *
 *	Check the blacklist and disable UDMA5 if matched
 */

static unsigned long serverworks_csb_filter(struct ata_device *adev, unsigned long mask)
{
	const char *p;
	char model_num[ATA_ID_PROD_LEN + 1];
	int i;

	/* Disk, UDMA */
	if (adev->class != ATA_DEV_ATA)
		return ata_bmdma_mode_filter(adev, mask);

	/* Actually do need to check */
	ata_id_c_string(adev->id, model_num, ATA_ID_PROD, sizeof(model_num));

	for (i = 0; (p = csb_bad_ata100[i]) != NULL; i++) {
		if (!strcmp(p, model_num))
			mask &= ~(0xE0 << ATA_SHIFT_UDMA);
	}
	return ata_bmdma_mode_filter(adev, mask);
}

/**
 *	serverworks_set_piomode	-	set initial PIO mode data
 *	@ap: ATA interface
 *	@adev: ATA device
 *
 *	Program the OSB4/CSB5 timing registers for PIO. The PIO register
 *	load is done as a simple lookup.
 */
static void serverworks_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
	static const u8 pio_mode[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 };
	int offset = 1 + 2 * ap->port_no - adev->devno;
	int devbits = (2 * ap->port_no + adev->devno) * 4;
	u16 csb5_pio;
	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
	int pio = adev->pio_mode - XFER_PIO_0;

	pci_write_config_byte(pdev, 0x40 + offset, pio_mode[pio]);

	/* The OSB4 just requires the timing but the CSB series want the
	   mode number as well */
	if (serverworks_is_csb(pdev)) {
		pci_read_config_word(pdev, 0x4A, &csb5_pio);
		csb5_pio &= ~(0x0F << devbits);
		pci_write_config_byte(pdev, 0x4A, csb5_pio | (pio << devbits));
	}
}

/**
 *	serverworks_set_dmamode	-	set initial DMA mode data
 *	@ap: ATA interface
 *	@adev: ATA device
 *
 *	Program the MWDMA/UDMA modes for the serverworks OSB4/CSB5
 *	chipset. The MWDMA mode values are pulled from a lookup table
 *	while the chipset uses mode number for UDMA.
 */

static void serverworks_set_dmamode(struct ata_port *ap, struct ata_device *adev)
{
	static const u8 dma_mode[] = { 0x77, 0x21, 0x20 };
	int offset = 1 + 2 * ap->port_no - adev->devno;
	int devbits = 2 * ap->port_no + adev->devno;
	u8 ultra;
	u8 ultra_cfg;
	struct pci_dev *pdev = to_pci_dev(ap->host->dev);

	pci_read_config_byte(pdev, 0x54, &ultra_cfg);
	pci_read_config_byte(pdev, 0x56 + ap->port_no, &ultra);
	ultra &= ~(0x0F << (adev->devno * 4));

	if (adev->dma_mode >= XFER_UDMA_0) {
		pci_write_config_byte(pdev, 0x44 + offset,  0x20);

		ultra |= (adev->dma_mode - XFER_UDMA_0)
					<< (adev->devno * 4);
		ultra_cfg |=  (1 << devbits);
	} else {
		pci_write_config_byte(pdev, 0x44 + offset,
			dma_mode[adev->dma_mode - XFER_MW_DMA_0]);
		ultra_cfg &= ~(1 << devbits);
	}
	pci_write_config_byte(pdev, 0x56 + ap->port_no, ultra);
	pci_write_config_byte(pdev, 0x54, ultra_cfg);
}

static struct scsi_host_template serverworks_sht = {
	ATA_BMDMA_SHT(DRV_NAME),
};

static struct ata_port_operations serverworks_osb4_port_ops = {
	.inherits	= &ata_bmdma_port_ops,
	.cable_detect	= serverworks_cable_detect,
	.mode_filter	= serverworks_osb4_filter,
	.set_piomode	= serverworks_set_piomode,
	.set_dmamode	= serverworks_set_dmamode,
};

static struct ata_port_operations serverworks_csb_port_ops = {
	.inherits	= &serverworks_osb4_port_ops,
	.mode_filter	= serverworks_csb_filter,
};

static int serverworks_fixup_osb4(struct pci_dev *pdev)
{
	u32 reg;
	struct pci_dev *isa_dev = pci_get_device(PCI_VENDOR_ID_SERVERWORKS,
		  PCI_DEVICE_ID_SERVERWORKS_OSB4, NULL);
	if (isa_dev) {
		pci_read_config_dword(isa_dev, 0x64, &reg);
		reg &= ~0x00002000; /* disable 600ns interrupt mask */
		if (!(reg & 0x00004000))
			printk(KERN_DEBUG DRV_NAME ": UDMA not BIOS enabled.\n");
		reg |=  0x00004000; /* enable UDMA/33 support */
		pci_write_config_dword(isa_dev, 0x64, reg);
		pci_dev_put(isa_dev);
		return 0;
	}
	printk(KERN_WARNING "ata_serverworks: Unable to find bridge.\n");
	return -ENODEV;
}

static int serverworks_fixup_csb(struct pci_dev *pdev)
{
	u8 btr;

	/* Third Channel Test */
	if (!(PCI_FUNC(pdev->devfn) & 1)) {
		struct pci_dev * findev = NULL;
		u32 reg4c = 0;
		findev = pci_get_device(PCI_VENDOR_ID_SERVERWORKS,
			PCI_DEVICE_ID_SERVERWORKS_CSB5, NULL);
		if (findev) {
			pci_read_config_dword(findev, 0x4C, &reg4c);
			reg4c &= ~0x000007FF;
			reg4c |=  0x00000040;
			reg4c |=  0x00000020;
			pci_write_config_dword(findev, 0x4C, reg4c);
			pci_dev_put(findev);
		}
	} else {
		struct pci_dev * findev = NULL;
		u8 reg41 = 0;

		findev = pci_get_device(PCI_VENDOR_ID_SERVERWORKS,
				PCI_DEVICE_ID_SERVERWORKS_CSB6, NULL);
		if (findev) {
			pci_read_config_byte(findev, 0x41, &reg41);
			reg41 &= ~0x40;
			pci_write_config_byte(findev, 0x41, reg41);
			pci_dev_put(findev);
		}
	}
	/* setup the UDMA Control register
	 *
	 * 1. clear bit 6 to enable DMA
	 * 2. enable DMA modes with bits 0-1
	 * 	00 : legacy
	 * 	01 : udma2
	 * 	10 : udma2/udma4
	 * 	11 : udma2/udma4/udma5
	 */
	pci_read_config_byte(pdev, 0x5A, &btr);
	btr &= ~0x40;
	if (!(PCI_FUNC(pdev->devfn) & 1))
		btr |= 0x2;
	else
		btr |= (pdev->revision >= SVWKS_CSB5_REVISION_NEW) ? 0x3 : 0x2;
	pci_write_config_byte(pdev, 0x5A, btr);

	return btr;
}

static void serverworks_fixup_ht1000(struct pci_dev *pdev)
{
	u8 btr;
	/* Setup HT1000 SouthBridge Controller - Single Channel Only */
	pci_read_config_byte(pdev, 0x5A, &btr);
	btr &= ~0x40;
	btr |= 0x3;
	pci_write_config_byte(pdev, 0x5A, btr);
}


static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
	static const struct ata_port_info info[4] = {
		{ /* OSB4 */
			.flags = ATA_FLAG_SLAVE_POSS,
			.pio_mask = 0x1f,
			.mwdma_mask = 0x07,
			.udma_mask = 0x07,
			.port_ops = &serverworks_osb4_port_ops
		}, { /* OSB4 no UDMA */
			.flags = ATA_FLAG_SLAVE_POSS,
			.pio_mask = 0x1f,
			.mwdma_mask = 0x07,
			.udma_mask = 0x00,
			.port_ops = &serverworks_osb4_port_ops
		}, { /* CSB5 */
			.flags = ATA_FLAG_SLAVE_POSS,
			.pio_mask = 0x1f,
			.mwdma_mask = 0x07,
			.udma_mask = ATA_UDMA4,
			.port_ops = &serverworks_csb_port_ops
		}, { /* CSB5 - later revisions*/
			.flags = ATA_FLAG_SLAVE_POSS,
			.pio_mask = 0x1f,
			.mwdma_mask = 0x07,
			.udma_mask = ATA_UDMA5,
			.port_ops = &serverworks_csb_port_ops
		}
	};
	const struct ata_port_info *ppi[] = { &info[id->driver_data], NULL };
	int rc;

	rc = pcim_enable_device(pdev);
	if (rc)
		return rc;

	/* Force master latency timer to 64 PCI clocks */
	pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x40);

	/* OSB4 : South Bridge and IDE */
	if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) {
		/* Select non UDMA capable OSB4 if we can't do fixups */
		if ( serverworks_fixup_osb4(pdev) < 0)
			ppi[0] = &info[1];
	}
	/* setup CSB5/CSB6 : South Bridge and IDE option RAID */
	else if ((pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE) ||
		 (pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) ||
		 (pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) {

		 /* If the returned btr is the newer revision then
		    select the right info block */
		 if (serverworks_fixup_csb(pdev) == 3)
		 	ppi[0] = &info[3];

		/* Is this the 3rd channel CSB6 IDE ? */
		if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)
			ppi[1] = &ata_dummy_port_info;
	}
	/* setup HT1000E */
	else if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_HT1000IDE)
		serverworks_fixup_ht1000(pdev);

	if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE)
		ata_pci_bmdma_clear_simplex(pdev);

	return ata_pci_sff_init_one(pdev, ppi, &serverworks_sht, NULL);
}

#ifdef CONFIG_PM
static int serverworks_reinit_one(struct pci_dev *pdev)
{
	struct ata_host *host = dev_get_drvdata(&pdev->dev);
	int rc;

	rc = ata_pci_device_do_resume(pdev);
	if (rc)
		return rc;

	/* Force master latency timer to 64 PCI clocks */
	pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x40);

	switch (pdev->device) {
		case PCI_DEVICE_ID_SERVERWORKS_OSB4IDE:
			serverworks_fixup_osb4(pdev);
			break;
		case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE:
			ata_pci_bmdma_clear_simplex(pdev);
			/* fall through */
		case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE:
		case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2:
			serverworks_fixup_csb(pdev);
			break;
		case PCI_DEVICE_ID_SERVERWORKS_HT1000IDE:
			serverworks_fixup_ht1000(pdev);
			break;
	}

	ata_host_resume(host);
	return 0;
}
#endif

static const struct pci_device_id serverworks[] = {
	{ PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE), 0},
	{ PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE), 2},
	{ PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE), 2},
	{ PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2), 2},
	{ PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000IDE), 2},

	{ },
};

static struct pci_driver serverworks_pci_driver = {
	.name 		= DRV_NAME,
	.id_table	= serverworks,
	.probe 		= serverworks_init_one,
	.remove		= ata_pci_remove_one,
#ifdef CONFIG_PM
	.suspend	= ata_pci_device_suspend,
	.resume		= serverworks_reinit_one,
#endif
};

static int __init serverworks_init(void)
{
	return pci_register_driver(&serverworks_pci_driver);
}

static void __exit serverworks_exit(void)
{
	pci_unregister_driver(&serverworks_pci_driver);
}

MODULE_AUTHOR("Alan Cox");
MODULE_DESCRIPTION("low-level driver for Serverworks OSB4/CSB5/CSB6");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, serverworks);
MODULE_VERSION(DRV_VERSION);

module_init(serverworks_init);
module_exit(serverworks_exit);
