Loading arch/arm/mach-omap1/clock.c +48 −59 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <linux/clk.h> #include <asm/io.h> #include <asm/mach-types.h> #include <asm/arch/cpu.h> #include <asm/arch/usb.h> Loading Loading @@ -586,77 +587,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) { if ((u32)clk->enable_reg == DSP_IDLECT2) { printk(KERN_INFO "Skipping reset check for DSP domain " "clock \"%s\"\n", p->name); continue; "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); if (clk->flags & ENABLE_REG_32BIT) { if (clk->flags & VIRTUAL_IO_ADDRESS) regval32 = __raw_readl(clk->enable_reg); else regval32 = omap_readl(p->enable_reg); regval32 = omap_readl(clk->enable_reg); } else { if (p->flags & VIRTUAL_IO_ADDRESS) regval32 = __raw_readw(p->enable_reg); if (clk->flags & VIRTUAL_IO_ADDRESS) regval32 = __raw_readw(clk->enable_reg); else regval32 = omap_readw(p->enable_reg); regval32 = omap_readw(clk->enable_reg); } if ((regval32 & (1 << p->enable_bit)) == 0) continue; if ((regval32 & (1 << clk->enable_bit)) == 0) return; /* 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 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", p->name); continue; clk->name); return; } printk(KERN_INFO "Disabling unused clock \"%s\"... ", p->name); p->disable(p); printk(KERN_INFO "Disabling unused clock \"%s\"... ", clk->name); clk->disable(clk); printk(" done\n"); } return 0; } 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 = { Loading @@ -664,6 +641,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) Loading @@ -671,8 +649,13 @@ int __init omap1_clk_init(void) struct clk ** clkp; const struct omap_clock_config *info; int crystal_type = 0; /* Default 12 MHz */ u32 reg; /* 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); omap_writew(0, SOFT_REQ_REG2); omap1_early_clk_reset(); clk_init(&omap1_clk_functions); /* By default all idlect1 clocks are allowed to idle */ Loading Loading @@ -772,6 +755,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()) Loading arch/arm/mach-omap1/clock.h +14 −0 Original line number Diff line number Diff line Loading @@ -89,6 +89,7 @@ struct arm_idlect1_clk { #define EN_DSPTIMCK 5 /* Various register defines for clock controls scattered around OMAP chip */ #define SDW_MCLK_INV_BIT 2 /* In ULPD_CLKC_CTRL */ #define USB_MCLK_EN_BIT 4 /* In ULPD_CLKC_CTRL */ #define USB_HOST_HHC_UHOST_EN 9 /* In MOD_CONF_CTRL_0 */ #define SWD_ULPD_PLL_CLK_REQ 1 /* In SWD_CLK_DIV_CTRL_SEL */ Loading Loading @@ -741,6 +742,18 @@ static struct clk i2c_fck = { .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, .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, Loading Loading @@ -790,6 +803,7 @@ static struct clk * onchip_clks[] = { /* Virtual clocks */ &virtual_ck_mpu, &i2c_fck, &i2c_ick, }; #endif arch/arm/mach-omap2/clock.c +17 −22 Original line number Diff line number Diff line Loading @@ -1025,12 +1025,29 @@ static int omap2_select_table_rate(struct clk * clk, unsigned long rate) * Omap2 clock reset and init functions *-------------------------------------------------------------------------*/ #ifdef CONFIG_OMAP_RESET_CLOCKS static void __init omap2_clk_disable_unused(struct clk *clk) { u32 regval32; regval32 = __raw_readl(clk->enable_reg); if ((regval32 & (1 << clk->enable_bit)) == 0) return; printk(KERN_INFO "Disabling unused clock \"%s\"\n", clk->name); _omap2_clk_disable(clk); } #else #define omap2_clk_disable_unused NULL #endif static struct clk_functions omap2_clk_functions = { .clk_enable = omap2_clk_enable, .clk_disable = omap2_clk_disable, .clk_round_rate = omap2_clk_round_rate, .clk_set_rate = omap2_clk_set_rate, .clk_set_parent = omap2_clk_set_parent, .clk_disable_unused = omap2_clk_disable_unused, }; static void __init omap2_get_crystal_rate(struct clk *osc, struct clk *sys) Loading Loading @@ -1070,28 +1087,6 @@ void omap2_clk_prepare_for_reboot(void) clk_set_rate(vclk, rate); } #ifdef CONFIG_OMAP_RESET_CLOCKS static void __init omap2_disable_unused_clocks(void) { struct clk *ck; u32 regval32; list_for_each_entry(ck, &clocks, node) { if (ck->usecount > 0 || (ck->flags & ALWAYS_ENABLED) || ck->enable_reg == 0) continue; regval32 = __raw_readl(ck->enable_reg); if ((regval32 & (1 << ck->enable_bit)) == 0) continue; printk(KERN_INFO "Disabling unused clock \"%s\"\n", ck->name); _omap2_clk_disable(ck); } } late_initcall(omap2_disable_unused_clocks); #endif /* * Switch the MPU rate if specified on cmdline. * We cannot do this early until cmdline is parsed. Loading arch/arm/mach-omap2/clock.h +12 −6 Original line number Diff line number Diff line Loading @@ -1368,7 +1368,8 @@ static struct clk mcbsp5_fck = { }; static struct clk mcspi1_ick = { .name = "mcspi1_ick", .name = "mcspi_ick", .id = 1, .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, Loading @@ -1377,7 +1378,8 @@ static struct clk mcspi1_ick = { }; static struct clk mcspi1_fck = { .name = "mcspi1_fck", .name = "mcspi_fck", .id = 1, .parent = &func_48m_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, Loading @@ -1386,7 +1388,8 @@ static struct clk mcspi1_fck = { }; static struct clk mcspi2_ick = { .name = "mcspi2_ick", .name = "mcspi_ick", .id = 2, .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, Loading @@ -1395,7 +1398,8 @@ static struct clk mcspi2_ick = { }; static struct clk mcspi2_fck = { .name = "mcspi2_fck", .name = "mcspi_fck", .id = 2, .parent = &func_48m_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, Loading @@ -1404,7 +1408,8 @@ static struct clk mcspi2_fck = { }; static struct clk mcspi3_ick = { .name = "mcspi3_ick", .name = "mcspi_ick", .id = 3, .parent = &l4_ck, .flags = CLOCK_IN_OMAP243X, .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE, Loading @@ -1413,7 +1418,8 @@ static struct clk mcspi3_ick = { }; static struct clk mcspi3_fck = { .name = "mcspi3_fck", .name = "mcspi_fck", .id = 3, .parent = &func_48m_ck, .flags = CLOCK_IN_OMAP243X, .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE, Loading arch/arm/plat-omap/clock.c +25 −0 Original line number Diff line number Diff line Loading @@ -323,6 +323,31 @@ EXPORT_SYMBOL(clk_allow_idle); /*-------------------------------------------------------------------------*/ #ifdef CONFIG_OMAP_RESET_CLOCKS /* * Disable any unused clocks left on by the bootloader */ static int __init clk_disable_unused(void) { struct clk *ck; unsigned long flags; list_for_each_entry(ck, &clocks, node) { if (ck->usecount > 0 || (ck->flags & ALWAYS_ENABLED) || ck->enable_reg == 0) continue; spin_lock_irqsave(&clockfw_lock, flags); if (arch_clock->clk_disable_unused) arch_clock->clk_disable_unused(ck); spin_unlock_irqrestore(&clockfw_lock, flags); } return 0; } late_initcall(clk_disable_unused); #endif int __init clk_init(struct clk_functions * custom_clocks) { if (!custom_clocks) { Loading Loading
arch/arm/mach-omap1/clock.c +48 −59 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <linux/clk.h> #include <asm/io.h> #include <asm/mach-types.h> #include <asm/arch/cpu.h> #include <asm/arch/usb.h> Loading Loading @@ -586,77 +587,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) { if ((u32)clk->enable_reg == DSP_IDLECT2) { printk(KERN_INFO "Skipping reset check for DSP domain " "clock \"%s\"\n", p->name); continue; "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); if (clk->flags & ENABLE_REG_32BIT) { if (clk->flags & VIRTUAL_IO_ADDRESS) regval32 = __raw_readl(clk->enable_reg); else regval32 = omap_readl(p->enable_reg); regval32 = omap_readl(clk->enable_reg); } else { if (p->flags & VIRTUAL_IO_ADDRESS) regval32 = __raw_readw(p->enable_reg); if (clk->flags & VIRTUAL_IO_ADDRESS) regval32 = __raw_readw(clk->enable_reg); else regval32 = omap_readw(p->enable_reg); regval32 = omap_readw(clk->enable_reg); } if ((regval32 & (1 << p->enable_bit)) == 0) continue; if ((regval32 & (1 << clk->enable_bit)) == 0) return; /* 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 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", p->name); continue; clk->name); return; } printk(KERN_INFO "Disabling unused clock \"%s\"... ", p->name); p->disable(p); printk(KERN_INFO "Disabling unused clock \"%s\"... ", clk->name); clk->disable(clk); printk(" done\n"); } return 0; } 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 = { Loading @@ -664,6 +641,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) Loading @@ -671,8 +649,13 @@ int __init omap1_clk_init(void) struct clk ** clkp; const struct omap_clock_config *info; int crystal_type = 0; /* Default 12 MHz */ u32 reg; /* 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); omap_writew(0, SOFT_REQ_REG2); omap1_early_clk_reset(); clk_init(&omap1_clk_functions); /* By default all idlect1 clocks are allowed to idle */ Loading Loading @@ -772,6 +755,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()) Loading
arch/arm/mach-omap1/clock.h +14 −0 Original line number Diff line number Diff line Loading @@ -89,6 +89,7 @@ struct arm_idlect1_clk { #define EN_DSPTIMCK 5 /* Various register defines for clock controls scattered around OMAP chip */ #define SDW_MCLK_INV_BIT 2 /* In ULPD_CLKC_CTRL */ #define USB_MCLK_EN_BIT 4 /* In ULPD_CLKC_CTRL */ #define USB_HOST_HHC_UHOST_EN 9 /* In MOD_CONF_CTRL_0 */ #define SWD_ULPD_PLL_CLK_REQ 1 /* In SWD_CLK_DIV_CTRL_SEL */ Loading Loading @@ -741,6 +742,18 @@ static struct clk i2c_fck = { .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, .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, Loading Loading @@ -790,6 +803,7 @@ static struct clk * onchip_clks[] = { /* Virtual clocks */ &virtual_ck_mpu, &i2c_fck, &i2c_ick, }; #endif
arch/arm/mach-omap2/clock.c +17 −22 Original line number Diff line number Diff line Loading @@ -1025,12 +1025,29 @@ static int omap2_select_table_rate(struct clk * clk, unsigned long rate) * Omap2 clock reset and init functions *-------------------------------------------------------------------------*/ #ifdef CONFIG_OMAP_RESET_CLOCKS static void __init omap2_clk_disable_unused(struct clk *clk) { u32 regval32; regval32 = __raw_readl(clk->enable_reg); if ((regval32 & (1 << clk->enable_bit)) == 0) return; printk(KERN_INFO "Disabling unused clock \"%s\"\n", clk->name); _omap2_clk_disable(clk); } #else #define omap2_clk_disable_unused NULL #endif static struct clk_functions omap2_clk_functions = { .clk_enable = omap2_clk_enable, .clk_disable = omap2_clk_disable, .clk_round_rate = omap2_clk_round_rate, .clk_set_rate = omap2_clk_set_rate, .clk_set_parent = omap2_clk_set_parent, .clk_disable_unused = omap2_clk_disable_unused, }; static void __init omap2_get_crystal_rate(struct clk *osc, struct clk *sys) Loading Loading @@ -1070,28 +1087,6 @@ void omap2_clk_prepare_for_reboot(void) clk_set_rate(vclk, rate); } #ifdef CONFIG_OMAP_RESET_CLOCKS static void __init omap2_disable_unused_clocks(void) { struct clk *ck; u32 regval32; list_for_each_entry(ck, &clocks, node) { if (ck->usecount > 0 || (ck->flags & ALWAYS_ENABLED) || ck->enable_reg == 0) continue; regval32 = __raw_readl(ck->enable_reg); if ((regval32 & (1 << ck->enable_bit)) == 0) continue; printk(KERN_INFO "Disabling unused clock \"%s\"\n", ck->name); _omap2_clk_disable(ck); } } late_initcall(omap2_disable_unused_clocks); #endif /* * Switch the MPU rate if specified on cmdline. * We cannot do this early until cmdline is parsed. Loading
arch/arm/mach-omap2/clock.h +12 −6 Original line number Diff line number Diff line Loading @@ -1368,7 +1368,8 @@ static struct clk mcbsp5_fck = { }; static struct clk mcspi1_ick = { .name = "mcspi1_ick", .name = "mcspi_ick", .id = 1, .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, Loading @@ -1377,7 +1378,8 @@ static struct clk mcspi1_ick = { }; static struct clk mcspi1_fck = { .name = "mcspi1_fck", .name = "mcspi_fck", .id = 1, .parent = &func_48m_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, Loading @@ -1386,7 +1388,8 @@ static struct clk mcspi1_fck = { }; static struct clk mcspi2_ick = { .name = "mcspi2_ick", .name = "mcspi_ick", .id = 2, .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, Loading @@ -1395,7 +1398,8 @@ static struct clk mcspi2_ick = { }; static struct clk mcspi2_fck = { .name = "mcspi2_fck", .name = "mcspi_fck", .id = 2, .parent = &func_48m_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, Loading @@ -1404,7 +1408,8 @@ static struct clk mcspi2_fck = { }; static struct clk mcspi3_ick = { .name = "mcspi3_ick", .name = "mcspi_ick", .id = 3, .parent = &l4_ck, .flags = CLOCK_IN_OMAP243X, .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE, Loading @@ -1413,7 +1418,8 @@ static struct clk mcspi3_ick = { }; static struct clk mcspi3_fck = { .name = "mcspi3_fck", .name = "mcspi_fck", .id = 3, .parent = &func_48m_ck, .flags = CLOCK_IN_OMAP243X, .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE, Loading
arch/arm/plat-omap/clock.c +25 −0 Original line number Diff line number Diff line Loading @@ -323,6 +323,31 @@ EXPORT_SYMBOL(clk_allow_idle); /*-------------------------------------------------------------------------*/ #ifdef CONFIG_OMAP_RESET_CLOCKS /* * Disable any unused clocks left on by the bootloader */ static int __init clk_disable_unused(void) { struct clk *ck; unsigned long flags; list_for_each_entry(ck, &clocks, node) { if (ck->usecount > 0 || (ck->flags & ALWAYS_ENABLED) || ck->enable_reg == 0) continue; spin_lock_irqsave(&clockfw_lock, flags); if (arch_clock->clk_disable_unused) arch_clock->clk_disable_unused(ck); spin_unlock_irqrestore(&clockfw_lock, flags); } return 0; } late_initcall(clk_disable_unused); #endif int __init clk_init(struct clk_functions * custom_clocks) { if (!custom_clocks) { Loading