OMAP3/4 clock: split into per-chip family files
Paul Walmsley [Tue, 23 Feb 2010 05:09:20 +0000 (22:09 -0700)]
clock34xx_data.c now contains data for the OMAP34xx family, the
OMAP36xx family, and the OMAP3517 family, so rename it to
clock3xxx_data.c.  Rename clock34xx.c to clock3xxx.c, and move the
chip family-specific clock functions to clock34xx.c, clock36xx.c, or
clock3517.c, as appropriate.  So now "clock3xxx.*" refers to the OMAP3
superset.

The main goal here is to prepare to compile chip family-specific clock
functions only for kernel builds that target that chip family.  To get to
that point, we also need to add CONFIG_SOC_* options for those other
chip families; that will be done in future patches, planned for 2.6.35.

OMAP4 is also affected by this.  It duplicated the OMAP3 non-CORE DPLL
clkops structure.  The OMAP4 variant of this clkops structure has been
removed, and since there was nothing else currently in clock44xx.c, it
too has been removed -- it can always be added back later when there
is some content for it.  (The OMAP4 clock autogeneration scripts have been
updated accordingly.)

Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Benoît Cousson <b-cousson@ti.com>
Cc: Rajendra Nayak <rnayak@ti.com>
Cc: Ranjith Lohithakshan <ranjithl@ti.com>
Cc: Tony Lindgren <tony@atomide.com>

17 files changed:
arch/arm/mach-omap2/Makefile
arch/arm/mach-omap2/clkt34xx_dpll3m2.c
arch/arm/mach-omap2/clock.c
arch/arm/mach-omap2/clock.h
arch/arm/mach-omap2/clock34xx.c
arch/arm/mach-omap2/clock34xx.h
arch/arm/mach-omap2/clock3517.c [new file with mode: 0644]
arch/arm/mach-omap2/clock3517.h [new file with mode: 0644]
arch/arm/mach-omap2/clock36xx.c [new file with mode: 0644]
arch/arm/mach-omap2/clock36xx.h [new file with mode: 0644]
arch/arm/mach-omap2/clock3xxx.c [new file with mode: 0644]
arch/arm/mach-omap2/clock3xxx.h [new file with mode: 0644]
arch/arm/mach-omap2/clock3xxx_data.c [moved from arch/arm/mach-omap2/clock34xx_data.c with 99% similarity]
arch/arm/mach-omap2/clock44xx.c [deleted file]
arch/arm/mach-omap2/clock44xx.h
arch/arm/mach-omap2/clock44xx_data.c
arch/arm/mach-omap2/io.c

index 3ebd0b6..5f10d32 100644 (file)
@@ -7,22 +7,14 @@ obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o
 
 omap-2-3-common                                = irq.o sdrc.o omap_hwmod.o \
                                          omap_hwmod_common_data.o
-omap-3-4-common                                = dpll3xxx.o
 prcm-common                            = prcm.o powerdomain.o
 clock-common                           = clock.o clock_common_data.o \
                                          clockdomain.o clkt_dpll.o \
                                          clkt_clksel.o
-clock-omap2xxx                         = clkt2xxx_dpllcore.o \
-                                         clkt2xxx_virt_prcm_set.o \
-                                         clkt2xxx_apll.o clkt2xxx_osc.o \
-                                         clkt2xxx_sys.o
-clock-omap3xxx                         = clkt34xx_dpll3m2.o
-
-obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(prcm-common) $(clock-common) \
-                           $(clock-omap2xxx)
-obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(prcm-common) $(clock-common) \
-                           $(omap-3-4-common) $(clock-omap3xxx)
-obj-$(CONFIG_ARCH_OMAP4) += $(omap-3-4-common) $(prcm-common) $(clock-common)
+
+obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(prcm-common)
+obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(prcm-common)
+obj-$(CONFIG_ARCH_OMAP4) += $(prcm-common)
 
 obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
 
@@ -64,14 +56,24 @@ obj-$(CONFIG_ARCH_OMAP3)            += cm.o
 obj-$(CONFIG_ARCH_OMAP4)               += cm4xxx.o
 
 # Clock framework
-obj-$(CONFIG_ARCH_OMAP2)               += clock2xxx.o clock2xxx_data.o
+obj-$(CONFIG_ARCH_OMAP2)               += $(clock-common) clock2xxx.o \
+                                          clock2xxx_data.o clkt2xxx_sys.o \
+                                          clkt2xxx_dpllcore.o \
+                                          clkt2xxx_virt_prcm_set.o \
+                                          clkt2xxx_apll.o clkt2xxx_osc.o
+obj-$(CONFIG_ARCH_OMAP3)               += $(clock-common) clock3xxx.o \
+                                          clock34xx.o clkt34xx_dpll3m2.o \
+                                          clock3517.o clock36xx.o \
+                                          dpll3xxx.o clock3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP4)               += $(clock-common) clock44xx_data.o \
+                                          dpll3xxx.o
+
+# OMAP2 clock rate set data (old "OPP" data)
 obj-$(CONFIG_ARCH_OMAP2420)            += opp2420_data.o
-obj-$(CONFIG_ARCH_OMAP3)               += clock34xx.o clock34xx_data.o
 obj-$(CONFIG_ARCH_OMAP2430)            += opp2430_data.o
