/*
 * PRCC clock implementation for ux500 platform.
 *
 * Copyright (C) 2012 ST-Ericsson SA
 * Author: Ulf Hansson <ulf.hansson@linaro.org>
 *
 * License terms: GNU General Public License (GPL) version 2
 */

#include <linux/clk-provider.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/err.h>
#include <linux/types.h>

#include "clk.h"

#define PRCC_PCKEN			0x000
#define PRCC_PCKDIS			0x004
#define PRCC_KCKEN			0x008
#define PRCC_KCKDIS			0x00C
#define PRCC_PCKSR			0x010
#define PRCC_KCKSR			0x014

#define to_clk_prcc(_hw) container_of(_hw, struct clk_prcc, hw)

struct clk_prcc {
	struct clk_hw hw;
	void __iomem *base;
	u32 cg_sel;
	int is_enabled;
};

/* PRCC clock operations. */

static int clk_prcc_pclk_enable(struct clk_hw *hw)
{
	struct clk_prcc *clk = to_clk_prcc(hw);

	writel(clk->cg_sel, (clk->base + PRCC_PCKEN));
	while (!(readl(clk->base + PRCC_PCKSR) & clk->cg_sel))
		cpu_relax();

	clk->is_enabled = 1;
	return 0;
}

static void clk_prcc_pclk_disable(struct clk_hw *hw)
{
	struct clk_prcc *clk = to_clk_prcc(hw);

	writel(clk->cg_sel, (clk->base + PRCC_PCKDIS));
	clk->is_enabled = 0;
}

static int clk_prcc_kclk_enable(struct clk_hw *hw)
{
	struct clk_prcc *clk = to_clk_prcc(hw);

	writel(clk->cg_sel, (clk->base + PRCC_KCKEN));
	while (!(readl(clk->base + PRCC_KCKSR) & clk->cg_sel))
		cpu_relax();

	clk->is_enabled = 1;
	return 0;
}

static void clk_prcc_kclk_disable(struct clk_hw *hw)
{
	struct clk_prcc *clk = to_clk_prcc(hw);

	writel(clk->cg_sel, (clk->base + PRCC_KCKDIS));
	clk->is_enabled = 0;
}

static int clk_prcc_is_enabled(struct clk_hw *hw)
{
	struct clk_prcc *clk = to_clk_prcc(hw);
	return clk->is_enabled;
}

static const struct clk_ops clk_prcc_pclk_ops = {
	.enable = clk_prcc_pclk_enable,
	.disable = clk_prcc_pclk_disable,
	.is_enabled = clk_prcc_is_enabled,
};

static const struct clk_ops clk_prcc_kclk_ops = {
	.enable = clk_prcc_kclk_enable,
	.disable = clk_prcc_kclk_disable,
	.is_enabled = clk_prcc_is_enabled,
};

static struct clk *clk_reg_prcc(const char *name,
				const char *parent_name,
				resource_size_t phy_base,
				u32 cg_sel,
				unsigned long flags,
				const struct clk_ops *clk_prcc_ops)
{
	struct clk_prcc *clk;
	struct clk_init_data clk_prcc_init;
	struct clk *clk_reg;

	if (!name) {
		pr_err("clk_prcc: %s invalid arguments passed\n", __func__);
		return ERR_PTR(-EINVAL);
	}

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

	clk->base = ioremap(phy_base, SZ_4K);
	if (!clk->base)
		goto free_clk;

	clk->cg_sel = cg_sel;
	clk->is_enabled = 1;

	clk_prcc_init.name = name;
	clk_prcc_init.ops = clk_prcc_ops;
	clk_prcc_init.flags = flags;
	clk_prcc_init.parent_names = (parent_name ? &parent_name : NULL);
	clk_prcc_init.num_parents = (parent_name ? 1 : 0);
	clk->hw.init = &clk_prcc_init;

	clk_reg = clk_register(NULL, &clk->hw);
	if (IS_ERR_OR_NULL(clk_reg))
		goto unmap_clk;

	return clk_reg;

unmap_clk:
	iounmap(clk->base);
free_clk:
	kfree(clk);
	pr_err("clk_prcc: %s failed to register clk\n", __func__);
	return ERR_PTR(-ENOMEM);
}

struct clk *clk_reg_prcc_pclk(const char *name,
			      const char *parent_name,
			      resource_size_t phy_base,
			      u32 cg_sel,
			      unsigned long flags)
{
	return clk_reg_prcc(name, parent_name, phy_base, cg_sel, flags,
			&clk_prcc_pclk_ops);
}

struct clk *clk_reg_prcc_kclk(const char *name,
			      const char *parent_name,
			      resource_size_t phy_base,
			      u32 cg_sel,
			      unsigned long flags)
{
	return clk_reg_prcc(name, parent_name, phy_base, cg_sel, flags,
			&clk_prcc_kclk_ops);
}
