// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2016 Google, Inc
 * Written by Simon Glass <sjg@chromium.org>
 */

#include <common.h>
#include <clk.h>
#include <div64.h>
#include <dm.h>
#include <log.h>
#include <pwm.h>
#include <regmap.h>
#include <syscon.h>
#include <asm/io.h>
#include <asm/arch-rockchip/pwm.h>
#include <linux/bitops.h>
#include <power/regulator.h>

DECLARE_GLOBAL_DATA_PTR;

struct rockchip_pwm_data {
	struct rockchip_pwm_regs regs;
	unsigned int prescaler;
	bool supports_polarity;
	bool supports_lock;
	u32 enable_conf;
	u32 enable_conf_mask;
};

struct rk_pwm_priv {
	fdt_addr_t base;
	ulong freq;
	u32 conf_polarity;
	const struct rockchip_pwm_data *data;
};

static int rk_pwm_set_invert(struct udevice *dev, uint channel, bool polarity)
{
	struct rk_pwm_priv *priv = dev_get_priv(dev);

	if (!priv->data->supports_polarity) {
		debug("%s: Do not support polarity\n", __func__);
		return 0;
	}

	debug("%s: polarity=%u\n", __func__, polarity);
	if (polarity)
		priv->conf_polarity = PWM_DUTY_NEGATIVE | PWM_INACTIVE_POSTIVE;
	else
		priv->conf_polarity = PWM_DUTY_POSTIVE | PWM_INACTIVE_NEGATIVE;

	return 0;
}

static int rk_pwm_set_config(struct udevice *dev, uint channel, uint period_ns,
			     uint duty_ns)
{
	struct rk_pwm_priv *priv = dev_get_priv(dev);
	const struct rockchip_pwm_regs *regs = &priv->data->regs;
	unsigned long period, duty;
	u32 ctrl;

	debug("%s: period_ns=%u, duty_ns=%u\n", __func__, period_ns, duty_ns);

	ctrl = readl(priv->base + regs->ctrl);
	/*
	 * Lock the period and duty of previous configuration, then
	 * change the duty and period, that would not be effective.
	 */
	if (priv->data->supports_lock) {
		ctrl |= PWM_LOCK;
		writel(ctrl, priv->base + regs->ctrl);
	}

	period = lldiv((uint64_t)priv->freq * period_ns,
		       priv->data->prescaler * 1000000000);
	duty = lldiv((uint64_t)priv->freq * duty_ns,
		     priv->data->prescaler * 1000000000);

	writel(period, priv->base + regs->period);
	writel(duty, priv->base + regs->duty);

	if (priv->data->supports_polarity) {
		ctrl &= ~(PWM_DUTY_MASK | PWM_INACTIVE_MASK);
		ctrl |= priv->conf_polarity;
	}

	/*
	 * Unlock and set polarity at the same time,
	 * the configuration of duty, period and polarity
	 * would be effective together at next period.
	 */
	if (priv->data->supports_lock)
		ctrl &= ~PWM_LOCK;
	writel(ctrl, priv->base + regs->ctrl);

	debug("%s: period=%lu, duty=%lu\n", __func__, period, duty);

	return 0;
}

static int rk_pwm_set_enable(struct udevice *dev, uint channel, bool enable)
{
	struct rk_pwm_priv *priv = dev_get_priv(dev);
	const struct rockchip_pwm_regs *regs = &priv->data->regs;
	u32 ctrl;

	debug("%s: Enable '%s'\n", __func__, dev->name);

	ctrl = readl(priv->base + regs->ctrl);
	ctrl &= ~priv->data->enable_conf_mask;

	if (enable)
		ctrl |= priv->data->enable_conf;
	else
		ctrl &= ~priv->data->enable_conf;

	writel(ctrl, priv->base + regs->ctrl);

	return 0;
}

static int rk_pwm_ofdata_to_platdata(struct udevice *dev)
{
	struct rk_pwm_priv *priv = dev_get_priv(dev);

	priv->base = dev_read_addr(dev);

	return 0;
}

static int rk_pwm_probe(struct udevice *dev)
{
	struct rk_pwm_priv *priv = dev_get_priv(dev);
	struct clk clk;
	int ret = 0;

	ret = clk_get_by_index(dev, 0, &clk);
	if (ret < 0) {
		debug("%s get clock fail!\n", __func__);
		return -EINVAL;
	}

	priv->freq = clk_get_rate(&clk);
	priv->data = (struct rockchip_pwm_data *)dev_get_driver_data(dev);

	if (priv->data->supports_polarity)
		priv->conf_polarity = PWM_DUTY_POSTIVE | PWM_INACTIVE_POSTIVE;

	return 0;
}

static const struct pwm_ops rk_pwm_ops = {
	.set_invert	= rk_pwm_set_invert,
	.set_config	= rk_pwm_set_config,
	.set_enable	= rk_pwm_set_enable,
};

static const struct rockchip_pwm_data pwm_data_v1 = {
	.regs = {
		.duty = 0x04,
		.period = 0x08,
		.cntr = 0x00,
		.ctrl = 0x0c,
	},
	.prescaler = 2,
	.supports_polarity = false,
	.supports_lock = false,
	.enable_conf = PWM_CTRL_OUTPUT_EN | PWM_CTRL_TIMER_EN,
	.enable_conf_mask = BIT(1) | BIT(3),
};

static const struct rockchip_pwm_data pwm_data_v2 = {
	.regs = {
		.duty = 0x08,
		.period = 0x04,
		.cntr = 0x00,
		.ctrl = 0x0c,
	},
	.prescaler = 1,
	.supports_polarity = true,
	.supports_lock = false,
	.enable_conf = PWM_OUTPUT_LEFT | PWM_LP_DISABLE | RK_PWM_ENABLE |
		       PWM_CONTINUOUS,
	.enable_conf_mask = GENMASK(2, 0) | BIT(5) | BIT(8),
};

static const struct rockchip_pwm_data pwm_data_v3 = {
	.regs = {
		.duty = 0x08,
		.period = 0x04,
		.cntr = 0x00,
		.ctrl = 0x0c,
	},
	.prescaler = 1,
	.supports_polarity = true,
	.supports_lock = true,
	.enable_conf = PWM_OUTPUT_LEFT | PWM_LP_DISABLE | RK_PWM_ENABLE |
		       PWM_CONTINUOUS,
	.enable_conf_mask = GENMASK(2, 0) | BIT(5) | BIT(8),
};

static const struct udevice_id rk_pwm_ids[] = {
	{ .compatible = "rockchip,rk2928-pwm", .data = (ulong)&pwm_data_v1},
	{ .compatible = "rockchip,rk3288-pwm", .data = (ulong)&pwm_data_v2},
	{ .compatible = "rockchip,rk3328-pwm", .data = (ulong)&pwm_data_v3},
	{ }
};

U_BOOT_DRIVER(rk_pwm) = {
	.name	= "rk_pwm",
	.id	= UCLASS_PWM,
	.of_match = rk_pwm_ids,
	.ops	= &rk_pwm_ops,
	.ofdata_to_platdata	= rk_pwm_ofdata_to_platdata,
	.probe		= rk_pwm_probe,
	.priv_auto_alloc_size	= sizeof(struct rk_pwm_priv),
};
