/*
 * pata_serverworks.c 	- Serverworks PATA for new ATA layer
 *			  (C) 2005 Red Hat Inc
 *			  (C) 2010 Bartlomiej Zolnierkiewicz
 *
 * 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
 *
 *	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 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 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 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_word(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 DRV_NAME ": 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 = ATA_PIO4,
			.mwdma_mask = ATA_MWDMA2,
			.udma_mask = ATA_UDMA2,
			.port_ops = &serverworks_osb4_port_ops
		}, { /* OSB4 no UDMA */
			.flags = ATA_FLAG_SLAVE_POSS,
			.pio_mask = ATA_PIO4,
			.mwdma_mask = ATA_MWDMA2,
			/* No UDMA */
			.port_ops = &serverworks_osb4_port_ops
		}, { /* CSB5 */
			.flags = ATA_FLAG_SLAVE_POSS,
			.pio_mask = ATA_PIO4,
			.mwdma_mask = ATA_MWDMA2,
			.udma_mask = ATA_UDMA4,
			.port_ops = &serverworks_csb_port_ops
		}, { /* CSB5 - later revisions*/
			.flags = ATA_FLAG_SLAVE_POSS,
			.pio_mask = ATA_PIO4,
			.mwdma_mask = ATA_MWDMA2,
			.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_bmdma_init_one(pdev, ppi, &serverworks_sht, NULL, 0);
}

#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);
