/*
 * PATA driver for AT91SAM9260 Static Memory Controller
 * with CompactFlash interface in True IDE mode
 *
 * Copyright (C) 2009 Matyukevich Sergey
 *               2011 Igor Plyatov
 *
 * Based on:
 *      * generic platform driver by Paul Mundt: drivers/ata/pata_platform.c
 *      * pata_at32 driver by Kristoffer Nyborg Gregertsen
 *      * at91_ide driver by Stanislaw Gruszka
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2
 * as published by the Free Software Foundation.
 *
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/gfp.h>
#include <scsi/scsi_host.h>
#include <linux/ata.h>
#include <linux/clk.h>
#include <linux/libata.h>
#include <linux/platform_device.h>
#include <linux/ata_platform.h>

#include <mach/at91sam9_smc.h>
#include <mach/board.h>
#include <asm/gpio.h>

#define DRV_NAME		"pata_at91"
#define DRV_VERSION		"0.3"

#define CF_IDE_OFFSET		0x00c00000
#define CF_ALT_IDE_OFFSET	0x00e00000
#define CF_IDE_RES_SIZE		0x08
#define CS_PULSE_MAXIMUM	319
#define ER_SMC_CALC		1
#define ER_SMC_RECALC		2

struct at91_ide_info {
	unsigned long mode;
	unsigned int cs;
	struct clk *mck;
	void __iomem *ide_addr;
	void __iomem *alt_addr;
};

/**
 * struct smc_range - range of valid values for SMC register.
 */
struct smc_range {
	int min;
	int max;
};

/**
 * adjust_smc_value - adjust value for one of SMC registers.
 * @value: adjusted value
 * @range: array of SMC ranges with valid values
 * @size: SMC ranges array size
 *
 * This returns the difference between input and output value or negative
 * in case of invalid input value.
 * If negative returned, then output value = maximal possible from ranges.
 */
static int adjust_smc_value(int *value, struct smc_range *range, int size)
{
	int maximum = (range + size - 1)->max;
	int remainder;

	do {
		if (*value < range->min) {
			remainder = range->min - *value;
			*value = range->min; /* nearest valid value */
			return remainder;
		} else if ((range->min <= *value) && (*value <= range->max))
			return 0;

		range++;
	} while (--size);
	*value = maximum;

	return -1; /* invalid value */
}

/**
 * calc_smc_vals - calculate SMC register values
 * @dev: ATA device
 * @setup: SMC_SETUP register value
 * @pulse: SMC_PULSE register value
 * @cycle: SMC_CYCLE register value
 *
 * This returns negative in case of invalid values for SMC registers:
 * -ER_SMC_RECALC - recalculation required for SMC values,
 * -ER_SMC_CALC - calculation failed (invalid input values).
 *
 * SMC use special coding scheme, see "Coding and Range of Timing
 * Parameters" table from AT91SAM9 datasheets.
 *
 *	SMC_SETUP = 128*setup[5] + setup[4:0]
 *	SMC_PULSE = 256*pulse[6] + pulse[5:0]
 *	SMC_CYCLE = 256*cycle[8:7] + cycle[6:0]
 */
