// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
 *
 * Author: Sam Shih <sam.shih@mediatek.com>
 */

#include <common.h>
#include <clk.h>
#include <dm.h>
#include <pwm.h>
#include <div64.h>
#include <linux/bitops.h>
#include <linux/io.h>

/* PWM registers and bits definitions */
#define PWMCON			0x00
#define PWMHDUR			0x04
#define PWMLDUR			0x08
#define PWMGDUR			0x0c
#define PWMWAVENUM		0x28
#define PWMDWIDTH		0x2c
#define PWM45DWIDTH_FIXUP	0x30
#define PWMTHRES		0x30
#define PWM45THRES_FIXUP	0x34

#define PWM_CLK_DIV_MAX		7
#define MAX_PWM_NUM		8

#define NSEC_PER_SEC 1000000000L

static const unsigned int mtk_pwm_reg_offset[] = {
	0x0010, 0x0050, 0x0090, 0x00d0, 0x0110, 0x0150, 0x0190, 0x0220
};

struct mtk_pwm_soc {
	unsigned int num_pwms;
	bool pwm45_fixup;
};

struct mtk_pwm_priv {
	void __iomem *base;
	struct clk top_clk;
	struct clk main_clk;
	struct clk pwm_clks[MAX_PWM_NUM];
	const struct mtk_pwm_soc *soc;
};

static void mtk_pwm_w32(struct udevice *dev, uint channel, uint reg, uint val)
{
	struct mtk_pwm_priv *priv = dev_get_priv(dev);
	u32 offset = mtk_pwm_reg_offset[channel];

	writel(val, priv->base + offset + reg);
}

static int mtk_pwm_set_config(struct udevice *dev, uint channel,
			      uint period_ns, uint duty_ns)
{
	struct mtk_pwm_priv *priv = dev_get_priv(dev);
	u32 clkdiv = 0, clksel = 0, cnt_period, cnt_duty,
	    reg_width = PWMDWIDTH, reg_thres = PWMTHRES;
	u64 resolution;
	int ret = 0;

	clk_enable(&priv->top_clk);
	clk_enable(&priv->main_clk);
	/* Using resolution in picosecond gets accuracy higher */
	resolution = (u64)NSEC_PER_SEC * 1000;
	do_div(resolution, clk_get_rate(&priv->pwm_clks[channel]));
	cnt_period = DIV_ROUND_CLOSEST_ULL((u64)period_ns * 1000, resolution);
	while (cnt_period > 8191) {
		resolution *= 2;
		clkdiv++;
		cnt_period = DIV_ROUND_CLOSEST_ULL((u64)period_ns * 1000,
						   resolution);
		if (clkdiv > PWM_CLK_DIV_MAX && clksel == 0) {
			clksel = 1;
			clkdiv = 0;
			resolution = (u64)NSEC_PER_SEC * 1000 * 1625;
			do_div(resolution,
			       clk_get_rate(&priv->pwm_clks[channel]));
			cnt_period = DIV_ROUND_CLOSEST_ULL(
					(u64)period_ns * 1000, resolution);
			clk_enable(&priv->pwm_clks[channel]);
		}
	}
	if (clkdiv > PWM_CLK_DIV_MAX && clksel == 1) {
		printf("pwm period %u not supported\n", period_ns);
		return -EINVAL;
	}
	if (priv->soc->pwm45_fixup && channel > 2) {
		/*
		 * PWM[4,5] has distinct offset for PWMDWIDTH and PWMTHRES
		 * from the other PWMs on MT7623.
		 */
		reg_width = PWM45DWIDTH_FIXUP;
		reg_thres = PWM45THRES_FIXUP;
	}
	cnt_duty = DIV_ROUND_CLOSEST_ULL((u64)duty_ns * 1000, resolution);
	if (clksel == 1)
		mtk_pwm_w32(dev, channel, PWMCON, BIT(15) | BIT(3) | clkdiv);
	else
		mtk_pwm_w32(dev, channel, PWMCON, BIT(15) | clkdiv);
	mtk_pwm_w32(dev, channel, reg_width, cnt_period);
	mtk_pwm_w32(dev, channel, reg_thres, cnt_duty);

	return ret;
};

static int mtk_pwm_set_enable(struct udevice *dev, uint channel, bool enable)
{
	struct mtk_pwm_priv *priv = dev_get_priv(dev);
	u32 val = 0;

	val = readl(priv->base);
	if (enable)
		val |= BIT(channel);
	else
		val &= ~BIT(channel);
	writel(val, priv->base);

	return 0;
};

static int mtk_pwm_probe(struct udevice *dev)
{
	struct mtk_pwm_priv *priv = dev_get_priv(dev);
	int ret = 0;
	int i;

	priv->soc = (struct mtk_pwm_soc *)dev_get_driver_data(dev);
	priv->base = (void __iomem *)devfdt_get_addr(dev);
	if (!priv->base)
		return -EINVAL;
	ret = clk_get_by_name(dev, "top", &priv->top_clk);
	if (ret < 0)
		return ret;
	ret = clk_get_by_name(dev, "main", &priv->main_clk);
	if (ret < 0)
		return ret;
	for (i = 0; i < priv->soc->num_pwms; i++) {
		char name[8];

		snprintf(name, sizeof(name), "pwm%d", i + 1);
		ret = clk_get_by_name(dev, name, &priv->pwm_clks[i]);
		if (ret < 0)
			return ret;
	}

	return ret;
}

static const struct pwm_ops mtk_pwm_ops = {
	.set_config	= mtk_pwm_set_config,
	.set_enable	= mtk_pwm_set_enable,
};

static const struct mtk_pwm_soc mt7622_data = {
	.num_pwms = 6,
	.pwm45_fixup = false,
};

static const struct mtk_pwm_soc mt7623_data = {
	.num_pwms = 5,
	.pwm45_fixup = true,
};

static const struct mtk_pwm_soc mt7629_data = {
	.num_pwms = 1,
	.pwm45_fixup = false,
};

static const struct udevice_id mtk_pwm_ids[] = {
	{ .compatible = "mediatek,mt7622-pwm", .data = (ulong)&mt7622_data },
	{ .compatible = "mediatek,mt7623-pwm", .data = (ulong)&mt7623_data },
	{ .compatible = "mediatek,mt7629-pwm", .data = (ulong)&mt7629_data },
	{ }
};

U_BOOT_DRIVER(mtk_pwm) = {
	.name = "mtk_pwm",
	.id = UCLASS_PWM,
	.of_match = mtk_pwm_ids,
	.ops = &mtk_pwm_ops,
	.probe = mtk_pwm_probe,
	.priv_auto_alloc_size = sizeof(struct mtk_pwm_priv),
};
