/*
 * Intel Atom platform clocks driver for BayTrail and CherryTrail SoCs
 *
 * Copyright (C) 2016, Intel Corporation
 * Author: Irina Tirdea <irina.tirdea@intel.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope 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/clk-provider.h>
#include <linux/clkdev.h>
#include <linux/err.h>
#include <linux/platform_data/x86/clk-pmc-atom.h>
#include <linux/platform_device.h>
#include <linux/slab.h>

#define PLT_CLK_NAME_BASE	"pmc_plt_clk"

#define PMC_CLK_CTL_OFFSET		0x60
#define PMC_CLK_CTL_SIZE		4
#define PMC_CLK_NUM			6
#define PMC_CLK_CTL_GATED_ON_D3		0x0
#define PMC_CLK_CTL_FORCE_ON		0x1
#define PMC_CLK_CTL_FORCE_OFF		0x2
#define PMC_CLK_CTL_RESERVED		0x3
#define PMC_MASK_CLK_CTL		GENMASK(1, 0)
#define PMC_MASK_CLK_FREQ		BIT(2)
#define PMC_CLK_FREQ_XTAL		(0 << 2)	/* 25 MHz */
#define PMC_CLK_FREQ_PLL		(1 << 2)	/* 19.2 MHz */

struct clk_plt_fixed {
	struct clk_hw *clk;
	struct clk_lookup *lookup;
};

struct clk_plt {
	struct clk_hw hw;
	void __iomem *reg;
	struct clk_lookup *lookup;
	/* protect access to PMC registers */
	spinlock_t lock;
};

#define to_clk_plt(_hw) container_of(_hw, struct clk_plt, hw)

struct clk_plt_data {
	struct clk_plt_fixed **parents;
	u8 nparents;
	struct clk_plt *clks[PMC_CLK_NUM];
	struct clk_lookup *mclk_lookup;
	struct clk_lookup *ether_clk_lookup;
};

/* Return an index in parent table */
static inline int plt_reg_to_parent(int reg)
{
	switch (reg & PMC_MASK_CLK_FREQ) {
	default:
	case PMC_CLK_FREQ_XTAL:
		return 0;
	case PMC_CLK_FREQ_PLL:
		return 1;
	}
}

/* Return clk index of parent */
static inline int plt_parent_to_reg(int index)
{
	switch (index) {
	default:
	case 0:
		return PMC_CLK_FREQ_XTAL;
	case 1:
		return PMC_CLK_FREQ_PLL;
	}
}

/* Abstract status in simpler enabled/disabled value */
static inline int plt_reg_to_enabled(int reg)
{
	switch (reg & PMC_MASK_CLK_CTL) {
	case PMC_CLK_CTL_GATED_ON_D3:
	case PMC_CLK_CTL_FORCE_ON:
		return 1;	/* enabled */
	case PMC_CLK_CTL_FORCE_OFF:
	case PMC_CLK_CTL_RESERVED:
	default:
		return 0;	/* disabled */
	}
}

static void plt_clk_reg_update(struct clk_plt *clk, u32 mask, u32 val)
{
	u32 tmp;
	unsigned long flags;

	spin_lock_irqsave(&clk->lock, flags);

	tmp = readl(clk->reg);
	tmp = (tmp & ~mask) | (val & mask);
	writel(tmp, clk->reg);

	spin_unlock_irqrestore(&clk->lock, flags);
}

static int plt_clk_set_parent(struct clk_hw *hw, u8 index)
{
	struct clk_plt *clk = to_clk_plt(hw);

	plt_clk_reg_update(clk, PMC_MASK_CLK_FREQ, plt_parent_to_reg(index));

	return 0;
}

static u8 plt_clk_get_parent(struct clk_hw *hw)
{
	struct clk_plt *clk = to_clk_plt(hw);
	u32 value;

	value = readl(clk->reg);

	return plt_reg_to_parent(value);
}

static int plt_clk_enable(struct clk_hw *hw)
{
	struct clk_plt *clk = to_clk_plt(hw);

	plt_clk_reg_update(clk, PMC_MASK_CLK_CTL, PMC_CLK_CTL_FORCE_ON);

	return 0;
}

