// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright © 2015 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 iproc_nand_soc {
	struct brcmnand_soc soc;

	void __iomem *idm_base;
	void __iomem *ext_base;
	spinlock_t idm_lock;
};

#define IPROC_NAND_CTLR_READY_OFFSET       0x10
#define IPROC_NAND_CTLR_READY              BIT(0)

#define IPROC_NAND_IO_CTRL_OFFSET          0x00
#define IPROC_NAND_APB_LE_MODE             BIT(24)
#define IPROC_NAND_INT_CTRL_READ_ENABLE    BIT(6)

static bool iproc_nand_intc_ack(struct brcmnand_soc *soc)
{
	struct iproc_nand_soc *priv =
			container_of(soc, struct iproc_nand_soc, soc);
	void __iomem *mmio = priv->ext_base + IPROC_NAND_CTLR_READY_OFFSET;
	u32 val = brcmnand_readl(mmio);

	if (val & IPROC_NAND_CTLR_READY) {
		brcmnand_writel(IPROC_NAND_CTLR_READY, mmio);
		return true;
	}

	return false;
}

static void iproc_nand_intc_set(struct brcmnand_soc *soc, bool en)
{
	struct iproc_nand_soc *priv =
			container_of(soc, struct iproc_nand_soc, soc);
	void __iomem *mmio = priv->idm_base + IPROC_NAND_IO_CTRL_OFFSET;
	u32 val;
	unsigned long flags;

	spin_lock_irqsave(&priv->idm_lock, flags);

	val = brcmnand_readl(mmio);

	if (en)
		val |= IPROC_NAND_INT_CTRL_READ_ENABLE;
	else
		val &= ~IPROC_NAND_INT_CTRL_READ_ENABLE;

	brcmnand_writel(val, mmio);

	spin_unlock_irqrestore(&priv->idm_lock, flags);
}

static void iproc_nand_apb_access(struct brcmnand_soc *soc, bool prepare,
				  bool is_param)
{
	struct iproc_nand_soc *priv =
			container_of(soc, struct iproc_nand_soc, soc);
	void __iomem *mmio = priv->idm_base + IPROC_NAND_IO_CTRL_OFFSET;
	u32 val;
	unsigned long flags;

	spin_lock_irqsave(&priv->idm_lock, flags);

	val = brcmnand_readl(mmio);

	/*
	 * In the case of BE or when dealing with NAND data, alway configure
	 * the APB bus to LE mode before accessing the FIFO and back to BE mode
	 * after the access is done
	 */
	if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN) || !is_param) {
		if (prepare)
			val |= IPROC_NAND_APB_LE_MODE;
		else
			val &= ~IPROC_NAND_APB_LE_MODE;
	} else { /* when in LE accessing the parameter page, keep APB in BE */
		val &= ~IPROC_NAND_APB_LE_MODE;
	}

	brcmnand_writel(val, mmio);

	spin_unlock_irqrestore(&priv->idm_lock, flags);
}

static int iproc_nand_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct iproc_nand_soc *priv;
	struct brcmnand_soc *soc;

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

	spin_lock_init(&priv->idm_lock);

	priv->idm_base = devm_platform_ioremap_resource_byname(pdev, "iproc-idm");
	if (IS_ERR(priv->idm_base))
		return PTR_ERR(priv->idm_base);

	priv->ext_base = devm_platform_ioremap_resource_byname(pdev, "iproc-ext");
	if (IS_ERR(priv->ext_base))
		return PTR_ERR(priv->ext_base);

	soc->ctlrdy_ack = iproc_nand_intc_ack;
	soc->ctlrdy_set_enabled = iproc_nand_intc_set;
	soc->prepare_data_bus = iproc_nand_apb_access;

	return brcmnand_probe(pdev, soc);
}

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

static struct platform_driver iproc_nand_driver = {
	.probe			= iproc_nand_probe,
	.remove_new		= brcmnand_remove,
	.driver = {
		.name		= "iproc_nand",
		.pm		= &brcmnand_pm_ops,
		.of_match_table	= iproc_nand_of_match,
	}
};
module_platform_driver(iproc_nand_driver);

MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Brian Norris");
MODULE_AUTHOR("Ray Jui");
MODULE_DESCRIPTION("NAND driver for Broadcom IPROC-based SoCs");
