// SPDX-License-Identifier: GPL-2.0+
/*
 * OMAP clock controller support
 *
 * Copyright (C) 2020 Dario Binacchi <dariobin@libero.it>
 */

#include <common.h>
#include <dm.h>
#include <dm/device_compat.h>
#include <clk-uclass.h>
#include <asm/arch-am33xx/clock.h>

struct clk_ti_ctrl_offs {
	fdt_addr_t start;
	fdt_size_t end;
};

struct clk_ti_ctrl_priv {
	int offs_num;
	struct clk_ti_ctrl_offs *offs;
};

static int clk_ti_ctrl_check_offs(struct clk *clk, fdt_addr_t offs)
{
	struct clk_ti_ctrl_priv *priv = dev_get_priv(clk->dev);
	int i;

	for (i = 0; i < priv->offs_num; i++) {
		if (offs >= priv->offs[i].start && offs <= priv->offs[i].end)
			return 0;
	}

	return -EFAULT;
}

static int clk_ti_ctrl_disable(struct clk *clk)
{
	struct clk_ti_ctrl_priv *priv = dev_get_priv(clk->dev);
	u32 *clk_modules[2] = { };
	fdt_addr_t offs;
	int err;

	offs = priv->offs[0].start + clk->id;
	err = clk_ti_ctrl_check_offs(clk, offs);
	if (err) {
		dev_err(clk->dev, "invalid offset: 0x%lx\n", offs);
		return err;
	}

	clk_modules[0] = (u32 *)(offs);
	dev_dbg(clk->dev, "disable module @ %p\n", clk_modules[0]);
	do_disable_clocks(NULL, clk_modules, 1);
	return 0;
}

static int clk_ti_ctrl_enable(struct clk *clk)
{
	struct clk_ti_ctrl_priv *priv = dev_get_priv(clk->dev);
	u32 *clk_modules[2] = { };
	fdt_addr_t offs;
	int err;

	offs = priv->offs[0].start + clk->id;
	err = clk_ti_ctrl_check_offs(clk, offs);
	if (err) {
		dev_err(clk->dev, "invalid offset: 0x%lx\n", offs);
		return err;
	}

	clk_modules[0] = (u32 *)(offs);
	dev_dbg(clk->dev, "enable module @ %p\n", clk_modules[0]);
	do_enable_clocks(NULL, clk_modules, 1);
	return 0;
}

static ulong clk_ti_ctrl_get_rate(struct clk *clk)
{
	return 0;
}

static int clk_ti_ctrl_of_xlate(struct clk *clk,
				struct ofnode_phandle_args *args)
{
	if (args->args_count != 2) {
		dev_err(clk->dev, "invalid args_count: %d\n", args->args_count);
		return -EINVAL;
	}

	if (args->args_count)
		clk->id = args->args[0];
	else
		clk->id = 0;

	dev_dbg(clk->dev, "name=%s, id=%ld\n", clk->dev->name, clk->id);
	return 0;
}

static int clk_ti_ctrl_of_to_plat(struct udevice *dev)
{
	struct clk_ti_ctrl_priv *priv = dev_get_priv(dev);
	fdt_size_t fdt_size;
	int i, size;

	size = dev_read_size(dev, "reg");
	if (size < 0) {
		dev_err(dev, "failed to get 'reg' size\n");
		return size;
	}

	priv->offs_num = size / 2 / sizeof(u32);
	dev_dbg(dev, "size=%d, regs_num=%d\n", size, priv->offs_num);

	priv->offs = kmalloc_array(priv->offs_num, sizeof(*priv->offs),
				   GFP_KERNEL);
	if (!priv->offs)
		return -ENOMEM;

	for (i = 0; i < priv->offs_num; i++) {
		priv->offs[i].start =
			dev_read_addr_size_index(dev, i, &fdt_size);
		if (priv->offs[i].start == FDT_ADDR_T_NONE) {
			dev_err(dev, "failed to get offset %d\n", i);
			return -EINVAL;
		}

		priv->offs[i].end = priv->offs[i].start + fdt_size;
		dev_dbg(dev, "start=0x%08lx, end=0x%08lx\n",
			priv->offs[i].start, priv->offs[i].end);
	}

	return 0;
}

static struct clk_ops clk_ti_ctrl_ops = {
	.of_xlate = clk_ti_ctrl_of_xlate,
	.enable = clk_ti_ctrl_enable,
	.disable = clk_ti_ctrl_disable,
	.get_rate = clk_ti_ctrl_get_rate,
};

static const struct udevice_id clk_ti_ctrl_ids[] = {
	{.compatible = "ti,clkctrl"},
	{},
};

U_BOOT_DRIVER(clk_ti_ctrl) = {
	.name = "ti_ctrl_clk",
	.id = UCLASS_CLK,
	.of_match = clk_ti_ctrl_ids,
	.of_to_plat = clk_ti_ctrl_of_to_plat,
	.ops = &clk_ti_ctrl_ops,
	.priv_auto = sizeof(struct clk_ti_ctrl_priv),
};
