/*
 * (C) Copyright 2007
 * Sascha Hauer, Pengutronix
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#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
