/*
 * Copyright (C) 2016 Socionext Inc.
 *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/io.h>
#include <linux/sizes.h>

#include "pll.h"

/* PLL type: SSC */
#define SC_PLLCTRL_SSC_DK_MASK		GENMASK(14, 0)
#define SC_PLLCTRL_SSC_EN		BIT(31)
#define SC_PLLCTRL2_NRSTDS		BIT(28)
#define SC_PLLCTRL2_SSC_JK_MASK		GENMASK(26, 0)
#define SC_PLLCTRL3_REGI_MASK		GENMASK(19, 16)

/* PLL type: VPLL27 */
#define SC_VPLL27CTRL_WP		BIT(0)
#define SC_VPLL27CTRL3_K_LD		BIT(28)

/* PLL type: DSPLL */
#define SC_DSPLLCTRL2_K_LD		BIT(28)

int uniphier_ld20_sscpll_init(unsigned long reg_base, unsigned int freq,
			      unsigned int ssc_rate, unsigned int divn)
{
	void __iomem *base;
	u32 tmp;

	base = ioremap(reg_base, SZ_16);
	if (!base)
		return -ENOMEM;

	if (freq != UNIPHIER_PLL_FREQ_DEFAULT) {
		tmp = readl(base);	/* SSCPLLCTRL */
		tmp &= ~SC_PLLCTRL_SSC_DK_MASK;
		tmp |= FIELD_PREP(SC_PLLCTRL_SSC_DK_MASK,
				  DIV_ROUND_CLOSEST(487UL * freq * ssc_rate,
						    divn * 512));
		writel(tmp, base);

		tmp = readl(base + 4);
		tmp &= ~SC_PLLCTRL2_SSC_JK_MASK;
		tmp |= FIELD_PREP(SC_PLLCTRL2_SSC_JK_MASK,
				  DIV_ROUND_CLOSEST(21431887UL * freq,
						    divn * 512));
		writel(tmp, base + 4);

		udelay(50);
	}

	tmp = readl(base + 4);		/* SSCPLLCTRL2 */
	tmp |= SC_PLLCTRL2_NRSTDS;
	writel(tmp, base + 4);

	iounmap(base);

	return 0;
}

int uniphier_ld20_sscpll_ssc_en(unsigned long reg_base)
{
	void __iomem *base;
	u32 tmp;

	base = ioremap(reg_base, SZ_16);
	if (!base)
		return -ENOMEM;

	tmp = readl(base);	/* SSCPLLCTRL */
	tmp |= SC_PLLCTRL_SSC_EN;
	writel(tmp, base);

	iounmap(base);

	return 0;
}

int uniphier_ld20_sscpll_set_regi(unsigned long reg_base, unsigned regi)
{
	void __iomem *base;
	u32 tmp;

	base = ioremap(reg_base, SZ_16);
	if (!base)
		return -ENOMEM;

	tmp = readl(base + 8);	/* SSCPLLCTRL3 */
	tmp &= ~SC_PLLCTRL3_REGI_MASK;
	tmp |= FIELD_PREP(SC_PLLCTRL3_REGI_MASK, regi);
	writel(tmp, base + 8);

	iounmap(base);

	return 0;
}

int uniphier_ld20_vpll27_init(unsigned long reg_base)
{
	void __iomem *base;
	u32 tmp;

	base = ioremap(reg_base, SZ_16);
	if (!base)
		return -ENOMEM;

	tmp = readl(base);		/* VPLL27CTRL */
	tmp |= SC_VPLL27CTRL_WP;	/* write protect off */
	writel(tmp, base);

	tmp = readl(base + 8);		/* VPLL27CTRL3 */
	tmp |= SC_VPLL27CTRL3_K_LD;
	writel(tmp, base + 8);

	tmp = readl(base);		/* VPLL27CTRL */
	tmp &= ~SC_VPLL27CTRL_WP;	/* write protect on */
	writel(tmp, base);

	iounmap(base);

	return 0;
}

int uniphier_ld20_dspll_init(unsigned long reg_base)
{
	void __iomem *base;
	u32 tmp;

	base = ioremap(reg_base, SZ_16);
	if (!base)
		return -ENOMEM;

	tmp = readl(base + 4);		/* DSPLLCTRL2 */
	tmp |= SC_DSPLLCTRL2_K_LD;
	writel(tmp, base + 4);

	iounmap(base);

	return 0;
}