-obj-$(CONFIG_ARCH_OMAP4)               += clock44xx.o clock44xx_data.o
 
 # EMU peripherals
-obj-$(CONFIG_OMAP3_EMU)                += emu.o
+obj-$(CONFIG_OMAP3_EMU)                        += emu.o
 
 obj-$(CONFIG_OMAP_MBOX_FWK)            += mailbox_mach.o
 mailbox_mach-objs                      := mailbox.o
@@ -127,7 +129,7 @@ obj-$(CONFIG_MACH_OMAP3_TOUCHBOOK)  += board-omap3touchbook.o \
                                           hsmmc.o
 obj-$(CONFIG_MACH_OMAP_4430SDP)                += board-4430sdp.o
 
-obj-$(CONFIG_MACH_OMAP3517EVM)     += board-am3517evm.o
+obj-$(CONFIG_MACH_OMAP3517EVM)         += board-am3517evm.o
 
 # Platform specific device init code
 obj-y                                  += usb-musb.o
index 8716a01..b2b1e37 100644 (file)
@@ -26,6 +26,7 @@
 #include <plat/sdrc.h>
 
 #include "clock.h"
+#include "clock3xxx.h"
 #include "clock34xx.h"
 #include "sdrc.h"
 
index 9df5937..82b17ef 100644 (file)
@@ -336,6 +336,18 @@ int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
        return omap2_clksel_set_parent(clk, new_parent);
 }
 
+/* OMAP3/4 non-CORE DPLL clkops */
+
+#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
+
+const struct clkops clkops_omap3_noncore_dpll_ops = {
+       .enable         = omap3_noncore_dpll_enable,
+       .disable        = omap3_noncore_dpll_disable,
+};
+
+#endif
+
+
 /*-------------------------------------------------------------------------
  * Omap2 clock reset and init functions
  *-------------------------------------------------------------------------*/
index 0b0f520..f98dd04 100644 (file)
@@ -141,4 +141,6 @@ extern void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table)
 #define omap2_clk_exit_cpufreq_table   0
 #endif
 
+extern const struct clkops clkops_omap3_noncore_dpll_ops;
+
 #endif
index 9039e8c..6febd5f 100644 (file)
@@ -8,7 +8,8 @@
  * Jouni Högander
  *
  * Parts of this code are based on code written by
- * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu
+ * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu,
+ * Russell King
  *
  * 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
 #undef DEBUG
 
 #include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/delay.h>
 #include <linux/clk.h>
 #include <linux/io.h>
-#include <linux/err.h>
 
-#include <plat/cpu.h>
 #include <plat/clock.h>
 
 #include "clock.h"
 #include "clock34xx.h"
-#include "prm.h"
-#include "prm-regbits-34xx.h"
 #include "cm.h"
 #include "cm-regbits-34xx.h"
 
