/*
 * Copyright (c) 2012, 2013, NVIDIA CORPORATION.  All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/io.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/delay.h>
#include <linux/export.h>
#include <linux/clk/tegra.h>

#include "clk.h"
#include "clk-id.h"

#define AUDIO_SYNC_CLK_I2S0 0x4a0
#define AUDIO_SYNC_CLK_I2S1 0x4a4
#define AUDIO_SYNC_CLK_I2S2 0x4a8
#define AUDIO_SYNC_CLK_I2S3 0x4ac
#define AUDIO_SYNC_CLK_I2S4 0x4b0
#define AUDIO_SYNC_CLK_SPDIF 0x4b4

#define AUDIO_SYNC_DOUBLER 0x49c

#define PLLA_OUT 0xb4

struct tegra_sync_source_initdata {
	char		*name;
	unsigned long	rate;
	unsigned long	max_rate;
	int		clk_id;
};

#define SYNC(_name) \
	{\
		.name		= #_name,\
		.rate		= 24000000,\
		.max_rate	= 24000000,\
		.clk_id		= tegra_clk_ ## _name,\
	}

struct tegra_audio_clk_initdata {
	char		*gate_name;
	char		*mux_name;
	u32		offset;
	int		gate_clk_id;
	int		mux_clk_id;
};

#define AUDIO(_name, _offset) \
	{\
		.gate_name	= #_name,\
		.mux_name	= #_name"_mux",\
		.offset		= _offset,\
		.gate_clk_id	= tegra_clk_ ## _name,\
		.mux_clk_id	= tegra_clk_ ## _name ## _mux,\
	}

struct tegra_audio2x_clk_initdata {
	char		*parent;
	char		*gate_name;
	char		*name_2x;
	char		*div_name;
	int		clk_id;
	int		clk_num;
	u8		div_offset;
};

#define AUDIO2X(_name, _num, _offset) \
	{\
		.parent		= #_name,\
		.gate_name	= #_name"_2x",\
		.name_2x	= #_name"_doubler",\
		.div_name	= #_name"_div",\
		.clk_id		= tegra_clk_ ## _name ## _2x,\
		.clk_num	= _num,\
		.div_offset	= _offset,\
	}

static DEFINE_SPINLOCK(clk_doubler_lock);

static const char *mux_audio_sync_clk[] = { "spdif_in_sync", "i2s0_sync",
	"i2s1_sync", "i2s2_sync", "i2s3_sync", "i2s4_sync", "vimclk_sync",
};

static struct tegra_sync_source_initdata sync_source_clks[] __initdata = {
	SYNC(spdif_in_sync),
	SYNC(i2s0_sync),
	SYNC(i2s1_sync),
	SYNC(i2s2_sync),
	SYNC(i2s3_sync),
	SYNC(i2s4_sync),
	SYNC(vimclk_sync),
};

static struct tegra_audio_clk_initdata audio_clks[] = {
	AUDIO(audio0, AUDIO_SYNC_CLK_I2S0),
	AUDIO(audio1, AUDIO_SYNC_CLK_I2S1),
	AUDIO(audio2, AUDIO_SYNC_CLK_I2S2),
	AUDIO(audio3, AUDIO_SYNC_CLK_I2S3),
	AUDIO(audio4, AUDIO_SYNC_CLK_I2S4),
	AUDIO(spdif, AUDIO_SYNC_CLK_SPDIF),
};

static struct tegra_audio2x_clk_initdata audio2x_clks[] = {
	AUDIO2X(audio0, 113, 24),
	AUDIO2X(audio1, 114, 25),
	AUDIO2X(audio2, 115, 26),
	AUDIO2X(audio3, 116, 27),
	AUDIO2X(audio4, 117, 28),
	AUDIO2X(spdif, 118, 29),
};

void __init tegra_audio_clk_init(void __iomem *clk_base,
			void __iomem *pmc_base, struct tegra_clk *tegra_clks,
			struct tegra_clk_pll_params *pll_a_params)
{
	struct clk *clk;
	struct clk **dt_clk;
	int i;

	/* PLLA */
	dt_clk = tegra_lookup_dt_id(tegra_clk_pll_a, tegra_clks);
	if (dt_clk) {
		clk = tegra_clk_register_pll("pll_a", "pll_p_out1", clk_base,
				pmc_base, 0, pll_a_params, NULL);
		*dt_clk = clk;
	}

	/* PLLA_OUT0 */
	dt_clk = tegra_lookup_dt_id(tegra_clk_pll_a_out0, tegra_clks);
	if (dt_clk) {
		clk = tegra_clk_register_divider("pll_a_out0_div", "pll_a",
				clk_base + PLLA_OUT, 0, TEGRA_DIVIDER_ROUND_UP,
				8, 8, 1, NULL);
		clk = tegra_clk_register_pll_out("pll_a_out0", "pll_a_out0_div",
				clk_base + PLLA_OUT, 1, 0, CLK_IGNORE_UNUSED |
				CLK_SET_RATE_PARENT, 0, NULL);
		*dt_clk = clk;
	}

	for (i = 0; i < ARRAY_SIZE(sync_source_clks); i++) {
		struct tegra_sync_source_initdata *data;

		data = &sync_source_clks[i];

		dt_clk = tegra_lookup_dt_id(data->clk_id, tegra_clks);
		if (!dt_clk)
			continue;

		clk = tegra_clk_register_sync_source(data->name,
					data->rate, data->max_rate);
		*dt_clk = clk;
	}

	for (i = 0; i < ARRAY_SIZE(audio_clks); i++) {
		struct tegra_audio_clk_initdata *data;

		data = &audio_clks[i];
		dt_clk = tegra_lookup_dt_id(data->mux_clk_id, tegra_clks);

		if (!dt_clk)
			continue;
		clk = clk_register_mux(NULL, data->mux_name, mux_audio_sync_clk,
					ARRAY_SIZE(mux_audio_sync_clk),
					CLK_SET_RATE_NO_REPARENT,
					clk_base + data->offset, 0, 3, 0,
					NULL);
		*dt_clk = clk;

		dt_clk = tegra_lookup_dt_id(data->gate_clk_id, tegra_clks);
		if (!dt_clk)
			continue;

		clk = clk_register_gate(NULL, data->gate_name, data->mux_name,
					0, clk_base + data->offset, 4,
					CLK_GATE_SET_TO_DISABLE, NULL);
		*dt_clk = clk;
	}

	for (i = 0; i < ARRAY_SIZE(audio2x_clks); i++) {
		struct tegra_audio2x_clk_initdata *data;

		data = &audio2x_clks[i];
		dt_clk = tegra_lookup_dt_id(data->clk_id, tegra_clks);
		if (!dt_clk)
			continue;

		clk = clk_register_fixed_factor(NULL, data->name_2x,
				data->parent, CLK_SET_RATE_PARENT, 2, 1);
		clk = tegra_clk_register_divider(data->div_name,
				data->name_2x, clk_base + AUDIO_SYNC_DOUBLER,
				0, 0, data->div_offset, 1, 0,
				&clk_doubler_lock);
		clk = tegra_clk_register_periph_gate(data->gate_name,
				data->div_name, TEGRA_PERIPH_NO_RESET,
				clk_base, CLK_SET_RATE_PARENT, data->clk_num,
				periph_clk_enb_refcnt);
		*dt_clk = clk;
	}
}

