/*
 * (C) Copyright 2007
 * Sascha Hauer, Pengutronix
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <div64.h>
#include <asm/arch/imx-regs.h>
#include <asm/arch/clock.h>
#include <asm/io.h>
#include <asm/arch/sys_proto.h>

static u32 mx31_decode_pll(u32 reg, u32 infreq)
{
	u32 mfi = GET_PLL_MFI(reg);
	s32 mfn = GET_PLL_MFN(reg);
	u32 mfd = GET_PLL_MFD(reg);
	u32 pd =  GET_PLL_PD(reg);

	mfi = mfi <= 5 ? 5 : mfi;
	mfn = mfn >= 512 ? mfn - 1024 : mfn;
	mfd += 1;
	pd += 1;

	return lldiv(2 * (u64)infreq * (mfi * mfd + mfn),
		mfd * pd);
}

static u32 mx31_get_mpl_dpdgck_clk(void)
{
	u32 infreq;

	if ((readl(CCM_CCMR) & CCMR_PRCS_MASK) == CCMR_FPM)
		infreq = MXC_CLK32 * 1024;
	else
		infreq = MXC_HCLK;

	return mx31_decode_pll(readl(CCM_MPCTL), infreq);
}

static u32 mx31_get_mcu_main_clk(void)
{
	/* For now we assume mpl_dpdgck_clk == mcu_main_clk
	 * which should be correct for most boards
	 */
	return mx31_get_mpl_dpdgck_clk();
}

static u32 mx31_get_ipg_clk(void)
{
	u32 freq = mx31_get_mcu_main_clk();
	u32 pdr0 = readl(CCM_PDR0);

	freq /= GET_PDR0_MAX_PODF(pdr0) + 1;
	freq /= GET_PDR0_IPG_PODF(pdr0) + 1;

	return freq;
}

/* hsp is the clock for the ipu */
static u32 mx31_get_hsp_clk(void)
{
	u32 freq = mx31_get_mcu_main_clk();
	u32 pdr0 = readl(CCM_PDR0);

	freq /= GET_PDR0_HSP_PODF(pdr0) + 1;

	return freq;
}

void mx31_dump_clocks(void)
{
	u32 cpufreq = mx31_get_mcu_main_clk();
	printf("mx31 cpu clock: %dMHz\n", cpufreq / 1000000);
	printf("ipg clock     : %dHz\n", mx31_get_ipg_clk());
	printf("hsp clock     : %dHz\n", mx31_get_hsp_clk());
}

unsigned int mxc_get_clock(enum mxc_clock clk)
{
	switch (clk) {
	case MXC_ARM_CLK:
		return mx31_get_mcu_main_clk();
	case MXC_IPG_CLK:
	case MXC_IPG_PERCLK:
	case MXC_CSPI_CLK:
	case MXC_UART_CLK:
	case MXC_ESDHC_CLK:
	case MXC_I2C_CLK:
		return mx31_get_ipg_clk();
	case MXC_IPU_CLK:
		return mx31_get_hsp_clk();
	}
	return -1;
}

u32 imx_get_uartclk(void)
{
	return mxc_get_clock(MXC_UART_CLK);
}

void mx31_gpio_mux(unsigned long mode)
{
	unsigned long reg, shift, tmp;

	reg = IOMUXC_BASE + (mode & 0x1fc);
	shift = (~mode & 0x3) * 8;

	tmp = readl(reg);
	tmp &= ~(0xff << shift);
	tmp |= ((mode >> IOMUX_MODE_POS) & 0xff) << shift;
	writel(tmp, reg);
}

void mx31_set_pad(enum iomux_pins pin, u32 config)
{
	u32 field, l, reg;

	pin &= IOMUX_PADNUM_MASK;
	reg = (IOMUXC_BASE + 0x154) + (pin + 2) / 3 * 4;
	field = (pin + 2) % 3;

	l = readl(reg);
	l &= ~(0x1ff << (field * 10));
	l |= config << (field * 10);
	writel(l, reg);

}

void mx31_set_gpr(enum iomux_gp_func gp, char en)
{
	u32 l;
	struct iomuxc_regs *iomuxc = (struct iomuxc_regs *)IOMUXC_BASE;

	l = readl(&iomuxc->gpr);
	if (en)
		l |= gp;
	else
		l &= ~gp;

	writel(l, &iomuxc->gpr);
}

void mxc_setup_weimcs(int cs, const struct mxc_weimcs *weimcs)
{
	struct mx31_weim *weim = (struct mx31_weim *) WEIM_BASE;
	struct mx31_weim_cscr *cscr = &weim->cscr[cs];

	writel(weimcs->upper, &cscr->upper);
	writel(weimcs->lower, &cscr->lower);
	writel(weimcs->additional, &cscr->additional);
}

struct mx3_cpu_type mx31_cpu_type[] = {
	{ .srev = 0x00, .v = 0x10 },
	{ .srev = 0x10, .v = 0x11 },
	{ .srev = 0x11, .v = 0x11 },
	{ .srev = 0x12, .v = 0x1F },
	{ .srev = 0x13, .v = 0x1F },
	{ .srev = 0x14, .v = 0x12 },
	{ .srev = 0x15, .v = 0x12 },
	{ .srev = 0x28, .v = 0x20 },
	{ .srev = 0x29, .v = 0x20 },
};

u32 get_cpu_rev(void)
{
	u32 i, srev;

	/* read SREV register from IIM module */
	struct iim_regs *iim = (struct iim_regs *)MX31_IIM_BASE_ADDR;
	srev = readl(&iim->iim_srev);

	for (i = 0; i < ARRAY_SIZE(mx31_cpu_type); i++)
		if (srev == mx31_cpu_type[i].srev)
			return mx31_cpu_type[i].v;

	return srev | 0x8000;
}

static char *get_reset_cause(void)
{
	/* read RCSR register from CCM module */
	struct clock_control_regs *ccm =
		(struct clock_control_regs *)CCM_BASE;

	u32 cause = readl(&ccm->rcsr) & 0x07;

	switch (cause) {
	case 0x0000:
		return "POR";
	case 0x0001:
		return "RST";
	case 0x0002:
		return "WDOG";
	case 0x0006:
		return "JTAG";
	case 0x0007:
		return "ARM11P power gating";
	default:
		return "unknown reset";
	}
}

#if defined(CONFIG_DISPLAY_CPUINFO)
int print_cpuinfo(void)
{
	u32 srev = get_cpu_rev();

	printf("CPU:   Freescale i.MX31 rev %d.%d%s at %d MHz.\n",
			(srev & 0xF0) >> 4, (srev & 0x0F),
			((srev & 0x8000) ? " unknown" : ""),
			mx31_get_mcu_main_clk() / 1000000);
	printf("Reset cause: %s\n", get_reset_cause());
	return 0;
}
#endif
