From cc2b14904ddff99a0b24d3757c293db53fb4fff2 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 26 Sep 2005 17:04:44 +0300 Subject: [PATCH] ARM: OMAP: Clock framework fixes to allow adding omap2 clocks Clock framework fixes to allow adding omap2 clocks --- arch/arm/mach-omap1/clock.c | 3 ++ arch/arm/mach-omap1/clock.h | 60 +++++++++++++++---------------- arch/arm/plat-omap/clock.c | 48 +++++++++++++++++++++---- include/asm-arm/arch-omap/clock.h | 11 ++++-- 4 files changed, 83 insertions(+), 39 deletions(-) diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c index 3d88de5e8fa..1482c00965a 100644 --- a/arch/arm/mach-omap1/clock.c +++ b/arch/arm/mach-omap1/clock.c @@ -4,6 +4,9 @@ * Copyright (C) 2004 - 2005 Nokia corporation * Written by Tuukka Tikkanen * + * Modified to use omap shared clock framework by + * Tony Lindgren + * * 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. diff --git a/arch/arm/mach-omap1/clock.h b/arch/arm/mach-omap1/clock.h index 8c429c5708c..f3bdfb50e01 100644 --- a/arch/arm/mach-omap1/clock.h +++ b/arch/arm/mach-omap1/clock.h @@ -170,7 +170,7 @@ static struct arm_idlect1_clk ck_dpll1out = { .name = "ck_dpll1out", .parent = &ck_dpll1, .flags = CLOCK_IN_OMAP16XX | CLOCK_IDLE_CONTROL, - .enable_reg = ARM_IDLECT2, + .enable_reg = (void __iomem *)ARM_IDLECT2, .enable_bit = EN_CKOUT_ARM, .recalc = &followparent_recalc, .enable = &omap1_clk_enable, @@ -196,7 +196,7 @@ static struct arm_idlect1_clk armper_ck = { .parent = &ck_dpll1, .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | RATE_CKCTL | CLOCK_IDLE_CONTROL, - .enable_reg = ARM_IDLECT2, + .enable_reg = (void __iomem *)ARM_IDLECT2, .enable_bit = EN_PERCK, .rate_offset = CKCTL_PERDIV_OFFSET, .recalc = &omap1_ckctl_recalc, @@ -210,7 +210,7 @@ static struct clk arm_gpio_ck = { .name = "arm_gpio_ck", .parent = &ck_dpll1, .flags = CLOCK_IN_OMAP1510, - .enable_reg = ARM_IDLECT2, + .enable_reg = (void __iomem *)ARM_IDLECT2, .enable_bit = EN_GPIOCK, .recalc = &followparent_recalc, .enable = &omap1_clk_enable, @@ -223,7 +223,7 @@ static struct arm_idlect1_clk armxor_ck = { .parent = &ck_ref, .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IDLE_CONTROL, - .enable_reg = ARM_IDLECT2, + .enable_reg = (void __iomem *)ARM_IDLECT2, .enable_bit = EN_XORPCK, .recalc = &followparent_recalc, .enable = &omap1_clk_enable, @@ -238,7 +238,7 @@ static struct arm_idlect1_clk armtim_ck = { .parent = &ck_ref, .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IDLE_CONTROL, - .enable_reg = ARM_IDLECT2, + .enable_reg = (void __iomem *)ARM_IDLECT2, .enable_bit = EN_TIMCK, .recalc = &followparent_recalc, .enable = &omap1_clk_enable, @@ -253,7 +253,7 @@ static struct arm_idlect1_clk armwdt_ck = { .parent = &ck_ref, .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IDLE_CONTROL, - .enable_reg = ARM_IDLECT2, + .enable_reg = (void __iomem *)ARM_IDLECT2, .enable_bit = EN_WDTCK, .recalc = &omap1_watchdog_recalc, .enable = &omap1_clk_enable, @@ -281,7 +281,7 @@ static struct clk dsp_ck = { .parent = &ck_dpll1, .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | RATE_CKCTL, - .enable_reg = ARM_CKCTL, + .enable_reg = (void __iomem *)ARM_CKCTL, .enable_bit = EN_DSPCK, .rate_offset = CKCTL_DSPDIV_OFFSET, .recalc = &omap1_ckctl_recalc, @@ -305,7 +305,7 @@ static struct clk dspper_ck = { .parent = &ck_dpll1, .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | RATE_CKCTL | VIRTUAL_IO_ADDRESS, - .enable_reg = DSP_IDLECT2, + .enable_reg = (void __iomem *)DSP_IDLECT2, .enable_bit = EN_PERCK, .rate_offset = CKCTL_PERDIV_OFFSET, .recalc = &omap1_ckctl_recalc_dsp_domain, @@ -319,7 +319,7 @@ static struct clk dspxor_ck = { .parent = &ck_ref, .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | VIRTUAL_IO_ADDRESS, - .enable_reg = DSP_IDLECT2, + .enable_reg = (void __iomem *)DSP_IDLECT2, .enable_bit = EN_XORPCK, .recalc = &followparent_recalc, .enable = &omap1_clk_enable_dsp_domain, @@ -331,7 +331,7 @@ static struct clk dsptim_ck = { .parent = &ck_ref, .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | VIRTUAL_IO_ADDRESS, - .enable_reg = DSP_IDLECT2, + .enable_reg = (void __iomem *)DSP_IDLECT2, .enable_bit = EN_DSPTIMCK, .recalc = &followparent_recalc, .enable = &omap1_clk_enable_dsp_domain, @@ -383,7 +383,7 @@ static struct clk l3_ocpi_ck = { .name = "l3_ocpi_ck", .parent = &tc_ck.clk, .flags = CLOCK_IN_OMAP16XX, - .enable_reg = ARM_IDLECT3, + .enable_reg = (void __iomem *)ARM_IDLECT3, .enable_bit = EN_OCPI_CK, .recalc = &followparent_recalc, .enable = &omap1_clk_enable, @@ -394,7 +394,7 @@ static struct clk tc1_ck = { .name = "tc1_ck", .parent = &tc_ck.clk, .flags = CLOCK_IN_OMAP16XX, - .enable_reg = ARM_IDLECT3, + .enable_reg = (void __iomem *)ARM_IDLECT3, .enable_bit = EN_TC1_CK, .recalc = &followparent_recalc, .enable = &omap1_clk_enable, @@ -405,7 +405,7 @@ static struct clk tc2_ck = { .name = "tc2_ck", .parent = &tc_ck.clk, .flags = CLOCK_IN_OMAP16XX, - .enable_reg = ARM_IDLECT3, + .enable_reg = (void __iomem *)ARM_IDLECT3, .enable_bit = EN_TC2_CK, .recalc = &followparent_recalc, .enable = &omap1_clk_enable, @@ -438,7 +438,7 @@ static struct arm_idlect1_clk api_ck = { .parent = &tc_ck.clk, .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IDLE_CONTROL, - .enable_reg = ARM_IDLECT2, + .enable_reg = (void __iomem *)ARM_IDLECT2, .enable_bit = EN_APICK, .recalc = &followparent_recalc, .enable = &omap1_clk_enable, @@ -452,7 +452,7 @@ static struct arm_idlect1_clk lb_ck = { .name = "lb_ck", .parent = &tc_ck.clk, .flags = CLOCK_IN_OMAP1510 | CLOCK_IDLE_CONTROL, - .enable_reg = ARM_IDLECT2, + .enable_reg = (void __iomem *)ARM_IDLECT2, .enable_bit = EN_LBCK, .recalc = &followparent_recalc, .enable = &omap1_clk_enable, @@ -483,7 +483,7 @@ static struct clk lcd_ck_16xx = { .name = "lcd_ck", .parent = &ck_dpll1, .flags = CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730 | RATE_CKCTL, - .enable_reg = ARM_IDLECT2, + .enable_reg = (void __iomem *)ARM_IDLECT2, .enable_bit = EN_LCDCK, .rate_offset = CKCTL_LCDDIV_OFFSET, .recalc = &omap1_ckctl_recalc, @@ -497,7 +497,7 @@ static struct arm_idlect1_clk lcd_ck_1510 = { .parent = &ck_dpll1, .flags = CLOCK_IN_OMAP1510 | RATE_CKCTL | CLOCK_IDLE_CONTROL, - .enable_reg = ARM_IDLECT2, + .enable_reg = (void __iomem *)ARM_IDLECT2, .enable_bit = EN_LCDCK, .rate_offset = CKCTL_LCDDIV_OFFSET, .recalc = &omap1_ckctl_recalc, @@ -514,7 +514,7 @@ static struct clk uart1_1510 = { .rate = 12000000, .flags = CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT | ALWAYS_ENABLED | CLOCK_NO_IDLE_PARENT, - .enable_reg = MOD_CONF_CTRL_0, + .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, .enable_bit = 29, /* Chooses between 12MHz and 48MHz */ .set_rate = &omap1_set_uart_rate, .recalc = &omap1_uart_recalc, @@ -530,7 +530,7 @@ static struct uart_clk uart1_16xx = { .rate = 48000000, .flags = CLOCK_IN_OMAP16XX | RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, - .enable_reg = MOD_CONF_CTRL_0, + .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, .enable_bit = 29, .enable = &omap1_clk_enable_uart_functional, .disable = &omap1_clk_disable_uart_functional, @@ -546,7 +546,7 @@ static struct clk uart2_ck = { .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | ENABLE_REG_32BIT | ALWAYS_ENABLED | CLOCK_NO_IDLE_PARENT, - .enable_reg = MOD_CONF_CTRL_0, + .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, .enable_bit = 30, /* Chooses between 12MHz and 48MHz */ .set_rate = &omap1_set_uart_rate, .recalc = &omap1_uart_recalc, @@ -561,7 +561,7 @@ static struct clk uart3_1510 = { .rate = 12000000, .flags = CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT | ALWAYS_ENABLED | CLOCK_NO_IDLE_PARENT, - .enable_reg = MOD_CONF_CTRL_0, + .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, .enable_bit = 31, /* Chooses between 12MHz and 48MHz */ .set_rate = &omap1_set_uart_rate, .recalc = &omap1_uart_recalc, @@ -577,7 +577,7 @@ static struct uart_clk uart3_16xx = { .rate = 48000000, .flags = CLOCK_IN_OMAP16XX | RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, - .enable_reg = MOD_CONF_CTRL_0, + .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, .enable_bit = 31, .enable = &omap1_clk_enable_uart_functional, .disable = &omap1_clk_disable_uart_functional, @@ -591,7 +591,7 @@ static struct clk usb_clko = { /* 6 MHz output on W4_USB_CLKO */ .rate = 6000000, .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | RATE_FIXED | ENABLE_REG_32BIT, - .enable_reg = ULPD_CLOCK_CTRL, + .enable_reg = (void __iomem *)ULPD_CLOCK_CTRL, .enable_bit = USB_MCLK_EN_BIT, .enable = &omap1_clk_enable, .disable = &omap1_clk_disable, @@ -603,7 +603,7 @@ static struct clk usb_hhc_ck1510 = { .rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */ .flags = CLOCK_IN_OMAP1510 | RATE_FIXED | ENABLE_REG_32BIT, - .enable_reg = MOD_CONF_CTRL_0, + .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, .enable_bit = USB_HOST_HHC_UHOST_EN, .enable = &omap1_clk_enable, .disable = &omap1_clk_disable, @@ -616,7 +616,7 @@ static struct clk usb_hhc_ck16xx = { /* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */ .flags = CLOCK_IN_OMAP16XX | RATE_FIXED | ENABLE_REG_32BIT, - .enable_reg = OTG_BASE + 0x08 /* OTG_SYSCON_2 */, + .enable_reg = (void __iomem *)OTG_BASE + 0x08 /* OTG_SYSCON_2 */, .enable_bit = 8 /* UHOST_EN */, .enable = &omap1_clk_enable, .disable = &omap1_clk_disable, @@ -627,7 +627,7 @@ static struct clk usb_dc_ck = { /* Direct from ULPD, no parent */ .rate = 48000000, .flags = CLOCK_IN_OMAP16XX | RATE_FIXED, - .enable_reg = SOFT_REQ_REG, + .enable_reg = (void __iomem *)SOFT_REQ_REG, .enable_bit = 4, .enable = &omap1_clk_enable, .disable = &omap1_clk_disable, @@ -646,7 +646,7 @@ static struct clk mclk_16xx = { .name = "mclk", /* Direct from ULPD, no parent. May be enabled by ext hardware. */ .flags = CLOCK_IN_OMAP16XX, - .enable_reg = COM_CLK_DIV_CTRL_SEL, + .enable_reg = (void __iomem *)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, @@ -668,7 +668,7 @@ static struct clk bclk_16xx = { .name = "bclk", /* Direct from ULPD, no parent. May be enabled by ext hardware. */ .flags = CLOCK_IN_OMAP16XX, - .enable_reg = SWD_CLK_DIV_CTRL_SEL, + .enable_reg = (void __iomem *)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, @@ -684,7 +684,7 @@ static struct clk mmc1_ck = { .rate = 48000000, .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, - .enable_reg = MOD_CONF_CTRL_0, + .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, .enable_bit = 23, .enable = &omap1_clk_enable, .disable = &omap1_clk_disable, @@ -697,7 +697,7 @@ static struct clk mmc2_ck = { .rate = 48000000, .flags = CLOCK_IN_OMAP16XX | RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, - .enable_reg = MOD_CONF_CTRL_0, + .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, .enable_bit = 20, .enable = &omap1_clk_enable, .disable = &omap1_clk_disable, diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c index c4a6d1c4cdf..4320f5a638d 100644 --- a/arch/arm/plat-omap/clock.c +++ b/arch/arm/plat-omap/clock.c @@ -4,12 +4,17 @@ * Copyright (C) 2004 - 2005 Nokia corporation * Written by Tuukka Tikkanen * + * Modified for omap shared clock framework by Tony Lindgren + * * 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. */ -#include +#include +#include #include +#include +#include #include #include #include @@ -22,7 +27,7 @@ LIST_HEAD(clocks); static DECLARE_MUTEX(clocks_sem); -static DEFINE_SPINLOCK(clockfw_lock); +DEFINE_SPINLOCK(clockfw_lock); static struct clk_functions *arch_clock; @@ -50,10 +55,15 @@ EXPORT_SYMBOL(clk_get); int clk_enable(struct clk *clk) { unsigned long flags; - int ret; + int ret = 0; spin_lock_irqsave(&clockfw_lock, flags); - ret = clk->enable(clk); + if (clk->enable) + ret = clk->enable(clk); + else if (arch_clock->clk_enable) + ret = arch_clock->clk_enable(clk); + else + printk(KERN_ERR "Could not enable clock %s\n", clk->name); spin_unlock_irqrestore(&clockfw_lock, flags); return ret; @@ -65,7 +75,12 @@ void clk_disable(struct clk *clk) unsigned long flags; spin_lock_irqsave(&clockfw_lock, flags); - clk->disable(clk); + if (clk->disable) + clk->disable(clk); + else if (arch_clock->clk_disable) + arch_clock->clk_disable(clk); + else + printk(KERN_ERR "Could not disable clock %s\n", clk->name); spin_unlock_irqrestore(&clockfw_lock, flags); } EXPORT_SYMBOL(clk_disable); @@ -192,12 +207,33 @@ EXPORT_SYMBOL(clk_get_parent); * OMAP specific clock functions shared between omap1 and omap2 *-------------------------------------------------------------------------*/ +unsigned int __initdata mpurate; + +/* + * By default we use the rate set by the bootloader. + * You can override this with mpurate= cmdline option. + */ +static int __init omap_clk_setup(char *str) +{ + get_option(&str, &mpurate); + + if (!mpurate) + return 1; + + if (mpurate < 1000) + mpurate *= 1000000; + + return 1; +} +__setup("mpurate=", omap_clk_setup); + /* Used for clocks that always have same value as the parent clock */ -void followparent_recalc(struct clk * clk) +void followparent_recalc(struct clk *clk) { clk->rate = clk->parent->rate; } +/* Propagate rate to children */ void propagate_rate(struct clk * tclk) { struct clk *clkp; diff --git a/include/asm-arm/arch-omap/clock.h b/include/asm-arm/arch-omap/clock.h index 589a097524d..740c297eb11 100644 --- a/include/asm-arm/arch-omap/clock.h +++ b/include/asm-arm/arch-omap/clock.h @@ -22,7 +22,7 @@ struct clk { struct clk *parent; unsigned long rate; __u32 flags; - __u32 enable_reg; + void __iomem *enable_reg; __u8 enable_bit; __u8 rate_offset; __u8 src_offset; @@ -36,6 +36,8 @@ struct clk { }; struct clk_functions { + int (*clk_enable)(struct clk *clk); + void (*clk_disable)(struct clk *clk); int (*clk_use)(struct clk *clk); void (*clk_unuse)(struct clk *clk); long (*clk_round_rate)(struct clk *clk, unsigned long rate); @@ -46,14 +48,17 @@ struct clk_functions { void (*clk_deny_idle)(struct clk *clk); }; -extern spinlock_t clockfw_lock; +extern unsigned int mpurate; extern struct list_head clocks; +extern spinlock_t clockfw_lock; extern int clk_init(struct clk_functions * custom_clocks); extern int clk_register(struct clk *clk); extern void clk_unregister(struct clk *clk); extern void propagate_rate(struct clk *clk); -extern void followparent_recalc(struct clk * clk); +extern void followparent_recalc(struct clk * clk); +extern void clk_allow_idle(struct clk *clk); +extern void clk_deny_idle(struct clk *clk); /* Clock flags */ #define RATE_CKCTL (1 << 0) /* Main fixed ratio clocks */ -- 2.41.1