/*
* arch/arm/mach-tegra/tegra2_clocks.c
*
* Copyright (C) 2010 Google, Inc.
* Copyright (c) 2012 NVIDIA CORPORATION. All rights reserved.
*
* Author:
* Colin Cross <ccross@google.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that 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.
*
*/
#include <linux/clk-private.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/clk.h>
#include "clock.h"
#include "fuse.h"
#include "tegra2_emc.h"
#include "tegra20_clocks.h"
#include "tegra_cpu_car.h"
/* Clock definitions */
#define DEFINE_CLK_TEGRA(_name, _rate, _ops, _flags, \
_parent_names, _parents, _parent) \
static struct clk tegra_##_name = { \
.hw = &tegra_##_name##_hw.hw, \
.name = #_name, \
.rate = _rate, \
.ops = _ops, \
.flags = _flags, \
.parent_names = _parent_names, \
.parents = _parents, \
.num_parents = ARRAY_SIZE(_parent_names), \
.parent = _parent, \
};
static struct clk tegra_clk_32k;
static struct clk_tegra tegra_clk_32k_hw = {
.hw = {
.clk = &tegra_clk_32k,
},
.fixed_rate = 32768,
};
static struct clk tegra_clk_32k = {
.name = "clk_32k",
.rate = 32768,
.ops = &tegra_clk_32k_ops,
.hw = &tegra_clk_32k_hw.hw,
.flags = CLK_IS_ROOT,
};
static struct clk tegra_clk_m;
static struct clk_tegra tegra_clk_m_hw = {
.hw = {
.clk = &tegra_clk_m,
},
.flags = ENABLE_ON_INIT,
.reg = 0x1fc,
.reg_shift = 28,
.max_rate = 26000000,
.fixed_rate = 0,
};
static struct clk tegra_clk_m = {
.name = "clk_m",
.ops = &tegra_clk_m_ops,
.hw = &tegra_clk_m_hw.hw,
.flags = CLK_IS_ROOT,
};
#define DEFINE_PLL(_name, _flags, _reg, _max_rate, _input_min, \
_input_max, _cf_min, _cf_max, _vco_min, \
_vco_max, _freq_table, _lock_delay, _ops, \
_fixed_rate, _parent) \
static const char *tegra_##_name##_parent_names[] = { \
#_parent, \
}; \
static struct clk *tegra_##_name##_parents[] = { \
&tegra_##_parent, \
}; \
static struct clk tegra_##_name; \
static struct clk_tegra tegra_##_name##_hw = { \
.hw = { \
.clk = &tegra_##_name, \
}, \
.flags = _flags, \
.reg = _reg, \
.max_rate = _max_rate, \
.u.pll = { \
.input_min = _input_min, \
.input_max = _input_max, \
.cf_min = _cf_min, \
.cf_max = _cf_max, \
.vco_min = _vco_min, \
.vco_max = _vco_max, \
.freq_table = _freq_table, \
.lock_delay = _lock_delay, \
.fixed_rate = _fixed_rate, \
}, \
}; \
static struct clk tegra_##_name = { \
.name = #_name, \
.ops = &_ops, \
.hw = &tegra_##_name##_hw.hw, \
.parent = &tegra_##_parent, \
.parent_names = tegra_##_name##_parent_names, \
.parents = tegra_##_name##_parents, \
.num_parents = 1, \
};
#define DEFINE_PLL_OUT(_name, _flags, _reg, _reg_shift, \
_max_rate, _ops, _parent, _clk_flags) \
static const char *tegra_##_name##_parent_names[] = { \
#_parent, \
}; \
static struct clk *tegra_##_name##_parents[] = { \
&tegra_##_parent, \
}; \
static struct clk tegra_##_name; \
static struct clk_tegra tegra_##_name##_hw = { \
.hw = { \
.clk = &tegra_##_name, \
}, \
.flags = _flags, \
.reg = _reg, \
.max_rate = _max_rate, \
.reg_shift = _reg_shift, \
}; \
static struct clk tegra_##_name = { \
.name = #_name, \
.ops = &tegra_pll_div_ops, \
.hw = &tegra_##_name##_hw.hw, \
.parent = &tegra_##_parent, \
.parent_names = tegra_##_name##_parent_names, \
.parents = tegra_##_name##_parents, \
.num_parents = 1, \
.flags = _clk_flags, \
};
static struct clk_pll_freq_table tegra_pll_s_freq_table[] = {
{32768, 12000000, 366, 1, 1, 0},
{32768, 13000000, 397, 1, 1, 0},
{32768, 19200000, 586, 1, 1, 0},
{32768, 26000000, 793, 1, 1, 0},
{0, 0, 0, 0, 0, 0},
};
DEFINE_PLL(pll_s, PLL_ALT_MISC_REG, 0xf0, 26000000, 32768, 32768, 0,
0, 12000000, 26000000, tegra_pll_s_freq_table, 300,
tegra_pll_ops, 0, clk_32k);
static struct clk_pll_freq_table tegra_pll_c_freq_table[] = {
{ 12000000, 600000000, 600, 12, 1,