2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2024-11-20 00:26:39 +08:00

Merge branch 'omap-clks3' into devel

Conflicts:

	arch/arm/mach-omap2/clock.c
This commit is contained in:
Russell King 2009-03-19 12:39:58 +00:00 committed by Russell King
commit 14b6848bc0
60 changed files with 3148 additions and 2603 deletions

View File

@ -20,41 +20,161 @@
#include <linux/io.h>
#include <asm/mach-types.h>
#include <asm/clkdev.h>
#include <mach/cpu.h>
#include <mach/usb.h>
#include <mach/clock.h>
#include <mach/sram.h>
static const struct clkops clkops_generic;
static const struct clkops clkops_uart;
static const struct clkops clkops_dspck;
#include "clock.h"
static int clk_omap1_dummy_enable(struct clk *clk)
{
return 0;
}
static void clk_omap1_dummy_disable(struct clk *clk)
{
}
static const struct clkops clkops_dummy = {
.enable = clk_omap1_dummy_enable,
.disable = clk_omap1_dummy_disable,
};
static struct clk dummy_ck = {
.name = "dummy",
.ops = &clkops_dummy,
.flags = RATE_FIXED,
};
struct omap_clk {
u32 cpu;
struct clk_lookup lk;
};
#define CLK(dev, con, ck, cp) \
{ \
.cpu = cp, \
.lk = { \
.dev_id = dev, \
.con_id = con, \
.clk = ck, \
}, \
}
#define CK_310 (1 << 0)
#define CK_730 (1 << 1)
#define CK_1510 (1 << 2)
#define CK_16XX (1 << 3)
static struct omap_clk omap_clks[] = {
/* non-ULPD clocks */
CLK(NULL, "ck_ref", &ck_ref, CK_16XX | CK_1510 | CK_310),
CLK(NULL, "ck_dpll1", &ck_dpll1, CK_16XX | CK_1510 | CK_310),
/* CK_GEN1 clocks */
CLK(NULL, "ck_dpll1out", &ck_dpll1out.clk, CK_16XX),
CLK(NULL, "ck_sossi", &sossi_ck, CK_16XX),
CLK(NULL, "arm_ck", &arm_ck, CK_16XX | CK_1510 | CK_310),
CLK(NULL, "armper_ck", &armper_ck.clk, CK_16XX | CK_1510 | CK_310),
CLK(NULL, "arm_gpio_ck", &arm_gpio_ck, CK_1510 | CK_310),
CLK(NULL, "armxor_ck", &armxor_ck.clk, CK_16XX | CK_1510 | CK_310),
CLK(NULL, "armtim_ck", &armtim_ck.clk, CK_16XX | CK_1510 | CK_310),
CLK("omap_wdt", "fck", &armwdt_ck.clk, CK_16XX | CK_1510 | CK_310),
CLK("omap_wdt", "ick", &armper_ck.clk, CK_16XX),
CLK("omap_wdt", "ick", &dummy_ck, CK_1510 | CK_310),
CLK(NULL, "arminth_ck", &arminth_ck1510, CK_1510 | CK_310),
CLK(NULL, "arminth_ck", &arminth_ck16xx, CK_16XX),
/* CK_GEN2 clocks */
CLK(NULL, "dsp_ck", &dsp_ck, CK_16XX | CK_1510 | CK_310),
CLK(NULL, "dspmmu_ck", &dspmmu_ck, CK_16XX | CK_1510 | CK_310),
CLK(NULL, "dspper_ck", &dspper_ck, CK_16XX | CK_1510 | CK_310),
CLK(NULL, "dspxor_ck", &dspxor_ck, CK_16XX | CK_1510 | CK_310),
CLK(NULL, "dsptim_ck", &dsptim_ck, CK_16XX | CK_1510 | CK_310),
/* CK_GEN3 clocks */
CLK(NULL, "tc_ck", &tc_ck.clk, CK_16XX | CK_1510 | CK_310 | CK_730),
CLK(NULL, "tipb_ck", &tipb_ck, CK_1510 | CK_310),
CLK(NULL, "l3_ocpi_ck", &l3_ocpi_ck, CK_16XX),
CLK(NULL, "tc1_ck", &tc1_ck, CK_16XX),
CLK(NULL, "tc2_ck", &tc2_ck, CK_16XX),
CLK(NULL, "dma_ck", &dma_ck, CK_16XX | CK_1510 | CK_310),
CLK(NULL, "dma_lcdfree_ck", &dma_lcdfree_ck, CK_16XX),
CLK(NULL, "api_ck", &api_ck.clk, CK_16XX | CK_1510 | CK_310),
CLK(NULL, "lb_ck", &lb_ck.clk, CK_1510 | CK_310),
CLK(NULL, "rhea1_ck", &rhea1_ck, CK_16XX),
CLK(NULL, "rhea2_ck", &rhea2_ck, CK_16XX),
CLK(NULL, "lcd_ck", &lcd_ck_16xx, CK_16XX | CK_730),
CLK(NULL, "lcd_ck", &lcd_ck_1510.clk, CK_1510 | CK_310),
/* ULPD clocks */
CLK(NULL, "uart1_ck", &uart1_1510, CK_1510 | CK_310),
CLK(NULL, "uart1_ck", &uart1_16xx.clk, CK_16XX),
CLK(NULL, "uart2_ck", &uart2_ck, CK_16XX | CK_1510 | CK_310),
CLK(NULL, "uart3_ck", &uart3_1510, CK_1510 | CK_310),
CLK(NULL, "uart3_ck", &uart3_16xx.clk, CK_16XX),
CLK(NULL, "usb_clko", &usb_clko, CK_16XX | CK_1510 | CK_310),
CLK(NULL, "usb_hhc_ck", &usb_hhc_ck1510, CK_1510 | CK_310),
CLK(NULL, "usb_hhc_ck", &usb_hhc_ck16xx, CK_16XX),
CLK(NULL, "usb_dc_ck", &usb_dc_ck, CK_16XX),
CLK(NULL, "mclk", &mclk_1510, CK_1510 | CK_310),
CLK(NULL, "mclk", &mclk_16xx, CK_16XX),
CLK(NULL, "bclk", &bclk_1510, CK_1510 | CK_310),
CLK(NULL, "bclk", &bclk_16xx, CK_16XX),
CLK("mmci-omap.0", "fck", &mmc1_ck, CK_16XX | CK_1510 | CK_310),
CLK("mmci-omap.0", "ick", &armper_ck.clk, CK_16XX | CK_1510 | CK_310),
CLK("mmci-omap.1", "fck", &mmc2_ck, CK_16XX),
CLK("mmci-omap.1", "ick", &armper_ck.clk, CK_16XX),
/* Virtual clocks */
CLK(NULL, "mpu", &virtual_ck_mpu, CK_16XX | CK_1510 | CK_310),
CLK("i2c_omap.1", "fck", &i2c_fck, CK_16XX | CK_1510 | CK_310),
CLK("i2c_omap.1", "ick", &i2c_ick, CK_16XX),
CLK("i2c_omap.1", "ick", &dummy_ck, CK_1510 | CK_310),
CLK("omap_uwire", "fck", &armxor_ck.clk, CK_16XX | CK_1510 | CK_310),
CLK("omap-mcbsp.1", "ick", &dspper_ck, CK_16XX),
CLK("omap-mcbsp.1", "ick", &dummy_ck, CK_1510 | CK_310),
CLK("omap-mcbsp.2", "ick", &armper_ck.clk, CK_16XX),
CLK("omap-mcbsp.2", "ick", &dummy_ck, CK_1510 | CK_310),
CLK("omap-mcbsp.3", "ick", &dspper_ck, CK_16XX),
CLK("omap-mcbsp.3", "ick", &dummy_ck, CK_1510 | CK_310),
CLK("omap-mcbsp.1", "fck", &dspxor_ck, CK_16XX | CK_1510 | CK_310),
CLK("omap-mcbsp.2", "fck", &armper_ck.clk, CK_16XX | CK_1510 | CK_310),
CLK("omap-mcbsp.3", "fck", &dspxor_ck, CK_16XX | CK_1510 | CK_310),
};
static int omap1_clk_enable_generic(struct clk * clk);
static int omap1_clk_enable(struct clk *clk);
static void omap1_clk_disable_generic(struct clk * clk);
static void omap1_clk_disable(struct clk *clk);
__u32 arm_idlect1_mask;
/*-------------------------------------------------------------------------
* Omap1 specific clock functions
*-------------------------------------------------------------------------*/
static void omap1_watchdog_recalc(struct clk * clk)
static unsigned long omap1_watchdog_recalc(struct clk *clk)
{
clk->rate = clk->parent->rate / 14;
return clk->parent->rate / 14;
}
static void omap1_uart_recalc(struct clk * clk)
static unsigned long omap1_uart_recalc(struct clk *clk)
{
unsigned int val = omap_readl(clk->enable_reg);
if (val & clk->enable_bit)
clk->rate = 48000000;
else
clk->rate = 12000000;
unsigned int val = __raw_readl(clk->enable_reg);
return val & clk->enable_bit ? 48000000 : 12000000;
}
static void omap1_sossi_recalc(struct clk *clk)
static unsigned long omap1_sossi_recalc(struct clk *clk)
{
u32 div = omap_readl(MOD_CONF_CTRL_1);
div = (div >> 17) & 0x7;
div++;
clk->rate = clk->parent->rate / div;
return clk->parent->rate / div;
}
static int omap1_clk_enable_dsp_domain(struct clk *clk)
@ -78,6 +198,11 @@ static void omap1_clk_disable_dsp_domain(struct clk *clk)
}
}
static const struct clkops clkops_dspck = {
.enable = &omap1_clk_enable_dsp_domain,
.disable = &omap1_clk_disable_dsp_domain,
};
static int omap1_clk_enable_uart_functional(struct clk *clk)
{
int ret;
@ -105,6 +230,11 @@ static void omap1_clk_disable_uart_functional(struct clk *clk)
omap1_clk_disable_generic(clk);
}
static const struct clkops clkops_uart = {
.enable = &omap1_clk_enable_uart_functional,
.disable = &omap1_clk_disable_uart_functional,
};
static void omap1_clk_allow_idle(struct clk *clk)
{
struct arm_idlect1_clk * iclk = (struct arm_idlect1_clk *)clk;
@ -197,9 +327,6 @@ static int calc_dsor_exp(struct clk *clk, unsigned long rate)
struct clk * parent;
unsigned dsor_exp;
if (unlikely(!(clk->flags & RATE_CKCTL)))
return -EINVAL;
parent = clk->parent;
if (unlikely(parent == NULL))
return -EIO;
@ -215,22 +342,15 @@ static int calc_dsor_exp(struct clk *clk, unsigned long rate)
return dsor_exp;
}
static void omap1_ckctl_recalc(struct clk * clk)
static unsigned long omap1_ckctl_recalc(struct clk *clk)
{
int dsor;
/* Calculate divisor encoded as 2-bit exponent */
dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset));
int dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset));
if (unlikely(clk->rate == clk->parent->rate / dsor))
return; /* No change, quick exit */
clk->rate = clk->parent->rate / dsor;
if (unlikely(clk->flags & RATE_PROPAGATES))
propagate_rate(clk);
return clk->parent->rate / dsor;
}
static void omap1_ckctl_recalc_dsp_domain(struct clk * clk)
static unsigned long omap1_ckctl_recalc_dsp_domain(struct clk *clk)
{
int dsor;
@ -245,12 +365,7 @@ static void omap1_ckctl_recalc_dsp_domain(struct clk * clk)
dsor = 1 << (3 & (__raw_readw(DSP_CKCTL) >> clk->rate_offset));
omap1_clk_disable(&api_ck.clk);
if (unlikely(clk->rate == clk->parent->rate / dsor))
return; /* No change, quick exit */
clk->rate = clk->parent->rate / dsor;
if (unlikely(clk->flags & RATE_PROPAGATES))
propagate_rate(clk);
return clk->parent->rate / dsor;
}
/* MPU virtual clock functions */
@ -289,35 +404,57 @@ static int omap1_select_table_rate(struct clk * clk, unsigned long rate)
omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val);
ck_dpll1.rate = ptr->pll_rate;
propagate_rate(&ck_dpll1);
return 0;
}
static int omap1_clk_set_rate_dsp_domain(struct clk *clk, unsigned long rate)
{
int ret = -EINVAL;
int dsor_exp;
__u16 regval;
int dsor_exp;
u16 regval;
if (clk->flags & RATE_CKCTL) {
dsor_exp = calc_dsor_exp(clk, rate);
if (dsor_exp > 3)
dsor_exp = -EINVAL;
if (dsor_exp < 0)
return dsor_exp;
dsor_exp = calc_dsor_exp(clk, rate);
if (dsor_exp > 3)
dsor_exp = -EINVAL;
if (dsor_exp < 0)
return dsor_exp;
regval = __raw_readw(DSP_CKCTL);
regval &= ~(3 << clk->rate_offset);
regval |= dsor_exp << clk->rate_offset;
__raw_writew(regval, DSP_CKCTL);
clk->rate = clk->parent->rate / (1 << dsor_exp);
ret = 0;
}
regval = __raw_readw(DSP_CKCTL);
regval &= ~(3 << clk->rate_offset);
regval |= dsor_exp << clk->rate_offset;
__raw_writew(regval, DSP_CKCTL);
clk->rate = clk->parent->rate / (1 << dsor_exp);
if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES)))
propagate_rate(clk);
return 0;
}
return ret;
static long omap1_clk_round_rate_ckctl_arm(struct clk *clk, unsigned long rate)
{
int dsor_exp = calc_dsor_exp(clk, rate);
if (dsor_exp < 0)
return dsor_exp;
if (dsor_exp > 3)
dsor_exp = 3;
return clk->parent->rate / (1 << dsor_exp);
}
static int omap1_clk_set_rate_ckctl_arm(struct clk *clk, unsigned long rate)
{
int dsor_exp;
u16 regval;
dsor_exp = calc_dsor_exp(clk, rate);
if (dsor_exp > 3)
dsor_exp = -EINVAL;
if (dsor_exp < 0)
return dsor_exp;
regval = omap_readw(ARM_CKCTL);
regval &= ~(3 << clk->rate_offset);
regval |= dsor_exp << clk->rate_offset;
regval = verify_ckctl_value(regval);
omap_writew(regval, ARM_CKCTL);
clk->rate = clk->parent->rate / (1 << dsor_exp);
return 0;
}
static long omap1_round_to_table_rate(struct clk * clk, unsigned long rate)
@ -372,14 +509,14 @@ static int omap1_set_uart_rate(struct clk * clk, unsigned long rate)
{
unsigned int val;
val = omap_readl(clk->enable_reg);
val = __raw_readl(clk->enable_reg);
if (rate == 12000000)
val &= ~(1 << clk->enable_bit);
else if (rate == 48000000)
val |= (1 << clk->enable_bit);
else
return -EINVAL;
omap_writel(val, clk->enable_reg);
__raw_writel(val, clk->enable_reg);
clk->rate = rate;
return 0;
@ -398,8 +535,8 @@ static int omap1_set_ext_clk_rate(struct clk * clk, unsigned long rate)
else
ratio_bits = (dsor - 2) << 2;
ratio_bits |= omap_readw(clk->enable_reg) & ~0xfd;
omap_writew(ratio_bits, clk->enable_reg);
ratio_bits |= __raw_readw(clk->enable_reg) & ~0xfd;
__raw_writew(ratio_bits, clk->enable_reg);
return 0;
}
@ -423,8 +560,6 @@ static int omap1_set_sossi_rate(struct clk *clk, unsigned long rate)
omap_writel(l, MOD_CONF_CTRL_1);
clk->rate = p_rate / (div + 1);
if (unlikely(clk->flags & RATE_PROPAGATES))
propagate_rate(clk);
return 0;
}
@ -440,8 +575,8 @@ static void omap1_init_ext_clk(struct clk * clk)
__u16 ratio_bits;
/* Determine current rate and ensure clock is based on 96MHz APLL */
ratio_bits = omap_readw(clk->enable_reg) & ~1;
omap_writew(ratio_bits, clk->enable_reg);
ratio_bits = __raw_readw(clk->enable_reg) & ~1;
__raw_writew(ratio_bits, clk->enable_reg);
ratio_bits = (ratio_bits & 0xfc) >> 2;
if (ratio_bits > 6)
@ -468,7 +603,7 @@ static int omap1_clk_enable(struct clk *clk)
omap1_clk_deny_idle(clk->parent);
}
ret = clk->enable(clk);
ret = clk->ops->enable(clk);
if (unlikely(ret != 0) && clk->parent) {
omap1_clk_disable(clk->parent);
@ -482,7 +617,7 @@ static int omap1_clk_enable(struct clk *clk)
static void omap1_clk_disable(struct clk *clk)
{
if (clk->usecount > 0 && !(--clk->usecount)) {
clk->disable(clk);
clk->ops->disable(clk);
if (likely(clk->parent)) {
omap1_clk_disable(clk->parent);
if (clk->flags & CLOCK_NO_IDLE_PARENT)
@ -496,9 +631,6 @@ static int omap1_clk_enable_generic(struct clk *clk)
__u16 regval16;
__u32 regval32;
if (clk->flags & ALWAYS_ENABLED)
return 0;
if (unlikely(clk->enable_reg == NULL)) {
printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
clk->name);
@ -506,25 +638,13 @@ static int omap1_clk_enable_generic(struct clk *clk)
}
if (clk->flags & ENABLE_REG_32BIT) {
if (clk->flags & VIRTUAL_IO_ADDRESS) {
regval32 = __raw_readl(clk->enable_reg);
regval32 |= (1 << clk->enable_bit);
__raw_writel(regval32, clk->enable_reg);
} else {
regval32 = omap_readl(clk->enable_reg);
regval32 |= (1 << clk->enable_bit);
omap_writel(regval32, clk->enable_reg);
}
regval32 = __raw_readl(clk->enable_reg);
regval32 |= (1 << clk->enable_bit);
__raw_writel(regval32, clk->enable_reg);
} else {
if (clk->flags & VIRTUAL_IO_ADDRESS) {
regval16 = __raw_readw(clk->enable_reg);
regval16 |= (1 << clk->enable_bit);
__raw_writew(regval16, clk->enable_reg);
} else {
regval16 = omap_readw(clk->enable_reg);
regval16 |= (1 << clk->enable_bit);
omap_writew(regval16, clk->enable_reg);
}
regval16 = __raw_readw(clk->enable_reg);
regval16 |= (1 << clk->enable_bit);
__raw_writew(regval16, clk->enable_reg);
}
return 0;
@ -539,44 +659,26 @@ static void omap1_clk_disable_generic(struct clk *clk)
return;
if (clk->flags & ENABLE_REG_32BIT) {
if (clk->flags & VIRTUAL_IO_ADDRESS) {
regval32 = __raw_readl(clk->enable_reg);
regval32 &= ~(1 << clk->enable_bit);
__raw_writel(regval32, clk->enable_reg);
} else {
regval32 = omap_readl(clk->enable_reg);
regval32 &= ~(1 << clk->enable_bit);
omap_writel(regval32, clk->enable_reg);
}
regval32 = __raw_readl(clk->enable_reg);
regval32 &= ~(1 << clk->enable_bit);
__raw_writel(regval32, clk->enable_reg);
} else {
if (clk->flags & VIRTUAL_IO_ADDRESS) {
regval16 = __raw_readw(clk->enable_reg);
regval16 &= ~(1 << clk->enable_bit);
__raw_writew(regval16, clk->enable_reg);
} else {
regval16 = omap_readw(clk->enable_reg);
regval16 &= ~(1 << clk->enable_bit);
omap_writew(regval16, clk->enable_reg);
}
regval16 = __raw_readw(clk->enable_reg);
regval16 &= ~(1 << clk->enable_bit);
__raw_writew(regval16, clk->enable_reg);
}
}
static const struct clkops clkops_generic = {
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
};
static long omap1_clk_round_rate(struct clk *clk, unsigned long rate)
{
int dsor_exp;
if (clk->flags & RATE_FIXED)
return clk->rate;
if (clk->flags & RATE_CKCTL) {
dsor_exp = calc_dsor_exp(clk, rate);
if (dsor_exp < 0)
return dsor_exp;
if (dsor_exp > 3)
dsor_exp = 3;
return clk->parent->rate / (1 << dsor_exp);
}
if (clk->round_rate != NULL)
return clk->round_rate(clk, rate);
@ -586,30 +688,9 @@ static long omap1_clk_round_rate(struct clk *clk, unsigned long rate)
static int omap1_clk_set_rate(struct clk *clk, unsigned long rate)
{
int ret = -EINVAL;
int dsor_exp;
__u16 regval;
if (clk->set_rate)
ret = clk->set_rate(clk, rate);
else if (clk->flags & RATE_CKCTL) {
dsor_exp = calc_dsor_exp(clk, rate);
if (dsor_exp > 3)
dsor_exp = -EINVAL;
if (dsor_exp < 0)
return dsor_exp;
regval = omap_readw(ARM_CKCTL);
regval &= ~(3 << clk->rate_offset);
regval |= dsor_exp << clk->rate_offset;
regval = verify_ckctl_value(regval);
omap_writew(regval, ARM_CKCTL);
clk->rate = clk->parent->rate / (1 << dsor_exp);
ret = 0;
}
if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES)))
propagate_rate(clk);
return ret;
}
@ -632,17 +713,10 @@ static void __init omap1_clk_disable_unused(struct clk *clk)
}
/* Is the clock already disabled? */
if (clk->flags & ENABLE_REG_32BIT) {
if (clk->flags & VIRTUAL_IO_ADDRESS)
regval32 = __raw_readl(clk->enable_reg);
else
regval32 = omap_readl(clk->enable_reg);
} else {
if (clk->flags & VIRTUAL_IO_ADDRESS)
regval32 = __raw_readw(clk->enable_reg);
else
regval32 = omap_readw(clk->enable_reg);
}
if (clk->flags & ENABLE_REG_32BIT)
regval32 = __raw_readl(clk->enable_reg);
else
regval32 = __raw_readw(clk->enable_reg);
if ((regval32 & (1 << clk->enable_bit)) == 0)
return;
@ -659,7 +733,7 @@ static void __init omap1_clk_disable_unused(struct clk *clk)
}
printk(KERN_INFO "Disabling unused clock \"%s\"... ", clk->name);
clk->disable(clk);
clk->ops->disable(clk);
printk(" done\n");
}
@ -677,10 +751,10 @@ static struct clk_functions omap1_clk_functions = {
int __init omap1_clk_init(void)
{
struct clk ** clkp;
struct omap_clk *c;
const struct omap_clock_config *info;
int crystal_type = 0; /* Default 12 MHz */
u32 reg;
u32 reg, cpu_mask;
#ifdef CONFIG_DEBUG_LL
/* Resets some clocks that may be left on from bootloader,
@ -700,28 +774,25 @@ int __init omap1_clk_init(void)
/* By default all idlect1 clocks are allowed to idle */
arm_idlect1_mask = ~0;
for (clkp = onchip_clks; clkp < onchip_clks+ARRAY_SIZE(onchip_clks); clkp++) {
if (((*clkp)->flags &CLOCK_IN_OMAP1510) && cpu_is_omap1510()) {
clk_register(*clkp);
continue;
}
for (c = omap_clks; c < omap_clks + ARRAY_SIZE(omap_clks); c++)
clk_init_one(c->lk.clk);
if (((*clkp)->flags &CLOCK_IN_OMAP16XX) && cpu_is_omap16xx()) {
clk_register(*clkp);
continue;
}
cpu_mask = 0;
if (cpu_is_omap16xx())
cpu_mask |= CK_16XX;
if (cpu_is_omap1510())
cpu_mask |= CK_1510;
if (cpu_is_omap730())
cpu_mask |= CK_730;
if (cpu_is_omap310())
cpu_mask |= CK_310;
if (((*clkp)->flags &CLOCK_IN_OMAP730) && cpu_is_omap730()) {
clk_register(*clkp);
continue;
for (c = omap_clks; c < omap_clks + ARRAY_SIZE(omap_clks); c++)
if (c->cpu & cpu_mask) {
clkdev_add(&c->lk);
clk_register(c->lk.clk);
}
if (((*clkp)->flags &CLOCK_IN_OMAP310) && cpu_is_omap310()) {
clk_register(*clkp);
continue;
}
}
info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config);
if (info != NULL) {
if (!cpu_is_omap15xx())
@ -769,7 +840,6 @@ int __init omap1_clk_init(void)
}
}
}
propagate_rate(&ck_dpll1);
#else
/* Find the highest supported frequency and enable it */
if (omap1_select_table_rate(&virtual_ck_mpu, ~0)) {
@ -778,9 +848,9 @@ int __init omap1_clk_init(void)
omap_writew(0x2290, DPLL_CTL);
omap_writew(cpu_is_omap730() ? 0x3005 : 0x1005, ARM_CKCTL);
ck_dpll1.rate = 60000000;
propagate_rate(&ck_dpll1);
}
#endif
propagate_rate(&ck_dpll1);
/* Cache rates for clocks connected to ck_ref (not dpll1) */
propagate_rate(&ck_ref);
printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): "
@ -832,4 +902,3 @@ int __init omap1_clk_init(void)
return 0;
}

View File

