/*
 * Cortina Gemini SoC Clock Controller driver
 * Copyright (c) 2017 Linus Walleij <linus.walleij@linaro.org>
 */

#define pr_fmt(fmt) "clk-gemini: " fmt

#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/clk-provider.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>
#include <linux/spinlock.h>
#include <linux/reset-controller.h>
#include <dt-bindings/reset/cortina,gemini-reset.h>
#include <dt-bindings/clock/cortina,gemini-clock.h>

/* Globally visible clocks */
static DEFINE_SPINLOCK(gemini_clk_lock);

#define GEMINI_GLOBAL_STATUS		0x04
#define PLL_OSC_SEL			BIT(30)
#define AHBSPEED_SHIFT			(15)
#define AHBSPEED_MASK			0x07
#define CPU_AHB_RATIO_SHIFT		(18)
#define CPU_AHB_RATIO_MASK		0x03

#define GEMINI_GLOBAL_PLL_CONTROL	0x08

#define GEMINI_GLOBAL_SOFT_RESET	0x0c

#define GEMINI_GLOBAL_MISC_CONTROL	0x30
#define PCI_CLK_66MHZ			BIT(18)
#define PCI_CLK_OE			BIT(17)

#define GEMINI_GLOBAL_CLOCK_CONTROL	0x34
#define PCI_CLKRUN_EN			BIT(16)
#define TVC_HALFDIV_SHIFT		(24)
#define TVC_HALFDIV_MASK		0x1f
#define SECURITY_CLK_SEL		BIT(29)

#define GEMINI_GLOBAL_PCI_DLL_CONTROL	0x44
#define PCI_DLL_BYPASS			BIT(31)
#define PCI_DLL_TAP_SEL_MASK		0x1f

/**
 * struct gemini_data_data - Gemini gated clocks
 * @bit_idx: the bit used to gate this clock in the clock register
 * @name: the clock name
 * @parent_name: the name of the parent clock
 * @flags: standard clock framework flags
 */
struct gemini_gate_data {
	u8 bit_idx;
	const char *name;
	const char *parent_name;
	unsigned long flags;
};

/**
 * struct clk_gemini_pci - Gemini PCI clock
 * @hw: corresponding clock hardware entry
 * @map: regmap to access the registers
 * @rate: current rate
 */
struct clk_gemini_pci {
	struct clk_hw hw;
	struct regmap *map;
	unsigned long rate;
};

/**
 * struct gemini_reset - gemini reset controller
 * @map: regmap to access the containing system controller
 * @rcdev: reset controller device
 */
struct gemini_reset {
	struct regmap *map;
	struct reset_controller_dev rcdev;
};

/* Keeps track of all clocks */
static struct clk_hw_onecell_data *gemini_clk_data;

static const struct gemini_gate_data gemini_gates[] = {
	{ 1, "security-gate", "secdiv", 0 },
	{ 2, "gmac0-gate", "ahb", 0 },
	{ 3, "gmac1-gate", "ahb", 0 },
	{ 4, "sata0-gate", "ahb", 0 },
	{ 5, "sata1-gate", "ahb", 0 },
	{ 6, "usb0-gate", "ahb", 0 },
	{ 7, "usb1-gate", "ahb", 0 },
	{ 8, "ide-gate", "ahb", 0 },
	{ 9, "pci-gate", "ahb", 0 },
	/*
	 * The DDR controller may never have a driver, but certainly must
	 * not be gated off.
	 */
	{ 10, "ddr-gate", "ahb", CLK_IS_CRITICAL },
	/*
	 * The flash controller must be on to access NOR flash through the
	 * memory map.
	 */
	{ 11, "flash-gate", "ahb", CLK_IGNORE_UNUSED },
	{ 12, "tvc-gate", "ahb", 0 },
	{ 13, "boot-gate", "apb", 0 },
};

#define to_pciclk(_hw) container_of(_hw, struct clk_gemini_pci, hw)

#define to_gemini_reset(p) container_of((p), struct gemini_reset, rcdev)

