X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=arch%2Farm%2Fmach-omap1%2Fclock.c;h=5d9faa68d2ecdb7eb5c32b1915ec4b02120a374e;hb=0c326331c8b107abc0a160e8899d749150b8f76a;hp=f1958e882e8694e3bd480dd46b62af3f351c6d28;hpb=b20e481ab595e9667c33e2393bdfe9a31870d11f;p=pandora-kernel.git diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c index f1958e882e86..5d9faa68d2ec 100644 --- a/arch/arm/mach-omap1/clock.c +++ b/arch/arm/mach-omap1/clock.c @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -48,6 +49,15 @@ static void omap1_uart_recalc(struct clk * clk) clk->rate = 12000000; } +static void 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; +} + static int omap1_clk_enable_dsp_domain(struct clk *clk) { int retval; @@ -395,6 +405,31 @@ static int omap1_set_ext_clk_rate(struct clk * clk, unsigned long rate) return 0; } +static int omap1_set_sossi_rate(struct clk *clk, unsigned long rate) +{ + u32 l; + int div; + unsigned long p_rate; + + p_rate = clk->parent->rate; + /* Round towards slower frequency */ + div = (p_rate + rate - 1) / rate; + div--; + if (div < 0 || div > 7) + return -EINVAL; + + l = omap_readl(MOD_CONF_CTRL_1); + l &= ~(7 << 17); + l |= div << 17; + omap_writel(l, MOD_CONF_CTRL_1); + + clk->rate = p_rate / (div + 1); + if (unlikely(clk->flags & RATE_PROPAGATES)) + propagate_rate(clk); + + return 0; +} + static long omap1_round_ext_clk_rate(struct clk * clk, unsigned long rate) { return 96000000 / calc_ext_dsor(rate); @@ -431,8 +466,7 @@ static int omap1_clk_enable(struct clk *clk) } if (clk->flags & CLOCK_NO_IDLE_PARENT) - if (!cpu_is_omap24xx()) - omap1_clk_deny_idle(clk->parent); + omap1_clk_deny_idle(clk->parent); } ret = clk->enable(clk); @@ -453,8 +487,7 @@ static void omap1_clk_disable(struct clk *clk) if (likely(clk->parent)) { omap1_clk_disable(clk->parent); if (clk->flags & CLOCK_NO_IDLE_PARENT) - if (!cpu_is_omap24xx()) - omap1_clk_allow_idle(clk->parent); + omap1_clk_allow_idle(clk->parent); } } } @@ -470,7 +503,7 @@ static int omap1_clk_enable_generic(struct clk *clk) if (unlikely(clk->enable_reg == 0)) { printk(KERN_ERR "clock.c: Enable for %s without enable code\n", clk->name); - return 0; + return -EINVAL; } if (clk->flags & ENABLE_REG_32BIT) { @@ -586,77 +619,53 @@ static int omap1_clk_set_rate(struct clk *clk, unsigned long rate) *-------------------------------------------------------------------------*/ #ifdef CONFIG_OMAP_RESET_CLOCKS -/* - * Resets some clocks that may be left on from bootloader, - * but leaves serial clocks on. See also omap_late_clk_reset(). - */ -static inline void omap1_early_clk_reset(void) -{ - //omap_writel(0x3 << 29, MOD_CONF_CTRL_0); -} -static int __init omap1_late_clk_reset(void) +static void __init omap1_clk_disable_unused(struct clk *clk) { - /* Turn off all unused clocks */ - struct clk *p; __u32 regval32; - /* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */ - regval32 = omap_readw(SOFT_REQ_REG) & (1 << 4); - omap_writew(regval32, SOFT_REQ_REG); - omap_writew(0, SOFT_REQ_REG2); - - list_for_each_entry(p, &clocks, node) { - if (p->usecount > 0 || (p->flags & ALWAYS_ENABLED) || - p->enable_reg == 0) - continue; - - /* Clocks in the DSP domain need api_ck. Just assume bootloader - * has not enabled any DSP clocks */ - if ((u32)p->enable_reg == DSP_IDLECT2) { - printk(KERN_INFO "Skipping reset check for DSP domain " - "clock \"%s\"\n", p->name); - continue; - } + /* Clocks in the DSP domain need api_ck. Just assume bootloader + * has not enabled any DSP clocks */ + if ((u32)clk->enable_reg == DSP_IDLECT2) { + printk(KERN_INFO "Skipping reset check for DSP domain " + "clock \"%s\"\n", clk->name); + return; + } - /* Is the clock already disabled? */ - if (p->flags & ENABLE_REG_32BIT) { - if (p->flags & VIRTUAL_IO_ADDRESS) - regval32 = __raw_readl(p->enable_reg); - else - regval32 = omap_readl(p->enable_reg); - } else { - if (p->flags & VIRTUAL_IO_ADDRESS) - regval32 = __raw_readw(p->enable_reg); + /* 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_readw(p->enable_reg); - } - - if ((regval32 & (1 << p->enable_bit)) == 0) - continue; + 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); + } - /* FIXME: This clock seems to be necessary but no-one - * has asked for its activation. */ - if (p == &tc2_ck // FIX: pm.c (SRAM), CCP, Camera - || p == &ck_dpll1out.clk // FIX: SoSSI, SSR - || p == &arm_gpio_ck // FIX: GPIO code for 1510 - ) { - printk(KERN_INFO "FIXME: Clock \"%s\" seems unused\n", - p->name); - continue; - } + if ((regval32 & (1 << clk->enable_bit)) == 0) + return; - printk(KERN_INFO "Disabling unused clock \"%s\"... ", p->name); - p->disable(p); - printk(" done\n"); + /* FIXME: This clock seems to be necessary but no-one + * has asked for its activation. */ + if (clk == &tc2_ck // FIX: pm.c (SRAM), CCP, Camera + || clk == &ck_dpll1out.clk // FIX: SoSSI, SSR + || clk == &arm_gpio_ck // FIX: GPIO code for 1510 + ) { + printk(KERN_INFO "FIXME: Clock \"%s\" seems unused\n", + clk->name); + return; } - return 0; + printk(KERN_INFO "Disabling unused clock \"%s\"... ", clk->name); + clk->disable(clk); + printk(" done\n"); } -late_initcall(omap1_late_clk_reset); #else -#define omap1_early_clk_reset() {} +#define omap1_clk_disable_unused NULL #endif static struct clk_functions omap1_clk_functions = { @@ -664,6 +673,7 @@ static struct clk_functions omap1_clk_functions = { .clk_disable = omap1_clk_disable, .clk_round_rate = omap1_clk_round_rate, .clk_set_rate = omap1_clk_set_rate, + .clk_disable_unused = omap1_clk_disable_unused, }; int __init omap1_clk_init(void) @@ -671,8 +681,21 @@ int __init omap1_clk_init(void) struct clk ** clkp; const struct omap_clock_config *info; int crystal_type = 0; /* Default 12 MHz */ + u32 reg; + +#ifdef CONFIG_DEBUG_LL + /* Resets some clocks that may be left on from bootloader, + * but leaves serial clocks on. + */ + omap_writel(0x3 << 29, MOD_CONF_CTRL_0); +#endif + + /* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */ + reg = omap_readw(SOFT_REQ_REG) & (1 << 4); + omap_writew(reg, SOFT_REQ_REG); + if (!cpu_is_omap15xx()) + omap_writew(0, SOFT_REQ_REG2); - omap1_early_clk_reset(); clk_init(&omap1_clk_functions); /* By default all idlect1 clocks are allowed to idle */ @@ -702,7 +725,7 @@ int __init omap1_clk_init(void) info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config); if (info != NULL) { - if (!cpu_is_omap1510()) + if (!cpu_is_omap15xx()) crystal_type = info->system_clock_type; } @@ -772,6 +795,12 @@ int __init omap1_clk_init(void) omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL) & ~0x1, OMAP730_PCC_UPLD_CTRL); #endif + /* Amstrad Delta wants BCLK high when inactive */ + if (machine_is_ams_delta()) + omap_writel(omap_readl(ULPD_CLOCK_CTRL) | + (1 << SDW_MCLK_INV_BIT), + ULPD_CLOCK_CTRL); + /* Turn off DSP and ARM_TIMXO. Make sure ARM_INTHCK is not divided */ /* (on 730, bit 13 must not be cleared) */ if (cpu_is_omap730())