/*
 * pata_optidma.c 	- Opti DMA PATA for new ATA layer
 *			  (C) 2006 Red Hat Inc
 *			  Alan Cox <alan@redhat.com>
 *
 *	The Opti DMA controllers are related to the older PIO PCI controllers
 *	and indeed the VLB ones. The main differences are that the timing
 *	numbers are now based off PCI clocks not VLB and differ, and that
 *	MWDMA is supported.
 *
 *	This driver should support Viper-N+, FireStar, FireStar Plus.
 *
 *	These devices support virtual DMA for read (aka the CS5520). Later
 *	chips support UDMA33, but only if the rest of the board logic does,
 *	so you have to get this right. We don't support the virtual DMA
 *	but we do handle UDMA.
 *
 *	Bits that are worth knowing
 *		Most control registers are shadowed into I/O registers
 *		0x1F5 bit 0 tells you if the PCI/VLB clock is 33 or 25Mhz
 *		Virtual DMA registers *move* between rev 0x02 and rev 0x10
 *		UDMA requires a 66MHz FSB
 *
 */

#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_optidma"
#define DRV_VERSION "0.2.1"

enum {
	READ_REG	= 0,	/* index of Read cycle timing register */
	WRITE_REG 	= 1,	/* index of Write cycle timing register */
	CNTRL_REG 	= 3,	/* index of Control register */
	STRAP_REG 	= 5,	/* index of Strap register */
	MISC_REG 	= 6	/* index of Miscellaneous register */
};

static int pci_clock;	/* 0 = 33 1 = 25 */

/**
 *	optidma_pre_reset		-	probe begin
 *	@ap: ATA port
 *
 *	Set up cable type and use generic probe init
 */
 
static int optidma_pre_reset(struct ata_port *ap)
{
	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
	static const struct pci_bits optidma_enable_bits = { 
		0x40, 1, 0x08, 0x00
	};

	if (ap->port_no && !pci_test_config_bits(pdev, &optidma_enable_bits)) {
		ata_port_disable(ap);
		printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id);
		return 0;
	}
	ap->cbl = ATA_CBL_PATA40;
	return ata_std_prereset(ap);
}

/**
 *	optidma_probe_reset		-	probe reset
 *	@ap: ATA port
 *
 *	Perform the ATA probe and bus reset sequence plus specific handling
 *	for this hardware. The Opti needs little handling - we have no UDMA66
 *	capability that needs cable detection. All we must do is check the port
 *	is enabled.
 */

