/*
 * Copyright (c) 2013 Samsung Electronics Co., Ltd.
 * Author: Hyunki Koo <hyunki00.koo@samsung.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * Common Clock Framework support for pwm timer Clock Controller.
*/

#include <linux/clkdev.h>
#include <linux/io.h>
#include <linux/clk-provider.h>
#include <linux/of_address.h>

#include "clk.h"

/* Each of the timers 0 through 5 go through the following
 * clock tree, with the inputs depending on the timers.
 *
 * pclk ---- [ prescaler 0 ] -+---> timer 0
 *			      +---> timer 1
 *
 * pclk ---- [ prescaler 1 ] -+---> timer 2
 *			      +---> timer 3
 *			      \---> timer 4
 *
 * Which are fed into the timers as so:
 *
 * prescaled 0 ---- [ div 2,4,8,16 ] ---\
 *				       [mux] -> timer 0 (tin)
 * tclk 0 ------------------------------/
 *
 * prescaled 0 ---- [ div 2,4,8,16 ] ---\
 *				       [mux] -> timer 1 (tin)
 * tclk 0 ------------------------------/
 *
 *
 * prescaled 1 ---- [ div 2,4,8,16 ] ---\
 *				       [mux] -> timer 2 (tin)
 * tclk 1 ------------------------------/
 *
 * prescaled 1 ---- [ div 2,4,8,16 ] ---\
 *				       [mux] -> timer 3 (tin)
 * tclk 1 ------------------------------/
 *
 * prescaled 1 ---- [ div 2,4,8, 16 ] --\
 *				       [mux] -> timer 4 (tin)
 * tclk 1 ------------------------------/
 *
 * Since the mux and the divider are tied together in the
 * same register space, it is impossible to set the parent
 * and the rate at the same time. To avoid this, we add an
 * intermediate 'prescaled-and-divided' clock to select
 * as the parent for the timer input clock called tdiv.
 *
 * prescaled clk --> pwm-tdiv ---\
 *                             [ mux ] --> timer X
 * tclk -------------------------/
 *
 * tclk is deprecated in exynos
 *
*/

static DEFINE_SPINLOCK(lock);
static struct clk **clk_table;
static struct clk_onecell_data clk_data;

#define REG_TCFG0			0x00
#define REG_TCFG1			0x04
#define REG_TCON			0x08
#define REG_TINT_CSTAT			0x44
#define MASK_TCFG0_PRESCALE0		0x00FF
#define MASK_TCFG0_PRESCALE1		0xFF00

enum exynos_pwm_clks {
	pwm_clock = 0,
	pwm_scaler0,
	pwm_scaler1,
	pwm_tclk0,
	pwm_tclk1,
	pwm_tdiv0 = 5,
	pwm_tdiv1,
	pwm_tdiv2,
	pwm_tdiv3,
	pwm_tdiv4,
	pwm_tin0 = 10,
	pwm_tin1,
	pwm_tin2,
	pwm_tin3,
	pwm_tin4,
	exynos_pwm_max_clks,
};

static const char *pwm_tin0_p[] = { "pwm-tdiv0", "pwm-tclk" };
static const char *pwm_tin1_p[] = { "pwm-tdiv1", "pwm-tclk" };
static const char *pwm_tin2_p[] = { "pwm-tdiv2", "pwm-tclk" };
static const char *pwm_tin3_p[] = { "pwm-tdiv3", "pwm-tclk" };
static const char *pwm_tin4_p[] = { "pwm-tdiv4", "pwm-tclk" };

static const struct clk_div_table pwm_div_table[5] = {
	/* { val, div } */
	{ 0, 1 },
	{ 1, 2 },
	{ 2, 4 },
	{ 3, 8 },
	{ 4, 16 },
};

