/*
 * Marvell Armada 370 SoC clocks
 *
 * Copyright (C) 2012 Marvell
 *
 * Gregory CLEMENT <gregory.clement@free-electrons.com>
 * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
 * Andrew Lunn <andrew@lunn.ch>
 *
 * This file is licensed under the terms of the GNU General Public
 * License version 2.  This program is licensed "as is" without any
 * warranty of any kind, whether express or implied.
 */

#include <linux/kernel.h>
#include <linux/clk-provider.h>
#include <linux/io.h>
#include <linux/of.h>
#include "common.h"

/*
 * Core Clocks
 */

#define SARL				0	/* Low part [0:31] */
#define	 SARL_A370_PCLK_FREQ_OPT	11
#define	 SARL_A370_PCLK_FREQ_OPT_MASK	0xF
#define	 SARL_A370_FAB_FREQ_OPT		15
#define	 SARL_A370_FAB_FREQ_OPT_MASK	0x1F
#define	 SARL_A370_TCLK_FREQ_OPT	20
#define	 SARL_A370_TCLK_FREQ_OPT_MASK	0x1

enum { A370_CPU_TO_NBCLK, A370_CPU_TO_HCLK, A370_CPU_TO_DRAMCLK };

static const struct coreclk_ratio a370_coreclk_ratios[] __initconst = {
	{ .id = A370_CPU_TO_NBCLK, .name = "nbclk" },
	{ .id = A370_CPU_TO_HCLK, .name = "hclk" },
	{ .id = A370_CPU_TO_DRAMCLK, .name = "dramclk" },
};

static const u32 a370_tclk_freqs[] __initconst = {
	16600000,
	20000000,
};

static u32 __init a370_get_tclk_freq(void __iomem *sar)
{
	u8 tclk_freq_select = 0;

	tclk_freq_select = ((readl(sar) >> SARL_A370_TCLK_FREQ_OPT) &
			    SARL_A370_TCLK_FREQ_OPT_MASK);
	return a370_tclk_freqs[tclk_freq_select];
}

static const u32 a370_cpu_freqs[] __initconst = {
	400000000,
	533000000,
	667000000,
	800000000,
	1000000000,
	1067000000,
	1200000000,
};

static u32 __init a370_get_cpu_freq(void __iomem *sar)
{
	u32 cpu_freq;
	u8 cpu_freq_select = 0;

	cpu_freq_select = ((readl(sar) >> SARL_A370_PCLK_FREQ_OPT) &
			   SARL_A370_PCLK_FREQ_OPT_MASK);
	if (cpu_freq_select >= ARRAY_SIZE(a370_cpu_freqs)) {
		pr_err("CPU freq select unsupported %d\n", cpu_freq_select);
		cpu_freq = 0;
	} else
		cpu_freq = a370_cpu_freqs[cpu_freq_select];

	return cpu_freq;
}

static const int a370_nbclk_ratios[32][2] __initconst = {
	{0, 1}, {1, 2}, {2, 2}, {2, 2},
	{1, 2}, {1, 2}, {1, 1}, {2, 3},
	{0, 1}, {1, 2}, {2, 4}, {0, 1},
	{1, 2}, {0, 1}, {0, 1}, {2, 2},
	{0, 1}, {0, 1}, {0, 1}, {1, 1},
	{2, 3}, {0, 1}, {0, 1}, {0, 1},
	{0, 1}, {0, 1}, {0, 1}, {1, 1},
	{0, 1}, {0, 1}, {0, 1}, {0, 1},
};

static const int a370_hclk_ratios[32][2] __initconst = {
	{0, 1}, {1, 2}, {2, 6}, {2, 3},
	{1, 3}, {1, 4}, {1, 2}, {2, 6},
	{0, 1}, {1, 6}, {2, 10}, {0, 1},
	{1, 4}, {0, 1}, {0, 1}, {2, 5},
	{0, 1}, {0, 1}, {0, 1}, {1, 2},
	{2, 6}, {0, 1}, {0, 1}, {0, 1},
	{0, 1}, {0, 1}, {0, 1}, {1, 1},
	{0, 1}, {0, 1}, {0, 1}, {0, 1},
};

static const int a370_dramclk_ratios[32][2] __initconst = {
	{0, 1}, {1, 2}, {2, 3}, {2, 3},
	{1, 3}, {1, 2}, {1, 2}, {2, 6},
	{0, 1}, {1, 3}, {2, 5}, {0, 1},
	{1, 4}, {0, 1}, {0, 1}, {2, 5},
	{0, 1}, {0, 1}, {0, 1}, {1, 1},
	{2, 3}, {0, 1}, {0, 1}, {0, 1},
	{0, 1}, {0, 1}, {0, 1}, {1, 1},
	{0, 1}, {0, 1}, {0, 1}, {0, 1},
};

static void __init a370_get_clk_ratio(
	void __iomem *sar, int id, int *mult, int *div)
{
	u32 opt = ((readl(sar) >> SARL_A370_FAB_FREQ_OPT) &
		SARL_A370_FAB_FREQ_OPT_MASK);

	switch (id) {
	case A370_CPU_TO_NBCLK:
		*mult = a370_nbclk_ratios[opt][0];
		*div = a370_nbclk_ratios[opt][1];
		break;
	case A370_CPU_TO_HCLK:
		*mult = a370_hclk_ratios[opt][0];
		*div = a370_hclk_ratios[opt][1];
		break;
	case A370_CPU_TO_DRAMCLK:
		*mult = a370_dramclk_ratios[opt][0];
		*div = a370_dramclk_ratios[opt][1];
		break;
	}
}

static const struct coreclk_soc_desc a370_coreclks = {
	.get_tclk_freq = a370_get_tclk_freq,
	.get_cpu_freq = a370_get_cpu_freq,
	.get_clk_ratio = a370_get_clk_ratio,
	.ratios = a370_coreclk_ratios,
	.num_ratios = ARRAY_SIZE(a370_coreclk_ratios),
};

static void __init a370_coreclk_init(struct device_node *np)
{
	mvebu_coreclk_setup(np, &a370_coreclks);
}
CLK_OF_DECLARE(a370_core_clk, "marvell,armada-370-core-clock",
	       a370_coreclk_init);

/*
 * Clock Gating Control
 */

static const struct clk_gating_soc_desc a370_gating_desc[] __initconst = {
	{ "audio", NULL, 0, 0 },
	{ "pex0_en", NULL, 1, 0 },
	{ "pex1_en", NULL,  2, 0 },
	{ "ge1", NULL, 3, 0 },
	{ "ge0", NULL, 4, 0 },
	{ "pex0", "pex0_en", 5, 0 },
	{ "pex1", "pex1_en", 9, 0 },
	{ "sata0", NULL, 15, 0 },
	{ "sdio", NULL, 17, 0 },
	{ "tdm", NULL, 25, 0 },
	{ "ddr", NULL, 28, CLK_IGNORE_UNUSED },
	{ "sata1", NULL, 30, 0 },
	{ }
};

static void __init a370_clk_gating_init(struct device_node *np)
{
	mvebu_clk_gating_setup(np, a370_gating_desc);
}
CLK_OF_DECLARE(a370_clk_gating, "marvell,armada-370-gating-clock",
	       a370_clk_gating_init);