-/*
- * DPLL5_FREQ_FOR_USBHOST: USBHOST and USBTLL are the only clocks
- * that are sourced by DPLL5, and both of these require this clock
- * to be at 120 MHz for proper operation.
- */
-#define DPLL5_FREQ_FOR_USBHOST         120000000
-
-/*
- * In AM35xx IPSS, the {ICK,FCK} enable bits for modules are exported
- * in the same register at a bit offset of 0x8. The EN_ACK for ICK is
- * at an offset of 4 from ICK enable bit.
- */
-#define AM35XX_IPSS_ICK_MASK                   0xF
-#define AM35XX_IPSS_ICK_EN_ACK_OFFSET  0x4
-#define AM35XX_IPSS_ICK_FCK_OFFSET             0x8
-#define AM35XX_IPSS_CLK_IDLEST_VAL             0
-
-/* needed by omap3_core_dpll_m2_set_rate() */
-struct clk *sdrc_ick_p, *arm_fck_p;
-
 /**
  * omap3430es2_clk_ssi_find_idlest - return CM_IDLEST info for SSI
  * @clk: struct clk * being enabled
@@ -149,234 +124,3 @@ const struct clkops clkops_omap3430es2_hsotgusb_wait = {
        .find_idlest    = omap3430es2_clk_hsotgusb_find_idlest,
        .find_companion = omap2_clk_dflt_find_companion,
 };
-
-/**
- * omap36xx_pwrdn_clk_enable_with_hsdiv_restore - enable clocks suffering
- *         from HSDivider PWRDN problem Implements Errata ID: i556.
- * @clk: DPLL output struct clk
- *
- * 3630 only: dpll3_m3_ck, dpll4_m2_ck, dpll4_m3_ck, dpll4_m4_ck,
- * dpll4_m5_ck & dpll4_m6_ck dividers gets loaded with reset
- * valueafter their respective PWRDN bits are set.  Any dummy write
- * (Any other value different from the Read value) to the
- * corresponding CM_CLKSEL register will refresh the dividers.
- */
-static int omap36xx_pwrdn_clk_enable_with_hsdiv_restore(struct clk *clk)
-{
-       u32 dummy_v, orig_v, clksel_shift;
-       int ret;
-
-       /* Clear PWRDN bit of HSDIVIDER */
-       ret = omap2_dflt_clk_enable(clk);
-
-       /* Restore the dividers */
-       if (!ret) {
-               clksel_shift = __ffs(clk->parent->clksel_mask);
-               orig_v = __raw_readl(clk->parent->clksel_reg);
-               dummy_v = orig_v;
-
-               /* Write any other value different from the Read value */
-               dummy_v ^= (1 << clksel_shift);
-               __raw_writel(dummy_v, clk->parent->clksel_reg);
-
-               /* Write the original divider */
-               __raw_writel(orig_v, clk->parent->clksel_reg);
-       }
-
-       return ret;
-}
-
-const struct clkops clkops_omap36xx_pwrdn_with_hsdiv_wait_restore = {
-       .enable         = omap36xx_pwrdn_clk_enable_with_hsdiv_restore,
-       .disable        = omap2_dflt_clk_disable,
-       .find_companion = omap2_clk_dflt_find_companion,
-       .find_idlest    = omap2_clk_dflt_find_idlest,
-};
-
-const struct clkops omap3_clkops_noncore_dpll_ops = {
-       .enable         = omap3_noncore_dpll_enable,
-       .disable        = omap3_noncore_dpll_disable,
-};
-
-/**
- * am35xx_clk_find_idlest - return clock ACK info for AM35XX IPSS
- * @clk: struct clk * being enabled
- * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
- * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
- * @idlest_val: pointer to a u8 to store the CM_IDLEST indicator
- *
- * The interface clocks on AM35xx IPSS reflects the clock idle status
- * in the enable register itsel at a bit offset of 4 from the enable
- * bit. A value of 1 indicates that clock is enabled.
- */
-static void am35xx_clk_find_idlest(struct clk *clk,
-                                           void __iomem **idlest_reg,
-                                           u8 *idlest_bit,
-                                           u8 *idlest_val)
-{
-       *idlest_reg = (__force void __iomem *)(clk->enable_reg);
-       *idlest_bit = clk->enable_bit + AM35XX_IPSS_ICK_EN_ACK_OFFSET;
-       *idlest_val = AM35XX_IPSS_CLK_IDLEST_VAL;
-}
-
-/**
- * am35xx_clk_find_companion - find companion clock to @clk
- * @clk: struct clk * to find the companion clock of
- * @other_reg: void __iomem ** to return the companion clock CM_*CLKEN va in
- * @other_bit: u8 ** to return the companion clock bit shift in
- *
- * Some clocks don't have companion clocks.  For example, modules with
- * only an interface clock (such as HECC) don't have a companion
- * clock.  Right now, this code relies on the hardware exporting a bit
- * in the correct companion register that indicates that the
- * nonexistent 'companion clock' is active.  Future patches will
- * associate this type of code with per-module data structures to
- * avoid this issue, and remove the casts.  No return value.
- */
-static void am35xx_clk_find_companion(struct clk *clk, void __iomem **other_reg,
-                                           u8 *other_bit)
-{
-       *other_reg = (__force void __iomem *)(clk->enable_reg);
-       if (clk->enable_bit & AM35XX_IPSS_ICK_MASK)
-               *other_bit = clk->enable_bit + AM35XX_IPSS_ICK_FCK_OFFSET;
-       else
-               *other_bit = clk->enable_bit - AM35XX_IPSS_ICK_FCK_OFFSET;
-}
-
-const struct clkops clkops_am35xx_ipss_module_wait = {
-       .enable         = omap2_dflt_clk_enable,
-       .disable        = omap2_dflt_clk_disable,
-       .find_idlest    = am35xx_clk_find_idlest,
-       .find_companion = am35xx_clk_find_companion,
-};
-
-/**
- * am35xx_clk_ipss_find_idlest - return CM_IDLEST info for IPSS
- * @clk: struct clk * being enabled
- * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
- * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
- * @idlest_val: pointer to a u8 to store the CM_IDLEST indicator
- *
- * The IPSS target CM_IDLEST bit is at a different shift from the
- * CM_{I,F}CLKEN bit.  Pass back the correct info via @idlest_reg
- * and @idlest_bit.  No return value.
- */
-static void am35xx_clk_ipss_find_idlest(struct clk *clk,
-                                           void __iomem **idlest_reg,
-                                           u8 *idlest_bit,
-                                           u8 *idlest_val)
-{
-       u32 r;
-
-       r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20);
-       *idlest_reg = (__force void __iomem *)r;
-       *idlest_bit = AM35XX_ST_IPSS_SHIFT;
-       *idlest_val = OMAP34XX_CM_IDLEST_VAL;
-}
-
-const struct clkops clkops_am35xx_ipss_wait = {
-       .enable         = omap2_dflt_clk_enable,
-       .disable        = omap2_dflt_clk_disable,
-       .find_idlest    = am35xx_clk_ipss_find_idlest,
-       .find_companion = omap2_clk_dflt_find_companion,
-};
-
-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);
-}
-
-void __init omap3_clk_lock_dpll5(void)
-{
-       struct clk *dpll5_clk;
-       struct clk *dpll5_m2_clk;
-
-       dpll5_clk = clk_get(NULL, "dpll5_ck");
-       clk_set_rate(dpll5_clk, DPLL5_FREQ_FOR_USBHOST);
-       clk_enable(dpll5_clk);
-
-       /* Enable autoidle to allow it to enter low power bypass */
-       omap3_dpll_allow_idle(dpll5_clk);
-
-       /* Program dpll5_m2_clk divider for no division */
-       dpll5_m2_clk = clk_get(NULL, "dpll5_m2_ck");
-       clk_enable(dpll5_m2_clk);
-       clk_set_rate(dpll5_m2_clk, DPLL5_FREQ_FOR_USBHOST);
-
-       clk_disable(dpll5_m2_clk);
-       clk_disable(dpll5_clk);
-       return;
-}
-
-/* Common clock code */
-
-/* REVISIT: Move this init stuff out into clock.c */
-
-/*
- * Switch the MPU rate if specified on cmdline.
- * We cannot do this early until cmdline is parsed.
- */
-static int __init omap3xxx_clk_arch_init(void)
-{
-       struct clk *osc_sys_ck, *dpll1_ck, *arm_fck, *core_ck;
-       unsigned long osc_sys_rate;
-       bool err = 0;
-
-       if (!cpu_is_omap34xx())
-               return 0;
-
-       if (!mpurate)
-               return -EINVAL;
-
-       /* XXX test these for success */
-       dpll1_ck = clk_get(NULL, "dpll1_ck");
-       if (WARN(IS_ERR(dpll1_ck), "Failed to get dpll1_ck.\n"))
-               err = 1;
-
-       arm_fck = clk_get(NULL, "arm_fck");
-       if (WARN(IS_ERR(arm_fck), "Failed to get arm_fck.\n"))
-               err = 1;
-
-       core_ck = clk_get(NULL, "core_ck");
-       if (WARN(IS_ERR(core_ck), "Failed to get core_ck.\n"))
-               err = 1;
-
-       osc_sys_ck = clk_get(NULL, "osc_sys_ck");
-       if (WARN(IS_ERR(osc_sys_ck), "Failed to get osc_sys_ck.\n"))
-               err = 1;
-
-       if (err)
-               return -ENOENT;
-
-       /* REVISIT: not yet ready for 343x */
-       if (clk_set_rate(dpll1_ck, mpurate))
-               printk(KERN_ERR "*** Unable to set MPU rate\n");
-
-       recalculate_root_clocks();
-
-       osc_sys_rate = clk_get_rate(osc_sys_ck);
-
-       pr_info("Switched to new clocking rate (Crystal/Core/MPU): "
-               "%ld.%01ld/%ld/%ld MHz\n",
-               (osc_sys_rate / 1000000),
-               ((osc_sys_rate / 100000) % 10),
-               (clk_get_rate(core_ck) / 1000000),
-               (clk_get_rate(arm_fck) / 1000000));
-
-       calibrate_delay();
-
-       return 0;
-}
-arch_initcall(omap3xxx_clk_arch_init);
-
-
index 720091d..628e8de 100644 (file)
@@ -1,32 +1,15 @@
 /*
- * OMAP3 clock function prototypes and macros
+ * OMAP34xx clock function prototypes and macros
  *
- * Copyright (C) 2007-2009 Texas Instruments, Inc.
- * Copyright (C) 2007-2009 Nokia Corporation
+ * Copyright (C) 2007-2010 Texas Instruments, Inc.
+ * Copyright (C) 2007-2010 Nokia Corporation
  */
 
