/*
 * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
 *
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <linux/mm.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/jiffies.h>

#include <asm/clkdev.h>
#include <asm/div64.h>

#include <mach/mx23.h>
#include <mach/common.h>
#include <mach/clock.h>

#include "regs-clkctrl-mx23.h"

#define CLKCTRL_BASE_ADDR	MX23_IO_ADDRESS(MX23_CLKCTRL_BASE_ADDR)
#define DIGCTRL_BASE_ADDR	MX23_IO_ADDRESS(MX23_DIGCTL_BASE_ADDR)

#define PARENT_RATE_SHIFT	8

static int _raw_clk_enable(struct clk *clk)
{
	u32 reg;

	if (clk->enable_reg) {
		reg = __raw_readl(clk->enable_reg);
		reg &= ~(1 << clk->enable_shift);
		__raw_writel(reg, clk->enable_reg);
	}

	return 0;
}

static void _raw_clk_disable(struct clk *clk)
{
	u32 reg;

	if (clk->enable_reg) {
		reg = __raw_readl(clk->enable_reg);
		reg |= 1 << clk->enable_shift;
		__raw_writel(reg, clk->enable_reg);
	}
}

/*
 * ref_xtal_clk
 */
static unsigned long ref_xtal_clk_get_rate(struct clk *clk)
{
	return 24000000;
}

static struct clk ref_xtal_clk = {
	.get_rate = ref_xtal_clk_get_rate,
};

/*
 * pll_clk
 */
static unsigned long pll_clk_get_rate(struct clk *clk)
{
	return 480000000;
}

static int pll_clk_enable(struct clk *clk)
{
	__raw_writel(BM_CLKCTRL_PLLCTRL0_POWER |
			BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS,
			CLKCTRL_BASE_ADDR + HW_CLKCTRL_PLLCTRL0_SET);

	/* Only a 10us delay is need. PLLCTRL1 LOCK bitfied is only a timer
	 * and is incorrect (excessive). Per definition of the PLLCTRL0
	 * POWER field, waiting at least 10us.
	 */
	udelay(10);

	return 0;
}

static void pll_clk_disable(struct clk *clk)
{
	__raw_writel(BM_CLKCTRL_PLLCTRL0_POWER |
			BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS,
			CLKCTRL_BASE_ADDR + HW_CLKCTRL_PLLCTRL0_CLR);
}

static struct clk pll_clk = {
	 .get_rate = pll_clk_get_rate,
	 .enable = pll_clk_enable,
	 .disable = pll_clk_disable,
	 .parent = &ref_xtal_clk,
};

/*
 * ref_clk
 */