@ -13,27 +13,22 @@
#ifndef __ARCH_ARM_MACH_OMAP1_CLOCK_H
#define __ARCH_ARM_MACH_OMAP1_CLOCK_H
static int omap1_clk_enable_generic(struct clk * clk);
static void omap1_clk_disable_generic(struct clk * clk);
static void omap1_ckctl_recalc(struct clk * clk);
static void omap1_watchdog_recalc(struct clk * clk);
static unsigned long omap1_ckctl_recalc(struct clk *clk);
static unsigned long omap1_watchdog_recalc(struct clk *clk);
static int omap1_set_sossi_rate(struct clk *clk, unsigned long rate);
static void omap1_sossi_recalc(struct clk *clk);
static void omap1_ckctl_recalc_dsp_domain(struct clk * clk);
static int omap1_clk_enable_dsp_domain(struct clk * clk);
static unsigned long omap1_sossi_recalc(struct clk *clk);
static unsigned long omap1_ckctl_recalc_dsp_domain(struct clk *clk);
static int omap1_clk_set_rate_dsp_domain(struct clk * clk, unsigned long rate);
static void omap1_clk_disable_dsp_domain(struct clk * clk);
static int omap1_set_uart_rate(struct clk * clk, unsigned long rate);
static void omap1_uart_recalc(struct clk * clk);
static int omap1_clk_enable_uart_functional(struct clk * clk);
static void omap1_clk_disable_uart_functional(struct clk * clk);
static unsigned long omap1_uart_recalc(struct clk *clk);
static int omap1_set_ext_clk_rate(struct clk * clk, unsigned long rate);
static long omap1_round_ext_clk_rate(struct clk * clk, unsigned long rate);
static void omap1_init_ext_clk(struct clk * clk);
static int omap1_select_table_rate(struct clk * clk, unsigned long rate);
static long omap1_round_to_table_rate(struct clk * clk, unsigned long rate);
static int omap1_clk_enable(struct clk *clk);
static void omap1_clk_disable(struct clk *clk);
static int omap1_clk_set_rate_ckctl_arm(struct clk *clk, unsigned long rate);
static long omap1_clk_round_rate_ckctl_arm(struct clk *clk, unsigned long rate);
struct mpu_rate {
unsigned long rate;
@ -152,101 +147,84 @@ static struct mpu_rate rate_table[] = {
static struct clk ck_ref = {
.name = "ck_ref",
.ops = &clkops_null,
.rate = 12000000,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
};
static struct clk ck_dpll1 = {
.name = "ck_dpll1",
.ops = &clkops_null,
.parent = &ck_ref,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
CLOCK_IN_OMAP310 | RATE_PROPAGATES | ALWAYS_ENABLED,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
};
static struct arm_idlect1_clk ck_dpll1out = {
.clk = {
.name = "ck_dpll1out",
.ops = &clkops_generic,
.parent = &ck_dpll1,
.flags = CLOCK_IN_OMAP16XX | CLOCK_IDLE_CONTROL |
ENABLE_REG_32BIT | RATE_PROPAGATES,
.enable_reg = (void __iomem *)ARM_IDLECT2,
.flags = CLOCK_IDLE_CONTROL | ENABLE_REG_32BIT,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_CKOUT_ARM,
.recalc = &followparent_recalc,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
},
.idlect_shift = 12,
};
static struct clk sossi_ck = {
.name = "ck_sossi",
.ops = &clkops_generic,
.parent = &ck_dpll1out.clk,
.flags = CLOCK_IN_OMAP16XX | CLOCK_NO_IDLE_PARENT |
ENABLE_REG_32BIT,
.enable_reg = (void __iomem *)MOD_CONF_CTRL_1,
.flags = CLOCK_NO_IDLE_PARENT | ENABLE_REG_32BIT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_1),
.enable_bit = 16,
.recalc = &omap1_sossi_recalc,
.set_rate = &omap1_set_sossi_rate,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
};
static struct clk arm_ck = {
.name = "arm_ck",
.ops = &clkops_null,
.parent = &ck_dpll1,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
CLOCK_IN_OMAP310 | RATE_CKCTL | RATE_PROPAGATES |
ALWAYS_ENABLED,
.rate_offset = CKCTL_ARMDIV_OFFSET,
.recalc = &omap1_ckctl_recalc,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
.round_rate = omap1_clk_round_rate_ckctl_arm,
.set_rate = omap1_clk_set_rate_ckctl_arm,
};
static struct arm_idlect1_clk armper_ck = {
.clk = {
.name = "armper_ck",
.ops = &clkops_generic,
.parent = &ck_dpll1,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
CLOCK_IN_OMAP310 | RATE_CKCTL |
CLOCK_IDLE_CONTROL,
.enable_reg = (void __iomem *)ARM_IDLECT2,
.flags = CLOCK_IDLE_CONTROL,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_PERCK,
.rate_offset = CKCTL_PERDIV_OFFSET,
.recalc = &omap1_ckctl_recalc,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
.round_rate = omap1_clk_round_rate_ckctl_arm,
.set_rate = omap1_clk_set_rate_ckctl_arm,
},
.idlect_shift = 2,
};
static struct clk arm_gpio_ck = {
.name = "arm_gpio_ck",
.ops = &clkops_generic,
.parent = &ck_dpll1,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
.enable_reg = (void __iomem *)ARM_IDLECT2,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_GPIOCK,
.recalc = &followparent_recalc,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
};
static struct arm_idlect1_clk armxor_ck = {
.clk = {
.name = "armxor_ck",
.ops = &clkops_generic,
.parent = &ck_ref,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL,
.enable_reg = (void __iomem *)ARM_IDLECT2,
.flags = CLOCK_IDLE_CONTROL,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_XORPCK,
.recalc = &followparent_recalc,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
},
.idlect_shift = 1,
};
@ -254,14 +232,12 @@ static struct arm_idlect1_clk armxor_ck = {
static struct arm_idlect1_clk armtim_ck = {
.clk = {
.name = "armtim_ck",
.ops = &clkops_generic,
.parent = &ck_ref,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL,
.enable_reg = (void __iomem *)ARM_IDLECT2,
.flags = CLOCK_IDLE_CONTROL,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_TIMCK,
.recalc = &followparent_recalc,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
},
.idlect_shift = 9,
};
@ -269,201 +245,166 @@ static struct arm_idlect1_clk armtim_ck = {
static struct arm_idlect1_clk armwdt_ck = {
.clk = {
.name = "armwdt_ck",
.ops = &clkops_generic,
.parent = &ck_ref,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL,
.enable_reg = (void __iomem *)ARM_IDLECT2,
.flags = CLOCK_IDLE_CONTROL,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_WDTCK,
.recalc = &omap1_watchdog_recalc,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
},
.idlect_shift = 0,
};
static struct clk arminth_ck16xx = {
.name = "arminth_ck",
.ops = &clkops_null,
.parent = &arm_ck,
.flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
.recalc = &followparent_recalc,
/* Note: On 16xx the frequency can be divided by 2 by programming
* ARM_CKCTL:ARM_INTHCK_SEL(14) to 1
*
* 1510 version is in TC clocks.
*/
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
};
static struct clk dsp_ck = {
.name = "dsp_ck",
.ops = &clkops_generic,
.parent = &ck_dpll1,
.flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
RATE_CKCTL,
.enable_reg = (void __iomem *)ARM_CKCTL,
.enable_reg = OMAP1_IO_ADDRESS(ARM_CKCTL),
.enable_bit = EN_DSPCK,
.rate_offset = CKCTL_DSPDIV_OFFSET,
.recalc = &omap1_ckctl_recalc,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
.round_rate = omap1_clk_round_rate_ckctl_arm,
.set_rate = omap1_clk_set_rate_ckctl_arm,
};
static struct clk dspmmu_ck = {
.name = "dspmmu_ck",
.ops = &clkops_null,
.parent = &ck_dpll1,
.flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
RATE_CKCTL | ALWAYS_ENABLED,
.rate_offset = CKCTL_DSPMMUDIV_OFFSET,
.recalc = &omap1_ckctl_recalc,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
.round_rate = omap1_clk_round_rate_ckctl_arm,
.set_rate = omap1_clk_set_rate_ckctl_arm,
};
static struct clk dspper_ck = {
.name = "dspper_ck",
.ops = &clkops_dspck,
.parent = &ck_dpll1,
.flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
RATE_CKCTL | VIRTUAL_IO_ADDRESS,
.enable_reg = DSP_IDLECT2,
.enable_bit = EN_PERCK,
.rate_offset = CKCTL_PERDIV_OFFSET,
.recalc = &omap1_ckctl_recalc_dsp_domain,
.round_rate = omap1_clk_round_rate_ckctl_arm,
.set_rate = &omap1_clk_set_rate_dsp_domain,
.enable = &omap1_clk_enable_dsp_domain,
.disable = &omap1_clk_disable_dsp_domain,
};
static struct clk dspxor_ck = {
.name = "dspxor_ck",
.ops = &clkops_dspck,
.parent = &ck_ref,
.flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
VIRTUAL_IO_ADDRESS,
.enable_reg = DSP_IDLECT2,
.enable_bit = EN_XORPCK,
.recalc = &followparent_recalc,
.enable = &omap1_clk_enable_dsp_domain,
.disable = &omap1_clk_disable_dsp_domain,
};
static struct clk dsptim_ck = {
.name = "dsptim_ck",
.ops = &clkops_dspck,
.parent = &ck_ref,
.flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
VIRTUAL_IO_ADDRESS,
.enable_reg = DSP_IDLECT2,
.enable_bit = EN_DSPTIMCK,
.recalc = &followparent_recalc,
.enable = &omap1_clk_enable_dsp_domain,
.disable = &omap1_clk_disable_dsp_domain,
};
/* Tie ARM_IDLECT1:IDLIF_ARM to this logical clock structure */
static struct arm_idlect1_clk tc_ck = {
.clk = {
.name = "tc_ck",
.ops = &clkops_null,
.parent = &ck_dpll1,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
CLOCK_IN_OMAP730 | CLOCK_IN_OMAP310 |
RATE_CKCTL | RATE_PROPAGATES |
ALWAYS_ENABLED | CLOCK_IDLE_CONTROL,
.flags = CLOCK_IDLE_CONTROL,
.rate_offset = CKCTL_TCDIV_OFFSET,
.recalc = &omap1_ckctl_recalc,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
.round_rate = omap1_clk_round_rate_ckctl_arm,
.set_rate = omap1_clk_set_rate_ckctl_arm,
},
.idlect_shift = 6,
};
static struct clk arminth_ck1510 = {
.name = "arminth_ck",
.ops = &clkops_null,
.parent = &tc_ck.clk,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
ALWAYS_ENABLED,
.recalc = &followparent_recalc,
/* Note: On 1510 the frequency follows TC_CK
*
* 16xx version is in MPU clocks.
*/
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
};
static struct clk tipb_ck = {
/* No-idle controlled by "tc_ck" */
.name = "tipb_ck",
.ops = &clkops_null,
.parent = &tc_ck.clk,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
ALWAYS_ENABLED,
.recalc = &followparent_recalc,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
};
static struct clk l3_ocpi_ck = {
/* No-idle controlled by "tc_ck" */
.name = "l3_ocpi_ck",
.ops = &clkops_generic,
.parent = &tc_ck.clk,
.flags = CLOCK_IN_OMAP16XX,
.enable_reg = (void __iomem *)ARM_IDLECT3,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT3),
.enable_bit = EN_OCPI_CK,
.recalc = &followparent_recalc,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
};
static struct clk tc1_ck = {
.name = "tc1_ck",
.ops = &clkops_generic,
.parent = &tc_ck.clk,
.flags = CLOCK_IN_OMAP16XX,
.enable_reg = (void __iomem *)ARM_IDLECT3,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT3),
.enable_bit = EN_TC1_CK,
.recalc = &followparent_recalc,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
};
static struct clk tc2_ck = {
.name = "tc2_ck",
.ops = &clkops_generic,
.parent = &tc_ck.clk,
.flags = CLOCK_IN_OMAP16XX,
.enable_reg = (void __iomem *)ARM_IDLECT3,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT3),
.enable_bit = EN_TC2_CK,
.recalc = &followparent_recalc,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
};
static struct clk dma_ck = {
/* No-idle controlled by "tc_ck" */
.name = "dma_ck",
.ops = &clkops_null,
.parent = &tc_ck.clk,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
.recalc = &followparent_recalc,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
};
static struct clk dma_lcdfree_ck = {
.name = "dma_lcdfree_ck",
.ops = &clkops_null,
.parent = &tc_ck.clk,
.flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
.recalc = &followparent_recalc,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
};
static struct arm_idlect1_clk api_ck = {
.clk = {
.name = "api_ck",
.ops = &clkops_generic,
.parent = &tc_ck.clk,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL,
.enable_reg = (void __iomem *)ARM_IDLECT2,
.flags = CLOCK_IDLE_CONTROL,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_APICK,
.recalc = &followparent_recalc,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
},
.idlect_shift = 8,
};
@ -471,276 +412,238 @@ static struct arm_idlect1_clk api_ck = {
static struct arm_idlect1_clk lb_ck = {
.clk = {
.name = "lb_ck",
.ops = &clkops_generic,
.parent = &tc_ck.clk,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
CLOCK_IDLE_CONTROL,
.enable_reg = (void __iomem *)ARM_IDLECT2,
.flags = CLOCK_IDLE_CONTROL,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_LBCK,
.recalc = &followparent_recalc,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
},
.idlect_shift = 4,
};
static struct clk rhea1_ck = {
.name = "rhea1_ck",
.ops = &clkops_null,
.parent = &tc_ck.clk,
.flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
.recalc = &followparent_recalc,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
};
static struct clk rhea2_ck = {
.name = "rhea2_ck",
.ops = &clkops_null,
.parent = &tc_ck.clk,
.flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
.recalc = &followparent_recalc,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
};
static struct clk lcd_ck_16xx = {
.name = "lcd_ck",
.ops = &clkops_generic,
.parent = &ck_dpll1,
.flags = CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730 | RATE_CKCTL,
.enable_reg = (void __iomem *)ARM_IDLECT2,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_LCDCK,
.rate_offset = CKCTL_LCDDIV_OFFSET,
.recalc = &omap1_ckctl_recalc,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
.round_rate = omap1_clk_round_rate_ckctl_arm,
.set_rate = omap1_clk_set_rate_ckctl_arm,
};
static struct arm_idlect1_clk lcd_ck_1510 = {
.clk = {
.name = "lcd_ck",
.ops = &clkops_generic,
.parent = &ck_dpll1,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
RATE_CKCTL | CLOCK_IDLE_CONTROL,
.enable_reg = (void __iomem *)ARM_IDLECT2,
.flags = CLOCK_IDLE_CONTROL,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_LCDCK,
.rate_offset = CKCTL_LCDDIV_OFFSET,
.recalc = &omap1_ckctl_recalc,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
.round_rate = omap1_clk_round_rate_ckctl_arm,
.set_rate = omap1_clk_set_rate_ckctl_arm,
},
.idlect_shift = 3,
};
static struct clk uart1_1510 = {
.name = "uart1_ck",
.ops = &clkops_null,
/* Direct from ULPD, no real parent */
.parent = &armper_ck.clk,
.rate = 12000000,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
ENABLE_REG_32BIT | ALWAYS_ENABLED |
CLOCK_NO_IDLE_PARENT,
.enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
.enable_bit = 29, /* Chooses between 12MHz and 48MHz */
.set_rate = &omap1_set_uart_rate,
.recalc = &omap1_uart_recalc,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
};
static struct uart_clk uart1_16xx = {
.clk = {
.name = "uart1_ck",
.ops = &clkops_uart,
/* Direct from ULPD, no real parent */
.parent = &armper_ck.clk,
.rate = 48000000,
.flags = CLOCK_IN_OMAP16XX | RATE_FIXED |
ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
.flags = RATE_FIXED | ENABLE_REG_32BIT |
CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
.enable_bit = 29,
.enable = &omap1_clk_enable_uart_functional,
.disable = &omap1_clk_disable_uart_functional,
},
.sysc_addr = 0xfffb0054,
};
static struct clk uart2_ck = {
.name = "uart2_ck",
.ops = &clkops_null,
/* Direct from ULPD, no real parent */
.parent = &armper_ck.clk,
.rate = 12000000,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
CLOCK_IN_OMAP310 | ENABLE_REG_32BIT |
ALWAYS_ENABLED | CLOCK_NO_IDLE_PARENT,
.enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
.enable_bit = 30, /* Chooses between 12MHz and 48MHz */
.set_rate = &omap1_set_uart_rate,
.recalc = &omap1_uart_recalc,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
};
static struct clk uart3_1510 = {
.name = "uart3_ck",
.ops = &clkops_null,
/* Direct from ULPD, no real parent */
.parent = &armper_ck.clk,
.rate = 12000000,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
ENABLE_REG_32BIT | ALWAYS_ENABLED |
CLOCK_NO_IDLE_PARENT,
.enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
.enable_bit = 31, /* Chooses between 12MHz and 48MHz */
.set_rate = &omap1_set_uart_rate,
.recalc = &omap1_uart_recalc,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
};
static struct uart_clk uart3_16xx = {
.clk = {
.name = "uart3_ck",
.ops = &clkops_uart,
/* Direct from ULPD, no real parent */
.parent = &armper_ck.clk,
.rate = 48000000,
.flags = CLOCK_IN_OMAP16XX | RATE_FIXED |
ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
.flags = RATE_FIXED | ENABLE_REG_32BIT |
CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
.enable_bit = 31,
.enable = &omap1_clk_enable_uart_functional,
.disable = &omap1_clk_disable_uart_functional,
},
.sysc_addr = 0xfffb9854,
};
static struct clk usb_clko = { /* 6 MHz output on W4_USB_CLKO */
.name = "usb_clko",
.ops = &clkops_generic,
/* Direct from ULPD, no parent */
.rate = 6000000,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
CLOCK_IN_OMAP310 | RATE_FIXED | ENABLE_REG_32BIT,
.enable_reg = (void __iomem *)ULPD_CLOCK_CTRL,
.flags = RATE_FIXED | ENABLE_REG_32BIT,
.enable_reg = OMAP1_IO_ADDRESS(ULPD_CLOCK_CTRL),
.enable_bit = USB_MCLK_EN_BIT,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
};
static struct clk usb_hhc_ck1510 = {
.name = "usb_hhc_ck",
.ops = &clkops_generic,
/* Direct from ULPD, no parent */
.rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
RATE_FIXED | ENABLE_REG_32BIT,
.enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
.flags = RATE_FIXED | ENABLE_REG_32BIT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
.enable_bit = USB_HOST_HHC_UHOST_EN,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
};
static struct clk usb_hhc_ck16xx = {
.name = "usb_hhc_ck",
.ops = &clkops_generic,
/* Direct from ULPD, no parent */
.rate = 48000000,
/* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */
.flags = CLOCK_IN_OMAP16XX |
RATE_FIXED | ENABLE_REG_32BIT,
.enable_reg = (void __iomem *)OTG_BASE + 0x08 /* OTG_SYSCON_2 */,
.flags = RATE_FIXED | ENABLE_REG_32BIT,
.enable_reg = OMAP1_IO_ADDRESS(OTG_BASE + 0x08), /* OTG_SYSCON_2 */
.enable_bit = 8 /* UHOST_EN */,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
};
static struct clk usb_dc_ck = {
.name = "usb_dc_ck",
.ops = &clkops_generic,
/* Direct from ULPD, no parent */
.rate = 48000000,
.flags = CLOCK_IN_OMAP16XX | RATE_FIXED,
.enable_reg = (void __iomem *)SOFT_REQ_REG,
.flags = RATE_FIXED,
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
.enable_bit = 4,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
};
static struct clk mclk_1510 = {
.name = "mclk",
.ops = &clkops_generic,
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
.rate = 12000000,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | RATE_FIXED,
.enable_reg = (void __iomem *)SOFT_REQ_REG,
.enable_bit = 6,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
.flags = RATE_FIXED,
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
.enable_bit = 6,
};
static struct clk mclk_16xx = {
.name = "mclk",
.ops = &clkops_generic,
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
.flags = CLOCK_IN_OMAP16XX,
.enable_reg = (void __iomem *)COM_CLK_DIV_CTRL_SEL,
.enable_reg = OMAP1_IO_ADDRESS(COM_CLK_DIV_CTRL_SEL),
.enable_bit = COM_ULPD_PLL_CLK_REQ,
.set_rate = &omap1_set_ext_clk_rate,
.round_rate = &omap1_round_ext_clk_rate,
.init = &omap1_init_ext_clk,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
};
static struct clk bclk_1510 = {
.name = "bclk",
.ops = &clkops_generic,
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
.rate = 12000000,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | RATE_FIXED,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
.flags = RATE_FIXED,
};
static struct clk bclk_16xx = {
.name = "bclk",
.ops = &clkops_generic,
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
.flags = CLOCK_IN_OMAP16XX,
.enable_reg = (void __iomem *)SWD_CLK_DIV_CTRL_SEL,
.enable_reg = OMAP1_IO_ADDRESS(SWD_CLK_DIV_CTRL_SEL),
.enable_bit = SWD_ULPD_PLL_CLK_REQ,
.set_rate = &omap1_set_ext_clk_rate,
.round_rate = &omap1_round_ext_clk_rate,
.init = &omap1_init_ext_clk,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
};
static struct clk mmc1_ck = {
.name = "mmc_ck",
.ops = &clkops_generic,
/* Functional clock is direct from ULPD, interface clock is ARMPER */
.parent = &armper_ck.clk,
.rate = 48000000,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
CLOCK_IN_OMAP310 | RATE_FIXED | ENABLE_REG_32BIT |
CLOCK_NO_IDLE_PARENT,
.enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
.flags = RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
.enable_bit = 23,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
};
static struct clk mmc2_ck = {
.name = "mmc_ck",
.id = 1,
.ops = &clkops_generic,
/* Functional clock is direct from ULPD, interface clock is ARMPER */
.parent = &armper_ck.clk,
.rate = 48000000,
.flags = CLOCK_IN_OMAP16XX |
RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
.flags = RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
.enable_bit = 20,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
};
static struct clk virtual_ck_mpu = {
.name = "mpu",
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
CLOCK_IN_OMAP310 | VIRTUAL_CLOCK | ALWAYS_ENABLED,
.ops = &clkops_null,
.parent = &arm_ck, /* Is smarter alias for */
.recalc = &followparent_recalc,
.set_rate = &omap1_select_table_rate,
.round_rate = &omap1_round_to_table_rate,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
};
/* virtual functional clock domain for I2C. Just for making sure that ARMXOR_CK
@ -748,78 +651,19 @@ remains active during MPU idle whenever this is enabled */
static struct clk i2c_fck = {
.name = "i2c_fck",
.id = 1,
.flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
VIRTUAL_CLOCK | CLOCK_NO_IDLE_PARENT |
ALWAYS_ENABLED,
.ops = &clkops_null,
.flags = CLOCK_NO_IDLE_PARENT,
.parent = &armxor_ck.clk,
.recalc = &followparent_recalc,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
};
static struct clk i2c_ick = {
.name = "i2c_ick",
.id = 1,
.flags = CLOCK_IN_OMAP16XX |
VIRTUAL_CLOCK | CLOCK_NO_IDLE_PARENT |
ALWAYS_ENABLED,
.ops = &clkops_null,
.flags = CLOCK_NO_IDLE_PARENT,
.parent = &armper_ck.clk,
.recalc = &followparent_recalc,
.enable = &omap1_clk_enable_generic,
.disable = &omap1_clk_disable_generic,
};
static struct clk * onchip_clks[] = {
/* non-ULPD clocks */
&ck_ref,
&ck_dpll1,
/* CK_GEN1 clocks */
&ck_dpll1out.clk,
&sossi_ck,
&arm_ck,
&armper_ck.clk,
&arm_gpio_ck,
&armxor_ck.clk,
&armtim_ck.clk,
&armwdt_ck.clk,
&arminth_ck1510, &arminth_ck16xx,
/* CK_GEN2 clocks */
&dsp_ck,
&dspmmu_ck,
&dspper_ck,
&dspxor_ck,
&dsptim_ck,
/* CK_GEN3 clocks */
&tc_ck.clk,
&tipb_ck,
&l3_ocpi_ck,
&tc1_ck,
&tc2_ck,
&dma_ck,
&dma_lcdfree_ck,
&api_ck.clk,
&lb_ck.clk,
&rhea1_ck,
&rhea2_ck,
&lcd_ck_16xx,
&lcd_ck_1510.clk,
/* ULPD clocks */
&uart1_1510,
&uart1_16xx.clk,
&uart2_ck,
&uart3_1510,
&uart3_16xx.clk,
&usb_clko,
&usb_hhc_ck1510, &usb_hhc_ck16xx,
&usb_dc_ck,
&mclk_1510, &mclk_16xx,
&bclk_1510, &bclk_16xx,
&mmc1_ck,
&mmc2_ck,
/* Virtual clocks */
&virtual_ck_mpu,
&i2c_fck,
&i2c_ick,
};
#endif

View File

@ -28,9 +28,9 @@
#define DPS_RSTCT2_PER_EN (1 << 0)
#define DSP_RSTCT2_WD_PER_EN (1 << 1)
#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX)
const char *clk_names[] = { "dsp_ck", "api_ck", "dspxor_ck" };
#endif
static int dsp_use;
static struct clk *api_clk;
static struct clk *dsp_clk;
static void omap1_mcbsp_request(unsigned int id)
{
@ -39,20 +39,40 @@ static void omap1_mcbsp_request(unsigned int id)
* are DSP public peripherals.
*/
if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) {
omap_dsp_request_mem();
/*
* DSP external peripheral reset
* FIXME: This should be moved to dsp code
*/
__raw_writew(__raw_readw(DSP_RSTCT2) | DPS_RSTCT2_PER_EN |
DSP_RSTCT2_WD_PER_EN, DSP_RSTCT2);
if (dsp_use++ == 0) {
api_clk = clk_get(NULL, "api_clk");
dsp_clk = clk_get(NULL, "dsp_clk");
if (!IS_ERR(api_clk) && !IS_ERR(dsp_clk)) {
clk_enable(api_clk);
clk_enable(dsp_clk);
omap_dsp_request_mem();
/*
* DSP external peripheral reset
* FIXME: This should be moved to dsp code
*/
__raw_writew(__raw_readw(DSP_RSTCT2) | DPS_RSTCT2_PER_EN |
DSP_RSTCT2_WD_PER_EN, DSP_RSTCT2);
}
}
}
}
static void omap1_mcbsp_free(unsigned int id)
{
if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3)
omap_dsp_release_mem();
if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) {
if (--dsp_use == 0) {
omap_dsp_release_mem();
if (!IS_ERR(api_clk)) {
clk_disable(api_clk);
clk_put(api_clk);
}
if (!IS_ERR(dsp_clk)) {
clk_disable(dsp_clk);
clk_put(dsp_clk);
}
}
}
}
static struct omap_mcbsp_ops omap1_mcbsp_ops = {
@ -94,8 +114,6 @@ static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata[] = {
.rx_irq = INT_McBSP1RX,
.tx_irq = INT_McBSP1TX,
.ops = &omap1_mcbsp_ops,
.clk_names = clk_names,
.num_clks = 3,
},
{
.phys_base = OMAP1510_MCBSP2_BASE,
@ -112,8 +130,6 @@ static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata[] = {
.rx_irq = INT_McBSP3RX,
.tx_irq = INT_McBSP3TX,
.ops = &omap1_mcbsp_ops,
.clk_names = clk_names,
.num_clks = 3,
},
};
#define OMAP15XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap15xx_mcbsp_pdata)
@ -131,8 +147,6 @@ static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata[] = {
.rx_irq = INT_McBSP1RX,
.tx_irq = INT_McBSP1TX,
.ops = &omap1_mcbsp_ops,
.clk_names = clk_names,
.num_clks = 3,
},
{
.phys_base = OMAP1610_MCBSP2_BASE,
@ -149,8 +163,6 @@ static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata[] = {
.rx_irq = INT_McBSP3RX,
.tx_irq = INT_McBSP3TX,
.ops = &omap1_mcbsp_ops,
.clk_names = clk_names,
.num_clks = 3,
},
};
#define OMAP16XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap16xx_mcbsp_pdata)

View File

@ -3,7 +3,7 @@
#
# Common support
obj-y := irq.o id.o io.o memory.o control.o prcm.o clock.o mux.o \
obj-y := irq.o id.o io.o sdrc.o control.o prcm.o clock.o mux.o \
devices.o serial.o gpmc.o timer-gp.o powerdomain.o \
clockdomain.o
@ -14,6 +14,10 @@ obj-$(CONFIG_ARCH_OMAP2420) += sram242x.o
obj-$(CONFIG_ARCH_OMAP2430) += sram243x.o
obj-$(CONFIG_ARCH_OMAP3) += sram34xx.o
# SMS/SDRC
obj-$(CONFIG_ARCH_OMAP2) += sdrc2xxx.o
# obj-$(CONFIG_ARCH_OMAP3) += sdrc3xxx.o
# Power Management
ifeq ($(CONFIG_PM),y)
obj-y += pm.o

View File

@ -185,7 +185,7 @@ out:
static void __init omap_2430sdp_init_irq(void)
{
omap2_init_common_hw();
omap2_init_common_hw(NULL);
omap_init_irq();
omap_gpio_init();
sdp2430_init_smc91x();

View File

@ -249,7 +249,7 @@ out:
static void __init omap_apollon_init_irq(void)
{
omap2_init_common_hw();
omap2_init_common_hw(NULL);
omap_init_irq();
omap_gpio_init();
apollon_init_smc91x();

View File

@ -33,7 +33,7 @@
static void __init omap_generic_init_irq(void)
{
omap2_init_common_hw();
omap2_init_common_hw(NULL);
omap_init_irq();
}

View File

@ -363,7 +363,7 @@ static void __init h4_init_flash(void)
static void __init omap_h4_init_irq(void)
{
omap2_init_common_hw();
omap2_init_common_hw(NULL);
omap_init_irq();
omap_gpio_init();
h4_init_flash();

View File

@ -98,7 +98,7 @@ static inline void __init ldp_init_smc911x(void)
static void __init omap_ldp_init_irq(void)
{
omap2_init_common_hw();
omap2_init_common_hw(NULL);
omap_init_irq();
omap_gpio_init();
ldp_init_smc911x();

View File

@ -184,7 +184,7 @@ static int __init omap3_beagle_i2c_init(void)
static void __init omap3_beagle_init_irq(void)
{
omap2_init_common_hw();
omap2_init_common_hw(NULL);
omap_init_irq();
omap_gpio_init();
}

View File

@ -26,11 +26,10 @@
#include <mach/clock.h>
#include <mach/clockdomain.h>
#include <mach/sram.h>
#include <mach/cpu.h>
#include <asm/div64.h>
#include "memory.h"
#include <mach/sdrc.h>
#include "sdrc.h"
#include "clock.h"
#include "prm.h"
@ -46,7 +45,7 @@
#define DPLL_MIN_DIVIDER 1
/* Possible error results from _dpll_test_mult */
#define DPLL_MULT_UNDERFLOW (1 << 0)
#define DPLL_MULT_UNDERFLOW -1
/*
* Scale factor to mitigate roundoff errors in DPLL rate rounding.
@ -59,12 +58,90 @@
#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 specific clock 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)
{
if (!cpu_is_omap24xx())
return;
if (!(clk->flags & DELAYED_APP))
return;
prm_write_mod_reg(OMAP24XX_VALID_CONFIG, OMAP24XX_GR_MOD,
OMAP24XX_PRCM_CLKCFG_CTRL_OFFSET);
/* OCP barrier */
prm_read_mod_reg(OMAP24XX_GR_MOD, OMAP24XX_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
@ -120,7 +197,7 @@ void omap2_init_clksel_parent(struct clk *clk)
clk->name, clks->parent->name,
((clk->parent) ?
clk->parent->name : "NULL"));
clk->parent = clks->parent;
clk_reparent(clk, clks->parent);
};
found = 1;
}
@ -134,25 +211,52 @@ void omap2_init_clksel_parent(struct clk *clk)
return;
}
/* Returns the DPLL rate */
/**
* 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, dpll;
u32 dpll_mult, dpll_div, v;
struct dpll_data *dd;
dd = clk->dpll_data;
/* REVISIT: What do we return on error? */
if (!dd)
return 0;
dpll = __raw_readl(dd->mult_div1_reg);
dpll_mult = dpll & dd->mult_mask;
/* 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;
}
v = __raw_readl(dd->mult_div1_reg);
dpll_mult = v & dd->mult_mask;
dpll_mult >>= __ffs(dd->mult_mask);
dpll_div = dpll & dd->div1_mask;
dpll_div = v & dd->div1_mask;
dpll_div >>= __ffs(dd->div1_mask);
dpll_clk = (long long)clk->parent->rate * dpll_mult;
dpll_clk = (long long)dd->clk_ref->rate * dpll_mult;
do_div(dpll_clk, dpll_div + 1);
return dpll_clk;
@ -162,14 +266,11 @@ u32 omap2_get_dpll_rate(struct clk *clk)
* Used for clocks that have the same value as the parent clock,
* divided by some factor
*/
void omap2_fixed_divisor_recalc(struct clk *clk)
unsigned long omap2_fixed_divisor_recalc(struct clk *clk)
{
WARN_ON(!clk->fixed_div);
clk->rate = clk->parent->rate / clk->fixed_div;
if (clk->flags & RATE_PROPAGATES)
propagate_rate(clk);
return clk->parent->rate / clk->fixed_div;
}
/**
@ -190,11 +291,10 @@ int omap2_wait_clock_ready(void __iomem *reg, u32 mask, const char *name)
* 24xx uses 0 to indicate not ready, and 1 to indicate ready.
* 34xx reverses this, just to keep us on our toes
*/
if (cpu_mask & (RATE_IN_242X | RATE_IN_243X)) {
if (cpu_mask & (RATE_IN_242X | RATE_IN_243X))
ena = mask;
} else if (cpu_mask & RATE_IN_343X) {
else if (cpu_mask & RATE_IN_343X)
ena = 0;
}
/* Wait for lock */
while (((__raw_readl(reg) & mask) != ena) &&
@ -228,31 +328,12 @@ static void omap2_clk_wait_ready(struct clk *clk)
* it and pull it into struct clk itself somehow.
*/
reg = clk->enable_reg;
if ((((u32)reg & 0xff) >= CM_FCLKEN1) &&
(((u32)reg & 0xff) <= OMAP24XX_CM_FCLKEN2))
other_reg = (void __iomem *)(((u32)reg & ~0xf0) | 0x10); /* CM_ICLKEN* */
else if ((((u32)reg & 0xff) >= CM_ICLKEN1) &&
(((u32)reg & 0xff) <= OMAP24XX_CM_ICLKEN4))
other_reg = (void __iomem *)(((u32)reg & ~0xf0) | 0x00); /* CM_FCLKEN* */
else
return;
/* REVISIT: What are the appropriate exclusions for 34XX? */
/* No check for DSS or cam clocks */
if (cpu_is_omap24xx() && ((u32)reg & 0x0f) == 0) { /* CM_{F,I}CLKEN1 */
if (clk->enable_bit == OMAP24XX_EN_DSS2_SHIFT ||
clk->enable_bit == OMAP24XX_EN_DSS1_SHIFT ||
clk->enable_bit == OMAP24XX_EN_CAM_SHIFT)
return;
}
/* REVISIT: What are the appropriate exclusions for 34XX? */
/* OMAP3: ignore DSS-mod clocks */
if (cpu_is_omap34xx() &&
(((u32)reg & ~0xff) == (u32)OMAP_CM_REGADDR(OMAP3430_DSS_MOD, 0) ||
((((u32)reg & ~0xff) == (u32)OMAP_CM_REGADDR(CORE_MOD, 0)) &&
clk->enable_bit == OMAP3430_EN_SSI_SHIFT)))
return;
/*
* Convert CM_ICLKEN* <-> CM_FCLKEN*. This conversion assumes
* it's just a matter of XORing the bits.
*/
other_reg = (void __iomem *)((u32)reg ^ (CM_FCLKEN ^ CM_ICLKEN));
/* Check if both functional and interface clocks
* are running. */
@ -264,18 +345,9 @@ static void omap2_clk_wait_ready(struct clk *clk)
omap2_wait_clock_ready(st_reg, bit, clk->name);
}
/* Enables clock without considering parent dependencies or use count
* REVISIT: Maybe change this to use clk->enable like on omap1?
*/
int _omap2_clk_enable(struct clk *clk)
static int omap2_dflt_clk_enable(struct clk *clk)
{
u32 regval32;
if (clk->flags & (ALWAYS_ENABLED | PARENT_CONTROLS_CLOCK))
return 0;
if (clk->enable)
return clk->enable(clk);
u32 v;
if (unlikely(clk->enable_reg == NULL)) {
printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
@ -283,33 +355,38 @@ int _omap2_clk_enable(struct clk *clk)
return 0; /* REVISIT: -EINVAL */
}
regval32 = __raw_readl(clk->enable_reg);
v = __raw_readl(clk->enable_reg);
if (clk->flags & INVERT_ENABLE)
regval32 &= ~(1 << clk->enable_bit);
v &= ~(1 << clk->enable_bit);
else
regval32 |= (1 << clk->enable_bit);
__raw_writel(regval32, clk->enable_reg);
wmb();
omap2_clk_wait_ready(clk);
v |= (1 << clk->enable_bit);
__raw_writel(v, clk->enable_reg);
v = __raw_readl(clk->enable_reg); /* OCP barrier */
return 0;
}
/* Disables clock without considering parent dependencies or use count */
void _omap2_clk_disable(struct clk *clk)
static int omap2_dflt_clk_enable_wait(struct clk *clk)
{
u32 regval32;
int ret;
if (clk->flags & (ALWAYS_ENABLED | PARENT_CONTROLS_CLOCK))
return;
if (clk->disable) {
clk->disable(clk);
return;
if (!clk->enable_reg) {
printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
clk->name);
return 0; /* REVISIT: -EINVAL */
}
if (clk->enable_reg == NULL) {
ret = omap2_dflt_clk_enable(clk);
if (ret == 0)
omap2_clk_wait_ready(clk);
return ret;
}
static void omap2_dflt_clk_disable(struct clk *clk)
{
u32 v;
if (!clk->enable_reg) {
/*
* 'Independent' here refers to a clock which is not
* controlled by its parent.
@ -319,20 +396,44 @@ void _omap2_clk_disable(struct clk *clk)
return;
}
regval32 = __raw_readl(clk->enable_reg);
v = __raw_readl(clk->enable_reg);
if (clk->flags & INVERT_ENABLE)
regval32 |= (1 << clk->enable_bit);
v |= (1 << clk->enable_bit);
else
regval32 &= ~(1 << clk->enable_bit);
__raw_writel(regval32, clk->enable_reg);
wmb();
v &= ~(1 << clk->enable_bit);
__raw_writel(v, clk->enable_reg);
/* No OCP barrier needed here since it is a disable operation */
}
const struct clkops clkops_omap2_dflt_wait = {
.enable = omap2_dflt_clk_enable_wait,
.disable = omap2_dflt_clk_disable,
};
const struct clkops clkops_omap2_dflt = {
.enable = omap2_dflt_clk_enable,
.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 (likely((u32)clk->parent))
if (clk->parent)
omap2_clk_disable(clk->parent);
if (clk->clkdm)
omap2_clkdm_clk_disable(clk->clkdm, clk);
@ -345,30 +446,29 @@ int omap2_clk_enable(struct clk *clk)
int ret = 0;
if (clk->usecount++ == 0) {
if (likely((u32)clk->parent))
ret = omap2_clk_enable(clk->parent);
if (unlikely(ret != 0)) {
clk->usecount--;
return ret;
}
if (clk->clkdm)
omap2_clkdm_clk_enable(clk->clkdm, clk);
if (clk->parent) {
ret = omap2_clk_enable(clk->parent);
if (ret)
goto err;
}
ret = _omap2_clk_enable(clk);
if (unlikely(ret != 0)) {
if (clk->clkdm)
omap2_clkdm_clk_disable(clk->clkdm, clk);
if (clk->parent) {
if (ret) {
if (clk->parent)
omap2_clk_disable(clk->parent);
clk->usecount--;
}
goto err;
}
}
return ret;
err:
if (clk->clkdm)
omap2_clkdm_clk_disable(clk->clkdm, clk);
clk->usecount--;
return ret;
}
@ -376,24 +476,22 @@ int omap2_clk_enable(struct clk *clk)
* Used for clocks that are part of CLKSEL_xyz governed clocks.
* REVISIT: Maybe change to use clk->enable() functions like on omap1?
*/
void omap2_clksel_recalc(struct clk *clk)
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;
return clk->rate;
if (unlikely(clk->rate == clk->parent->rate / div))
return;
clk->rate = clk->parent->rate / div;
rate = clk->parent->rate / div;
pr_debug("clock: new clock rate is %ld (div %d)\n", clk->rate, div);
pr_debug("clock: new clock rate is %ld (div %d)\n", rate, div);
if (unlikely(clk->flags & RATE_PROPAGATES))
propagate_rate(clk);
return rate;
}
/**
@ -405,8 +503,8 @@ void omap2_clksel_recalc(struct clk *clk)
* the element associated with the supplied parent clock address.
* Returns a pointer to the struct clksel on success or NULL on error.
*/
const struct clksel *omap2_get_clksel_by_parent(struct clk *clk,
struct clk *src_clk)
static const struct clksel *omap2_get_clksel_by_parent(struct clk *clk,
struct clk *src_clk)
{
const struct clksel *clks;
@ -455,7 +553,7 @@ u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
*new_div = 1;
clks = omap2_get_clksel_by_parent(clk, clk->parent);
if (clks == NULL)
if (!clks)
return ~0;
for (clkr = clks->rates; clkr->div; clkr++) {
@ -514,7 +612,7 @@ long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate)
/* 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 != NULL)
if (clk->round_rate)
return clk->round_rate(clk, rate);
if (clk->flags & RATE_FIXED)
@ -540,7 +638,7 @@ u32 omap2_clksel_to_divisor(struct clk *clk, u32 field_val)
const struct clksel_rate *clkr;
clks = omap2_get_clksel_by_parent(clk, clk->parent);
if (clks == NULL)
if (!clks)
return 0;
for (clkr = clks->rates; clkr->div; clkr++) {
@ -576,7 +674,7 @@ u32 omap2_divisor_to_clksel(struct clk *clk, u32 div)
WARN_ON(div == 0);
clks = omap2_get_clksel_by_parent(clk, clk->parent);
if (clks == NULL)
if (!clks)
return ~0;
for (clkr = clks->rates; clkr->div; clkr++) {
@ -594,23 +692,6 @@ u32 omap2_divisor_to_clksel(struct clk *clk, u32 div)
return clkr->val;
}
/**
* omap2_get_clksel - find clksel register addr & field mask for a clk
* @clk: struct clk to use
* @field_mask: ptr to u32 to store the register field mask
*
* Returns the address of the clksel register upon success or NULL on error.
*/
void __iomem *omap2_get_clksel(struct clk *clk, u32 *field_mask)
{
if (unlikely((clk->clksel_reg == NULL) || (clk->clksel_mask == NULL)))
return NULL;
*field_mask = clk->clksel_mask;
return clk->clksel_reg;
}
/**
* omap2_clksel_get_divisor - get current divider applied to parent clock.
* @clk: OMAP struct clk to use.
@ -619,49 +700,41 @@ void __iomem *omap2_get_clksel(struct clk *clk, u32 *field_mask)
*/
u32 omap2_clksel_get_divisor(struct clk *clk)
{
u32 field_mask, field_val;
void __iomem *div_addr;
u32 v;
div_addr = omap2_get_clksel(clk, &field_mask);
if (div_addr == NULL)
if (!clk->clksel_mask)
return 0;
field_val = __raw_readl(div_addr) & field_mask;
field_val >>= __ffs(field_mask);
v = __raw_readl(clk->clksel_reg) & clk->clksel_mask;
v >>= __ffs(clk->clksel_mask);
return omap2_clksel_to_divisor(clk, field_val);
return omap2_clksel_to_divisor(clk, v);
}
int omap2_clksel_set_rate(struct clk *clk, unsigned long rate)
{
u32 field_mask, field_val, reg_val, validrate, new_div = 0;
void __iomem *div_addr;
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;
div_addr = omap2_get_clksel(clk, &field_mask);
if (div_addr == NULL)
return -EINVAL;
field_val = omap2_divisor_to_clksel(clk, new_div);
if (field_val == ~0)
return -EINVAL;
reg_val = __raw_readl(div_addr);
reg_val &= ~field_mask;
reg_val |= (field_val << __ffs(field_mask));
__raw_writel(reg_val, div_addr);
wmb();
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;
if (clk->flags & DELAYED_APP && cpu_is_omap24xx()) {
prm_write_mod_reg(OMAP24XX_VALID_CONFIG,
OMAP24XX_GR_MOD, OMAP24XX_PRCM_CLKCFG_CTRL_OFFSET);
wmb();
}
_omap2xxx_clk_commit(clk);
return 0;
}
@ -680,31 +753,24 @@ int omap2_clk_set_rate(struct clk *clk, unsigned long rate)
return -EINVAL;
/* dpll_ck, core_ck, virt_prcm_set; plus all clksel clocks */
if (clk->set_rate != NULL)
if (clk->set_rate)
ret = clk->set_rate(clk, rate);
if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES)))
propagate_rate(clk);
return ret;
}
/*
* Converts encoded control register address into a full address
* On error, *src_addr will be returned as 0.
* On error, the return value (parent_div) will be 0.
*/
static u32 omap2_clksel_get_src_field(void __iomem **src_addr,
struct clk *src_clk, u32 *field_mask,
struct clk *clk, u32 *parent_div)
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;
*parent_div = 0;
*src_addr = NULL;
clks = omap2_get_clksel_by_parent(clk, src_clk);
if (clks == NULL)
if (!clks)
return 0;
for (clkr = clks->rates; clkr->div; clkr++) {
@ -722,47 +788,35 @@ static u32 omap2_clksel_get_src_field(void __iomem **src_addr,
/* Should never happen. Add a clksel mask to the struct clk. */
WARN_ON(clk->clksel_mask == 0);
*field_mask = clk->clksel_mask;
*src_addr = clk->clksel_reg;
*parent_div = clkr->div;
*field_val = clkr->val;
return clkr->val;
return clkr->div;
}
int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
{
void __iomem *src_addr;
u32 field_val, field_mask, reg_val, parent_div;
u32 field_val, v, parent_div;
if (unlikely(clk->flags & CONFIG_PARTICIPANT))
if (clk->flags & CONFIG_PARTICIPANT)
return -EINVAL;
if (!clk->clksel)
return -EINVAL;
field_val = omap2_clksel_get_src_field(&src_addr, new_parent,
&field_mask, clk, &parent_div);
if (src_addr == NULL)
parent_div = _omap2_clksel_get_src_field(new_parent, clk, &field_val);
if (!parent_div)
return -EINVAL;
if (clk->usecount > 0)
omap2_clk_disable(clk);
/* Set new source value (previous dividers if any in effect) */
reg_val = __raw_readl(src_addr) & ~field_mask;
reg_val |= (field_val << __ffs(field_mask));
__raw_writel(reg_val, src_addr);
wmb();
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 */
if (clk->flags & DELAYED_APP && cpu_is_omap24xx()) {
__raw_writel(OMAP24XX_VALID_CONFIG, OMAP24XX_PRCM_CLKCFG_CTRL);
wmb();
}
_omap2xxx_clk_commit(clk);
clk->parent = new_parent;
if (clk->usecount > 0)
omap2_clk_enable(clk);
clk_reparent(clk, new_parent);
/* CLKSEL clocks follow their parents' rates, divided by a divisor */
clk->rate = new_parent->rate;
@ -773,9 +827,6 @@ int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
pr_debug("clock: set parent of %s to %s (new rate %ld)\n",
clk->name, clk->parent->name, clk->rate);
if (unlikely(clk->flags & RATE_PROPAGATES))
propagate_rate(clk);
return 0;
}
@ -805,7 +856,8 @@ int omap2_dpll_set_rate_tolerance(struct clk *clk, unsigned int tolerance)
return 0;
}
static unsigned long _dpll_compute_new_rate(unsigned long parent_rate, unsigned int m, unsigned int n)
static unsigned long _dpll_compute_new_rate(unsigned long parent_rate,
unsigned int m, unsigned int n)
{
unsigned long long num;
@ -838,7 +890,7 @@ static int _dpll_test_mult(int *m, int n, unsigned long *new_rate,
unsigned long target_rate,
unsigned long parent_rate)
{
int flags = 0, carry = 0;
int r = 0, carry = 0;
/* Unscale m and round if necessary */
if (*m % DPLL_SCALE_FACTOR >= DPLL_ROUNDING_VAL)
@ -859,13 +911,13 @@ static int _dpll_test_mult(int *m, int n, unsigned long *new_rate,
if (*m < DPLL_MIN_MULTIPLIER) {
*m = DPLL_MIN_MULTIPLIER;
*new_rate = 0;
flags = DPLL_MULT_UNDERFLOW;
r = DPLL_MULT_UNDERFLOW;
}
if (*new_rate == 0)
*new_rate = _dpll_compute_new_rate(parent_rate, *m, n);
return flags;
return r;
}
/**
@ -889,54 +941,65 @@ 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 / (clk->parent->rate / DPLL_SCALE_FACTOR);
scaled_max_m = clk->dpll_data->max_multiplier * DPLL_SCALE_FACTOR;
scaled_rt_rp = target_rate / (dd->clk_ref->rate / DPLL_SCALE_FACTOR);
scaled_max_m = dd->max_multiplier * DPLL_SCALE_FACTOR;
clk->dpll_data->last_rounded_rate = 0;
dd->last_rounded_rate = 0;
for (n = clk->dpll_data->max_divider; n >= DPLL_MIN_DIVIDER; n--) {
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 down, a m overflow means we can
* can immediately skip to the next 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)
continue;
break;
r = _dpll_test_mult(&m, n, &new_rate, target_rate,
clk->parent->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) - clk->dpll_data->rate_tolerance)) {
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);
}
/*
* Since we're counting n down, a m underflow means we
* can bail out completely (since as n decreases in
* the next iteration, there's no way that m can
* increase beyond the current m)
*/
if (r & DPLL_MULT_UNDERFLOW)
break;
/* We found good settings -- bail out now */
if (min_e <= dd->rate_tolerance)
break;
}
}
if (min_e < 0) {
@ -944,17 +1007,17 @@ long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
return ~0;
}
clk->dpll_data->last_rounded_m = min_e_m;
clk->dpll_data->last_rounded_n = min_e_n;
clk->dpll_data->last_rounded_rate =
_dpll_compute_new_rate(clk->parent->rate, min_e_m, min_e_n);
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",
clk->dpll_data->last_rounded_rate, target_rate);
dd->last_rounded_rate, target_rate);
return clk->dpll_data->last_rounded_rate;
return dd->last_rounded_rate;
}
/*-------------------------------------------------------------------------
@ -973,6 +1036,10 @@ void omap2_clk_disable_unused(struct clk *clk)
return;
printk(KERN_INFO "Disabling unused clock \"%s\"\n", clk->name);
_omap2_clk_disable(clk);
if (cpu_is_omap34xx()) {
omap2_clk_enable(clk);
omap2_clk_disable(clk);
} else
_omap2_clk_disable(clk);
}
#endif

View File

@ -21,13 +21,28 @@
/* The maximum error between a target DPLL rate and the rounded rate in Hz */
#define DEFAULT_DPLL_RATE_TOLERANCE 50000
/* CM_CLKSEL2_PLL.CORE_CLK_SRC bits (2XXX) */
#define CORE_CLK_SRC_32K 0x0
#define CORE_CLK_SRC_DPLL 0x1
#define CORE_CLK_SRC_DPLL_X2 0x2
/* OMAP2xxx CM_CLKEN_PLL.EN_DPLL bits - for omap2_get_dpll_rate() */
#define OMAP2XXX_EN_DPLL_LPBYPASS 0x1
#define OMAP2XXX_EN_DPLL_FRBYPASS 0x2
#define OMAP2XXX_EN_DPLL_LOCKED 0x3
/* OMAP3xxx CM_CLKEN_PLL*.EN_*_DPLL bits - for omap2_get_dpll_rate() */
#define OMAP3XXX_EN_DPLL_LPBYPASS 0x5
#define OMAP3XXX_EN_DPLL_FRBYPASS 0x6
#define OMAP3XXX_EN_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);
int omap2_clk_set_rate(struct clk *clk, unsigned long rate);
int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent);
int omap2_dpll_rate_tolerance_set(struct clk *clk, unsigned int tolerance);
int omap2_dpll_set_rate_tolerance(struct clk *clk, unsigned int tolerance);
long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate);
#ifdef CONFIG_OMAP_RESET_CLOCKS
@ -36,7 +51,7 @@ void omap2_clk_disable_unused(struct clk *clk);
#define omap2_clk_disable_unused NULL
#endif
void omap2_clksel_recalc(struct clk *clk);
unsigned long omap2_clksel_recalc(struct clk *clk);
void omap2_init_clk_clkdm(struct clk *clk);
void omap2_init_clksel_parent(struct clk *clk);
u32 omap2_clksel_get_divisor(struct clk *clk);
@ -44,13 +59,16 @@ 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);
void omap2_fixed_divisor_recalc(struct clk *clk);
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);
u32 omap2_get_dpll_rate(struct clk *clk);
int omap2_wait_clock_ready(void __iomem *reg, u32 cval, const char *name);
void omap2_clk_prepare_for_reboot(void);
extern const struct clkops clkops_omap2_dflt_wait;
extern const struct clkops clkops_omap2_dflt;
extern u8 cpu_mask;
/* clksel_rate data common to 24xx/343x */

