/*
 * 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/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/mfd/syscon.h>
#include <linux/mfd/syscon/atmel-smc.h>
#include <linux/platform_device.h>
#include <linux/ata_platform.h>
#include <linux/platform_data/atmel.h>
#include <linux/regmap.h>
#include <linux/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;
};

struct regmap *smc;

struct at91sam9_smc_generic_fields {
	struct regmap_field *setup;
	struct regmap_field *pulse;
	struct regmap_field *cycle;
	struct regmap_field *mode;
} fields;

/**
 * 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_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);

	regmap_fields_write(fields.setup, info->cs,
			    AT91SAM9_SMC_NRDSETUP(setup) |
			    AT91SAM9_SMC_NWESETUP(setup) |
			    AT91SAM9_SMC_NCS_NRDSETUP(0) |
			    AT91SAM9_SMC_NCS_WRSETUP(0));
	regmap_fields_write(fields.pulse, info->cs,
			    AT91SAM9_SMC_NRDPULSE(pulse) |
			    AT91SAM9_SMC_NWEPULSE(pulse) |
			    AT91SAM9_SMC_NCS_NRDPULSE(cs_pulse) |
			    AT91SAM9_SMC_NCS_WRPULSE(cs_pulse));
	regmap_fields_write(fields.cycle, info->cs,
			    AT91SAM9_SMC_NRDCYCLE(cycle) |
			    AT91SAM9_SMC_NWECYCLE(cycle));
	regmap_fields_write(fields.mode, info->cs, info->mode |
			    AT91_SMC_TDF_(tdf_cycles));
}

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 int mode;
	unsigned long flags;

	local_irq_save(flags);
	regmap_fields_read(fields.mode, info->cs, &mode);

	/* set 16bit mode before writing data */
	regmap_fields_write(fields.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 */
	regmap_fields_write(fields.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 at91sam9_smc_fields_init(struct device *dev)
{
	struct reg_field field = REG_FIELD(0, 0, 31);

	field.id_size = 8;
	field.id_offset = AT91SAM9_SMC_GENERIC_BLK_SZ;

	field.reg = AT91SAM9_SMC_SETUP(AT91SAM9_SMC_GENERIC);
	fields.setup = devm_regmap_field_alloc(dev, smc, field);
	if (IS_ERR(fields.setup))
		return PTR_ERR(fields.setup);

	field.reg = AT91SAM9_SMC_PULSE(AT91SAM9_SMC_GENERIC);
	fields.pulse = devm_regmap_field_alloc(dev, smc, field);
	if (IS_ERR(fields.pulse))
		return PTR_ERR(fields.pulse);

	field.reg = AT91SAM9_SMC_CYCLE(AT91SAM9_SMC_GENERIC);
	fields.cycle = devm_regmap_field_alloc(dev, smc, field);
	if (IS_ERR(fields.cycle))
		return PTR_ERR(fields.cycle);

	field.reg = AT91SAM9_SMC_MODE(AT91SAM9_SMC_GENERIC);
	fields.mode = devm_regmap_field_alloc(dev, smc, field);
	if (IS_ERR(fields.mode))
		return PTR_ERR(fields.mode);

	return 0;
}

static int pata_at91_probe(struct platform_device *pdev)
{
	struct at91_cf_data *board = dev_get_platdata(&pdev->dev);
	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;

	smc = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "atmel,smc");
	if (IS_ERR(smc))
		return PTR_ERR(smc);

	ret = at91sam9_smc_fields_init(dev);
	if (ret < 0)
		return ret;

	/* 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 (!gpio_is_valid(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;

	ret = ata_host_activate(host, gpio_is_valid(irq) ? gpio_to_irq(irq) : 0,
				gpio_is_valid(irq) ? ata_sff_interrupt : NULL,
				irq_flags, &pata_at91_sht);
	if (ret)
		goto err_put;

	return 0;

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

static int pata_at91_remove(struct platform_device *pdev)
{
	struct ata_host *host = platform_get_drvdata(pdev);
	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		= pata_at91_remove,
	.driver		= {
		.name		= DRV_NAME,
	},
};

module_platform_driver(pata_at91_driver);

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

