diff options
author | Tony Lindgren <tony@atomide.com> | 2010-12-22 11:32:24 -0800 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2010-12-22 11:32:24 -0800 |
commit | 808601b75804475c9022f6375e76b7c62c99a10a (patch) | |
tree | 355a3100269e88460e36f251ef0ce2f1ed88d52e /arch/arm/plat-omap | |
parent | c10abbb26513f4ccff89c4d80912cb4d36fcd3e8 (diff) | |
parent | f17f9726c27c3921e00a5750e85070e6dd7e1ff7 (diff) |
Merge branch 'integration-2.6.38-for-tony' of git://git.pwsan.com/linux-2.6 into omap-for-linus
Diffstat (limited to 'arch/arm/plat-omap')
-rw-r--r-- | arch/arm/plat-omap/gpio.c | 5 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/clkdev_omap.h | 20 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/clock.h | 16 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/clockdomain.h | 141 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/common.h | 2 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/gpio.h | 2 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/io.h | 5 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/omap-pm.h | 8 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/omap_device.h | 1 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/omap_hwmod.h | 55 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/powerdomain.h | 167 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/prcm.h | 20 | ||||
-rw-r--r-- | arch/arm/plat-omap/mcbsp.c | 10 | ||||
-rw-r--r-- | arch/arm/plat-omap/omap-pm-noop.c | 67 | ||||
-rw-r--r-- | arch/arm/plat-omap/omap_device.c | 28 | ||||
-rw-r--r-- | arch/arm/plat-omap/sram.c | 5 |
16 files changed, 164 insertions, 388 deletions
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 8d493b992e7..1f98e0b9484 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -29,7 +29,6 @@ #include <mach/irqs.h> #include <mach/gpio.h> #include <asm/mach/irq.h> -#include <plat/powerdomain.h> /* * OMAP1510 GPIO registers @@ -1864,7 +1863,7 @@ static struct sys_device omap_gpio_device = { static int workaround_enabled; -void omap2_gpio_prepare_for_idle(int power_state) +void omap2_gpio_prepare_for_idle(int off_mode) { int i, c = 0; int min = 0; @@ -1880,7 +1879,7 @@ void omap2_gpio_prepare_for_idle(int power_state) for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++) clk_disable(bank->dbck); - if (power_state > PWRDM_POWER_OFF) + if (!off_mode) continue; /* If going to OFF, remove triggering for all diff --git a/arch/arm/plat-omap/include/plat/clkdev_omap.h b/arch/arm/plat-omap/include/plat/clkdev_omap.h index bb937f3fabe..b19774c9c11 100644 --- a/arch/arm/plat-omap/include/plat/clkdev_omap.h +++ b/arch/arm/plat-omap/include/plat/clkdev_omap.h @@ -31,18 +31,18 @@ struct omap_clk { #define CK_1510 (1 << 2) #define CK_16XX (1 << 3) /* 16xx, 17xx, 5912 */ #define CK_242X (1 << 4) -#define CK_243X (1 << 5) -#define CK_3XXX (1 << 6) /* OMAP3 + AM3 common clocks*/ -#define CK_343X (1 << 7) /* OMAP34xx common clocks */ -#define CK_3430ES1 (1 << 8) /* 34xxES1 only */ -#define CK_3430ES2 (1 << 9) /* 34xxES2, ES3, non-Sitara 35xx only */ -#define CK_3505 (1 << 10) -#define CK_3517 (1 << 11) -#define CK_36XX (1 << 12) /* OMAP36xx/37xx-specific clocks */ -#define CK_443X (1 << 13) +#define CK_243X (1 << 5) /* 243x, 253x */ +#define CK_3430ES1 (1 << 6) /* 34xxES1 only */ +#define CK_3430ES2PLUS (1 << 7) /* 34xxES2, ES3, non-Sitara 35xx only */ +#define CK_3505 (1 << 8) +#define CK_3517 (1 << 9) +#define CK_36XX (1 << 10) /* 36xx/37xx-specific clocks */ +#define CK_443X (1 << 11) -#define CK_AM35XX (CK_3505 | CK_3517) /* all Sitara AM35xx */ +#define CK_34XX (CK_3430ES1 | CK_3430ES2PLUS) +#define CK_AM35XX (CK_3505 | CK_3517) /* all Sitara AM35xx */ +#define CK_3XXX (CK_34XX | CK_AM35XX | CK_36XX) #endif diff --git a/arch/arm/plat-omap/include/plat/clock.h b/arch/arm/plat-omap/include/plat/clock.h index fef4696dcf6..8eb0adab19e 100644 --- a/arch/arm/plat-omap/include/plat/clock.h +++ b/arch/arm/plat-omap/include/plat/clock.h @@ -49,13 +49,18 @@ struct clkops { /* 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_3430ES1 (1 << 2) /* 3430ES1 rates only */ +#define RATE_IN_3430ES2PLUS (1 << 3) /* 3430 ES >= 2 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) +#define RATE_IN_34XX (RATE_IN_3430ES1 | RATE_IN_3430ES2PLUS) +#define RATE_IN_3XXX (RATE_IN_34XX | RATE_IN_36XX) + +/* RATE_IN_3430ES2PLUS_36XX includes 34xx/35xx with ES >=2, and all 36xx/37xx */ +#define RATE_IN_3430ES2PLUS_36XX (RATE_IN_3430ES2PLUS | RATE_IN_36XX) + /** * struct clksel_rate - register bitfield values corresponding to clk divisors @@ -119,8 +124,7 @@ struct clksel { * * Possible values for @flags: * DPLL_J_TYPE: "J-type DPLL" (only some 36xx, 4xxx DPLLs) - * NO_DCO_SEL: don't program DCO (only for some J-type DPLLs) - + * * @freqsel_mask is only used on the OMAP34xx family and AM35xx. * * XXX Some DPLLs have multiple bypass inputs, so it's not technically @@ -156,6 +160,8 @@ struct dpll_data { u32 autoidle_mask; u32 freqsel_mask; u32 idlest_mask; + u32 dco_mask; + u32 sddiv_mask; u8 auto_recal_bit; u8 recal_en_bit; u8 recal_st_bit; diff --git a/arch/arm/plat-omap/include/plat/clockdomain.h b/arch/arm/plat-omap/include/plat/clockdomain.h deleted file mode 100644 index ba0a6c07c0f..00000000000 --- a/arch/arm/plat-omap/include/plat/clockdomain.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - * arch/arm/plat-omap/include/mach/clockdomain.h - * - * OMAP2/3 clockdomain framework functions - * - * Copyright (C) 2008 Texas Instruments, Inc. - * Copyright (C) 2008-2009 Nokia Corporation - * - * Written by Paul Walmsley - * - * 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. - */ - -#ifndef __ASM_ARM_ARCH_OMAP_CLOCKDOMAIN_H -#define __ASM_ARM_ARCH_OMAP_CLOCKDOMAIN_H - -#include <plat/powerdomain.h> -#include <plat/clock.h> -#include <plat/cpu.h> - -/* Clockdomain capability flags */ -#define CLKDM_CAN_FORCE_SLEEP (1 << 0) -#define CLKDM_CAN_FORCE_WAKEUP (1 << 1) -#define CLKDM_CAN_ENABLE_AUTO (1 << 2) -#define CLKDM_CAN_DISABLE_AUTO (1 << 3) - -#define CLKDM_CAN_HWSUP (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_DISABLE_AUTO) -#define CLKDM_CAN_SWSUP (CLKDM_CAN_FORCE_SLEEP | CLKDM_CAN_FORCE_WAKEUP) -#define CLKDM_CAN_HWSUP_SWSUP (CLKDM_CAN_SWSUP | CLKDM_CAN_HWSUP) - -/* OMAP24XX CM_CLKSTCTRL_*.AUTOSTATE_* register bit values */ -#define OMAP24XX_CLKSTCTRL_DISABLE_AUTO 0x0 -#define OMAP24XX_CLKSTCTRL_ENABLE_AUTO 0x1 - -/* OMAP3XXX CM_CLKSTCTRL_*.CLKTRCTRL_* register bit values */ -#define OMAP34XX_CLKSTCTRL_DISABLE_AUTO 0x0 -#define OMAP34XX_CLKSTCTRL_FORCE_SLEEP 0x1 -#define OMAP34XX_CLKSTCTRL_FORCE_WAKEUP 0x2 -#define OMAP34XX_CLKSTCTRL_ENABLE_AUTO 0x3 - -/** - * struct clkdm_autodep - clkdm deps to add when entering/exiting hwsup mode - * @clkdm: clockdomain to add wkdep+sleepdep on - set name member only - * @omap_chip: OMAP chip types that this autodep is valid on - * - * A clockdomain that should have wkdeps and sleepdeps added when a - * clockdomain should stay active in hwsup mode; and conversely, - * removed when the clockdomain should be allowed to go inactive in - * hwsup mode. - * - * Autodeps are deprecated and should be removed after - * omap_hwmod-based fine-grained module idle control is added. - */ -struct clkdm_autodep { - union { - const char *name; - struct clockdomain *ptr; - } clkdm; - const struct omap_chip_id omap_chip; -}; - -/** - * struct clkdm_dep - encode dependencies between clockdomains - * @clkdm_name: clockdomain name - * @clkdm: pointer to the struct clockdomain of @clkdm_name - * @omap_chip: OMAP chip types that this dependency is valid on - * @wkdep_usecount: Number of wakeup dependencies causing this clkdm to wake - * @sleepdep_usecount: Number of sleep deps that could prevent clkdm from idle - * - * Statically defined. @clkdm is resolved from @clkdm_name at runtime and - * should not be pre-initialized. - * - * XXX Should also include hardware (fixed) dependencies. - */ -struct clkdm_dep { - const char *clkdm_name; - struct clockdomain *clkdm; - atomic_t wkdep_usecount; - atomic_t sleepdep_usecount; - const struct omap_chip_id omap_chip; -}; - -/** - * struct clockdomain - OMAP clockdomain - * @name: clockdomain name - * @pwrdm: powerdomain containing this clockdomain - * @clktrctrl_reg: CLKSTCTRL reg for the given clock domain - * @clktrctrl_mask: CLKTRCTRL/AUTOSTATE field mask in CM_CLKSTCTRL reg - * @flags: Clockdomain capability flags - * @dep_bit: Bit shift of this clockdomain's PM_WKDEP/CM_SLEEPDEP bit - * @wkdep_srcs: Clockdomains that can be told to wake this powerdomain up - * @sleepdep_srcs: Clockdomains that can be told to keep this clkdm from inact - * @omap_chip: OMAP chip types that this clockdomain is valid on - * @usecount: Usecount tracking - * @node: list_head to link all clockdomains together - */ -struct clockdomain { - const char *name; - union { - const char *name; - struct powerdomain *ptr; - } pwrdm; - void __iomem *clkstctrl_reg; - const u16 clktrctrl_mask; - const u8 flags; - const u8 dep_bit; - struct clkdm_dep *wkdep_srcs; - struct clkdm_dep *sleepdep_srcs; - const struct omap_chip_id omap_chip; - atomic_t usecount; - struct list_head node; -}; - -void clkdm_init(struct clockdomain **clkdms, struct clkdm_autodep *autodeps); -struct clockdomain *clkdm_lookup(const char *name); - -int clkdm_for_each(int (*fn)(struct clockdomain *clkdm, void *user), - void *user); -struct powerdomain *clkdm_get_pwrdm(struct clockdomain *clkdm); - -int clkdm_add_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2); -int clkdm_del_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2); -int clkdm_read_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2); -int clkdm_clear_all_wkdeps(struct clockdomain *clkdm); -int clkdm_add_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2); -int clkdm_del_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2); -int clkdm_read_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2); -int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm); - -void omap2_clkdm_allow_idle(struct clockdomain *clkdm); -void omap2_clkdm_deny_idle(struct clockdomain *clkdm); - -int omap2_clkdm_wakeup(struct clockdomain *clkdm); -int omap2_clkdm_sleep(struct clockdomain *clkdm); - -int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk); -int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk); - -#endif diff --git a/arch/arm/plat-omap/include/plat/common.h b/arch/arm/plat-omap/include/plat/common.h index a9d69a09920..6b8088ec74a 100644 --- a/arch/arm/plat-omap/include/plat/common.h +++ b/arch/arm/plat-omap/include/plat/common.h @@ -27,6 +27,8 @@ #ifndef __ARCH_ARM_MACH_OMAP_COMMON_H #define __ARCH_ARM_MACH_OMAP_COMMON_H +#include <linux/delay.h> + #include <plat/i2c.h> struct sys_timer; diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h index 41ff2f8943f..d6f9fa0f62a 100644 --- a/arch/arm/plat-omap/include/plat/gpio.h +++ b/arch/arm/plat-omap/include/plat/gpio.h @@ -82,7 +82,7 @@ struct omap_gpio_platform_data { /* TODO: Analyze removing gpio_bank_count usage from driver code */ extern int gpio_bank_count; -extern void omap2_gpio_prepare_for_idle(int power_state); +extern void omap2_gpio_prepare_for_idle(int off_mode); extern void omap2_gpio_resume_after_idle(void); extern void omap_set_gpio_debounce(int gpio, int enable); extern void omap_set_gpio_debounce_time(int gpio, int enable); diff --git a/arch/arm/plat-omap/include/plat/io.h b/arch/arm/plat-omap/include/plat/io.h index 204865f91d9..ef4106c1318 100644 --- a/arch/arm/plat-omap/include/plat/io.h +++ b/arch/arm/plat-omap/include/plat/io.h @@ -291,8 +291,9 @@ static inline void omap44xx_map_common_io(void) } #endif -extern void omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0, - struct omap_sdrc_params *sdrc_cs1); +extern void omap2_init_common_infrastructure(void); +extern void omap2_init_common_devices(struct omap_sdrc_params *sdrc_cs0, + struct omap_sdrc_params *sdrc_cs1); #define __arch_ioremap omap_ioremap #define __arch_iounmap omap_iounmap diff --git a/arch/arm/plat-omap/include/plat/omap-pm.h b/arch/arm/plat-omap/include/plat/omap-pm.h index 62c3fe918ab..c0a75205303 100644 --- a/arch/arm/plat-omap/include/plat/omap-pm.h +++ b/arch/arm/plat-omap/include/plat/omap-pm.h @@ -19,8 +19,6 @@ #include <linux/clk.h> #include <linux/opp.h> -#include "powerdomain.h" - /* * agent_id values for use with omap_pm_set_min_bus_tput(): * @@ -352,9 +350,11 @@ unsigned long omap_pm_cpu_get_freq(void); * driver must restore device context. If the number of context losses * exceeds the maximum positive integer, the function will wrap to 0 and * continue counting. Returns the number of context losses for this device, - * or -EINVAL upon error. + * or zero upon error. */ -int omap_pm_get_dev_context_loss_count(struct device *dev); +u32 omap_pm_get_dev_context_loss_count(struct device *dev); +void omap_pm_enable_off_mode(void); +void omap_pm_disable_off_mode(void); #endif diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h index 28e2d1a7843..e4c349ff9fd 100644 --- a/arch/arm/plat-omap/include/plat/omap_device.h +++ b/arch/arm/plat-omap/include/plat/omap_device.h @@ -107,6 +107,7 @@ void __iomem *omap_device_get_rt_va(struct omap_device *od); int omap_device_align_pm_lat(struct platform_device *pdev, u32 new_wakeup_lat_limit); struct powerdomain *omap_device_get_pwrdm(struct omap_device *od); +u32 omap_device_get_context_loss_count(struct platform_device *pdev); /* Other */ diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index 7eaa8edf3b1..2825b456da0 100644 --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -23,7 +23,7 @@ * - add pinmuxing * - init_conn_id_bit (CONNID_BIT_VECTOR) * - implement default hwmod SMS/SDRC flags? - * - remove unused fields + * - move Linux-specific data ("non-ROM data") out * */ #ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD_H @@ -32,7 +32,7 @@ #include <linux/kernel.h> #include <linux/list.h> #include <linux/ioport.h> -#include <linux/mutex.h> +#include <linux/spinlock.h> #include <plat/cpu.h> struct omap_device; @@ -76,6 +76,8 @@ extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type2; #define HWMOD_IDLEMODE_FORCE (1 << 0) #define HWMOD_IDLEMODE_NO (1 << 1) #define HWMOD_IDLEMODE_SMART (1 << 2) +/* Slave idle mode flag only */ +#define HWMOD_IDLEMODE_SMART_WKUP (1 << 3) /** * struct omap_hwmod_irq_info - MPU IRQs used by the hwmod @@ -159,7 +161,7 @@ struct omap_hwmod_omap2_firewall { * ADDR_MAP_ON_INIT: Map this address space during omap_hwmod init. * ADDR_TYPE_RT: Address space contains module register target data. */ -#define ADDR_MAP_ON_INIT (1 << 0) +#define ADDR_MAP_ON_INIT (1 << 0) /* XXX does not belong */ #define ADDR_TYPE_RT (1 << 1) /** @@ -200,8 +202,6 @@ struct omap_hwmod_addr_space { * @fw: interface firewall data * @addr_cnt: ARRAY_SIZE(@addr) * @width: OCP data width - * @thread_cnt: number of threads - * @max_burst_len: maximum burst length in @width sized words (0 if unlimited) * @user: initiators using this interface (see OCP_USER_* macros above) * @flags: OCP interface flags (see OCPIF_* macros above) * @@ -221,8 +221,6 @@ struct omap_hwmod_ocp_if { } fw; u8 addr_cnt; u8 width; - u8 thread_cnt; - u8 max_burst_len; u8 user; u8 flags; }; @@ -231,11 +229,12 @@ struct omap_hwmod_ocp_if { /* Macros for use in struct omap_hwmod_sysconfig */ /* Flags for use in omap_hwmod_sysconfig.idlemodes */ -#define MASTER_STANDBY_SHIFT 2 +#define MASTER_STANDBY_SHIFT 4 #define SLAVE_IDLE_SHIFT 0 #define SIDLE_FORCE (HWMOD_IDLEMODE_FORCE << SLAVE_IDLE_SHIFT) #define SIDLE_NO (HWMOD_IDLEMODE_NO << SLAVE_IDLE_SHIFT) #define SIDLE_SMART (HWMOD_IDLEMODE_SMART << SLAVE_IDLE_SHIFT) +#define SIDLE_SMART_WKUP (HWMOD_IDLEMODE_SMART_WKUP << SLAVE_IDLE_SHIFT) #define MSTANDBY_FORCE (HWMOD_IDLEMODE_FORCE << MASTER_STANDBY_SHIFT) #define MSTANDBY_NO (HWMOD_IDLEMODE_NO << MASTER_STANDBY_SHIFT) #define MSTANDBY_SMART (HWMOD_IDLEMODE_SMART << MASTER_STANDBY_SHIFT) @@ -357,14 +356,14 @@ struct omap_hwmod_omap4_prcm { * HWMOD_SWSUP_MSTDBY: omap_hwmod code should manually bring module in and out * of standby, rather than relying on module smart-standby * HWMOD_INIT_NO_RESET: don't reset this module at boot - important for - * SDRAM controller, etc. + * SDRAM controller, etc. XXX probably belongs outside the main hwmod file * HWMOD_INIT_NO_IDLE: don't idle this module at boot - important for SDRAM - * controller, etc. + * controller, etc. XXX probably belongs outside the main hwmod file * HWMOD_NO_AUTOIDLE: disable module autoidle (OCP_SYSCONFIG.AUTOIDLE) * when module is enabled, rather than the default, which is to * enable autoidle * HWMOD_SET_DEFAULT_CLOCKACT: program CLOCKACTIVITY bits at startup - * HWMOD_NO_IDLEST : this module does not have idle status - this is the case + * HWMOD_NO_IDLEST: this module does not have idle status - this is the case * only for few initiator modules on OMAP2 & 3. * HWMOD_CONTROL_OPT_CLKS_IN_RESET: Enable all optional clocks during reset. * This is needed for devices like DSS that require optional clocks enabled @@ -415,14 +414,31 @@ struct omap_hwmod_omap4_prcm { * @name: name of the hwmod_class * @sysc: device SYSCONFIG/SYSSTATUS register data * @rev: revision of the IP class + * @pre_shutdown: ptr to fn to be executed immediately prior to device shutdown + * @reset: ptr to fn to be executed in place of the standard hwmod reset fn * * Represent the class of a OMAP hardware "modules" (e.g. timer, * smartreflex, gpio, uart...) + * + * @pre_shutdown is a function that will be run immediately before + * hwmod clocks are disabled, etc. It is intended for use for hwmods + * like the MPU watchdog, which cannot be disabled with the standard + * omap_hwmod_shutdown(). The function should return 0 upon success, + * or some negative error upon failure. Returning an error will cause + * omap_hwmod_shutdown() to abort the device shutdown and return an + * error. + * + * If @reset is defined, then the function it points to will be + * executed in place of the standard hwmod _reset() code in + * mach-omap2/omap_hwmod.c. This is needed for IP blocks which have + * unusual reset sequences - usually processor IP blocks like the IVA. */ struct omap_hwmod_class { const char *name; struct omap_hwmod_class_sysconfig *sysc; u32 rev; + int (*pre_shutdown)(struct omap_hwmod *oh); + int (*reset)(struct omap_hwmod *oh); }; /** @@ -442,8 +458,6 @@ struct omap_hwmod_class { * @_sysc_cache: internal-use hwmod flags * @_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 * @mpu_irqs_cnt: number of @mpu_irqs * @sdma_reqs_cnt: number of @sdma_reqs * @opt_clks_cnt: number of @opt_clks @@ -452,9 +466,10 @@ struct omap_hwmod_class { * @response_lat: device OCP response latency (in interface clock cycles) * @_int_flags: internal-use hwmod flags * @_state: internal-use hwmod state + * @_postsetup_state: internal-use state to leave the hwmod in after _setup() * @flags: hwmod flags (documented below) * @omap_chip: OMAP chips this hwmod is present on - * @_mutex: mutex serializing operations on this hwmod + * @_lock: spinlock serializing operations on this hwmod * @node: list node for hwmod list (internal use) * * @main_clk refers to this module's "main clock," which for our @@ -484,12 +499,10 @@ struct omap_hwmod { void *dev_attr; u32 _sysc_cache; void __iomem *_mpu_rt_va; - struct mutex _mutex; + spinlock_t _lock; struct list_head node; u16 flags; u8 _mpu_port_index; - u8 msuspendmux_reg_id; - u8 msuspendmux_shift; u8 response_lat; u8 mpu_irqs_cnt; u8 sdma_reqs_cnt; @@ -500,16 +513,15 @@ struct omap_hwmod { u8 hwmods_cnt; u8 _int_flags; u8 _state; + u8 _postsetup_state; const struct omap_chip_id omap_chip; }; 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, void *data), void *data); -int omap_hwmod_late_init(u8 skip_setup_idle); +int omap_hwmod_late_init(void); int omap_hwmod_enable(struct omap_hwmod *oh); int _omap_hwmod_enable(struct omap_hwmod *oh); @@ -556,6 +568,9 @@ int omap_hwmod_for_each_by_class(const char *classname, void *user), void *user); +int omap_hwmod_set_postsetup_state(struct omap_hwmod *oh, u8 state); +u32 omap_hwmod_get_context_loss_count(struct omap_hwmod *oh); + /* * Chip variant-specific hwmod init routines - XXX should be converted * to use initcalls once the initial boot ordering is straightened out diff --git a/arch/arm/plat-omap/include/plat/powerdomain.h b/arch/arm/plat-omap/include/plat/powerdomain.h deleted file mode 100644 index 9ca420dcd2f..00000000000 --- a/arch/arm/plat-omap/include/plat/powerdomain.h +++ /dev/null @@ -1,167 +0,0 @@ -/* - * OMAP2/3 powerdomain control - * - * Copyright (C) 2007-2008 Texas Instruments, Inc. - * Copyright (C) 2007-2009 Nokia Corporation - * - * Written by Paul Walmsley - * - * 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. - */ - -#ifndef ASM_ARM_ARCH_OMAP_POWERDOMAIN -#define ASM_ARM_ARCH_OMAP_POWERDOMAIN - -#include <linux/types.h> -#include <linux/list.h> - -#include <asm/atomic.h> - -#include <plat/cpu.h> - - -/* Powerdomain basic power states */ -#define PWRDM_POWER_OFF 0x0 -#define PWRDM_POWER_RET 0x1 -#define PWRDM_POWER_INACTIVE 0x2 -#define PWRDM_POWER_ON 0x3 - -#define PWRDM_MAX_PWRSTS 4 - -/* Powerdomain allowable state bitfields */ -#define PWRSTS_ON (1 << PWRDM_POWER_ON) -#define PWRSTS_OFF (1 << PWRDM_POWER_OFF) -#define PWRSTS_OFF_ON ((1 << PWRDM_POWER_OFF) | \ - (1 << PWRDM_POWER_ON)) - -#define PWRSTS_OFF_RET ((1 << PWRDM_POWER_OFF) | \ - (1 << PWRDM_POWER_RET)) - -#define PWRSTS_RET_ON ((1 << PWRDM_POWER_RET) | \ - (1 << PWRDM_POWER_ON)) - -#define PWRSTS_OFF_RET_ON (PWRSTS_OFF_RET | (1 << PWRDM_POWER_ON)) - - -/* Powerdomain flags */ -#define PWRDM_HAS_HDWR_SAR (1 << 0) /* hardware save-and-restore support */ -#define PWRDM_HAS_MPU_QUIRK (1 << 1) /* MPU pwr domain has MEM bank 0 bits - * in MEM bank 1 position. This is - * true for OMAP3430 - */ -#define PWRDM_HAS_LOWPOWERSTATECHANGE (1 << 2) /* - * support to transition from a - * sleep state to a lower sleep - * state without waking up the - * powerdomain - */ - -/* - * Number of memory banks that are power-controllable. On OMAP4430, the - * maximum is 5. - */ -#define PWRDM_MAX_MEM_BANKS 5 - -/* - * Maximum number of clockdomains that can be associated with a powerdomain. - * CORE powerdomain on OMAP4 is the worst case - */ -#define PWRDM_MAX_CLKDMS 9 - -/* XXX A completely arbitrary number. What is reasonable here? */ -#define PWRDM_TRANSITION_BAILOUT 100000 - -struct clockdomain; -struct powerdomain; - -/** - * struct powerdomain - OMAP powerdomain - * @name: Powerdomain name - * @omap_chip: represents the OMAP chip types containing this pwrdm - * @prcm_offs: the address offset from CM_BASE/PRM_BASE - * @pwrsts: Possible powerdomain power states - * @pwrsts_logic_ret: Possible logic power states when pwrdm in RETENTION - * @flags: Powerdomain flags - * @banks: Number of software-controllable memory banks in this powerdomain - * @pwrsts_mem_ret: Possible memory bank pwrstates when pwrdm in RETENTION - * @pwrsts_mem_on: Possible memory bank pwrstates when pwrdm in ON - * @pwrdm_clkdms: Clockdomains in this powerdomain - * @node: list_head linking all powerdomains - * @state: - * @state_counter: - * @timer: - * @state_timer: - */ -struct powerdomain { - const char *name; - const struct omap_chip_id omap_chip; - const s16 prcm_offs; - const u8 pwrsts; - const u8 pwrsts_logic_ret; - const u8 flags; - const u8 banks; - const u8 pwrsts_mem_ret[PWRDM_MAX_MEM_BANKS]; - const u8 pwrsts_mem_on[PWRDM_MAX_MEM_BANKS]; - struct clockdomain *pwrdm_clkdms[PWRDM_MAX_CLKDMS]; - struct list_head node; - int state; - unsigned state_counter[PWRDM_MAX_PWRSTS]; - unsigned ret_logic_off_counter; - unsigned ret_mem_off_counter[PWRDM_MAX_MEM_BANKS]; - -#ifdef CONFIG_PM_DEBUG - s64 timer; - s64 state_timer[PWRDM_MAX_PWRSTS]; -#endif -}; - - -void pwrdm_init(struct powerdomain **pwrdm_list); - -struct powerdomain *pwrdm_lookup(const char *name); - -int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user), - void *user); -int pwrdm_for_each_nolock(int (*fn)(struct powerdomain *pwrdm, void *user), - void *user); - -int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm); -int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm); -int pwrdm_for_each_clkdm(struct powerdomain *pwrdm, - int (*fn)(struct powerdomain *pwrdm, - struct clockdomain *clkdm)); - -int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm); - -int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst); -int pwrdm_read_next_pwrst(struct powerdomain *pwrdm); -int pwrdm_read_pwrst(struct powerdomain *pwrdm); -int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm); -int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm); - -int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst); -int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst); -int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst); - -int pwrdm_read_logic_pwrst(struct powerdomain *pwrdm); -int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm); -int pwrdm_read_logic_retst(struct powerdomain *pwrdm); -int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank); -int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank); -int pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank); - -int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm); -int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm); -bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm); - -int pwrdm_wait_transition(struct powerdomain *pwrdm); - -int pwrdm_state_switch(struct powerdomain *pwrdm); -int pwrdm_clkdm_state_switch(struct clockdomain *clkdm); -int pwrdm_pre_transition(void); -int pwrdm_post_transition(void); -int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm); - -#endif diff --git a/arch/arm/plat-omap/include/plat/prcm.h b/arch/arm/plat-omap/include/plat/prcm.h index ab77442e42a..2fdf8c80d39 100644 --- a/arch/arm/plat-omap/include/plat/prcm.h +++ b/arch/arm/plat-omap/include/plat/prcm.h @@ -18,6 +18,10 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * XXX This file is deprecated. The PRCM is an OMAP2+-only subsystem, + * so this file doesn't belong in plat-omap/include/plat. Please + * do not add anything new to this file. */ #ifndef __ASM_ARM_ARCH_OMAP_PRCM_H @@ -28,22 +32,6 @@ void omap_prcm_arch_reset(char mode, const char *cmd); int omap2_cm_wait_idlest(void __iomem *reg, u32 mask, u8 idlest, const char *name); -#define START_PADCONF_SAVE 0x2 -#define PADCONF_SAVE_DONE 0x1 - -void omap3_prcm_save_context(void); -void omap3_prcm_restore_context(void); - -u32 prm_read_mod_reg(s16 module, u16 idx); -void prm_write_mod_reg(u32 val, s16 module, u16 idx); -u32 prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx); -u32 prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask); -u32 omap4_prm_read_bits_shift(void __iomem *reg, u32 mask); -u32 omap4_prm_rmw_reg_bits(u32 mask, u32 bits, void __iomem *reg); -u32 cm_read_mod_reg(s16 module, u16 idx); -void cm_write_mod_reg(u32 val, s16 module, u16 idx); -u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx); - #endif diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index fdecd339d4f..b5a6e178a7f 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c @@ -28,6 +28,8 @@ #include <plat/dma.h> #include <plat/mcbsp.h> +/* XXX These "sideways" includes are a sign that something is wrong */ +#include "../mach-omap2/cm2xxx_3xxx.h" #include "../mach-omap2/cm-regbits-34xx.h" struct omap_mcbsp **mcbsp_ptr; @@ -234,9 +236,9 @@ static void omap_st_on(struct omap_mcbsp *mcbsp) * Sidetone uses McBSP ICLK - which must not idle when sidetones * are enabled or sidetones start sounding ugly. */ - w = cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE); + w = omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE); w &= ~(1 << (mcbsp->id - 2)); - cm_write_mod_reg(w, OMAP3430_PER_MOD, CM_AUTOIDLE); + omap2_cm_write_mod_reg(w, OMAP3430_PER_MOD, CM_AUTOIDLE); /* Enable McBSP Sidetone */ w = MCBSP_READ(mcbsp, SSELCR); @@ -263,9 +265,9 @@ static void omap_st_off(struct omap_mcbsp *mcbsp) w = MCBSP_READ(mcbsp, SSELCR); MCBSP_WRITE(mcbsp, SSELCR, w & ~(SIDETONEEN)); - w = cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE); + w = omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE); w |= 1 << (mcbsp->id - 2); - cm_write_mod_reg(w, OMAP3430_PER_MOD, CM_AUTOIDLE); + omap2_cm_write_mod_reg(w, OMAP3430_PER_MOD, CM_AUTOIDLE); } static void omap_st_fir_write(struct omap_mcbsp *mcbsp, s16 *fir) diff --git a/arch/arm/plat-omap/omap-pm-noop.c b/arch/arm/plat-omap/omap-pm-noop.c index ca75abb1806..b0471bb2d47 100644 --- a/arch/arm/plat-omap/omap-pm-noop.c +++ b/arch/arm/plat-omap/omap-pm-noop.c @@ -20,11 +20,14 @@ #include <linux/init.h> #include <linux/cpufreq.h> #include <linux/device.h> +#include <linux/platform_device.h> /* Interface documentation is in mach/omap-pm.h */ #include <plat/omap-pm.h> +#include <plat/omap_device.h> -#include <plat/powerdomain.h> +static bool off_mode_enabled; +static u32 dummy_context_loss_counter; /* * Device-driver-originated constraints (via board-*.c files) @@ -280,28 +283,66 @@ unsigned long omap_pm_cpu_get_freq(void) return 0; } +/** + * omap_pm_enable_off_mode - notify OMAP PM that off-mode is enabled + * + * Intended for use only by OMAP PM core code to notify this layer + * that off mode has been enabled. + */ +void omap_pm_enable_off_mode(void) +{ + off_mode_enabled = true; +} + +/** + * omap_pm_disable_off_mode - notify OMAP PM that off-mode is disabled + * + * Intended for use only by OMAP PM core code to notify this layer + * that off mode has been disabled. + */ +void omap_pm_disable_off_mode(void) +{ + off_mode_enabled = false; +} + /* * Device context loss tracking */ -int omap_pm_get_dev_context_loss_count(struct device *dev) +#ifdef CONFIG_ARCH_OMAP2PLUS + +u32 omap_pm_get_dev_context_loss_count(struct device *dev) { - if (!dev) { - WARN_ON(1); - return -EINVAL; - }; + struct platform_device *pdev = to_platform_device(dev); + u32 count; + + if (WARN_ON(!dev)) + return 0; + + if (dev->parent == &omap_device_parent) { + count = omap_device_get_context_loss_count(pdev); + } else { + WARN_ONCE(off_mode_enabled, "omap_pm: using dummy context loss counter; device %s should be converted to omap_device", + dev_name(dev)); + if (off_mode_enabled) + dummy_context_loss_counter++; + count = dummy_context_loss_counter; + } - pr_debug("OMAP PM: returning context loss count for dev %s\n", - dev_name(dev)); + pr_debug("OMAP PM: context loss count for dev %s = %d\n", + dev_name(dev), count); - /* - * Map the device to the powerdomain. Return the powerdomain - * off counter. - */ + return count; +} - return 0; +#else + +u32 omap_pm_get_dev_context_loss_count(struct device *dev) +{ + return dummy_context_loss_counter; } +#endif /* Should be called before clk framework init */ int __init omap_pm_if_early_init(void) diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c index abe933cd8f0..57adb270767 100644 --- a/arch/arm/plat-omap/omap_device.c +++ b/arch/arm/plat-omap/omap_device.c @@ -280,6 +280,34 @@ static void _add_optional_clock_alias(struct omap_device *od, /* Public functions for use by core code */ /** + * omap_device_get_context_loss_count - get lost context count + * @od: struct omap_device * + * + * Using the primary hwmod, query the context loss count for this + * device. + * + * Callers should consider context for this device lost any time this + * function returns a value different than the value the caller got + * the last time it called this function. + * + * If any hwmods exist for the omap_device assoiated with @pdev, + * return the context loss counter for that hwmod, otherwise return + * zero. + */ +u32 omap_device_get_context_loss_count(struct platform_device *pdev) +{ + struct omap_device *od; + u32 ret = 0; + + od = _find_by_pdev(pdev); + + if (od->hwmods_cnt) + ret = omap_hwmod_get_context_loss_count(od->hwmods[0]); + + return ret; +} + +/** * omap_device_count_resources - count number of struct resource entries needed * @od: struct omap_device * * diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index 1a686c89d8d..e26e50487d6 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c @@ -33,9 +33,10 @@ #include "sram.h" #include "fb.h" + +/* XXX These "sideways" includes are a sign that something is wrong */ #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) -# include "../mach-omap2/prm.h" -# include "../mach-omap2/cm.h" +# include "../mach-omap2/prm2xxx_3xxx.h" # include "../mach-omap2/sdrc.h" #endif |