/*
 *  Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
 *
 * 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.
 *
 */

#include <linux/clk-provider.h>
#include <linux/clkdev.h>
#include <linux/clk/at91_pmc.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/io.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/irq.h>

#include "pmc.h"

#define MASTER_SOURCE_MAX	4

#define MASTER_PRES_MASK	0x7
#define MASTER_PRES_MAX		MASTER_PRES_MASK
#define MASTER_DIV_SHIFT	8
#define MASTER_DIV_MASK		0x3

struct clk_master_characteristics {
	struct clk_range output;
	u32 divisors[4];
	u8 have_div3_pres;
};

struct clk_master_layout {
	u32 mask;
	u8 pres_shift;
};

#define to_clk_master(hw) container_of(hw, struct clk_master, hw)

struct clk_master {
	struct clk_hw hw;
	struct at91_pmc *pmc;
	unsigned int irq;
	wait_queue_head_t wait;
	const struct clk_master_layout *layout;
	const struct clk_master_characteristics *characteristics;
};

static irqreturn_t clk_master_irq_handler(int irq, void *dev_id)
{
	struct clk_master *master = (struct clk_master *)dev_id;

	wake_up(&master->wait);
	disable_irq_nosync(master->irq);

	return IRQ_HANDLED;
}
static int clk_master_prepare(struct clk_hw *hw)
{
	struct clk_master *master = to_clk_master(hw);
	struct at91_pmc *pmc = master->pmc;

	while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MCKRDY)) {
		enable_irq(master->irq);
		wait_event(master->wait,
			   pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MCKRDY);
	}

	return 0;
}

static int clk_master_is_prepared(struct clk_hw *hw)
{
	struct clk_master *master = to_clk_master(hw);

	return !!(pmc_read(master->pmc, AT91_PMC_SR) & AT91_PMC_MCKRDY);
}

static unsigned long clk_master_recalc_rate(struct clk_hw *hw,
					    unsigned long parent_rate)
{
	u8 pres;
	u8 div;
	unsigned long rate = parent_rate;
	struct clk_master *master = to_clk_master(hw);
	struct at91_pmc *pmc = master->pmc;
	const struct clk_master_layout *layout = master->layout;
	const struct clk_master_characteristics *characteristics =
						master->characteristics;
	u32 tmp;

	pmc_lock(pmc);
	tmp = pmc_read(pmc, AT91_PMC_MCKR) & layout->mask;
	pmc_unlock(pmc);

	pres = (tmp >> layout->pres_shift) & MASTER_PRES_MASK;
	div = (tmp >> MASTER_DIV_SHIFT) & MASTER_DIV_MASK;

	if (characteristics->have_div3_pres && pres == MASTER_PRES_MAX)
		rate /= 3;
	else
		rate >>= pres;

	rate /= characteristics->divisors[div];

	if (rate < characteristics->output.min)
		pr_warn("master clk is underclocked");
	else if (rate > characteristics->output.max)
		pr_warn("master clk is overclocked");

	return rate;
}

static u8 clk_master_get_parent(struct clk_hw *hw)
{
	struct clk_master *master = to_clk_master(hw);
	struct at91_pmc *pmc = master->pmc;

	return pmc_read(pmc, AT91_PMC_MCKR) & AT91_PMC_CSS;
}

static const struct clk_ops master_ops = {
	.prepare = clk_master_prepare,
	.is_prepared = clk_master_is_prepared,
	.recalc_rate = clk_master_recalc_rate,
	.get_parent = clk_master_get_parent,
};

static struct clk * __init
at91_clk_register_master(struct at91_pmc *pmc, unsigned int irq,
		const char *name, int num_parents,
		const char **parent_names,
		const struct clk_master_layout *layout,
		const struct clk_master_characteristics *characteristics)
{
	int ret;
	struct clk_master *master;
	struct clk *clk = NULL;
	struct clk_init_data init;

	if (!pmc || !irq || !name || !num_parents || !parent_names)
		return ERR_PTR(-EINVAL);

	master = kzalloc(sizeof(*master), GFP_KERNEL);
	if (!master)
		return ERR_PTR(-ENOMEM);

	init.name = name;
	init.ops = &master_ops;
	init.parent_names = parent_names;
	init.num_parents = num_parents;
	init.flags = 0;

	master->hw.init = &init;
	master->layout = layout;
	master->characteristics = characteristics;
	master->pmc = pmc;
	master->irq = irq;
	init_waitqueue_head(&master->wait);
	irq_set_status_flags(master->irq, IRQ_NOAUTOEN);
	ret = request_irq(master->irq, clk_master_irq_handler,
			  IRQF_TRIGGER_HIGH, "clk-master", master);
	if (ret)
		return ERR_PTR(ret);

	clk = clk_register(NULL, &master->hw);
	if (IS_ERR(clk))
		kfree(master);

	return clk;
}


static const struct clk_master_layout at91rm9200_master_layout = {
	.mask = 0x31F,
	.pres_shift = 2,
};

static const struct clk_master_layout at91sam9x5_master_layout = {
	.mask = 0x373,
	.pres_shift = 4,
};


static struct clk_master_characteristics * __init
of_at91_clk_master_get_characteristics(struct device_node *np)
{
	struct clk_master_characteristics *characteristics;

	characteristics = kzalloc(sizeof(*characteristics), GFP_KERNEL);
	if (!characteristics)
		return NULL;

	if (of_at91_get_clk_range(np, "atmel,clk-output-range", &characteristics->output))
		goto out_free_characteristics;

	of_property_read_u32_array(np, "atmel,clk-divisors",
				   characteristics->divisors, 4);

	characteristics->have_div3_pres =
		of_property_read_bool(np, "atmel,master-clk-have-div3-pres");

	return characteristics;

out_free_characteristics:
	kfree(characteristics);
	return NULL;
}

static void __init
of_at91_clk_master_setup(struct device_node *np, struct at91_pmc *pmc,
			 const struct clk_master_layout *layout)
{
	struct clk *clk;
	int num_parents;
	int i;
	unsigned int irq;
	const char *parent_names[MASTER_SOURCE_MAX];
	const char *name = np->name;
	struct clk_master_characteristics *characteristics;

	num_parents = of_count_phandle_with_args(np, "clocks", "#clock-cells");
	if (num_parents <= 0 || num_parents > MASTER_SOURCE_MAX)
		return;

	for (i = 0; i < num_parents; ++i) {
		parent_names[i] = of_clk_get_parent_name(np, i);
		if (!parent_names[i])
			return;
	}

	of_property_read_string(np, "clock-output-names", &name);

	characteristics = of_at91_clk_master_get_characteristics(np);
	if (!characteristics)
		return;

	irq = irq_of_parse_and_map(np, 0);
	if (!irq)
		goto out_free_characteristics;

	clk = at91_clk_register_master(pmc, irq, name, num_parents,
				       parent_names, layout,
				       characteristics);
	if (IS_ERR(clk))
		goto out_free_characteristics;

	of_clk_add_provider(np, of_clk_src_simple_get, clk);
	return;

out_free_characteristics:
	kfree(characteristics);
}

void __init of_at91rm9200_clk_master_setup(struct device_node *np,
					   struct at91_pmc *pmc)
{
	of_at91_clk_master_setup(np, pmc, &at91rm9200_master_layout);
}

void __init of_at91sam9x5_clk_master_setup(struct device_node *np,
					   struct at91_pmc *pmc)
{
	of_at91_clk_master_setup(np, pmc, &at91sam9x5_master_layout);
}
