/*
 * Copyright (c) 2013, The Linux Foundation. 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 version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * 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.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/errno.h>

#include <linux/clk.h>
#include <mach/clk-provider.h>
#include <mach/clk.h>
#include <mach/clock-generic.h>
#include <mach/msm-krait-l2-accessors.h>
#include "clock-krait.h"
#include "avs.h"

static DEFINE_SPINLOCK(kpss_clock_reg_lock);

#define LPL_SHIFT	8
static void __kpss_mux_set_sel(struct mux_clk *mux, int sel)
{
	unsigned long flags;
	u32 regval;

	spin_lock_irqsave(&kpss_clock_reg_lock, flags);
	regval = get_l2_indirect_reg(mux->offset);
	regval &= ~(mux->mask << mux->shift);
	regval |= (sel & mux->mask) << mux->shift;
	if (mux->priv) {
		regval &= ~(mux->mask << (mux->shift + LPL_SHIFT));
		regval |= (sel & mux->mask) << (mux->shift + LPL_SHIFT);
	}
	set_l2_indirect_reg(mux->offset, regval);
	spin_unlock_irqrestore(&kpss_clock_reg_lock, flags);

	/* Wait for switch to complete. */
	mb();
	udelay(1);
}
static int kpss_mux_set_sel(struct mux_clk *mux, int sel)
{
	mux->en_mask = sel;
	if (mux->c.count)
		__kpss_mux_set_sel(mux, sel);
	return 0;
}

static int kpss_mux_get_sel(struct mux_clk *mux)
{
	u32 sel;

	sel = get_l2_indirect_reg(mux->offset);
	sel >>= mux->shift;
	sel &= mux->mask;
	mux->en_mask = sel;

	return sel;
}

static int kpss_mux_enable(struct mux_clk *mux)
{
	__kpss_mux_set_sel(mux, mux->en_mask);
	return 0;
}

static void kpss_mux_disable(struct mux_clk *mux)
{
	__kpss_mux_set_sel(mux, mux->safe_sel);
}

struct clk_mux_ops clk_mux_ops_kpss = {
	.enable = kpss_mux_enable,
	.disable = kpss_mux_disable,
	.set_mux_sel = kpss_mux_set_sel,
	.get_mux_sel = kpss_mux_get_sel,
};

/*
 * The divider can divide by 2, 4, 6 and 8. But we only really need div-2. So
 * force it to div-2 during handoff and treat it like a fixed div-2 clock.
 */
static int kpss_div2_get_div(struct div_clk *div)
{
	unsigned long flags;
	u32 regval;
	int val;

	spin_lock_irqsave(&kpss_clock_reg_lock, flags);
	regval = get_l2_indirect_reg(div->offset);
	val = (regval >> div->shift) & div->mask;
	regval &= ~(div->mask << div->shift);
	if (div->priv)
		regval &= ~(div->mask << (div->shift + LPL_SHIFT));
	set_l2_indirect_reg(div->offset, regval);
	spin_unlock_irqrestore(&kpss_clock_reg_lock, flags);

	val = (val + 1) * 2;
	WARN(val != 2, "Divider %s was configured to div-%d instead of 2!\n",
		div->c.dbg_name, val);

	return 2;
}

struct clk_div_ops clk_div_ops_kpss_div2 = {
	.get_div = kpss_div2_get_div,
};

#define LOCK_BIT	BIT(16)

/* Initialize a HFPLL at a given rate and enable it. */
static void __hfpll_clk_init_once(struct clk *c)
{
	struct hfpll_clk *h = to_hfpll_clk(c);
	struct hfpll_data const *hd = h->d;

	if (likely(h->init_done))
		return;

	/* Configure PLL parameters for integer mode. */
	if (hd->config_val)
		writel_relaxed(hd->config_val, h->base + hd->config_offset);
	writel_relaxed(0, h->base + hd->m_offset);
	writel_relaxed(1, h->base + hd->n_offset);

	if (hd->user_offset) {
		u32 regval = hd->user_val;
		unsigned long rate;

		rate = readl_relaxed(h->base + hd->l_offset) * h->src_rate;

		/* Pick the right VCO. */
		if (hd->user_vco_mask && rate > hd->low_vco_max_rate)
			regval |= hd->user_vco_mask;
		writel_relaxed(regval, h->base + hd->user_offset);
	}

	if (hd->droop_offset)
		writel_relaxed(hd->droop_val, h->base + hd->droop_offset);

	h->init_done = true;
}