static int calc_smc_vals(struct device *dev,
		int *setup, int *pulse, int *cycle, int *cs_pulse)
{
	int ret_val;
	int err = 0;
	struct smc_range range_setup[] = {	/* SMC_SETUP valid values */
		{.min = 0,	.max = 31},	/* first  range */
		{.min = 128,	.max = 159}	/* second range */
	};
	struct smc_range range_pulse[] = {	/* SMC_PULSE valid values */
		{.min = 0,	.max = 63},	/* first  range */
		{.min = 256,	.max = 319}	/* second range */
	};
	struct smc_range range_cycle[] = {	/* SMC_CYCLE valid values */
		{.min = 0,	.max = 127},	/* first  range */
		{.min = 256,	.max = 383},	/* second range */
		{.min = 512,	.max = 639},	/* third  range */
		{.min = 768,	.max = 895}	/* fourth range */
	};

	ret_val = adjust_smc_value(setup, range_setup, ARRAY_SIZE(range_setup));
	if (ret_val < 0)
		dev_warn(dev, "maximal SMC Setup value\n");
	else
		*cycle += ret_val;

	ret_val = adjust_smc_value(pulse, range_pulse, ARRAY_SIZE(range_pulse));
	if (ret_val < 0)
		dev_warn(dev, "maximal SMC Pulse value\n");
	else
		*cycle += ret_val;

	ret_val = adjust_smc_value(cycle, range_cycle, ARRAY_SIZE(range_cycle));
	if (ret_val < 0)
		dev_warn(dev, "maximal SMC Cycle value\n");

	*cs_pulse = *cycle;
	if (*cs_pulse > CS_PULSE_MAXIMUM) {
		dev_err(dev, "unable to calculate valid SMC settings\n");
		return -ER_SMC_CALC;
	}

	ret_val = adjust_smc_value(cs_pulse, range_pulse,
					ARRAY_SIZE(range_pulse));
	if (ret_val < 0) {
		dev_warn(dev, "maximal SMC CS Pulse value\n");
	} else if (ret_val != 0) {
		*cycle = *cs_pulse;
		dev_warn(dev, "SMC Cycle extended\n");
		err = -ER_SMC_RECALC;
	}

	return err;
}

/**
 * to_smc_format - convert values into SMC format
 * @setup: SETUP value of SMC Setup Register
 * @pulse: PULSE value of SMC Pulse Register
 * @cycle: CYCLE value of SMC Cycle Register
 * @cs_pulse: NCS_PULSE value of SMC Pulse Register
 */
static void to_smc_format(int *setup, int *pulse, int *cycle, int *cs_pulse)
{
	*setup = (*setup & 0x1f) | ((*setup & 0x80) >> 2);
	*pulse = (*pulse & 0x3f) | ((*pulse & 0x100) >> 2);
	*cycle = (*cycle & 0x7f) | ((*cycle & 0x300) >> 1);
	*cs_pulse = (*cs_pulse & 0x3f) | ((*cs_pulse & 0x100) >> 2);
}

static unsigned long calc_mck_cycles(unsigned long ns, unsigned long mck_hz)
{
	unsigned long mul;

	/*
	* cycles = x [nsec] * f [Hz] / 10^9 [ns in sec] =
	*     x * (f / 1_000_000_000) =
	*     x * ((f * 65536) / 1_000_000_000) / 65536 =
	*     x * (((f / 10_000) * 65536) / 100_000) / 65536 =
	*/

	mul = (mck_hz / 10000) << 16;
	mul /= 100000;

	return (ns * mul + 65536) >> 16;    /* rounding */
}

/**
 * set_smc_timing - SMC timings setup.
 * @dev: device
 * @info: AT91 IDE info
 * @ata: ATA timings
 *
 * Its assumed that write timings are same as read timings,
 * cs_setup = 0 and cs_pulse = cycle.
 */
static void set_smc_timing(struct device *dev, struct ata_device *adev,
		struct at91_ide_info *info, const struct ata_timing *ata)
{
	int ret = 0;
	int use_iordy;
	unsigned int t6z;         /* data tristate time in ns */
	unsigned int cycle;       /* SMC Cycle width in MCK ticks */
	unsigned int setup;       /* SMC Setup width in MCK ticks */
	unsigned int pulse;       /* CFIOR and CFIOW pulse width in MCK ticks */
	unsigned int cs_setup = 0;/* CS4 or CS5 setup width in MCK ticks */
	unsigned int cs_pulse;    /* CS4 or CS5 pulse width in MCK ticks*/
	unsigned int tdf_cycles;  /* SMC TDF MCK ticks */
	unsigned long mck_hz;     /* MCK frequency in Hz */

	t6z = (ata->mode < XFER_PIO_5) ? 30 : 20;
	mck_hz = clk_get_rate(info->mck);
	cycle = calc_mck_cycles(ata->cyc8b, mck_hz);
	setup = calc_mck_cycles(ata->setup, mck_hz);
	pulse = calc_mck_cycles(ata->act8b, mck_hz);
	tdf_cycles = calc_mck_cycles(t6z, mck_hz);

	do {
		ret = calc_smc_vals(dev, &setup, &pulse, &cycle, &cs_pulse);
	} while (ret == -ER_SMC_RECALC);

