// SPDX-License-Identifier: GPL-2.0+
// Copyright IBM Corp

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

#include <linux/mfd/syscon.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/slab.h>

#include <dt-bindings/clock/aspeed-clock.h>

#include "clk-aspeed.h"

#define ASPEED_NUM_CLKS		38

#define ASPEED_RESET2_OFFSET	32

#define ASPEED_RESET_CTRL	0x04
#define ASPEED_CLK_SELECTION	0x08
#define ASPEED_CLK_STOP_CTRL	0x0c
#define ASPEED_MPLL_PARAM	0x20
#define ASPEED_HPLL_PARAM	0x24
#define  AST2500_HPLL_BYPASS_EN	BIT(20)
#define  AST2400_HPLL_PROGRAMMED BIT(18)
#define  AST2400_HPLL_BYPASS_EN	BIT(17)
#define ASPEED_MISC_CTRL	0x2c
#define  UART_DIV13_EN		BIT(12)
#define ASPEED_MAC_CLK_DLY	0x48
#define ASPEED_STRAP		0x70
#define  CLKIN_25MHZ_EN		BIT(23)
#define  AST2400_CLK_SOURCE_SEL	BIT(18)
#define ASPEED_CLK_SELECTION_2	0xd8
#define ASPEED_RESET_CTRL2	0xd4

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

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

static void __iomem *scu_base;

/* TODO: ask Aspeed about the actual parent data */
static const struct aspeed_gate_data aspeed_gates[] = {
	/*				 clk rst   name			parent	flags */
	[ASPEED_CLK_GATE_ECLK] =	{  0,  6, "eclk-gate",		"eclk",	0 }, /* Video Engine */
	[ASPEED_CLK_GATE_GCLK] =	{  1,  7, "gclk-gate",		NULL,	0 }, /* 2D engine */
	[ASPEED_CLK_GATE_MCLK] =	{  2, -1, "mclk-gate",		"mpll",	CLK_IS_CRITICAL }, /* SDRAM */
	[ASPEED_CLK_GATE_VCLK] =	{  3, -1, "vclk-gate",		NULL,	0 }, /* Video Capture */
	[ASPEED_CLK_GATE_BCLK] =	{  4,  8, "bclk-gate",		"bclk",	CLK_IS_CRITICAL }, /* PCIe/PCI */
	[ASPEED_CLK_GATE_DCLK] =	{  5, -1, "dclk-gate",		NULL,	CLK_IS_CRITICAL }, /* DAC */
	[ASPEED_CLK_GATE_REFCLK] =	{  6, -1, "refclk-gate",	"clkin", CLK_IS_CRITICAL },
	[ASPEED_CLK_GATE_USBPORT2CLK] =	{  7,  3, "usb-port2-gate",	NULL,	0 }, /* USB2.0 Host port 2 */
	[ASPEED_CLK_GATE_LCLK] =	{  8,  5, "lclk-gate",		NULL,	0 }, /* LPC */
	[ASPEED_CLK_GATE_USBUHCICLK] =	{  9, 15, "usb-uhci-gate",	NULL,	0 }, /* USB1.1 (requires port 2 enabled) */
	[ASPEED_CLK_GATE_D1CLK] =	{ 10, 13, "d1clk-gate",		NULL,	0 }, /* GFX CRT */
	[ASPEED_CLK_GATE_YCLK] =	{ 13,  4, "yclk-gate",		NULL,	0 }, /* HAC */
	[ASPEED_CLK_GATE_USBPORT1CLK] = { 14, 14, "usb-port1-gate",	NULL,	0 }, /* USB2 hub/USB2 host port 1/USB1.1 dev */
	[ASPEED_CLK_GATE_UART1CLK] =	{ 15, -1, "uart1clk-gate",	"uart",	0 }, /* UART1 */
	[ASPEED_CLK_GATE_UART2CLK] =	{ 16, -1, "uart2clk-gate",	"uart",	0 }, /* UART2 */
	[ASPEED_CLK_GATE_UART5CLK] =	{ 17, -1, "uart5clk-gate",	"uart",	0 }, /* UART5 */
	[ASPEED_CLK_GATE_ESPICLK] =	{ 19, -1, "espiclk-gate",	NULL,	0 }, /* eSPI */
	[ASPEED_CLK_GATE_MAC1CLK] =	{ 20, 11, "mac1clk-gate",	"mac",	0 }, /* MAC1 */
	[ASPEED_CLK_GATE_MAC2CLK] =	{ 21, 12, "mac2clk-gate",	"mac",	0 }, /* MAC2 */
	[ASPEED_CLK_GATE_RSACLK] =	{ 24, -1, "rsaclk-gate",	NULL,	0 }, /* RSA */
	[ASPEED_CLK_GATE_UART3CLK] =	{ 25, -1, "uart3clk-gate",	"uart",	0 }, /* UART3 */
	[ASPEED_CLK_GATE_UART4CLK] =	{ 26, -1, "uart4clk-gate",	"uart",	0 }, /* UART4 */
	[ASPEED_CLK_GATE_SDCLK] =	{ 27, 16, "sdclk-gate",		NULL,	0 }, /* SDIO/SD */
	[ASPEED_CLK_GATE_LHCCLK] =	{ 28, -1, "lhclk-gate",		"lhclk", 0 }, /* LPC master/LPC+ */
};