/* Enable an already-configured HFPLL. */
static int hfpll_clk_enable(struct clk *c)
{
	struct hfpll_clk *h = to_hfpll_clk(c);
	struct hfpll_data const *hd = h->d;

	if (!h->base)
		return -ENODEV;

	__hfpll_clk_init_once(c);

	/* Disable PLL bypass mode. */
	writel_relaxed(0x2, h->base + hd->mode_offset);

	/*
	 * H/W requires a 5us delay between disabling the bypass and
	 * de-asserting the reset. Delay 10us just to be safe.
	 */
	mb();
	udelay(10);

	/* De-assert active-low PLL reset. */
	writel_relaxed(0x6, h->base + hd->mode_offset);

	/* Wait for PLL to lock. */
	if (hd->status_offset) {
		while (!(readl_relaxed(h->base + hd->status_offset) & LOCK_BIT))
			;
	} else {
		mb();
		udelay(60);
	}

	/* Enable PLL output. */
	writel_relaxed(0x7, h->base + hd->mode_offset);

	/* Make sure the enable is done before returning. */
	mb();

	return 0;
}

static void hfpll_clk_disable(struct clk *c)
{
	struct hfpll_clk *h = to_hfpll_clk(c);
	struct hfpll_data const *hd = h->d;

	/*
	 * Disable the PLL output, disable test mode, enable the bypass mode,
	 * and assert the reset.
	 */
	writel_relaxed(0, h->base + hd->mode_offset);
}

static long hfpll_clk_round_rate(struct clk *c, unsigned long rate)
{
	struct hfpll_clk *h = to_hfpll_clk(c);
	struct hfpll_data const *hd = h->d;
	unsigned long rrate;

	if (!h->src_rate)
		return 0;

	rate = max(rate, hd->min_rate);
	rate = min(rate, hd->max_rate);

	rrate = DIV_ROUND_UP(rate, h->src_rate) * h->src_rate;
	if (rrate > hd->max_rate)
		rrate -= h->src_rate;

	return rrate;
}

/*
 * For optimization reasons, assumes no downstream clocks are actively using
 * it.
 */
static int hfpll_clk_set_rate(struct clk *c, unsigned long rate)
{
	struct hfpll_clk *h = to_hfpll_clk(c);
	struct hfpll_data const *hd = h->d;
	unsigned long flags;
	u32 l_val;

	if (!h->base)
		return -ENODEV;

	if (rate != hfpll_clk_round_rate(c, rate))
		return -EINVAL;

	l_val = rate / h->src_rate;

	spin_lock_irqsave(&c->lock, flags);

	if (c->count)
		hfpll_clk_disable(c);

	/* Pick the right VCO. */
	if (hd->user_offset && hd->user_vco_mask) {
		u32 regval;
		regval = readl_relaxed(h->base + hd->user_offset);
		if (rate <= hd->low_vco_max_rate)
			regval &= ~hd->user_vco_mask;
		else
			regval |= hd->user_vco_mask;
		writel_relaxed(regval, h->base  + hd->user_offset);
	}

	writel_relaxed(l_val, h->base + hd->l_offset);

	if (c->count)
		hfpll_clk_enable(c);

	spin_unlock_irqrestore(&c->lock, flags);

	return 0;
}

static enum handoff hfpll_clk_handoff(struct clk *c)
{
	struct hfpll_clk *h = to_hfpll_clk(c);
	struct hfpll_data const *hd = h->d;
	u32 l_val, mode;

	if (!hd)
		return HANDOFF_DISABLED_CLK;

	if (!h->base)
		return HANDOFF_DISABLED_CLK;

	/* Assume parent rate doesn't change and cache it. */
	h->src_rate = clk_get_rate(c->parent);
	l_val = readl_relaxed(h->base + hd->l_offset);
	c->rate = l_val * h->src_rate;

