Merge branch 'for_2.6.34_4f4e65_a' of git://git.pwsan.com/linux-2.6 into omap-for-linus
This commit is contained in:
Коммит
9ba874506b
|
@ -52,12 +52,6 @@ const struct clkops clkops_dummy = {
|
|||
.disable = clk_omap1_dummy_disable,
|
||||
};
|
||||
|
||||
/* XXX can be replaced with a fixed_divisor_recalc */
|
||||
unsigned long omap1_watchdog_recalc(struct clk *clk)
|
||||
{
|
||||
return clk->parent->rate / 14;
|
||||
}
|
||||
|
||||
unsigned long omap1_uart_recalc(struct clk *clk)
|
||||
{
|
||||
unsigned int val = __raw_readl(clk->enable_reg);
|
||||
|
|
|
@ -149,7 +149,8 @@ static struct arm_idlect1_clk armwdt_ck = {
|
|||
.flags = CLOCK_IDLE_CONTROL,
|
||||
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
|
||||
.enable_bit = EN_WDTCK,
|
||||
.recalc = &omap1_watchdog_recalc,
|
||||
.fixed_div = 14,
|
||||
.recalc = &omap_fixed_divisor_recalc,
|
||||
},
|
||||
.idlect_shift = 0,
|
||||
};
|
||||
|
|
|
@ -6,14 +6,22 @@
|
|||
obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o
|
||||
|
||||
omap-2-3-common = irq.o sdrc.o omap_hwmod.o
|
||||
omap-3-4-common = dpll.o
|
||||
omap-3-4-common = dpll3xxx.o
|
||||
prcm-common = prcm.o powerdomain.o
|
||||
clock-common = clock.o clock_common_data.o clockdomain.o
|
||||
clock-common = clock.o clock_common_data.o \
|
||||
clockdomain.o clkt_dpll.o \
|
||||
clkt_clksel.o
|
||||
clock-omap2xxx = clkt2xxx_dpllcore.o \
|
||||
clkt2xxx_virt_prcm_set.o \
|
||||
clkt2xxx_apll.o clkt2xxx_osc.o \
|
||||
clkt2xxx_sys.o
|
||||
clock-omap3xxx = clkt34xx_dpll3m2.o
|
||||
|
||||
obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(prcm-common) $(clock-common)
|
||||
obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(prcm-common) $(clock-common) \
|
||||
$(clock-omap2xxx)
|
||||
obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(prcm-common) $(clock-common) \
|
||||
$(omap-3-4-common)
|
||||
obj-$(CONFIG_ARCH_OMAP4) += $(omap-3-4-common) prcm.o clock.o
|
||||
$(omap-3-4-common) $(clock-omap3xxx)
|
||||
obj-$(CONFIG_ARCH_OMAP4) += $(omap-3-4-common) $(prcm-common) $(clock-common)
|
||||
|
||||
obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
|
||||
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* OMAP2xxx APLL clock control functions
|
||||
*
|
||||
* Copyright (C) 2005-2008 Texas Instruments, Inc.
|
||||
* Copyright (C) 2004-2010 Nokia Corporation
|
||||
*
|
||||
* Contacts:
|
||||
* Richard Woodruff <r-woodruff2@ti.com>
|
||||
* Paul Walmsley
|
||||
*
|
||||
* Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
|
||||
* Gordon McNutt and RidgeRun, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#undef DEBUG
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <plat/clock.h>
|
||||
#include <plat/prcm.h>
|
||||
|
||||
#include "clock.h"
|
||||
#include "clock2xxx.h"
|
||||
#include "cm.h"
|
||||
#include "cm-regbits-24xx.h"
|
||||
|
||||
/* CM_CLKEN_PLL.EN_{54,96}M_PLL options (24XX) */
|
||||
#define EN_APLL_STOPPED 0
|
||||
#define EN_APLL_LOCKED 3
|
||||
|
||||
/* CM_CLKSEL1_PLL.APLLS_CLKIN options (24XX) */
|
||||
#define APLLS_CLKIN_19_2MHZ 0
|
||||
#define APLLS_CLKIN_13MHZ 2
|
||||
#define APLLS_CLKIN_12MHZ 3
|
||||
|
||||
/* Private functions */
|
||||
|
||||
/* Enable an APLL if off */
|
||||
static int omap2_clk_apll_enable(struct clk *clk, u32 status_mask)
|
||||
{
|
||||
u32 cval, apll_mask;
|
||||
|
||||
apll_mask = EN_APLL_LOCKED << clk->enable_bit;
|
||||
|
||||
cval = cm_read_mod_reg(PLL_MOD, CM_CLKEN);
|
||||
|
||||
if ((cval & apll_mask) == apll_mask)
|
||||
return 0; /* apll already enabled */
|
||||
|
||||
cval &= ~apll_mask;
|
||||
cval |= apll_mask;
|
||||
cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
|
||||
|
||||
omap2_cm_wait_idlest(OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), status_mask,
|
||||
clk->name);
|
||||
|
||||
/*
|
||||
* REVISIT: Should we return an error code if omap2_wait_clock_ready()
|
||||
* fails?
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap2_clk_apll96_enable(struct clk *clk)
|
||||
{
|
||||
return omap2_clk_apll_enable(clk, OMAP24XX_ST_96M_APLL);
|
||||
}
|
||||
|
||||
static int omap2_clk_apll54_enable(struct clk *clk)
|
||||
{
|
||||
return omap2_clk_apll_enable(clk, OMAP24XX_ST_54M_APLL);
|
||||
}
|
||||
|
||||
/* Stop APLL */
|
||||
static void omap2_clk_apll_disable(struct clk *clk)
|
||||
{
|
||||
u32 cval;
|
||||
|
||||
cval = cm_read_mod_reg(PLL_MOD, CM_CLKEN);
|
||||
cval &= ~(EN_APLL_LOCKED << clk->enable_bit);
|
||||
cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
|
||||
}
|
||||
|
||||
/* Public data */
|
||||
|
||||
const struct clkops clkops_apll96 = {
|
||||
.enable = omap2_clk_apll96_enable,
|
||||
.disable = omap2_clk_apll_disable,
|
||||
};
|
||||
|
||||
const struct clkops clkops_apll54 = {
|
||||
.enable = omap2_clk_apll54_enable,
|
||||
.disable = omap2_clk_apll_disable,
|
||||
};
|
||||
|
||||
/* Public functions */
|
||||
|
||||
u32 omap2xxx_get_apll_clkin(void)
|
||||
{
|
||||
u32 aplls, srate = 0;
|
||||
|
||||
aplls = cm_read_mod_reg(PLL_MOD, CM_CLKSEL1);
|
||||
aplls &= OMAP24XX_APLLS_CLKIN_MASK;
|
||||
aplls >>= OMAP24XX_APLLS_CLKIN_SHIFT;
|
||||
|
||||
if (aplls == APLLS_CLKIN_19_2MHZ)
|
||||
srate = 19200000;
|
||||
else if (aplls == APLLS_CLKIN_13MHZ)
|
||||
srate = 13000000;
|
||||
else if (aplls == APLLS_CLKIN_12MHZ)
|
||||
srate = 12000000;
|
||||
|
||||
return srate;
|
||||
}
|
||||
|
|
@ -0,0 +1,173 @@
|
|||
/*
|
||||
* DPLL + CORE_CLK composite clock functions
|
||||
*
|
||||
* Copyright (C) 2005-2008 Texas Instruments, Inc.
|
||||
* Copyright (C) 2004-2010 Nokia Corporation
|
||||
*
|
||||
* Contacts:
|
||||
* Richard Woodruff <r-woodruff2@ti.com>
|
||||
* Paul Walmsley
|
||||
*
|
||||
* Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
|
||||
* Gordon McNutt and RidgeRun, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* XXX The DPLL and CORE clocks should be split into two separate clock
|
||||
* types.
|
||||
*/
|
||||
#undef DEBUG
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <plat/clock.h>
|
||||
#include <plat/sram.h>
|
||||
#include <plat/sdrc.h>
|
||||
|
||||
#include "clock.h"
|
||||
#include "clock2xxx.h"
|
||||
#include "opp2xxx.h"
|
||||
#include "cm.h"
|
||||
#include "cm-regbits-24xx.h"
|
||||
|
||||
/* #define DOWN_VARIABLE_DPLL 1 */ /* Experimental */
|
||||
|
||||
/**
|
||||
* omap2xxx_clk_get_core_rate - return the CORE_CLK rate
|
||||
* @clk: pointer to the combined dpll_ck + core_ck (currently "dpll_ck")
|
||||
*
|
||||
* Returns the CORE_CLK rate. CORE_CLK can have one of three rate
|
||||
* sources on OMAP2xxx: the DPLL CLKOUT rate, DPLL CLKOUTX2, or 32KHz
|
||||
* (the latter is unusual). This currently should be called with
|
||||
* struct clk *dpll_ck, which is a composite clock of dpll_ck and
|
||||
* core_ck.
|
||||
*/
|
||||
unsigned long omap2xxx_clk_get_core_rate(struct clk *clk)
|
||||
{
|
||||
long long core_clk;
|
||||
u32 v;
|
||||
|
||||
core_clk = omap2_get_dpll_rate(clk);
|
||||
|
||||
v = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
|
||||
v &= OMAP24XX_CORE_CLK_SRC_MASK;
|
||||
|
||||
if (v == CORE_CLK_SRC_32K)
|
||||
core_clk = 32768;
|
||||
else
|
||||
core_clk *= v;
|
||||
|
||||
return core_clk;
|
||||
}
|
||||
|
||||
/*
|
||||
* Uses the current prcm set to tell if a rate is valid.
|
||||
* You can go slower, but not faster within a given rate set.
|
||||
*/
|
||||
static long omap2_dpllcore_round_rate(unsigned long target_rate)
|
||||
{
|
||||
u32 high, low, core_clk_src;
|
||||
|
||||
core_clk_src = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
|
||||
core_clk_src &= OMAP24XX_CORE_CLK_SRC_MASK;
|
||||
|
||||
if (core_clk_src == CORE_CLK_SRC_DPLL) { /* DPLL clockout */
|
||||
high = curr_prcm_set->dpll_speed * 2;
|
||||
low = curr_prcm_set->dpll_speed;
|
||||
} else { /* DPLL clockout x 2 */
|
||||
high = curr_prcm_set->dpll_speed;
|
||||
low = curr_prcm_set->dpll_speed / 2;
|
||||
}
|
||||
|
||||
#ifdef DOWN_VARIABLE_DPLL
|
||||
if (target_rate > high)
|
||||
return high;
|
||||
else
|
||||
return target_rate;
|
||||
#else
|
||||
if (target_rate > low)
|
||||
return high;
|
||||
else
|
||||
return low;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
unsigned long omap2_dpllcore_recalc(struct clk *clk)
|
||||
{
|
||||
return omap2xxx_clk_get_core_rate(clk);
|
||||
}
|
||||
|
||||
int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
u32 cur_rate, low, mult, div, valid_rate, done_rate;
|
||||
u32 bypass = 0;
|
||||
struct prcm_config tmpset;
|
||||
const struct dpll_data *dd;
|
||||
|
||||
cur_rate = omap2xxx_clk_get_core_rate(dclk);
|
||||
mult = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
|
||||
mult &= OMAP24XX_CORE_CLK_SRC_MASK;
|
||||
|
||||
if ((rate == (cur_rate / 2)) && (mult == 2)) {
|
||||
omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1);
|
||||
} else if ((rate == (cur_rate * 2)) && (mult == 1)) {
|
||||
omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
|
||||
} else if (rate != cur_rate) {
|
||||
valid_rate = omap2_dpllcore_round_rate(rate);
|
||||
if (valid_rate != rate)
|
||||
return -EINVAL;
|
||||
|
||||
if (mult == 1)
|
||||
low = curr_prcm_set->dpll_speed;
|
||||
else
|
||||
low = curr_prcm_set->dpll_speed / 2;
|
||||
|
||||
dd = clk->dpll_data;
|
||||
if (!dd)
|
||||
return -EINVAL;
|
||||
|
||||
tmpset.cm_clksel1_pll = __raw_readl(dd->mult_div1_reg);
|
||||
tmpset.cm_clksel1_pll &= ~(dd->mult_mask |
|
||||
dd->div1_mask);
|
||||
div = ((curr_prcm_set->xtal_speed / 1000000) - 1);
|
||||
tmpset.cm_clksel2_pll = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
|
||||
tmpset.cm_clksel2_pll &= ~OMAP24XX_CORE_CLK_SRC_MASK;
|
||||
if (rate > low) {
|
||||
tmpset.cm_clksel2_pll |= CORE_CLK_SRC_DPLL_X2;
|
||||
mult = ((rate / 2) / 1000000);
|
||||
done_rate = CORE_CLK_SRC_DPLL_X2;
|
||||
} else {
|
||||
tmpset.cm_clksel2_pll |= CORE_CLK_SRC_DPLL;
|
||||
mult = (rate / 1000000);
|
||||
done_rate = CORE_CLK_SRC_DPLL;
|
||||
}
|
||||
tmpset.cm_clksel1_pll |= (div << __ffs(dd->mult_mask));
|
||||
tmpset.cm_clksel1_pll |= (mult << __ffs(dd->div1_mask));
|
||||
|
||||
/* Worst case */
|
||||
tmpset.base_sdrc_rfr = SDRC_RFR_CTRL_BYPASS;
|
||||
|
||||
if (rate == curr_prcm_set->xtal_speed) /* If asking for 1-1 */
|
||||
bypass = 1;
|
||||
|
||||
/* For omap2xxx_sdrc_init_params() */
|
||||
omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
|
||||
|
||||
/* Force dll lock mode */
|
||||
omap2_set_prcm(tmpset.cm_clksel1_pll, tmpset.base_sdrc_rfr,
|
||||
bypass);
|
||||
|
||||
/* Errata: ret dll entry state */
|
||||
omap2xxx_sdrc_init_params(omap2xxx_sdrc_dll_is_unlocked());
|
||||
omap2xxx_sdrc_reprogram(done_rate, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* OMAP2xxx osc_clk-specific clock code
|
||||
*
|
||||
* Copyright (C) 2005-2008 Texas Instruments, Inc.
|
||||
* Copyright (C) 2004-2010 Nokia Corporation
|
||||
*
|
||||
* Contacts:
|
||||
* Richard Woodruff <r-woodruff2@ti.com>
|
||||
* Paul Walmsley
|
||||
*
|
||||
* Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
|
||||
* Gordon McNutt and RidgeRun, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#undef DEBUG
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <plat/clock.h>
|
||||
|
||||
#include "clock.h"
|
||||
#include "clock2xxx.h"
|
||||
#include "prm.h"
|
||||
#include "prm-regbits-24xx.h"
|
||||
|
||||
static int omap2_enable_osc_ck(struct clk *clk)
|
||||
{
|
||||
u32 pcc;
|
||||
|
||||
pcc = __raw_readl(prcm_clksrc_ctrl);
|
||||
|
||||
__raw_writel(pcc & ~OMAP_AUTOEXTCLKMODE_MASK, prcm_clksrc_ctrl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void omap2_disable_osc_ck(struct clk *clk)
|
||||
{
|
||||
u32 pcc;
|
||||
|
||||
pcc = __raw_readl(prcm_clksrc_ctrl);
|
||||
|
||||
__raw_writel(pcc | OMAP_AUTOEXTCLKMODE_MASK, prcm_clksrc_ctrl);
|
||||
}
|
||||
|
||||
const struct clkops clkops_oscck = {
|
||||
.enable = omap2_enable_osc_ck,
|
||||
.disable = omap2_disable_osc_ck,
|
||||
};
|
||||
|
||||
unsigned long omap2_osc_clk_recalc(struct clk *clk)
|
||||
{
|
||||
return omap2xxx_get_apll_clkin() * omap2xxx_get_sysclkdiv();
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* OMAP2xxx sys_clk-specific clock code
|
||||
*
|
||||
* Copyright (C) 2005-2008 Texas Instruments, Inc.
|
||||
* Copyright (C) 2004-2010 Nokia Corporation
|
||||
*
|
||||
* Contacts:
|
||||
* Richard Woodruff <r-woodruff2@ti.com>
|
||||
* Paul Walmsley
|
||||
*
|
||||
* Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
|
||||
* Gordon McNutt and RidgeRun, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#undef DEBUG
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <plat/clock.h>
|
||||
|
||||
#include "clock.h"
|
||||
#include "clock2xxx.h"
|
||||
#include "prm.h"
|
||||
#include "prm-regbits-24xx.h"
|
||||
|
||||
void __iomem *prcm_clksrc_ctrl;
|
||||
|
||||
u32 omap2xxx_get_sysclkdiv(void)
|
||||
{
|
||||
u32 div;
|
||||
|
||||
div = __raw_readl(prcm_clksrc_ctrl);
|
||||
div &= OMAP_SYSCLKDIV_MASK;
|
||||
div >>= OMAP_SYSCLKDIV_SHIFT;
|
||||
|
||||
return div;
|
||||
}
|
||||
|
||||
unsigned long omap2xxx_sys_clk_recalc(struct clk *clk)
|
||||
{
|
||||
return clk->parent->rate / omap2xxx_get_sysclkdiv();
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,254 @@
|
|||
/*
|
||||
* OMAP2xxx DVFS virtual clock functions
|
||||
*
|
||||
* Copyright (C) 2005-2008 Texas Instruments, Inc.
|
||||
* Copyright (C) 2004-2010 Nokia Corporation
|
||||
*
|
||||
* Contacts:
|
||||
* Richard Woodruff <r-woodruff2@ti.com>
|
||||
* Paul Walmsley
|
||||
*
|
||||
* Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
|
||||
* Gordon McNutt and RidgeRun, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* XXX Some of this code should be replaceable by the upcoming OPP layer
|
||||
* code. However, some notion of "rate set" is probably still necessary
|
||||
* for OMAP2xxx at least. Rate sets should be generalized so they can be
|
||||
* used for any OMAP chip, not just OMAP2xxx. In particular, Richard Woodruff
|
||||
* has in the past expressed a preference to use rate sets for OPP changes,
|
||||
* rather than dynamically recalculating the clock tree, so if someone wants
|
||||
* this badly enough to write the code to handle it, we should support it
|
||||
* as an option.
|
||||
*/
|
||||
#undef DEBUG
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/cpufreq.h>
|
||||
|
||||
#include <plat/clock.h>
|
||||
#include <plat/sram.h>
|
||||
#include <plat/sdrc.h>
|
||||
|
||||
#include "clock.h"
|
||||
#include "clock2xxx.h"
|
||||
#include "opp2xxx.h"
|
||||
#include "cm.h"
|
||||
#include "cm-regbits-24xx.h"
|
||||
|
||||
const struct prcm_config *curr_prcm_set;
|
||||
const struct prcm_config *rate_table;
|
||||
|
||||
/**
|
||||
* omap2_table_mpu_recalc - just return the MPU speed
|
||||
* @clk: virt_prcm_set struct clk
|
||||
*
|
||||
* Set virt_prcm_set's rate to the mpu_speed field of the current PRCM set.
|
||||
*/
|
||||
unsigned long omap2_table_mpu_recalc(struct clk *clk)
|
||||
{
|
||||
return curr_prcm_set->mpu_speed;
|
||||
}
|
||||
|
||||
/*
|
||||
* Look for a rate equal or less than the target rate given a configuration set.
|
||||
*
|
||||
* What's not entirely clear is "which" field represents the key field.
|
||||
* Some might argue L3-DDR, others ARM, others IVA. This code is simple and
|
||||
* just uses the ARM rates.
|
||||
*/
|
||||
long omap2_round_to_table_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
const struct prcm_config *ptr;
|
||||
long highest_rate;
|
||||
long sys_ck_rate;
|
||||
|
||||
sys_ck_rate = clk_get_rate(sclk);
|
||||
|
||||
highest_rate = -EINVAL;
|
||||
|
||||
for (ptr = rate_table; ptr->mpu_speed; ptr++) {
|
||||
if (!(ptr->flags & cpu_mask))
|
||||
continue;
|
||||
if (ptr->xtal_speed != sys_ck_rate)
|
||||
continue;
|
||||
|
||||
highest_rate = ptr->mpu_speed;
|
||||
|
||||
/* Can check only after xtal frequency check */
|
||||
if (ptr->mpu_speed <= rate)
|
||||
break;
|
||||
}
|
||||
return highest_rate;
|
||||
}
|
||||
|
||||
/* Sets basic clocks based on the specified rate */
|
||||
int omap2_select_table_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
u32 cur_rate, done_rate, bypass = 0, tmp;
|
||||
const struct prcm_config *prcm;
|
||||
unsigned long found_speed = 0;
|
||||
unsigned long flags;
|
||||
long sys_ck_rate;
|
||||
|
||||
sys_ck_rate = clk_get_rate(sclk);
|
||||
|
||||
for (prcm = rate_table; prcm->mpu_speed; prcm++) {
|
||||
if (!(prcm->flags & cpu_mask))
|
||||
continue;
|
||||
|
||||
if (prcm->xtal_speed != sys_ck_rate)
|
||||
continue;
|
||||
|
||||
if (prcm->mpu_speed <= rate) {
|
||||
found_speed = prcm->mpu_speed;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found_speed) {
|
||||
printk(KERN_INFO "Could not set MPU rate to %luMHz\n",
|
||||
rate / 1000000);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
curr_prcm_set = prcm;
|
||||
cur_rate = omap2xxx_clk_get_core_rate(dclk);
|
||||
|
||||
if (prcm->dpll_speed == cur_rate / 2) {
|
||||
omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1);
|
||||
} else if (prcm->dpll_speed == cur_rate * 2) {
|
||||
omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
|
||||
} else if (prcm->dpll_speed != cur_rate) {
|
||||
local_irq_save(flags);
|
||||
|
||||
if (prcm->dpll_speed == prcm->xtal_speed)
|
||||
bypass = 1;
|
||||
|
||||
if ((prcm->cm_clksel2_pll & OMAP24XX_CORE_CLK_SRC_MASK) ==
|
||||
CORE_CLK_SRC_DPLL_X2)
|
||||
done_rate = CORE_CLK_SRC_DPLL_X2;
|
||||
else
|
||||
done_rate = CORE_CLK_SRC_DPLL;
|
||||
|
||||
/* MPU divider */
|
||||
cm_write_mod_reg(prcm->cm_clksel_mpu, MPU_MOD, CM_CLKSEL);
|
||||
|
||||
/* dsp + iva1 div(2420), iva2.1(2430) */
|
||||
cm_write_mod_reg(prcm->cm_clksel_dsp,
|
||||
OMAP24XX_DSP_MOD, CM_CLKSEL);
|
||||
|
||||
cm_write_mod_reg(prcm->cm_clksel_gfx, GFX_MOD, CM_CLKSEL);
|
||||
|
||||
/* Major subsystem dividers */
|
||||
tmp = cm_read_mod_reg(CORE_MOD, CM_CLKSEL1) & OMAP24XX_CLKSEL_DSS2_MASK;
|
||||
cm_write_mod_reg(prcm->cm_clksel1_core | tmp, CORE_MOD,
|
||||
CM_CLKSEL1);
|
||||
|
||||
if (cpu_is_omap2430())
|
||||
cm_write_mod_reg(prcm->cm_clksel_mdm,
|
||||
OMAP2430_MDM_MOD, CM_CLKSEL);
|
||||
|
||||
/* x2 to enter omap2xxx_sdrc_init_params() */
|
||||
omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
|
||||
|
||||
omap2_set_prcm(prcm->cm_clksel1_pll, prcm->base_sdrc_rfr,
|
||||
bypass);
|
||||
|
||||
omap2xxx_sdrc_init_params(omap2xxx_sdrc_dll_is_unlocked());
|
||||
omap2xxx_sdrc_reprogram(done_rate, 0);
|
||||
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CPU_FREQ
|
||||
/*
|
||||
* Walk PRCM rate table and fillout cpufreq freq_table
|
||||
* XXX This should be replaced by an OPP layer in the near future
|
||||
*/
|
||||
static struct cpufreq_frequency_table *freq_table;
|
||||
|
||||
void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table)
|
||||
{
|
||||
const struct prcm_config *prcm;
|
||||
long sys_ck_rate;
|
||||
int i = 0;
|
||||
int tbl_sz = 0;
|
||||
|
||||
if (!cpu_is_omap24xx())
|
||||
return;
|
||||
|
||||
sys_ck_rate = clk_get_rate(sclk);
|
||||
|
||||
for (prcm = rate_table; prcm->mpu_speed; prcm++) {
|
||||
if (!(prcm->flags & cpu_mask))
|
||||
continue;
|
||||
if (prcm->xtal_speed != sys_ck_rate)
|
||||
continue;
|
||||
|
||||
/* don't put bypass rates in table */
|
||||
if (prcm->dpll_speed == prcm->xtal_speed)
|
||||
continue;
|
||||
|
||||
tbl_sz++;
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX Ensure that we're doing what CPUFreq expects for this error
|
||||
* case and the following one
|
||||
*/
|
||||
if (tbl_sz == 0) {
|
||||
pr_warning("%s: no matching entries in rate_table\n",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Include the CPUFREQ_TABLE_END terminator entry */
|
||||
tbl_sz++;
|
||||
|
||||
freq_table = kzalloc(sizeof(struct cpufreq_frequency_table) * tbl_sz,
|
||||
GFP_ATOMIC);
|
||||
if (!freq_table) {
|
||||
pr_err("%s: could not kzalloc frequency table\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
for (prcm = rate_table; prcm->mpu_speed; prcm++) {
|
||||
if (!(prcm->flags & cpu_mask))
|
||||
continue;
|
||||
if (prcm->xtal_speed != sys_ck_rate)
|
||||
continue;
|
||||
|
||||
/* don't put bypass rates in table */
|
||||
if (prcm->dpll_speed == prcm->xtal_speed)
|
||||
continue;
|
||||
|
||||
freq_table[i].index = i;
|
||||
freq_table[i].frequency = prcm->mpu_speed / 1000;
|
||||
i++;
|
||||
}
|
||||
|
||||
freq_table[i].index = i;
|
||||
freq_table[i].frequency = CPUFREQ_TABLE_END;
|
||||
|
||||
*table = &freq_table[0];
|
||||
}
|
||||
|
||||
void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table)
|
||||
{
|
||||
if (!cpu_is_omap24xx())
|
||||
return;
|
||||
|
||||
kfree(freq_table);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* OMAP34xx M2 divider clock code
|
||||
*
|
||||
* Copyright (C) 2007-2008 Texas Instruments, Inc.
|
||||
* Copyright (C) 2007-2010 Nokia Corporation
|
||||
*
|
||||
* Paul Walmsley
|
||||
* Jouni Högander
|
||||
*
|
||||
* Parts of this code are based on code written by
|
||||
* Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#undef DEBUG
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <plat/clock.h>
|
||||
#include <plat/sram.h>
|
||||
#include <plat/sdrc.h>
|
||||
|
||||
#include "clock.h"
|
||||
#include "clock34xx.h"
|
||||
#include "sdrc.h"
|
||||
|
||||
#define CYCLES_PER_MHZ 1000000
|
||||
|
||||
/*
|
||||
* CORE DPLL (DPLL3) M2 divider rate programming functions
|
||||
*
|
||||
* These call into SRAM code to do the actual CM writes, since the SDRAM
|
||||
* is clocked from DPLL3.
|
||||
*/
|
||||
|
||||
/**
|
||||
* omap3_core_dpll_m2_set_rate - set CORE DPLL M2 divider
|
||||
* @clk: struct clk * of DPLL to set
|
||||
* @rate: rounded target rate
|
||||
*
|
||||
* Program the DPLL M2 divider with the rounded target rate. Returns
|
||||
* -EINVAL upon error, or 0 upon success.
|
||||
*/
|
||||
int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
u32 new_div = 0;
|
||||
u32 unlock_dll = 0;
|
||||
u32 c;
|
||||
unsigned long validrate, sdrcrate, _mpurate;
|
||||
struct omap_sdrc_params *sdrc_cs0;
|
||||
struct omap_sdrc_params *sdrc_cs1;
|
||||
int ret;
|
||||
|
||||
if (!clk || !rate)
|
||||
return -EINVAL;
|
||||
|
||||
validrate = omap2_clksel_round_rate_div(clk, rate, &new_div);
|
||||
if (validrate != rate)
|
||||
return -EINVAL;
|
||||
|
||||
sdrcrate = sdrc_ick_p->rate;
|
||||
if (rate > clk->rate)
|
||||
sdrcrate <<= ((rate / clk->rate) >> 1);
|
||||
else
|
||||
sdrcrate >>= ((clk->rate / rate) >> 1);
|
||||
|
||||
ret = omap2_sdrc_get_params(sdrcrate, &sdrc_cs0, &sdrc_cs1);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
|
||||
if (sdrcrate < MIN_SDRC_DLL_LOCK_FREQ) {
|
||||
pr_debug("clock: will unlock SDRC DLL\n");
|
||||
unlock_dll = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX This only needs to be done when the CPU frequency changes
|
||||
*/
|
||||
_mpurate = arm_fck_p->rate / CYCLES_PER_MHZ;
|
||||
c = (_mpurate << SDRC_MPURATE_SCALE) >> SDRC_MPURATE_BASE_SHIFT;
|
||||
c += 1; /* for safety */
|
||||
c *= SDRC_MPURATE_LOOPS;
|
||||
c >>= SDRC_MPURATE_SCALE;
|
||||
if (c == 0)
|
||||
c = 1;
|
||||
|
||||
pr_debug("clock: changing CORE DPLL rate from %lu to %lu\n", clk->rate,
|
||||
validrate);
|
||||
pr_debug("clock: SDRC CS0 timing params used:"
|
||||
" RFR %08x CTRLA %08x CTRLB %08x MR %08x\n",
|
||||
sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
|
||||
sdrc_cs0->actim_ctrlb, sdrc_cs0->mr);
|
||||
if (sdrc_cs1)
|
||||
pr_debug("clock: SDRC CS1 timing params used: "
|
||||
" RFR %08x CTRLA %08x CTRLB %08x MR %08x\n",
|
||||
sdrc_cs1->rfr_ctrl, sdrc_cs1->actim_ctrla,
|
||||
sdrc_cs1->actim_ctrlb, sdrc_cs1->mr);
|
||||
|
||||
if (sdrc_cs1)
|
||||
omap3_configure_core_dpll(
|
||||
new_div, unlock_dll, c, rate > clk->rate,
|
||||
sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
|
||||
sdrc_cs0->actim_ctrlb, sdrc_cs0->mr,
|
||||
sdrc_cs1->rfr_ctrl, sdrc_cs1->actim_ctrla,
|
||||
sdrc_cs1->actim_ctrlb, sdrc_cs1->mr);
|
||||
else
|
||||
omap3_configure_core_dpll(
|
||||
new_div, unlock_dll, c, rate > clk->rate,
|
||||
sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
|
||||
sdrc_cs0->actim_ctrlb, sdrc_cs0->mr,
|
||||
0, 0, 0, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,417 @@
|
|||
/*
|
||||
* clkt_clksel.c - OMAP2/3/4 clksel clock functions
|
||||
*
|
||||
* Copyright (C) 2005-2008 Texas Instruments, Inc.
|
||||
* Copyright (C) 2004-2010 Nokia Corporation
|
||||
*
|
||||
* Contacts:
|
||||
* Richard Woodruff <r-woodruff2@ti.com>
|
||||
* Paul Walmsley
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* XXX At some point these clksel clocks should be split into
|
||||
* "divider" clocks and "mux" clocks to better match the hardware.
|
||||
*
|
||||
* XXX Currently these clocks are only used in the OMAP2/3/4 code, but
|
||||
* many of the OMAP1 clocks should be convertible to use this
|
||||
* mechanism.
|
||||
*/
|
||||
#undef DEBUG
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <plat/clock.h>
|
||||
|
||||
#include "clock.h"
|
||||
#include "cm.h"
|
||||
#include "cm-regbits-24xx.h"
|
||||
#include "cm-regbits-34xx.h"
|
||||
|
||||
/* Private functions */
|
||||
|
||||
/**
|
||||
* _omap2_get_clksel_by_parent - return clksel struct for a given clk & parent
|
||||
* @clk: OMAP struct clk ptr to inspect
|
||||
* @src_clk: OMAP struct clk ptr of the parent clk to search for
|
||||
*
|
||||
* Scan the struct clksel array associated with the clock to find
|
||||
* the element associated with the supplied parent clock address.
|
||||
* Returns a pointer to the struct clksel on success or NULL on error.
|
||||
*/
|
||||
static const struct clksel *_omap2_get_clksel_by_parent(struct clk *clk,
|
||||
struct clk *src_clk)
|
||||
{
|
||||
const struct clksel *clks;
|
||||
|
||||
if (!clk->clksel)
|
||||
return NULL;
|
||||
|
||||
for (clks = clk->clksel; clks->parent; clks++) {
|
||||
if (clks->parent == src_clk)
|
||||
break; /* Found the requested parent */
|
||||
}
|
||||
|
||||
if (!clks->parent) {
|
||||
printk(KERN_ERR "clock: Could not find parent clock %s in "
|
||||
"clksel array of clock %s\n", src_clk->name,
|
||||
clk->name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return clks;
|
||||
}
|
||||
|
||||
/*
|
||||
* Converts encoded control register address into a full address
|
||||
* On error, the return value (parent_div) will be 0.
|
||||
*/
|
||||
static u32 _omap2_clksel_get_src_field(struct clk *src_clk, struct clk *clk,
|
||||
u32 *field_val)
|
||||
{
|
||||
const struct clksel *clks;
|
||||
const struct clksel_rate *clkr;
|
||||
|
||||
clks = _omap2_get_clksel_by_parent(clk, src_clk);
|
||||
if (!clks)
|
||||
return 0;
|
||||
|
||||
for (clkr = clks->rates; clkr->div; clkr++) {
|
||||
if (clkr->flags & cpu_mask && clkr->flags & DEFAULT_RATE)
|
||||
break; /* Found the default rate for this platform */
|
||||
}
|
||||
|
||||
if (!clkr->div) {
|
||||
printk(KERN_ERR "clock: Could not find default rate for "
|
||||
"clock %s parent %s\n", clk->name,
|
||||
src_clk->parent->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Should never happen. Add a clksel mask to the struct clk. */
|
||||
WARN_ON(clk->clksel_mask == 0);
|
||||
|
||||
*field_val = clkr->val;
|
||||
|
||||
return clkr->div;
|
||||
}
|
||||
|
||||
|
||||
/* Public functions */
|
||||
|
||||
/**
|
||||
* omap2_init_clksel_parent - set a clksel clk's parent field from the hardware
|
||||
* @clk: OMAP clock struct ptr to use
|
||||
*
|
||||
* Given a pointer to a source-selectable struct clk, read the hardware
|
||||
* register and determine what its parent is currently set to. Update the
|
||||
* clk->parent field with the appropriate clk ptr.
|
||||
*/
|
||||
void omap2_init_clksel_parent(struct clk *clk)
|
||||
{
|
||||
const struct clksel *clks;
|
||||
const struct clksel_rate *clkr;
|
||||
u32 r, found = 0;
|
||||
|
||||
if (!clk->clksel)
|
||||
return;
|
||||
|
||||
r = __raw_readl(clk->clksel_reg) & clk->clksel_mask;
|
||||
r >>= __ffs(clk->clksel_mask);
|
||||
|
||||
for (clks = clk->clksel; clks->parent && !found; clks++) {
|
||||
for (clkr = clks->rates; clkr->div && !found; clkr++) {
|
||||
if ((clkr->flags & cpu_mask) && (clkr->val == r)) {
|
||||
if (clk->parent != clks->parent) {
|
||||
pr_debug("clock: inited %s parent "
|
||||
"to %s (was %s)\n",
|
||||
clk->name, clks->parent->name,
|
||||
((clk->parent) ?
|
||||
clk->parent->name : "NULL"));
|
||||
clk_reparent(clk, clks->parent);
|
||||
};
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
printk(KERN_ERR "clock: init parent: could not find "
|
||||
"regval %0x for clock %s\n", r, clk->name);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Used for clocks that are part of CLKSEL_xyz governed clocks.
|
||||
* REVISIT: Maybe change to use clk->enable() functions like on omap1?
|
||||
*/
|
||||
unsigned long omap2_clksel_recalc(struct clk *clk)
|
||||
{
|
||||
unsigned long rate;
|
||||
u32 div = 0;
|
||||
|
||||
pr_debug("clock: recalc'ing clksel clk %s\n", clk->name);
|
||||
|
||||
div = omap2_clksel_get_divisor(clk);
|
||||
if (div == 0)
|
||||
return clk->rate;
|
||||
|
||||
rate = clk->parent->rate / div;
|
||||
|
||||
pr_debug("clock: new clock rate is %ld (div %d)\n", rate, div);
|
||||
|
||||
return rate;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap2_clksel_round_rate_div - find divisor for the given clock and rate
|
||||
* @clk: OMAP struct clk to use
|
||||
* @target_rate: desired clock rate
|
||||
* @new_div: ptr to where we should store the divisor
|
||||
*
|
||||
* Finds 'best' divider value in an array based on the source and target
|
||||
* rates. The divider array must be sorted with smallest divider first.
|
||||
* Note that this will not work for clocks which are part of CONFIG_PARTICIPANT,
|
||||
* they are only settable as part of virtual_prcm set.
|
||||
*
|
||||
* Returns the rounded clock rate or returns 0xffffffff on error.
|
||||
*/
|
||||
u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
|
||||
u32 *new_div)
|
||||
{
|
||||
unsigned long test_rate;
|
||||
const struct clksel *clks;
|
||||
const struct clksel_rate *clkr;
|
||||
u32 last_div = 0;
|
||||
|
||||
pr_debug("clock: clksel_round_rate_div: %s target_rate %ld\n",
|
||||
clk->name, target_rate);
|
||||
|
||||
*new_div = 1;
|
||||
|
||||
clks = _omap2_get_clksel_by_parent(clk, clk->parent);
|
||||
if (!clks)
|
||||
return ~0;
|
||||
|
||||
for (clkr = clks->rates; clkr->div; clkr++) {
|
||||
if (!(clkr->flags & cpu_mask))
|
||||
continue;
|
||||
|
||||
/* Sanity check */
|
||||
if (clkr->div <= last_div)
|
||||
pr_err("clock: clksel_rate table not sorted "
|
||||
"for clock %s", clk->name);
|
||||
|
||||
last_div = clkr->div;
|
||||
|
||||
test_rate = clk->parent->rate / clkr->div;
|
||||
|
||||
if (test_rate <= target_rate)
|
||||
break; /* found it */
|
||||
}
|
||||
|
||||
if (!clkr->div) {
|
||||
pr_err("clock: Could not find divisor for target "
|
||||
"rate %ld for clock %s parent %s\n", target_rate,
|
||||
clk->name, clk->parent->name);
|
||||
return ~0;
|
||||
}
|
||||
|
||||
*new_div = clkr->div;
|
||||
|
||||
pr_debug("clock: new_div = %d, new_rate = %ld\n", *new_div,
|
||||
(clk->parent->rate / clkr->div));
|
||||
|
||||
return clk->parent->rate / clkr->div;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap2_clksel_round_rate - find rounded rate for the given clock and rate
|
||||
* @clk: OMAP struct clk to use
|
||||
* @target_rate: desired clock rate
|
||||
*
|
||||
* Compatibility wrapper for OMAP clock framework
|
||||
* Finds best target rate based on the source clock and possible dividers.
|
||||
* rates. The divider array must be sorted with smallest divider first.
|
||||
* Note that this will not work for clocks which are part of CONFIG_PARTICIPANT,
|
||||
* they are only settable as part of virtual_prcm set.
|
||||
*
|
||||
* Returns the rounded clock rate or returns 0xffffffff on error.
|
||||
*/
|
||||
long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate)
|
||||
{
|
||||
u32 new_div;
|
||||
|
||||
return omap2_clksel_round_rate_div(clk, target_rate, &new_div);
|
||||
}
|
||||
|
||||
|
||||
/* Given a clock and a rate apply a clock specific rounding function */
|
||||
long omap2_clk_round_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
if (clk->round_rate)
|
||||
return clk->round_rate(clk, rate);
|
||||
|
||||
if (clk->flags & RATE_FIXED)
|
||||
printk(KERN_ERR "clock: generic omap2_clk_round_rate called "
|
||||
"on fixed-rate clock %s\n", clk->name);
|
||||
|
||||
return clk->rate;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap2_clksel_to_divisor() - turn clksel field value into integer divider
|
||||
* @clk: OMAP struct clk to use
|
||||
* @field_val: register field value to find
|
||||
*
|
||||
* Given a struct clk of a rate-selectable clksel clock, and a register field
|
||||
* value to search for, find the corresponding clock divisor. The register
|
||||
* field value should be pre-masked and shifted down so the LSB is at bit 0
|
||||
* before calling. Returns 0 on error
|
||||
*/
|
||||
u32 omap2_clksel_to_divisor(struct clk *clk, u32 field_val)
|
||||
{
|
||||
const struct clksel *clks;
|
||||
const struct clksel_rate *clkr;
|
||||
|
||||
clks = _omap2_get_clksel_by_parent(clk, clk->parent);
|
||||
if (!clks)
|
||||
return 0;
|
||||
|
||||
for (clkr = clks->rates; clkr->div; clkr++) {
|
||||
if ((clkr->flags & cpu_mask) && (clkr->val == field_val))
|
||||
break;
|
||||
}
|
||||
|
||||
if (!clkr->div) {
|
||||
printk(KERN_ERR "clock: Could not find fieldval %d for "
|
||||
"clock %s parent %s\n", field_val, clk->name,
|
||||
clk->parent->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return clkr->div;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap2_divisor_to_clksel() - turn clksel integer divisor into a field value
|
||||
* @clk: OMAP struct clk to use
|
||||
* @div: integer divisor to search for
|
||||
*
|
||||
* Given a struct clk of a rate-selectable clksel clock, and a clock divisor,
|
||||
* find the corresponding register field value. The return register value is
|
||||
* the value before left-shifting. Returns ~0 on error
|
||||
*/
|
||||
u32 omap2_divisor_to_clksel(struct clk *clk, u32 div)
|
||||
{
|
||||
const struct clksel *clks;
|
||||
const struct clksel_rate *clkr;
|
||||
|
||||
/* should never happen */
|
||||
WARN_ON(div == 0);
|
||||
|
||||
clks = _omap2_get_clksel_by_parent(clk, clk->parent);
|
||||
if (!clks)
|
||||
return ~0;
|
||||
|
||||
for (clkr = clks->rates; clkr->div; clkr++) {
|
||||
if ((clkr->flags & cpu_mask) && (clkr->div == div))
|
||||
break;
|
||||
}
|
||||
|
||||
if (!clkr->div) {
|
||||
printk(KERN_ERR "clock: Could not find divisor %d for "
|
||||
"clock %s parent %s\n", div, clk->name,
|
||||
clk->parent->name);
|
||||
return ~0;
|
||||
}
|
||||
|
||||
return clkr->val;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap2_clksel_get_divisor - get current divider applied to parent clock.
|
||||
* @clk: OMAP struct clk to use.
|
||||
*
|
||||
* Returns the integer divisor upon success or 0 on error.
|
||||
*/
|
||||
u32 omap2_clksel_get_divisor(struct clk *clk)
|
||||
{
|
||||
u32 v;
|
||||
|
||||
if (!clk->clksel_mask)
|
||||
return 0;
|
||||
|
||||
v = __raw_readl(clk->clksel_reg) & clk->clksel_mask;
|
||||
v >>= __ffs(clk->clksel_mask);
|
||||
|
||||
return omap2_clksel_to_divisor(clk, v);
|
||||
}
|
||||
|
||||
int omap2_clksel_set_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
u32 v, field_val, validrate, new_div = 0;
|
||||
|
||||
if (!clk->clksel_mask)
|
||||
return -EINVAL;
|
||||
|
||||
validrate = omap2_clksel_round_rate_div(clk, rate, &new_div);
|
||||
if (validrate != rate)
|
||||
return -EINVAL;
|
||||
|
||||
field_val = omap2_divisor_to_clksel(clk, new_div);
|
||||
if (field_val == ~0)
|
||||
return -EINVAL;
|
||||
|
||||
v = __raw_readl(clk->clksel_reg);
|
||||
v &= ~clk->clksel_mask;
|
||||
v |= field_val << __ffs(clk->clksel_mask);
|
||||
__raw_writel(v, clk->clksel_reg);
|
||||
v = __raw_readl(clk->clksel_reg); /* OCP barrier */
|
||||
|
||||
clk->rate = clk->parent->rate / new_div;
|
||||
|
||||
omap2xxx_clk_commit(clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int omap2_clksel_set_parent(struct clk *clk, struct clk *new_parent)
|
||||
{
|
||||
u32 field_val, v, parent_div;
|
||||
|
||||
if (!clk->clksel)
|
||||
return -EINVAL;
|
||||
|
||||
parent_div = _omap2_clksel_get_src_field(new_parent, clk, &field_val);
|
||||
if (!parent_div)
|
||||
return -EINVAL;
|
||||
|
||||
/* Set new source value (previous dividers if any in effect) */
|
||||
v = __raw_readl(clk->clksel_reg);
|
||||
v &= ~clk->clksel_mask;
|
||||
v |= field_val << __ffs(clk->clksel_mask);
|
||||
__raw_writel(v, clk->clksel_reg);
|
||||
v = __raw_readl(clk->clksel_reg); /* OCP barrier */
|
||||
|
||||
omap2xxx_clk_commit(clk);
|
||||
|
||||
clk_reparent(clk, new_parent);
|
||||
|
||||
/* CLKSEL clocks follow their parents' rates, divided by a divisor */
|
||||
clk->rate = new_parent->rate;
|
||||
|
||||
if (parent_div > 0)
|
||||
clk->rate /= parent_div;
|
||||
|
||||
pr_debug("clock: set parent of %s to %s (new rate %ld)\n",
|
||||
clk->name, clk->parent->name, clk->rate);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,386 @@
|
|||
/*
|
||||
* OMAP2/3/4 DPLL clock functions
|
||||
*
|
||||
* Copyright (C) 2005-2008 Texas Instruments, Inc.
|
||||
* Copyright (C) 2004-2010 Nokia Corporation
|
||||
*
|
||||
* Contacts:
|
||||
* Richard Woodruff <r-woodruff2@ti.com>
|
||||
* Paul Walmsley
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#undef DEBUG
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <asm/div64.h>
|
||||
|
||||
#include <plat/clock.h>
|
||||
|
||||
#include "clock.h"
|
||||
#include "cm.h"
|
||||
#include "cm-regbits-24xx.h"
|
||||
#include "cm-regbits-34xx.h"
|
||||
|
||||
/* DPLL rate rounding: minimum DPLL multiplier, divider values */
|
||||
#define DPLL_MIN_MULTIPLIER 1
|
||||
#define DPLL_MIN_DIVIDER 1
|
||||
|
||||
/* Possible error results from _dpll_test_mult */
|
||||
#define DPLL_MULT_UNDERFLOW -1
|
||||
|
||||
/*
|
||||
* Scale factor to mitigate roundoff errors in DPLL rate rounding.
|
||||
* The higher the scale factor, the greater the risk of arithmetic overflow,
|
||||
* but the closer the rounded rate to the target rate. DPLL_SCALE_FACTOR
|
||||
* must be a power of DPLL_SCALE_BASE.
|
||||
*/
|
||||
#define DPLL_SCALE_FACTOR 64
|
||||
#define DPLL_SCALE_BASE 2
|
||||
#define DPLL_ROUNDING_VAL ((DPLL_SCALE_BASE / 2) * \
|
||||
(DPLL_SCALE_FACTOR / DPLL_SCALE_BASE))
|
||||
|
||||
/* DPLL valid Fint frequency band limits - from 34xx TRM Section 4.7.6.2 */
|
||||
#define DPLL_FINT_BAND1_MIN 750000
|
||||
#define DPLL_FINT_BAND1_MAX 2100000
|
||||
#define DPLL_FINT_BAND2_MIN 7500000
|
||||
#define DPLL_FINT_BAND2_MAX 21000000
|
||||
|
||||
/* _dpll_test_fint() return codes */
|
||||
#define DPLL_FINT_UNDERFLOW -1
|
||||
#define DPLL_FINT_INVALID -2
|
||||
|
||||
/* Private functions */
|
||||
|
||||
/*
|
||||
* _dpll_test_fint - test whether an Fint value is valid for the DPLL
|
||||
* @clk: DPLL struct clk to test
|
||||
* @n: divider value (N) to test
|
||||
*
|
||||
* Tests whether a particular divider @n will result in a valid DPLL
|
||||
* internal clock frequency Fint. See the 34xx TRM 4.7.6.2 "DPLL Jitter
|
||||
* Correction". Returns 0 if OK, -1 if the enclosing loop can terminate
|
||||
* (assuming that it is counting N upwards), or -2 if the enclosing loop
|
||||
* should skip to the next iteration (again assuming N is increasing).
|
||||
*/
|
||||
static int _dpll_test_fint(struct clk *clk, u8 n)
|
||||
{
|
||||
struct dpll_data *dd;
|
||||
long fint;
|
||||
int ret = 0;
|
||||
|
||||
dd = clk->dpll_data;
|
||||
|
||||
/* DPLL divider must result in a valid jitter correction val */
|
||||
fint = clk->parent->rate / (n + 1);
|
||||
if (fint < DPLL_FINT_BAND1_MIN) {
|
||||
|
||||
pr_debug("rejecting n=%d due to Fint failure, "
|
||||
"lowering max_divider\n", n);
|
||||
dd->max_divider = n;
|
||||
ret = DPLL_FINT_UNDERFLOW;
|
||||
|
||||
} else if (fint > DPLL_FINT_BAND1_MAX &&
|
||||
fint < DPLL_FINT_BAND2_MIN) {
|
||||
|
||||
pr_debug("rejecting n=%d due to Fint failure\n", n);
|
||||
ret = DPLL_FINT_INVALID;
|
||||
|
||||
} else if (fint > DPLL_FINT_BAND2_MAX) {
|
||||
|
||||
pr_debug("rejecting n=%d due to Fint failure, "
|
||||
"boosting min_divider\n", n);
|
||||
dd->min_divider = n;
|
||||
ret = DPLL_FINT_INVALID;
|
||||
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static unsigned long _dpll_compute_new_rate(unsigned long parent_rate,
|
||||
unsigned int m, unsigned int n)
|
||||
{
|
||||
unsigned long long num;
|
||||
|
||||
num = (unsigned long long)parent_rate * m;
|
||||
do_div(num, n);
|
||||
return num;
|
||||
}
|
||||
|
||||
/*
|
||||
* _dpll_test_mult - test a DPLL multiplier value
|
||||
* @m: pointer to the DPLL m (multiplier) value under test
|
||||
* @n: current DPLL n (divider) value under test
|
||||
* @new_rate: pointer to storage for the resulting rounded rate
|
||||
* @target_rate: the desired DPLL rate
|
||||
* @parent_rate: the DPLL's parent clock rate
|
||||
*
|
||||
* This code tests a DPLL multiplier value, ensuring that the
|
||||
* resulting rate will not be higher than the target_rate, and that
|
||||
* the multiplier value itself is valid for the DPLL. Initially, the
|
||||
* integer pointed to by the m argument should be prescaled by
|
||||
* multiplying by DPLL_SCALE_FACTOR. The code will replace this with
|
||||
* a non-scaled m upon return. This non-scaled m will result in a
|
||||
* new_rate as close as possible to target_rate (but not greater than
|
||||
* target_rate) given the current (parent_rate, n, prescaled m)
|
||||
* triple. Returns DPLL_MULT_UNDERFLOW in the event that the
|
||||
* non-scaled m attempted to underflow, which can allow the calling
|
||||
* function to bail out early; or 0 upon success.
|
||||
*/
|
||||
static int _dpll_test_mult(int *m, int n, unsigned long *new_rate,
|
||||
unsigned long target_rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
int r = 0, carry = 0;
|
||||
|
||||
/* Unscale m and round if necessary */
|
||||
if (*m % DPLL_SCALE_FACTOR >= DPLL_ROUNDING_VAL)
|
||||
carry = 1;
|
||||
*m = (*m / DPLL_SCALE_FACTOR) + carry;
|
||||
|
||||
/*
|
||||
* The new rate must be <= the target rate to avoid programming
|
||||
* a rate that is impossible for the hardware to handle
|
||||
*/
|
||||
*new_rate = _dpll_compute_new_rate(parent_rate, *m, n);
|
||||
if (*new_rate > target_rate) {
|
||||
(*m)--;
|
||||
*new_rate = 0;
|
||||
}
|
||||
|
||||
/* Guard against m underflow */
|
||||
if (*m < DPLL_MIN_MULTIPLIER) {
|
||||
*m = DPLL_MIN_MULTIPLIER;
|
||||
*new_rate = 0;
|
||||
r = DPLL_MULT_UNDERFLOW;
|
||||
}
|
||||
|
||||
if (*new_rate == 0)
|
||||
*new_rate = _dpll_compute_new_rate(parent_rate, *m, n);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Public functions */
|
||||
|
||||
void omap2_init_dpll_parent(struct clk *clk)
|
||||
{
|
||||
u32 v;
|
||||
struct dpll_data *dd;
|
||||
|
||||
dd = clk->dpll_data;
|
||||
if (!dd)
|
||||
return;
|
||||
|
||||
/* Return bypass rate if DPLL is bypassed */
|
||||
v = __raw_readl(dd->control_reg);
|
||||
v &= dd->enable_mask;
|
||||
v >>= __ffs(dd->enable_mask);
|
||||
|
||||
/* Reparent in case the dpll is in bypass */
|
||||
if (cpu_is_omap24xx()) {
|
||||
if (v == OMAP2XXX_EN_DPLL_LPBYPASS ||
|
||||
v == OMAP2XXX_EN_DPLL_FRBYPASS)
|
||||
clk_reparent(clk, dd->clk_bypass);
|
||||
} else if (cpu_is_omap34xx()) {
|
||||
if (v == OMAP3XXX_EN_DPLL_LPBYPASS ||
|
||||
v == OMAP3XXX_EN_DPLL_FRBYPASS)
|
||||
clk_reparent(clk, dd->clk_bypass);
|
||||
} else if (cpu_is_omap44xx()) {
|
||||
if (v == OMAP4XXX_EN_DPLL_LPBYPASS ||
|
||||
v == OMAP4XXX_EN_DPLL_FRBYPASS ||
|
||||
v == OMAP4XXX_EN_DPLL_MNBYPASS)
|
||||
clk_reparent(clk, dd->clk_bypass);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap2_get_dpll_rate - returns the current DPLL CLKOUT rate
|
||||
* @clk: struct clk * of a DPLL
|
||||
*
|
||||
* DPLLs can be locked or bypassed - basically, enabled or disabled.
|
||||
* When locked, the DPLL output depends on the M and N values. When
|
||||
* bypassed, on OMAP2xxx, the output rate is either the 32KiHz clock
|
||||
* or sys_clk. Bypass rates on OMAP3 depend on the DPLL: DPLLs 1 and
|
||||
* 2 are bypassed with dpll1_fclk and dpll2_fclk respectively
|
||||
* (generated by DPLL3), while DPLL 3, 4, and 5 bypass rates are sys_clk.
|
||||
* Returns the current DPLL CLKOUT rate (*not* CLKOUTX2) if the DPLL is
|
||||
* locked, or the appropriate bypass rate if the DPLL is bypassed, or 0
|
||||
* if the clock @clk is not a DPLL.
|
||||
*/
|
||||
u32 omap2_get_dpll_rate(struct clk *clk)
|
||||
{
|
||||
long long dpll_clk;
|
||||
u32 dpll_mult, dpll_div, v;
|
||||
struct dpll_data *dd;
|
||||
|
||||
dd = clk->dpll_data;
|
||||
if (!dd)
|
||||
return 0;
|
||||
|
||||
/* Return bypass rate if DPLL is bypassed */
|
||||
v = __raw_readl(dd->control_reg);
|
||||
v &= dd->enable_mask;
|
||||
v >>= __ffs(dd->enable_mask);
|
||||
|
||||
if (cpu_is_omap24xx()) {
|
||||
if (v == OMAP2XXX_EN_DPLL_LPBYPASS ||
|
||||
v == OMAP2XXX_EN_DPLL_FRBYPASS)
|
||||
return dd->clk_bypass->rate;
|
||||
} else if (cpu_is_omap34xx()) {
|
||||
if (v == OMAP3XXX_EN_DPLL_LPBYPASS ||
|
||||
v == OMAP3XXX_EN_DPLL_FRBYPASS)
|
||||
return dd->clk_bypass->rate;
|
||||
} else if (cpu_is_omap44xx()) {
|
||||
if (v == OMAP4XXX_EN_DPLL_LPBYPASS ||
|
||||
v == OMAP4XXX_EN_DPLL_FRBYPASS ||
|
||||
v == OMAP4XXX_EN_DPLL_MNBYPASS)
|
||||
return dd->clk_bypass->rate;
|
||||
}
|
||||
|
||||
v = __raw_readl(dd->mult_div1_reg);
|
||||
dpll_mult = v & dd->mult_mask;
|
||||
dpll_mult >>= __ffs(dd->mult_mask);
|
||||
dpll_div = v & dd->div1_mask;
|
||||
dpll_div >>= __ffs(dd->div1_mask);
|
||||
|
||||
dpll_clk = (long long)dd->clk_ref->rate * dpll_mult;
|
||||
do_div(dpll_clk, dpll_div + 1);
|
||||
|
||||
return dpll_clk;
|
||||
}
|
||||
|
||||
/* DPLL rate rounding code */
|
||||
|
||||
/**
|
||||
* omap2_dpll_set_rate_tolerance: set the error tolerance during rate rounding
|
||||
* @clk: struct clk * of the DPLL
|
||||
* @tolerance: maximum rate error tolerance
|
||||
*
|
||||
* Set the maximum DPLL rate error tolerance for the rate rounding
|
||||
* algorithm. The rate tolerance is an attempt to balance DPLL power
|
||||
* saving (the least divider value "n") vs. rate fidelity (the least
|
||||
* difference between the desired DPLL target rate and the rounded
|
||||
* rate out of the algorithm). So, increasing the tolerance is likely
|
||||
* to decrease DPLL power consumption and increase DPLL rate error.
|
||||
* Returns -EINVAL if provided a null clock ptr or a clk that is not a
|
||||
* DPLL; or 0 upon success.
|
||||
*/
|
||||
int omap2_dpll_set_rate_tolerance(struct clk *clk, unsigned int tolerance)
|
||||
{
|
||||
if (!clk || !clk->dpll_data)
|
||||
return -EINVAL;
|
||||
|
||||
clk->dpll_data->rate_tolerance = tolerance;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap2_dpll_round_rate - round a target rate for an OMAP DPLL
|
||||
* @clk: struct clk * for a DPLL
|
||||
* @target_rate: desired DPLL clock rate
|
||||
*
|
||||
* Given a DPLL, a desired target rate, and a rate tolerance, round
|
||||
* the target rate to a possible, programmable rate for this DPLL.
|
||||
* Rate tolerance is assumed to be set by the caller before this
|
||||
* function is called. Attempts to select the minimum possible n
|
||||
* within the tolerance to reduce power consumption. Stores the
|
||||
* computed (m, n) in the DPLL's dpll_data structure so set_rate()
|
||||
* will not need to call this (expensive) function again. Returns ~0
|
||||
* if the target rate cannot be rounded, either because the rate is
|
||||
* too low or because the rate tolerance is set too tightly; or the
|
||||
* rounded rate upon success.
|
||||
*/
|
||||
long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
|
||||
{
|
||||
int m, n, r, e, scaled_max_m;
|
||||
unsigned long scaled_rt_rp, new_rate;
|
||||
int min_e = -1, min_e_m = -1, min_e_n = -1;
|
||||
struct dpll_data *dd;
|
||||
|
||||
if (!clk || !clk->dpll_data)
|
||||
return ~0;
|
||||
|
||||
dd = clk->dpll_data;
|
||||
|
||||
pr_debug("clock: starting DPLL round_rate for clock %s, target rate "
|
||||
"%ld\n", clk->name, target_rate);
|
||||
|
||||
scaled_rt_rp = target_rate / (dd->clk_ref->rate / DPLL_SCALE_FACTOR);
|
||||
scaled_max_m = dd->max_multiplier * DPLL_SCALE_FACTOR;
|
||||
|
||||
dd->last_rounded_rate = 0;
|
||||
|
||||
for (n = dd->min_divider; n <= dd->max_divider; n++) {
|
||||
|
||||
/* Is the (input clk, divider) pair valid for the DPLL? */
|
||||
r = _dpll_test_fint(clk, n);
|
||||
if (r == DPLL_FINT_UNDERFLOW)
|
||||
break;
|
||||
else if (r == DPLL_FINT_INVALID)
|
||||
continue;
|
||||
|
||||
/* Compute the scaled DPLL multiplier, based on the divider */
|
||||
m = scaled_rt_rp * n;
|
||||
|
||||
/*
|
||||
* Since we're counting n up, a m overflow means we
|
||||
* can bail out completely (since as n increases in
|
||||
* the next iteration, there's no way that m can
|
||||
* increase beyond the current m)
|
||||
*/
|
||||
if (m > scaled_max_m)
|
||||
break;
|
||||
|
||||
r = _dpll_test_mult(&m, n, &new_rate, target_rate,
|
||||
dd->clk_ref->rate);
|
||||
|
||||
/* m can't be set low enough for this n - try with a larger n */
|
||||
if (r == DPLL_MULT_UNDERFLOW)
|
||||
continue;
|
||||
|
||||
e = target_rate - new_rate;
|
||||
pr_debug("clock: n = %d: m = %d: rate error is %d "
|
||||
"(new_rate = %ld)\n", n, m, e, new_rate);
|
||||
|
||||
if (min_e == -1 ||
|
||||
min_e >= (int)(abs(e) - dd->rate_tolerance)) {
|
||||
min_e = e;
|
||||
min_e_m = m;
|
||||
min_e_n = n;
|
||||
|
||||
pr_debug("clock: found new least error %d\n", min_e);
|
||||
|
||||
/* We found good settings -- bail out now */
|
||||
if (min_e <= dd->rate_tolerance)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (min_e < 0) {
|
||||
pr_debug("clock: error: target rate or tolerance too low\n");
|
||||
return ~0;
|
||||
}
|
||||
|
||||
dd->last_rounded_m = min_e_m;
|
||||
dd->last_rounded_n = min_e_n;
|
||||
dd->last_rounded_rate = _dpll_compute_new_rate(dd->clk_ref->rate,
|
||||
min_e_m, min_e_n);
|
||||
|
||||
pr_debug("clock: final least error: e = %d, m = %d, n = %d\n",
|
||||
min_e, min_e_m, min_e_n);
|
||||
pr_debug("clock: final rate: %ld (target rate: %ld)\n",
|
||||
dd->last_rounded_rate, target_rate);
|
||||
|
||||
return dd->last_rounded_rate;
|
||||
}
|
||||
|
|
@ -28,10 +28,7 @@
|
|||
#include <plat/clockdomain.h>
|
||||
#include <plat/cpu.h>
|
||||
#include <plat/prcm.h>
|
||||
#include <asm/div64.h>
|
||||
|
||||
#include <plat/sdrc.h>
|
||||
#include "sdrc.h"
|
||||
#include "clock.h"
|
||||
#include "prm.h"
|
||||
#include "prm-regbits-24xx.h"
|
||||
|
@ -39,81 +36,66 @@
|
|||
#include "cm-regbits-24xx.h"
|
||||
#include "cm-regbits-34xx.h"
|
||||
|
||||
/* DPLL rate rounding: minimum DPLL multiplier, divider values */
|
||||
#define DPLL_MIN_MULTIPLIER 1
|
||||
#define DPLL_MIN_DIVIDER 1
|
||||
|
||||
/* Possible error results from _dpll_test_mult */
|
||||
#define DPLL_MULT_UNDERFLOW -1
|
||||
|
||||
/*
|
||||
* Scale factor to mitigate roundoff errors in DPLL rate rounding.
|
||||
* The higher the scale factor, the greater the risk of arithmetic overflow,
|
||||
* but the closer the rounded rate to the target rate. DPLL_SCALE_FACTOR
|
||||
* must be a power of DPLL_SCALE_BASE.
|
||||
*/
|
||||
#define DPLL_SCALE_FACTOR 64
|
||||
#define DPLL_SCALE_BASE 2
|
||||
#define DPLL_ROUNDING_VAL ((DPLL_SCALE_BASE / 2) * \
|
||||
(DPLL_SCALE_FACTOR / DPLL_SCALE_BASE))
|
||||
|
||||
/* DPLL valid Fint frequency band limits - from 34xx TRM Section 4.7.6.2 */
|
||||
#define DPLL_FINT_BAND1_MIN 750000
|
||||
#define DPLL_FINT_BAND1_MAX 2100000
|
||||
#define DPLL_FINT_BAND2_MIN 7500000
|
||||
#define DPLL_FINT_BAND2_MAX 21000000
|
||||
|
||||
/* _dpll_test_fint() return codes */
|
||||
#define DPLL_FINT_UNDERFLOW -1
|
||||
#define DPLL_FINT_INVALID -2
|
||||
|
||||
u8 cpu_mask;
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* OMAP2/3/4 specific clock functions
|
||||
*-------------------------------------------------------------------------*/
|
||||
|
||||
void omap2_init_dpll_parent(struct clk *clk)
|
||||
{
|
||||
u32 v;
|
||||
struct dpll_data *dd;
|
||||
|
||||
dd = clk->dpll_data;
|
||||
if (!dd)
|
||||
return;
|
||||
|
||||
/* Return bypass rate if DPLL is bypassed */
|
||||
v = __raw_readl(dd->control_reg);
|
||||
v &= dd->enable_mask;
|
||||
v >>= __ffs(dd->enable_mask);
|
||||
|
||||
/* Reparent in case the dpll is in bypass */
|
||||
if (cpu_is_omap24xx()) {
|
||||
if (v == OMAP2XXX_EN_DPLL_LPBYPASS ||
|
||||
v == OMAP2XXX_EN_DPLL_FRBYPASS)
|
||||
clk_reparent(clk, dd->clk_bypass);
|
||||
} else if (cpu_is_omap34xx()) {
|
||||
if (v == OMAP3XXX_EN_DPLL_LPBYPASS ||
|
||||
v == OMAP3XXX_EN_DPLL_FRBYPASS)
|
||||
clk_reparent(clk, dd->clk_bypass);
|
||||
} else if (cpu_is_omap44xx()) {
|
||||
if (v == OMAP4XXX_EN_DPLL_LPBYPASS ||
|
||||
v == OMAP4XXX_EN_DPLL_FRBYPASS ||
|
||||
v == OMAP4XXX_EN_DPLL_MNBYPASS)
|
||||
clk_reparent(clk, dd->clk_bypass);
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* Private functions */
|
||||
|
||||
/**
|
||||
* _omap2xxx_clk_commit - commit clock parent/rate changes in hardware
|
||||
* _omap2_module_wait_ready - wait for an OMAP module to leave IDLE
|
||||
* @clk: struct clk * belonging to the module
|
||||
*
|
||||
* If the necessary clocks for the OMAP hardware IP block that
|
||||
* corresponds to clock @clk are enabled, then wait for the module to
|
||||
* indicate readiness (i.e., to leave IDLE). This code does not
|
||||
* belong in the clock code and will be moved in the medium term to
|
||||
* module-dependent code. No return value.
|
||||
*/
|
||||
static void _omap2_module_wait_ready(struct clk *clk)
|
||||
{
|
||||
void __iomem *companion_reg, *idlest_reg;
|
||||
u8 other_bit, idlest_bit;
|
||||
|
||||
/* Not all modules have multiple clocks that their IDLEST depends on */
|
||||
if (clk->ops->find_companion) {
|
||||
clk->ops->find_companion(clk, &companion_reg, &other_bit);
|
||||
if (!(__raw_readl(companion_reg) & (1 << other_bit)))
|
||||
return;
|
||||
}
|
||||
|
||||
clk->ops->find_idlest(clk, &idlest_reg, &idlest_bit);
|
||||
|
||||
omap2_cm_wait_idlest(idlest_reg, (1 << idlest_bit), clk->name);
|
||||
}
|
||||
|
||||
/* Enables clock without considering parent dependencies or use count
|
||||
* REVISIT: Maybe change this to use clk->enable like on omap1?
|
||||
*/
|
||||
static int _omap2_clk_enable(struct clk *clk)
|
||||
{
|
||||
return clk->ops->enable(clk);
|
||||
}
|
||||
|
||||
/* Disables clock without considering parent dependencies or use count */
|
||||
static void _omap2_clk_disable(struct clk *clk)
|
||||
{
|
||||
clk->ops->disable(clk);
|
||||
}
|
||||
|
||||
/* Public functions */
|
||||
|
||||
/**
|
||||
* omap2xxx_clk_commit - commit clock parent/rate changes in hardware
|
||||
* @clk: struct clk *
|
||||
*
|
||||
* If @clk has the DELAYED_APP flag set, meaning that parent/rate changes
|
||||
* don't take effect until the VALID_CONFIG bit is written, write the
|
||||
* VALID_CONFIG bit and wait for the write to complete. No return value.
|
||||
*/
|
||||
static void _omap2xxx_clk_commit(struct clk *clk)
|
||||
void omap2xxx_clk_commit(struct clk *clk)
|
||||
{
|
||||
if (!cpu_is_omap24xx())
|
||||
return;
|
||||
|
@ -127,52 +109,6 @@ static void _omap2xxx_clk_commit(struct clk *clk)
|
|||
prm_read_mod_reg(OMAP24XX_GR_MOD, OMAP2_PRCM_CLKCFG_CTRL_OFFSET);
|
||||
}
|
||||
|
||||
/*
|
||||
* _dpll_test_fint - test whether an Fint value is valid for the DPLL
|
||||
* @clk: DPLL struct clk to test
|
||||
* @n: divider value (N) to test
|
||||
*
|
||||
* Tests whether a particular divider @n will result in a valid DPLL
|
||||
* internal clock frequency Fint. See the 34xx TRM 4.7.6.2 "DPLL Jitter
|
||||
* Correction". Returns 0 if OK, -1 if the enclosing loop can terminate
|
||||
* (assuming that it is counting N upwards), or -2 if the enclosing loop
|
||||
* should skip to the next iteration (again assuming N is increasing).
|
||||
*/
|
||||
static int _dpll_test_fint(struct clk *clk, u8 n)
|
||||
{
|
||||
struct dpll_data *dd;
|
||||
long fint;
|
||||
int ret = 0;
|
||||
|
||||
dd = clk->dpll_data;
|
||||
|
||||
/* DPLL divider must result in a valid jitter correction val */
|
||||
fint = clk->parent->rate / (n + 1);
|
||||
if (fint < DPLL_FINT_BAND1_MIN) {
|
||||
|
||||
pr_debug("rejecting n=%d due to Fint failure, "
|
||||
"lowering max_divider\n", n);
|
||||
dd->max_divider = n;
|
||||
ret = DPLL_FINT_UNDERFLOW;
|
||||
|
||||
} else if (fint > DPLL_FINT_BAND1_MAX &&
|
||||
fint < DPLL_FINT_BAND2_MIN) {
|
||||
|
||||
pr_debug("rejecting n=%d due to Fint failure\n", n);
|
||||
ret = DPLL_FINT_INVALID;
|
||||
|
||||
} else if (fint > DPLL_FINT_BAND2_MAX) {
|
||||
|
||||
pr_debug("rejecting n=%d due to Fint failure, "
|
||||
"boosting min_divider\n", n);
|
||||
dd->min_divider = n;
|
||||
ret = DPLL_FINT_INVALID;
|
||||
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap2_init_clk_clkdm - look up a clockdomain name, store pointer in clk
|
||||
* @clk: OMAP clock struct ptr to use
|
||||
|
@ -181,7 +117,6 @@ static int _dpll_test_fint(struct clk *clk, u8 n)
|
|||
* clockdomain pointer, and save it into the struct clk. Intended to be
|
||||
* called during clk_register(). No return value.
|
||||
*/
|
||||
#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once clkdm f/w is in place */
|
||||
void omap2_init_clk_clkdm(struct clk *clk)
|
||||
{
|
||||
struct clockdomain *clkdm;
|
||||
|
@ -199,117 +134,6 @@ void omap2_init_clk_clkdm(struct clk *clk)
|
|||
"clkdm %s\n", clk->name, clk->clkdm_name);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* omap2_init_clksel_parent - set a clksel clk's parent field from the hardware
|
||||
* @clk: OMAP clock struct ptr to use
|
||||
*
|
||||
* Given a pointer to a source-selectable struct clk, read the hardware
|
||||
* register and determine what its parent is currently set to. Update the
|
||||
* clk->parent field with the appropriate clk ptr.
|
||||
*/
|
||||
void omap2_init_clksel_parent(struct clk *clk)
|
||||
{
|
||||
const struct clksel *clks;
|
||||
const struct clksel_rate *clkr;
|
||||
u32 r, found = 0;
|
||||
|
||||
if (!clk->clksel)
|
||||
return;
|
||||
|
||||
r = __raw_readl(clk->clksel_reg) & clk->clksel_mask;
|
||||
r >>= __ffs(clk->clksel_mask);
|
||||
|
||||
for (clks = clk->clksel; clks->parent && !found; clks++) {
|
||||
for (clkr = clks->rates; clkr->div && !found; clkr++) {
|
||||
if ((clkr->flags & cpu_mask) && (clkr->val == r)) {
|
||||
if (clk->parent != clks->parent) {
|
||||
pr_debug("clock: inited %s parent "
|
||||
"to %s (was %s)\n",
|
||||
clk->name, clks->parent->name,
|
||||
((clk->parent) ?
|
||||
clk->parent->name : "NULL"));
|
||||
clk_reparent(clk, clks->parent);
|
||||
};
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
printk(KERN_ERR "clock: init parent: could not find "
|
||||
"regval %0x for clock %s\n", r, clk->name);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap2_get_dpll_rate - returns the current DPLL CLKOUT rate
|
||||
* @clk: struct clk * of a DPLL
|
||||
*
|
||||
* DPLLs can be locked or bypassed - basically, enabled or disabled.
|
||||
* When locked, the DPLL output depends on the M and N values. When
|
||||
* bypassed, on OMAP2xxx, the output rate is either the 32KiHz clock
|
||||
* or sys_clk. Bypass rates on OMAP3 depend on the DPLL: DPLLs 1 and
|
||||
* 2 are bypassed with dpll1_fclk and dpll2_fclk respectively
|
||||
* (generated by DPLL3), while DPLL 3, 4, and 5 bypass rates are sys_clk.
|
||||
* Returns the current DPLL CLKOUT rate (*not* CLKOUTX2) if the DPLL is
|
||||
* locked, or the appropriate bypass rate if the DPLL is bypassed, or 0
|
||||
* if the clock @clk is not a DPLL.
|
||||
*/
|
||||
u32 omap2_get_dpll_rate(struct clk *clk)
|
||||
{
|
||||
long long dpll_clk;
|
||||
u32 dpll_mult, dpll_div, v;
|
||||
struct dpll_data *dd;
|
||||
|
||||
dd = clk->dpll_data;
|
||||
if (!dd)
|
||||
return 0;
|
||||
|
||||
/* Return bypass rate if DPLL is bypassed */
|
||||
v = __raw_readl(dd->control_reg);
|
||||
v &= dd->enable_mask;
|
||||
v >>= __ffs(dd->enable_mask);
|
||||
|
||||
if (cpu_is_omap24xx()) {
|
||||
if (v == OMAP2XXX_EN_DPLL_LPBYPASS ||
|
||||
v == OMAP2XXX_EN_DPLL_FRBYPASS)
|
||||
return dd->clk_bypass->rate;
|
||||
} else if (cpu_is_omap34xx()) {
|
||||
if (v == OMAP3XXX_EN_DPLL_LPBYPASS ||
|
||||
v == OMAP3XXX_EN_DPLL_FRBYPASS)
|
||||
return dd->clk_bypass->rate;
|
||||
} else if (cpu_is_omap44xx()) {
|
||||
if (v == OMAP4XXX_EN_DPLL_LPBYPASS ||
|
||||
v == OMAP4XXX_EN_DPLL_FRBYPASS ||
|
||||
v == OMAP4XXX_EN_DPLL_MNBYPASS)
|
||||
return dd->clk_bypass->rate;
|
||||
}
|
||||
|
||||
v = __raw_readl(dd->mult_div1_reg);
|
||||
dpll_mult = v & dd->mult_mask;
|
||||
dpll_mult >>= __ffs(dd->mult_mask);
|
||||
dpll_div = v & dd->div1_mask;
|
||||
dpll_div >>= __ffs(dd->div1_mask);
|
||||
|
||||
dpll_clk = (long long)dd->clk_ref->rate * dpll_mult;
|
||||
do_div(dpll_clk, dpll_div + 1);
|
||||
|
||||
return dpll_clk;
|
||||
}
|
||||
|
||||
/*
|
||||
* Used for clocks that have the same value as the parent clock,
|
||||
* divided by some factor
|
||||
*/
|
||||
unsigned long omap2_fixed_divisor_recalc(struct clk *clk)
|
||||
{
|
||||
WARN_ON(!clk->fixed_div);
|
||||
|
||||
return clk->parent->rate / clk->fixed_div;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap2_clk_dflt_find_companion - find companion clock to @clk
|
||||
|
@ -370,33 +194,6 @@ void omap2_clk_dflt_find_idlest(struct clk *clk, void __iomem **idlest_reg,
|
|||
*idlest_bit = clk->enable_bit;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap2_module_wait_ready - wait for an OMAP module to leave IDLE
|
||||
* @clk: struct clk * belonging to the module
|
||||
*
|
||||
* If the necessary clocks for the OMAP hardware IP block that
|
||||
* corresponds to clock @clk are enabled, then wait for the module to
|
||||
* indicate readiness (i.e., to leave IDLE). This code does not
|
||||
* belong in the clock code and will be moved in the medium term to
|
||||
* module-dependent code. No return value.
|
||||
*/
|
||||
static void omap2_module_wait_ready(struct clk *clk)
|
||||
{
|
||||
void __iomem *companion_reg, *idlest_reg;
|
||||
u8 other_bit, idlest_bit;
|
||||
|
||||
/* Not all modules have multiple clocks that their IDLEST depends on */
|
||||
if (clk->ops->find_companion) {
|
||||
clk->ops->find_companion(clk, &companion_reg, &other_bit);
|
||||
if (!(__raw_readl(companion_reg) & (1 << other_bit)))
|
||||
return;
|
||||
}
|
||||
|
||||
clk->ops->find_idlest(clk, &idlest_reg, &idlest_bit);
|
||||
|
||||
omap2_cm_wait_idlest(idlest_reg, (1 << idlest_bit), clk->name);
|
||||
}
|
||||
|
||||
int omap2_dflt_clk_enable(struct clk *clk)
|
||||
{
|
||||
u32 v;
|
||||
|
@ -416,7 +213,7 @@ int omap2_dflt_clk_enable(struct clk *clk)
|
|||
v = __raw_readl(clk->enable_reg); /* OCP barrier */
|
||||
|
||||
if (clk->ops->find_idlest)
|
||||
omap2_module_wait_ready(clk);
|
||||
_omap2_module_wait_ready(clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -456,30 +253,14 @@ const struct clkops clkops_omap2_dflt = {
|
|||
.disable = omap2_dflt_clk_disable,
|
||||
};
|
||||
|
||||
/* Enables clock without considering parent dependencies or use count
|
||||
* REVISIT: Maybe change this to use clk->enable like on omap1?
|
||||
*/
|
||||
static int _omap2_clk_enable(struct clk *clk)
|
||||
{
|
||||
return clk->ops->enable(clk);
|
||||
}
|
||||
|
||||
/* Disables clock without considering parent dependencies or use count */
|
||||
static void _omap2_clk_disable(struct clk *clk)
|
||||
{
|
||||
clk->ops->disable(clk);
|
||||
}
|
||||
|
||||
void omap2_clk_disable(struct clk *clk)
|
||||
{
|
||||
if (clk->usecount > 0 && !(--clk->usecount)) {
|
||||
_omap2_clk_disable(clk);
|
||||
if (clk->parent)
|
||||
omap2_clk_disable(clk->parent);
|
||||
#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once clkdm f/w is in place */
|
||||
if (clk->clkdm)
|
||||
omap2_clkdm_clk_disable(clk->clkdm, clk);
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -489,10 +270,8 @@ int omap2_clk_enable(struct clk *clk)
|
|||
int ret = 0;
|
||||
|
||||
if (clk->usecount++ == 0) {
|
||||
#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once clkdm f/w is in place */
|
||||
if (clk->clkdm)
|
||||
omap2_clkdm_clk_enable(clk->clkdm, clk);
|
||||
#endif
|
||||
|
||||
if (clk->parent) {
|
||||
ret = omap2_clk_enable(clk->parent);
|
||||
|
@ -511,282 +290,12 @@ int omap2_clk_enable(struct clk *clk)
|
|||
return ret;
|
||||
|
||||
err:
|
||||
#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once clkdm f/w is in place */
|
||||
if (clk->clkdm)
|
||||
omap2_clkdm_clk_disable(clk->clkdm, clk);
|
||||
#endif
|
||||
clk->usecount--;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Used for clocks that are part of CLKSEL_xyz governed clocks.
|
||||
* REVISIT: Maybe change to use clk->enable() functions like on omap1?
|
||||
*/
|
||||
unsigned long omap2_clksel_recalc(struct clk *clk)
|
||||
{
|
||||
unsigned long rate;
|
||||
u32 div = 0;
|
||||
|
||||
pr_debug("clock: recalc'ing clksel clk %s\n", clk->name);
|
||||
|
||||
div = omap2_clksel_get_divisor(clk);
|
||||
if (div == 0)
|
||||
return clk->rate;
|
||||
|
||||
rate = clk->parent->rate / div;
|
||||
|
||||
pr_debug("clock: new clock rate is %ld (div %d)\n", rate, div);
|
||||
|
||||
return rate;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap2_get_clksel_by_parent - return clksel struct for a given clk & parent
|
||||
* @clk: OMAP struct clk ptr to inspect
|
||||
* @src_clk: OMAP struct clk ptr of the parent clk to search for
|
||||
*
|
||||
* Scan the struct clksel array associated with the clock to find
|
||||
* the element associated with the supplied parent clock address.
|
||||
* Returns a pointer to the struct clksel on success or NULL on error.
|
||||
*/
|
||||
static const struct clksel *omap2_get_clksel_by_parent(struct clk *clk,
|
||||
struct clk *src_clk)
|
||||
{
|
||||
const struct clksel *clks;
|
||||
|
||||
if (!clk->clksel)
|
||||
return NULL;
|
||||
|
||||
for (clks = clk->clksel; clks->parent; clks++) {
|
||||
if (clks->parent == src_clk)
|
||||
break; /* Found the requested parent */
|
||||
}
|
||||
|
||||
if (!clks->parent) {
|
||||
printk(KERN_ERR "clock: Could not find parent clock %s in "
|
||||
"clksel array of clock %s\n", src_clk->name,
|
||||
clk->name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return clks;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap2_clksel_round_rate_div - find divisor for the given clock and rate
|
||||
* @clk: OMAP struct clk to use
|
||||
* @target_rate: desired clock rate
|
||||
* @new_div: ptr to where we should store the divisor
|
||||
*
|
||||
* Finds 'best' divider value in an array based on the source and target
|
||||
* rates. The divider array must be sorted with smallest divider first.
|
||||
* Note that this will not work for clocks which are part of CONFIG_PARTICIPANT,
|
||||
* they are only settable as part of virtual_prcm set.
|
||||
*
|
||||
* Returns the rounded clock rate or returns 0xffffffff on error.
|
||||
*/
|
||||
u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
|
||||
u32 *new_div)
|
||||
{
|
||||
unsigned long test_rate;
|
||||
const struct clksel *clks;
|
||||
const struct clksel_rate *clkr;
|
||||
u32 last_div = 0;
|
||||
|
||||
pr_debug("clock: clksel_round_rate_div: %s target_rate %ld\n",
|
||||
clk->name, target_rate);
|
||||
|
||||
*new_div = 1;
|
||||
|
||||
clks = omap2_get_clksel_by_parent(clk, clk->parent);
|
||||
if (!clks)
|
||||
return ~0;
|
||||
|
||||
for (clkr = clks->rates; clkr->div; clkr++) {
|
||||
if (!(clkr->flags & cpu_mask))
|
||||
continue;
|
||||
|
||||
/* Sanity check */
|
||||
if (clkr->div <= last_div)
|
||||
pr_err("clock: clksel_rate table not sorted "
|
||||
"for clock %s", clk->name);
|
||||
|
||||
last_div = clkr->div;
|
||||
|
||||
test_rate = clk->parent->rate / clkr->div;
|
||||
|
||||
if (test_rate <= target_rate)
|
||||
break; /* found it */
|
||||
}
|
||||
|
||||
if (!clkr->div) {
|
||||
pr_err("clock: Could not find divisor for target "
|
||||
"rate %ld for clock %s parent %s\n", target_rate,
|
||||
clk->name, clk->parent->name);
|
||||
return ~0;
|
||||
}
|
||||
|
||||
*new_div = clkr->div;
|
||||
|
||||
pr_debug("clock: new_div = %d, new_rate = %ld\n", *new_div,
|
||||
(clk->parent->rate / clkr->div));
|
||||
|
||||
return (clk->parent->rate / clkr->div);
|
||||
}
|
||||
|
||||
/**
|
||||
* omap2_clksel_round_rate - find rounded rate for the given clock and rate
|
||||
* @clk: OMAP struct clk to use
|
||||
* @target_rate: desired clock rate
|
||||
*
|
||||
* Compatibility wrapper for OMAP clock framework
|
||||
* Finds best target rate based on the source clock and possible dividers.
|
||||
* rates. The divider array must be sorted with smallest divider first.
|
||||
* Note that this will not work for clocks which are part of CONFIG_PARTICIPANT,
|
||||
* they are only settable as part of virtual_prcm set.
|
||||
*
|
||||
* Returns the rounded clock rate or returns 0xffffffff on error.
|
||||
*/
|
||||
long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate)
|
||||
{
|
||||
u32 new_div;
|
||||
|
||||
return omap2_clksel_round_rate_div(clk, target_rate, &new_div);
|
||||
}
|
||||
|
||||
|
||||
/* Given a clock and a rate apply a clock specific rounding function */
|
||||
long omap2_clk_round_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
if (clk->round_rate)
|
||||
return clk->round_rate(clk, rate);
|
||||
|
||||
if (clk->flags & RATE_FIXED)
|
||||
printk(KERN_ERR "clock: generic omap2_clk_round_rate called "
|
||||
"on fixed-rate clock %s\n", clk->name);
|
||||
|
||||
return clk->rate;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap2_clksel_to_divisor() - turn clksel field value into integer divider
|
||||
* @clk: OMAP struct clk to use
|
||||
* @field_val: register field value to find
|
||||
*
|
||||
* Given a struct clk of a rate-selectable clksel clock, and a register field
|
||||
* value to search for, find the corresponding clock divisor. The register
|
||||
* field value should be pre-masked and shifted down so the LSB is at bit 0
|
||||
* before calling. Returns 0 on error
|
||||
*/
|
||||
u32 omap2_clksel_to_divisor(struct clk *clk, u32 field_val)
|
||||
{
|
||||
const struct clksel *clks;
|
||||
const struct clksel_rate *clkr;
|
||||
|
||||
clks = omap2_get_clksel_by_parent(clk, clk->parent);
|
||||
if (!clks)
|
||||
return 0;
|
||||
|
||||
for (clkr = clks->rates; clkr->div; clkr++) {
|
||||
if ((clkr->flags & cpu_mask) && (clkr->val == field_val))
|
||||
break;
|
||||
}
|
||||
|
||||
if (!clkr->div) {
|
||||
printk(KERN_ERR "clock: Could not find fieldval %d for "
|
||||
"clock %s parent %s\n", field_val, clk->name,
|
||||
clk->parent->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return clkr->div;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap2_divisor_to_clksel() - turn clksel integer divisor into a field value
|
||||
* @clk: OMAP struct clk to use
|
||||
* @div: integer divisor to search for
|
||||
*
|
||||
* Given a struct clk of a rate-selectable clksel clock, and a clock divisor,
|
||||
* find the corresponding register field value. The return register value is
|
||||
* the value before left-shifting. Returns ~0 on error
|
||||
*/
|
||||
u32 omap2_divisor_to_clksel(struct clk *clk, u32 div)
|
||||
{
|
||||
const struct clksel *clks;
|
||||
const struct clksel_rate *clkr;
|
||||
|
||||
/* should never happen */
|
||||
WARN_ON(div == 0);
|
||||
|
||||
clks = omap2_get_clksel_by_parent(clk, clk->parent);
|
||||
if (!clks)
|
||||
return ~0;
|
||||
|
||||
for (clkr = clks->rates; clkr->div; clkr++) {
|
||||
if ((clkr->flags & cpu_mask) && (clkr->div == div))
|
||||
break;
|
||||
}
|
||||
|
||||
if (!clkr->div) {
|
||||
printk(KERN_ERR "clock: Could not find divisor %d for "
|
||||
"clock %s parent %s\n", div, clk->name,
|
||||
clk->parent->name);
|
||||
return ~0;
|
||||
}
|
||||
|
||||
return clkr->val;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap2_clksel_get_divisor - get current divider applied to parent clock.
|
||||
* @clk: OMAP struct clk to use.
|
||||
*
|
||||
* Returns the integer divisor upon success or 0 on error.
|
||||
*/
|
||||
u32 omap2_clksel_get_divisor(struct clk *clk)
|
||||
{
|
||||
u32 v;
|
||||
|
||||
if (!clk->clksel_mask)
|
||||
return 0;
|
||||
|
||||
v = __raw_readl(clk->clksel_reg) & clk->clksel_mask;
|
||||
v >>= __ffs(clk->clksel_mask);
|
||||
|
||||
return omap2_clksel_to_divisor(clk, v);
|
||||
}
|
||||
|
||||
int omap2_clksel_set_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
u32 v, field_val, validrate, new_div = 0;
|
||||
|
||||
if (!clk->clksel_mask)
|
||||
return -EINVAL;
|
||||
|
||||
validrate = omap2_clksel_round_rate_div(clk, rate, &new_div);
|
||||
if (validrate != rate)
|
||||
return -EINVAL;
|
||||
|
||||
field_val = omap2_divisor_to_clksel(clk, new_div);
|
||||
if (field_val == ~0)
|
||||
return -EINVAL;
|
||||
|
||||
v = __raw_readl(clk->clksel_reg);
|
||||
v &= ~clk->clksel_mask;
|
||||
v |= field_val << __ffs(clk->clksel_mask);
|
||||
__raw_writel(v, clk->clksel_reg);
|
||||
v = __raw_readl(clk->clksel_reg); /* OCP barrier */
|
||||
|
||||
clk->rate = clk->parent->rate / new_div;
|
||||
|
||||
_omap2xxx_clk_commit(clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Set the clock rate for a clock source */
|
||||
int omap2_clk_set_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
|
@ -806,265 +315,15 @@ int omap2_clk_set_rate(struct clk *clk, unsigned long rate)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Converts encoded control register address into a full address
|
||||
* On error, the return value (parent_div) will be 0.
|
||||
*/
|
||||
static u32 _omap2_clksel_get_src_field(struct clk *src_clk, struct clk *clk,
|
||||
u32 *field_val)
|
||||
{
|
||||
const struct clksel *clks;
|
||||
const struct clksel_rate *clkr;
|
||||
|
||||
clks = omap2_get_clksel_by_parent(clk, src_clk);
|
||||
if (!clks)
|
||||
return 0;
|
||||
|
||||
for (clkr = clks->rates; clkr->div; clkr++) {
|
||||
if (clkr->flags & cpu_mask && clkr->flags & DEFAULT_RATE)
|
||||
break; /* Found the default rate for this platform */
|
||||
}
|
||||
|
||||
if (!clkr->div) {
|
||||
printk(KERN_ERR "clock: Could not find default rate for "
|
||||
"clock %s parent %s\n", clk->name,
|
||||
src_clk->parent->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Should never happen. Add a clksel mask to the struct clk. */
|
||||
WARN_ON(clk->clksel_mask == 0);
|
||||
|
||||
*field_val = clkr->val;
|
||||
|
||||
return clkr->div;
|
||||
}
|
||||
|
||||
int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
|
||||
{
|
||||
u32 field_val, v, parent_div;
|
||||
|
||||
if (clk->flags & CONFIG_PARTICIPANT)
|
||||
return -EINVAL;
|
||||
|
||||
if (!clk->clksel)
|
||||
return -EINVAL;
|
||||
|
||||
parent_div = _omap2_clksel_get_src_field(new_parent, clk, &field_val);
|
||||
if (!parent_div)
|
||||
return -EINVAL;
|
||||
|
||||
/* Set new source value (previous dividers if any in effect) */
|
||||
v = __raw_readl(clk->clksel_reg);
|
||||
v &= ~clk->clksel_mask;
|
||||
v |= field_val << __ffs(clk->clksel_mask);
|
||||
__raw_writel(v, clk->clksel_reg);
|
||||
v = __raw_readl(clk->clksel_reg); /* OCP barrier */
|
||||
|
||||
_omap2xxx_clk_commit(clk);
|
||||
|
||||
clk_reparent(clk, new_parent);
|
||||
|
||||
/* CLKSEL clocks follow their parents' rates, divided by a divisor */
|
||||
clk->rate = new_parent->rate;
|
||||
|
||||
if (parent_div > 0)
|
||||
clk->rate /= parent_div;
|
||||
|
||||
pr_debug("clock: set parent of %s to %s (new rate %ld)\n",
|
||||
clk->name, clk->parent->name, clk->rate);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* DPLL rate rounding code */
|
||||
|
||||
/**
|
||||
* omap2_dpll_set_rate_tolerance: set the error tolerance during rate rounding
|
||||
* @clk: struct clk * of the DPLL
|
||||
* @tolerance: maximum rate error tolerance
|
||||
*
|
||||
* Set the maximum DPLL rate error tolerance for the rate rounding
|
||||
* algorithm. The rate tolerance is an attempt to balance DPLL power
|
||||
* saving (the least divider value "n") vs. rate fidelity (the least
|
||||
* difference between the desired DPLL target rate and the rounded
|
||||
* rate out of the algorithm). So, increasing the tolerance is likely
|
||||
* to decrease DPLL power consumption and increase DPLL rate error.
|
||||
* Returns -EINVAL if provided a null clock ptr or a clk that is not a
|
||||
* DPLL; or 0 upon success.
|
||||
*/
|
||||
int omap2_dpll_set_rate_tolerance(struct clk *clk, unsigned int tolerance)
|
||||
{
|
||||
if (!clk || !clk->dpll_data)
|
||||
return -EINVAL;
|
||||
|
||||
clk->dpll_data->rate_tolerance = tolerance;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned long _dpll_compute_new_rate(unsigned long parent_rate,
|
||||
unsigned int m, unsigned int n)
|
||||
{
|
||||
unsigned long long num;
|
||||
|
||||
num = (unsigned long long)parent_rate * m;
|
||||
do_div(num, n);
|
||||
return num;
|
||||
}
|
||||
|
||||
/*
|
||||
* _dpll_test_mult - test a DPLL multiplier value
|
||||
* @m: pointer to the DPLL m (multiplier) value under test
|
||||
* @n: current DPLL n (divider) value under test
|
||||
* @new_rate: pointer to storage for the resulting rounded rate
|
||||
* @target_rate: the desired DPLL rate
|
||||
* @parent_rate: the DPLL's parent clock rate
|
||||
*
|
||||
* This code tests a DPLL multiplier value, ensuring that the
|
||||
* resulting rate will not be higher than the target_rate, and that
|
||||
* the multiplier value itself is valid for the DPLL. Initially, the
|
||||
* integer pointed to by the m argument should be prescaled by
|
||||
* multiplying by DPLL_SCALE_FACTOR. The code will replace this with
|
||||
* a non-scaled m upon return. This non-scaled m will result in a
|
||||
* new_rate as close as possible to target_rate (but not greater than
|
||||
* target_rate) given the current (parent_rate, n, prescaled m)
|
||||
* triple. Returns DPLL_MULT_UNDERFLOW in the event that the
|
||||
* non-scaled m attempted to underflow, which can allow the calling
|
||||
* function to bail out early; or 0 upon success.
|
||||
*/
|
||||
static int _dpll_test_mult(int *m, int n, unsigned long *new_rate,
|
||||
unsigned long target_rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
int r = 0, carry = 0;
|
||||
|
||||
/* Unscale m and round if necessary */
|
||||
if (*m % DPLL_SCALE_FACTOR >= DPLL_ROUNDING_VAL)
|
||||
carry = 1;
|
||||
*m = (*m / DPLL_SCALE_FACTOR) + carry;
|
||||
|
||||
/*
|
||||
* The new rate must be <= the target rate to avoid programming
|
||||
* a rate that is impossible for the hardware to handle
|
||||
*/
|
||||
*new_rate = _dpll_compute_new_rate(parent_rate, *m, n);
|
||||
if (*new_rate > target_rate) {
|
||||
(*m)--;
|
||||
*new_rate = 0;
|
||||
}
|
||||
|
||||
/* Guard against m underflow */
|
||||
if (*m < DPLL_MIN_MULTIPLIER) {
|
||||
*m = DPLL_MIN_MULTIPLIER;
|
||||
*new_rate = 0;
|
||||
r = DPLL_MULT_UNDERFLOW;
|
||||
}
|
||||
|
||||
if (*new_rate == 0)
|
||||
*new_rate = _dpll_compute_new_rate(parent_rate, *m, n);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap2_dpll_round_rate - round a target rate for an OMAP DPLL
|
||||
* @clk: struct clk * for a DPLL
|
||||
* @target_rate: desired DPLL clock rate
|
||||
*
|
||||
* Given a DPLL, a desired target rate, and a rate tolerance, round
|
||||
* the target rate to a possible, programmable rate for this DPLL.
|
||||
* Rate tolerance is assumed to be set by the caller before this
|
||||
* function is called. Attempts to select the minimum possible n
|
||||
* within the tolerance to reduce power consumption. Stores the
|
||||
* computed (m, n) in the DPLL's dpll_data structure so set_rate()
|
||||
* will not need to call this (expensive) function again. Returns ~0
|
||||
* if the target rate cannot be rounded, either because the rate is
|
||||
* too low or because the rate tolerance is set too tightly; or the
|
||||
* rounded rate upon success.
|
||||
*/
|
||||
long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
|
||||
{
|
||||
int m, n, r, e, scaled_max_m;
|
||||
unsigned long scaled_rt_rp, new_rate;
|
||||
int min_e = -1, min_e_m = -1, min_e_n = -1;
|
||||
struct dpll_data *dd;
|
||||
|
||||
if (!clk || !clk->dpll_data)
|
||||
return ~0;
|
||||
|
||||
dd = clk->dpll_data;
|
||||
|
||||
pr_debug("clock: starting DPLL round_rate for clock %s, target rate "
|
||||
"%ld\n", clk->name, target_rate);
|
||||
|
||||
scaled_rt_rp = target_rate / (dd->clk_ref->rate / DPLL_SCALE_FACTOR);
|
||||
scaled_max_m = dd->max_multiplier * DPLL_SCALE_FACTOR;
|
||||
|
||||
dd->last_rounded_rate = 0;
|
||||
|
||||
for (n = dd->min_divider; n <= dd->max_divider; n++) {
|
||||
|
||||
/* Is the (input clk, divider) pair valid for the DPLL? */
|
||||
r = _dpll_test_fint(clk, n);
|
||||
if (r == DPLL_FINT_UNDERFLOW)
|
||||
break;
|
||||
else if (r == DPLL_FINT_INVALID)
|
||||
continue;
|
||||
|
||||
/* Compute the scaled DPLL multiplier, based on the divider */
|
||||
m = scaled_rt_rp * n;
|
||||
|
||||
/*
|
||||
* Since we're counting n up, a m overflow means we
|
||||
* can bail out completely (since as n increases in
|
||||
* the next iteration, there's no way that m can
|
||||
* increase beyond the current m)
|
||||
*/
|
||||
if (m > scaled_max_m)
|
||||
break;
|
||||
|
||||
r = _dpll_test_mult(&m, n, &new_rate, target_rate,
|
||||
dd->clk_ref->rate);
|
||||
|
||||
/* m can't be set low enough for this n - try with a larger n */
|
||||
if (r == DPLL_MULT_UNDERFLOW)
|
||||
continue;
|
||||
|
||||
e = target_rate - new_rate;
|
||||
pr_debug("clock: n = %d: m = %d: rate error is %d "
|
||||
"(new_rate = %ld)\n", n, m, e, new_rate);
|
||||
|
||||
if (min_e == -1 ||
|
||||
min_e >= (int)(abs(e) - dd->rate_tolerance)) {
|
||||
min_e = e;
|
||||
min_e_m = m;
|
||||
min_e_n = n;
|
||||
|
||||
pr_debug("clock: found new least error %d\n", min_e);
|
||||
|
||||
/* We found good settings -- bail out now */
|
||||
if (min_e <= dd->rate_tolerance)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (min_e < 0) {
|
||||
pr_debug("clock: error: target rate or tolerance too low\n");
|
||||
return ~0;
|
||||
}
|
||||
|
||||
dd->last_rounded_m = min_e_m;
|
||||
dd->last_rounded_n = min_e_n;
|
||||
dd->last_rounded_rate = _dpll_compute_new_rate(dd->clk_ref->rate,
|
||||
min_e_m, min_e_n);
|
||||
|
||||
pr_debug("clock: final least error: e = %d, m = %d, n = %d\n",
|
||||
min_e, min_e_m, min_e_n);
|
||||
pr_debug("clock: final rate: %ld (target rate: %ld)\n",
|
||||
dd->last_rounded_rate, target_rate);
|
||||
|
||||
return dd->last_rounded_rate;
|
||||
return omap2_clksel_set_parent(clk, new_parent);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
|
@ -1092,3 +351,20 @@ void omap2_clk_disable_unused(struct clk *clk)
|
|||
pwrdm_clkdm_state_switch(clk->clkdm);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Common data */
|
||||
|
||||
struct clk_functions omap2_clk_functions = {
|
||||
.clk_enable = omap2_clk_enable,
|
||||
.clk_disable = omap2_clk_disable,
|
||||
.clk_round_rate = omap2_clk_round_rate,
|
||||
.clk_set_rate = omap2_clk_set_rate,
|
||||
.clk_set_parent = omap2_clk_set_parent,
|
||||
.clk_disable_unused = omap2_clk_disable_unused,
|
||||
#ifdef CONFIG_CPU_FREQ
|
||||
/* These will be removed when the OPP code is integrated */
|
||||
.clk_init_cpufreq_table = omap2_clk_init_cpufreq_table,
|
||||
.clk_exit_cpufreq_table = omap2_clk_exit_cpufreq_table,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -47,7 +47,6 @@
|
|||
#define DPLL_LOW_POWER_BYPASS 0x5
|
||||
#define DPLL_LOCKED 0x7
|
||||
|
||||
int omap2_clk_init(void);
|
||||
int omap2_clk_enable(struct clk *clk);
|
||||
void omap2_clk_disable(struct clk *clk);
|
||||
long omap2_clk_round_rate(struct clk *clk, unsigned long rate);
|
||||
|
@ -78,19 +77,19 @@ u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
|
|||
u32 *new_div);
|
||||
u32 omap2_clksel_to_divisor(struct clk *clk, u32 field_val);
|
||||
u32 omap2_divisor_to_clksel(struct clk *clk, u32 div);
|
||||
unsigned long omap2_fixed_divisor_recalc(struct clk *clk);
|
||||
long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate);
|
||||
int omap2_clksel_set_rate(struct clk *clk, unsigned long rate);
|
||||
int omap2_clksel_set_parent(struct clk *clk, struct clk *new_parent);
|
||||
u32 omap2_get_dpll_rate(struct clk *clk);
|
||||
void omap2_init_dpll_parent(struct clk *clk);
|
||||
int omap2_wait_clock_ready(void __iomem *reg, u32 cval, const char *name);
|
||||
void omap2_clk_prepare_for_reboot(void);
|
||||
int omap2_dflt_clk_enable(struct clk *clk);
|
||||
void omap2_dflt_clk_disable(struct clk *clk);
|
||||
void omap2_clk_dflt_find_companion(struct clk *clk, void __iomem **other_reg,
|
||||
u8 *other_bit);
|
||||
void omap2_clk_dflt_find_idlest(struct clk *clk, void __iomem **idlest_reg,
|
||||
u8 *idlest_bit);
|
||||
void omap2xxx_clk_commit(struct clk *clk);
|
||||
|
||||
extern u8 cpu_mask;
|
||||
|
||||
|
@ -104,5 +103,12 @@ extern const struct clksel_rate gpt_32k_rates[];
|
|||
extern const struct clksel_rate gpt_sys_rates[];
|
||||
extern const struct clksel_rate gfx_l3_rates[];
|
||||
|
||||
#if defined(CONFIG_ARCH_OMAP24XX) && defined(CONFIG_CPU_FREQ)
|
||||
extern void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table);
|
||||
extern void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table);
|
||||
#else
|
||||
#define omap2_clk_init_cpufreq_table 0
|
||||
#define omap2_clk_exit_cpufreq_table 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
/*
|
||||
* linux/arch/arm/mach-omap2/clock.c
|
||||
* clock2xxx.c - OMAP2xxx-specific clock integration code
|
||||
*
|
||||
* Copyright (C) 2005-2008 Texas Instruments, Inc.
|
||||
* Copyright (C) 2004-2008 Nokia Corporation
|
||||
* Copyright (C) 2005-2008 Texas Instruments, Inc.
|
||||
* Copyright (C) 2004-2010 Nokia Corporation
|
||||
*
|
||||
* Contacts:
|
||||
* Richard Woodruff <r-woodruff2@ti.com>
|
||||
* Paul Walmsley
|
||||
* Contacts:
|
||||
* Richard Woodruff <r-woodruff2@ti.com>
|
||||
* Paul Walmsley
|
||||
*
|
||||
* Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
|
||||
* Gordon McNutt and RidgeRun, Inc.
|
||||
* Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
|
||||
* Gordon McNutt and RidgeRun, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
|
@ -17,55 +17,25 @@
|
|||
*/
|
||||
#undef DEBUG
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/bitops.h>
|
||||
|
||||
#include <plat/clock.h>
|
||||
#include <plat/sram.h>
|
||||
#include <plat/prcm.h>
|
||||
#include <plat/clkdev_omap.h>
|
||||
#include <asm/div64.h>
|
||||
#include <asm/clkdev.h>
|
||||
|
||||
#include <plat/sdrc.h>
|
||||
#include "clock.h"
|
||||
#include "clock2xxx.h"
|
||||
#include "opp2xxx.h"
|
||||
#include "prm.h"
|
||||
#include "prm-regbits-24xx.h"
|
||||
#include "cm.h"
|
||||
#include "cm-regbits-24xx.h"
|
||||
|
||||
|
||||
/* CM_CLKEN_PLL.EN_{54,96}M_PLL options (24XX) */
|
||||
#define EN_APLL_STOPPED 0
|
||||
#define EN_APLL_LOCKED 3
|
||||
|
||||
/* CM_CLKSEL1_PLL.APLLS_CLKIN options (24XX) */
|
||||
#define APLLS_CLKIN_19_2MHZ 0
|
||||
#define APLLS_CLKIN_13MHZ 2
|
||||
#define APLLS_CLKIN_12MHZ 3
|
||||
|
||||
/* #define DOWN_VARIABLE_DPLL 1 */ /* Experimental */
|
||||
|
||||
const struct prcm_config *curr_prcm_set;
|
||||
const struct prcm_config *rate_table;
|
||||
|
||||
struct clk *vclk, *sclk, *dclk;
|
||||
|
||||
void __iomem *prcm_clksrc_ctrl;
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
/*
|
||||
* Omap24xx specific clock functions
|
||||
*-------------------------------------------------------------------------*/
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP2430
|
||||
|
||||
/**
|
||||
* omap2430_clk_i2chs_find_idlest - return CM_IDLEST info for 2430 I2CHS
|
||||
|
@ -86,6 +56,10 @@ static void omap2430_clk_i2chs_find_idlest(struct clk *clk,
|
|||
*idlest_bit = clk->enable_bit;
|
||||
}
|
||||
|
||||
#else
|
||||
#define omap2430_clk_i2chs_find_idlest NULL
|
||||
#endif
|
||||
|
||||
/* 2430 I2CHS has non-standard IDLEST register */
|
||||
const struct clkops clkops_omap2430_i2chs_wait = {
|
||||
.enable = omap2_dflt_clk_enable,
|
||||
|
@ -94,491 +68,10 @@ const struct clkops clkops_omap2430_i2chs_wait = {
|
|||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
};
|
||||
|
||||
/**
|
||||
* omap2xxx_clk_get_core_rate - return the CORE_CLK rate
|
||||
* @clk: pointer to the combined dpll_ck + core_ck (currently "dpll_ck")
|
||||
*
|
||||
* Returns the CORE_CLK rate. CORE_CLK can have one of three rate
|
||||
* sources on OMAP2xxx: the DPLL CLKOUT rate, DPLL CLKOUTX2, or 32KHz
|
||||
* (the latter is unusual). This currently should be called with
|
||||
* struct clk *dpll_ck, which is a composite clock of dpll_ck and
|
||||
* core_ck.
|
||||
*/
|
||||
unsigned long omap2xxx_clk_get_core_rate(struct clk *clk)
|
||||
{
|
||||
long long core_clk;
|
||||
u32 v;
|
||||
|
||||
core_clk = omap2_get_dpll_rate(clk);
|
||||
|
||||
v = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
|
||||
v &= OMAP24XX_CORE_CLK_SRC_MASK;
|
||||
|
||||
if (v == CORE_CLK_SRC_32K)
|
||||
core_clk = 32768;
|
||||
else
|
||||
core_clk *= v;
|
||||
|
||||
return core_clk;
|
||||
}
|
||||
|
||||
static int omap2_enable_osc_ck(struct clk *clk)
|
||||
{
|
||||
u32 pcc;
|
||||
|
||||
pcc = __raw_readl(prcm_clksrc_ctrl);
|
||||
|
||||
__raw_writel(pcc & ~OMAP_AUTOEXTCLKMODE_MASK, prcm_clksrc_ctrl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void omap2_disable_osc_ck(struct clk *clk)
|
||||
{
|
||||
u32 pcc;
|
||||
|
||||
pcc = __raw_readl(prcm_clksrc_ctrl);
|
||||
|
||||
__raw_writel(pcc | OMAP_AUTOEXTCLKMODE_MASK, prcm_clksrc_ctrl);
|
||||
}
|
||||
|
||||
const struct clkops clkops_oscck = {
|
||||
.enable = omap2_enable_osc_ck,
|
||||
.disable = omap2_disable_osc_ck,
|
||||
};
|
||||
|
||||
#ifdef OLD_CK
|
||||
/* Recalculate SYST_CLK */
|
||||
static void omap2_sys_clk_recalc(struct clk *clk)
|
||||
{
|
||||
u32 div = PRCM_CLKSRC_CTRL;
|
||||
div &= (1 << 7) | (1 << 6); /* Test if ext clk divided by 1 or 2 */
|
||||
div >>= clk->rate_offset;
|
||||
clk->rate = (clk->parent->rate / div);
|
||||
propagate_rate(clk);
|
||||
}
|
||||
#endif /* OLD_CK */
|
||||
|
||||
/* Enable an APLL if off */
|
||||
static int omap2_clk_apll_enable(struct clk *clk, u32 status_mask)
|
||||
{
|
||||
u32 cval, apll_mask;
|
||||
|
||||
apll_mask = EN_APLL_LOCKED << clk->enable_bit;
|
||||
|
||||
cval = cm_read_mod_reg(PLL_MOD, CM_CLKEN);
|
||||
|
||||
if ((cval & apll_mask) == apll_mask)
|
||||
return 0; /* apll already enabled */
|
||||
|
||||
cval &= ~apll_mask;
|
||||
cval |= apll_mask;
|
||||
cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
|
||||
|
||||
omap2_cm_wait_idlest(OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), status_mask,
|
||||
clk->name);
|
||||
|
||||
/*
|
||||
* REVISIT: Should we return an error code if omap2_wait_clock_ready()
|
||||
* fails?
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap2_clk_apll96_enable(struct clk *clk)
|
||||
{
|
||||
return omap2_clk_apll_enable(clk, OMAP24XX_ST_96M_APLL);
|
||||
}
|
||||
|
||||
static int omap2_clk_apll54_enable(struct clk *clk)
|
||||
{
|
||||
return omap2_clk_apll_enable(clk, OMAP24XX_ST_54M_APLL);
|
||||
}
|
||||
|
||||
/* Stop APLL */
|
||||
static void omap2_clk_apll_disable(struct clk *clk)
|
||||
{
|
||||
u32 cval;
|
||||
|
||||
cval = cm_read_mod_reg(PLL_MOD, CM_CLKEN);
|
||||
cval &= ~(EN_APLL_LOCKED << clk->enable_bit);
|
||||
cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
|
||||
}
|
||||
|
||||
const struct clkops clkops_apll96 = {
|
||||
.enable = omap2_clk_apll96_enable,
|
||||
.disable = omap2_clk_apll_disable,
|
||||
};
|
||||
|
||||
const struct clkops clkops_apll54 = {
|
||||
.enable = omap2_clk_apll54_enable,
|
||||
.disable = omap2_clk_apll_disable,
|
||||
};
|
||||
|
||||
/*
|
||||
* Uses the current prcm set to tell if a rate is valid.
|
||||
* You can go slower, but not faster within a given rate set.
|
||||
*/
|
||||
long omap2_dpllcore_round_rate(unsigned long target_rate)
|
||||
{
|
||||
u32 high, low, core_clk_src;
|
||||
|
||||
core_clk_src = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
|
||||
core_clk_src &= OMAP24XX_CORE_CLK_SRC_MASK;
|
||||
|
||||
if (core_clk_src == CORE_CLK_SRC_DPLL) { /* DPLL clockout */
|
||||
high = curr_prcm_set->dpll_speed * 2;
|
||||
low = curr_prcm_set->dpll_speed;
|
||||
} else { /* DPLL clockout x 2 */
|
||||
high = curr_prcm_set->dpll_speed;
|
||||
low = curr_prcm_set->dpll_speed / 2;
|
||||
}
|
||||
|
||||
#ifdef DOWN_VARIABLE_DPLL
|
||||
if (target_rate > high)
|
||||
return high;
|
||||
else
|
||||
return target_rate;
|
||||
#else
|
||||
if (target_rate > low)
|
||||
return high;
|
||||
else
|
||||
return low;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
unsigned long omap2_dpllcore_recalc(struct clk *clk)
|
||||
{
|
||||
return omap2xxx_clk_get_core_rate(clk);
|
||||
}
|
||||
|
||||
int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
u32 cur_rate, low, mult, div, valid_rate, done_rate;
|
||||
u32 bypass = 0;
|
||||
struct prcm_config tmpset;
|
||||
const struct dpll_data *dd;
|
||||
|
||||
cur_rate = omap2xxx_clk_get_core_rate(dclk);
|
||||
mult = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
|
||||
mult &= OMAP24XX_CORE_CLK_SRC_MASK;
|
||||
|
||||
if ((rate == (cur_rate / 2)) && (mult == 2)) {
|
||||
omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1);
|
||||
} else if ((rate == (cur_rate * 2)) && (mult == 1)) {
|
||||
omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
|
||||
} else if (rate != cur_rate) {
|
||||
valid_rate = omap2_dpllcore_round_rate(rate);
|
||||
if (valid_rate != rate)
|
||||
return -EINVAL;
|
||||
|
||||
if (mult == 1)
|
||||
low = curr_prcm_set->dpll_speed;
|
||||
else
|
||||
low = curr_prcm_set->dpll_speed / 2;
|
||||
|
||||
dd = clk->dpll_data;
|
||||
if (!dd)
|
||||
return -EINVAL;
|
||||
|
||||
tmpset.cm_clksel1_pll = __raw_readl(dd->mult_div1_reg);
|
||||
tmpset.cm_clksel1_pll &= ~(dd->mult_mask |
|
||||
dd->div1_mask);
|
||||
div = ((curr_prcm_set->xtal_speed / 1000000) - 1);
|
||||
tmpset.cm_clksel2_pll = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
|
||||
tmpset.cm_clksel2_pll &= ~OMAP24XX_CORE_CLK_SRC_MASK;
|
||||
if (rate > low) {
|
||||
tmpset.cm_clksel2_pll |= CORE_CLK_SRC_DPLL_X2;
|
||||
mult = ((rate / 2) / 1000000);
|
||||
done_rate = CORE_CLK_SRC_DPLL_X2;
|
||||
} else {
|
||||
tmpset.cm_clksel2_pll |= CORE_CLK_SRC_DPLL;
|
||||
mult = (rate / 1000000);
|
||||
done_rate = CORE_CLK_SRC_DPLL;
|
||||
}
|
||||
tmpset.cm_clksel1_pll |= (div << __ffs(dd->mult_mask));
|
||||
tmpset.cm_clksel1_pll |= (mult << __ffs(dd->div1_mask));
|
||||
|
||||
/* Worst case */
|
||||
tmpset.base_sdrc_rfr = SDRC_RFR_CTRL_BYPASS;
|
||||
|
||||
if (rate == curr_prcm_set->xtal_speed) /* If asking for 1-1 */
|
||||
bypass = 1;
|
||||
|
||||
/* For omap2xxx_sdrc_init_params() */
|
||||
omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
|
||||
|
||||
/* Force dll lock mode */
|
||||
omap2_set_prcm(tmpset.cm_clksel1_pll, tmpset.base_sdrc_rfr,
|
||||
bypass);
|
||||
|
||||
/* Errata: ret dll entry state */
|
||||
omap2xxx_sdrc_init_params(omap2xxx_sdrc_dll_is_unlocked());
|
||||
omap2xxx_sdrc_reprogram(done_rate, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap2_table_mpu_recalc - just return the MPU speed
|
||||
* @clk: virt_prcm_set struct clk
|
||||
*
|
||||
* Set virt_prcm_set's rate to the mpu_speed field of the current PRCM set.
|
||||
*/
|
||||
unsigned long omap2_table_mpu_recalc(struct clk *clk)
|
||||
{
|
||||
return curr_prcm_set->mpu_speed;
|
||||
}
|
||||
|
||||
/*
|
||||
* Look for a rate equal or less than the target rate given a configuration set.
|
||||
*
|
||||
* What's not entirely clear is "which" field represents the key field.
|
||||
* Some might argue L3-DDR, others ARM, others IVA. This code is simple and
|
||||
* just uses the ARM rates.
|
||||
*/
|
||||
long omap2_round_to_table_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
const struct prcm_config *ptr;
|
||||
long highest_rate;
|
||||
long sys_ck_rate;
|
||||
|
||||
sys_ck_rate = clk_get_rate(sclk);
|
||||
|
||||
highest_rate = -EINVAL;
|
||||
|
||||
for (ptr = rate_table; ptr->mpu_speed; ptr++) {
|
||||
if (!(ptr->flags & cpu_mask))
|
||||
continue;
|
||||
if (ptr->xtal_speed != sys_ck_rate)
|
||||
continue;
|
||||
|
||||
highest_rate = ptr->mpu_speed;
|
||||
|
||||
/* Can check only after xtal frequency check */
|
||||
if (ptr->mpu_speed <= rate)
|
||||
break;
|
||||
}
|
||||
return highest_rate;
|
||||
}
|
||||
|
||||
/* Sets basic clocks based on the specified rate */
|
||||
int omap2_select_table_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
u32 cur_rate, done_rate, bypass = 0, tmp;
|
||||
const struct prcm_config *prcm;
|
||||
unsigned long found_speed = 0;
|
||||
unsigned long flags;
|
||||
long sys_ck_rate;
|
||||
|
||||
sys_ck_rate = clk_get_rate(sclk);
|
||||
|
||||
for (prcm = rate_table; prcm->mpu_speed; prcm++) {
|
||||
if (!(prcm->flags & cpu_mask))
|
||||
continue;
|
||||
|
||||
if (prcm->xtal_speed != sys_ck_rate)
|
||||
continue;
|
||||
|
||||
if (prcm->mpu_speed <= rate) {
|
||||
found_speed = prcm->mpu_speed;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found_speed) {
|
||||
printk(KERN_INFO "Could not set MPU rate to %luMHz\n",
|
||||
rate / 1000000);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
curr_prcm_set = prcm;
|
||||
cur_rate = omap2xxx_clk_get_core_rate(dclk);
|
||||
|
||||
if (prcm->dpll_speed == cur_rate / 2) {
|
||||
omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1);
|
||||
} else if (prcm->dpll_speed == cur_rate * 2) {
|
||||
omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
|
||||
} else if (prcm->dpll_speed != cur_rate) {
|
||||
local_irq_save(flags);
|
||||
|
||||
if (prcm->dpll_speed == prcm->xtal_speed)
|
||||
bypass = 1;
|
||||
|
||||
if ((prcm->cm_clksel2_pll & OMAP24XX_CORE_CLK_SRC_MASK) ==
|
||||
CORE_CLK_SRC_DPLL_X2)
|
||||
done_rate = CORE_CLK_SRC_DPLL_X2;
|
||||
else
|
||||
done_rate = CORE_CLK_SRC_DPLL;
|
||||
|
||||
/* MPU divider */
|
||||
cm_write_mod_reg(prcm->cm_clksel_mpu, MPU_MOD, CM_CLKSEL);
|
||||
|
||||
/* dsp + iva1 div(2420), iva2.1(2430) */
|
||||
cm_write_mod_reg(prcm->cm_clksel_dsp,
|
||||
OMAP24XX_DSP_MOD, CM_CLKSEL);
|
||||
|
||||
cm_write_mod_reg(prcm->cm_clksel_gfx, GFX_MOD, CM_CLKSEL);
|
||||
|
||||
/* Major subsystem dividers */
|
||||
tmp = cm_read_mod_reg(CORE_MOD, CM_CLKSEL1) & OMAP24XX_CLKSEL_DSS2_MASK;
|
||||
cm_write_mod_reg(prcm->cm_clksel1_core | tmp, CORE_MOD,
|
||||
CM_CLKSEL1);
|
||||
|
||||
if (cpu_is_omap2430())
|
||||
cm_write_mod_reg(prcm->cm_clksel_mdm,
|
||||
OMAP2430_MDM_MOD, CM_CLKSEL);
|
||||
|
||||
/* x2 to enter omap2xxx_sdrc_init_params() */
|
||||
omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
|
||||
|
||||
omap2_set_prcm(prcm->cm_clksel1_pll, prcm->base_sdrc_rfr,
|
||||
bypass);
|
||||
|
||||
omap2xxx_sdrc_init_params(omap2xxx_sdrc_dll_is_unlocked());
|
||||
omap2xxx_sdrc_reprogram(done_rate, 0);
|
||||
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CPU_FREQ
|
||||
/*
|
||||
* Walk PRCM rate table and fillout cpufreq freq_table
|
||||
* XXX This should be replaced by an OPP layer in the near future
|
||||
*/
|
||||
static struct cpufreq_frequency_table *freq_table;
|
||||
|
||||
void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table)
|
||||
{
|
||||
const struct prcm_config *prcm;
|
||||
long sys_ck_rate;
|
||||
int i = 0;
|
||||
int tbl_sz = 0;
|
||||
|
||||
sys_ck_rate = clk_get_rate(sclk);
|
||||
|
||||
for (prcm = rate_table; prcm->mpu_speed; prcm++) {
|
||||
if (!(prcm->flags & cpu_mask))
|
||||
continue;
|
||||
if (prcm->xtal_speed != sys_ck_rate)
|
||||
continue;
|
||||
|
||||
/* don't put bypass rates in table */
|
||||
if (prcm->dpll_speed == prcm->xtal_speed)
|
||||
continue;
|
||||
|
||||
tbl_sz++;
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX Ensure that we're doing what CPUFreq expects for this error
|
||||
* case and the following one
|
||||
*/
|
||||
if (tbl_sz == 0) {
|
||||
pr_warning("%s: no matching entries in rate_table\n",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Include the CPUFREQ_TABLE_END terminator entry */
|
||||
tbl_sz++;
|
||||
|
||||
freq_table = kzalloc(sizeof(struct cpufreq_frequency_table) * tbl_sz,
|
||||
GFP_ATOMIC);
|
||||
if (!freq_table) {
|
||||
pr_err("%s: could not kzalloc frequency table\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
for (prcm = rate_table; prcm->mpu_speed; prcm++) {
|
||||
if (!(prcm->flags & cpu_mask))
|
||||
continue;
|
||||
if (prcm->xtal_speed != sys_ck_rate)
|
||||
continue;
|
||||
|
||||
/* don't put bypass rates in table */
|
||||
if (prcm->dpll_speed == prcm->xtal_speed)
|
||||
continue;
|
||||
|
||||
freq_table[i].index = i;
|
||||
freq_table[i].frequency = prcm->mpu_speed / 1000;
|
||||
i++;
|
||||
}
|
||||
|
||||
freq_table[i].index = i;
|
||||
freq_table[i].frequency = CPUFREQ_TABLE_END;
|
||||
|
||||
*table = &freq_table[0];
|
||||
}
|
||||
|
||||
void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table)
|
||||
{
|
||||
kfree(freq_table);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
struct clk_functions omap2_clk_functions = {
|
||||
.clk_enable = omap2_clk_enable,
|
||||
.clk_disable = omap2_clk_disable,
|
||||
.clk_round_rate = omap2_clk_round_rate,
|
||||
.clk_set_rate = omap2_clk_set_rate,
|
||||
.clk_set_parent = omap2_clk_set_parent,
|
||||
.clk_disable_unused = omap2_clk_disable_unused,
|
||||
#ifdef CONFIG_CPU_FREQ
|
||||
.clk_init_cpufreq_table = omap2_clk_init_cpufreq_table,
|
||||
.clk_exit_cpufreq_table = omap2_clk_exit_cpufreq_table,
|
||||
#endif
|
||||
};
|
||||
|
||||
static u32 omap2_get_apll_clkin(void)
|
||||
{
|
||||
u32 aplls, srate = 0;
|
||||
|
||||
aplls = cm_read_mod_reg(PLL_MOD, CM_CLKSEL1);
|
||||
aplls &= OMAP24XX_APLLS_CLKIN_MASK;
|
||||
aplls >>= OMAP24XX_APLLS_CLKIN_SHIFT;
|
||||
|
||||
if (aplls == APLLS_CLKIN_19_2MHZ)
|
||||
srate = 19200000;
|
||||
else if (aplls == APLLS_CLKIN_13MHZ)
|
||||
srate = 13000000;
|
||||
else if (aplls == APLLS_CLKIN_12MHZ)
|
||||
srate = 12000000;
|
||||
|
||||
return srate;
|
||||
}
|
||||
|
||||
static u32 omap2_get_sysclkdiv(void)
|
||||
{
|
||||
u32 div;
|
||||
|
||||
div = __raw_readl(prcm_clksrc_ctrl);
|
||||
div &= OMAP_SYSCLKDIV_MASK;
|
||||
div >>= OMAP_SYSCLKDIV_SHIFT;
|
||||
|
||||
return div;
|
||||
}
|
||||
|
||||
unsigned long omap2_osc_clk_recalc(struct clk *clk)
|
||||
{
|
||||
return omap2_get_apll_clkin() * omap2_get_sysclkdiv();
|
||||
}
|
||||
|
||||
unsigned long omap2_sys_clk_recalc(struct clk *clk)
|
||||
{
|
||||
return clk->parent->rate / omap2_get_sysclkdiv();
|
||||
}
|
||||
|
||||
/*
|
||||
* Set clocks for bypass mode for reboot to work.
|
||||
*/
|
||||
void omap2_clk_prepare_for_reboot(void)
|
||||
void omap2xxx_clk_prepare_for_reboot(void)
|
||||
{
|
||||
u32 rate;
|
||||
|
||||
|
@ -593,11 +86,14 @@ void omap2_clk_prepare_for_reboot(void)
|
|||
* Switch the MPU rate if specified on cmdline.
|
||||
* We cannot do this early until cmdline is parsed.
|
||||
*/
|
||||
static int __init omap2_clk_arch_init(void)
|
||||
static int __init omap2xxx_clk_arch_init(void)
|
||||
{
|
||||
struct clk *virt_prcm_set, *sys_ck, *dpll_ck, *mpu_ck;
|
||||
unsigned long sys_ck_rate;
|
||||
|
||||
if (!cpu_is_omap24xx())
|
||||
return 0;
|
||||
|
||||
if (!mpurate)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -621,6 +117,6 @@ static int __init omap2_clk_arch_init(void)
|
|||
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(omap2_clk_arch_init);
|
||||
arch_initcall(omap2xxx_clk_arch_init);
|
||||
|
||||
|
||||
|
|
|
@ -11,12 +11,15 @@
|
|||
unsigned long omap2_table_mpu_recalc(struct clk *clk);
|
||||
int omap2_select_table_rate(struct clk *clk, unsigned long rate);
|
||||
long omap2_round_to_table_rate(struct clk *clk, unsigned long rate);
|
||||
unsigned long omap2_sys_clk_recalc(struct clk *clk);
|
||||
unsigned long omap2xxx_sys_clk_recalc(struct clk *clk);
|
||||
unsigned long omap2_osc_clk_recalc(struct clk *clk);
|
||||
unsigned long omap2_sys_clk_recalc(struct clk *clk);
|
||||
unsigned long omap2_dpllcore_recalc(struct clk *clk);
|
||||
int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate);
|
||||
unsigned long omap2xxx_clk_get_core_rate(struct clk *clk);
|
||||
u32 omap2xxx_get_apll_clkin(void);
|
||||
u32 omap2xxx_get_sysclkdiv(void);
|
||||
void omap2xxx_clk_prepare_for_reboot(void);
|
||||
int omap2xxx_clk_init(void);
|
||||
|
||||
/* REVISIT: These should be set dynamically for CONFIG_MULTI_OMAP2 */
|
||||
#ifdef CONFIG_ARCH_OMAP2420
|
||||
|
|
|
@ -79,7 +79,7 @@ static struct clk sys_ck = { /* (*12, *13, 19.2, 26, 38.4)MHz */
|
|||
.ops = &clkops_null,
|
||||
.parent = &osc_ck,
|
||||
.clkdm_name = "wkup_clkdm",
|
||||
.recalc = &omap2_sys_clk_recalc,
|
||||
.recalc = &omap2xxx_sys_clk_recalc,
|
||||
};
|
||||
|
||||
static struct clk alt_ck = { /* Typical 54M or 48M, may not exist */
|
||||
|
@ -261,7 +261,7 @@ static struct clk func_12m_ck = {
|
|||
.parent = &func_48m_ck,
|
||||
.fixed_div = 4,
|
||||
.clkdm_name = "wkup_clkdm",
|
||||
.recalc = &omap2_fixed_divisor_recalc,
|
||||
.recalc = &omap_fixed_divisor_recalc,
|
||||
};
|
||||
|
||||
/* Secure timer, only available in secure mode */
|
||||
|
@ -557,7 +557,7 @@ static struct clk iva1_mpu_int_ifck = {
|
|||
.enable_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
|
||||
.enable_bit = OMAP2420_EN_IVA_MPU_SHIFT,
|
||||
.fixed_div = 2,
|
||||
.recalc = &omap2_fixed_divisor_recalc,
|
||||
.recalc = &omap_fixed_divisor_recalc,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -2238,7 +2238,7 @@ static struct omap_clk omap24xx_clks[] = {
|
|||
* init code
|
||||
*/
|
||||
|
||||
int __init omap2_clk_init(void)
|
||||
int __init omap2xxx_clk_init(void)
|
||||
{
|
||||
const struct prcm_config *prcm;
|
||||
struct omap_clk *c;
|
||||
|
@ -2264,7 +2264,7 @@ int __init omap2_clk_init(void)
|
|||
|
||||
osc_ck.rate = omap2_osc_clk_recalc(&osc_ck);
|
||||
propagate_rate(&osc_ck);
|
||||
sys_ck.rate = omap2_sys_clk_recalc(&sys_ck);
|
||||
sys_ck.rate = omap2xxx_sys_clk_recalc(&sys_ck);
|
||||
propagate_rate(&sys_ck);
|
||||
|
||||
for (c = omap24xx_clks; c < omap24xx_clks + ARRAY_SIZE(omap24xx_clks); c++)
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
* OMAP3-specific clock framework functions
|
||||
*
|
||||
* Copyright (C) 2007-2008 Texas Instruments, Inc.
|
||||
* Copyright (C) 2007-2009 Nokia Corporation
|
||||
* Copyright (C) 2007-2010 Nokia Corporation
|
||||
*
|
||||
* Written by Paul Walmsley
|
||||
* Testing and integration fixes by Jouni Högander
|
||||
* Paul Walmsley
|
||||
* Jouni Högander
|
||||
*
|
||||
* Parts of this code are based on code written by
|
||||
* Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu
|
||||
|
@ -16,34 +16,22 @@
|
|||
*/
|
||||
#undef DEBUG
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/limits.h>
|
||||
#include <linux/bitops.h>
|
||||
|
||||
#include <plat/cpu.h>
|
||||
#include <plat/clock.h>
|
||||
#include <plat/sram.h>
|
||||
#include <plat/sdrc.h>
|
||||
#include <asm/div64.h>
|
||||
#include <asm/clkdev.h>
|
||||
|
||||
#include "clock.h"
|
||||
#include "clock34xx.h"
|
||||
#include "sdrc.h"
|
||||
#include "prm.h"
|
||||
#include "prm-regbits-34xx.h"
|
||||
#include "cm.h"
|
||||
#include "cm-regbits-34xx.h"
|
||||
|
||||
#define CYCLES_PER_MHZ 1000000
|
||||
|
||||
/*
|
||||
* DPLL5_FREQ_FOR_USBHOST: USBHOST and USBTLL are the only clocks
|
||||
* that are sourced by DPLL5, and both of these require this clock
|
||||
|
@ -162,129 +150,7 @@ int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate)
|
|||
return omap3_noncore_dpll_set_rate(clk, rate);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* CORE DPLL (DPLL3) rate programming functions
|
||||
*
|
||||
* These call into SRAM code to do the actual CM writes, since the SDRAM
|
||||
* is clocked from DPLL3.
|
||||
*/
|
||||
|
||||
/**
|
||||
* omap3_core_dpll_m2_set_rate - set CORE DPLL M2 divider
|
||||
* @clk: struct clk * of DPLL to set
|
||||
* @rate: rounded target rate
|
||||
*
|
||||
* Program the DPLL M2 divider with the rounded target rate. Returns
|
||||
* -EINVAL upon error, or 0 upon success.
|
||||
*/
|
||||
int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
u32 new_div = 0;
|
||||
u32 unlock_dll = 0;
|
||||
u32 c;
|
||||
unsigned long validrate, sdrcrate, _mpurate;
|
||||
struct omap_sdrc_params *sdrc_cs0;
|
||||
struct omap_sdrc_params *sdrc_cs1;
|
||||
int ret;
|
||||
|
||||
if (!clk || !rate)
|
||||
return -EINVAL;
|
||||
|
||||
validrate = omap2_clksel_round_rate_div(clk, rate, &new_div);
|
||||
if (validrate != rate)
|
||||
return -EINVAL;
|
||||
|
||||
sdrcrate = sdrc_ick_p->rate;
|
||||
if (rate > clk->rate)
|
||||
sdrcrate <<= ((rate / clk->rate) >> 1);
|
||||
else
|
||||
sdrcrate >>= ((clk->rate / rate) >> 1);
|
||||
|
||||
ret = omap2_sdrc_get_params(sdrcrate, &sdrc_cs0, &sdrc_cs1);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
|
||||
if (sdrcrate < MIN_SDRC_DLL_LOCK_FREQ) {
|
||||
pr_debug("clock: will unlock SDRC DLL\n");
|
||||
unlock_dll = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX This only needs to be done when the CPU frequency changes
|
||||
*/
|
||||
_mpurate = arm_fck_p->rate / CYCLES_PER_MHZ;
|
||||
c = (_mpurate << SDRC_MPURATE_SCALE) >> SDRC_MPURATE_BASE_SHIFT;
|
||||
c += 1; /* for safety */
|
||||
c *= SDRC_MPURATE_LOOPS;
|
||||
c >>= SDRC_MPURATE_SCALE;
|
||||
if (c == 0)
|
||||
c = 1;
|
||||
|
||||
pr_debug("clock: changing CORE DPLL rate from %lu to %lu\n", clk->rate,
|
||||
validrate);
|
||||
pr_debug("clock: SDRC CS0 timing params used:"
|
||||
" RFR %08x CTRLA %08x CTRLB %08x MR %08x\n",
|
||||
sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
|
||||
sdrc_cs0->actim_ctrlb, sdrc_cs0->mr);
|
||||
if (sdrc_cs1)
|
||||
pr_debug("clock: SDRC CS1 timing params used: "
|
||||
" RFR %08x CTRLA %08x CTRLB %08x MR %08x\n",
|
||||
sdrc_cs1->rfr_ctrl, sdrc_cs1->actim_ctrla,
|
||||
sdrc_cs1->actim_ctrlb, sdrc_cs1->mr);
|
||||
|
||||
if (sdrc_cs1)
|
||||
omap3_configure_core_dpll(
|
||||
new_div, unlock_dll, c, rate > clk->rate,
|
||||
sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
|
||||
sdrc_cs0->actim_ctrlb, sdrc_cs0->mr,
|
||||
sdrc_cs1->rfr_ctrl, sdrc_cs1->actim_ctrla,
|
||||
sdrc_cs1->actim_ctrlb, sdrc_cs1->mr);
|
||||
else
|
||||
omap3_configure_core_dpll(
|
||||
new_div, unlock_dll, c, rate > clk->rate,
|
||||
sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
|
||||
sdrc_cs0->actim_ctrlb, sdrc_cs0->mr,
|
||||
0, 0, 0, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Common clock code */
|
||||
|
||||
/*
|
||||
* As it is structured now, this will prevent an OMAP2/3 multiboot
|
||||
* kernel from compiling. This will need further attention.
|
||||
*/
|
||||
#if defined(CONFIG_ARCH_OMAP3)
|
||||
|
||||
struct clk_functions omap2_clk_functions = {
|
||||
.clk_enable = omap2_clk_enable,
|
||||
.clk_disable = omap2_clk_disable,
|
||||
.clk_round_rate = omap2_clk_round_rate,
|
||||
.clk_set_rate = omap2_clk_set_rate,
|
||||
.clk_set_parent = omap2_clk_set_parent,
|
||||
.clk_disable_unused = omap2_clk_disable_unused,
|
||||
};
|
||||
|
||||
/*
|
||||
* Set clocks for bypass mode for reboot to work.
|
||||
*/
|
||||
void omap2_clk_prepare_for_reboot(void)
|
||||
{
|
||||
/* REVISIT: Not ready for 343x */
|
||||
#if 0
|
||||
u32 rate;
|
||||
|
||||
if (vclk == NULL || sclk == NULL)
|
||||
return;
|
||||
|
||||
rate = clk_get_rate(sclk);
|
||||
clk_set_rate(vclk, rate);
|
||||
#endif
|
||||
}
|
||||
|
||||
void omap3_clk_lock_dpll5(void)
|
||||
void __init omap3_clk_lock_dpll5(void)
|
||||
{
|
||||
struct clk *dpll5_clk;
|
||||
struct clk *dpll5_m2_clk;
|
||||
|
@ -306,17 +172,22 @@ void omap3_clk_lock_dpll5(void)
|
|||
return;
|
||||
}
|
||||
|
||||
/* Common clock code */
|
||||
|
||||
/* REVISIT: Move this init stuff out into clock.c */
|
||||
|
||||
/*
|
||||
* Switch the MPU rate if specified on cmdline.
|
||||
* We cannot do this early until cmdline is parsed.
|
||||
*/
|
||||
static int __init omap2_clk_arch_init(void)
|
||||
static int __init omap3xxx_clk_arch_init(void)
|
||||
{
|
||||
struct clk *osc_sys_ck, *dpll1_ck, *arm_fck, *core_ck;
|
||||
unsigned long osc_sys_rate;
|
||||
|
||||
if (!cpu_is_omap34xx())
|
||||
return 0;
|
||||
|
||||
if (!mpurate)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -345,9 +216,6 @@ static int __init omap2_clk_arch_init(void)
|
|||
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(omap2_clk_arch_init);
|
||||
|
||||
|
||||
#endif
|
||||
arch_initcall(omap3xxx_clk_arch_init);
|
||||
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK_34XX_H
|
||||
#define __ARCH_ARM_MACH_OMAP2_CLOCK_34XX_H
|
||||
|
||||
int omap3xxx_clk_init(void);
|
||||
int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate);
|
||||
int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate);
|
||||
void omap3_clk_lock_dpll5(void);
|
||||
|
|
|
@ -735,7 +735,7 @@ static struct clk omap_12m_fck = {
|
|||
.ops = &clkops_null,
|
||||
.parent = &omap_48m_fck,
|
||||
.fixed_div = 4,
|
||||
.recalc = &omap2_fixed_divisor_recalc,
|
||||
.recalc = &omap_fixed_divisor_recalc,
|
||||
};
|
||||
|
||||
/* This virstual clock is the source for dpll4_m4x2_ck */
|
||||
|
@ -1588,7 +1588,7 @@ static struct clk ssi_sst_fck_3430es1 = {
|
|||
.ops = &clkops_null,
|
||||
.parent = &ssi_ssr_fck_3430es1,
|
||||
.fixed_div = 2,
|
||||
.recalc = &omap2_fixed_divisor_recalc,
|
||||
.recalc = &omap_fixed_divisor_recalc,
|
||||
};
|
||||
|
||||
static struct clk ssi_sst_fck_3430es2 = {
|
||||
|
@ -1596,7 +1596,7 @@ static struct clk ssi_sst_fck_3430es2 = {
|
|||
.ops = &clkops_null,
|
||||
.parent = &ssi_ssr_fck_3430es2,
|
||||
.fixed_div = 2,
|
||||
.recalc = &omap2_fixed_divisor_recalc,
|
||||
.recalc = &omap_fixed_divisor_recalc,
|
||||
};
|
||||
|
||||
|
||||
|
@ -2988,139 +2988,140 @@ static struct clk wdt1_fck = {
|
|||
* clkdev
|
||||
*/
|
||||
|
||||
static struct omap_clk omap34xx_clks[] = {
|
||||
CLK(NULL, "omap_32k_fck", &omap_32k_fck, CK_343X),
|
||||
CLK(NULL, "virt_12m_ck", &virt_12m_ck, CK_343X),
|
||||
CLK(NULL, "virt_13m_ck", &virt_13m_ck, CK_343X),
|
||||
CLK(NULL, "virt_16_8m_ck", &virt_16_8m_ck, CK_3430ES2),
|
||||
CLK(NULL, "virt_19_2m_ck", &virt_19_2m_ck, CK_343X),
|
||||
CLK(NULL, "virt_26m_ck", &virt_26m_ck, CK_343X),
|
||||
CLK(NULL, "virt_38_4m_ck", &virt_38_4m_ck, CK_343X),
|
||||
CLK(NULL, "osc_sys_ck", &osc_sys_ck, CK_343X),
|
||||
CLK(NULL, "sys_ck", &sys_ck, CK_343X),
|
||||
CLK(NULL, "sys_altclk", &sys_altclk, CK_343X),
|
||||
CLK(NULL, "mcbsp_clks", &mcbsp_clks, CK_343X),
|
||||
CLK(NULL, "sys_clkout1", &sys_clkout1, CK_343X),
|
||||
CLK(NULL, "dpll1_ck", &dpll1_ck, CK_343X),
|
||||
CLK(NULL, "dpll1_x2_ck", &dpll1_x2_ck, CK_343X),
|
||||
CLK(NULL, "dpll1_x2m2_ck", &dpll1_x2m2_ck, CK_343X),
|
||||
/* XXX At some point we should rename this file to clock3xxx_data.c */
|
||||
static struct omap_clk omap3xxx_clks[] = {
|
||||
CLK(NULL, "omap_32k_fck", &omap_32k_fck, CK_3XXX),
|
||||
CLK(NULL, "virt_12m_ck", &virt_12m_ck, CK_3XXX),
|
||||
CLK(NULL, "virt_13m_ck", &virt_13m_ck, CK_3XXX),
|
||||
CLK(NULL, "virt_16_8m_ck", &virt_16_8m_ck, CK_3430ES2 | CK_AM35XX),
|
||||
CLK(NULL, "virt_19_2m_ck", &virt_19_2m_ck, CK_3XXX),
|
||||
CLK(NULL, "virt_26m_ck", &virt_26m_ck, CK_3XXX),
|
||||
CLK(NULL, "virt_38_4m_ck", &virt_38_4m_ck, CK_3XXX),
|
||||
CLK(NULL, "osc_sys_ck", &osc_sys_ck, CK_3XXX),
|
||||
CLK(NULL, "sys_ck", &sys_ck, CK_3XXX),
|
||||
CLK(NULL, "sys_altclk", &sys_altclk, CK_3XXX),
|
||||
CLK(NULL, "mcbsp_clks", &mcbsp_clks, CK_3XXX),
|
||||
CLK(NULL, "sys_clkout1", &sys_clkout1, CK_3XXX),
|
||||
CLK(NULL, "dpll1_ck", &dpll1_ck, CK_3XXX),
|
||||
CLK(NULL, "dpll1_x2_ck", &dpll1_x2_ck, CK_3XXX),
|
||||
CLK(NULL, "dpll1_x2m2_ck", &dpll1_x2m2_ck, CK_3XXX),
|
||||
CLK(NULL, "dpll2_ck", &dpll2_ck, CK_343X),
|
||||
CLK(NULL, "dpll2_m2_ck", &dpll2_m2_ck, CK_343X),
|
||||
CLK(NULL, "dpll3_ck", &dpll3_ck, CK_343X),
|
||||
CLK(NULL, "core_ck", &core_ck, CK_343X),
|
||||
CLK(NULL, "dpll3_x2_ck", &dpll3_x2_ck, CK_343X),
|
||||
CLK(NULL, "dpll3_m2_ck", &dpll3_m2_ck, CK_343X),
|
||||
CLK(NULL, "dpll3_m2x2_ck", &dpll3_m2x2_ck, CK_343X),
|
||||
CLK(NULL, "dpll3_m3_ck", &dpll3_m3_ck, CK_343X),
|
||||
CLK(NULL, "dpll3_m3x2_ck", &dpll3_m3x2_ck, CK_343X),
|
||||
CLK("etb", "emu_core_alwon_ck", &emu_core_alwon_ck, CK_343X),
|
||||
CLK(NULL, "dpll4_ck", &dpll4_ck, CK_343X),
|
||||
CLK(NULL, "dpll4_x2_ck", &dpll4_x2_ck, CK_343X),
|
||||
CLK(NULL, "omap_96m_alwon_fck", &omap_96m_alwon_fck, CK_343X),
|
||||
CLK(NULL, "omap_96m_fck", &omap_96m_fck, CK_343X),
|
||||
CLK(NULL, "cm_96m_fck", &cm_96m_fck, CK_343X),
|
||||
CLK(NULL, "omap_54m_fck", &omap_54m_fck, CK_343X),
|
||||
CLK(NULL, "omap_48m_fck", &omap_48m_fck, CK_343X),
|
||||
CLK(NULL, "omap_12m_fck", &omap_12m_fck, CK_343X),
|
||||
CLK(NULL, "dpll4_m2_ck", &dpll4_m2_ck, CK_343X),
|
||||
CLK(NULL, "dpll4_m2x2_ck", &dpll4_m2x2_ck, CK_343X),
|
||||
CLK(NULL, "dpll4_m3_ck", &dpll4_m3_ck, CK_343X),
|
||||
CLK(NULL, "dpll4_m3x2_ck", &dpll4_m3x2_ck, CK_343X),
|
||||
CLK(NULL, "dpll4_m4_ck", &dpll4_m4_ck, CK_343X),
|
||||
CLK(NULL, "dpll4_m4x2_ck", &dpll4_m4x2_ck, CK_343X),
|
||||
CLK(NULL, "dpll4_m5_ck", &dpll4_m5_ck, CK_343X),
|
||||
CLK(NULL, "dpll4_m5x2_ck", &dpll4_m5x2_ck, CK_343X),
|
||||
CLK(NULL, "dpll4_m6_ck", &dpll4_m6_ck, CK_343X),
|
||||
CLK(NULL, "dpll4_m6x2_ck", &dpll4_m6x2_ck, CK_343X),
|
||||
CLK("etb", "emu_per_alwon_ck", &emu_per_alwon_ck, CK_343X),
|
||||
CLK(NULL, "dpll5_ck", &dpll5_ck, CK_3430ES2),
|
||||
CLK(NULL, "dpll5_m2_ck", &dpll5_m2_ck, CK_3430ES2),
|
||||
CLK(NULL, "clkout2_src_ck", &clkout2_src_ck, CK_343X),
|
||||
CLK(NULL, "sys_clkout2", &sys_clkout2, CK_343X),
|
||||
CLK(NULL, "corex2_fck", &corex2_fck, CK_343X),
|
||||
CLK(NULL, "dpll1_fck", &dpll1_fck, CK_343X),
|
||||
CLK(NULL, "mpu_ck", &mpu_ck, CK_343X),
|
||||
CLK(NULL, "arm_fck", &arm_fck, CK_343X),
|
||||
CLK("etb", "emu_mpu_alwon_ck", &emu_mpu_alwon_ck, CK_343X),
|
||||
CLK(NULL, "dpll3_ck", &dpll3_ck, CK_3XXX),
|
||||
CLK(NULL, "core_ck", &core_ck, CK_3XXX),
|
||||
CLK(NULL, "dpll3_x2_ck", &dpll3_x2_ck, CK_3XXX),
|
||||
CLK(NULL, "dpll3_m2_ck", &dpll3_m2_ck, CK_3XXX),
|
||||
CLK(NULL, "dpll3_m2x2_ck", &dpll3_m2x2_ck, CK_3XXX),
|
||||
CLK(NULL, "dpll3_m3_ck", &dpll3_m3_ck, CK_3XXX),
|
||||
CLK(NULL, "dpll3_m3x2_ck", &dpll3_m3x2_ck, CK_3XXX),
|
||||
CLK("etb", "emu_core_alwon_ck", &emu_core_alwon_ck, CK_3XXX),
|
||||
CLK(NULL, "dpll4_ck", &dpll4_ck, CK_3XXX),
|
||||
CLK(NULL, "dpll4_x2_ck", &dpll4_x2_ck, CK_3XXX),
|
||||
CLK(NULL, "omap_96m_alwon_fck", &omap_96m_alwon_fck, CK_3XXX),
|
||||
CLK(NULL, "omap_96m_fck", &omap_96m_fck, CK_3XXX),
|
||||
CLK(NULL, "cm_96m_fck", &cm_96m_fck, CK_3XXX),
|
||||
CLK(NULL, "omap_54m_fck", &omap_54m_fck, CK_3XXX),
|
||||
CLK(NULL, "omap_48m_fck", &omap_48m_fck, CK_3XXX),
|
||||
CLK(NULL, "omap_12m_fck", &omap_12m_fck, CK_3XXX),
|
||||
CLK(NULL, "dpll4_m2_ck", &dpll4_m2_ck, CK_3XXX),
|
||||
CLK(NULL, "dpll4_m2x2_ck", &dpll4_m2x2_ck, CK_3XXX),
|
||||
CLK(NULL, "dpll4_m3_ck", &dpll4_m3_ck, CK_3XXX),
|
||||
CLK(NULL, "dpll4_m3x2_ck", &dpll4_m3x2_ck, CK_3XXX),
|
||||
CLK(NULL, "dpll4_m4_ck", &dpll4_m4_ck, CK_3XXX),
|
||||
CLK(NULL, "dpll4_m4x2_ck", &dpll4_m4x2_ck, CK_3XXX),
|
||||
CLK(NULL, "dpll4_m5_ck", &dpll4_m5_ck, CK_3XXX),
|
||||
CLK(NULL, "dpll4_m5x2_ck", &dpll4_m5x2_ck, CK_3XXX),
|
||||
CLK(NULL, "dpll4_m6_ck", &dpll4_m6_ck, CK_3XXX),
|
||||
CLK(NULL, "dpll4_m6x2_ck", &dpll4_m6x2_ck, CK_3XXX),
|
||||
CLK("etb", "emu_per_alwon_ck", &emu_per_alwon_ck, CK_3XXX),
|
||||
CLK(NULL, "dpll5_ck", &dpll5_ck, CK_3430ES2 | CK_AM35XX),
|
||||
CLK(NULL, "dpll5_m2_ck", &dpll5_m2_ck, CK_3430ES2 | CK_AM35XX),
|
||||
CLK(NULL, "clkout2_src_ck", &clkout2_src_ck, CK_3XXX),
|
||||
CLK(NULL, "sys_clkout2", &sys_clkout2, CK_3XXX),
|
||||
CLK(NULL, "corex2_fck", &corex2_fck, CK_3XXX),
|
||||
CLK(NULL, "dpll1_fck", &dpll1_fck, CK_3XXX),
|
||||
CLK(NULL, "mpu_ck", &mpu_ck, CK_3XXX),
|
||||
CLK(NULL, "arm_fck", &arm_fck, CK_3XXX),
|
||||
CLK("etb", "emu_mpu_alwon_ck", &emu_mpu_alwon_ck, CK_3XXX),
|
||||
CLK(NULL, "dpll2_fck", &dpll2_fck, CK_343X),
|
||||
CLK(NULL, "iva2_ck", &iva2_ck, CK_343X),
|
||||
CLK(NULL, "l3_ick", &l3_ick, CK_343X),
|
||||
CLK(NULL, "l4_ick", &l4_ick, CK_343X),
|
||||
CLK(NULL, "rm_ick", &rm_ick, CK_343X),
|
||||
CLK(NULL, "l3_ick", &l3_ick, CK_3XXX),
|
||||
CLK(NULL, "l4_ick", &l4_ick, CK_3XXX),
|
||||
CLK(NULL, "rm_ick", &rm_ick, CK_3XXX),
|
||||
CLK(NULL, "gfx_l3_ck", &gfx_l3_ck, CK_3430ES1),
|
||||
CLK(NULL, "gfx_l3_fck", &gfx_l3_fck, CK_3430ES1),
|
||||
CLK(NULL, "gfx_l3_ick", &gfx_l3_ick, CK_3430ES1),
|
||||
CLK(NULL, "gfx_cg1_ck", &gfx_cg1_ck, CK_3430ES1),
|
||||
CLK(NULL, "gfx_cg2_ck", &gfx_cg2_ck, CK_3430ES1),
|
||||
CLK(NULL, "sgx_fck", &sgx_fck, CK_3430ES2),
|
||||
CLK(NULL, "sgx_ick", &sgx_ick, CK_3430ES2),
|
||||
CLK(NULL, "sgx_fck", &sgx_fck, CK_3430ES2 | CK_3517),
|
||||
CLK(NULL, "sgx_ick", &sgx_ick, CK_3430ES2 | CK_3517),
|
||||
CLK(NULL, "d2d_26m_fck", &d2d_26m_fck, CK_3430ES1),
|
||||
CLK(NULL, "modem_fck", &modem_fck, CK_343X),
|
||||
CLK(NULL, "sad2d_ick", &sad2d_ick, CK_343X),
|
||||
CLK(NULL, "mad2d_ick", &mad2d_ick, CK_343X),
|
||||
CLK(NULL, "gpt10_fck", &gpt10_fck, CK_343X),
|
||||
CLK(NULL, "gpt11_fck", &gpt11_fck, CK_343X),
|
||||
CLK(NULL, "cpefuse_fck", &cpefuse_fck, CK_3430ES2),
|
||||
CLK(NULL, "ts_fck", &ts_fck, CK_3430ES2),
|
||||
CLK(NULL, "usbtll_fck", &usbtll_fck, CK_3430ES2),
|
||||
CLK(NULL, "core_96m_fck", &core_96m_fck, CK_343X),
|
||||
CLK("mmci-omap-hs.2", "fck", &mmchs3_fck, CK_3430ES2),
|
||||
CLK("mmci-omap-hs.1", "fck", &mmchs2_fck, CK_343X),
|
||||
CLK(NULL, "gpt10_fck", &gpt10_fck, CK_3XXX),
|
||||
CLK(NULL, "gpt11_fck", &gpt11_fck, CK_3XXX),
|
||||
CLK(NULL, "cpefuse_fck", &cpefuse_fck, CK_3430ES2 | CK_AM35XX),
|
||||
CLK(NULL, "ts_fck", &ts_fck, CK_3430ES2 | CK_AM35XX),
|
||||
CLK(NULL, "usbtll_fck", &usbtll_fck, CK_3430ES2 | CK_AM35XX),
|
||||
CLK(NULL, "core_96m_fck", &core_96m_fck, CK_3XXX),
|
||||
CLK("mmci-omap-hs.2", "fck", &mmchs3_fck, CK_3430ES2 | CK_AM35XX),
|
||||
CLK("mmci-omap-hs.1", "fck", &mmchs2_fck, CK_3XXX),
|
||||
CLK(NULL, "mspro_fck", &mspro_fck, CK_343X),
|
||||
CLK("mmci-omap-hs.0", "fck", &mmchs1_fck, CK_343X),
|
||||
CLK("i2c_omap.3", "fck", &i2c3_fck, CK_343X),
|
||||
CLK("i2c_omap.2", "fck", &i2c2_fck, CK_343X),
|
||||
CLK("i2c_omap.1", "fck", &i2c1_fck, CK_343X),
|
||||
CLK("omap-mcbsp.5", "fck", &mcbsp5_fck, CK_343X),
|
||||
CLK("omap-mcbsp.1", "fck", &mcbsp1_fck, CK_343X),
|
||||
CLK(NULL, "core_48m_fck", &core_48m_fck, CK_343X),
|
||||
CLK("omap2_mcspi.4", "fck", &mcspi4_fck, CK_343X),
|
||||
CLK("omap2_mcspi.3", "fck", &mcspi3_fck, CK_343X),
|
||||
CLK("omap2_mcspi.2", "fck", &mcspi2_fck, CK_343X),
|
||||
CLK("omap2_mcspi.1", "fck", &mcspi1_fck, CK_343X),
|
||||
CLK(NULL, "uart2_fck", &uart2_fck, CK_343X),
|
||||
CLK(NULL, "uart1_fck", &uart1_fck, CK_343X),
|
||||
CLK("mmci-omap-hs.0", "fck", &mmchs1_fck, CK_3XXX),
|
||||
CLK("i2c_omap.3", "fck", &i2c3_fck, CK_3XXX),
|
||||
CLK("i2c_omap.2", "fck", &i2c2_fck, CK_3XXX),
|
||||
CLK("i2c_omap.1", "fck", &i2c1_fck, CK_3XXX),
|
||||
CLK("omap-mcbsp.5", "fck", &mcbsp5_fck, CK_3XXX),
|
||||
CLK("omap-mcbsp.1", "fck", &mcbsp1_fck, CK_3XXX),
|
||||
CLK(NULL, "core_48m_fck", &core_48m_fck, CK_3XXX),
|
||||
CLK("omap2_mcspi.4", "fck", &mcspi4_fck, CK_3XXX),
|
||||
CLK("omap2_mcspi.3", "fck", &mcspi3_fck, CK_3XXX),
|
||||
CLK("omap2_mcspi.2", "fck", &mcspi2_fck, CK_3XXX),
|
||||
CLK("omap2_mcspi.1", "fck", &mcspi1_fck, CK_3XXX),
|
||||
CLK(NULL, "uart2_fck", &uart2_fck, CK_3XXX),
|
||||
CLK(NULL, "uart1_fck", &uart1_fck, CK_3XXX),
|
||||
CLK(NULL, "fshostusb_fck", &fshostusb_fck, CK_3430ES1),
|
||||
CLK(NULL, "core_12m_fck", &core_12m_fck, CK_343X),
|
||||
CLK("omap_hdq.0", "fck", &hdq_fck, CK_343X),
|
||||
CLK(NULL, "core_12m_fck", &core_12m_fck, CK_3XXX),
|
||||
CLK("omap_hdq.0", "fck", &hdq_fck, CK_3XXX),
|
||||
CLK(NULL, "ssi_ssr_fck", &ssi_ssr_fck_3430es1, CK_3430ES1),
|
||||
CLK(NULL, "ssi_ssr_fck", &ssi_ssr_fck_3430es2, CK_3430ES2),
|
||||
CLK(NULL, "ssi_sst_fck", &ssi_sst_fck_3430es1, CK_3430ES1),
|
||||
CLK(NULL, "ssi_sst_fck", &ssi_sst_fck_3430es2, CK_3430ES2),
|
||||
CLK(NULL, "core_l3_ick", &core_l3_ick, CK_343X),
|
||||
CLK(NULL, "core_l3_ick", &core_l3_ick, CK_3XXX),
|
||||
CLK("musb_hdrc", "ick", &hsotgusb_ick_3430es1, CK_3430ES1),
|
||||
CLK("musb_hdrc", "ick", &hsotgusb_ick_3430es2, CK_3430ES2),
|
||||
CLK(NULL, "sdrc_ick", &sdrc_ick, CK_343X),
|
||||
CLK(NULL, "gpmc_fck", &gpmc_fck, CK_343X),
|
||||
CLK(NULL, "sdrc_ick", &sdrc_ick, CK_3XXX),
|
||||
CLK(NULL, "gpmc_fck", &gpmc_fck, CK_3XXX),
|
||||
CLK(NULL, "security_l3_ick", &security_l3_ick, CK_343X),
|
||||
CLK(NULL, "pka_ick", &pka_ick, CK_343X),
|
||||
CLK(NULL, "core_l4_ick", &core_l4_ick, CK_343X),
|
||||
CLK(NULL, "usbtll_ick", &usbtll_ick, CK_3430ES2),
|
||||
CLK("mmci-omap-hs.2", "ick", &mmchs3_ick, CK_3430ES2),
|
||||
CLK(NULL, "core_l4_ick", &core_l4_ick, CK_3XXX),
|
||||
CLK(NULL, "usbtll_ick", &usbtll_ick, CK_3430ES2 | CK_AM35XX),
|
||||
CLK("mmci-omap-hs.2", "ick", &mmchs3_ick, CK_3430ES2 | CK_AM35XX),
|
||||
CLK(NULL, "icr_ick", &icr_ick, CK_343X),
|
||||
CLK(NULL, "aes2_ick", &aes2_ick, CK_343X),
|
||||
CLK(NULL, "sha12_ick", &sha12_ick, CK_343X),
|
||||
CLK(NULL, "des2_ick", &des2_ick, CK_343X),
|
||||
CLK("mmci-omap-hs.1", "ick", &mmchs2_ick, CK_343X),
|
||||
CLK("mmci-omap-hs.0", "ick", &mmchs1_ick, CK_343X),
|
||||
CLK("mmci-omap-hs.1", "ick", &mmchs2_ick, CK_3XXX),
|
||||
CLK("mmci-omap-hs.0", "ick", &mmchs1_ick, CK_3XXX),
|
||||
CLK(NULL, "mspro_ick", &mspro_ick, CK_343X),
|
||||
CLK("omap_hdq.0", "ick", &hdq_ick, CK_343X),
|
||||
CLK("omap2_mcspi.4", "ick", &mcspi4_ick, CK_343X),
|
||||
CLK("omap2_mcspi.3", "ick", &mcspi3_ick, CK_343X),
|
||||
CLK("omap2_mcspi.2", "ick", &mcspi2_ick, CK_343X),
|
||||
CLK("omap2_mcspi.1", "ick", &mcspi1_ick, CK_343X),
|
||||
CLK("i2c_omap.3", "ick", &i2c3_ick, CK_343X),
|
||||
CLK("i2c_omap.2", "ick", &i2c2_ick, CK_343X),
|
||||
CLK("i2c_omap.1", "ick", &i2c1_ick, CK_343X),
|
||||
CLK(NULL, "uart2_ick", &uart2_ick, CK_343X),
|
||||
CLK(NULL, "uart1_ick", &uart1_ick, CK_343X),
|
||||
CLK(NULL, "gpt11_ick", &gpt11_ick, CK_343X),
|
||||
CLK(NULL, "gpt10_ick", &gpt10_ick, CK_343X),
|
||||
CLK("omap-mcbsp.5", "ick", &mcbsp5_ick, CK_343X),
|
||||
CLK("omap-mcbsp.1", "ick", &mcbsp1_ick, CK_343X),
|
||||
CLK("omap_hdq.0", "ick", &hdq_ick, CK_3XXX),
|
||||
CLK("omap2_mcspi.4", "ick", &mcspi4_ick, CK_3XXX),
|
||||
CLK("omap2_mcspi.3", "ick", &mcspi3_ick, CK_3XXX),
|
||||
CLK("omap2_mcspi.2", "ick", &mcspi2_ick, CK_3XXX),
|
||||
CLK("omap2_mcspi.1", "ick", &mcspi1_ick, CK_3XXX),
|
||||
CLK("i2c_omap.3", "ick", &i2c3_ick, CK_3XXX),
|
||||
CLK("i2c_omap.2", "ick", &i2c2_ick, CK_3XXX),
|
||||
CLK("i2c_omap.1", "ick", &i2c1_ick, CK_3XXX),
|
||||
CLK(NULL, "uart2_ick", &uart2_ick, CK_3XXX),
|
||||
CLK(NULL, "uart1_ick", &uart1_ick, CK_3XXX),
|
||||
CLK(NULL, "gpt11_ick", &gpt11_ick, CK_3XXX),
|
||||
CLK(NULL, "gpt10_ick", &gpt10_ick, CK_3XXX),
|
||||
CLK("omap-mcbsp.5", "ick", &mcbsp5_ick, CK_3XXX),
|
||||
CLK("omap-mcbsp.1", "ick", &mcbsp1_ick, CK_3XXX),
|
||||
CLK(NULL, "fac_ick", &fac_ick, CK_3430ES1),
|
||||
CLK(NULL, "mailboxes_ick", &mailboxes_ick, CK_343X),
|
||||
CLK(NULL, "omapctrl_ick", &omapctrl_ick, CK_343X),
|
||||
CLK(NULL, "omapctrl_ick", &omapctrl_ick, CK_3XXX),
|
||||
CLK(NULL, "ssi_l4_ick", &ssi_l4_ick, CK_343X),
|
||||
CLK(NULL, "ssi_ick", &ssi_ick_3430es1, CK_3430ES1),
|
||||
CLK(NULL, "ssi_ick", &ssi_ick_3430es2, CK_3430ES2),
|
||||
|
@ -3131,96 +3132,100 @@ static struct omap_clk omap34xx_clks[] = {
|
|||
CLK(NULL, "sha11_ick", &sha11_ick, CK_343X),
|
||||
CLK(NULL, "des1_ick", &des1_ick, CK_343X),
|
||||
CLK("omapdss", "dss1_fck", &dss1_alwon_fck_3430es1, CK_3430ES1),
|
||||
CLK("omapdss", "dss1_fck", &dss1_alwon_fck_3430es2, CK_3430ES2),
|
||||
CLK("omapdss", "tv_fck", &dss_tv_fck, CK_343X),
|
||||
CLK("omapdss", "video_fck", &dss_96m_fck, CK_343X),
|
||||
CLK("omapdss", "dss2_fck", &dss2_alwon_fck, CK_343X),
|
||||
CLK("omapdss", "dss1_fck", &dss1_alwon_fck_3430es2, CK_3430ES2 | CK_AM35XX),
|
||||
CLK("omapdss", "tv_fck", &dss_tv_fck, CK_3XXX),
|
||||
CLK("omapdss", "video_fck", &dss_96m_fck, CK_3XXX),
|
||||
CLK("omapdss", "dss2_fck", &dss2_alwon_fck, CK_3XXX),
|
||||
CLK("omapdss", "ick", &dss_ick_3430es1, CK_3430ES1),
|
||||
CLK("omapdss", "ick", &dss_ick_3430es2, CK_3430ES2),
|
||||
CLK("omapdss", "ick", &dss_ick_3430es2, CK_3430ES2 | CK_AM35XX),
|
||||
CLK(NULL, "cam_mclk", &cam_mclk, CK_343X),
|
||||
CLK(NULL, "cam_ick", &cam_ick, CK_343X),
|
||||
CLK(NULL, "csi2_96m_fck", &csi2_96m_fck, CK_343X),
|
||||
CLK(NULL, "usbhost_120m_fck", &usbhost_120m_fck, CK_3430ES2),
|
||||
CLK(NULL, "usbhost_48m_fck", &usbhost_48m_fck, CK_3430ES2),
|
||||
CLK(NULL, "usbhost_ick", &usbhost_ick, CK_3430ES2),
|
||||
CLK(NULL, "usbhost_120m_fck", &usbhost_120m_fck, CK_3430ES2 | CK_AM35XX),
|
||||
CLK(NULL, "usbhost_48m_fck", &usbhost_48m_fck, CK_3430ES2 | CK_AM35XX),
|
||||
CLK(NULL, "usbhost_ick", &usbhost_ick, CK_3430ES2 | CK_AM35XX),
|
||||
CLK(NULL, "usim_fck", &usim_fck, CK_3430ES2),
|
||||
CLK(NULL, "gpt1_fck", &gpt1_fck, CK_343X),
|
||||
CLK(NULL, "wkup_32k_fck", &wkup_32k_fck, CK_343X),
|
||||
CLK(NULL, "gpio1_dbck", &gpio1_dbck, CK_343X),
|
||||
CLK("omap_wdt", "fck", &wdt2_fck, CK_343X),
|
||||
CLK(NULL, "gpt1_fck", &gpt1_fck, CK_3XXX),
|
||||
CLK(NULL, "wkup_32k_fck", &wkup_32k_fck, CK_3XXX),
|
||||
CLK(NULL, "gpio1_dbck", &gpio1_dbck, CK_3XXX),
|
||||
CLK("omap_wdt", "fck", &wdt2_fck, CK_3XXX),
|
||||
CLK(NULL, "wkup_l4_ick", &wkup_l4_ick, CK_343X),
|
||||
CLK(NULL, "usim_ick", &usim_ick, CK_3430ES2),
|
||||
CLK("omap_wdt", "ick", &wdt2_ick, CK_343X),
|
||||
CLK(NULL, "wdt1_ick", &wdt1_ick, CK_343X),
|
||||
CLK(NULL, "gpio1_ick", &gpio1_ick, CK_343X),
|
||||
CLK(NULL, "omap_32ksync_ick", &omap_32ksync_ick, CK_343X),
|
||||
CLK(NULL, "gpt12_ick", &gpt12_ick, CK_343X),
|
||||
CLK(NULL, "gpt1_ick", &gpt1_ick, CK_343X),
|
||||
CLK(NULL, "per_96m_fck", &per_96m_fck, CK_343X),
|
||||
CLK(NULL, "per_48m_fck", &per_48m_fck, CK_343X),
|
||||
CLK(NULL, "uart3_fck", &uart3_fck, CK_343X),
|
||||
CLK(NULL, "gpt2_fck", &gpt2_fck, CK_343X),
|
||||
CLK(NULL, "gpt3_fck", &gpt3_fck, CK_343X),
|
||||
CLK(NULL, "gpt4_fck", &gpt4_fck, CK_343X),
|
||||
CLK(NULL, "gpt5_fck", &gpt5_fck, CK_343X),
|
||||
CLK(NULL, "gpt6_fck", &gpt6_fck, CK_343X),
|
||||
CLK(NULL, "gpt7_fck", &gpt7_fck, CK_343X),
|
||||
CLK(NULL, "gpt8_fck", &gpt8_fck, CK_343X),
|
||||
CLK(NULL, "gpt9_fck", &gpt9_fck, CK_343X),
|
||||
CLK(NULL, "per_32k_alwon_fck", &per_32k_alwon_fck, CK_343X),
|
||||
CLK(NULL, "gpio6_dbck", &gpio6_dbck, CK_343X),
|
||||
CLK(NULL, "gpio5_dbck", &gpio5_dbck, CK_343X),
|
||||
CLK(NULL, "gpio4_dbck", &gpio4_dbck, CK_343X),
|
||||
CLK(NULL, "gpio3_dbck", &gpio3_dbck, CK_343X),
|
||||
CLK(NULL, "gpio2_dbck", &gpio2_dbck, CK_343X),
|
||||
CLK(NULL, "wdt3_fck", &wdt3_fck, CK_343X),
|
||||
CLK(NULL, "per_l4_ick", &per_l4_ick, CK_343X),
|
||||
CLK(NULL, "gpio6_ick", &gpio6_ick, CK_343X),
|
||||
CLK(NULL, "gpio5_ick", &gpio5_ick, CK_343X),
|
||||
CLK(NULL, "gpio4_ick", &gpio4_ick, CK_343X),
|
||||
CLK(NULL, "gpio3_ick", &gpio3_ick, CK_343X),
|
||||
CLK(NULL, "gpio2_ick", &gpio2_ick, CK_343X),
|
||||
CLK(NULL, "wdt3_ick", &wdt3_ick, CK_343X),
|
||||
CLK(NULL, "uart3_ick", &uart3_ick, CK_343X),
|
||||
CLK(NULL, "gpt9_ick", &gpt9_ick, CK_343X),
|
||||
CLK(NULL, "gpt8_ick", &gpt8_ick, CK_343X),
|
||||
CLK(NULL, "gpt7_ick", &gpt7_ick, CK_343X),
|
||||
CLK(NULL, "gpt6_ick", &gpt6_ick, CK_343X),
|
||||
CLK(NULL, "gpt5_ick", &gpt5_ick, CK_343X),
|
||||
CLK(NULL, "gpt4_ick", &gpt4_ick, CK_343X),
|
||||
CLK(NULL, "gpt3_ick", &gpt3_ick, CK_343X),
|
||||
CLK(NULL, "gpt2_ick", &gpt2_ick, CK_343X),
|
||||
CLK("omap-mcbsp.2", "ick", &mcbsp2_ick, CK_343X),
|
||||
CLK("omap-mcbsp.3", "ick", &mcbsp3_ick, CK_343X),
|
||||
CLK("omap-mcbsp.4", "ick", &mcbsp4_ick, CK_343X),
|
||||
CLK("omap-mcbsp.2", "fck", &mcbsp2_fck, CK_343X),
|
||||
CLK("omap-mcbsp.3", "fck", &mcbsp3_fck, CK_343X),
|
||||
CLK("omap-mcbsp.4", "fck", &mcbsp4_fck, CK_343X),
|
||||
CLK("etb", "emu_src_ck", &emu_src_ck, CK_343X),
|
||||
CLK(NULL, "pclk_fck", &pclk_fck, CK_343X),
|
||||
CLK(NULL, "pclkx2_fck", &pclkx2_fck, CK_343X),
|
||||
CLK(NULL, "atclk_fck", &atclk_fck, CK_343X),
|
||||
CLK(NULL, "traceclk_src_fck", &traceclk_src_fck, CK_343X),
|
||||
CLK(NULL, "traceclk_fck", &traceclk_fck, CK_343X),
|
||||
CLK("omap_wdt", "ick", &wdt2_ick, CK_3XXX),
|
||||
CLK(NULL, "wdt1_ick", &wdt1_ick, CK_3XXX),
|
||||
CLK(NULL, "gpio1_ick", &gpio1_ick, CK_3XXX),
|
||||
CLK(NULL, "omap_32ksync_ick", &omap_32ksync_ick, CK_3XXX),
|
||||
CLK(NULL, "gpt12_ick", &gpt12_ick, CK_3XXX),
|
||||
CLK(NULL, "gpt1_ick", &gpt1_ick, CK_3XXX),
|
||||
CLK(NULL, "per_96m_fck", &per_96m_fck, CK_3XXX),
|
||||
CLK(NULL, "per_48m_fck", &per_48m_fck, CK_3XXX),
|
||||
CLK(NULL, "uart3_fck", &uart3_fck, CK_3XXX),
|
||||
CLK(NULL, "gpt2_fck", &gpt2_fck, CK_3XXX),
|
||||
CLK(NULL, "gpt3_fck", &gpt3_fck, CK_3XXX),
|
||||
CLK(NULL, "gpt4_fck", &gpt4_fck, CK_3XXX),
|
||||
CLK(NULL, "gpt5_fck", &gpt5_fck, CK_3XXX),
|
||||
CLK(NULL, "gpt6_fck", &gpt6_fck, CK_3XXX),
|
||||
CLK(NULL, "gpt7_fck", &gpt7_fck, CK_3XXX),
|
||||
CLK(NULL, "gpt8_fck", &gpt8_fck, CK_3XXX),
|
||||
CLK(NULL, "gpt9_fck", &gpt9_fck, CK_3XXX),
|
||||
CLK(NULL, "per_32k_alwon_fck", &per_32k_alwon_fck, CK_3XXX),
|
||||
CLK(NULL, "gpio6_dbck", &gpio6_dbck, CK_3XXX),
|
||||
CLK(NULL, "gpio5_dbck", &gpio5_dbck, CK_3XXX),
|
||||
CLK(NULL, "gpio4_dbck", &gpio4_dbck, CK_3XXX),
|
||||
CLK(NULL, "gpio3_dbck", &gpio3_dbck, CK_3XXX),
|
||||
CLK(NULL, "gpio2_dbck", &gpio2_dbck, CK_3XXX),
|
||||
CLK(NULL, "wdt3_fck", &wdt3_fck, CK_3XXX),
|
||||
CLK(NULL, "per_l4_ick", &per_l4_ick, CK_3XXX),
|
||||
CLK(NULL, "gpio6_ick", &gpio6_ick, CK_3XXX),
|
||||
CLK(NULL, "gpio5_ick", &gpio5_ick, CK_3XXX),
|
||||
CLK(NULL, "gpio4_ick", &gpio4_ick, CK_3XXX),
|
||||
CLK(NULL, "gpio3_ick", &gpio3_ick, CK_3XXX),
|
||||
CLK(NULL, "gpio2_ick", &gpio2_ick, CK_3XXX),
|
||||
CLK(NULL, "wdt3_ick", &wdt3_ick, CK_3XXX),
|
||||
CLK(NULL, "uart3_ick", &uart3_ick, CK_3XXX),
|
||||
CLK(NULL, "gpt9_ick", &gpt9_ick, CK_3XXX),
|
||||
CLK(NULL, "gpt8_ick", &gpt8_ick, CK_3XXX),
|
||||
CLK(NULL, "gpt7_ick", &gpt7_ick, CK_3XXX),
|
||||
CLK(NULL, "gpt6_ick", &gpt6_ick, CK_3XXX),
|
||||
CLK(NULL, "gpt5_ick", &gpt5_ick, CK_3XXX),
|
||||
CLK(NULL, "gpt4_ick", &gpt4_ick, CK_3XXX),
|
||||
CLK(NULL, "gpt3_ick", &gpt3_ick, CK_3XXX),
|
||||
CLK(NULL, "gpt2_ick", &gpt2_ick, CK_3XXX),
|
||||
CLK("omap-mcbsp.2", "ick", &mcbsp2_ick, CK_3XXX),
|
||||
CLK("omap-mcbsp.3", "ick", &mcbsp3_ick, CK_3XXX),
|
||||
CLK("omap-mcbsp.4", "ick", &mcbsp4_ick, CK_3XXX),
|
||||
CLK("omap-mcbsp.2", "fck", &mcbsp2_fck, CK_3XXX),
|
||||
CLK("omap-mcbsp.3", "fck", &mcbsp3_fck, CK_3XXX),
|
||||
CLK("omap-mcbsp.4", "fck", &mcbsp4_fck, CK_3XXX),
|
||||
CLK("etb", "emu_src_ck", &emu_src_ck, CK_3XXX),
|
||||
CLK(NULL, "pclk_fck", &pclk_fck, CK_3XXX),
|
||||
CLK(NULL, "pclkx2_fck", &pclkx2_fck, CK_3XXX),
|
||||
CLK(NULL, "atclk_fck", &atclk_fck, CK_3XXX),
|
||||
CLK(NULL, "traceclk_src_fck", &traceclk_src_fck, CK_3XXX),
|
||||
CLK(NULL, "traceclk_fck", &traceclk_fck, CK_3XXX),
|
||||
CLK(NULL, "sr1_fck", &sr1_fck, CK_343X),
|
||||
CLK(NULL, "sr2_fck", &sr2_fck, CK_343X),
|
||||
CLK(NULL, "sr_l4_ick", &sr_l4_ick, CK_343X),
|
||||
CLK(NULL, "secure_32k_fck", &secure_32k_fck, CK_343X),
|
||||
CLK(NULL, "gpt12_fck", &gpt12_fck, CK_343X),
|
||||
CLK(NULL, "wdt1_fck", &wdt1_fck, CK_343X),
|
||||
CLK(NULL, "secure_32k_fck", &secure_32k_fck, CK_3XXX),
|
||||
CLK(NULL, "gpt12_fck", &gpt12_fck, CK_3XXX),
|
||||
CLK(NULL, "wdt1_fck", &wdt1_fck, CK_3XXX),
|
||||
};
|
||||
|
||||
|
||||
int __init omap2_clk_init(void)
|
||||
int __init omap3xxx_clk_init(void)
|
||||
{
|
||||
/* struct prcm_config *prcm; */
|
||||
struct omap_clk *c;
|
||||
/* u32 clkrate; */
|
||||
u32 cpu_clkflg;
|
||||
u32 cpu_clkflg = CK_3XXX;
|
||||
|
||||
if (cpu_is_omap34xx()) {
|
||||
if (cpu_is_omap3517()) {
|
||||
cpu_mask = RATE_IN_343X | RATE_IN_3430ES2;
|
||||
cpu_clkflg |= CK_3517;
|
||||
} else if (cpu_is_omap3505()) {
|
||||
cpu_mask = RATE_IN_343X | RATE_IN_3430ES2;
|
||||
cpu_clkflg |= CK_3505;
|
||||
} else if (cpu_is_omap34xx()) {
|
||||
cpu_mask = RATE_IN_343X;
|
||||
cpu_clkflg = CK_343X;
|
||||
cpu_clkflg |= CK_343X;
|
||||
|
||||
/*
|
||||
* Update this if there are further clock changes between ES2
|
||||
|
@ -3237,31 +3242,16 @@ int __init omap2_clk_init(void)
|
|||
|
||||
clk_init(&omap2_clk_functions);
|
||||
|
||||
for (c = omap34xx_clks; c < omap34xx_clks + ARRAY_SIZE(omap34xx_clks); c++)
|
||||
for (c = omap3xxx_clks; c < omap3xxx_clks + ARRAY_SIZE(omap3xxx_clks); c++)
|
||||
clk_preinit(c->lk.clk);
|
||||
|
||||
for (c = omap34xx_clks; c < omap34xx_clks + ARRAY_SIZE(omap34xx_clks); c++)
|
||||
for (c = omap3xxx_clks; c < omap3xxx_clks + ARRAY_SIZE(omap3xxx_clks); c++)
|
||||
if (c->cpu & cpu_clkflg) {
|
||||
clkdev_add(&c->lk);
|
||||
clk_register(c->lk.clk);
|
||||
omap2_init_clk_clkdm(c->lk.clk);
|
||||
}
|
||||
|
||||
/* REVISIT: Not yet ready for OMAP3 */
|
||||
#if 0
|
||||
/* Check the MPU rate set by bootloader */
|
||||
clkrate = omap2_get_dpll_rate_24xx(&dpll_ck);
|
||||
for (prcm = rate_table; prcm->mpu_speed; prcm++) {
|
||||
if (!(prcm->flags & cpu_mask))
|
||||
continue;
|
||||
if (prcm->xtal_speed != sys_ck.rate)
|
||||
continue;
|
||||
if (prcm->dpll_speed <= clkrate)
|
||||
break;
|
||||
}
|
||||
curr_prcm_set = prcm;
|
||||
#endif
|
||||
|
||||
recalculate_root_clocks();
|
||||
|
||||
printk(KERN_INFO "Clocking rate (Crystal/Core/MPU): "
|
||||
|
|
|
@ -13,21 +13,7 @@
|
|||
#include <linux/errno.h>
|
||||
#include "clock.h"
|
||||
|
||||
struct clk_functions omap2_clk_functions = {
|
||||
.clk_enable = omap2_clk_enable,
|
||||
.clk_disable = omap2_clk_disable,
|
||||
.clk_round_rate = omap2_clk_round_rate,
|
||||
.clk_set_rate = omap2_clk_set_rate,
|
||||
.clk_set_parent = omap2_clk_set_parent,
|
||||
.clk_disable_unused = omap2_clk_disable_unused,
|
||||
};
|
||||
|
||||
const struct clkops clkops_noncore_dpll_ops = {
|
||||
.enable = &omap3_noncore_dpll_enable,
|
||||
.disable = &omap3_noncore_dpll_disable,
|
||||
};
|
||||
|
||||
void omap2_clk_prepare_for_reboot(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#define OMAP4430_MAX_DPLL_MULT 2048
|
||||
#define OMAP4430_MAX_DPLL_DIV 128
|
||||
|
||||
int omap4xxx_clk_init(void);
|
||||
|
||||
extern const struct clkops clkops_noncore_dpll_ops;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2726,11 +2726,9 @@ static struct omap_clk omap44xx_clks[] = {
|
|||
CLK(NULL, "utmi_p2_gfclk_ck", &utmi_p2_gfclk_ck, CK_443X),
|
||||
};
|
||||
|
||||
int __init omap2_clk_init(void)
|
||||
int __init omap4xxx_clk_init(void)
|
||||
{
|
||||
/* struct prcm_config *prcm; */
|
||||
struct omap_clk *c;
|
||||
/* u32 clkrate; */
|
||||
u32 cpu_clkflg;
|
||||
|
||||
if (cpu_is_omap44xx()) {
|
||||
|
@ -2749,9 +2747,7 @@ int __init omap2_clk_init(void)
|
|||
if (c->cpu & cpu_clkflg) {
|
||||
clkdev_add(&c->lk);
|
||||
clk_register(c->lk.clk);
|
||||
/* TODO
|
||||
omap2_init_clk_clkdm(c->lk.clk);
|
||||
*/
|
||||
}
|
||||
|
||||
recalculate_root_clocks();
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,16 +1,420 @@
|
|||
/*
|
||||
* OMAP2/3 clockdomains
|
||||
*
|
||||
* Copyright (C) 2008 Texas Instruments, Inc.
|
||||
* Copyright (C) 2008 Nokia Corporation
|
||||
* Copyright (C) 2008-2009 Texas Instruments, Inc.
|
||||
* Copyright (C) 2008-2010 Nokia Corporation
|
||||
*
|
||||
* Written by Paul Walmsley
|
||||
* Written by Paul Walmsley and Jouni Högander
|
||||
*
|
||||
* This file contains clockdomains and clockdomain wakeup/sleep
|
||||
* dependencies for the OMAP2/3 chips. Some notes:
|
||||
*
|
||||
* A useful validation rule for struct clockdomain: Any clockdomain
|
||||
* referenced by a wkdep_srcs or sleepdep_srcs array must have a
|
||||
* dep_bit assigned. So wkdep_srcs/sleepdep_srcs are really just
|
||||
* software-controllable dependencies. Non-software-controllable
|
||||
* dependencies do exist, but they are not encoded below (yet).
|
||||
*
|
||||
* 24xx does not support programmable sleep dependencies (SLEEPDEP)
|
||||
*
|
||||
* The overly-specific dep_bit names are due to a bit name collision
|
||||
* with CM_FCLKEN_{DSP,IVA2}. The DSP/IVA2 PM_WKDEP and CM_SLEEPDEP shift
|
||||
* value are the same for all powerdomains: 2
|
||||
*
|
||||
* XXX should dep_bit be a mask, so we can test to see if it is 0 as a
|
||||
* sanity check?
|
||||
* XXX encode hardware fixed wakeup dependencies -- esp. for 3430 CORE
|
||||
*/
|
||||
|
||||
/*
|
||||
* To-Do List
|
||||
* -> Port the Sleep/Wakeup dependencies for the domains
|
||||
* from the Power domain framework
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ARM_MACH_OMAP2_CLOCKDOMAINS_H
|
||||
#define __ARCH_ARM_MACH_OMAP2_CLOCKDOMAINS_H
|
||||
|
||||
#include <plat/clockdomain.h>
|
||||
#include "cm.h"
|
||||
#include "prm.h"
|
||||
|
||||
/*
|
||||
* Clockdomain dependencies for wkdeps/sleepdeps
|
||||
*
|
||||
* XXX Hardware dependencies (e.g., dependencies that cannot be
|
||||
* changed in software) are not included here yet, but should be.
|
||||
*/
|
||||
|
||||
/* OMAP2/3-common wakeup dependencies */
|
||||
|
||||
/*
|
||||
* 2420/2430 PM_WKDEP_GFX: CORE, MPU, WKUP
|
||||
* 3430ES1 PM_WKDEP_GFX: adds IVA2, removes CORE
|
||||
* 3430ES2 PM_WKDEP_SGX: adds IVA2, removes CORE
|
||||
* These can share data since they will never be present simultaneously
|
||||
* on the same device.
|
||||
*/
|
||||
static struct clkdm_dep gfx_sgx_wkdeps[] = {
|
||||
{
|
||||
.clkdm_name = "core_l3_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "core_l4_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "iva2_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "mpu_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX |
|
||||
CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "wkup_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX |
|
||||
CHIP_IS_OMAP3430)
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
|
||||
/* 24XX-specific possible dependencies */
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP24XX
|
||||
|
||||
/* Wakeup dependency source arrays */
|
||||
|
||||
/* 2420/2430 PM_WKDEP_DSP: CORE, MPU, WKUP */
|
||||
static struct clkdm_dep dsp_24xx_wkdeps[] = {
|
||||
{
|
||||
.clkdm_name = "core_l3_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "core_l4_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "mpu_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "wkup_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
/*
|
||||
* 2420 PM_WKDEP_MPU: CORE, DSP, WKUP
|
||||
* 2430 adds MDM
|
||||
*/
|
||||
static struct clkdm_dep mpu_24xx_wkdeps[] = {
|
||||
{
|
||||
.clkdm_name = "core_l3_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "core_l4_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "dsp_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "wkup_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "mdm_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
/*
|
||||
* 2420 PM_WKDEP_CORE: DSP, GFX, MPU, WKUP
|
||||
* 2430 adds MDM
|
||||
*/
|
||||
static struct clkdm_dep core_24xx_wkdeps[] = {
|
||||
{
|
||||
.clkdm_name = "dsp_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "gfx_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "mpu_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "wkup_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "mdm_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* 2430-specific possible wakeup dependencies */
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP2430
|
||||
|
||||
/* 2430 PM_WKDEP_MDM: CORE, MPU, WKUP */
|
||||
static struct clkdm_dep mdm_2430_wkdeps[] = {
|
||||
{
|
||||
.clkdm_name = "core_l3_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "core_l4_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "mpu_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "wkup_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
#endif /* CONFIG_ARCH_OMAP2430 */
|
||||
|
||||
|
||||
/* OMAP3-specific possible dependencies */
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP3
|
||||
|
||||
/* 3430: PM_WKDEP_PER: CORE, IVA2, MPU, WKUP */
|
||||
static struct clkdm_dep per_wkdeps[] = {
|
||||
{
|
||||
.clkdm_name = "core_l3_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "core_l4_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "iva2_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "mpu_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "wkup_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
/* 3430ES2: PM_WKDEP_USBHOST: CORE, IVA2, MPU, WKUP */
|
||||
static struct clkdm_dep usbhost_wkdeps[] = {
|
||||
{
|
||||
.clkdm_name = "core_l3_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "core_l4_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "iva2_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "mpu_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "wkup_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
/* 3430 PM_WKDEP_MPU: CORE, IVA2, DSS, PER */
|
||||
static struct clkdm_dep mpu_3xxx_wkdeps[] = {
|
||||
{
|
||||
.clkdm_name = "core_l3_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "core_l4_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "iva2_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "dss_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "per_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
/* 3430 PM_WKDEP_IVA2: CORE, MPU, WKUP, DSS, PER */
|
||||
static struct clkdm_dep iva2_wkdeps[] = {
|
||||
{
|
||||
.clkdm_name = "core_l3_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "core_l4_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "mpu_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "wkup_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "dss_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "per_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
|
||||
/* 3430 PM_WKDEP_CAM: IVA2, MPU, WKUP */
|
||||
static struct clkdm_dep cam_wkdeps[] = {
|
||||
{
|
||||
.clkdm_name = "iva2_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "mpu_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "wkup_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
/* 3430 PM_WKDEP_DSS: IVA2, MPU, WKUP */
|
||||
static struct clkdm_dep dss_wkdeps[] = {
|
||||
{
|
||||
.clkdm_name = "iva2_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "mpu_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "wkup_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
/* 3430: PM_WKDEP_NEON: MPU */
|
||||
static struct clkdm_dep neon_wkdeps[] = {
|
||||
{
|
||||
.clkdm_name = "mpu_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
|
||||
/* Sleep dependency source arrays for OMAP3-specific clkdms */
|
||||
|
||||
/* 3430: CM_SLEEPDEP_DSS: MPU, IVA */
|
||||
static struct clkdm_dep dss_sleepdeps[] = {
|
||||
{
|
||||
.clkdm_name = "mpu_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "iva2_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
/* 3430: CM_SLEEPDEP_PER: MPU, IVA */
|
||||
static struct clkdm_dep per_sleepdeps[] = {
|
||||
{
|
||||
.clkdm_name = "mpu_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "iva2_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
/* 3430ES2: CM_SLEEPDEP_USBHOST: MPU, IVA */
|
||||
static struct clkdm_dep usbhost_sleepdeps[] = {
|
||||
{
|
||||
.clkdm_name = "mpu_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.clkdm_name = "iva2_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
/* 3430: CM_SLEEPDEP_CAM: MPU */
|
||||
static struct clkdm_dep cam_sleepdeps[] = {
|
||||
{
|
||||
.clkdm_name = "mpu_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
/*
|
||||
* 3430ES1: CM_SLEEPDEP_GFX: MPU
|
||||
* 3430ES2: CM_SLEEPDEP_SGX: MPU
|
||||
* These can share data since they will never be present simultaneously
|
||||
* on the same device.
|
||||
*/
|
||||
static struct clkdm_dep gfx_sgx_sleepdeps[] = {
|
||||
{
|
||||
.clkdm_name = "mpu_clkdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
#endif /* CONFIG_ARCH_OMAP3 */
|
||||
|
||||
|
||||
/*
|
||||
* OMAP2/3-common clockdomains
|
||||
|
@ -21,10 +425,13 @@
|
|||
* sys_clkout/sys_clkout2.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
|
||||
|
||||
/* This is an implicit clockdomain - it is never defined as such in TRM */
|
||||
static struct clockdomain wkup_clkdm = {
|
||||
.name = "wkup_clkdm",
|
||||
.pwrdm = { .name = "wkup_pwrdm" },
|
||||
.dep_bit = OMAP_EN_WKUP_SHIFT,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430),
|
||||
};
|
||||
|
||||
|
@ -40,6 +447,8 @@ static struct clockdomain cm_clkdm = {
|
|||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430),
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 2420-only clockdomains
|
||||
*/
|
||||
|
@ -50,6 +459,8 @@ static struct clockdomain mpu_2420_clkdm = {
|
|||
.name = "mpu_clkdm",
|
||||
.pwrdm = { .name = "mpu_pwrdm" },
|
||||
.flags = CLKDM_CAN_HWSUP,
|
||||
.clkstctrl_reg = OMAP2420_CM_REGADDR(MPU_MOD, OMAP2_CM_CLKSTCTRL),
|
||||
.wkdep_srcs = mpu_24xx_wkdeps,
|
||||
.clktrctrl_mask = OMAP24XX_AUTOSTATE_MPU_MASK,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
|
||||
};
|
||||
|
@ -58,11 +469,64 @@ static struct clockdomain iva1_2420_clkdm = {
|
|||
.name = "iva1_clkdm",
|
||||
.pwrdm = { .name = "dsp_pwrdm" },
|
||||
.flags = CLKDM_CAN_HWSUP_SWSUP,
|
||||
.clkstctrl_reg = OMAP2420_CM_REGADDR(OMAP24XX_DSP_MOD,
|
||||
OMAP2_CM_CLKSTCTRL),
|
||||
.dep_bit = OMAP24XX_PM_WKDEP_MPU_EN_DSP_SHIFT,
|
||||
.wkdep_srcs = dsp_24xx_wkdeps,
|
||||
.clktrctrl_mask = OMAP2420_AUTOSTATE_IVA_MASK,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
|
||||
};
|
||||
|
||||
#endif /* CONFIG_ARCH_OMAP2420 */
|
||||
static struct clockdomain dsp_2420_clkdm = {
|
||||
.name = "dsp_clkdm",
|
||||
.pwrdm = { .name = "dsp_pwrdm" },
|
||||
.flags = CLKDM_CAN_HWSUP_SWSUP,
|
||||
.clkstctrl_reg = OMAP2420_CM_REGADDR(OMAP24XX_DSP_MOD,
|
||||
OMAP2_CM_CLKSTCTRL),
|
||||
.clktrctrl_mask = OMAP24XX_AUTOSTATE_DSP_MASK,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
|
||||
};
|
||||
|
||||
static struct clockdomain gfx_2420_clkdm = {
|
||||
.name = "gfx_clkdm",
|
||||
.pwrdm = { .name = "gfx_pwrdm" },
|
||||
.flags = CLKDM_CAN_HWSUP_SWSUP,
|
||||
.clkstctrl_reg = OMAP2420_CM_REGADDR(GFX_MOD, OMAP2_CM_CLKSTCTRL),
|
||||
.wkdep_srcs = gfx_sgx_wkdeps,
|
||||
.clktrctrl_mask = OMAP24XX_AUTOSTATE_GFX_MASK,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
|
||||
};
|
||||
|
||||
static struct clockdomain core_l3_2420_clkdm = {
|
||||
.name = "core_l3_clkdm",
|
||||
.pwrdm = { .name = "core_pwrdm" },
|
||||
.flags = CLKDM_CAN_HWSUP,
|
||||
.clkstctrl_reg = OMAP2420_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL),
|
||||
.wkdep_srcs = core_24xx_wkdeps,
|
||||
.clktrctrl_mask = OMAP24XX_AUTOSTATE_L3_MASK,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
|
||||
};
|
||||
|
||||
static struct clockdomain core_l4_2420_clkdm = {
|
||||
.name = "core_l4_clkdm",
|
||||
.pwrdm = { .name = "core_pwrdm" },
|
||||
.flags = CLKDM_CAN_HWSUP,
|
||||
.clkstctrl_reg = OMAP2420_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL),
|
||||
.wkdep_srcs = core_24xx_wkdeps,
|
||||
.clktrctrl_mask = OMAP24XX_AUTOSTATE_L4_MASK,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
|
||||
};
|
||||
|
||||
static struct clockdomain dss_2420_clkdm = {
|
||||
.name = "dss_clkdm",
|
||||
.pwrdm = { .name = "core_pwrdm" },
|
||||
.flags = CLKDM_CAN_HWSUP,
|
||||
.clkstctrl_reg = OMAP2420_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL),
|
||||
.clktrctrl_mask = OMAP24XX_AUTOSTATE_DSS_MASK,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
|
||||
};
|
||||
|
||||
#endif /* CONFIG_ARCH_OMAP2420 */
|
||||
|
||||
|
||||
/*
|
||||
|
@ -75,80 +539,105 @@ static struct clockdomain mpu_2430_clkdm = {
|
|||
.name = "mpu_clkdm",
|
||||
.pwrdm = { .name = "mpu_pwrdm" },
|
||||
.flags = CLKDM_CAN_HWSUP_SWSUP,
|
||||
.clkstctrl_reg = OMAP2430_CM_REGADDR(MPU_MOD,
|
||||
OMAP2_CM_CLKSTCTRL),
|
||||
.wkdep_srcs = mpu_24xx_wkdeps,
|
||||
.clktrctrl_mask = OMAP24XX_AUTOSTATE_MPU_MASK,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
|
||||
};
|
||||
|
||||
/* Another case of bit name collisions between several registers: EN_MDM */
|
||||
static struct clockdomain mdm_clkdm = {
|
||||
.name = "mdm_clkdm",
|
||||
.pwrdm = { .name = "mdm_pwrdm" },
|
||||
.flags = CLKDM_CAN_HWSUP_SWSUP,
|
||||
.clkstctrl_reg = OMAP2430_CM_REGADDR(OMAP2430_MDM_MOD,
|
||||
OMAP2_CM_CLKSTCTRL),
|
||||
.dep_bit = OMAP2430_PM_WKDEP_MPU_EN_MDM_SHIFT,
|
||||
.wkdep_srcs = mdm_2430_wkdeps,
|
||||
.clktrctrl_mask = OMAP2430_AUTOSTATE_MDM_MASK,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
|
||||
};
|
||||
|
||||
static struct clockdomain dsp_2430_clkdm = {
|
||||
.name = "dsp_clkdm",
|
||||
.pwrdm = { .name = "dsp_pwrdm" },
|
||||
.flags = CLKDM_CAN_HWSUP_SWSUP,
|
||||
.clkstctrl_reg = OMAP2430_CM_REGADDR(OMAP24XX_DSP_MOD,
|
||||
OMAP2_CM_CLKSTCTRL),
|
||||
.dep_bit = OMAP24XX_PM_WKDEP_MPU_EN_DSP_SHIFT,
|
||||
.wkdep_srcs = dsp_24xx_wkdeps,
|
||||
.clktrctrl_mask = OMAP24XX_AUTOSTATE_DSP_MASK,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
|
||||
};
|
||||
|
||||
static struct clockdomain gfx_2430_clkdm = {
|
||||
.name = "gfx_clkdm",
|
||||
.pwrdm = { .name = "gfx_pwrdm" },
|
||||
.flags = CLKDM_CAN_HWSUP_SWSUP,
|
||||
.clkstctrl_reg = OMAP2430_CM_REGADDR(GFX_MOD, OMAP2_CM_CLKSTCTRL),
|
||||
.wkdep_srcs = gfx_sgx_wkdeps,
|
||||
.clktrctrl_mask = OMAP24XX_AUTOSTATE_GFX_MASK,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
|
||||
};
|
||||
|
||||
/*
|
||||
* XXX add usecounting for clkdm dependencies, otherwise the presence
|
||||
* of a single dep bit for core_l3_24xx_clkdm and core_l4_24xx_clkdm
|
||||
* could cause trouble
|
||||
*/
|
||||
static struct clockdomain core_l3_2430_clkdm = {
|
||||
.name = "core_l3_clkdm",
|
||||
.pwrdm = { .name = "core_pwrdm" },
|
||||
.flags = CLKDM_CAN_HWSUP,
|
||||
.clkstctrl_reg = OMAP2430_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL),
|
||||
.dep_bit = OMAP24XX_EN_CORE_SHIFT,
|
||||
.wkdep_srcs = core_24xx_wkdeps,
|
||||
.clktrctrl_mask = OMAP24XX_AUTOSTATE_L3_MASK,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
|
||||
};
|
||||
|
||||
/*
|
||||
* XXX add usecounting for clkdm dependencies, otherwise the presence
|
||||
* of a single dep bit for core_l3_24xx_clkdm and core_l4_24xx_clkdm
|
||||
* could cause trouble
|
||||
*/
|
||||
static struct clockdomain core_l4_2430_clkdm = {
|
||||
.name = "core_l4_clkdm",
|
||||
.pwrdm = { .name = "core_pwrdm" },
|
||||
.flags = CLKDM_CAN_HWSUP,
|
||||
.clkstctrl_reg = OMAP2430_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL),
|
||||
.dep_bit = OMAP24XX_EN_CORE_SHIFT,
|
||||
.wkdep_srcs = core_24xx_wkdeps,
|
||||
.clktrctrl_mask = OMAP24XX_AUTOSTATE_L4_MASK,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
|
||||
};
|
||||
|
||||
static struct clockdomain dss_2430_clkdm = {
|
||||
.name = "dss_clkdm",
|
||||
.pwrdm = { .name = "core_pwrdm" },
|
||||
.flags = CLKDM_CAN_HWSUP,
|
||||
.clkstctrl_reg = OMAP2430_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL),
|
||||
.clktrctrl_mask = OMAP24XX_AUTOSTATE_DSS_MASK,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
|
||||
};
|
||||
|
||||
#endif /* CONFIG_ARCH_OMAP2430 */
|
||||
|
||||
|
||||
/*
|
||||
* 24XX-only clockdomains
|
||||
* OMAP3 clockdomains
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_ARCH_OMAP24XX)
|
||||
#if defined(CONFIG_ARCH_OMAP3)
|
||||
|
||||
static struct clockdomain dsp_clkdm = {
|
||||
.name = "dsp_clkdm",
|
||||
.pwrdm = { .name = "dsp_pwrdm" },
|
||||
.flags = CLKDM_CAN_HWSUP_SWSUP,
|
||||
.clktrctrl_mask = OMAP24XX_AUTOSTATE_DSP_MASK,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
|
||||
};
|
||||
|
||||
static struct clockdomain gfx_24xx_clkdm = {
|
||||
.name = "gfx_clkdm",
|
||||
.pwrdm = { .name = "gfx_pwrdm" },
|
||||
.flags = CLKDM_CAN_HWSUP_SWSUP,
|
||||
.clktrctrl_mask = OMAP24XX_AUTOSTATE_GFX_MASK,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
|
||||
};
|
||||
|
||||
static struct clockdomain core_l3_24xx_clkdm = {
|
||||
.name = "core_l3_clkdm",
|
||||
.pwrdm = { .name = "core_pwrdm" },
|
||||
.flags = CLKDM_CAN_HWSUP,
|
||||
.clktrctrl_mask = OMAP24XX_AUTOSTATE_L3_MASK,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
|
||||
};
|
||||
|
||||
static struct clockdomain core_l4_24xx_clkdm = {
|
||||
.name = "core_l4_clkdm",
|
||||
.pwrdm = { .name = "core_pwrdm" },
|
||||
.flags = CLKDM_CAN_HWSUP,
|
||||
.clktrctrl_mask = OMAP24XX_AUTOSTATE_L4_MASK,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
|
||||
};
|
||||
|
||||
static struct clockdomain dss_24xx_clkdm = {
|
||||
.name = "dss_clkdm",
|
||||
.pwrdm = { .name = "core_pwrdm" },
|
||||
.flags = CLKDM_CAN_HWSUP,
|
||||
.clktrctrl_mask = OMAP24XX_AUTOSTATE_DSS_MASK,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
|
||||
};
|
||||
|
||||
#endif /* CONFIG_ARCH_OMAP24XX */
|
||||
|
||||
|
||||
/*
|
||||
* 34xx clockdomains
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_ARCH_OMAP34XX)
|
||||
|
||||
static struct clockdomain mpu_34xx_clkdm = {
|
||||
static struct clockdomain mpu_3xxx_clkdm = {
|
||||
.name = "mpu_clkdm",
|
||||
.pwrdm = { .name = "mpu_pwrdm" },
|
||||
.flags = CLKDM_CAN_HWSUP | CLKDM_CAN_FORCE_WAKEUP,
|
||||
.clkstctrl_reg = OMAP34XX_CM_REGADDR(MPU_MOD, OMAP2_CM_CLKSTCTRL),
|
||||
.dep_bit = OMAP3430_EN_MPU_SHIFT,
|
||||
.wkdep_srcs = mpu_3xxx_wkdeps,
|
||||
.clktrctrl_mask = OMAP3430_CLKTRCTRL_MPU_MASK,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
|
||||
};
|
||||
|
@ -157,6 +646,9 @@ static struct clockdomain neon_clkdm = {
|
|||
.name = "neon_clkdm",
|
||||
.pwrdm = { .name = "neon_pwrdm" },
|
||||
.flags = CLKDM_CAN_HWSUP_SWSUP,
|
||||
.clkstctrl_reg = OMAP34XX_CM_REGADDR(OMAP3430_NEON_MOD,
|
||||
OMAP2_CM_CLKSTCTRL),
|
||||
.wkdep_srcs = neon_wkdeps,
|
||||
.clktrctrl_mask = OMAP3430_CLKTRCTRL_NEON_MASK,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
|
||||
};
|
||||
|
@ -165,6 +657,10 @@ static struct clockdomain iva2_clkdm = {
|
|||
.name = "iva2_clkdm",
|
||||
.pwrdm = { .name = "iva2_pwrdm" },
|
||||
.flags = CLKDM_CAN_HWSUP_SWSUP,
|
||||
.clkstctrl_reg = OMAP34XX_CM_REGADDR(OMAP3430_IVA2_MOD,
|
||||
OMAP2_CM_CLKSTCTRL),
|
||||
.dep_bit = OMAP3430_PM_WKDEP_MPU_EN_IVA2_SHIFT,
|
||||
.wkdep_srcs = iva2_wkdeps,
|
||||
.clktrctrl_mask = OMAP3430_CLKTRCTRL_IVA2_MASK,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
|
||||
};
|
||||
|
@ -173,6 +669,9 @@ static struct clockdomain gfx_3430es1_clkdm = {
|
|||
.name = "gfx_clkdm",
|
||||
.pwrdm = { .name = "gfx_pwrdm" },
|
||||
.flags = CLKDM_CAN_HWSUP_SWSUP,
|
||||
.clkstctrl_reg = OMAP34XX_CM_REGADDR(GFX_MOD, OMAP2_CM_CLKSTCTRL),
|
||||
.wkdep_srcs = gfx_sgx_wkdeps,
|
||||
.sleepdep_srcs = gfx_sgx_sleepdeps,
|
||||
.clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_GFX_MASK,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1),
|
||||
};
|
||||
|
@ -181,6 +680,10 @@ static struct clockdomain sgx_clkdm = {
|
|||
.name = "sgx_clkdm",
|
||||
.pwrdm = { .name = "sgx_pwrdm" },
|
||||
.flags = CLKDM_CAN_HWSUP_SWSUP,
|
||||
.clkstctrl_reg = OMAP34XX_CM_REGADDR(OMAP3430ES2_SGX_MOD,
|
||||
OMAP2_CM_CLKSTCTRL),
|
||||
.wkdep_srcs = gfx_sgx_wkdeps,
|
||||
.sleepdep_srcs = gfx_sgx_sleepdeps,
|
||||
.clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_SGX_MASK,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
|
||||
};
|
||||
|
@ -196,30 +699,51 @@ static struct clockdomain d2d_clkdm = {
|
|||
.name = "d2d_clkdm",
|
||||
.pwrdm = { .name = "core_pwrdm" },
|
||||
.flags = CLKDM_CAN_HWSUP_SWSUP,
|
||||
.clkstctrl_reg = OMAP34XX_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL),
|
||||
.clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_D2D_MASK,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
|
||||
};
|
||||
|
||||
static struct clockdomain core_l3_34xx_clkdm = {
|
||||
/*
|
||||
* XXX add usecounting for clkdm dependencies, otherwise the presence
|
||||
* of a single dep bit for core_l3_3xxx_clkdm and core_l4_3xxx_clkdm
|
||||
* could cause trouble
|
||||
*/
|
||||
static struct clockdomain core_l3_3xxx_clkdm = {
|
||||
.name = "core_l3_clkdm",
|
||||
.pwrdm = { .name = "core_pwrdm" },
|
||||
.flags = CLKDM_CAN_HWSUP,
|
||||
.clkstctrl_reg = OMAP34XX_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL),
|
||||
.dep_bit = OMAP3430_EN_CORE_SHIFT,
|
||||
.clktrctrl_mask = OMAP3430_CLKTRCTRL_L3_MASK,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
|
||||
};
|
||||
|
||||
static struct clockdomain core_l4_34xx_clkdm = {
|
||||
/*
|
||||
* XXX add usecounting for clkdm dependencies, otherwise the presence
|
||||
* of a single dep bit for core_l3_3xxx_clkdm and core_l4_3xxx_clkdm
|
||||
* could cause trouble
|
||||
*/
|
||||
static struct clockdomain core_l4_3xxx_clkdm = {
|
||||
.name = "core_l4_clkdm",
|
||||
.pwrdm = { .name = "core_pwrdm" },
|
||||
.flags = CLKDM_CAN_HWSUP,
|
||||
.clkstctrl_reg = OMAP34XX_CM_REGADDR(CORE_MOD, OMAP2_CM_CLKSTCTRL),
|
||||
.dep_bit = OMAP3430_EN_CORE_SHIFT,
|
||||
.clktrctrl_mask = OMAP3430_CLKTRCTRL_L4_MASK,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
|
||||
};
|
||||
|
||||
static struct clockdomain dss_34xx_clkdm = {
|
||||
/* Another case of bit name collisions between several registers: EN_DSS */
|
||||
static struct clockdomain dss_3xxx_clkdm = {
|
||||
.name = "dss_clkdm",
|
||||
.pwrdm = { .name = "dss_pwrdm" },
|
||||
.flags = CLKDM_CAN_HWSUP_SWSUP,
|
||||
.clkstctrl_reg = OMAP34XX_CM_REGADDR(OMAP3430_DSS_MOD,
|
||||
OMAP2_CM_CLKSTCTRL),
|
||||
.dep_bit = OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT,
|
||||
.wkdep_srcs = dss_wkdeps,
|
||||
.sleepdep_srcs = dss_sleepdeps,
|
||||
.clktrctrl_mask = OMAP3430_CLKTRCTRL_DSS_MASK,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
|
||||
};
|
||||
|
@ -228,6 +752,10 @@ static struct clockdomain cam_clkdm = {
|
|||
.name = "cam_clkdm",
|
||||
.pwrdm = { .name = "cam_pwrdm" },
|
||||
.flags = CLKDM_CAN_HWSUP_SWSUP,
|
||||
.clkstctrl_reg = OMAP34XX_CM_REGADDR(OMAP3430_CAM_MOD,
|
||||
OMAP2_CM_CLKSTCTRL),
|
||||
.wkdep_srcs = cam_wkdeps,
|
||||
.sleepdep_srcs = cam_sleepdeps,
|
||||
.clktrctrl_mask = OMAP3430_CLKTRCTRL_CAM_MASK,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
|
||||
};
|
||||
|
@ -236,6 +764,10 @@ static struct clockdomain usbhost_clkdm = {
|
|||
.name = "usbhost_clkdm",
|
||||
.pwrdm = { .name = "usbhost_pwrdm" },
|
||||
.flags = CLKDM_CAN_HWSUP_SWSUP,
|
||||
.clkstctrl_reg = OMAP34XX_CM_REGADDR(OMAP3430ES2_USBHOST_MOD,
|
||||
OMAP2_CM_CLKSTCTRL),
|
||||
.wkdep_srcs = usbhost_wkdeps,
|
||||
.sleepdep_srcs = usbhost_sleepdeps,
|
||||
.clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_USBHOST_MASK,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
|
||||
};
|
||||
|
@ -244,6 +776,11 @@ static struct clockdomain per_clkdm = {
|
|||
.name = "per_clkdm",
|
||||
.pwrdm = { .name = "per_pwrdm" },
|
||||
.flags = CLKDM_CAN_HWSUP_SWSUP,
|
||||
.clkstctrl_reg = OMAP34XX_CM_REGADDR(OMAP3430_PER_MOD,
|
||||
OMAP2_CM_CLKSTCTRL),
|
||||
.dep_bit = OMAP3430_EN_PER_SHIFT,
|
||||
.wkdep_srcs = per_wkdeps,
|
||||
.sleepdep_srcs = per_sleepdeps,
|
||||
.clktrctrl_mask = OMAP3430_CLKTRCTRL_PER_MASK,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
|
||||
};
|
||||
|
@ -256,6 +793,8 @@ static struct clockdomain emu_clkdm = {
|
|||
.name = "emu_clkdm",
|
||||
.pwrdm = { .name = "emu_pwrdm" },
|
||||
.flags = /* CLKDM_CAN_ENABLE_AUTO | */CLKDM_CAN_SWSUP,
|
||||
.clkstctrl_reg = OMAP34XX_CM_REGADDR(OMAP3430_EMU_MOD,
|
||||
OMAP2_CM_CLKSTCTRL),
|
||||
.clktrctrl_mask = OMAP3430_CLKTRCTRL_EMU_MASK,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
|
||||
};
|
||||
|
@ -290,64 +829,70 @@ static struct clockdomain dpll5_clkdm = {
|
|||
.omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
|
||||
};
|
||||
|
||||
#endif /* CONFIG_ARCH_OMAP34XX */
|
||||
#endif /* CONFIG_ARCH_OMAP3 */
|
||||
|
||||
#include "clockdomains44xx.h"
|
||||
|
||||
/*
|
||||
* Clockdomain-powerdomain hwsup dependencies (34XX only)
|
||||
* Clockdomain hwsup dependencies (OMAP3 only)
|
||||
*/
|
||||
|
||||
static struct clkdm_pwrdm_autodep clkdm_pwrdm_autodeps[] = {
|
||||
static struct clkdm_autodep clkdm_autodeps[] = {
|
||||
{
|
||||
.pwrdm = { .name = "mpu_pwrdm" },
|
||||
.clkdm = { .name = "mpu_clkdm" },
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.pwrdm = { .name = "iva2_pwrdm" },
|
||||
.clkdm = { .name = "iva2_clkdm" },
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.pwrdm = { .name = NULL },
|
||||
.clkdm = { .name = NULL },
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
*
|
||||
* List of clockdomain pointers per platform
|
||||
*/
|
||||
|
||||
static struct clockdomain *clockdomains_omap[] = {
|
||||
|
||||
#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
|
||||
&wkup_clkdm,
|
||||
&cm_clkdm,
|
||||
&prm_clkdm,
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP2420
|
||||
&mpu_2420_clkdm,
|
||||
&iva1_2420_clkdm,
|
||||
&dsp_2420_clkdm,
|
||||
&gfx_2420_clkdm,
|
||||
&core_l3_2420_clkdm,
|
||||
&core_l4_2420_clkdm,
|
||||
&dss_2420_clkdm,
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP2430
|
||||
&mpu_2430_clkdm,
|
||||
&mdm_clkdm,
|
||||
&dsp_2430_clkdm,
|
||||
&gfx_2430_clkdm,
|
||||
&core_l3_2430_clkdm,
|
||||
&core_l4_2430_clkdm,
|
||||
&dss_2430_clkdm,
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP24XX
|
||||
&dsp_clkdm,
|
||||
&gfx_24xx_clkdm,
|
||||
&core_l3_24xx_clkdm,
|
||||
&core_l4_24xx_clkdm,
|
||||
&dss_24xx_clkdm,
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP34XX
|
||||
&mpu_34xx_clkdm,
|
||||
#ifdef CONFIG_ARCH_OMAP3
|
||||
&mpu_3xxx_clkdm,
|
||||
&neon_clkdm,
|
||||
&iva2_clkdm,
|
||||
&gfx_3430es1_clkdm,
|
||||
&sgx_clkdm,
|
||||
&d2d_clkdm,
|
||||
&core_l3_34xx_clkdm,
|
||||
&core_l4_34xx_clkdm,
|
||||
&dss_34xx_clkdm,
|
||||
&core_l3_3xxx_clkdm,
|
||||
&core_l4_3xxx_clkdm,
|
||||
&dss_3xxx_clkdm,
|
||||
&cam_clkdm,
|
||||
&usbhost_clkdm,
|
||||
&per_clkdm,
|
||||
|
@ -359,6 +904,33 @@ static struct clockdomain *clockdomains_omap[] = {
|
|||
&dpll5_clkdm,
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP4
|
||||
&l4_cefuse_44xx_clkdm,
|
||||
&l4_cfg_44xx_clkdm,
|
||||
&tesla_44xx_clkdm,
|
||||
&l3_gfx_44xx_clkdm,
|
||||
&ivahd_44xx_clkdm,
|
||||
&l4_secure_44xx_clkdm,
|
||||
&l4_per_44xx_clkdm,
|
||||
&abe_44xx_clkdm,
|
||||
&l3_instr_44xx_clkdm,
|
||||
&l3_init_44xx_clkdm,
|
||||
&mpuss_44xx_clkdm,
|
||||
&mpu0_44xx_clkdm,
|
||||
&mpu1_44xx_clkdm,
|
||||
&l3_emif_44xx_clkdm,
|
||||
&l4_ao_44xx_clkdm,
|
||||
&ducati_44xx_clkdm,
|
||||
&l3_2_44xx_clkdm,
|
||||
&l3_1_44xx_clkdm,
|
||||
&l3_d2d_44xx_clkdm,
|
||||
&iss_44xx_clkdm,
|
||||
&l3_dss_44xx_clkdm,
|
||||
&l4_wkup_44xx_clkdm,
|
||||
&emu_sys_44xx_clkdm,
|
||||
&l3_dma_44xx_clkdm,
|
||||
#endif
|
||||
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,250 @@
|
|||
/*
|
||||
* OMAP4 Clock domains framework
|
||||
*
|
||||
* Copyright (C) 2009 Texas Instruments, Inc.
|
||||
* Copyright (C) 2009 Nokia Corporation
|
||||
*
|
||||
* Abhijit Pagare (abhijitpagare@ti.com)
|
||||
* Benoit Cousson (b-cousson@ti.com)
|
||||
*
|
||||
* This file is automatically generated from the OMAP hardware databases.
|
||||
* We respectfully ask that any modifications to this file be coordinated
|
||||
* with the public linux-omap@vger.kernel.org mailing list and the
|
||||
* authors above to ensure that the autogeneration scripts are kept
|
||||
* up-to-date with the file contents.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
/*
|
||||
* To-Do List
|
||||
* -> Populate the Sleep/Wakeup dependencies for the domains
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ARM_MACH_OMAP2_CLOCKDOMAINS44XX_H
|
||||
#define __ARCH_ARM_MACH_OMAP2_CLOCKDOMAINS44XX_H
|
||||
|
||||
#include <plat/clockdomain.h>
|
||||
|
||||
#if defined(CONFIG_ARCH_OMAP4)
|
||||
|
||||
static struct clockdomain l4_cefuse_44xx_clkdm = {
|
||||
.name = "l4_cefuse_clkdm",
|
||||
.pwrdm = { .name = "cefuse_pwrdm" },
|
||||
.clkstctrl_reg = OMAP4430_CM_CEFUSE_CLKSTCTRL,
|
||||
.clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
|
||||
.flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
};
|
||||
|
||||
static struct clockdomain l4_cfg_44xx_clkdm = {
|
||||
.name = "l4_cfg_clkdm",
|
||||
.pwrdm = { .name = "core_pwrdm" },
|
||||
.clkstctrl_reg = OMAP4430_CM_L4CFG_CLKSTCTRL,
|
||||
.clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
|
||||
.flags = CLKDM_CAN_HWSUP,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
};
|
||||
|
||||
static struct clockdomain tesla_44xx_clkdm = {
|
||||
.name = "tesla_clkdm",
|
||||
.pwrdm = { .name = "tesla_pwrdm" },
|
||||
.clkstctrl_reg = OMAP4430_CM_TESLA_CLKSTCTRL,
|
||||
.clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
|
||||
.flags = CLKDM_CAN_HWSUP_SWSUP,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
};
|
||||
|
||||
static struct clockdomain l3_gfx_44xx_clkdm = {
|
||||
.name = "l3_gfx_clkdm",
|
||||
.pwrdm = { .name = "gfx_pwrdm" },
|
||||
.clkstctrl_reg = OMAP4430_CM_GFX_CLKSTCTRL,
|
||||
.clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
|
||||
.flags = CLKDM_CAN_HWSUP_SWSUP,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
};
|
||||
|
||||
static struct clockdomain ivahd_44xx_clkdm = {
|
||||
.name = "ivahd_clkdm",
|
||||
.pwrdm = { .name = "ivahd_pwrdm" },
|
||||
.clkstctrl_reg = OMAP4430_CM_IVAHD_CLKSTCTRL,
|
||||
.clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
|
||||
.flags = CLKDM_CAN_HWSUP_SWSUP,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
};
|
||||
|
||||
static struct clockdomain l4_secure_44xx_clkdm = {
|
||||
.name = "l4_secure_clkdm",
|
||||
.pwrdm = { .name = "l4per_pwrdm" },
|
||||
.clkstctrl_reg = OMAP4430_CM_L4SEC_CLKSTCTRL,
|
||||
.clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
|
||||
.flags = CLKDM_CAN_HWSUP_SWSUP,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
};
|
||||
|
||||
static struct clockdomain l4_per_44xx_clkdm = {
|
||||
.name = "l4_per_clkdm",
|
||||
.pwrdm = { .name = "l4per_pwrdm" },
|
||||
.clkstctrl_reg = OMAP4430_CM_L4PER_CLKSTCTRL,
|
||||
.clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
|
||||
.flags = CLKDM_CAN_HWSUP_SWSUP,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
};
|
||||
|
||||
static struct clockdomain abe_44xx_clkdm = {
|
||||
.name = "abe_clkdm",
|
||||
.pwrdm = { .name = "abe_pwrdm" },
|
||||
.clkstctrl_reg = OMAP4430_CM1_ABE_CLKSTCTRL,
|
||||
.clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
|
||||
.flags = CLKDM_CAN_HWSUP_SWSUP,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
};
|
||||
|
||||
static struct clockdomain l3_instr_44xx_clkdm = {
|
||||
.name = "l3_instr_clkdm",
|
||||
.pwrdm = { .name = "core_pwrdm" },
|
||||
.clkstctrl_reg = OMAP4430_CM_L3INSTR_CLKSTCTRL,
|
||||
.clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
};
|
||||
|
||||
static struct clockdomain l3_init_44xx_clkdm = {
|
||||
.name = "l3_init_clkdm",
|
||||
.pwrdm = { .name = "l3init_pwrdm" },
|
||||
.clkstctrl_reg = OMAP4430_CM_L3INIT_CLKSTCTRL,
|
||||
.clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
|
||||
.flags = CLKDM_CAN_HWSUP_SWSUP,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
};
|
||||
|
||||
static struct clockdomain mpuss_44xx_clkdm = {
|
||||
.name = "mpuss_clkdm",
|
||||
.pwrdm = { .name = "mpu_pwrdm" },
|
||||
.clkstctrl_reg = OMAP4430_CM_MPU_CLKSTCTRL,
|
||||
.clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
|
||||
.flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
};
|
||||
|
||||
static struct clockdomain mpu0_44xx_clkdm = {
|
||||
.name = "mpu0_clkdm",
|
||||
.pwrdm = { .name = "cpu0_pwrdm" },
|
||||
.clkstctrl_reg = OMAP4430_CM_PDA_CPU0_CLKSTCTRL,
|
||||
.clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
|
||||
.flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
};
|
||||
|
||||
static struct clockdomain mpu1_44xx_clkdm = {
|
||||
.name = "mpu1_clkdm",
|
||||
.pwrdm = { .name = "cpu1_pwrdm" },
|
||||
.clkstctrl_reg = OMAP4430_CM_PDA_CPU1_CLKSTCTRL,
|
||||
.clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
|
||||
.flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
};
|
||||
|
||||
static struct clockdomain l3_emif_44xx_clkdm = {
|
||||
.name = "l3_emif_clkdm",
|
||||
.pwrdm = { .name = "core_pwrdm" },
|
||||
.clkstctrl_reg = OMAP4430_CM_MEMIF_CLKSTCTRL,
|
||||
.clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
|
||||
.flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
};
|
||||
|
||||
static struct clockdomain l4_ao_44xx_clkdm = {
|
||||
.name = "l4_ao_clkdm",
|
||||
.pwrdm = { .name = "always_on_core_pwrdm" },
|
||||
.clkstctrl_reg = OMAP4430_CM_ALWON_CLKSTCTRL,
|
||||
.clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
|
||||
.flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
};
|
||||
|
||||
static struct clockdomain ducati_44xx_clkdm = {
|
||||
.name = "ducati_clkdm",
|
||||
.pwrdm = { .name = "core_pwrdm" },
|
||||
.clkstctrl_reg = OMAP4430_CM_DUCATI_CLKSTCTRL,
|
||||
.clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
|
||||
.flags = CLKDM_CAN_HWSUP_SWSUP,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
};
|
||||
|
||||
static struct clockdomain l3_2_44xx_clkdm = {
|
||||
.name = "l3_2_clkdm",
|
||||
.pwrdm = { .name = "core_pwrdm" },
|
||||
.clkstctrl_reg = OMAP4430_CM_L3_2_CLKSTCTRL,
|
||||
.clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
|
||||
.flags = CLKDM_CAN_HWSUP,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
};
|
||||
|
||||
static struct clockdomain l3_1_44xx_clkdm = {
|
||||
.name = "l3_1_clkdm",
|
||||
.pwrdm = { .name = "core_pwrdm" },
|
||||
.clkstctrl_reg = OMAP4430_CM_L3_1_CLKSTCTRL,
|
||||
.clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
|
||||
.flags = CLKDM_CAN_HWSUP,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
};
|
||||
|
||||
static struct clockdomain l3_d2d_44xx_clkdm = {
|
||||
.name = "l3_d2d_clkdm",
|
||||
.pwrdm = { .name = "core_pwrdm" },
|
||||
.clkstctrl_reg = OMAP4430_CM_D2D_CLKSTCTRL,
|
||||
.clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
|
||||
.flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
};
|
||||
|
||||
static struct clockdomain iss_44xx_clkdm = {
|
||||
.name = "iss_clkdm",
|
||||
.pwrdm = { .name = "cam_pwrdm" },
|
||||
.clkstctrl_reg = OMAP4430_CM_CAM_CLKSTCTRL,
|
||||
.clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
|
||||
.flags = CLKDM_CAN_HWSUP_SWSUP,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
};
|
||||
|
||||
static struct clockdomain l3_dss_44xx_clkdm = {
|
||||
.name = "l3_dss_clkdm",
|
||||
.pwrdm = { .name = "dss_pwrdm" },
|
||||
.clkstctrl_reg = OMAP4430_CM_DSS_CLKSTCTRL,
|
||||
.clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
|
||||
.flags = CLKDM_CAN_HWSUP_SWSUP,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
};
|
||||
|
||||
static struct clockdomain l4_wkup_44xx_clkdm = {
|
||||
.name = "l4_wkup_clkdm",
|
||||
.pwrdm = { .name = "wkup_pwrdm" },
|
||||
.clkstctrl_reg = OMAP4430_CM_WKUP_CLKSTCTRL,
|
||||
.clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
|
||||
.flags = CLKDM_CAN_HWSUP,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
};
|
||||
|
||||
static struct clockdomain emu_sys_44xx_clkdm = {
|
||||
.name = "emu_sys_clkdm",
|
||||
.pwrdm = { .name = "emu_pwrdm" },
|
||||
.clkstctrl_reg = OMAP4430_CM_EMU_CLKSTCTRL,
|
||||
.clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
|
||||
.flags = CLKDM_CAN_HWSUP,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
};
|
||||
|
||||
static struct clockdomain l3_dma_44xx_clkdm = {
|
||||
.name = "l3_dma_clkdm",
|
||||
.pwrdm = { .name = "core_pwrdm" },
|
||||
.clkstctrl_reg = OMAP4430_CM_SDMA_CLKSTCTRL,
|
||||
.clktrctrl_mask = OMAP4430_CLKTRCTRL_MASK,
|
||||
.flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -67,7 +67,8 @@
|
|||
#define CM_CLKSEL 0x0040
|
||||
#define CM_CLKSEL1 CM_CLKSEL
|
||||
#define CM_CLKSEL2 0x0044
|
||||
#define CM_CLKSTCTRL 0x0048
|
||||
#define OMAP2_CM_CLKSTCTRL 0x0048
|
||||
#define OMAP4_CM_CLKSTCTRL 0x0000
|
||||
|
||||
|
||||
/* Architecture-specific registers */
|
||||
|
@ -88,7 +89,7 @@
|
|||
#define OMAP3430_CM_CLKSEL1_PLL CM_CLKSEL
|
||||
#define OMAP3430_CM_CLKSEL2_PLL CM_CLKSEL2
|
||||
#define OMAP3430_CM_SLEEPDEP CM_CLKSEL2
|
||||
#define OMAP3430_CM_CLKSEL3 CM_CLKSTCTRL
|
||||
#define OMAP3430_CM_CLKSEL3 OMAP2_CM_CLKSTCTRL
|
||||
#define OMAP3430_CM_CLKSTST 0x004c
|
||||
#define OMAP3430ES2_CM_CLKSEL4 0x004c
|
||||
#define OMAP3430ES2_CM_CLKSEL5 0x0050
|
||||
|
|
|
@ -44,17 +44,7 @@
|
|||
|
||||
#define MAX_DPLL_WAIT_TRIES 1000000
|
||||
|
||||
|
||||
/**
|
||||
* omap3_dpll_recalc - recalculate DPLL rate
|
||||
* @clk: DPLL struct clk
|
||||
*
|
||||
* Recalculate and propagate the DPLL rate.
|
||||
*/
|
||||
unsigned long omap3_dpll_recalc(struct clk *clk)
|
||||
{
|
||||
return omap2_get_dpll_rate(clk);
|
||||
}
|
||||
/* Private functions */
|
||||
|
||||
/* _omap3_dpll_write_clken - write clken_bits arg to a DPLL's enable bits */
|
||||
static void _omap3_dpll_write_clken(struct clk *clk, u8 clken_bits)
|
||||
|
@ -136,8 +126,6 @@ static u16 _omap3_dpll_compute_freqsel(struct clk *clk, u8 n)
|
|||
return f;
|
||||
}
|
||||
|
||||
/* Non-CORE DPLL (e.g., DPLLs that do not control SDRC) clock functions */
|
||||
|
||||
/*
|
||||
* _omap3_noncore_dpll_lock - instruct a DPLL to lock and wait for readiness
|
||||
* @clk: pointer to a DPLL struct clk
|
||||
|
@ -237,6 +225,63 @@ static int _omap3_noncore_dpll_stop(struct clk *clk)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* _omap3_noncore_dpll_program - set non-core DPLL M,N values directly
|
||||
* @clk: struct clk * of DPLL to set
|
||||
* @m: DPLL multiplier to set
|
||||
* @n: DPLL divider to set
|
||||
* @freqsel: FREQSEL value to set
|
||||
*
|
||||
* Program the DPLL with the supplied M, N values, and wait for the DPLL to
|
||||
* lock.. Returns -EINVAL upon error, or 0 upon success.
|
||||
*/
|
||||
static int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel)
|
||||
{
|
||||
struct dpll_data *dd = clk->dpll_data;
|
||||
u32 v;
|
||||
|
||||
/* 3430 ES2 TRM: 4.7.6.9 DPLL Programming Sequence */
|
||||
_omap3_noncore_dpll_bypass(clk);
|
||||
|
||||
/* Set jitter correction */
|
||||
if (!cpu_is_omap44xx()) {
|
||||
v = __raw_readl(dd->control_reg);
|
||||
v &= ~dd->freqsel_mask;
|
||||
v |= freqsel << __ffs(dd->freqsel_mask);
|
||||
__raw_writel(v, dd->control_reg);
|
||||
}
|
||||
|
||||
/* Set DPLL multiplier, divider */
|
||||
v = __raw_readl(dd->mult_div1_reg);
|
||||
v &= ~(dd->mult_mask | dd->div1_mask);
|
||||
v |= m << __ffs(dd->mult_mask);
|
||||
v |= (n - 1) << __ffs(dd->div1_mask);
|
||||
__raw_writel(v, dd->mult_div1_reg);
|
||||
|
||||
/* We let the clock framework set the other output dividers later */
|
||||
|
||||
/* REVISIT: Set ramp-up delay? */
|
||||
|
||||
_omap3_noncore_dpll_lock(clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Public functions */
|
||||
|
||||
/**
|
||||
* omap3_dpll_recalc - recalculate DPLL rate
|
||||
* @clk: DPLL struct clk
|
||||
*
|
||||
* Recalculate and propagate the DPLL rate.
|
||||
*/
|
||||
unsigned long omap3_dpll_recalc(struct clk *clk)
|
||||
{
|
||||
return omap2_get_dpll_rate(clk);
|
||||
}
|
||||
|
||||
/* Non-CORE DPLL (e.g., DPLLs that do not control SDRC) clock functions */
|
||||
|
||||
/**
|
||||
* omap3_noncore_dpll_enable - instruct a DPLL to enter bypass or lock mode
|
||||
* @clk: pointer to a DPLL struct clk
|
||||
|
@ -292,48 +337,6 @@ void omap3_noncore_dpll_disable(struct clk *clk)
|
|||
|
||||
/* Non-CORE DPLL rate set code */
|
||||
|
||||
/*
|
||||
* omap3_noncore_dpll_program - set non-core DPLL M,N values directly
|
||||
* @clk: struct clk * of DPLL to set
|
||||
* @m: DPLL multiplier to set
|
||||
* @n: DPLL divider to set
|
||||
* @freqsel: FREQSEL value to set
|
||||
*
|
||||
* Program the DPLL with the supplied M, N values, and wait for the DPLL to
|
||||
* lock.. Returns -EINVAL upon error, or 0 upon success.
|
||||
*/
|
||||
int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel)
|
||||
{
|
||||
struct dpll_data *dd = clk->dpll_data;
|
||||
u32 v;
|
||||
|
||||
/* 3430 ES2 TRM: 4.7.6.9 DPLL Programming Sequence */
|
||||
_omap3_noncore_dpll_bypass(clk);
|
||||
|
||||
/* Set jitter correction */
|
||||
if (!cpu_is_omap44xx()) {
|
||||
v = __raw_readl(dd->control_reg);
|
||||
v &= ~dd->freqsel_mask;
|
||||
v |= freqsel << __ffs(dd->freqsel_mask);
|
||||
__raw_writel(v, dd->control_reg);
|
||||
}
|
||||
|
||||
/* Set DPLL multiplier, divider */
|
||||
v = __raw_readl(dd->mult_div1_reg);
|
||||
v &= ~(dd->mult_mask | dd->div1_mask);
|
||||
v |= m << __ffs(dd->mult_mask);
|
||||
v |= (n - 1) << __ffs(dd->div1_mask);
|
||||
__raw_writel(v, dd->mult_div1_reg);
|
||||
|
||||
/* We let the clock framework set the other output dividers later */
|
||||
|
||||
/* REVISIT: Set ramp-up delay? */
|
||||
|
||||
_omap3_noncore_dpll_lock(clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap3_noncore_dpll_set_rate - set non-core DPLL rate
|
||||
* @clk: struct clk * of DPLL to set
|
|
@ -281,6 +281,7 @@ void __init omap4_check_revision(void)
|
|||
|
||||
if ((hawkeye == 0xb852) && (rev == 0x0)) {
|
||||
omap_revision = OMAP4430_REV_ES1_0;
|
||||
omap_chip.oc |= CHIP_IS_OMAP4430ES1;
|
||||
pr_info("OMAP%04x %s\n", omap_rev() >> 16, rev_name);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -35,7 +35,9 @@
|
|||
#include <plat/serial.h>
|
||||
#include <plat/vram.h>
|
||||
|
||||
#include "clock.h"
|
||||
#include "clock2xxx.h"
|
||||
#include "clock34xx.h"
|
||||
#include "clock44xx.h"
|
||||
|
||||
#include <plat/omap-pm.h>
|
||||
#include <plat/powerdomain.h>
|
||||
|
@ -312,15 +314,24 @@ void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
|
|||
else if (cpu_is_omap34xx())
|
||||
hwmods = omap34xx_hwmods;
|
||||
|
||||
pwrdm_init(powerdomains_omap);
|
||||
clkdm_init(clockdomains_omap, clkdm_autodeps);
|
||||
#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once the clkdev is ready */
|
||||
/* The OPP tables have to be registered before a clk init */
|
||||
omap_hwmod_init(hwmods);
|
||||
omap2_mux_init();
|
||||
omap_pm_if_early_init(mpu_opps, dsp_opps, l3_opps);
|
||||
pwrdm_init(powerdomains_omap);
|
||||
clkdm_init(clockdomains_omap, clkdm_pwrdm_autodeps);
|
||||
#endif
|
||||
omap2_clk_init();
|
||||
|
||||
if (cpu_is_omap24xx())
|
||||
omap2xxx_clk_init();
|
||||
else if (cpu_is_omap34xx())
|
||||
omap3xxx_clk_init();
|
||||
else if (cpu_is_omap44xx())
|
||||
omap4xxx_clk_init();
|
||||
else
|
||||
pr_err("Could not init clock framework - unknown CPU\n");
|
||||
|
||||
omap_serial_early_init();
|
||||
#ifndef CONFIG_ARCH_OMAP4
|
||||
omap_hwmod_late_init();
|
||||
|
|
|
@ -299,15 +299,14 @@ static int _disable_wakeup(struct omap_hwmod *oh)
|
|||
* be accessed by the IVA, there should be a sleepdep between the IVA
|
||||
* initiator and the module). Only applies to modules in smart-idle
|
||||
* mode. Returns -EINVAL upon error or passes along
|
||||
* pwrdm_add_sleepdep() value upon success.
|
||||
* clkdm_add_sleepdep() value upon success.
|
||||
*/
|
||||
static int _add_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
|
||||
{
|
||||
if (!oh->_clk)
|
||||
return -EINVAL;
|
||||
|
||||
return pwrdm_add_sleepdep(oh->_clk->clkdm->pwrdm.ptr,
|
||||
init_oh->_clk->clkdm->pwrdm.ptr);
|
||||
return clkdm_add_sleepdep(oh->_clk->clkdm, init_oh->_clk->clkdm);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -320,15 +319,14 @@ static int _add_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
|
|||
* be accessed by the IVA, there should be no sleepdep between the IVA
|
||||
* initiator and the module). Only applies to modules in smart-idle
|
||||
* mode. Returns -EINVAL upon error or passes along
|
||||
* pwrdm_add_sleepdep() value upon success.
|
||||
* clkdm_del_sleepdep() value upon success.
|
||||
*/
|
||||
static int _del_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
|
||||
{
|
||||
if (!oh->_clk)
|
||||
return -EINVAL;
|
||||
|
||||
return pwrdm_del_sleepdep(oh->_clk->clkdm->pwrdm.ptr,
|
||||
init_oh->_clk->clkdm->pwrdm.ptr);
|
||||
return clkdm_del_sleepdep(oh->_clk->clkdm, init_oh->_clk->clkdm);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -994,6 +992,23 @@ void omap_hwmod_writel(u32 v, struct omap_hwmod *oh, u16 reg_offs)
|
|||
__raw_writel(v, oh->_rt_va + reg_offs);
|
||||
}
|
||||
|
||||
int omap_hwmod_set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode)
|
||||
{
|
||||
u32 v;
|
||||
int retval = 0;
|
||||
|
||||
if (!oh)
|
||||
return -EINVAL;
|
||||
|
||||
v = oh->_sysc_cache;
|
||||
|
||||
retval = _set_slave_idlemode(oh, idlemode, &v);
|
||||
if (!retval)
|
||||
_write_sysconfig(v, oh);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap_hwmod_register - register a struct omap_hwmod
|
||||
* @oh: struct omap_hwmod *
|
||||
|
|
|
@ -67,9 +67,9 @@ void omap2_pm_dump(int mode, int resume, unsigned int us)
|
|||
#if 0
|
||||
/* MPU */
|
||||
DUMP_PRM_MOD_REG(OCP_MOD, OMAP2_PRM_IRQENABLE_MPU_OFFSET);
|
||||
DUMP_CM_MOD_REG(MPU_MOD, CM_CLKSTCTRL);
|
||||
DUMP_PRM_MOD_REG(MPU_MOD, PM_PWSTCTRL);
|
||||
DUMP_PRM_MOD_REG(MPU_MOD, PM_PWSTST);
|
||||
DUMP_CM_MOD_REG(MPU_MOD, OMAP2_CM_CLKSTCTRL);
|
||||
DUMP_PRM_MOD_REG(MPU_MOD, OMAP2_PM_PWSTCTRL);
|
||||
DUMP_PRM_MOD_REG(MPU_MOD, OMAP2_PM_PWSTST);
|
||||
DUMP_PRM_MOD_REG(MPU_MOD, PM_WKDEP);
|
||||
#endif
|
||||
#if 0
|
||||
|
@ -93,7 +93,7 @@ void omap2_pm_dump(int mode, int resume, unsigned int us)
|
|||
DUMP_CM_MOD_REG(WKUP_MOD, CM_ICLKEN);
|
||||
DUMP_CM_MOD_REG(PLL_MOD, CM_CLKEN);
|
||||
DUMP_CM_MOD_REG(PLL_MOD, CM_AUTOIDLE);
|
||||
DUMP_PRM_MOD_REG(CORE_MOD, PM_PWSTST);
|
||||
DUMP_PRM_MOD_REG(CORE_MOD, OMAP2_PM_PWSTST);
|
||||
#endif
|
||||
#if 0
|
||||
/* DSP */
|
||||
|
@ -103,11 +103,11 @@ void omap2_pm_dump(int mode, int resume, unsigned int us)
|
|||
DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_IDLEST);
|
||||
DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_AUTOIDLE);
|
||||
DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_CLKSEL);
|
||||
DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_CLKSTCTRL);
|
||||
DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, RM_RSTCTRL);
|
||||
DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, RM_RSTST);
|
||||
DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, PM_PWSTCTRL);
|
||||
DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, PM_PWSTST);
|
||||
DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, OMAP2_CM_CLKSTCTRL);
|
||||
DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, OMAP2_RM_RSTCTRL);
|
||||
DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, OMAP2_RM_RSTST);
|
||||
DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, OMAP2_PM_PWSTCTRL);
|
||||
DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, OMAP2_PM_PWSTST);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
|
@ -577,7 +577,7 @@ static int __init pm_dbg_init(void)
|
|||
(void) debugfs_create_file("time", S_IRUGO,
|
||||
d, (void *)DEBUG_FILE_TIMERS, &debug_fops);
|
||||
|
||||
pwrdm_for_each_nolock(pwrdms_setup, (void *)d);
|
||||
pwrdm_for_each(pwrdms_setup, (void *)d);
|
||||
|
||||
pm_dbg_dir = debugfs_create_dir("registers", d);
|
||||
if (IS_ERR(pm_dbg_dir))
|
||||
|
|
|
@ -57,11 +57,8 @@ static void (*omap2_sram_idle)(void);
|
|||
static void (*omap2_sram_suspend)(u32 dllctrl, void __iomem *sdrc_dlla_ctrl,
|
||||
void __iomem *sdrc_power);
|
||||
|
||||
static struct powerdomain *mpu_pwrdm;
|
||||
static struct powerdomain *core_pwrdm;
|
||||
|
||||
static struct clockdomain *dsp_clkdm;
|
||||
static struct clockdomain *gfx_clkdm;
|
||||
static struct powerdomain *mpu_pwrdm, *core_pwrdm;
|
||||
static struct clockdomain *dsp_clkdm, *mpu_clkdm, *wkup_clkdm, *gfx_clkdm;
|
||||
|
||||
static struct clk *osc_ck, *emul_ck;
|
||||
|
||||
|
@ -219,11 +216,12 @@ static void omap2_enter_mpu_retention(void)
|
|||
/* Try to enter MPU retention */
|
||||
prm_write_mod_reg((0x01 << OMAP_POWERSTATE_SHIFT) |
|
||||
OMAP_LOGICRETSTATE,
|
||||
MPU_MOD, PM_PWSTCTRL);
|
||||
MPU_MOD, OMAP2_PM_PWSTCTRL);
|
||||
} else {
|
||||
/* Block MPU retention */
|
||||
|
||||
prm_write_mod_reg(OMAP_LOGICRETSTATE, MPU_MOD, PM_PWSTCTRL);
|
||||
prm_write_mod_reg(OMAP_LOGICRETSTATE, MPU_MOD,
|
||||
OMAP2_PM_PWSTCTRL);
|
||||
only_idle = 1;
|
||||
}
|
||||
|
||||
|
@ -333,9 +331,17 @@ static struct platform_suspend_ops omap_pm_ops = {
|
|||
.valid = suspend_valid_only_mem,
|
||||
};
|
||||
|
||||
static int _pm_clkdm_enable_hwsup(struct clockdomain *clkdm, void *unused)
|
||||
/* XXX This function should be shareable between OMAP2xxx and OMAP3 */
|
||||
static int __init clkdms_setup(struct clockdomain *clkdm, void *unused)
|
||||
{
|
||||
omap2_clkdm_allow_idle(clkdm);
|
||||
clkdm_clear_all_wkdeps(clkdm);
|
||||
clkdm_clear_all_sleepdeps(clkdm);
|
||||
|
||||
if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO)
|
||||
omap2_clkdm_allow_idle(clkdm);
|
||||
else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
|
||||
atomic_read(&clkdm->usecount) == 0)
|
||||
omap2_clkdm_sleep(clkdm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -348,14 +354,6 @@ static void __init prcm_setup_regs(void)
|
|||
prm_write_mod_reg(OMAP24XX_AUTOIDLE, OCP_MOD,
|
||||
OMAP2_PRCM_SYSCONFIG_OFFSET);
|
||||
|
||||
/* Set all domain wakeup dependencies */
|
||||
prm_write_mod_reg(OMAP_EN_WKUP_MASK, MPU_MOD, PM_WKDEP);
|
||||
prm_write_mod_reg(0, OMAP24XX_DSP_MOD, PM_WKDEP);
|
||||
prm_write_mod_reg(0, GFX_MOD, PM_WKDEP);
|
||||
prm_write_mod_reg(0, CORE_MOD, PM_WKDEP);
|
||||
if (cpu_is_omap2430())
|
||||
prm_write_mod_reg(0, OMAP2430_MDM_MOD, PM_WKDEP);
|
||||
|
||||
/*
|
||||
* Set CORE powerdomain memory banks to retain their contents
|
||||
* during RETENTION
|
||||
|
@ -384,8 +382,12 @@ static void __init prcm_setup_regs(void)
|
|||
pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF);
|
||||
omap2_clkdm_sleep(gfx_clkdm);
|
||||
|
||||
/* Enable clockdomain hardware-supervised control for all clkdms */
|
||||
clkdm_for_each(_pm_clkdm_enable_hwsup, NULL);
|
||||
/*
|
||||
* Clear clockdomain wakeup dependencies and enable
|
||||
* hardware-supervised idle for all clkdms
|
||||
*/
|
||||
clkdm_for_each(clkdms_setup, NULL);
|
||||
clkdm_add_wkdep(mpu_clkdm, wkup_clkdm);
|
||||
|
||||
/* Enable clock autoidle for all domains */
|
||||
cm_write_mod_reg(OMAP24XX_AUTO_CAM |
|
||||
|
@ -481,7 +483,7 @@ static int __init omap2_pm_init(void)
|
|||
l = prm_read_mod_reg(OCP_MOD, OMAP2_PRCM_REVISION_OFFSET);
|
||||
printk(KERN_INFO "PRCM revision %d.%d\n", (l >> 4) & 0x0f, l & 0x0f);
|
||||
|
||||
/* Look up important powerdomains, clockdomains */
|
||||
/* Look up important powerdomains */
|
||||
|
||||
mpu_pwrdm = pwrdm_lookup("mpu_pwrdm");
|
||||
if (!mpu_pwrdm)
|
||||
|
@ -491,9 +493,19 @@ static int __init omap2_pm_init(void)
|
|||
if (!core_pwrdm)
|
||||
pr_err("PM: core_pwrdm not found\n");
|
||||
|
||||
/* Look up important clockdomains */
|
||||
|
||||
mpu_clkdm = clkdm_lookup("mpu_clkdm");
|
||||
if (!mpu_clkdm)
|
||||
pr_err("PM: mpu_clkdm not found\n");
|
||||
|
||||
wkup_clkdm = clkdm_lookup("wkup_clkdm");
|
||||
if (!wkup_clkdm)
|
||||
pr_err("PM: wkup_clkdm not found\n");
|
||||
|
||||
dsp_clkdm = clkdm_lookup("dsp_clkdm");
|
||||
if (!dsp_clkdm)
|
||||
pr_err("PM: mpu_clkdm not found\n");
|
||||
pr_err("PM: dsp_clkdm not found\n");
|
||||
|
||||
gfx_clkdm = clkdm_lookup("gfx_clkdm");
|
||||
if (!gfx_clkdm)
|
||||
|
|
|
@ -685,7 +685,7 @@ static void __init omap3_iva_idle(void)
|
|||
prm_write_mod_reg(OMAP3430_RST1_IVA2 |
|
||||
OMAP3430_RST2_IVA2 |
|
||||
OMAP3430_RST3_IVA2,
|
||||
OMAP3430_IVA2_MOD, RM_RSTCTRL);
|
||||
OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
|
||||
|
||||
/* Enable IVA2 clock */
|
||||
cm_write_mod_reg(OMAP3430_CM_FCLKEN_IVA2_EN_IVA2,
|
||||
|
@ -696,7 +696,7 @@ static void __init omap3_iva_idle(void)
|
|||
OMAP343X_CONTROL_IVA2_BOOTMOD);
|
||||
|
||||
/* Un-reset IVA2 */
|
||||
prm_write_mod_reg(0, OMAP3430_IVA2_MOD, RM_RSTCTRL);
|
||||
prm_write_mod_reg(0, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
|
||||
|
||||
/* Disable IVA2 clock */
|
||||
cm_write_mod_reg(0, OMAP3430_IVA2_MOD, CM_FCLKEN);
|
||||
|
@ -705,7 +705,7 @@ static void __init omap3_iva_idle(void)
|
|||
prm_write_mod_reg(OMAP3430_RST1_IVA2 |
|
||||
OMAP3430_RST2_IVA2 |
|
||||
OMAP3430_RST3_IVA2,
|
||||
OMAP3430_IVA2_MOD, RM_RSTCTRL);
|
||||
OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
|
||||
}
|
||||
|
||||
static void __init omap3_d2d_idle(void)
|
||||
|
@ -728,8 +728,8 @@ static void __init omap3_d2d_idle(void)
|
|||
/* reset modem */
|
||||
prm_write_mod_reg(OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RSTPWRON |
|
||||
OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RST,
|
||||
CORE_MOD, RM_RSTCTRL);
|
||||
prm_write_mod_reg(0, CORE_MOD, RM_RSTCTRL);
|
||||
CORE_MOD, OMAP2_RM_RSTCTRL);
|
||||
prm_write_mod_reg(0, CORE_MOD, OMAP2_RM_RSTCTRL);
|
||||
}
|
||||
|
||||
static void __init prcm_setup_regs(void)
|
||||
|
@ -916,13 +916,13 @@ static void __init prcm_setup_regs(void)
|
|||
prm_write_mod_reg(0, OMAP3430_PER_MOD, OMAP3430_PM_IVAGRPSEL);
|
||||
|
||||
/* Clear any pending 'reset' flags */
|
||||
prm_write_mod_reg(0xffffffff, MPU_MOD, RM_RSTST);
|
||||
prm_write_mod_reg(0xffffffff, CORE_MOD, RM_RSTST);
|
||||
prm_write_mod_reg(0xffffffff, OMAP3430_PER_MOD, RM_RSTST);
|
||||
prm_write_mod_reg(0xffffffff, OMAP3430_EMU_MOD, RM_RSTST);
|
||||
prm_write_mod_reg(0xffffffff, OMAP3430_NEON_MOD, RM_RSTST);
|
||||
prm_write_mod_reg(0xffffffff, OMAP3430_DSS_MOD, RM_RSTST);
|
||||
prm_write_mod_reg(0xffffffff, OMAP3430ES2_USBHOST_MOD, RM_RSTST);
|
||||
prm_write_mod_reg(0xffffffff, MPU_MOD, OMAP2_RM_RSTST);
|
||||
prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP2_RM_RSTST);
|
||||
prm_write_mod_reg(0xffffffff, OMAP3430_PER_MOD, OMAP2_RM_RSTST);
|
||||
prm_write_mod_reg(0xffffffff, OMAP3430_EMU_MOD, OMAP2_RM_RSTST);
|
||||
prm_write_mod_reg(0xffffffff, OMAP3430_NEON_MOD, OMAP2_RM_RSTST);
|
||||
prm_write_mod_reg(0xffffffff, OMAP3430_DSS_MOD, OMAP2_RM_RSTST);
|
||||
prm_write_mod_reg(0xffffffff, OMAP3430ES2_USBHOST_MOD, OMAP2_RM_RSTST);
|
||||
|
||||
/* Clear any pending PRCM interrupts */
|
||||
prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
|
||||
|
@ -998,6 +998,9 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
|
|||
*/
|
||||
static int __init clkdms_setup(struct clockdomain *clkdm, void *unused)
|
||||
{
|
||||
clkdm_clear_all_wkdeps(clkdm);
|
||||
clkdm_clear_all_sleepdeps(clkdm);
|
||||
|
||||
if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO)
|
||||
omap2_clkdm_allow_idle(clkdm);
|
||||
else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
|
||||
|
@ -1018,6 +1021,7 @@ void omap_push_sram_idle(void)
|
|||
static int __init omap3_pm_init(void)
|
||||
{
|
||||
struct power_state *pwrst, *tmp;
|
||||
struct clockdomain *neon_clkdm, *per_clkdm, *mpu_clkdm, *core_clkdm;
|
||||
int ret;
|
||||
|
||||
if (!cpu_is_omap34xx())
|
||||
|
@ -1057,6 +1061,11 @@ static int __init omap3_pm_init(void)
|
|||
core_pwrdm = pwrdm_lookup("core_pwrdm");
|
||||
cam_pwrdm = pwrdm_lookup("cam_pwrdm");
|
||||
|
||||
neon_clkdm = clkdm_lookup("neon_clkdm");
|
||||
mpu_clkdm = clkdm_lookup("mpu_clkdm");
|
||||
per_clkdm = clkdm_lookup("per_clkdm");
|
||||
core_clkdm = clkdm_lookup("core_clkdm");
|
||||
|
||||
omap_push_sram_idle();
|
||||
#ifdef CONFIG_SUSPEND
|
||||
suspend_set_ops(&omap_pm_ops);
|
||||
|
@ -1065,14 +1074,14 @@ static int __init omap3_pm_init(void)
|
|||
pm_idle = omap3_pm_idle;
|
||||
omap3_idle_init();
|
||||
|
||||
pwrdm_add_wkdep(neon_pwrdm, mpu_pwrdm);
|
||||
clkdm_add_wkdep(neon_clkdm, mpu_clkdm);
|
||||
/*
|
||||
* REVISIT: This wkdep is only necessary when GPIO2-6 are enabled for
|
||||
* IO-pad wakeup. Otherwise it will unnecessarily waste power
|
||||
* waking up PER with every CORE wakeup - see
|
||||
* http://marc.info/?l=linux-omap&m=121852150710062&w=2
|
||||
*/
|
||||
pwrdm_add_wkdep(per_pwrdm, core_pwrdm);
|
||||
clkdm_add_wkdep(per_clkdm, core_clkdm);
|
||||
|
||||
if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
|
||||
omap3_secure_ram_storage =
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* OMAP2/3 common powerdomain definitions
|
||||
*
|
||||
* Copyright (C) 2007-8 Texas Instruments, Inc.
|
||||
* Copyright (C) 2007-8 Nokia Corporation
|
||||
* Copyright (C) 2007-2008 Texas Instruments, Inc.
|
||||
* Copyright (C) 2007-2009 Nokia Corporation
|
||||
*
|
||||
* Written by Paul Walmsley
|
||||
* Debugging and integration fixes by Jouni Högander
|
||||
|
@ -12,26 +12,21 @@
|
|||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
/*
|
||||
* To Do List
|
||||
* -> Move the Sleep/Wakeup dependencies from Power Domain framework to
|
||||
* Clock Domain Framework
|
||||
*/
|
||||
|
||||
#ifndef ARCH_ARM_MACH_OMAP2_POWERDOMAINS
|
||||
#define ARCH_ARM_MACH_OMAP2_POWERDOMAINS
|
||||
|
||||
/*
|
||||
* This file contains all of the powerdomains that have some element
|
||||
* of software control for the OMAP24xx and OMAP34XX chips.
|
||||
*
|
||||
* A few notes:
|
||||
* of software control for the OMAP24xx and OMAP34xx chips.
|
||||
*
|
||||
* This is not an exhaustive listing of powerdomains on the chips; only
|
||||
* powerdomains that can be controlled in software.
|
||||
*
|
||||
* A useful validation rule for struct powerdomain:
|
||||
* Any powerdomain referenced by a wkdep_srcs or sleepdep_srcs array
|
||||
* must have a dep_bit assigned. So wkdep_srcs/sleepdep_srcs are really
|
||||
* just software-controllable dependencies. Non-software-controllable
|
||||
* dependencies do exist, but they are not encoded below (yet).
|
||||
*
|
||||
* 24xx does not support programmable sleep dependencies (SLEEPDEP)
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -41,26 +36,17 @@
|
|||
*
|
||||
* On the 2420, this is a 'C55 DSP called, simply, the DSP. Its
|
||||
* powerdomain is called the "DSP power domain." On the 2430, the
|
||||
* on-board DSP is a 'C64 DSP, now called the IVA2 or IVA2.1. Its
|
||||
* powerdomain is still called the "DSP power domain." On the 3430,
|
||||
* the DSP is a 'C64 DSP like the 2430, also known as the IVA2; but
|
||||
* its powerdomain is now called the "IVA2 power domain."
|
||||
* on-board DSP is a 'C64 DSP, now called (along with its hardware
|
||||
* accelerators) the IVA2 or IVA2.1. Its powerdomain is still called
|
||||
* the "DSP power domain." On the 3430, the DSP is a 'C64 DSP like the
|
||||
* 2430, also known as the IVA2; but its powerdomain is now called the
|
||||
* "IVA2 power domain."
|
||||
*
|
||||
* The 2420 also has something called the IVA, which is a separate ARM
|
||||
* core, and has nothing to do with the DSP/IVA2.
|
||||
*
|
||||
* Ideally the DSP/IVA2 could just be the same powerdomain, but the PRCM
|
||||
* address offset is different between the C55 and C64 DSPs.
|
||||
*
|
||||
* The overly-specific dep_bit names are due to a bit name collision
|
||||
* with CM_FCLKEN_{DSP,IVA2}. The DSP/IVA2 PM_WKDEP and CM_SLEEPDEP shift
|
||||
* value are the same for all powerdomains: 2
|
||||
*/
|
||||
|
||||
/*
|
||||
* XXX should dep_bit be a mask, so we can test to see if it is 0 as a
|
||||
* sanity check?
|
||||
* XXX encode hardware fixed wakeup dependencies -- esp. for 3430 CORE
|
||||
*/
|
||||
|
||||
#include <plat/powerdomain.h>
|
||||
|
@ -68,69 +54,23 @@
|
|||
#include "prcm-common.h"
|
||||
#include "prm.h"
|
||||
#include "cm.h"
|
||||
|
||||
/* OMAP2/3-common powerdomains and wakeup dependencies */
|
||||
|
||||
/*
|
||||
* 2420/2430 PM_WKDEP_GFX: CORE, MPU, WKUP
|
||||
* 3430ES1 PM_WKDEP_GFX: adds IVA2, removes CORE
|
||||
* 3430ES2 PM_WKDEP_SGX: adds IVA2, removes CORE
|
||||
*/
|
||||
static struct pwrdm_dep gfx_sgx_wkdeps[] = {
|
||||
{
|
||||
.pwrdm_name = "core_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
|
||||
},
|
||||
{
|
||||
.pwrdm_name = "iva2_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.pwrdm_name = "mpu_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX |
|
||||
CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.pwrdm_name = "wkup_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX |
|
||||
CHIP_IS_OMAP3430)
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
/*
|
||||
* 3430: CM_SLEEPDEP_CAM: MPU
|
||||
* 3430ES1: CM_SLEEPDEP_GFX: MPU
|
||||
* 3430ES2: CM_SLEEPDEP_SGX: MPU
|
||||
*/
|
||||
static struct pwrdm_dep cam_gfx_sleepdeps[] = {
|
||||
{
|
||||
.pwrdm_name = "mpu_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
|
||||
#include "powerdomains24xx.h"
|
||||
#include "powerdomains34xx.h"
|
||||
#include "powerdomains44xx.h"
|
||||
|
||||
/* OMAP2/3-common powerdomains */
|
||||
|
||||
/*
|
||||
* OMAP2/3 common powerdomains
|
||||
*/
|
||||
#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
|
||||
|
||||
/*
|
||||
* The GFX powerdomain is not present on 3430ES2, but currently we do not
|
||||
* have a macro to filter it out at compile-time.
|
||||
*/
|
||||
static struct powerdomain gfx_pwrdm = {
|
||||
static struct powerdomain gfx_omap2_pwrdm = {
|
||||
.name = "gfx_pwrdm",
|
||||
.prcm_offs = GFX_MOD,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX |
|
||||
CHIP_IS_OMAP3430ES1),
|
||||
.wkdep_srcs = gfx_sgx_wkdeps,
|
||||
.sleepdep_srcs = cam_gfx_sleepdeps,
|
||||
.pwrsts = PWRSTS_OFF_RET_ON,
|
||||
.pwrsts_logic_ret = PWRDM_POWER_RET,
|
||||
.banks = 1,
|
||||
|
@ -142,22 +82,24 @@ static struct powerdomain gfx_pwrdm = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct powerdomain wkup_pwrdm = {
|
||||
static struct powerdomain wkup_omap2_pwrdm = {
|
||||
.name = "wkup_pwrdm",
|
||||
.prcm_offs = WKUP_MOD,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430),
|
||||
.dep_bit = OMAP_EN_WKUP_SHIFT,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* As powerdomains are added or removed above, this list must also be changed */
|
||||
static struct powerdomain *powerdomains_omap[] __initdata = {
|
||||
|
||||
&gfx_pwrdm,
|
||||
&wkup_pwrdm,
|
||||
#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
|
||||
&wkup_omap2_pwrdm,
|
||||
&gfx_omap2_pwrdm,
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP24XX
|
||||
#ifdef CONFIG_ARCH_OMAP2
|
||||
&dsp_pwrdm,
|
||||
&mpu_24xx_pwrdm,
|
||||
&core_24xx_pwrdm,
|
||||
|
@ -167,12 +109,12 @@ static struct powerdomain *powerdomains_omap[] __initdata = {
|
|||
&mdm_pwrdm,
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP34XX
|
||||
#ifdef CONFIG_ARCH_OMAP3
|
||||
&iva2_pwrdm,
|
||||
&mpu_34xx_pwrdm,
|
||||
&mpu_3xxx_pwrdm,
|
||||
&neon_pwrdm,
|
||||
&core_34xx_pre_es3_1_pwrdm,
|
||||
&core_34xx_es3_1_pwrdm,
|
||||
&core_3xxx_pre_es3_1_pwrdm,
|
||||
&core_3xxx_es3_1_pwrdm,
|
||||
&cam_pwrdm,
|
||||
&dss_pwrdm,
|
||||
&per_pwrdm,
|
||||
|
@ -186,6 +128,24 @@ static struct powerdomain *powerdomains_omap[] __initdata = {
|
|||
&dpll5_pwrdm,
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP4
|
||||
&core_44xx_pwrdm,
|
||||
&gfx_44xx_pwrdm,
|
||||
&abe_44xx_pwrdm,
|
||||
&dss_44xx_pwrdm,
|
||||
&tesla_44xx_pwrdm,
|
||||
&wkup_44xx_pwrdm,
|
||||
&cpu0_44xx_pwrdm,
|
||||
&cpu1_44xx_pwrdm,
|
||||
&emu_44xx_pwrdm,
|
||||
&mpu_44xx_pwrdm,
|
||||
&ivahd_44xx_pwrdm,
|
||||
&cam_44xx_pwrdm,
|
||||
&l3init_44xx_pwrdm,
|
||||
&l4per_44xx_pwrdm,
|
||||
&always_on_core_44xx_pwrdm,
|
||||
&cefuse_44xx_pwrdm,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* OMAP24XX powerdomain definitions
|
||||
*
|
||||
* Copyright (C) 2007-2008 Texas Instruments, Inc.
|
||||
* Copyright (C) 2007-2008 Nokia Corporation
|
||||
* Copyright (C) 2007-2009 Nokia Corporation
|
||||
*
|
||||
* Written by Paul Walmsley
|
||||
* Debugging and integration fixes by Jouni Högander
|
||||
|
@ -32,90 +32,12 @@
|
|||
|
||||
#ifdef CONFIG_ARCH_OMAP24XX
|
||||
|
||||
|
||||
/* Wakeup dependency source arrays */
|
||||
|
||||
/*
|
||||
* 2420/2430 PM_WKDEP_DSP: CORE, MPU, WKUP
|
||||
* 2430 PM_WKDEP_MDM: same as above
|
||||
*/
|
||||
static struct pwrdm_dep dsp_mdm_24xx_wkdeps[] = {
|
||||
{
|
||||
.pwrdm_name = "core_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
|
||||
},
|
||||
{
|
||||
.pwrdm_name = "mpu_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
|
||||
},
|
||||
{
|
||||
.pwrdm_name = "wkup_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
/*
|
||||
* 2420 PM_WKDEP_MPU: CORE, DSP, WKUP
|
||||
* 2430 adds MDM
|
||||
*/
|
||||
static struct pwrdm_dep mpu_24xx_wkdeps[] = {
|
||||
{
|
||||
.pwrdm_name = "core_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
|
||||
},
|
||||
{
|
||||
.pwrdm_name = "dsp_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
|
||||
},
|
||||
{
|
||||
.pwrdm_name = "wkup_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
|
||||
},
|
||||
{
|
||||
.pwrdm_name = "mdm_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
/*
|
||||
* 2420 PM_WKDEP_CORE: DSP, GFX, MPU, WKUP
|
||||
* 2430 adds MDM
|
||||
*/
|
||||
static struct pwrdm_dep core_24xx_wkdeps[] = {
|
||||
{
|
||||
.pwrdm_name = "dsp_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
|
||||
},
|
||||
{
|
||||
.pwrdm_name = "gfx_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
|
||||
},
|
||||
{
|
||||
.pwrdm_name = "mpu_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
|
||||
},
|
||||
{
|
||||
.pwrdm_name = "wkup_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
|
||||
},
|
||||
{
|
||||
.pwrdm_name = "mdm_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
|
||||
/* Powerdomains */
|
||||
|
||||
static struct powerdomain dsp_pwrdm = {
|
||||
.name = "dsp_pwrdm",
|
||||
.prcm_offs = OMAP24XX_DSP_MOD,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
|
||||
.dep_bit = OMAP24XX_PM_WKDEP_MPU_EN_DSP_SHIFT,
|
||||
.wkdep_srcs = dsp_mdm_24xx_wkdeps,
|
||||
.pwrsts = PWRSTS_OFF_RET_ON,
|
||||
.pwrsts_logic_ret = PWRDM_POWER_RET,
|
||||
.banks = 1,
|
||||
|
@ -131,8 +53,6 @@ static struct powerdomain mpu_24xx_pwrdm = {
|
|||
.name = "mpu_pwrdm",
|
||||
.prcm_offs = MPU_MOD,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
|
||||
.dep_bit = OMAP24XX_EN_MPU_SHIFT,
|
||||
.wkdep_srcs = mpu_24xx_wkdeps,
|
||||
.pwrsts = PWRSTS_OFF_RET_ON,
|
||||
.pwrsts_logic_ret = PWRSTS_OFF_RET,
|
||||
.banks = 1,
|
||||
|
@ -148,9 +68,7 @@ static struct powerdomain core_24xx_pwrdm = {
|
|||
.name = "core_pwrdm",
|
||||
.prcm_offs = CORE_MOD,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
|
||||
.wkdep_srcs = core_24xx_wkdeps,
|
||||
.pwrsts = PWRSTS_OFF_RET_ON,
|
||||
.dep_bit = OMAP24XX_EN_CORE_SHIFT,
|
||||
.banks = 3,
|
||||
.pwrsts_mem_ret = {
|
||||
[0] = PWRSTS_OFF_RET, /* MEM1RETSTATE */
|
||||
|
@ -176,13 +94,10 @@ static struct powerdomain core_24xx_pwrdm = {
|
|||
|
||||
/* XXX 2430 KILLDOMAINWKUP bit? No current users apparently */
|
||||
|
||||
/* Another case of bit name collisions between several registers: EN_MDM */
|
||||
static struct powerdomain mdm_pwrdm = {
|
||||
.name = "mdm_pwrdm",
|
||||
.prcm_offs = OMAP2430_MDM_MOD,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
|
||||
.dep_bit = OMAP2430_PM_WKDEP_MPU_EN_MDM_SHIFT,
|
||||
.wkdep_srcs = dsp_mdm_24xx_wkdeps,
|
||||
.pwrsts = PWRSTS_OFF_RET_ON,
|
||||
.pwrsts_logic_ret = PWRDM_POWER_RET,
|
||||
.banks = 1,
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* OMAP34XX powerdomain definitions
|
||||
* OMAP3 powerdomain definitions
|
||||
*
|
||||
* Copyright (C) 2007-2008 Texas Instruments, Inc.
|
||||
* Copyright (C) 2007-2008 Nokia Corporation
|
||||
* Copyright (C) 2007-2010 Nokia Corporation
|
||||
*
|
||||
* Written by Paul Walmsley
|
||||
* Debugging and integration fixes by Jouni Högander
|
||||
|
@ -32,128 +32,7 @@
|
|||
* 34XX-specific powerdomains, dependencies
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP34XX
|
||||
|
||||
/*
|
||||
* 3430: PM_WKDEP_{PER,USBHOST}: CORE, IVA2, MPU, WKUP
|
||||
* (USBHOST is ES2 only)
|
||||
*/
|
||||
static struct pwrdm_dep per_usbhost_wkdeps[] = {
|
||||
{
|
||||
.pwrdm_name = "core_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.pwrdm_name = "iva2_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.pwrdm_name = "mpu_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.pwrdm_name = "wkup_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
/*
|
||||
* 3430 PM_WKDEP_MPU: CORE, IVA2, DSS, PER
|
||||
*/
|
||||
static struct pwrdm_dep mpu_34xx_wkdeps[] = {
|
||||
{
|
||||
.pwrdm_name = "core_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.pwrdm_name = "iva2_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.pwrdm_name = "dss_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.pwrdm_name = "per_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
/*
|
||||
* 3430 PM_WKDEP_IVA2: CORE, MPU, WKUP, DSS, PER
|
||||
*/
|
||||
static struct pwrdm_dep iva2_wkdeps[] = {
|
||||
{
|
||||
.pwrdm_name = "core_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.pwrdm_name = "mpu_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.pwrdm_name = "wkup_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.pwrdm_name = "dss_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.pwrdm_name = "per_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
|
||||
/* 3430 PM_WKDEP_{CAM,DSS}: IVA2, MPU, WKUP */
|
||||
static struct pwrdm_dep cam_dss_wkdeps[] = {
|
||||
{
|
||||
.pwrdm_name = "iva2_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.pwrdm_name = "mpu_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.pwrdm_name = "wkup_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
/* 3430: PM_WKDEP_NEON: MPU */
|
||||
static struct pwrdm_dep neon_wkdeps[] = {
|
||||
{
|
||||
.pwrdm_name = "mpu_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
|
||||
/* Sleep dependency source arrays for 34xx-specific pwrdms - 34XX only */
|
||||
|
||||
/*
|
||||
* 3430: CM_SLEEPDEP_{DSS,PER}: MPU, IVA
|
||||
* 3430ES2: CM_SLEEPDEP_USBHOST: MPU, IVA
|
||||
*/
|
||||
static struct pwrdm_dep dss_per_usbhost_sleepdeps[] = {
|
||||
{
|
||||
.pwrdm_name = "mpu_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{
|
||||
.pwrdm_name = "iva2_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP3
|
||||
|
||||
/*
|
||||
* Powerdomains
|
||||
|
@ -163,8 +42,6 @@ static struct powerdomain iva2_pwrdm = {
|
|||
.name = "iva2_pwrdm",
|
||||
.prcm_offs = OMAP3430_IVA2_MOD,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
|
||||
.dep_bit = OMAP3430_PM_WKDEP_MPU_EN_IVA2_SHIFT,
|
||||
.wkdep_srcs = iva2_wkdeps,
|
||||
.pwrsts = PWRSTS_OFF_RET_ON,
|
||||
.pwrsts_logic_ret = PWRSTS_OFF_RET,
|
||||
.banks = 4,
|
||||
|
@ -182,12 +59,10 @@ static struct powerdomain iva2_pwrdm = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct powerdomain mpu_34xx_pwrdm = {
|
||||
static struct powerdomain mpu_3xxx_pwrdm = {
|
||||
.name = "mpu_pwrdm",
|
||||
.prcm_offs = MPU_MOD,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
|
||||
.dep_bit = OMAP3430_EN_MPU_SHIFT,
|
||||
.wkdep_srcs = mpu_34xx_wkdeps,
|
||||
.pwrsts = PWRSTS_OFF_RET_ON,
|
||||
.pwrsts_logic_ret = PWRSTS_OFF_RET,
|
||||
.flags = PWRDM_HAS_MPU_QUIRK,
|
||||
|
@ -200,15 +75,13 @@ static struct powerdomain mpu_34xx_pwrdm = {
|
|||
},
|
||||
};
|
||||
|
||||
/* No wkdeps or sleepdeps for 34xx core apparently */
|
||||
static struct powerdomain core_34xx_pre_es3_1_pwrdm = {
|
||||
static struct powerdomain core_3xxx_pre_es3_1_pwrdm = {
|
||||
.name = "core_pwrdm",
|
||||
.prcm_offs = CORE_MOD,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1 |
|
||||
CHIP_IS_OMAP3430ES2 |
|
||||
CHIP_IS_OMAP3430ES3_0),
|
||||
.pwrsts = PWRSTS_OFF_RET_ON,
|
||||
.dep_bit = OMAP3430_EN_CORE_SHIFT,
|
||||
.banks = 2,
|
||||
.pwrsts_mem_ret = {
|
||||
[0] = PWRSTS_OFF_RET, /* MEM1RETSTATE */
|
||||
|
@ -220,13 +93,11 @@ static struct powerdomain core_34xx_pre_es3_1_pwrdm = {
|
|||
},
|
||||
};
|
||||
|
||||
/* No wkdeps or sleepdeps for 34xx core apparently */
|
||||
static struct powerdomain core_34xx_es3_1_pwrdm = {
|
||||
static struct powerdomain core_3xxx_es3_1_pwrdm = {
|
||||
.name = "core_pwrdm",
|
||||
.prcm_offs = CORE_MOD,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES3_1),
|
||||
.pwrsts = PWRSTS_OFF_RET_ON,
|
||||
.dep_bit = OMAP3430_EN_CORE_SHIFT,
|
||||
.flags = PWRDM_HAS_HDWR_SAR, /* for USBTLL only */
|
||||
.banks = 2,
|
||||
.pwrsts_mem_ret = {
|
||||
|
@ -239,14 +110,10 @@ static struct powerdomain core_34xx_es3_1_pwrdm = {
|
|||
},
|
||||
};
|
||||
|
||||
/* Another case of bit name collisions between several registers: EN_DSS */
|
||||
static struct powerdomain dss_pwrdm = {
|
||||
.name = "dss_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
|
||||
.prcm_offs = OMAP3430_DSS_MOD,
|
||||
.dep_bit = OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT,
|
||||
.wkdep_srcs = cam_dss_wkdeps,
|
||||
.sleepdep_srcs = dss_per_usbhost_sleepdeps,
|
||||
.pwrsts = PWRSTS_OFF_RET_ON,
|
||||
.pwrsts_logic_ret = PWRDM_POWER_RET,
|
||||
.banks = 1,
|
||||
|
@ -267,8 +134,6 @@ static struct powerdomain sgx_pwrdm = {
|
|||
.name = "sgx_pwrdm",
|
||||
.prcm_offs = OMAP3430ES2_SGX_MOD,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
|
||||
.wkdep_srcs = gfx_sgx_wkdeps,
|
||||
.sleepdep_srcs = cam_gfx_sleepdeps,
|
||||
/* XXX This is accurate for 3430 SGX, but what about GFX? */
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.pwrsts_logic_ret = PWRDM_POWER_RET,
|
||||
|
@ -285,8 +150,6 @@ static struct powerdomain cam_pwrdm = {
|
|||
.name = "cam_pwrdm",
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
|
||||
.prcm_offs = OMAP3430_CAM_MOD,
|
||||
.wkdep_srcs = cam_dss_wkdeps,
|
||||
.sleepdep_srcs = cam_gfx_sleepdeps,
|
||||
.pwrsts = PWRSTS_OFF_RET_ON,
|
||||
.pwrsts_logic_ret = PWRDM_POWER_RET,
|
||||
.banks = 1,
|
||||
|
@ -302,9 +165,6 @@ static struct powerdomain per_pwrdm = {
|
|||
.name = "per_pwrdm",
|
||||
.prcm_offs = OMAP3430_PER_MOD,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
|
||||
.dep_bit = OMAP3430_EN_PER_SHIFT,
|
||||
.wkdep_srcs = per_usbhost_wkdeps,
|
||||
.sleepdep_srcs = dss_per_usbhost_sleepdeps,
|
||||
.pwrsts = PWRSTS_OFF_RET_ON,
|
||||
.pwrsts_logic_ret = PWRSTS_OFF_RET,
|
||||
.banks = 1,
|
||||
|
@ -326,7 +186,6 @@ static struct powerdomain neon_pwrdm = {
|
|||
.name = "neon_pwrdm",
|
||||
.prcm_offs = OMAP3430_NEON_MOD,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
|
||||
.wkdep_srcs = neon_wkdeps,
|
||||
.pwrsts = PWRSTS_OFF_RET_ON,
|
||||
.pwrsts_logic_ret = PWRDM_POWER_RET,
|
||||
};
|
||||
|
@ -335,8 +194,6 @@ static struct powerdomain usbhost_pwrdm = {
|
|||
.name = "usbhost_pwrdm",
|
||||
.prcm_offs = OMAP3430ES2_USBHOST_MOD,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
|
||||
.wkdep_srcs = per_usbhost_wkdeps,
|
||||
.sleepdep_srcs = dss_per_usbhost_sleepdeps,
|
||||
.pwrsts = PWRSTS_OFF_RET_ON,
|
||||
.pwrsts_logic_ret = PWRDM_POWER_RET,
|
||||
/*
|
||||
|
@ -386,7 +243,7 @@ static struct powerdomain dpll5_pwrdm = {
|
|||
};
|
||||
|
||||
|
||||
#endif /* CONFIG_ARCH_OMAP34XX */
|
||||
#endif /* CONFIG_ARCH_OMAP3 */
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,310 @@
|
|||
/*
|
||||
* OMAP4 Power domains framework
|
||||
*
|
||||
* Copyright (C) 2009 Texas Instruments, Inc.
|
||||
* Copyright (C) 2009 Nokia Corporation
|
||||
*
|
||||
* Abhijit Pagare (abhijitpagare@ti.com)
|
||||
* Benoit Cousson (b-cousson@ti.com)
|
||||
* Paul Walmsley
|
||||
*
|
||||
* This file is automatically generated from the OMAP hardware databases.
|
||||
* We respectfully ask that any modifications to this file be coordinated
|
||||
* with the public linux-omap@vger.kernel.org mailing list and the
|
||||
* authors above to ensure that the autogeneration scripts are kept
|
||||
* up-to-date with the file contents.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ARM_MACH_OMAP2_POWERDOMAINS44XX_H
|
||||
#define __ARCH_ARM_MACH_OMAP2_POWERDOMAINS44XX_H
|
||||
|
||||
#include <plat/powerdomain.h>
|
||||
|
||||
#include "prcm-common.h"
|
||||
#include "cm.h"
|
||||
#include "cm-regbits-44xx.h"
|
||||
#include "prm.h"
|
||||
#include "prm-regbits-44xx.h"
|
||||
|
||||
#if defined(CONFIG_ARCH_OMAP4)
|
||||
|
||||
/* core_44xx_pwrdm: CORE power domain */
|
||||
static struct powerdomain core_44xx_pwrdm = {
|
||||
.name = "core_pwrdm",
|
||||
.prcm_offs = OMAP4430_PRM_CORE_MOD,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
.pwrsts = PWRSTS_RET_ON,
|
||||
.pwrsts_logic_ret = PWRSTS_OFF_RET,
|
||||
.banks = 5,
|
||||
.pwrsts_mem_ret = {
|
||||
[0] = PWRDM_POWER_OFF, /* core_nret_bank */
|
||||
[1] = PWRSTS_OFF_RET, /* core_ocmram */
|
||||
[2] = PWRDM_POWER_RET, /* core_other_bank */
|
||||
[3] = PWRSTS_OFF_RET, /* ducati_l2ram */
|
||||
[4] = PWRSTS_OFF_RET, /* ducati_unicache */
|
||||
},
|
||||
.pwrsts_mem_on = {
|
||||
[0] = PWRDM_POWER_ON, /* core_nret_bank */
|
||||
[1] = PWRSTS_OFF_RET, /* core_ocmram */
|
||||
[2] = PWRDM_POWER_ON, /* core_other_bank */
|
||||
[3] = PWRDM_POWER_ON, /* ducati_l2ram */
|
||||
[4] = PWRDM_POWER_ON, /* ducati_unicache */
|
||||
},
|
||||
};
|
||||
|
||||
/* gfx_44xx_pwrdm: 3D accelerator power domain */
|
||||
static struct powerdomain gfx_44xx_pwrdm = {
|
||||
.name = "gfx_pwrdm",
|
||||
.prcm_offs = OMAP4430_PRM_GFX_MOD,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.banks = 1,
|
||||
.pwrsts_mem_ret = {
|
||||
[0] = PWRDM_POWER_OFF, /* gfx_mem */
|
||||
},
|
||||
.pwrsts_mem_on = {
|
||||
[0] = PWRDM_POWER_ON, /* gfx_mem */
|
||||
},
|
||||
};
|
||||
|
||||
/* abe_44xx_pwrdm: Audio back end power domain */
|
||||
static struct powerdomain abe_44xx_pwrdm = {
|
||||
.name = "abe_pwrdm",
|
||||
.prcm_offs = OMAP4430_PRM_ABE_MOD,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
.pwrsts = PWRSTS_OFF_RET_ON,
|
||||
.pwrsts_logic_ret = PWRDM_POWER_OFF,
|
||||
.banks = 2,
|
||||
.pwrsts_mem_ret = {
|
||||
[0] = PWRDM_POWER_RET, /* aessmem */
|
||||
[1] = PWRDM_POWER_OFF, /* periphmem */
|
||||
},
|
||||
.pwrsts_mem_on = {
|
||||
[0] = PWRDM_POWER_ON, /* aessmem */
|
||||
[1] = PWRDM_POWER_ON, /* periphmem */
|
||||
},
|
||||
};
|
||||
|
||||
/* dss_44xx_pwrdm: Display subsystem power domain */
|
||||
static struct powerdomain dss_44xx_pwrdm = {
|
||||
.name = "dss_pwrdm",
|
||||
.prcm_offs = OMAP4430_PRM_DSS_MOD,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
.pwrsts = PWRSTS_OFF_RET_ON,
|
||||
.pwrsts_logic_ret = PWRSTS_OFF_RET,
|
||||
.banks = 1,
|
||||
.pwrsts_mem_ret = {
|
||||
[0] = PWRDM_POWER_OFF, /* dss_mem */
|
||||
},
|
||||
.pwrsts_mem_on = {
|
||||
[0] = PWRDM_POWER_ON, /* dss_mem */
|
||||
},
|
||||
};
|
||||
|
||||
/* tesla_44xx_pwrdm: Tesla processor power domain */
|
||||
static struct powerdomain tesla_44xx_pwrdm = {
|
||||
.name = "tesla_pwrdm",
|
||||
.prcm_offs = OMAP4430_PRM_TESLA_MOD,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
.pwrsts = PWRSTS_OFF_RET_ON,
|
||||
.pwrsts_logic_ret = PWRSTS_OFF_RET,
|
||||
.banks = 3,
|
||||
.pwrsts_mem_ret = {
|
||||
[0] = PWRDM_POWER_RET, /* tesla_edma */
|
||||
[1] = PWRSTS_OFF_RET, /* tesla_l1 */
|
||||
[2] = PWRSTS_OFF_RET, /* tesla_l2 */
|
||||
},
|
||||
.pwrsts_mem_on = {
|
||||
[0] = PWRDM_POWER_ON, /* tesla_edma */
|
||||
[1] = PWRDM_POWER_ON, /* tesla_l1 */
|
||||
[2] = PWRDM_POWER_ON, /* tesla_l2 */
|
||||
},
|
||||
};
|
||||
|
||||
/* wkup_44xx_pwrdm: Wake-up power domain */
|
||||
static struct powerdomain wkup_44xx_pwrdm = {
|
||||
.name = "wkup_pwrdm",
|
||||
.prcm_offs = OMAP4430_PRM_WKUP_MOD,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
.pwrsts = PWRDM_POWER_ON,
|
||||
.banks = 1,
|
||||
.pwrsts_mem_ret = {
|
||||
[0] = PWRDM_POWER_OFF, /* wkup_bank */
|
||||
},
|
||||
.pwrsts_mem_on = {
|
||||
[0] = PWRDM_POWER_ON, /* wkup_bank */
|
||||
},
|
||||
};
|
||||
|
||||
/* cpu0_44xx_pwrdm: MPU0 processor and Neon coprocessor power domain */
|
||||
static struct powerdomain cpu0_44xx_pwrdm = {
|
||||
.name = "cpu0_pwrdm",
|
||||
.prcm_offs = OMAP4430_CHIRONSS_CHIRONSS_CPU0_MOD,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
.pwrsts = PWRSTS_OFF_RET_ON,
|
||||
.pwrsts_logic_ret = PWRSTS_OFF_RET,
|
||||
.banks = 1,
|
||||
.pwrsts_mem_ret = {
|
||||
[0] = PWRSTS_OFF_RET, /* cpu0_l1 */
|
||||
},
|
||||
.pwrsts_mem_on = {
|
||||
[0] = PWRDM_POWER_ON, /* cpu0_l1 */
|
||||
},
|
||||
};
|
||||
|
||||
/* cpu1_44xx_pwrdm: MPU1 processor and Neon coprocessor power domain */
|
||||
static struct powerdomain cpu1_44xx_pwrdm = {
|
||||
.name = "cpu1_pwrdm",
|
||||
.prcm_offs = OMAP4430_CHIRONSS_CHIRONSS_CPU1_MOD,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
.pwrsts = PWRSTS_OFF_RET_ON,
|
||||
.pwrsts_logic_ret = PWRSTS_OFF_RET,
|
||||
.banks = 1,
|
||||
.pwrsts_mem_ret = {
|
||||
[0] = PWRSTS_OFF_RET, /* cpu1_l1 */
|
||||
},
|
||||
.pwrsts_mem_on = {
|
||||
[0] = PWRDM_POWER_ON, /* cpu1_l1 */
|
||||
},
|
||||
};
|
||||
|
||||
/* emu_44xx_pwrdm: Emulation power domain */
|
||||
static struct powerdomain emu_44xx_pwrdm = {
|
||||
.name = "emu_pwrdm",
|
||||
.prcm_offs = OMAP4430_PRM_EMU_MOD,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.banks = 1,
|
||||
.pwrsts_mem_ret = {
|
||||
[0] = PWRDM_POWER_OFF, /* emu_bank */
|
||||
},
|
||||
.pwrsts_mem_on = {
|
||||
[0] = PWRDM_POWER_ON, /* emu_bank */
|
||||
},
|
||||
};
|
||||
|
||||
/* mpu_44xx_pwrdm: Modena processor and the Neon coprocessor power domain */
|
||||
static struct powerdomain mpu_44xx_pwrdm = {
|
||||
.name = "mpu_pwrdm",
|
||||
.prcm_offs = OMAP4430_PRM_MPU_MOD,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
.pwrsts = PWRSTS_OFF_RET_ON,
|
||||
.pwrsts_logic_ret = PWRSTS_OFF_RET,
|
||||
.banks = 3,
|
||||
.pwrsts_mem_ret = {
|
||||
[0] = PWRSTS_OFF_RET, /* mpu_l1 */
|
||||
[1] = PWRSTS_OFF_RET, /* mpu_l2 */
|
||||
[2] = PWRDM_POWER_RET, /* mpu_ram */
|
||||
},
|
||||
.pwrsts_mem_on = {
|
||||
[0] = PWRDM_POWER_ON, /* mpu_l1 */
|
||||
[1] = PWRDM_POWER_ON, /* mpu_l2 */
|
||||
[2] = PWRDM_POWER_ON, /* mpu_ram */
|
||||
},
|
||||
};
|
||||
|
||||
/* ivahd_44xx_pwrdm: IVA-HD power domain */
|
||||
static struct powerdomain ivahd_44xx_pwrdm = {
|
||||
.name = "ivahd_pwrdm",
|
||||
.prcm_offs = OMAP4430_PRM_IVAHD_MOD,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
.pwrsts = PWRSTS_OFF_RET_ON,
|
||||
.pwrsts_logic_ret = PWRDM_POWER_OFF,
|
||||
.banks = 4,
|
||||
.pwrsts_mem_ret = {
|
||||
[0] = PWRDM_POWER_OFF, /* hwa_mem */
|
||||
[1] = PWRSTS_OFF_RET, /* sl2_mem */
|
||||
[2] = PWRSTS_OFF_RET, /* tcm1_mem */
|
||||
[3] = PWRSTS_OFF_RET, /* tcm2_mem */
|
||||
},
|
||||
.pwrsts_mem_on = {
|
||||
[0] = PWRDM_POWER_ON, /* hwa_mem */
|
||||
[1] = PWRDM_POWER_ON, /* sl2_mem */
|
||||
[2] = PWRDM_POWER_ON, /* tcm1_mem */
|
||||
[3] = PWRDM_POWER_ON, /* tcm2_mem */
|
||||
},
|
||||
};
|
||||
|
||||
/* cam_44xx_pwrdm: Camera subsystem power domain */
|
||||
static struct powerdomain cam_44xx_pwrdm = {
|
||||
.name = "cam_pwrdm",
|
||||
.prcm_offs = OMAP4430_PRM_CAM_MOD,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.banks = 1,
|
||||
.pwrsts_mem_ret = {
|
||||
[0] = PWRDM_POWER_OFF, /* cam_mem */
|
||||
},
|
||||
.pwrsts_mem_on = {
|
||||
[0] = PWRDM_POWER_ON, /* cam_mem */
|
||||
},
|
||||
};
|
||||
|
||||
/* l3init_44xx_pwrdm: L3 initators pheripherals power domain */
|
||||
static struct powerdomain l3init_44xx_pwrdm = {
|
||||
.name = "l3init_pwrdm",
|
||||
.prcm_offs = OMAP4430_PRM_L3INIT_MOD,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
.pwrsts = PWRSTS_OFF_RET_ON,
|
||||
.pwrsts_logic_ret = PWRSTS_OFF_RET,
|
||||
.banks = 1,
|
||||
.pwrsts_mem_ret = {
|
||||
[0] = PWRDM_POWER_OFF, /* l3init_bank1 */
|
||||
},
|
||||
.pwrsts_mem_on = {
|
||||
[0] = PWRDM_POWER_ON, /* l3init_bank1 */
|
||||
},
|
||||
};
|
||||
|
||||
/* l4per_44xx_pwrdm: Target peripherals power domain */
|
||||
static struct powerdomain l4per_44xx_pwrdm = {
|
||||
.name = "l4per_pwrdm",
|
||||
.prcm_offs = OMAP4430_PRM_L4PER_MOD,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
.pwrsts = PWRSTS_OFF_RET_ON,
|
||||
.pwrsts_logic_ret = PWRSTS_OFF_RET,
|
||||
.banks = 2,
|
||||
.pwrsts_mem_ret = {
|
||||
[0] = PWRDM_POWER_OFF, /* nonretained_bank */
|
||||
[1] = PWRDM_POWER_RET, /* retained_bank */
|
||||
},
|
||||
.pwrsts_mem_on = {
|
||||
[0] = PWRDM_POWER_ON, /* nonretained_bank */
|
||||
[1] = PWRDM_POWER_ON, /* retained_bank */
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* always_on_core_44xx_pwrdm: Always ON logic that sits in VDD_CORE voltage
|
||||
* domain
|
||||
*/
|
||||
static struct powerdomain always_on_core_44xx_pwrdm = {
|
||||
.name = "always_on_core_pwrdm",
|
||||
.prcm_offs = OMAP4430_PRM_ALWAYS_ON_MOD,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
.pwrsts = PWRDM_POWER_ON,
|
||||
};
|
||||
|
||||
/* cefuse_44xx_pwrdm: Customer efuse controller power domain */
|
||||
static struct powerdomain cefuse_44xx_pwrdm = {
|
||||
.name = "cefuse_pwrdm",
|
||||
.prcm_offs = OMAP4430_PRM_CEFUSE_MOD,
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
/*
|
||||
* The following power domains are not under SW control
|
||||
*
|
||||
* always_on_iva
|
||||
* always_on_mpu
|
||||
* stdefuse
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -119,6 +119,15 @@
|
|||
#define OMAP4430_CHIRONSS_CHIRONSS_CPU0_MOD 0x0400
|
||||
#define OMAP4430_CHIRONSS_CHIRONSS_CPU1_MOD 0x0800
|
||||
|
||||
/* Base Addresses for the OMAP4 */
|
||||
|
||||
#define OMAP4430_CM1_BASE 0x4a004000
|
||||
#define OMAP4430_CM2_BASE 0x4a008000
|
||||
#define OMAP4430_PRM_BASE 0x4a306000
|
||||
#define OMAP4430_SCRM_BASE 0x4a30a000
|
||||
#define OMAP4430_CHIRONSS_BASE 0x48243000
|
||||
|
||||
|
||||
/* 24XX register bits shared between CM & PRM registers */
|
||||
|
||||
/* CM_FCLKEN1_CORE, CM_ICLKEN1_CORE, PM_WKEN1_CORE shared bits */
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
* Rajendra Nayak <rnayak@ti.com>
|
||||
*
|
||||
* Some pieces of code Copyright (C) 2005 Texas Instruments, Inc.
|
||||
* Upgraded with OMAP4 support by Abhijit Pagare <abhijitpagare@ti.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
|
@ -28,6 +29,7 @@
|
|||
#include <plat/control.h>
|
||||
|
||||
#include "clock.h"
|
||||
#include "clock2xxx.h"
|
||||
#include "cm.h"
|
||||
#include "prm.h"
|
||||
#include "prm-regbits-24xx.h"
|
||||
|
@ -121,7 +123,10 @@ struct omap3_prcm_regs prcm_context;
|
|||
u32 omap_prcm_get_reset_sources(void)
|
||||
{
|
||||
/* XXX This presumably needs modification for 34XX */
|
||||
return prm_read_mod_reg(WKUP_MOD, RM_RSTST) & 0x7f;
|
||||
if (cpu_is_omap24xx() | cpu_is_omap34xx())
|
||||
return prm_read_mod_reg(WKUP_MOD, OMAP2_RM_RSTST) & 0x7f;
|
||||
if (cpu_is_omap44xx())
|
||||
return prm_read_mod_reg(WKUP_MOD, OMAP4_RM_RSTST) & 0x7f;
|
||||
}
|
||||
EXPORT_SYMBOL(omap_prcm_get_reset_sources);
|
||||
|
||||
|
@ -129,11 +134,12 @@ EXPORT_SYMBOL(omap_prcm_get_reset_sources);
|
|||
void omap_prcm_arch_reset(char mode)
|
||||
{
|
||||
s16 prcm_offs;
|
||||
omap2_clk_prepare_for_reboot();
|
||||
|
||||
if (cpu_is_omap24xx())
|
||||
if (cpu_is_omap24xx()) {
|
||||
omap2xxx_clk_prepare_for_reboot();
|
||||
|
||||
prcm_offs = WKUP_MOD;
|
||||
else if (cpu_is_omap34xx()) {
|
||||
} else if (cpu_is_omap34xx()) {
|
||||
u32 l;
|
||||
|
||||
prcm_offs = OMAP3430_GR_MOD;
|
||||
|
@ -144,10 +150,17 @@ void omap_prcm_arch_reset(char mode)
|
|||
* cf. OMAP34xx TRM, Initialization / Software Booting
|
||||
* Configuration. */
|
||||
omap_writel(l, OMAP343X_SCRATCHPAD + 4);
|
||||
} else
|
||||
} else if (cpu_is_omap44xx())
|
||||
prcm_offs = OMAP4430_PRM_DEVICE_MOD;
|
||||
else
|
||||
WARN_ON(1);
|
||||
|
||||
prm_set_mod_reg_bits(OMAP_RST_DPLL3, prcm_offs, RM_RSTCTRL);
|
||||
if (cpu_is_omap24xx() | cpu_is_omap34xx())
|
||||
prm_set_mod_reg_bits(OMAP_RST_DPLL3, prcm_offs,
|
||||
OMAP2_RM_RSTCTRL);
|
||||
if (cpu_is_omap44xx())
|
||||
prm_set_mod_reg_bits(OMAP_RST_DPLL3, prcm_offs,
|
||||
OMAP4_RM_RSTCTRL);
|
||||
}
|
||||
|
||||
static inline u32 __omap_prcm_read(void __iomem *base, s16 module, u16 reg)
|
||||
|
@ -188,6 +201,18 @@ u32 prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx)
|
|||
return v;
|
||||
}
|
||||
|
||||
/* Read a PRM register, AND it, and shift the result down to bit 0 */
|
||||
u32 prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask)
|
||||
{
|
||||
u32 v;
|
||||
|
||||
v = prm_read_mod_reg(domain, idx);
|
||||
v &= mask;
|
||||
v >>= __ffs(mask);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
/* Read a register in a CM module */
|
||||
u32 cm_read_mod_reg(s16 module, u16 idx)
|
||||
{
|
||||
|
@ -280,7 +305,7 @@ void omap3_prcm_save_context(void)
|
|||
prcm_context.emu_cm_clksel =
|
||||
cm_read_mod_reg(OMAP3430_EMU_MOD, CM_CLKSEL1);
|
||||
prcm_context.emu_cm_clkstctrl =
|
||||
cm_read_mod_reg(OMAP3430_EMU_MOD, CM_CLKSTCTRL);
|
||||
cm_read_mod_reg(OMAP3430_EMU_MOD, OMAP2_CM_CLKSTCTRL);
|
||||
prcm_context.pll_cm_autoidle2 =
|
||||
cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE2);
|
||||
prcm_context.pll_cm_clksel4 =
|
||||
|
@ -333,23 +358,25 @@ void omap3_prcm_save_context(void)
|
|||
prcm_context.mpu_cm_autoidle2 =
|
||||
cm_read_mod_reg(MPU_MOD, CM_AUTOIDLE2);
|
||||
prcm_context.iva2_cm_clkstctrl =
|
||||
cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSTCTRL);
|
||||
cm_read_mod_reg(OMAP3430_IVA2_MOD, OMAP2_CM_CLKSTCTRL);
|
||||
prcm_context.mpu_cm_clkstctrl =
|
||||
cm_read_mod_reg(MPU_MOD, CM_CLKSTCTRL);
|
||||
cm_read_mod_reg(MPU_MOD, OMAP2_CM_CLKSTCTRL);
|
||||
prcm_context.core_cm_clkstctrl =
|
||||
cm_read_mod_reg(CORE_MOD, CM_CLKSTCTRL);
|
||||
cm_read_mod_reg(CORE_MOD, OMAP2_CM_CLKSTCTRL);
|
||||
prcm_context.sgx_cm_clkstctrl =
|
||||
cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_CLKSTCTRL);
|
||||
cm_read_mod_reg(OMAP3430ES2_SGX_MOD,
|
||||
OMAP2_CM_CLKSTCTRL);
|
||||
prcm_context.dss_cm_clkstctrl =
|
||||
cm_read_mod_reg(OMAP3430_DSS_MOD, CM_CLKSTCTRL);
|
||||
cm_read_mod_reg(OMAP3430_DSS_MOD, OMAP2_CM_CLKSTCTRL);
|
||||
prcm_context.cam_cm_clkstctrl =
|
||||
cm_read_mod_reg(OMAP3430_CAM_MOD, CM_CLKSTCTRL);
|
||||
cm_read_mod_reg(OMAP3430_CAM_MOD, OMAP2_CM_CLKSTCTRL);
|
||||
prcm_context.per_cm_clkstctrl =
|
||||
cm_read_mod_reg(OMAP3430_PER_MOD, CM_CLKSTCTRL);
|
||||
cm_read_mod_reg(OMAP3430_PER_MOD, OMAP2_CM_CLKSTCTRL);
|
||||
prcm_context.neon_cm_clkstctrl =
|
||||
cm_read_mod_reg(OMAP3430_NEON_MOD, CM_CLKSTCTRL);
|
||||
cm_read_mod_reg(OMAP3430_NEON_MOD, OMAP2_CM_CLKSTCTRL);
|
||||
prcm_context.usbhost_cm_clkstctrl =
|
||||
cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_CLKSTCTRL);
|
||||
cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
|
||||
OMAP2_CM_CLKSTCTRL);
|
||||
prcm_context.core_cm_autoidle1 =
|
||||
cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE1);
|
||||
prcm_context.core_cm_autoidle2 =
|
||||
|
@ -432,7 +459,7 @@ void omap3_prcm_restore_context(void)
|
|||
cm_write_mod_reg(prcm_context.emu_cm_clksel, OMAP3430_EMU_MOD,
|
||||
CM_CLKSEL1);
|
||||
cm_write_mod_reg(prcm_context.emu_cm_clkstctrl, OMAP3430_EMU_MOD,
|
||||
CM_CLKSTCTRL);
|
||||
OMAP2_CM_CLKSTCTRL);
|
||||
cm_write_mod_reg(prcm_context.pll_cm_autoidle2, PLL_MOD,
|
||||
CM_AUTOIDLE2);
|
||||
cm_write_mod_reg(prcm_context.pll_cm_clksel4, PLL_MOD,
|
||||
|
@ -478,22 +505,23 @@ void omap3_prcm_restore_context(void)
|
|||
CM_AUTOIDLE2);
|
||||
cm_write_mod_reg(prcm_context.mpu_cm_autoidle2, MPU_MOD, CM_AUTOIDLE2);
|
||||
cm_write_mod_reg(prcm_context.iva2_cm_clkstctrl, OMAP3430_IVA2_MOD,
|
||||
CM_CLKSTCTRL);
|
||||
cm_write_mod_reg(prcm_context.mpu_cm_clkstctrl, MPU_MOD, CM_CLKSTCTRL);
|
||||
OMAP2_CM_CLKSTCTRL);
|
||||
cm_write_mod_reg(prcm_context.mpu_cm_clkstctrl, MPU_MOD,
|
||||
OMAP2_CM_CLKSTCTRL);
|
||||
cm_write_mod_reg(prcm_context.core_cm_clkstctrl, CORE_MOD,
|
||||
CM_CLKSTCTRL);
|
||||
OMAP2_CM_CLKSTCTRL);
|
||||
cm_write_mod_reg(prcm_context.sgx_cm_clkstctrl, OMAP3430ES2_SGX_MOD,
|
||||
CM_CLKSTCTRL);
|
||||
OMAP2_CM_CLKSTCTRL);
|
||||
cm_write_mod_reg(prcm_context.dss_cm_clkstctrl, OMAP3430_DSS_MOD,
|
||||
CM_CLKSTCTRL);
|
||||
OMAP2_CM_CLKSTCTRL);
|
||||
cm_write_mod_reg(prcm_context.cam_cm_clkstctrl, OMAP3430_CAM_MOD,
|
||||
CM_CLKSTCTRL);
|
||||
OMAP2_CM_CLKSTCTRL);
|
||||
cm_write_mod_reg(prcm_context.per_cm_clkstctrl, OMAP3430_PER_MOD,
|
||||
CM_CLKSTCTRL);
|
||||
OMAP2_CM_CLKSTCTRL);
|
||||
cm_write_mod_reg(prcm_context.neon_cm_clkstctrl, OMAP3430_NEON_MOD,
|
||||
CM_CLKSTCTRL);
|
||||
OMAP2_CM_CLKSTCTRL);
|
||||
cm_write_mod_reg(prcm_context.usbhost_cm_clkstctrl,
|
||||
OMAP3430ES2_USBHOST_MOD, CM_CLKSTCTRL);
|
||||
OMAP3430ES2_USBHOST_MOD, OMAP2_CM_CLKSTCTRL);
|
||||
cm_write_mod_reg(prcm_context.core_cm_autoidle1, CORE_MOD,
|
||||
CM_AUTOIDLE1);
|
||||
cm_write_mod_reg(prcm_context.core_cm_autoidle2, CORE_MOD,
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -179,9 +179,11 @@
|
|||
|
||||
/* Registers appearing on both 24xx and 34xx */
|
||||
|
||||
#define RM_RSTCTRL 0x0050
|
||||
#define RM_RSTTIME 0x0054
|
||||
#define RM_RSTST 0x0058
|
||||
#define OMAP2_RM_RSTCTRL 0x0050
|
||||
#define OMAP2_RM_RSTTIME 0x0054
|
||||
#define OMAP2_RM_RSTST 0x0058
|
||||
#define OMAP2_PM_PWSTCTRL 0x00e0
|
||||
#define OMAP2_PM_PWSTST 0x00e4
|
||||
|
||||
#define PM_WKEN 0x00a0
|
||||
#define PM_WKEN1 PM_WKEN
|
||||
|
@ -191,8 +193,6 @@
|
|||
#define PM_EVGENCTRL 0x00d4
|
||||
#define PM_EVGENONTIM 0x00d8
|
||||
#define PM_EVGENOFFTIM 0x00dc
|
||||
#define PM_PWSTCTRL 0x00e0
|
||||
#define PM_PWSTST 0x00e4
|
||||
|
||||
/* Omap2 specific registers */
|
||||
#define OMAP24XX_PM_WKEN2 0x00a4
|
||||
|
@ -220,6 +220,13 @@
|
|||
#define OMAP3430_PRM_IRQSTATUS_IVA2 0x00f8
|
||||
#define OMAP3430_PRM_IRQENABLE_IVA2 0x00fc
|
||||
|
||||
/* Omap4 specific registers */
|
||||
#define OMAP4_RM_RSTCTRL 0x0000
|
||||
#define OMAP4_RM_RSTTIME 0x0004
|
||||
#define OMAP4_RM_RSTST 0x0008
|
||||
#define OMAP4_PM_PWSTCTRL 0x0000
|
||||
#define OMAP4_PM_PWSTST 0x0004
|
||||
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
#define PM_PREPWSTST_CORE_P 0x48306AE8
|
||||
#define PM_PREPWSTST_MPU_V OMAP34XX_PRM_REGADDR(MPU_MOD, \
|
||||
OMAP3430_PM_PREPWSTST)
|
||||
#define PM_PWSTCTRL_MPU_P OMAP3430_PRM_BASE + MPU_MOD + PM_PWSTCTRL
|
||||
#define PM_PWSTCTRL_MPU_P OMAP3430_PRM_BASE + MPU_MOD + OMAP2_PM_PWSTCTRL
|
||||
#define CM_IDLEST1_CORE_V OMAP34XX_CM_REGADDR(CORE_MOD, CM_IDLEST1)
|
||||
#define SRAM_BASE_P 0x40200000
|
||||
#define CONTROL_STAT 0x480022F0
|
||||
|
|
|
@ -173,7 +173,7 @@ EXPORT_SYMBOL(clk_get_parent);
|
|||
* OMAP specific clock functions shared between omap1 and omap2
|
||||
*-------------------------------------------------------------------------*/
|
||||
|
||||
unsigned int __initdata mpurate;
|
||||
int __initdata mpurate;
|
||||
|
||||
/*
|
||||
* By default we use the rate set by the bootloader.
|
||||
|
@ -199,6 +199,17 @@ unsigned long followparent_recalc(struct clk *clk)
|
|||
return clk->parent->rate;
|
||||
}
|
||||
|
||||
/*
|
||||
* Used for clocks that have the same value as the parent clock,
|
||||
* divided by some factor
|
||||
*/
|
||||
unsigned long omap_fixed_divisor_recalc(struct clk *clk)
|
||||
{
|
||||
WARN_ON(!clk->fixed_div);
|
||||
|
||||
return clk->parent->rate / clk->fixed_div;
|
||||
}
|
||||
|
||||
void clk_reparent(struct clk *child, struct clk *parent)
|
||||
{
|
||||
list_del_init(&child->sibling);
|
||||
|
|
|
@ -25,17 +25,25 @@ struct omap_clk {
|
|||
}, \
|
||||
}
|
||||
|
||||
|
||||
/* Platform flags for the clkdev-OMAP integration code */
|
||||
#define CK_310 (1 << 0)
|
||||
#define CK_7XX (1 << 1)
|
||||
#define CK_7XX (1 << 1) /* 7xx, 850 */
|
||||
#define CK_1510 (1 << 2)
|
||||
#define CK_16XX (1 << 3)
|
||||
#define CK_243X (1 << 4)
|
||||
#define CK_242X (1 << 5)
|
||||
#define CK_343X (1 << 6)
|
||||
#define CK_3430ES1 (1 << 7)
|
||||
#define CK_3430ES2 (1 << 8)
|
||||
#define CK_443X (1 << 9)
|
||||
#define CK_16XX (1 << 3) /* 16xx, 17xx, 5912 */
|
||||
#define CK_242X (1 << 4)
|
||||
#define CK_243X (1 << 5)
|
||||
#define CK_3XXX (1 << 6) /* OMAP3 + AM3 common clocks*/
|
||||
#define CK_343X (1 << 7) /* OMAP34xx common clocks */
|
||||
#define CK_3430ES1 (1 << 8) /* 34xxES1 only */
|
||||
#define CK_3430ES2 (1 << 9) /* 34xxES2, ES3, non-Sitara 35xx only */
|
||||
#define CK_3505 (1 << 10)
|
||||
#define CK_3517 (1 << 11)
|
||||
#define CK_36XX (1 << 12) /* OMAP36xx/37xx-specific clocks */
|
||||
#define CK_443X (1 << 13)
|
||||
|
||||
#define CK_AM35XX (CK_3505 | CK_3517) /* all Sitara AM35xx */
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -88,9 +88,9 @@ struct clk {
|
|||
void (*init)(struct clk *);
|
||||
__u8 enable_bit;
|
||||
__s8 usecount;
|
||||
u8 fixed_div;
|
||||
#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
|
||||
defined(CONFIG_ARCH_OMAP4)
|
||||
u8 fixed_div;
|
||||
void __iomem *clksel_reg;
|
||||
u32 clksel_mask;
|
||||
const struct clksel *clksel;
|
||||
|
@ -123,7 +123,7 @@ struct clk_functions {
|
|||
#endif
|
||||
};
|
||||
|
||||
extern unsigned int mpurate;
|
||||
extern int mpurate;
|
||||
|
||||
extern int clk_init(struct clk_functions *custom_clocks);
|
||||
extern void clk_preinit(struct clk *clk);
|
||||
|
@ -134,6 +134,7 @@ extern void propagate_rate(struct clk *clk);
|
|||
extern void recalculate_root_clocks(void);
|
||||
extern unsigned long followparent_recalc(struct clk *clk);
|
||||
extern void clk_enable_init_clocks(void);
|
||||
unsigned long omap_fixed_divisor_recalc(struct clk *clk);
|
||||
#ifdef CONFIG_CPU_FREQ
|
||||
extern void clk_init_cpufreq_table(struct cpufreq_frequency_table **table);
|
||||
extern void clk_exit_cpufreq_table(struct cpufreq_frequency_table **table);
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* OMAP2/3 clockdomain framework functions
|
||||
*
|
||||
* Copyright (C) 2008 Texas Instruments, Inc.
|
||||
* Copyright (C) 2008 Nokia Corporation
|
||||
* Copyright (C) 2008-2009 Nokia Corporation
|
||||
*
|
||||
* Written by Paul Walmsley
|
||||
*
|
||||
|
@ -40,65 +40,95 @@
|
|||
#define OMAP34XX_CLKSTCTRL_FORCE_WAKEUP 0x2
|
||||
#define OMAP34XX_CLKSTCTRL_ENABLE_AUTO 0x3
|
||||
|
||||
/*
|
||||
* struct clkdm_pwrdm_autodep - a powerdomain that should have wkdeps
|
||||
* and sleepdeps added when a powerdomain should stay active in hwsup mode;
|
||||
* and conversely, removed when the powerdomain should be allowed to go
|
||||
* inactive in hwsup mode.
|
||||
/**
|
||||
* struct clkdm_autodep - clkdm deps to add when entering/exiting hwsup mode
|
||||
* @clkdm: clockdomain to add wkdep+sleepdep on - set name member only
|
||||
* @omap_chip: OMAP chip types that this autodep is valid on
|
||||
*
|
||||
* A clockdomain that should have wkdeps and sleepdeps added when a
|
||||
* clockdomain should stay active in hwsup mode; and conversely,
|
||||
* removed when the clockdomain should be allowed to go inactive in
|
||||
* hwsup mode.
|
||||
*
|
||||
* Autodeps are deprecated and should be removed after
|
||||
* omap_hwmod-based fine-grained module idle control is added.
|
||||
*/
|
||||
struct clkdm_pwrdm_autodep {
|
||||
|
||||
struct clkdm_autodep {
|
||||
union {
|
||||
/* Name of the powerdomain to add a wkdep/sleepdep on */
|
||||
const char *name;
|
||||
|
||||
/* Powerdomain pointer (looked up at clkdm_init() time) */
|
||||
struct powerdomain *ptr;
|
||||
} pwrdm;
|
||||
|
||||
/* OMAP chip types that this clockdomain dep is valid on */
|
||||
struct clockdomain *ptr;
|
||||
} clkdm;
|
||||
const struct omap_chip_id omap_chip;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* struct clkdm_dep - encode dependencies between clockdomains
|
||||
* @clkdm_name: clockdomain name
|
||||
* @clkdm: pointer to the struct clockdomain of @clkdm_name
|
||||
* @omap_chip: OMAP chip types that this dependency is valid on
|
||||
* @wkdep_usecount: Number of wakeup dependencies causing this clkdm to wake
|
||||
* @sleepdep_usecount: Number of sleep deps that could prevent clkdm from idle
|
||||
*
|
||||
* Statically defined. @clkdm is resolved from @clkdm_name at runtime and
|
||||
* should not be pre-initialized.
|
||||
*
|
||||
* XXX Should also include hardware (fixed) dependencies.
|
||||
*/
|
||||
struct clkdm_dep {
|
||||
const char *clkdm_name;
|
||||
struct clockdomain *clkdm;
|
||||
atomic_t wkdep_usecount;
|
||||
atomic_t sleepdep_usecount;
|
||||
const struct omap_chip_id omap_chip;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct clockdomain - OMAP clockdomain
|
||||
* @name: clockdomain name
|
||||
* @pwrdm: powerdomain containing this clockdomain
|
||||
* @clktrctrl_reg: CLKSTCTRL reg for the given clock domain
|
||||
* @clktrctrl_mask: CLKTRCTRL/AUTOSTATE field mask in CM_CLKSTCTRL reg
|
||||
* @flags: Clockdomain capability flags
|
||||
* @dep_bit: Bit shift of this clockdomain's PM_WKDEP/CM_SLEEPDEP bit
|
||||
* @wkdep_srcs: Clockdomains that can be told to wake this powerdomain up
|
||||
* @sleepdep_srcs: Clockdomains that can be told to keep this clkdm from inact
|
||||
* @omap_chip: OMAP chip types that this clockdomain is valid on
|
||||
* @usecount: Usecount tracking
|
||||
* @node: list_head to link all clockdomains together
|
||||
*/
|
||||
struct clockdomain {
|
||||
|
||||
/* Clockdomain name */
|
||||
const char *name;
|
||||
|
||||
union {
|
||||
/* Powerdomain enclosing this clockdomain */
|
||||
const char *name;
|
||||
|
||||
/* Powerdomain pointer assigned at clkdm_register() */
|
||||
struct powerdomain *ptr;
|
||||
} pwrdm;
|
||||
|
||||
/* CLKTRCTRL/AUTOSTATE field mask in CM_CLKSTCTRL reg */
|
||||
void __iomem *clkstctrl_reg;
|
||||
const u16 clktrctrl_mask;
|
||||
|
||||
/* Clockdomain capability flags */
|
||||
const u8 flags;
|
||||
|
||||
/* OMAP chip types that this clockdomain is valid on */
|
||||
const u8 dep_bit;
|
||||
struct clkdm_dep *wkdep_srcs;
|
||||
struct clkdm_dep *sleepdep_srcs;
|
||||
const struct omap_chip_id omap_chip;
|
||||
|
||||
/* Usecount tracking */
|
||||
atomic_t usecount;
|
||||
|
||||
struct list_head node;
|
||||
|
||||
};
|
||||
|
||||
void clkdm_init(struct clockdomain **clkdms, struct clkdm_pwrdm_autodep *autodeps);
|
||||
int clkdm_register(struct clockdomain *clkdm);
|
||||
int clkdm_unregister(struct clockdomain *clkdm);
|
||||
void clkdm_init(struct clockdomain **clkdms, struct clkdm_autodep *autodeps);
|
||||
struct clockdomain *clkdm_lookup(const char *name);
|
||||
|
||||
int clkdm_for_each(int (*fn)(struct clockdomain *clkdm, void *user),
|
||||
void *user);
|
||||
struct powerdomain *clkdm_get_pwrdm(struct clockdomain *clkdm);
|
||||
|
||||
int clkdm_add_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
|
||||
int clkdm_del_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
|
||||
int clkdm_read_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
|
||||
int clkdm_clear_all_wkdeps(struct clockdomain *clkdm);
|
||||
int clkdm_add_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
|
||||
int clkdm_del_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
|
||||
int clkdm_read_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
|
||||
int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm);
|
||||
|
||||
void omap2_clkdm_allow_idle(struct clockdomain *clkdm);
|
||||
void omap2_clkdm_deny_idle(struct clockdomain *clkdm);
|
||||
|
||||
|
|
|
@ -160,6 +160,14 @@
|
|||
#define OMAP343X_CONTROL_SRAMLDO5 (OMAP2_CONTROL_GENERAL + 0x02C0)
|
||||
#define OMAP343X_CONTROL_CSI (OMAP2_CONTROL_GENERAL + 0x02C4)
|
||||
|
||||
/* AM35XX only CONTROL_GENERAL register offsets */
|
||||
#define AM35XX_CONTROL_MSUSPENDMUX_6 (OMAP2_CONTROL_GENERAL + 0x0038)
|
||||
#define AM35XX_CONTROL_DEVCONF2 (OMAP2_CONTROL_GENERAL + 0x0310)
|
||||
#define AM35XX_CONTROL_DEVCONF3 (OMAP2_CONTROL_GENERAL + 0x0314)
|
||||
#define AM35XX_CONTROL_CBA_PRIORITY (OMAP2_CONTROL_GENERAL + 0x0320)
|
||||
#define AM35XX_CONTROL_LVL_INTR_CLEAR (OMAP2_CONTROL_GENERAL + 0x0324)
|
||||
#define AM35XX_CONTROL_IP_SW_RESET (OMAP2_CONTROL_GENERAL + 0x0328)
|
||||
#define AM35XX_CONTROL_IPSS_CLK_CTRL (OMAP2_CONTROL_GENERAL + 0x032C)
|
||||
|
||||
/* 34xx PADCONF register offsets */
|
||||
#define OMAP343X_PADCONF_ETK(i) (OMAP2_CONTROL_PADCONFS + 0x5a8 + \
|
||||
|
@ -257,6 +265,15 @@
|
|||
#define OMAP343X_SCRATCHPAD (OMAP343X_CTRL_BASE + 0x910)
|
||||
#define OMAP343X_SCRATCHPAD_ROM_OFFSET 0x19C
|
||||
|
||||
/* AM35XX_CONTROL_IPSS_CLK_CTRL bits */
|
||||
#define AM35XX_USBOTG_VBUSP_CLK_SHIFT 0
|
||||
#define AM35XX_CPGMAC_VBUSP_CLK_SHIFT 1
|
||||
#define AM35XX_VPFE_VBUSP_CLK_SHIFT 2
|
||||
#define AM35XX_HECC_VBUSP_CLK_SHIFT 3
|
||||
#define AM35XX_USBOTG_FCLK_SHIFT 8
|
||||
#define AM35XX_CPGMAC_FCLK_SHIFT 9
|
||||
#define AM35XX_VPFE_FCLK_SHIFT 10
|
||||
|
||||
/*
|
||||
* CONTROL OMAP STATUS register to identify OMAP3 features
|
||||
*/
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
int omap_type(void);
|
||||
|
||||
struct omap_chip_id {
|
||||
u8 oc;
|
||||
u16 oc;
|
||||
u8 type;
|
||||
};
|
||||
|
||||
|
@ -154,6 +154,7 @@ unsigned int omap_rev(void);
|
|||
* cpu_is_omap242x(): True for OMAP2420, OMAP2422, OMAP2423
|
||||
* cpu_is_omap243x(): True for OMAP2430
|
||||
* cpu_is_omap343x(): True for OMAP3430
|
||||
* cpu_is_omap443x(): True for OMAP4430
|
||||
*/
|
||||
#define GET_OMAP_CLASS (omap_rev() & 0xff)
|
||||
|
||||
|
@ -286,6 +287,7 @@ IS_OMAP_SUBCLASS(443x, 0x443)
|
|||
* cpu_is_omap2423(): True for OMAP2423
|
||||
* cpu_is_omap2430(): True for OMAP2430
|
||||
* cpu_is_omap3430(): True for OMAP3430
|
||||
* cpu_is_omap4430(): True for OMAP4430
|
||||
* cpu_is_omap3505(): True for OMAP3505
|
||||
* cpu_is_omap3517(): True for OMAP3517
|
||||
*/
|
||||
|
@ -334,6 +336,7 @@ IS_OMAP_TYPE(3517, 0x3517)
|
|||
#define cpu_is_omap3505() 0
|
||||
#define cpu_is_omap3517() 0
|
||||
#define cpu_is_omap3430() 0
|
||||
#define cpu_is_omap4430() 0
|
||||
#define cpu_is_omap3630() 0
|
||||
|
||||
/*
|
||||
|
@ -471,9 +474,12 @@ IS_OMAP_TYPE(3517, 0x3517)
|
|||
#define CHIP_IS_OMAP3430ES3_0 (1 << 5)
|
||||
#define CHIP_IS_OMAP3430ES3_1 (1 << 6)
|
||||
#define CHIP_IS_OMAP3630ES1 (1 << 7)
|
||||
#define CHIP_IS_OMAP4430ES1 (1 << 8)
|
||||
|
||||
#define CHIP_IS_OMAP24XX (CHIP_IS_OMAP2420 | CHIP_IS_OMAP2430)
|
||||
|
||||
#define CHIP_IS_OMAP4430 (CHIP_IS_OMAP4430ES1)
|
||||
|
||||
/*
|
||||
* "GE" here represents "greater than or equal to" in terms of ES
|
||||
* levels. So CHIP_GE_OMAP3430ES2 is intended to match all OMAP3430
|
||||
|
|
|
@ -131,11 +131,15 @@ int omap_device_enable_clocks(struct omap_device *od);
|
|||
*/
|
||||
struct omap_device_pm_latency {
|
||||
u32 deactivate_lat;
|
||||
u32 deactivate_lat_worst;
|
||||
int (*deactivate_func)(struct omap_device *od);
|
||||
u32 activate_lat;
|
||||
u32 activate_lat_worst;
|
||||
int (*activate_func)(struct omap_device *od);
|
||||
u32 flags;
|
||||
};
|
||||
|
||||
#define OMAP_DEVICE_LATENCY_AUTO_ADJUST BIT(1)
|
||||
|
||||
/* Get omap_device pointer from platform_device pointer */
|
||||
#define to_omap_device(x) container_of((x), struct omap_device, pdev)
|
||||
|
|
|
@ -441,6 +441,8 @@ int omap_hwmod_shutdown(struct omap_hwmod *oh);
|
|||
int omap_hwmod_enable_clocks(struct omap_hwmod *oh);
|
||||
int omap_hwmod_disable_clocks(struct omap_hwmod *oh);
|
||||
|
||||
int omap_hwmod_set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode);
|
||||
|
||||
int omap_hwmod_reset(struct omap_hwmod *oh);
|
||||
void omap_hwmod_ocp_barrier(struct omap_hwmod *oh);
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* OMAP2/3 powerdomain control
|
||||
*
|
||||
* Copyright (C) 2007-8 Texas Instruments, Inc.
|
||||
* Copyright (C) 2007-8 Nokia Corporation
|
||||
* Copyright (C) 2007-2008 Texas Instruments, Inc.
|
||||
* Copyright (C) 2007-2009 Nokia Corporation
|
||||
*
|
||||
* Written by Paul Walmsley
|
||||
*
|
||||
|
@ -37,6 +37,9 @@
|
|||
#define PWRSTS_OFF_RET ((1 << PWRDM_POWER_OFF) | \
|
||||
(1 << PWRDM_POWER_RET))
|
||||
|
||||
#define PWRSTS_RET_ON ((1 << PWRDM_POWER_RET) | \
|
||||
(1 << PWRDM_POWER_ON))
|
||||
|
||||
#define PWRSTS_OFF_RET_ON (PWRSTS_OFF_RET | (1 << PWRDM_POWER_ON))
|
||||
|
||||
|
||||
|
@ -48,16 +51,16 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* Number of memory banks that are power-controllable. On OMAP3430, the
|
||||
* maximum is 4.
|
||||
* Number of memory banks that are power-controllable. On OMAP4430, the
|
||||
* maximum is 5.
|
||||
*/
|
||||
#define PWRDM_MAX_MEM_BANKS 4
|
||||
#define PWRDM_MAX_MEM_BANKS 5
|
||||
|
||||
/*
|
||||
* Maximum number of clockdomains that can be associated with a powerdomain.
|
||||
* CORE powerdomain on OMAP3 is the worst case
|
||||
* CORE powerdomain on OMAP4 is the worst case
|
||||
*/
|
||||
#define PWRDM_MAX_CLKDMS 4
|
||||
#define PWRDM_MAX_CLKDMS 9
|
||||
|
||||
/* XXX A completely arbitrary number. What is reasonable here? */
|
||||
#define PWRDM_TRANSITION_BAILOUT 100000
|
||||
|
@ -65,63 +68,36 @@
|
|||
struct clockdomain;
|
||||
struct powerdomain;
|
||||
|
||||
/* Encodes dependencies between powerdomains - statically defined */
|
||||
struct pwrdm_dep {
|
||||
|
||||
/* Powerdomain name */
|
||||
const char *pwrdm_name;
|
||||
|
||||
/* Powerdomain pointer - resolved by the powerdomain code */
|
||||
struct powerdomain *pwrdm;
|
||||
|
||||
/* Flags to mark OMAP chip restrictions, etc. */
|
||||
const struct omap_chip_id omap_chip;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* struct powerdomain - OMAP powerdomain
|
||||
* @name: Powerdomain name
|
||||
* @omap_chip: represents the OMAP chip types containing this pwrdm
|
||||
* @prcm_offs: the address offset from CM_BASE/PRM_BASE
|
||||
* @pwrsts: Possible powerdomain power states
|
||||
* @pwrsts_logic_ret: Possible logic power states when pwrdm in RETENTION
|
||||
* @flags: Powerdomain flags
|
||||
* @banks: Number of software-controllable memory banks in this powerdomain
|
||||
* @pwrsts_mem_ret: Possible memory bank pwrstates when pwrdm in RETENTION
|
||||
* @pwrsts_mem_on: Possible memory bank pwrstates when pwrdm in ON
|
||||
* @pwrdm_clkdms: Clockdomains in this powerdomain
|
||||
* @node: list_head linking all powerdomains
|
||||
* @state:
|
||||
* @state_counter:
|
||||
* @timer:
|
||||
* @state_timer:
|
||||
*/
|
||||
struct powerdomain {
|
||||
|
||||
/* Powerdomain name */
|
||||
const char *name;
|
||||
|
||||
/* the address offset from CM_BASE/PRM_BASE */
|
||||
const s16 prcm_offs;
|
||||
|
||||
/* Used to represent the OMAP chip types containing this pwrdm */
|
||||
const struct omap_chip_id omap_chip;
|
||||
|
||||
/* Powerdomains that can be told to wake this powerdomain up */
|
||||
struct pwrdm_dep *wkdep_srcs;
|
||||
|
||||
/* Powerdomains that can be told to keep this pwrdm from inactivity */
|
||||
struct pwrdm_dep *sleepdep_srcs;
|
||||
|
||||
/* Bit shift of this powerdomain's PM_WKDEP/CM_SLEEPDEP bit */
|
||||
const u8 dep_bit;
|
||||
|
||||
/* Possible powerdomain power states */
|
||||
const s16 prcm_offs;
|
||||
const u8 pwrsts;
|
||||
|
||||
/* Possible logic power states when pwrdm in RETENTION */
|
||||
const u8 pwrsts_logic_ret;
|
||||
|
||||
/* Powerdomain flags */
|
||||
const u8 flags;
|
||||
|
||||
/* Number of software-controllable memory banks in this powerdomain */
|
||||
const u8 banks;
|
||||
|
||||
/* Possible memory bank pwrstates when pwrdm in RETENTION */
|
||||
const u8 pwrsts_mem_ret[PWRDM_MAX_MEM_BANKS];
|
||||
|
||||
/* Possible memory bank pwrstates when pwrdm is ON */
|
||||
const u8 pwrsts_mem_on[PWRDM_MAX_MEM_BANKS];
|
||||
|
||||
/* Clockdomains in this powerdomain */
|
||||
struct clockdomain *pwrdm_clkdms[PWRDM_MAX_CLKDMS];
|
||||
|
||||
struct list_head node;
|
||||
|
||||
int state;
|
||||
unsigned state_counter[PWRDM_MAX_PWRSTS];
|
||||
|
||||
|
@ -134,8 +110,6 @@ struct powerdomain {
|
|||
|
||||
void pwrdm_init(struct powerdomain **pwrdm_list);
|
||||
|
||||
int pwrdm_register(struct powerdomain *pwrdm);
|
||||
int pwrdm_unregister(struct powerdomain *pwrdm);
|
||||
struct powerdomain *pwrdm_lookup(const char *name);
|
||||
|
||||
int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user),
|
||||
|
@ -149,13 +123,6 @@ int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
|
|||
int (*fn)(struct powerdomain *pwrdm,
|
||||
struct clockdomain *clkdm));
|
||||
|
||||
int pwrdm_add_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
|
||||
int pwrdm_del_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
|
||||
int pwrdm_read_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
|
||||
int pwrdm_add_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
|
||||
int pwrdm_del_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
|
||||
int pwrdm_read_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
|
||||
|
||||
int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm);
|
||||
|
||||
int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst);
|
||||
|
|
|
@ -33,6 +33,14 @@ int omap2_cm_wait_idlest(void __iomem *reg, u32 mask, const char *name);
|
|||
void omap3_prcm_save_context(void);
|
||||
void omap3_prcm_restore_context(void);
|
||||
|
||||
u32 prm_read_mod_reg(s16 module, u16 idx);
|
||||
void prm_write_mod_reg(u32 val, s16 module, u16 idx);
|
||||
u32 prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx);
|
||||
u32 prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask);
|
||||
u32 cm_read_mod_reg(s16 module, u16 idx);
|
||||
void cm_write_mod_reg(u32 val, s16 module, u16 idx);
|
||||
u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -148,10 +148,22 @@ static int _omap_device_activate(struct omap_device *od, u8 ignore_lat)
|
|||
"%llu nsec\n", od->pdev.name, od->pm_lat_level,
|
||||
act_lat);
|
||||
|
||||
WARN(act_lat > odpl->activate_lat, "omap_device: %s.%d: "
|
||||
"activate step %d took longer than expected (%llu > %d)\n",
|
||||
od->pdev.name, od->pdev.id, od->pm_lat_level,
|
||||
act_lat, odpl->activate_lat);
|
||||
if (act_lat > odpl->activate_lat) {
|
||||
odpl->activate_lat_worst = act_lat;
|
||||
if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) {
|
||||
odpl->activate_lat = act_lat;
|
||||
pr_warning("omap_device: %s.%d: new worst case "
|
||||
"activate latency %d: %llu\n",
|
||||
od->pdev.name, od->pdev.id,
|
||||
od->pm_lat_level, act_lat);
|
||||
} else
|
||||
pr_warning("omap_device: %s.%d: activate "
|
||||
"latency %d higher than exptected. "
|
||||
"(%llu > %d)\n",
|
||||
od->pdev.name, od->pdev.id,
|
||||
od->pm_lat_level, act_lat,
|
||||
odpl->activate_lat);
|
||||
}
|
||||
|
||||
od->dev_wakeup_lat -= odpl->activate_lat;
|
||||
}
|
||||
|
@ -204,10 +216,23 @@ static int _omap_device_deactivate(struct omap_device *od, u8 ignore_lat)
|
|||
"%llu nsec\n", od->pdev.name, od->pm_lat_level,
|
||||
deact_lat);
|
||||
|
||||
WARN(deact_lat > odpl->deactivate_lat, "omap_device: %s.%d: "
|
||||
"deactivate step %d took longer than expected "
|
||||
"(%llu > %d)\n", od->pdev.name, od->pdev.id,
|
||||
od->pm_lat_level, deact_lat, odpl->deactivate_lat);
|
||||
if (deact_lat > odpl->deactivate_lat) {
|
||||
odpl->deactivate_lat_worst = deact_lat;
|
||||
if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) {
|
||||
odpl->deactivate_lat = deact_lat;
|
||||
pr_warning("omap_device: %s.%d: new worst case "
|
||||
"deactivate latency %d: %llu\n",
|
||||
od->pdev.name, od->pdev.id,
|
||||
od->pm_lat_level, deact_lat);
|
||||
} else
|
||||
pr_warning("omap_device: %s.%d: deactivate "
|
||||
"latency %d higher than exptected. "
|
||||
"(%llu > %d)\n",
|
||||
od->pdev.name, od->pdev.id,
|
||||
od->pm_lat_level, deact_lat,
|
||||
odpl->deactivate_lat);
|
||||
}
|
||||
|
||||
|
||||
od->dev_wakeup_lat += odpl->activate_lat;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче