// SPDX-License-Identifier: GPL-2.0+
/*
 * Texas Instruments CDCE913/925/937/949 clock synthesizer driver
 *
 * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
 *	Tero Kristo <t-kristo@ti.com>
 *
 * Based on Linux kernel clk-cdce925.c.
 */

#include <common.h>
#include <dm.h>
#include <errno.h>
#include <clk-uclass.h>
#include <i2c.h>

#define MAX_NUMBER_OF_PLLS		4
#define MAX_NUMER_OF_OUTPUTS		9

#define CDCE9XX_REG_GLOBAL1		0x01
#define CDCE9XX_REG_Y1SPIPDIVH		0x02
#define CDCE9XX_REG_PDIV1L		0x03
#define CDCE9XX_REG_XCSEL		0x05

#define CDCE9XX_PDIV1_H_MASK		0x3

#define CDCE9XX_REG_PDIV(clk)		(0x16 + (((clk) - 1) & 1) + \
					 ((clk) - 1) / 2 * 0x10)

#define CDCE9XX_PDIV_MASK		0x7f

#define CDCE9XX_BYTE_TRANSFER		BIT(7)

struct cdce9xx_chip_info {
	int num_plls;
	int num_outputs;
};

struct cdce9xx_clk_data {
	struct udevice *i2c;
	struct cdce9xx_chip_info *chip;
	u32 xtal_rate;
};

static const struct cdce9xx_chip_info cdce913_chip_info = {
	.num_plls = 1, .num_outputs = 3,
};

static const struct cdce9xx_chip_info cdce925_chip_info = {
	.num_plls = 2, .num_outputs = 5,
};

static const struct cdce9xx_chip_info cdce937_chip_info = {
	.num_plls = 3, .num_outputs = 7,
};

static const struct cdce9xx_chip_info cdce949_chip_info = {
	.num_plls = 4, .num_outputs = 9,
};

static int cdce9xx_reg_read(struct udevice *dev, u8 addr, u8 *buf)
{
	struct cdce9xx_clk_data *data = dev_get_priv(dev);
	int ret;

	ret = dm_i2c_read(data->i2c, addr | CDCE9XX_BYTE_TRANSFER, buf, 1);
	if (ret)
		dev_err(dev, "%s: failed for addr:%x, ret:%d\n", __func__,
			addr, ret);

	return ret;
}

static int cdce9xx_reg_write(struct udevice *dev, u8 addr, u8 val)
{
	struct cdce9xx_clk_data *data = dev_get_priv(dev);
	int ret;

	ret = dm_i2c_write(data->i2c, addr | CDCE9XX_BYTE_TRANSFER, &val, 1);
	if (ret)
		dev_err(dev, "%s: failed for addr:%x, ret:%d\n", __func__,
			addr, ret);

	return ret;
}

static int cdce9xx_clk_of_xlate(struct clk *clk,
				struct ofnode_phandle_args *args)
{
	struct cdce9xx_clk_data *data = dev_get_priv(clk->dev);

	if (args->args_count != 1)
		return -EINVAL;

	if (args->args[0] > data->chip->num_outputs)
		return -EINVAL;

	clk->id = args->args[0];

	return 0;
}

static int cdce9xx_clk_probe(struct udevice *dev)
{
	struct cdce9xx_clk_data *data = dev_get_priv(dev);
	struct cdce9xx_chip_info *chip = (void *)dev_get_driver_data(dev);
	int ret;
	u32 val;
	struct clk clk;

	val = (u32)dev_read_addr_ptr(dev);

	ret = i2c_get_chip(dev->parent, val, 1, &data->i2c);
	if (ret) {
		dev_err(dev, "I2C probe failed.\n");
		return ret;
	}

	data->chip = chip;

	ret = clk_get_by_index(dev, 0, &clk);
	data->xtal_rate = clk_get_rate(&clk);

	val = dev_read_u32_default(dev, "xtal-load-pf", -1);
	if (val >= 0)
		cdce9xx_reg_write(dev, CDCE9XX_REG_XCSEL, val << 3);

	return 0;
}

static u16 cdce9xx_clk_get_pdiv(struct clk *clk)
{
	u8 val;
	u16 pdiv;
	int ret;

	if (clk->id == 0) {
		ret = cdce9xx_reg_read(clk->dev, CDCE9XX_REG_Y1SPIPDIVH, &val);
		if (ret)
			return 0;

		pdiv = (val & CDCE9XX_PDIV1_H_MASK) << 8;

		ret = cdce9xx_reg_read(clk->dev, CDCE9XX_REG_PDIV1L, &val);
		if (ret)
			return 0;

		pdiv |= val;
	} else {
		ret = cdce9xx_reg_read(clk->dev, CDCE9XX_REG_PDIV(clk->id),
				       &val);
		if (ret)
			return 0;

		pdiv = val & CDCE9XX_PDIV_MASK;
	}

	return pdiv;
}

static u32 cdce9xx_clk_get_parent_rate(struct clk *clk)
{
	struct cdce9xx_clk_data *data = dev_get_priv(clk->dev);

	return data->xtal_rate;
}

static ulong cdce9xx_clk_get_rate(struct clk *clk)
{
	u32 parent_rate;
	u16 pdiv;

	parent_rate = cdce9xx_clk_get_parent_rate(clk);

	pdiv = cdce9xx_clk_get_pdiv(clk);

	return parent_rate / pdiv;
}

static ulong cdce9xx_clk_set_rate(struct clk *clk, ulong rate)
{
	u32 parent_rate;
	int pdiv;
	u32 diff;
	u8 val;
	int ret;

	parent_rate = cdce9xx_clk_get_parent_rate(clk);

	pdiv = parent_rate / rate;

	diff = rate - parent_rate / pdiv;

	if (rate - parent_rate / (pdiv + 1) < diff)
		pdiv++;

	if (clk->id == 0) {
		ret = cdce9xx_reg_read(clk->dev, CDCE9XX_REG_Y1SPIPDIVH, &val);
		if (ret)
			return ret;

		val &= ~CDCE9XX_PDIV1_H_MASK;

		val |= (pdiv >> 8);

		ret = cdce9xx_reg_write(clk->dev, CDCE9XX_REG_Y1SPIPDIVH, val);
		if (ret)
			return ret;

		ret = cdce9xx_reg_write(clk->dev, CDCE9XX_REG_PDIV1L,
					(pdiv & 0xff));
		if (ret)
			return ret;
	} else {
		ret = cdce9xx_reg_read(clk->dev, CDCE9XX_REG_PDIV(clk->id),
				       &val);
		if (ret)
			return ret;

		val &= ~CDCE9XX_PDIV_MASK;

		val |= pdiv;

		ret = cdce9xx_reg_write(clk->dev, CDCE9XX_REG_PDIV(clk->id),
					val);
		if (ret)
			return ret;
	}

	return 0;
}

static const struct udevice_id cdce9xx_clk_of_match[] = {
	{ .compatible = "ti,cdce913", .data = (u32)&cdce913_chip_info },
	{ .compatible = "ti,cdce925", .data = (u32)&cdce925_chip_info },
	{ .compatible = "ti,cdce937", .data = (u32)&cdce937_chip_info },
	{ .compatible = "ti,cdce949", .data = (u32)&cdce949_chip_info },
	{ /* sentinel */ },
};

static const struct clk_ops cdce9xx_clk_ops = {
	.of_xlate = cdce9xx_clk_of_xlate,
	.get_rate = cdce9xx_clk_get_rate,
	.set_rate = cdce9xx_clk_set_rate,
};

U_BOOT_DRIVER(cdce9xx_clk) = {
	.name = "cdce9xx-clk",
	.id = UCLASS_CLK,
	.of_match = cdce9xx_clk_of_match,
	.probe = cdce9xx_clk_probe,
	.priv_auto_alloc_size = sizeof(struct cdce9xx_clk_data),
	.ops = &cdce9xx_clk_ops,
};
