Loading arch/arm/mach-omap1/clock.c +238 −169 Original line number Diff line number Diff line Loading @@ -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) Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; Loading @@ -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 */ Loading Loading @@ -289,17 +404,14 @@ 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; u16 regval; if (clk->flags & RATE_CKCTL) { dsor_exp = calc_dsor_exp(clk, rate); if (dsor_exp > 3) dsor_exp = -EINVAL; Loading @@ -311,13 +423,38 @@ static int omap1_clk_set_rate_dsp_domain(struct clk *clk, unsigned long rate) regval |= dsor_exp << clk->rate_offset; __raw_writew(regval, DSP_CKCTL); clk->rate = clk->parent->rate / (1 << dsor_exp); ret = 0; return 0; } if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES))) propagate_rate(clk); 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); } return ret; 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) Loading Loading @@ -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; Loading @@ -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; } Loading @@ -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; } Loading @@ -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) Loading @@ -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); Loading @@ -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) Loading @@ -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); Loading @@ -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); } } 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); } } return 0; Loading @@ -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); } } 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); } } } 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); Loading @@ -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; } Loading @@ -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) if (clk->flags & ENABLE_REG_32BIT) 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 ((regval32 & (1 << clk->enable_bit)) == 0) return; Loading @@ -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"); } Loading @@ -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, Loading @@ -700,26 +774,23 @@ 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; } if (((*clkp)->flags &CLOCK_IN_OMAP730) && cpu_is_omap730()) { 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_OMAP310) && cpu_is_omap310()) { 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); } info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config); Loading Loading @@ -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)) { Loading @@ -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): " Loading Loading @@ -832,4 +902,3 @@ int __init omap1_clk_init(void) return 0; } Loading
arch/arm/mach-omap1/clock.c +238 −169 Original line number Diff line number Diff line Loading @@ -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) Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; Loading @@ -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 */ Loading Loading @@ -289,17 +404,14 @@ 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; u16 regval; if (clk->flags & RATE_CKCTL) { dsor_exp = calc_dsor_exp(clk, rate); if (dsor_exp > 3) dsor_exp = -EINVAL; Loading @@ -311,13 +423,38 @@ static int omap1_clk_set_rate_dsp_domain(struct clk *clk, unsigned long rate) regval |= dsor_exp << clk->rate_offset; __raw_writew(regval, DSP_CKCTL); clk->rate = clk->parent->rate / (1 << dsor_exp); ret = 0; return 0; } if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES))) propagate_rate(clk); 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); } return ret; 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) Loading Loading @@ -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; Loading @@ -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; } Loading @@ -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; } Loading @@ -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) Loading @@ -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); Loading @@ -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) Loading @@ -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); Loading @@ -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); } } 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); } } return 0; Loading @@ -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); } } 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); } } } 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); Loading @@ -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; } Loading @@ -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) if (clk->flags & ENABLE_REG_32BIT) 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 ((regval32 & (1 << clk->enable_bit)) == 0) return; Loading @@ -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"); } Loading @@ -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, Loading @@ -700,26 +774,23 @@ 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; } if (((*clkp)->flags &CLOCK_IN_OMAP730) && cpu_is_omap730()) { 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_OMAP310) && cpu_is_omap310()) { 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); } info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config); Loading Loading @@ -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)) { Loading @@ -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): " Loading Loading @@ -832,4 +902,3 @@ int __init omap1_clk_init(void) return 0; }