/*
 *  Copyright (C) 1996-2001  Linus Torvalds & author (see below)
 */

/*
 *  Version 0.03	Cleaned auto-tune, added probe
 *  Version 0.04	Added second channel tuning
 *  Version 0.05	Enhanced tuning ; added qd6500 support
 *  Version 0.06	Added dos driver's list
 *  Version 0.07	Second channel bug fix 
 *
 * QDI QD6500/QD6580 EIDE controller fast support
 *
 * To activate controller support, use "ide0=qd65xx"
 */

/*
 * Rewritten from the work of Colten Edwards <pje120@cs.usask.ca> by
 * Samuel Thibault <samuel.thibault@fnac.net>
 */

#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/ide.h>
#include <linux/init.h>
#include <asm/system.h>
#include <asm/io.h>

#define DRV_NAME "qd65xx"

#include "qd65xx.h"

/*
 * I/O ports are 0x30-0x31 (and 0x32-0x33 for qd6580)
 *            or 0xb0-0xb1 (and 0xb2-0xb3 for qd6580)
 *	-- qd6500 is a single IDE interface
 *	-- qd6580 is a dual IDE interface
 *
 * More research on qd6580 being done by willmore@cig.mot.com (David)
 * More Information given by Petr Soucek (petr@ryston.cz)
 * http://www.ryston.cz/petr/vlb
 */

/*
 * base: Timer1
 *
 *
 * base+0x01: Config (R/O)
 *
 * bit 0: ide baseport: 1 = 0x1f0 ; 0 = 0x170 (only useful for qd6500)
 * bit 1: qd65xx baseport: 1 = 0xb0 ; 0 = 0x30
 * bit 2: ID3: bus speed: 1 = <=33MHz ; 0 = >33MHz
 * bit 3: qd6500: 1 = disabled, 0 = enabled
 *        qd6580: 1
 * upper nibble:
 *        qd6500: 1100
 *        qd6580: either 1010 or 0101
 *
 *
 * base+0x02: Timer2 (qd6580 only)
 *
 *
 * base+0x03: Control (qd6580 only)
 *
 * bits 0-3 must always be set 1
 * bit 4 must be set 1, but is set 0 by dos driver while measuring vlb clock
 * bit 0 : 1 = Only primary port enabled : channel 0 for hda, channel 1 for hdb
 *         0 = Primary and Secondary ports enabled : channel 0 for hda & hdb
 *                                                   channel 1 for hdc & hdd
 * bit 1 : 1 = only disks on primary port
 *         0 = disks & ATAPI devices on primary port
 * bit 2-4 : always 0
 * bit 5 : status, but of what ?
 * bit 6 : always set 1 by dos driver
 * bit 7 : set 1 for non-ATAPI devices on primary port
 *	(maybe read-ahead and post-write buffer ?)
 */

static int timings[4]={-1,-1,-1,-1}; /* stores current timing for each timer */

/*
 * qd65xx_select:
 *
 * This routine is invoked to prepare for access to a given drive.
 */

static void qd65xx_select(ide_drive_t *drive)
{
	u8 index = ((	(QD_TIMREG(drive)) & 0x80 ) >> 7) |
			(QD_TIMREG(drive) & 0x02);

	if (timings[index] != QD_TIMING(drive))
		outb(timings[index] = QD_TIMING(drive), QD_TIMREG(drive));
}

/*
 * qd6500_compute_timing
 *
 * computes the timing value where
 *	lower nibble represents active time,   in count of VLB clocks
 *	upper nibble represents recovery time, in count of VLB clocks
 */

static u8 qd6500_compute_timing (ide_hwif_t *hwif, int active_time, int recovery_time)
{
	int clk = ide_vlb_clk ? ide_vlb_clk : system_bus_clock();
	u8 act_cyc, rec_cyc;

	if (clk <= 33) {
		act_cyc =  9 - IDE_IN(active_time   * clk / 1000 + 1, 2,  9);
		rec_cyc = 15 - IDE_IN(recovery_time * clk / 1000 + 1, 0, 15);
	} else {
		act_cyc =  8 - IDE_IN(active_time   * clk / 1000 + 1, 1,  8);
		rec_cyc = 18 - IDE_IN(recovery_time * clk / 1000 + 1, 3, 18);
	}

	return (rec_cyc << 4) | 0x08 | act_cyc;
}

/*
 * qd6580_compute_timing
 *
 * idem for qd6580
 */

