/*
* AM33XX Clock data
*
* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
* Vaibhav Hiremath <hvaibhav@ti.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation version 2.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/clk.h>
#include <plat/clkdev_omap.h>
#include "am33xx.h"
#include "iomap.h"
#include "control.h"
#include "clock.h"
#include "cm.h"
#include "cm33xx.h"
#include "cm-regbits-33xx.h"
#include "prm.h"
/* Maximum DPLL multiplier, divider values for AM33XX */
#define AM33XX_MAX_DPLL_MULT 2047
#define AM33XX_MAX_DPLL_DIV 128
/* Modulemode control */
#define AM33XX_MODULEMODE_HWCTRL 0
#define AM33XX_MODULEMODE_SWCTRL 1
/* TRM ERRATA: Timer 3 & 6 default parent (TCLKIN) may not be always
* physically present, in such a case HWMOD enabling of
* clock would be failure with default parent. And timer
* probe thinks clock is already enabled, this leads to
* crash upon accessing timer 3 & 6 registers in probe.
* Fix by setting parent of both these timers to master
* oscillator clock.
*/
static inline void am33xx_init_timer_parent(struct clk *clk)
{
omap2_clksel_set_parent(clk, clk->parent);
}
/* Root clocks */
/* RTC 32k */
static struct clk clk_32768_ck = {
.name = "clk_32768_ck",
.clkdm_name = "l4_rtc_clkdm",
.rate = 32768,
.ops = &clkops_null,
};
/* On-Chip 32KHz RC OSC */
static struct clk clk_rc32k_ck = {
.name = "clk_rc32k_ck",
.rate = 32000,
.ops = &clkops_null,
};
/* Crystal input clks */
static struct clk virt_24000000_ck = {
.name = "virt_24000000_ck",
.rate = 24000000,
.ops = &clkops_null,
};
static struct clk virt_25000000_ck = {
.name = "virt_25000000_ck",
.rate = 25000000,
.ops = &clkops_null,
};
/* Oscillator clock */
/* 19.2, 24, 25 or 26 MHz */
static const struct clksel sys_clkin_sel[] = {
{ .parent = &virt_19200000_ck, .rates = div_1_0_rates },
{ .parent = &virt_24000000_ck, .rates = div_1_1_rates },
{ .parent = &virt_25000000_ck, .rates = div_1_2_rates },
{ .parent = &virt_26000000_ck, .rates = div_1_3_rates },
{ .parent = NULL },
};
/* External clock - 12 MHz */
static struct clk tclkin_ck = {
.name = "tclkin_ck",
.rate = 12000000,
.ops = &clkops_null,
};
/*
* sys_clk in: input to the dpll and also used as funtional clock for,
* adc_tsc, smartreflex0-1, timer1-7, mcasp0-1, dcan0-1, cefuse
*
*/
static struct clk sys_clkin_ck = {
.name = "sys_clkin_ck",
.parent = &virt_24000000_ck,
.init = &omap2_init_clksel_parent,
.clksel_reg = AM33XX_CTRL_REGADDR(AM33XX_CONTROL_STATUS),
.clksel_mask = AM33XX_CONTROL_STATUS_SYSBOOT1_MASK,
.clksel = sys_clkin_sel,
.ops = &clkops_null,
.recalc = &omap2_clksel_recalc,
};
/* DPLL_CORE */
static struct dpll_data dpll_core_dd = {
.mult_div1_reg = AM33XX_CM_CLKSEL_DPLL_CORE,
.clk_bypass = &sys_clkin_ck,
.clk_ref = &sys_clkin_ck,
.control_reg = AM33XX_CM_CLKMODE_DPLL_CORE,
.modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
.idlest_reg = AM33XX_CM_IDLEST_DPLL_CORE,
.mult_mask = AM33XX_DPLL_MULT_MASK,
.div1_mask = AM33XX_DPLL_DIV_MASK,
.enable_mask = AM33XX_DPLL_EN_MASK,
.idlest_mask = AM33XX_ST_DPLL_CLK_MASK,
.max_multiplier = AM33XX_MAX_DPLL_MULT,
.max_divider = AM33XX_MAX_DPLL_DIV,
.min_divider = 1,
};
/* CLKDCOLDO output */
static struct clk dpll_core_ck = {
.name = "dpll_core_ck",
.parent = &