/*
 * Copyright (c) 2013-2014, 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, see <http://www.gnu.org/licenses/>.
 *
 * Based on drivers/misc/eeprom/sunxi_sid.c
 */

#include <linux/device.h>
#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/kobject.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/random.h>

#include <soc/tegra/fuse.h>

#include "fuse.h"

#define FUSE_BEGIN	0x100
#define FUSE_SIZE	0x1f8
#define FUSE_UID_LOW	0x08
#define FUSE_UID_HIGH	0x0c

static phys_addr_t fuse_phys;
static struct clk *fuse_clk;
static void __iomem __initdata *fuse_base;

static DEFINE_MUTEX(apb_dma_lock);
static DECLARE_COMPLETION(apb_dma_wait);
static struct dma_chan *apb_dma_chan;
static struct dma_slave_config dma_sconfig;
static u32 *apb_buffer;
static dma_addr_t apb_buffer_phys;

static void apb_dma_complete(void *args)
{
	complete(&apb_dma_wait);
}

static u32 tegra20_fuse_readl(const unsigned int offset)
{
	int ret;
	u32 val = 0;
	struct dma_async_tx_descriptor *dma_desc;

	mutex_lock(&apb_dma_lock);

	dma_sconfig.src_addr = fuse_phys + FUSE_BEGIN + offset;
	ret = dmaengine_slave_config(apb_dma_chan, &dma_sconfig);
	if (ret)
		goto out;

	dma_desc = dmaengine_prep_slave_single(apb_dma_chan, apb_buffer_phys,
			sizeof(u32), DMA_DEV_TO_MEM,
			DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
	if (!dma_desc)
		goto out;

	dma_desc->callback = apb_dma_complete;
	dma_desc->callback_param = NULL;

	reinit_completion(&apb_dma_wait);

	clk_prepare_enable(fuse_clk);

	dmaengine_submit(dma_desc);
	dma_async_issue_pending(apb_dma_chan);
	ret = wait_for_completion_timeout(&apb_dma_wait, msecs_to_jiffies(50));

	if (WARN(ret == 0, "apb read dma timed out"))
		dmaengine_terminate_all(apb_dma_chan);
	else
		val = *apb_buffer;

	clk_disable_unprepare(fuse_clk);
out:
	mutex_unlock(&apb_dma_lock);

	return val;
}

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

static int apb_dma_init(void)
{
	dma_cap_mask_t mask;

	dma_cap_zero(mask);
	dma_cap_set(DMA_SLAVE, mask);
	apb_dma_chan = dma_request_channel(mask, NULL, NULL);
	if (!apb_dma_chan)
		return -EPROBE_DEFER;

	apb_buffer = dma_alloc_coherent(NULL, sizeof(u32), &apb_buffer_phys,
					GFP_KERNEL);
	if (!apb_buffer) {
		dma_release_channel(apb_dma_chan);
		return -ENOMEM;
	}

	dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
	dma_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
	dma_sconfig.src_maxburst = 1;
	dma_sconfig.dst_maxburst = 1;

	return 0;
}

static int tegra20_fuse_probe(struct platform_device *pdev)
{
	struct resource *res;
	int err;

	fuse_clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(fuse_clk)) {
		dev_err(&pdev->dev, "missing clock");
		return PTR_ERR(fuse_clk);
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res)
		return -EINVAL;
	fuse_phys = res->start;

	err = apb_dma_init();
	if (err)
		return err;

	if (tegra_fuse_create_sysfs(&pdev->dev, FUSE_SIZE, tegra20_fuse_readl))
		return -ENODEV;

	dev_dbg(&pdev->dev, "loaded\n");

	return 0;
}

static struct platform_driver tegra20_fuse_driver = {
	.probe = tegra20_fuse_probe,
	.driver = {
		.name = "tegra20_fuse",
		.of_match_table = tegra20_fuse_of_match,
	}
};

static int __init tegra20_fuse_init(void)
{
	return platform_driver_register(&tegra20_fuse_driver);
}
postcore_initcall(tegra20_fuse_init);

/* Early boot code. This code is called before the devices are created */

u32 __init tegra20_fuse_early(const unsigned int offset)
{
	return readl_relaxed(fuse_base + FUSE_BEGIN + offset);
}

bool __init tegra20_spare_fuse_early(int spare_bit)
{
	u32 offset = spare_bit * 4;
	bool value;

	value = tegra20_fuse_early(offset + 0x100);

	return value;
}

static void __init tegra20_fuse_add_randomness(void)
{
	u32 randomness[7];

	randomness[0] = tegra_sku_info.sku_id;
	randomness[1] = tegra_read_straps();
	randomness[2] = tegra_read_chipid();
	randomness[3] = tegra_sku_info.cpu_process_id << 16;
	randomness[3] |= tegra_sku_info.core_process_id;
	randomness[4] = tegra_sku_info.cpu_speedo_id << 16;
	randomness[4] |= tegra_sku_info.soc_speedo_id;
	randomness[5] = tegra20_fuse_early(FUSE_UID_LOW);
	randomness[6] = tegra20_fuse_early(FUSE_UID_HIGH);

	add_device_randomness(randomness, sizeof(randomness));
}

void __init tegra20_init_fuse_early(void)
{
	fuse_base = ioremap(TEGRA_FUSE_BASE, TEGRA_FUSE_SIZE);

	tegra_init_revision();
	tegra20_init_speedo_data(&tegra_sku_info);
	tegra20_fuse_add_randomness();

	iounmap(fuse_base);
}