static void plt_clk_disable(struct clk_hw *hw)
{
	struct clk_plt *clk = to_clk_plt(hw);

	plt_clk_reg_update(clk, PMC_MASK_CLK_CTL, PMC_CLK_CTL_FORCE_OFF);
}

static int plt_clk_is_enabled(struct clk_hw *hw)
{
	struct clk_plt *clk = to_clk_plt(hw);
	u32 value;

	value = readl(clk->reg);

	return plt_reg_to_enabled(value);
}

static const struct clk_ops plt_clk_ops = {
	.enable = plt_clk_enable,
	.disable = plt_clk_disable,
	.is_enabled = plt_clk_is_enabled,
	.get_parent = plt_clk_get_parent,
	.set_parent = plt_clk_set_parent,
	.determine_rate = __clk_mux_determine_rate,
};

static struct clk_plt *plt_clk_register(struct platform_device *pdev, int id,
					const struct pmc_clk_data *pmc_data,
					const char **parent_names,
					int num_parents)
{
	struct clk_plt *pclk;
	struct clk_init_data init;
	int ret;

	pclk = devm_kzalloc(&pdev->dev, sizeof(*pclk), GFP_KERNEL);
	if (!pclk)
		return ERR_PTR(-ENOMEM);

	init.name =  kasprintf(GFP_KERNEL, "%s_%d", PLT_CLK_NAME_BASE, id);
	init.ops = &plt_clk_ops;
	init.flags = 0;
	init.parent_names = parent_names;
	init.num_parents = num_parents;

	pclk->hw.init = &init;
	pclk->reg = pmc_data->base + PMC_CLK_CTL_OFFSET + id * PMC_CLK_CTL_SIZE;
	spin_lock_init(&pclk->lock);

	/*
	 * On some systems, the pmc_plt_clocks already enabled by the
	 * firmware are being marked as critical to avoid them being
	 * gated by the clock framework.
	 */
	if (pmc_data->critical && plt_clk_is_enabled(&pclk->hw))
		init.flags |= CLK_IS_CRITICAL;

	ret = devm_clk_hw_register(&pdev->dev, &pclk->hw);
	if (ret) {
		pclk = ERR_PTR(ret);
		goto err_free_init;
	}

	pclk->lookup = clkdev_hw_create(&pclk->hw, init.name, NULL);
	if (!pclk->lookup) {
		pclk = ERR_PTR(-ENOMEM);
		goto err_free_init;
	}

err_free_init:
	kfree(init.name);
	return pclk;
}

static void plt_clk_unregister(struct clk_plt *pclk)
{
	clkdev_drop(pclk->lookup);
}

static struct clk_plt_fixed *plt_clk_register_fixed_rate(struct platform_device *pdev,
						 const char *name,
						 const char *parent_name,
						 unsigned long fixed_rate)
{
	struct clk_plt_fixed *pclk;

	pclk = devm_kzalloc(&pdev->dev, sizeof(*pclk), GFP_KERNEL);
	if (!pclk)
		return ERR_PTR(-ENOMEM);

	pclk->clk = clk_hw_register_fixed_rate(&pdev->dev, name, parent_name,
					       0, fixed_rate);
	if (IS_ERR(pclk->clk))
		return ERR_CAST(pclk->clk);

	pclk->lookup = clkdev_hw_create(pclk->clk, name, NULL);
	if (!pclk->lookup) {
		clk_hw_unregister_fixed_rate(pclk->clk);
		return ERR_PTR(-ENOMEM);
	}

	return pclk;
}

static void plt_clk_unregister_fixed_rate(struct clk_plt_fixed *pclk)
{
	clkdev_drop(pclk->lookup);
	clk_hw_unregister_fixed_rate(pclk->clk);
}

static void plt_clk_unregister_fixed_rate_loop(struct clk_plt_data *data,
					       unsigned int i)
{
	while (i--)
		plt_clk_unregister_fixed_rate(data->parents[i]);
}

static void plt_clk_free_parent_names_loop(const char **parent_names,
					   unsigned int i)
{
	while (i--)
		kfree_const(parent_names[i]);
	kfree(parent_names);
}

