// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright 2015 Chen-Yu Tsai
 *
 * Chen-Yu Tsai <wens@csie.org>
 */

#include <linux/clk-provider.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/reset-controller.h>
#include <linux/slab.h>
#include <linux/spinlock.h>

static DEFINE_SPINLOCK(ve_lock);

#define SUN4I_VE_ENABLE		31
#define SUN4I_VE_DIVIDER_SHIFT	16
#define SUN4I_VE_DIVIDER_WIDTH	3
#define SUN4I_VE_RESET		0

/**
 * sunxi_ve_reset... - reset bit in ve clk registers handling
 */

struct ve_reset_data {
	void __iomem			*reg;
	spinlock_t			*lock;
	struct reset_controller_dev	rcdev;
};

static int sunxi_ve_reset_assert(struct reset_controller_dev *rcdev,
				 unsigned long id)
{
	struct ve_reset_data *data = container_of(rcdev,
						  struct ve_reset_data,
						  rcdev);
	unsigned long flags;
	u32 reg;

	spin_lock_irqsave(data->lock, flags);

	reg = readl(data->reg);
	writel(reg & ~BIT(SUN4I_VE_RESET), data->reg);

	spin_unlock_irqrestore(data->lock, flags);

	return 0;
}

static int sunxi_ve_reset_deassert(struct reset_controller_dev *rcdev,
				   unsigned long id)
{
	struct ve_reset_data *data = container_of(rcdev,
						  struct ve_reset_data,
						  rcdev);
	unsigned long flags;
	u32 reg;

	spin_lock_irqsave(data->lock, flags);

	reg = readl(data->reg);
	writel(reg | BIT(SUN4I_VE_RESET), data->reg);

	spin_unlock_irqrestore(data->lock, flags);

	return 0;
}

static int sunxi_ve_of_xlate(struct reset_controller_dev *rcdev,
			     const struct of_phandle_args *reset_spec)
{
	if (WARN_ON(reset_spec->args_count != 0))
		return -EINVAL;

	return 0;
}

static const struct reset_control_ops sunxi_ve_reset_ops = {
	.assert		= sunxi_ve_reset_assert,
	.deassert	= sunxi_ve_reset_deassert,
};

static void __init sun4i_ve_clk_setup(struct device_node *node)
{
	struct clk *clk;
	struct clk_divider *div;
	struct clk_gate *gate;
	struct ve_reset_data *reset_data;
	const char *parent;
	const char *clk_name = node->name;
	void __iomem *reg;
	int err;

	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
	if (IS_ERR(reg))
		return;

	div = kzalloc(sizeof(*div), GFP_KERNEL);
	if (!div)
		goto err_unmap;

	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
	if (!gate)
		goto err_free_div;

	of_property_read_string(node, "clock-output-names", &clk_name);
	parent = of_clk_get_parent_name(node, 0);

	gate->reg = reg;
	gate->bit_idx = SUN4I_VE_ENABLE;
	gate->lock = &ve_lock;

	div->reg = reg;
	div->shift = SUN4I_VE_DIVIDER_SHIFT;
	div->width = SUN4I_VE_DIVIDER_WIDTH;
	div->lock = &ve_lock;

	clk = clk_register_composite(NULL, clk_name, &parent, 1,
				     NULL, NULL,
				     &div->hw, &clk_divider_ops,
				     &gate->hw, &clk_gate_ops,
				     CLK_SET_RATE_PARENT);
	if (IS_ERR(clk))
		goto err_free_gate;

	err = of_clk_add_provider(node, of_clk_src_simple_get, clk);
	if (err)
		goto err_unregister_clk;

	reset_data = kzalloc(sizeof(*reset_data), GFP_KERNEL);
	if (!reset_data)
		goto err_del_provider;

	reset_data->reg = reg;
	reset_data->lock = &ve_lock;
	reset_data->rcdev.nr_resets = 1;
	reset_data->rcdev.ops = &sunxi_ve_reset_ops;
	reset_data->rcdev.of_node = node;
	reset_data->rcdev.of_xlate = sunxi_ve_of_xlate;
	reset_data->rcdev.of_reset_n_cells = 0;
	err = reset_controller_register(&reset_data->rcdev);
	if (err)
		goto err_free_reset;

	return;

err_free_reset:
	kfree(reset_data);
err_del_provider:
	of_clk_del_provider(node);
err_unregister_clk:
	clk_unregister(clk);
err_free_gate:
	kfree(gate);
err_free_div:
	kfree(div);
err_unmap:
	iounmap(reg);
}
CLK_OF_DECLARE(sun4i_ve, "allwinner,sun4i-a10-ve-clk",
	       sun4i_ve_clk_setup);