-#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK_34XX_H
-#define __ARCH_ARM_MACH_OMAP2_CLOCK_34XX_H
+#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK34XX_H
+#define __ARCH_ARM_MACH_OMAP2_CLOCK34XX_H
 
-int omap3xxx_clk_init(void);
-int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate);
-int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate);
-void omap3_clk_lock_dpll5(void);
-
-extern struct clk *sdrc_ick_p;
-extern struct clk *arm_fck_p;
-
-/* OMAP34xx-specific clkops */
 extern const struct clkops clkops_omap3430es2_ssi_wait;
 extern const struct clkops clkops_omap3430es2_hsotgusb_wait;
 extern const struct clkops clkops_omap3430es2_dss_usbhost_wait;
-extern const struct clkops omap3_clkops_noncore_dpll_ops;
-
-/* AM35xx-specific clkops */
-extern const struct clkops clkops_am35xx_ipss_module_wait;
-extern const struct clkops clkops_am35xx_ipss_wait;
-
-/* OMAP36xx-specific clkops */
-extern const struct clkops clkops_omap36xx_pwrdn_with_hsdiv_wait_restore;
 
 #endif
diff --git a/arch/arm/mach-omap2/clock3517.c b/arch/arm/mach-omap2/clock3517.c
new file mode 100644 (file)
index 0000000..b496a93
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * OMAP3517/3505-specific clock framework functions
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Copyright (C) 2010 Nokia Corporation
+ *
+ * Ranjith Lohithakshan
+ * Paul Walmsley
+ *
+ * Parts of this code are based on code written by
+ * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu,
+ * Russell King
+ *
+ * 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/kernel.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+
+#include "clock.h"
+#include "clock3517.h"
+#include "cm.h"
+#include "cm-regbits-34xx.h"
+
+/*
+ * In AM35xx IPSS, the {ICK,FCK} enable bits for modules are exported
+ * in the same register at a bit offset of 0x8. The EN_ACK for ICK is
+ * at an offset of 4 from ICK enable bit.
+ */
+#define AM35XX_IPSS_ICK_MASK                   0xF
+#define AM35XX_IPSS_ICK_EN_ACK_OFFSET          0x4
+#define AM35XX_IPSS_ICK_FCK_OFFSET             0x8
+#define AM35XX_IPSS_CLK_IDLEST_VAL             0
+
+/**
+ * am35xx_clk_find_idlest - return clock ACK info for AM35XX IPSS
+ * @clk: struct clk * being enabled
+ * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
+ * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
+ * @idlest_val: pointer to a u8 to store the CM_IDLEST indicator
+ *
+ * The interface clocks on AM35xx IPSS reflects the clock idle status
+ * in the enable register itsel at a bit offset of 4 from the enable
+ * bit. A value of 1 indicates that clock is enabled.
+ */
+static void am35xx_clk_find_idlest(struct clk *clk,
+                                           void __iomem **idlest_reg,
+                                           u8 *idlest_bit,
+                                           u8 *idlest_val)
+{
+       *idlest_reg = (__force void __iomem *)(clk->enable_reg);
+       *idlest_bit = clk->enable_bit + AM35XX_IPSS_ICK_EN_ACK_OFFSET;
+       *idlest_val = AM35XX_IPSS_CLK_IDLEST_VAL;
+}
+
+/**
+ * am35xx_clk_find_companion - find companion clock to @clk
+ * @clk: struct clk * to find the companion clock of
+ * @other_reg: void __iomem ** to return the companion clock CM_*CLKEN va in
+ * @other_bit: u8 ** to return the companion clock bit shift in
+ *
+ * Some clocks don't have companion clocks.  For example, modules with
+ * only an interface clock (such as HECC) don't have a companion
+ * clock.  Right now, this code relies on the hardware exporting a bit
+ * in the correct companion register that indicates that the
+ * nonexistent 'companion clock' is active.  Future patches will
+ * associate this type of code with per-module data structures to
+ * avoid this issue, and remove the casts.  No return value.
+ */
+static void am35xx_clk_find_companion(struct clk *clk, void __iomem **other_reg,
+                                           u8 *other_bit)
+{
+       *other_reg = (__force void __iomem *)(clk->enable_reg);
+       if (clk->enable_bit & AM35XX_IPSS_ICK_MASK)
+               *other_bit = clk->enable_bit + AM35XX_IPSS_ICK_FCK_OFFSET;
+       else
+               *other_bit = clk->enable_bit - AM35XX_IPSS_ICK_FCK_OFFSET;
+}
+
+const struct clkops clkops_am35xx_ipss_module_wait = {
+       .enable         = omap2_dflt_clk_enable,
+       .disable        = omap2_dflt_clk_disable,
+       .find_idlest    = am35xx_clk_find_idlest,
+       .find_companion = am35xx_clk_find_companion,
+};
+
+/**
+ * am35xx_clk_ipss_find_idlest - return CM_IDLEST info for IPSS
+ * @clk: struct clk * being enabled
+ * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
+ * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
+ * @idlest_val: pointer to a u8 to store the CM_IDLEST indicator
+ *
+ * The IPSS target CM_IDLEST bit is at a different shift from the
+ * CM_{I,F}CLKEN bit.  Pass back the correct info via @idlest_reg
+ * and @idlest_bit.  No return value.
+ */
+static void am35xx_clk_ipss_find_idlest(struct clk *clk,
+                                           void __iomem **idlest_reg,
+                                           u8 *idlest_bit,
+                                           u8 *idlest_val)
+{
+       u32 r;
+
+       r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20);
+       *idlest_reg = (__force void __iomem *)r;
+       *idlest_bit = AM35XX_ST_IPSS_SHIFT;
+       *idlest_val = OMAP34XX_CM_IDLEST_VAL;
+}
+
+const struct clkops clkops_am35xx_ipss_wait = {
+       .enable         = omap2_dflt_clk_enable,
+       .disable        = omap2_dflt_clk_disable,
+       .find_idlest    = am35xx_clk_ipss_find_idlest,
+       .find_companion = omap2_clk_dflt_find_companion,
+};
+
+
diff --git a/arch/arm/mach-omap2/clock3517.h b/arch/arm/mach-omap2/clock3517.h
new file mode 100644 (file)
index 0000000..ca5e5a6
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * OMAP3517/3505 clock function prototypes and macros
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Copyright (C) 2010 Nokia Corporation
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK3517_H
+#define __ARCH_ARM_MACH_OMAP2_CLOCK3517_H
+
+extern const struct clkops clkops_am35xx_ipss_module_wait;
+extern const struct clkops clkops_am35xx_ipss_wait;
+
+#endif
diff --git a/arch/arm/mach-omap2/clock36xx.c b/arch/arm/mach-omap2/clock36xx.c
new file mode 100644 (file)
index 0000000..0c5e25e
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * OMAP36xx-specific clkops
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Copyright (C) 2010 Nokia Corporation
+ *
+ * Mike Turquette
+ * Vijaykumar GN
+ * Paul Walmsley
+ *
+ * Parts of this code are based on code written by
+ * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu,
+ * Russell King
+ *
+ * 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/kernel.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+
+#include "clock.h"
+#include "clock36xx.h"
+
+
+/**
+ * omap36xx_pwrdn_clk_enable_with_hsdiv_restore - enable clocks suffering
+ *         from HSDivider PWRDN problem Implements Errata ID: i556.
+ * @clk: DPLL output struct clk
+ *
+ * 3630 only: dpll3_m3_ck, dpll4_m2_ck, dpll4_m3_ck, dpll4_m4_ck,
+ * dpll4_m5_ck & dpll4_m6_ck dividers gets loaded with reset
+ * valueafter their respective PWRDN bits are set.  Any dummy write
+ * (Any other value different from the Read value) to the
+ * corresponding CM_CLKSEL register will refresh the dividers.
+ */
+static int omap36xx_pwrdn_clk_enable_with_hsdiv_restore(struct clk *clk)
+{
+       u32 dummy_v, orig_v, clksel_shift;
+       int ret;
+
+       /* Clear PWRDN bit of HSDIVIDER */
+       ret = omap2_dflt_clk_enable(clk);
+
+       /* Restore the dividers */
+       if (!ret) {
+               clksel_shift = __ffs(clk->parent->clksel_mask);
+               orig_v = __raw_readl(clk->parent->clksel_reg);
+               dummy_v = orig_v;
+
+               /* Write any other value different from the Read value */
+               dummy_v ^= (1 << clksel_shift);
+               __raw_writel(dummy_v, clk->parent->clksel_reg);
+
+               /* Write the original divider */
+               __raw_writel(orig_v, clk->parent->clksel_reg);
+       }
+
+       return ret;
+}
+
+const struct clkops clkops_omap36xx_pwrdn_with_hsdiv_wait_restore = {
+       .enable         = omap36xx_pwrdn_clk_enable_with_hsdiv_restore,
+       .disable        = omap2_dflt_clk_disable,
+       .find_companion = omap2_clk_dflt_find_companion,
+       .find_idlest    = omap2_clk_dflt_find_idlest,
+};
diff --git a/arch/arm/mach-omap2/clock36xx.h b/arch/arm/mach-omap2/clock36xx.h
new file mode 100644 (file)
index 0000000..a7dee5b
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ * OMAP36xx clock function prototypes and macros
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Copyright (C) 2010 Nokia Corporation
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK36XX_H
+#define __ARCH_ARM_MACH_OMAP2_CLOCK36XX_H
+
+extern const struct clkops clkops_omap36xx_pwrdn_with_hsdiv_wait_restore;
+
+#endif
diff --git a/arch/arm/mach-omap2/clock3xxx.c b/arch/arm/mach-omap2/clock3xxx.c
new file mode 100644 (file)
index 0000000..d142457
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * OMAP3-specific clock framework functions
+ *
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Copyright (C) 2007-2010 Nokia Corporation
+ *
+ * Paul Walmsley
+ * Jouni Högander
+ *
+ * Parts of this code are based on code written by
+ * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu
+ *
+ * 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/kernel.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/err.h>
+
+#include <plat/cpu.h>
+#include <plat/clock.h>
+
+#include "clock.h"
+#include "clock3xxx.h"
+#include "prm.h"
+#include "prm-regbits-34xx.h"
+#include "cm.h"
+#include "cm-regbits-34xx.h"
+
+/*
+ * DPLL5_FREQ_FOR_USBHOST: USBHOST and USBTLL are the only clocks
+ * that are sourced by DPLL5, and both of these require this clock
+ * to be at 120 MHz for proper operation.
+ */
+#define DPLL5_FREQ_FOR_USBHOST         120000000
+
+/* needed by omap3_core_dpll_m2_set_rate() */
+struct clk *sdrc_ick_p, *arm_fck_p;
+
+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) {
+               pr_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);
+}
+
+void __init omap3_clk_lock_dpll5(void)
+{
+       struct clk *dpll5_clk;
+       struct clk *dpll5_m2_clk;
+
+       dpll5_clk = clk_get(NULL, "dpll5_ck");
+       clk_set_rate(dpll5_clk, DPLL5_FREQ_FOR_USBHOST);
+       clk_enable(dpll5_clk);
+
+       /* Enable autoidle to allow it to enter low power bypass */
+       omap3_dpll_allow_idle(dpll5_clk);
+
+       /* Program dpll5_m2_clk divider for no division */
+       dpll5_m2_clk = clk_get(NULL, "dpll5_m2_ck");
+       clk_enable(dpll5_m2_clk);
+       clk_set_rate(dpll5_m2_clk, DPLL5_FREQ_FOR_USBHOST);
+
+       clk_disable(dpll5_m2_clk);
+       clk_disable(dpll5_clk);
+       return;
+}
+
+/* Common clock code */
+
+/* REVISIT: Move this init stuff out into clock.c */
+
+/*
+ * Switch the MPU rate if specified on cmdline.
+ * We cannot do this early until cmdline is parsed.
+ */
+static int __init omap3xxx_clk_arch_init(void)
+{
+       struct clk *osc_sys_ck, *dpll1_ck, *arm_fck, *core_ck;
+       unsigned long osc_sys_rate;
+       bool err = 0;
+
+       if (!cpu_is_omap34xx())
+               return 0;
+
+       if (!mpurate)
+               return -EINVAL;
+
+       /* XXX test these for success */
+       dpll1_ck = clk_get(NULL, "dpll1_ck");
+       if (WARN(IS_ERR(dpll1_ck), "Failed to get dpll1_ck.\n"))
+               err = 1;
+
+       arm_fck = clk_get(NULL, "arm_fck");
+       if (WARN(IS_ERR(arm_fck), "Failed to get arm_fck.\n"))
+               err = 1;
+
+       core_ck = clk_get(NULL, "core_ck");
+       if (WARN(IS_ERR(core_ck), "Failed to get core_ck.\n"))
+               err = 1;
+
+       osc_sys_ck = clk_get(NULL, "osc_sys_ck");
+       if (WARN(IS_ERR(osc_sys_ck), "Failed to get osc_sys_ck.\n"))
+               err = 1;
+
+       if (err)
+               return -ENOENT;
+
+       /* REVISIT: not yet ready for 343x */
+       if (clk_set_rate(dpll1_ck, mpurate))
+               printk(KERN_ERR "*** Unable to set MPU rate\n");
+
+       recalculate_root_clocks();
+
+       osc_sys_rate = clk_get_rate(osc_sys_ck);
+
+       pr_info("Switched to new clocking rate (Crystal/Core/MPU): "
+               "%ld.%01ld/%ld/%ld MHz\n",
+               (osc_sys_rate / 1000000),
+               ((osc_sys_rate / 100000) % 10),
+               (clk_get_rate(core_ck) / 1000000),
+               (clk_get_rate(arm_fck) / 1000000));
+
+       calibrate_delay();
+
+       return 0;
+}
+arch_initcall(omap3xxx_clk_arch_init);
+
+
diff --git a/arch/arm/mach-omap2/clock3xxx.h b/arch/arm/mach-omap2/clock3xxx.h
new file mode 100644 (file)
index 0000000..8bbeeaf
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * OMAP3-common clock function prototypes and macros
+ *
+ * Copyright (C) 2007-2010 Texas Instruments, Inc.
+ * Copyright (C) 2007-2010 Nokia Corporation
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK3XXX_H
+#define __ARCH_ARM_MACH_OMAP2_CLOCK3XXX_H
+
+int omap3xxx_clk_init(void);
+int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate);
+int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate);
+void omap3_clk_lock_dpll5(void);
+
+extern struct clk *sdrc_ick_p;
+extern struct clk *arm_fck_p;
+
+extern const struct clkops clkops_noncore_dpll_ops;
+
+#endif
similarity index 99%
rename from arch/arm/mach-omap2/clock34xx_data.c
rename to arch/arm/mach-omap2/clock3xxx_data.c
index 995d5d4..f237902 100644 (file)
 #include <plat/clkdev_omap.h>
 
 #include "clock.h"