static const char * const eclk_parent_names[] = {
	"mpll",
	"hpll",
	"dpll",
};

static const struct clk_div_table ast2500_eclk_div_table[] = {
	{ 0x0, 2 },
	{ 0x1, 2 },
	{ 0x2, 3 },
	{ 0x3, 4 },
	{ 0x4, 5 },
	{ 0x5, 6 },
	{ 0x6, 7 },
	{ 0x7, 8 },
	{ 0 }
};

static const struct clk_div_table ast2500_mac_div_table[] = {
	{ 0x0, 4 }, /* Yep, really. Aspeed confirmed this is correct */
	{ 0x1, 4 },
	{ 0x2, 6 },
	{ 0x3, 8 },
	{ 0x4, 10 },
	{ 0x5, 12 },
	{ 0x6, 14 },
	{ 0x7, 16 },
	{ 0 }
};

static const struct clk_div_table ast2400_div_table[] = {
	{ 0x0, 2 },
	{ 0x1, 4 },
	{ 0x2, 6 },
	{ 0x3, 8 },
	{ 0x4, 10 },
	{ 0x5, 12 },
	{ 0x6, 14 },
	{ 0x7, 16 },
	{ 0 }
};

static const struct clk_div_table ast2500_div_table[] = {
	{ 0x0, 4 },
	{ 0x1, 8 },
	{ 0x2, 12 },
	{ 0x3, 16 },
	{ 0x4, 20 },
	{ 0x5, 24 },
	{ 0x6, 28 },
	{ 0x7, 32 },
	{ 0 }
};

static struct clk_hw *aspeed_ast2400_calc_pll(const char *name, u32 val)
{
	unsigned int mult, div;

	if (val & AST2400_HPLL_BYPASS_EN) {
		/* Pass through mode */
		mult = div = 1;
	} else {
		/* F = 24Mhz * (2-OD) * [(N + 2) / (D + 1)] */
		u32 n = (val >> 5) & 0x3f;
		u32 od = (val >> 4) & 0x1;
		u32 d = val & 0xf;

		mult = (2 - od) * (n + 2);
		div = d + 1;
	}
	return clk_hw_register_fixed_factor(NULL, name, "clkin", 0,
			mult, div);
};

static struct clk_hw *aspeed_ast2500_calc_pll(const char *name, u32 val)
{
	unsigned int mult, div;

	if (val & AST2500_HPLL_BYPASS_EN) {
		/* Pass through mode */
		mult = div = 1;
	} else {
		/* F = clkin * [(M+1) / (N+1)] / (P + 1) */
		u32 p = (val >> 13) & 0x3f;
		u32 m = (val >> 5) & 0xff;
		u32 n = val & 0x1f;

		mult = (m + 1) / (n + 1);
		div = p + 1;
	}

	return clk_hw_register_fixed_factor(NULL, name, "clkin", 0,
			mult, div);
}

static const struct aspeed_clk_soc_data ast2500_data = {
	.div_table = ast2500_div_table,
	.eclk_div_table = ast2500_eclk_div_table,
	.mac_div_table = ast2500_mac_div_table,
	.calc_pll = aspeed_ast2500_calc_pll,
};