	if (ret == -ER_SMC_CALC)
		dev_err(dev, "Interface may not operate correctly\n");

	dev_dbg(dev, "SMC Setup=%u, Pulse=%u, Cycle=%u, CS Pulse=%u\n",
		setup, pulse, cycle, cs_pulse);
	to_smc_format(&setup, &pulse, &cycle, &cs_pulse);
	/* disable or enable waiting for IORDY signal */
	use_iordy = ata_pio_need_iordy(adev);
	if (use_iordy)
		info->mode |= AT91_SMC_EXNWMODE_READY;

	if (tdf_cycles > 15) {
		tdf_cycles = 15;
		dev_warn(dev, "maximal SMC TDF Cycles value\n");
	}

	dev_dbg(dev, "Use IORDY=%u, TDF Cycles=%u\n", use_iordy, tdf_cycles);
	info->mode |= AT91_SMC_TDF_(tdf_cycles);

	/* write SMC Setup Register */
	at91_sys_write(AT91_SMC_SETUP(info->cs),
			AT91_SMC_NWESETUP_(setup) |
			AT91_SMC_NRDSETUP_(setup) |
			AT91_SMC_NCS_WRSETUP_(cs_setup) |
			AT91_SMC_NCS_RDSETUP_(cs_setup));
	/* write SMC Pulse Register */
	at91_sys_write(AT91_SMC_PULSE(info->cs),
			AT91_SMC_NWEPULSE_(pulse) |
			AT91_SMC_NRDPULSE_(pulse) |
			AT91_SMC_NCS_WRPULSE_(cs_pulse) |
			AT91_SMC_NCS_RDPULSE_(cs_pulse));
	/* write SMC Cycle Register */
	at91_sys_write(AT91_SMC_CYCLE(info->cs),
			AT91_SMC_NWECYCLE_(cycle) |
			AT91_SMC_NRDCYCLE_(cycle));
	/* write SMC Mode Register*/
	at91_sys_write(AT91_SMC_MODE(info->cs), info->mode);
}

static void pata_at91_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
	struct at91_ide_info *info = ap->host->private_data;
	struct ata_timing timing;
	int ret;

	/* Compute ATA timing and set it to SMC */
	ret = ata_timing_compute(adev, adev->pio_mode, &timing, 1000, 0);
	if (ret) {
		dev_warn(ap->dev, "Failed to compute ATA timing %d, "
			 "set PIO_0 timing\n", ret);
		timing = *ata_timing_find_mode(XFER_PIO_0);
	}
	set_smc_timing(ap->dev, adev, info, &timing);
}

static unsigned int pata_at91_data_xfer_noirq(struct ata_device *dev,
		unsigned char *buf, unsigned int buflen, int rw)
{
	struct at91_ide_info *info = dev->link->ap->host->private_data;
	unsigned int consumed;
	unsigned long flags;
	unsigned int mode;

	local_irq_save(flags);
	mode = at91_sys_read(AT91_SMC_MODE(info->cs));

	/* set 16bit mode before writing data */
	at91_sys_write(AT91_SMC_MODE(info->cs),
			(mode & ~AT91_SMC_DBW) | AT91_SMC_DBW_16);

	consumed = ata_sff_data_xfer(dev, buf, buflen, rw);

	/* restore 8bit mode after data is written */
	at91_sys_write(AT91_SMC_MODE(info->cs),
			(mode & ~AT91_SMC_DBW) | AT91_SMC_DBW_8);

	local_irq_restore(flags);
	return consumed;
}

static struct scsi_host_template pata_at91_sht = {
	ATA_PIO_SHT(DRV_NAME),
};

static struct ata_port_operations pata_at91_port_ops = {
	.inherits	= &ata_sff_port_ops,

	.sff_data_xfer	= pata_at91_data_xfer_noirq,
	.set_piomode	= pata_at91_set_piomode,
	.cable_detect	= ata_cable_40wire,
};