#define _CLK_GET_RATE_REF(name, sr, ss)					\
static unsigned long name##_get_rate(struct clk *clk)			\
{									\
	unsigned long parent_rate;					\
	u32 reg, div;							\
									\
	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##sr);		\
	div = (reg >> BP_CLKCTRL_##sr##_##ss##FRAC) & 0x3f;		\
	parent_rate = clk_get_rate(clk->parent);			\
									\
	return SH_DIV((parent_rate >> PARENT_RATE_SHIFT) * 18,		\
			div, PARENT_RATE_SHIFT);			\
}

_CLK_GET_RATE_REF(ref_cpu_clk, FRAC, CPU)
_CLK_GET_RATE_REF(ref_emi_clk, FRAC, EMI)
_CLK_GET_RATE_REF(ref_pix_clk, FRAC, PIX)
_CLK_GET_RATE_REF(ref_io_clk, FRAC, IO)

#define _DEFINE_CLOCK_REF(name, er, es)					\
	static struct clk name = {					\
		.enable_reg	= CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er,	\
		.enable_shift	= BP_CLKCTRL_##er##_CLKGATE##es,	\
		.get_rate	= name##_get_rate,			\
		.enable		= _raw_clk_enable,			\
		.disable	= _raw_clk_disable,			\
		.parent		= &pll_clk,				\
	}

_DEFINE_CLOCK_REF(ref_cpu_clk, FRAC, CPU);
_DEFINE_CLOCK_REF(ref_emi_clk, FRAC, EMI);
_DEFINE_CLOCK_REF(ref_pix_clk, FRAC, PIX);
_DEFINE_CLOCK_REF(ref_io_clk, FRAC, IO);

/*
 * General clocks
 *
 * clk_get_rate
 */
static unsigned long rtc_clk_get_rate(struct clk *clk)
{
	/* ref_xtal_clk is implemented as the only parent */
	return clk_get_rate(clk->parent) / 768;
}

static unsigned long clk32k_clk_get_rate(struct clk *clk)
{
	return clk->parent->get_rate(clk->parent) / 750;
}

#define _CLK_GET_RATE(name, rs)						\
static unsigned long name##_get_rate(struct clk *clk)			\
{									\
	u32 reg, div;							\
									\
	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs);		\
									\
	if (clk->parent == &ref_xtal_clk)				\
		div = (reg & BM_CLKCTRL_##rs##_DIV_XTAL) >>		\
			BP_CLKCTRL_##rs##_DIV_XTAL;			\
	else								\
		div = (reg & BM_CLKCTRL_##rs##_DIV_##rs) >>		\
			BP_CLKCTRL_##rs##_DIV_##rs;			\
									\
	if (!div)							\
		return -EINVAL;						\
									\
	return clk_get_rate(clk->parent) / div;				\
}

_CLK_GET_RATE(cpu_clk, CPU)
_CLK_GET_RATE(emi_clk, EMI)

#define _CLK_GET_RATE1(name, rs)					\
static unsigned long name##_get_rate(struct clk *clk)			\
{									\
	u32 reg, div;							\
									\
	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs);		\
	div = (reg & BM_CLKCTRL_##rs##_DIV) >> BP_CLKCTRL_##rs##_DIV;	\
									\
	if (!div)							\
		return -EINVAL;						\
									\
	return clk_get_rate(clk->parent) / div;				\
}

_CLK_GET_RATE1(hbus_clk, HBUS)
_CLK_GET_RATE1(xbus_clk, XBUS)
_CLK_GET_RATE1(ssp_clk, SSP)
_CLK_GET_RATE1(gpmi_clk, GPMI)
_CLK_GET_RATE1(lcdif_clk, PIX)

#define _CLK_GET_RATE_STUB(name)					\
static unsigned long name##_get_rate(struct clk *clk)			\
{									\
	return clk_get_rate(clk->parent);				\
}

_CLK_GET_RATE_STUB(uart_clk)
_CLK_GET_RATE_STUB(audio_clk)
_CLK_GET_RATE_STUB(pwm_clk)

/*
 * clk_set_rate
 */
static int cpu_clk_set_rate(struct clk *clk, unsigned long rate)
{
	u32 reg, bm_busy, div_max, d, f, div, frac;
	unsigned long diff, parent_rate, calc_rate;
	int i;

	parent_rate = clk_get_rate(clk->parent);

	if (clk->parent == &ref_xtal_clk) {
		div_max = BM_CLKCTRL_CPU_DIV_XTAL >> BP_CLKCTRL_CPU_DIV_XTAL;
		bm_busy = BM_CLKCTRL_CPU_BUSY_REF_XTAL;
		div = DIV_ROUND_UP(parent_rate, rate);
		if (div == 0 || div > div_max)
			return -EINVAL;
	} else {
		div_max = BM_CLKCTRL_CPU_DIV_CPU >> BP_CLKCTRL_CPU_DIV_CPU;
		bm_busy = BM_CLKCTRL_CPU_BUSY_REF_CPU;
		rate >>= PARENT_RATE_SHIFT;
		parent_rate >>= PARENT_RATE_SHIFT;
		diff = parent_rate;
		div = frac = 1;
		for (d = 1; d <= div_max; d++) {
			f = parent_rate * 18 / d / rate;
			if ((parent_rate * 18 / d) % rate)
				f++;
			if (f < 18 || f > 35)
				continue;

			calc_rate = parent_rate * 18 / f / d;
			if (calc_rate > rate)
				continue;

			if (rate - calc_rate < diff) {
				frac = f;
				div = d;
				diff = rate - calc_rate;
			}

			if (diff == 0)
				break;
		}

		if (diff == parent_rate)
			return -EINVAL;

		reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
		reg &= ~BM_CLKCTRL_FRAC_CPUFRAC;
		reg |= frac;
		__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
	}

	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU);
	reg &= ~BM_CLKCTRL_CPU_DIV_CPU;
	reg |= div << BP_CLKCTRL_CPU_DIV_CPU;
	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU);

	for (i = 10000; i; i--)
		if (!(__raw_readl(CLKCTRL_BASE_ADDR +
					HW_CLKCTRL_CPU) & bm_busy))
			break;
	if (!i)	{
		pr_err("%s: divider writing timeout\n", __func__);
		return -ETIMEDOUT;
	}

	return 0;
}

