/*
 *  Marvell Berlin SoC clk driver
 *  Author:	Jisheng Zhang <jszhang@marvell.com>
 *  Copyright:	Marvell International Ltd.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 */

#include <linux/export.h>
#include <linux/kernel.h>
#include <linux/clk.h>
#include <linux/io.h>

#include <mach/galois_platform.h>

#include "clock.h"

static inline u32 rdlc(int offset)
{
	return __raw_readl(IOMEM(MEMMAP_CHIP_CTRL_REG_BASE + offset));
}

static u32 vcodiv[] = {10, 15, 20, 25, 30, 40, 50, 60, 80};
static u32 clkdiv[] = {1, 2, 4, 6, 8, 12, 1, 1};

static inline u32 cpu0_get_divider(void)
{
	u32 val;

	val = rdlc(RA_GBL_CLKSWITCH);
	if ((val >> 8) & 0x1)
		return 3;
	if ((val >> 7) & 0x1) {
		u32 clksel = (rdlc(RA_GBL_CLKSELECT) >> 9) & 0x7;
		return clkdiv[clksel];
	} else
		return 1;
}

static inline u32 cfg_get_divider(void)
{
	u32 val;

	val = rdlc(RA_GBL_CLKSWITCH);
	if ((val >> 17) & 0x1)
		return 3;
	if ((val >> 16) & 0x1) {
		u32 clksel = (rdlc(RA_GBL_CLKSELECT) >> 26) & 0x7;
		return clkdiv[clksel];
	} else
		return 1;
}

static inline u32 perif_get_divider(void)
{
	u32 val;

	val = rdlc(RA_GBL_CLKSWITCH);
	if ((val >> 26) & 0x1)
		return 3;
	if ((val >> 25) & 0x1) {
		u32 clksel = (rdlc(RA_GBL_CLKSELECT1) >> 12) & 0x7;
		return clkdiv[clksel];
	} else
		return 1;
}

static inline u32 sdioxin_get_divider(void)
{
	u32 val;

	val = rdlc(RA_GBL_SDIOXINCLKCTRL);
	if ((val >> 6) & 0x1)
		return 3;
	if ((val >> 5) & 0x1) {
		u32 clksel = (val >> 7) & 0x7;
		return clkdiv[clksel];
	} else
		return 1;
}

static inline u32 sdio1xin_get_divider(void)
{
	u32 val;

	val = rdlc(RA_GBL_SDIO1XINCLKCTRL);
	if ((val >> 6) & 0x1)
		return 3;
	if ((val >> 5) & 0x1) {
		u32 clksel = (val >> 7) & 0x7;
		return clkdiv[clksel];
	} else
		return 1;
}

static inline u32 nfcecc_get_divider(void)
{
	u32 val;

	val = rdlc(RA_GBL_CLKSWITCH1);
	if ((val >> 3) & 0x1)
		return 3;
	if ((val >> 2) & 0x1) {
		u32 clksel = rdlc(RA_GBL_CLKSELECT2) & 0x7;
		return clkdiv[clksel];
	} else
		return 1;
}


/* input clock is 25MHZ */
#define CLKIN 25
unsigned long get_pll(struct clk *clk)
{
	u32 val, fbdiv, rfdiv, vcodivsel;
	unsigned long pll;

	val = rdlc(clk->ctl);
	fbdiv = (val >> 6) & 0x1ff;
	rfdiv = (val >> 1) & 0x1f;
	if (rfdiv == 0)
		rfdiv = 1;
	pll = CLKIN * fbdiv / rfdiv;
	val = rdlc(clk->ctl1);
	vcodivsel = (val >> 7) & 0xf;
	pll = pll * 10 / vcodiv[vcodivsel];

	return pll;
}

static unsigned long twd_get_rate(struct clk *clk)
{
	unsigned long pll = get_pll(clk);
	u32 divider = cpu0_get_divider();
	return 1000000 * pll / divider / 3;
}

static struct clkops twd_clk_ops = {
	.getrate	= twd_get_rate,
};

static struct clk twd_clk = {
	.ctl	= RA_GBL_CPUPLLCTL,
	.ctl1	= RA_GBL_CPUPLLCTL1,
	.ops	= &twd_clk_ops,
};

static unsigned long cfg_get_rate(struct clk *clk)
{
	unsigned long pll = get_pll(clk);
	u32 divider = cfg_get_divider();
	return 1000000*pll/divider;
}

static struct clkops cfg_clk_ops = {
	.getrate	= cfg_get_rate,
};

static struct clk cfg_clk = {
	.ctl	= RA_GBL_SYSPLLCTL,
	.ctl1	= RA_GBL_SYSPLLCTL1,
	.ops	= &cfg_clk_ops,
};

CLK(cpu0, RA_GBL_CPUPLLCTL, RA_GBL_CPUPLLCTL1);
CLK(perif, RA_GBL_SYSPLLCTL, RA_GBL_SYSPLLCTL1);
CLK(sdioxin, RA_GBL_SYSPLLCTL, RA_GBL_SYSPLLCTL1);
CLK(sdio1xin, RA_GBL_SYSPLLCTL, RA_GBL_SYSPLLCTL1);
CLK(nfcecc, RA_GBL_SYSPLLCTL, RA_GBL_SYSPLLCTL1);

static struct clk_lookup clks[] = {
	CLK_LOOKUP(NULL, "cpu0", cpu0_clk),
	CLK_LOOKUP(NULL, "cfg", cfg_clk),
	CLK_LOOKUP(NULL, "perif", perif_clk),
	CLK_LOOKUP("smp_twd", NULL, twd_clk),
	CLK_LOOKUP("f7ab0000.sdhci", NULL, sdioxin_clk),
	CLK_LOOKUP("f7ab0800.sdhci", NULL, sdio1xin_clk),
	CLK_LOOKUP("f7ab1000.sdhci", NULL, nfcecc_clk),
	CLK_LOOKUP("f7e81400.i2c", NULL, cfg_clk),
	CLK_LOOKUP("f7e81800.i2c", NULL, cfg_clk),
	CLK_LOOKUP("f7fc7000.i2c", NULL, cfg_clk),
	CLK_LOOKUP("f7fc8000.i2c", NULL, cfg_clk),
};

void __init berlin_clk_init(void)
{
	clkdev_add_table(clks, ARRAY_SIZE(clks));
}
#if 0
int clk_enable(struct clk *clk)
{
	return 0;
}
EXPORT_SYMBOL(clk_enable);

void clk_disable(struct clk *clk)
{
}
EXPORT_SYMBOL(clk_disable);
#endif
unsigned long clk_get_rate(struct clk *clk)
{
	unsigned long rate;

	if (clk->ops->getrate)
		rate = clk->ops->getrate(clk);
	else
		rate = 0;

	return rate;
}
EXPORT_SYMBOL(clk_get_rate);