static void plt_clk_unregister_loop(struct clk_plt_data *data,
				    unsigned int i)
{
	while (i--)
		plt_clk_unregister(data->clks[i]);
}

static const char **plt_clk_register_parents(struct platform_device *pdev,
					     struct clk_plt_data *data,
					     const struct pmc_clk *clks)
{
	const char **parent_names;
	unsigned int i;
	int err;
	int nparents = 0;

	data->nparents = 0;
	while (clks[nparents].name)
		nparents++;

	data->parents = devm_kcalloc(&pdev->dev, nparents,
				     sizeof(*data->parents), GFP_KERNEL);
	if (!data->parents)
		return ERR_PTR(-ENOMEM);

	parent_names = kcalloc(nparents, sizeof(*parent_names),
			       GFP_KERNEL);
	if (!parent_names)
		return ERR_PTR(-ENOMEM);

	for (i = 0; i < nparents; i++) {
		data->parents[i] =
			plt_clk_register_fixed_rate(pdev, clks[i].name,
						    clks[i].parent_name,
						    clks[i].freq);
		if (IS_ERR(data->parents[i])) {
			err = PTR_ERR(data->parents[i]);
			goto err_unreg;
		}
		parent_names[i] = kstrdup_const(clks[i].name, GFP_KERNEL);
	}

	data->nparents = nparents;
	return parent_names;

err_unreg:
	plt_clk_unregister_fixed_rate_loop(data, i);
	plt_clk_free_parent_names_loop(parent_names, i);
	return ERR_PTR(err);
}

static void plt_clk_unregister_parents(struct clk_plt_data *data)
{
	plt_clk_unregister_fixed_rate_loop(data, data->nparents);
}

static int plt_clk_probe(struct platform_device *pdev)
{
	const struct pmc_clk_data *pmc_data;
	const char **parent_names;
	struct clk_plt_data *data;
	unsigned int i;
	int err;

	pmc_data = dev_get_platdata(&pdev->dev);
	if (!pmc_data || !pmc_data->clks)
		return -EINVAL;

	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	parent_names = plt_clk_register_parents(pdev, data, pmc_data->clks);
	if (IS_ERR(parent_names))
		return PTR_ERR(parent_names);

	for (i = 0; i < PMC_CLK_NUM; i++) {
		data->clks[i] = plt_clk_register(pdev, i, pmc_data,
						 parent_names, data->nparents);
		if (IS_ERR(data->clks[i])) {
			err = PTR_ERR(data->clks[i]);
			goto err_unreg_clk_plt;
		}
	}
	data->mclk_lookup = clkdev_hw_create(&data->clks[3]->hw, "mclk", NULL);
	if (!data->mclk_lookup) {
		err = -ENOMEM;
		goto err_unreg_clk_plt;
	}

	data->ether_clk_lookup = clkdev_hw_create(&data->clks[4]->hw,
						  "ether_clk", NULL);
	if (!data->ether_clk_lookup) {
		err = -ENOMEM;
		goto err_drop_mclk;
	}

	plt_clk_free_parent_names_loop(parent_names, data->nparents);

	platform_set_drvdata(pdev, data);
	return 0;

err_drop_mclk:
	clkdev_drop(data->mclk_lookup);
err_unreg_clk_plt:
	plt_clk_unregister_loop(data, i);
	plt_clk_unregister_parents(data);
	plt_clk_free_parent_names_loop(parent_names, data->nparents);
	return err;
}

static int plt_clk_remove(struct platform_device *pdev)
{
	struct clk_plt_data *data;

	data = platform_get_drvdata(pdev);

	clkdev_drop(data->ether_clk_lookup);
	clkdev_drop(data->mclk_lookup);
	plt_clk_unregister_loop(data, PMC_CLK_NUM);
	plt_clk_unregister_parents(data);
	return 0;
}

static struct platform_driver plt_clk_driver = {
	.driver = {
		.name = "clk-pmc-atom",
	},
	.probe = plt_clk_probe,
	.remove = plt_clk_remove,
};
builtin_platform_driver(plt_clk_driver);
