]> git.karo-electronics.de Git - mv-sheeva.git/commitdiff
Merge branch 'for_2.6.36' of git://git.pwsan.com/linux-2.6 into omap-for-linus
authorTony Lindgren <tony@atomide.com>
Wed, 4 Aug 2010 05:46:24 +0000 (08:46 +0300)
committerTony Lindgren <tony@atomide.com>
Wed, 4 Aug 2010 05:46:24 +0000 (08:46 +0300)
24 files changed:
arch/arm/mach-omap1/Kconfig
arch/arm/mach-omap1/clock.c
arch/arm/mach-omap1/clock.h
arch/arm/mach-omap1/clock_data.c
arch/arm/mach-omap2/Makefile
arch/arm/mach-omap2/clock3xxx_data.c
arch/arm/mach-omap2/cm.c
arch/arm/mach-omap2/io.c
arch/arm/mach-omap2/omap_hwmod.c
arch/arm/mach-omap2/omap_hwmod_2420_data.c
arch/arm/mach-omap2/omap_hwmod_2430_data.c
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
arch/arm/mach-omap2/omap_hwmod_common_data.c
arch/arm/mach-omap2/omap_hwmod_common_data.h
arch/arm/mach-omap2/pm.c [new file with mode: 0644]
arch/arm/plat-omap/Makefile
arch/arm/plat-omap/i2c.c
arch/arm/plat-omap/include/plat/clock.h
arch/arm/plat-omap/include/plat/common.h
arch/arm/plat-omap/include/plat/omap-pm.h
arch/arm/plat-omap/include/plat/omap_device.h
arch/arm/plat-omap/include/plat/omap_hwmod.h
arch/arm/plat-omap/omap-pm-noop.c
arch/arm/plat-omap/omap_device.c

index c911cdbf886f3cdd6779e4429f6031de2ca9785b..3b02d3b944af401cbe3f41918a45fec3a982b266 100644 (file)
@@ -228,6 +228,12 @@ config OMAP_ARM_120MHZ
        help
           Enable 120MHz clock for OMAP CPU. If unsure, say N.
 
+config OMAP_ARM_96MHZ
+       bool "OMAP ARM 96 MHz CPU"
+       depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850)
+       help
+          Enable 96MHz clock for OMAP CPU. If unsure, say N.
+
 config OMAP_ARM_60MHZ
        bool "OMAP ARM 60 MHz CPU"
        depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850)
index 6bbb1b8b82947776845bc4e7f9ece576995a42d4..b8c7fb9d792108adbccb8b342083c7551830924f 100644 (file)
@@ -11,7 +11,6 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/errno.h>
@@ -34,9 +33,9 @@
 __u32 arm_idlect1_mask;
 struct clk *api_ck_p, *ck_dpll1_p, *ck_ref_p;
 