static unsigned long gemini_pci_recalc_rate(struct clk_hw *hw,
					    unsigned long parent_rate)
{
	struct clk_gemini_pci *pciclk = to_pciclk(hw);
	u32 val;

	regmap_read(pciclk->map, GEMINI_GLOBAL_MISC_CONTROL, &val);
	if (val & PCI_CLK_66MHZ)
		return 66000000;
	return 33000000;
}

static long gemini_pci_round_rate(struct clk_hw *hw, unsigned long rate,
				  unsigned long *prate)
{
	/* We support 33 and 66 MHz */
	if (rate < 48000000)
		return 33000000;
	return 66000000;
}

static int gemini_pci_set_rate(struct clk_hw *hw, unsigned long rate,
			       unsigned long parent_rate)
{
	struct clk_gemini_pci *pciclk = to_pciclk(hw);

	if (rate == 33000000)
		return regmap_update_bits(pciclk->map,
					  GEMINI_GLOBAL_MISC_CONTROL,
					  PCI_CLK_66MHZ, 0);
	if (rate == 66000000)
		return regmap_update_bits(pciclk->map,
					  GEMINI_GLOBAL_MISC_CONTROL,
					  0, PCI_CLK_66MHZ);
	return -EINVAL;
}

static int gemini_pci_enable(struct clk_hw *hw)
{
	struct clk_gemini_pci *pciclk = to_pciclk(hw);

	regmap_update_bits(pciclk->map, GEMINI_GLOBAL_CLOCK_CONTROL,
			   0, PCI_CLKRUN_EN);
	regmap_update_bits(pciclk->map,
			   GEMINI_GLOBAL_MISC_CONTROL,
			   0, PCI_CLK_OE);
	return 0;
}

static void gemini_pci_disable(struct clk_hw *hw)
{
	struct clk_gemini_pci *pciclk = to_pciclk(hw);

	regmap_update_bits(pciclk->map,
			   GEMINI_GLOBAL_MISC_CONTROL,
			   PCI_CLK_OE, 0);
	regmap_update_bits(pciclk->map, GEMINI_GLOBAL_CLOCK_CONTROL,
			   PCI_CLKRUN_EN, 0);
}

static int gemini_pci_is_enabled(struct clk_hw *hw)
{
	struct clk_gemini_pci *pciclk = to_pciclk(hw);
	unsigned int val;

	regmap_read(pciclk->map, GEMINI_GLOBAL_CLOCK_CONTROL, &val);
	return !!(val & PCI_CLKRUN_EN);
}

static const struct clk_ops gemini_pci_clk_ops = {
	.recalc_rate = gemini_pci_recalc_rate,
	.round_rate = gemini_pci_round_rate,
	.set_rate = gemini_pci_set_rate,
	.enable = gemini_pci_enable,
	.disable = gemini_pci_disable,
	.is_enabled = gemini_pci_is_enabled,
};

static struct clk_hw *gemini_pci_clk_setup(const char *name,
					   const char *parent_name,
					   struct regmap *map)
{
	struct clk_gemini_pci *pciclk;
	struct clk_init_data init;
	int ret;

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

	init.name = name;
	init.ops = &gemini_pci_clk_ops;
	init.flags = 0;
	init.parent_names = &parent_name;
	init.num_parents = 1;
	pciclk->map = map;
	pciclk->hw.init = &init;

	ret = clk_hw_register(NULL, &pciclk->hw);
	if (ret) {
		kfree(pciclk);
		return ERR_PTR(ret);
	}

	return &pciclk->hw;
}

/*
 * This is a self-deasserting reset controller.
 */
static int gemini_reset(struct reset_controller_dev *rcdev,
			unsigned long id)
{
	struct gemini_reset *gr = to_gemini_reset(rcdev);

	/* Manual says to always set BIT 30 (CPU1) to 1 */
	return regmap_write(gr->map,
			    GEMINI_GLOBAL_SOFT_RESET,
			    BIT(GEMINI_RESET_CPU1) | BIT(id));
}

