/*
 * TI clock support
 *
 * Copyright (C) 2013 Texas Instruments, Inc.
 *
 * Tero Kristo <t-kristo@ti.com>
 *
 * 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.
 *
 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
 * kind, whether express or implied; without even the implied warranty
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/clkdev.h>
#include <linux/clk/ti.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/list.h>
#include <linux/regmap.h>
#include <linux/bootmem.h>
#include <linux/device.h>

#include "clock.h"

#undef pr_fmt
#define pr_fmt(fmt) "%s: " fmt, __func__

struct ti_clk_ll_ops *ti_clk_ll_ops;
static struct device_node *clocks_node_ptr[CLK_MAX_MEMMAPS];

static struct ti_clk_features ti_clk_features;

struct clk_iomap {
	struct regmap *regmap;
	void __iomem *mem;
};

static struct clk_iomap *clk_memmaps[CLK_MAX_MEMMAPS];

static void clk_memmap_writel(u32 val, const struct clk_omap_reg *reg)
{
	struct clk_iomap *io = clk_memmaps[reg->index];

	if (reg->ptr)
		writel_relaxed(val, reg->ptr);
	else if (io->regmap)
		regmap_write(io->regmap, reg->offset, val);
	else
		writel_relaxed(val, io->mem + reg->offset);
}

static u32 clk_memmap_readl(const struct clk_omap_reg *reg)
{
	u32 val;
	struct clk_iomap *io = clk_memmaps[reg->index];

	if (reg->ptr)
		val = readl_relaxed(reg->ptr);
	else if (io->regmap)
		regmap_read(io->regmap, reg->offset, &val);
	else
		val = readl_relaxed(io->mem + reg->offset);

	return val;
}

/**
 * ti_clk_setup_ll_ops - setup low level clock operations
 * @ops: low level clock ops descriptor
 *
 * Sets up low level clock operations for TI clock driver. This is used
 * to provide various callbacks for the clock driver towards platform
 * specific code. Returns 0 on success, -EBUSY if ll_ops have been
 * registered already.
 */
int ti_clk_setup_ll_ops(struct ti_clk_ll_ops *ops)
{
	if (ti_clk_ll_ops) {
		pr_err("Attempt to register ll_ops multiple times.\n");
		return -EBUSY;
	}

	ti_clk_ll_ops = ops;
	ops->clk_readl = clk_memmap_readl;
	ops->clk_writel = clk_memmap_writel;

	return 0;
}

/**
 * ti_dt_clocks_register - register DT alias clocks during boot
 * @oclks: list of clocks to register
 *
 * Register alias or non-standard DT clock entries during boot. By
 * default, DT clocks are found based on their node name. If any
 * additional con-id / dev-id -> clock mapping is required, use this
 * function to list these.
 */
void __init ti_dt_clocks_register(struct ti_dt_clk oclks[])
{
	struct ti_dt_clk *c;
	struct device_node *node;
	struct clk *clk;
	struct of_phandle_args clkspec;

	for (c = oclks; c->node_name != NULL; c++) {
		node = of_find_node_by_name(NULL, c->node_name);
		clkspec.np = node;
		clk = of_clk_get_from_provider(&clkspec);

		if (!IS_ERR(clk)) {
			c->lk.clk = clk;
			clkdev_add(&c->lk);
		} else {
			pr_warn("failed to lookup clock node %s\n",
				c->node_name);
		}
	}
}

struct clk_init_item {
	struct device_node *node;
	struct clk_hw *hw;
	ti_of_clk_init_cb_t func;
	struct list_head link;
};

static LIST_HEAD(retry_list);

/**
 * ti_clk_retry_init - retries a failed clock init at later phase
 * @node: device not for the clock
 * @hw: partially initialized clk_hw struct for the clock
 * @func: init function to be called for the clock
 *
 * Adds a failed clock init to the retry list. The retry list is parsed
 * once all the other clocks have been initialized.
 */
int __init ti_clk_retry_init(struct device_node *node, struct clk_hw *hw,
			      ti_of_clk_init_cb_t func)
{
	struct clk_init_item *retry;

	pr_debug("%s: adding to retry list...\n", node->name);
	retry = kzalloc(sizeof(*retry), GFP_KERNEL);
	if (!retry)
		return -ENOMEM;

	retry->node = node;
	retry->func = func;
	retry->hw = hw;
	list_add(&retry->link, &retry_list);

	return 0;
}

/**
 * ti_clk_get_reg_addr - get register address for a clock register
 * @node: device node for the clock
 * @index: register index from the clock node
 * @reg: pointer to target register struct
 *
 * Builds clock register address from device tree information, and returns
 * the data via the provided output pointer @reg. Returns 0 on success,
 * negative error value on failure.
 */
int ti_clk_get_reg_addr(struct device_node *node, int index,
			struct clk_omap_reg *reg)
{
	u32 val;
	int i;

	for (i = 0; i < CLK_MAX_MEMMAPS; i++) {
		if (clocks_node_ptr[i] == node->parent)
			break;
	}

	if (i == CLK_MAX_MEMMAPS) {
		pr_err("clk-provider not found for %s!\n", node->name);
		return -ENOENT;
	}

