/* Copyright (c) 2014-2016, 2018 The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that 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.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/msm-bus.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include "vmem.h"
#include "vmem_debugfs.h"

/* Registers */
#define OCIMEM_BASE(v)               ((uint8_t *)(v)->reg.base)
#define OCIMEM_HW_VERSION(v)         (OCIMEM_BASE(v) + 0x00)
#define OCIMEM_HW_PROFILE(v)         (OCIMEM_BASE(v) + 0x04)
#define OCIMEM_GEN_CTL(v)            (OCIMEM_BASE(v) + 0x08)
#define OCIMEM_GEN_STAT(v)           (OCIMEM_BASE(v) + 0x0C)
#define OCIMEM_INTC_CLR(v)           (OCIMEM_BASE(v) + 0x10)
#define OCIMEM_INTC_MASK(v)          (OCIMEM_BASE(v) + 0x14)
#define OCIMEM_INTC_STAT(v)          (OCIMEM_BASE(v) + 0x18)
#define OCIMEM_OSW_STATUS(v)         (OCIMEM_BASE(v) + 0x1C)
#define OCIMEM_PSCGC_TIMERS(v)       (OCIMEM_BASE(v) + 0x34)
#define OCIMEM_PSCGC_STAT(v)         (OCIMEM_BASE(v) + 0x38)
#define OCIMEM_PSCGC_M0_M7_CTL(v)    (OCIMEM_BASE(v) + 0x3C)
#define OCIMEM_ERR_ADDRESS(v)        (OCIMEM_BASE(v) + 0x60)
#define OCIMEM_AXI_ERR_SYNDROME(v)   (OCIMEM_BASE(v) + 0x64)
#define OCIMEM_DEBUG_CTL(v)          (OCIMEM_BASE(v) + 0x68)

/*
 * Helper macro to help out with masks and shifts for values packed into
 * registers.
 */