static void optidma_error_handler(struct ata_port *ap)
{
	ata_bmdma_drive_eh(ap, optidma_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
}

/**
 *	optidma_unlock		-	unlock control registers
 *	@ap: ATA port
 *
 *	Unlock the control register block for this adapter. Registers must not
 *	be unlocked in a situation where libata might look at them.
 */
 
static void optidma_unlock(struct ata_port *ap)
{
	unsigned long regio = ap->ioaddr.cmd_addr;
	
	/* These 3 unlock the control register access */
	inw(regio + 1);
	inw(regio + 1);
	outb(3, regio + 2);
}

/**
 *	optidma_lock		-	issue temporary relock
 *	@ap: ATA port
 *
 *	Re-lock the configuration register settings.
 */
 
static void optidma_lock(struct ata_port *ap)
{
	unsigned long regio = ap->ioaddr.cmd_addr;
	
	/* Relock */
	outb(0x83, regio + 2);
}

/**
 *	optidma_set_mode	-	set mode data
 *	@ap: ATA interface
 *	@adev: ATA device
 *	@mode: Mode to set
 *
 *	Called to do the DMA or PIO mode setup. Timing numbers are all
 *	pre computed to keep the code clean. There are two tables depending
 *	on the hardware clock speed.
 *
 *	WARNING: While we do this the IDE registers vanish. If we take an
 *	IRQ here we depend on the host set locking to avoid catastrophe.
 */

static void optidma_set_mode(struct ata_port *ap, struct ata_device *adev, u8 mode)
{
	struct ata_device *pair = ata_dev_pair(adev);
	int pio = adev->pio_mode - XFER_PIO_0;
	int dma = adev->dma_mode - XFER_MW_DMA_0;
	unsigned long regio = ap->ioaddr.cmd_addr;
	u8 addr;

	/* Address table precomputed with a DCLK of 2 */
	static const u8 addr_timing[2][5] = {
		{ 0x30, 0x20, 0x20, 0x10, 0x10 },
		{ 0x20, 0x20, 0x10, 0x10, 0x10 }
	};
	static const u8 data_rec_timing[2][5] = {
		{ 0x59, 0x46, 0x30, 0x20, 0x20 },
		{ 0x46, 0x32, 0x20, 0x20, 0x10 }
	};
	static const u8 dma_data_rec_timing[2][3] = {
		{ 0x76, 0x20, 0x20 },
		{ 0x54, 0x20, 0x10 }
	};

	/* Switch from IDE to control mode */
	optidma_unlock(ap);
	

	/*
 	 *	As with many controllers the address setup time is shared
 	 *	and must suit both devices if present. FIXME: Check if we
 	 *	need to look at slowest of PIO/DMA mode of either device
	 */

	if (mode >= XFER_MW_DMA_0)
		addr = 0;
	else
		addr = addr_timing[pci_clock][pio];
	
	if (pair) {
		u8 pair_addr;
		/* Hardware constraint */
		if (pair->dma_mode)
			pair_addr = 0;
		else
			pair_addr = addr_timing[pci_clock][pair->pio_mode - XFER_PIO_0];
		if (pair_addr > addr)
			addr = pair_addr;
	}
	
	/* Commence primary programming sequence */
	/* First we load the device number into the timing select */
	outb(adev->devno, regio + MISC_REG);
	/* Now we load the data timings into read data/write data */
	if (mode < XFER_MW_DMA_0) {
		outb(data_rec_timing[pci_clock][pio], regio + READ_REG);
		outb(data_rec_timing[pci_clock][pio], regio + WRITE_REG);
	} else if (mode < XFER_UDMA_0) {
		outb(dma_data_rec_timing[pci_clock][dma], regio + READ_REG);
		outb(dma_data_rec_timing[pci_clock][dma], regio + WRITE_REG);
	}
	/* Finally we load the address setup into the misc register */
	outb(addr | adev->devno, regio + MISC_REG);

	/* Programming sequence complete, timing 0 dev 0, timing 1 dev 1 */
	outb(0x85, regio + CNTRL_REG);
	
	/* Switch back to IDE mode */
	optidma_lock(ap);
	
	/* Note: at this point our programming is incomplete. We are
	   not supposed to program PCI 0x43 "things we hacked onto the chip"
	   until we've done both sets of PIO/DMA timings */
}

/**
 *	optiplus_set_mode	-	DMA setup for Firestar Plus
 *	@ap: ATA port
 *	@adev: device
 *	@mode: desired mode
 *
 *	The Firestar plus has additional UDMA functionality for UDMA0-2 and
 *	requires we do some additional work. Because the base work we must do
 *	is mostly shared we wrap the Firestar setup functionality in this
 *	one
 */

static void optiplus_set_mode(struct ata_port *ap, struct ata_device *adev, u8 mode)
{
	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
	u8 udcfg;
	u8 udslave;
	int dev2 = 2 * adev->devno;
	int unit = 2 * ap->port_no + adev->devno;
	int udma = mode - XFER_UDMA_0;
	
	pci_read_config_byte(pdev, 0x44, &udcfg);
	if (mode <= XFER_UDMA_0) {
		udcfg &= ~(1 << unit);
		optidma_set_mode(ap, adev, adev->dma_mode);
	} else {
		udcfg |=  (1 << unit);
		if (ap->port_no) {
			pci_read_config_byte(pdev, 0x45, &udslave);
			udslave &= ~(0x03 << dev2);
			udslave |= (udma << dev2);
			pci_write_config_byte(pdev, 0x45, udslave);
		} else {
			udcfg &= ~(0x30 << dev2);
			udcfg |= (udma << dev2);
		}
	}
	pci_write_config_byte(pdev, 0x44, udcfg);
}

/**
 *	optidma_set_pio_mode	-	PIO setup callback
 *	@ap: ATA port
 *	@adev: Device
 *
 *	The libata core provides separate functions for handling PIO and
 *	DMA programming. The architecture of the Firestar makes it easier
 *	for us to have a common function so we provide wrappers
 */
 
static void optidma_set_pio_mode(struct ata_port *ap, struct ata_device *adev)
{
	optidma_set_mode(ap, adev, adev->pio_mode);
}

/**
 *	optidma_set_dma_mode	-	DMA setup callback
 *	@ap: ATA port
 *	@adev: Device
 *
 *	The libata core provides separate functions for handling PIO and
 *	DMA programming. The architecture of the Firestar makes it easier
 *	for us to have a common function so we provide wrappers
 */
 
static void optidma_set_dma_mode(struct ata_port *ap, struct ata_device *adev)
{
	optidma_set_mode(ap, adev, adev->dma_mode);
}

/**
 *	optiplus_set_pio_mode	-	PIO setup callback
 *	@ap: ATA port
 *	@adev: Device
 *
 *	The libata core provides separate functions for handling PIO and
 *	DMA programming. The architecture of the Firestar makes it easier
 *	for us to have a common function so we provide wrappers
 */
 
static void optiplus_set_pio_mode(struct ata_port *ap, struct ata_device *adev)
{
	optiplus_set_mode(ap, adev, adev->pio_mode);
}

/**
 *	optiplus_set_dma_mode	-	DMA setup callback
 *	@ap: ATA port
 *	@adev: Device
 *
 *	The libata core provides separate functions for handling PIO and
 *	DMA programming. The architecture of the Firestar makes it easier
 *	for us to have a common function so we provide wrappers
 */
 
static void optiplus_set_dma_mode(struct ata_port *ap, struct ata_device *adev)
{
	optiplus_set_mode(ap, adev, adev->dma_mode);
}

/**
 *	optidma_make_bits	-	PCI setup helper
 *	@adev: ATA device
 *
 *	Turn the ATA device setup into PCI configuration bits
 *	for register 0x43 and return the two bits needed.
 */
 
static u8 optidma_make_bits43(struct ata_device *adev)
{
	static const u8 bits43[5] = {
		0, 0, 0, 1, 2
	};
	if (!ata_dev_enabled(adev))
		return 0;
	if (adev->dma_mode)
		return adev->dma_mode - XFER_MW_DMA_0;
	return bits43[adev->pio_mode - XFER_PIO_0];
}

/**
 *	optidma_post_set_mode	-	finalize PCI setup
 *	@ap: port to set up
 *
 *	Finalise the configuration by writing the nibble of extra bits
 *	of data into the chip.
 */
 
static void optidma_post_set_mode(struct ata_port *ap)
{
	u8 r;
	int nybble = 4 * ap->port_no;
	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
	
	pci_read_config_byte(pdev, 0x43, &r);
	
	r &= (0x0F << nybble);
	r |= (optidma_make_bits43(&ap->device[0]) + 
	     (optidma_make_bits43(&ap->device[0]) << 2)) << nybble;

	pci_write_config_byte(pdev, 0x43, r);
}

static struct scsi_host_template optidma_sht = {
	.module			= THIS_MODULE,
	.name			= DRV_NAME,
	.ioctl			= ata_scsi_ioctl,
	.queuecommand		= ata_scsi_queuecmd,
	.can_queue		= ATA_DEF_QUEUE,
	.this_id		= ATA_SHT_THIS_ID,
	.sg_tablesize		= LIBATA_MAX_PRD,
	.max_sectors		= ATA_MAX_SECTORS,
	.cmd_per_lun		= ATA_SHT_CMD_PER_LUN,
	.emulated		= ATA_SHT_EMULATED,
	.use_clustering		= ATA_SHT_USE_CLUSTERING,
	.proc_name		= DRV_NAME,
	.dma_boundary		= ATA_DMA_BOUNDARY,
	.slave_configure	= ata_scsi_slave_config,
	.bios_param		= ata_std_bios_param,
};

static struct ata_port_operations optidma_port_ops = {
	.port_disable	= ata_port_disable,
	.set_piomode	= optidma_set_pio_mode,
	.set_dmamode	= optidma_set_dma_mode,

	.tf_load	= ata_tf_load,
	.tf_read	= ata_tf_read,
	.check_status 	= ata_check_status,
	.exec_command	= ata_exec_command,
	.dev_select 	= ata_std_dev_select,

	.freeze		= ata_bmdma_freeze,
	.thaw		= ata_bmdma_thaw,
	.post_internal_cmd = ata_bmdma_post_internal_cmd,
	.error_handler	= optidma_error_handler,
	.post_set_mode	= optidma_post_set_mode,

	.bmdma_setup 	= ata_bmdma_setup,
	.bmdma_start 	= ata_bmdma_start,
	.bmdma_stop	= ata_bmdma_stop,
	.bmdma_status 	= ata_bmdma_status,

	.qc_prep 	= ata_qc_prep,
	.qc_issue	= ata_qc_issue_prot,
	.eng_timeout	= ata_eng_timeout,
	.data_xfer	= ata_pio_data_xfer,

	.irq_handler	= ata_interrupt,
	.irq_clear	= ata_bmdma_irq_clear,

	.port_start	= ata_port_start,
	.port_stop	= ata_port_stop,
	.host_stop	= ata_host_stop
};

static struct ata_port_operations optiplus_port_ops = {
	.port_disable	= ata_port_disable,
	.set_piomode	= optiplus_set_pio_mode,
	.set_dmamode	= optiplus_set_dma_mode,

	.tf_load	= ata_tf_load,
	.tf_read	= ata_tf_read,
	.check_status 	= ata_check_status,
	.exec_command	= ata_exec_command,
	.dev_select 	= ata_std_dev_select,

	.freeze		= ata_bmdma_freeze,
	.thaw		= ata_bmdma_thaw,
	.post_internal_cmd = ata_bmdma_post_internal_cmd,
	.error_handler	= optidma_error_handler,
	.post_set_mode	= optidma_post_set_mode,

	.bmdma_setup 	= ata_bmdma_setup,
	.bmdma_start 	= ata_bmdma_start,
	.bmdma_stop	= ata_bmdma_stop,
	.bmdma_status 	= ata_bmdma_status,

	.qc_prep 	= ata_qc_prep,
	.qc_issue	= ata_qc_issue_prot,
	.eng_timeout	= ata_eng_timeout,
	.data_xfer	= ata_pio_data_xfer,

	.irq_handler	= ata_interrupt,
	.irq_clear	= ata_bmdma_irq_clear,

	.port_start	= ata_port_start,
	.port_stop	= ata_port_stop,
	.host_stop	= ata_host_stop
};

/**
 *	optiplus_with_udma	-	Look for UDMA capable setup
 *	@pdev; ATA controller
 */
 
static int optiplus_with_udma(struct pci_dev *pdev)
{
	u8 r;
	int ret = 0;
	int ioport = 0x22;
	struct pci_dev *dev1;
	
	/* Find function 1 */
	dev1 = pci_get_device(0x1045, 0xC701, NULL);
	if(dev1 == NULL)
		return 0;
	
	/* Rev must be >= 0x10 */
	pci_read_config_byte(dev1, 0x08, &r);
	if (r < 0x10)
		goto done_nomsg;
	/* Read the chipset system configuration to check our mode */
	pci_read_config_byte(dev1, 0x5F, &r);
	ioport |= (r << 8);
	outb(0x10, ioport);
	/* Must be 66Mhz sync */
	if ((inb(ioport + 2) & 1) == 0)
		goto done;

	/* Check the ATA arbitration/timing is suitable */
	pci_read_config_byte(pdev, 0x42, &r);
	if ((r & 0x36) != 0x36)
		goto done;
	pci_read_config_byte(dev1, 0x52, &r);
	if (r & 0x80)	/* IDEDIR disabled */
		ret = 1;
done:		
	printk(KERN_WARNING "UDMA not supported in this configuration.\n");
done_nomsg:		/* Wrong chip revision */
	pci_dev_put(dev1);
	return ret;
}

static int optidma_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
	static struct ata_port_info info_82c700 = {
		.sht = &optidma_sht,
		.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
		.pio_mask = 0x1f,
		.mwdma_mask = 0x07,
		.port_ops = &optidma_port_ops
	};
	static struct ata_port_info info_82c700_udma = {
		.sht = &optidma_sht,
		.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
		.pio_mask = 0x1f,
		.mwdma_mask = 0x07,
		.udma_mask = 0x07,
		.port_ops = &optiplus_port_ops
	};
	static struct ata_port_info *port_info[2];
	struct ata_port_info *info = &info_82c700;
	static int printed_version;

	if (!printed_version++)
		dev_printk(KERN_DEBUG, &dev->dev, "version " DRV_VERSION "\n");

	/* Fixed location chipset magic */
	inw(0x1F1);
	inw(0x1F1);
	pci_clock = inb(0x1F5) & 1;		/* 0 = 33Mhz, 1 = 25Mhz */
	
	if (optiplus_with_udma(dev))
		info = &info_82c700_udma;

	port_info[0] = port_info[1] = info;
	return ata_pci_init_one(dev, port_info, 2);
}

static const struct pci_device_id optidma[] = {
	{ PCI_DEVICE(0x1045, 0xD568), },	/* Opti 82C700 */
	{ 0, },
};

static struct pci_driver optidma_pci_driver = {
        .name 		= DRV_NAME,
	.id_table	= optidma,
	.probe 		= optidma_init_one,
	.remove		= ata_pci_remove_one
};

static int __init optidma_init(void)
{
	return pci_register_driver(&optidma_pci_driver);
}


static void __exit optidma_exit(void)
{
	pci_unregister_driver(&optidma_pci_driver);
}


MODULE_AUTHOR("Alan Cox");
MODULE_DESCRIPTION("low-level driver for Opti Firestar/Firestar Plus");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, optidma);
MODULE_VERSION(DRV_VERSION);

module_init(optidma_init);
module_exit(optidma_exit);