	reg->index = i;

	if (of_property_read_u32_index(node, "reg", index, &val)) {
		pr_err("%s must have reg[%d]!\n", node->name, index);
		return -EINVAL;
	}

	reg->offset = val;
	reg->ptr = NULL;

	return 0;
}

/**
 * omap2_clk_provider_init - init master clock provider
 * @parent: master node
 * @index: internal index for clk_reg_ops
 * @syscon: syscon regmap pointer for accessing clock registers
 * @mem: iomem pointer for the clock provider memory area, only used if
 *       syscon is not provided
 *
 * Initializes a master clock IP block. This basically sets up the
 * mapping from clocks node to the memory map index. All the clocks
 * are then initialized through the common of_clk_init call, and the
 * clocks will access their memory maps based on the node layout.
 * Returns 0 in success.
 */
int __init omap2_clk_provider_init(struct device_node *parent, int index,
				   struct regmap *syscon, void __iomem *mem)
{
	struct device_node *clocks;
	struct clk_iomap *io;

	/* get clocks for this parent */
	clocks = of_get_child_by_name(parent, "clocks");
	if (!clocks) {
		pr_err("%s missing 'clocks' child node.\n", parent->name);
		return -EINVAL;
	}

	/* add clocks node info */
	clocks_node_ptr[index] = clocks;

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

	io->regmap = syscon;
	io->mem = mem;

	clk_memmaps[index] = io;

	return 0;
}

/**
 * omap2_clk_legacy_provider_init - initialize a legacy clock provider
 * @index: index for the clock provider
 * @mem: iomem pointer for the clock provider memory area
 *
 * Initializes a legacy clock provider memory mapping.
 */
void __init omap2_clk_legacy_provider_init(int index, void __iomem *mem)
{
	struct clk_iomap *io;

	io = memblock_virt_alloc(sizeof(*io), 0);

	io->mem = mem;

	clk_memmaps[index] = io;
}

/**
 * ti_dt_clk_init_retry_clks - init clocks from the retry list
 *
 * Initializes any clocks that have failed to initialize before,
 * reasons being missing parent node(s) during earlier init. This
 * typically happens only for DPLLs which need to have both of their
 * parent clocks ready during init.
 */
void ti_dt_clk_init_retry_clks(void)
{
	struct clk_init_item *retry;
	struct clk_init_item *tmp;
	int retries = 5;

	while (!list_empty(&retry_list) && retries) {
		list_for_each_entry_safe(retry, tmp, &retry_list, link) {
			pr_debug("retry-init: %s\n", retry->node->name);
			retry->func(retry->hw, retry->node);
			list_del(&retry->link);
			kfree(retry);
		}
		retries--;
	}
}

#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_ATAGS)
void __init ti_clk_patch_legacy_clks(struct ti_clk **patch)
{
	while (*patch) {
		memcpy((*patch)->patch, *patch, sizeof(**patch));
		patch++;
	}
}

struct clk __init *ti_clk_register_clk(struct ti_clk *setup)
{
	struct clk *clk;
	struct ti_clk_fixed *fixed;
	struct ti_clk_fixed_factor *fixed_factor;
	struct clk_hw *clk_hw;
	int ret;

	if (setup->clk)
		return setup->clk;

	switch (setup->type) {
	case TI_CLK_FIXED:
		fixed = setup->data;

		clk = clk_register_fixed_rate(NULL, setup->name, NULL, 0,
					      fixed->frequency);
		if (!IS_ERR(clk)) {
			ret = ti_clk_add_alias(NULL, clk, setup->name);
			if (ret) {
				clk_unregister(clk);
				clk = ERR_PTR(ret);
			}
		}
		break;
	case TI_CLK_MUX:
		clk = ti_clk_register_mux(setup);
		break;
	case TI_CLK_DIVIDER:
		clk = ti_clk_register_divider(setup);
		break;
	case TI_CLK_COMPOSITE:
		clk = ti_clk_register_composite(setup);
		break;
	case TI_CLK_FIXED_FACTOR:
		fixed_factor = setup->data;

		clk = clk_register_fixed_factor(NULL, setup->name,
						fixed_factor->parent,
						0, fixed_factor->mult,
						fixed_factor->div);
		if (!IS_ERR(clk)) {
			ret = ti_clk_add_alias(NULL, clk, setup->name);
			if (ret) {
				clk_unregister(clk);
				clk = ERR_PTR(ret);
			}
		}
		break;
	case TI_CLK_GATE:
		clk = ti_clk_register_gate(setup);
		break;
	case TI_CLK_DPLL:
		clk = ti_clk_register_dpll(setup);
		break;
	default:
		pr_err("bad type for %s!\n", setup->name);
		clk = ERR_PTR(-EINVAL);
	}

	if (!IS_ERR(clk)) {
		setup->clk = clk;
		if (setup->clkdm_name) {
			clk_hw = __clk_get_hw(clk);
			if (clk_hw_get_flags(clk_hw) & CLK_IS_BASIC) {
				pr_warn("can't setup clkdm for basic clk %s\n",
					setup->name);
			} else {
				to_clk_hw_omap(clk_hw)->clkdm_name =
					setup->clkdm_name;
				omap2_init_clk_clkdm(clk_hw);
			}
		}
	}

