// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (c) 2014 MundoReader S.L.
 * Author: Heiko Stuebner <heiko@sntech.de>
 */

#include <linux/slab.h>
#include <linux/io.h>
#include <linux/reset-controller.h>
#include <linux/spinlock.h>
#include "clk.h"

struct rockchip_softrst {
	struct reset_controller_dev	rcdev;
	const int			*lut;
	void __iomem			*reg_base;
	int				num_regs;
	int				num_per_reg;
	u8				flags;
	spinlock_t			lock;
};

static int rockchip_softrst_assert(struct reset_controller_dev *rcdev,
			      unsigned long id)
{
	struct rockchip_softrst *softrst = container_of(rcdev,
						     struct rockchip_softrst,
						     rcdev);
	int bank, offset;

	if (softrst->lut)
		id = softrst->lut[id];

	bank = id / softrst->num_per_reg;
	offset = id % softrst->num_per_reg;

	if (softrst->flags & ROCKCHIP_SOFTRST_HIWORD_MASK) {
		writel(BIT(offset) | (BIT(offset) << 16),
		       softrst->reg_base + (bank * 4));
	} else {
		unsigned long flags;
		u32 reg;

		spin_lock_irqsave(&softrst->lock, flags);

		reg = readl(softrst->reg_base + (bank * 4));
		writel(reg | BIT(offset), softrst->reg_base + (bank * 4));

		spin_unlock_irqrestore(&softrst->lock, flags);
	}

	return 0;
}

static int rockchip_softrst_deassert(struct reset_controller_dev *rcdev,
				unsigned long id)
{
	struct rockchip_softrst *softrst = container_of(rcdev,
						     struct rockchip_softrst,
						     rcdev);
	int bank, offset;

	if (softrst->lut)
		id = softrst->lut[id];

	bank = id / softrst->num_per_reg;
	offset = id % softrst->num_per_reg;

	if (softrst->flags & ROCKCHIP_SOFTRST_HIWORD_MASK) {
		writel((BIT(offset) << 16), softrst->reg_base + (bank * 4));
	} else {
		unsigned long flags;
		u32 reg;

		spin_lock_irqsave(&softrst->lock, flags);

		reg = readl(softrst->reg_base + (bank * 4));
		writel(reg & ~BIT(offset), softrst->reg_base + (bank * 4));

		spin_unlock_irqrestore(&softrst->lock, flags);
	}

	return 0;
}

static const struct reset_control_ops rockchip_softrst_ops = {
	.assert		= rockchip_softrst_assert,
	.deassert	= rockchip_softrst_deassert,
};

void rockchip_register_softrst_lut(struct device_node *np,
				   const int *lookup_table,
				   unsigned int num_regs,
				   void __iomem *base, u8 flags)
{
	struct rockchip_softrst *softrst;
	int ret;

	softrst = kzalloc(sizeof(*softrst), GFP_KERNEL);
	if (!softrst)
		return;

	spin_lock_init(&softrst->lock);

	softrst->reg_base = base;
	softrst->lut = lookup_table;
	softrst->flags = flags;
	softrst->num_regs = num_regs;
	softrst->num_per_reg = (flags & ROCKCHIP_SOFTRST_HIWORD_MASK) ? 16
								      : 32;

	softrst->rcdev.owner = THIS_MODULE;
	if (lookup_table)
		softrst->rcdev.nr_resets = num_regs;
	else
		softrst->rcdev.nr_resets = num_regs * softrst->num_per_reg;
	softrst->rcdev.ops = &rockchip_softrst_ops;
	softrst->rcdev.of_node = np;
	ret = reset_controller_register(&softrst->rcdev);
	if (ret) {
		pr_err("%s: could not register reset controller, %d\n",
		       __func__, ret);
		kfree(softrst);
	}
};
EXPORT_SYMBOL_GPL(rockchip_register_softrst_lut);