#define _CLK_SET_RATE(name, dr)						\
static int name##_set_rate(struct clk *clk, unsigned long rate)		\
{									\
	u32 reg, div_max, div;						\
	unsigned long parent_rate;					\
	int i;								\
									\
	parent_rate = clk_get_rate(clk->parent);			\
	div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV;	\
									\
	div = DIV_ROUND_UP(parent_rate, rate);				\
	if (div == 0 || div > div_max)					\
		return -EINVAL;						\
									\
	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr);		\
	reg &= ~BM_CLKCTRL_##dr##_DIV;					\
	reg |= div << BP_CLKCTRL_##dr##_DIV;				\
	if (reg | (1 << clk->enable_shift)) {				\
		pr_err("%s: clock is gated\n", __func__);		\
		return -EINVAL;						\
	}								\
	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr);		\
									\
	for (i = 10000; i; i--)						\
		if (!(__raw_readl(CLKCTRL_BASE_ADDR +			\
			HW_CLKCTRL_##dr) & BM_CLKCTRL_##dr##_BUSY))	\
			break;						\
	if (!i)	{							\
		pr_err("%s: divider writing timeout\n", __func__);	\
		return -ETIMEDOUT;					\
	}								\
									\
	return 0;							\
}

_CLK_SET_RATE(xbus_clk, XBUS)
_CLK_SET_RATE(ssp_clk, SSP)
_CLK_SET_RATE(gpmi_clk, GPMI)
_CLK_SET_RATE(lcdif_clk, PIX)

#define _CLK_SET_RATE_STUB(name)					\
static int name##_set_rate(struct clk *clk, unsigned long rate)		\
{									\
	return -EINVAL;							\
}

_CLK_SET_RATE_STUB(emi_clk)
_CLK_SET_RATE_STUB(uart_clk)
_CLK_SET_RATE_STUB(audio_clk)
_CLK_SET_RATE_STUB(pwm_clk)
_CLK_SET_RATE_STUB(clk32k_clk)

/*
 * clk_set_parent
 */
#define _CLK_SET_PARENT(name, bit)					\
static int name##_set_parent(struct clk *clk, struct clk *parent)	\
{									\
	if (parent != clk->parent) {					\
		__raw_writel(BM_CLKCTRL_CLKSEQ_BYPASS_##bit,		\
			 HW_CLKCTRL_CLKSEQ_TOG);			\
		clk->parent = parent;					\
	}								\
									\
	return 0;							\
}

_CLK_SET_PARENT(cpu_clk, CPU)
_CLK_SET_PARENT(emi_clk, EMI)
_CLK_SET_PARENT(ssp_clk, SSP)
_CLK_SET_PARENT(gpmi_clk, GPMI)
_CLK_SET_PARENT(lcdif_clk, PIX)

#define _CLK_SET_PARENT_STUB(name)					\
static int name##_set_parent(struct clk *clk, struct clk *parent)	\
{									\
	if (parent != clk->parent)					\
		return -EINVAL;						\
	else								\
		return 0;						\
}

_CLK_SET_PARENT_STUB(uart_clk)
_CLK_SET_PARENT_STUB(audio_clk)
_CLK_SET_PARENT_STUB(pwm_clk)
_CLK_SET_PARENT_STUB(clk32k_clk)

/*
 * clk definition
 */
static struct clk cpu_clk = {
	.get_rate = cpu_clk_get_rate,
	.set_rate = cpu_clk_set_rate,
	.set_parent = cpu_clk_set_parent,
	.parent = &ref_cpu_clk,
};

static struct clk hbus_clk = {
	.get_rate = hbus_clk_get_rate,
	.parent = &cpu_clk,
};

static struct clk xbus_clk = {
	.get_rate = xbus_clk_get_rate,
	.set_rate = xbus_clk_set_rate,
	.parent = &ref_xtal_clk,
};

static struct clk rtc_clk = {
	.get_rate = rtc_clk_get_rate,
	.parent = &ref_xtal_clk,
};

/* usb_clk gate is controlled in DIGCTRL other than CLKCTRL */
static struct clk usb_clk = {
	.enable_reg = DIGCTRL_BASE_ADDR,
	.enable_shift = 2,
	.enable = _raw_clk_enable,
	.disable = _raw_clk_disable,
	.parent = &pll_clk,
};

#define _DEFINE_CLOCK(name, er, es, p)					\
	static struct clk name = {					\
		.enable_reg	= CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er,	\
		.enable_shift	= BP_CLKCTRL_##er##_##es,		\
		.get_rate	= name##_get_rate,			\
		.set_rate	= name##_set_rate,			\
		.set_parent	= name##_set_parent,			\
		.enable		= _raw_clk_enable,			\
		.disable	= _raw_clk_disable,			\
		.parent		= p,					\
	}

_DEFINE_CLOCK(emi_clk, EMI, CLKGATE, &ref_xtal_clk);
_DEFINE_CLOCK(ssp_clk, SSP, CLKGATE, &ref_xtal_clk);
_DEFINE_CLOCK(gpmi_clk, GPMI, CLKGATE, &ref_xtal_clk);
_DEFINE_CLOCK(lcdif_clk, PIX, CLKGATE, &ref_xtal_clk);
_DEFINE_CLOCK(uart_clk, XTAL, UART_CLK_GATE, &ref_xtal_clk);
_DEFINE_CLOCK(audio_clk, XTAL, FILT_CLK24M_GATE, &ref_xtal_clk);
_DEFINE_CLOCK(pwm_clk, XTAL, PWM_CLK24M_GATE, &ref_xtal_clk);
_DEFINE_CLOCK(clk32k_clk, XTAL, TIMROT_CLK32K_GATE, &ref_xtal_clk);

#define _REGISTER_CLOCK(d, n, c) \
	{ \
		.dev_id = d, \
		.con_id = n, \
		.clk = &c, \
	},

static struct clk_lookup lookups[] = {
	_REGISTER_CLOCK("mxs-duart.0", NULL, uart_clk)
	_REGISTER_CLOCK("rtc", NULL, rtc_clk)
	_REGISTER_CLOCK(NULL, "hclk", hbus_clk)
	_REGISTER_CLOCK(NULL, "xclk", xbus_clk)
	_REGISTER_CLOCK(NULL, "usb", usb_clk)
	_REGISTER_CLOCK(NULL, "audio", audio_clk)
	_REGISTER_CLOCK(NULL, "pwm", pwm_clk)
};

static int clk_misc_init(void)
{
	u32 reg;
	int i;

	/* Fix up parent per register setting */
	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ);
	cpu_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_CPU) ?
			&ref_xtal_clk : &ref_cpu_clk;
	emi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_EMI) ?
			&ref_xtal_clk : &ref_emi_clk;
	ssp_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP) ?
			&ref_xtal_clk : &ref_io_clk;
	gpmi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_GPMI) ?
			&ref_xtal_clk : &ref_io_clk;
	lcdif_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_PIX) ?
			&ref_xtal_clk : &ref_pix_clk;

	/* Use int div over frac when both are available */
	__raw_writel(BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN,
			CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
	__raw_writel(BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN,
			CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
	__raw_writel(BM_CLKCTRL_HBUS_DIV_FRAC_EN,
			CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS_CLR);

	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
	reg &= ~BM_CLKCTRL_XBUS_DIV_FRAC_EN;
	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);

	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP);
	reg &= ~BM_CLKCTRL_SSP_DIV_FRAC_EN;
	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP);

	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
	reg &= ~BM_CLKCTRL_GPMI_DIV_FRAC_EN;
	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);

	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_PIX);
	reg &= ~BM_CLKCTRL_PIX_DIV_FRAC_EN;
	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_PIX);

	/*
	 * Set safe hbus clock divider. A divider of 3 ensure that
	 * the Vddd voltage required for the cpu clock is sufficiently
	 * high for the hbus clock.
	 */
	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
	reg &= BM_CLKCTRL_HBUS_DIV;
	reg |= 3 << BP_CLKCTRL_HBUS_DIV;
	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);

	for (i = 10000; i; i--)
		if (!(__raw_readl(CLKCTRL_BASE_ADDR +
			HW_CLKCTRL_HBUS) & BM_CLKCTRL_HBUS_BUSY))
			break;
	if (!i) {
		pr_err("%s: divider writing timeout\n", __func__);
		return -ETIMEDOUT;
	}

	/* Gate off cpu clock in WFI for power saving */
	__raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,
			CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_SET);

	return 0;
}

int __init mx23_clocks_init(void)
{
	clk_misc_init();

	clkdev_add_table(lookups, ARRAY_SIZE(lookups));

	mxs_timer_init(&clk32k_clk, MX23_INT_TIMER0);

	return 0;
}
