/*
 * Tegra20 Memory Controller
 *
 * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope 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.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/ratelimit.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/io.h>

#define DRV_NAME "tegra20-mc"

#define MC_INTSTATUS			0x0
#define MC_INTMASK			0x4

#define MC_INT_ERR_SHIFT		6
#define MC_INT_ERR_MASK			(0x1f << MC_INT_ERR_SHIFT)
#define MC_INT_DECERR_EMEM		BIT(MC_INT_ERR_SHIFT)
#define MC_INT_INVALID_GART_PAGE	BIT(MC_INT_ERR_SHIFT + 1)
#define MC_INT_SECURITY_VIOLATION	BIT(MC_INT_ERR_SHIFT + 2)
#define MC_INT_ARBITRATION_EMEM		BIT(MC_INT_ERR_SHIFT + 3)

#define MC_GART_ERROR_REQ		0x30
#define MC_DECERR_EMEM_OTHERS_STATUS	0x58
#define MC_SECURITY_VIOLATION_STATUS	0x74

#define SECURITY_VIOLATION_TYPE		BIT(30)	/* 0=TRUSTZONE, 1=CARVEOUT */

#define MC_CLIENT_ID_MASK		0x3f

#define NUM_MC_REG_BANKS		2

struct tegra20_mc {
	void __iomem *regs[NUM_MC_REG_BANKS];
	struct device *dev;
};

static inline u32 mc_readl(struct tegra20_mc *mc, u32 offs)
{
	u32 val = 0;

	if (offs < 0x24)
		val = readl(mc->regs[0] + offs);
	else if (offs < 0x400)
		val = readl(mc->regs[1] + offs - 0x3c);

	return val;
}

static inline void mc_writel(struct tegra20_mc *mc, u32 val, u32 offs)
{
	if (offs < 0x24)
		writel(val, mc->regs[0] + offs);
	else if (offs < 0x400)
		writel(val, mc->regs[1] + offs - 0x3c);
}

static const char * const tegra20_mc_client[] = {
	"cbr_display0a",
	"cbr_display0ab",
	"cbr_display0b",
	"cbr_display0bb",
	"cbr_display0c",
	"cbr_display0cb",
	"cbr_display1b",
	"cbr_display1bb",
	"cbr_eppup",
	"cbr_g2pr",
	"cbr_g2sr",
	"cbr_mpeunifbr",
	"cbr_viruv",
	"csr_avpcarm7r",
	"csr_displayhc",
	"csr_displayhcb",
	"csr_fdcdrd",
	"csr_g2dr",
	"csr_host1xdmar",
	"csr_host1xr",
	"csr_idxsrd",
	"csr_mpcorer",
	"csr_mpe_ipred",
	"csr_mpeamemrd",
	"csr_mpecsrd",
	"csr_ppcsahbdmar",
	"csr_ppcsahbslvr",
	"csr_texsrd",
	"csr_vdebsevr",
	"csr_vdember",
	"csr_vdemcer",
	"csr_vdetper",
	"cbw_eppu",
	"cbw_eppv",
	"cbw_eppy",
	"cbw_mpeunifbw",
	"cbw_viwsb",
	"cbw_viwu",
	"cbw_viwv",
	"cbw_viwy",
	"ccw_g2dw",
	"csw_avpcarm7w",
	"csw_fdcdwr",
	"csw_host1xw",
	"csw_ispw",
	"csw_mpcorew",
	"csw_mpecswr",
	"csw_ppcsahbdmaw",
	"csw_ppcsahbslvw",
	"csw_vdebsevw",
	"csw_vdembew",
	"csw_vdetpmw",
};

static void tegra20_mc_decode(struct tegra20_mc *mc, int n)
{
	u32 addr, req;
	const char *client = "Unknown";
	int idx, cid;
	const struct reg_info {
		u32 offset;
		u32 write_bit;	/* 0=READ, 1=WRITE */
		int cid_shift;
		char *message;
	} reg[] = {
		{
			.offset = MC_DECERR_EMEM_OTHERS_STATUS,
			.write_bit = 31,
			.message = "MC_DECERR",
		},
		{
			.offset	= MC_GART_ERROR_REQ,
			.cid_shift = 1,
			.message = "MC_GART_ERR",

		},
		{
			.offset = MC_SECURITY_VIOLATION_STATUS,
			.write_bit = 31,
			.message = "MC_SECURITY_ERR",
		},
	};

	idx = n - MC_INT_ERR_SHIFT;
	if ((idx < 0) || (idx >= ARRAY_SIZE(reg))) {
		dev_err_ratelimited(mc->dev, "Unknown interrupt status %08lx\n",
				    BIT(n));
		return;
	}

	req = mc_readl(mc, reg[idx].offset);
	cid = (req >> reg[idx].cid_shift) & MC_CLIENT_ID_MASK;
	if (cid < ARRAY_SIZE(tegra20_mc_client))
		client = tegra20_mc_client[cid];

	addr = mc_readl(mc, reg[idx].offset + sizeof(u32));

	dev_err_ratelimited(mc->dev, "%s (0x%08x): 0x%08x %s (%s %s)\n",
			   reg[idx].message, req, addr, client,
			   (req & BIT(reg[idx].write_bit)) ? "write" : "read",
			   (reg[idx].offset == MC_SECURITY_VIOLATION_STATUS) ?
			   ((req & SECURITY_VIOLATION_TYPE) ?
			    "carveout" : "trustzone") : "");
}

static const struct of_device_id tegra20_mc_of_match[] = {
	{ .compatible = "nvidia,tegra20-mc", },
	{},
};

static irqreturn_t tegra20_mc_isr(int irq, void *data)
{
	u32 stat, mask, bit;
	struct tegra20_mc *mc = data;

	stat = mc_readl(mc, MC_INTSTATUS);
	mask = mc_readl(mc, MC_INTMASK);
	mask &= stat;
	if (!mask)
		return IRQ_NONE;
	while ((bit = ffs(mask)) != 0) {
		tegra20_mc_decode(mc, bit - 1);
		mask &= ~BIT(bit - 1);
	}

	mc_writel(mc, stat, MC_INTSTATUS);
	return IRQ_HANDLED;
}

static int tegra20_mc_probe(struct platform_device *pdev)
{
	struct resource *irq;
	struct tegra20_mc *mc;
	int i, err;
	u32 intmask;

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

	for (i = 0; i < ARRAY_SIZE(mc->regs); i++) {
		struct resource *res;

		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
		mc->regs[i] = devm_ioremap_resource(&pdev->dev, res);
		if (IS_ERR(mc->regs[i]))
			return PTR_ERR(mc->regs[i]);
	}

	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!irq)
		return -ENODEV;
	err = devm_request_irq(&pdev->dev, irq->start, tegra20_mc_isr,
			       IRQF_SHARED, dev_name(&pdev->dev), mc);
	if (err)
		return -ENODEV;

	platform_set_drvdata(pdev, mc);

	intmask = MC_INT_INVALID_GART_PAGE |
		MC_INT_DECERR_EMEM | MC_INT_SECURITY_VIOLATION;
	mc_writel(mc, intmask, MC_INTMASK);
	return 0;
}

static struct platform_driver tegra20_mc_driver = {
	.probe = tegra20_mc_probe,
	.driver = {
		.name = DRV_NAME,
		.of_match_table = tegra20_mc_of_match,
	},
};
module_platform_driver(tegra20_mc_driver);

MODULE_AUTHOR("Hiroshi DOYU <hdoyu@nvidia.com>");
MODULE_DESCRIPTION("Tegra20 MC driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:" DRV_NAME);
