/*
 * drivers/mtd/maps/intel_vr_nor.c
 *
 * An MTD map driver for a NOR flash bank on the Expansion Bus of the Intel
 * Vermilion Range chipset.
 *
 * The Vermilion Range Expansion Bus supports four chip selects, each of which
 * has 64MiB of address space.  The 2nd BAR of the Expansion Bus PCI Device
 * is a 256MiB memory region containing the address spaces for all four of the
 * chip selects, with start addresses hardcoded on 64MiB boundaries.
 *
 * This map driver only supports NOR flash on chip select 0.  The buswidth
 * (either 8 bits or 16 bits) is determined by reading the Expansion Bus Timing
 * and Control Register for Chip Select 0 (EXP_TIMING_CS0).  This driver does
 * not modify the value in the EXP_TIMING_CS0 register except to enable writing
 * and disable boot acceleration.  The timing parameters in the register are
 * assumed to have been properly initialized by the BIOS.  The reset default
 * timing parameters are maximally conservative (slow), so access to the flash
 * will be slower than it should be if the BIOS has not initialized the timing
 * parameters.
 *
 * Author: Andy Lowe <alowe@mvista.com>
 *
 * 2006 (c) MontaVista Software, Inc. This file is licensed under
 * the terms of the GNU General Public License version 2. This program
 * is licensed "as is" without any warranty of any kind, whether express
 * or implied.
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/cfi.h>
#include <linux/mtd/flashchip.h>

#define DRV_NAME "vr_nor"

struct vr_nor_mtd {
	void __iomem *csr_base;
	struct map_info map;
	struct mtd_info *info;
	struct pci_dev *dev;
};

/* Expansion Bus Configuration and Status Registers are in BAR 0 */
#define EXP_CSR_MBAR 0
/* Expansion Bus Memory Window is BAR 1 */
#define EXP_WIN_MBAR 1
/* Maximum address space for Chip Select 0 is 64MiB */
#define CS0_SIZE 0x04000000
/* Chip Select 0 is at offset 0 in the Memory Window */
#define CS0_START 0x0
/* Chip Select 0 Timing Register is at offset 0 in CSR */
#define EXP_TIMING_CS0 0x00
#define TIMING_CS_EN		(1 << 31)	/* Chip Select Enable */
#define TIMING_BOOT_ACCEL_DIS	(1 <<  8)	/* Boot Acceleration Disable */
#define TIMING_WR_EN		(1 <<  1)	/* Write Enable */
#define TIMING_BYTE_EN		(1 <<  0)	/* 8-bit vs 16-bit bus */
#define TIMING_MASK		0x3FFF0000

static void vr_nor_destroy_partitions(struct vr_nor_mtd *p)
{
	mtd_device_unregister(p->info);
}

static int vr_nor_init_partitions(struct vr_nor_mtd *p)
{
	/* register the flash bank */
	/* partition the flash bank */
	return mtd_device_register(p->info, NULL, 0);
}

static void vr_nor_destroy_mtd_setup(struct vr_nor_mtd *p)
{
	map_destroy(p->info);
}

static int vr_nor_mtd_setup(struct vr_nor_mtd *p)
{
	static const char * const probe_types[] =
	    { "cfi_probe", "jedec_probe", NULL };
	const char * const *type;

	for (type = probe_types; !p->info && *type; type++)
		p->info = do_map_probe(*type, &p->map);
	if (!p->info)
		return -ENODEV;

	p->info->dev.parent = &p->dev->dev;

	return 0;
}

static void vr_nor_destroy_maps(struct vr_nor_mtd *p)
{
	unsigned int exp_timing_cs0;

	/* write-protect the flash bank */
	exp_timing_cs0 = readl(p->csr_base + EXP_TIMING_CS0);
	exp_timing_cs0 &= ~TIMING_WR_EN;
	writel(exp_timing_cs0, p->csr_base + EXP_TIMING_CS0);

	/* unmap the flash window */
	iounmap(p->map.virt);

	/* unmap the csr window */
	iounmap(p->csr_base);
}

/*
 * Initialize the map_info structure and map the flash.
 * Returns 0 on success, nonzero otherwise.
 */
