/*
 * IPMMU/IPMMUI
 * Copyright (C) 2012  Hideki EIRAKU
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 */

#include <linux/err.h>
#include <linux/export.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/platform_data/sh_ipmmu.h>
#include "shmobile-ipmmu.h"

#define IMCTR1 0x000
#define IMCTR2 0x004
#define IMASID 0x010
#define IMTTBR 0x014
#define IMTTBCR 0x018

#define IMCTR1_TLBEN (1 << 0)
#define IMCTR1_FLUSH (1 << 1)

static void ipmmu_reg_write(struct shmobile_ipmmu *ipmmu, unsigned long reg_off,
			    unsigned long data)
{
	iowrite32(data, ipmmu->ipmmu_base + reg_off);
}

void ipmmu_tlb_flush(struct shmobile_ipmmu *ipmmu)
{
	if (!ipmmu)
		return;

	mutex_lock(&ipmmu->flush_lock);
	if (ipmmu->tlb_enabled)
		ipmmu_reg_write(ipmmu, IMCTR1, IMCTR1_FLUSH | IMCTR1_TLBEN);
	else
		ipmmu_reg_write(ipmmu, IMCTR1, IMCTR1_FLUSH);
	mutex_unlock(&ipmmu->flush_lock);
}

void ipmmu_tlb_set(struct shmobile_ipmmu *ipmmu, unsigned long phys, int size,
		   int asid)
{
	if (!ipmmu)
		return;

	mutex_lock(&ipmmu->flush_lock);
	switch (size) {
	default:
		ipmmu->tlb_enabled = 0;
		break;
	case 0x2000:
		ipmmu_reg_write(ipmmu, IMTTBCR, 1);
		ipmmu->tlb_enabled = 1;
		break;
	case 0x1000:
		ipmmu_reg_write(ipmmu, IMTTBCR, 2);
		ipmmu->tlb_enabled = 1;
		break;
	case 0x800:
		ipmmu_reg_write(ipmmu, IMTTBCR, 3);
		ipmmu->tlb_enabled = 1;
		break;
	case 0x400:
		ipmmu_reg_write(ipmmu, IMTTBCR, 4);
		ipmmu->tlb_enabled = 1;
		break;
	case 0x200:
		ipmmu_reg_write(ipmmu, IMTTBCR, 5);
		ipmmu->tlb_enabled = 1;
		break;
	case 0x100:
		ipmmu_reg_write(ipmmu, IMTTBCR, 6);
		ipmmu->tlb_enabled = 1;
		break;
	case 0x80:
		ipmmu_reg_write(ipmmu, IMTTBCR, 7);
		ipmmu->tlb_enabled = 1;
		break;
	}
	ipmmu_reg_write(ipmmu, IMTTBR, phys);
	ipmmu_reg_write(ipmmu, IMASID, asid);
	mutex_unlock(&ipmmu->flush_lock);
}

static int ipmmu_probe(struct platform_device *pdev)
{
	struct shmobile_ipmmu *ipmmu;
	struct resource *res;
	struct shmobile_ipmmu_platform_data *pdata = pdev->dev.platform_data;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "cannot get platform resources\n");
		return -ENOENT;
	}
	ipmmu = devm_kzalloc(&pdev->dev, sizeof(*ipmmu), GFP_KERNEL);
	if (!ipmmu) {
		dev_err(&pdev->dev, "cannot allocate device data\n");
		return -ENOMEM;
	}
	mutex_init(&ipmmu->flush_lock);
	ipmmu->dev = &pdev->dev;
	ipmmu->ipmmu_base = devm_ioremap_nocache(&pdev->dev, res->start,
						resource_size(res));
	if (!ipmmu->ipmmu_base) {
		dev_err(&pdev->dev, "ioremap_nocache failed\n");
		return -ENOMEM;
	}
	ipmmu->dev_names = pdata->dev_names;
	ipmmu->num_dev_names = pdata->num_dev_names;
	platform_set_drvdata(pdev, ipmmu);
	ipmmu_reg_write(ipmmu, IMCTR1, 0x0); /* disable TLB */
	ipmmu_reg_write(ipmmu, IMCTR2, 0x0); /* disable PMB */
	ipmmu_iommu_init(ipmmu);
	return 0;
}

static struct platform_driver ipmmu_driver = {
	.probe = ipmmu_probe,
	.driver = {
		.owner = THIS_MODULE,
		.name = "ipmmu",
	},
};

static int __init ipmmu_init(void)
{
	return platform_driver_register(&ipmmu_driver);
}
subsys_initcall(ipmmu_init);
