/*
 * 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 <mach/imx-regs.h>
#include <asm/io.h>
#include <mach/clock.h>
#include <mach/generic.h>
#include <init.h>

unsigned long imx_get_mpllclk(void)
{
	ulong mpctl = readl(IMX_CCM_BASE + CCM_MPCTL);
	return imx_decode_pll(mpctl, CONFIG_MX35_HCLK_FREQ);
}

static unsigned long imx_get_ppllclk(void)
{
	ulong ppctl = readl(IMX_CCM_BASE + CCM_PPCTL);
	return imx_decode_pll(ppctl, CONFIG_MX35_HCLK_FREQ);
}

struct arm_ahb_div {
	unsigned char arm, ahb, sel;
};

static struct arm_ahb_div clk_consumer[] = {
	{ .arm = 1, .ahb = 4, .sel = 0},
	{ .arm = 1, .ahb = 3, .sel = 1},
	{ .arm = 2, .ahb = 2, .sel = 0},
	{ .arm = 0, .ahb = 0, .sel = 0},
	{ .arm = 0, .ahb = 0, .sel = 0},
	{ .arm = 0, .ahb = 0, .sel = 0},
	{ .arm = 4, .ahb = 1, .sel = 0},
	{ .arm = 1, .ahb = 5, .sel = 0},
	{ .arm = 1, .ahb = 8, .sel = 0},
	{ .arm = 1, .ahb = 6, .sel = 1},
	{ .arm = 2, .ahb = 4, .sel = 0},
	{ .arm = 0, .ahb = 0, .sel = 0},
	{ .arm = 0, .ahb = 0, .sel = 0},
	{ .arm = 0, .ahb = 0, .sel = 0},
	{ .arm = 4, .ahb = 2, .sel = 0},
	{ .arm = 0, .ahb = 0, .sel = 0},
};

static unsigned long imx_get_armclk(void)
{
	unsigned long pdr0 = readl(IMX_CCM_BASE + CCM_PDR0);
	struct arm_ahb_div *aad;
	unsigned long fref = imx_get_mpllclk();

	/* consumer path is selected */
	aad = &clk_consumer[(pdr0 >> 16) & 0xf];
	if (aad->sel)
		fref = fref * 3 / 4;

	return fref / aad->arm;
}

unsigned long imx_get_ahbclk(void)
{
	unsigned long pdr0 = readl(IMX_CCM_BASE + CCM_PDR0);
	struct arm_ahb_div *aad;
	unsigned long fref = imx_get_mpllclk();

	aad = &clk_consumer[(pdr0 >> 16) & 0xf];
	if (aad->sel)
		fref = fref * 3 / 4;

	return fref / aad->ahb;
}

static unsigned long imx_get_ipgclk(void)
{
	ulong clk = imx_get_ahbclk();

	return clk >> 1;
}

static unsigned long get_3_3_div(unsigned long in)
{
	return (((in >> 3) & 0x7) + 1) * ((in & 0x7) + 1);
}

static unsigned long imx_get_ipg_perclk(void)
{
	ulong pdr0 = readl(IMX_CCM_BASE + CCM_PDR0);
	ulong pdr4 = readl(IMX_CCM_BASE + CCM_PDR4);
	ulong div;
	ulong fref;

	if (pdr0 & PDR0_PER_SEL) {
		/* perclk from arm high frequency clock and synched with AHB clki */
		fref = imx_get_armclk();
		div = get_3_3_div((pdr4 >> 16));
	} else {
		/* perclk from AHB divided clock */
		fref = imx_get_ahbclk();
		div = ((pdr0 >> 12) & 0x7) + 1;
	}

	return fref / div;
}

unsigned long imx_get_gptclk(void)
{
	return imx_get_ipgclk();
}

/**
 * Calculate the current pixel clock speed (aka HSP or IPU)
 * @return 0 on failure or current frequency in Hz
 */
unsigned long imx_get_lcdclk(void)
{
	unsigned long hsp_podf = (readl(IMX_CCM_BASE + CCM_PDR0) >> 20) & 0x03;
	unsigned long base_clk = imx_get_armclk();

	if (base_clk > 400 * 1000 * 1000) {
		switch(hsp_podf) {
		case 0:
			return base_clk >> 2;
		case 1:
			return base_clk >> 3;
		case 2:
			return base_clk / 3;
		}
	} else {
		switch(hsp_podf) {
		case 0:
		case 2:
			return base_clk / 3;
		case 1:
			return base_clk / 6;
		}
	}

	return 0;
}

unsigned long imx_get_uartclk(void)
{
	unsigned long pdr3 = readl(IMX_CCM_BASE + CCM_PDR3);
	unsigned long pdr4 = readl(IMX_CCM_BASE + CCM_PDR4);
	unsigned long div = get_3_3_div(pdr4 >> 10);

	if (pdr3 & (1 << 14))
		return imx_get_armclk() / div;
	else
		return imx_get_ppllclk() / div;
}

unsigned long imx_get_mmcclk(void)
{
	unsigned long pdr3 = readl(IMX_CCM_BASE + CCM_PDR3);
	unsigned long div = get_3_3_div(pdr3);

	if (pdr3 & (1 << 6))
		return imx_get_armclk() / div;
	else
		return imx_get_ppllclk() / div;
}

ulong imx_get_fecclk(void)
{
	return imx_get_ipgclk();
}

ulong imx_get_i2cclk(void)
{
	return imx_get_ipg_perclk();
}

void imx_dump_clocks(void)
{
	printf("mpll:    %10ld Hz\n", imx_get_mpllclk());
	printf("ppll:    %10ld Hz\n", imx_get_ppllclk());
	printf("arm:     %10ld Hz\n", imx_get_armclk());
	printf("gpt:     %10ld Hz\n", imx_get_gptclk());
	printf("ahb:     %10ld Hz\n", imx_get_ahbclk());
	printf("ipg:     %10ld Hz\n", imx_get_ipgclk());
	printf("ipg_per: %10ld Hz\n", imx_get_ipg_perclk());
	printf("uart:	 %10ld Hz\n", imx_get_uartclk());
	printf("sdhc1:   %10ld Hz\n", imx_get_mmcclk());
}

/*
 * Set the divider of the CLKO pin. Returns
 * the new divider (which may be smaller
 * than the desired one)
 */
int imx_clko_set_div(int div)
{
	unsigned long cosr = readl(IMX_CCM_BASE + CCM_COSR);

	div -= 1;
	div &= 0x3f;

	cosr &= ~(0x3f << 10);
	cosr |= div << 10;

	writel(cosr, IMX_CCM_BASE + CCM_COSR);

	return div + 1;
}

/*
 * Set the clock source for the CLKO pin
 */
void imx_clko_set_src(int src)
{
	unsigned long cosr = readl(IMX_CCM_BASE + CCM_COSR);

	if (src < 0) {
		cosr &= ~(1 << 5);
		writel(cosr, IMX_CCM_BASE + CCM_COSR);
		return;
	}

	cosr |= 1 << 5;
	cosr &= ~0x1f;
	cosr &= ~(1 << 6);
	cosr |= src & 0x1f;

	writel(cosr, IMX_CCM_BASE + CCM_COSR);
}