static int gemini_reset_status(struct reset_controller_dev *rcdev,
			     unsigned long id)
{
	struct gemini_reset *gr = to_gemini_reset(rcdev);
	u32 val;
	int ret;

	ret = regmap_read(gr->map, GEMINI_GLOBAL_SOFT_RESET, &val);
	if (ret)
		return ret;

	return !!(val & BIT(id));
}

static const struct reset_control_ops gemini_reset_ops = {
	.reset = gemini_reset,
	.status = gemini_reset_status,
};

static int gemini_clk_probe(struct platform_device *pdev)
{
	/* Gives the fracions 1x, 1.5x, 1.85x and 2x */
	unsigned int cpu_ahb_mult[4] = { 1, 3, 24, 2 };
	unsigned int cpu_ahb_div[4] = { 1, 2, 13, 1 };
	void __iomem *base;
	struct gemini_reset *gr;
	struct regmap *map;
	struct clk_hw *hw;
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	unsigned int mult, div;
	struct resource *res;
	u32 val;
	int ret;
	int i;

	gr = devm_kzalloc(dev, sizeof(*gr), GFP_KERNEL);
	if (!gr)
		return -ENOMEM;

	/* Remap the system controller for the exclusive register */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	base = devm_ioremap_resource(dev, res);
	if (IS_ERR(base))
		return PTR_ERR(base);

	map = syscon_node_to_regmap(np);
	if (IS_ERR(map)) {
		dev_err(dev, "no syscon regmap\n");
		return PTR_ERR(map);
	}

	gr->map = map;
	gr->rcdev.owner = THIS_MODULE;
	gr->rcdev.nr_resets = 32;
	gr->rcdev.ops = &gemini_reset_ops;
	gr->rcdev.of_node = np;

	ret = devm_reset_controller_register(dev, &gr->rcdev);
	if (ret) {
		dev_err(dev, "could not register reset controller\n");
		return ret;
	}

	/* RTC clock 32768 Hz */
	hw = clk_hw_register_fixed_rate(NULL, "rtc", NULL, 0, 32768);
	gemini_clk_data->hws[GEMINI_CLK_RTC] = hw;

	/* CPU clock derived as a fixed ratio from the AHB clock */
	regmap_read(map, GEMINI_GLOBAL_STATUS, &val);
	val >>= CPU_AHB_RATIO_SHIFT;
	val &= CPU_AHB_RATIO_MASK;
	hw = clk_hw_register_fixed_factor(NULL, "cpu", "ahb", 0,
					  cpu_ahb_mult[val],
					  cpu_ahb_div[val]);
	gemini_clk_data->hws[GEMINI_CLK_CPU] = hw;

	/* Security clock is 1:1 or 0.75 of APB */
	regmap_read(map, GEMINI_GLOBAL_CLOCK_CONTROL, &val);
	if (val & SECURITY_CLK_SEL) {
		mult = 1;
		div = 1;
	} else {
		mult = 3;
		div = 4;
	}
	hw = clk_hw_register_fixed_factor(NULL, "secdiv", "ahb", 0, mult, div);

	/*
	 * These are the leaf gates, at boot no clocks are gated.
	 */
	for (i = 0; i < ARRAY_SIZE(gemini_gates); i++) {
		const struct gemini_gate_data *gd;

		gd = &gemini_gates[i];
		gemini_clk_data->hws[GEMINI_CLK_GATES + i] =
			clk_hw_register_gate(NULL, gd->name,
					     gd->parent_name,
					     gd->flags,
					     base + GEMINI_GLOBAL_CLOCK_CONTROL,
					     gd->bit_idx,
					     CLK_GATE_SET_TO_DISABLE,
					     &gemini_clk_lock);
	}

	/*
	 * The TV Interface Controller has a 5-bit half divider register.
	 * This clock is supposed to be 27MHz as this is an exact multiple
	 * of PAL and NTSC frequencies. The register is undocumented :(
	 * FIXME: figure out the parent and how the divider works.
	 */
	mult = 1;
	div = ((val >> TVC_HALFDIV_SHIFT) & TVC_HALFDIV_MASK);
	dev_dbg(dev, "TVC half divider value = %d\n", div);
	div += 1;
	hw = clk_hw_register_fixed_rate(NULL, "tvcdiv", "xtal", 0, 27000000);
	gemini_clk_data->hws[GEMINI_CLK_TVC] = hw;

	/* FIXME: very unclear what the parent is */
	hw = gemini_pci_clk_setup("PCI", "xtal", map);
	gemini_clk_data->hws[GEMINI_CLK_PCI] = hw;

	/* FIXME: very unclear what the parent is */
	hw = clk_hw_register_fixed_rate(NULL, "uart", "xtal", 0, 48000000);
	gemini_clk_data->hws[GEMINI_CLK_UART] = hw;

	return 0;
}

