/*
 * 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-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_audio_clk_info *audio_info,
			unsigned int num_plls)
{
	struct clk *clk;
	struct clk **dt_clk;
	int i;

	if (!audio_info || num_plls < 1) {
		pr_err("No audio data passed to tegra_audio_clk_init\n");
		WARN_ON(1);
		return;
	}

	for (i = 0; i < num_plls; i++) {
		struct tegra_audio_clk_info *info = &audio_info[i];

		dt_clk = tegra_lookup_dt_id(info->clk_id, tegra_clks);
		if (dt_clk) {
			clk = tegra_clk_register_pll(info->name, info->parent,
					clk_base, pmc_base, 0, info->pll_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;
	}
}