static u8 qd6580_compute_timing (int active_time, int recovery_time)
{
	int clk = ide_vlb_clk ? ide_vlb_clk : system_bus_clock();
	u8 act_cyc, rec_cyc;

	act_cyc = 17 - IDE_IN(active_time   * clk / 1000 + 1, 2, 17);
	rec_cyc = 15 - IDE_IN(recovery_time * clk / 1000 + 1, 2, 15);

	return (rec_cyc << 4) | act_cyc;
}

/*
 * qd_find_disk_type
 *
 * tries to find timing from dos driver's table
 */

static int qd_find_disk_type (ide_drive_t *drive,
		int *active_time, int *recovery_time)
{
	struct qd65xx_timing_s *p;
	char model[40];

	if (!*drive->id->model) return 0;

	strncpy(model,drive->id->model,40);
	ide_fixstring(model,40,1); /* byte-swap */

	for (p = qd65xx_timing ; p->offset != -1 ; p++) {
		if (!strncmp(p->model, model+p->offset, 4)) {
			printk(KERN_DEBUG "%s: listed !\n", drive->name);
			*active_time = p->active;
			*recovery_time = p->recovery;
			return 1;
		}
	}
	return 0;
}

/*
 * qd_set_timing:
 *
 * records the timing
 */

static void qd_set_timing (ide_drive_t *drive, u8 timing)
{
	drive->drive_data &= 0xff00;
	drive->drive_data |= timing;

	printk(KERN_DEBUG "%s: %#x\n", drive->name, timing);
}

static void qd6500_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
	int active_time   = 175;
	int recovery_time = 415; /* worst case values from the dos driver */

	/*
	 * FIXME: use "pio" value
	 */
	if (drive->id && !qd_find_disk_type(drive, &active_time, &recovery_time)
		&& drive->id->tPIO && (drive->id->field_valid & 0x02)
		&& drive->id->eide_pio >= 240) {

		printk(KERN_INFO "%s: PIO mode%d\n", drive->name,
				drive->id->tPIO);
		active_time = 110;
		recovery_time = drive->id->eide_pio - 120;
	}

	qd_set_timing(drive, qd6500_compute_timing(HWIF(drive), active_time, recovery_time));
}

static void qd6580_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
	ide_hwif_t *hwif = drive->hwif;
	unsigned int cycle_time;
	int active_time   = 175;
	int recovery_time = 415; /* worst case values from the dos driver */
	u8 base = (hwif->config_data & 0xff00) >> 8;

	if (drive->id && !qd_find_disk_type(drive, &active_time, &recovery_time)) {
		cycle_time = ide_pio_cycle_time(drive, pio);

		switch (pio) {
			case 0: break;
			case 3:
				if (cycle_time >= 110) {
					active_time = 86;
					recovery_time = cycle_time - 102;
				} else
					printk(KERN_WARNING "%s: Strange recovery time !\n",drive->name);
				break;
			case 4:
				if (cycle_time >= 69) {
					active_time = 70;
					recovery_time = cycle_time - 61;
				} else
					printk(KERN_WARNING "%s: Strange recovery time !\n",drive->name);
				break;
			default:
				if (cycle_time >= 180) {
					active_time = 110;
					recovery_time = cycle_time - 120;
				} else {
					active_time = ide_pio_timings[pio].active_time;
					recovery_time = cycle_time - active_time;
				}
		}
		printk(KERN_INFO "%s: PIO mode%d\n", drive->name,pio);
	}

	if (!HWIF(drive)->channel && drive->media != ide_disk) {
		outb(0x5f, QD_CONTROL_PORT);
		printk(KERN_WARNING "%s: ATAPI: disabled read-ahead FIFO "
			"and post-write buffer on %s.\n",
			drive->name, HWIF(drive)->name);
	}

	qd_set_timing(drive, qd6580_compute_timing(active_time, recovery_time));
}

/*
 * qd_testreg
 *
 * tests if the given port is a register
 */

static int __init qd_testreg(int port)
{
	unsigned long flags;
	u8 savereg, readreg;

	local_irq_save(flags);
	savereg = inb_p(port);
	outb_p(QD_TESTVAL, port);	/* safe value */
	readreg = inb_p(port);
	outb(savereg, port);
	local_irq_restore(flags);

	if (savereg == QD_TESTVAL) {
		printk(KERN_ERR "Outch ! the probe for qd65xx isn't reliable !\n");
		printk(KERN_ERR "Please contact maintainers to tell about your hardware\n");
		printk(KERN_ERR "Assuming qd65xx is not present.\n");
		return 1;
	}

	return (readreg != QD_TESTVAL);
}