static const struct aspeed_clk_soc_data ast2400_data = {
	.div_table = ast2400_div_table,
	.eclk_div_table = ast2400_div_table,
	.mac_div_table = ast2400_div_table,
	.calc_pll = aspeed_ast2400_calc_pll,
};

static int aspeed_clk_is_enabled(struct clk_hw *hw)
{
	struct aspeed_clk_gate *gate = to_aspeed_clk_gate(hw);
	u32 clk = BIT(gate->clock_idx);
	u32 rst = BIT(gate->reset_idx);
	u32 enval = (gate->flags & CLK_GATE_SET_TO_DISABLE) ? 0 : clk;
	u32 reg;

	/*
	 * If the IP is in reset, treat the clock as not enabled,
	 * this happens with some clocks such as the USB one when
	 * coming from cold reset. Without this, aspeed_clk_enable()
	 * will fail to lift the reset.
	 */
	if (gate->reset_idx >= 0) {
		regmap_read(gate->map, ASPEED_RESET_CTRL, &reg);
		if (reg & rst)
			return 0;
	}

	regmap_read(gate->map, ASPEED_CLK_STOP_CTRL, &reg);

	return ((reg & clk) == enval) ? 1 : 0;
}

static int aspeed_clk_enable(struct clk_hw *hw)
{
	struct aspeed_clk_gate *gate = to_aspeed_clk_gate(hw);
	unsigned long flags;
	u32 clk = BIT(gate->clock_idx);
	u32 rst = BIT(gate->reset_idx);
	u32 enval;

	spin_lock_irqsave(gate->lock, flags);

	if (aspeed_clk_is_enabled(hw)) {
		spin_unlock_irqrestore(gate->lock, flags);
		return 0;
	}

	if (gate->reset_idx >= 0) {
		/* Put IP in reset */
		regmap_update_bits(gate->map, ASPEED_RESET_CTRL, rst, rst);

		/* Delay 100us */
		udelay(100);
	}

	/* Enable clock */
	enval = (gate->flags & CLK_GATE_SET_TO_DISABLE) ? 0 : clk;
	regmap_update_bits(gate->map, ASPEED_CLK_STOP_CTRL, clk, enval);

	if (gate->reset_idx >= 0) {
		/* A delay of 10ms is specified by the ASPEED docs */
		mdelay(10);

		/* Take IP out of reset */
		regmap_update_bits(gate->map, ASPEED_RESET_CTRL, rst, 0);
	}

	spin_unlock_irqrestore(gate->lock, flags);

	return 0;
}

static void aspeed_clk_disable(struct clk_hw *hw)
{
	struct aspeed_clk_gate *gate = to_aspeed_clk_gate(hw);
	unsigned long flags;
	u32 clk = BIT(gate->clock_idx);
	u32 enval;

	spin_lock_irqsave(gate->lock, flags);

	enval = (gate->flags & CLK_GATE_SET_TO_DISABLE) ? clk : 0;
	regmap_update_bits(gate->map, ASPEED_CLK_STOP_CTRL, clk, enval);

	spin_unlock_irqrestore(gate->lock, flags);
}

static const struct clk_ops aspeed_clk_gate_ops = {
	.enable = aspeed_clk_enable,
	.disable = aspeed_clk_disable,
	.is_enabled = aspeed_clk_is_enabled,
};

static const u8 aspeed_resets[] = {
	/* SCU04 resets */
	[ASPEED_RESET_XDMA]	= 25,
	[ASPEED_RESET_MCTP]	= 24,
	[ASPEED_RESET_ADC]	= 23,
	[ASPEED_RESET_JTAG_MASTER] = 22,
	[ASPEED_RESET_MIC]	= 18,
	[ASPEED_RESET_PWM]	=  9,
	[ASPEED_RESET_PECI]	= 10,
	[ASPEED_RESET_I2C]	=  2,
	[ASPEED_RESET_AHB]	=  1,

	/*
	 * SCUD4 resets start at an offset to separate them from
	 * the SCU04 resets.
	 */
	[ASPEED_RESET_CRT1]	= ASPEED_RESET2_OFFSET + 5,
};