#define DECLARE_TYPE(__type, __end, __start)                                   \
	static const unsigned int __type##_BITS = (__end) - (__start) + 1;     \
	static const unsigned int __type##_SHIFT = (__start);                  \
	static const unsigned int __type##_MASK = GENMASK((__end), (__start)); \
	static inline unsigned int __type(uint32_t val)                        \
	{                                                                      \
		return (val & __type##_MASK) >> __type##_SHIFT;                \
	}                                                                      \
	static inline uint32_t __type##_UPDATE(unsigned int val)               \
	{                                                                      \
		return (val << __type##_SHIFT) & __type##_MASK;                \
	}

/* Register masks */
/* OCIMEM_PSCGC_M0_M7_CTL */
DECLARE_TYPE(BANK0_STATE, 3, 0);
DECLARE_TYPE(BANK1_STATE, 7, 4);
DECLARE_TYPE(BANK2_STATE, 11, 8);
DECLARE_TYPE(BANK3_STATE, 15, 12);
/* OCIMEM_PSCGC_TIMERS */
DECLARE_TYPE(TIMERS_WAKEUP, 3, 0);
DECLARE_TYPE(TIMERS_SLEEP, 11, 8);
/* OCIMEM_HW_VERSION */
DECLARE_TYPE(VERSION_STEP, 15, 0);
DECLARE_TYPE(VERSION_MINOR, 27, 16);
DECLARE_TYPE(VERSION_MAJOR, 31, 28);
/* OCIMEM_HW_PROFILE */
DECLARE_TYPE(PROFILE_BANKS, 16, 12);
/* OCIMEM_AXI_ERR_SYNDROME */
DECLARE_TYPE(ERR_SYN_ATID, 14, 8);
DECLARE_TYPE(ERR_SYN_AMID, 23, 16);
DECLARE_TYPE(ERR_SYN_APID, 28, 24);
DECLARE_TYPE(ERR_SYN_ABID, 31, 29);
/* OCIMEM_INTC_MASK */
DECLARE_TYPE(AXI_ERR_INT, 0, 0);

/* Internal stuff */
#define MAX_BANKS 4

enum bank_state {
	BANK_STATE_NORM_PASSTHRU = 0,
	BANK_STATE_NORM_FORCE_CORE_ON = 2,
	BANK_STATE_NORM_FORCE_PERIPH_ON = 1,
	BANK_STATE_NORM_FORCE_ALL_ON = 3,
	BANK_STATE_SLEEP_RET = 6,
	BANK_STATE_SLEEP_RET_PERIPH_ON = 7,
	BANK_STATE_SLEEP_NO_RET = 4,
};

struct vmem {
	int irq;
	int num_banks;
	int bank_size;
	struct {
		struct resource *resource;
		void __iomem *base;
	} reg, mem;
	struct regulator *vdd;
	struct {
		const char *name;
		struct clk *clk;
	} *clocks;
	int num_clocks;
	struct {
		struct msm_bus_scale_pdata *pdata;
		uint32_t priv;
	} bus;
	atomic_t alloc_count;
	struct dentry *debugfs_root;
};

static struct vmem *vmem;

static inline u32 __readl(void * __iomem addr)
{
	u32 value = 0;

	pr_debug("read %pK ", addr);
	value = readl_relaxed(addr);
	pr_debug("-> %08x\n", value);

	return value;
}

static inline void __writel(u32 val, void * __iomem addr)
{
	pr_debug("write %08x -> %pK\n", val, addr);
	writel_relaxed(val, addr);
	/*
	 * Commit all writes via a mem barrier, as subsequent __readl()
	 * will depend on the state that's set via __writel().
	 */
	mb();
}

static inline void __wait_timer(struct vmem *v, bool wakeup)
{
	uint32_t ticks = 0;
	unsigned int (*timer)(uint32_t) = wakeup ?
		TIMERS_WAKEUP : TIMERS_SLEEP;

	ticks = timer(__readl(OCIMEM_PSCGC_TIMERS(v)));

	/* Sleep for `ticks` nanoseconds as per h/w spec */
	ndelay(ticks);
}

static inline void __wait_wakeup(struct vmem *v)
{
	return __wait_timer(v, true);
}

static inline void __wait_sleep(struct vmem *v)
{
	return __wait_timer(v, false);
}

static inline int __power_on(struct vmem *v)
{
	int rc = 0, c = 0;

	rc = msm_bus_scale_client_update_request(v->bus.priv, 1);
	if (rc) {
		pr_err("Failed to vote for buses (%d)\n", rc);
		goto exit;
	}
	pr_debug("Voted for buses\n");

	rc = regulator_enable(v->vdd);
	if (rc) {
		pr_err("Failed to power on gdsc (%d)", rc);
		goto unvote_bus;
	}
	pr_debug("Enabled regulator vdd\n");

	for (c = 0; c < v->num_clocks; ++c) {
		rc = clk_prepare_enable(v->clocks[c].clk);
		if (rc) {
			pr_err("Failed to enable %s clock (%d)\n",
					v->clocks[c].name, rc);
			goto disable_clocks;
		}

		pr_debug("Enabled clock %s\n", v->clocks[c].name);
	}

	return 0;
disable_clocks:
	for (--c; c >= 0; c--)
		clk_disable_unprepare(v->clocks[c].clk);
	regulator_disable(v->vdd);
unvote_bus:
	msm_bus_scale_client_update_request(v->bus.priv, 0);
exit:
	return rc;
}

static inline int __power_off(struct vmem *v)
{
	int c = 0;

	for (c = 0; c < v->num_clocks; ++c) {
		clk_disable_unprepare(v->clocks[c].clk);
		pr_debug("Disabled clock %s\n", v->clocks[c].name);
	}

	regulator_disable(v->vdd);
	pr_debug("Disabled regulator vdd\n");

	msm_bus_scale_client_update_request(v->bus.priv, 0);
	pr_debug("Unvoted for buses\n");

	return 0;
}

static inline enum bank_state __bank_get_state(struct vmem *v,
		unsigned int bank)
{
	unsigned int (*func[MAX_BANKS])(uint32_t) = {
		BANK0_STATE, BANK1_STATE, BANK2_STATE, BANK3_STATE
	};

	WARN_ON(bank >= ARRAY_SIZE(func));
	return func[bank](__readl(OCIMEM_PSCGC_M0_M7_CTL(v)));
}

static inline void __bank_set_state(struct vmem *v, unsigned int bank,
		enum bank_state state)
{
	uint32_t bank_state = 0;
	struct {
		uint32_t (*update)(unsigned int);
		uint32_t mask;
	} banks[MAX_BANKS] = {
		{BANK0_STATE_UPDATE, BANK0_STATE_MASK},
		{BANK1_STATE_UPDATE, BANK1_STATE_MASK},
		{BANK2_STATE_UPDATE, BANK2_STATE_MASK},
		{BANK3_STATE_UPDATE, BANK3_STATE_MASK},
	};

	WARN_ON(bank >= ARRAY_SIZE(banks));

	bank_state = __readl(OCIMEM_PSCGC_M0_M7_CTL(v));
	bank_state &= ~banks[bank].mask;
	bank_state |= banks[bank].update(state);

	__writel(bank_state, OCIMEM_PSCGC_M0_M7_CTL(v));
}

static inline void __toggle_interrupts(struct vmem *v, bool enable)
{
	uint32_t ints = __readl(OCIMEM_INTC_MASK(v)),
		mask = AXI_ERR_INT_MASK,
		update = AXI_ERR_INT_UPDATE(!enable);

	ints &= ~mask;
	ints |= update;

	__writel(ints, OCIMEM_INTC_MASK(v));
}

static void __enable_interrupts(struct vmem *v)
{
	pr_debug("Enabling interrupts\n");
	enable_irq(v->irq);
	__toggle_interrupts(v, true);
}

static void __disable_interrupts(struct vmem *v)
{
	pr_debug("Disabling interrupts\n");
	__toggle_interrupts(v, false);
	disable_irq_nosync(v->irq);
}

/**
 * vmem_allocate: - Allocates memory from VMEM.  Allocations have a few
 * restrictions: only allocations of the entire VMEM memory are allowed, and
 * , as a result, only single outstanding allocations are allowed.
 *
 * @size: amount of bytes to allocate
 * @addr: A pointer to phys_addr_t where the physical address of the memory
 * allocated is stored.
 *
 * Return: 0 in case of successful allocation (i.e. *addr != NULL). -ENOTSUPP,
 * if platform doesn't support VMEM. -EEXIST, if there are outstanding VMEM
 * allocations.  -ENOMEM, if platform can't support allocation of `size` bytes.
 * -EAGAIN, if `size` does not allocate the entire VMEM region.  -EIO in case of
 * internal errors.
 */
int vmem_allocate(size_t size, phys_addr_t *addr)
{
	int rc = 0, c = 0;
	resource_size_t max_size = 0;

	if (!vmem) {
		pr_err("No vmem, try rebooting your device\n");
		rc = -ENOTSUPP;
		goto exit;
	}
	if (!size) {
		pr_err("%s Invalid size %ld\n", __func__, size);
		rc = -EINVAL;
		goto exit;
	}

	max_size = resource_size(vmem->mem.resource);

	if (atomic_read(&vmem->alloc_count)) {
		pr_err("Only single allocations allowed for vmem\n");
		rc = -EEXIST;
		goto exit;
	} else if (size > max_size) {
		pr_err("Out of memory, have max %pa\n", &max_size);
		rc = -ENOMEM;
		goto exit;
	} else if (size != max_size) {
		pr_err("Only support allocations of size %pa\n", &max_size);
		rc = -EAGAIN;
		goto exit;
	}

	rc = __power_on(vmem);
	if (rc) {
		pr_err("Failed power on (%d)\n", rc);
		goto exit;
	}

	WARN_ON(vmem->num_banks != DIV_ROUND_UP(size, vmem->bank_size));

	/* Turn on the necessary banks */
	for (c = 0; c < vmem->num_banks; ++c) {
		__bank_set_state(vmem, c, BANK_STATE_NORM_FORCE_CORE_ON);
		__wait_wakeup(vmem);
	}

	/* Enable interrupts to detect faults */
	__enable_interrupts(vmem);

	atomic_inc(&vmem->alloc_count);
	*addr = (phys_addr_t)vmem->mem.resource->start;
	return 0;
exit:
	return rc;
}

/**
 * vmem_free: - Frees the memory allocated via vmem_allocate.  Undefined
 * behaviour if to_free is a not a pointer returned via vmem_allocate
 */
void vmem_free(phys_addr_t to_free)
{
	int c = 0;

	if (!to_free || !vmem)
		return;

	WARN_ON(atomic_read(&vmem->alloc_count) == 0);

	for (c = 0; c < vmem->num_banks; ++c) {
		enum bank_state curr_state = __bank_get_state(vmem, c);

		if (curr_state != BANK_STATE_NORM_FORCE_CORE_ON) {
			pr_warn("When freeing, expected bank state to be %d, was instead %d\n",
					BANK_STATE_NORM_FORCE_CORE_ON,
					curr_state);
		}

		__bank_set_state(vmem, c, BANK_STATE_SLEEP_NO_RET);
	}

	__disable_interrupts(vmem);
	__power_off(vmem);
	atomic_dec(&vmem->alloc_count);
}

struct vmem_interrupt_cookie {
	struct vmem *vmem;
	struct work_struct work;
};

static void __irq_helper(struct work_struct *work)
{
	struct vmem_interrupt_cookie *cookie = container_of(work,
			struct vmem_interrupt_cookie, work);
	struct vmem *v = cookie->vmem;
	unsigned int stat, gen_stat, pscgc_stat, err_addr_abs,
		err_addr_rel, err_syn;

	stat = __readl(OCIMEM_INTC_STAT(v));
	gen_stat = __readl(OCIMEM_GEN_CTL(v));
	pscgc_stat = __readl(OCIMEM_PSCGC_STAT(v));

	err_addr_abs = __readl(OCIMEM_ERR_ADDRESS(v));
	err_addr_rel = v->mem.resource->start - err_addr_abs;

	err_syn = __readl(OCIMEM_AXI_ERR_SYNDROME(v));

	pr_crit("Detected a fault on VMEM:\n");
	pr_cont("\tinterrupt status: %x\n", stat);
	pr_cont("\tgeneral status: %x\n", gen_stat);
	pr_cont("\tmemory status: %x\n", pscgc_stat);
	pr_cont("\tfault address: %x (absolute), %x (relative)\n",
			err_addr_abs, err_addr_rel);
	pr_cont("\tfault bank: %x\n", err_addr_rel / v->bank_size);
	pr_cont("\tfault core: %u (mid), %u (pid), %u (bid)\n",
			ERR_SYN_AMID(err_syn), ERR_SYN_APID(err_syn),
			ERR_SYN_ABID(err_syn));

	/* Clear the interrupt */
	__writel(0, OCIMEM_INTC_CLR(v));

	__enable_interrupts(v);
}

static struct vmem_interrupt_cookie interrupt_cookie;

static irqreturn_t __irq_handler(int irq, void *cookie)
{
	struct vmem *v = cookie;
	irqreturn_t status = __readl(OCIMEM_INTC_STAT(vmem)) ?
		IRQ_HANDLED : IRQ_NONE;

	if (status != IRQ_NONE) {
		/* Mask further interrupts while handling this one */
		__disable_interrupts(v);

		interrupt_cookie.vmem = v;
		INIT_WORK(&interrupt_cookie.work, __irq_helper);
		schedule_work(&interrupt_cookie.work);
	}

	return status;
}

static inline int __init_resources(struct vmem *v,
		struct platform_device *pdev)
{
	int rc = 0, c = 0;

	v->irq = platform_get_irq(pdev, 0);
	if (v->irq < 0) {
		rc = v->irq;
		pr_err("Failed to get irq (%d)\n", rc);
		v->irq = 0;
		goto exit;
	}

	/* Registers and memory */
	v->reg.resource = platform_get_resource_byname(pdev, IORESOURCE_MEM,
			"reg-base");
	if (!v->reg.resource) {
		pr_err("Failed to find register base\n");
		rc = -ENOENT;
		goto exit;
	}

	v->reg.base = devm_ioremap_resource(&pdev->dev, v->reg.resource);
	if (IS_ERR_OR_NULL(v->reg.base)) {
		rc = PTR_ERR(v->reg.base) ?: -EIO;
		pr_err("Failed to map register base into kernel (%d)\n", rc);
		v->reg.base = NULL;
		goto exit;
	}

	pr_debug("Register range: %pa -> %pa\n", &v->reg.resource->start,
			&v->reg.resource->end);

	v->mem.resource = platform_get_resource_byname(pdev, IORESOURCE_MEM,
			"mem-base");
	if (!v->mem.resource) {
		pr_err("Failed to find memory base\n");
		rc = -ENOENT;
		goto exit;
	}

	v->mem.base = NULL;
	pr_debug("Memory range: %pa -> %pa\n", &v->mem.resource->start,
			&v->mem.resource->end);

	/* Buses, Clocks & Regulators*/
	v->num_clocks = of_property_count_strings(pdev->dev.of_node,
			"clock-names");
	if (v->num_clocks <= 0) {
		pr_err("Can't find any clocks\n");
		goto exit;
	}

	v->clocks = devm_kzalloc(&pdev->dev, sizeof(*v->clocks) * v->num_clocks,
			GFP_KERNEL);
	if (!v->clocks) {
		rc = -ENOMEM;
		goto exit;
	}

	for (c = 0; c < v->num_clocks; ++c) {
		const char *name = NULL;
		struct clk *temp = NULL;

		of_property_read_string_index(pdev->dev.of_node, "clock-names",
				c, &name);
		temp = devm_clk_get(&pdev->dev, name);
		if (IS_ERR_OR_NULL(temp)) {
			rc = PTR_ERR(temp) ?: -ENOENT;
			pr_err("Failed to find %s (%d)\n", name, rc);
			goto exit;
		}

		v->clocks[c].clk = temp;
		v->clocks[c].name = name;
	}

	v->vdd = devm_regulator_get(&pdev->dev, "vdd");
	if (IS_ERR_OR_NULL(v->vdd)) {
		rc = PTR_ERR(v->vdd) ?: -ENOENT;
		pr_err("Failed to find regulator (vdd) (%d)\n", rc);
		goto exit;
	}

	v->bus.pdata = msm_bus_cl_get_pdata(pdev);
	if (IS_ERR_OR_NULL(v->bus.pdata)) {
		rc = PTR_ERR(v->bus.pdata) ?: -ENOENT;
		pr_err("Failed to find bus vectors (%d)\n", rc);
		goto exit;
	}

	v->bus.priv = msm_bus_scale_register_client(v->bus.pdata);
	if (!v->bus.priv) {
		rc = -EBADHANDLE;
		pr_err("Failed to register bus client\n");
		goto free_pdata;
	}

	/* Misc. */
	rc = of_property_read_u32(pdev->dev.of_node, "qcom,bank-size",
			&v->bank_size);
	if (rc || !v->bank_size) {
		pr_err("Failed reading (or found invalid) qcom,bank-size in %s (%d)\n",
				of_node_full_name(pdev->dev.of_node), rc);
		rc = -ENOENT;
		goto free_pdata;
	}

	v->num_banks = resource_size(v->mem.resource) / v->bank_size;

	pr_debug("Found configuration with %d banks with size %d\n",
			v->num_banks, v->bank_size);

	return 0;
free_pdata:
	msm_bus_cl_clear_pdata(v->bus.pdata);
exit:
	return rc;
}

static inline void __uninit_resources(struct vmem *v,
		struct platform_device *pdev)
{
	int c = 0;

	msm_bus_cl_clear_pdata(v->bus.pdata);
	v->bus.pdata = NULL;
	v->bus.priv = 0;

	for (c = 0; c < v->num_clocks; ++c) {
		v->clocks[c].clk = NULL;
		v->clocks[c].name = NULL;
	}

	v->vdd = NULL;
}

static int vmem_probe(struct platform_device *pdev)
{
	uint32_t version = 0, num_banks = 0, rc = 0;
	struct vmem *v = NULL;

	if (vmem) {
		pr_err("Only one instance of %s allowed", pdev->name);
		return -EEXIST;
	}

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

	rc = __init_resources(v, pdev);
	if (rc) {
		pr_err("Failed to read resources\n");
		goto exit;
	}

	/*
	 * For now, only support up to 4 banks. It's unrealistic that VMEM has
	 * more banks than that (even in the future).
	 */
	if (v->num_banks > MAX_BANKS) {
		pr_err("Number of banks (%d) exceeds what's supported (%d)\n",
			v->num_banks, MAX_BANKS);
		rc = -ENOTSUPP;
		goto exit;
	}

	/* Cross check the platform resources with what's available on chip */
	rc = __power_on(v);
	if (rc) {
		pr_err("Failed to power on (%d)\n", rc);
		goto exit;
	}

	version = __readl(OCIMEM_HW_VERSION(v));
	pr_debug("v%d.%d.%d\n", VERSION_MAJOR(version), VERSION_MINOR(version),
			VERSION_STEP(version));

	num_banks = PROFILE_BANKS(__readl(OCIMEM_HW_PROFILE(v)));
	pr_debug("Found %d banks on chip\n", num_banks);
	if (v->num_banks != num_banks) {
		pr_err("Platform configuration of %d banks differs from what's available on chip (%d)\n",
				v->num_banks, num_banks);
		rc = -EINVAL;
		goto disable_clocks;
	}

	rc = devm_request_irq(&pdev->dev, v->irq, __irq_handler,
			IRQF_TRIGGER_HIGH, "vmem", v);
	if (rc) {
		pr_err("Failed to setup irq (%d)\n", rc);
		goto disable_clocks;
	}

	__disable_interrupts(v);

	/* Everything good so far, set up the global context and debug hooks */
	pr_info("Up and running with %d banks of memory from %pR\n",
			v->num_banks, &v->mem.resource);
	v->debugfs_root = vmem_debugfs_init(pdev);
	platform_set_drvdata(pdev, v);
	vmem = v;

disable_clocks:
	__power_off(v);
exit:
	return rc;
}

static int vmem_remove(struct platform_device *pdev)
{
	struct vmem *v = platform_get_drvdata(pdev);

	WARN_ON(v != vmem);

	__uninit_resources(v, pdev);
	vmem_debugfs_deinit(v->debugfs_root);
	vmem = NULL;

	return 0;
}

static const struct of_device_id vmem_of_match[] = {
	{.compatible = "qcom,msm-vmem"},
	{}
};

MODULE_DEVICE_TABLE(of, vmem_of_match);

static struct platform_driver vmem_driver = {
	.probe = vmem_probe,
	.remove = vmem_remove,
	.driver = {
		.name = "msm_vidc_vmem",
		.owner = THIS_MODULE,
		.of_match_table = vmem_of_match,
	},
};

static int __init vmem_init(void)
{
	return platform_driver_register(&vmem_driver);
}

static void __exit vmem_exit(void)
{
	platform_driver_unregister(&vmem_driver);
}

module_init(vmem_init);
module_exit(vmem_exit);
