Powerdomains: add OMAP2/3 powerdomain code, and common OMAP type bitfield
Subsystems (5)
Paul Walmsley
maintainercover Powerdomains: add OMAP2/3 powerdomain code, and common OMAP type bitfield
Hello,
this patch series adds a hardware control and monitoring interface for OMAP2/3 powerdomains. The interface is fully documented in the code.
The series also adds a common OMAP chip type detection bitfield for use with powerdomain and clockdomain structures; it is planned to expand its use to the clock framework in the future.
Powerdomain code tested on 3430SDP ES2.1; also boot-tested on N800.
Many people at Nokia and TI provided commentary and review during the development of the powerdomain patches. Particular help came from (in alphabetical order): Jouni Högander, Tony Lindgren, Sakari Poussa, Igor Stoppa, and Richard Woodruff.
Comments welcome,
- Paul
size:
text data bss dec hex filename
3265548 151032 100736 3517316 35ab84 vmlinux.3430sdp.orig 3270062 151896 100832 3522790 35c0e6 vmlinux.3430sdp
diffstat:
arch/arm/mach-omap2/Makefile | 2 arch/arm/mach-omap2/id.c | 166 ++++-- arch/arm/mach-omap2/io.c | 7 arch/arm/mach-omap2/pm.c | 2 arch/arm/mach-omap2/powerdomain.c | 884 ++++++++++++++++++++++++++++++++ arch/arm/mach-omap2/powerdomains.h | 180 ++++++ arch/arm/mach-omap2/powerdomains24xx.h | 176 ++++++ arch/arm/mach-omap2/powerdomains34xx.h | 296 ++++++++++ arch/arm/mach-omap2/prcm-common.h | 3 arch/arm/mach-omap2/prm-regbits-24xx.h | 12 arch/arm/mach-omap2/prm-regbits-34xx.h | 11 arch/arm/mach-omap2/prm.h | 3 arch/arm/plat-omap/Kconfig | 12 include/asm-arm/arch-omap/cpu.h | 27 include/asm-arm/arch-omap/powerdomain.h | 137 ++++ 15 files changed, 1853 insertions(+), 65 deletions(-)
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Paul Walmsley
maintainerPATCH 1/5 Powerdomains: add OMAP chip type global bitfield; clean up mach-omap2/id.c
Add a new kind of OMAP identification, omap_chip. omap_chip is a bitfield which contains one bit for each OMAP2/3 CPU type, and, on 3430 and beyond, ES level.
For example, the CHIP_IS_OMAP2420 bit is set in omap_type at boot on an OMAP2420. On OMAP3430ES2, both CHIP_IS_OMAP3430 and CHIP_IS_OMAP3430ES2 bits are set.
omap_chip is set in mach-omap2/id.c by _set_omap_chip(). omap_chip is declared static to prevent external code from accessing it directly. Other code can test against omap_chip via the omap_chip_is() function.
omap_chip will be used by the forthcoming powerdomain and clockdomain patches. Each powerdomain/clockdomain structure has a "omap_type" field, in which one or more of these bits are set, to indicate the OMAP chips that the structure is valid for.
External code should define omap_type fields as omap_type_t, so omap_type_t can be transparently extended from its current u8 storage size without generating a lot of patch noise.
Also, clean up id.c by splitting some code out of omap_check_revision() into its own function, _set_system_rev(); and converting some debug printk()s into pr_debug().
--- arch/arm/mach-omap2/id.c | 166 ++++++++++++++++++++++++++++------------ include/asm-arm/arch-omap/cpu.h | 27 ++++++ 2 files changed, 144 insertions(+), 49 deletions(-)
arch/arm/mach-omap2/id.c +117 -49
@@ -18,6 +18,7 @@#include <asm/io.h> #include <asm/arch/control.h> +#include <asm/arch/cpu.h> #if defined(CONFIG_ARCH_OMAP2420 )#define TAP_BASE io_p2v(0x48014000)
@@ -62,6 +63,21 @@ { .hawkeye = 0xb68a, .dev = 0x0, .type = 0x24300000 }, }; +static omap_chip_t omap_chip; + +/** +* omap_chip_is - test whether currently running OMAP matches a chip type +* @oc: omap_chip_t to test against +* +* Test whether the currently-running OMAP chip matches the supplied +* chip type 'oc'. Returns 1 upon a match; 0 upon failure. +*/ +int omap_chip_is (omap_chip_t oc) +{ +return (oc & omap_chip) ?1 :0 ; +} +EXPORT_SYMBOL (omap_chip_is); +static u32 __init read_tap_reg (int reg) {unsigned int regval =0 ;
@@ -93,9 +109,91 @@ } +/* +* _set_system_rev - set the system_rev global based on current OMAP chip type +* +* Set the system_rev global. This is primarily used by the cpu_is_omapxxxx() +* macros. +*/ +static void __init _set_system_rev (u32 type,u8 rev) +{ +u32 i, ctrl_status; + +/* +* system_rev encoding is as follows +* system_rev & 0xff000000 -> Omap Class (24xx/34xx) +* system_rev & 0xfff00000 -> Omap Sub Class (242x/343x) +* system_rev & 0xffff0000 -> Omap type (2420/2422/2423/2430/3430) +* system_rev & 0x0000f000 -> Silicon revision (ES1, ES2 ) +* system_rev & 0x00000700 -> Device Type ( EMU/HS/GP/BAD ) +* system_rev & 0x000000c0 -> IDCODE revision[6:7] +* system_rev & 0x0000003f -> sys_boot[0:5] +*/ +/* Embedding the ES revision info in type field */ + system_rev = type; +/* Also add IDCODE revision info only two lower bits */ + system_rev |= ((rev &0x3 ) <<6 ); + +/* Add in the device type and sys_boot fields (see above) */ +if (cpu_is_omap24xx ()) { + i =OMAP24XX_CONTROL_STATUS ; + }else if (cpu_is_omap343x ()) { + i =OMAP343X_CONTROL_STATUS ; + }else { +printk (KERN_ERR "id: unknown CPU type\n" ); +BUG (); + } + ctrl_status =omap_ctrl_readl (i); + system_rev |= (ctrl_status & (OMAP2_SYSBOOT_5_MASK | +OMAP2_SYSBOOT_4_MASK | +OMAP2_SYSBOOT_3_MASK | +OMAP2_SYSBOOT_2_MASK | +OMAP2_SYSBOOT_1_MASK | +OMAP2_SYSBOOT_0_MASK )); + system_rev |= (ctrl_status &OMAP2_DEVICETYPE_MASK ); +} + + +/* +* _set_omap_chip - set the omap_chip global based on OMAP chip type +* +* Build the omap_cpu_type bits. This variable is used by powerdomain and +* clockdomain code to indicate whether structures are applicable for +* the current OMAP chip type by ANDing it against a 'platform' bitfield +* in the structure. +*/ +static void __init _set_omap_chip (void ) +{ +if (cpu_is_omap343x ()) { + + omap_chip |=CHIP_IS_OMAP3430 ; +if (is_sil_rev_equal_to (OMAP3430_REV_ES1_0 )) + omap_chip |=CHIP_IS_OMAP3430ES1 ; +else if (is_sil_rev_greater_than (OMAP3430_REV_ES1_0 )) + omap_chip |=CHIP_IS_OMAP3430ES2 ; + + }else if (cpu_is_omap243x ()) { + +/* Currently only supports 2430ES2.1 and 2430-all */ + omap_chip |=CHIP_IS_OMAP2430 ; + + }else if (cpu_is_omap242x ()) { + +/* Currently only supports 2420ES2.1.1 and 2420-all */ + omap_chip |=CHIP_IS_OMAP2420 ; + + }else { + +/* Current CPU not supported by this code. */ +printk (KERN_WARNING "OMAP chip type code does not yet support " +"this CPU type.\n" ); +WARN_ON (1 ); + + } +} +void __init omap2_check_revision (void ) { -int ctrl_status =0 ;int i, j;u32 idcode;u32 prod_id;
@@ -109,21 +207,19 @@ rev = (idcode >>28 ) &0x0f ; dev_type = (prod_id >>16 ) &0x0f ; -#ifdef DEBUG -printk (KERN_DEBUG "OMAP_TAP_IDCODE 0x%08x REV %i HAWKEYE 0x%04x MANF %03x\n" , - idcode, rev, hawkeye, (idcode >>1 ) &0x7ff ); -printk (KERN_DEBUG "OMAP_TAP_DIE_ID_0: 0x%08x\n" , -read_tap_reg (OMAP_TAP_DIE_ID_0 )); -printk (KERN_DEBUG "OMAP_TAP_DIE_ID_1: 0x%08x DEV_REV: %i\n" , -read_tap_reg (OMAP_TAP_DIE_ID_1 ), - (read_tap_reg (OMAP_TAP_DIE_ID_1 ) >>28 ) &0xf ); -printk (KERN_DEBUG "OMAP_TAP_DIE_ID_2: 0x%08x\n" , -read_tap_reg (OMAP_TAP_DIE_ID_2 )); -printk (KERN_DEBUG "OMAP_TAP_DIE_ID_3: 0x%08x\n" , -read_tap_reg (OMAP_TAP_DIE_ID_3 )); -printk (KERN_DEBUG "OMAP_TAP_PROD_ID_0: 0x%08x DEV_TYPE: %i\n" , - prod_id, dev_type); -#endif +pr_debug ("OMAP_TAP_IDCODE 0x%08x REV %i HAWKEYE 0x%04x MANF %03x\n" , + idcode, rev, hawkeye, (idcode >>1 ) &0x7ff ); +pr_debug ("OMAP_TAP_DIE_ID_0: 0x%08x\n" , +read_tap_reg (OMAP_TAP_DIE_ID_0 )); +pr_debug ("OMAP_TAP_DIE_ID_1: 0x%08x DEV_REV: %i\n" , +read_tap_reg (OMAP_TAP_DIE_ID_1 ), + (read_tap_reg (OMAP_TAP_DIE_ID_1 ) >>28 ) &0xf ); +pr_debug ("OMAP_TAP_DIE_ID_2: 0x%08x\n" , +read_tap_reg (OMAP_TAP_DIE_ID_2 )); +pr_debug ("OMAP_TAP_DIE_ID_3: 0x%08x\n" , +read_tap_reg (OMAP_TAP_DIE_ID_3 )); +pr_debug ("OMAP_TAP_PROD_ID_0: 0x%08x DEV_TYPE: %i\n" , + prod_id, dev_type);/* * Detection for 34xx ES2.0 and above can be done with just
@@ -159,43 +255,15 @@ j = i; } -/* -* system_rev encoding is as follows -* system_rev & 0xff000000 -> Omap Class (24xx/34xx) -* system_rev & 0xfff00000 -> Omap Sub Class (242x/343x) -* system_rev & 0xffff0000 -> Omap type (2420/2422/2423/2430/3430) -* system_rev & 0x0000f000 -> Silicon revision (ES1, ES2 ) -* system_rev & 0x00000700 -> Device Type ( EMU/HS/GP/BAD ) -* system_rev & 0x000000c0 -> IDCODE revision[6:7] -* system_rev & 0x0000003f -> sys_boot[0:5] -*/ -/* Embedding the ES revision info in type field */ - system_rev = omap_ids[j].type; -/* Also add IDCODE revision info only two lower bits */ - system_rev |= ((rev &0x3 ) <<6 ); +_set_system_rev (omap_ids[j].type, rev); + +_set_omap_chip (); -/* Add in the device type and sys_boot fields (see above) */ -if (cpu_is_omap24xx ()) { - i =OMAP24XX_CONTROL_STATUS ; - }else if (cpu_is_omap343x ()) { - i =OMAP343X_CONTROL_STATUS ; - }else { -printk (KERN_ERR "id: unknown CPU type\n" ); -BUG (); - } - ctrl_status =omap_ctrl_readl (i); - system_rev |= (ctrl_status & (OMAP2_SYSBOOT_5_MASK | -OMAP2_SYSBOOT_4_MASK | -OMAP2_SYSBOOT_3_MASK | -OMAP2_SYSBOOT_2_MASK | -OMAP2_SYSBOOT_1_MASK | -OMAP2_SYSBOOT_0_MASK )); - system_rev |= (ctrl_status &OMAP2_DEVICETYPE_MASK );pr_info ("OMAP%04x" , system_rev >>16 );if ((system_rev >>8 ) &0x0f ) -printk ("ES%x" , (system_rev >>12 ) &0xf ); -printk ("\n" ); +pr_info ("ES%x" , (system_rev >>12 ) &0xf ); +pr_info ("\n" ); }
include/asm-arm/arch-omap/cpu.h +27 -0
@@ -26,6 +26,8 @@#ifndef __ASM_ARCH_OMAP_CPU_H#define __ASM_ARCH_OMAP_CPU_H +typedef u8 omap_chip_t ; +extern unsigned int system_rev;#define omap2_cpu_rev () ((system_rev >> 12) & 0x0f)
@@ -349,6 +351,31 @@#define OMAP3430_REV_ES2_2 0x34303000/* +* omap_chip bits +* +* CHIP_IS_OMAP{2420,2430,3430} indicate that a particular structure is +* valid on all chips of that type. CHIP_IS_OMAP3430ES{1,2} indicates +* something that is only valid on that particular ES revision. +* +* These bits may be ANDed together to indicate structures that are +* available on multiple chip types. +* +* To test whether a particular structure matches the current OMAP chip type, +* use omap_chip_is(). +* +*/ +#define CHIP_IS_OMAP2420 (1 << 0) +#define CHIP_IS_OMAP2430 (1 << 1) +#define CHIP_IS_OMAP3430 (1 << 2) +#define CHIP_IS_OMAP3430ES1 (1 << 3) +#define CHIP_IS_OMAP3430ES2 (1 << 4) + +#define CHIP_IS_OMAP24XX (CHIP_IS_OMAP2420 | CHIP_IS_OMAP2430) + +int omap_chip_is (omap_chip_t oc); + + +/* * Macro to detect device type i.e. EMU/HS/TST/GP/BAD */ #define DEVICE_TYPE_TEST 0
Tony Lindgren
maintainerRe: [PATCH 1/5] Powerdomains: add OMAP chip type global bitfield; clean up mach-omap2/id.c
One comment below:
Quoted 248 lines · Paul Walmsley
Add a new kind of OMAP identification,
omap_chip.omap_chipis a bitfield which contains one bit for each OMAP2/3 CPU type, and, on 3430 and beyond, ES level.For example, the
CHIP_IS_OMAP2420bit is set inomap_typeat boot on an OMAP2420. On OMAP3430ES2, bothCHIP_IS_OMAP3430andCHIP_IS_OMAP3430ES2bits are set.
omap_chipis set inmach-omap2/id.cby_set_omap_chip().omap_chipis declared static to prevent external code from accessing it directly. Other code can test againstomap_chipvia theomap_chip_is()function.
omap_chipwill be used by the forthcoming powerdomain and clockdomain patches. Each powerdomain/clockdomain structure has a "omap_type" field, in which one or more of these bits are set, to indicate the OMAP chips that the structure is valid for.External code should define
omap_typefields asomap_type_t, soomap_type_tcan be transparently extended from its current u8 storage size without generating a lot of patch noise.Also, clean up
id.cby splitting some code out ofomap_check_revision()into its own function,_set_system_rev(); and converting some debug printk()s intopr_debug().Signed-off-by Paul Walmsley <[email protected]>--- arch/arm/mach-omap2/id.c | 166 ++++++++++++++++++++++++++++------------ include/asm-arm/arch-omap/cpu.h | 27 ++++++ 2 files changed, 144 insertions(+), 49 deletions(-)Index:
linux-omap/arch/arm/mach-omap2/id.c
===================================================================arch/arm/mach-omap2/id.c +117
-49@@ -18,6 +18,7 @@#include <asm/io.h> #include <asm/arch/control.h> +#include <asm/arch/cpu.h> #if defined(CONFIG_ARCH_OMAP2420 )#define TAP_BASE io_p2v(0x48014000)@@ -62,6 +63,21 @@ { .hawkeye = 0xb68a, .dev = 0x0, .type = 0x24300000 }, }; +static omap_chip_t omap_chip; + +/** +* omap_chip_is - test whether currently running OMAP matches a chip type +* @oc: omap_chip_t to test against +* +* Test whether the currently-running OMAP chip matches the supplied +* chip type 'oc'. Returns 1 upon a match; 0 upon failure. +*/ +int omap_chip_is (omap_chip_t oc) +{ +return (oc & omap_chip) ?1 :0 ; +} +EXPORT_SYMBOL (omap_chip_is); +static u32 __init read_tap_reg (int reg) {unsigned int regval =0 ;@@ -93,9 +109,91 @@ } +/* +* _set_system_rev - set the system_rev global based on current OMAP chip type +* +* Set the system_rev global. This is primarily used by the cpu_is_omapxxxx() +* macros. +*/ +static void __init _set_system_rev (u32 type,u8 rev) +{ +u32 i, ctrl_status; + +/* +* system_rev encoding is as follows +* system_rev & 0xff000000 -> Omap Class (24xx/34xx) +* system_rev & 0xfff00000 -> Omap Sub Class (242x/343x) +* system_rev & 0xffff0000 -> Omap type (2420/2422/2423/2430/3430) +* system_rev & 0x0000f000 -> Silicon revision (ES1, ES2 ) +* system_rev & 0x00000700 -> Device Type ( EMU/HS/GP/BAD ) +* system_rev & 0x000000c0 -> IDCODE revision[6:7] +* system_rev & 0x0000003f -> sys_boot[0:5] +*/ +/* Embedding the ES revision info in type field */ + system_rev = type; +/* Also add IDCODE revision info only two lower bits */ + system_rev |= ((rev &0x3 ) <<6 ); + +/* Add in the device type and sys_boot fields (see above) */ +if (cpu_is_omap24xx ()) { + i =OMAP24XX_CONTROL_STATUS ; + }else if (cpu_is_omap343x ()) { + i =OMAP343X_CONTROL_STATUS ; + }else { +printk (KERN_ERR "id: unknown CPU type\n" ); +BUG (); + } + ctrl_status =omap_ctrl_readl (i); + system_rev |= (ctrl_status & (OMAP2_SYSBOOT_5_MASK | +OMAP2_SYSBOOT_4_MASK | +OMAP2_SYSBOOT_3_MASK | +OMAP2_SYSBOOT_2_MASK | +OMAP2_SYSBOOT_1_MASK | +OMAP2_SYSBOOT_0_MASK )); + system_rev |= (ctrl_status &OMAP2_DEVICETYPE_MASK ); +} + + +/* +* _set_omap_chip - set the omap_chip global based on OMAP chip type +* +* Build the omap_cpu_type bits. This variable is used by powerdomain and +* clockdomain code to indicate whether structures are applicable for +* the current OMAP chip type by ANDing it against a 'platform' bitfield +* in the structure. +*/ +static void __init _set_omap_chip (void ) +{ +if (cpu_is_omap343x ()) { + + omap_chip |=CHIP_IS_OMAP3430 ; +if (is_sil_rev_equal_to (OMAP3430_REV_ES1_0 )) + omap_chip |=CHIP_IS_OMAP3430ES1 ; +else if (is_sil_rev_greater_than (OMAP3430_REV_ES1_0 )) + omap_chip |=CHIP_IS_OMAP3430ES2 ; + + }else if (cpu_is_omap243x ()) { + +/* Currently only supports 2430ES2.1 and 2430-all */ + omap_chip |=CHIP_IS_OMAP2430 ; + + }else if (cpu_is_omap242x ()) { + +/* Currently only supports 2420ES2.1.1 and 2420-all */ + omap_chip |=CHIP_IS_OMAP2420 ; + + }else { + +/* Current CPU not supported by this code. */ +printk (KERN_WARNING "OMAP chip type code does not yet support " +"this CPU type.\n" ); +WARN_ON (1 ); + + } +} +void __init omap2_check_revision (void ) { -int ctrl_status =0 ;int i, j;u32 idcode;u32 prod_id;@@ -109,21 +207,19 @@ rev = (idcode >>28 ) &0x0f ; dev_type = (prod_id >>16 ) &0x0f ; -#ifdef DEBUG -printk (KERN_DEBUG "OMAP_TAP_IDCODE 0x%08x REV %i HAWKEYE 0x%04x MANF %03x\n" , - idcode, rev, hawkeye, (idcode >>1 ) &0x7ff ); -printk (KERN_DEBUG "OMAP_TAP_DIE_ID_0: 0x%08x\n" , -read_tap_reg (OMAP_TAP_DIE_ID_0 )); -printk (KERN_DEBUG "OMAP_TAP_DIE_ID_1: 0x%08x DEV_REV: %i\n" , -read_tap_reg (OMAP_TAP_DIE_ID_1 ), - (read_tap_reg (OMAP_TAP_DIE_ID_1 ) >>28 ) &0xf ); -printk (KERN_DEBUG "OMAP_TAP_DIE_ID_2: 0x%08x\n" , -read_tap_reg (OMAP_TAP_DIE_ID_2 )); -printk (KERN_DEBUG "OMAP_TAP_DIE_ID_3: 0x%08x\n" , -read_tap_reg (OMAP_TAP_DIE_ID_3 )); -printk (KERN_DEBUG "OMAP_TAP_PROD_ID_0: 0x%08x DEV_TYPE: %i\n" , - prod_id, dev_type); -#endif +pr_debug ("OMAP_TAP_IDCODE 0x%08x REV %i HAWKEYE 0x%04x MANF %03x\n" , + idcode, rev, hawkeye, (idcode >>1 ) &0x7ff ); +pr_debug ("OMAP_TAP_DIE_ID_0: 0x%08x\n" , +read_tap_reg (OMAP_TAP_DIE_ID_0 )); +pr_debug ("OMAP_TAP_DIE_ID_1: 0x%08x DEV_REV: %i\n" , +read_tap_reg (OMAP_TAP_DIE_ID_1 ), + (read_tap_reg (OMAP_TAP_DIE_ID_1 ) >>28 ) &0xf ); +pr_debug ("OMAP_TAP_DIE_ID_2: 0x%08x\n" , +read_tap_reg (OMAP_TAP_DIE_ID_2 )); +pr_debug ("OMAP_TAP_DIE_ID_3: 0x%08x\n" , +read_tap_reg (OMAP_TAP_DIE_ID_3 )); +pr_debug ("OMAP_TAP_PROD_ID_0: 0x%08x DEV_TYPE: %i\n" , + prod_id, dev_type);/* * Detection for 34xx ES2.0 and above can be done with just @@ -159,43 +255,15 @@ j = i; } -/* -* system_rev encoding is as follows -* system_rev & 0xff000000 -> Omap Class (24xx/34xx) -* system_rev & 0xfff00000 -> Omap Sub Class (242x/343x) -* system_rev & 0xffff0000 -> Omap type (2420/2422/2423/2430/3430) -* system_rev & 0x0000f000 -> Silicon revision (ES1, ES2 ) -* system_rev & 0x00000700 -> Device Type ( EMU/HS/GP/BAD ) -* system_rev & 0x000000c0 -> IDCODE revision[6:7] -* system_rev & 0x0000003f -> sys_boot[0:5] -*/ -/* Embedding the ES revision info in type field */ - system_rev = omap_ids[j].type; -/* Also add IDCODE revision info only two lower bits */ - system_rev |= ((rev &0x3 ) <<6 ); +_set_system_rev (omap_ids[j].type, rev); + +_set_omap_chip (); -/* Add in the device type and sys_boot fields (see above) */ -if (cpu_is_omap24xx ()) { - i =OMAP24XX_CONTROL_STATUS ; - }else if (cpu_is_omap343x ()) { - i =OMAP343X_CONTROL_STATUS ; - }else { -printk (KERN_ERR "id: unknown CPU type\n" ); -BUG (); - } - ctrl_status =omap_ctrl_readl (i); - system_rev |= (ctrl_status & (OMAP2_SYSBOOT_5_MASK | -OMAP2_SYSBOOT_4_MASK | -OMAP2_SYSBOOT_3_MASK | -OMAP2_SYSBOOT_2_MASK | -OMAP2_SYSBOOT_1_MASK | -OMAP2_SYSBOOT_0_MASK )); - system_rev |= (ctrl_status &OMAP2_DEVICETYPE_MASK );pr_info ("OMAP%04x" , system_rev >>16 );if ((system_rev >>8 ) &0x0f ) -printk ("ES%x" , (system_rev >>12 ) &0xf ); -printk ("\n" ); +pr_info ("ES%x" , (system_rev >>12 ) &0xf ); +pr_info ("\n" ); }Index:
linux-omap/include/asm-arm/arch-omap/cpu.h
===================================================================
include/asm-arm/arch-omap/cpu.h line 33
Quoted 8 lines
include/asm-arm/arch-omap/cpu.h +2
-0@@ -26,6 +26,8 @@#ifndef __ASM_ARCH_OMAP_CPU_H#define __ASM_ARCH_OMAP_CPU_H +typedef u8 omap_chip_t ; +extern unsigned int system_rev;#define omap2_cpu_rev () ((system_rev >> 12) & 0x0f)
New typedefs are not liked, that should be just u8.
include/asm-arm/arch-omap/cpu.h line 362
Quoted 13 lines
include/asm-arm/arch-omap/cpu.h +9
-0@@ -349,6 +351,31 @@#define OMAP3430_REV_ES2_2 0x34303000/* +* omap_chip bits +* +* CHIP_IS_OMAP{2420,2430,3430} indicate that a particular structure is +* valid on all chips of that type. CHIP_IS_OMAP3430ES{1,2} indicates +* something that is only valid on that particular ES revision. +* +* These bits may be ANDed together to indicate structures that are +* available on multiple chip types. +*
Shouldn't above say ORed together?
Quoted 26 lines
include/asm-arm/arch-omap/cpu.h +16
-0+* To test whether a particular structure matches the current OMAP chip type, +* use omap_chip_is(). +* +*/ +#define CHIP_IS_OMAP2420 (1 << 0) +#define CHIP_IS_OMAP2430 (1 << 1) +#define CHIP_IS_OMAP3430 (1 << 2) +#define CHIP_IS_OMAP3430ES1 (1 << 3) +#define CHIP_IS_OMAP3430ES2 (1 << 4) + +#define CHIP_IS_OMAP24XX (CHIP_IS_OMAP2420 | CHIP_IS_OMAP2430) + +int omap_chip_is (omap_chip_t oc); + + +/* * Macro to detect device type i.e. EMU/HS/TST/GP/BAD */ #define DEVICE_TYPE_TEST 0Signature · 6 lines
-- -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/5] Powerdomains: add OMAP chip type global bitfield; clean up mach-omap2/id.c
In reply to Paul WalmsleyQuoted 11 lines
Add a new kind of OMAP identification,
omap_chip.omap_chipis a bitfield which contains one bit for each OMAP2/3 CPU type, and, on 3430 and beyond, ES level.For example, the
CHIP_IS_OMAP2420bit is set inomap_typeat boot on an OMAP2420. On OMAP3430ES2, bothCHIP_IS_OMAP3430andCHIP_IS_OMAP3430ES2bits are set.
omap_chipis set inmach-omap2/id.cby_set_omap_chip().omap_chipis declared static to prevent external code from accessing it directly. Other code can test againstomap_chipvia theomap_chip_is()function.
Omap chip is not set correctly in case of omap3 es2.x. You should change your code something like this:
arch/arm/mach-omap2/id.c +1 -1
@@ -229,6 +229,7 @@ void __init omap2_check_revision(void)if (hawkeye ==0xb7ae ) { system_rev =0x34300000 | ((1 + rev) <<12 );pr_info ("OMAP%04x ES2.%i\n" , system_rev >>16 , rev); +_set_omap_chip ();return ; } --
Jouni Högander
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Paul Walmsley
maintainerRe: [PATCH 1/5] Powerdomains: add OMAP chip type global bitfield; clean up mach-omap2/id.c
Quoted 2 lines · Högander Jouni
Omap chip is not set correctly in case of omap3 es2.x. You should change your code something like this:
Thanks Jouni, that fix is in the latest version which will be posted later today.
- Paul
Paul Walmsley
maintainerPATCH 2/5 Powerdomains: add base OMAP2/3 powerdomain code
In reply to Paul WalmsleyThis patch adds an interface to the powerdomain registers in the PRM/CM modules on OMAP2/3. This interface is intended to be used by PM code, e.g., pm.c; not by device drivers directly.
Each powerdomain will be defined in later patches as static structures. Also definable are dependencies between powerdomains, used for adding and removing PM_WKDEP and CM_SLEEPDEP bits. The powerdomain structures are linked into a list at boot by pwrdm_register(), similar to the OMAP clock code.
The patch adds a Kconfig option, CONFIG_OMAP_DEBUG_POWERDOMAIN, which when enabled will emit verbose debug messages via pr_debug().
--- arch/arm/mach-omap2/Makefile | 2 arch/arm/mach-omap2/io.c | 3 arch/arm/mach-omap2/powerdomain.c | 884 ++++++++++++++++++++++++++++++++ arch/arm/plat-omap/Kconfig | 12 include/asm-arm/arch-omap/powerdomain.h | 137 ++++ 5 files changed, 1037 insertions(+), 1 deletion(-)
arch/arm/mach-omap2/Makefile +1 -1
@@ -4,7 +4,7 @@ # Common support obj-y := irq.o id.o io.o memory.o control.o prcm.o clock.o mux.o \ - devices.o serial.o gpmc.o timer-gp.o + devices.o serial.o gpmc.o timer-gp.o powerdomain.o # Functions loaded to SRAM obj-$(CONFIG_ARCH_OMAP2) += sram24xx.o
arch/arm/mach-omap2/io.c +3 -0
@@ -27,6 +27,8 @@#include <asm/arch/mux.h> #include <asm/arch/omapfb.h> +#include <asm/arch/powerdomain.h> +extern void omap_sram_init (void );extern int omap2_clk_init (void );extern void omap2_check_revision (void );
@@ -188,6 +190,7 @@void __init omap2_init_common_hw (void ) {omap2_mux_init (); +pwrdm_init (NULL );omap2_clk_init ();omap2_init_memory ();gpmc_init ();
arch/arm/mach-omap2/powerdomain.c new file +884 -0
884 lines not on this page · raw message
arch/arm/plat-omap/Kconfig +12 -0
@@ -42,6 +42,18 @@ confident in your SRAM code, disabling this will save about 600 bytes. +config OMAP_DEBUG_POWERDOMAIN + bool "Emit debug messages from powerdomain layer" + depends on ARCH_OMAP2 || ARCH_OMAP3 + default n + help + Say Y here if you want to compile in powerdomain layer + debugging messages for OMAP2/3. These messages can + provide more detail as to why some powerdomain calls + may be failing, and will also emit a descriptive message + for every powerdomain register write. However, the + extra detail costs some memory. + config OMAP_RESET_CLOCKS bool "Reset unused clocks during boot" depends on ARCH_OMAP
include/asm-arm/arch-omap/powerdomain.h new file +137 -0
137 lines not on this page · raw message
Tony Lindgren
maintainerRe: [PATCH 2/5] Powerdomains: add base OMAP2/3 powerdomain code
Quoted 50 lines · Paul Walmsley
This patch adds an interface to the powerdomain registers in the PRM/CM modules on OMAP2/3. This interface is intended to be used by PM code, e.g.,
pm.c; not by device drivers directly.Each powerdomain will be defined in later patches as static structures. Also definable are dependencies between powerdomains, used for adding and removing
PM_WKDEPandCM_SLEEPDEPbits. The powerdomain structures are linked into a list at boot bypwrdm_register(), similar to the OMAP clock code.The patch adds a
Kconfigoption,CONFIG_OMAP_DEBUG_POWERDOMAIN, which when enabled will emit verbose debug messages viapr_debug().Signed-off-by Paul Walmsley <[email protected]>--- arch/arm/mach-omap2/Makefile | 2 arch/arm/mach-omap2/io.c | 3 arch/arm/mach-omap2/powerdomain.c | 884 ++++++++++++++++++++++++++++++++ arch/arm/plat-omap/Kconfig | 12 include/asm-arm/arch-omap/powerdomain.h | 137 ++++ 5 files changed, 1037 insertions(+), 1 deletion(-)Index: linux-omap/arch/arm/mach-omap2/Makefile
===================================================================arch/arm/mach-omap2/Makefile +1
-1@@ -4,7 +4,7 @@ # Common support obj-y := irq.o id.o io.o memory.o control.o prcm.o clock.o mux.o \ - devices.o serial.o gpmc.o timer-gp.o + devices.o serial.o gpmc.o timer-gp.o powerdomain.o # Functions loaded to SRAM obj-$(CONFIG_ARCH_OMAP2) += sram24xx.oIndex:
linux-omap/arch/arm/mach-omap2/io.c
===================================================================arch/arm/mach-omap2/io.c +2
-0@@ -27,6 +27,8 @@#include <asm/arch/mux.h> #include <asm/arch/omapfb.h> +#include <asm/arch/powerdomain.h> +extern void omap_sram_init (void );extern int omap2_clk_init (void );extern void omap2_check_revision (void );
arch/arm/mach-omap2/io.c line 196
Quoted 7 lines
arch/arm/mach-omap2/io.c +1
-0@@ -188,6 +190,7 @@void __init omap2_init_common_hw (void ) {omap2_mux_init (); +pwrdm_init (NULL );omap2_clk_init ();omap2_init_memory ();gpmc_init ();
The pwrdm_init() above does not do anything, is the plan to make it do something later on?
Quoted 79 lines
Index:
linux-omap/arch/arm/mach-omap2/powerdomain.c
===================================================================arch/arm/mach-omap2/powerdomain.c new file +74
-0@@ -0,0 +1,884 @@ +/* +* OMAP powerdomain control +* +* Copyright (C) 2007-2008 Texas Instruments, Inc. +* Copyright (C) 2007-2008 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. +*/ +#ifdef CONFIG_OMAP_DEBUG_POWERDOMAIN +# define DEBUG +#endif + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/types.h> +#include <linux/delay.h> +#include <linux/mutex.h> +#include <linux/list.h> +#include <linux/errno.h> +#include <linux/err.h> + +#include <asm/atomic.h> + +#include "cm.h" +#include "cm-regbits-34xx.h" +#include "prm.h" +#include "prm-regbits-34xx.h" + +#include <asm/arch/cpu.h> +#include <asm/arch/powerdomain.h> + +/* pwrdm_list contains all registered struct powerdomains */ +static LIST_HEAD (pwrdm_list); + +/* pwrdm_mutex protects pwrdm_list add and del ops */ +static DEFINE_MUTEX (pwrdm_mutex); + +/* Private functions */ + +static u32 __attribute__((unused))prm_read_mod_bits_shift (s16 domain,s16 idx,u32 mask) +{ +u32 v; + + v =prm_read_mod_reg (domain, idx); + v &= mask; + v >>=__ffs (mask); + +return v; +} + +/* _pwrdm_deps_lookup - look up the specified powerdomain in a pwrdm list */ +static struct powerdomain *_pwrdm_deps_lookup (struct powerdomain *pwrdm, +const struct pwrdm_dep *deps) +{ +const struct pwrdm_dep *pd; + +if (!pwrdm || !deps || !omap_chip_is (pwrdm->omap_chip)) +return ERR_PTR (-EINVAL ); + +for (pd = deps; pd; pd++) +if (pd->pwrdm == pwrdm &&omap_chip_is (pd->omap_chip)) +break ; + +if (!pd) +return ERR_PTR (-ENOENT ); + +return pd->pwrdm; +} + +
arch/arm/mach-omap2/powerdomain.c line 84
Quoted 10 lines
arch/arm/mach-omap2/powerdomain.c new file +10
-0+/* Public functions */ + +/** +* pwrdm_init - set up the powerdomain layer +* +* * Loop through the list of powerdomains, registering all that are +* available on the current CPU. If pwrdm_list is supplied and not +* null, all of the referenced powerdomains will be registered. No +* return value. +*/
There seems to be a tab befoe No above.
Quoted 29 lines
arch/arm/mach-omap2/powerdomain.c new file +29
-0+void pwrdm_init (struct powerdomain **pwrdm_list) +{ +struct powerdomain **p =NULL ; + +if (pwrdm_list) +for (p = pwrdm_list; *p; p++) +pwrdm_register (*p); +} + + +/** +* pwrdm_register - register a powerdomain +* @pwrdm: struct powerdomain * to register +* +* Adds a powerdomain to the internal powerdomain list. Returns +* -EINVAL if given a null pointer, -EEXIST if a powerdomain is +* already registered by the provided name, or 0 upon success. +*/ +int pwrdm_register (struct powerdomain *pwrdm) +{ +if (!pwrdm) +return -EINVAL ; + +if (!omap_chip_is (pwrdm->omap_chip)) +return -EINVAL ; + +/* Verify that the powerdomain is not already registered */ +if (pwrdm_lookup (pwrdm->name)) +return -EEXIST ;
arch/arm/mach-omap2/powerdomain.c line 123
Quoted 10 lines
arch/arm/mach-omap2/powerdomain.c new file +10
-0+ +mutex_lock (&pwrdm_mutex); +list_add (&pwrdm->node, &pwrdm_list); +mutex_unlock (&pwrdm_mutex); + +pr_debug ("powerdomain: registered %s\n" , pwrdm->name); + +return 0 ; +} +EXPORT_SYMBOL (pwrdm_register);
Maybe you should have unlocked _pwrdm_lookup() and mutex_locked() pwrdm_lookup() that calls _pwrdm_lookup(). Then mutex_lock() the lookup and addition of new chip in pwrdm_register()?
Otherwise there's a slight chance that powerdomain gets added between pwrdm_lookup() and list_add().
Quoted 933 lines
arch/arm/mach-omap2/powerdomain.c new file +761
-0+ +/** +* pwrdm_unregister - unregister a powerdomain +* @pwrdm: struct powerdomain * to unregister +* +* Removes a powerdomain from the internal powerdomain list. Returns +* -EINVAL if pwrdm argument is NULL. +*/ +int pwrdm_unregister (struct powerdomain *pwrdm) +{ +if (!pwrdm) +return -EINVAL ; + +mutex_lock (&pwrdm_mutex); +list_del (&pwrdm->node); +mutex_unlock (&pwrdm_mutex); + +pr_debug ("powerdomain: unregistered %s\n" , pwrdm->name); + +return 0 ; +} +EXPORT_SYMBOL (pwrdm_unregister); + +/** +* pwrdm_lookup - look up a powerdomain by name, return a pointer +* @name: name of powerdomain +* +* Find a registered powerdomain by its name. Returns a pointer to the +* struct powerdomain if found, or NULL otherwise. +*/ +struct powerdomain *pwrdm_lookup (const char *name) +{ +struct powerdomain *pwrdm, *temp_pwrdm; + +if (!name) +return NULL ; + + pwrdm =NULL ; + +mutex_lock (&pwrdm_mutex); +list_for_each_entry (temp_pwrdm, &pwrdm_list, node) { +if (!strcmp (name, temp_pwrdm->name)) { + pwrdm = temp_pwrdm; +break ; + } + } +mutex_unlock (&pwrdm_mutex); + +return pwrdm; +} +EXPORT_SYMBOL (pwrdm_lookup); + +/** +* pwrdm_for_each - call function on each registered clockdomain +* @fn: callback function * +* +* Call the supplied function for each registered powerdomain. +* The callback function can return anything but 0 to bail +* out early from the iterator. The callback function is called with +* the pwrdm_mutex held, so no powerdomain structure manipulation +* functions should be called from the callback, although hardware +* powerdomain control functions are fine. Returns the last return +* value of the callback function, which should be 0 for success or +* anything else to indicate failure; or -EINVAL if the function pointer +* is null. +*/ +int pwrdm_for_each (int (*fn)(struct powerdomain *pwrdm)) +{ +struct powerdomain *temp_pwrdm; +int ret =0 ; + +if (!fn) +return -EINVAL ; + +mutex_lock (&pwrdm_mutex); +list_for_each_entry (temp_pwrdm, &pwrdm_list, node) { + ret = (*fn)(temp_pwrdm); +if (ret) +break ; + } +mutex_unlock (&pwrdm_mutex); + +return ret; +} +EXPORT_SYMBOL (pwrdm_for_each); + +/** +* pwrdm_add_wkdep - add a wakeup dependency from pwrdm2 to pwrdm1 +* @pwrdm1: wake this struct powerdomain * up (dependent) +* @pwrdm2: when this struct powerdomain * wakes up (source) +* +* When the powerdomain represented by pwrdm2 wakes up (due to an +* interrupt), wake up pwrdm1. Implemented in hardware on the OMAP, +* this feature is designed to reduce wakeup latency of the dependent +* powerdomain. Returns -EINVAL if presented with invalid powerdomain +* pointers, -ENOENT if pwrdm2 cannot wake up pwrdm1 in hardware, or +* 0 upon success. +*/ +int pwrdm_add_wkdep (struct powerdomain *pwrdm1,struct powerdomain *pwrdm2) +{ +struct powerdomain *p; + +if (!pwrdm1) +return -EINVAL ; + + p =_pwrdm_deps_lookup (pwrdm2, pwrdm1->wkdep_srcs); +if (IS_ERR (p)) { +pr_debug ("powerdomain: hardware cannot set/clear wake up of " +"%s when %s wakes up\n" , pwrdm1->name, pwrdm2->name); +return IS_ERR (p); + } + +pr_debug ("powerdomain: hardware will wake up %s when %s wakes up\n" , + pwrdm1->name, pwrdm2->name); + +prm_set_mod_reg_bits ((1 << pwrdm2->dep_bit), + pwrdm1->prcm_offs,PM_WKDEP ); + +return 0 ; +} +EXPORT_SYMBOL (pwrdm_add_wkdep); + +/** +* pwrdm_del_wkdep - remove a wakeup dependency from pwrdm2 to pwrdm1 +* @pwrdm1: wake this struct powerdomain * up (dependent) +* @pwrdm2: when this struct powerdomain * wakes up (source) +* +* Remove a wakeup dependency that causes pwrdm1 to wake up when pwrdm2 +* wakes up. Returns -EINVAL if presented with invalid powerdomain +* pointers, -ENOENT if pwrdm2 cannot wake up pwrdm1 in hardware, or +* 0 upon success. +*/ +int pwrdm_del_wkdep (struct powerdomain *pwrdm1,struct powerdomain *pwrdm2) +{ +struct powerdomain *p; + +if (!pwrdm1) +return -EINVAL ; + + p =_pwrdm_deps_lookup (pwrdm2, pwrdm1->wkdep_srcs); +if (IS_ERR (p)) { +pr_debug ("powerdomain: hardware cannot set/clear wake up of " +"%s when %s wakes up\n" , pwrdm1->name, pwrdm2->name); +return IS_ERR (p); + } + +pr_debug ("powerdomain: hardware will no longer wake up %s after %s " +"wakes up\n" , pwrdm1->name, pwrdm2->name); + +prm_clear_mod_reg_bits ((1 << pwrdm2->dep_bit), + pwrdm1->prcm_offs,PM_WKDEP ); + +return 0 ; +} +EXPORT_SYMBOL (pwrdm_del_wkdep); + +/** +* pwrdm_read_wkdep - read wakeup dependency state from pwrdm2 to pwrdm1 +* @pwrdm1: wake this struct powerdomain * up (dependent) +* @pwrdm2: when this struct powerdomain * wakes up (source) +* +* Return 1 if a hardware wakeup dependency exists wherein pwrdm1 will be +* awoken when pwrdm2 wakes up; 0 if dependency is not set; -EINVAL +* if either powerdomain pointer is invalid; or -ENOENT if the hardware +* is incapable. +* +* REVISIT: Currently this function only represents software-controllable +* wakeup dependencies. Wakeup dependencies fixed in hardware are not +* yet handled here. +*/ +int pwrdm_read_wkdep (struct powerdomain *pwrdm1,struct powerdomain *pwrdm2) +{ +struct powerdomain *p; + +if (!pwrdm1) +return -EINVAL ; + + p =_pwrdm_deps_lookup (pwrdm2, pwrdm1->wkdep_srcs); +if (IS_ERR (p)) { +pr_debug ("powerdomain: hardware cannot set/clear wake up of " +"%s when %s wakes up\n" , pwrdm1->name, pwrdm2->name); +return IS_ERR (p); + } + +return prm_read_mod_bits_shift (pwrdm1->prcm_offs,PM_WKDEP , + (1 << pwrdm2->dep_bit)); +} +EXPORT_SYMBOL (pwrdm_read_wkdep); + +/** +* pwrdm_add_sleepdep - add a sleep dependency from pwrdm2 to pwrdm1 +* @pwrdm1: prevent this struct powerdomain * from sleeping (dependent) +* @pwrdm2: when this struct powerdomain * is active (source) +* +* Prevent pwrdm1 from automatically going inactive (and then to +* retention or off) if pwrdm2 is still active. Returns -EINVAL if +* presented with invalid powerdomain pointers or called on a machine +* that does not support software-configurable hardware sleep dependencies, +* -ENOENT if the specified dependency cannot be set in hardware, or +* 0 upon success. +*/ +int pwrdm_add_sleepdep (struct powerdomain *pwrdm1,struct powerdomain *pwrdm2) +{ +struct powerdomain *p; + +if (!pwrdm1) +return -EINVAL ; + +if (!cpu_is_omap34xx ()) +return -EINVAL ; + + p =_pwrdm_deps_lookup (pwrdm2, pwrdm1->sleepdep_srcs); +if (IS_ERR (p)) { +pr_debug ("powerdomain: hardware cannot set/clear sleep " +"dependency affecting %s from %s\n" , pwrdm1->name, + pwrdm2->name); +return IS_ERR (p); + } + +pr_debug ("powerdomain: will prevent %s from sleeping if %s is active\n" , + pwrdm1->name, pwrdm2->name); + +cm_set_mod_reg_bits ((1 << pwrdm2->dep_bit), + pwrdm1->prcm_offs,OMAP3430_CM_SLEEPDEP ); + +return 0 ; +} +EXPORT_SYMBOL (pwrdm_add_sleepdep); + +/** +* pwrdm_del_sleepdep - remove a sleep dependency from pwrdm2 to pwrdm1 +* @pwrdm1: prevent this struct powerdomain * from sleeping (dependent) +* @pwrdm2: when this struct powerdomain * is active (source) +* +* Allow pwrdm1 to automatically go inactive (and then to retention or +* off), independent of the activity state of pwrdm2. Returns -EINVAL +* if presented with invalid powerdomain pointers or called on a machine +* that does not support software-configurable hardware sleep dependencies, +* -ENOENT if the specified dependency cannot be cleared in hardware, or +* 0 upon success. +*/ +int pwrdm_del_sleepdep (struct powerdomain *pwrdm1,struct powerdomain *pwrdm2) +{ +struct powerdomain *p; + +if (!pwrdm1) +return -EINVAL ; + +if (!cpu_is_omap34xx ()) +return -EINVAL ; + + p =_pwrdm_deps_lookup (pwrdm2, pwrdm1->sleepdep_srcs); +if (IS_ERR (p)) { +pr_debug ("powerdomain: hardware cannot set/clear sleep " +"dependency affecting %s from %s\n" , pwrdm1->name, + pwrdm2->name); +return IS_ERR (p); + } + +pr_debug ("powerdomain: will no longer prevent %s from sleeping if " +"%s is active\n" , pwrdm1->name, pwrdm2->name); + +cm_clear_mod_reg_bits ((1 << pwrdm2->dep_bit), + pwrdm1->prcm_offs,OMAP3430_CM_SLEEPDEP ); + +return 0 ; +} +EXPORT_SYMBOL (pwrdm_del_sleepdep); + +/** +* pwrdm_read_sleepdep - read sleep dependency state from pwrdm2 to pwrdm1 +* @pwrdm1: prevent this struct powerdomain * from sleeping (dependent) +* @pwrdm2: when this struct powerdomain * is active (source) +* +* Return 1 if a hardware sleep dependency exists wherein pwrdm1 will +* not be allowed to automatically go inactive if pwrdm2 is active; +* 0 if pwrdm1's automatic power state inactivity transition is independent +* of pwrdm2's; -EINVAL if either powerdomain pointer is invalid or called +* on a machine that does not support software-configurable hardware sleep +* dependencies; or -ENOENT if the hardware is incapable. +* +* REVISIT: Currently this function only represents software-controllable +* sleep dependencies. Sleep dependencies fixed in hardware are not +* yet handled here. +*/ +int pwrdm_read_sleepdep (struct powerdomain *pwrdm1,struct powerdomain *pwrdm2) +{ +struct powerdomain *p; + +if (!pwrdm1) +return -EINVAL ; + +if (!cpu_is_omap34xx ()) +return -EINVAL ; + + p =_pwrdm_deps_lookup (pwrdm2, pwrdm1->sleepdep_srcs); +if (IS_ERR (p)) { +pr_debug ("powerdomain: hardware cannot set/clear sleep " +"dependency affecting %s from %s\n" , pwrdm1->name, + pwrdm2->name); +return IS_ERR (p); + } + +return prm_read_mod_bits_shift (pwrdm1->prcm_offs,OMAP3430_CM_SLEEPDEP , + (1 << pwrdm2->dep_bit)); +} +EXPORT_SYMBOL (pwrdm_read_sleepdep); + + +/** +* pwrdm_set_next_pwrst - set next powerdomain power state +* @pwrdm: struct powerdomain * to set +* @pwrst: one of the PWRDM_POWER_* macros +* +* Set the powerdomain pwrdm's next power state to pwrst. The powerdomain +* may not enter this state immediately if the preconditions for this state +* have not been satisfied. Returns -EINVAL if the powerdomain pointer is +* null or if the power state is invalid for the powerdomin, or returns 0 +* upon success. +*/ +int pwrdm_set_next_pwrst (struct powerdomain *pwrdm,u8 pwrst) +{ +if (!pwrdm) +return -EINVAL ; + +if (!(pwrdm->pwrsts & (1 << pwrst))) +return -EINVAL ; + +pr_debug ("powerdomain: setting next powerstate for %s to %0x\n" , + pwrdm->name, pwrst); + +prm_rmw_mod_reg_bits (OMAP_POWERSTATE_MASK , + (pwrst <<OMAP_POWERSTATE_SHIFT ), + pwrdm->prcm_offs,PM_PWSTCTRL ); + +return 0 ; +} +EXPORT_SYMBOL (pwrdm_set_next_pwrst); + +/** +* pwrdm_read_next_pwrst - get next powerdomain power state +* @pwrdm: struct powerdomain * to get power state +* +* Return the powerdomain pwrdm's next power state. Returns -EINVAL +* if the powerdomain pointer is null or returns the next power state +* upon success. +*/ +int pwrdm_read_next_pwrst (struct powerdomain *pwrdm) +{ +if (!pwrdm) +return -EINVAL ; + +return prm_read_mod_bits_shift (pwrdm->prcm_offs,PM_PWSTCTRL , +OMAP_POWERSTATE_MASK ); +} +EXPORT_SYMBOL (pwrdm_read_next_pwrst); + +/** +* pwrdm_read_pwrst - get current powerdomain power state +* @pwrdm: struct powerdomain * to get power state +* +* Return the powerdomain pwrdm's current power state. Returns -EINVAL +* if the powerdomain pointer is null or returns the current power state +* upon success. +*/ +int pwrdm_read_pwrst (struct powerdomain *pwrdm) +{ +if (!pwrdm) +return -EINVAL ; + +return prm_read_mod_bits_shift (pwrdm->prcm_offs,PM_PWSTST , +OMAP_POWERSTATEST_MASK ); +} +EXPORT_SYMBOL (pwrdm_read_pwrst); + +/** +* pwrdm_read_prev_pwrst - get previous powerdomain power state +* @pwrdm: struct powerdomain * to get previous power state +* +* Return the powerdomain pwrdm's previous power state. Returns -EINVAL +* if the powerdomain pointer is null or returns the previous power state +* upon success. +*/ +int pwrdm_read_prev_pwrst (struct powerdomain *pwrdm) +{ +if (!pwrdm) +return -EINVAL ; + +return prm_read_mod_bits_shift (pwrdm->prcm_offs,OMAP3430_PM_PREPWSTST , +OMAP3430_LASTPOWERSTATEENTERED_MASK ); +} +EXPORT_SYMBOL (pwrdm_read_prev_pwrst); + +/** +* pwrdm_set_logic_retst - set powerdomain logic power state upon retention +* @pwrdm: struct powerdomain * to set +* @pwrst: one of the PWRDM_POWER_* macros +* +* Set the next power state that the logic portion of the powerdomain +* pwrdm will enter when the powerdomain enters retention. This will +* be either RETENTION or OFF, if supported. Returns -EINVAL if the +* powerdomain pointer is null or the target power state is not not +* supported, or returns 0 upon success. +*/ +int pwrdm_set_logic_retst (struct powerdomain *pwrdm,u8 pwrst) +{ +if (!pwrdm) +return -EINVAL ; + +if (!(pwrdm->pwrsts_logic_ret & (1 << pwrst))) +return -EINVAL ; + +pr_debug ("powerdomain: setting next logic powerstate for %s to %0x\n" , + pwrdm->name, pwrst); + +/* +* The register bit names below may not correspond to the +* actual names of the bits in each powerdomain's register, +* but the type of value returned is the same for each +* powerdomain. +*/ +prm_rmw_mod_reg_bits (OMAP3430_LOGICL1CACHERETSTATE , + (pwrst <<__ffs (OMAP3430_LOGICL1CACHERETSTATE )), + pwrdm->prcm_offs,PM_PWSTCTRL ); + +return 0 ; +} +EXPORT_SYMBOL (pwrdm_set_logic_retst); + +/** +* pwrdm_set_mem_onst - set memory power state while powerdomain ON +* @pwrdm: struct powerdomain * to set +* @bank: memory bank number to set (0-3) +* @pwrst: one of the PWRDM_POWER_* macros +* +* Set the next power state that memory bank x of the powerdomain +* pwrdm will enter when the powerdomain enters the ON state. Bank +* will be a number from 0 to 3, and represents different types of +* memory, depending on the powerdomain. Returns -EINVAL if the +* powerdomain pointer is null or the target power state is not not +* supported for this memory bank, -EEXIST if the target memory bank +* does not exist or is not controllable, or returns 0 upon success. +*/ +int pwrdm_set_mem_onst (struct powerdomain *pwrdm,u8 bank,u8 pwrst) +{ +u32 m; + +if (!pwrdm) +return -EINVAL ; + +if (pwrdm->banks < (bank +1 )) +return -EEXIST ; + +if (!(pwrdm->pwrsts_mem_on[bank] & (1 << pwrst))) +return -EINVAL ; + +pr_debug ("powerdomain: setting next memory powerstate for domain %s " +"bank %0x while pwrdm-ON to %0x\n" , pwrdm->name, bank, pwrst); + +/* +* The register bit names below may not correspond to the +* actual names of the bits in each powerdomain's register, +* but the type of value returned is the same for each +* powerdomain. +*/ +switch (bank) { +case 0 : + m =OMAP3430_SHAREDL1CACHEFLATONSTATE_MASK ; +break ; +case 1 : + m =OMAP3430_L1FLATMEMONSTATE_MASK ; +break ; +case 2 : + m =OMAP3430_SHAREDL2CACHEFLATONSTATE_MASK ; +break ; +case 3 : + m =OMAP3430_L2FLATMEMONSTATE_MASK ; +break ; +default : +WARN_ON (1 );/* should never happen */ +return -EEXIST ; + } + +prm_rmw_mod_reg_bits (m, (pwrst <<__ffs (m)), + pwrdm->prcm_offs,PM_PWSTCTRL ); + +return 0 ; +} +EXPORT_SYMBOL (pwrdm_set_mem_onst); + +/** +* pwrdm_set_mem_retst - set memory power state while powerdomain in RET +* @pwrdm: struct powerdomain * to set +* @bank: memory bank number to set (0-3) +* @pwrst: one of the PWRDM_POWER_* macros +* +* Set the next power state that memory bank x of the powerdomain +* pwrdm will enter when the powerdomain enters the RETENTION state. +* Bank will be a number from 0 to 3, and represents different types +* of memory, depending on the powerdomain. pwrst will be either +* RETENTION or OFF, if supported. Returns -EINVAL if the powerdomain +* pointer is null or the target power state is not not supported for +* this memory bank, -EEXIST if the target memory bank does not exist +* or is not controllable, or returns 0 upon success. +*/ +int pwrdm_set_mem_retst (struct powerdomain *pwrdm,u8 bank,u8 pwrst) +{ +u32 m; + +if (!pwrdm) +return -EINVAL ; + +if (pwrdm->banks < (bank +1 )) +return -EEXIST ; + +if (!(pwrdm->pwrsts_mem_ret[bank] & (1 << pwrst))) +return -EINVAL ; + +pr_debug ("powerdomain: setting next memory powerstate for domain %s " +"bank %0x while pwrdm-RET to %0x\n" , pwrdm->name, bank, pwrst); + +/* +* The register bit names below may not correspond to the +* actual names of the bits in each powerdomain's register, +* but the type of value returned is the same for each +* powerdomain. +*/ +switch (bank) { +case 0 : + m =OMAP3430_SHAREDL1CACHEFLATRETSTATE ; +break ; +case 1 : + m =OMAP3430_L1FLATMEMRETSTATE ; +break ; +case 2 : + m =OMAP3430_SHAREDL2CACHEFLATRETSTATE ; +break ; +case 3 : + m =OMAP3430_L2FLATMEMRETSTATE ; +break ; +default : +WARN_ON (1 );/* should never happen */ +return -EEXIST ; + } + +prm_rmw_mod_reg_bits (m, (pwrst <<__ffs (m)), pwrdm->prcm_offs, +PM_PWSTCTRL ); + +return 0 ; +} +EXPORT_SYMBOL (pwrdm_set_mem_retst); + +/** +* pwrdm_read_logic_pwrst - get current powerdomain logic retention power state +* @pwrdm: struct powerdomain * to get current logic retention power state +* +* Return the current power state that the logic portion of +* powerdomain pwrdm will enter +* Returns -EINVAL if the powerdomain pointer is null or returns the +* current logic retention power state upon success. +*/ +int pwrdm_read_logic_pwrst (struct powerdomain *pwrdm) +{ +if (!pwrdm) +return -EINVAL ; + +return prm_read_mod_bits_shift (pwrdm->prcm_offs,PM_PWSTST , +OMAP3430_LOGICSTATEST ); +} +EXPORT_SYMBOL (pwrdm_read_logic_pwrst); + +/** +* pwrdm_read_prev_logic_pwrst - get previous powerdomain logic power state +* @pwrdm: struct powerdomain * to get previous logic power state +* +* Return the powerdomain pwrdm's logic power state. Returns -EINVAL +* if the powerdomain pointer is null or returns the previous logic +* power state upon success. +*/ +int pwrdm_read_prev_logic_pwrst (struct powerdomain *pwrdm) +{ +if (!pwrdm) +return -EINVAL ; + +/* +* The register bit names below may not correspond to the +* actual names of the bits in each powerdomain's register, +* but the type of value returned is the same for each +* powerdomain. +*/ +return prm_read_mod_bits_shift (pwrdm->prcm_offs,OMAP3430_PM_PREPWSTST , +OMAP3430_LASTLOGICSTATEENTERED ); +} +EXPORT_SYMBOL (pwrdm_read_prev_logic_pwrst); + +/** +* pwrdm_read_mem_pwrst - get current memory bank power state +* @pwrdm: struct powerdomain * to get current memory bank power state +* @bank: memory bank number (0-3) +* +* Return the powerdomain pwrdm's current memory power state for bank +* x. Returns -EINVAL if the powerdomain pointer is null, -EEXIST if +* the target memory bank does not exist or is not controllable, or +* returns the current memory power state upon success. +*/ +int pwrdm_read_mem_pwrst (struct powerdomain *pwrdm,u8 bank) +{ +u32 m; + +if (!pwrdm) +return -EINVAL ; + +if (pwrdm->banks < (bank +1 )) +return -EEXIST ; + +/* +* The register bit names below may not correspond to the +* actual names of the bits in each powerdomain's register, +* but the type of value returned is the same for each +* powerdomain. +*/ +switch (bank) { +case 0 : + m =OMAP3430_SHAREDL1CACHEFLATSTATEST_MASK ; +break ; +case 1 : + m =OMAP3430_L1FLATMEMSTATEST_MASK ; +break ; +case 2 : + m =OMAP3430_SHAREDL2CACHEFLATSTATEST_MASK ; +break ; +case 3 : + m =OMAP3430_L2FLATMEMSTATEST_MASK ; +break ; +default : +WARN_ON (1 );/* should never happen */ +return -EEXIST ; + } + +return prm_read_mod_bits_shift (pwrdm->prcm_offs,PM_PWSTST , m); +} +EXPORT_SYMBOL (pwrdm_read_mem_pwrst); + +/** +* pwrdm_read_prev_mem_pwrst - get previous memory bank power state +* @pwrdm: struct powerdomain * to get previous memory bank power state +* @bank: memory bank number (0-3) +* +* Return the powerdomain pwrdm's previous memory power state for bank +* x. Returns -EINVAL if the powerdomain pointer is null, -EEXIST if +* the target memory bank does not exist or is not controllable, or +* returns the previous memory power state upon success. +*/ +int pwrdm_read_prev_mem_pwrst (struct powerdomain *pwrdm,u8 bank) +{ +u32 m; + +if (!pwrdm) +return -EINVAL ; + +if (pwrdm->banks < (bank +1 )) +return -EEXIST ; + +/* +* The register bit names below may not correspond to the actual +* names of the bits in each powerdomain's register, +* but the type of value returned is the same for each powerdomain. +*/ +switch (bank) { +case 0 : + m =OMAP3430_LASTMEM1STATEENTERED_MASK ; +break ; +case 1 : + m =OMAP3430_LASTMEM2STATEENTERED_MASK ; +break ; +case 2 : + m =OMAP3430_LASTSHAREDL2CACHEFLATSTATEENTERED_MASK ; +break ; +case 3 : + m =OMAP3430_LASTL2FLATMEMSTATEENTERED_MASK ; +break ; +default : +WARN_ON (1 );/* should never happen */ +return -EEXIST ; + } + +return prm_read_mod_bits_shift (pwrdm->prcm_offs, +OMAP3430_PM_PREPWSTST , m); +} +EXPORT_SYMBOL (pwrdm_read_prev_mem_pwrst); + +/** +* pwrdm_clear_all_prev_pwrst - clear previous powerstate register for a pwrdm +* @pwrdm: struct powerdomain * to clear +* +* Clear the powerdomain's previous power state register. Clears the +* entire register, including logic and memory bank previous power states. +* Returns -EINVAL if the powerdomain pointer is null, or returns 0 upon +* success. +*/ +int pwrdm_clear_all_prev_pwrst (struct powerdomain *pwrdm) +{ +if (!pwrdm) +return -EINVAL ; + +/* +* XXX should get the powerdomain's current state here; +* warn & fail if it is not ON. +*/ + +pr_debug ("powerdomain: clearing previous power state reg for %s\n" , + pwrdm->name); + +prm_write_mod_reg (0 , pwrdm->prcm_offs,OMAP3430_PM_PREPWSTST ); + +return 0 ; +} +EXPORT_SYMBOL (pwrdm_clear_all_prev_pwrst); + +/** +* pwrdm_wait_transition - wait for powerdomain power transition to finish +* @pwrdm: struct powerdomain * to wait for +* +* If the powerdomain pwrdm is in the process of a state transition, +* spin until it completes the power transition, or until an iteration +* bailout value is reached. Returns -EINVAL if the powerdomain +* pointer is null, -EAGAIN if the bailout value was reached, or +* returns 0 upon success. +*/ +int pwrdm_wait_transition (struct powerdomain *pwrdm) +{ +u32 c =0 ; + +if (!pwrdm) +return -EINVAL ; + +/* +* REVISIT: pwrdm_wait_transition() may be better implemented +* via a callback and a periodic timer check -- how long do we expect +* powerdomain transitions to take? +*/ + +/* XXX Is this udelay() value meaningful? */ +while ((prm_read_mod_reg (pwrdm->prcm_offs,PM_PWSTST ) & +OMAP_INTRANSITION ) && + (c++ <PWRDM_TRANSITION_BAILOUT )) +udelay (1 ); + +if (c >=PWRDM_TRANSITION_BAILOUT ) { +printk (KERN_ERR "powerdomain: waited too long for " +"powerdomain %s to complete transition\n" , pwrdm->name); +return -EAGAIN ; + } + +pr_debug ("powerdomain: completed transition in %d loops\n" , c); + +return 0 ; +} +EXPORT_SYMBOL (pwrdm_wait_transition); + +Index: linux-omap/arch/arm/plat-omap/Kconfig
===================================================================arch/arm/plat-omap/Kconfig +12
-0@@ -42,6 +42,18 @@ confident in your SRAM code, disabling this will save about 600 bytes. +config OMAP_DEBUG_POWERDOMAIN + bool "Emit debug messages from powerdomain layer" + depends on ARCH_OMAP2 || ARCH_OMAP3 + default n + help + Say Y here if you want to compile in powerdomain layer + debugging messages for OMAP2/3. These messages can + provide more detail as to why some powerdomain calls + may be failing, and will also emit a descriptive message + for every powerdomain register write. However, the + extra detail costs some memory. + config OMAP_RESET_CLOCKS bool "Reset unused clocks during boot" depends on ARCH_OMAPIndex:
linux-omap/include/asm-arm/arch-omap/powerdomain.h
===================================================================include/asm-arm/arch-omap/powerdomain.h new file +137
-0@@ -0,0 +1,137 @@ +/* +* OMAP2/3 powerdomain control +* +* Copyright (C) 2007-8 Texas Instruments, Inc. +* Copyright (C) 2007-8 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 <asm/arch/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 + +/* Powerdomain allowable state bitfields */ +#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_OFF_RET_ON (PWRSTS_OFF_RET | (1 << PWRDM_POWER_ON)) + + +/* +* Number of memory banks that are power-controllable. On OMAP3430, the +* maximum is 4. +*/ +#define PWRDM_MAX_MEM_BANKS 4 + +/* XXX A completely arbitrary number. What is reasonable here? */ +#define PWRDM_TRANSITION_BAILOUT 100000 + +struct powerdomain ; + +/* Encodes dependencies between powerdomains - statically defined */ +struct pwrdm_dep { + +struct powerdomain *pwrdm; + +/* Flags to mark OMAP chip restrictions, etc. */ +const omap_chip_t omap_chip; + +}; + +struct powerdomain { + +/* Powerdomain name */ +const char *name; + +/* the address offset from CM_BASE/PRM_BASE */ +const s16 prcm_offs; + +/* Used to represent the OMAP chip types containing this pwrdm */ +const omap_chip_t omap_chip; + +/* Bit shift of this powerdomain's PM_WKDEP/CM_SLEEPDEP bit */ +const u8 dep_bit; + +/* Powerdomains that can be told to wake this powerdomain up */ +const struct pwrdm_dep *wkdep_srcs; + +/* Powerdomains that can be told to keep this pwrdm from inactivity */ +const struct pwrdm_dep *sleepdep_srcs; + +/* Possible powerdomain power states */ +const u8 pwrsts; + +/* Possible logic power states when pwrdm in RETENTION */ +const u8 pwrsts_logic_ret; + +/* Number of software-controllable memory banks in this powerdomain */ +const u8 banks; + +/* Possible memory bank pwrstates when pwrdm in RETENTION */ +const u8 pwrsts_mem_ret[PWRDM_MAX_MEM_BANKS ]; + +/* Possible memory bank pwrstates when pwrdm is ON */ +const u8 pwrsts_mem_on[PWRDM_MAX_MEM_BANKS ]; + +/* List of clockdomains in this powerdomain */ +struct list_head pwrdm_clkdms; + +struct kobject *kobj; +struct list_head node; + +}; + + +void pwrdm_init (struct powerdomain **pwrdm_list); + +int pwrdm_register (struct powerdomain *pwrdm); +int pwrdm_unregister (struct powerdomain *pwrdm); +struct powerdomain *pwrdm_lookup (const char *name); + +int pwrdm_for_each (int (*fn)(struct powerdomain *pwrdm)); + +int pwrdm_add_wkdep (struct powerdomain *pwrdm1,struct powerdomain *pwrdm2); +int pwrdm_del_wkdep (struct powerdomain *pwrdm1,struct powerdomain *pwrdm2); +int pwrdm_read_wkdep (struct powerdomain *pwrdm1,struct powerdomain *pwrdm2); +int pwrdm_add_sleepdep (struct powerdomain *pwrdm1,struct powerdomain *pwrdm2); +int pwrdm_del_sleepdep (struct powerdomain *pwrdm1,struct powerdomain *pwrdm2); +int pwrdm_read_sleepdep (struct powerdomain *pwrdm1,struct powerdomain *pwrdm2); + +int pwrdm_set_next_pwrst (struct powerdomain *pwrdm,u8 pwrst); +int pwrdm_read_next_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_mem_pwrst (struct powerdomain *pwrdm,u8 bank); +int pwrdm_read_prev_mem_pwrst (struct powerdomain *pwrdm,u8 bank); + +int pwrdm_wait_transition (struct powerdomain *pwrdm); + +#endif Signature · 6 lines
-- -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Paul Walmsley
maintainerPATCH 3/5 Powerdomains: add OMAP2/3 common powerdomains
In reply to Paul WalmsleyAdd powerdomains common to both OMAP2 and OMAP3 (WKUP and GFX/SGX), and modify mach-omap2/io.c to initialize the powerdomain code on boot.
--- arch/arm/mach-omap2/io.c | 4 - arch/arm/mach-omap2/pm.c | 2 arch/arm/mach-omap2/powerdomains.h | 144 +++++++++++++++++++++++++++++++++++++ arch/arm/mach-omap2/prm.h | 3 4 files changed, 150 insertions(+), 3 deletions(-)
arch/arm/mach-omap2/io.c +3 -1
@@ -29,6 +29,8 @@#include <asm/arch/powerdomain.h> +#include "powerdomains.h" +extern void omap_sram_init (void );extern int omap2_clk_init (void );extern void omap2_check_revision (void );
@@ -190,7 +192,7 @@void __init omap2_init_common_hw (void ) {omap2_mux_init (); -pwrdm_init (NULL ); +pwrdm_init (powerdomains_omap);omap2_clk_init ();omap2_init_memory ();gpmc_init ();
arch/arm/mach-omap2/pm.c +1 -1
@@ -651,7 +651,7 @@__raw_writel (OMAP24XX_AUTOIDLE ,OMAP24XX_PRCM_SYSCONFIG );/* Set all domain wakeup dependencies */ -prm_write_mod_reg (OMAP_EN_WKUP ,MPU_MOD ,PM_WKDEP ); +prm_write_mod_reg (OMAP_EN_WKUP_MASK ,MPU_MOD ,PM_WKDEP );prm_write_mod_reg (0 ,OMAP24XX_DSP_MOD ,PM_WKDEP );prm_write_mod_reg (0 ,GFX_MOD ,PM_WKDEP );prm_write_mod_reg (0 ,CORE_MOD ,PM_WKDEP );
arch/arm/mach-omap2/powerdomains.h new file +144 -0
144 lines not on this page · raw message
arch/arm/mach-omap2/prm.h +2 -1
@@ -323,7 +323,8 @@* 3430: PM_WKDEP_IVA2, PM_WKDEP_GFX, PM_WKDEP_DSS, PM_WKDEP_CAM, * PM_WKDEP_PER */ -#define OMAP_EN_WKUP (1 << 4) +#define OMAP_EN_WKUP_SHIFT 4 +#define OMAP_EN_WKUP_MASK (1 << 4)/* * 24XX: PM_PWSTCTRL_MPU, PM_PWSTCTRL_CORE, PM_PWSTCTRL_GFX,
Signature · 4 lines
-- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Paul Walmsley
maintainerPATCH 4/5 Powerdomains: add OMAP2 powerdomains
In reply to Paul WalmsleyAdd OMAP2-specific powerdomains.
--- arch/arm/mach-omap2/powerdomains.h | 16 ++- arch/arm/mach-omap2/powerdomains24xx.h | 176 +++++++++++++++++++++++++++++++++ arch/arm/mach-omap2/prm-regbits-24xx.h | 12 +- 3 files changed, 199 insertions(+), 5 deletions(-)
arch/arm/mach-omap2/powerdomains.h +15 -1
@@ -79,7 +79,6 @@static struct powerdomain mpu_34xx_pwrdm;static struct powerdomain iva2_pwrdm; -/* OMAP2/3-common powerdomains and wakeup dependencies */ /*
@@ -96,6 +95,11 @@ { NULL }, }; +/* Include 24XX-specific powerdomains (which may reference the above wkdeps) */ + +#include "powerdomains24xx.h" + +/* * OMAP2/3 common powerdomains */
@@ -137,6 +141,16 @@ &gfx_pwrdm, &wkup_pwrdm, +#ifdef CONFIG_ARCH_OMAP24XX + &dsp_pwrdm, + &mpu_24xx_pwrdm, + &core_24xx_pwrdm, +#endif + +#ifdef CONFIG_ARCH_OMAP243X + &mdm_pwrdm, +#endif + NULL };
arch/arm/mach-omap2/powerdomains24xx.h new file +176 -0
176 lines not on this page · raw message
arch/arm/mach-omap2/prm-regbits-24xx.h +8 -4
@@ -29,8 +29,10 @@#define OMAP24XX_WKUP1_EN (1 << 0)/* PM_WKDEP_GFX, PM_WKDEP_MPU, PM_WKDEP_DSP, PM_WKDEP_MDM shared bits */ -#define OMAP24XX_EN_MPU (1 << 1) -#define OMAP24XX_EN_CORE (1 << 0) +#define OMAP24XX_EN_MPU_SHIFT 1 +#define OMAP24XX_EN_MPU_MASK (1 << 1) +#define OMAP24XX_EN_CORE_SHIFT 0 +#define OMAP24XX_EN_CORE_MASK (1 << 0)/* * PM_PWSTCTRL_MPU, PM_PWSTCTRL_GFX, PM_PWSTCTRL_DSP, PM_PWSTCTRL_MDM
@@ -140,8 +142,10 @@/* 2430 calls GLOBALWMPU_RST "GLOBALWARM_RST" instead */ /* PM_WKDEP_MPU specific bits */ -#define OMAP2430_PM_WKDEP_MPU_EN_MDM (1 << 5) -#define OMAP24XX_PM_WKDEP_MPU_EN_DSP (1 << 2) +#define OMAP2430_PM_WKDEP_MPU_EN_MDM_SHIFT 5 +#define OMAP2430_PM_WKDEP_MPU_EN_MDM_MASK (1 << 5) +#define OMAP24XX_PM_WKDEP_MPU_EN_DSP_SHIFT 2 +#define OMAP24XX_PM_WKDEP_MPU_EN_DSP_MASK (1 << 2)/* PM_EVGENCTRL_MPU specific bits */
Signature · 4 lines
-- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Paul Walmsley
maintainerPATCH 5/5 Powerdomains: Add OMAP3 powerdomains
In reply to Paul WalmsleyAdd OMAP3 powerdomains
--- arch/arm/mach-omap2/powerdomains.h | 20 ++ arch/arm/mach-omap2/powerdomains34xx.h | 296 +++++++++++++++++++++++++++++++++ arch/arm/mach-omap2/prcm-common.h | 3 arch/arm/mach-omap2/prm-regbits-34xx.h | 11 - 4 files changed, 323 insertions(+), 7 deletions(-)
arch/arm/mach-omap2/powerdomains.h +18 -2
@@ -95,9 +95,12 @@ { NULL }, }; -/* Include 24XX-specific powerdomains (which may reference the above wkdeps) */ - +/* +* Include 24XX & 34XX-specific powerdomains (which may reference the +* above wkdeps) +*/ #include "powerdomains24xx.h" +#include "powerdomains34xx.h" /*
@@ -151,6 +154,19 @@ &mdm_pwrdm,#endif +#ifdef CONFIG_ARCH_OMAP34XX + &iva2_pwrdm, + &mpu_34xx_pwrdm, + &neon_pwrdm, + &core_34xx_pwrdm, + &cam_pwrdm, + &dss_pwrdm, + &per_pwrdm, + &emu_pwrdm, + &sgx_pwrdm, + &usbhost_pwrdm, +#endif +NULL };
arch/arm/mach-omap2/powerdomains34xx.h new file +296 -0
296 lines not on this page · raw message
arch/arm/mach-omap2/prcm-common.h +2 -1
@@ -311,7 +311,8 @@#define OMAP3430_ST_GPT2 (1 << 3)/* CM_SLEEPDEP_PER, PM_WKDEP_IVA2, PM_WKDEP_MPU, PM_WKDEP_PER shared bits */ -#define OMAP3430_EN_CORE (1 << 0) +#define OMAP3430_EN_CORE_SHIFT 0 +#define OMAP3430_EN_CORE_MASK (1 << 0)#endif
arch/arm/mach-omap2/prm-regbits-34xx.h +7 -4
@@ -68,7 +68,8 @@#define OMAP3430_VPINIDLE (1 << 0)/* PM_WKDEP_IVA2, PM_WKDEP_MPU shared bits */ -#define OMAP3430_EN_PER (1 << 7) +#define OMAP3430_EN_PER_SHIFT 7 +#define OMAP3430_EN_PER_MASK (1 << 7)/* PM_PWSTCTRL_IVA2, PM_PWSTCTRL_MPU, PM_PWSTCTRL_CORE shared bits */ #define OMAP3430_MEMORYCHANGE (1 << 3)
@@ -77,7 +78,7 @@#define OMAP3430_LOGICSTATEST (1 << 2)/* PM_PREPWSTST_IVA2, PM_PREPWSTST_CORE shared bits */ -#define OMAP3430_LASTLOGICSTATEENTERED (1 << 2) +#define OMAP3430_LASTLOGICSTATEENTERED (1 << 2)/* * PM_PREPWSTST_IVA2, PM_PREPWSTST_MPU, PM_PREPWSTST_CORE,
@@ -278,8 +279,10 @@#define OMAP3430_EMULATION_MPU_RST (1 << 11)/* PM_WKDEP_MPU specific bits */ -#define OMAP3430_PM_WKDEP_MPU_EN_DSS (1 << 5) -#define OMAP3430_PM_WKDEP_MPU_EN_IVA2 (1 << 2) +#define OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT 5 +#define OMAP3430_PM_WKDEP_MPU_EN_DSS_MASK (1 << 5) +#define OMAP3430_PM_WKDEP_MPU_EN_IVA2_SHIFT 2 +#define OMAP3430_PM_WKDEP_MPU_EN_IVA2_MASK (1 << 2)/* PM_EVGENCTRL_MPU */ #define OMAP3430_OFFLOADMODE_SHIFT 3
Signature · 4 lines
-- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Tony Lindgren
maintainerRe: [PATCH 5/5] Powerdomains: Add OMAP3 powerdomains
Quoted 1 line · Paul Walmsley
Add OMAP3 powerdomains
This one seems to be missing S-o-b.
Tony
Quoted 404 lines
--- arch/arm/mach-omap2/powerdomains.h | 20 ++ arch/arm/mach-omap2/powerdomains34xx.h | 296 +++++++++++++++++++++++++++++++++ arch/arm/mach-omap2/prcm-common.h | 3 arch/arm/mach-omap2/prm-regbits-34xx.h | 11 - 4 files changed, 323 insertions(+), 7 deletions(-)Index:
linux-omap/arch/arm/mach-omap2/powerdomains.h
===================================================================arch/arm/mach-omap2/powerdomains.h +18
-2@@ -95,9 +95,12 @@ { NULL }, }; -/* Include 24XX-specific powerdomains (which may reference the above wkdeps) */ - +/* +* Include 24XX & 34XX-specific powerdomains (which may reference the +* above wkdeps) +*/ #include "powerdomains24xx.h" +#include "powerdomains34xx.h" /* @@ -151,6 +154,19 @@ &mdm_pwrdm,#endif +#ifdef CONFIG_ARCH_OMAP34XX + &iva2_pwrdm, + &mpu_34xx_pwrdm, + &neon_pwrdm, + &core_34xx_pwrdm, + &cam_pwrdm, + &dss_pwrdm, + &per_pwrdm, + &emu_pwrdm, + &sgx_pwrdm, + &usbhost_pwrdm, +#endif +NULL };Index:
linux-omap/arch/arm/mach-omap2/powerdomains34xx.h
===================================================================arch/arm/mach-omap2/powerdomains34xx.h new file +296
-0@@ -0,0 +1,296 @@ +/* +* OMAP34XX powerdomain definitions +* +* Copyright (C) 2007-8 Texas Instruments, Inc. +* Copyright (C) 2007-8 Nokia Corporation +* +* Written by Paul Walmsley +* Debugging and integration fixes by Jouni Högander +* +* 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 ARCH_ARM_MACH_OMAP2_POWERDOMAINS34XX +#define ARCH_ARM_MACH_OMAP2_POWERDOMAINS34XX + +/* +* N.B. If powerdomains are added or removed from this file, update +* the array in mach-omap2/powerdomains.h. +*/ + +#include <asm/arch/powerdomain.h> + +#include "prcm-common.h" +#include "prm.h" +#include "prm-regbits-34xx.h" +#include "cm.h" +#include "cm-regbits-34xx.h" + +/* Forward declarations - so powerdomain dependencies can be encoded */ + +#ifdef CONFIG_ARCH_OMAP34XX +static struct powerdomain mpu_34xx_pwrdm; +static struct powerdomain core_34xx_pwrdm; +static struct powerdomain dss_pwrdm; +static struct powerdomain sgx_pwrdm; +static struct powerdomain cam_pwrdm; +static struct powerdomain per_pwrdm; +static struct powerdomain emu_pwrdm; +static struct powerdomain neon_pwrdm; +static struct powerdomain usbhost_pwrdm; + +static struct pwrdm_dep cam_gfx_sleepdeps[]; +#endif + + +/* +* 34XX-specific powerdomains, dependencies +*/ + +#ifdef CONFIG_ARCH_OMAP34XX + +/* +* 3430: PM_WKDEP_{PER,USBHOST}: CORE, IVA2, MPU, WKUP +* (USBHOST is ES2 only) +*/ +static struct pwrdm_dep per_usbhost_wkdeps[] = { + { .pwrdm = &core_34xx_pwrdm, .omap_chip =CHIP_IS_OMAP3430 }, + { .pwrdm = &iva2_pwrdm, .omap_chip =CHIP_IS_OMAP3430 }, + { .pwrdm = &mpu_34xx_pwrdm, .omap_chip =CHIP_IS_OMAP3430 }, + { .pwrdm = &wkup_pwrdm, .omap_chip =CHIP_IS_OMAP3430 }, + {NULL }, +}; + +/* +* 3430 PM_WKDEP_MPU: CORE, IVA2, DSS, PER +*/ +static struct pwrdm_dep mpu_34xx_wkdeps[] = { + { .pwrdm = &core_34xx_pwrdm, .omap_chip =CHIP_IS_OMAP3430 }, + { .pwrdm = &iva2_pwrdm, .omap_chip =CHIP_IS_OMAP3430 }, + { .pwrdm = &dss_pwrdm, .omap_chip =CHIP_IS_OMAP3430 }, + { .pwrdm = &per_pwrdm, .omap_chip =CHIP_IS_OMAP3430 }, + {NULL }, +}; + +/* +* 3430 PM_WKDEP_IVA2: CORE, MPU, WKUP, DSS, PER +*/ +static struct pwrdm_dep iva2_wkdeps[] = { + { .pwrdm = &core_34xx_pwrdm, .omap_chip =CHIP_IS_OMAP3430 }, + { .pwrdm = &mpu_34xx_pwrdm, .omap_chip =CHIP_IS_OMAP3430 }, + { .pwrdm = &wkup_pwrdm, .omap_chip =CHIP_IS_OMAP3430 }, + { .pwrdm = &dss_pwrdm, .omap_chip =CHIP_IS_OMAP3430 }, + { .pwrdm = &per_pwrdm, .omap_chip =CHIP_IS_OMAP3430 }, + {NULL }, +}; + + +/* 3430 PM_WKDEP_{CAM,DSS}: IVA2, MPU, WKUP */ +static struct pwrdm_dep cam_dss_wkdeps[] = { + { .pwrdm = &iva2_pwrdm, .omap_chip =CHIP_IS_OMAP3430 }, + { .pwrdm = &mpu_34xx_pwrdm, .omap_chip =CHIP_IS_OMAP3430 }, + { .pwrdm = &wkup_pwrdm, .omap_chip =CHIP_IS_OMAP3430 }, + {NULL }, +}; + +/* 3430: PM_WKDEP_NEON: MPU */ +static struct pwrdm_dep neon_wkdeps[] = { + { .pwrdm = &mpu_34xx_pwrdm, .omap_chip =CHIP_IS_OMAP3430 }, + {NULL }, +}; + + +/* Sleep dependency source arrays - 34XX only */ + +/* +* 3430: CM_SLEEPDEP_CAM: MPU +* 3430ES1: CM_SLEEPDEP_GFX: MPU +* 3430ES2: CM_SLEEPDEP_SGX: MPU +*/ +static struct pwrdm_dep cam_gfx_sleepdeps[] = { + { .pwrdm = &mpu_34xx_pwrdm, .omap_chip =CHIP_IS_OMAP3430 }, + {NULL }, +}; + +/* +* 3430: CM_SLEEPDEP_{DSS,PER}: MPU, IVA +* 3430ES2: CM_SLEEPDEP_USBHOST: MPU, IVA +*/ +static struct pwrdm_dep dss_per_usbhost_sleepdeps[] = { + { .pwrdm = &mpu_34xx_pwrdm, .omap_chip =CHIP_IS_OMAP3430 }, + {NULL }, +}; + + +/* +* Powerdomains +*/ + +static struct powerdomain iva2_pwrdm = { + .name ="iva2_pwrdm" , + .prcm_offs =OMAP3430_IVA2_MOD , + .omap_chip =CHIP_IS_OMAP3430 , + .dep_bit =OMAP3430_PM_WKDEP_MPU_EN_IVA2_SHIFT , + .wkdep_srcs = iva2_wkdeps, + .pwrsts =PWRSTS_OFF_RET_ON , + .pwrsts_logic_ret =PWRSTS_OFF_RET , + .banks =4 , + .pwrsts_mem_ret = { + [0 ] =PWRSTS_OFF_RET , + [1 ] =PWRSTS_OFF_RET , + [2 ] =PWRSTS_OFF_RET , + [3 ] =PWRSTS_OFF_RET , + }, + .pwrsts_mem_on = { + [0 ] =PWRDM_POWER_ON , + [1 ] =PWRDM_POWER_ON , + [2 ] =PWRSTS_OFF_ON , + [3 ] =PWRDM_POWER_ON , + }, +}; + +static struct powerdomain mpu_34xx_pwrdm = { + .name ="mpu_pwrdm" , + .prcm_offs =MPU_MOD , + .omap_chip =CHIP_IS_OMAP3430 , + .dep_bit =OMAP3430_EN_MPU_SHIFT , + .wkdep_srcs = mpu_34xx_wkdeps, + .pwrsts =PWRSTS_OFF_RET_ON , + .pwrsts_logic_ret =PWRSTS_OFF_RET , + .banks =1 , + .pwrsts_mem_ret = { + [0 ] =PWRSTS_OFF_RET , + }, + .pwrsts_mem_on = { + [0 ] =PWRSTS_OFF_ON , + }, +}; + +/* No wkdeps or sleepdeps for 34xx core apparently */ +static struct powerdomain core_34xx_pwrdm = { + .name ="core_pwrdm" , + .prcm_offs =CORE_MOD , + .omap_chip =CHIP_IS_OMAP3430 , + .pwrsts =PWRSTS_OFF_RET_ON , + .dep_bit =OMAP3430_EN_CORE_SHIFT , + .banks =2 , + .pwrsts_mem_ret = { + [0 ] =PWRSTS_OFF_RET ,/* MEM1RETSTATE */ + [1 ] =PWRSTS_OFF_RET ,/* MEM2RETSTATE */ + }, + .pwrsts_mem_on = { + [0 ] =PWRSTS_OFF_RET_ON ,/* MEM1ONSTATE */ + [1 ] =PWRSTS_OFF_RET_ON ,/* MEM2ONSTATE */ + }, +}; + +/* Another case of bit name collisions between several registers: EN_DSS */ +static struct powerdomain dss_pwrdm = { + .name ="dss_pwrdm" , + .omap_chip =CHIP_IS_OMAP3430 , + .prcm_offs =OMAP3430_DSS_MOD , + .dep_bit =OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT , + .wkdep_srcs = cam_dss_wkdeps, + .sleepdep_srcs = dss_per_usbhost_sleepdeps, + .pwrsts =PWRSTS_OFF_RET_ON , + .pwrsts_logic_ret =PWRDM_POWER_RET , + .banks =1 , + .pwrsts_mem_ret = { + [0 ] =PWRDM_POWER_RET ,/* MEMRETSTATE */ + }, + .pwrsts_mem_on = { + [0 ] =PWRDM_POWER_ON ,/* MEMONSTATE */ + }, +}; + +static struct powerdomain sgx_pwrdm = { + .name ="sgx_pwrdm" , + .prcm_offs =OMAP3430ES2_SGX_MOD , + .omap_chip =CHIP_IS_OMAP3430ES2 , + .wkdep_srcs = gfx_sgx_wkdeps, + .sleepdep_srcs = cam_gfx_sleepdeps, +/* XXX This is accurate for 3430 SGX, but what about GFX? */ + .pwrsts =PWRSTS_OFF_RET_ON , + .pwrsts_logic_ret =PWRDM_POWER_RET , + .banks =1 , + .pwrsts_mem_ret = { + [0 ] =PWRDM_POWER_RET ,/* MEMRETSTATE */ + }, + .pwrsts_mem_on = { + [0 ] =PWRDM_POWER_ON ,/* MEMONSTATE */ + }, +}; + +static struct powerdomain cam_pwrdm = { + .name ="cam_pwrdm" , + .omap_chip =CHIP_IS_OMAP3430 , + .prcm_offs =OMAP3430_CAM_MOD , + .wkdep_srcs = cam_dss_wkdeps, + .sleepdep_srcs = cam_gfx_sleepdeps, + .pwrsts =PWRSTS_OFF_RET_ON , + .pwrsts_logic_ret =PWRDM_POWER_RET , + .banks =1 , + .pwrsts_mem_ret = { + [0 ] =PWRDM_POWER_RET ,/* MEMRETSTATE */ + }, + .pwrsts_mem_on = { + [0 ] =PWRDM_POWER_ON ,/* MEMONSTATE */ + }, +}; + +static struct powerdomain per_pwrdm = { + .name ="per_pwrdm" , + .prcm_offs =OMAP3430_PER_MOD , + .omap_chip =CHIP_IS_OMAP3430 , + .dep_bit =OMAP3430_EN_PER_SHIFT , + .wkdep_srcs = per_usbhost_wkdeps, + .sleepdep_srcs = dss_per_usbhost_sleepdeps, + .pwrsts =PWRSTS_OFF_RET_ON , + .pwrsts_logic_ret =PWRSTS_OFF_RET , + .banks =1 , + .pwrsts_mem_ret = { + [0 ] =PWRDM_POWER_RET ,/* MEMRETSTATE */ + }, + .pwrsts_mem_on = { + [0 ] =PWRDM_POWER_ON ,/* MEMONSTATE */ + }, +}; + +static struct powerdomain emu_pwrdm = { + .name ="emu_pwrdm" , + .prcm_offs =OMAP3430_EMU_MOD , + .omap_chip =CHIP_IS_OMAP3430 , +}; + +static struct powerdomain neon_pwrdm = { + .name ="neon_pwrdm" , + .prcm_offs =OMAP3430_NEON_MOD , + .omap_chip =CHIP_IS_OMAP3430 , + .wkdep_srcs = neon_wkdeps, + .pwrsts =PWRSTS_OFF_RET_ON , + .pwrsts_logic_ret =PWRDM_POWER_RET , +}; + +static struct powerdomain usbhost_pwrdm = { + .name ="usbhost_pwrdm" , + .prcm_offs =OMAP3430ES2_USBHOST_MOD , + .omap_chip =CHIP_IS_OMAP3430ES2 , + .wkdep_srcs = per_usbhost_wkdeps, + .sleepdep_srcs = dss_per_usbhost_sleepdeps, + .pwrsts =PWRSTS_OFF_RET_ON , + .pwrsts_logic_ret =PWRDM_POWER_RET , + .banks =1 , + .pwrsts_mem_ret = { + [0 ] =PWRDM_POWER_RET ,/* MEMRETSTATE */ + }, + .pwrsts_mem_on = { + [0 ] =PWRDM_POWER_ON ,/* MEMONSTATE */ + }, +}; + +#endif /* CONFIG_ARCH_OMAP34XX */ + + +#endif Index:
linux-omap/arch/arm/mach-omap2/prcm-common.h
===================================================================arch/arm/mach-omap2/prcm-common.h +2
-1@@ -311,7 +311,8 @@#define OMAP3430_ST_GPT2 (1 << 3)/* CM_SLEEPDEP_PER, PM_WKDEP_IVA2, PM_WKDEP_MPU, PM_WKDEP_PER shared bits */ -#define OMAP3430_EN_CORE (1 << 0) +#define OMAP3430_EN_CORE_SHIFT 0 +#define OMAP3430_EN_CORE_MASK (1 << 0)#endif Index:
linux-omap/arch/arm/mach-omap2/prm-regbits-34xx.h
===================================================================arch/arm/mach-omap2/prm-regbits-34xx.h +7
-4@@ -68,7 +68,8 @@#define OMAP3430_VPINIDLE (1 << 0)/* PM_WKDEP_IVA2, PM_WKDEP_MPU shared bits */ -#define OMAP3430_EN_PER (1 << 7) +#define OMAP3430_EN_PER_SHIFT 7 +#define OMAP3430_EN_PER_MASK (1 << 7)/* PM_PWSTCTRL_IVA2, PM_PWSTCTRL_MPU, PM_PWSTCTRL_CORE shared bits */ #define OMAP3430_MEMORYCHANGE (1 << 3)@@ -77,7 +78,7 @@#define OMAP3430_LOGICSTATEST (1 << 2)/* PM_PREPWSTST_IVA2, PM_PREPWSTST_CORE shared bits */ -#define OMAP3430_LASTLOGICSTATEENTERED (1 << 2) +#define OMAP3430_LASTLOGICSTATEENTERED (1 << 2)/* * PM_PREPWSTST_IVA2, PM_PREPWSTST_MPU, PM_PREPWSTST_CORE, @@ -278,8 +279,10 @@#define OMAP3430_EMULATION_MPU_RST (1 << 11)/* PM_WKDEP_MPU specific bits */ -#define OMAP3430_PM_WKDEP_MPU_EN_DSS (1 << 5) -#define OMAP3430_PM_WKDEP_MPU_EN_IVA2 (1 << 2) +#define OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT 5 +#define OMAP3430_PM_WKDEP_MPU_EN_DSS_MASK (1 << 5) +#define OMAP3430_PM_WKDEP_MPU_EN_IVA2_SHIFT 2 +#define OMAP3430_PM_WKDEP_MPU_EN_IVA2_MASK (1 << 2)/* PM_EVGENCTRL_MPU */ #define OMAP3430_OFFLOADMODE_SHIFT 3Signature · 6 lines
-- -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Paul Walmsley
maintainerRe: [PATCH 5/5] Powerdomains: Add OMAP3 powerdomains
Hi Tony,
these changes all look good, I will repost.
Thanks for the comments,
- Paul