/*
 * Copyright (C) 2017 Synopsys.
 *
 * Synopsys HSDKv1 SDP reset driver.
 *
 * This file is licensed under the terms of the GNU General Public
 * License version 2. This program is licensed "as is" without any
 * warranty of any kind, whether express or implied.
 */

#include <linux/delay.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/reset-controller.h>
#include <linux/slab.h>
#include <linux/types.h>

#define to_hsdkv1_rst(p)	container_of((p), struct hsdkv1_rst, rcdev)

struct hsdkv1_rst {
	void __iomem			*regs_ctl;
	void __iomem			*regs_rst;
	spinlock_t			lock;
	struct reset_controller_dev	rcdev;
};

static const u32 rst_map[] = {
	BIT(16), /* APB_RST  */
	BIT(17), /* AXI_RST  */
	BIT(18), /* ETH_RST  */
	BIT(19), /* USB_RST  */
	BIT(20), /* SDIO_RST */
	BIT(21), /* HDMI_RST */
	BIT(22), /* GFX_RST  */
	BIT(25), /* DMAC_RST */
	BIT(31), /* EBI_RST  */
};

#define HSDK_MAX_RESETS			ARRAY_SIZE(rst_map)

#define CGU_SYS_RST_CTRL		0x0
#define CGU_IP_SW_RESET			0x0
#define CGU_IP_SW_RESET_DELAY_SHIFT	16
#define CGU_IP_SW_RESET_DELAY_MASK	GENMASK(31, CGU_IP_SW_RESET_DELAY_SHIFT)
#define CGU_IP_SW_RESET_DELAY		0
#define CGU_IP_SW_RESET_RESET		BIT(0)
#define SW_RESET_TIMEOUT		10000

static void hsdkv1_reset_config(struct hsdkv1_rst *rst, unsigned long id)
{
	writel(rst_map[id], rst->regs_ctl + CGU_SYS_RST_CTRL);
}

static int hsdkv1_reset_do(struct hsdkv1_rst *rst)
{
	u32 reg;

	reg = readl(rst->regs_rst + CGU_IP_SW_RESET);
	reg &= ~CGU_IP_SW_RESET_DELAY_MASK;
	reg |= CGU_IP_SW_RESET_DELAY << CGU_IP_SW_RESET_DELAY_SHIFT;
	reg |= CGU_IP_SW_RESET_RESET;
	writel(reg, rst->regs_rst + CGU_IP_SW_RESET);

	/* wait till reset bit is back to 0 */
	return readl_poll_timeout_atomic(rst->regs_rst + CGU_IP_SW_RESET, reg,
		!(reg & CGU_IP_SW_RESET_RESET), 5, SW_RESET_TIMEOUT);
}

static int hsdkv1_reset_reset(struct reset_controller_dev *rcdev,
			      unsigned long id)
{
	struct hsdkv1_rst *rst = to_hsdkv1_rst(rcdev);
	unsigned long flags;
	int ret;

	spin_lock_irqsave(&rst->lock, flags);
	hsdkv1_reset_config(rst, id);
	ret = hsdkv1_reset_do(rst);
	spin_unlock_irqrestore(&rst->lock, flags);

	return ret;
}

static const struct reset_control_ops hsdkv1_reset_ops = {
	.reset	= hsdkv1_reset_reset,
};

static int hsdkv1_reset_probe(struct platform_device *pdev)
{
	struct hsdkv1_rst *rst;
	struct resource *mem;

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

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	rst->regs_ctl = devm_ioremap_resource(&pdev->dev, mem);
	if (IS_ERR(rst->regs_ctl))
		return PTR_ERR(rst->regs_ctl);

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	rst->regs_rst = devm_ioremap_resource(&pdev->dev, mem);
	if (IS_ERR(rst->regs_rst))
		return PTR_ERR(rst->regs_rst);

	spin_lock_init(&rst->lock);

	rst->rcdev.owner = THIS_MODULE;
	rst->rcdev.ops = &hsdkv1_reset_ops;
	rst->rcdev.of_node = pdev->dev.of_node;
	rst->rcdev.nr_resets = HSDK_MAX_RESETS;
	rst->rcdev.of_reset_n_cells = 1;

	return reset_controller_register(&rst->rcdev);
}

static const struct of_device_id hsdkv1_reset_dt_match[] = {
	{ .compatible = "snps,hsdk-v1.0-reset" },
	{ },
};

static struct platform_driver hsdkv1_reset_driver = {
	.probe	= hsdkv1_reset_probe,
	.driver	= {
		.name = "hsdk-v1.0-reset",
		.of_match_table = hsdkv1_reset_dt_match,
	},
};
builtin_platform_driver(hsdkv1_reset_driver);

MODULE_AUTHOR("Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>");
MODULE_DESCRIPTION("Synopsys HSDKv1 SDP reset driver");
MODULE_LICENSE("GPL v2");