static void __init qd6500_port_init_devs(ide_hwif_t *hwif)
{
	u8 base = (hwif->config_data & 0xff00) >> 8;
	u8 config = QD_CONFIG(hwif);

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

static void __init qd6580_port_init_devs(ide_hwif_t *hwif)
{
	u16 t1, t2;
	u8 base = (hwif->config_data & 0xff00) >> 8;
	u8 config = QD_CONFIG(hwif);

	if (hwif->host_flags & IDE_HFLAG_SINGLE) {
		t1 = QD6580_DEF_DATA;
		t2 = QD6580_DEF_DATA2;
	} else
		t2 = t1 = hwif->channel ? QD6580_DEF_DATA2 : QD6580_DEF_DATA;

	hwif->drives[0].drive_data = t1;
	hwif->drives[1].drive_data = t2;
}

static const struct ide_port_ops qd6500_port_ops = {
	.port_init_devs		= qd6500_port_init_devs,
	.set_pio_mode		= qd6500_set_pio_mode,
	.selectproc		= qd65xx_select,
};

static const struct ide_port_ops qd6580_port_ops = {
	.port_init_devs		= qd6580_port_init_devs,
	.set_pio_mode		= qd6580_set_pio_mode,
	.selectproc		= qd65xx_select,
};

static const struct ide_port_info qd65xx_port_info __initdata = {
	.name			= DRV_NAME,
	.chipset		= ide_qd65xx,
	.host_flags		= IDE_HFLAG_IO_32BIT |
				  IDE_HFLAG_NO_DMA,
	.pio_mask		= ATA_PIO4,
};

/*
 * qd_probe:
 *
 * looks at the specified baseport, and if qd found, registers & initialises it
 * return 1 if another qd may be probed
 */

static int __init qd_probe(int base)
{
	int rc;
	u8 config, unit, control;
	struct ide_port_info d = qd65xx_port_info;

	config = inb(QD_CONFIG_PORT);

	if (! ((config & QD_CONFIG_BASEPORT) >> 1 == (base == 0xb0)) )
		return -ENODEV;

	unit = ! (config & QD_CONFIG_IDE_BASEPORT);

	if (unit)
		d.host_flags |= IDE_HFLAG_QD_2ND_PORT;

	switch (config & 0xf0) {
	case QD_CONFIG_QD6500:
		if (qd_testreg(base))
			 return -ENODEV;	/* bad register */

		if (config & QD_CONFIG_DISABLED) {
			printk(KERN_WARNING "qd6500 is disabled !\n");
			return -ENODEV;
		}

		printk(KERN_NOTICE "qd6500 at %#x\n", base);
		printk(KERN_DEBUG "qd6500: config=%#x, ID3=%u\n",
			config, QD_ID3);

		d.port_ops = &qd6500_port_ops;
		d.host_flags |= IDE_HFLAG_SINGLE;
		break;
	case QD_CONFIG_QD6580_A:
	case QD_CONFIG_QD6580_B:
		if (qd_testreg(base) || qd_testreg(base + 0x02))
			return -ENODEV;	/* bad registers */

		control = inb(QD_CONTROL_PORT);

		printk(KERN_NOTICE "qd6580 at %#x\n", base);
		printk(KERN_DEBUG "qd6580: config=%#x, control=%#x, ID3=%u\n",
			config, control, QD_ID3);

		outb(QD_DEF_CONTR, QD_CONTROL_PORT);

		d.port_ops = &qd6580_port_ops;
		if (control & QD_CONTR_SEC_DISABLED)
			d.host_flags |= IDE_HFLAG_SINGLE;

		printk(KERN_INFO "qd6580: %s IDE board\n",
			(control & QD_CONTR_SEC_DISABLED) ? "single" : "dual");
		break;
	default:
		return -ENODEV;
	}

	rc = ide_legacy_device_add(&d, (base << 8) | config);

	if (d.host_flags & IDE_HFLAG_SINGLE)
		return (rc == 0) ? 1 : rc;

	return rc;
}

static int probe_qd65xx;

module_param_named(probe, probe_qd65xx, bool, 0);
MODULE_PARM_DESC(probe, "probe for QD65xx chipsets");

static int __init qd65xx_init(void)
{
	int rc1, rc2 = -ENODEV;

	if (probe_qd65xx == 0)
		return -ENODEV;

	rc1 = qd_probe(0x30);
	if (rc1)
		rc2 = qd_probe(0xb0);

	if (rc1 < 0 && rc2 < 0)
		return -ENODEV;

	return 0;
}

module_init(qd65xx_init);

MODULE_AUTHOR("Samuel Thibault");
MODULE_DESCRIPTION("support of qd65xx vlb ide chipset");
MODULE_LICENSE("GPL");
