/*
 * Copyright 2015 Simon Arlott
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * Derived from bcm63138_nand.c:
 * Copyright © 2015 Broadcom Corporation
 *
 * Derived from bcm963xx_4.12L.06B_consumer/shared/opensource/include/bcm963xx/63268_map_part.h:
 * Copyright 2000-2010 Broadcom Corporation
 *
 * Derived from bcm963xx_4.12L.06B_consumer/shared/opensource/flash/nandflash.c:
 * Copyright 2000-2010 Broadcom Corporation
 */

#include <linux/device.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/slab.h>

#include "brcmnand.h"

struct bcm6368_nand_soc {
	struct brcmnand_soc soc;
	void __iomem *base;
};

#define BCM6368_NAND_INT		0x00
#define  BCM6368_NAND_STATUS_SHIFT	0
#define  BCM6368_NAND_STATUS_MASK	(0xfff << BCM6368_NAND_STATUS_SHIFT)
#define  BCM6368_NAND_ENABLE_SHIFT	16
#define  BCM6368_NAND_ENABLE_MASK	(0xffff << BCM6368_NAND_ENABLE_SHIFT)
#define BCM6368_NAND_BASE_ADDR0	0x04
#define BCM6368_NAND_BASE_ADDR1	0x0c

enum {
	BCM6368_NP_READ		= BIT(0),
	BCM6368_BLOCK_ERASE	= BIT(1),
	BCM6368_COPY_BACK	= BIT(2),
	BCM6368_PAGE_PGM	= BIT(3),
	BCM6368_CTRL_READY	= BIT(4),
	BCM6368_DEV_RBPIN	= BIT(5),
	BCM6368_ECC_ERR_UNC	= BIT(6),
	BCM6368_ECC_ERR_CORR	= BIT(7),
};

static bool bcm6368_nand_intc_ack(struct brcmnand_soc *soc)
{
	struct bcm6368_nand_soc *priv =
			container_of(soc, struct bcm6368_nand_soc, soc);
	void __iomem *mmio = priv->base + BCM6368_NAND_INT;
	u32 val = brcmnand_readl(mmio);

	if (val & (BCM6368_CTRL_READY << BCM6368_NAND_STATUS_SHIFT)) {
		/* Ack interrupt */
		val &= ~BCM6368_NAND_STATUS_MASK;
		val |= BCM6368_CTRL_READY << BCM6368_NAND_STATUS_SHIFT;
		brcmnand_writel(val, mmio);
		return true;
	}

	return false;
}

static void bcm6368_nand_intc_set(struct brcmnand_soc *soc, bool en)
{
	struct bcm6368_nand_soc *priv =
			container_of(soc, struct bcm6368_nand_soc, soc);
	void __iomem *mmio = priv->base + BCM6368_NAND_INT;
	u32 val = brcmnand_readl(mmio);

	/* Don't ack any interrupts */
	val &= ~BCM6368_NAND_STATUS_MASK;

	if (en)
		val |= BCM6368_CTRL_READY << BCM6368_NAND_ENABLE_SHIFT;
	else
		val &= ~(BCM6368_CTRL_READY << BCM6368_NAND_ENABLE_SHIFT);

	brcmnand_writel(val, mmio);
}

static int bcm6368_nand_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct bcm6368_nand_soc *priv;
	struct brcmnand_soc *soc;
	struct resource *res;

	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;
	soc = &priv->soc;

	res = platform_get_resource_byname(pdev,
		IORESOURCE_MEM, "nand-int-base");
	priv->base = devm_ioremap_resource(dev, res);
	if (IS_ERR(priv->base))
		return PTR_ERR(priv->base);

	soc->ctlrdy_ack = bcm6368_nand_intc_ack;
	soc->ctlrdy_set_enabled = bcm6368_nand_intc_set;

	/* Disable and ack all interrupts  */
	brcmnand_writel(0, priv->base + BCM6368_NAND_INT);
	brcmnand_writel(BCM6368_NAND_STATUS_MASK,
			priv->base + BCM6368_NAND_INT);

	return brcmnand_probe(pdev, soc);
}

static const struct of_device_id bcm6368_nand_of_match[] = {
	{ .compatible = "brcm,nand-bcm6368" },
	{},
};
MODULE_DEVICE_TABLE(of, bcm6368_nand_of_match);

static struct platform_driver bcm6368_nand_driver = {
	.probe			= bcm6368_nand_probe,
	.remove			= brcmnand_remove,
	.driver = {
		.name		= "bcm6368_nand",
		.pm		= &brcmnand_pm_ops,
		.of_match_table	= bcm6368_nand_of_match,
	}
};
module_platform_driver(bcm6368_nand_driver);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Simon Arlott");
MODULE_DESCRIPTION("NAND driver for BCM6368");