	return clk;
}

int __init ti_clk_register_legacy_clks(struct ti_clk_alias *clks)
{
	struct clk *clk;
	bool retry;
	struct ti_clk_alias *retry_clk;
	struct ti_clk_alias *tmp;

	while (clks->clk) {
		clk = ti_clk_register_clk(clks->clk);
		if (IS_ERR(clk)) {
			if (PTR_ERR(clk) == -EAGAIN) {
				list_add(&clks->link, &retry_list);
			} else {
				pr_err("register for %s failed: %ld\n",
				       clks->clk->name, PTR_ERR(clk));
				return PTR_ERR(clk);
			}
		}
		clks++;
	}

	retry = true;

	while (!list_empty(&retry_list) && retry) {
		retry = false;
		list_for_each_entry_safe(retry_clk, tmp, &retry_list, link) {
			pr_debug("retry-init: %s\n", retry_clk->clk->name);
			clk = ti_clk_register_clk(retry_clk->clk);
			if (IS_ERR(clk)) {
				if (PTR_ERR(clk) == -EAGAIN) {
					continue;
				} else {
					pr_err("register for %s failed: %ld\n",
					       retry_clk->clk->name,
					       PTR_ERR(clk));
					return PTR_ERR(clk);
				}
			} else {
				retry = true;
				list_del(&retry_clk->link);
			}
		}
	}

	return 0;
}
#endif

static const struct of_device_id simple_clk_match_table[] __initconst = {
	{ .compatible = "fixed-clock" },
	{ .compatible = "fixed-factor-clock" },
	{ }
};

/**
 * ti_clk_add_aliases - setup clock aliases
 *
 * Sets up any missing clock aliases. No return value.
 */
void __init ti_clk_add_aliases(void)
{
	struct device_node *np;
	struct clk *clk;

	for_each_matching_node(np, simple_clk_match_table) {
		struct of_phandle_args clkspec;

		clkspec.np = np;
		clk = of_clk_get_from_provider(&clkspec);

		ti_clk_add_alias(NULL, clk, np->name);
	}
}

/**
 * ti_clk_setup_features - setup clock features flags
 * @features: features definition to use
 *
 * Initializes the clock driver features flags based on platform
 * provided data. No return value.
 */
void __init ti_clk_setup_features(struct ti_clk_features *features)
{
	memcpy(&ti_clk_features, features, sizeof(*features));
}

/**
 * ti_clk_get_features - get clock driver features flags
 *
 * Get TI clock driver features description. Returns a pointer
 * to the current feature setup.
 */
const struct ti_clk_features *ti_clk_get_features(void)
{
	return &ti_clk_features;
}

/**
 * omap2_clk_enable_init_clocks - prepare & enable a list of clocks
 * @clk_names: ptr to an array of strings of clock names to enable
 * @num_clocks: number of clock names in @clk_names
 *
 * Prepare and enable a list of clocks, named by @clk_names.  No
 * return value. XXX Deprecated; only needed until these clocks are
 * properly claimed and enabled by the drivers or core code that uses
 * them.  XXX What code disables & calls clk_put on these clocks?
 */
void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks)
{
	struct clk *init_clk;
	int i;

	for (i = 0; i < num_clocks; i++) {
		init_clk = clk_get(NULL, clk_names[i]);
		if (WARN(IS_ERR(init_clk), "could not find init clock %s\n",
			 clk_names[i]))
			continue;
		clk_prepare_enable(init_clk);
	}
}

/**
 * ti_clk_add_alias - add a clock alias for a TI clock
 * @dev: device alias for this clock
 * @clk: clock handle to create alias for
 * @con: connection ID for this clock
 *
 * Creates a clock alias for a TI clock. Allocates the clock lookup entry
 * and assigns the data to it. Returns 0 if successful, negative error
 * value otherwise.
 */
int ti_clk_add_alias(struct device *dev, struct clk *clk, const char *con)
{
	struct clk_lookup *cl;

	if (!clk)
		return 0;

	if (IS_ERR(clk))
		return PTR_ERR(clk);

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

	if (dev)
		cl->dev_id = dev_name(dev);
	cl->con_id = con;
	cl->clk = clk;

	clkdev_add(cl);

	return 0;
}

/**
 * ti_clk_register - register a TI clock to the common clock framework
 * @dev: device for this clock
 * @hw: hardware clock handle
 * @con: connection ID for this clock
 *
 * Registers a TI clock to the common clock framework, and adds a clock
 * alias for it. Returns a handle to the registered clock if successful,
 * ERR_PTR value in failure.
 */
struct clk *ti_clk_register(struct device *dev, struct clk_hw *hw,
			    const char *con)
{
	struct clk *clk;
	int ret;

	clk = clk_register(dev, hw);
	if (IS_ERR(clk))
		return clk;

	ret = ti_clk_add_alias(dev, clk, con);
	if (ret) {
		clk_unregister(clk);
		return ERR_PTR(ret);
	}

	return clk;
}