	mode = readl_relaxed(h->base + hd->mode_offset) & 0x7;
	if (mode != 0x7) {
		__hfpll_clk_init_once(c);
		return HANDOFF_DISABLED_CLK;
	}

	if (hd->status_offset &&
		!(readl_relaxed(h->base + hd->status_offset) & LOCK_BIT)) {
		WARN(1, "HFPLL %s is ON, but not locked!\n", c->dbg_name);
		hfpll_clk_disable(c);
		__hfpll_clk_init_once(c);
		return HANDOFF_DISABLED_CLK;
	}

	WARN(c->rate < hd->min_rate || c->rate > hd->max_rate,
		"HFPLL %s rate %lu outside spec!\n", c->dbg_name, c->rate);

	return HANDOFF_ENABLED_CLK;
}

struct clk_ops clk_ops_hfpll = {
	.enable = hfpll_clk_enable,
	.disable = hfpll_clk_disable,
	.round_rate = hfpll_clk_round_rate,
	.set_rate = hfpll_clk_set_rate,
	.handoff = hfpll_clk_handoff,
};

struct cpu_hwcg_action {
	bool read;
	bool enable;
};

static void cpu_hwcg_rw(void *info)
{
	struct cpu_hwcg_action *action = info;

	u32 val;
	asm volatile ("mrc p15, 7, %[cpmr0], c15, c0, 5\n\t"
			: [cpmr0]"=r" (val));

	if (action->read) {
		action->enable = !(val & BIT(0));
		return;
	}

	if (action->enable)
		val &= ~BIT(0);
	else
		val |= BIT(0);

	asm volatile ("mcr p15, 7, %[cpmr0], c15, c0, 5\n\t"
			: : [cpmr0]"r" (val));
}

static void kpss_cpu_enable_hwcg(struct clk *c)
{
	struct kpss_core_clk *cpu = to_kpss_core_clk(c);
	struct cpu_hwcg_action action = { .enable = true };

	smp_call_function_single(cpu->id, cpu_hwcg_rw, &action, 1);
}

static void kpss_cpu_disable_hwcg(struct clk *c)
{
	struct kpss_core_clk *cpu = to_kpss_core_clk(c);
	struct cpu_hwcg_action action = { .enable = false };

	smp_call_function_single(cpu->id, cpu_hwcg_rw, &action, 1);
}

static int kpss_cpu_in_hwcg_mode(struct clk *c)
{
	struct kpss_core_clk *cpu = to_kpss_core_clk(c);
	struct cpu_hwcg_action action = { .read = true };

	smp_call_function_single(cpu->id, cpu_hwcg_rw, &action, 1);
	return action.enable;
}

static enum handoff kpss_cpu_handoff(struct clk *c)
{
	struct kpss_core_clk *cpu = to_kpss_core_clk(c);

	c->rate = clk_get_rate(c->parent);

	/*
	 * Don't unnecessarily turn on the parents for an offline CPU and
	 * then have them turned off at late init.
	 */
	return (cpu_online(cpu->id) ?
		HANDOFF_ENABLED_CLK : HANDOFF_DISABLED_CLK);
}

u32 find_dscr(struct avs_data *t, unsigned long rate)
{
	int i;

	if (!t)
		return 0;

	for (i = 0; i < t->num; i++) {
		if (t->rate[i] == rate)
			return t->dscr[i];
	}

	return 0;
}

static int kpss_cpu_pre_set_rate(struct clk *c, unsigned long new_rate)
{
	struct kpss_core_clk *cpu = to_kpss_core_clk(c);
	u32 dscr = find_dscr(cpu->avs_tbl, c->rate);

	if (dscr)
		AVS_DISABLE(cpu->id);
	return 0;
}

static long kpss_core_round_rate(struct clk *c, unsigned long rate)
{
	if (c->fmax && c->num_fmax)
		rate = min(rate, c->fmax[c->num_fmax-1]);

	return clk_round_rate(c->parent, rate);
}