/* register exynos_pwm clocks */
void __init exynos_pwm_clk_init(struct device_node *np)
{
	static void __iomem *reg_base;
	unsigned int reg_tcfg0;

	reg_base = of_iomap(np, 0);

	if (!reg_base) {
		pr_err("%s: failed to map pwm registers\n", __func__);
		return;
	}

	clk_table = kzalloc(sizeof(struct clk *) * exynos_pwm_max_clks,
				GFP_KERNEL);
	if (!clk_table) {
		pr_err("%s: could not allocate clk lookup table\n", __func__);
		return;
	}

	clk_data.clks = clk_table;
	clk_data.clk_num = exynos_pwm_max_clks;
	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);

	reg_tcfg0 = __raw_readl(reg_base + REG_TCFG0);
	reg_tcfg0 &= ~(MASK_TCFG0_PRESCALE0 | MASK_TCFG0_PRESCALE1);
	__raw_writel(reg_tcfg0, reg_base + REG_TCFG0);
	__raw_writel(0, reg_base + REG_TCFG1);

	clk_table[pwm_scaler0] = clk_register_divider(NULL, "pwm-scaler0",
				"pwm-clock", 0, reg_base + REG_TCFG0, 0, 8,
				CLK_DIVIDER_ALLOW_ZERO, &lock);
	clk_table[pwm_scaler1] = clk_register_divider(NULL, "pwm-scaler1",
				"pwm-clock", 0, reg_base + REG_TCFG0, 8, 8,
				CLK_DIVIDER_ALLOW_ZERO, &lock);

	clk_table[pwm_tdiv0] = clk_register_divider_table(NULL, "pwm-tdiv0",
				"pwm-scaler0", 0, reg_base + REG_TCFG1, 0, 4,
				CLK_DIVIDER_ALLOW_ZERO, pwm_div_table, &lock);

	clk_table[pwm_tdiv1] = clk_register_divider_table(NULL, "pwm-tdiv1",
				"pwm-scaler0", 0, reg_base + REG_TCFG1, 4, 4,
				CLK_DIVIDER_ALLOW_ZERO, pwm_div_table, &lock);

	clk_table[pwm_tdiv2] = clk_register_divider_table(NULL, "pwm-tdiv2",
				"pwm-scaler1", 0, reg_base + REG_TCFG1, 8, 4,
				CLK_DIVIDER_ALLOW_ZERO, pwm_div_table, &lock);

	clk_table[pwm_tdiv3] = clk_register_divider_table(NULL, "pwm-tdiv3",
				"pwm-scaler1", 0, reg_base + REG_TCFG1, 12, 4,
				CLK_DIVIDER_ALLOW_ZERO, pwm_div_table, &lock);

	clk_table[pwm_tdiv4] = clk_register_divider_table(NULL, "pwm-tdiv4",
				"pwm-scaler1", 0, reg_base + REG_TCFG1, 16, 4,
				CLK_DIVIDER_ALLOW_ZERO, pwm_div_table, &lock);

	clk_table[pwm_tin0] = clk_register_mux(NULL, "pwm-tin0",
				pwm_tin0_p, ARRAY_SIZE(pwm_tin0_p), 0,
				reg_base + REG_TCFG1, 3, 0, 0, &lock);

	clk_table[pwm_tin1] = clk_register_mux(NULL, "pwm-tin1",
				pwm_tin1_p, ARRAY_SIZE(pwm_tin1_p), 0,
				reg_base + REG_TCFG1, 7, 0, 0, &lock);

	clk_table[pwm_tin2] = clk_register_mux(NULL, "pwm-tin2",
				pwm_tin2_p, ARRAY_SIZE(pwm_tin2_p), 0,
				reg_base + REG_TCFG1, 11, 0, 0, &lock);

	clk_table[pwm_tin3] = clk_register_mux(NULL, "pwm-tin3",
				pwm_tin3_p, ARRAY_SIZE(pwm_tin3_p), 0,
				reg_base + REG_TCFG1, 15, 0, 0, &lock);

	clk_table[pwm_tin4] = clk_register_mux(NULL, "pwm-tin4",
				pwm_tin4_p, ARRAY_SIZE(pwm_tin4_p), 0,
				reg_base + REG_TCFG1, 19, 0, 0, &lock);

	pr_info("Exynos: pwm: clock setup completed\n");
}
CLK_OF_DECLARE(exynos_pwm_clk, "samsung,exynos-pwm-clock",
		exynos_pwm_clk_init);
