Merge branch 'omap-clock-fixes' into omap-fixes
This commit is contained in:
commit
535ff672e3
@ -40,8 +40,8 @@ static void omap1_mcbsp_request(unsigned int id)
|
||||
*/
|
||||
if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) {
|
||||
if (dsp_use++ == 0) {
|
||||
api_clk = clk_get(NULL, "api_clk");
|
||||
dsp_clk = clk_get(NULL, "dsp_clk");
|
||||
api_clk = clk_get(NULL, "api_ck");
|
||||
dsp_clk = clk_get(NULL, "dsp_ck");
|
||||
if (!IS_ERR(api_clk) && !IS_ERR(dsp_clk)) {
|
||||
clk_enable(api_clk);
|
||||
clk_enable(dsp_clk);
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include <mach/nand.h>
|
||||
#include <mach/mux.h>
|
||||
#include <mach/usb.h>
|
||||
#include <mach/timer-gp.h>
|
||||
|
||||
#include "mmc-twl4030.h"
|
||||
|
||||
@ -186,6 +187,9 @@ static void __init omap3_beagle_init_irq(void)
|
||||
{
|
||||
omap2_init_common_hw(NULL);
|
||||
omap_init_irq();
|
||||
#ifdef CONFIG_OMAP_32K_TIMER
|
||||
omap2_gp_clockevent_set_gptimer(12);
|
||||
#endif
|
||||
omap_gpio_init();
|
||||
}
|
||||
|
||||
|
@ -60,12 +60,13 @@ struct omap_clk {
|
||||
}, \
|
||||
}
|
||||
|
||||
#define CK_243X (1 << 0)
|
||||
#define CK_242X (1 << 1)
|
||||
#define CK_243X RATE_IN_243X
|
||||
#define CK_242X RATE_IN_242X
|
||||
|
||||
static struct omap_clk omap24xx_clks[] = {
|
||||
/* external root sources */
|
||||
CLK(NULL, "func_32k_ck", &func_32k_ck, CK_243X | CK_242X),
|
||||
CLK(NULL, "secure_32k_ck", &secure_32k_ck, CK_243X | CK_242X),
|
||||
CLK(NULL, "osc_ck", &osc_ck, CK_243X | CK_242X),
|
||||
CLK(NULL, "sys_ck", &sys_ck, CK_243X | CK_242X),
|
||||
CLK(NULL, "alt_ck", &alt_ck, CK_243X | CK_242X),
|
||||
@ -711,7 +712,7 @@ int __init omap2_clk_init(void)
|
||||
{
|
||||
struct prcm_config *prcm;
|
||||
struct omap_clk *c;
|
||||
u32 clkrate, cpu_mask;
|
||||
u32 clkrate;
|
||||
|
||||
if (cpu_is_omap242x())
|
||||
cpu_mask = RATE_IN_242X;
|
||||
@ -720,20 +721,14 @@ int __init omap2_clk_init(void)
|
||||
|
||||
clk_init(&omap2_clk_functions);
|
||||
|
||||
for (c = omap24xx_clks; c < omap24xx_clks + ARRAY_SIZE(omap24xx_clks); c++)
|
||||
clk_init_one(c->lk.clk);
|
||||
|
||||
osc_ck.rate = omap2_osc_clk_recalc(&osc_ck);
|
||||
propagate_rate(&osc_ck);
|
||||
sys_ck.rate = omap2_sys_clk_recalc(&sys_ck);
|
||||
propagate_rate(&sys_ck);
|
||||
|
||||
for (c = omap24xx_clks; c < omap24xx_clks + ARRAY_SIZE(omap24xx_clks); c++)
|
||||
clk_init_one(c->lk.clk);
|
||||
|
||||
cpu_mask = 0;
|
||||
if (cpu_is_omap2420())
|
||||
cpu_mask |= CK_242X;
|
||||
if (cpu_is_omap2430())
|
||||
cpu_mask |= CK_243X;
|
||||
|
||||
for (c = omap24xx_clks; c < omap24xx_clks + ARRAY_SIZE(omap24xx_clks); c++)
|
||||
if (c->cpu & cpu_mask) {
|
||||
clkdev_add(&c->lk);
|
||||
|
@ -625,6 +625,14 @@ static struct clk func_32k_ck = {
|
||||
.clkdm_name = "wkup_clkdm",
|
||||
};
|
||||
|
||||
static struct clk secure_32k_ck = {
|
||||
.name = "secure_32k_ck",
|
||||
.ops = &clkops_null,
|
||||
.rate = 32768,
|
||||
.flags = RATE_FIXED,
|
||||
.clkdm_name = "wkup_clkdm",
|
||||
};
|
||||
|
||||
/* Typical 12/13MHz in standalone mode, will be 26Mhz in chassis mode */
|
||||
static struct clk osc_ck = { /* (*12, *13, 19.2, *26, 38.4)MHz */
|
||||
.name = "osc_ck",
|
||||
@ -1790,7 +1798,7 @@ static struct clk gpt12_ick = {
|
||||
static struct clk gpt12_fck = {
|
||||
.name = "gpt12_fck",
|
||||
.ops = &clkops_omap2_dflt_wait,
|
||||
.parent = &func_32k_ck,
|
||||
.parent = &secure_32k_ck,
|
||||
.clkdm_name = "core_l4_clkdm",
|
||||
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
|
||||
.enable_bit = OMAP24XX_EN_GPT12_SHIFT,
|
||||
|
@ -2052,7 +2052,7 @@ static struct clk dss_ick = {
|
||||
|
||||
static struct clk cam_mclk = {
|
||||
.name = "cam_mclk",
|
||||
.ops = &clkops_omap2_dflt_wait,
|
||||
.ops = &clkops_omap2_dflt,
|
||||
.parent = &dpll4_m5x2_ck,
|
||||
.enable_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN),
|
||||
.enable_bit = OMAP3430_EN_CAM_SHIFT,
|
||||
@ -2063,7 +2063,7 @@ static struct clk cam_mclk = {
|
||||
static struct clk cam_ick = {
|
||||
/* Handles both L3 and L4 clocks */
|
||||
.name = "cam_ick",
|
||||
.ops = &clkops_omap2_dflt_wait,
|
||||
.ops = &clkops_omap2_dflt,
|
||||
.parent = &l4_ick,
|
||||
.init = &omap2_init_clk_clkdm,
|
||||
.enable_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_ICLKEN),
|
||||
@ -2074,7 +2074,7 @@ static struct clk cam_ick = {
|
||||
|
||||
static struct clk csi2_96m_fck = {
|
||||
.name = "csi2_96m_fck",
|
||||
.ops = &clkops_omap2_dflt_wait,
|
||||
.ops = &clkops_omap2_dflt,
|
||||
.parent = &core_96m_fck,
|
||||
.init = &omap2_init_clk_clkdm,
|
||||
.enable_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN),
|
||||
@ -2901,7 +2901,6 @@ static struct clk sr_l4_ick = {
|
||||
|
||||
/* SECURE_32K_FCK clocks */
|
||||
|
||||
/* XXX This clock no longer exists in 3430 TRM rev F */
|
||||
static struct clk gpt12_fck = {
|
||||
.name = "gpt12_fck",
|
||||
.ops = &clkops_null,
|
||||
|
@ -3,6 +3,8 @@
|
||||
*
|
||||
* OMAP2 GP timer support.
|
||||
*
|
||||
* Copyright (C) 2009 Nokia Corporation
|
||||
*
|
||||
* Update to use new clocksource/clockevent layers
|
||||
* Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com>
|
||||
* Copyright (C) 2007 MontaVista Software, Inc.
|
||||
@ -36,8 +38,13 @@
|
||||
#include <asm/mach/time.h>
|
||||
#include <mach/dmtimer.h>
|
||||
|
||||
/* MAX_GPTIMER_ID: number of GPTIMERs on the chip */
|
||||
#define MAX_GPTIMER_ID 12
|
||||
|
||||
static struct omap_dm_timer *gptimer;
|
||||
static struct clock_event_device clockevent_gpt;
|
||||
static u8 __initdata gptimer_id = 1;
|
||||
static u8 __initdata inited;
|
||||
|
||||
static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
@ -95,20 +102,53 @@ static struct clock_event_device clockevent_gpt = {
|
||||
.set_mode = omap2_gp_timer_set_mode,
|
||||
};
|
||||
|
||||
/**
|
||||
* omap2_gp_clockevent_set_gptimer - set which GPTIMER is used for clockevents
|
||||
* @id: GPTIMER to use (1..MAX_GPTIMER_ID)
|
||||
*
|
||||
* Define the GPTIMER that the system should use for the tick timer.
|
||||
* Meant to be called from board-*.c files in the event that GPTIMER1, the
|
||||
* default, is unsuitable. Returns -EINVAL on error or 0 on success.
|
||||
*/
|
||||
int __init omap2_gp_clockevent_set_gptimer(u8 id)
|
||||
{
|
||||
if (id < 1 || id > MAX_GPTIMER_ID)
|
||||
return -EINVAL;
|
||||
|
||||
BUG_ON(inited);
|
||||
|
||||
gptimer_id = id;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __init omap2_gp_clockevent_init(void)
|
||||
{
|
||||
u32 tick_rate;
|
||||
int src;
|
||||
|
||||
gptimer = omap_dm_timer_request_specific(1);
|
||||
inited = 1;
|
||||
|
||||
gptimer = omap_dm_timer_request_specific(gptimer_id);
|
||||
BUG_ON(gptimer == NULL);
|
||||
|
||||
#if defined(CONFIG_OMAP_32K_TIMER)
|
||||
omap_dm_timer_set_source(gptimer, OMAP_TIMER_SRC_32_KHZ);
|
||||
src = OMAP_TIMER_SRC_32_KHZ;
|
||||
#else
|
||||
omap_dm_timer_set_source(gptimer, OMAP_TIMER_SRC_SYS_CLK);
|
||||
src = OMAP_TIMER_SRC_SYS_CLK;
|
||||
WARN(gptimer_id == 12, "WARNING: GPTIMER12 can only use the "
|
||||
"secure 32KiHz clock source\n");
|
||||
#endif
|
||||
|
||||
if (gptimer_id != 12)
|
||||
WARN(IS_ERR_VALUE(omap_dm_timer_set_source(gptimer, src)),
|
||||
"timer-gp: omap_dm_timer_set_source() failed\n");
|
||||
|
||||
tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer));
|
||||
|
||||
pr_info("OMAP clockevent source: GPTIMER%d at %u Hz\n",
|
||||
gptimer_id, tick_rate);
|
||||
|
||||
omap2_gp_timer_irq.dev_id = (void *)gptimer;
|
||||
setup_irq(omap_dm_timer_get_irq(gptimer), &omap2_gp_timer_irq);
|
||||
omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_OVERFLOW);
|
||||
@ -125,6 +165,8 @@ static void __init omap2_gp_clockevent_init(void)
|
||||
clockevents_register_device(&clockevent_gpt);
|
||||
}
|
||||
|
||||
/* Clocksource code */
|
||||
|
||||
#ifdef CONFIG_OMAP_32K_TIMER
|
||||
/*
|
||||
* When 32k-timer is enabled, don't use GPTimer for clocksource
|
||||
|
@ -239,6 +239,13 @@ void recalculate_root_clocks(void)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clk_init_one - initialize any fields in the struct clk before clk init
|
||||
* @clk: struct clk * to initialize
|
||||
*
|
||||
* Initialize any struct clk fields needed before normal clk initialization
|
||||
* can run. No return value.
|
||||
*/
|
||||
void clk_init_one(struct clk *clk)
|
||||
{
|
||||
INIT_LIST_HEAD(&clk->children);
|
||||
|
@ -238,7 +238,7 @@ static struct omap_dm_timer omap3_dm_timers[] = {
|
||||
{ .phys_base = 0x49040000, .irq = INT_24XX_GPTIMER9 },
|
||||
{ .phys_base = 0x48086000, .irq = INT_24XX_GPTIMER10 },
|
||||
{ .phys_base = 0x48088000, .irq = INT_24XX_GPTIMER11 },
|
||||
{ .phys_base = 0x48304000, .irq = INT_24XX_GPTIMER12 },
|
||||
{ .phys_base = 0x48304000, .irq = INT_34XX_GPT12_IRQ },
|
||||
};
|
||||
|
||||
static const char *omap3_dm_source_names[] __initdata = {
|
||||
@ -321,11 +321,9 @@ static void omap_dm_timer_reset(struct omap_dm_timer *timer)
|
||||
l |= 0x2 << 8; /* Set clock activity to perserve f-clock on idle */
|
||||
|
||||
/*
|
||||
* Enable wake-up only for GPT1 on OMAP2 CPUs.
|
||||
* FIXME: All timers should have wake-up enabled and clear
|
||||
* PRCM status.
|
||||
* Enable wake-up on OMAP2 CPUs.
|
||||
*/
|
||||
if (cpu_class_is_omap2() && (timer == &dm_timers[0]))
|
||||
if (cpu_class_is_omap2())
|
||||
l |= 1 << 2;
|
||||
omap_dm_timer_write_reg(timer, OMAP_TIMER_OCP_CFG_REG, l);
|
||||
|
||||
@ -511,7 +509,7 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_stop);
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP1
|
||||
|
||||
void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
|
||||
int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
|
||||
{
|
||||
int n = (timer - dm_timers) << 1;
|
||||
u32 l;
|
||||
@ -519,23 +517,31 @@ void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
|
||||
l = omap_readl(MOD_CONF_CTRL_1) & ~(0x03 << n);
|
||||
l |= source << n;
|
||||
omap_writel(l, MOD_CONF_CTRL_1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(omap_dm_timer_set_source);
|
||||
|
||||
#else
|
||||
|
||||
void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
|
||||
int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (source < 0 || source >= 3)
|
||||
return;
|
||||
return -EINVAL;
|
||||
|
||||
clk_disable(timer->fclk);
|
||||
clk_set_parent(timer->fclk, dm_source_clocks[source]);
|
||||
ret = clk_set_parent(timer->fclk, dm_source_clocks[source]);
|
||||
clk_enable(timer->fclk);
|
||||
|
||||
/* When the functional clock disappears, too quick writes seem to
|
||||
* cause an abort. */
|
||||
/*
|
||||
* When the functional clock disappears, too quick writes seem
|
||||
* to cause an abort. XXX Is this still necessary?
|
||||
*/
|
||||
__delay(150000);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(omap_dm_timer_set_source);
|
||||
|
||||
|
@ -64,7 +64,7 @@ void omap_dm_timer_trigger(struct omap_dm_timer *timer);
|
||||
void omap_dm_timer_start(struct omap_dm_timer *timer);
|
||||
void omap_dm_timer_stop(struct omap_dm_timer *timer);
|
||||
|
||||
void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source);
|
||||
int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source);
|
||||
void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload, unsigned int value);
|
||||
void omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload, unsigned int value);
|
||||
void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, unsigned int match);
|
||||
|
17
arch/arm/plat-omap/include/mach/timer-gp.h
Normal file
17
arch/arm/plat-omap/include/mach/timer-gp.h
Normal file
@ -0,0 +1,17 @@
|
||||
/*
|
||||
* OMAP2/3 GPTIMER support.headers
|
||||
*
|
||||
* Copyright (C) 2009 Nokia Corporation
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_TIMER_GP_H
|
||||
#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_TIMER_GP_H
|
||||
|
||||
int __init omap2_gp_clockevent_set_gptimer(u8 id);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user