View File

@ -31,15 +31,192 @@
#include <mach/clock.h>
#include <mach/sram.h>
#include <asm/div64.h>
#include <asm/clkdev.h>
#include "memory.h"
#include <mach/sdrc.h>
#include "clock.h"
#include "clock24xx.h"
#include "prm.h"
#include "prm-regbits-24xx.h"
#include "cm.h"
#include "cm-regbits-24xx.h"
static const struct clkops clkops_oscck;
static const struct clkops clkops_fixed;
#include "clock24xx.h"
struct omap_clk {
u32 cpu;
struct clk_lookup lk;
};
#define CLK(dev, con, ck, cp) \
{ \
.cpu = cp, \
.lk = { \
.dev_id = dev, \
.con_id = con, \
.clk = ck, \
}, \
}
#define CK_243X (1 << 0)
#define CK_242X (1 << 1)
static struct omap_clk omap24xx_clks[] = {
/* external root sources */
CLK(NULL, "func_32k_ck", &func_32k_ck, CK_243X | CK_242X),
CLK(NULL, "osc_ck", &osc_ck, CK_243X | CK_242X),
CLK(NULL, "sys_ck", &sys_ck, CK_243X | CK_242X),
CLK(NULL, "alt_ck", &alt_ck, CK_243X | CK_242X),
/* internal analog sources */
CLK(NULL, "dpll_ck", &dpll_ck, CK_243X | CK_242X),
CLK(NULL, "apll96_ck", &apll96_ck, CK_243X | CK_242X),
CLK(NULL, "apll54_ck", &apll54_ck, CK_243X | CK_242X),
/* internal prcm root sources */
CLK(NULL, "func_54m_ck", &func_54m_ck, CK_243X | CK_242X),
CLK(NULL, "core_ck", &core_ck, CK_243X | CK_242X),
CLK(NULL, "func_96m_ck", &func_96m_ck, CK_243X | CK_242X),
CLK(NULL, "func_48m_ck", &func_48m_ck, CK_243X | CK_242X),
CLK(NULL, "func_12m_ck", &func_12m_ck, CK_243X | CK_242X),
CLK(NULL, "ck_wdt1_osc", &wdt1_osc_ck, CK_243X | CK_242X),
CLK(NULL, "sys_clkout_src", &sys_clkout_src, CK_243X | CK_242X),
CLK(NULL, "sys_clkout", &sys_clkout, CK_243X | CK_242X),
CLK(NULL, "sys_clkout2_src", &sys_clkout2_src, CK_242X),
CLK(NULL, "sys_clkout2", &sys_clkout2, CK_242X),
CLK(NULL, "emul_ck", &emul_ck, CK_242X),
/* mpu domain clocks */
CLK(NULL, "mpu_ck", &mpu_ck, CK_243X | CK_242X),
/* dsp domain clocks */
CLK(NULL, "dsp_fck", &dsp_fck, CK_243X | CK_242X),
CLK(NULL, "dsp_irate_ick", &dsp_irate_ick, CK_243X | CK_242X),
CLK(NULL, "dsp_ick", &dsp_ick, CK_242X),
CLK(NULL, "iva2_1_ick", &iva2_1_ick, CK_243X),
CLK(NULL, "iva1_ifck", &iva1_ifck, CK_242X),
CLK(NULL, "iva1_mpu_int_ifck", &iva1_mpu_int_ifck, CK_242X),
/* GFX domain clocks */
CLK(NULL, "gfx_3d_fck", &gfx_3d_fck, CK_243X | CK_242X),
CLK(NULL, "gfx_2d_fck", &gfx_2d_fck, CK_243X | CK_242X),
CLK(NULL, "gfx_ick", &gfx_ick, CK_243X | CK_242X),
/* Modem domain clocks */
CLK(NULL, "mdm_ick", &mdm_ick, CK_243X),
CLK(NULL, "mdm_osc_ck", &mdm_osc_ck, CK_243X),
/* DSS domain clocks */
CLK(NULL, "dss_ick", &dss_ick, CK_243X | CK_242X),
CLK(NULL, "dss1_fck", &dss1_fck, CK_243X | CK_242X),
CLK(NULL, "dss2_fck", &dss2_fck, CK_243X | CK_242X),
CLK(NULL, "dss_54m_fck", &dss_54m_fck, CK_243X | CK_242X),
/* L3 domain clocks */
CLK(NULL, "core_l3_ck", &core_l3_ck, CK_243X | CK_242X),
CLK(NULL, "ssi_fck", &ssi_ssr_sst_fck, CK_243X | CK_242X),
CLK(NULL, "usb_l4_ick", &usb_l4_ick, CK_243X | CK_242X),
/* L4 domain clocks */
CLK(NULL, "l4_ck", &l4_ck, CK_243X | CK_242X),
CLK(NULL, "ssi_l4_ick", &ssi_l4_ick, CK_243X | CK_242X),
/* virtual meta-group clock */
CLK(NULL, "virt_prcm_set", &virt_prcm_set, CK_243X | CK_242X),
/* general l4 interface ck, multi-parent functional clk */
CLK(NULL, "gpt1_ick", &gpt1_ick, CK_243X | CK_242X),
CLK(NULL, "gpt1_fck", &gpt1_fck, CK_243X | CK_242X),
CLK(NULL, "gpt2_ick", &gpt2_ick, CK_243X | CK_242X),
CLK(NULL, "gpt2_fck", &gpt2_fck, CK_243X | CK_242X),
CLK(NULL, "gpt3_ick", &gpt3_ick, CK_243X | CK_242X),
CLK(NULL, "gpt3_fck", &gpt3_fck, CK_243X | CK_242X),
CLK(NULL, "gpt4_ick", &gpt4_ick, CK_243X | CK_242X),
CLK(NULL, "gpt4_fck", &gpt4_fck, CK_243X | CK_242X),
CLK(NULL, "gpt5_ick", &gpt5_ick, CK_243X | CK_242X),
CLK(NULL, "gpt5_fck", &gpt5_fck, CK_243X | CK_242X),
CLK(NULL, "gpt6_ick", &gpt6_ick, CK_243X | CK_242X),
CLK(NULL, "gpt6_fck", &gpt6_fck, CK_243X | CK_242X),
CLK(NULL, "gpt7_ick", &gpt7_ick, CK_243X | CK_242X),
CLK(NULL, "gpt7_fck", &gpt7_fck, CK_243X | CK_242X),
CLK(NULL, "gpt8_ick", &gpt8_ick, CK_243X | CK_242X),
CLK(NULL, "gpt8_fck", &gpt8_fck, CK_243X | CK_242X),
CLK(NULL, "gpt9_ick", &gpt9_ick, CK_243X | CK_242X),
CLK(NULL, "gpt9_fck", &gpt9_fck, CK_243X | CK_242X),
CLK(NULL, "gpt10_ick", &gpt10_ick, CK_243X | CK_242X),
CLK(NULL, "gpt10_fck", &gpt10_fck, CK_243X | CK_242X),
CLK(NULL, "gpt11_ick", &gpt11_ick, CK_243X | CK_242X),
CLK(NULL, "gpt11_fck", &gpt11_fck, CK_243X | CK_242X),
CLK(NULL, "gpt12_ick", &gpt12_ick, CK_243X | CK_242X),
CLK(NULL, "gpt12_fck", &gpt12_fck, CK_243X | CK_242X),
CLK("omap-mcbsp.1", "ick", &mcbsp1_ick, CK_243X | CK_242X),
CLK("omap-mcbsp.1", "fck", &mcbsp1_fck, CK_243X | CK_242X),
CLK("omap-mcbsp.2", "ick", &mcbsp2_ick, CK_243X | CK_242X),
CLK("omap-mcbsp.2", "fck", &mcbsp2_fck, CK_243X | CK_242X),
CLK("omap-mcbsp.3", "ick", &mcbsp3_ick, CK_243X),
CLK("omap-mcbsp.3", "fck", &mcbsp3_fck, CK_243X),
CLK("omap-mcbsp.4", "ick", &mcbsp4_ick, CK_243X),
CLK("omap-mcbsp.4", "fck", &mcbsp4_fck, CK_243X),
CLK("omap-mcbsp.5", "ick", &mcbsp5_ick, CK_243X),
CLK("omap-mcbsp.5", "fck", &mcbsp5_fck, CK_243X),
CLK("omap2_mcspi.1", "ick", &mcspi1_ick, CK_243X | CK_242X),
CLK("omap2_mcspi.1", "fck", &mcspi1_fck, CK_243X | CK_242X),
CLK("omap2_mcspi.2", "ick", &mcspi2_ick, CK_243X | CK_242X),
CLK("omap2_mcspi.2", "fck", &mcspi2_fck, CK_243X | CK_242X),
CLK("omap2_mcspi.3", "ick", &mcspi3_ick, CK_243X),
CLK("omap2_mcspi.3", "fck", &mcspi3_fck, CK_243X),
CLK(NULL, "uart1_ick", &uart1_ick, CK_243X | CK_242X),
CLK(NULL, "uart1_fck", &uart1_fck, CK_243X | CK_242X),
CLK(NULL, "uart2_ick", &uart2_ick, CK_243X | CK_242X),
CLK(NULL, "uart2_fck", &uart2_fck, CK_243X | CK_242X),
CLK(NULL, "uart3_ick", &uart3_ick, CK_243X | CK_242X),
CLK(NULL, "uart3_fck", &uart3_fck, CK_243X | CK_242X),
CLK(NULL, "gpios_ick", &gpios_ick, CK_243X | CK_242X),
CLK(NULL, "gpios_fck", &gpios_fck, CK_243X | CK_242X),
CLK("omap_wdt", "ick", &mpu_wdt_ick, CK_243X | CK_242X),
CLK("omap_wdt", "fck", &mpu_wdt_fck, CK_243X | CK_242X),
CLK(NULL, "sync_32k_ick", &sync_32k_ick, CK_243X | CK_242X),
CLK(NULL, "wdt1_ick", &wdt1_ick, CK_243X | CK_242X),
CLK(NULL, "omapctrl_ick", &omapctrl_ick, CK_243X | CK_242X),
CLK(NULL, "icr_ick", &icr_ick, CK_243X),
CLK("omap24xxcam", "fck", &cam_fck, CK_243X | CK_242X),
CLK("omap24xxcam", "ick", &cam_ick, CK_243X | CK_242X),
CLK(NULL, "mailboxes_ick", &mailboxes_ick, CK_243X | CK_242X),
CLK(NULL, "wdt4_ick", &wdt4_ick, CK_243X | CK_242X),
CLK(NULL, "wdt4_fck", &wdt4_fck, CK_243X | CK_242X),
CLK(NULL, "wdt3_ick", &wdt3_ick, CK_242X),
CLK(NULL, "wdt3_fck", &wdt3_fck, CK_242X),
CLK(NULL, "mspro_ick", &mspro_ick, CK_243X | CK_242X),
CLK(NULL, "mspro_fck", &mspro_fck, CK_243X | CK_242X),
CLK("mmci-omap.0", "ick", &mmc_ick, CK_242X),
CLK("mmci-omap.0", "fck", &mmc_fck, CK_242X),
CLK(NULL, "fac_ick", &fac_ick, CK_243X | CK_242X),
CLK(NULL, "fac_fck", &fac_fck, CK_243X | CK_242X),
CLK(NULL, "eac_ick", &eac_ick, CK_242X),
CLK(NULL, "eac_fck", &eac_fck, CK_242X),
CLK("omap_hdq.0", "ick", &hdq_ick, CK_243X | CK_242X),
CLK("omap_hdq.1", "fck", &hdq_fck, CK_243X | CK_242X),
CLK("i2c_omap.1", "ick", &i2c1_ick, CK_243X | CK_242X),
CLK("i2c_omap.1", "fck", &i2c1_fck, CK_242X),
CLK("i2c_omap.1", "fck", &i2chs1_fck, CK_243X),
CLK("i2c_omap.2", "ick", &i2c2_ick, CK_243X | CK_242X),
CLK("i2c_omap.2", "fck", &i2c2_fck, CK_242X),
CLK("i2c_omap.2", "fck", &i2chs2_fck, CK_243X),
CLK(NULL, "gpmc_fck", &gpmc_fck, CK_243X | CK_242X),
CLK(NULL, "sdma_fck", &sdma_fck, CK_243X | CK_242X),
CLK(NULL, "sdma_ick", &sdma_ick, CK_243X | CK_242X),
CLK(NULL, "vlynq_ick", &vlynq_ick, CK_242X),
CLK(NULL, "vlynq_fck", &vlynq_fck, CK_242X),
CLK(NULL, "sdrc_ick", &sdrc_ick, CK_243X),
CLK(NULL, "des_ick", &des_ick, CK_243X | CK_242X),
CLK(NULL, "sha_ick", &sha_ick, CK_243X | CK_242X),
CLK("omap_rng", "ick", &rng_ick, CK_243X | CK_242X),
CLK(NULL, "aes_ick", &aes_ick, CK_243X | CK_242X),
CLK(NULL, "pka_ick", &pka_ick, CK_243X | CK_242X),
CLK(NULL, "usb_fck", &usb_fck, CK_243X | CK_242X),
CLK(NULL, "usbhs_ick", &usbhs_ick, CK_243X),
CLK("mmci-omap-hs.0", "ick", &mmchs1_ick, CK_243X),
CLK("mmci-omap-hs.0", "fck", &mmchs1_fck, CK_243X),
CLK("mmci-omap-hs.1", "ick", &mmchs2_ick, CK_243X),
CLK("mmci-omap-hs.1", "fck", &mmchs2_fck, CK_243X),
CLK(NULL, "gpio5_ick", &gpio5_ick, CK_243X),
CLK(NULL, "gpio5_fck", &gpio5_fck, CK_243X),
CLK(NULL, "mdm_intc_ick", &mdm_intc_ick, CK_243X),
CLK("mmci-omap-hs.0", "mmchsdb_fck", &mmchsdb1_fck, CK_243X),
CLK("mmci-omap-hs.1", "mmchsdb_fck", &mmchsdb2_fck, CK_243X),
};
/* CM_CLKEN_PLL.EN_{54,96}M_PLL options (24XX) */
#define EN_APLL_STOPPED 0
#define EN_APLL_LOCKED 3
@ -59,19 +236,32 @@ static struct clk *sclk;
* Omap24xx specific clock functions
*-------------------------------------------------------------------------*/
/* This actually returns the rate of core_ck, not dpll_ck. */
static u32 omap2_get_dpll_rate_24xx(struct clk *tclk)
/**
* 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.
*/
static unsigned long omap2xxx_clk_get_core_rate(struct clk *clk)
{
long long dpll_clk;
u8 amult;
long long core_clk;
u32 v;
dpll_clk = omap2_get_dpll_rate(tclk);
core_clk = omap2_get_dpll_rate(clk);
amult = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
amult &= OMAP24XX_CORE_CLK_SRC_MASK;
dpll_clk *= amult;
v = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
v &= OMAP24XX_CORE_CLK_SRC_MASK;
return dpll_clk;
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)
@ -96,6 +286,11 @@ static void omap2_disable_osc_ck(struct clk *clk)
OMAP24XX_PRCM_CLKSRC_CTRL);
}
static 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)
@ -149,11 +344,16 @@ static void omap2_clk_fixed_disable(struct clk *clk)
cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
}
static const struct clkops clkops_fixed = {
.enable = &omap2_clk_fixed_enable,
.disable = &omap2_clk_fixed_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)
static long omap2_dpllcore_round_rate(unsigned long target_rate)
{
u32 high, low, core_clk_src;
@ -182,11 +382,9 @@ long omap2_dpllcore_round_rate(unsigned long target_rate)
}
static void omap2_dpllcore_recalc(struct clk *clk)
static unsigned long omap2_dpllcore_recalc(struct clk *clk)
{
clk->rate = omap2_get_dpll_rate_24xx(clk);
propagate_rate(clk);
return omap2xxx_clk_get_core_rate(clk);
}
static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
@ -195,22 +393,19 @@ static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
u32 bypass = 0;
struct prcm_config tmpset;
const struct dpll_data *dd;
unsigned long flags;
int ret = -EINVAL;
local_irq_save(flags);
cur_rate = omap2_get_dpll_rate_24xx(&dpll_ck);
cur_rate = omap2xxx_clk_get_core_rate(&dpll_ck);
mult = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
mult &= OMAP24XX_CORE_CLK_SRC_MASK;
if ((rate == (cur_rate / 2)) && (mult == 2)) {
omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL, 1);
omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1);
} else if ((rate == (cur_rate * 2)) && (mult == 1)) {
omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL_X2, 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)
goto dpll_exit;
return -EINVAL;
if (mult == 1)
low = curr_prcm_set->dpll_speed;
@ -219,7 +414,7 @@ static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
dd = clk->dpll_data;
if (!dd)
goto dpll_exit;
return -EINVAL;
tmpset.cm_clksel1_pll = __raw_readl(dd->mult_div1_reg);
tmpset.cm_clksel1_pll &= ~(dd->mult_mask |
@ -245,22 +440,19 @@ static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
if (rate == curr_prcm_set->xtal_speed) /* If asking for 1-1 */
bypass = 1;
omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL_X2, 1); /* For init_mem */
/* 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 */
omap2_init_memory_params(omap2_dll_force_needed());
omap2_reprogram_sdrc(done_rate, 0);
omap2xxx_sdrc_init_params(omap2xxx_sdrc_dll_is_unlocked());
omap2xxx_sdrc_reprogram(done_rate, 0);
}
omap2_dpllcore_recalc(&dpll_ck);
ret = 0;
dpll_exit:
local_irq_restore(flags);
return(ret);
return 0;
}
/**
@ -269,9 +461,9 @@ dpll_exit:
*
* Set virt_prcm_set's rate to the mpu_speed field of the current PRCM set.
*/
static void omap2_table_mpu_recalc(struct clk *clk)
static unsigned long omap2_table_mpu_recalc(struct clk *clk)
{
clk->rate = curr_prcm_set->mpu_speed;
return curr_prcm_set->mpu_speed;
}
/*
@ -337,12 +529,12 @@ static int omap2_select_table_rate(struct clk *clk, unsigned long rate)
}
curr_prcm_set = prcm;
cur_rate = omap2_get_dpll_rate_24xx(&dpll_ck);
cur_rate = omap2xxx_clk_get_core_rate(&dpll_ck);
if (prcm->dpll_speed == cur_rate / 2) {
omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL, 1);
omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1);
} else if (prcm->dpll_speed == cur_rate * 2) {
omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL_X2, 1);
omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
} else if (prcm->dpll_speed != cur_rate) {
local_irq_save(flags);
@ -366,27 +558,67 @@ static int omap2_select_table_rate(struct clk *clk, unsigned long rate)
/* 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);
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 init_mem */
omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL_X2, 1);
/* 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);
omap2_init_memory_params(omap2_dll_force_needed());
omap2_reprogram_sdrc(done_rate, 0);
omap2xxx_sdrc_init_params(omap2xxx_sdrc_dll_is_unlocked());
omap2xxx_sdrc_reprogram(done_rate, 0);
local_irq_restore(flags);
}
omap2_dpllcore_recalc(&dpll_ck);
return 0;
}
#ifdef CONFIG_CPU_FREQ
/*
* Walk PRCM rate table and fillout cpufreq freq_table
*/
static struct cpufreq_frequency_table freq_table[ARRAY_SIZE(rate_table)];
void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table)
{
struct prcm_config *prcm;
int i = 0;
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++;
}
if (i == 0) {
printk(KERN_WARNING "%s: failed to initialize frequency "
"table\n", __func__);
return;
}
freq_table[i].index = i;
freq_table[i].frequency = CPUFREQ_TABLE_END;
*table = &freq_table[0];
}
#endif
static struct clk_functions omap2_clk_functions = {
.clk_enable = omap2_clk_enable,
.clk_disable = omap2_clk_disable,
@ -394,24 +626,27 @@ static struct clk_functions omap2_clk_functions = {
.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,
#endif
};
static u32 omap2_get_apll_clkin(void)
{
u32 aplls, sclk = 0;
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)
sclk = 19200000;
srate = 19200000;
else if (aplls == APLLS_CLKIN_13MHZ)
sclk = 13000000;
srate = 13000000;
else if (aplls == APLLS_CLKIN_12MHZ)
sclk = 12000000;
srate = 12000000;
return sclk;
return srate;
}
static u32 omap2_get_sysclkdiv(void)
@ -425,16 +660,14 @@ static u32 omap2_get_sysclkdiv(void)
return div;
}
static void omap2_osc_clk_recalc(struct clk *clk)
static unsigned long omap2_osc_clk_recalc(struct clk *clk)
{
clk->rate = omap2_get_apll_clkin() * omap2_get_sysclkdiv();
propagate_rate(clk);
return omap2_get_apll_clkin() * omap2_get_sysclkdiv();
}
static void omap2_sys_clk_recalc(struct clk *clk)
static unsigned long omap2_sys_clk_recalc(struct clk *clk)
{
clk->rate = clk->parent->rate / omap2_get_sysclkdiv();
propagate_rate(clk);
return clk->parent->rate / omap2_get_sysclkdiv();
}
/*
@ -460,7 +693,7 @@ static int __init omap2_clk_arch_init(void)
if (!mpurate)
return -EINVAL;
if (omap2_select_table_rate(&virt_prcm_set, mpurate))
if (clk_set_rate(&virt_prcm_set, mpurate))
printk(KERN_ERR "Could not find matching MPU rate\n");
recalculate_root_clocks();
@ -477,8 +710,8 @@ arch_initcall(omap2_clk_arch_init);
int __init omap2_clk_init(void)
{
struct prcm_config *prcm;
struct clk **clkp;
u32 clkrate;
struct omap_clk *c;
u32 clkrate, cpu_mask;
if (cpu_is_omap242x())
cpu_mask = RATE_IN_242X;
@ -487,26 +720,28 @@ int __init omap2_clk_init(void)
clk_init(&omap2_clk_functions);
omap2_osc_clk_recalc(&osc_ck);
omap2_sys_clk_recalc(&sys_ck);
osc_ck.rate = omap2_osc_clk_recalc(&osc_ck);
propagate_rate(&osc_ck);
sys_ck.rate = omap2_sys_clk_recalc(&sys_ck);
propagate_rate(&sys_ck);
for (clkp = onchip_24xx_clks;
clkp < onchip_24xx_clks + ARRAY_SIZE(onchip_24xx_clks);
clkp++) {
for (c = omap24xx_clks; c < omap24xx_clks + ARRAY_SIZE(omap24xx_clks); c++)
clk_init_one(c->lk.clk);
if ((*clkp)->flags & CLOCK_IN_OMAP242X && cpu_is_omap2420()) {
clk_register(*clkp);
continue;
cpu_mask = 0;
if (cpu_is_omap2420())
cpu_mask |= CK_242X;
if (cpu_is_omap2430())
cpu_mask |= CK_243X;
for (c = omap24xx_clks; c < omap24xx_clks + ARRAY_SIZE(omap24xx_clks); c++)
if (c->cpu & cpu_mask) {
clkdev_add(&c->lk);
clk_register(c->lk.clk);
}
if ((*clkp)->flags & CLOCK_IN_OMAP243X && cpu_is_omap2430()) {
clk_register(*clkp);
continue;
}
}
/* Check the MPU rate set by bootloader */
clkrate = omap2_get_dpll_rate_24xx(&dpll_ck);
clkrate = omap2xxx_clk_get_core_rate(&dpll_ck);
for (prcm = rate_table; prcm->mpu_speed; prcm++) {
if (!(prcm->flags & cpu_mask))
continue;

File diff suppressed because it is too large Load Diff

View File

@ -30,15 +30,251 @@
#include <mach/clock.h>
#include <mach/sram.h>
#include <asm/div64.h>
#include <asm/clkdev.h>
#include "memory.h"
#include <mach/sdrc.h>
#include "clock.h"
#include "clock34xx.h"
#include "prm.h"
#include "prm-regbits-34xx.h"
#include "cm.h"
#include "cm-regbits-34xx.h"
static const struct clkops clkops_noncore_dpll_ops;
#include "clock34xx.h"
struct omap_clk {
u32 cpu;
struct clk_lookup lk;
};
#define CLK(dev, con, ck, cp) \
{ \
.cpu = cp, \
.lk = { \
.dev_id = dev, \
.con_id = con, \
.clk = ck, \
}, \
}
#define CK_343X (1 << 0)
#define CK_3430ES1 (1 << 1)
#define CK_3430ES2 (1 << 2)
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),
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(NULL, "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(NULL, "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(NULL, "emu_mpu_alwon_ck", &emu_mpu_alwon_ck, CK_343X),
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, "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, "d2d_26m_fck", &d2d_26m_fck, CK_3430ES1),
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, "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(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, "ssi_ssr_fck", &ssi_ssr_fck, CK_343X),
CLK(NULL, "ssi_sst_fck", &ssi_sst_fck, CK_343X),
CLK(NULL, "core_l3_ick", &core_l3_ick, CK_343X),
CLK(NULL, "hsotgusb_ick", &hsotgusb_ick, CK_343X),
CLK(NULL, "sdrc_ick", &sdrc_ick, CK_343X),
CLK(NULL, "gpmc_fck", &gpmc_fck, CK_343X),
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, "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(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(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, "ssi_l4_ick", &ssi_l4_ick, CK_343X),
CLK(NULL, "ssi_ick", &ssi_ick, CK_343X),
CLK(NULL, "usb_l4_ick", &usb_l4_ick, CK_3430ES1),
CLK(NULL, "security_l4_ick2", &security_l4_ick2, CK_343X),
CLK(NULL, "aes1_ick", &aes1_ick, CK_343X),
CLK("omap_rng", "ick", &rng_ick, CK_343X),
CLK(NULL, "sha11_ick", &sha11_ick, CK_343X),
CLK(NULL, "des1_ick", &des1_ick, CK_343X),
CLK(NULL, "dss1_alwon_fck", &dss1_alwon_fck, CK_343X),
CLK(NULL, "dss_tv_fck", &dss_tv_fck, CK_343X),
CLK(NULL, "dss_96m_fck", &dss_96m_fck, CK_343X),
CLK(NULL, "dss2_alwon_fck", &dss2_alwon_fck, CK_343X),
CLK(NULL, "dss_ick", &dss_ick, CK_343X),
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, "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, "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(NULL, "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(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),
};
/* CM_AUTOIDLE_PLL*.AUTO_* bit values */
#define DPLL_AUTOIDLE_DISABLE 0x0
#define DPLL_AUTOIDLE_LOW_POWER_STOP 0x1
@ -51,11 +287,9 @@
*
* Recalculate and propagate the DPLL rate.
*/
static void omap3_dpll_recalc(struct clk *clk)
static unsigned long omap3_dpll_recalc(struct clk *clk)
{
clk->rate = omap2_get_dpll_rate(clk);
propagate_rate(clk);
return omap2_get_dpll_rate(clk);
}
/* _omap3_dpll_write_clken - write clken_bits arg to a DPLL's enable bits */
@ -78,14 +312,12 @@ static int _omap3_wait_dpll_status(struct clk *clk, u8 state)
const struct dpll_data *dd;
int i = 0;
int ret = -EINVAL;
u32 idlest_mask;
dd = clk->dpll_data;
state <<= dd->idlest_bit;
idlest_mask = 1 << dd->idlest_bit;
state <<= __ffs(dd->idlest_mask);
while (((__raw_readl(dd->idlest_reg) & idlest_mask) != state) &&
while (((__raw_readl(dd->idlest_reg) & dd->idlest_mask) != state) &&
i < MAX_DPLL_WAIT_TRIES) {
i++;
udelay(1);
@ -104,6 +336,42 @@ static int _omap3_wait_dpll_status(struct clk *clk, u8 state)
return ret;
}
/* From 3430 TRM ES2 4.7.6.2 */
static u16 _omap3_dpll_compute_freqsel(struct clk *clk, u8 n)
{
unsigned long fint;
u16 f = 0;
fint = clk->dpll_data->clk_ref->rate / (n + 1);
pr_debug("clock: fint is %lu\n", fint);
if (fint >= 750000 && fint <= 1000000)
f = 0x3;
else if (fint > 1000000 && fint <= 1250000)
f = 0x4;
else if (fint > 1250000 && fint <= 1500000)
f = 0x5;
else if (fint > 1500000 && fint <= 1750000)
f = 0x6;
else if (fint > 1750000 && fint <= 2100000)
f = 0x7;
else if (fint > 7500000 && fint <= 10000000)
f = 0xB;
else if (fint > 10000000 && fint <= 12500000)
f = 0xC;
else if (fint > 12500000 && fint <= 15000000)
f = 0xD;
else if (fint > 15000000 && fint <= 17500000)
f = 0xE;
else if (fint > 17500000 && fint <= 21000000)
f = 0xF;
else
pr_debug("clock: unknown freqsel setting for %d\n", n);
return f;
}
/* Non-CORE DPLL (e.g., DPLLs that do not control SDRC) clock functions */
/*
@ -128,25 +396,20 @@ static int _omap3_noncore_dpll_lock(struct clk *clk)
ai = omap3_dpll_autoidle_read(clk);
omap3_dpll_deny_idle(clk);
_omap3_dpll_write_clken(clk, DPLL_LOCKED);
if (ai) {
/*
* If no downstream clocks are enabled, CM_IDLEST bit
* may never become active, so don't wait for DPLL to lock.
*/
r = 0;
r = _omap3_wait_dpll_status(clk, 1);
if (ai)
omap3_dpll_allow_idle(clk);
} else {
r = _omap3_wait_dpll_status(clk, 1);
omap3_dpll_deny_idle(clk);
};
return r;
}
/*
* omap3_noncore_dpll_bypass - instruct a DPLL to bypass and wait for readiness
* _omap3_noncore_dpll_bypass - instruct a DPLL to bypass and wait for readiness
* @clk: pointer to a DPLL struct clk
*
* Instructs a non-CORE DPLL to enter low-power bypass mode. In
@ -236,14 +499,25 @@ static int _omap3_noncore_dpll_stop(struct clk *clk)
static int omap3_noncore_dpll_enable(struct clk *clk)
{
int r;
struct dpll_data *dd;
if (clk == &dpll3_ck)
return -EINVAL;
if (clk->parent->rate == clk_get_rate(clk))
dd = clk->dpll_data;
if (!dd)
return -EINVAL;
if (clk->rate == dd->clk_bypass->rate) {
WARN_ON(clk->parent != dd->clk_bypass);
r = _omap3_noncore_dpll_bypass(clk);
else
} else {
WARN_ON(clk->parent != dd->clk_ref);
r = _omap3_noncore_dpll_lock(clk);
}
/* FIXME: this is dubious - if clk->rate has changed, what about propagating? */
if (!r)
clk->rate = omap2_get_dpll_rate(clk);
return r;
}
@ -270,6 +544,215 @@ static void omap3_noncore_dpll_disable(struct clk *clk)
_omap3_noncore_dpll_stop(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.
*/
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 */
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
* @rate: rounded target rate
*
* Set the DPLL CLKOUT to the target rate. If the DPLL can enter
* low-power bypass, and the target rate is the bypass source clock
* rate, then configure the DPLL for bypass. Otherwise, round the
* target rate if it hasn't been done already, then program and lock
* the DPLL. Returns -EINVAL upon error, or 0 upon success.
*/
static int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate)
{
struct clk *new_parent = NULL;
u16 freqsel;
struct dpll_data *dd;
int ret;
if (!clk || !rate)
return -EINVAL;
dd = clk->dpll_data;
if (!dd)
return -EINVAL;
if (rate == omap2_get_dpll_rate(clk))
return 0;
/*
* Ensure both the bypass and ref clocks are enabled prior to
* doing anything; we need the bypass clock running to reprogram
* the DPLL.
*/
omap2_clk_enable(dd->clk_bypass);
omap2_clk_enable(dd->clk_ref);
if (dd->clk_bypass->rate == rate &&
(clk->dpll_data->modes & (1 << DPLL_LOW_POWER_BYPASS))) {
pr_debug("clock: %s: set rate: entering bypass.\n", clk->name);
ret = _omap3_noncore_dpll_bypass(clk);
if (!ret)
new_parent = dd->clk_bypass;
} else {
if (dd->last_rounded_rate != rate)
omap2_dpll_round_rate(clk, rate);
if (dd->last_rounded_rate == 0)
return -EINVAL;
freqsel = _omap3_dpll_compute_freqsel(clk, dd->last_rounded_n);
if (!freqsel)
WARN_ON(1);
pr_debug("clock: %s: set rate: locking rate to %lu.\n",
clk->name, rate);
ret = omap3_noncore_dpll_program(clk, dd->last_rounded_m,
dd->last_rounded_n, freqsel);
if (!ret)
new_parent = dd->clk_ref;
}
if (!ret) {
/*
* Switch the parent clock in the heirarchy, and make sure
* that the new parent's usecount is correct. Note: we
* enable the new parent before disabling the old to avoid
* any unnecessary hardware disable->enable transitions.
*/
if (clk->usecount) {
omap2_clk_enable(new_parent);
omap2_clk_disable(clk->parent);
}
clk_reparent(clk, new_parent);
clk->rate = rate;
}
omap2_clk_disable(dd->clk_ref);
omap2_clk_disable(dd->clk_bypass);
return 0;
}
static int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate)
{
/*
* According to the 12-5 CDP code from TI, "Limitation 2.5"
* on 3430ES1 prevents us from changing DPLL multipliers or dividers
* on DPLL4.
*/
if (omap_rev() == OMAP3430_REV_ES1_0) {
printk(KERN_ERR "clock: DPLL4 cannot change rate due to "
"silicon 'Limitation 2.5' on 3430ES1.\n");
return -EINVAL;
}
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.
*/
static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
{
u32 new_div = 0;
unsigned long validrate, sdrcrate;
struct omap_sdrc_params *sp;
if (!clk || !rate)
return -EINVAL;
if (clk != &dpll3_m2_ck)
return -EINVAL;
if (rate == clk->rate)
return 0;
validrate = omap2_clksel_round_rate_div(clk, rate, &new_div);
if (validrate != rate)
return -EINVAL;
sdrcrate = sdrc_ick.rate;
if (rate > clk->rate)
sdrcrate <<= ((rate / clk->rate) - 1);
else
sdrcrate >>= ((clk->rate / rate) - 1);
sp = omap2_sdrc_get_params(sdrcrate);
if (!sp)
return -EINVAL;
pr_info("clock: changing CORE DPLL rate from %lu to %lu\n", clk->rate,
validrate);
pr_info("clock: SDRC timing params used: %08x %08x %08x\n",
sp->rfr_ctrl, sp->actim_ctrla, sp->actim_ctrlb);
/* REVISIT: SRAM code doesn't support other M2 divisors yet */
WARN_ON(new_div != 1 && new_div != 2);
/* REVISIT: Add SDRC_MR changing to this code also */
omap3_configure_core_dpll(sp->rfr_ctrl, sp->actim_ctrla,
sp->actim_ctrlb, new_div);
return 0;
}
static const struct clkops clkops_noncore_dpll_ops = {
.enable = &omap3_noncore_dpll_enable,
.disable = &omap3_noncore_dpll_disable,
};
/* DPLL autoidle read/set code */
/**
* omap3_dpll_autoidle_read - read a DPLL's autoidle bits
* @clk: struct clk * of the DPLL to read
@ -356,9 +839,10 @@ static void omap3_dpll_deny_idle(struct clk *clk)
* Using parent clock DPLL data, look up DPLL state. If locked, set our
* rate to the dpll_clk * 2; otherwise, just use dpll_clk.
*/
static void omap3_clkoutx2_recalc(struct clk *clk)
static unsigned long omap3_clkoutx2_recalc(struct clk *clk)
{
const struct dpll_data *dd;
unsigned long rate;
u32 v;
struct clk *pclk;
@ -372,17 +856,15 @@ static void omap3_clkoutx2_recalc(struct clk *clk)
dd = pclk->dpll_data;
WARN_ON(!dd->control_reg || !dd->enable_mask);
WARN_ON(!dd->enable_mask);
v = __raw_readl(dd->control_reg) & dd->enable_mask;
v >>= __ffs(dd->enable_mask);
if (v != DPLL_LOCKED)
clk->rate = clk->parent->rate;
if (v != OMAP3XXX_EN_DPLL_LOCKED)
rate = clk->parent->rate;
else
clk->rate = clk->parent->rate * 2;
if (clk->flags & RATE_PROPAGATES)
propagate_rate(clk);
rate = clk->parent->rate * 2;
return rate;
}
/* Common clock code */
@ -432,7 +914,7 @@ static int __init omap2_clk_arch_init(void)
/* REVISIT: not yet ready for 343x */
#if 0
if (omap2_select_table_rate(&virt_prcm_set, mpurate))
if (clk_set_rate(&virt_prcm_set, mpurate))
printk(KERN_ERR "Could not find matching MPU rate\n");
#endif
@ -450,26 +932,13 @@ arch_initcall(omap2_clk_arch_init);
int __init omap2_clk_init(void)
{
/* struct prcm_config *prcm; */
struct clk **clkp;
struct omap_clk *c;
/* u32 clkrate; */
u32 cpu_clkflg;
/* REVISIT: Ultimately this will be used for multiboot */
#if 0
if (cpu_is_omap242x()) {
cpu_mask = RATE_IN_242X;
cpu_clkflg = CLOCK_IN_OMAP242X;
clkp = onchip_24xx_clks;
} else if (cpu_is_omap2430()) {
cpu_mask = RATE_IN_243X;
cpu_clkflg = CLOCK_IN_OMAP243X;
clkp = onchip_24xx_clks;
}
#endif
if (cpu_is_omap34xx()) {
cpu_mask = RATE_IN_343X;
cpu_clkflg = CLOCK_IN_OMAP343X;
clkp = onchip_34xx_clks;
cpu_clkflg = CK_343X;
/*
* Update this if there are further clock changes between ES2
@ -477,23 +946,24 @@ int __init omap2_clk_init(void)
*/
if (omap_rev() == OMAP3430_REV_ES1_0) {
/* No 3430ES1-only rates exist, so no RATE_IN_3430ES1 */
cpu_clkflg |= CLOCK_IN_OMAP3430ES1;
cpu_clkflg |= CK_3430ES1;
} else {
cpu_mask |= RATE_IN_3430ES2;
cpu_clkflg |= CLOCK_IN_OMAP3430ES2;
cpu_clkflg |= CK_3430ES2;
}
}
clk_init(&omap2_clk_functions);
for (clkp = onchip_34xx_clks;
clkp < onchip_34xx_clks + ARRAY_SIZE(onchip_34xx_clks);
clkp++) {
if ((*clkp)->flags & cpu_clkflg) {
clk_register(*clkp);
omap2_init_clk_clkdm(*clkp);
for (c = omap34xx_clks; c < omap34xx_clks + ARRAY_SIZE(omap34xx_clks); c++)
clk_init_one(c->lk.clk);
for (c = omap34xx_clks; c < omap34xx_clks + ARRAY_SIZE(omap34xx_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

File diff suppressed because it is too large Load Diff

View File

@ -22,6 +22,7 @@
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/limits.h>
#include <linux/err.h>
#include <linux/io.h>
@ -71,16 +72,13 @@ static void _autodep_lookup(struct clkdm_pwrdm_autodep *autodep)
if (!omap_chip_is(autodep->omap_chip))
return;
pwrdm = pwrdm_lookup(autodep->pwrdm_name);
pwrdm = pwrdm_lookup(autodep->pwrdm.name);
if (!pwrdm) {
pr_debug("clockdomain: _autodep_lookup: powerdomain %s "
"does not exist\n", autodep->pwrdm_name);
WARN_ON(1);
return;
pr_err("clockdomain: autodeps: powerdomain %s does not exist\n",
autodep->pwrdm.name);
pwrdm = ERR_PTR(-ENOENT);
}
autodep->pwrdm = pwrdm;
return;
autodep->pwrdm.ptr = pwrdm;
}
/*
@ -95,16 +93,19 @@ static void _clkdm_add_autodeps(struct clockdomain *clkdm)
{
struct clkdm_pwrdm_autodep *autodep;
for (autodep = autodeps; autodep->pwrdm_name; autodep++) {
if (!autodep->pwrdm)
for (autodep = autodeps; autodep->pwrdm.ptr; autodep++) {
if (IS_ERR(autodep->pwrdm.ptr))
continue;
if (!omap_chip_is(autodep->omap_chip))
continue;
pr_debug("clockdomain: adding %s sleepdep/wkdep for "
"pwrdm %s\n", autodep->pwrdm_name,
clkdm->pwrdm->name);
"pwrdm %s\n", autodep->pwrdm.ptr->name,
clkdm->pwrdm.ptr->name);
pwrdm_add_sleepdep(clkdm->pwrdm, autodep->pwrdm);
pwrdm_add_wkdep(clkdm->pwrdm, autodep->pwrdm);
pwrdm_add_sleepdep(clkdm->pwrdm.ptr, autodep->pwrdm.ptr);
pwrdm_add_wkdep(clkdm->pwrdm.ptr, autodep->pwrdm.ptr);
}
}
@ -120,16 +121,19 @@ static void _clkdm_del_autodeps(struct clockdomain *clkdm)
{
struct clkdm_pwrdm_autodep *autodep;
for (autodep = autodeps; autodep->pwrdm_name; autodep++) {
if (!autodep->pwrdm)
for (autodep = autodeps; autodep->pwrdm.ptr; autodep++) {
if (IS_ERR(autodep->pwrdm.ptr))
continue;
if (!omap_chip_is(autodep->omap_chip))
continue;
pr_debug("clockdomain: removing %s sleepdep/wkdep for "
"pwrdm %s\n", autodep->pwrdm_name,
clkdm->pwrdm->name);
"pwrdm %s\n", autodep->pwrdm.ptr->name,
clkdm->pwrdm.ptr->name);
pwrdm_del_sleepdep(clkdm->pwrdm, autodep->pwrdm);
pwrdm_del_wkdep(clkdm->pwrdm, autodep->pwrdm);
pwrdm_del_sleepdep(clkdm->pwrdm.ptr, autodep->pwrdm.ptr);
pwrdm_del_wkdep(clkdm->pwrdm.ptr, autodep->pwrdm.ptr);
}
}
@ -179,7 +183,7 @@ void clkdm_init(struct clockdomain **clkdms,
autodeps = init_autodeps;
if (autodeps)
for (autodep = autodeps; autodep->pwrdm_name; autodep++)
for (autodep = autodeps; autodep->pwrdm.ptr; autodep++)
_autodep_lookup(autodep);
}
@ -202,20 +206,20 @@ int clkdm_register(struct clockdomain *clkdm)
if (!omap_chip_is(clkdm->omap_chip))
return -EINVAL;
pwrdm = pwrdm_lookup(clkdm->pwrdm_name);
pwrdm = pwrdm_lookup(clkdm->pwrdm.name);
if (!pwrdm) {
pr_debug("clockdomain: clkdm_register %s: powerdomain %s "
"does not exist\n", clkdm->name, clkdm->pwrdm_name);
pr_err("clockdomain: %s: powerdomain %s does not exist\n",
clkdm->name, clkdm->pwrdm.name);
return -EINVAL;
}
clkdm->pwrdm = pwrdm;
clkdm->pwrdm.ptr = pwrdm;
mutex_lock(&clkdm_mutex);
/* Verify that the clockdomain is not already registered */
if (_clkdm_lookup(clkdm->name)) {
ret = -EEXIST;
goto cr_unlock;
};
}
list_add(&clkdm->node, &clkdm_list);
@ -242,7 +246,7 @@ int clkdm_unregister(struct clockdomain *clkdm)
if (!clkdm)
return -EINVAL;
pwrdm_del_clkdm(clkdm->pwrdm, clkdm);
pwrdm_del_clkdm(clkdm->pwrdm.ptr, clkdm);
mutex_lock(&clkdm_mutex);
list_del(&clkdm->node);
@ -327,7 +331,7 @@ struct powerdomain *clkdm_get_pwrdm(struct clockdomain *clkdm)
if (!clkdm)
return NULL;
return clkdm->pwrdm;
return clkdm->pwrdm.ptr;
}
@ -348,7 +352,7 @@ static int omap2_clkdm_clktrctrl_read(struct clockdomain *clkdm)
if (!clkdm)
return -EINVAL;
v = cm_read_mod_reg(clkdm->pwrdm->prcm_offs, CM_CLKSTCTRL);
v = cm_read_mod_reg(clkdm->pwrdm.ptr->prcm_offs, CM_CLKSTCTRL);
v &= clkdm->clktrctrl_mask;
v >>= __ffs(clkdm->clktrctrl_mask);
@ -380,7 +384,7 @@ int omap2_clkdm_sleep(struct clockdomain *clkdm)
if (cpu_is_omap24xx()) {
cm_set_mod_reg_bits(OMAP24XX_FORCESTATE,
clkdm->pwrdm->prcm_offs, PM_PWSTCTRL);
clkdm->pwrdm.ptr->prcm_offs, PM_PWSTCTRL);
} else if (cpu_is_omap34xx()) {
@ -388,7 +392,7 @@ int omap2_clkdm_sleep(struct clockdomain *clkdm)
__ffs(clkdm->clktrctrl_mask));
cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask, v,
clkdm->pwrdm->prcm_offs, CM_CLKSTCTRL);
clkdm->pwrdm.ptr->prcm_offs, CM_CLKSTCTRL);
} else {
BUG();
@ -422,7 +426,7 @@ int omap2_clkdm_wakeup(struct clockdomain *clkdm)
if (cpu_is_omap24xx()) {
cm_clear_mod_reg_bits(OMAP24XX_FORCESTATE,
clkdm->pwrdm->prcm_offs, PM_PWSTCTRL);
clkdm->pwrdm.ptr->prcm_offs, PM_PWSTCTRL);
} else if (cpu_is_omap34xx()) {
@ -430,7 +434,7 @@ int omap2_clkdm_wakeup(struct clockdomain *clkdm)
__ffs(clkdm->clktrctrl_mask));
cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask, v,
clkdm->pwrdm->prcm_offs, CM_CLKSTCTRL);
clkdm->pwrdm.ptr->prcm_offs, CM_CLKSTCTRL);
} else {
BUG();
@ -478,7 +482,7 @@ void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask,
v << __ffs(clkdm->clktrctrl_mask),
clkdm->pwrdm->prcm_offs,
clkdm->pwrdm.ptr->prcm_offs,
CM_CLKSTCTRL);
}
@ -516,7 +520,7 @@ void omap2_clkdm_deny_idle(struct clockdomain *clkdm)
cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask,
v << __ffs(clkdm->clktrctrl_mask),
clkdm->pwrdm->prcm_offs, CM_CLKSTCTRL);
clkdm->pwrdm.ptr->prcm_offs, CM_CLKSTCTRL);
if (atomic_read(&clkdm->usecount) > 0)
_clkdm_del_autodeps(clkdm);
@ -567,6 +571,8 @@ int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
else
omap2_clkdm_wakeup(clkdm);
pwrdm_wait_transition(clkdm->pwrdm.ptr);
return 0;
}

