// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2019 Intel Corporation.
 * Lei Chuanhua <Chuanhua.lei@intel.com>
 */

#include <linux/bitfield.h>
#include <linux/init.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/reboot.h>
#include <linux/regmap.h>
#include <linux/reset-controller.h>

#define RCU_RST_STAT	0x0024
#define RCU_RST_REQ	0x0048

#define REG_OFFSET	GENMASK(31, 16)
#define BIT_OFFSET	GENMASK(15, 8)
#define STAT_BIT_OFFSET	GENMASK(7, 0)

#define to_reset_data(x)	container_of(x, struct intel_reset_data, rcdev)

struct intel_reset_soc {
	bool legacy;
	u32 reset_cell_count;
};

struct intel_reset_data {
	struct reset_controller_dev rcdev;
	struct notifier_block restart_nb;
	const struct intel_reset_soc *soc_data;
	struct regmap *regmap;
	struct device *dev;
	u32 reboot_id;
};

static const struct regmap_config intel_rcu_regmap_config = {
	.name =		"intel-reset",
	.reg_bits =	32,
	.reg_stride =	4,
	.val_bits =	32,
	.fast_io =	true,
};

/*
 * Reset status register offset relative to
 * the reset control register(X) is X + 4
 */
static u32 id_to_reg_and_bit_offsets(struct intel_reset_data *data,
				     unsigned long id, u32 *rst_req,
				     u32 *req_bit, u32 *stat_bit)
{
	*rst_req = FIELD_GET(REG_OFFSET, id);
	*req_bit = FIELD_GET(BIT_OFFSET, id);

	if (data->soc_data->legacy)
		*stat_bit = FIELD_GET(STAT_BIT_OFFSET, id);
	else
		*stat_bit = *req_bit;

	if (data->soc_data->legacy && *rst_req == RCU_RST_REQ)
		return RCU_RST_STAT;
	else
		return *rst_req + 0x4;
}

static int intel_set_clr_bits(struct intel_reset_data *data, unsigned long id,
			      bool set)
{
	u32 rst_req, req_bit, rst_stat, stat_bit, val;
	int ret;

	rst_stat = id_to_reg_and_bit_offsets(data, id, &rst_req,
					     &req_bit, &stat_bit);

	val = set ? BIT(req_bit) : 0;
	ret = regmap_update_bits(data->regmap, rst_req,  BIT(req_bit), val);
	if (ret)
		return ret;

	return regmap_read_poll_timeout(data->regmap, rst_stat, val,
					set == !!(val & BIT(stat_bit)), 20,
					200);
}

static int intel_assert_device(struct reset_controller_dev *rcdev,
			       unsigned long id)
{
	struct intel_reset_data *data = to_reset_data(rcdev);
	int ret;

	ret = intel_set_clr_bits(data, id, true);
	if (ret)
		dev_err(data->dev, "Reset assert failed %d\n", ret);

	return ret;
}

static int intel_deassert_device(struct reset_controller_dev *rcdev,
				 unsigned long id)
{
	struct intel_reset_data *data = to_reset_data(rcdev);
	int ret;

	ret = intel_set_clr_bits(data, id, false);
	if (ret)
		dev_err(data->dev, "Reset deassert failed %d\n", ret);

	return ret;
}

static int intel_reset_status(struct reset_controller_dev *rcdev,
			      unsigned long id)
{
	struct intel_reset_data *data = to_reset_data(rcdev);
	u32 rst_req, req_bit, rst_stat, stat_bit, val;
	int ret;

	rst_stat = id_to_reg_and_bit_offsets(data, id, &rst_req,
					     &req_bit, &stat_bit);
	ret = regmap_read(data->regmap, rst_stat, &val);
	if (ret)
		return ret;

	return !!(val & BIT(stat_bit));
}

static const struct reset_control_ops intel_reset_ops = {
	.assert =	intel_assert_device,
	.deassert =	intel_deassert_device,
	.status	=	intel_reset_status,
};

static int intel_reset_xlate(struct reset_controller_dev *rcdev,
			     const struct of_phandle_args *spec)
{
	struct intel_reset_data *data = to_reset_data(rcdev);
	u32 id;

	if (spec->args[1] > 31)
		return -EINVAL;

	id = FIELD_PREP(REG_OFFSET, spec->args[0]);
	id |= FIELD_PREP(BIT_OFFSET, spec->args[1]);

	if (data->soc_data->legacy) {
		if (spec->args[2] > 31)
			return -EINVAL;

		id |= FIELD_PREP(STAT_BIT_OFFSET, spec->args[2]);
	}

	return id;
}

static int intel_reset_restart_handler(struct notifier_block *nb,
				       unsigned long action, void *data)
{
	struct intel_reset_data *reset_data;

	reset_data = container_of(nb, struct intel_reset_data, restart_nb);
	intel_assert_device(&reset_data->rcdev, reset_data->reboot_id);

	return NOTIFY_DONE;
}

static int intel_reset_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct device *dev = &pdev->dev;
	struct intel_reset_data *data;
	void __iomem *base;
	u32 rb_id[3];
	int ret;

	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	data->soc_data = of_device_get_match_data(dev);
	if (!data->soc_data)
		return -ENODEV;

	base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(base))
		return PTR_ERR(base);

	data->regmap = devm_regmap_init_mmio(dev, base,
					     &intel_rcu_regmap_config);
	if (IS_ERR(data->regmap)) {
		dev_err(dev, "regmap initialization failed\n");
		return PTR_ERR(data->regmap);
	}

	ret = device_property_read_u32_array(dev, "intel,global-reset", rb_id,
					     data->soc_data->reset_cell_count);
	if (ret) {
		dev_err(dev, "Failed to get global reset offset!\n");
		return ret;
	}

	data->dev =			dev;
	data->rcdev.of_node =		np;
	data->rcdev.owner =		dev->driver->owner;
	data->rcdev.ops	=		&intel_reset_ops;
	data->rcdev.of_xlate =		intel_reset_xlate;
	data->rcdev.of_reset_n_cells =	data->soc_data->reset_cell_count;
	ret = devm_reset_controller_register(&pdev->dev, &data->rcdev);
	if (ret)
		return ret;

	data->reboot_id = FIELD_PREP(REG_OFFSET, rb_id[0]);
	data->reboot_id |= FIELD_PREP(BIT_OFFSET, rb_id[1]);

	if (data->soc_data->legacy)
		data->reboot_id |= FIELD_PREP(STAT_BIT_OFFSET, rb_id[2]);

	data->restart_nb.notifier_call =	intel_reset_restart_handler;
	data->restart_nb.priority =		128;
	register_restart_handler(&data->restart_nb);

	return 0;
}

static const struct intel_reset_soc xrx200_data = {
	.legacy =		true,
	.reset_cell_count =	3,
};

static const struct intel_reset_soc lgm_data = {
	.legacy =		false,
	.reset_cell_count =	2,
};

static const struct of_device_id intel_reset_match[] = {
	{ .compatible = "intel,rcu-lgm", .data = &lgm_data },
	{ .compatible = "intel,rcu-xrx200", .data = &xrx200_data },
	{}
};

static struct platform_driver intel_reset_driver = {
	.probe = intel_reset_probe,
	.driver = {
		.name = "intel-reset",
		.of_match_table = intel_reset_match,
	},
};

static int __init intel_reset_init(void)
{
	return platform_driver_register(&intel_reset_driver);
}

/*
 * RCU is system core entity which is in Always On Domain whose clocks
 * or resource initialization happens in system core initialization.
 * Also, it is required for most of the platform or architecture
 * specific devices to perform reset operation as part of initialization.
 * So perform RCU as post core initialization.
 */
postcore_initcall(intel_reset_init);