-/*-------------------------------------------------------------------------
+/*
  * Omap1 specific clock functions
- *-------------------------------------------------------------------------*/
+ */
 
 unsigned long omap1_uart_recalc(struct clk *clk)
 {
@@ -523,7 +522,8 @@ const struct clkops clkops_dspck = {
        .disable        = omap1_clk_disable_dsp_domain,
 };
 
-static int omap1_clk_enable_uart_functional(struct clk *clk)
+/* XXX SYSC register handling does not belong in the clock framework */
+static int omap1_clk_enable_uart_functional_16xx(struct clk *clk)
 {
        int ret;
        struct uart_clk *uclk;
@@ -539,7 +539,8 @@ static int omap1_clk_enable_uart_functional(struct clk *clk)
        return ret;
 }
 
-static void omap1_clk_disable_uart_functional(struct clk *clk)
+/* XXX SYSC register handling does not belong in the clock framework */
+static void omap1_clk_disable_uart_functional_16xx(struct clk *clk)
 {
        struct uart_clk *uclk;
 
@@ -550,9 +551,10 @@ static void omap1_clk_disable_uart_functional(struct clk *clk)
        omap1_clk_disable_generic(clk);
 }
 
-const struct clkops clkops_uart = {
-       .enable         = omap1_clk_enable_uart_functional,
-       .disable        = omap1_clk_disable_uart_functional,
+/* XXX SYSC register handling does not belong in the clock framework */
+const struct clkops clkops_uart_16xx = {
+       .enable         = omap1_clk_enable_uart_functional_16xx,
+       .disable        = omap1_clk_disable_uart_functional_16xx,
 };
 
 long omap1_clk_round_rate(struct clk *clk, unsigned long rate)
@@ -572,9 +574,9 @@ int omap1_clk_set_rate(struct clk *clk, unsigned long rate)
        return ret;
 }
 
-/*-------------------------------------------------------------------------
+/*
  * Omap1 clock reset and init functions
- *-------------------------------------------------------------------------*/
+ */
 
 #ifdef CONFIG_OMAP_RESET_CLOCKS
 
index 75d0d7d90bff6b08fbd6e5d6ff8e8496a5680d96..eaf09efb91caec613eeb73e961e7fbd77a93cf21 100644 (file)
@@ -107,7 +107,7 @@ extern struct clk *api_ck_p, *ck_dpll1_p, *ck_ref_p;
 
 extern const struct clkops clkops_dspck;
 extern const struct clkops clkops_dummy;
-extern const struct clkops clkops_uart;
+extern const struct clkops clkops_uart_16xx;
 extern const struct clkops clkops_generic;
 
 #endif
index 9240bc1026a3d24b622f1144d100200abd4ed9a0..af54114b8f08660c447a35fbc2d4fbbb2482df69 100644 (file)
@@ -8,6 +8,10 @@
  * 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.
+ *
+ * To do:
+ * - Clocks that are only available on some chips should be marked with the
+ *   chips that they are present on.
  */
 
 #include <linux/kernel.h>
 
 #include "clock.h"
 
-/*------------------------------------------------------------------------
+/* Some ARM_IDLECT1 bit shifts - used in struct arm_idlect1_clk */
+#define IDL_CLKOUT_ARM_SHIFT                   12
+#define IDLTIM_ARM_SHIFT                       9
+#define IDLAPI_ARM_SHIFT                       8
+#define IDLIF_ARM_SHIFT                                6
+#define IDLLB_ARM_SHIFT                                4       /* undocumented? */
+#define OMAP1510_IDLLCD_ARM_SHIFT              3       /* undocumented? */
+#define IDLPER_ARM_SHIFT                       2
+#define IDLXORP_ARM_SHIFT                      1
+#define IDLWDT_ARM_SHIFT                       0
+
+/* Some MOD_CONF_CTRL_0 bit shifts - used in struct clk.enable_bit */
+#define CONF_MOD_UART3_CLK_MODE_R              31
+#define CONF_MOD_UART2_CLK_MODE_R              30
+#define CONF_MOD_UART1_CLK_MODE_R              29
+#define CONF_MOD_MMC_SD_CLK_REQ_R              23
+#define CONF_MOD_MCBSP3_AUXON                  20
+
+/* Some MOD_CONF_CTRL_1 bit shifts - used in struct clk.enable_bit */
+#define CONF_MOD_SOSSI_CLK_EN_R                        16
+
+/* Some OTG_SYSCON_2-specific bit fields */
+#define OTG_SYSCON_2_UHOST_EN_SHIFT            8
+
+/* Some SOFT_REQ_REG bit fields - used in struct clk.enable_bit */
+#define SOFT_MMC2_DPLL_REQ_SHIFT       13
+#define SOFT_MMC_DPLL_REQ_SHIFT                12
+#define SOFT_UART3_DPLL_REQ_SHIFT      11
+#define SOFT_UART2_DPLL_REQ_SHIFT      10
+#define SOFT_UART1_DPLL_REQ_SHIFT      9
+#define SOFT_USB_OTG_DPLL_REQ_SHIFT    8
+#define SOFT_CAM_DPLL_REQ_SHIFT                7
+#define SOFT_COM_MCKO_REQ_SHIFT                6
+#define SOFT_PERIPH_REQ_SHIFT          5       /* sys_ck gate for UART2 ? */
+#define USB_REQ_EN_SHIFT               4
+#define SOFT_USB_REQ_SHIFT             3       /* sys_ck gate for USB host? */
+#define SOFT_SDW_REQ_SHIFT             2       /* sys_ck gate for Bluetooth? */
+#define SOFT_COM_REQ_SHIFT             1       /* sys_ck gate for com proc? */
+#define SOFT_DPLL_REQ_SHIFT            0
+
+/*
  * Omap1 clocks
- *-------------------------------------------------------------------------*/
+ */
 
 static struct clk ck_ref = {
        .name           = "ck_ref",
@@ -54,7 +98,7 @@ static struct arm_idlect1_clk ck_dpll1out = {
                .enable_bit     = EN_CKOUT_ARM,
                .recalc         = &followparent_recalc,
        },
-       .idlect_shift   = 12,
+       .idlect_shift   = IDL_CLKOUT_ARM_SHIFT,
 };
 
 static struct clk sossi_ck = {
@@ -63,7 +107,7 @@ static struct clk sossi_ck = {
        .parent         = &ck_dpll1out.clk,
        .flags          = CLOCK_NO_IDLE_PARENT | ENABLE_REG_32BIT,
        .enable_reg     = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_1),
-       .enable_bit     = 16,
+       .enable_bit     = CONF_MOD_SOSSI_CLK_EN_R,
        .recalc         = &omap1_sossi_recalc,
        .set_rate       = &omap1_set_sossi_rate,
 };
@@ -91,7 +135,7 @@ static struct arm_idlect1_clk armper_ck = {
                .round_rate     = omap1_clk_round_rate_ckctl_arm,
                .set_rate       = omap1_clk_set_rate_ckctl_arm,
        },
-       .idlect_shift   = 2,
+       .idlect_shift   = IDLPER_ARM_SHIFT,
 };
 
 /*
@@ -118,7 +162,7 @@ static struct arm_idlect1_clk armxor_ck = {
                .enable_bit     = EN_XORPCK,
                .recalc         = &followparent_recalc,
        },
-       .idlect_shift   = 1,
+       .idlect_shift   = IDLXORP_ARM_SHIFT,
 };
 
 static struct arm_idlect1_clk armtim_ck = {
@@ -131,7 +175,7 @@ static struct arm_idlect1_clk armtim_ck = {
                .enable_bit     = EN_TIMCK,
                .recalc         = &followparent_recalc,
        },
-       .idlect_shift   = 9,
+       .idlect_shift   = IDLTIM_ARM_SHIFT,
 };
 
 static struct arm_idlect1_clk armwdt_ck = {
@@ -145,7 +189,7 @@ static struct arm_idlect1_clk armwdt_ck = {
                .fixed_div      = 14,
                .recalc         = &omap_fixed_divisor_recalc,
        },
-       .idlect_shift   = 0,
+       .idlect_shift   = IDLWDT_ARM_SHIFT,
 };
 
 static struct clk arminth_ck16xx = {
@@ -212,7 +256,6 @@ static struct clk dsptim_ck = {
        .recalc         = &followparent_recalc,
 };
 
-/* Tie ARM_IDLECT1:IDLIF_ARM to this logical clock structure */
 static struct arm_idlect1_clk tc_ck = {
        .clk = {
                .name           = "tc_ck",
@@ -224,7 +267,7 @@ static struct arm_idlect1_clk tc_ck = {
                .round_rate     = omap1_clk_round_rate_ckctl_arm,
                .set_rate       = omap1_clk_set_rate_ckctl_arm,
        },
-       .idlect_shift   = 6,
+       .idlect_shift   = IDLIF_ARM_SHIFT,
 };
 
 static struct clk arminth_ck1510 = {
@@ -304,7 +347,7 @@ static struct arm_idlect1_clk api_ck = {
                .enable_bit     = EN_APICK,
                .recalc         = &followparent_recalc,
        },
-       .idlect_shift   = 8,
+       .idlect_shift   = IDLAPI_ARM_SHIFT,
 };
 
 static struct arm_idlect1_clk lb_ck = {
@@ -317,7 +360,7 @@ static struct arm_idlect1_clk lb_ck = {
                .enable_bit     = EN_LBCK,
                .recalc         = &followparent_recalc,
        },
-       .idlect_shift   = 4,
+       .idlect_shift   = IDLLB_ARM_SHIFT,
 };
 
 static struct clk rhea1_ck = {
@@ -359,9 +402,15 @@ static struct arm_idlect1_clk lcd_ck_1510 = {
                .round_rate     = omap1_clk_round_rate_ckctl_arm,
                .set_rate       = omap1_clk_set_rate_ckctl_arm,
        },
-       .idlect_shift   = 3,
+       .idlect_shift   = OMAP1510_IDLLCD_ARM_SHIFT,
 };
 
+/*
+ * XXX The enable_bit here is misused - it simply switches between 12MHz
+ * and 48MHz.  Reimplement with clksel.
+ *
+ * XXX does this need SYSC register handling?
+ */
 static struct clk uart1_1510 = {
        .name           = "uart1_ck",
        .ops            = &clkops_null,
@@ -370,25 +419,37 @@ static struct clk uart1_1510 = {
        .rate           = 12000000,
        .flags          = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
        .enable_reg     = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
-       .enable_bit     = 29,   /* Chooses between 12MHz and 48MHz */
+       .enable_bit     = CONF_MOD_UART1_CLK_MODE_R,
        .set_rate       = &omap1_set_uart_rate,
        .recalc         = &omap1_uart_recalc,
 };
 
+/*
+ * XXX The enable_bit here is misused - it simply switches between 12MHz
+ * and 48MHz.  Reimplement with clksel.
+ *
+ * XXX SYSC register handling does not belong in the clock framework
+ */
 static struct uart_clk uart1_16xx = {
        .clk    = {
                .name           = "uart1_ck",
-               .ops            = &clkops_uart,
+               .ops            = &clkops_uart_16xx,
                /* Direct from ULPD, no real parent */
                .parent         = &armper_ck.clk,
                .rate           = 48000000,
                .flags          = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
                .enable_reg     = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
-               .enable_bit     = 29,
+               .enable_bit     = CONF_MOD_UART1_CLK_MODE_R,
        },
        .sysc_addr      = 0xfffb0054,
 };
 
+/*
+ * XXX The enable_bit here is misused - it simply switches between 12MHz
+ * and 48MHz.  Reimplement with clksel.
+ *
+ * XXX does this need SYSC register handling?
+ */
 static struct clk uart2_ck = {
        .name           = "uart2_ck",
        .ops            = &clkops_null,
@@ -397,11 +458,17 @@ static struct clk uart2_ck = {
        .rate           = 12000000,
        .flags          = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
        .enable_reg     = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
-       .enable_bit     = 30,   /* Chooses between 12MHz and 48MHz */
+       .enable_bit     = CONF_MOD_UART2_CLK_MODE_R,
        .set_rate       = &omap1_set_uart_rate,
        .recalc         = &omap1_uart_recalc,
 };
 
+/*
+ * XXX The enable_bit here is misused - it simply switches between 12MHz
+ * and 48MHz.  Reimplement with clksel.
+ *
+ * XXX does this need SYSC register handling?
+ */
 static struct clk uart3_1510 = {
        .name           = "uart3_ck",
        .ops            = &clkops_null,
@@ -410,21 +477,27 @@ static struct clk uart3_1510 = {
        .rate           = 12000000,
        .flags          = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
        .enable_reg     = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
-       .enable_bit     = 31,   /* Chooses between 12MHz and 48MHz */
+       .enable_bit     = CONF_MOD_UART3_CLK_MODE_R,
        .set_rate       = &omap1_set_uart_rate,
        .recalc         = &omap1_uart_recalc,
 };
 
+/*
+ * XXX The enable_bit here is misused - it simply switches between 12MHz
+ * and 48MHz.  Reimplement with clksel.
+ *
+ * XXX SYSC register handling does not belong in the clock framework
+ */
 static struct uart_clk uart3_16xx = {
        .clk    = {
                .name           = "uart3_ck",
-               .ops            = &clkops_uart,
+               .ops            = &clkops_uart_16xx,
                /* Direct from ULPD, no real parent */
                .parent         = &armper_ck.clk,
                .rate           = 48000000,
                .flags          = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
                .enable_reg     = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
-               .enable_bit     = 31,
+               .enable_bit     = CONF_MOD_UART3_CLK_MODE_R,
        },
        .sysc_addr      = 0xfffb9854,
 };
@@ -457,7 +530,7 @@ static struct clk usb_hhc_ck16xx = {
        /* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */
        .flags          = ENABLE_REG_32BIT,
        .enable_reg     = OMAP1_IO_ADDRESS(OTG_BASE + 0x08), /* OTG_SYSCON_2 */
-       .enable_bit     = 8 /* UHOST_EN */,
+       .enable_bit     = OTG_SYSCON_2_UHOST_EN_SHIFT
 };
 
 static struct clk usb_dc_ck = {
@@ -466,7 +539,7 @@ static struct clk usb_dc_ck = {
        /* Direct from ULPD, no parent */
        .rate           = 48000000,
        .enable_reg     = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
-       .enable_bit     = 4,
+       .enable_bit     = USB_REQ_EN_SHIFT,
 };
 
 static struct clk usb_dc_ck7xx = {
@@ -475,7 +548,7 @@ static struct clk usb_dc_ck7xx = {
        /* Direct from ULPD, no parent */
        .rate           = 48000000,
        .enable_reg     = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
-       .enable_bit     = 8,
+       .enable_bit     = SOFT_USB_OTG_DPLL_REQ_SHIFT,
 };
 
 static struct clk uart1_7xx = {
@@ -502,7 +575,7 @@ static struct clk mclk_1510 = {
        /* Direct from ULPD, no parent. May be enabled by ext hardware. */
        .rate           = 12000000,
        .enable_reg     = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
-       .enable_bit     = 6,
+       .enable_bit     = SOFT_COM_MCKO_REQ_SHIFT,
 };
 
 static struct clk mclk_16xx = {
@@ -542,9 +615,13 @@ static struct clk mmc1_ck = {
        .rate           = 48000000,
        .flags          = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
        .enable_reg     = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
-       .enable_bit     = 23,
+       .enable_bit     = CONF_MOD_MMC_SD_CLK_REQ_R,
 };
 
+/*
+ * XXX MOD_CONF_CTRL_0 bit 20 is defined in the 1510 TRM as
+ * CONF_MOD_MCBSP3_AUXON ??
+ */
 static struct clk mmc2_ck = {
        .name           = "mmc2_ck",
        .ops            = &clkops_generic,
@@ -564,7 +641,7 @@ static struct clk mmc3_ck = {
        .rate           = 48000000,
        .flags          = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
        .enable_reg     = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
-       .enable_bit     = 12,
+       .enable_bit     = SOFT_MMC_DPLL_REQ_SHIFT,
 };
 
 static struct clk virtual_ck_mpu = {
index a5266fab6177e565f7870f0b7022abc786ecc215..63b2d8859c3c291af8e8af729f63d8302ad4915e 100644 (file)
@@ -3,7 +3,7 @@
 #
 
 # Common support
-obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o
+obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o pm.o
 
 omap-2-3-common                                = irq.o sdrc.o
 hwmod-common                           = omap_hwmod.o \
@@ -15,7 +15,7 @@ clock-common                          = clock.o clock_common_data.o \
 
 obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(prcm-common) $(hwmod-common)
 obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(prcm-common) $(hwmod-common)
-obj-$(CONFIG_ARCH_OMAP4) += $(prcm-common)
+obj-$(CONFIG_ARCH_OMAP4) += $(prcm-common) $(hwmod-common)
 
 obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
 
index 41b155acfca7cf2605202f78ffbe45a84ebf594a..c226798e9ac613526548e15007608bfb587ca906 100644 (file)
@@ -1408,7 +1408,7 @@ static struct clk ts_fck = {
 
 static struct clk usbtll_fck = {
        .name           = "usbtll_fck",
-       .ops            = &clkops_omap2_dflt,
+       .ops            = &clkops_omap2_dflt_wait,
        .parent         = &dpll5_m2_ck,
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3),
        .enable_bit     = OMAP3430ES2_EN_USBTLL_SHIFT,
index 2d83565d2be29b8d0be4ea06f4208aaf593378bb..721c3b66740acd1475793c6ee4029c65e8db3815 100644 (file)
@@ -50,15 +50,15 @@ int omap2_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)
 
        cm_idlest_reg = cm_idlest_offs[idlest_id - 1];
 
+       mask = 1 << idlest_shift;
+
        if (cpu_is_omap24xx())
-               ena = idlest_shift;
+               ena = mask;
        else if (cpu_is_omap34xx())
                ena = 0;
        else
                BUG();
 
-       mask = 1 << idlest_shift;
-
        /* XXX should be OMAP2 CM */
        omap_test_timeout(((cm_read_mod_reg(prcm_mod, cm_idlest_reg) & mask) == ena),
                          MAX_MODULE_READY_TIME, i);
index b12d715dee5b0806af16ad88cb782d00f76d4eab..210de9d292fbc98182535921d7e1b6dfd41b2cd8 100644 (file)
@@ -44,6 +44,7 @@
 
 #include <plat/clockdomain.h>
 #include "clockdomains.h"
+
 #include <plat/omap_hwmod.h>
 
 /*
@@ -315,6 +316,8 @@ static int __init _omap2_init_reprogram_sdrc(void)
 void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
                                 struct omap_sdrc_params *sdrc_cs1)
 {
+       u8 skip_setup_idle = 0;
+
        pwrdm_init(powerdomains_omap);
        clkdm_init(clockdomains_omap, clkdm_autodeps);
        if (cpu_is_omap242x())
@@ -338,9 +341,13 @@ void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
                pr_err("Could not init clock framework - unknown CPU\n");
 
        omap_serial_early_init();
+
+#ifndef CONFIG_PM_RUNTIME
+       skip_setup_idle = 1;
+#endif
        if (cpu_is_omap24xx() || cpu_is_omap34xx())   /* FIXME: OMAP4 */
-               omap_hwmod_late_init();
-       omap_pm_if_init();
+               omap_hwmod_late_init(skip_setup_idle);
+
        if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
                omap2_sdrc_init(sdrc_cs0, sdrc_cs1);
                _omap2_init_reprogram_sdrc();
index b7a4133267d80b73cd0ff59fe8d339efae649839..cb911d7d1a3c1535ba88eda74577ea6ef2e1ecd0 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * omap_hwmod implementation for OMAP2/3/4
  *
- * Copyright (C) 2009 Nokia Corporation
+ * Copyright (C) 2009-2010 Nokia Corporation
  *
  * Paul Walmsley, BenoĆ®t Cousson, Kevin Hilman
  *
@@ -423,7 +423,7 @@ static int _init_main_clk(struct omap_hwmod *oh)
 }
 
 /**
- * _init_interface_clk - get a struct clk * for the the hwmod's interface clks
+ * _init_interface_clks - get a struct clk * for the the hwmod's interface clks
  * @oh: struct omap_hwmod *
  *
  * Called from _init_clocks().  Populates the @oh OCP slave interface
@@ -764,6 +764,7 @@ static struct omap_hwmod *_lookup(const char *name)
 /**
  * _init_clocks - clk_get() all clocks associated with this hwmod
  * @oh: struct omap_hwmod *
+ * @data: not used; pass NULL
  *
  * Called by omap_hwmod_late_init() (after omap2_clk_init()).
  * Resolves all clock names embedded in the hwmod.  Must be called
@@ -771,7 +772,7 @@ static struct omap_hwmod *_lookup(const char *name)
  * has not yet been registered or if the clocks have already been
  * initialized, 0 on success, or a non-zero error on failure.
  */
-static int _init_clocks(struct omap_hwmod *oh)
+static int _init_clocks(struct omap_hwmod *oh, void *data)
 {
        int ret = 0;
 
@@ -886,7 +887,7 @@ static int _reset(struct omap_hwmod *oh)
 }
 
 /**
- * _enable - enable an omap_hwmod
+ * _omap_hwmod_enable - enable an omap_hwmod
  * @oh: struct omap_hwmod *
  *
  * Enables an omap_hwmod @oh such that the MPU can access the hwmod's
@@ -894,7 +895,7 @@ static int _reset(struct omap_hwmod *oh)
  * Returns -EINVAL if the hwmod is in the wrong state or passes along
  * the return value of _wait_target_ready().
  */
-static int _enable(struct omap_hwmod *oh)
+int _omap_hwmod_enable(struct omap_hwmod *oh)
 {
        int r;
 
@@ -939,7 +940,7 @@ static int _enable(struct omap_hwmod *oh)
  * no further work.  Returns -EINVAL if the hwmod is in the wrong
  * state or returns 0.
  */
-static int _idle(struct omap_hwmod *oh)
+int _omap_hwmod_idle(struct omap_hwmod *oh)
 {
        if (oh->_state != _HWMOD_STATE_ENABLED) {
                WARN(1, "omap_hwmod: %s: idle state can only be entered from "
@@ -996,19 +997,25 @@ static int _shutdown(struct omap_hwmod *oh)
 /**
  * _setup - do initial configuration of omap_hwmod
  * @oh: struct omap_hwmod *
+ * @skip_setup_idle_p: do not idle hwmods at the end of the fn if 1
  *
  * Writes the CLOCKACTIVITY bits @clockact to the hwmod @oh
- * OCP_SYSCONFIG register.  Must be called with omap_hwmod_mutex
- * held.  Returns -EINVAL if the hwmod is in the wrong state or returns
- * 0.
+ * OCP_SYSCONFIG register.  Must be called with omap_hwmod_mutex held.
+ * @skip_setup_idle is intended to be used on a system that will not
+ * call omap_hwmod_enable() to enable devices (e.g., a system without
+ * PM runtime).  Returns -EINVAL if the hwmod is in the wrong state or
+ * returns 0.
  */
-static int _setup(struct omap_hwmod *oh)
+static int _setup(struct omap_hwmod *oh, void *data)
 {
        int i, r;
+       u8 skip_setup_idle;
 
-       if (!oh)
+       if (!oh || !data)
                return -EINVAL;
 
+       skip_setup_idle = *(u8 *)data;
+
        /* Set iclk autoidle mode */
        if (oh->slaves_cnt > 0) {
                for (i = 0; i < oh->slaves_cnt; i++) {
@@ -1029,7 +1036,7 @@ static int _setup(struct omap_hwmod *oh)
 
        oh->_state = _HWMOD_STATE_INITIALIZED;
 
-       r = _enable(oh);
+       r = _omap_hwmod_enable(oh);
        if (r) {
                pr_warning("omap_hwmod: %s: cannot be enabled (%d)\n",
                           oh->name, oh->_state);
@@ -1041,7 +1048,7 @@ static int _setup(struct omap_hwmod *oh)
                 * XXX Do the OCP_SYSCONFIG bits need to be
                 * reprogrammed after a reset?  If not, then this can
                 * be removed.  If they do, then probably the
-                * _enable() function should be split to avoid the
+                * _omap_hwmod_enable() function should be split to avoid the
                 * rewrite of the OCP_SYSCONFIG register.
                 */
                if (oh->class->sysc) {
@@ -1050,8 +1057,8 @@ static int _setup(struct omap_hwmod *oh)
                }
        }
 
-       if (!(oh->flags & HWMOD_INIT_NO_IDLE))
-               _idle(oh);
+       if (!(oh->flags & HWMOD_INIT_NO_IDLE) && !skip_setup_idle)
+               _omap_hwmod_idle(oh);
 
        return 0;
 }
@@ -1062,14 +1069,29 @@ static int _setup(struct omap_hwmod *oh)
 
 u32 omap_hwmod_readl(struct omap_hwmod *oh, u16 reg_offs)
 {
-       return __raw_readl(oh->_rt_va + reg_offs);
+       return __raw_readl(oh->_mpu_rt_va + reg_offs);
 }
 
 void omap_hwmod_writel(u32 v, struct omap_hwmod *oh, u16 reg_offs)
 {
-       __raw_writel(v, oh->_rt_va + reg_offs);
+       __raw_writel(v, oh->_mpu_rt_va + reg_offs);
 }
 
+/**
+ * omap_hwmod_set_slave_idlemode - set the hwmod's OCP slave idlemode
+ * @oh: struct omap_hwmod *
+ * @idlemode: SIDLEMODE field bits (shifted to bit 0)
+ *
+ * Sets the IP block's OCP slave idlemode in hardware, and updates our
+ * local copy.  Intended to be used by drivers that have some erratum
+ * that requires direct manipulation of the SIDLEMODE bits.  Returns
+ * -EINVAL if @oh is null, or passes along the return value from
+ * _set_slave_idlemode().
+ *
+ * XXX Does this function have any current users?  If not, we should
+ * remove it; it is better to let the rest of the hwmod code handle this.
+ * Any users of this function should be scrutinized carefully.
+ */
 int omap_hwmod_set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode)
 {
        u32 v;
@@ -1124,7 +1146,7 @@ int omap_hwmod_register(struct omap_hwmod *oh)
        ms_id = _find_mpu_port_index(oh);
        if (!IS_ERR_VALUE(ms_id)) {
                oh->_mpu_port_index = ms_id;
-               oh->_rt_va = _find_mpu_rt_base(oh, oh->_mpu_port_index);
+               oh->_mpu_rt_va = _find_mpu_rt_base(oh, oh->_mpu_port_index);
        } else {
                oh->_int_flags |= _HWMOD_NO_MPU_PORT;
        }
@@ -1164,6 +1186,7 @@ struct omap_hwmod *omap_hwmod_lookup(const char *name)
 /**
  * omap_hwmod_for_each - call function for each registered omap_hwmod
  * @fn: pointer to a callback function
+ * @data: void * data to pass to callback function
  *
  * Call @fn for each registered omap_hwmod, passing @data to each
  * function.  @fn must return 0 for success or any other value for
@@ -1172,7 +1195,8 @@ struct omap_hwmod *omap_hwmod_lookup(const char *name)
  * caller of omap_hwmod_for_each().  @fn is called with
  * omap_hwmod_for_each() held.
  */
-int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh))
+int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data),
+                       void *data)
 {
        struct omap_hwmod *temp_oh;
        int ret;
@@ -1182,7 +1206,7 @@ int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh))
 
        mutex_lock(&omap_hwmod_mutex);
        list_for_each_entry(temp_oh, &omap_hwmod_list, node) {
-               ret = (*fn)(temp_oh);
+               ret = (*fn)(temp_oh, data);
                if (ret)
                        break;
        }
@@ -1229,24 +1253,28 @@ int omap_hwmod_init(struct omap_hwmod **ohs)
 
 /**
  * omap_hwmod_late_init - do some post-clock framework initialization
+ * @skip_setup_idle: if 1, do not idle hwmods in _setup()
  *
  * Must be called after omap2_clk_init().  Resolves the struct clk names
  * to struct clk pointers for each registered omap_hwmod.  Also calls
  * _setup() on each hwmod.  Returns 0.
  */
-int omap_hwmod_late_init(void)
+int omap_hwmod_late_init(u8 skip_setup_idle)
 {
        int r;
 
        /* XXX check return value */
-       r = omap_hwmod_for_each(_init_clocks);
+       r = omap_hwmod_for_each(_init_clocks, NULL);
        WARN(r, "omap_hwmod: omap_hwmod_late_init(): _init_clocks failed\n");
 
        mpu_oh = omap_hwmod_lookup(MPU_INITIATOR_NAME);
        WARN(!mpu_oh, "omap_hwmod: could not find MPU initiator hwmod %s\n",
             MPU_INITIATOR_NAME);
 
-       omap_hwmod_for_each(_setup);
+       if (skip_setup_idle)
+               pr_debug("omap_hwmod: will leave hwmods enabled during setup\n");
+
+       omap_hwmod_for_each(_setup, &skip_setup_idle);
 
        return 0;
 }
@@ -1270,7 +1298,7 @@ int omap_hwmod_unregister(struct omap_hwmod *oh)
        pr_debug("omap_hwmod: %s: unregistering\n", oh->name);
 
        mutex_lock(&omap_hwmod_mutex);
-       iounmap(oh->_rt_va);
+       iounmap(oh->_mpu_rt_va);
        list_del(&oh->node);
        mutex_unlock(&omap_hwmod_mutex);
 
@@ -1292,12 +1320,13 @@ int omap_hwmod_enable(struct omap_hwmod *oh)
                return -EINVAL;
 
        mutex_lock(&omap_hwmod_mutex);
-       r = _enable(oh);
+       r = _omap_hwmod_enable(oh);
        mutex_unlock(&omap_hwmod_mutex);
 
        return r;
 }
 
+
 /**
  * omap_hwmod_idle - idle an omap_hwmod
  * @oh: struct omap_hwmod *
@@ -1311,7 +1340,7 @@ int omap_hwmod_idle(struct omap_hwmod *oh)
                return -EINVAL;
 
        mutex_lock(&omap_hwmod_mutex);
-       _idle(oh);
+       _omap_hwmod_idle(oh);
        mutex_unlock(&omap_hwmod_mutex);
 
        return 0;
@@ -1413,7 +1442,7 @@ int omap_hwmod_reset(struct omap_hwmod *oh)
        mutex_lock(&omap_hwmod_mutex);
        r = _reset(oh);
        if (!r)
-               r = _enable(oh);
+               r = _omap_hwmod_enable(oh);
        mutex_unlock(&omap_hwmod_mutex);
 
        return r;
@@ -1529,6 +1558,29 @@ struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh)
 
 }
 
+/**
+ * omap_hwmod_get_mpu_rt_va - return the module's base address (for the MPU)
+ * @oh: struct omap_hwmod *
+ *
+ * Returns the virtual address corresponding to the beginning of the
+ * module's register target, in the address range that is intended to
+ * be used by the MPU.  Returns the virtual address upon success or NULL
+ * upon error.
+ */
+void __iomem *omap_hwmod_get_mpu_rt_va(struct omap_hwmod *oh)
+{
+       if (!oh)
+               return NULL;
+
+       if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
+               return NULL;
+
+       if (oh->_state == _HWMOD_STATE_UNKNOWN)
+               return NULL;
+
+       return oh->_mpu_rt_va;
+}
+
 /**
  * omap_hwmod_add_initiator_dep - add sleepdep from @init_oh to @oh
  * @oh: struct omap_hwmod *
index e5530c51f77dd15729967ee1490f3211ba884954..3cc768e8bc04f41a38ae335f941eb5577009037a 100644 (file)
  */
 
 static struct omap_hwmod omap2420_mpu_hwmod;
-static struct omap_hwmod omap2420_l3_hwmod;
+static struct omap_hwmod omap2420_iva_hwmod;
+static struct omap_hwmod omap2420_l3_main_hwmod;
 static struct omap_hwmod omap2420_l4_core_hwmod;
 
 /* L3 -> L4_CORE interface */
-static struct omap_hwmod_ocp_if omap2420_l3__l4_core = {
-       .master = &omap2420_l3_hwmod,
+static struct omap_hwmod_ocp_if omap2420_l3_main__l4_core = {
+       .master = &omap2420_l3_main_hwmod,
        .slave  = &omap2420_l4_core_hwmod,
        .user   = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
 /* MPU -> L3 interface */
-static struct omap_hwmod_ocp_if omap2420_mpu__l3 = {
+static struct omap_hwmod_ocp_if omap2420_mpu__l3_main = {
        .master = &omap2420_mpu_hwmod,
-       .slave  = &omap2420_l3_hwmod,
+       .slave  = &omap2420_l3_main_hwmod,
        .user   = OCP_USER_MPU,
 };
 
 /* Slave interfaces on the L3 interconnect */
-static struct omap_hwmod_ocp_if *omap2420_l3_slaves[] = {
-       &omap2420_mpu__l3,
+static struct omap_hwmod_ocp_if *omap2420_l3_main_slaves[] = {
+       &omap2420_mpu__l3_main,
 };
 
 /* Master interfaces on the L3 interconnect */
-static struct omap_hwmod_ocp_if *omap2420_l3_masters[] = {
-       &omap2420_l3__l4_core,
+static struct omap_hwmod_ocp_if *omap2420_l3_main_masters[] = {
+       &omap2420_l3_main__l4_core,
 };
 
 /* L3 */
-static struct omap_hwmod omap2420_l3_hwmod = {
-       .name           = "l3_hwmod",
+static struct omap_hwmod omap2420_l3_main_hwmod = {
+       .name           = "l3_main",
        .class          = &l3_hwmod_class,
-       .masters        = omap2420_l3_masters,
-       .masters_cnt    = ARRAY_SIZE(omap2420_l3_masters),
-       .slaves         = omap2420_l3_slaves,
-       .slaves_cnt     = ARRAY_SIZE(omap2420_l3_slaves),
-       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
+       .masters        = omap2420_l3_main_masters,
+       .masters_cnt    = ARRAY_SIZE(omap2420_l3_main_masters),
+       .slaves         = omap2420_l3_main_slaves,
+       .slaves_cnt     = ARRAY_SIZE(omap2420_l3_main_slaves),
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+       .flags          = HWMOD_NO_IDLEST,
 };
 
 static struct omap_hwmod omap2420_l4_wkup_hwmod;
@@ -79,7 +81,7 @@ static struct omap_hwmod_ocp_if omap2420_l4_core__l4_wkup = {
 
 /* Slave interfaces on the L4_CORE interconnect */
 static struct omap_hwmod_ocp_if *omap2420_l4_core_slaves[] = {
-       &omap2420_l3__l4_core,
+       &omap2420_l3_main__l4_core,
 };
 
 /* Master interfaces on the L4_CORE interconnect */
@@ -89,13 +91,14 @@ static struct omap_hwmod_ocp_if *omap2420_l4_core_masters[] = {
 
 /* L4 CORE */
 static struct omap_hwmod omap2420_l4_core_hwmod = {
-       .name           = "l4_core_hwmod",
+       .name           = "l4_core",
        .class          = &l4_hwmod_class,
        .masters        = omap2420_l4_core_masters,
        .masters_cnt    = ARRAY_SIZE(omap2420_l4_core_masters),
        .slaves         = omap2420_l4_core_slaves,
        .slaves_cnt     = ARRAY_SIZE(omap2420_l4_core_slaves),
-       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+       .flags          = HWMOD_NO_IDLEST,
 };
 
 /* Slave interfaces on the L4_WKUP interconnect */
@@ -109,18 +112,19 @@ static struct omap_hwmod_ocp_if *omap2420_l4_wkup_masters[] = {
 
 /* L4 WKUP */
 static struct omap_hwmod omap2420_l4_wkup_hwmod = {
-       .name           = "l4_wkup_hwmod",
+       .name           = "l4_wkup",
        .class          = &l4_hwmod_class,
        .masters        = omap2420_l4_wkup_masters,
        .masters_cnt    = ARRAY_SIZE(omap2420_l4_wkup_masters),
        .slaves         = omap2420_l4_wkup_slaves,
        .slaves_cnt     = ARRAY_SIZE(omap2420_l4_wkup_slaves),
-       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+       .flags          = HWMOD_NO_IDLEST,
 };
 
 /* Master interfaces on the MPU device */
 static struct omap_hwmod_ocp_if *omap2420_mpu_masters[] = {
-       &omap2420_mpu__l3,
+       &omap2420_mpu__l3_main,
 };
 
 /* MPU */
@@ -133,11 +137,40 @@ static struct omap_hwmod omap2420_mpu_hwmod = {
        .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
 };
 
+/*
+ * IVA1 interface data
+ */
+
+/* IVA <- L3 interface */
+static struct omap_hwmod_ocp_if omap2420_l3__iva = {
+       .master         = &omap2420_l3_main_hwmod,
+       .slave          = &omap2420_iva_hwmod,
+       .clk            = "iva1_ifck",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if *omap2420_iva_masters[] = {
+       &omap2420_l3__iva,
+};
+
+/*
+ * IVA2 (IVA2)
+ */
+
+static struct omap_hwmod omap2420_iva_hwmod = {
+       .name           = "iva",
+       .class          = &iva_hwmod_class,
+       .masters        = omap2420_iva_masters,
+       .masters_cnt    = ARRAY_SIZE(omap2420_iva_masters),
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
+};
+
 static __initdata struct omap_hwmod *omap2420_hwmods[] = {
-       &omap2420_l3_hwmod,
+       &omap2420_l3_main_hwmod,
        &omap2420_l4_core_hwmod,
        &omap2420_l4_wkup_hwmod,
        &omap2420_mpu_hwmod,
+       &omap2420_iva_hwmod,
        NULL,
 };
 
index 0852d954da406590e954e018b5287819b000608b..4526628ed287222cba29d2f42521fbaaca052f37 100644 (file)
  */
 
 static struct omap_hwmod omap2430_mpu_hwmod;
-static struct omap_hwmod omap2430_l3_hwmod;
+static struct omap_hwmod omap2430_iva_hwmod;
+static struct omap_hwmod omap2430_l3_main_hwmod;
 static struct omap_hwmod omap2430_l4_core_hwmod;
 
 /* L3 -> L4_CORE interface */
-static struct omap_hwmod_ocp_if omap2430_l3__l4_core = {
-       .master = &omap2430_l3_hwmod,
+static struct omap_hwmod_ocp_if omap2430_l3_main__l4_core = {
+       .master = &omap2430_l3_main_hwmod,
        .slave  = &omap2430_l4_core_hwmod,
        .user   = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
 /* MPU -> L3 interface */
-static struct omap_hwmod_ocp_if omap2430_mpu__l3 = {
+static struct omap_hwmod_ocp_if omap2430_mpu__l3_main = {
        .master = &omap2430_mpu_hwmod,
-       .slave  = &omap2430_l3_hwmod,
+       .slave  = &omap2430_l3_main_hwmod,
        .user   = OCP_USER_MPU,
 };
 
 /* Slave interfaces on the L3 interconnect */
-static struct omap_hwmod_ocp_if *omap2430_l3_slaves[] = {
-       &omap2430_mpu__l3,
+static struct omap_hwmod_ocp_if *omap2430_l3_main_slaves[] = {
+       &omap2430_mpu__l3_main,
 };
 
 /* Master interfaces on the L3 interconnect */
-static struct omap_hwmod_ocp_if *omap2430_l3_masters[] = {
-       &omap2430_l3__l4_core,
+static struct omap_hwmod_ocp_if *omap2430_l3_main_masters[] = {
+       &omap2430_l3_main__l4_core,
 };
 
 /* L3 */
-static struct omap_hwmod omap2430_l3_hwmod = {
-       .name           = "l3_hwmod",
+static struct omap_hwmod omap2430_l3_main_hwmod = {
+       .name           = "l3_main",
        .class          = &l3_hwmod_class,
-       .masters        = omap2430_l3_masters,
-       .masters_cnt    = ARRAY_SIZE(omap2430_l3_masters),
-       .slaves         = omap2430_l3_slaves,
-       .slaves_cnt     = ARRAY_SIZE(omap2430_l3_slaves),
-       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
+       .masters        = omap2430_l3_main_masters,
+       .masters_cnt    = ARRAY_SIZE(omap2430_l3_main_masters),
+       .slaves         = omap2430_l3_main_slaves,
+       .slaves_cnt     = ARRAY_SIZE(omap2430_l3_main_slaves),
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+       .flags          = HWMOD_NO_IDLEST,
 };
 
 static struct omap_hwmod omap2430_l4_wkup_hwmod;
-static struct omap_hwmod omap2430_mmc1_hwmod;
-static struct omap_hwmod omap2430_mmc2_hwmod;
 
 /* L4_CORE -> L4_WKUP interface */
 static struct omap_hwmod_ocp_if omap2430_l4_core__l4_wkup = {
@@ -81,7 +81,7 @@ static struct omap_hwmod_ocp_if omap2430_l4_core__l4_wkup = {
 
 /* Slave interfaces on the L4_CORE interconnect */
 static struct omap_hwmod_ocp_if *omap2430_l4_core_slaves[] = {
-       &omap2430_l3__l4_core,
+       &omap2430_l3_main__l4_core,
 };
 
 /* Master interfaces on the L4_CORE interconnect */
@@ -91,13 +91,14 @@ static struct omap_hwmod_ocp_if *omap2430_l4_core_masters[] = {
 
 /* L4 CORE */
 static struct omap_hwmod omap2430_l4_core_hwmod = {
-       .name           = "l4_core_hwmod",
+       .name           = "l4_core",
        .class          = &l4_hwmod_class,
        .masters        = omap2430_l4_core_masters,
        .masters_cnt    = ARRAY_SIZE(omap2430_l4_core_masters),
        .slaves         = omap2430_l4_core_slaves,
        .slaves_cnt     = ARRAY_SIZE(omap2430_l4_core_slaves),
-       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+       .flags          = HWMOD_NO_IDLEST,
 };
 
 /* Slave interfaces on the L4_WKUP interconnect */
@@ -111,18 +112,19 @@ static struct omap_hwmod_ocp_if *omap2430_l4_wkup_masters[] = {
 
 /* L4 WKUP */
 static struct omap_hwmod omap2430_l4_wkup_hwmod = {
-       .name           = "l4_wkup_hwmod",
+       .name           = "l4_wkup",
        .class          = &l4_hwmod_class,
        .masters        = omap2430_l4_wkup_masters,
        .masters_cnt    = ARRAY_SIZE(omap2430_l4_wkup_masters),
        .slaves         = omap2430_l4_wkup_slaves,
        .slaves_cnt     = ARRAY_SIZE(omap2430_l4_wkup_slaves),
-       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+       .flags          = HWMOD_NO_IDLEST,
 };
 
 /* Master interfaces on the MPU device */
 static struct omap_hwmod_ocp_if *omap2430_mpu_masters[] = {
-       &omap2430_mpu__l3,
+       &omap2430_mpu__l3_main,
 };
 
 /* MPU */
@@ -135,11 +137,40 @@ static struct omap_hwmod omap2430_mpu_hwmod = {
        .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
 };
 
+/*
+ * IVA2_1 interface data
+ */
+
+/* IVA2 <- L3 interface */
+static struct omap_hwmod_ocp_if omap2430_l3__iva = {
+       .master         = &omap2430_l3_main_hwmod,
+       .slave          = &omap2430_iva_hwmod,
+       .clk            = "dsp_fck",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if *omap2430_iva_masters[] = {
+       &omap2430_l3__iva,
+};
+
+/*
+ * IVA2 (IVA2)
+ */
+
+static struct omap_hwmod omap2430_iva_hwmod = {
+       .name           = "iva",
+       .class          = &iva_hwmod_class,
+       .masters        = omap2430_iva_masters,
+       .masters_cnt    = ARRAY_SIZE(omap2430_iva_masters),
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
+};
+
 static __initdata struct omap_hwmod *omap2430_hwmods[] = {
-       &omap2430_l3_hwmod,
+       &omap2430_l3_main_hwmod,
        &omap2430_l4_core_hwmod,
        &omap2430_l4_wkup_hwmod,
        &omap2430_mpu_hwmod,
+       &omap2430_iva_hwmod,
        NULL,
 };
 
index 39b0c0eaa37d27d89552984c4de8bbdb171ac387..5d8eb58ba5e340f68875f28936aa38d6451b8ebd 100644 (file)
  */
 
 static struct omap_hwmod omap3xxx_mpu_hwmod;
-static struct omap_hwmod omap3xxx_l3_hwmod;
+static struct omap_hwmod omap3xxx_iva_hwmod;
+static struct omap_hwmod omap3xxx_l3_main_hwmod;
 static struct omap_hwmod omap3xxx_l4_core_hwmod;
 static struct omap_hwmod omap3xxx_l4_per_hwmod;
 
 /* L3 -> L4_CORE interface */
-static struct omap_hwmod_ocp_if omap3xxx_l3__l4_core = {
-       .master = &omap3xxx_l3_hwmod,
+static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_core = {
+       .master = &omap3xxx_l3_main_hwmod,
        .slave  = &omap3xxx_l4_core_hwmod,
        .user   = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
 /* L3 -> L4_PER interface */
-static struct omap_hwmod_ocp_if omap3xxx_l3__l4_per = {
-       .master = &omap3xxx_l3_hwmod,
+static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_per = {
+       .master = &omap3xxx_l3_main_hwmod,
        .slave  = &omap3xxx_l4_per_hwmod,
        .user   = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
 /* MPU -> L3 interface */
-static struct omap_hwmod_ocp_if omap3xxx_mpu__l3 = {
+static struct omap_hwmod_ocp_if omap3xxx_mpu__l3_main = {
        .master = &omap3xxx_mpu_hwmod,
-       .slave  = &omap3xxx_l3_hwmod,
+       .slave  = &omap3xxx_l3_main_hwmod,
        .user   = OCP_USER_MPU,
 };
 
 /* Slave interfaces on the L3 interconnect */
-static struct omap_hwmod_ocp_if *omap3xxx_l3_slaves[] = {
-       &omap3xxx_mpu__l3,
+static struct omap_hwmod_ocp_if *omap3xxx_l3_main_slaves[] = {
+       &omap3xxx_mpu__l3_main,
 };
 
 /* Master interfaces on the L3 interconnect */
-static struct omap_hwmod_ocp_if *omap3xxx_l3_masters[] = {
-       &omap3xxx_l3__l4_core,
-       &omap3xxx_l3__l4_per,
+static struct omap_hwmod_ocp_if *omap3xxx_l3_main_masters[] = {
+       &omap3xxx_l3_main__l4_core,
+       &omap3xxx_l3_main__l4_per,
 };
 
 /* L3 */
-static struct omap_hwmod omap3xxx_l3_hwmod = {
-       .name           = "l3_hwmod",
+static struct omap_hwmod omap3xxx_l3_main_hwmod = {
+       .name           = "l3_main",
        .class          = &l3_hwmod_class,
-       .masters        = omap3xxx_l3_masters,
-       .masters_cnt    = ARRAY_SIZE(omap3xxx_l3_masters),
-       .slaves         = omap3xxx_l3_slaves,
-       .slaves_cnt     = ARRAY_SIZE(omap3xxx_l3_slaves),
-       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+       .masters        = omap3xxx_l3_main_masters,
+       .masters_cnt    = ARRAY_SIZE(omap3xxx_l3_main_masters),
+       .slaves         = omap3xxx_l3_main_slaves,
+       .slaves_cnt     = ARRAY_SIZE(omap3xxx_l3_main_slaves),
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+       .flags          = HWMOD_NO_IDLEST,
 };
 
 static struct omap_hwmod omap3xxx_l4_wkup_hwmod;
@@ -90,7 +92,7 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_core__l4_wkup = {
 
 /* Slave interfaces on the L4_CORE interconnect */
 static struct omap_hwmod_ocp_if *omap3xxx_l4_core_slaves[] = {
-       &omap3xxx_l3__l4_core,
+       &omap3xxx_l3_main__l4_core,
 };
 
 /* Master interfaces on the L4_CORE interconnect */
@@ -100,18 +102,19 @@ static struct omap_hwmod_ocp_if *omap3xxx_l4_core_masters[] = {
 
 /* L4 CORE */
 static struct omap_hwmod omap3xxx_l4_core_hwmod = {
-       .name           = "l4_core_hwmod",
+       .name           = "l4_core",
        .class          = &l4_hwmod_class,
        .masters        = omap3xxx_l4_core_masters,
        .masters_cnt    = ARRAY_SIZE(omap3xxx_l4_core_masters),
        .slaves         = omap3xxx_l4_core_slaves,
        .slaves_cnt     = ARRAY_SIZE(omap3xxx_l4_core_slaves),
-       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+       .flags          = HWMOD_NO_IDLEST,
 };
 
 /* Slave interfaces on the L4_PER interconnect */
 static struct omap_hwmod_ocp_if *omap3xxx_l4_per_slaves[] = {
-       &omap3xxx_l3__l4_per,
+       &omap3xxx_l3_main__l4_per,
 };
 
 /* Master interfaces on the L4_PER interconnect */
@@ -120,13 +123,14 @@ static struct omap_hwmod_ocp_if *omap3xxx_l4_per_masters[] = {
 
 /* L4 PER */
 static struct omap_hwmod omap3xxx_l4_per_hwmod = {
-       .name           = "l4_per_hwmod",
+       .name           = "l4_per",
        .class          = &l4_hwmod_class,
        .masters        = omap3xxx_l4_per_masters,
        .masters_cnt    = ARRAY_SIZE(omap3xxx_l4_per_masters),
        .slaves         = omap3xxx_l4_per_slaves,
        .slaves_cnt     = ARRAY_SIZE(omap3xxx_l4_per_slaves),
-       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+       .flags          = HWMOD_NO_IDLEST,
 };
 
 /* Slave interfaces on the L4_WKUP interconnect */
@@ -140,18 +144,19 @@ static struct omap_hwmod_ocp_if *omap3xxx_l4_wkup_masters[] = {
 
 /* L4 WKUP */
 static struct omap_hwmod omap3xxx_l4_wkup_hwmod = {
-       .name           = "l4_wkup_hwmod",
+       .name           = "l4_wkup",
        .class          = &l4_hwmod_class,
        .masters        = omap3xxx_l4_wkup_masters,
        .masters_cnt    = ARRAY_SIZE(omap3xxx_l4_wkup_masters),
        .slaves         = omap3xxx_l4_wkup_slaves,
        .slaves_cnt     = ARRAY_SIZE(omap3xxx_l4_wkup_slaves),
-       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+       .flags          = HWMOD_NO_IDLEST,
 };
 
 /* Master interfaces on the MPU device */
 static struct omap_hwmod_ocp_if *omap3xxx_mpu_masters[] = {
-       &omap3xxx_mpu__l3,
+       &omap3xxx_mpu__l3_main,
 };
 
 /* MPU */
@@ -164,12 +169,41 @@ static struct omap_hwmod omap3xxx_mpu_hwmod = {
        .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
 };
 
+/*
+ * IVA2_2 interface data
+ */
+
+/* IVA2 <- L3 interface */
+static struct omap_hwmod_ocp_if omap3xxx_l3__iva = {
+       .master         = &omap3xxx_l3_main_hwmod,
+       .slave          = &omap3xxx_iva_hwmod,
+       .clk            = "iva2_ck",
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_iva_masters[] = {
+       &omap3xxx_l3__iva,
+};
+
+/*
+ * IVA2 (IVA2)
+ */
+
+static struct omap_hwmod omap3xxx_iva_hwmod = {
+       .name           = "iva",
+       .class          = &iva_hwmod_class,
+       .masters        = omap3xxx_iva_masters,
+       .masters_cnt    = ARRAY_SIZE(omap3xxx_iva_masters),
+       .omap_chip      = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+};
+
 static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
-       &omap3xxx_l3_hwmod,
+       &omap3xxx_l3_main_hwmod,
        &omap3xxx_l4_core_hwmod,
        &omap3xxx_l4_per_hwmod,
        &omap3xxx_l4_wkup_hwmod,
        &omap3xxx_mpu_hwmod,
+       &omap3xxx_iva_hwmod,
        NULL,
 };
 
index 1e80b914fa1ab32c7e6161bd84ff64ea2c4be8f7..08a134243ecba3febb134effb19dda5cda8dbd25 100644 (file)
@@ -66,3 +66,6 @@ struct omap_hwmod_class mpu_hwmod_class = {
        .name = "mpu"
 };
 
+struct omap_hwmod_class iva_hwmod_class = {
+       .name = "iva"
+};
index 3645a28c7c27935723f2de7984740346f2e46304..c34e98bf124295906fc578873d21a1c84bad7bb3 100644 (file)
@@ -20,5 +20,6 @@
 extern struct omap_hwmod_class l3_hwmod_class;
 extern struct omap_hwmod_class l4_hwmod_class;
 extern struct omap_hwmod_class mpu_hwmod_class;
+extern struct omap_hwmod_class iva_hwmod_class;
 
 #endif
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
new file mode 100644 (file)
index 0000000..68f9f2e
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * pm.c - Common OMAP2+ power management-related code
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Copyright (C) 2010 Nokia Corporation
+ *
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/err.h>
+
+#include <plat/omap-pm.h>
+#include <plat/omap_device.h>
+#include <plat/common.h>
+
+static struct omap_device_pm_latency *pm_lats;
+
+static struct device *mpu_dev;
+static struct device *dsp_dev;
+static struct device *l3_dev;
+
+struct device *omap2_get_mpuss_device(void)
+{
+       WARN_ON_ONCE(!mpu_dev);
+       return mpu_dev;
+}
+
+struct device *omap2_get_dsp_device(void)
+{
+       WARN_ON_ONCE(!dsp_dev);
+       return dsp_dev;
+}
+
+struct device *omap2_get_l3_device(void)
+{
+       WARN_ON_ONCE(!l3_dev);
+       return l3_dev;
+}
+
+/* static int _init_omap_device(struct omap_hwmod *oh, void *user) */
+static int _init_omap_device(char *name, struct device **new_dev)
+{
+       struct omap_hwmod *oh;
+       struct omap_device *od;
+
+       oh = omap_hwmod_lookup(name);
+       if (WARN(!oh, "%s: could not find omap_hwmod for %s\n",
+                __func__, name))
+               return -ENODEV;
+
+       od = omap_device_build(oh->name, 0, oh, NULL, 0, pm_lats, 0, false);
+       if (WARN(IS_ERR(od), "%s: could not build omap_device for %s\n",
+                __func__, name))
+               return -ENODEV;
+
+       *new_dev = &od->pdev.dev;
+
+       return 0;
+}
+
+/*
+ * Build omap_devices for processors and bus.
+ */
+static void omap2_init_processor_devices(void)
+{
+       _init_omap_device("mpu", &mpu_dev);
+       _init_omap_device("iva", &dsp_dev);
+       _init_omap_device("l3_main", &l3_dev);
+}
+
+static int __init omap2_common_pm_init(void)
+{
+       omap2_init_processor_devices();
+       omap_pm_if_init();
+
+       return 0;
+}
+device_initcall(omap2_common_pm_init);
+
index 98f01910c2cfa1568d9858f4180890fdf518d929..9405831b746a5e63dd4dc3a2a6220afce032713c 100644 (file)
@@ -15,6 +15,7 @@ obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o
 # omap_device support (OMAP2+ only at the moment)
 obj-$(CONFIG_ARCH_OMAP2) += omap_device.o
 obj-$(CONFIG_ARCH_OMAP3) += omap_device.o
+obj-$(CONFIG_ARCH_OMAP4) += omap_device.o
 
 obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
 obj-$(CONFIG_OMAP_IOMMU) += iommu.o iovmm.o
index eec2b4993c6951f12fdfbe2bc283b7098eaddae1..a5ce4f0aad35b47864609a3eff307205dae64e21 100644 (file)
@@ -138,6 +138,16 @@ static inline int omap1_i2c_add_bus(struct platform_device *pdev, int bus_id)
        return platform_device_register(pdev);
 }
 
+/*
+ * XXX This function is a temporary compatibility wrapper - only
+ * needed until the I2C driver can be converted to call
+ * omap_pm_set_max_dev_wakeup_lat() and handle a return code.
+ */
+static void omap_pm_set_max_mpu_wakeup_lat_compat(struct device *dev, long t)
+{
+       omap_pm_set_max_mpu_wakeup_lat(dev, t);
+}
+
 static inline int omap2_i2c_add_bus(struct platform_device *pdev, int bus_id)
 {
        struct resource *res;
@@ -168,7 +178,7 @@ static inline int omap2_i2c_add_bus(struct platform_device *pdev, int bus_id)
                struct omap_i2c_bus_platform_data *pd;
 
                pd = pdev->dev.platform_data;
-               pd->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat;
+               pd->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
        }
 
        return platform_device_register(pdev);
index dfc472ca0cc44acab0877b404c958ff87a21c730..fef4696dcf674c464e3154210a504380429ba76a 100644 (file)
@@ -19,6 +19,22 @@ struct module;
 struct clk;
 struct clockdomain;
 
+/**
+ * struct clkops - some clock function pointers
+ * @enable: fn ptr that enables the current clock in hardware
+ * @disable: fn ptr that enables the current clock in hardware
+ * @find_idlest: function returning the IDLEST register for the clock's IP blk
+ * @find_companion: function returning the "companion" clk reg for the clock
+ *
+ * A "companion" clk is an accompanying clock to the one being queried
+ * that must be enabled for the IP module connected to the clock to
+ * become accessible by the hardware.  Neither @find_idlest nor
+ * @find_companion should be needed; that information is IP
+ * block-specific; the hwmod code has been created to handle this, but
+ * until hwmod data is ready and drivers have been converted to use PM
+ * runtime calls in place of clk_enable()/clk_disable(), @find_idlest and
+ * @find_companion must, unfortunately, remain.
+ */
 struct clkops {
        int                     (*enable)(struct clk *);
        void                    (*disable)(struct clk *);
@@ -30,12 +46,45 @@ struct clkops {
 
 #ifdef CONFIG_ARCH_OMAP2PLUS
 
+/* struct clksel_rate.flags possibilities */
+#define RATE_IN_242X           (1 << 0)
+#define RATE_IN_243X           (1 << 1)
+#define RATE_IN_3XXX           (1 << 2)        /* rates common to all OMAP3 */
+#define RATE_IN_3430ES2                (1 << 3)        /* 3430ES2 rates only */
+#define RATE_IN_36XX           (1 << 4)
+#define RATE_IN_4430           (1 << 5)
+
+#define RATE_IN_24XX           (RATE_IN_242X | RATE_IN_243X)
+#define RATE_IN_3430ES2PLUS    (RATE_IN_3430ES2 | RATE_IN_36XX)
+
+/**
+ * struct clksel_rate - register bitfield values corresponding to clk divisors
+ * @val: register bitfield value (shifted to bit 0)
+ * @div: clock divisor corresponding to @val
+ * @flags: (see "struct clksel_rate.flags possibilities" above)
+ *
+ * @val should match the value of a read from struct clk.clksel_reg
+ * AND'ed with struct clk.clksel_mask, shifted right to bit 0.
+ *
+ * @div is the divisor that should be applied to the parent clock's rate
+ * to produce the current clock's rate.
+ *
+ * XXX @flags probably should be replaced with an struct omap_chip.
+ */
 struct clksel_rate {
        u32                     val;
        u8                      div;
        u8                      flags;
 };
 
+/**
+ * struct clksel - available parent clocks, and a pointer to their divisors
+ * @parent: struct clk * to a possible parent clock
+ * @rates: available divisors for this parent clock
+ *
+ * A struct clksel is always associated with one or more struct clks
+ * and one or more struct clksel_rates.
+ */
 struct clksel {
        struct clk               *parent;
        const struct clksel_rate *rates;
@@ -116,6 +165,60 @@ struct dpll_data {
 
 #endif
 
+/* struct clk.flags possibilities */
+#define ENABLE_REG_32BIT       (1 << 0)        /* Use 32-bit access */
+#define CLOCK_IDLE_CONTROL     (1 << 1)
+#define CLOCK_NO_IDLE_PARENT   (1 << 2)
+#define ENABLE_ON_INIT         (1 << 3)        /* Enable upon framework init */
+#define INVERT_ENABLE          (1 << 4)        /* 0 enables, 1 disables */
+
+/**
+ * struct clk - OMAP struct clk
+ * @node: list_head connecting this clock into the full clock list
+ * @ops: struct clkops * for this clock
+ * @name: the name of the clock in the hardware (used in hwmod data and debug)
+ * @parent: pointer to this clock's parent struct clk
+ * @children: list_head connecting to the child clks' @sibling list_heads
+ * @sibling: list_head connecting this clk to its parent clk's @children
+ * @rate: current clock rate
+ * @enable_reg: register to write to enable the clock (see @enable_bit)
+ * @recalc: fn ptr that returns the clock's current rate
+ * @set_rate: fn ptr that can change the clock's current rate
+ * @round_rate: fn ptr that can round the clock's current rate
+ * @init: fn ptr to do clock-specific initialization
+ * @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg)
+ * @usecount: number of users that have requested this clock to be enabled
+ * @fixed_div: when > 0, this clock's rate is its parent's rate / @fixed_div
+ * @flags: see "struct clk.flags possibilities" above
+ * @clksel_reg: for clksel clks, register va containing src/divisor select
+ * @clksel_mask: bitmask in @clksel_reg for the src/divisor selector
+ * @clksel: for clksel clks, pointer to struct clksel for this clock
+ * @dpll_data: for DPLLs, pointer to struct dpll_data for this clock
+ * @clkdm_name: clockdomain name that this clock is contained in
+ * @clkdm: pointer to struct clockdomain, resolved from @clkdm_name at runtime
+ * @rate_offset: bitshift for rate selection bitfield (OMAP1 only)
+ * @src_offset: bitshift for source selection bitfield (OMAP1 only)
+ *
+ * XXX @rate_offset, @src_offset should probably be removed and OMAP1
+ * clock code converted to use clksel.
+ *
+ * XXX @usecount is poorly named.  It should be "enable_count" or
+ * something similar.  "users" in the description refers to kernel
+ * code (core code or drivers) that have called clk_enable() and not
+ * yet called clk_disable(); the usecount of parent clocks is also
+ * incremented by the clock code when clk_enable() is called on child
+ * clocks and decremented by the clock code when clk_disable() is
+ * called on child clocks.
+ *
+ * XXX @clkdm, @usecount, @children, @sibling should be marked for
+ * internal use only.
+ *
+ * @children and @sibling are used to optimize parent-to-child clock
+ * tree traversals.  (child-to-parent traversals use @parent.)
+ *
+ * XXX The notion of the clock's current rate probably needs to be
+ * separated from the clock's target rate.
+ */
 struct clk {
        struct list_head        node;
        const struct clkops     *ops;
@@ -129,8 +232,8 @@ struct clk {
        int                     (*set_rate)(struct clk *, unsigned long);
        long                    (*round_rate)(struct clk *, unsigned long);
        void                    (*init)(struct clk *);
-       __u8                    enable_bit;
-       __s8                    usecount;
+       u8                      enable_bit;
+       s8                      usecount;
        u8                      fixed_div;
        u8                      flags;
 #ifdef CONFIG_ARCH_OMAP2PLUS
@@ -141,8 +244,8 @@ struct clk {
        const char              *clkdm_name;
        struct clockdomain      *clkdm;
 #else
-       __u8                    rate_offset;
-       __u8                    src_offset;
+       u8                      rate_offset;
+       u8                      src_offset;
 #endif
 #if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
        struct dentry           *dent;  /* For visible tree hierarchy */
@@ -188,23 +291,4 @@ extern const struct clkops clkops_null;
 
 extern struct clk dummy_ck;
 
-/* Clock flags */
-#define ENABLE_REG_32BIT       (1 << 0)        /* Use 32-bit access */
-#define CLOCK_IDLE_CONTROL     (1 << 1)
-#define CLOCK_NO_IDLE_PARENT   (1 << 2)
-#define ENABLE_ON_INIT         (1 << 3)        /* Enable upon framework init */
-#define INVERT_ENABLE          (1 << 4)        /* 0 enables, 1 disables */
-
-/* Clksel_rate flags */
-#define RATE_IN_242X           (1 << 0)
-#define RATE_IN_243X           (1 << 1)
-#define RATE_IN_3XXX           (1 << 2)        /* rates common to all OMAP3 */
-#define RATE_IN_3430ES2                (1 << 3)        /* 3430ES2 rates only */
-#define RATE_IN_36XX           (1 << 4)
-#define RATE_IN_4430           (1 << 5)
-
-#define RATE_IN_24XX           (RATE_IN_242X | RATE_IN_243X)
-
-#define RATE_IN_3430ES2PLUS    (RATE_IN_3430ES2 | RATE_IN_36XX)
-
 #endif
index d265018f5e6b729a146a351388f3213dc8c72472..fe83e901ba6c585454b327e89d36f78976fe0e4d 100644 (file)
@@ -87,4 +87,8 @@ void omap2_set_globals_uart(struct omap_globals *);
        }                                                       \
 })
 
+extern struct device *omap2_get_mpuss_device(void);
+extern struct device *omap2_get_dsp_device(void);
+extern struct device *omap2_get_l3_device(void);
+
 #endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */
index 3ee41d7114929d771cadbb9f02191fd16c5b5abe..728fbb9dd549ac4bf987b2dfc2144371da184718 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * omap-pm.h - OMAP power management interface
  *
- * Copyright (C) 2008-2009 Texas Instruments, Inc.
- * Copyright (C) 2008-2009 Nokia Corporation
+ * Copyright (C) 2008-2010 Texas Instruments, Inc.
+ * Copyright (C) 2008-2010 Nokia Corporation
  * Paul Walmsley
  *
  * Interface developed by (in alphabetical order): Karthik Dasu, Jouni
@@ -16,6 +16,7 @@
 
 #include <linux/device.h>
 #include <linux/cpufreq.h>
+#include <linux/clk.h>
 
 #include "powerdomain.h"
 
@@ -89,7 +90,7 @@ void omap_pm_if_exit(void);
  * @t: maximum MPU wakeup latency in microseconds
  *
  * Request that the maximum interrupt latency for the MPU to be no
- * greater than 't' microseconds. "Interrupt latency" in this case is
+ * greater than @t microseconds. "Interrupt latency" in this case is
  * defined as the elapsed time from the occurrence of a hardware or
  * timer interrupt to the time when the device driver's interrupt
  * service routine has been entered by the MPU.
@@ -105,15 +106,19 @@ void omap_pm_if_exit(void);
  * elapsed from when a device driver enables a hardware device with
  * clk_enable(), to when the device is ready for register access or
  * other use.  To control this device wakeup latency, use
- * set_max_dev_wakeup_lat()
+ * omap_pm_set_max_dev_wakeup_lat()
  *
- * Multiple calls to set_max_mpu_wakeup_lat() will replace the
+ * Multiple calls to omap_pm_set_max_mpu_wakeup_lat() will replace the
  * previous t value.  To remove the latency target for the MPU, call
  * with t = -1.
  *
- * No return value.
+ * XXX This constraint will be deprecated soon in favor of the more
+ * general omap_pm_set_max_dev_wakeup_lat()
+ *
+ * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
+ * is not satisfiable, or 0 upon success.
  */
-void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t);
+int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t);
 
 
 /**
@@ -123,8 +128,8 @@ void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t);
  * @r: minimum throughput (in KiB/s)
  *
  * Request that the minimum data throughput on the OCP interconnect
- * attached to device 'dev' interconnect agent 'tbus_id' be no less
- * than 'r' KiB/s.
+ * attached to device @dev interconnect agent @tbus_id be no less
+ * than @r KiB/s.
  *
  * It is expected that the OMAP PM or bus code will use this
  * information to set the interconnect clock to run at the lowest
@@ -138,40 +143,44 @@ void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t);
  * code will also need to add an minimum L3 interconnect speed
  * constraint,
  *
- * Multiple calls to set_min_bus_tput() will replace the previous rate
- * value for this device.  To remove the interconnect throughput
- * restriction for this device, call with r = 0.
+ * Multiple calls to omap_pm_set_min_bus_tput() will replace the
+ * previous rate value for this device.  To remove the interconnect
+ * throughput restriction for this device, call with r = 0.
  *
- * No return value.
+ * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
+ * is not satisfiable, or 0 upon success.
  */
-void omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r);
+int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r);
 
 
 /**
  * omap_pm_set_max_dev_wakeup_lat - set the maximum device enable latency
- * @dev: struct device *
+ * @req_dev: struct device * requesting the constraint, or NULL if none
+ * @dev: struct device * to set the constraint one
  * @t: maximum device wakeup latency in microseconds
  *
- * Request that the maximum amount of time necessary for a device to
- * become accessible after its clocks are enabled should be no greater
- * than 't' microseconds.  Specifically, this represents the time from
- * when a device driver enables device clocks with clk_enable(), to
- * when the register reads and writes on the device will succeed.
- * This function should be called before clk_disable() is called,
- * since the power state transition decision may be made during
- * clk_disable().
+ * Request that the maximum amount of time necessary for a device @dev
+ * to become accessible after its clocks are enabled should be no
+ * greater than @t microseconds.  Specifically, this represents the
+ * time from when a device driver enables device clocks with
+ * clk_enable(), to when the register reads and writes on the device
+ * will succeed.  This function should be called before clk_disable()
+ * is called, since the power state transition decision may be made
+ * during clk_disable().
  *
  * It is intended that underlying PM code will use this information to
  * determine what power state to put the powerdomain enclosing this
  * device into.
  *
- * Multiple calls to set_max_dev_wakeup_lat() will replace the
- * previous wakeup latency values for this device.  To remove the wakeup
- * latency restriction for this device, call with t = -1.
+ * Multiple calls to omap_pm_set_max_dev_wakeup_lat() will replace the
+ * previous wakeup latency values for this device.  To remove the
+ * wakeup latency restriction for this device, call with t = -1.
  *
- * No return value.
+ * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
+ * is not satisfiable, or 0 upon success.
  */
-void omap_pm_set_max_dev_wakeup_lat(struct device *dev, long t);
+int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev,
+                                  long t);
 
 
 /**
@@ -198,10 +207,71 @@ void omap_pm_set_max_dev_wakeup_lat(struct device *dev, long t);
  * value for this device.  To remove the maximum DMA latency for this
  * device, call with t = -1.
  *
- * No return value.
+ * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
+ * is not satisfiable, or 0 upon success.
  */
-void omap_pm_set_max_sdma_lat(struct device *dev, long t);
+int omap_pm_set_max_sdma_lat(struct device *dev, long t);
+
 
+/**
+ * omap_pm_set_min_clk_rate - set minimum clock rate requested by @dev
+ * @dev: struct device * requesting the constraint
+ * @clk: struct clk * to set the minimum rate constraint on
+ * @r: minimum rate in Hz
+ *
+ * Request that the minimum clock rate on the device @dev's clk @clk
+ * be no less than @r Hz.
+ *
+ * It is expected that the OMAP PM code will use this information to
+ * find an OPP or clock setting that will satisfy this clock rate
+ * constraint, along with any other applicable system constraints on
+ * the clock rate or corresponding voltage, etc.
+ *
+ * omap_pm_set_min_clk_rate() differs from the clock code's
+ * clk_set_rate() in that it considers other constraints before taking
+ * any hardware action, and may change a system OPP rather than just a
+ * clock rate.  clk_set_rate() is intended to be a low-level
+ * interface.
+ *
+ * omap_pm_set_min_clk_rate() is easily open to abuse.  A better API
+ * would be something like "omap_pm_set_min_dev_performance()";
+ * however, there is no easily-generalizable concept of performance
+ * that applies to all devices.  Only a device (and possibly the
+ * device subsystem) has both the subsystem-specific knowledge, and
+ * the hardware IP block-specific knowledge, to translate a constraint
+ * on "touchscreen sampling accuracy" or "number of pixels or polygons
+ * rendered per second" to a clock rate.  This translation can be
+ * dependent on the hardware IP block's revision, or firmware version,
+ * and the driver is the only code on the system that has this
+ * information and can know how to translate that into a clock rate.
+ *
+ * The intended use-case for this function is for userspace or other
+ * kernel code to communicate a particular performance requirement to
+ * a subsystem; then for the subsystem to communicate that requirement
+ * to something that is meaningful to the device driver; then for the
+ * device driver to convert that requirement to a clock rate, and to
+ * then call omap_pm_set_min_clk_rate().
+ *
+ * Users of this function (such as device drivers) should not simply
+ * call this function with some high clock rate to ensure "high
+ * performance."  Rather, the device driver should take a performance
+ * constraint from its subsystem, such as "render at least X polygons
+ * per second," and use some formula or table to convert that into a
+ * clock rate constraint given the hardware type and hardware
+ * revision.  Device drivers or subsystems should not assume that they
+ * know how to make a power/performance tradeoff - some device use
+ * cases may tolerate a lower-fidelity device function for lower power
+ * consumption; others may demand a higher-fidelity device function,
+ * no matter what the power consumption.
+ *
+ * Multiple calls to omap_pm_set_min_clk_rate() will replace the
+ * previous rate value for the device @dev.  To remove the minimum clock
+ * rate constraint for the device, call with r = 0.
+ *
+ * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
+ * is not satisfiable, or 0 upon success.
+ */
+int omap_pm_set_min_clk_rate(struct device *dev, struct clk *c, long r);
 
 /*
  * DSP Bridge-specific constraints
index 3694b622c4acd4cf6b01bb8f19298fb6e968e1a8..25cd9ac3b0958eb1a61d166b485731be2a480dab 100644 (file)
@@ -101,6 +101,8 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
 int omap_device_register(struct omap_device *od);
 int omap_early_device_register(struct omap_device *od);
 
+void __iomem *omap_device_get_rt_va(struct omap_device *od);
+
 /* OMAP PM interface */
 int omap_device_align_pm_lat(struct platform_device *pdev,
                             u32 new_wakeup_lat_limit);
index 0eccc09ac4a9f634ebc782b88b979548d6da3c38..a4e508dfaba2716a46a9d20d1ac59337dce1fae2 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * omap_hwmod macros, structures
  *
- * Copyright (C) 2009 Nokia Corporation
+ * Copyright (C) 2009-2010 Nokia Corporation
  * Paul Walmsley
  *
  * Created in collaboration with (alphabetical order): BenoĆ®t Cousson,
@@ -419,7 +419,7 @@ struct omap_hwmod_class {
  * @slaves: ptr to array of OCP ifs that this hwmod can respond on
  * @dev_attr: arbitrary device attributes that can be passed to the driver
  * @_sysc_cache: internal-use hwmod flags
- * @_rt_va: cached register target start address (internal use)
+ * @_mpu_rt_va: cached register target start address (internal use)
  * @_mpu_port_index: cached MPU register target slave ID (internal use)
  * @msuspendmux_reg_id: CONTROL_MSUSPENDMUX register ID (1-6)
  * @msuspendmux_shift: CONTROL_MSUSPENDMUX register bit shift
@@ -460,7 +460,7 @@ struct omap_hwmod {
        struct omap_hwmod_ocp_if        **slaves;  /* connect to *_TA */
        void                            *dev_attr;
        u32                             _sysc_cache;
-       void __iomem                    *_rt_va;
+       void __iomem                    *_mpu_rt_va;
        struct list_head                node;
        u16                             flags;
        u8                              _mpu_port_index;
@@ -482,11 +482,14 @@ int omap_hwmod_init(struct omap_hwmod **ohs);
 int omap_hwmod_register(struct omap_hwmod *oh);
 int omap_hwmod_unregister(struct omap_hwmod *oh);
 struct omap_hwmod *omap_hwmod_lookup(const char *name);
-int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh));
-int omap_hwmod_late_init(void);
+int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data),
+                       void *data);
+int omap_hwmod_late_init(u8 skip_setup_idle);
 
 int omap_hwmod_enable(struct omap_hwmod *oh);
+int _omap_hwmod_enable(struct omap_hwmod *oh);
 int omap_hwmod_idle(struct omap_hwmod *oh);
+int _omap_hwmod_idle(struct omap_hwmod *oh);
 int omap_hwmod_shutdown(struct omap_hwmod *oh);
 
 int omap_hwmod_enable_clocks(struct omap_hwmod *oh);
@@ -504,6 +507,7 @@ int omap_hwmod_count_resources(struct omap_hwmod *oh);
 int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res);
 
 struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh);
+void __iomem *omap_hwmod_get_mpu_rt_va(struct omap_hwmod *oh);
 
 int omap_hwmod_add_initiator_dep(struct omap_hwmod *oh,
                                 struct omap_hwmod *init_oh);
index 186bca82cfab76dbe64cb8ebb883efedbee18ba2..e129ce80c53b515b934d940bfc5fe09163ddbbdd 100644 (file)
@@ -34,11 +34,11 @@ struct omap_opp *l3_opps;
  * Device-driver-originated constraints (via board-*.c files)
  */
 
-void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t)
+int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t)
 {
        if (!dev || t < -1) {
-               WARN_ON(1);
-               return;
+               WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
+               return -EINVAL;
        };
 
        if (t == -1)
@@ -58,14 +58,16 @@ void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t)
         *
         * TI CDP code can call constraint_set here.
         */
+
+       return 0;
 }
 
-void omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r)
+int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r)
 {
        if (!dev || (agent_id != OCP_INITIATOR_AGENT &&
            agent_id != OCP_TARGET_AGENT)) {
-               WARN_ON(1);
-               return;
+               WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
+               return -EINVAL;
        };
 
        if (r == 0)
@@ -83,13 +85,16 @@ void omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r)
         *
         * TI CDP code can call constraint_set here on the VDD2 OPP.
         */
+
+       return 0;
 }
 
-void omap_pm_set_max_dev_wakeup_lat(struct device *dev, long t)
+int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev,
+                                  long t)
 {
-       if (!dev || t < -1) {
-               WARN_ON(1);
-               return;
+       if (!req_dev || !dev || t < -1) {
+               WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
+               return -EINVAL;
        };
 
        if (t == -1)
@@ -111,13 +116,15 @@ void omap_pm_set_max_dev_wakeup_lat(struct device *dev, long t)
         *
         * TI CDP code can call constraint_set here.
         */
+
+       return 0;
 }
 
-void omap_pm_set_max_sdma_lat(struct device *dev, long t)
+int omap_pm_set_max_sdma_lat(struct device *dev, long t)
 {
        if (!dev || t < -1) {
-               WARN_ON(1);
-               return;
+               WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
+               return -EINVAL;
        };
 
        if (t == -1)
@@ -139,8 +146,36 @@ void omap_pm_set_max_sdma_lat(struct device *dev, long t)
         * TI CDP code can call constraint_set here.
         */
 
+       return 0;
 }
 
+int omap_pm_set_min_clk_rate(struct device *dev, struct clk *c, long r)
+{
+       if (!dev || !c || r < 0) {
+               WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
+               return -EINVAL;
+       }
+
+       if (r == 0)
+               pr_debug("OMAP PM: remove min clk rate constraint: "
+                        "dev %s\n", dev_name(dev));
+       else
+               pr_debug("OMAP PM: add min clk rate constraint: "
+                        "dev %s, rate = %ld Hz\n", dev_name(dev), r);
+
+       /*
+        * Code in a real implementation should keep track of these
+        * constraints on the clock, and determine the highest minimum
+        * clock rate.  It should iterate over each OPP and determine
+        * whether the OPP will result in a clock rate that would
+        * satisfy this constraint (and any other PM constraint in effect
+        * at that time).  Once it finds the lowest-voltage OPP that
+        * meets those conditions, it should switch to it, or return
+        * an error if the code is not capable of doing so.
+        */
+
+       return 0;
+}
 
 /*
  * DSP Bridge-specific constraints
index f899603051ac628b83cebd32badac5cf4c55ddad..ea0d659fcb1c54d52eb4d59fce283e8f154806bd 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * omap_device implementation
  *
- * Copyright (C) 2009 Nokia Corporation
+ * Copyright (C) 2009-2010 Nokia Corporation
  * Paul Walmsley, Kevin Hilman
  *
  * Developed in collaboration with (alphabetical order): Benoit
 #define USE_WAKEUP_LAT                 0
 #define IGNORE_WAKEUP_LAT              1
 
-
-#define OMAP_DEVICE_MAGIC 0xf00dcafe
+/*
+ * OMAP_DEVICE_MAGIC: used to determine whether a struct omap_device
+ * obtained via container_of() is in fact a struct omap_device
+ */
+#define OMAP_DEVICE_MAGIC               0xf00dcafe
 
 /* Private functions */
 
@@ -359,7 +362,7 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
        struct omap_device *od;
        char *pdev_name2;
        struct resource *res = NULL;
-       int res_count;
+       int i, res_count;
        struct omap_hwmod **hwmods;
 
        if (!ohs || oh_cnt == 0 || !pdev_name)
@@ -416,6 +419,9 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
        else
                ret = omap_device_register(od);
 
+       for (i = 0; i < oh_cnt; i++)
+               hwmods[i]->od = od;
+
        if (ret)
                goto odbs_exit4;
 
@@ -652,6 +658,25 @@ struct powerdomain *omap_device_get_pwrdm(struct omap_device *od)
        return omap_hwmod_get_pwrdm(od->hwmods[0]);
 }
 
+/**
+ * omap_device_get_mpu_rt_va - return the MPU's virtual addr for the hwmod base
+ * @od: struct omap_device *
+ *
+ * Return the MPU's virtual address for the base of the hwmod, from
+ * the ioremap() that the hwmod code does.  Only valid if there is one
+ * hwmod associated with this device.  Returns NULL if there are zero
+ * or more than one hwmods associated with this omap_device;
+ * otherwise, passes along the return value from
+ * omap_hwmod_get_mpu_rt_va().
+ */
+void __iomem *omap_device_get_rt_va(struct omap_device *od)
+{
+       if (od->hwmods_cnt != 1)
+               return NULL;
+
+       return omap_hwmod_get_mpu_rt_va(od->hwmods[0]);
+}
+
 /*
  * Public functions intended for use in omap_device_pm_latency
  * .activate_func and .deactivate_func function pointers