View File

@ -14,12 +14,29 @@
/*
* OMAP2/3-common clockdomains
*
* Even though the 2420 has a single PRCM module from the
* interconnect's perspective, internally it does appear to have
* separate PRM and CM clockdomains. The usual test case is
* sys_clkout/sys_clkout2.
*/
/* 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",
.pwrdm = { .name = "wkup_pwrdm" },
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430),
};
static struct clockdomain prm_clkdm = {
.name = "prm_clkdm",
.pwrdm = { .name = "wkup_pwrdm" },
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430),
};
static struct clockdomain cm_clkdm = {
.name = "cm_clkdm",
.pwrdm = { .name = "core_pwrdm" },
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430),
};
@ -31,7 +48,7 @@ static struct clockdomain wkup_clkdm = {
static struct clockdomain mpu_2420_clkdm = {
.name = "mpu_clkdm",
.pwrdm_name = "mpu_pwrdm",
.pwrdm = { .name = "mpu_pwrdm" },
.flags = CLKDM_CAN_HWSUP,
.clktrctrl_mask = OMAP24XX_AUTOSTATE_MPU_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
@ -39,7 +56,7 @@ static struct clockdomain mpu_2420_clkdm = {
static struct clockdomain iva1_2420_clkdm = {
.name = "iva1_clkdm",
.pwrdm_name = "dsp_pwrdm",
.pwrdm = { .name = "dsp_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
.clktrctrl_mask = OMAP2420_AUTOSTATE_IVA_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
@ -56,7 +73,7 @@ static struct clockdomain iva1_2420_clkdm = {
static struct clockdomain mpu_2430_clkdm = {
.name = "mpu_clkdm",
.pwrdm_name = "mpu_pwrdm",
.pwrdm = { .name = "mpu_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
.clktrctrl_mask = OMAP24XX_AUTOSTATE_MPU_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
@ -64,7 +81,7 @@ static struct clockdomain mpu_2430_clkdm = {
static struct clockdomain mdm_clkdm = {
.name = "mdm_clkdm",
.pwrdm_name = "mdm_pwrdm",
.pwrdm = { .name = "mdm_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
.clktrctrl_mask = OMAP2430_AUTOSTATE_MDM_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
@ -81,7 +98,7 @@ static struct clockdomain mdm_clkdm = {
static struct clockdomain dsp_clkdm = {
.name = "dsp_clkdm",
.pwrdm_name = "dsp_pwrdm",
.pwrdm = { .name = "dsp_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
.clktrctrl_mask = OMAP24XX_AUTOSTATE_DSP_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
@ -89,7 +106,7 @@ static struct clockdomain dsp_clkdm = {
static struct clockdomain gfx_24xx_clkdm = {
.name = "gfx_clkdm",
.pwrdm_name = "gfx_pwrdm",
.pwrdm = { .name = "gfx_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
.clktrctrl_mask = OMAP24XX_AUTOSTATE_GFX_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
@ -97,7 +114,7 @@ static struct clockdomain gfx_24xx_clkdm = {
static struct clockdomain core_l3_24xx_clkdm = {
.name = "core_l3_clkdm",
.pwrdm_name = "core_pwrdm",
.pwrdm = { .name = "core_pwrdm" },
.flags = CLKDM_CAN_HWSUP,
.clktrctrl_mask = OMAP24XX_AUTOSTATE_L3_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
@ -105,7 +122,7 @@ static struct clockdomain core_l3_24xx_clkdm = {
static struct clockdomain core_l4_24xx_clkdm = {
.name = "core_l4_clkdm",
.pwrdm_name = "core_pwrdm",
.pwrdm = { .name = "core_pwrdm" },
.flags = CLKDM_CAN_HWSUP,
.clktrctrl_mask = OMAP24XX_AUTOSTATE_L4_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
@ -113,7 +130,7 @@ static struct clockdomain core_l4_24xx_clkdm = {
static struct clockdomain dss_24xx_clkdm = {
.name = "dss_clkdm",
.pwrdm_name = "core_pwrdm",
.pwrdm = { .name = "core_pwrdm" },
.flags = CLKDM_CAN_HWSUP,
.clktrctrl_mask = OMAP24XX_AUTOSTATE_DSS_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
@ -130,7 +147,7 @@ static struct clockdomain dss_24xx_clkdm = {
static struct clockdomain mpu_34xx_clkdm = {
.name = "mpu_clkdm",
.pwrdm_name = "mpu_pwrdm",
.pwrdm = { .name = "mpu_pwrdm" },
.flags = CLKDM_CAN_HWSUP | CLKDM_CAN_FORCE_WAKEUP,
.clktrctrl_mask = OMAP3430_CLKTRCTRL_MPU_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
@ -138,7 +155,7 @@ static struct clockdomain mpu_34xx_clkdm = {
static struct clockdomain neon_clkdm = {
.name = "neon_clkdm",
.pwrdm_name = "neon_pwrdm",
.pwrdm = { .name = "neon_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
.clktrctrl_mask = OMAP3430_CLKTRCTRL_NEON_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
@ -146,7 +163,7 @@ static struct clockdomain neon_clkdm = {
static struct clockdomain iva2_clkdm = {
.name = "iva2_clkdm",
.pwrdm_name = "iva2_pwrdm",
.pwrdm = { .name = "iva2_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
.clktrctrl_mask = OMAP3430_CLKTRCTRL_IVA2_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
@ -154,7 +171,7 @@ static struct clockdomain iva2_clkdm = {
static struct clockdomain gfx_3430es1_clkdm = {
.name = "gfx_clkdm",
.pwrdm_name = "gfx_pwrdm",
.pwrdm = { .name = "gfx_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
.clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_GFX_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1),
@ -162,10 +179,10 @@ static struct clockdomain gfx_3430es1_clkdm = {
static struct clockdomain sgx_clkdm = {
.name = "sgx_clkdm",
.pwrdm_name = "sgx_pwrdm",
.pwrdm = { .name = "sgx_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
.clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_SGX_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2),
.omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
};
/*
@ -177,7 +194,7 @@ static struct clockdomain sgx_clkdm = {
*/
static struct clockdomain d2d_clkdm = {
.name = "d2d_clkdm",
.pwrdm_name = "core_pwrdm",
.pwrdm = { .name = "core_pwrdm" },
.flags = CLKDM_CAN_HWSUP,
.clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_D2D_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
@ -185,7 +202,7 @@ static struct clockdomain d2d_clkdm = {
static struct clockdomain core_l3_34xx_clkdm = {
.name = "core_l3_clkdm",
.pwrdm_name = "core_pwrdm",
.pwrdm = { .name = "core_pwrdm" },
.flags = CLKDM_CAN_HWSUP,
.clktrctrl_mask = OMAP3430_CLKTRCTRL_L3_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
@ -193,7 +210,7 @@ static struct clockdomain core_l3_34xx_clkdm = {
static struct clockdomain core_l4_34xx_clkdm = {
.name = "core_l4_clkdm",
.pwrdm_name = "core_pwrdm",
.pwrdm = { .name = "core_pwrdm" },
.flags = CLKDM_CAN_HWSUP,
.clktrctrl_mask = OMAP3430_CLKTRCTRL_L4_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
@ -201,7 +218,7 @@ static struct clockdomain core_l4_34xx_clkdm = {
static struct clockdomain dss_34xx_clkdm = {
.name = "dss_clkdm",
.pwrdm_name = "dss_pwrdm",
.pwrdm = { .name = "dss_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
.clktrctrl_mask = OMAP3430_CLKTRCTRL_DSS_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
@ -209,7 +226,7 @@ static struct clockdomain dss_34xx_clkdm = {
static struct clockdomain cam_clkdm = {
.name = "cam_clkdm",
.pwrdm_name = "cam_pwrdm",
.pwrdm = { .name = "cam_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
.clktrctrl_mask = OMAP3430_CLKTRCTRL_CAM_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
@ -217,28 +234,62 @@ static struct clockdomain cam_clkdm = {
static struct clockdomain usbhost_clkdm = {
.name = "usbhost_clkdm",
.pwrdm_name = "usbhost_pwrdm",
.pwrdm = { .name = "usbhost_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
.clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_USBHOST_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2),
.omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
};
static struct clockdomain per_clkdm = {
.name = "per_clkdm",
.pwrdm_name = "per_pwrdm",
.pwrdm = { .name = "per_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
.clktrctrl_mask = OMAP3430_CLKTRCTRL_PER_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
/*
* Disable hw supervised mode for emu_clkdm, because emu_pwrdm is
* switched of even if sdti is in use
*/
static struct clockdomain emu_clkdm = {
.name = "emu_clkdm",
.pwrdm_name = "emu_pwrdm",
.flags = CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_SWSUP,
.pwrdm = { .name = "emu_pwrdm" },
.flags = /* CLKDM_CAN_ENABLE_AUTO | */CLKDM_CAN_SWSUP,
.clktrctrl_mask = OMAP3430_CLKTRCTRL_EMU_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
static struct clockdomain dpll1_clkdm = {
.name = "dpll1_clkdm",
.pwrdm = { .name = "dpll1_pwrdm" },
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
static struct clockdomain dpll2_clkdm = {
.name = "dpll2_clkdm",
.pwrdm = { .name = "dpll2_pwrdm" },
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
static struct clockdomain dpll3_clkdm = {
.name = "dpll3_clkdm",
.pwrdm = { .name = "dpll3_pwrdm" },
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
static struct clockdomain dpll4_clkdm = {
.name = "dpll4_clkdm",
.pwrdm = { .name = "dpll4_pwrdm" },
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
static struct clockdomain dpll5_clkdm = {
.name = "dpll5_clkdm",
.pwrdm = { .name = "dpll5_pwrdm" },
.omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
};
#endif /* CONFIG_ARCH_OMAP34XX */
/*
@ -247,14 +298,16 @@ static struct clockdomain emu_clkdm = {
static struct clkdm_pwrdm_autodep clkdm_pwrdm_autodeps[] = {
{
.pwrdm_name = "mpu_pwrdm",
.pwrdm = { .name = "mpu_pwrdm" },
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
},
{
.pwrdm_name = "iva2_pwrdm",
.pwrdm = { .name = "iva2_pwrdm" },
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
},
{ NULL }
{
.pwrdm = { .name = NULL },
}
};
/*
@ -264,6 +317,8 @@ static struct clkdm_pwrdm_autodep clkdm_pwrdm_autodeps[] = {
static struct clockdomain *clockdomains_omap[] = {
&wkup_clkdm,
&cm_clkdm,
&prm_clkdm,
#ifdef CONFIG_ARCH_OMAP2420
&mpu_2420_clkdm,
@ -297,6 +352,11 @@ static struct clockdomain *clockdomains_omap[] = {
&usbhost_clkdm,
&per_clkdm,
&emu_clkdm,
&dpll1_clkdm,
&dpll2_clkdm,
&dpll3_clkdm,
&dpll4_clkdm,
&dpll5_clkdm,
#endif
NULL,

View File

@ -110,35 +110,56 @@
#define OMAP24XX_EN_DES (1 << 0)
/* CM_IDLEST1_CORE specific bits */
#define OMAP24XX_ST_MAILBOXES (1 << 30)
#define OMAP24XX_ST_WDT4 (1 << 29)
#define OMAP2420_ST_WDT3 (1 << 28)
#define OMAP24XX_ST_MSPRO (1 << 27)
#define OMAP24XX_ST_FAC (1 << 25)
#define OMAP2420_ST_EAC (1 << 24)
#define OMAP24XX_ST_HDQ (1 << 23)
#define OMAP24XX_ST_I2C2 (1 << 20)
#define OMAP24XX_ST_I2C1 (1 << 19)
#define OMAP24XX_ST_MCBSP2 (1 << 16)
#define OMAP24XX_ST_MCBSP1 (1 << 15)
#define OMAP24XX_ST_DSS (1 << 0)
#define OMAP24XX_ST_MAILBOXES_SHIFT 30
#define OMAP24XX_ST_MAILBOXES_MASK (1 << 30)
#define OMAP24XX_ST_WDT4_SHIFT 29
#define OMAP24XX_ST_WDT4_MASK (1 << 29)
#define OMAP2420_ST_WDT3_SHIFT 28
#define OMAP2420_ST_WDT3_MASK (1 << 28)
#define OMAP24XX_ST_MSPRO_SHIFT 27
#define OMAP24XX_ST_MSPRO_MASK (1 << 27)
#define OMAP24XX_ST_FAC_SHIFT 25
#define OMAP24XX_ST_FAC_MASK (1 << 25)
#define OMAP2420_ST_EAC_SHIFT 24
#define OMAP2420_ST_EAC_MASK (1 << 24)
#define OMAP24XX_ST_HDQ_SHIFT 23
#define OMAP24XX_ST_HDQ_MASK (1 << 23)
#define OMAP2420_ST_I2C2_SHIFT 20
#define OMAP2420_ST_I2C2_MASK (1 << 20)
#define OMAP2420_ST_I2C1_SHIFT 19
#define OMAP2420_ST_I2C1_MASK (1 << 19)
#define OMAP24XX_ST_MCBSP2_SHIFT 16
#define OMAP24XX_ST_MCBSP2_MASK (1 << 16)
#define OMAP24XX_ST_MCBSP1_SHIFT 15
#define OMAP24XX_ST_MCBSP1_MASK (1 << 15)
#define OMAP24XX_ST_DSS_SHIFT 0
#define OMAP24XX_ST_DSS_MASK (1 << 0)
/* CM_IDLEST2_CORE */
#define OMAP2430_ST_MCBSP5 (1 << 5)
#define OMAP2430_ST_MCBSP4 (1 << 4)
#define OMAP2430_ST_MCBSP3 (1 << 3)
#define OMAP24XX_ST_SSI (1 << 1)
#define OMAP2430_ST_MCBSP5_SHIFT 5
#define OMAP2430_ST_MCBSP5_MASK (1 << 5)
#define OMAP2430_ST_MCBSP4_SHIFT 4
#define OMAP2430_ST_MCBSP4_MASK (1 << 4)
#define OMAP2430_ST_MCBSP3_SHIFT 3
#define OMAP2430_ST_MCBSP3_MASK (1 << 3)
#define OMAP24XX_ST_SSI_SHIFT 1
#define OMAP24XX_ST_SSI_MASK (1 << 1)
/* CM_IDLEST3_CORE */
/* 2430 only */
#define OMAP2430_ST_SDRC (1 << 2)
#define OMAP2430_ST_SDRC_MASK (1 << 2)
/* CM_IDLEST4_CORE */
#define OMAP24XX_ST_PKA (1 << 4)
#define OMAP24XX_ST_AES (1 << 3)
#define OMAP24XX_ST_RNG (1 << 2)
#define OMAP24XX_ST_SHA (1 << 1)
#define OMAP24XX_ST_DES (1 << 0)
#define OMAP24XX_ST_PKA_SHIFT 4
#define OMAP24XX_ST_PKA_MASK (1 << 4)
#define OMAP24XX_ST_AES_SHIFT 3
#define OMAP24XX_ST_AES_MASK (1 << 3)
#define OMAP24XX_ST_RNG_SHIFT 2
#define OMAP24XX_ST_RNG_MASK (1 << 2)
#define OMAP24XX_ST_SHA_SHIFT 1
#define OMAP24XX_ST_SHA_MASK (1 << 1)
#define OMAP24XX_ST_DES_SHIFT 0
#define OMAP24XX_ST_DES_MASK (1 << 0)
/* CM_AUTOIDLE1_CORE */
#define OMAP24XX_AUTO_CAM (1 << 31)
@ -275,11 +296,16 @@
#define OMAP24XX_EN_32KSYNC (1 << 1)
/* CM_IDLEST_WKUP specific bits */
#define OMAP2430_ST_ICR (1 << 6)
#define OMAP24XX_ST_OMAPCTRL (1 << 5)
#define OMAP24XX_ST_WDT1 (1 << 4)
#define OMAP24XX_ST_MPU_WDT (1 << 3)
#define OMAP24XX_ST_32KSYNC (1 << 1)
#define OMAP2430_ST_ICR_SHIFT 6
#define OMAP2430_ST_ICR_MASK (1 << 6)
#define OMAP24XX_ST_OMAPCTRL_SHIFT 5
#define OMAP24XX_ST_OMAPCTRL_MASK (1 << 5)
#define OMAP24XX_ST_WDT1_SHIFT 4
#define OMAP24XX_ST_WDT1_MASK (1 << 4)
#define OMAP24XX_ST_MPU_WDT_SHIFT 3
#define OMAP24XX_ST_MPU_WDT_MASK (1 << 3)
#define OMAP24XX_ST_32KSYNC_SHIFT 1
#define OMAP24XX_ST_32KSYNC_MASK (1 << 1)
/* CM_AUTOIDLE_WKUP */
#define OMAP24XX_AUTO_OMAPCTRL (1 << 5)

View File

@ -183,31 +183,58 @@
#define OMAP3430ES2_EN_CPEFUSE_MASK (1 << 0)
/* CM_IDLEST1_CORE specific bits */
#define OMAP3430_ST_ICR (1 << 29)
#define OMAP3430_ST_AES2 (1 << 28)
#define OMAP3430_ST_SHA12 (1 << 27)
#define OMAP3430_ST_DES2 (1 << 26)
#define OMAP3430_ST_MSPRO (1 << 23)
#define OMAP3430_ST_HDQ (1 << 22)
#define OMAP3430ES1_ST_FAC (1 << 8)
#define OMAP3430ES1_ST_MAILBOXES (1 << 7)
#define OMAP3430_ST_OMAPCTRL (1 << 6)
#define OMAP3430_ST_SDMA (1 << 2)
#define OMAP3430_ST_SDRC (1 << 1)
#define OMAP3430_ST_SSI (1 << 0)
#define OMAP3430ES2_ST_MMC3_SHIFT 30
#define OMAP3430ES2_ST_MMC3_MASK (1 << 30)
#define OMAP3430_ST_ICR_SHIFT 29
#define OMAP3430_ST_ICR_MASK (1 << 29)
#define OMAP3430_ST_AES2_SHIFT 28
#define OMAP3430_ST_AES2_MASK (1 << 28)
#define OMAP3430_ST_SHA12_SHIFT 27
#define OMAP3430_ST_SHA12_MASK (1 << 27)
#define OMAP3430_ST_DES2_SHIFT 26
#define OMAP3430_ST_DES2_MASK (1 << 26)
#define OMAP3430_ST_MSPRO_SHIFT 23
#define OMAP3430_ST_MSPRO_MASK (1 << 23)
#define OMAP3430_ST_HDQ_SHIFT 22
#define OMAP3430_ST_HDQ_MASK (1 << 22)
#define OMAP3430ES1_ST_FAC_SHIFT 8
#define OMAP3430ES1_ST_FAC_MASK (1 << 8)
#define OMAP3430ES2_ST_SSI_IDLE_SHIFT 8
#define OMAP3430ES2_ST_SSI_IDLE_MASK (1 << 8)
#define OMAP3430_ST_MAILBOXES_SHIFT 7
#define OMAP3430_ST_MAILBOXES_MASK (1 << 7)
#define OMAP3430_ST_OMAPCTRL_SHIFT 6
#define OMAP3430_ST_OMAPCTRL_MASK (1 << 6)
#define OMAP3430_ST_SDMA_SHIFT 2
#define OMAP3430_ST_SDMA_MASK (1 << 2)
#define OMAP3430_ST_SDRC_SHIFT 1
#define OMAP3430_ST_SDRC_MASK (1 << 1)
#define OMAP3430_ST_SSI_STDBY_SHIFT 0
#define OMAP3430_ST_SSI_STDBY_MASK (1 << 0)
/* CM_IDLEST2_CORE */
#define OMAP3430_ST_PKA (1 << 4)
#define OMAP3430_ST_AES1 (1 << 3)
#define OMAP3430_ST_RNG (1 << 2)
#define OMAP3430_ST_SHA11 (1 << 1)
#define OMAP3430_ST_DES1 (1 << 0)
#define OMAP3430_ST_PKA_SHIFT 4
#define OMAP3430_ST_PKA_MASK (1 << 4)
#define OMAP3430_ST_AES1_SHIFT 3
#define OMAP3430_ST_AES1_MASK (1 << 3)
#define OMAP3430_ST_RNG_SHIFT 2
#define OMAP3430_ST_RNG_MASK (1 << 2)
#define OMAP3430_ST_SHA11_SHIFT 1
#define OMAP3430_ST_SHA11_MASK (1 << 1)
#define OMAP3430_ST_DES1_SHIFT 0
#define OMAP3430_ST_DES1_MASK (1 << 0)
/* CM_IDLEST3_CORE */
#define OMAP3430ES2_ST_USBTLL_SHIFT 2
#define OMAP3430ES2_ST_USBTLL_MASK (1 << 2)
#define OMAP3430ES2_ST_CPEFUSE_SHIFT 0
#define OMAP3430ES2_ST_CPEFUSE_MASK (1 << 0)
/* CM_AUTOIDLE1_CORE */
#define OMAP3430ES2_AUTO_MMC3 (1 << 30)
#define OMAP3430ES2_AUTO_MMC3_SHIFT 30
#define OMAP3430ES2_AUTO_ICR (1 << 29)
#define OMAP3430ES2_AUTO_ICR_SHIFT 29
#define OMAP3430_AUTO_AES2 (1 << 28)
#define OMAP3430_AUTO_AES2_SHIFT 28
#define OMAP3430_AUTO_SHA12 (1 << 27)
@ -276,6 +303,9 @@
#define OMAP3430_AUTO_DES1_SHIFT 0
/* CM_AUTOIDLE3_CORE */
#define OMAP3430ES2_AUTO_USBHOST (1 << 0)
#define OMAP3430ES2_AUTO_USBHOST_SHIFT 0
#define OMAP3430ES2_AUTO_USBTLL (1 << 2)
#define OMAP3430ES2_AUTO_USBTLL_SHIFT 2
#define OMAP3430ES2_AUTO_USBTLL_MASK (1 << 2)
@ -332,8 +362,12 @@
#define OMAP3430ES1_CLKACTIVITY_GFX_MASK (1 << 0)
/* CM_FCLKEN_SGX */
#define OMAP3430ES2_EN_SGX_SHIFT 1
#define OMAP3430ES2_EN_SGX_MASK (1 << 1)
#define OMAP3430ES2_CM_FCLKEN_SGX_EN_SGX_SHIFT 1
#define OMAP3430ES2_CM_FCLKEN_SGX_EN_SGX_MASK (1 << 1)
/* CM_ICLKEN_SGX */
#define OMAP3430ES2_CM_ICLKEN_SGX_EN_SGX_SHIFT 0
#define OMAP3430ES2_CM_ICLKEN_SGX_EN_SGX_MASK (1 << 0)
/* CM_CLKSEL_SGX */
#define OMAP3430ES2_CLKSEL_SGX_SHIFT 0
@ -349,6 +383,7 @@
/* CM_FCLKEN_WKUP specific bits */
#define OMAP3430ES2_EN_USIMOCP_SHIFT 9
#define OMAP3430ES2_EN_USIMOCP_MASK (1 << 9)
/* CM_ICLKEN_WKUP specific bits */
#define OMAP3430_EN_WDT1 (1 << 4)
@ -357,11 +392,18 @@
#define OMAP3430_EN_32KSYNC_SHIFT 2
/* CM_IDLEST_WKUP specific bits */
#define OMAP3430_ST_WDT2 (1 << 5)
#define OMAP3430_ST_WDT1 (1 << 4)
#define OMAP3430_ST_32KSYNC (1 << 2)
#define OMAP3430ES2_ST_USIMOCP_SHIFT 9
#define OMAP3430ES2_ST_USIMOCP_MASK (1 << 9)
#define OMAP3430_ST_WDT2_SHIFT 5
#define OMAP3430_ST_WDT2_MASK (1 << 5)
#define OMAP3430_ST_WDT1_SHIFT 4
#define OMAP3430_ST_WDT1_MASK (1 << 4)
#define OMAP3430_ST_32KSYNC_SHIFT 2
#define OMAP3430_ST_32KSYNC_MASK (1 << 2)
/* CM_AUTOIDLE_WKUP */
#define OMAP3430ES2_AUTO_USIMOCP (1 << 9)
#define OMAP3430ES2_AUTO_USIMOCP_SHIFT 9
#define OMAP3430_AUTO_WDT2 (1 << 5)
#define OMAP3430_AUTO_WDT2_SHIFT 5
#define OMAP3430_AUTO_WDT1 (1 << 4)
@ -426,6 +468,8 @@
#define OMAP3430_ST_CORE_CLK_MASK (1 << 0)
/* CM_IDLEST2_CKGEN */
#define OMAP3430ES2_ST_USIM_CLK_SHIFT 2
#define OMAP3430ES2_ST_USIM_CLK_MASK (1 << 2)
#define OMAP3430ES2_ST_120M_CLK_SHIFT 1
#define OMAP3430ES2_ST_120M_CLK_MASK (1 << 1)
#define OMAP3430ES2_ST_PERIPH2_CLK_SHIFT 0
@ -449,8 +493,12 @@
#define OMAP3430_CORE_DPLL_MULT_MASK (0x7ff << 16)
#define OMAP3430_CORE_DPLL_DIV_SHIFT 8
#define OMAP3430_CORE_DPLL_DIV_MASK (0x7f << 8)
#define OMAP3430_SOURCE_54M (1 << 5)
#define OMAP3430_SOURCE_48M (1 << 3)
#define OMAP3430_SOURCE_96M_SHIFT 6
#define OMAP3430_SOURCE_96M_MASK (1 << 6)
#define OMAP3430_SOURCE_54M_SHIFT 5
#define OMAP3430_SOURCE_54M_MASK (1 << 5)
#define OMAP3430_SOURCE_48M_SHIFT 3
#define OMAP3430_SOURCE_48M_MASK (1 << 3)
/* CM_CLKSEL2_PLL */
#define OMAP3430_PERIPH_DPLL_MULT_SHIFT 8
@ -493,7 +541,12 @@
#define OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT 0
/* CM_IDLEST_DSS */
#define OMAP3430_ST_DSS (1 << 0)
#define OMAP3430ES2_ST_DSS_IDLE_SHIFT 1
#define OMAP3430ES2_ST_DSS_IDLE_MASK (1 << 1)
#define OMAP3430ES2_ST_DSS_STDBY_SHIFT 0
#define OMAP3430ES2_ST_DSS_STDBY_MASK (1 << 0)
#define OMAP3430ES1_ST_DSS_SHIFT 0
#define OMAP3430ES1_ST_DSS_MASK (1 << 0)
/* CM_AUTOIDLE_DSS */
#define OMAP3430_AUTO_DSS (1 << 0)
@ -516,6 +569,8 @@
#define OMAP3430_CLKACTIVITY_DSS_MASK (1 << 0)
/* CM_FCLKEN_CAM specific bits */
#define OMAP3430_EN_CSI2 (1 << 1)
#define OMAP3430_EN_CSI2_SHIFT 1
/* CM_ICLKEN_CAM specific bits */
@ -545,10 +600,14 @@
/* CM_ICLKEN_PER specific bits */
/* CM_IDLEST_PER */
#define OMAP3430_ST_WDT3 (1 << 12)
#define OMAP3430_ST_MCBSP4 (1 << 2)
#define OMAP3430_ST_MCBSP3 (1 << 1)
#define OMAP3430_ST_MCBSP2 (1 << 0)
#define OMAP3430_ST_WDT3_SHIFT 12
#define OMAP3430_ST_WDT3_MASK (1 << 12)
#define OMAP3430_ST_MCBSP4_SHIFT 2
#define OMAP3430_ST_MCBSP4_MASK (1 << 2)
#define OMAP3430_ST_MCBSP3_SHIFT 1
#define OMAP3430_ST_MCBSP3_MASK (1 << 1)
#define OMAP3430_ST_MCBSP2_SHIFT 0
#define OMAP3430_ST_MCBSP2_MASK (1 << 0)
/* CM_AUTOIDLE_PER */
#define OMAP3430_AUTO_GPIO6 (1 << 17)
@ -676,6 +735,10 @@
#define OMAP3430ES2_EN_USBHOST_MASK (1 << 0)
/* CM_IDLEST_USBHOST */
#define OMAP3430ES2_ST_USBHOST_IDLE_SHIFT 1
#define OMAP3430ES2_ST_USBHOST_IDLE_MASK (1 << 1)
#define OMAP3430ES2_ST_USBHOST_STDBY_SHIFT 0
#define OMAP3430ES2_ST_USBHOST_STDBY_MASK (1 << 0)
/* CM_AUTOIDLE_USBHOST */
#define OMAP3430ES2_AUTO_USBHOST_SHIFT 0

View File

@ -348,11 +348,12 @@ static void __init omap_hsmmc_reset(void)
}
dummy_pdev.id = i;
iclk = clk_get(dev, "mmchs_ick");
dev_set_name(&dummy_pdev.dev, "mmci-omap-hs.%d", i);
iclk = clk_get(dev, "ick");
if (iclk && clk_enable(iclk))
iclk = NULL;
fclk = clk_get(dev, "mmchs_fck");
fclk = clk_get(dev, "fck");
if (fclk && clk_enable(fclk))
fclk = NULL;

View File

@ -217,8 +217,13 @@ void __init omap2_check_revision(void)
omap_chip.oc = CHIP_IS_OMAP3430;
if (omap_rev() == OMAP3430_REV_ES1_0)
omap_chip.oc |= CHIP_IS_OMAP3430ES1;
else if (omap_rev() > OMAP3430_REV_ES1_0)
else if (omap_rev() >= OMAP3430_REV_ES2_0 &&
omap_rev() <= OMAP3430_REV_ES2_1)
omap_chip.oc |= CHIP_IS_OMAP3430ES2;
else if (omap_rev() == OMAP3430_REV_ES3_0)
omap_chip.oc |= CHIP_IS_OMAP3430ES3_0;
else if (omap_rev() == OMAP3430_REV_ES3_1)
omap_chip.oc |= CHIP_IS_OMAP3430ES3_1;
} else {
pr_err("Uninitialized omap_chip, please fix!\n");
}

View File

@ -27,8 +27,8 @@
#include <mach/mux.h>
#include <mach/omapfb.h>
#include <mach/sram.h>
#include "memory.h"
#include <mach/sdrc.h>
#include <mach/gpmc.h>
#include "clock.h"
@ -195,12 +195,12 @@ void __init omap2_map_common_io(void)
omapfb_reserve_sdram();
}
void __init omap2_init_common_hw(void)
void __init omap2_init_common_hw(struct omap_sdrc_params *sp)
{
omap2_mux_init();
pwrdm_init(powerdomains_omap);
clkdm_init(clockdomains_omap, clkdm_pwrdm_autodeps);
omap2_clk_init();
omap2_init_memory();
omap2_sdrc_init(sp);
gpmc_init();
}

View File

@ -24,8 +24,6 @@
#include <mach/cpu.h>
#include <mach/mcbsp.h>
const char *clk_names[] = { "mcbsp_ick", "mcbsp_fck" };
static void omap2_mcbsp2_mux_setup(void)
{
omap_cfg_reg(Y15_24XX_MCBSP2_CLKX);
@ -57,8 +55,6 @@ static struct omap_mcbsp_platform_data omap2420_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP1_IRQ_RX,
.tx_irq = INT_24XX_MCBSP1_IRQ_TX,
.ops = &omap2_mcbsp_ops,
.clk_names = clk_names,
.num_clks = 2,
},
{
.phys_base = OMAP24XX_MCBSP2_BASE,
@ -67,8 +63,6 @@ static struct omap_mcbsp_platform_data omap2420_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP2_IRQ_RX,
.tx_irq = INT_24XX_MCBSP2_IRQ_TX,
.ops = &omap2_mcbsp_ops,
.clk_names = clk_names,
.num_clks = 2,
},
};
#define OMAP2420_MCBSP_PDATA_SZ ARRAY_SIZE(omap2420_mcbsp_pdata)
@ -86,8 +80,6 @@ static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP1_IRQ_RX,
.tx_irq = INT_24XX_MCBSP1_IRQ_TX,
.ops = &omap2_mcbsp_ops,
.clk_names = clk_names,
.num_clks = 2,
},
{
.phys_base = OMAP24XX_MCBSP2_BASE,
@ -96,8 +88,6 @@ static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP2_IRQ_RX,
.tx_irq = INT_24XX_MCBSP2_IRQ_TX,
.ops = &omap2_mcbsp_ops,
.clk_names = clk_names,
.num_clks = 2,
},
{
.phys_base = OMAP2430_MCBSP3_BASE,
@ -106,8 +96,6 @@ static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP3_IRQ_RX,
.tx_irq = INT_24XX_MCBSP3_IRQ_TX,
.ops = &omap2_mcbsp_ops,
.clk_names = clk_names,
.num_clks = 2,
},
{
.phys_base = OMAP2430_MCBSP4_BASE,
@ -116,8 +104,6 @@ static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP4_IRQ_RX,
.tx_irq = INT_24XX_MCBSP4_IRQ_TX,
.ops = &omap2_mcbsp_ops,
.clk_names = clk_names,
.num_clks = 2,
},
{
.phys_base = OMAP2430_MCBSP5_BASE,
@ -126,8 +112,6 @@ static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP5_IRQ_RX,
.tx_irq = INT_24XX_MCBSP5_IRQ_TX,
.ops = &omap2_mcbsp_ops,
.clk_names = clk_names,
.num_clks = 2,
},
};
#define OMAP2430_MCBSP_PDATA_SZ ARRAY_SIZE(omap2430_mcbsp_pdata)
@ -145,8 +129,6 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP1_IRQ_RX,
.tx_irq = INT_24XX_MCBSP1_IRQ_TX,
.ops = &omap2_mcbsp_ops,
.clk_names = clk_names,
.num_clks = 2,
},
{
.phys_base = OMAP34XX_MCBSP2_BASE,
@ -155,8 +137,6 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP2_IRQ_RX,
.tx_irq = INT_24XX_MCBSP2_IRQ_TX,
.ops = &omap2_mcbsp_ops,
.clk_names = clk_names,
.num_clks = 2,
},
{
.phys_base = OMAP34XX_MCBSP3_BASE,
@ -165,8 +145,6 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP3_IRQ_RX,
.tx_irq = INT_24XX_MCBSP3_IRQ_TX,
.ops = &omap2_mcbsp_ops,
.clk_names = clk_names,
.num_clks = 2,
},
{
.phys_base = OMAP34XX_MCBSP4_BASE,
@ -175,8 +153,6 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP4_IRQ_RX,
.tx_irq = INT_24XX_MCBSP4_IRQ_TX,
.ops = &omap2_mcbsp_ops,
.clk_names = clk_names,
.num_clks = 2,
},
{
.phys_base = OMAP34XX_MCBSP5_BASE,
@ -185,8 +161,6 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP5_IRQ_RX,
.tx_irq = INT_24XX_MCBSP5_IRQ_TX,
.ops = &omap2_mcbsp_ops,
.clk_names = clk_names,
.num_clks = 2,
},
};
#define OMAP34XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap34xx_mcbsp_pdata)

View File

@ -1,43 +0,0 @@
/*
* linux/arch/arm/mach-omap2/memory.h
*
* Interface for memory timing related functions for OMAP24XX
*
* Copyright (C) 2005 Texas Instruments Inc.
* Richard Woodruff <r-woodruff2@ti.com>
*
* Copyright (C) 2005 Nokia Corporation
* Tony Lindgren <tony@atomide.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
* published by the Free Software Foundation.
*/
#ifndef ARCH_ARM_MACH_OMAP2_MEMORY_H
#define ARCH_ARM_MACH_OMAP2_MEMORY_H
/* Memory timings */
#define M_DDR 1
#define M_LOCK_CTRL (1 << 2)
#define M_UNLOCK 0
#define M_LOCK 1
struct memory_timings {
u32 m_type; /* ddr = 1, sdr = 0 */
u32 dll_mode; /* use lock mode = 1, unlock mode = 0 */
u32 slow_dll_ctrl; /* unlock mode, dll value for slow speed */
u32 fast_dll_ctrl; /* unlock mode, dll value for fast speed */
u32 base_cs; /* base chip select to use for calculations */
};
extern void omap2_init_memory_params(u32 force_lock_to_unlock_mode);
extern u32 omap2_memory_get_slow_dll_ctrl(void);
extern u32 omap2_memory_get_fast_dll_ctrl(void);
extern u32 omap2_memory_get_type(void);
u32 omap2_dll_force_needed(void);
u32 omap2_reprogram_sdrc(u32 level, u32 force);
void __init omap2_init_memory(void);
void __init gpmc_init(void);
#endif

View File

@ -103,7 +103,7 @@ static struct platform_suspend_ops omap_pm_ops = {
.valid = suspend_valid_only_mem,
};
int __init omap2_pm_init(void)
static int __init omap2_pm_init(void)
{
return 0;
}

View File

@ -171,13 +171,19 @@ static struct powerdomain *powerdomains_omap[] __initdata = {
&iva2_pwrdm,
&mpu_34xx_pwrdm,
&neon_pwrdm,
&core_34xx_pwrdm,
&core_34xx_pre_es3_1_pwrdm,
&core_34xx_es3_1_pwrdm,
&cam_pwrdm,
&dss_pwrdm,
&per_pwrdm,
&emu_pwrdm,
&sgx_pwrdm,
&usbhost_pwrdm,
&dpll1_pwrdm,
&dpll2_pwrdm,
&dpll3_pwrdm,
&dpll4_pwrdm,
&dpll5_pwrdm,
#endif
NULL

View File

@ -200,10 +200,12 @@ static struct powerdomain mpu_34xx_pwrdm = {
};
/* No wkdeps or sleepdeps for 34xx core apparently */
static struct powerdomain core_34xx_pwrdm = {
static struct powerdomain core_34xx_pre_es3_1_pwrdm = {
.name = "core_pwrdm",
.prcm_offs = CORE_MOD,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
.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,
@ -217,6 +219,25 @@ static struct powerdomain core_34xx_pwrdm = {
},
};
/* No wkdeps or sleepdeps for 34xx core apparently */
static struct powerdomain core_34xx_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 = {
[0] = PWRSTS_OFF_RET, /* MEM1RETSTATE */
[1] = PWRSTS_OFF_RET, /* MEM2RETSTATE */
},
.pwrsts_mem_on = {
[0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */
[1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */
},
};
/* Another case of bit name collisions between several registers: EN_DSS */
static struct powerdomain dss_pwrdm = {
.name = "dss_pwrdm",
@ -236,14 +257,19 @@ static struct powerdomain dss_pwrdm = {
},
};
/*
* Although the 34XX TRM Rev K Table 4-371 notes that retention is a
* possible SGX powerstate, the SGX device itself does not support
* retention.
*/
static struct powerdomain sgx_pwrdm = {
.name = "sgx_pwrdm",
.prcm_offs = OMAP3430ES2_SGX_MOD,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2),
.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_RET_ON,
.pwrsts = PWRSTS_OFF_ON,
.pwrsts_logic_ret = PWRDM_POWER_RET,
.banks = 1,
.pwrsts_mem_ret = {
@ -307,11 +333,12 @@ static struct powerdomain neon_pwrdm = {
static struct powerdomain usbhost_pwrdm = {
.name = "usbhost_pwrdm",
.prcm_offs = OMAP3430ES2_USBHOST_MOD,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2),
.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,
.flags = PWRDM_HAS_HDWR_SAR, /* for USBHOST ctrlr only */
.banks = 1,
.pwrsts_mem_ret = {
[0] = PWRDM_POWER_RET, /* MEMRETSTATE */
@ -321,6 +348,37 @@ static struct powerdomain usbhost_pwrdm = {
},
};
static struct powerdomain dpll1_pwrdm = {
.name = "dpll1_pwrdm",
.prcm_offs = MPU_MOD,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
static struct powerdomain dpll2_pwrdm = {
.name = "dpll2_pwrdm",
.prcm_offs = OMAP3430_IVA2_MOD,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
static struct powerdomain dpll3_pwrdm = {
.name = "dpll3_pwrdm",
.prcm_offs = PLL_MOD,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
static struct powerdomain dpll4_pwrdm = {
.name = "dpll4_pwrdm",
.prcm_offs = PLL_MOD,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
static struct powerdomain dpll5_pwrdm = {
.name = "dpll5_pwrdm",
.prcm_offs = PLL_MOD,
.omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
};
#endif /* CONFIG_ARCH_OMAP34XX */

View File

@ -113,33 +113,58 @@
#define OMAP2430_EN_USBHS (1 << 6)
/* CM_IDLEST1_CORE, PM_WKST1_CORE shared bits */
#define OMAP2420_ST_MMC (1 << 26)
#define OMAP24XX_ST_UART2 (1 << 22)
#define OMAP24XX_ST_UART1 (1 << 21)
#define OMAP24XX_ST_MCSPI2 (1 << 18)
#define OMAP24XX_ST_MCSPI1 (1 << 17)
#define OMAP24XX_ST_GPT12 (1 << 14)
#define OMAP24XX_ST_GPT11 (1 << 13)
#define OMAP24XX_ST_GPT10 (1 << 12)
#define OMAP24XX_ST_GPT9 (1 << 11)
#define OMAP24XX_ST_GPT8 (1 << 10)
#define OMAP24XX_ST_GPT7 (1 << 9)
#define OMAP24XX_ST_GPT6 (1 << 8)
#define OMAP24XX_ST_GPT5 (1 << 7)
#define OMAP24XX_ST_GPT4 (1 << 6)
#define OMAP24XX_ST_GPT3 (1 << 5)
#define OMAP24XX_ST_GPT2 (1 << 4)
#define OMAP2420_ST_VLYNQ (1 << 3)
#define OMAP2420_ST_MMC_SHIFT 26
#define OMAP2420_ST_MMC_MASK (1 << 26)
#define OMAP24XX_ST_UART2_SHIFT 22
#define OMAP24XX_ST_UART2_MASK (1 << 22)
#define OMAP24XX_ST_UART1_SHIFT 21
#define OMAP24XX_ST_UART1_MASK (1 << 21)
#define OMAP24XX_ST_MCSPI2_SHIFT 18
#define OMAP24XX_ST_MCSPI2_MASK (1 << 18)
#define OMAP24XX_ST_MCSPI1_SHIFT 17
#define OMAP24XX_ST_MCSPI1_MASK (1 << 17)
#define OMAP24XX_ST_GPT12_SHIFT 14
#define OMAP24XX_ST_GPT12_MASK (1 << 14)
#define OMAP24XX_ST_GPT11_SHIFT 13
#define OMAP24XX_ST_GPT11_MASK (1 << 13)
#define OMAP24XX_ST_GPT10_SHIFT 12
#define OMAP24XX_ST_GPT10_MASK (1 << 12)
#define OMAP24XX_ST_GPT9_SHIFT 11
#define OMAP24XX_ST_GPT9_MASK (1 << 11)
#define OMAP24XX_ST_GPT8_SHIFT 10
#define OMAP24XX_ST_GPT8_MASK (1 << 10)
#define OMAP24XX_ST_GPT7_SHIFT 9
#define OMAP24XX_ST_GPT7_MASK (1 << 9)
#define OMAP24XX_ST_GPT6_SHIFT 8
#define OMAP24XX_ST_GPT6_MASK (1 << 8)
#define OMAP24XX_ST_GPT5_SHIFT 7
#define OMAP24XX_ST_GPT5_MASK (1 << 7)
#define OMAP24XX_ST_GPT4_SHIFT 6
#define OMAP24XX_ST_GPT4_MASK (1 << 6)
#define OMAP24XX_ST_GPT3_SHIFT 5
#define OMAP24XX_ST_GPT3_MASK (1 << 5)
#define OMAP24XX_ST_GPT2_SHIFT 4
#define OMAP24XX_ST_GPT2_MASK (1 << 4)
#define OMAP2420_ST_VLYNQ_SHIFT 3
#define OMAP2420_ST_VLYNQ_MASK (1 << 3)
/* CM_IDLEST2_CORE, PM_WKST2_CORE shared bits */
#define OMAP2430_ST_MDM_INTC (1 << 11)
#define OMAP2430_ST_GPIO5 (1 << 10)
#define OMAP2430_ST_MCSPI3 (1 << 9)
#define OMAP2430_ST_MMCHS2 (1 << 8)
#define OMAP2430_ST_MMCHS1 (1 << 7)
#define OMAP2430_ST_USBHS (1 << 6)
#define OMAP24XX_ST_UART3 (1 << 2)
#define OMAP24XX_ST_USB (1 << 0)
#define OMAP2430_ST_MDM_INTC_SHIFT 11
#define OMAP2430_ST_MDM_INTC_MASK (1 << 11)
#define OMAP2430_ST_GPIO5_SHIFT 10
#define OMAP2430_ST_GPIO5_MASK (1 << 10)
#define OMAP2430_ST_MCSPI3_SHIFT 9
#define OMAP2430_ST_MCSPI3_MASK (1 << 9)
#define OMAP2430_ST_MMCHS2_SHIFT 8
#define OMAP2430_ST_MMCHS2_MASK (1 << 8)
#define OMAP2430_ST_MMCHS1_SHIFT 7
#define OMAP2430_ST_MMCHS1_MASK (1 << 7)
#define OMAP2430_ST_USBHS_SHIFT 6
#define OMAP2430_ST_USBHS_MASK (1 << 6)
#define OMAP24XX_ST_UART3_SHIFT 2
#define OMAP24XX_ST_UART3_MASK (1 << 2)
#define OMAP24XX_ST_USB_SHIFT 0
#define OMAP24XX_ST_USB_MASK (1 << 0)
/* CM_FCLKEN_WKUP, CM_ICLKEN_WKUP, PM_WKEN_WKUP shared bits */
#define OMAP24XX_EN_GPIOS_SHIFT 2
@ -148,11 +173,13 @@
#define OMAP24XX_EN_GPT1 (1 << 0)
/* PM_WKST_WKUP, CM_IDLEST_WKUP shared bits */
#define OMAP24XX_ST_GPIOS (1 << 2)
#define OMAP24XX_ST_GPT1 (1 << 0)
#define OMAP24XX_ST_GPIOS_SHIFT (1 << 2)
#define OMAP24XX_ST_GPIOS_MASK 2
#define OMAP24XX_ST_GPT1_SHIFT (1 << 0)
#define OMAP24XX_ST_GPT1_MASK 0
/* CM_IDLEST_MDM and PM_WKST_MDM shared bits */
#define OMAP2430_ST_MDM (1 << 0)
#define OMAP2430_ST_MDM_SHIFT (1 << 0)
/* 3430 register bits shared between CM & PRM registers */
@ -205,24 +232,46 @@
#define OMAP3430_EN_HSOTGUSB_SHIFT 4
/* PM_WKST1_CORE, CM_IDLEST1_CORE shared bits */
#define OMAP3430_ST_MMC2 (1 << 25)
#define OMAP3430_ST_MMC1 (1 << 24)
#define OMAP3430_ST_MCSPI4 (1 << 21)
#define OMAP3430_ST_MCSPI3 (1 << 20)
#define OMAP3430_ST_MCSPI2 (1 << 19)
#define OMAP3430_ST_MCSPI1 (1 << 18)
#define OMAP3430_ST_I2C3 (1 << 17)
#define OMAP3430_ST_I2C2 (1 << 16)
#define OMAP3430_ST_I2C1 (1 << 15)
#define OMAP3430_ST_UART2 (1 << 14)
#define OMAP3430_ST_UART1 (1 << 13)
#define OMAP3430_ST_GPT11 (1 << 12)
#define OMAP3430_ST_GPT10 (1 << 11)
#define OMAP3430_ST_MCBSP5 (1 << 10)
#define OMAP3430_ST_MCBSP1 (1 << 9)
#define OMAP3430_ST_FSHOSTUSB (1 << 5)
#define OMAP3430_ST_HSOTGUSB (1 << 4)
#define OMAP3430_ST_D2D (1 << 3)
#define OMAP3430_ST_MMC2_SHIFT 25
#define OMAP3430_ST_MMC2_MASK (1 << 25)
#define OMAP3430_ST_MMC1_SHIFT 24
#define OMAP3430_ST_MMC1_MASK (1 << 24)
#define OMAP3430_ST_MCSPI4_SHIFT 21
#define OMAP3430_ST_MCSPI4_MASK (1 << 21)
#define OMAP3430_ST_MCSPI3_SHIFT 20
#define OMAP3430_ST_MCSPI3_MASK (1 << 20)
#define OMAP3430_ST_MCSPI2_SHIFT 19
#define OMAP3430_ST_MCSPI2_MASK (1 << 19)
#define OMAP3430_ST_MCSPI1_SHIFT 18
#define OMAP3430_ST_MCSPI1_MASK (1 << 18)
#define OMAP3430_ST_I2C3_SHIFT 17
#define OMAP3430_ST_I2C3_MASK (1 << 17)
#define OMAP3430_ST_I2C2_SHIFT 16
#define OMAP3430_ST_I2C2_MASK (1 << 16)
#define OMAP3430_ST_I2C1_SHIFT 15
#define OMAP3430_ST_I2C1_MASK (1 << 15)
#define OMAP3430_ST_UART2_SHIFT 14
#define OMAP3430_ST_UART2_MASK (1 << 14)
#define OMAP3430_ST_UART1_SHIFT 13
#define OMAP3430_ST_UART1_MASK (1 << 13)
#define OMAP3430_ST_GPT11_SHIFT 12
#define OMAP3430_ST_GPT11_MASK (1 << 12)
#define OMAP3430_ST_GPT10_SHIFT 11
#define OMAP3430_ST_GPT10_MASK (1 << 11)
#define OMAP3430_ST_MCBSP5_SHIFT 10
#define OMAP3430_ST_MCBSP5_MASK (1 << 10)
#define OMAP3430_ST_MCBSP1_SHIFT 9
#define OMAP3430_ST_MCBSP1_MASK (1 << 9)
#define OMAP3430ES1_ST_FSHOSTUSB_SHIFT 5
#define OMAP3430ES1_ST_FSHOSTUSB_MASK (1 << 5)
#define OMAP3430ES1_ST_HSOTGUSB_SHIFT 4
#define OMAP3430ES1_ST_HSOTGUSB_MASK (1 << 4)
#define OMAP3430ES2_ST_HSOTGUSB_IDLE_SHIFT 5
#define OMAP3430ES2_ST_HSOTGUSB_IDLE_MASK (1 << 5)
#define OMAP3430ES2_ST_HSOTGUSB_STDBY_SHIFT 4
#define OMAP3430ES2_ST_HSOTGUSB_STDBY_MASK (1 << 4)
#define OMAP3430_ST_D2D_SHIFT 3
#define OMAP3430_ST_D2D_MASK (1 << 3)
/* CM_FCLKEN_WKUP, CM_ICLKEN_WKUP, PM_WKEN_WKUP shared bits */
#define OMAP3430_EN_GPIO1 (1 << 3)
@ -241,11 +290,16 @@
#define OMAP3430_EN_GPT12_SHIFT 1
/* CM_IDLEST_WKUP, PM_WKST_WKUP shared bits */
#define OMAP3430_ST_SR2 (1 << 7)
#define OMAP3430_ST_SR1 (1 << 6)
#define OMAP3430_ST_GPIO1 (1 << 3)
#define OMAP3430_ST_GPT12 (1 << 1)
#define OMAP3430_ST_GPT1 (1 << 0)
#define OMAP3430_ST_SR2_SHIFT 7
#define OMAP3430_ST_SR2_MASK (1 << 7)
#define OMAP3430_ST_SR1_SHIFT 6
#define OMAP3430_ST_SR1_MASK (1 << 6)
#define OMAP3430_ST_GPIO1_SHIFT 3
#define OMAP3430_ST_GPIO1_MASK (1 << 3)
#define OMAP3430_ST_GPT12_SHIFT 1
#define OMAP3430_ST_GPT12_MASK (1 << 1)
#define OMAP3430_ST_GPT1_SHIFT 0
#define OMAP3430_ST_GPT1_MASK (1 << 0)
/*
* CM_SLEEPDEP_GFX, CM_SLEEPDEP_DSS, CM_SLEEPDEP_CAM,
@ -296,20 +350,34 @@
#define OMAP3430_EN_MCBSP2_SHIFT 0
/* CM_IDLEST_PER, PM_WKST_PER shared bits */
#define OMAP3430_ST_GPIO6 (1 << 17)
#define OMAP3430_ST_GPIO5 (1 << 16)
#define OMAP3430_ST_GPIO4 (1 << 15)
#define OMAP3430_ST_GPIO3 (1 << 14)
#define OMAP3430_ST_GPIO2 (1 << 13)
#define OMAP3430_ST_UART3 (1 << 11)
#define OMAP3430_ST_GPT9 (1 << 10)
#define OMAP3430_ST_GPT8 (1 << 9)
#define OMAP3430_ST_GPT7 (1 << 8)
#define OMAP3430_ST_GPT6 (1 << 7)
#define OMAP3430_ST_GPT5 (1 << 6)
#define OMAP3430_ST_GPT4 (1 << 5)
#define OMAP3430_ST_GPT3 (1 << 4)
#define OMAP3430_ST_GPT2 (1 << 3)
#define OMAP3430_ST_GPIO6_SHIFT 17
#define OMAP3430_ST_GPIO6_MASK (1 << 17)
#define OMAP3430_ST_GPIO5_SHIFT 16
#define OMAP3430_ST_GPIO5_MASK (1 << 16)
#define OMAP3430_ST_GPIO4_SHIFT 15
#define OMAP3430_ST_GPIO4_MASK (1 << 15)
#define OMAP3430_ST_GPIO3_SHIFT 14
#define OMAP3430_ST_GPIO3_MASK (1 << 14)
#define OMAP3430_ST_GPIO2_SHIFT 13
#define OMAP3430_ST_GPIO2_MASK (1 << 13)
#define OMAP3430_ST_UART3_SHIFT 11
#define OMAP3430_ST_UART3_MASK (1 << 11)
#define OMAP3430_ST_GPT9_SHIFT 10
#define OMAP3430_ST_GPT9_MASK (1 << 10)
#define OMAP3430_ST_GPT8_SHIFT 9
#define OMAP3430_ST_GPT8_MASK (1 << 9)
#define OMAP3430_ST_GPT7_SHIFT 8
#define OMAP3430_ST_GPT7_MASK (1 << 8)
#define OMAP3430_ST_GPT6_SHIFT 7
#define OMAP3430_ST_GPT6_MASK (1 << 7)
#define OMAP3430_ST_GPT5_SHIFT 6
#define OMAP3430_ST_GPT5_MASK (1 << 6)
#define OMAP3430_ST_GPT4_SHIFT 5
#define OMAP3430_ST_GPT4_MASK (1 << 5)
#define OMAP3430_ST_GPT3_SHIFT 4
#define OMAP3430_ST_GPT3_MASK (1 << 4)
#define OMAP3430_ST_GPT2_SHIFT 3
#define OMAP3430_ST_GPT2_MASK (1 << 3)
/* CM_SLEEPDEP_PER, PM_WKDEP_IVA2, PM_WKDEP_MPU, PM_WKDEP_PER shared bits */
#define OMAP3430_EN_CORE_SHIFT 0

View File

@ -366,6 +366,7 @@
/* PM_WKEN_WKUP specific bits */
#define OMAP3430_EN_IO (1 << 8)
#define OMAP3430_EN_GPIO1 (1 << 3)
/* PM_MPUGRPSEL_WKUP specific bits */
@ -452,6 +453,14 @@
#define OMAP3430_CMDRA0_MASK (0xff << 0)
/* PRM_VC_CMD_VAL_0 specific bits */
#define OMAP3430_VC_CMD_ON_SHIFT 24
#define OMAP3430_VC_CMD_ON_MASK (0xFF << 24)
#define OMAP3430_VC_CMD_ONLP_SHIFT 16
#define OMAP3430_VC_CMD_ONLP_MASK (0xFF << 16)
#define OMAP3430_VC_CMD_RET_SHIFT 8
#define OMAP3430_VC_CMD_RET_MASK (0xFF << 8)
#define OMAP3430_VC_CMD_OFF_SHIFT 0
#define OMAP3430_VC_CMD_OFF_MASK (0xFF << 0)
/* PRM_VC_CMD_VAL_1 specific bits */

View File

@ -141,6 +141,19 @@
#define PM_PWSTCTRL 0x00e0
#define PM_PWSTST 0x00e4
/* Omap2 specific registers */
#define OMAP24XX_PM_WKEN2 0x00a4
#define OMAP24XX_PM_WKST2 0x00b4
#define OMAP24XX_PRCM_IRQSTATUS_DSP 0x00f0 /* IVA mod */
#define OMAP24XX_PRCM_IRQENABLE_DSP 0x00f4 /* IVA mod */
#define OMAP24XX_PRCM_IRQSTATUS_IVA 0x00f8
#define OMAP24XX_PRCM_IRQENABLE_IVA 0x00fc
/* Omap3 specific registers */
#define OMAP3430ES2_PM_WKEN3 0x00f0
#define OMAP3430ES2_PM_WKST3 0x00b8
#define OMAP3430_PM_MPUGRPSEL 0x00a4
#define OMAP3430_PM_MPUGRPSEL1 OMAP3430_PM_MPUGRPSEL
@ -153,16 +166,6 @@
#define OMAP3430_PRM_IRQENABLE_IVA2 0x00fc
/* Architecture-specific registers */
#define OMAP24XX_PM_WKEN2 0x00a4
#define OMAP24XX_PM_WKST2 0x00b4
#define OMAP24XX_PRCM_IRQSTATUS_DSP 0x00f0 /* IVA mod */
#define OMAP24XX_PRCM_IRQENABLE_DSP 0x00f4 /* IVA mod */
#define OMAP24XX_PRCM_IRQSTATUS_IVA 0x00f8
#define OMAP24XX_PRCM_IRQENABLE_IVA 0x00fc
#ifndef __ASSEMBLER__
/* Power/reset management domain register get/set */
@ -228,7 +231,6 @@ static inline u32 prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
#define OMAP_RSTTIME1_SHIFT 0
#define OMAP_RSTTIME1_MASK (0xff << 0)
/* PRM_RSTCTRL */
/* Named RM_RSTCTRL_WKUP on the 24xx */
/* 2420 calls RST_DPLL3 'RST_DPLL' */

View File

@ -0,0 +1,93 @@
/*
* SMS/SDRC (SDRAM controller) common code for OMAP2/3
*
* Copyright (C) 2005, 2008 Texas Instruments Inc.
* Copyright (C) 2005, 2008 Nokia Corporation
*
* Tony Lindgren <tony@atomide.com>
* Paul Walmsley
* Richard Woodruff <r-woodruff2@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
* published by the Free Software Foundation.
*/
#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 <mach/common.h>
#include <mach/clock.h>
#include <mach/sram.h>
#include "prm.h"
#include <mach/sdrc.h>
#include "sdrc.h"
static struct omap_sdrc_params *sdrc_init_params;
void __iomem *omap2_sdrc_base;
void __iomem *omap2_sms_base;
/**
* omap2_sdrc_get_params - return SDRC register values for a given clock rate
* @r: SDRC clock rate (in Hz)
*
* Return pre-calculated values for the SDRC_ACTIM_CTRLA,
* SDRC_ACTIM_CTRLB, SDRC_RFR_CTRL, and SDRC_MR registers, for a given
* SDRC clock rate 'r'. These parameters control various timing
* delays in the SDRAM controller that are expressed in terms of the
* number of SDRC clock cycles to wait; hence the clock rate
* dependency. Note that sdrc_init_params must be sorted rate
* descending. Also assumes that both chip-selects use the same
* timing parameters. Returns a struct omap_sdrc_params * upon
* success, or NULL upon failure.
*/
struct omap_sdrc_params *omap2_sdrc_get_params(unsigned long r)
{
struct omap_sdrc_params *sp;
sp = sdrc_init_params;
while (sp->rate != r)
sp++;
if (!sp->rate)
return NULL;
return sp;
}
void __init omap2_set_globals_sdrc(struct omap_globals *omap2_globals)
{
omap2_sdrc_base = omap2_globals->sdrc;
omap2_sms_base = omap2_globals->sms;
}
/* turn on smart idle modes for SDRAM scheduler and controller */
void __init omap2_sdrc_init(struct omap_sdrc_params *sp)
{
u32 l;
l = sms_read_reg(SMS_SYSCONFIG);
l &= ~(0x3 << 3);
l |= (0x2 << 3);
sms_write_reg(l, SMS_SYSCONFIG);
l = sdrc_read_reg(SDRC_SYSCONFIG);
l &= ~(0x3 << 3);
l |= (0x2 << 3);
sdrc_write_reg(l, SDRC_SYSCONFIG);
sdrc_init_params = sp;
}

View File

@ -1,13 +1,14 @@
/*
* linux/arch/arm/mach-omap2/memory.c
* linux/arch/arm/mach-omap2/sdrc2xxx.c
*
* Memory timing related functions for OMAP24XX
* SDRAM timing related functions for OMAP2xxx
*
* Copyright (C) 2005 Texas Instruments Inc.
* Richard Woodruff <r-woodruff2@ti.com>
* Copyright (C) 2005, 2008 Texas Instruments Inc.
* Copyright (C) 2005, 2008 Nokia Corporation
*
* Copyright (C) 2005 Nokia Corporation
* Tony Lindgren <tony@atomide.com>
* Paul Walmsley
* Richard Woodruff <r-woodruff2@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,27 +29,31 @@
#include <mach/sram.h>
#include "prm.h"
#include "memory.h"
#include "clock.h"
#include <mach/sdrc.h>
#include "sdrc.h"
void __iomem *omap2_sdrc_base;
void __iomem *omap2_sms_base;
/* Memory timing, DLL mode flags */
#define M_DDR 1
#define M_LOCK_CTRL (1 << 2)
#define M_UNLOCK 0
#define M_LOCK 1
static struct memory_timings mem_timings;
static u32 curr_perf_level = CORE_CLK_SRC_DPLL_X2;
u32 omap2_memory_get_slow_dll_ctrl(void)
static u32 omap2xxx_sdrc_get_slow_dll_ctrl(void)
{
return mem_timings.slow_dll_ctrl;
}
u32 omap2_memory_get_fast_dll_ctrl(void)
static u32 omap2xxx_sdrc_get_fast_dll_ctrl(void)
{
return mem_timings.fast_dll_ctrl;
}
u32 omap2_memory_get_type(void)
static u32 omap2xxx_sdrc_get_type(void)
{
return mem_timings.m_type;
}
@ -57,7 +62,7 @@ u32 omap2_memory_get_type(void)
* Check the DLL lock state, and return tue if running in unlock mode.
* This is needed to compensate for the shifted DLL value in unlock mode.
*/
u32 omap2_dll_force_needed(void)
u32 omap2xxx_sdrc_dll_is_unlocked(void)
{
/* dlla and dllb are a set */
u32 dll_state = sdrc_read_reg(SDRC_DLLA_CTRL);
@ -72,8 +77,10 @@ u32 omap2_dll_force_needed(void)
* 'level' is the value to store to CM_CLKSEL2_PLL.CORE_CLK_SRC.
* Practical values are CORE_CLK_SRC_DPLL (for CORE_CLK = DPLL_CLK) or
* CORE_CLK_SRC_DPLL_X2 (for CORE_CLK = * DPLL_CLK * 2)
*
* Used by the clock framework during CORE DPLL changes
*/
u32 omap2_reprogram_sdrc(u32 level, u32 force)
u32 omap2xxx_sdrc_reprogram(u32 level, u32 force)
{
u32 dll_ctrl, m_type;
u32 prev = curr_perf_level;
@ -82,15 +89,14 @@ u32 omap2_reprogram_sdrc(u32 level, u32 force)
if ((curr_perf_level == level) && !force)
return prev;
if (level == CORE_CLK_SRC_DPLL) {
dll_ctrl = omap2_memory_get_slow_dll_ctrl();
} else if (level == CORE_CLK_SRC_DPLL_X2) {
dll_ctrl = omap2_memory_get_fast_dll_ctrl();
} else {
if (level == CORE_CLK_SRC_DPLL)
dll_ctrl = omap2xxx_sdrc_get_slow_dll_ctrl();
else if (level == CORE_CLK_SRC_DPLL_X2)
dll_ctrl = omap2xxx_sdrc_get_fast_dll_ctrl();
else
return prev;
}
m_type = omap2_memory_get_type();
m_type = omap2xxx_sdrc_get_type();
local_irq_save(flags);
__raw_writel(0xffff, OMAP24XX_PRCM_VOLTSETUP);
@ -101,23 +107,14 @@ u32 omap2_reprogram_sdrc(u32 level, u32 force)
return prev;
}
#if !defined(CONFIG_ARCH_OMAP2)
void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
u32 base_cs, u32 force_unlock)
{
}
void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val,
u32 mem_type)
{
}
#endif
void omap2_init_memory_params(u32 force_lock_to_unlock_mode)
/* Used by the clock framework during CORE DPLL changes */
void omap2xxx_sdrc_init_params(u32 force_lock_to_unlock_mode)
{
unsigned long dll_cnt;
u32 fast_dll = 0;
mem_timings.m_type = !((sdrc_read_reg(SDRC_MR_0) & 0x3) == 0x1); /* DDR = 1, SDR = 0 */
/* DDR = 1, SDR = 0 */
mem_timings.m_type = !((sdrc_read_reg(SDRC_MR_0) & 0x3) == 0x1);
/* 2422 es2.05 and beyond has a single SIP DDR instead of 2 like others.
* In the case of 2422, its ok to use CS1 instead of CS0.
@ -164,28 +161,3 @@ void omap2_init_memory_params(u32 force_lock_to_unlock_mode)
/* 90 degree phase for anything below 133Mhz + disable DLL filter */
mem_timings.slow_dll_ctrl |= ((1 << 1) | (3 << 8));
}
void __init omap2_set_globals_memory(struct omap_globals *omap2_globals)
{
omap2_sdrc_base = omap2_globals->sdrc;
omap2_sms_base = omap2_globals->sms;
}
/* turn on smart idle modes for SDRAM scheduler and controller */
void __init omap2_init_memory(void)
{
u32 l;
if (!cpu_is_omap2420())
return;
l = sms_read_reg(SMS_SYSCONFIG);
l &= ~(0x3 << 3);
l |= (0x2 << 3);
sms_write_reg(l, SMS_SYSCONFIG);
l = sdrc_read_reg(SDRC_SYSCONFIG);
l &= ~(0x3 << 3);
l |= (0x2 << 3);
sdrc_write_reg(l, SDRC_SYSCONFIG);
}

View File

@ -11,14 +11,17 @@ choice
config ARCH_OMAP1
bool "TI OMAP1"
select COMMON_CLKDEV
config ARCH_OMAP2
bool "TI OMAP2"
select CPU_V6
select COMMON_CLKDEV
config ARCH_OMAP3
bool "TI OMAP3"
select CPU_V7
select COMMON_CLKDEV
endchoice

View File

@ -36,44 +36,6 @@ static struct clk_functions *arch_clock;
* Standard clock functions defined in include/linux/clk.h
*-------------------------------------------------------------------------*/
/*
* Returns a clock. Note that we first try to use device id on the bus
* and clock name. If this fails, we try to use clock name only.
*/
struct clk * clk_get(struct device *dev, const char *id)
{
struct clk *p, *clk = ERR_PTR(-ENOENT);
int idno;
if (dev == NULL || dev->bus != &platform_bus_type)
idno = -1;
else
idno = to_platform_device(dev)->id;
mutex_lock(&clocks_mutex);
list_for_each_entry(p, &clocks, node) {
if (p->id == idno &&
strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
clk = p;
goto found;
}
}
list_for_each_entry(p, &clocks, node) {
if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
clk = p;
break;
}
}
found:
mutex_unlock(&clocks_mutex);
return clk;
}
EXPORT_SYMBOL(clk_get);
int clk_enable(struct clk *clk)
{
unsigned long flags;
@ -114,22 +76,6 @@ out:
}
EXPORT_SYMBOL(clk_disable);
int clk_get_usecount(struct clk *clk)
{
unsigned long flags;
int ret = 0;
if (clk == NULL || IS_ERR(clk))
return 0;
spin_lock_irqsave(&clockfw_lock, flags);
ret = clk->usecount;
spin_unlock_irqrestore(&clockfw_lock, flags);
return ret;
}
EXPORT_SYMBOL(clk_get_usecount);
unsigned long clk_get_rate(struct clk *clk)
{
unsigned long flags;
@ -146,13 +92,6 @@ unsigned long clk_get_rate(struct clk *clk)
}
EXPORT_SYMBOL(clk_get_rate);
void clk_put(struct clk *clk)
{
if (clk && !IS_ERR(clk))
module_put(clk->owner);
}
EXPORT_SYMBOL(clk_put);
/*-------------------------------------------------------------------------
* Optional clock functions defined in include/linux/clk.h
*-------------------------------------------------------------------------*/
@ -185,6 +124,11 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
spin_lock_irqsave(&clockfw_lock, flags);
if (arch_clock->clk_set_rate)
ret = arch_clock->clk_set_rate(clk, rate);
if (ret == 0) {
if (clk->recalc)
clk->rate = clk->recalc(clk);
propagate_rate(clk);
}
spin_unlock_irqrestore(&clockfw_lock, flags);
return ret;
@ -200,8 +144,16 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
return ret;
spin_lock_irqsave(&clockfw_lock, flags);
if (arch_clock->clk_set_parent)
ret = arch_clock->clk_set_parent(clk, parent);
if (clk->usecount == 0) {
if (arch_clock->clk_set_parent)
ret = arch_clock->clk_set_parent(clk, parent);
if (ret == 0) {
if (clk->recalc)
clk->rate = clk->recalc(clk);
propagate_rate(clk);
}
} else
ret = -EBUSY;
spin_unlock_irqrestore(&clockfw_lock, flags);
return ret;
@ -210,18 +162,7 @@ EXPORT_SYMBOL(clk_set_parent);
struct clk *clk_get_parent(struct clk *clk)
{
unsigned long flags;
struct clk * ret = NULL;
if (clk == NULL || IS_ERR(clk))
return ret;
spin_lock_irqsave(&clockfw_lock, flags);
if (arch_clock->clk_get_parent)
ret = arch_clock->clk_get_parent(clk);
spin_unlock_irqrestore(&clockfw_lock, flags);
return ret;
return clk->parent;
}
EXPORT_SYMBOL(clk_get_parent);
@ -250,14 +191,20 @@ static int __init omap_clk_setup(char *str)
__setup("mpurate=", omap_clk_setup);
/* Used for clocks that always have same value as the parent clock */
void followparent_recalc(struct clk *clk)
unsigned long followparent_recalc(struct clk *clk)
{
if (clk == NULL || IS_ERR(clk))
return;
return clk->parent->rate;
}
clk->rate = clk->parent->rate;
if (unlikely(clk->flags & RATE_PROPAGATES))
propagate_rate(clk);
void clk_reparent(struct clk *child, struct clk *parent)
{
list_del_init(&child->sibling);
if (parent)
list_add(&child->sibling, &parent->children);
child->parent = parent;
/* now do the debugfs renaming to reattach the child
to the proper parent */
}
/* Propagate rate to children */
@ -265,17 +212,15 @@ void propagate_rate(struct clk * tclk)
{
struct clk *clkp;
if (tclk == NULL || IS_ERR(tclk))
return;
list_for_each_entry(clkp, &clocks, node) {
if (likely(clkp->parent != tclk))
continue;
if (likely((u32)clkp->recalc))
clkp->recalc(clkp);
list_for_each_entry(clkp, &tclk->children, sibling) {
if (clkp->recalc)
clkp->rate = clkp->recalc(clkp);
propagate_rate(clkp);
}
}
static LIST_HEAD(root_clks);
/**
* recalculate_root_clocks - recalculate and propagate all root clocks
*
@ -287,18 +232,35 @@ void recalculate_root_clocks(void)
{
struct clk *clkp;
list_for_each_entry(clkp, &clocks, node) {
if (unlikely(!clkp->parent) && likely((u32)clkp->recalc))
clkp->recalc(clkp);
list_for_each_entry(clkp, &root_clks, sibling) {
if (clkp->recalc)
clkp->rate = clkp->recalc(clkp);
propagate_rate(clkp);
}
}
void clk_init_one(struct clk *clk)
{
INIT_LIST_HEAD(&clk->children);
}
int clk_register(struct clk *clk)
{
if (clk == NULL || IS_ERR(clk))
return -EINVAL;
/*
* trap out already registered clocks
*/
if (clk->node.next || clk->node.prev)
return 0;
mutex_lock(&clocks_mutex);
if (clk->parent)
list_add(&clk->sibling, &clk->parent->children);
else
list_add(&clk->sibling, &root_clks);
list_add(&clk->node, &clocks);
if (clk->init)
clk->init(clk);
@ -314,39 +276,12 @@ void clk_unregister(struct clk *clk)
return;
mutex_lock(&clocks_mutex);
list_del(&clk->sibling);
list_del(&clk->node);
mutex_unlock(&clocks_mutex);
}
EXPORT_SYMBOL(clk_unregister);
void clk_deny_idle(struct clk *clk)
{
unsigned long flags;
if (clk == NULL || IS_ERR(clk))
return;
spin_lock_irqsave(&clockfw_lock, flags);
if (arch_clock->clk_deny_idle)
arch_clock->clk_deny_idle(clk);
spin_unlock_irqrestore(&clockfw_lock, flags);
}
EXPORT_SYMBOL(clk_deny_idle);
void clk_allow_idle(struct clk *clk)
{
unsigned long flags;
if (clk == NULL || IS_ERR(clk))
return;
spin_lock_irqsave(&clockfw_lock, flags);
if (arch_clock->clk_allow_idle)
arch_clock->clk_allow_idle(clk);
spin_unlock_irqrestore(&clockfw_lock, flags);
}
EXPORT_SYMBOL(clk_allow_idle);
void clk_enable_init_clocks(void)
{
struct clk *clkp;
@ -358,6 +293,23 @@ void clk_enable_init_clocks(void)
}
EXPORT_SYMBOL(clk_enable_init_clocks);
/*
* Low level helpers
*/
static int clkll_enable_null(struct clk *clk)
{
return 0;
}
static void clkll_disable_null(struct clk *clk)
{
}
const struct clkops clkops_null = {
.enable = clkll_enable_null,
.disable = clkll_disable_null,
};
#ifdef CONFIG_CPU_FREQ
void clk_init_cpufreq_table(struct cpufreq_frequency_table **table)
{
@ -383,8 +335,10 @@ static int __init clk_disable_unused(void)
unsigned long flags;
list_for_each_entry(ck, &clocks, node) {
if (ck->usecount > 0 || (ck->flags & ALWAYS_ENABLED) ||
ck->enable_reg == 0)
if (ck->ops == &clkops_null)
continue;
if (ck->usecount > 0 || ck->enable_reg == 0)
continue;
spin_lock_irqsave(&clockfw_lock, flags);

View File

@ -249,7 +249,7 @@ static struct omap_globals *omap2_globals;
static void __init __omap2_set_globals(void)
{
omap2_set_globals_tap(omap2_globals);
omap2_set_globals_memory(omap2_globals);
omap2_set_globals_sdrc(omap2_globals);
omap2_set_globals_control(omap2_globals);
omap2_set_globals_prcm(omap2_globals);
}

View File

@ -23,10 +23,13 @@
#include <linux/io.h>
#include <mach/hardware.h>
#include <mach/clock.h>
#include <asm/system.h>
#define VERY_HI_RATE 900000000
static struct cpufreq_frequency_table *freq_table;
#ifdef CONFIG_ARCH_OMAP1
#define MPU_CLK "mpu"
#else
@ -39,6 +42,9 @@ static struct clk *mpu_clk;
int omap_verify_speed(struct cpufreq_policy *policy)
{
if (freq_table)
return cpufreq_frequency_table_verify(policy, freq_table);
if (policy->cpu)
return -EINVAL;
@ -70,12 +76,26 @@ static int omap_target(struct cpufreq_policy *policy,
struct cpufreq_freqs freqs;
int ret = 0;
/* Ensure desired rate is within allowed range. Some govenors
* (ondemand) will just pass target_freq=0 to get the minimum. */
if (target_freq < policy->cpuinfo.min_freq)
target_freq = policy->cpuinfo.min_freq;
if (target_freq > policy->cpuinfo.max_freq)
target_freq = policy->cpuinfo.max_freq;
freqs.old = omap_getspeed(0);
freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
freqs.cpu = 0;
if (freqs.old == freqs.new)
return ret;
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
ret = clk_set_rate(mpu_clk, target_freq * 1000);
#ifdef CONFIG_CPU_FREQ_DEBUG
printk(KERN_DEBUG "cpufreq-omap: transition: %u --> %u\n",
freqs.old, freqs.new);
#endif
ret = clk_set_rate(mpu_clk, freqs.new * 1000);
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
return ret;
@ -83,16 +103,31 @@ static int omap_target(struct cpufreq_policy *policy,
static int __init omap_cpu_init(struct cpufreq_policy *policy)
{
int result = 0;
mpu_clk = clk_get(NULL, MPU_CLK);
if (IS_ERR(mpu_clk))
return PTR_ERR(mpu_clk);
if (policy->cpu != 0)
return -EINVAL;
policy->cur = policy->min = policy->max = omap_getspeed(0);
policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000;
policy->cpuinfo.max_freq = clk_round_rate(mpu_clk, VERY_HI_RATE) / 1000;
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
clk_init_cpufreq_table(&freq_table);
if (freq_table) {
result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
if (!result)
cpufreq_frequency_table_get_attr(freq_table,
policy->cpu);
} else {
policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000;
policy->cpuinfo.max_freq = clk_round_rate(mpu_clk,
VERY_HI_RATE) / 1000;
}
/* FIXME: what's the actual transition time? */
policy->cpuinfo.transition_latency = 10 * 1000 * 1000;
return 0;
}
@ -103,6 +138,11 @@ static int omap_cpu_exit(struct cpufreq_policy *policy)
return 0;
}
static struct freq_attr *omap_cpufreq_attr[] = {
&cpufreq_freq_attr_scaling_available_freqs,
NULL,
};
static struct cpufreq_driver omap_driver = {
.flags = CPUFREQ_STICKY,
.verify = omap_verify_speed,
@ -111,6 +151,7 @@ static struct cpufreq_driver omap_driver = {
.init = omap_cpu_init,
.exit = omap_cpu_exit,
.name = "omap",
.attr = omap_cpufreq_attr,
};
static int __init omap_cpufreq_init(void)
@ -119,3 +160,11 @@ static int __init omap_cpufreq_init(void)
}
arch_initcall(omap_cpufreq_init);
/*
* if ever we want to remove this, upon cleanup call:
*
* cpufreq_unregister_driver()
* cpufreq_frequency_table_put_attr()
*/

View File

@ -0,0 +1,13 @@
#ifndef __MACH_CLKDEV_H
#define __MACH_CLKDEV_H
static inline int __clk_get(struct clk *clk)
{
return 1;
}
static inline void __clk_put(struct clk *clk)
{
}
#endif

View File

@ -17,11 +17,16 @@ struct module;
struct clk;
struct clockdomain;
struct clkops {
int (*enable)(struct clk *);
void (*disable)(struct clk *);
};
#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
struct clksel_rate {
u8 div;
u32 val;
u8 div;
u8 flags;
};
@ -34,24 +39,28 @@ struct dpll_data {
void __iomem *mult_div1_reg;
u32 mult_mask;
u32 div1_mask;
u16 last_rounded_m;
u8 last_rounded_n;
unsigned long last_rounded_rate;
unsigned int rate_tolerance;
u16 max_multiplier;
u8 max_divider;
u32 max_tolerance;
# if defined(CONFIG_ARCH_OMAP3)
u8 modes;
struct clk *clk_bypass;
struct clk *clk_ref;
void __iomem *control_reg;
u32 enable_mask;
unsigned int rate_tolerance;
unsigned long last_rounded_rate;
u16 last_rounded_m;
u8 last_rounded_n;
u8 min_divider;
u8 max_divider;
u32 max_tolerance;
u16 max_multiplier;
# if defined(CONFIG_ARCH_OMAP3)
u8 modes;
void __iomem *autoidle_reg;
void __iomem *idlest_reg;
u32 autoidle_mask;
u32 freqsel_mask;
u32 idlest_mask;
u8 auto_recal_bit;
u8 recal_en_bit;
u8 recal_st_bit;
void __iomem *autoidle_reg;
u32 autoidle_mask;
void __iomem *idlest_reg;
u8 idlest_bit;
# endif
};
@ -59,21 +68,21 @@ struct dpll_data {
struct clk {
struct list_head node;
struct module *owner;
const struct clkops *ops;
const char *name;
int id;
struct clk *parent;
struct list_head children;
struct list_head sibling; /* node for children */
unsigned long rate;
__u32 flags;
void __iomem *enable_reg;
__u8 enable_bit;
__s8 usecount;
void (*recalc)(struct clk *);
unsigned long (*recalc)(struct clk *);
int (*set_rate)(struct clk *, unsigned long);
long (*round_rate)(struct clk *, unsigned long);
void (*init)(struct clk *);
int (*enable)(struct clk *);
void (*disable)(struct clk *);
__u8 enable_bit;
__s8 usecount;
#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
u8 fixed_div;
void __iomem *clksel_reg;
@ -99,7 +108,6 @@ struct clk_functions {
long (*clk_round_rate)(struct clk *clk, unsigned long rate);
int (*clk_set_rate)(struct clk *clk, unsigned long rate);
int (*clk_set_parent)(struct clk *clk, struct clk *parent);
struct clk * (*clk_get_parent)(struct clk *clk);
void (*clk_allow_idle)(struct clk *clk);
void (*clk_deny_idle)(struct clk *clk);
void (*clk_disable_unused)(struct clk *clk);
@ -110,42 +118,33 @@ struct clk_functions {
extern unsigned int mpurate;
extern int clk_init(struct clk_functions * custom_clocks);
extern int clk_init(struct clk_functions *custom_clocks);
extern void clk_init_one(struct clk *clk);
extern int clk_register(struct clk *clk);
extern void clk_reparent(struct clk *child, struct clk *parent);
extern void clk_unregister(struct clk *clk);
extern void propagate_rate(struct clk *clk);
extern void recalculate_root_clocks(void);
extern void followparent_recalc(struct clk * clk);
extern void clk_allow_idle(struct clk *clk);
extern void clk_deny_idle(struct clk *clk);
extern int clk_get_usecount(struct clk *clk);
extern unsigned long followparent_recalc(struct clk *clk);
extern void clk_enable_init_clocks(void);
#ifdef CONFIG_CPU_FREQ
extern void clk_init_cpufreq_table(struct cpufreq_frequency_table **table);
#endif
extern const struct clkops clkops_null;
/* Clock flags */
#define RATE_CKCTL (1 << 0) /* Main fixed ratio clocks */
/* bit 0 is free */
#define RATE_FIXED (1 << 1) /* Fixed clock rate */
#define RATE_PROPAGATES (1 << 2) /* Program children too */
#define VIRTUAL_CLOCK (1 << 3) /* Composite clock from table */
#define ALWAYS_ENABLED (1 << 4) /* Clock cannot be disabled */
/* bits 2-4 are free */
#define ENABLE_REG_32BIT (1 << 5) /* Use 32-bit access */
#define VIRTUAL_IO_ADDRESS (1 << 6) /* Clock in virtual address */
#define CLOCK_IDLE_CONTROL (1 << 7)
#define CLOCK_NO_IDLE_PARENT (1 << 8)
#define DELAYED_APP (1 << 9) /* Delay application of clock */
#define CONFIG_PARTICIPANT (1 << 10) /* Fundamental clock */
#define ENABLE_ON_INIT (1 << 11) /* Enable upon framework init */
#define INVERT_ENABLE (1 << 12) /* 0 enables, 1 disables */
/* bits 13-20 are currently free */
#define CLOCK_IN_OMAP310 (1 << 21)
#define CLOCK_IN_OMAP730 (1 << 22)
#define CLOCK_IN_OMAP1510 (1 << 23)
#define CLOCK_IN_OMAP16XX (1 << 24)
#define CLOCK_IN_OMAP242X (1 << 25)
#define CLOCK_IN_OMAP243X (1 << 26)
#define CLOCK_IN_OMAP343X (1 << 27) /* clocks common to all 343X */
#define PARENT_CONTROLS_CLOCK (1 << 28)
#define CLOCK_IN_OMAP3430ES1 (1 << 29) /* 3430ES1 clocks only */
#define CLOCK_IN_OMAP3430ES2 (1 << 30) /* 3430ES2 clocks only */
/* bits 13-31 are currently free */
/* Clksel_rate flags */
#define DEFAULT_RATE (1 << 0)
@ -157,9 +156,4 @@ extern void clk_enable_init_clocks(void);
#define RATE_IN_24XX (RATE_IN_242X | RATE_IN_243X)
/* CM_CLKSEL2_PLL.CORE_CLK_SRC options (24XX) */
#define CORE_CLK_SRC_32K 0
#define CORE_CLK_SRC_DPLL 1
#define CORE_CLK_SRC_DPLL_X2 2
#endif

View File

@ -1,5 +1,5 @@
/*
* linux/include/asm-arm/arch-omap/clockdomain.h
* arch/arm/plat-omap/include/mach/clockdomain.h
*
* OMAP2/3 clockdomain framework functions
*
@ -48,11 +48,13 @@
*/
struct clkdm_pwrdm_autodep {
/* Name of the powerdomain to add a wkdep/sleepdep on */
const char *pwrdm_name;
union {
/* Name of the powerdomain to add a wkdep/sleepdep on */
const char *name;
/* Powerdomain pointer (looked up at clkdm_init() time) */
struct powerdomain *pwrdm;
/* Powerdomain pointer (looked up at clkdm_init() time) */
struct powerdomain *ptr;
} pwrdm;
/* OMAP chip types that this clockdomain dep is valid on */
const struct omap_chip_id omap_chip;
@ -64,8 +66,13 @@ struct clockdomain {
/* Clockdomain name */
const char *name;
/* Powerdomain enclosing this clockdomain */
const char *pwrdm_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 */
const u16 clktrctrl_mask;
@ -79,9 +86,6 @@ struct clockdomain {
/* Usecount tracking */
atomic_t usecount;
/* Powerdomain pointer assigned at clkdm_register() */
struct powerdomain *pwrdm;
struct list_head node;
};

View File

@ -65,7 +65,7 @@ void omap2_set_globals_343x(void);
/* These get called from omap2_set_globals_xxxx(), do not call these */
void omap2_set_globals_tap(struct omap_globals *);
void omap2_set_globals_memory(struct omap_globals *);
void omap2_set_globals_sdrc(struct omap_globals *);
void omap2_set_globals_control(struct omap_globals *);
void omap2_set_globals_prcm(struct omap_globals *);

View File

@ -355,13 +355,27 @@ IS_OMAP_TYPE(3430, 0x3430)
* use omap_chip_is().
*
*/
#define CHIP_IS_OMAP2420 (1 << 0)
#define CHIP_IS_OMAP2430 (1 << 1)
#define CHIP_IS_OMAP3430 (1 << 2)
#define CHIP_IS_OMAP3430ES1 (1 << 3)
#define CHIP_IS_OMAP3430ES2 (1 << 4)
#define CHIP_IS_OMAP2420 (1 << 0)
#define CHIP_IS_OMAP2430 (1 << 1)
#define CHIP_IS_OMAP3430 (1 << 2)
#define CHIP_IS_OMAP3430ES1 (1 << 3)
#define CHIP_IS_OMAP3430ES2 (1 << 4)
#define CHIP_IS_OMAP3430ES3_0 (1 << 5)
#define CHIP_IS_OMAP3430ES3_1 (1 << 6)
#define CHIP_IS_OMAP24XX (CHIP_IS_OMAP2420 | CHIP_IS_OMAP2430)
/*
* "GE" here represents "greater than or equal to" in terms of ES
* levels. So CHIP_GE_OMAP3430ES2 is intended to match all OMAP3430
* chips at ES2 and beyond, but not, for example, any OMAP lines after
* OMAP3.
*/
#define CHIP_GE_OMAP3430ES2 (CHIP_IS_OMAP3430ES2 | \
CHIP_IS_OMAP3430ES3_0 | \
CHIP_IS_OMAP3430ES3_1)
#define CHIP_GE_OMAP3430ES3_1 (CHIP_IS_OMAP3430ES3_1)
#define CHIP_IS_OMAP24XX (CHIP_IS_OMAP2420 | CHIP_IS_OMAP2430)
int omap_chip_is(struct omap_chip_id oci);
int omap_type(void);

View File

@ -103,6 +103,6 @@ extern int gpmc_cs_request(int cs, unsigned long size, unsigned long *base);
extern void gpmc_cs_free(int cs);
extern int gpmc_cs_set_reserved(int cs, int reserved);
extern int gpmc_cs_reserved(int cs);
extern void gpmc_init(void);
extern void __init gpmc_init(void);
#endif

View File

@ -185,11 +185,13 @@
#define omap_writew(v,a) __raw_writew(v, IO_ADDRESS(a))
#define omap_writel(v,a) __raw_writel(v, IO_ADDRESS(a))
struct omap_sdrc_params;
extern void omap1_map_common_io(void);
extern void omap1_init_common_hw(void);
extern void omap2_map_common_io(void);
extern void omap2_init_common_hw(void);
extern void omap2_init_common_hw(struct omap_sdrc_params *sp);
#define __arch_ioremap(p,s,t) omap_ioremap(p,s,t)
#define __arch_iounmap(v) omap_iounmap(v)

View File

@ -344,8 +344,6 @@ struct omap_mcbsp_platform_data {
u8 dma_rx_sync, dma_tx_sync;
u16 rx_irq, tx_irq;
struct omap_mcbsp_ops *ops;
char const **clk_names;
int num_clks;
};
struct omap_mcbsp {
@ -377,8 +375,8 @@ struct omap_mcbsp {
/* Protect the field .free, while checking if the mcbsp is in use */
spinlock_t lock;
struct omap_mcbsp_platform_data *pdata;
struct clk **clks;
int num_clks;
struct clk *iclk;
struct clk *fclk;
};
extern struct omap_mcbsp **mcbsp_ptr;
extern int omap_mcbsp_count;

View File

@ -118,18 +118,6 @@
extern void prevent_idle_sleep(void);
extern void allow_idle_sleep(void);
/**
* clk_deny_idle - Prevents the clock from being idled during MPU idle
* @clk: clock signal handle
*/
void clk_deny_idle(struct clk *clk);
/**
* clk_allow_idle - Counters previous clk_deny_idle
* @clk: clock signal handle
*/
void clk_allow_idle(struct clk *clk);
extern void omap_pm_idle(void);
extern void omap_pm_suspend(void);
extern void omap730_cpu_suspend(unsigned short, unsigned short);

View File

@ -50,9 +50,9 @@
/*
* Maximum number of clockdomains that can be associated with a powerdomain.
* CORE powerdomain is probably the worst case.
* CORE powerdomain on OMAP3 is the worst case
*/
#define PWRDM_MAX_CLKDMS 3
#define PWRDM_MAX_CLKDMS 4
/* XXX A completely arbitrary number. What is reasonable here? */
#define PWRDM_TRANSITION_BAILOUT 100000
@ -145,6 +145,7 @@ int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm);
int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst);
int pwrdm_read_next_pwrst(struct powerdomain *pwrdm);
int pwrdm_read_pwrst(struct powerdomain *pwrdm);
int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm);
int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm);

View File

@ -20,10 +20,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __ASM_ARM_ARCH_DPM_PRCM_H
#define __ASM_ARM_ARCH_DPM_PRCM_H
#ifndef __ASM_ARM_ARCH_OMAP_PRCM_H
#define __ASM_ARM_ARCH_OMAP_PRCM_H
u32 omap_prcm_get_reset_sources(void);
void omap_prcm_arch_reset(char mode);
#endif

View File

@ -4,10 +4,12 @@
/*
* OMAP2/3 SDRC/SMS register definitions
*
* Copyright (C) 2007 Texas Instruments, Inc.
* Copyright (C) 2007 Nokia Corporation
* Copyright (C) 2007-2008 Texas Instruments, Inc.
* Copyright (C) 2007-2008 Nokia Corporation
*
* Written by Paul Walmsley
* Tony Lindgren
* Paul Walmsley
* Richard Woodruff
*
* 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
@ -64,14 +66,62 @@
* SMS register access
*/
#define OMAP242X_SMS_REGADDR(reg) IO_ADDRESS(OMAP2420_SMS_BASE + reg)
#define OMAP243X_SMS_REGADDR(reg) IO_ADDRESS(OMAP243X_SMS_BASE + reg)
#define OMAP343X_SMS_REGADDR(reg) IO_ADDRESS(OMAP343X_SMS_BASE + reg)
#define OMAP242X_SMS_REGADDR(reg) \
(void __iomem *)IO_ADDRESS(OMAP2420_SMS_BASE + reg)
#define OMAP243X_SMS_REGADDR(reg) \
(void __iomem *)IO_ADDRESS(OMAP243X_SMS_BASE + reg)
#define OMAP343X_SMS_REGADDR(reg) \
(void __iomem *)IO_ADDRESS(OMAP343X_SMS_BASE + reg)
/* SMS register offsets - read/write with sms_{read,write}_reg() */
#define SMS_SYSCONFIG 0x010
/* REVISIT: fill in other SMS registers here */
#ifndef __ASSEMBLER__
/**
* struct omap_sdrc_params - SDRC parameters for a given SDRC clock rate
* @rate: SDRC clock rate (in Hz)
* @actim_ctrla: Value to program to SDRC_ACTIM_CTRLA for this rate
* @actim_ctrlb: Value to program to SDRC_ACTIM_CTRLB for this rate
* @rfr_ctrl: Value to program to SDRC_RFR_CTRL for this rate
* @mr: Value to program to SDRC_MR for this rate
*
* This structure holds a pre-computed set of register values for the
* SDRC for a given SDRC clock rate and SDRAM chip. These are
* intended to be pre-computed and specified in an array in the board-*.c
* files. The structure is keyed off the 'rate' field.
*/
struct omap_sdrc_params {
unsigned long rate;
u32 actim_ctrla;
u32 actim_ctrlb;
u32 rfr_ctrl;
u32 mr;
};
void __init omap2_sdrc_init(struct omap_sdrc_params *sp);
struct omap_sdrc_params *omap2_sdrc_get_params(unsigned long r);
#ifdef CONFIG_ARCH_OMAP2
struct memory_timings {
u32 m_type; /* ddr = 1, sdr = 0 */
u32 dll_mode; /* use lock mode = 1, unlock mode = 0 */
u32 slow_dll_ctrl; /* unlock mode, dll value for slow speed */
u32 fast_dll_ctrl; /* unlock mode, dll value for fast speed */
u32 base_cs; /* base chip select to use for calculations */
};
extern void omap2xxx_sdrc_init_params(u32 force_lock_to_unlock_mode);
u32 omap2xxx_sdrc_dll_is_unlocked(void);
u32 omap2xxx_sdrc_reprogram(u32 level, u32 force);
#endif /* CONFIG_ARCH_OMAP2 */
#endif /* __ASSEMBLER__ */
#endif

View File

@ -9,12 +9,12 @@
#include <asm/mach-types.h>
#include <mach/hardware.h>
#include <mach/prcm.h>
#ifndef CONFIG_MACH_VOICEBLUE
#define voiceblue_reset() do {} while (0)
#endif
extern void omap_prcm_arch_reset(char mode);
static inline void arch_idle(void)
{
cpu_do_idle();

View File

@ -214,7 +214,6 @@ EXPORT_SYMBOL(omap_mcbsp_set_io_type);
int omap_mcbsp_request(unsigned int id)
{
struct omap_mcbsp *mcbsp;
int i;
int err;
if (!omap_mcbsp_check_valid_id(id)) {
@ -223,23 +222,23 @@ int omap_mcbsp_request(unsigned int id)
}
mcbsp = id_to_mcbsp_ptr(id);
if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->request)
mcbsp->pdata->ops->request(id);
for (i = 0; i < mcbsp->num_clks; i++)
clk_enable(mcbsp->clks[i]);
spin_lock(&mcbsp->lock);
if (!mcbsp->free) {
dev_err(mcbsp->dev, "McBSP%d is currently in use\n",
mcbsp->id);
spin_unlock(&mcbsp->lock);
return -1;
return -EBUSY;
}
mcbsp->free = 0;
spin_unlock(&mcbsp->lock);
if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->request)
mcbsp->pdata->ops->request(id);
clk_enable(mcbsp->iclk);
clk_enable(mcbsp->fclk);
/*
* Make sure that transmitter, receiver and sample-rate generator are
* not running before activating IRQs.
@ -278,7 +277,6 @@ EXPORT_SYMBOL(omap_mcbsp_request);
void omap_mcbsp_free(unsigned int id)
{
struct omap_mcbsp *mcbsp;
int i;
if (!omap_mcbsp_check_valid_id(id)) {
printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
@ -289,8 +287,14 @@ void omap_mcbsp_free(unsigned int id)
if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free)
mcbsp->pdata->ops->free(id);
for (i = mcbsp->num_clks - 1; i >= 0; i--)
clk_disable(mcbsp->clks[i]);
clk_disable(mcbsp->fclk);
clk_disable(mcbsp->iclk);
if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) {
/* Free IRQs */
free_irq(mcbsp->rx_irq, (void *)mcbsp);
free_irq(mcbsp->tx_irq, (void *)mcbsp);
}
spin_lock(&mcbsp->lock);
if (mcbsp->free) {
@ -302,12 +306,6 @@ void omap_mcbsp_free(unsigned int id)
mcbsp->free = 1;
spin_unlock(&mcbsp->lock);
if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) {
/* Free IRQs */
free_irq(mcbsp->rx_irq, (void *)mcbsp);
free_irq(mcbsp->tx_irq, (void *)mcbsp);
}
}
EXPORT_SYMBOL(omap_mcbsp_free);
@ -876,7 +874,6 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
struct omap_mcbsp_platform_data *pdata = pdev->dev.platform_data;
struct omap_mcbsp *mcbsp;
int id = pdev->id - 1;
int i;
int ret = 0;
if (!pdata) {
@ -899,7 +896,6 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
ret = -ENOMEM;
goto exit;
}
mcbsp_ptr[id] = mcbsp;
spin_lock_init(&mcbsp->lock);
mcbsp->id = id + 1;
@ -921,39 +917,32 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
mcbsp->dma_rx_sync = pdata->dma_rx_sync;
mcbsp->dma_tx_sync = pdata->dma_tx_sync;
if (pdata->num_clks) {
mcbsp->num_clks = pdata->num_clks;
mcbsp->clks = kzalloc(mcbsp->num_clks * sizeof(struct clk *),
GFP_KERNEL);
if (!mcbsp->clks) {
ret = -ENOMEM;
goto exit;
}
for (i = 0; i < mcbsp->num_clks; i++) {
mcbsp->clks[i] = clk_get(&pdev->dev, pdata->clk_names[i]);
if (IS_ERR(mcbsp->clks[i])) {
dev_err(&pdev->dev,
"Invalid %s configuration for McBSP%d.\n",
pdata->clk_names[i], mcbsp->id);
ret = PTR_ERR(mcbsp->clks[i]);
goto err_clk;
}
}
mcbsp->iclk = clk_get(&pdev->dev, "ick");
if (IS_ERR(mcbsp->iclk)) {
ret = PTR_ERR(mcbsp->iclk);
dev_err(&pdev->dev, "unable to get ick: %d\n", ret);
goto err_iclk;
}
mcbsp->fclk = clk_get(&pdev->dev, "fck");
if (IS_ERR(mcbsp->fclk)) {
ret = PTR_ERR(mcbsp->fclk);
dev_err(&pdev->dev, "unable to get fck: %d\n", ret);
goto err_fclk;
}
mcbsp->pdata = pdata;
mcbsp->dev = &pdev->dev;
mcbsp_ptr[id] = mcbsp;
platform_set_drvdata(pdev, mcbsp);
return 0;
err_clk:
while (i--)
clk_put(mcbsp->clks[i]);
kfree(mcbsp->clks);
err_fclk:
clk_put(mcbsp->iclk);
err_iclk:
iounmap(mcbsp->io_base);
err_ioremap:
mcbsp->free = 0;
kfree(mcbsp);
exit:
return ret;
}
@ -961,7 +950,6 @@ exit:
static int __devexit omap_mcbsp_remove(struct platform_device *pdev)
{
struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev);
int i;
platform_set_drvdata(pdev, NULL);
if (mcbsp) {
@ -970,18 +958,15 @@ static int __devexit omap_mcbsp_remove(struct platform_device *pdev)
mcbsp->pdata->ops->free)
mcbsp->pdata->ops->free(mcbsp->id);
for (i = mcbsp->num_clks - 1; i >= 0; i--) {
clk_disable(mcbsp->clks[i]);
clk_put(mcbsp->clks[i]);
}
clk_disable(mcbsp->fclk);
clk_disable(mcbsp->iclk);
clk_put(mcbsp->fclk);
clk_put(mcbsp->iclk);
iounmap(mcbsp->io_base);
if (mcbsp->num_clks) {
kfree(mcbsp->clks);
mcbsp->clks = NULL;
mcbsp->num_clks = 0;
}
mcbsp->fclk = NULL;
mcbsp->iclk = NULL;
mcbsp->free = 0;
mcbsp->dev = NULL;
}
@ -1002,4 +987,3 @@ int __init omap_mcbsp_init(void)
/* Register the McBSP driver */
return platform_driver_register(&omap_mcbsp_driver);
}

View File

@ -102,7 +102,7 @@ static int __init omap_rng_probe(struct platform_device *pdev)
return -EBUSY;
if (cpu_is_omap24xx()) {
rng_ick = clk_get(&pdev->dev, "rng_ick");
rng_ick = clk_get(&pdev->dev, "ick");
if (IS_ERR(rng_ick)) {
dev_err(&pdev->dev, "Could not get rng_ick\n");
ret = PTR_ERR(rng_ick);

View File

@ -193,22 +193,24 @@ static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg)
static int __init omap_i2c_get_clocks(struct omap_i2c_dev *dev)
{
if (cpu_is_omap16xx() || cpu_class_is_omap2()) {
dev->iclk = clk_get(dev->dev, "i2c_ick");
if (IS_ERR(dev->iclk)) {
dev->iclk = NULL;
return -ENODEV;
}
int ret;
dev->iclk = clk_get(dev->dev, "ick");
if (IS_ERR(dev->iclk)) {
ret = PTR_ERR(dev->iclk);
dev->iclk = NULL;
return ret;
}
dev->fclk = clk_get(dev->dev, "i2c_fck");
dev->fclk = clk_get(dev->dev, "fck");
if (IS_ERR(dev->fclk)) {
ret = PTR_ERR(dev->fclk);
if (dev->iclk != NULL) {
clk_put(dev->iclk);
dev->iclk = NULL;
}
dev->fclk = NULL;
return -ENODEV;
return ret;
}
return 0;
@ -218,18 +220,15 @@ static void omap_i2c_put_clocks(struct omap_i2c_dev *dev)
{
clk_put(dev->fclk);
dev->fclk = NULL;
if (dev->iclk != NULL) {
clk_put(dev->iclk);
dev->iclk = NULL;
}
clk_put(dev->iclk);
dev->iclk = NULL;
}
static void omap_i2c_unidle(struct omap_i2c_dev *dev)
{
WARN_ON(!dev->idle);
if (dev->iclk != NULL)
clk_enable(dev->iclk);
clk_enable(dev->iclk);
clk_enable(dev->fclk);
dev->idle = 0;
if (dev->iestate)
@ -254,8 +253,7 @@ static void omap_i2c_idle(struct omap_i2c_dev *dev)
}
dev->idle = 1;
clk_disable(dev->fclk);
if (dev->iclk != NULL)
clk_disable(dev->iclk);
clk_disable(dev->iclk);
}
static int omap_i2c_init(struct omap_i2c_dev *dev)
@ -312,15 +310,14 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
if (cpu_class_is_omap1()) {
struct clk *armxor_ck;
/*
* The I2C functional clock is the armxor_ck, so there's
* no need to get "armxor_ck" separately. Now, if OMAP2420
* always returns 12MHz for the functional clock, we can
* do this bit unconditionally.
*/
fclk_rate = clk_get_rate(dev->fclk);
armxor_ck = clk_get(NULL, "armxor_ck");
if (IS_ERR(armxor_ck))
dev_warn(dev->dev, "Could not get armxor_ck\n");
else {
fclk_rate = clk_get_rate(armxor_ck);
clk_put(armxor_ck);
}
/* TRM for 5912 says the I2C clock must be prescaled to be
* between 7 - 12 MHz. The XOR input clock is typically
* 12, 13 or 19.2 MHz. So we should have code that produces:

View File

@ -80,17 +80,17 @@ static int omap24xxcam_clock_get(struct omap24xxcam_device *cam)
{
int rval = 0;
cam->fck = clk_get(cam->dev, "cam_fck");
cam->fck = clk_get(cam->dev, "fck");
if (IS_ERR(cam->fck)) {
dev_err(cam->dev, "can't get cam_fck");
dev_err(cam->dev, "can't get camera fck");
rval = PTR_ERR(cam->fck);
omap24xxcam_clock_put(cam);
return rval;
}
cam->ick = clk_get(cam->dev, "cam_ick");
cam->ick = clk_get(cam->dev, "ick");
if (IS_ERR(cam->ick)) {
dev_err(cam->dev, "can't get cam_ick");
dev_err(cam->dev, "can't get camera ick");
rval = PTR_ERR(cam->ick);
omap24xxcam_clock_put(cam);
}

View File

@ -1460,18 +1460,12 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
if (!host->virt_base)
goto err_ioremap;
if (cpu_is_omap24xx()) {
host->iclk = clk_get(&pdev->dev, "mmc_ick");
if (IS_ERR(host->iclk))
goto err_free_mmc_host;
clk_enable(host->iclk);
}
if (!cpu_is_omap24xx())
host->fclk = clk_get(&pdev->dev, "mmc_ck");
else
host->fclk = clk_get(&pdev->dev, "mmc_fck");
host->iclk = clk_get(&pdev->dev, "ick");
if (IS_ERR(host->iclk))
goto err_free_mmc_host;
clk_enable(host->iclk);
host->fclk = clk_get(&pdev->dev, "fck");
if (IS_ERR(host->fclk)) {
ret = PTR_ERR(host->fclk);
goto err_free_iclk;
@ -1536,10 +1530,10 @@ static int mmc_omap_remove(struct platform_device *pdev)
if (host->pdata->cleanup)
host->pdata->cleanup(&pdev->dev);
if (host->iclk && !IS_ERR(host->iclk))
clk_put(host->iclk);
if (host->fclk && !IS_ERR(host->fclk))
clk_put(host->fclk);
mmc_omap_fclk_enable(host, 0);
clk_put(host->fclk);
clk_disable(host->iclk);
clk_put(host->iclk);
iounmap(host->virt_base);
release_mem_region(pdev->resource[0].start,

View File

@ -956,13 +956,13 @@ static int __init omap_mmc_probe(struct platform_device *pdev)
sema_init(&host->sem, 1);
host->iclk = clk_get(&pdev->dev, "mmchs_ick");
host->iclk = clk_get(&pdev->dev, "ick");
if (IS_ERR(host->iclk)) {
ret = PTR_ERR(host->iclk);
host->iclk = NULL;
goto err1;
}
host->fclk = clk_get(&pdev->dev, "mmchs_fck");
host->fclk = clk_get(&pdev->dev, "fck");
if (IS_ERR(host->fclk)) {
ret = PTR_ERR(host->fclk);
host->fclk = NULL;

View File

@ -1021,13 +1021,13 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev)
spin_lock_init(&mcspi->lock);
INIT_LIST_HEAD(&mcspi->msg_queue);
mcspi->ick = clk_get(&pdev->dev, "mcspi_ick");
mcspi->ick = clk_get(&pdev->dev, "ick");
if (IS_ERR(mcspi->ick)) {
dev_dbg(&pdev->dev, "can't get mcspi_ick\n");
status = PTR_ERR(mcspi->ick);
goto err1a;
}
mcspi->fck = clk_get(&pdev->dev, "mcspi_fck");
mcspi->fck = clk_get(&pdev->dev, "fck");
if (IS_ERR(mcspi->fck)) {
dev_dbg(&pdev->dev, "can't get mcspi_fck\n");
status = PTR_ERR(mcspi->fck);

View File

@ -506,11 +506,12 @@ static int __init uwire_probe(struct platform_device *pdev)
dev_set_drvdata(&pdev->dev, uwire);
uwire->ck = clk_get(&pdev->dev, "armxor_ck");
if (!uwire->ck || IS_ERR(uwire->ck)) {
dev_dbg(&pdev->dev, "no mpu_xor_clk ?\n");
uwire->ck = clk_get(&pdev->dev, "fck");
if (IS_ERR(uwire->ck)) {
status = PTR_ERR(uwire->ck);
dev_dbg(&pdev->dev, "no functional clock?\n");
spi_master_put(master);
return -ENODEV;
return status;
}
clk_enable(uwire->ck);

View File

@ -590,8 +590,8 @@ static int __init omap_hdq_probe(struct platform_device *pdev)
}
/* get interface & functional clock objects */
hdq_data->hdq_ick = clk_get(&pdev->dev, "hdq_ick");
hdq_data->hdq_fck = clk_get(&pdev->dev, "hdq_fck");
hdq_data->hdq_ick = clk_get(&pdev->dev, "ick");
hdq_data->hdq_fck = clk_get(&pdev->dev, "fck");
if (IS_ERR(hdq_data->hdq_ick) || IS_ERR(hdq_data->hdq_fck)) {
dev_dbg(&pdev->dev, "Can't get HDQ clock objects\n");

View File

@ -60,9 +60,8 @@ struct omap_wdt_dev {
void __iomem *base; /* physical */
struct device *dev;
int omap_wdt_users;
struct clk *armwdt_ck;
struct clk *mpu_wdt_ick;
struct clk *mpu_wdt_fck;
struct clk *ick;
struct clk *fck;
struct resource *mem;
struct miscdevice omap_wdt_miscdev;
};
@ -146,13 +145,8 @@ static int omap_wdt_open(struct inode *inode, struct file *file)
if (test_and_set_bit(1, (unsigned long *)&(wdev->omap_wdt_users)))
return -EBUSY;
if (cpu_is_omap16xx())
clk_enable(wdev->armwdt_ck); /* Enable the clock */
if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
clk_enable(wdev->mpu_wdt_ick); /* Enable the interface clock */
clk_enable(wdev->mpu_wdt_fck); /* Enable the functional clock */
}
clk_enable(wdev->ick); /* Enable the interface clock */
clk_enable(wdev->fck); /* Enable the functional clock */
/* initialize prescaler */
while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x01)
@ -181,13 +175,8 @@ static int omap_wdt_release(struct inode *inode, struct file *file)
omap_wdt_disable(wdev);
if (cpu_is_omap16xx())
clk_disable(wdev->armwdt_ck); /* Disable the clock */
if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
clk_disable(wdev->mpu_wdt_ick); /* Disable the clock */
clk_disable(wdev->mpu_wdt_fck); /* Disable the clock */
}
clk_disable(wdev->ick);
clk_disable(wdev->fck);
#else
printk(KERN_CRIT "omap_wdt: Unexpected close, not stopping!\n");
#endif
@ -303,44 +292,19 @@ static int __init omap_wdt_probe(struct platform_device *pdev)
wdev->omap_wdt_users = 0;
wdev->mem = mem;
if (cpu_is_omap16xx()) {
wdev->armwdt_ck = clk_get(&pdev->dev, "armwdt_ck");
if (IS_ERR(wdev->armwdt_ck)) {
ret = PTR_ERR(wdev->armwdt_ck);
wdev->armwdt_ck = NULL;
goto err_clk;
}
wdev->ick = clk_get(&pdev->dev, "ick");
if (IS_ERR(wdev->ick)) {
ret = PTR_ERR(wdev->ick);
wdev->ick = NULL;
goto err_clk;
}
wdev->fck = clk_get(&pdev->dev, "fck");
if (IS_ERR(wdev->fck)) {
ret = PTR_ERR(wdev->fck);
wdev->fck = NULL;
goto err_clk;
}
if (cpu_is_omap24xx()) {
wdev->mpu_wdt_ick = clk_get(&pdev->dev, "mpu_wdt_ick");
if (IS_ERR(wdev->mpu_wdt_ick)) {
ret = PTR_ERR(wdev->mpu_wdt_ick);
wdev->mpu_wdt_ick = NULL;
goto err_clk;
}
wdev->mpu_wdt_fck = clk_get(&pdev->dev, "mpu_wdt_fck");
if (IS_ERR(wdev->mpu_wdt_fck)) {
ret = PTR_ERR(wdev->mpu_wdt_fck);
wdev->mpu_wdt_fck = NULL;
goto err_clk;
}
}
if (cpu_is_omap34xx()) {
wdev->mpu_wdt_ick = clk_get(&pdev->dev, "wdt2_ick");
if (IS_ERR(wdev->mpu_wdt_ick)) {
ret = PTR_ERR(wdev->mpu_wdt_ick);
wdev->mpu_wdt_ick = NULL;
goto err_clk;
}
wdev->mpu_wdt_fck = clk_get(&pdev->dev, "wdt2_fck");
if (IS_ERR(wdev->mpu_wdt_fck)) {
ret = PTR_ERR(wdev->mpu_wdt_fck);
wdev->mpu_wdt_fck = NULL;
goto err_clk;
}
}
wdev->base = ioremap(res->start, res->end - res->start + 1);
if (!wdev->base) {
ret = -ENOMEM;
@ -380,12 +344,10 @@ err_ioremap:
wdev->base = NULL;
err_clk:
if (wdev->armwdt_ck)
clk_put(wdev->armwdt_ck);
if (wdev->mpu_wdt_ick)
clk_put(wdev->mpu_wdt_ick);
if (wdev->mpu_wdt_fck)
clk_put(wdev->mpu_wdt_fck);
if (wdev->ick)
clk_put(wdev->ick);
if (wdev->fck)
clk_put(wdev->fck);
kfree(wdev);
err_kzalloc:
@ -417,20 +379,8 @@ static int omap_wdt_remove(struct platform_device *pdev)
release_mem_region(res->start, res->end - res->start + 1);
platform_set_drvdata(pdev, NULL);
if (wdev->armwdt_ck) {
clk_put(wdev->armwdt_ck);
wdev->armwdt_ck = NULL;
}
if (wdev->mpu_wdt_ick) {
clk_put(wdev->mpu_wdt_ick);
wdev->mpu_wdt_ick = NULL;
}
if (wdev->mpu_wdt_fck) {
clk_put(wdev->mpu_wdt_fck);
wdev->mpu_wdt_fck = NULL;
}
clk_put(wdev->ick);
clk_put(wdev->fck);
iounmap(wdev->base);
kfree(wdev);