static int __devinit pata_at91_probe(struct platform_device *pdev)
{
	struct at91_cf_data *board = pdev->dev.platform_data;
	struct device *dev = &pdev->dev;
	struct at91_ide_info *info;
	struct resource *mem_res;
	struct ata_host *host;
	struct ata_port *ap;

	int irq_flags = 0;
	int irq = 0;
	int ret;

	/*  get platform resources: IO/CTL memories and irq/rst pins */

	if (pdev->num_resources != 1) {
		dev_err(&pdev->dev, "invalid number of resources\n");
		return -EINVAL;
	}

	mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

	if (!mem_res) {
		dev_err(dev, "failed to get mem resource\n");
		return -EINVAL;
	}

	irq = board->irq_pin;

	/* init ata host */

	host = ata_host_alloc(dev, 1);

	if (!host)
		return -ENOMEM;

	ap = host->ports[0];
	ap->ops = &pata_at91_port_ops;
	ap->flags |= ATA_FLAG_SLAVE_POSS;
	ap->pio_mask = ATA_PIO4;

	if (!irq) {
		ap->flags |= ATA_FLAG_PIO_POLLING;
		ata_port_desc(ap, "no IRQ, using PIO polling");
	}

	info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);

	if (!info) {
		dev_err(dev, "failed to allocate memory for private data\n");
		return -ENOMEM;
	}

	info->mck = clk_get(NULL, "mck");

	if (IS_ERR(info->mck)) {
		dev_err(dev, "failed to get access to mck clock\n");
		return -ENODEV;
	}

	info->cs    = board->chipselect;
	info->mode  = AT91_SMC_READMODE | AT91_SMC_WRITEMODE |
		AT91_SMC_EXNWMODE_READY | AT91_SMC_BAT_SELECT |
		AT91_SMC_DBW_8 | AT91_SMC_TDF_(0);

	info->ide_addr = devm_ioremap(dev,
			mem_res->start + CF_IDE_OFFSET, CF_IDE_RES_SIZE);

	if (!info->ide_addr) {
		dev_err(dev, "failed to map IO base\n");
		ret = -ENOMEM;
		goto err_put;
	}

	info->alt_addr = devm_ioremap(dev,
			mem_res->start + CF_ALT_IDE_OFFSET, CF_IDE_RES_SIZE);

	if (!info->alt_addr) {
		dev_err(dev, "failed to map CTL base\n");
		ret = -ENOMEM;
		goto err_put;
	}

	ap->ioaddr.cmd_addr = info->ide_addr;
	ap->ioaddr.ctl_addr = info->alt_addr + 0x06;
	ap->ioaddr.altstatus_addr = ap->ioaddr.ctl_addr;

	ata_sff_std_ports(&ap->ioaddr);

	ata_port_desc(ap, "mmio cmd 0x%llx ctl 0x%llx",
			(unsigned long long)mem_res->start + CF_IDE_OFFSET,
			(unsigned long long)mem_res->start + CF_ALT_IDE_OFFSET);

	host->private_data = info;

	return ata_host_activate(host, irq ? gpio_to_irq(irq) : 0,
			irq ? ata_sff_interrupt : NULL,
			irq_flags, &pata_at91_sht);

err_put:
	clk_put(info->mck);
	return ret;
}

static int __devexit pata_at91_remove(struct platform_device *pdev)
{
	struct ata_host *host = dev_get_drvdata(&pdev->dev);
	struct at91_ide_info *info;

	if (!host)
		return 0;
	info = host->private_data;

	ata_host_detach(host);

	if (!info)
		return 0;

	clk_put(info->mck);

	return 0;
}

static struct platform_driver pata_at91_driver = {
	.probe		= pata_at91_probe,
	.remove		= __devexit_p(pata_at91_remove),
	.driver		= {
		.name		= DRV_NAME,
		.owner		= THIS_MODULE,
	},
};

static int __init pata_at91_init(void)
{
	return platform_driver_register(&pata_at91_driver);
}

static void __exit pata_at91_exit(void)
{
	platform_driver_unregister(&pata_at91_driver);
}


module_init(pata_at91_init);
module_exit(pata_at91_exit);


MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Driver for CF in True IDE mode on AT91SAM9260 SoC");
MODULE_AUTHOR("Matyukevich Sergey");
MODULE_VERSION(DRV_VERSION);

