/*
 * 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 = {
	166000000,
	200000000,
};

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),
};

/*
 * 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_init(struct device_node *np)
{
	struct device_node *cgnp =
		of_find_compatible_node(NULL, NULL, "marvell,armada-370-gating-clock");

	mvebu_coreclk_setup(np, &a370_coreclks);

	if (cgnp)
		mvebu_clk_gating_setup(cgnp, a370_gating_desc);
}
CLK_OF_DECLARE(a370_clk, "marvell,armada-370-core-clock", a370_clk_init);