static const struct of_device_id gemini_clk_dt_ids[] = {
	{ .compatible = "cortina,gemini-syscon", },
	{ /* sentinel */ },
};

static struct platform_driver gemini_clk_driver = {
	.probe  = gemini_clk_probe,
	.driver = {
		.name = "gemini-clk",
		.of_match_table = gemini_clk_dt_ids,
		.suppress_bind_attrs = true,
	},
};
builtin_platform_driver(gemini_clk_driver);

static void __init gemini_cc_init(struct device_node *np)
{
	struct regmap *map;
	struct clk_hw *hw;
	unsigned long freq;
	unsigned int mult, div;
	u32 val;
	int ret;
	int i;

	gemini_clk_data = kzalloc(sizeof(*gemini_clk_data) +
			sizeof(*gemini_clk_data->hws) * GEMINI_NUM_CLKS,
			GFP_KERNEL);
	if (!gemini_clk_data)
		return;

	/*
	 * This way all clock fetched before the platform device probes,
	 * except those we assign here for early use, will be deferred.
	 */
	for (i = 0; i < GEMINI_NUM_CLKS; i++)
		gemini_clk_data->hws[i] = ERR_PTR(-EPROBE_DEFER);

	map = syscon_node_to_regmap(np);
	if (IS_ERR(map)) {
		pr_err("no syscon regmap\n");
		return;
	}
	/*
	 * We check that the regmap works on this very first access,
	 * but as this is an MMIO-backed regmap, subsequent regmap
	 * access is not going to fail and we skip error checks from
	 * this point.
	 */
	ret = regmap_read(map, GEMINI_GLOBAL_STATUS, &val);
	if (ret) {
		pr_err("failed to read global status register\n");
		return;
	}

	/*
	 * XTAL is the crystal oscillator, 60 or 30 MHz selected from
	 * strap pin E6
	 */
	if (val & PLL_OSC_SEL)
		freq = 30000000;
	else
		freq = 60000000;
	hw = clk_hw_register_fixed_rate(NULL, "xtal", NULL, 0, freq);
	pr_debug("main crystal @%lu MHz\n", freq / 1000000);

	/* VCO clock derived from the crystal */
	mult = 13 + ((val >> AHBSPEED_SHIFT) & AHBSPEED_MASK);
	div = 2;
	/* If we run on 30 MHz crystal we have to multiply with two */
	if (val & PLL_OSC_SEL)
		mult *= 2;
	hw = clk_hw_register_fixed_factor(NULL, "vco", "xtal", 0, mult, div);

	/* The AHB clock is always 1/3 of the VCO */
	hw = clk_hw_register_fixed_factor(NULL, "ahb", "vco", 0, 1, 3);
	gemini_clk_data->hws[GEMINI_CLK_AHB] = hw;

	/* The APB clock is always 1/6 of the AHB */
	hw = clk_hw_register_fixed_factor(NULL, "apb", "ahb", 0, 1, 6);
	gemini_clk_data->hws[GEMINI_CLK_APB] = hw;

	/* Register the clocks to be accessed by the device tree */
	gemini_clk_data->num = GEMINI_NUM_CLKS;
	of_clk_add_hw_provider(np, of_clk_hw_onecell_get, gemini_clk_data);
}
CLK_OF_DECLARE_DRIVER(gemini_cc, "cortina,gemini-syscon", gemini_cc_init);