+#include "clock3xxx.h"
 #include "clock34xx.h"
+#include "clock36xx.h"
+#include "clock3517.h"
+
 #include "cm.h"
 #include "cm-regbits-34xx.h"
 #include "prm.h"
@@ -374,7 +378,7 @@ static struct dpll_data dpll2_dd = {
 
 static struct clk dpll2_ck = {
        .name           = "dpll2_ck",
-       .ops            = &omap3_clkops_noncore_dpll_ops,
+       .ops            = &clkops_omap3_noncore_dpll_ops,
        .parent         = &sys_ck,
        .dpll_data      = &dpll2_dd,
        .round_rate     = &omap2_dpll_round_rate,
@@ -615,7 +619,7 @@ static struct dpll_data dpll4_dd_3630 __initdata = {
 
 static struct clk dpll4_ck = {
        .name           = "dpll4_ck",
-       .ops            = &omap3_clkops_noncore_dpll_ops,
+       .ops            = &clkops_omap3_noncore_dpll_ops,
        .parent         = &sys_ck,
        .dpll_data      = &dpll4_dd,
        .round_rate     = &omap2_dpll_round_rate,
@@ -1023,7 +1027,7 @@ static struct dpll_data dpll5_dd = {
 
 static struct clk dpll5_ck = {
        .name           = "dpll5_ck",
-       .ops            = &omap3_clkops_noncore_dpll_ops,
+       .ops            = &clkops_omap3_noncore_dpll_ops,
        .parent         = &sys_ck,
        .dpll_data      = &dpll5_dd,
        .round_rate     = &omap2_dpll_round_rate,
@@ -3567,10 +3571,12 @@ int __init omap3xxx_clk_init(void)
 
        clk_init(&omap2_clk_functions);
 
-       for (c = omap3xxx_clks; c < omap3xxx_clks + ARRAY_SIZE(omap3xxx_clks); c++)
+       for (c = omap3xxx_clks; c < omap3xxx_clks + ARRAY_SIZE(omap3xxx_clks);
+            c++)
                clk_preinit(c->lk.clk);
 
-       for (c = omap3xxx_clks; c < omap3xxx_clks + ARRAY_SIZE(omap3xxx_clks); c++)
+       for (c = omap3xxx_clks; c < omap3xxx_clks + ARRAY_SIZE(omap3xxx_clks);
+            c++)
                if (c->cpu & cpu_clkflg) {
                        clkdev_add(&c->lk);
                        clk_register(c->lk.clk);
diff --git a/arch/arm/mach-omap2/clock44xx.c b/arch/arm/mach-omap2/clock44xx.c
deleted file mode 100644 (file)
index 84ee6b0..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * OMAP4-specific clock framework functions
- *
- * Copyright (C) 2009 Texas Instruments, Inc.
- *
- * Rajendra Nayak (rnayak@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.
- */
-
-#include <linux/errno.h>
-#include "clock.h"
-
-const struct clkops omap4_clkops_noncore_dpll_ops = {
-       .enable         = &omap3_noncore_dpll_enable,
-       .disable        = &omap3_noncore_dpll_disable,
-};
index 0c73972..6be1095 100644 (file)
@@ -5,8 +5,8 @@
  * Copyright (C) 2010 Nokia Corporation
  */
 
-#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK_44XX_H
-#define __ARCH_ARM_MACH_OMAP2_CLOCK_44XX_H
+#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK44XX_H
+#define __ARCH_ARM_MACH_OMAP2_CLOCK44XX_H
 
 /*
  * XXX Missing values for the OMAP4 DPLL_USB
@@ -17,6 +17,4 @@
 
 int omap4xxx_clk_init(void);
 
-extern const struct clkops omap4_clkops_noncore_dpll_ops;
-
 #endif
index 8c7ab76..022f1a7 100644 (file)
@@ -277,7 +277,7 @@ static struct clk dpll_abe_ck = {
        .parent         = &abe_dpll_refclk_mux_ck,
        .dpll_data      = &dpll_abe_dd,
        .init           = &omap2_init_dpll_parent,
-       .ops            = &omap4_clkops_noncore_dpll_ops,
+       .ops            = &clkops_omap3_noncore_dpll_ops,
        .recalc         = &omap3_dpll_recalc,
        .round_rate     = &omap2_dpll_round_rate,
        .set_rate       = &omap3_noncore_dpll_set_rate,
@@ -644,7 +644,7 @@ static struct clk dpll_iva_ck = {
        .parent         = &dpll_sys_ref_clk,
        .dpll_data      = &dpll_iva_dd,
        .init           = &omap2_init_dpll_parent,
-       .ops            = &omap4_clkops_noncore_dpll_ops,
+       .ops            = &clkops_omap3_noncore_dpll_ops,
        .recalc         = &omap3_dpll_recalc,
        .round_rate     = &omap2_dpll_round_rate,
        .set_rate       = &omap3_noncore_dpll_set_rate,
@@ -704,7 +704,7 @@ static struct clk dpll_mpu_ck = {
        .parent         = &dpll_sys_ref_clk,
        .dpll_data      = &dpll_mpu_dd,
        .init           = &omap2_init_dpll_parent,
-       .ops            = &omap4_clkops_noncore_dpll_ops,
+       .ops            = &clkops_omap3_noncore_dpll_ops,
        .recalc         = &omap3_dpll_recalc,
        .round_rate     = &omap2_dpll_round_rate,
        .set_rate       = &omap3_noncore_dpll_set_rate,
@@ -776,7 +776,7 @@ static struct clk dpll_per_ck = {
        .parent         = &dpll_sys_ref_clk,
        .dpll_data      = &dpll_per_dd,
        .init           = &omap2_init_dpll_parent,
-       .ops            = &omap4_clkops_noncore_dpll_ops,
+       .ops            = &clkops_omap3_noncore_dpll_ops,
        .recalc         = &omap3_dpll_recalc,
        .round_rate     = &omap2_dpll_round_rate,
        .set_rate       = &omap3_noncore_dpll_set_rate,
@@ -891,7 +891,7 @@ static struct clk dpll_unipro_ck = {
        .parent         = &dpll_sys_ref_clk,
        .dpll_data      = &dpll_unipro_dd,
        .init           = &omap2_init_dpll_parent,
-       .ops            = &omap4_clkops_noncore_dpll_ops,
+       .ops            = &clkops_omap3_noncore_dpll_ops,
        .recalc         = &omap3_dpll_recalc,
        .round_rate     = &omap2_dpll_round_rate,
        .set_rate       = &omap3_noncore_dpll_set_rate,
@@ -947,7 +947,7 @@ static struct clk dpll_usb_ck = {
        .parent         = &dpll_sys_ref_clk,
        .dpll_data      = &dpll_usb_dd,
        .init           = &omap2_init_dpll_parent,
-       .ops            = &omap4_clkops_noncore_dpll_ops,
+       .ops            = &clkops_omap3_noncore_dpll_ops,
        .recalc         = &omap3_dpll_recalc,
        .round_rate     = &omap2_dpll_round_rate,
        .set_rate       = &omap3_noncore_dpll_set_rate,
index 5a3d6f9..2c51854 100644 (file)
@@ -36,7 +36,7 @@
 #include <plat/vram.h>
 
 #include "clock2xxx.h"
-#include "clock34xx.h"
+#include "clock3xxx.h"
 #include "clock44xx.h"
 
 #include <plat/omap-pm.h>