static int kpss_core_set_rate(struct clk *c, unsigned long rate)
{
	return clk_set_rate(c->parent, rate);
}

static void kpss_cpu_post_set_rate(struct clk *c, unsigned long old_rate)
{
	struct kpss_core_clk *cpu = to_kpss_core_clk(c);
	u32 dscr = find_dscr(cpu->avs_tbl, c->rate);

	/*
	 * FIXME: If AVS enable/disable needs to be done in the
	 * enable/disable op to correctly handle power collapse, then might
	 * need to grab the spinlock here.
	 */
	if (dscr)
		AVS_ENABLE(cpu->id, dscr);
}

static unsigned long kpss_core_get_rate(struct clk *c)
{
	return clk_get_rate(c->parent);
}

static long kpss_core_list_rate(struct clk *c, unsigned n)
{
	if (!c->fmax || c->num_fmax <= n)
		return -ENXIO;

	return c->fmax[n];
}

struct clk_ops clk_ops_kpss_cpu = {
	.enable_hwcg = kpss_cpu_enable_hwcg,
	.disable_hwcg = kpss_cpu_disable_hwcg,
	.in_hwcg_mode = kpss_cpu_in_hwcg_mode,
	.pre_set_rate = kpss_cpu_pre_set_rate,
	.round_rate = kpss_core_round_rate,
	.set_rate = kpss_core_set_rate,
	.post_set_rate = kpss_cpu_post_set_rate,
	.get_rate = kpss_core_get_rate,
	.list_rate = kpss_core_list_rate,
	.handoff = kpss_cpu_handoff,
};

#define SLPDLY_SHIFT		10
#define SLPDLY_MASK		0x3
static void kpss_l2_enable_hwcg(struct clk *c)
{
	struct kpss_core_clk *l2 = to_kpss_core_clk(c);
	u32 regval;
	unsigned long flags;

	spin_lock_irqsave(&kpss_clock_reg_lock, flags);
	regval = get_l2_indirect_reg(l2->cp15_iaddr);
	regval &= ~(SLPDLY_MASK << SLPDLY_SHIFT);
	regval |= l2->l2_slp_delay;
	set_l2_indirect_reg(l2->cp15_iaddr, regval);
	spin_unlock_irqrestore(&kpss_clock_reg_lock, flags);
}

static void kpss_l2_disable_hwcg(struct clk *c)
{
	struct kpss_core_clk *l2 = to_kpss_core_clk(c);
	u32 regval;
	unsigned long flags;

	/*
	 * NOTE: Should not be called when HW clock gating is already
	 * disabled.
	 */
	spin_lock_irqsave(&kpss_clock_reg_lock, flags);
	regval = get_l2_indirect_reg(l2->cp15_iaddr);
	l2->l2_slp_delay = regval & (SLPDLY_MASK << SLPDLY_SHIFT);
	regval |= (SLPDLY_MASK << SLPDLY_SHIFT);
	set_l2_indirect_reg(l2->cp15_iaddr, regval);
	spin_unlock_irqrestore(&kpss_clock_reg_lock, flags);
}

static int kpss_l2_in_hwcg_mode(struct clk *c)
{
	struct kpss_core_clk *l2 = to_kpss_core_clk(c);
	u32 regval;

	regval = get_l2_indirect_reg(l2->cp15_iaddr);
	regval >>= SLPDLY_SHIFT;
	regval &= SLPDLY_MASK;
	return (regval != SLPDLY_MASK);
}

static enum handoff kpss_l2_handoff(struct clk *c)
{
	c->rate = clk_get_rate(c->parent);
	return HANDOFF_ENABLED_CLK;
}

struct clk_ops clk_ops_kpss_l2 = {
	.enable_hwcg = kpss_l2_enable_hwcg,
	.disable_hwcg = kpss_l2_disable_hwcg,
	.in_hwcg_mode = kpss_l2_in_hwcg_mode,
	.round_rate = kpss_core_round_rate,
	.set_rate = kpss_core_set_rate,
	.get_rate = kpss_core_get_rate,
	.list_rate = kpss_core_list_rate,
	.handoff = kpss_l2_handoff,
};