static int vr_nor_init_maps(struct vr_nor_mtd *p)
{
	unsigned long csr_phys, csr_len;
	unsigned long win_phys, win_len;
	unsigned int exp_timing_cs0;
	int err;

	csr_phys = pci_resource_start(p->dev, EXP_CSR_MBAR);
	csr_len = pci_resource_len(p->dev, EXP_CSR_MBAR);
	win_phys = pci_resource_start(p->dev, EXP_WIN_MBAR);
	win_len = pci_resource_len(p->dev, EXP_WIN_MBAR);

	if (!csr_phys || !csr_len || !win_phys || !win_len)
		return -ENODEV;

	if (win_len < (CS0_START + CS0_SIZE))
		return -ENXIO;

	p->csr_base = ioremap(csr_phys, csr_len);
	if (!p->csr_base)
		return -ENOMEM;

	exp_timing_cs0 = readl(p->csr_base + EXP_TIMING_CS0);
	if (!(exp_timing_cs0 & TIMING_CS_EN)) {
		dev_warn(&p->dev->dev, "Expansion Bus Chip Select 0 "
		       "is disabled.\n");
		err = -ENODEV;
		goto release;
	}
	if ((exp_timing_cs0 & TIMING_MASK) == TIMING_MASK) {
		dev_warn(&p->dev->dev, "Expansion Bus Chip Select 0 "
		       "is configured for maximally slow access times.\n");
	}
	p->map.name = DRV_NAME;
	p->map.bankwidth = (exp_timing_cs0 & TIMING_BYTE_EN) ? 1 : 2;
	p->map.phys = win_phys + CS0_START;
	p->map.size = CS0_SIZE;
	p->map.virt = ioremap(p->map.phys, p->map.size);
	if (!p->map.virt) {
		err = -ENOMEM;
		goto release;
	}
	simple_map_init(&p->map);

	/* Enable writes to flash bank */
	exp_timing_cs0 |= TIMING_BOOT_ACCEL_DIS | TIMING_WR_EN;
	writel(exp_timing_cs0, p->csr_base + EXP_TIMING_CS0);

	return 0;

      release:
	iounmap(p->csr_base);
	return err;
}

static const struct pci_device_id vr_nor_pci_ids[] = {
	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x500D)},
	{0,}
};

static void vr_nor_pci_remove(struct pci_dev *dev)
{
	struct vr_nor_mtd *p = pci_get_drvdata(dev);

	vr_nor_destroy_partitions(p);
	vr_nor_destroy_mtd_setup(p);
	vr_nor_destroy_maps(p);
	kfree(p);
	pci_release_regions(dev);
	pci_disable_device(dev);
}

static int vr_nor_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
	struct vr_nor_mtd *p = NULL;
	unsigned int exp_timing_cs0;
	int err;

	err = pci_enable_device(dev);
	if (err)
		goto out;

	err = pci_request_regions(dev, DRV_NAME);
	if (err)
		goto disable_dev;

	p = kzalloc(sizeof(*p), GFP_KERNEL);
	err = -ENOMEM;
	if (!p)
		goto release;

	p->dev = dev;

	err = vr_nor_init_maps(p);
	if (err)
		goto release;

	err = vr_nor_mtd_setup(p);
	if (err)
		goto destroy_maps;

	err = vr_nor_init_partitions(p);
	if (err)
		goto destroy_mtd_setup;

	pci_set_drvdata(dev, p);

	return 0;

      destroy_mtd_setup:
	map_destroy(p->info);

      destroy_maps:
	/* write-protect the flash bank */
	exp_timing_cs0 = readl(p->csr_base + EXP_TIMING_CS0);
	exp_timing_cs0 &= ~TIMING_WR_EN;
	writel(exp_timing_cs0, p->csr_base + EXP_TIMING_CS0);

	/* unmap the flash window */
	iounmap(p->map.virt);

	/* unmap the csr window */
	iounmap(p->csr_base);

      release:
	kfree(p);
	pci_release_regions(dev);

      disable_dev:
	pci_disable_device(dev);

      out:
	return err;
}

static struct pci_driver vr_nor_pci_driver = {
	.name = DRV_NAME,
	.probe = vr_nor_pci_probe,
	.remove = vr_nor_pci_remove,
	.id_table = vr_nor_pci_ids,
};

module_pci_driver(vr_nor_pci_driver);

MODULE_AUTHOR("Andy Lowe");
MODULE_DESCRIPTION("MTD map driver for NOR flash on Intel Vermilion Range");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, vr_nor_pci_ids);
