/*
 * Copyright (C) 2014 Nest Labs
 *
 * 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.
 *
 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
 * kind, whether express or implied; without even the implied warranty
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/firmware.h>
#include <linux/reset.h>

#define FIRMWARE_NAME	"sensor-cpu.bin"

#define SP_OFFSET	0
#define PC_OFFSET	4

struct nl_sensor_cpu_dev {
	struct device *device;
	void __iomem *base;
	struct reset_control *reset;
	void __iomem *sram;
	int sram_size;
};

struct fw_header {
	unsigned int sp;
	unsigned int pc;
};

static void nl_sensor_cpu_load_firmware(const struct firmware *fw, void *context)
{
	struct nl_sensor_cpu_dev *dev = context;

	if (!fw) {
		dev_err(dev->device, "Firmware not provided\n");
		return;
	}

	/* Ensure firmware length less than available SRAM */
	if (fw->size > dev->sram_size) {
		dev_err(dev->device, "Firmware too large\n");
		return;
	}

	/* Configure M4's initial SP and PC from firmware header */
	dev_info(dev->device, "SP = %08x\n", ((struct fw_header *)fw->data)->sp);
	dev_info(dev->device, "PC = %08x\n", ((struct fw_header *)fw->data)->pc);

	writel(((struct fw_header *)fw->data)->sp, dev->base + SP_OFFSET);
	writel(((struct fw_header *)fw->data)->pc, dev->base + PC_OFFSET);

	/* Load firmware into SRAM */
	memcpy(dev->sram, fw->data, fw->size);
	wmb();

	/* Release firmware */
	release_firmware(fw);

	/* De-Assert Reset */
	reset_control_deassert(dev->reset);

	dev_info(dev->device, "After reset deassert!\n");
}

static int nl_sensor_cpu_probe(struct platform_device *pdev)
{
	struct nl_sensor_cpu_dev *dev;
	struct resource *iomem;
	int ret;

	/* Allocate memory for private data structure */
	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
	if (!dev)
		return -ENOMEM;

	platform_set_drvdata(pdev, dev);
	dev->device = &pdev->dev;

	/* Map hardware registers */
	iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	dev->base = devm_ioremap_resource(dev->device, iomem);
	if (IS_ERR(dev->base))
		return PTR_ERR(dev->reset);

	/* Map SRAM - Should this come from the SRAM gen_pool? */
	iomem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	dev->sram = devm_ioremap_resource(dev->device, iomem);
	if (IS_ERR(dev->sram))
		return PTR_ERR(dev->reset);

	dev->sram_size = iomem->end - iomem->start;

	/* Acquire reset controller handle */
	dev->reset = devm_reset_control_get(dev->device, NULL);
	if (IS_ERR(dev->reset)) {
		dev_err(dev->device, "Failed to acquire reset controller handle\n");
		return PTR_ERR(dev->reset);
	}

	/* Load firmware and start M4 */
	ret = request_firmware_nowait(THIS_MODULE,
				FW_ACTION_HOTPLUG, FIRMWARE_NAME, dev->device,
				GFP_KERNEL, dev, nl_sensor_cpu_load_firmware);
	if (!ret)
		dev_err(dev->device, "Failed to request firmware\n");

	return ret;
}

static int nl_sensor_cpu_remove(struct platform_device *pdev)
{
	return 0;
}

static const struct of_device_id nl_sensor_cpu_of_match[] = {
	{.compatible = "nestlabs,imx6sx-sensor-cpu",},
	{},
};
MODULE_DEVICE_TABLE(of, nl_sensor_cpu_of_match);

static struct platform_driver nl_sensor_cpu_driver = {
	.driver = {
		   .name = "nl-sensor-cpu",
		   .owner = THIS_MODULE,
		   .of_match_table = nl_sensor_cpu_of_match,
		   },
	.probe = nl_sensor_cpu_probe,
	.remove = nl_sensor_cpu_remove,
};
module_platform_driver(nl_sensor_cpu_driver);

MODULE_AUTHOR("Tim Kryger <tkryger@nestlabs.com>");
MODULE_DESCRIPTION("Nestlabs Sensor Coprocessor Driver");
MODULE_LICENSE("GPL v2");