static int aspeed_reset_deassert(struct reset_controller_dev *rcdev,
				 unsigned long id)
{
	struct aspeed_reset *ar = to_aspeed_reset(rcdev);
	u32 reg = ASPEED_RESET_CTRL;
	u32 bit = aspeed_resets[id];

	if (bit >= ASPEED_RESET2_OFFSET) {
		bit -= ASPEED_RESET2_OFFSET;
		reg = ASPEED_RESET_CTRL2;
	}

	return regmap_update_bits(ar->map, reg, BIT(bit), 0);
}

static int aspeed_reset_assert(struct reset_controller_dev *rcdev,
			       unsigned long id)
{
	struct aspeed_reset *ar = to_aspeed_reset(rcdev);
	u32 reg = ASPEED_RESET_CTRL;
	u32 bit = aspeed_resets[id];

	if (bit >= ASPEED_RESET2_OFFSET) {
		bit -= ASPEED_RESET2_OFFSET;
		reg = ASPEED_RESET_CTRL2;
	}

	return regmap_update_bits(ar->map, reg, BIT(bit), BIT(bit));
}

static int aspeed_reset_status(struct reset_controller_dev *rcdev,
			       unsigned long id)
{
	struct aspeed_reset *ar = to_aspeed_reset(rcdev);
	u32 reg = ASPEED_RESET_CTRL;
	u32 bit = aspeed_resets[id];
	int ret, val;

	if (bit >= ASPEED_RESET2_OFFSET) {
		bit -= ASPEED_RESET2_OFFSET;
		reg = ASPEED_RESET_CTRL2;
	}

	ret = regmap_read(ar->map, reg, &val);
	if (ret)
		return ret;

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

static const struct reset_control_ops aspeed_reset_ops = {
	.assert = aspeed_reset_assert,
	.deassert = aspeed_reset_deassert,
	.status = aspeed_reset_status,
};

static struct clk_hw *aspeed_clk_hw_register_gate(struct device *dev,
		const char *name, const char *parent_name, unsigned long flags,
		struct regmap *map, u8 clock_idx, u8 reset_idx,
		u8 clk_gate_flags, spinlock_t *lock)
{
	struct aspeed_clk_gate *gate;
	struct clk_init_data init;
	struct clk_hw *hw;
	int ret;

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

	init.name = name;
	init.ops = &aspeed_clk_gate_ops;
	init.flags = flags;
	init.parent_names = parent_name ? &parent_name : NULL;
	init.num_parents = parent_name ? 1 : 0;

	gate->map = map;
	gate->clock_idx = clock_idx;
	gate->reset_idx = reset_idx;
	gate->flags = clk_gate_flags;
	gate->lock = lock;
	gate->hw.init = &init;

	hw = &gate->hw;
	ret = clk_hw_register(dev, hw);
	if (ret) {
		kfree(gate);
		hw = ERR_PTR(ret);
	}

	return hw;
}

static int aspeed_clk_probe(struct platform_device *pdev)
{
	const struct aspeed_clk_soc_data *soc_data;
	struct device *dev = &pdev->dev;
	struct aspeed_reset *ar;
	struct regmap *map;
	struct clk_hw *hw;
	u32 val, rate;
	int i, ret;

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

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

	ar->map = map;
	ar->rcdev.owner = THIS_MODULE;
	ar->rcdev.nr_resets = ARRAY_SIZE(aspeed_resets);
	ar->rcdev.ops = &aspeed_reset_ops;
	ar->rcdev.of_node = dev->of_node;

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

	/* SoC generations share common layouts but have different divisors */
	soc_data = of_device_get_match_data(dev);
	if (!soc_data) {
		dev_err(dev, "no match data for platform\n");
		return -EINVAL;
	}

	/* UART clock div13 setting */
	regmap_read(map, ASPEED_MISC_CTRL, &val);
	if (val & UART_DIV13_EN)
		rate = 24000000 / 13;
	else
		rate = 24000000;
	/* TODO: Find the parent data for the uart clock */
	hw = clk_hw_register_fixed_rate(dev, "uart", NULL, 0, rate);
	if (IS_ERR(hw))
		return PTR_ERR(hw);
	aspeed_clk_data->hws[ASPEED_CLK_UART] = hw;

	/*
	 * Memory controller (M-PLL) PLL. This clock is configured by the
	 * bootloader, and is exposed to Linux as a read-only clock rate.
	 */
	regmap_read(map, ASPEED_MPLL_PARAM, &val);
	hw = soc_data->calc_pll("mpll", val);
	if (IS_ERR(hw))
		return PTR_ERR(hw);
	aspeed_clk_data->hws[ASPEED_CLK_MPLL] =	hw;

	/* SD/SDIO clock divider and gate */
	hw = clk_hw_register_gate(dev, "sd_extclk_gate", "hpll", 0,
				  scu_base + ASPEED_CLK_SELECTION, 15, 0,
				  &aspeed_clk_lock);
	if (IS_ERR(hw))
		return PTR_ERR(hw);
	hw = clk_hw_register_divider_table(dev, "sd_extclk", "sd_extclk_gate",
			0, scu_base + ASPEED_CLK_SELECTION, 12, 3, 0,
			soc_data->div_table,
			&aspeed_clk_lock);
	if (IS_ERR(hw))
		return PTR_ERR(hw);
	aspeed_clk_data->hws[ASPEED_CLK_SDIO] = hw;

	/* MAC AHB bus clock divider */
	hw = clk_hw_register_divider_table(dev, "mac", "hpll", 0,
			scu_base + ASPEED_CLK_SELECTION, 16, 3, 0,
			soc_data->mac_div_table,
			&aspeed_clk_lock);
	if (IS_ERR(hw))
		return PTR_ERR(hw);
	aspeed_clk_data->hws[ASPEED_CLK_MAC] = hw;

	if (of_device_is_compatible(pdev->dev.of_node, "aspeed,ast2500-scu")) {
		/* RMII 50MHz RCLK */
		hw = clk_hw_register_fixed_rate(dev, "mac12rclk", "hpll", 0,
						50000000);
		if (IS_ERR(hw))
			return PTR_ERR(hw);

		/* RMII1 50MHz (RCLK) output enable */
		hw = clk_hw_register_gate(dev, "mac1rclk", "mac12rclk", 0,
				scu_base + ASPEED_MAC_CLK_DLY, 29, 0,
				&aspeed_clk_lock);
		if (IS_ERR(hw))
			return PTR_ERR(hw);
		aspeed_clk_data->hws[ASPEED_CLK_MAC1RCLK] = hw;

		/* RMII2 50MHz (RCLK) output enable */
		hw = clk_hw_register_gate(dev, "mac2rclk", "mac12rclk", 0,
				scu_base + ASPEED_MAC_CLK_DLY, 30, 0,
				&aspeed_clk_lock);
		if (IS_ERR(hw))
			return PTR_ERR(hw);
		aspeed_clk_data->hws[ASPEED_CLK_MAC2RCLK] = hw;
	}

	/* LPC Host (LHCLK) clock divider */
	hw = clk_hw_register_divider_table(dev, "lhclk", "hpll", 0,
			scu_base + ASPEED_CLK_SELECTION, 20, 3, 0,
			soc_data->div_table,
			&aspeed_clk_lock);
	if (IS_ERR(hw))
		return PTR_ERR(hw);
	aspeed_clk_data->hws[ASPEED_CLK_LHCLK] = hw;

	/* P-Bus (BCLK) clock divider */
	hw = clk_hw_register_divider_table(dev, "bclk", "hpll", 0,
			scu_base + ASPEED_CLK_SELECTION_2, 0, 2, 0,
			soc_data->div_table,
			&aspeed_clk_lock);
	if (IS_ERR(hw))
		return PTR_ERR(hw);
	aspeed_clk_data->hws[ASPEED_CLK_BCLK] = hw;

	/* Fixed 24MHz clock */
	hw = clk_hw_register_fixed_rate(NULL, "fixed-24m", "clkin",
					0, 24000000);
	if (IS_ERR(hw))
		return PTR_ERR(hw);
	aspeed_clk_data->hws[ASPEED_CLK_24M] = hw;

	hw = clk_hw_register_mux(dev, "eclk-mux", eclk_parent_names,
				 ARRAY_SIZE(eclk_parent_names), 0,
				 scu_base + ASPEED_CLK_SELECTION, 2, 0x3, 0,
				 &aspeed_clk_lock);
	if (IS_ERR(hw))
		return PTR_ERR(hw);
	aspeed_clk_data->hws[ASPEED_CLK_ECLK_MUX] = hw;

	hw = clk_hw_register_divider_table(dev, "eclk", "eclk-mux", 0,
					   scu_base + ASPEED_CLK_SELECTION, 28,
					   3, 0, soc_data->eclk_div_table,
					   &aspeed_clk_lock);
	if (IS_ERR(hw))
		return PTR_ERR(hw);
	aspeed_clk_data->hws[ASPEED_CLK_ECLK] = hw;

	/*
	 * TODO: There are a number of clocks that not included in this driver
	 * as more information is required:
	 *   D2-PLL
	 *   D-PLL
	 *   YCLK
	 *   RGMII
	 *   RMII
	 *   UART[1..5] clock source mux
	 */

	for (i = 0; i < ARRAY_SIZE(aspeed_gates); i++) {
		const struct aspeed_gate_data *gd = &aspeed_gates[i];
		u32 gate_flags;

		/* Special case: the USB port 1 clock (bit 14) is always
		 * working the opposite way from the other ones.
		 */
		gate_flags = (gd->clock_idx == 14) ? 0 : CLK_GATE_SET_TO_DISABLE;
		hw = aspeed_clk_hw_register_gate(dev,
				gd->name,
				gd->parent_name,
				gd->flags,
				map,
				gd->clock_idx,
				gd->reset_idx,
				gate_flags,
				&aspeed_clk_lock);
		if (IS_ERR(hw))
			return PTR_ERR(hw);
		aspeed_clk_data->hws[i] = hw;
	}

	return 0;
};

static const struct of_device_id aspeed_clk_dt_ids[] = {
	{ .compatible = "aspeed,ast2400-scu", .data = &ast2400_data },
	{ .compatible = "aspeed,ast2500-scu", .data = &ast2500_data },
	{ }
};

static struct platform_driver aspeed_clk_driver = {
	.probe  = aspeed_clk_probe,
	.driver = {
		.name = "aspeed-clk",
		.of_match_table = aspeed_clk_dt_ids,
		.suppress_bind_attrs = true,
	},
};
builtin_platform_driver(aspeed_clk_driver);

static void __init aspeed_ast2400_cc(struct regmap *map)
{
	struct clk_hw *hw;
	u32 val, div, clkin, hpll;
	const u16 hpll_rates[][4] = {
		{384, 360, 336, 408},
		{400, 375, 350, 425},
	};
	int rate;

	/*
	 * CLKIN is the crystal oscillator, 24, 48 or 25MHz selected by
	 * strapping
	 */
	regmap_read(map, ASPEED_STRAP, &val);
	rate = (val >> 8) & 3;
	if (val & CLKIN_25MHZ_EN) {
		clkin = 25000000;
		hpll = hpll_rates[1][rate];
	} else if (val & AST2400_CLK_SOURCE_SEL) {
		clkin = 48000000;
		hpll = hpll_rates[0][rate];
	} else {
		clkin = 24000000;
		hpll = hpll_rates[0][rate];
	}
	hw = clk_hw_register_fixed_rate(NULL, "clkin", NULL, 0, clkin);
	pr_debug("clkin @%u MHz\n", clkin / 1000000);

	/*
	 * High-speed PLL clock derived from the crystal. This the CPU clock,
	 * and we assume that it is enabled. It can be configured through the
	 * HPLL_PARAM register, or set to a specified frequency by strapping.
	 */
	regmap_read(map, ASPEED_HPLL_PARAM, &val);
	if (val & AST2400_HPLL_PROGRAMMED)
		hw = aspeed_ast2400_calc_pll("hpll", val);
	else
		hw = clk_hw_register_fixed_rate(NULL, "hpll", "clkin", 0,
				hpll * 1000000);

	aspeed_clk_data->hws[ASPEED_CLK_HPLL] = hw;

	/*
	 * Strap bits 11:10 define the CPU/AHB clock frequency ratio (aka HCLK)
	 *   00: Select CPU:AHB = 1:1
	 *   01: Select CPU:AHB = 2:1
	 *   10: Select CPU:AHB = 4:1
	 *   11: Select CPU:AHB = 3:1
	 */
	regmap_read(map, ASPEED_STRAP, &val);
	val = (val >> 10) & 0x3;
	div = val + 1;
	if (div == 3)
		div = 4;
	else if (div == 4)
		div = 3;
	hw = clk_hw_register_fixed_factor(NULL, "ahb", "hpll", 0, 1, div);
	aspeed_clk_data->hws[ASPEED_CLK_AHB] = hw;

	/* APB clock clock selection register SCU08 (aka PCLK) */
	hw = clk_hw_register_divider_table(NULL, "apb", "hpll", 0,
			scu_base + ASPEED_CLK_SELECTION, 23, 3, 0,
			ast2400_div_table,
			&aspeed_clk_lock);
	aspeed_clk_data->hws[ASPEED_CLK_APB] = hw;
}

static void __init aspeed_ast2500_cc(struct regmap *map)
{
	struct clk_hw *hw;
	u32 val, freq, div;

	/* CLKIN is the crystal oscillator, 24 or 25MHz selected by strapping */
	regmap_read(map, ASPEED_STRAP, &val);
	if (val & CLKIN_25MHZ_EN)
		freq = 25000000;
	else
		freq = 24000000;
	hw = clk_hw_register_fixed_rate(NULL, "clkin", NULL, 0, freq);
	pr_debug("clkin @%u MHz\n", freq / 1000000);

	/*
	 * High-speed PLL clock derived from the crystal. This the CPU clock,
	 * and we assume that it is enabled
	 */
	regmap_read(map, ASPEED_HPLL_PARAM, &val);
	aspeed_clk_data->hws[ASPEED_CLK_HPLL] = aspeed_ast2500_calc_pll("hpll", val);

	/* Strap bits 11:9 define the AXI/AHB clock frequency ratio (aka HCLK)*/
	regmap_read(map, ASPEED_STRAP, &val);
	val = (val >> 9) & 0x7;
	WARN(val == 0, "strapping is zero: cannot determine ahb clock");
	div = 2 * (val + 1);
	hw = clk_hw_register_fixed_factor(NULL, "ahb", "hpll", 0, 1, div);
	aspeed_clk_data->hws[ASPEED_CLK_AHB] = hw;

	/* APB clock clock selection register SCU08 (aka PCLK) */
	regmap_read(map, ASPEED_CLK_SELECTION, &val);
	val = (val >> 23) & 0x7;
	div = 4 * (val + 1);
	hw = clk_hw_register_fixed_factor(NULL, "apb", "hpll", 0, 1, div);
	aspeed_clk_data->hws[ASPEED_CLK_APB] = hw;
};

static void __init aspeed_cc_init(struct device_node *np)
{
	struct regmap *map;
	u32 val;
	int ret;
	int i;

	scu_base = of_iomap(np, 0);
	if (!scu_base)
		return;

	aspeed_clk_data = kzalloc(struct_size(aspeed_clk_data, hws,
					      ASPEED_NUM_CLKS),
				  GFP_KERNEL);
	if (!aspeed_clk_data)
		return;
	aspeed_clk_data->num = ASPEED_NUM_CLKS;

	/*
	 * This way all clocks fetched before the platform device probes,
	 * except those we assign here for early use, will be deferred.
	 */
	for (i = 0; i < ASPEED_NUM_CLKS; i++)
		aspeed_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, ASPEED_STRAP, &val);
	if (ret) {
		pr_err("failed to read strapping register\n");
		return;
	}

	if (of_device_is_compatible(np, "aspeed,ast2400-scu"))
		aspeed_ast2400_cc(map);
	else if (of_device_is_compatible(np, "aspeed,ast2500-scu"))
		aspeed_ast2500_cc(map);
	else
		pr_err("unknown platform, failed to add clocks\n");
	ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, aspeed_clk_data);
	if (ret)
		pr_err("failed to add DT provider: %d\n", ret);
};
CLK_OF_DECLARE_DRIVER(aspeed_cc_g5, "aspeed,ast2500-scu", aspeed_cc_init);
CLK_OF_DECLARE_DRIVER(aspeed_cc_g4, "aspeed,ast2400-scu", aspeed_cc_init);
