* [PATCH 0/29] PM: proposed branch for PM collaboration
@ 2008-09-11 12:31 Kevin Hilman
2008-09-11 12:33 ` [PATCH 01/29] PM: Dynamic GPIO clock handling Kevin Hilman
` (3 more replies)
0 siblings, 4 replies; 37+ messages in thread
From: Kevin Hilman @ 2008-09-11 12:31 UTC (permalink / raw)
To: linux-omap
Hello,
The following patchset is an attempt to collect the various PM patches
that have been flowing around, and organize them into one branch to be
used for further collaboration on PM development, in particular
OFF-mode support.
It is currently a collection of proposed patches[1] from TI and
various other patches from Nokia and others to get retention,
OFF-mode, CPUidle etc. working in the linux-omap tree.
This series is nowhere near ready for merging into linux-omap, but
will be useful for discussion and collaboration on getting the various
PM features working at the head of the linux-omap tree, and a place
where cleanup and rework efforts can be focused.
If there are no major objections, I will create a branch in linux-omap
git and commit this series there. As collaboration continues, I will
continue to collect and update patches, fix problems and rebase onto
the HEAD of linux-omap.
The goal of this branch is only to facilitate the rework and cleanup
of the PM code so it can be merged into linux-omap. Then, the branch
will disappear and work can be focused again on the HEAD of
linux-omap.
It has currently been tested with a minimal config on 3430SDP, and
OFF-mode is hit in suspend. In order to hit suspend:
echo 1 > /sys/power/voltage_off_while_idle
echo 1 > /sys/power/gpio_clocks_off_while_idle
echo 1 > /sys/power/uart_clocks_off_while_idle
echo mem > /sys/power/state
Kevin
[1] This series is roughly based on the following:
Jouni Hogander, Tero Kristo
[PATCH 0/4] Refreshed PM workaround patches 2 -- 15 Aug
Rajendra Nayak:
[PATCH 00/11] OMAP3 CPUidle patches - ver 2 -- 18 July
As well as several patches/hacks/cleanups that have not yet been
posted to the list.
Also, there have been newer versions of the CPUidle patches that have
been reviewed on the list, but do not apply for various reasons. As
soon as they are rebased and updated versions of those are available,
I will integrate them.
^ permalink raw reply [flat|nested] 37+ messages in thread* [PATCH 01/29] PM: Dynamic GPIO clock handling 2008-09-11 12:31 [PATCH 0/29] PM: proposed branch for PM collaboration Kevin Hilman @ 2008-09-11 12:33 ` Kevin Hilman 2008-09-11 12:33 ` [PATCH 02/29] Added sleep support to UART Kevin Hilman 2008-09-11 17:40 ` [PATCH 0/29] PM: proposed branch for PM collaboration Tony Lindgren ` (2 subsequent siblings) 3 siblings, 1 reply; 37+ messages in thread From: Kevin Hilman @ 2008-09-11 12:33 UTC (permalink / raw) To: linux-omap; +Cc: ext Jouni Hogander From: ext Jouni Hogander <jouni.hogander@nokia.com> In omap3 gpios 2-6 are in per domain. Functional clocks for these should be disabled. GPIO modules in PER domain are not able to act as a wake up source if PER domain is in retention. PER domain sleep transition before MPU is prevented by leaving icks active. PER domain still enters retention together with MPU. When this happens IOPAD wake up mechanism is used for gpios. Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com> --- arch/arm/mach-omap2/pm.c | 20 ++++++++------ arch/arm/mach-omap2/pm.h | 2 +- arch/arm/mach-omap2/pm34xx.c | 56 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 67 insertions(+), 11 deletions(-) diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index 4652136..1de5f14 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -32,7 +32,7 @@ #include "pm.h" unsigned short enable_dyn_sleep; -unsigned short clocks_off_while_idle; +unsigned short gpio_clocks_off_while_idle; atomic_t sleep_block = ATOMIC_INIT(0); static ssize_t idle_show(struct kobject *, struct kobj_attribute *, char *); @@ -42,16 +42,16 @@ static ssize_t idle_store(struct kobject *k, struct kobj_attribute *, static struct kobj_attribute sleep_while_idle_attr = __ATTR(sleep_while_idle, 0644, idle_show, idle_store); -static struct kobj_attribute clocks_off_while_idle_attr = - __ATTR(clocks_off_while_idle, 0644, idle_show, idle_store); +static struct kobj_attribute gpio_clocks_off_while_idle_attr = + __ATTR(gpio_clocks_off_while_idle, 0644, idle_show, idle_store); static ssize_t idle_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { if (attr == &sleep_while_idle_attr) return sprintf(buf, "%hu\n", enable_dyn_sleep); - else if (attr == &clocks_off_while_idle_attr) - return sprintf(buf, "%hu\n", clocks_off_while_idle); + else if (attr == &gpio_clocks_off_while_idle_attr) + return sprintf(buf, "%hu\n", gpio_clocks_off_while_idle); else return -EINVAL; } @@ -69,8 +69,8 @@ static ssize_t idle_store(struct kobject *kobj, struct kobj_attribute *attr, if (attr == &sleep_while_idle_attr) enable_dyn_sleep = value; - else if (attr == &clocks_off_while_idle_attr) - clocks_off_while_idle = value; + else if (attr == &gpio_clocks_off_while_idle_attr) + gpio_clocks_off_while_idle = value; else return -EINVAL; @@ -106,10 +106,12 @@ static int __init omap_pm_init(void) /* disabled till drivers are fixed */ enable_dyn_sleep = 0; error = sysfs_create_file(power_kobj, &sleep_while_idle_attr.attr); - if (error) + if (error) { printk(KERN_ERR "sysfs_create_file failed: %d\n", error); + return error; + } error = sysfs_create_file(power_kobj, - &clocks_off_while_idle_attr.attr); + &gpio_clocks_off_while_idle_attr.attr); if (error) printk(KERN_ERR "sysfs_create_file failed: %d\n", error); diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index 68c9278..d446ea4 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h @@ -17,7 +17,7 @@ extern int omap2_pm_init(void); extern int omap3_pm_init(void); extern unsigned short enable_dyn_sleep; -extern unsigned short clocks_off_while_idle; +extern unsigned short gpio_clocks_off_while_idle; extern atomic_t sleep_block; extern void omap2_block_sleep(void); diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index a16eb33..0baf359 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -53,6 +53,43 @@ static void (*saved_idle)(void); static struct powerdomain *mpu_pwrdm; +/* Dynamic GPIO clock handling for sleep routines. + * omap_sram_idle() will call these functions and they will dynamically + * enable / disable GPIO clocks to allow sleep transitions. */ +#define NUM_OF_PERGPIOS 5 +static struct clk *gpio_fcks[NUM_OF_PERGPIOS]; + +/* Enable GPIO clocks from sleep routines if allowed */ +static void per_gpio_clk_enable(void) +{ + int i; + + if (gpio_clocks_off_while_idle == 0) + return; + for (i = 1; i < NUM_OF_PERGPIOS + 1; i++) + clk_enable(gpio_fcks[i-1]); +} + +/* Disable GPIO clocks from sleep routines if allowed */ +static void per_gpio_clk_disable(void) +{ + int i; + + if (gpio_clocks_off_while_idle == 0) + return; + for (i = 1; i < NUM_OF_PERGPIOS + 1; i++) + clk_disable(gpio_fcks[i-1]); +} + +/* XXX This is for gpio fclk hack. Will be removed as gpio driver + * handles fcks correctly */ +static void gpio_fclk_mask(u32 *fclk) +{ + if (gpio_clocks_off_while_idle == 0) + return; + *fclk &= ~(0x1f << 13); +} + /* PRCM Interrupt Handler for wakeups */ static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id) { @@ -169,8 +206,14 @@ static void omap_sram_idle(void) omap2_gpio_prepare_for_retention(); + /* Disable GPIO clocks if allowed */ + per_gpio_clk_disable(); + _omap_sram_idle(NULL, save_state); + /* Enable GPIO clocks if allowed */ + per_gpio_clk_enable(); + omap2_gpio_resume_after_retention(); } @@ -203,6 +246,9 @@ static int omap3_fclks_active(void) CM_FCLKEN); fck_per = cm_read_mod_reg(OMAP3430_PER_MOD, CM_FCLKEN); + + gpio_fclk_mask(&fck_per); + if (fck_core1 | fck_core3 | fck_sgx | fck_dss | fck_cam | fck_per | fck_usbhost) return 1; @@ -544,7 +590,8 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm) int __init omap3_pm_init(void) { struct power_state *pwrst; - int ret; + char clk_name[11]; + int ret, i; printk(KERN_ERR "Power Management for TI OMAP3.\n"); @@ -580,6 +627,13 @@ int __init omap3_pm_init(void) pm_idle = omap3_pm_idle; + /* XXX This is for gpio fclk hack. Will be removed as gpio driver + * handles fcks correctly */ + for (i = 1; i < NUM_OF_PERGPIOS + 1; i++) { + sprintf(clk_name, "gpio%d_fck", i + 1); + gpio_fcks[i-1] = clk_get(NULL, clk_name); + } + err1: return ret; err2: -- 1.6.0 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 02/29] Added sleep support to UART 2008-09-11 12:33 ` [PATCH 01/29] PM: Dynamic GPIO clock handling Kevin Hilman @ 2008-09-11 12:33 ` Kevin Hilman 2008-09-11 12:33 ` [PATCH 03/29] PM debug support for 34xx Kevin Hilman 0 siblings, 1 reply; 37+ messages in thread From: Kevin Hilman @ 2008-09-11 12:33 UTC (permalink / raw) To: linux-omap; +Cc: Tero Kristo From: Tero Kristo <tero.kristo@nokia.com> UART usage (e.g. serial console) now denies sleep for 5 seconds. This makes it possible to use serial console when dynamic idle is enabled. Write 1 to /sys/power/uart_clocks_off_while_idle to enable uart clock disable on idle. Without this omap won't enter retention. Also moved code from pm-debug.c to serial.c, and made pm24xx.c use this new implementation. Sleep deny timer can be configured by writing desired value (in ms) to /sys/devices/platform/serial8250.0/serial_awake_time (default 5000, i.e. 5 seconds.) Signed-off-by: Tero Kristo <tero.kristo@nokia.com> --- arch/arm/mach-omap2/pm-debug.c | 132 ---------------------- arch/arm/mach-omap2/pm.c | 15 +++ arch/arm/mach-omap2/pm.h | 10 +-- arch/arm/mach-omap2/pm24xx.c | 54 +++++---- arch/arm/mach-omap2/pm34xx.c | 13 ++ arch/arm/mach-omap2/serial.c | 180 +++++++++++++++++++++++++++++- arch/arm/plat-omap/include/mach/common.h | 3 + 7 files changed, 242 insertions(+), 165 deletions(-) diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c index 1b14bcf..b00f5f4 100644 --- a/arch/arm/mach-omap2/pm-debug.c +++ b/arch/arm/mach-omap2/pm-debug.c @@ -37,138 +37,6 @@ #ifdef CONFIG_PM_DEBUG int omap2_pm_debug = 0; -static int serial_console_clock_disabled; -static int serial_console_uart; -static unsigned int serial_console_next_disable; - -static struct clk *console_iclk, *console_fclk; - -static void serial_console_kick(void) -{ - serial_console_next_disable = omap2_read_32k_sync_counter(); - /* Keep the clocks on for 4 secs */ - serial_console_next_disable += 4 * 32768; -} - -static void serial_wait_tx(void) -{ - static const unsigned long uart_bases[3] = { - 0x4806a000, 0x4806c000, 0x4806e000 - }; - unsigned long lsr_reg; - int looped = 0; - - /* Wait for TX FIFO and THR to get empty */ - lsr_reg = IO_ADDRESS(uart_bases[serial_console_uart - 1] + (5 << 2)); - while ((__raw_readb(lsr_reg) & 0x60) != 0x60) - looped = 1; - if (looped) - serial_console_kick(); -} - -u32 omap2_read_32k_sync_counter(void) -{ - return omap_readl(OMAP2_32KSYNCT_BASE + 0x0010); -} - -void serial_console_fclk_mask(u32 *f1, u32 *f2) -{ - switch (serial_console_uart) { - case 1: - *f1 &= ~(1 << 21); - break; - case 2: - *f1 &= ~(1 << 22); - break; - case 3: - *f2 &= ~(1 << 2); - break; - } -} - -void serial_console_sleep(int enable) -{ - if (console_iclk == NULL || console_fclk == NULL) - return; - - if (enable) { - BUG_ON(serial_console_clock_disabled); - if (clk_get_usecount(console_fclk) == 0) - return; - if ((int) serial_console_next_disable - (int) omap2_read_32k_sync_counter() >= 0) - return; - serial_wait_tx(); - clk_disable(console_iclk); - clk_disable(console_fclk); - serial_console_clock_disabled = 1; - } else { - int serial_wakeup = 0; - u32 l; - - switch (serial_console_uart) { - case 1: - l = prm_read_mod_reg(CORE_MOD, PM_WKST1); - if (l & OMAP24XX_ST_UART1) - serial_wakeup = 1; - break; - case 2: - l = prm_read_mod_reg(CORE_MOD, PM_WKST1); - if (l & OMAP24XX_ST_UART2) - serial_wakeup = 1; - break; - case 3: - l = prm_read_mod_reg(CORE_MOD, OMAP24XX_PM_WKST2); - if (l & OMAP24XX_ST_UART3) - serial_wakeup = 1; - break; - } - if (serial_wakeup) - serial_console_kick(); - if (!serial_console_clock_disabled) - return; - clk_enable(console_iclk); - clk_enable(console_fclk); - serial_console_clock_disabled = 0; - } -} - -void pm_init_serial_console(void) -{ - const struct omap_serial_console_config *conf; - char name[16]; - - conf = omap_get_config(OMAP_TAG_SERIAL_CONSOLE, - struct omap_serial_console_config); - if (conf == NULL) - return; - if (conf->console_uart > 3 || conf->console_uart < 1) - return; - serial_console_uart = conf->console_uart; - sprintf(name, "uart%d_fck", conf->console_uart); - console_fclk = clk_get(NULL, name); - if (IS_ERR(console_fclk)) - console_fclk = NULL; - name[6] = 'i'; - console_iclk = clk_get(NULL, name); - if (IS_ERR(console_fclk)) - console_iclk = NULL; - if (console_fclk == NULL || console_iclk == NULL) { - serial_console_uart = 0; - return; - } - switch (serial_console_uart) { - case 1: - prm_set_mod_reg_bits(OMAP24XX_ST_UART1, CORE_MOD, PM_WKEN1); - break; - case 2: - prm_set_mod_reg_bits(OMAP24XX_ST_UART2, CORE_MOD, PM_WKEN1); - break; - case 3: - prm_set_mod_reg_bits(OMAP24XX_ST_UART3, CORE_MOD, OMAP24XX_PM_WKEN2); - break; - } -} - #define DUMP_PRM_MOD_REG(mod, reg) \ regs[reg_count].name = #mod "." #reg; \ regs[reg_count++].val = prm_read_mod_reg(mod, reg) diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index 1de5f14..b8aae08 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -33,6 +33,7 @@ unsigned short enable_dyn_sleep; unsigned short gpio_clocks_off_while_idle; +unsigned short uart_clocks_off_while_idle; atomic_t sleep_block = ATOMIC_INIT(0); static ssize_t idle_show(struct kobject *, struct kobj_attribute *, char *); @@ -45,6 +46,9 @@ static struct kobj_attribute sleep_while_idle_attr = static struct kobj_attribute gpio_clocks_off_while_idle_attr = __ATTR(gpio_clocks_off_while_idle, 0644, idle_show, idle_store); +static struct kobj_attribute uart_clocks_off_while_idle_attr = + __ATTR(uart_clocks_off_while_idle, 0644, idle_show, idle_store); + static ssize_t idle_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { @@ -52,6 +56,8 @@ static ssize_t idle_show(struct kobject *kobj, struct kobj_attribute *attr, return sprintf(buf, "%hu\n", enable_dyn_sleep); else if (attr == &gpio_clocks_off_while_idle_attr) return sprintf(buf, "%hu\n", gpio_clocks_off_while_idle); + else if (attr == &uart_clocks_off_while_idle_attr) + return sprintf(buf, "%hu\n", uart_clocks_off_while_idle); else return -EINVAL; } @@ -71,6 +77,8 @@ static ssize_t idle_store(struct kobject *kobj, struct kobj_attribute *attr, enable_dyn_sleep = value; else if (attr == &gpio_clocks_off_while_idle_attr) gpio_clocks_off_while_idle = value; + else if (attr == &uart_clocks_off_while_idle_attr) + uart_clocks_off_while_idle = value; else return -EINVAL; @@ -111,6 +119,13 @@ static int __init omap_pm_init(void) return error; } error = sysfs_create_file(power_kobj, + &uart_clocks_off_while_idle_attr.attr); + if (error) { + printk(KERN_ERR "sysfs_create_file failed: %d\n", error); + return error; + } + + error = sysfs_create_file(power_kobj, &gpio_clocks_off_while_idle_attr.attr); if (error) printk(KERN_ERR "sysfs_create_file failed: %d\n", error); diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index d446ea4..60a386d 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h @@ -18,25 +18,17 @@ extern int omap3_pm_init(void); extern unsigned short enable_dyn_sleep; extern unsigned short gpio_clocks_off_while_idle; +extern unsigned short uart_clocks_off_while_idle; extern atomic_t sleep_block; extern void omap2_block_sleep(void); extern void omap2_allow_sleep(void); - #ifdef CONFIG_PM_DEBUG -extern u32 omap2_read_32k_sync_counter(void); extern void omap2_pm_dump(int mode, int resume, unsigned int us); -extern void serial_console_fclk_mask(u32 *f1, u32 *f2); -extern void pm_init_serial_console(void); -extern void serial_console_sleep(int enable); extern int omap2_pm_debug; #else -#define omap2_read_32k_sync_counter() 0 -#define serial_console_sleep(enable) do {} while (0); -#define pm_init_serial_console() do {} while (0); #define omap2_pm_dump(mode, resume, us) do {} while (0); -#define serial_console_fclk_mask(f1, f2) do {} while (0); #define omap2_pm_debug 0 #endif /* CONFIG_PM_DEBUG */ #endif diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c index 60ff04f..4be9385 100644 --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c @@ -44,6 +44,7 @@ #include <mach/mux.h> #include <mach/dma.h> #include <mach/board.h> +#include <mach/common.h> #include "prm.h" #include "prm-regbits-24xx.h" @@ -74,7 +75,9 @@ static int omap2_fclks_active(void) f1 = cm_read_mod_reg(CORE_MOD, CM_FCLKEN1); f2 = cm_read_mod_reg(CORE_MOD, OMAP24XX_CM_FCLKEN2); - serial_console_fclk_mask(&f1, &f2); + + omap_serial_fclk_mask(&f1, &f2); + if (f1 | f2) return 1; return 0; @@ -82,7 +85,8 @@ static int omap2_fclks_active(void) static void omap2_enter_full_retention(void) { - u32 l, sleep_time = 0; + u32 l = 0; + struct timespec sleep_time; /* There is 1 reference hold for all children of the oscillator * clock, the following will remove it. If no one else uses the @@ -112,30 +116,33 @@ static void omap2_enter_full_retention(void) if (omap2_pm_debug) { omap2_pm_dump(0, 0, 0); - sleep_time = omap2_read_32k_sync_counter(); + getnstimeofday(&sleep_time); } + omap_serial_enable_clocks(0); + /* One last check for pending IRQs to avoid extra latency due * to sleeping unnecessarily. */ if (omap_irq_pending()) goto no_sleep; - serial_console_sleep(1); /* Jump to SRAM suspend code */ omap2_sram_suspend(sdrc_read_reg(SDRC_DLLA_CTRL), OMAP_SDRC_REGADDR(SDRC_DLLA_CTRL), OMAP_SDRC_REGADDR(SDRC_POWER)); no_sleep: - serial_console_sleep(0); + omap_serial_check_wakeup(); + omap_serial_enable_clocks(1); if (omap2_pm_debug) { - unsigned long long tmp; - u32 resume_time; - - resume_time = omap2_read_32k_sync_counter(); - tmp = resume_time - sleep_time; - tmp *= 1000000; - omap2_pm_dump(0, 1, tmp / 32768); + struct timespec t; + struct timespec ts_delta; + + getnstimeofday(&t); + ts_delta = timespec_sub(t, sleep_time); + omap2_pm_dump(0, 1, + div_s64(timespec_to_ns(&ts_delta), + NSEC_PER_USEC)); } omap2_gpio_resume_after_retention(); @@ -196,7 +203,7 @@ static int omap2_allow_mpu_retention(void) static void omap2_enter_mpu_retention(void) { - u32 sleep_time = 0; + struct timespec sleep_time; int only_idle = 0; /* Putting MPU into the WFI state while a transfer is active @@ -225,19 +232,20 @@ static void omap2_enter_mpu_retention(void) if (omap2_pm_debug) { omap2_pm_dump(only_idle ? 2 : 1, 0, 0); - sleep_time = omap2_read_32k_sync_counter(); + getnstimeofday(&sleep_time); } omap2_sram_idle(); if (omap2_pm_debug) { - unsigned long long tmp; - u32 resume_time; - - resume_time = omap2_read_32k_sync_counter(); - tmp = resume_time - sleep_time; - tmp *= 1000000; - omap2_pm_dump(only_idle ? 2 : 1, 1, tmp / 32768); + struct timespec t; + struct timespec ts_delta; + + getnstimeofday(&t); + ts_delta = timespec_sub(t, sleep_time); + omap2_pm_dump(only_idle ? 2 : 1, 1, + div_s64(timespec_to_ns(&ts_delta), + NSEC_PER_USEC)); } } @@ -253,6 +261,8 @@ static int omap2_can_sleep(void) return 0; if (omap_dma_running()) return 0; + if (!omap_serial_can_sleep()) + return 0; return 1; } @@ -520,8 +530,6 @@ int __init omap2_pm_init(void) prcm_setup_regs(); - pm_init_serial_console(); - /* Hack to prevent MPU retention when STI console is enabled. */ { const struct omap_sti_console_config *sti; diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 0baf359..32922ae 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -29,6 +29,7 @@ #include <mach/pm.h> #include <mach/clockdomain.h> #include <mach/powerdomain.h> +#include <mach/common.h> #include "cm.h" #include "cm-regbits-34xx.h" @@ -96,6 +97,9 @@ static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id) u32 wkst, irqstatus_mpu; u32 fclk, iclk; + /* Check if we woke up to serial console activity */ + omap_serial_check_wakeup(); + /* WKUP */ wkst = prm_read_mod_reg(WKUP_MOD, PM_WKST); if (wkst) { @@ -209,8 +213,14 @@ static void omap_sram_idle(void) /* Disable GPIO clocks if allowed */ per_gpio_clk_disable(); + /* Disable UART clocks if allowed */ + omap_serial_enable_clocks(0); + _omap_sram_idle(NULL, save_state); + /* Enable UART clocks if allowed */ + omap_serial_enable_clocks(1); + /* Enable GPIO clocks if allowed */ per_gpio_clk_enable(); @@ -248,6 +258,7 @@ static int omap3_fclks_active(void) CM_FCLKEN); gpio_fclk_mask(&fck_per); + omap_serial_fclk_mask(&fck_core1, &fck_per); if (fck_core1 | fck_core3 | fck_sgx | fck_dss | fck_cam | fck_per | fck_usbhost) @@ -263,6 +274,8 @@ static int omap3_can_sleep(void) return 0; if (atomic_read(&sleep_block) > 0) return 0; + if (!omap_serial_can_sleep()) + return 0; return 1; } diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index dbbef90..281c1c7 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -22,9 +22,66 @@ #include <mach/common.h> #include <mach/board.h> +#include <mach/clock.h> +#include <mach/control.h> + +#include "prm.h" +#include "pm.h" + +static unsigned int serial_awake_time = 5000; static struct clk *uart_ick[OMAP_MAX_NR_PORTS]; static struct clk *uart_fck[OMAP_MAX_NR_PORTS]; +static struct timespec omap_serial_next_sleep; + +#ifdef CONFIG_ARCH_OMAP24XX +static const u32 omap2_uart_wk_st[OMAP_MAX_NR_PORTS] = { + OMAP2420_PRM_REGADDR(CORE_MOD, PM_WKST1), + OMAP2420_PRM_REGADDR(CORE_MOD, PM_WKST1), + OMAP2420_PRM_REGADDR(CORE_MOD, OMAP24XX_PM_WKST2) +}; +static const u32 omap2_uart_wk_en[OMAP_MAX_NR_PORTS] = { + OMAP2420_PRM_REGADDR(CORE_MOD, PM_WKEN1), + OMAP2420_PRM_REGADDR(CORE_MOD, PM_WKEN1), + OMAP2420_PRM_REGADDR(CORE_MOD, OMAP24XX_PM_WKEN2), +}; +static const u32 omap2_uart_wk_bit[OMAP_MAX_NR_PORTS] = { + OMAP24XX_ST_UART1, OMAP24XX_ST_UART2, OMAP24XX_ST_UART3 +}; +#endif + +#ifdef CONFIG_ARCH_OMAP34XX +static const u32 omap3_uart_wk_st[OMAP_MAX_NR_PORTS] = { + OMAP34XX_PRM_REGADDR(CORE_MOD, PM_WKST1), + OMAP34XX_PRM_REGADDR(CORE_MOD, PM_WKST1), + OMAP34XX_PRM_REGADDR(OMAP3430_PER_MOD, PM_WKST1) +}; +static const u32 omap3_uart_wk_en[OMAP_MAX_NR_PORTS] = { + OMAP34XX_PRM_REGADDR(CORE_MOD, PM_WKEN1), + OMAP34XX_PRM_REGADDR(CORE_MOD, PM_WKEN1), + OMAP34XX_PRM_REGADDR(OMAP3430_PER_MOD, PM_WKEN1) +}; +static const u32 omap3_uart_wk_bit[OMAP_MAX_NR_PORTS] = { + OMAP3430_ST_UART1, OMAP3430_ST_UART2, OMAP3430_ST_UART3 +}; +#endif + +static const u32 *omap_uart_wk_st; +static const u32 *omap_uart_wk_en; +static const u32 *omap_uart_wk_bit; + +/* UART padconfig registers, these may differ if non-default padconfig + is used */ +#define CONTROL_PADCONF_UART1_RX 0x182 +#define CONTROL_PADCONF_UART2_RX 0x17A +#define CONTROL_PADCONF_UART3_RX 0x19E +#define PADCONF_WAKEUP_ST 0x8000 + +static const u32 omap34xx_uart_padconf[OMAP_MAX_NR_PORTS] = { + CONTROL_PADCONF_UART1_RX, + CONTROL_PADCONF_UART2_RX, + CONTROL_PADCONF_UART3_RX +}; static struct plat_serial8250_port serial_platform_data[] = { { @@ -83,9 +140,18 @@ static inline void __init omap_serial_reset(struct plat_serial8250_port *p) serial_write_reg(p, UART_OMAP_SYSC, (0x02 << 3) | (1 << 2) | (1 << 0)); } +static void omap_serial_kick(void) +{ + getnstimeofday(&omap_serial_next_sleep); + timespec_add_ns(&omap_serial_next_sleep, (s64)serial_awake_time * + NSEC_PER_MSEC); +} + void omap_serial_enable_clocks(int enable) { int i; + if (uart_clocks_off_while_idle == 0) + return; for (i = 0; i < OMAP_MAX_NR_PORTS; i++) { if (uart_ick[i] && uart_fck[i]) { if (enable) { @@ -99,6 +165,68 @@ void omap_serial_enable_clocks(int enable) } } +void omap_serial_fclk_mask(u32 *f1, u32 *f2) +{ + if (uart_clocks_off_while_idle == 0) + return; + if (uart_ick[0]) + *f1 &= ~(1 << uart_fck[0]->enable_bit); + if (uart_ick[1]) + *f1 &= ~(1 << uart_fck[1]->enable_bit); + if (uart_ick[2]) + *f2 &= ~(1 << uart_fck[2]->enable_bit); +} + +void omap_serial_check_wakeup(void) +{ + int i; + + for (i = 0; i < OMAP_MAX_NR_PORTS; i++) { + if (!uart_ick[i]) + continue; + + if (cpu_is_omap34xx()) + if (omap_ctrl_readw(omap34xx_uart_padconf[i]) & + PADCONF_WAKEUP_ST) { + omap_serial_kick(); + return; + } + + if (__raw_readl(omap_uart_wk_st[i]) & + omap_uart_wk_bit[i]) { + omap_serial_kick(); + return; + } + } +} + +int omap_serial_can_sleep(void) +{ + int i; + struct timespec t; + + struct plat_serial8250_port *p = serial_platform_data; + + getnstimeofday(&t); + + for (i = 0; i < OMAP_MAX_NR_PORTS; i++) { + if (!uart_ick[i]) + continue; + /* Check if we have data in the transmit buffer */ + if ((serial_read_reg(p + i, UART_LSR) & + (UART_LSR_TEMT|UART_LSR_THRE)) + != (UART_LSR_TEMT|UART_LSR_THRE)) { + omap_serial_kick(); + return 0; + } + } + + if (timespec_compare(&t, &omap_serial_next_sleep) < 0) + return 0; + + return 1; +} + void __init omap_serial_init(void) { int i; @@ -116,8 +244,25 @@ void __init omap_serial_init(void) if (info == NULL) return; +#ifdef CONFIG_ARCH_OMAP24XX + if (cpu_is_omap242x()) { + omap_uart_wk_st = omap2_uart_wk_st; + omap_uart_wk_en = omap2_uart_wk_en; + omap_uart_wk_bit = omap2_uart_wk_bit; + } +#endif + +#ifdef CONFIG_ARCH_OMAP34XX + if (cpu_is_omap34xx()) { + omap_uart_wk_st = omap3_uart_wk_st; + omap_uart_wk_en = omap3_uart_wk_en; + omap_uart_wk_bit = omap3_uart_wk_bit; + } +#endif + for (i = 0; i < OMAP_MAX_NR_PORTS; i++) { struct plat_serial8250_port *p = serial_platform_data + i; + u32 v; if (!(info->enabled_uarts & (1 << i))) { p->membase = NULL; @@ -142,7 +287,31 @@ void __init omap_serial_init(void) clk_enable(uart_fck[i]); omap_serial_reset(p); + + v = __raw_readl(omap_uart_wk_en[i]); + v |= omap_uart_wk_bit[i]; + __raw_writel(v, omap_uart_wk_en[i]); } + + omap_serial_kick(); +} + +static ssize_t awake_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) +{ + return sprintf(buf, "%u\n", serial_awake_time); +} + +static ssize_t awake_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t n) +{ + unsigned int value; + if (sscanf(buf, "%u", &value) != 1) { + printk(KERN_ERR "awake_store: Invalid value\n"); + return -EINVAL; + } + serial_awake_time = value; + return n; } static struct platform_device serial_device = { @@ -153,8 +322,17 @@ static struct platform_device serial_device = { }, }; +static struct kobj_attribute serial_awake_attr = + __ATTR(serial_awake_time, 0644, awake_show, awake_store); + static int __init omap_init(void) { - return platform_device_register(&serial_device); + int ret; + + ret = platform_device_register(&serial_device); + if (!ret) + ret = sysfs_create_file(&serial_device.dev.kobj, + &serial_awake_attr.attr); + return ret; } arch_initcall(omap_init); diff --git a/arch/arm/plat-omap/include/mach/common.h b/arch/arm/plat-omap/include/mach/common.h index 5f46249..003c08e 100644 --- a/arch/arm/plat-omap/include/mach/common.h +++ b/arch/arm/plat-omap/include/mach/common.h @@ -35,6 +35,9 @@ extern void omap_map_common_io(void); extern struct sys_timer omap_timer; extern void omap_serial_init(void); extern void omap_serial_enable_clocks(int enable); +extern int omap_serial_can_sleep(void); +extern void omap_serial_fclk_mask(u32 *f1, u32 *f2); +void omap_serial_check_wakeup(void); #ifdef CONFIG_I2C_OMAP extern int omap_register_i2c_bus(int bus_id, u32 clkrate, struct i2c_board_info const *info, -- 1.6.0 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 03/29] PM debug support for 34xx 2008-09-11 12:33 ` [PATCH 02/29] Added sleep support to UART Kevin Hilman @ 2008-09-11 12:33 ` Kevin Hilman 2008-09-11 12:33 ` [PATCH 04/29] Sysfs interface for controlling suspend states + set_pwrdm_state fix Kevin Hilman 0 siblings, 1 reply; 37+ messages in thread From: Kevin Hilman @ 2008-09-11 12:33 UTC (permalink / raw) To: linux-omap; +Cc: Tero Kristo From: Tero Kristo <tero.kristo@nokia.com> This patch adds a few files to the debug file system for PM debugging purposes. Enabled with kernel config options CONFIG_PM_DEBUG and CONFIG_DEBUG_FS. Data available in debug filesystem after this patch: - State enter counters for power domains (OFF, RET, ON) - State timers for the above (in ns) - PM register dumps with programmable save points - Current power domain states - Interface to set_pwrdm_state() This patch depends on the PM workaround set from Jouni Hogander. Signed-off-by: Tero Kristo <tero.kristo@nokia.com> --- arch/arm/mach-omap2/clock.c | 2 + arch/arm/mach-omap2/clockdomain.c | 27 ++ arch/arm/mach-omap2/pm-debug.c | 406 +++++++++++++++++++++++++ arch/arm/mach-omap2/pm.c | 2 + arch/arm/mach-omap2/pm.h | 33 ++- arch/arm/mach-omap2/pm34xx.c | 6 +- arch/arm/mach-omap2/powerdomain.c | 69 +++++ arch/arm/plat-omap/include/mach/powerdomain.h | 7 +- 8 files changed, 548 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index 88c8ef4..a5fc5b0 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c @@ -39,6 +39,7 @@ #include "cm.h" #include "cm-regbits-24xx.h" #include "cm-regbits-34xx.h" +#include "pm.h" #define MAX_CLOCK_ENABLE_WAIT 100000 @@ -1025,5 +1026,6 @@ void omap2_clk_disable_unused(struct clk *clk) printk(KERN_INFO "Disabling unused clock \"%s\"\n", clk->name); _omap2_clk_disable(clk); + pm_dbg_clk_state_switch(clk); } #endif diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c index fa62f14..9670ed1 100644 --- a/arch/arm/mach-omap2/clockdomain.c +++ b/arch/arm/mach-omap2/clockdomain.c @@ -36,6 +36,8 @@ #include <mach/powerdomain.h> #include <mach/clockdomain.h> +#include "pm.h" + /* clkdm_list contains all registered struct clockdomains */ static LIST_HEAD(clkdm_list); @@ -567,6 +569,8 @@ int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk) else omap2_clkdm_wakeup(clkdm); + pm_dbg_clkdm_state_switch(clkdm); + return 0; } @@ -618,6 +622,29 @@ int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk) else omap2_clkdm_sleep(clkdm); + pm_dbg_clkdm_state_switch(clkdm); + + return 0; +} + +#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS) +#include <linux/debugfs.h> +#include <linux/seq_file.h> +int clkdm_dbg_show_counters(struct seq_file *s, void *unused) +{ + struct clockdomain *clkdm; + + list_for_each_entry(clkdm, &clkdm_list, node) { + if (strcmp(clkdm->name, "emu_clkdm") == 0 || + strcmp(clkdm->name, "wkup_clkdm") == 0) + continue; + seq_printf(s, "%s->%s (%d)", clkdm->name, + clkdm->pwrdm.ptr->name, + atomic_read(&clkdm->usecount)); + seq_printf(s, "\n"); + } + return 0; } +#endif diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c index b00f5f4..380a2a0 100644 --- a/arch/arm/mach-omap2/pm-debug.c +++ b/arch/arm/mach-omap2/pm-debug.c @@ -30,6 +30,9 @@ #include <mach/clock.h> #include <mach/board.h> +#include <mach/powerdomain.h> +#include <mach/clockdomain.h> +#include <mach/common.h> #include "prm.h" #include "cm.h" #include "pm.h" @@ -153,4 +156,407 @@ void omap2_pm_dump(int mode, int resume, unsigned int us) printk("%-20s: 0x%08x\n", regs[i].name, regs[i].val); } +#ifdef CONFIG_DEBUG_FS +#include <linux/debugfs.h> +#include <linux/seq_file.h> + +static void pm_dbg_regset_store(u32 *ptr); + +struct dentry *pm_dbg_dir; + +static int pm_dbg_init_done; + +enum { + PM_DBG_STATE_NOW = 0, + PM_DBG_STATE_PREV, +}; + +struct pm_module_def { + char name[8]; /* Name of the module */ + short type; /* CM or PRM */ + unsigned short offset; + int low; /* First register address on this module */ + int high; /* Last register address on this module */ +}; + +#define MOD_CM 0 +#define MOD_PRM 1 + +static const struct pm_module_def pm_dbg_reg_modules[] = { + { "IVA2", MOD_CM, OMAP3430_IVA2_MOD, 0, 0x4c }, + { "OCP", MOD_CM, OCP_MOD, 0, 0x10 }, + { "MPU", MOD_CM, MPU_MOD, 4, 0x4c }, + { "CORE", MOD_CM, CORE_MOD, 0, 0x4c }, + { "SGX", MOD_CM, OMAP3430ES2_SGX_MOD, 0, 0x4c }, + { "WKUP", MOD_CM, WKUP_MOD, 0, 0x40 }, + { "CCR", MOD_CM, PLL_MOD, 0, 0x70 }, + { "DSS", MOD_CM, OMAP3430_DSS_MOD, 0, 0x4c }, + { "CAM", MOD_CM, OMAP3430_CAM_MOD, 0, 0x4c }, + { "PER", MOD_CM, OMAP3430_PER_MOD, 0, 0x4c }, + { "EMU", MOD_CM, OMAP3430_EMU_MOD, 0x40, 0x54 }, + { "NEON", MOD_CM, OMAP3430_NEON_MOD, 0x20, 0x48 }, + { "USB", MOD_CM, OMAP3430ES2_USBHOST_MOD, 0, 0x4c }, + + { "IVA2", MOD_PRM, OMAP3430_IVA2_MOD, 0x50, 0xfc }, + { "OCP", MOD_PRM, OCP_MOD, 4, 0x1c }, + { "MPU", MOD_PRM, MPU_MOD, 0x58, 0xe8 }, + { "CORE", MOD_PRM, CORE_MOD, 0x58, 0xf8 }, + { "SGX", MOD_PRM, OMAP3430ES2_SGX_MOD, 0x58, 0xe8 }, + { "WKUP", MOD_PRM, WKUP_MOD, 0xa0, 0xb0 }, + { "CCR", MOD_PRM, PLL_MOD, 0x40, 0x70 }, + { "DSS", MOD_PRM, OMAP3430_DSS_MOD, 0x58, 0xe8 }, + { "CAM", MOD_PRM, OMAP3430_CAM_MOD, 0x58, 0xe8 }, + { "PER", MOD_PRM, OMAP3430_PER_MOD, 0x58, 0xe8 }, + { "EMU", MOD_PRM, OMAP3430_EMU_MOD, 0x58, 0xe4 }, + { "GLBL", MOD_PRM, OMAP3430_GR_MOD, 0x20, 0xe4 }, + { "NEON", MOD_PRM, OMAP3430_NEON_MOD, 0x58, 0xe8 }, + { "USB", MOD_PRM, OMAP3430ES2_USBHOST_MOD, 0x58, 0xe8 }, + { "", 0, 0, 0, 0 }, +}; + +#define PM_DBG_MAX_REG_SETS 4 + +static void *pm_dbg_reg_set[PM_DBG_MAX_REG_SETS]; + +static int pm_dbg_get_regset_size(void) +{ + static int regset_size; + + if (regset_size == 0) { + int i = 0; + + while (pm_dbg_reg_modules[i].name[0] != 0) { + regset_size += pm_dbg_reg_modules[i].high + + 4 - pm_dbg_reg_modules[i].low; + i++; + } + } + return regset_size; +} + +static int pm_dbg_show_regs(struct seq_file *s, void *unused) +{ + int i, j; + unsigned long val; + int reg_set = (int)s->private; + u32 *ptr; + void *store = NULL; + int regs; + + if (reg_set == 0) { + store = kmalloc(pm_dbg_get_regset_size(), GFP_KERNEL); + ptr = store; + pm_dbg_regset_store(ptr); + } else { + ptr = pm_dbg_reg_set[reg_set - 1]; + } + + i = 0; + + while (pm_dbg_reg_modules[i].name[0] != 0) { + regs = 0; + if (pm_dbg_reg_modules[i].type == MOD_CM) + seq_printf(s, "MOD: CM_%s (%08x)\n", + pm_dbg_reg_modules[i].name, + (u32)(OMAP2_CM_BASE + + pm_dbg_reg_modules[i].offset)); + else + seq_printf(s, "MOD: PRM_%s (%08x)\n", + pm_dbg_reg_modules[i].name, + (u32)(OMAP2_PRM_BASE + + pm_dbg_reg_modules[i].offset)); + + for (j = pm_dbg_reg_modules[i].low; + j <= pm_dbg_reg_modules[i].high; j += 4) { + val = *(ptr++); + if (val != 0) { + regs++; + seq_printf(s, " %02x => %08lx", j, val); + if (regs % 4 == 0) + seq_printf(s, "\n"); + } + } + seq_printf(s, "\n"); + i++; + } + + if (store != NULL) + kfree(store); + + return 0; +} + +static void pm_dbg_regset_store(u32 *ptr) +{ + int i, j; + u32 val; + + i = 0; + + while (pm_dbg_reg_modules[i].name[0] != 0) { + for (j = pm_dbg_reg_modules[i].low; + j <= pm_dbg_reg_modules[i].high; j += 4) { + if (pm_dbg_reg_modules[i].type == MOD_CM) + val = cm_read_mod_reg( + pm_dbg_reg_modules[i].offset, j); + else + val = prm_read_mod_reg( + pm_dbg_reg_modules[i].offset, j); + *(ptr++) = val; + } + i++; + } +} + +int pm_dbg_regset_save(int reg_set) +{ + if (pm_dbg_reg_set[reg_set-1] == NULL) + return -EINVAL; + + pm_dbg_regset_store(pm_dbg_reg_set[reg_set-1]); + + return 0; +} + +static int _pm_dbg_state_switch(struct powerdomain *pwrdm, int flag) +{ + s64 t; + struct timespec now; + int prev; + int state; + + if (pwrdm == NULL) + return -EINVAL; + + state = pwrdm_read_pwrst(pwrdm); + + switch (flag) { + case PM_DBG_STATE_NOW: + prev = pwrdm->state; + break; + case PM_DBG_STATE_PREV: + prev = pwrdm_read_prev_pwrst(pwrdm); + if (pwrdm->state != prev) + pwrdm->state_counter[prev]++; + break; + default: + return -EINVAL; + } + + if (pm_dbg_init_done) { + /* Update timer for previous state */ + getnstimeofday(&now); + t = timespec_to_ns(&now); + + pwrdm->state_timer[prev] += t - pwrdm->timer; + + pwrdm->timer = t; + + if (state != prev) + pwrdm->state_counter[state]++; + } + + pwrdm->state = state; + + return 0; +} + +int pm_dbg_pwrdm_state_switch(struct powerdomain *pwrdm) +{ + return _pm_dbg_state_switch(pwrdm, PM_DBG_STATE_NOW); +} + +int pm_dbg_clkdm_state_switch(struct clockdomain *clkdm) +{ + if (clkdm != NULL && clkdm->pwrdm.ptr != NULL) { + pwrdm_wait_transition(clkdm->pwrdm.ptr); + return pm_dbg_pwrdm_state_switch(clkdm->pwrdm.ptr); + } + + return -EINVAL; +} + +int pm_dbg_clk_state_switch(struct clk *clk) +{ + if (clk != NULL && clk->clkdm.ptr != NULL) + return pm_dbg_clkdm_state_switch(clk->clkdm.ptr); + return -EINVAL; +} + +static int pm_dbg_pre_suspend_cb(struct powerdomain *pwrdm) +{ + pwrdm_clear_all_prev_pwrst(pwrdm); + _pm_dbg_state_switch(pwrdm, PM_DBG_STATE_NOW); + return 0; +} + +static int pm_dbg_post_suspend_cb(struct powerdomain *pwrdm) +{ + _pm_dbg_state_switch(pwrdm, PM_DBG_STATE_PREV); + return 0; +} + +int pm_dbg_pre_suspend(void) +{ + pwrdm_for_each(pm_dbg_pre_suspend_cb); + return 0; +} + +int pm_dbg_post_suspend(void) +{ + pwrdm_for_each(pm_dbg_post_suspend_cb); + return 0; +} + +enum { + DEBUG_FILE_COUNTERS = 0, + DEBUG_FILE_TIMERS, +}; + +int pm_dbg_show_counters(struct seq_file *s, void *unused) +{ + pwrdm_dbg_show_counters(s, unused); + clkdm_dbg_show_counters(s, unused); + + return 0; +} + +static int pm_dbg_open(struct inode *inode, struct file *file) +{ + switch ((int)inode->i_private) { + case DEBUG_FILE_COUNTERS: + return single_open(file, pm_dbg_show_counters, + &inode->i_private); + case DEBUG_FILE_TIMERS: + default: + return single_open(file, pwrdm_dbg_show_timers, + &inode->i_private); + }; +} + +static int pm_dbg_reg_open(struct inode *inode, struct file *file) +{ + return single_open(file, pm_dbg_show_regs, inode->i_private); +} + +static const struct file_operations debug_fops = { + .open = pm_dbg_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static const struct file_operations debug_reg_fops = { + .open = pm_dbg_reg_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int pm_dbg_get_state(void *data, u64 *val) +{ + *val = pwrdm_read_pwrst((struct powerdomain *)data); + return 0; +} +static int pm_dbg_set_state(void *data, u64 val) +{ + set_pwrdm_state((struct powerdomain *)data, val); + return 0; +} +DEFINE_SIMPLE_ATTRIBUTE(debug_pwrdm_fops, pm_dbg_get_state, pm_dbg_set_state, "%llu\n"); + +int pm_dbg_regset_init(int reg_set) +{ + char name[2]; + + if (reg_set < 1 || reg_set > PM_DBG_MAX_REG_SETS || + pm_dbg_reg_set[reg_set-1] != NULL) + return -EINVAL; + + pm_dbg_reg_set[reg_set-1] = + kmalloc(pm_dbg_get_regset_size(), GFP_KERNEL); + + if (pm_dbg_reg_set[reg_set-1] == NULL) + return -ENOMEM; + + if (pm_dbg_dir != NULL) { + sprintf(name, "%d", reg_set); + + (void) debugfs_create_file(name, S_IRUGO, + pm_dbg_dir, (void *)reg_set, &debug_reg_fops); + } + + return 0; +} + +static int __init pwrdms_setup(struct powerdomain *pwrdm) +{ + s64 t; + int i; + struct timespec now; + + getnstimeofday(&now); + t = timespec_to_ns(&now); + + for (i = 0; i < 4; i++) { + pwrdm->state_counter[i] = 0; + pwrdm->state_timer[i] = 0; + } + + pwrdm_wait_transition(pwrdm); + pwrdm->state = pwrdm_read_pwrst(pwrdm); + pwrdm->state_counter[pwrdm->state] = 1; + pwrdm->timer = t; + + (void) debugfs_create_file(pwrdm->name, S_IRUGO|S_IWUSR, + pm_dbg_dir, pwrdm, &debug_pwrdm_fops); + + return 0; +} + +static int __init pm_dbg_init(void) +{ + int i; + struct dentry *d; + char name[2]; + + printk(KERN_INFO "pm_dbg_init()\n"); + + d = debugfs_create_dir("pm_debug", NULL); + if (IS_ERR(d)) + return PTR_ERR(d); + + (void) debugfs_create_file("count", S_IRUGO, + d, (void *)DEBUG_FILE_COUNTERS, &debug_fops); + (void) debugfs_create_file("time", S_IRUGO, + d, (void *)DEBUG_FILE_TIMERS, &debug_fops); + + pm_dbg_dir = debugfs_create_dir("pwrdm_ctrl", d); + if (IS_ERR(pm_dbg_dir)) + return PTR_ERR(pm_dbg_dir); + + pwrdm_for_each(pwrdms_setup); + + pm_dbg_dir = debugfs_create_dir("registers", d); + if (IS_ERR(pm_dbg_dir)) + return PTR_ERR(pm_dbg_dir); + + (void) debugfs_create_file("current", S_IRUGO, + pm_dbg_dir, (void *)0, &debug_reg_fops); + + for (i = 0; i < PM_DBG_MAX_REG_SETS; i++) + if (pm_dbg_reg_set[i] != NULL) { + sprintf(name, "%d", i+1); + (void) debugfs_create_file(name, S_IRUGO, + pm_dbg_dir, (void *)(i+1), &debug_reg_fops); + + } + + pm_dbg_init_done = 1; + + return 0; +} +late_initcall(pm_dbg_init); +#endif + #endif diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index b8aae08..c063565 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -28,6 +28,8 @@ #include <asm/mach/time.h> #include <asm/atomic.h> +#include <mach/powerdomain.h> + #include <mach/pm.h> #include "pm.h" diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index 60a386d..19da5c7 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h @@ -28,7 +28,36 @@ extern void omap2_allow_sleep(void); extern void omap2_pm_dump(int mode, int resume, unsigned int us); extern int omap2_pm_debug; #else -#define omap2_pm_dump(mode, resume, us) do {} while (0); -#define omap2_pm_debug 0 +#define omap2_pm_dump(mode, resume, us) do {} while (0); +#define omap2_pm_debug 0 +#endif + +#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS) +struct seq_file; +struct clk; +struct clockdomain; +struct powerdomain; +extern int pm_dbg_pwrdm_state_switch(struct powerdomain *pwrdm); +extern int pm_dbg_clkdm_state_switch(struct clockdomain *clkdm); +extern int pm_dbg_clk_state_switch(struct clk *clk); +extern int pm_dbg_pre_suspend(void); +extern int pm_dbg_post_suspend(void); +extern int pm_dbg_regset_save(int reg_set); +extern int pm_dbg_regset_init(int reg_set); +extern int pwrdm_dbg_show_counters(struct seq_file *s, void *unused); +extern int pwrdm_dbg_show_timers(struct seq_file *s, void *unused); +extern int clkdm_dbg_show_counters(struct seq_file *s, void *unused); +extern int set_pwrdm_state(struct powerdomain *pwrdm, u32 state); +#else +#define pm_dbg_pwrdm_state_switch(domain) do; while (0) +#define pm_dbg_clkdm_state_switch(domain) do; while (0) +#define pm_dbg_clk_state_switch(domain) do; while (0) +#define pm_dbg_pre_suspend() do; while (0) +#define pm_dbg_post_suspend() do; while (0) +#define pm_dbg_regset_save(reg_set) do; while (0) +#define pm_dbg_regset_init(reg_set) do; while (0) +#define pwrdm_dbg_show_counters(s,unused) do; while (0) +#define pwrdm_dbg_show_timers(s,unused) do; while (0) +#define clkdm_dbg_show_counters(s,unused) do; while (0) #endif /* CONFIG_PM_DEBUG */ #endif diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 32922ae..e0d1b1f 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -208,6 +208,8 @@ static void omap_sram_idle(void) return; } + pm_dbg_pre_suspend(); + omap2_gpio_prepare_for_retention(); /* Disable GPIO clocks if allowed */ @@ -225,6 +227,8 @@ static void omap_sram_idle(void) per_gpio_clk_enable(); omap2_gpio_resume_after_retention(); + + pm_dbg_post_suspend(); } /* @@ -298,7 +302,7 @@ static int _clkdm_allow_idle(struct powerdomain *pwrdm, /* This sets pwrdm state (other than mpu & core. Currently only ON & * RET are supported. Function is assuming that clkdm doesn't have * hw_sup mode enabled. */ -static int set_pwrdm_state(struct powerdomain *pwrdm, u32 state) +int set_pwrdm_state(struct powerdomain *pwrdm, u32 state) { u32 cur_state; int ret = 0; diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c index 73e2971..097d5c4 100644 --- a/arch/arm/mach-omap2/powerdomain.c +++ b/arch/arm/mach-omap2/powerdomain.c @@ -1110,4 +1110,73 @@ int pwrdm_wait_transition(struct powerdomain *pwrdm) return 0; } +#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS) +#include <linux/debugfs.h> +#include <linux/seq_file.h> +#include "pm.h" + +static const char pwrdm_state_names[][4] = { + "OFF", + "RET", + "INA", + "ON" +}; + +int pwrdm_dbg_show_counters(struct seq_file *s, void *unused) +{ + int i; + struct powerdomain *pwrdm; + unsigned long flags; + + read_lock_irqsave(&pwrdm_rwlock, flags); + list_for_each_entry(pwrdm, &pwrdm_list, node) { + if (strcmp(pwrdm->name, "emu_pwrdm") == 0 || + strcmp(pwrdm->name, "wkup_pwrdm") == 0) + continue; + if (pwrdm->state != pwrdm_read_pwrst(pwrdm)) + printk(KERN_ERR "pwrdm state mismatch(%s) %d != %d\n", + pwrdm->name, pwrdm->state, + pwrdm_read_pwrst(pwrdm)); + seq_printf(s, "%s (%s)", pwrdm->name, + pwrdm_state_names[pwrdm->state]); + for (i = 0; i < 4; i++) { + seq_printf(s, ",%s:%d", pwrdm_state_names[i], + pwrdm->state_counter[i]); + } + seq_printf(s, "\n"); + } + read_unlock_irqrestore(&pwrdm_rwlock, flags); + + return 0; +} + +int pwrdm_dbg_show_timers(struct seq_file *s, void *unused) +{ + int i; + struct powerdomain *pwrdm; + unsigned long flags; + + read_lock_irqsave(&pwrdm_rwlock, flags); + list_for_each_entry(pwrdm, &pwrdm_list, node) { + if (strcmp(pwrdm->name, "emu_pwrdm") == 0 || + strcmp(pwrdm->name, "wkup_pwrdm") == 0) + continue; + + /* Update timer for current state */ + pm_dbg_pwrdm_state_switch(pwrdm); + + seq_printf(s, "%s (%s)", pwrdm->name, + pwrdm_state_names[pwrdm->state]); + for (i = 0; i < 4; i++) { + seq_printf(s, ",%s:%lld", pwrdm_state_names[i], + pwrdm->state_timer[i]); + } + seq_printf(s, "\n"); + } + read_unlock_irqrestore(&pwrdm_rwlock, flags); + + return 0; +} + +#endif diff --git a/arch/arm/plat-omap/include/mach/powerdomain.h b/arch/arm/plat-omap/include/mach/powerdomain.h index 4948cb7..8785cb7 100644 --- a/arch/arm/plat-omap/include/mach/powerdomain.h +++ b/arch/arm/plat-omap/include/mach/powerdomain.h @@ -116,7 +116,12 @@ struct powerdomain { struct clockdomain *pwrdm_clkdms[PWRDM_MAX_CLKDMS]; struct list_head node; - +#ifdef CONFIG_PM_DEBUG + int state; + int state_counter[4]; + s64 timer; + s64 state_timer[4]; +#endif }; -- 1.6.0 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 04/29] Sysfs interface for controlling suspend states + set_pwrdm_state fix 2008-09-11 12:33 ` [PATCH 03/29] PM debug support for 34xx Kevin Hilman @ 2008-09-11 12:33 ` Kevin Hilman 2008-09-11 12:33 ` [PATCH 05/29] Basic cpuidle driver Kevin Hilman 0 siblings, 1 reply; 37+ messages in thread From: Kevin Hilman @ 2008-09-11 12:33 UTC (permalink / raw) To: linux-omap; +Cc: Tero Kristo From: Tero Kristo <tero.kristo@nokia.com> Target states for each powerdomain can now be set via sysfs interface. E.g. "echo 0 > /sys/power/suspend/mpu_pwrdm" will program MPU suspend state to be OFF. Also, set_pwrdm_state() should now work when pwrdm is currently in power save state. Signed-off-by: Tero Kristo <tero.kristo@nokia.com> --- arch/arm/mach-omap2/pm34xx.c | 97 +++++++++++++++++++++++++++++++++++++++++- 1 files changed, 96 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index e0d1b1f..a272720 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -82,6 +82,8 @@ static void per_gpio_clk_disable(void) clk_disable(gpio_fcks[i-1]); } +static struct kobject *suspend_dir_kobj; + /* XXX This is for gpio fclk hack. Will be removed as gpio driver * handles fcks correctly */ static void gpio_fclk_mask(u32 *fclk) @@ -306,6 +308,7 @@ int set_pwrdm_state(struct powerdomain *pwrdm, u32 state) { u32 cur_state; int ret = 0; + int sleep_switch = 0; if (pwrdm == NULL || IS_ERR(pwrdm)) return -EINVAL; @@ -315,6 +318,16 @@ int set_pwrdm_state(struct powerdomain *pwrdm, u32 state) if (cur_state == state) return ret; + /* Check if we need to wake-up the pwrdm for state switch */ + /* MPU, core and per are never in sleep states when we are here*/ + if (pwrdm_read_pwrst(pwrdm) < PWRDM_POWER_ON) { + if ((cm_read_mod_reg(pwrdm->prcm_offs, 0x48) & 0x3) == 0x3) { + sleep_switch = 1; + cm_rmw_mod_reg_bits(0x3, 0x2, pwrdm->prcm_offs, 0x48); + pwrdm_wait_transition(pwrdm); + } + } + pwrdm_for_each_clkdm(pwrdm, _clkdm_deny_idle); ret = pwrdm_set_next_pwrst(pwrdm, state); @@ -326,6 +339,12 @@ int set_pwrdm_state(struct powerdomain *pwrdm, u32 state) pwrdm_for_each_clkdm(pwrdm, _clkdm_allow_idle); + if (sleep_switch) { + cm_rmw_mod_reg_bits(0x3, 0x3, pwrdm->prcm_offs, 0x48); + pwrdm_wait_transition(pwrdm); + pm_dbg_pwrdm_state_switch(pwrdm); + } + err: return ret; } @@ -380,7 +399,6 @@ static int omap3_pm_suspend(void) restore: /* Restore next_pwrsts */ list_for_each_entry(pwrst, &pwrst_list, node) { - set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state); state = pwrdm_read_prev_pwrst(pwrst->pwrdm); if (state != pwrst->next_state) { printk(KERN_INFO "Powerdomain (%s) didn't enter " @@ -388,6 +406,7 @@ restore: pwrst->pwrdm->name, pwrst->next_state); ret = -1; } + set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state); } if (ret) printk(KERN_ERR "Could not enter target state in pm_suspend\n"); @@ -584,9 +603,67 @@ static void __init prcm_setup_regs(void) OCP_MOD, OMAP2_PRM_IRQENABLE_MPU_OFFSET); } +static struct power_state *get_pwrst_node(const char *name) +{ + struct powerdomain *pwrdm; + struct power_state *pwrst_tmp; + struct power_state *pwrst = NULL; + + pwrdm = pwrdm_lookup(name); + + if (pwrdm == NULL) { + printk(KERN_ERR "pwrdm not found %s\n", name); + return NULL; + } + + list_for_each_entry(pwrst_tmp, &pwrst_list, node) + if (pwrst_tmp->pwrdm == pwrdm) + pwrst = pwrst_tmp; + + if (pwrst == NULL) + printk(KERN_ERR "pwrdm not in suspend list %s\n", name); + + return pwrst; +} + +static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) +{ + struct power_state *pwrst; + + pwrst = get_pwrst_node(attr->attr.name); + + if (pwrst == NULL) + return -EINVAL; + + return sprintf(buf, "%hu\n", pwrst->next_state); +} + +static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t n) +{ + struct power_state *pwrst; + unsigned short value; + + if (sscanf(buf, "%hu", &value) != 1 || value > PWRDM_POWER_ON) { + printk(KERN_ERR "state_store: Invalid value\n"); + return -EINVAL; + } + + pwrst = get_pwrst_node(attr->attr.name); + + if (pwrst == NULL) + return -EINVAL; + + pwrst->next_state = value; + + return n; +} + static int __init pwrdms_setup(struct powerdomain *pwrdm) { struct power_state *pwrst; + struct kobj_attribute *attr; if (!pwrdm->pwrsts) return 0; @@ -601,6 +678,18 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm) if (pwrdm_has_hdwr_sar(pwrdm)) pwrdm_enable_hdwr_sar(pwrdm); + attr = kmalloc(sizeof(struct kobj_attribute), GFP_KERNEL); + if (!attr) + return -ENOMEM; + + attr->attr.name = pwrdm->name; + attr->attr.mode = 0644; + attr->show = state_show; + attr->store = state_store; + + if (sysfs_create_file(suspend_dir_kobj, &(attr->attr))) + return -ENOMEM; + return set_pwrdm_state(pwrst->pwrdm, pwrst->next_state); } @@ -625,6 +714,12 @@ int __init omap3_pm_init(void) goto err1; } + suspend_dir_kobj = kobject_create_and_add("suspend_config", power_kobj); + if (!suspend_dir_kobj) { + ret = -ENOMEM; + goto err2; + } + ret = pwrdm_for_each(pwrdms_setup); if (ret) { printk(KERN_ERR "Failed to setup powerdomains\n"); -- 1.6.0 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 05/29] Basic cpuidle driver 2008-09-11 12:33 ` [PATCH 04/29] Sysfs interface for controlling suspend states + set_pwrdm_state fix Kevin Hilman @ 2008-09-11 12:33 ` Kevin Hilman 2008-09-11 12:33 ` [PATCH 06/29] per/neon and core handling in idle Kevin Hilman 0 siblings, 1 reply; 37+ messages in thread From: Kevin Hilman @ 2008-09-11 12:33 UTC (permalink / raw) To: linux-omap; +Cc: Rajendra Nayak From: Rajendra Nayak <rnayak@ti.com> OMAP3 Basic cpuidle --- arch/arm/mach-omap2/Makefile | 2 +- arch/arm/mach-omap2/cpuidle34xx.c | 245 +++++++++++++++++++++++++++++++++++++ arch/arm/mach-omap2/cpuidle34xx.h | 56 +++++++++ arch/arm/mach-omap2/pm34xx.c | 5 +- 4 files changed, 306 insertions(+), 2 deletions(-) create mode 100644 arch/arm/mach-omap2/cpuidle34xx.c create mode 100644 arch/arm/mach-omap2/cpuidle34xx.h diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index e18da0c..a514562 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -23,7 +23,7 @@ ifeq ($(CONFIG_PM),y) obj-y += pm.o obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o obj-$(CONFIG_ARCH_OMAP24XX) += sleep24xx.o -obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o +obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o cpuidle34xx.o obj-$(CONFIG_PM_DEBUG) += pm-debug.o endif diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c new file mode 100644 index 0000000..d06146d --- /dev/null +++ b/arch/arm/mach-omap2/cpuidle34xx.c @@ -0,0 +1,245 @@ +/* + * linux/arch/arm/mach-omap2/cpuidle34xx.c + * + * OMAP3 CPU IDLE Routines + * + * Copyright (C) 2007-2008 Texas Instruments, Inc. + * Rajendra Nayak <rnayak@ti.com> + * + * Copyright (C) 2007 Texas Instruments, Inc. + * Karthik Dasu <karthik-dp@ti.com> + * + * Copyright (C) 2006 Nokia Corporation + * Tony Lindgren <tony@atomide.com> + * + * Copyright (C) 2005 Texas Instruments, Inc. + * Richard Woodruff <r-woodruff2@ti.com> + * + * Based on pm.c for omap2 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/cpuidle.h> +#include <asm/arch/pm.h> +#include <asm/arch/prcm.h> +#include <asm/arch/powerdomain.h> +#include "cpuidle34xx.h" + +#ifdef CONFIG_CPU_IDLE + +struct omap3_processor_cx omap3_power_states[OMAP3_MAX_STATES]; +struct omap3_processor_cx current_cx_state; + +static int omap3_idle_bm_check(void) +{ + return 0; +} + +/* omap3_enter_idle - Programs OMAP3 to enter the specified state. + * returns the total time during which the system was idle. + */ +static int omap3_enter_idle(struct cpuidle_device *dev, + struct cpuidle_state *state) +{ + struct omap3_processor_cx *cx = cpuidle_get_statedata(state); + struct timespec ts_preidle, ts_postidle, ts_idle; + struct powerdomain *mpu_pd; + + current_cx_state = *cx; + + /* Used to keep track of the total time in idle */ + getnstimeofday(&ts_preidle); + + + if (cx->type == OMAP3_STATE_C0) { + /* Do nothing for C0, not even a wfi */ + return 0; + } + + mpu_pd = pwrdm_lookup("mpu_pwrdm"); + /* Program MPU to target state */ + if (cx->mpu_state < PWRDM_POWER_ON) + pwrdm_set_next_pwrst(mpu_pd, cx->mpu_state); + + /* Execute ARM wfi */ + omap_sram_idle(); + + /* Program MPU to ON */ + if (cx->mpu_state < PWRDM_POWER_ON) + pwrdm_set_next_pwrst(mpu_pd, PWRDM_POWER_ON); + + getnstimeofday(&ts_postidle); + ts_idle = timespec_sub(ts_postidle, ts_preidle); + return timespec_to_ns(&ts_idle); +} + +static int omap3_enter_idle_bm(struct cpuidle_device *dev, + struct cpuidle_state *state) +{ + struct cpuidle_state *new_state = NULL; + int i, j; + + if ((state->flags & CPUIDLE_FLAG_CHECK_BM) && omap3_idle_bm_check()) { + + /* Find current state in list */ + for (i = 0; i < OMAP3_MAX_STATES; i++) + if (state == &dev->states[i]) + break; + BUG_ON(i == OMAP3_MAX_STATES); + + /* Back up to non 'CHECK_BM' state */ + for (j = i - 1; j > 0; j--) { + struct cpuidle_state *s = &dev->states[j]; + + if (!(s->flags & CPUIDLE_FLAG_CHECK_BM)) { + new_state = s; + break; + } + } + + pr_debug("%s: Bus activity: Entering %s (instead of %s)\n", + __func__, new_state->name, state->name); + } + + return omap3_enter_idle(dev, new_state ? : state); +} + +DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev); + +/* omap3_init_power_states - Initialises the OMAP3 specific C states. + * Below is the desciption of each C state. + * + C0 . System executing code + C1 . MPU WFI + Core active + C2 . MPU CSWR + Core active + C3 . MPU OFF + Core active + C4 . MPU CSWR + Core CSWR + C5 . MPU OFF + Core CSWR + C6 . MPU OFF + Core OFF + */ +void omap_init_power_states(void) +{ + /* C0 . System executing code */ + omap3_power_states[0].valid = 1; + omap3_power_states[0].type = OMAP3_STATE_C0; + omap3_power_states[0].sleep_latency = 0; + omap3_power_states[0].wakeup_latency = 0; + omap3_power_states[0].threshold = 0; + omap3_power_states[0].mpu_state = PWRDM_POWER_ON; + omap3_power_states[0].core_state = PWRDM_POWER_ON; + omap3_power_states[0].flags = CPUIDLE_FLAG_TIME_VALID; + + /* C1 . MPU WFI + Core active */ + omap3_power_states[1].valid = 1; + omap3_power_states[1].type = OMAP3_STATE_C1; + omap3_power_states[1].sleep_latency = 10; + omap3_power_states[1].wakeup_latency = 10; + omap3_power_states[1].threshold = 30; + omap3_power_states[1].mpu_state = PWRDM_POWER_ON; + omap3_power_states[1].core_state = PWRDM_POWER_ON; + omap3_power_states[1].flags = CPUIDLE_FLAG_TIME_VALID; + + /* C2 . MPU CSWR + Core active */ + omap3_power_states[2].valid = 1; + omap3_power_states[2].type = OMAP3_STATE_C2; + omap3_power_states[2].sleep_latency = 50; + omap3_power_states[2].wakeup_latency = 50; + omap3_power_states[2].threshold = 300; + omap3_power_states[2].mpu_state = PWRDM_POWER_RET; + omap3_power_states[2].core_state = PWRDM_POWER_ON; + omap3_power_states[2].flags = CPUIDLE_FLAG_TIME_VALID; + + /* C3 . MPU OFF + Core active */ + omap3_power_states[3].valid = 0; + omap3_power_states[3].type = OMAP3_STATE_C3; + omap3_power_states[3].sleep_latency = 1500; + omap3_power_states[3].wakeup_latency = 1800; + omap3_power_states[3].threshold = 4000; + omap3_power_states[3].mpu_state = PWRDM_POWER_OFF; + omap3_power_states[3].core_state = PWRDM_POWER_RET; + omap3_power_states[3].flags = CPUIDLE_FLAG_TIME_VALID; + + /* C4 . MPU CSWR + Core CSWR*/ + omap3_power_states[4].valid = 0; + omap3_power_states[4].type = OMAP3_STATE_C4; + omap3_power_states[4].sleep_latency = 2500; + omap3_power_states[4].wakeup_latency = 7500; + omap3_power_states[4].threshold = 12000; + omap3_power_states[4].mpu_state = PWRDM_POWER_RET; + omap3_power_states[4].core_state = PWRDM_POWER_RET; + omap3_power_states[4].flags = CPUIDLE_FLAG_TIME_VALID; + + /* C5 . MPU OFF + Core CSWR */ + omap3_power_states[5].valid = 0; + omap3_power_states[5].type = OMAP3_STATE_C5; + omap3_power_states[5].sleep_latency = 3000; + omap3_power_states[5].wakeup_latency = 8500; + omap3_power_states[5].threshold = 15000; + omap3_power_states[5].mpu_state = PWRDM_POWER_OFF; + omap3_power_states[5].core_state = PWRDM_POWER_RET; + omap3_power_states[5].flags = CPUIDLE_FLAG_TIME_VALID; + + /* C6 . MPU OFF + Core OFF */ + omap3_power_states[6].valid = 0; + omap3_power_states[6].type = OMAP3_STATE_C6; + omap3_power_states[6].sleep_latency = 10000; + omap3_power_states[6].wakeup_latency = 30000; + omap3_power_states[6].threshold = 300000; + omap3_power_states[6].mpu_state = PWRDM_POWER_OFF; + omap3_power_states[6].core_state = PWRDM_POWER_OFF; + omap3_power_states[6].flags = CPUIDLE_FLAG_TIME_VALID; +} + +struct cpuidle_driver omap3_idle_driver = { + .name = "omap3_idle", + .owner = THIS_MODULE, +}; +/* + * omap3_idle_init - Init routine for OMAP3 idle. Registers the OMAP3 specific + * cpuidle driver with the cpuidle f/w with the valid set of states. + */ +int omap3_idle_init(void) +{ + int i, count = 0; + struct omap3_processor_cx *cx; + struct cpuidle_state *state; + struct cpuidle_device *dev; + + omap_init_power_states(); + cpuidle_register_driver(&omap3_idle_driver); + + dev = &per_cpu(omap3_idle_dev, smp_processor_id()); + + for (i = 0; i < OMAP3_MAX_STATES; i++) { + cx = &omap3_power_states[i]; + state = &dev->states[count]; + + if (!cx->valid) + continue; + cpuidle_set_statedata(state, cx); + state->exit_latency = cx->sleep_latency + cx->wakeup_latency; + state->target_residency = cx->threshold; + state->flags = cx->flags; + state->enter = (state->flags & CPUIDLE_FLAG_CHECK_BM) ? + omap3_enter_idle_bm : omap3_enter_idle; + sprintf(state->name, "C%d", count+1); + count++; + } + + if (!count) + return -EINVAL; + dev->state_count = count; + + if (cpuidle_register_device(dev)) { + printk(KERN_ERR "%s: CPUidle register device failed\n", + __func__); + return -EIO; + } + + return 0; +} +__initcall(omap3_idle_init); +#endif /* CONFIG_CPU_IDLE */ diff --git a/arch/arm/mach-omap2/cpuidle34xx.h b/arch/arm/mach-omap2/cpuidle34xx.h new file mode 100644 index 0000000..ed8dc9b --- /dev/null +++ b/arch/arm/mach-omap2/cpuidle34xx.h @@ -0,0 +1,56 @@ +/* + * linux/arch/arm/mach-omap2/cpuidle34xx.h + * + * OMAP3 cpuidle structure definitions + * + * Copyright (C) 2007-2008 Texas Instruments, Inc. + * Written by Rajendra Nayak <rnayak@ti.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * History: + * + */ + +#ifndef ARCH_ARM_MACH_OMAP2_CPUIDLE_34XX +#define ARCH_ARM_MACH_OMAP2_CPUIDLE_34XX + +#define OMAP3_MAX_STATES 7 +#define OMAP3_STATE_C0 0 /* C0 - System executing code */ +#define OMAP3_STATE_C1 1 /* C1 - MPU WFI + Core active */ +#define OMAP3_STATE_C2 2 /* C2 - MPU CSWR + Core active */ +#define OMAP3_STATE_C3 3 /* C3 - MPU OFF + Core active */ +#define OMAP3_STATE_C4 4 /* C4 - MPU RET + Core RET */ +#define OMAP3_STATE_C5 5 /* C5 - MPU OFF + Core RET */ +#define OMAP3_STATE_C6 6 /* C6 - MPU OFF + Core OFF */ + +/* Currently, we support only upto C2 */ +#define MAX_SUPPORTED_STATES 3 + +extern void omap_sram_idle(void); +extern int omap3_irq_pending(void); +extern void per_gpio_clk_enable(void); +extern void per_gpio_clk_disable(void); + +struct omap3_processor_cx { + u8 valid; + u8 type; + u32 sleep_latency; + u32 wakeup_latency; + u32 mpu_state; + u32 core_state; + u32 threshold; + u32 flags; +}; + +void omap_init_power_states(void); +int omap3_idle_init(void); + +#endif /* ARCH_ARM_MACH_OMAP2_CPUIDLE_34XX */ + diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index a272720..8feab92 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -185,7 +185,7 @@ static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id) return IRQ_HANDLED; } -static void omap_sram_idle(void) +void omap_sram_idle(void) { /* Variable to tell what needs to be saved and restored * in omap_sram_idle*/ @@ -200,6 +200,7 @@ static void omap_sram_idle(void) mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm); switch (mpu_next_state) { + case PWRDM_POWER_ON: case PWRDM_POWER_RET: /* No need to save context */ save_state = 0; @@ -737,7 +738,9 @@ int __init omap3_pm_init(void) suspend_set_ops(&omap_pm_ops); +#ifndef CONFIG_CPU_IDLE pm_idle = omap3_pm_idle; +#endif /* XXX This is for gpio fclk hack. Will be removed as gpio driver * handles fcks correctly */ -- 1.6.0 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 06/29] per/neon and core handling in idle 2008-09-11 12:33 ` [PATCH 05/29] Basic cpuidle driver Kevin Hilman @ 2008-09-11 12:33 ` Kevin Hilman 2008-09-11 12:33 ` [PATCH 07/29] menuconfig updates for cpuidle Kevin Hilman 0 siblings, 1 reply; 37+ messages in thread From: Kevin Hilman @ 2008-09-11 12:33 UTC (permalink / raw) To: linux-omap; +Cc: Rajendra Nayak From: Rajendra Nayak <rnayak@ti.com> This patches adds handling of PER/NEON and CORE domain in idle. --- arch/arm/mach-omap2/cpuidle34xx.c | 94 ++++++++++++++++++++++++++++++------- arch/arm/mach-omap2/cpuidle34xx.h | 6 ++- arch/arm/mach-omap2/pm34xx.c | 38 ++++++++------- 3 files changed, 101 insertions(+), 37 deletions(-) diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c index d06146d..99ecd75 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c @@ -26,6 +26,8 @@ #include <asm/arch/pm.h> #include <asm/arch/prcm.h> #include <asm/arch/powerdomain.h> +#include <asm/arch/clockdomain.h> +#include <asm/arch/gpio.h> #include "cpuidle34xx.h" #ifdef CONFIG_CPU_IDLE @@ -35,6 +37,8 @@ struct omap3_processor_cx current_cx_state; static int omap3_idle_bm_check(void) { + if (!omap3_can_sleep()) + return 1; return 0; } @@ -46,34 +50,82 @@ static int omap3_enter_idle(struct cpuidle_device *dev, { struct omap3_processor_cx *cx = cpuidle_get_statedata(state); struct timespec ts_preidle, ts_postidle, ts_idle; - struct powerdomain *mpu_pd; + struct powerdomain *mpu_pd, *core_pd, *per_pd, *neon_pd; + int per_pwrst, neon_pwrst; current_cx_state = *cx; - /* Used to keep track of the total time in idle */ - getnstimeofday(&ts_preidle); - - if (cx->type == OMAP3_STATE_C0) { /* Do nothing for C0, not even a wfi */ return 0; } + /* Used to keep track of the total time in idle */ + getnstimeofday(&ts_preidle); + mpu_pd = pwrdm_lookup("mpu_pwrdm"); + core_pd = pwrdm_lookup("core_pwrdm"); + per_pd = pwrdm_lookup("per_pwrdm"); + neon_pd = pwrdm_lookup("neon_pwrdm"); + + /* Reset previous power state registers */ + pwrdm_clear_all_prev_pwrst(mpu_pd); + pwrdm_clear_all_prev_pwrst(neon_pd); + pwrdm_clear_all_prev_pwrst(core_pd); + pwrdm_clear_all_prev_pwrst(per_pd); + + if (omap_irq_pending()) + return 0; + + per_pwrst = pwrdm_read_pwrst(per_pd); + neon_pwrst = pwrdm_read_pwrst(neon_pd); + /* Program MPU to target state */ - if (cx->mpu_state < PWRDM_POWER_ON) + if (cx->mpu_state < PWRDM_POWER_ON) { + if (neon_pwrst == PWRDM_POWER_ON) + pwrdm_set_next_pwrst(neon_pd, PWRDM_POWER_RET); pwrdm_set_next_pwrst(mpu_pd, cx->mpu_state); + } + + /* Program CORE and PER to target state */ + if (cx->core_state < PWRDM_POWER_ON) { + if (per_pwrst == PWRDM_POWER_ON) { + omap2_gpio_prepare_for_retention(); + per_gpio_clk_disable(); + omap_serial_enable_clocks(0); + } + pwrdm_set_next_pwrst(core_pd, cx->core_state); + } /* Execute ARM wfi */ omap_sram_idle(); - /* Program MPU to ON */ - if (cx->mpu_state < PWRDM_POWER_ON) + /* Program MPU/NEON to ON */ + if (cx->mpu_state < PWRDM_POWER_ON) { + if (neon_pwrst == PWRDM_POWER_ON) + pwrdm_set_next_pwrst(neon_pd, PWRDM_POWER_ON); pwrdm_set_next_pwrst(mpu_pd, PWRDM_POWER_ON); + } + + if (cx->core_state < PWRDM_POWER_ON) { + if (per_pwrst == PWRDM_POWER_ON) { + omap_serial_enable_clocks(1); + per_gpio_clk_enable(); + omap2_gpio_resume_after_retention(); + } + pwrdm_set_next_pwrst(core_pd, PWRDM_POWER_ON); + } + + pr_debug("MPU prev st:%x,NEON prev st:%x\n", + pwrdm_read_prev_pwrst(mpu_pd), + pwrdm_read_prev_pwrst(neon_pd)); + pr_debug("PER prev st:%x,CORE prev st:%x\n", + pwrdm_read_prev_pwrst(per_pd), + pwrdm_read_prev_pwrst(core_pd)); getnstimeofday(&ts_postidle); ts_idle = timespec_sub(ts_postidle, ts_preidle); - return timespec_to_ns(&ts_idle); + return (u32)timespec_to_ns(&ts_idle)/1000; } static int omap3_enter_idle_bm(struct cpuidle_device *dev, @@ -130,7 +182,7 @@ void omap_init_power_states(void) omap3_power_states[0].threshold = 0; omap3_power_states[0].mpu_state = PWRDM_POWER_ON; omap3_power_states[0].core_state = PWRDM_POWER_ON; - omap3_power_states[0].flags = CPUIDLE_FLAG_TIME_VALID; + omap3_power_states[0].flags = CPUIDLE_FLAG_SHALLOW; /* C1 . MPU WFI + Core active */ omap3_power_states[1].valid = 1; @@ -140,7 +192,8 @@ void omap_init_power_states(void) omap3_power_states[1].threshold = 30; omap3_power_states[1].mpu_state = PWRDM_POWER_ON; omap3_power_states[1].core_state = PWRDM_POWER_ON; - omap3_power_states[1].flags = CPUIDLE_FLAG_TIME_VALID; + omap3_power_states[1].flags = CPUIDLE_FLAG_TIME_VALID | + CPUIDLE_FLAG_SHALLOW; /* C2 . MPU CSWR + Core active */ omap3_power_states[2].valid = 1; @@ -150,7 +203,8 @@ void omap_init_power_states(void) omap3_power_states[2].threshold = 300; omap3_power_states[2].mpu_state = PWRDM_POWER_RET; omap3_power_states[2].core_state = PWRDM_POWER_ON; - omap3_power_states[2].flags = CPUIDLE_FLAG_TIME_VALID; + omap3_power_states[2].flags = CPUIDLE_FLAG_TIME_VALID | + CPUIDLE_FLAG_BALANCED; /* C3 . MPU OFF + Core active */ omap3_power_states[3].valid = 0; @@ -159,18 +213,20 @@ void omap_init_power_states(void) omap3_power_states[3].wakeup_latency = 1800; omap3_power_states[3].threshold = 4000; omap3_power_states[3].mpu_state = PWRDM_POWER_OFF; - omap3_power_states[3].core_state = PWRDM_POWER_RET; - omap3_power_states[3].flags = CPUIDLE_FLAG_TIME_VALID; + omap3_power_states[3].core_state = PWRDM_POWER_ON; + omap3_power_states[3].flags = CPUIDLE_FLAG_TIME_VALID | + CPUIDLE_FLAG_BALANCED | CPUIDLE_FLAG_CHECK_BM; /* C4 . MPU CSWR + Core CSWR*/ - omap3_power_states[4].valid = 0; + omap3_power_states[4].valid = 1; omap3_power_states[4].type = OMAP3_STATE_C4; omap3_power_states[4].sleep_latency = 2500; omap3_power_states[4].wakeup_latency = 7500; omap3_power_states[4].threshold = 12000; omap3_power_states[4].mpu_state = PWRDM_POWER_RET; omap3_power_states[4].core_state = PWRDM_POWER_RET; - omap3_power_states[4].flags = CPUIDLE_FLAG_TIME_VALID; + omap3_power_states[4].flags = CPUIDLE_FLAG_TIME_VALID | + CPUIDLE_FLAG_BALANCED | CPUIDLE_FLAG_CHECK_BM; /* C5 . MPU OFF + Core CSWR */ omap3_power_states[5].valid = 0; @@ -180,7 +236,8 @@ void omap_init_power_states(void) omap3_power_states[5].threshold = 15000; omap3_power_states[5].mpu_state = PWRDM_POWER_OFF; omap3_power_states[5].core_state = PWRDM_POWER_RET; - omap3_power_states[5].flags = CPUIDLE_FLAG_TIME_VALID; + omap3_power_states[5].flags = CPUIDLE_FLAG_TIME_VALID | + CPUIDLE_FLAG_BALANCED | CPUIDLE_FLAG_CHECK_BM; /* C6 . MPU OFF + Core OFF */ omap3_power_states[6].valid = 0; @@ -190,7 +247,8 @@ void omap_init_power_states(void) omap3_power_states[6].threshold = 300000; omap3_power_states[6].mpu_state = PWRDM_POWER_OFF; omap3_power_states[6].core_state = PWRDM_POWER_OFF; - omap3_power_states[6].flags = CPUIDLE_FLAG_TIME_VALID; + omap3_power_states[6].flags = CPUIDLE_FLAG_TIME_VALID | + CPUIDLE_FLAG_DEEP | CPUIDLE_FLAG_CHECK_BM; } struct cpuidle_driver omap3_idle_driver = { diff --git a/arch/arm/mach-omap2/cpuidle34xx.h b/arch/arm/mach-omap2/cpuidle34xx.h index ed8dc9b..46ed51e 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.h +++ b/arch/arm/mach-omap2/cpuidle34xx.h @@ -33,11 +33,13 @@ /* Currently, we support only upto C2 */ #define MAX_SUPPORTED_STATES 3 +extern unsigned short clocks_off_while_idle; extern void omap_sram_idle(void); -extern int omap3_irq_pending(void); +extern int omap_irq_pending(void); extern void per_gpio_clk_enable(void); extern void per_gpio_clk_disable(void); - +extern void omap_serial_enable_clocks(int enable); +extern int omap3_can_sleep(); struct omap3_processor_cx { u8 valid; u8 type; diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 8feab92..0646595 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -61,7 +61,7 @@ static struct powerdomain *mpu_pwrdm; static struct clk *gpio_fcks[NUM_OF_PERGPIOS]; /* Enable GPIO clocks from sleep routines if allowed */ -static void per_gpio_clk_enable(void) +void per_gpio_clk_enable(void) { int i; @@ -72,7 +72,7 @@ static void per_gpio_clk_enable(void) } /* Disable GPIO clocks from sleep routines if allowed */ -static void per_gpio_clk_disable(void) +void per_gpio_clk_disable(void) { int i; @@ -213,22 +213,8 @@ void omap_sram_idle(void) pm_dbg_pre_suspend(); - omap2_gpio_prepare_for_retention(); - - /* Disable GPIO clocks if allowed */ - per_gpio_clk_disable(); - - /* Disable UART clocks if allowed */ - omap_serial_enable_clocks(0); - _omap_sram_idle(NULL, save_state); - /* Enable UART clocks if allowed */ - omap_serial_enable_clocks(1); - - /* Enable GPIO clocks if allowed */ - per_gpio_clk_enable(); - omap2_gpio_resume_after_retention(); pm_dbg_post_suspend(); @@ -273,7 +259,7 @@ static int omap3_fclks_active(void) return 0; } -static int omap3_can_sleep(void) +int omap3_can_sleep(void) { if (!enable_dyn_sleep) return 0; @@ -361,8 +347,17 @@ static void omap3_pm_idle(void) if (omap_irq_pending()) goto out; + omap2_gpio_prepare_for_retention(); + + omap_serial_enable_clocks(0); + per_gpio_clk_disable(); + omap_sram_idle(); + omap_serial_enable_clocks(1); + per_gpio_clk_enable(); + + omap2_gpio_resume_after_retention(); out: local_fiq_enable(); local_irq_enable(); @@ -395,8 +390,17 @@ static int omap3_pm_suspend(void) goto restore; } + omap2_gpio_prepare_for_retention(); + + omap_serial_enable_clocks(0); + per_gpio_clk_disable(); + omap_sram_idle(); + omap_serial_enable_clocks(1); + per_gpio_clk_enable(); + + omap2_gpio_resume_after_retention(); restore: /* Restore next_pwrsts */ list_for_each_entry(pwrst, &pwrst_list, node) { -- 1.6.0 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 07/29] menuconfig updates for cpuidle 2008-09-11 12:33 ` [PATCH 06/29] per/neon and core handling in idle Kevin Hilman @ 2008-09-11 12:33 ` Kevin Hilman 2008-09-11 12:33 ` [PATCH 08/29] scratchpad contents Kevin Hilman 0 siblings, 1 reply; 37+ messages in thread From: Kevin Hilman @ 2008-09-11 12:33 UTC (permalink / raw) To: linux-omap; +Cc: Rajendra Nayak From: Rajendra Nayak <rnayak@ti.com> This patch enables the cpuidle option in menuconfig and selects the menu governor --- arch/arm/Kconfig | 10 ++++++++++ drivers/cpuidle/Kconfig | 26 +++++++++++++++++++++----- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index aa475d9..a365bfc 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1005,6 +1005,16 @@ config ATAGS_PROC endmenu +if (ARCH_OMAP) + +menu "CPUIdle" + +source "drivers/cpuidle/Kconfig" + +endmenu + +endif + if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX || ARCH_PXA) menu "CPU Frequency scaling" diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig index 7dbc4a8..e27bb34 100644 --- a/drivers/cpuidle/Kconfig +++ b/drivers/cpuidle/Kconfig @@ -1,20 +1,36 @@ +menu "CPU idle PM support" config CPU_IDLE bool "CPU idle PM support" - default ACPI + default n help CPU idle is a generic framework for supporting software-controlled idle processor power management. It includes modular cross-platform governors that can be swapped during runtime. - If you're using an ACPI-enabled platform, you should say Y here. + If you're using a mobile platform that supports CPU idle PM (e.g. + an ACPI-capable notebook), you should say Y here. + +if CPU_IDLE + +comment "Governors" config CPU_IDLE_GOV_LADDER - bool + bool "ladder" depends on CPU_IDLE - default y + default n config CPU_IDLE_GOV_MENU - bool + bool "menu" depends on CPU_IDLE && NO_HZ default y + help + This cpuidle governor evaluates all available states and chooses the + deepest state that meets all of the following constraints: BM activity, + expected time until next timer interrupt, and last break event time + delta. It is designed to minimize power consumption. Currently + dynticks is required. + +endif # CPU_IDLE + +endmenu -- 1.6.0 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 08/29] scratchpad contents 2008-09-11 12:33 ` [PATCH 07/29] menuconfig updates for cpuidle Kevin Hilman @ 2008-09-11 12:33 ` Kevin Hilman 2008-09-11 12:33 ` [PATCH 09/29] mpu off state enabled Kevin Hilman 0 siblings, 1 reply; 37+ messages in thread From: Kevin Hilman @ 2008-09-11 12:33 UTC (permalink / raw) To: linux-omap; +Cc: Rajendra Nayak From: Rajendra Nayak <rnayak@ti.com> This patch populates the scratchpad --- arch/arm/mach-omap2/pm.h | 7 ++ arch/arm/mach-omap2/pm34xx.c | 170 +++++++++++++++++++++++++++++++++- arch/arm/mach-omap2/sleep34xx.S | 8 +- arch/arm/plat-omap/include/mach/pm.h | 5 + 4 files changed, 181 insertions(+), 9 deletions(-) diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index 19da5c7..7776cdb 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h @@ -24,6 +24,13 @@ extern atomic_t sleep_block; extern void omap2_block_sleep(void); extern void omap2_allow_sleep(void); +#define SCRATCHPAD_ROM 0x48002860 +#define SCRATCHPAD 0x48002910 +#define SCRATHPAD_ROM_OFFSET 0x19C +#define TABLE_ADDRESS_OFFSET 0x31 +#define TABLE_VALUE_OFFSET 0x30 +#define CONTROL_REG_VALUE_OFFSET 0x32 + #ifdef CONFIG_PM_DEBUG extern void omap2_pm_dump(int mode, int resume, unsigned int us); extern int omap2_pm_debug; diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 0646595..acfca0b 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -30,6 +30,9 @@ #include <mach/clockdomain.h> #include <mach/powerdomain.h> #include <mach/common.h> +#include <mach/sdrc.h> +#include <mach/tlbflush.h> +#include "sdrc.h" #include "cm.h" #include "cm-regbits-34xx.h" @@ -38,6 +41,12 @@ #include "prm.h" #include "pm.h" #include "smartreflex.h" +#include "clock34xx.h" + +#define OMAP3430_PRM_RSTST \ + OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0058) + +u32 context_mem[128]; struct power_state { struct powerdomain *pwrdm; @@ -46,6 +55,9 @@ struct power_state { struct list_head node; }; +u32 *scratchpad_restore_addr; +u32 restore_pointer_address; + static LIST_HEAD(pwrst_list); static void (*_omap_sram_idle)(u32 *addr, int save_state); @@ -185,6 +197,35 @@ static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id) return IRQ_HANDLED; } +static void restore_control_register(u32 val) +{ + __asm__ __volatile__ ("mcr p15, 0, %0, c1, c0, 0" : : "r" (val)); +} + +/* Function to restore the table entry that was modified for enabling MMU*/ +static void restore_table_entry(void) +{ + u32 *scratchpad_address; + u32 previous_value, control_reg_value; + u32 *address; + /* Get virtual address of SCRATCHPAD */ + scratchpad_address = (u32 *) io_p2v(SCRATCHPAD); + /* Get address of entry that was modified */ + address = (u32 *) *(scratchpad_address + TABLE_ADDRESS_OFFSET); + /* Get the previous value which needs to be restored */ + previous_value = *(scratchpad_address + TABLE_VALUE_OFFSET); + /* Convert address to virtual address */ + address = __va(address); + /* Restore table entry */ + *address = previous_value; + /* Flush TLB */ + flush_tlb_all(); + control_reg_value = *(scratchpad_address + CONTROL_REG_VALUE_OFFSET); + /* Restore control register*/ + /* This will enable caches and prediction */ + restore_control_register(control_reg_value); +} + void omap_sram_idle(void) { /* Variable to tell what needs to be saved and restored @@ -205,6 +246,9 @@ void omap_sram_idle(void) /* No need to save context */ save_state = 0; break; + case PWRDM_POWER_OFF: + save_state = 3; + break; default: /* Invalid state */ printk(KERN_ERR "Invalid mpu state in sram_idle\n"); @@ -213,9 +257,10 @@ void omap_sram_idle(void) pm_dbg_pre_suspend(); - _omap_sram_idle(NULL, save_state); - - omap2_gpio_resume_after_retention(); + _omap_sram_idle(context_mem, save_state); + /* Restore table entry modified during MMU restoration */ + if (pwrdm_read_prev_pwrst(mpu_pwrdm) == 0x0) + restore_table_entry(); pm_dbg_post_suspend(); } @@ -677,7 +722,10 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm) if (!pwrst) return -ENOMEM; pwrst->pwrdm = pwrdm; - pwrst->next_state = PWRDM_POWER_RET; + if (!strcmp(pwrst->pwrdm->name, "core_pwrdm")) + pwrst->next_state = PWRDM_POWER_RET; + else + pwrst->next_state = PWRDM_POWER_OFF; list_add(&pwrst->node, &pwrst_list); if (pwrdm_has_hdwr_sar(pwrdm)) @@ -764,6 +812,120 @@ err2: return ret; } +/* Clears the scratchpad contents in case of cold boot- called during bootup*/ +void clear_scratchpad_contents(void) +{ + u32 max_offset = SCRATHPAD_ROM_OFFSET; + u32 offset = 0; + u32 v; + u32 v_addr = io_p2v(SCRATCHPAD_ROM); + if (__raw_readl(OMAP3430_PRM_RSTST) & 0x1) { + for ( ; offset <= max_offset; offset += 0x4) + __raw_writel(0x0, (v_addr + offset)); + v = __raw_readl(OMAP3430_PRM_RSTST); + v |= 0x1; + __raw_writel(v, OMAP3430_PRM_RSTST); + } +} + +/* Populate the scratchpad structure with restore structure */ +void save_scratchpad_contents(void) +{ + u32 *scratchpad_address; + u32 *restore_address; + u32 *sdram_context_address; + + /* Get virtual address of SCRATCHPAD */ + scratchpad_address = (u32 *) io_p2v(SCRATCHPAD); + /* Get Restore pointer to jump to while waking up from OFF */ + restore_address = get_restore_pointer(); + /* Convert it to physical address */ + restore_address = (u32 *) io_v2p(restore_address); + /* Get address where registers are saved in SDRAM */ + sdram_context_address = (u32 *) io_v2p(context_mem); + /* Booting configuration pointer*/ + *(scratchpad_address++) = 0x0; + /* Public restore pointer */ + /* On ES 2.0, if scrathpad is populated with valid + * pointer, warm reset does not work + * So populate scrathpad restore address only in + * cpuidle and suspend calls + */ + scratchpad_restore_addr = scratchpad_address; + restore_pointer_address = (u32) restore_address; + *(scratchpad_address++) = 0x0; + /* Secure ram restore pointer */ + *(scratchpad_address++) = 0x0; + /* SDRC Module semaphore */ + *(scratchpad_address++) = 0x0; + /* PRCM Block Offset */ + *(scratchpad_address++) = 0x2C; + /* SDRC Block Offset */ + *(scratchpad_address++) = 0x64; + /* Empty */ + /* Offset 0x8*/ + *(scratchpad_address++) = 0x0; + *(scratchpad_address++) = 0x0; + /* Offset 0xC*/ + *(scratchpad_address++) = 0x0; + /* Offset 0x10*/ + *(scratchpad_address++) = 0x0; + /* Offset 0x14*/ + *(scratchpad_address++) = 0x0; + /* Offset 0x18*/ + /* PRCM Block */ + *(scratchpad_address++) = __raw_readl(OMAP3430_PRM_CLKSRC_CTRL); + *(scratchpad_address++) = __raw_readl(OMAP3430_PRM_CLKSEL); + *(scratchpad_address++) = cm_read_mod_reg(CORE_MOD, CM_CLKSEL); + *(scratchpad_address++) = cm_read_mod_reg(WKUP_MOD, CM_CLKSEL); + *(scratchpad_address++) = cm_read_mod_reg(PLL_MOD, + OMAP3430_CM_CLKEN_PLL); + *(scratchpad_address++) = cm_read_mod_reg(PLL_MOD, + OMAP3430_CM_AUTOIDLE_PLL); + *(scratchpad_address++) = cm_read_mod_reg(PLL_MOD, + OMAP3430_CM_CLKSEL1_PLL); + *(scratchpad_address++) = cm_read_mod_reg(PLL_MOD, + OMAP3430_CM_CLKSEL2_PLL); + *(scratchpad_address++) = cm_read_mod_reg(PLL_MOD, + OMAP3430_CM_CLKSEL3); + *(scratchpad_address++) = cm_read_mod_reg(MPU_MOD, + OMAP3430_CM_CLKEN_PLL); + *(scratchpad_address++) = cm_read_mod_reg(MPU_MOD, + OMAP3430_CM_AUTOIDLE_PLL); + *(scratchpad_address++) = cm_read_mod_reg(MPU_MOD, + OMAP3430_CM_CLKSEL1_PLL); + *(scratchpad_address++) = cm_read_mod_reg(MPU_MOD, + OMAP3430_CM_CLKSEL2_PLL); + *(scratchpad_address++) = 0x0; + /* SDRC Block */ + *(scratchpad_address++) = (((sdrc_read_reg(SDRC_CS_CFG) & 0xFFFF) << 16) + | (sdrc_read_reg(SDRC_SYSCONFIG) & 0xFFFF)); + *(scratchpad_address++) = (((sdrc_read_reg(SDRC_ERR_TYPE) + & 0xFFFF) << 16) + | (sdrc_read_reg(SDRC_SHARING) & 0xFFFF)); + *(scratchpad_address++) = sdrc_read_reg(SDRC_DLLA_CTRL); + *(scratchpad_address++) = 0x0; + *(scratchpad_address++) = sdrc_read_reg(SDRC_POWER); + *(scratchpad_address++) = 0x0; + *(scratchpad_address++) = sdrc_read_reg(SDRC_MCFG_0); + *(scratchpad_address++) = sdrc_read_reg(SDRC_MR_0) & 0xFFFF; + *(scratchpad_address++) = 0x0; + *(scratchpad_address++) = sdrc_read_reg(SDRC_ACTIM_CTRL_A_0); + *(scratchpad_address++) = sdrc_read_reg(SDRC_ACTIM_CTRL_B_0); + *(scratchpad_address++) = sdrc_read_reg(SDRC_RFR_CTRL_0); + *(scratchpad_address++) = 0x0; + *(scratchpad_address++) = sdrc_read_reg(SDRC_MCFG_1); + *(scratchpad_address++) = sdrc_read_reg(SDRC_MR_1) & 0xFFFF; + *(scratchpad_address++) = 0x0; + *(scratchpad_address++) = sdrc_read_reg(SDRC_ACTIM_CTRL_A_1); + *(scratchpad_address++) = sdrc_read_reg(SDRC_ACTIM_CTRL_B_1); + *(scratchpad_address++) = sdrc_read_reg(SDRC_RFR_CTRL_1); + *(scratchpad_address++) = 0x0; + *(scratchpad_address++) = 0x0; + *(scratchpad_address++) = 0x0; + *(scratchpad_address++) = (u32) sdram_context_address; +} + static void __init configure_vc(void) { prm_write_mod_reg((R_SRI2C_SLAVE_ADDR << OMAP3430_SMPS_SA1_SHIFT) | diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S index 125b75a..7cce8ef 100644 --- a/arch/arm/mach-omap2/sleep34xx.S +++ b/arch/arm/mach-omap2/sleep34xx.S @@ -37,12 +37,10 @@ OMAP3430_PM_PREPWSTST) #define PM_PREPWSTST_MPU_V OMAP34XX_PRM_REGADDR(MPU_MOD, \ OMAP3430_PM_PREPWSTST) -#define PM_PWSTCTRL_MPU_P OMAP34XX_PRM_REGADDR(MPU_MOD, PM_PWSTCTRL) +#define PM_PWSTCTRL_MPU_P 0x483069E0 #define SCRATCHPAD_MEM_OFFS 0x310 /* Move this as correct place is * available */ -#define SCRATCHPAD_BASE_P OMAP343X_CTRL_REGADDR(\ - OMAP343X_CONTROL_MEM_WKUP +\ - SCRATCHPAD_MEM_OFFS) +#define SCRATCHPAD_BASE_P 0x48002910 #define SDRC_POWER_V OMAP34XX_SDRC_REGADDR(SDRC_POWER) .text @@ -97,7 +95,7 @@ loop: ldmfd sp!, {r0-r12, pc} @ restore regs and return restore: - /* b restore*/ @ Enable to debug restore code + /* b restore*/ @ Enable to debug restore code /* Check what was the reason for mpu reset and store the reason in r9*/ /* 1 - Only L1 and logic lost */ /* 2 - Only L2 lost - In this case, we wont be here */ diff --git a/arch/arm/plat-omap/include/mach/pm.h b/arch/arm/plat-omap/include/mach/pm.h index e4cf1c5..fd08490 100644 --- a/arch/arm/plat-omap/include/mach/pm.h +++ b/arch/arm/plat-omap/include/mach/pm.h @@ -153,6 +153,11 @@ extern void omap1510_idle_loop_suspend(void); extern void omap1610_idle_loop_suspend(void); extern void omap24xx_idle_loop_suspend(void); +extern void save_scratchpad_contents(void); +extern void clear_scratchpad_contents(void); +extern u32 *get_restore_pointer(void); +extern void vfp_enable(void); + extern unsigned int omap730_cpu_suspend_sz; extern unsigned int omap1510_cpu_suspend_sz; extern unsigned int omap1610_cpu_suspend_sz; -- 1.6.0 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 09/29] mpu off state enabled 2008-09-11 12:33 ` [PATCH 08/29] scratchpad contents Kevin Hilman @ 2008-09-11 12:33 ` Kevin Hilman 2008-09-11 12:33 ` [PATCH 10/29] gpmc context save/restore Kevin Hilman 0 siblings, 1 reply; 37+ messages in thread From: Kevin Hilman @ 2008-09-11 12:33 UTC (permalink / raw) To: linux-omap; +Cc: Rajendra Nayak From: Rajendra Nayak <rnayak@ti.com> This patch updates the CPUidle code to handle MPU OFF related C states --- arch/arm/mach-omap2/cpuidle34xx.c | 19 +++++++++++++++---- arch/arm/mach-omap2/cpuidle34xx.h | 5 +++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c index 99ecd75..ee58873 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c @@ -82,8 +82,12 @@ static int omap3_enter_idle(struct cpuidle_device *dev, /* Program MPU to target state */ if (cx->mpu_state < PWRDM_POWER_ON) { - if (neon_pwrst == PWRDM_POWER_ON) - pwrdm_set_next_pwrst(neon_pd, PWRDM_POWER_RET); + if (neon_pwrst == PWRDM_POWER_ON) { + if (cx->mpu_state == PWRDM_POWER_RET) + pwrdm_set_next_pwrst(neon_pd, PWRDM_POWER_RET); + else if (cx->mpu_state == PWRDM_POWER_OFF) + pwrdm_set_next_pwrst(neon_pd, PWRDM_POWER_OFF); + } pwrdm_set_next_pwrst(mpu_pd, cx->mpu_state); } @@ -97,9 +101,13 @@ static int omap3_enter_idle(struct cpuidle_device *dev, pwrdm_set_next_pwrst(core_pd, cx->core_state); } + *(scratchpad_restore_addr) = restore_pointer_address; + /* Execute ARM wfi */ omap_sram_idle(); + *(scratchpad_restore_addr) = 0x0; + /* Program MPU/NEON to ON */ if (cx->mpu_state < PWRDM_POWER_ON) { if (neon_pwrst == PWRDM_POWER_ON) @@ -207,7 +215,7 @@ void omap_init_power_states(void) CPUIDLE_FLAG_BALANCED; /* C3 . MPU OFF + Core active */ - omap3_power_states[3].valid = 0; + omap3_power_states[3].valid = 1; omap3_power_states[3].type = OMAP3_STATE_C3; omap3_power_states[3].sleep_latency = 1500; omap3_power_states[3].wakeup_latency = 1800; @@ -229,7 +237,7 @@ void omap_init_power_states(void) CPUIDLE_FLAG_BALANCED | CPUIDLE_FLAG_CHECK_BM; /* C5 . MPU OFF + Core CSWR */ - omap3_power_states[5].valid = 0; + omap3_power_states[5].valid = 1; omap3_power_states[5].type = OMAP3_STATE_C5; omap3_power_states[5].sleep_latency = 3000; omap3_power_states[5].wakeup_latency = 8500; @@ -266,6 +274,9 @@ int omap3_idle_init(void) struct cpuidle_state *state; struct cpuidle_device *dev; + clear_scratchpad_contents(); + save_scratchpad_contents(); + omap_init_power_states(); cpuidle_register_driver(&omap3_idle_driver); diff --git a/arch/arm/mach-omap2/cpuidle34xx.h b/arch/arm/mach-omap2/cpuidle34xx.h index 46ed51e..f2ebe68 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.h +++ b/arch/arm/mach-omap2/cpuidle34xx.h @@ -40,6 +40,11 @@ extern void per_gpio_clk_enable(void); extern void per_gpio_clk_disable(void); extern void omap_serial_enable_clocks(int enable); extern int omap3_can_sleep(); +extern void clear_scratchpad_contents(void); +extern void save_scratchpad_contents(void); +extern u32 *scratchpad_restore_addr; +extern u32 restore_pointer_address; + struct omap3_processor_cx { u8 valid; u8 type; -- 1.6.0 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 10/29] gpmc context save/restore 2008-09-11 12:33 ` [PATCH 09/29] mpu off state enabled Kevin Hilman @ 2008-09-11 12:33 ` Kevin Hilman 2008-09-11 12:33 ` [PATCH 11/29] serial " Kevin Hilman 0 siblings, 1 reply; 37+ messages in thread From: Kevin Hilman @ 2008-09-11 12:33 UTC (permalink / raw) To: linux-omap; +Cc: Rajendra Nayak From: Rajendra Nayak <rnayak@ti.com> This patch adds the context save restore functions for GPMC --- arch/arm/mach-omap2/gpmc.c | 80 ++++++++++++++++++++++++++++++++ arch/arm/plat-omap/include/mach/gpmc.h | 14 ++++++ 2 files changed, 94 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index f3e0271..32f36fa 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -54,6 +54,21 @@ #define GPMC_CHUNK_SHIFT 24 /* 16 MB */ #define GPMC_SECTION_SHIFT 28 /* 128 MB */ +/* + * Structure to save/restore gpmc context + * to support core off + */ +static struct gpmc_context { + u32 sysconfig; + u32 irqenable; + u32 timeout_ctrl; + u32 config; + u32 prefetch_config1; + u32 prefetch_config2; + u32 prefetch_control; + struct gpmc_cs_config cs_context[GPMC_CS_NUM]; +} gpmc_ctx; + static struct resource gpmc_mem_root; static struct resource gpmc_cs_mem[GPMC_CS_NUM]; static DEFINE_SPINLOCK(gpmc_mem_lock); @@ -451,3 +466,68 @@ void __init gpmc_init(void) gpmc_mem_init(); } + +void omap_save_gpmc_ctx() +{ + int i; + gpmc_ctx.sysconfig = gpmc_read_reg(GPMC_SYSCONFIG); + gpmc_ctx.irqenable = gpmc_read_reg(GPMC_IRQENABLE); + gpmc_ctx.timeout_ctrl = gpmc_read_reg(GPMC_TIMEOUT_CONTROL); + gpmc_ctx.config = gpmc_read_reg(GPMC_CONFIG); + gpmc_ctx.prefetch_config1 = gpmc_read_reg(GPMC_PREFETCH_CONFIG1); + gpmc_ctx.prefetch_config2 = gpmc_read_reg(GPMC_PREFETCH_CONFIG2); + gpmc_ctx.prefetch_control = gpmc_read_reg(GPMC_PREFETCH_CONTROL); + for (i = 0; i < GPMC_CS_NUM; i++) { + gpmc_ctx.cs_context[i].is_valid = + (gpmc_cs_read_reg(i, GPMC_CS_CONFIG7)) + & (1 << 6); + if (gpmc_ctx.cs_context[i].is_valid) { + gpmc_ctx.cs_context[i].gpmc_config1 = + gpmc_cs_read_reg(i, GPMC_CS_CONFIG1); + gpmc_ctx.cs_context[i].gpmc_config2 = + gpmc_cs_read_reg(i, GPMC_CS_CONFIG2); + gpmc_ctx.cs_context[i].gpmc_config3 = + gpmc_cs_read_reg(i, GPMC_CS_CONFIG3); + gpmc_ctx.cs_context[i].gpmc_config4 = + gpmc_cs_read_reg(i, GPMC_CS_CONFIG4); + gpmc_ctx.cs_context[i].gpmc_config5 = + gpmc_cs_read_reg(i, GPMC_CS_CONFIG5); + gpmc_ctx.cs_context[i].gpmc_config6 = + gpmc_cs_read_reg(i, GPMC_CS_CONFIG6); + gpmc_ctx.cs_context[i].gpmc_config7 = + gpmc_cs_read_reg(i, GPMC_CS_CONFIG7); + } + } +} + +void omap_restore_gpmc_ctx() +{ + int i; + gpmc_write_reg(GPMC_SYSCONFIG, gpmc_ctx.sysconfig); + gpmc_write_reg(GPMC_IRQENABLE, gpmc_ctx.irqenable); + gpmc_write_reg(GPMC_TIMEOUT_CONTROL, gpmc_ctx.timeout_ctrl); + gpmc_write_reg(GPMC_CONFIG, gpmc_ctx.config); + gpmc_write_reg(GPMC_PREFETCH_CONFIG1, gpmc_ctx.prefetch_config1); + gpmc_write_reg(GPMC_PREFETCH_CONFIG2, gpmc_ctx.prefetch_config2); + gpmc_write_reg(GPMC_PREFETCH_CONTROL, gpmc_ctx.prefetch_control); + for (i = 0; i < GPMC_CS_NUM; i++) { + if (gpmc_ctx.cs_context[i].is_valid) { + gpmc_cs_write_reg(i, GPMC_CS_CONFIG1, + gpmc_ctx.cs_context[i].gpmc_config1); + gpmc_cs_write_reg(i, GPMC_CS_CONFIG2, + gpmc_ctx.cs_context[i].gpmc_config2); + gpmc_cs_write_reg(i, GPMC_CS_CONFIG3, + gpmc_ctx.cs_context[i].gpmc_config3); + gpmc_cs_write_reg(i, GPMC_CS_CONFIG4, + gpmc_ctx.cs_context[i].gpmc_config4); + gpmc_cs_write_reg(i, GPMC_CS_CONFIG5, + gpmc_ctx.cs_context[i].gpmc_config5); + gpmc_cs_write_reg(i, GPMC_CS_CONFIG6, + gpmc_ctx.cs_context[i].gpmc_config6); + gpmc_cs_write_reg(i, GPMC_CS_CONFIG7, + gpmc_ctx.cs_context[i].gpmc_config7); + } + } +} + + diff --git a/arch/arm/plat-omap/include/mach/gpmc.h b/arch/arm/plat-omap/include/mach/gpmc.h index 921b165..133991c 100644 --- a/arch/arm/plat-omap/include/mach/gpmc.h +++ b/arch/arm/plat-omap/include/mach/gpmc.h @@ -90,6 +90,18 @@ struct gpmc_timings { u16 wr_data_mux_bus; /* WRDATAONADMUXBUS */ }; +/* Structure to save gpmc cs context */ +struct gpmc_cs_config { + u32 gpmc_config1; + u32 gpmc_config2; + u32 gpmc_config3; + u32 gpmc_config4; + u32 gpmc_config5; + u32 gpmc_config6; + u32 gpmc_config7; + int is_valid; +}; + extern unsigned int gpmc_ns_to_ticks(unsigned int time_ns); extern unsigned int gpmc_ticks_to_ns(unsigned int ticks); extern unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns); @@ -103,6 +115,8 @@ extern int gpmc_cs_request(int cs, unsigned long size, unsigned long *base); extern void gpmc_cs_free(int cs); extern int gpmc_cs_set_reserved(int cs, int reserved); extern int gpmc_cs_reserved(int cs); +extern void omap_save_gpmc_ctx(void); +extern void omap_restore_gpmc_ctx(void); extern void __init gpmc_init(void); #endif -- 1.6.0 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 11/29] serial context save/restore 2008-09-11 12:33 ` [PATCH 10/29] gpmc context save/restore Kevin Hilman @ 2008-09-11 12:33 ` Kevin Hilman 2008-09-11 12:33 ` [PATCH 12/29] gpio " Kevin Hilman 0 siblings, 1 reply; 37+ messages in thread From: Kevin Hilman @ 2008-09-11 12:33 UTC (permalink / raw) To: linux-omap; +Cc: Rajendra Nayak From: Rajendra Nayak <rnayak@ti.com> This patch adds the context save restore functions for UART --- arch/arm/mach-omap2/serial.c | 62 ++++++++++++++++++++++++++++++++++++++++++ include/linux/serial_reg.h | 1 + 2 files changed, 63 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 281c1c7..879d7c1 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -83,6 +83,16 @@ static const u32 omap34xx_uart_padconf[OMAP_MAX_NR_PORTS] = { CONTROL_PADCONF_UART3_RX }; +struct omap_uart_regs { + u16 dll; + u16 dlh; + u16 ier; + u16 sysc; + u16 scr; + u16 wer; +}; +static struct omap_uart_regs uart_ctx[OMAP_MAX_NR_PORTS]; + static struct plat_serial8250_port serial_platform_data[] = { { .membase = IO_ADDRESS(OMAP_UART1_BASE), @@ -314,6 +324,58 @@ static ssize_t awake_store(struct kobject *kobj, struct kobj_attribute *attr, return n; } +void omap_save_uart_ctx(int unum) +{ + u16 lcr = 0; + + struct plat_serial8250_port *p = serial_platform_data + unum; + + if (uart_ick[unum] == NULL) + return; + + lcr = serial_read_reg(p, UART_LCR); + serial_write_reg(p, UART_LCR, 0xBF); + uart_ctx[unum].dll = serial_read_reg(p, UART_DLL); + uart_ctx[unum].dlh = serial_read_reg(p, UART_DLM); + serial_write_reg(p, UART_LCR, lcr); + uart_ctx[unum].ier = serial_read_reg(p, UART_IER); + uart_ctx[unum].sysc = serial_read_reg(p, UART_OMAP_SYSC); + uart_ctx[unum].scr = serial_read_reg(p, UART_OMAP_SCR); + uart_ctx[unum].wer = serial_read_reg(p, UART_OMAP_WER); +} +EXPORT_SYMBOL(omap_save_uart_ctx); + +void omap_restore_uart_ctx(int unum) +{ + u16 efr = 0; + + struct plat_serial8250_port *p = serial_platform_data + unum; + + if (uart_ick[unum] == NULL) + return; + + serial_write_reg(p, UART_OMAP_MDR1, 0x7); + serial_write_reg(p, UART_LCR, 0xBF); /* Config B mode */ + efr = serial_read_reg(p, UART_EFR); + serial_write_reg(p, UART_EFR, UART_EFR_ECB); + serial_write_reg(p, UART_LCR, 0x0); /* Operational mode */ + serial_write_reg(p, UART_IER, 0x0); + serial_write_reg(p, UART_LCR, 0xBF); /* Config B mode */ + serial_write_reg(p, UART_DLL, uart_ctx[unum].dll); + serial_write_reg(p, UART_DLM, uart_ctx[unum].dlh); + serial_write_reg(p, UART_LCR, 0x0); /* Operational mode */ + serial_write_reg(p, UART_IER, uart_ctx[unum].ier); + serial_write_reg(p, UART_FCR, 0xA1); + serial_write_reg(p, UART_LCR, 0xBF); /* Config B mode */ + serial_write_reg(p, UART_EFR, efr); + serial_write_reg(p, UART_LCR, UART_LCR_WLEN8); + serial_write_reg(p, UART_OMAP_SCR, uart_ctx[unum].scr); + serial_write_reg(p, UART_OMAP_WER, uart_ctx[unum].wer); + serial_write_reg(p, UART_OMAP_SYSC, uart_ctx[unum].sysc); + serial_write_reg(p, UART_OMAP_MDR1, 0x00); /* UART 16x mode */ +} +EXPORT_SYMBOL(omap_restore_uart_ctx); + static struct platform_device serial_device = { .name = "serial8250", .id = PLAT8250_DEV_PLATFORM, diff --git a/include/linux/serial_reg.h b/include/linux/serial_reg.h index 96c0d93..76ffd3c 100644 --- a/include/linux/serial_reg.h +++ b/include/linux/serial_reg.h @@ -323,6 +323,7 @@ #define UART_OMAP_MVER 0x14 /* Module version register */ #define UART_OMAP_SYSC 0x15 /* System configuration register */ #define UART_OMAP_SYSS 0x16 /* System status register */ +#define UART_OMAP_WER 0x17 /* Wake-up enable register */ #endif /* _LINUX_SERIAL_REG_H */ -- 1.6.0 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 12/29] gpio context save/restore 2008-09-11 12:33 ` [PATCH 11/29] serial " Kevin Hilman @ 2008-09-11 12:33 ` Kevin Hilman 2008-09-11 12:33 ` [PATCH 13/29] i2c " Kevin Hilman 0 siblings, 1 reply; 37+ messages in thread From: Kevin Hilman @ 2008-09-11 12:33 UTC (permalink / raw) To: linux-omap; +Cc: Rajendra Nayak From: Rajendra Nayak <rnayak@ti.com> This patch adds the context save restore functions for GPIO --- arch/arm/plat-omap/gpio.c | 92 ++++++++++++++++++++++++++++++ arch/arm/plat-omap/include/mach/common.h | 2 + 2 files changed, 94 insertions(+), 0 deletions(-) diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index ac55616..401120f 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -101,6 +101,7 @@ #define OMAP24XX_GPIO_IRQSTATUS2 0x0028 #define OMAP24XX_GPIO_IRQENABLE2 0x002c #define OMAP24XX_GPIO_IRQENABLE1 0x001c +#define OMAP24XX_GPIO_WAKE_EN 0x0020 #define OMAP24XX_GPIO_CTRL 0x0030 #define OMAP24XX_GPIO_OE 0x0034 #define OMAP24XX_GPIO_DATAIN 0x0038 @@ -217,6 +218,22 @@ static struct gpio_bank gpio_bank_34xx[6] = { { OMAP34XX_GPIO6_BASE, INT_34XX_GPIO_BANK6, IH_GPIO_BASE + 160, METHOD_GPIO_24XX }, }; +struct gpio_restore_regs { + u32 gpio_sysconfig; + u32 gpio_irqenable1; + u32 gpio_irqenable2; + u32 gpio_wake_en; + u32 gpio_ctrl; + u32 gpio_oe; + u32 gpio_leveldetect0; + u32 gpio_leveldetect1; + u32 gpio_risingdetect; + u32 gpio_fallingdetect; + u32 gpio_dataout; + u32 gpio_setwkuena; + u32 gpio_setdataout; +}; +static struct gpio_restore_regs gpio_restore_banks[6]; #endif static struct gpio_bank *gpio_bank; @@ -1707,6 +1724,81 @@ void omap2_gpio_resume_after_retention(void) #endif +#ifdef CONFIG_ARCH_OMAP34XX +/* save the registers of bank 2-6 */ +void omap_gpio_save(void) +{ + int i; + /* saving banks from 2-6 only */ + for (i = 1; i < gpio_bank_count; i++) { + struct gpio_bank *bank = &gpio_bank[i]; + gpio_restore_banks[i].gpio_sysconfig = + __raw_readl(bank->base + OMAP24XX_GPIO_SYSCONFIG); + gpio_restore_banks[i].gpio_irqenable1 = + __raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE1); + gpio_restore_banks[i].gpio_irqenable2 = + __raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE2); + gpio_restore_banks[i].gpio_wake_en = + __raw_readl(bank->base + OMAP24XX_GPIO_WAKE_EN); + gpio_restore_banks[i].gpio_ctrl = + __raw_readl(bank->base + OMAP24XX_GPIO_CTRL); + gpio_restore_banks[i].gpio_oe = + __raw_readl(bank->base + OMAP24XX_GPIO_OE); + gpio_restore_banks[i].gpio_leveldetect0 = + __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0); + gpio_restore_banks[i].gpio_leveldetect1 = + __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1); + gpio_restore_banks[i].gpio_risingdetect = + __raw_readl(bank->base + OMAP24XX_GPIO_RISINGDETECT); + gpio_restore_banks[i].gpio_fallingdetect = + __raw_readl(bank->base + OMAP24XX_GPIO_FALLINGDETECT); + gpio_restore_banks[i].gpio_dataout = + __raw_readl(bank->base + OMAP24XX_GPIO_DATAOUT); + gpio_restore_banks[i].gpio_setwkuena = + __raw_readl(bank->base + OMAP24XX_GPIO_SETWKUENA); + gpio_restore_banks[i].gpio_setdataout = + __raw_readl(bank->base + OMAP24XX_GPIO_SETDATAOUT); + } +} +EXPORT_SYMBOL(omap_gpio_save); + +/* restore the required registers of bank 2-6 */ +void omap_gpio_restore(void) +{ + int i; + for (i = 1; i < gpio_bank_count; i++) { + struct gpio_bank *bank = &gpio_bank[i]; + __raw_writel(gpio_restore_banks[i].gpio_sysconfig, + bank->base + OMAP24XX_GPIO_SYSCONFIG); + __raw_writel(gpio_restore_banks[i].gpio_irqenable1, + bank->base + OMAP24XX_GPIO_IRQENABLE1); + __raw_writel(gpio_restore_banks[i].gpio_irqenable2, + bank->base + OMAP24XX_GPIO_IRQENABLE2); + __raw_writel(gpio_restore_banks[i].gpio_wake_en, + bank->base + OMAP24XX_GPIO_WAKE_EN); + __raw_writel(gpio_restore_banks[i].gpio_ctrl, + bank->base + OMAP24XX_GPIO_CTRL); + __raw_writel(gpio_restore_banks[i].gpio_oe, + bank->base + OMAP24XX_GPIO_OE); + __raw_writel(gpio_restore_banks[i].gpio_leveldetect0, + bank->base + OMAP24XX_GPIO_LEVELDETECT0); + __raw_writel(gpio_restore_banks[i].gpio_leveldetect1, + bank->base + OMAP24XX_GPIO_LEVELDETECT1); + __raw_writel(gpio_restore_banks[i].gpio_risingdetect, + bank->base + OMAP24XX_GPIO_RISINGDETECT); + __raw_writel(gpio_restore_banks[i].gpio_fallingdetect, + bank->base + OMAP24XX_GPIO_FALLINGDETECT); + __raw_writel(gpio_restore_banks[i].gpio_dataout, + bank->base + OMAP24XX_GPIO_DATAOUT); + __raw_writel(gpio_restore_banks[i].gpio_setwkuena, + bank->base + OMAP24XX_GPIO_SETWKUENA); + __raw_writel(gpio_restore_banks[i].gpio_setdataout, + bank->base + OMAP24XX_GPIO_SETDATAOUT); + } +} +EXPORT_SYMBOL(omap_gpio_restore); +#endif + /* * This may get called early from board specific init * for boards that have interrupts routed via FPGA. diff --git a/arch/arm/plat-omap/include/mach/common.h b/arch/arm/plat-omap/include/mach/common.h index 003c08e..489add6 100644 --- a/arch/arm/plat-omap/include/mach/common.h +++ b/arch/arm/plat-omap/include/mach/common.h @@ -36,6 +36,8 @@ extern struct sys_timer omap_timer; extern void omap_serial_init(void); extern void omap_serial_enable_clocks(int enable); extern int omap_serial_can_sleep(void); +extern void omap_gpio_save(void); +extern void omap_gpio_restore(void); extern void omap_serial_fclk_mask(u32 *f1, u32 *f2); void omap_serial_check_wakeup(void); #ifdef CONFIG_I2C_OMAP -- 1.6.0 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 13/29] i2c context save/restore 2008-09-11 12:33 ` [PATCH 12/29] gpio " Kevin Hilman @ 2008-09-11 12:33 ` Kevin Hilman 2008-09-11 12:33 ` [PATCH 14/29] CORE " Kevin Hilman 0 siblings, 1 reply; 37+ messages in thread From: Kevin Hilman @ 2008-09-11 12:33 UTC (permalink / raw) To: linux-omap; +Cc: Rajendra Nayak From: Rajendra Nayak <rnayak@ti.com> This patch does i2c init/re-init for every transfer --- drivers/i2c/busses/i2c-omap.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 0f7cbe8..a661ed3 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -503,6 +503,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) omap_i2c_unidle(dev); + omap_i2c_init(dev); + if ((r = omap_i2c_wait_for_bb(dev)) < 0) goto out; -- 1.6.0 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 14/29] CORE context save/restore 2008-09-11 12:33 ` [PATCH 13/29] i2c " Kevin Hilman @ 2008-09-11 12:33 ` Kevin Hilman 2008-09-11 12:33 ` [PATCH 15/29] OMAP3: PM: Move serial console check from omap3_can_sleep to idle loop Kevin Hilman 0 siblings, 1 reply; 37+ messages in thread From: Kevin Hilman @ 2008-09-11 12:33 UTC (permalink / raw) To: linux-omap; +Cc: Rajendra Nayak From: Rajendra Nayak <rnayak@ti.com> This patch adds the CORE context save/restore routines - save/restores the following 1) PRCM registers 2) INTC context 3) System Control module context 4) Padconf --- arch/arm/mach-omap2/cpuidle34xx.c | 608 ++++++++++++++++++++++------- arch/arm/mach-omap2/cpuidle34xx.h | 33 ++- arch/arm/mach-omap2/pm34xx.c | 144 +++++++- arch/arm/mach-omap2/prm.h | 2 + arch/arm/mach-omap2/serial.c | 19 +- arch/arm/mach-omap2/sleep34xx.S | 12 +- arch/arm/plat-omap/include/mach/common.h | 2 +- arch/arm/plat-omap/include/mach/control.h | 22 +- arch/arm/plat-omap/include/mach/prcm.h | 56 +++- arch/arm/plat-omap/sram.c | 9 +- drivers/serial/8250.c | 20 + 11 files changed, 755 insertions(+), 172 deletions(-) diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c index ee58873..a02da6d 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c @@ -28,7 +28,382 @@ #include <asm/arch/powerdomain.h> #include <asm/arch/clockdomain.h> #include <asm/arch/gpio.h> +#include <asm/arch/gpmc.h> +#include <asm/arch/control.h> +#include <linux/sched.h> #include "cpuidle34xx.h" +#include "cm.h" +#include "cm-regbits-34xx.h" +#include "prm-regbits-34xx.h" +#include "prm.h" +#include "pm.h" +#include "clock34xx.h" + +static int padconf_saved; +void omap3_save_prcm_ctx(void) +{ + prcm_sleep_save[1] = omap_readl(INTC_MIR_0); + prcm_sleep_save[2] = omap_readl(INTC_MIR_1); + prcm_sleep_save[3] = omap_readl(INTC_MIR_2); + prcm_sleep_save[4] = omap_readl(CONTROL_PADCONF_SYS_NIRQ); + prcm_sleep_save[5] = omap_readl(OMAP34XX_GPIO1_IRQENABLE1); + prcm_sleep_save[6] = omap_readl(OMAP34XX_GPIO1_WAKEUPEN); + prcm_sleep_save[7] = cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSEL2); + prcm_sleep_save[8] = __raw_readl(OMAP3430_CM_SYSCONFIG); + prcm_sleep_save[9] = cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_CLKSEL); + prcm_sleep_save[10] = cm_read_mod_reg(WKUP_MOD, CM_CLKSEL); + prcm_sleep_save[11] = cm_read_mod_reg(OMAP3430_DSS_MOD, CM_CLKSEL); + prcm_sleep_save[12] = cm_read_mod_reg(OMAP3430_CAM_MOD, CM_CLKSEL); + prcm_sleep_save[13] = cm_read_mod_reg(OMAP3430_PER_MOD, CM_CLKSEL); + prcm_sleep_save[14] = cm_read_mod_reg(OMAP3430_EMU_MOD, CM_CLKSEL1); + prcm_sleep_save[15] = cm_read_mod_reg(OMAP3430_EMU_MOD, CM_CLKSTCTRL); + prcm_sleep_save[16] = cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE2); + prcm_sleep_save[17] = cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKSEL5); + prcm_sleep_save[18] = __raw_readl(OMAP3430_CM_POLCTRL); + prcm_sleep_save[19] = cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_FCLKEN); + prcm_sleep_save[20] = cm_read_mod_reg(CORE_MOD, CM_FCLKEN1); + prcm_sleep_save[21] = cm_read_mod_reg(CORE_MOD, OMAP3430ES2_CM_FCLKEN3); + prcm_sleep_save[22] = cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_FCLKEN); + prcm_sleep_save[23] = cm_read_mod_reg(WKUP_MOD, CM_FCLKEN); + prcm_sleep_save[24] = cm_read_mod_reg(OMAP3430_DSS_MOD, CM_FCLKEN); + prcm_sleep_save[25] = cm_read_mod_reg(OMAP3430_CAM_MOD, CM_FCLKEN); + prcm_sleep_save[26] = cm_read_mod_reg(OMAP3430_PER_MOD, CM_FCLKEN); + prcm_sleep_save[27] = cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, + CM_FCLKEN); + prcm_sleep_save[28] = cm_read_mod_reg(CORE_MOD, CM_ICLKEN1); + prcm_sleep_save[29] = cm_read_mod_reg(CORE_MOD, CM_ICLKEN2); + prcm_sleep_save[30] = cm_read_mod_reg(CORE_MOD, CM_ICLKEN3); + prcm_sleep_save[31] = cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_ICLKEN); + prcm_sleep_save[32] = cm_read_mod_reg(WKUP_MOD, CM_ICLKEN); + prcm_sleep_save[33] = cm_read_mod_reg(OMAP3430_DSS_MOD, CM_ICLKEN); + prcm_sleep_save[34] = cm_read_mod_reg(OMAP3430_CAM_MOD, CM_ICLKEN); + prcm_sleep_save[35] = cm_read_mod_reg(OMAP3430_PER_MOD, CM_ICLKEN); + prcm_sleep_save[36] = cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, + CM_ICLKEN); + prcm_sleep_save[37] = cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_AUTOIDLE2); + prcm_sleep_save[38] = cm_read_mod_reg(MPU_MOD, CM_AUTOIDLE2); + prcm_sleep_save[39] = cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE); + prcm_sleep_save[40] = cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSTCTRL); + prcm_sleep_save[41] = cm_read_mod_reg(MPU_MOD, CM_CLKSTCTRL); + prcm_sleep_save[42] = cm_read_mod_reg(CORE_MOD, CM_CLKSTCTRL); + prcm_sleep_save[43] = cm_read_mod_reg(OMAP3430ES2_SGX_MOD, + CM_CLKSTCTRL); + prcm_sleep_save[44] = cm_read_mod_reg(OMAP3430_DSS_MOD, CM_CLKSTCTRL); + prcm_sleep_save[45] = cm_read_mod_reg(OMAP3430_CAM_MOD, CM_CLKSTCTRL); + prcm_sleep_save[46] = cm_read_mod_reg(OMAP3430_PER_MOD, CM_CLKSTCTRL); + prcm_sleep_save[47] = cm_read_mod_reg(OMAP3430_NEON_MOD, CM_CLKSTCTRL); + prcm_sleep_save[48] = cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, + CM_CLKSTCTRL); + prcm_sleep_save[49] = cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE1); + prcm_sleep_save[50] = cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE2); + prcm_sleep_save[51] = cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE3); + prcm_sleep_save[52] = cm_read_mod_reg(WKUP_MOD, CM_AUTOIDLE); + prcm_sleep_save[53] = cm_read_mod_reg(OMAP3430_DSS_MOD, CM_AUTOIDLE); + prcm_sleep_save[54] = cm_read_mod_reg(OMAP3430_CAM_MOD, CM_AUTOIDLE); + prcm_sleep_save[55] = cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE); + prcm_sleep_save[56] = cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, + CM_AUTOIDLE); + prcm_sleep_save[57] = cm_read_mod_reg(OMAP3430ES2_SGX_MOD, + OMAP3430_CM_SLEEPDEP); + prcm_sleep_save[58] = cm_read_mod_reg(OMAP3430_DSS_MOD, + OMAP3430_CM_SLEEPDEP); + prcm_sleep_save[59] = cm_read_mod_reg(OMAP3430_CAM_MOD, + OMAP3430_CM_SLEEPDEP); + prcm_sleep_save[60] = cm_read_mod_reg(OMAP3430_PER_MOD, + OMAP3430_CM_SLEEPDEP); + prcm_sleep_save[61] = cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, + OMAP3430_CM_SLEEPDEP); + prcm_sleep_save[62] = __raw_readl(OMAP3430_CM_CLKOUT_CTRL); + prcm_sleep_save[63] = __raw_readl(OMAP3430_PRM_CLKOUT_CTRL); + prcm_sleep_save[64] = prm_read_mod_reg(OMAP3430ES2_SGX_MOD, PM_WKDEP); + prcm_sleep_save[65] = prm_read_mod_reg(OMAP3430_DSS_MOD, PM_WKDEP); + prcm_sleep_save[66] = prm_read_mod_reg(OMAP3430_CAM_MOD, PM_WKDEP); + prcm_sleep_save[67] = prm_read_mod_reg(OMAP3430_PER_MOD, PM_WKDEP); + prcm_sleep_save[68] = prm_read_mod_reg(OMAP3430_NEON_MOD, PM_WKDEP); + prcm_sleep_save[69] = prm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, + PM_WKDEP); + prcm_sleep_save[70] = prm_read_mod_reg(CORE_MOD, + OMAP3430_PM_MPUGRPSEL1); + prcm_sleep_save[71] = prm_read_mod_reg(OMAP3430_IVA2_MOD, + OMAP3430_PM_IVAGRPSEL1); + prcm_sleep_save[72] = prm_read_mod_reg(CORE_MOD, + OMAP3430ES2_PM_MPUGRPSEL3); + prcm_sleep_save[73] = prm_read_mod_reg(CORE_MOD, + OMAP3430ES2_PM_IVAGRPSEL3); + prcm_sleep_save[74] = prm_read_mod_reg(WKUP_MOD, OMAP3430_PM_MPUGRPSEL); + prcm_sleep_save[75] = prm_read_mod_reg(WKUP_MOD, + OMAP3430_PM_IVAGRPSEL); + prcm_sleep_save[76] = prm_read_mod_reg(OMAP3430_PER_MOD, + OMAP3430_PM_MPUGRPSEL); + prcm_sleep_save[77] = prm_read_mod_reg(OMAP3430_PER_MOD, + OMAP3430_PM_IVAGRPSEL); + prcm_sleep_save[78] = prm_read_mod_reg(WKUP_MOD, PM_WKEN); + return; +} + +void omap3_restore_prcm_ctx(void) +{ + omap_writel(prcm_sleep_save[1], INTC_MIR_0); + omap_writel(prcm_sleep_save[2], INTC_MIR_1); + omap_writel(prcm_sleep_save[3], INTC_MIR_2); + omap_writel(prcm_sleep_save[4], CONTROL_PADCONF_SYS_NIRQ); + omap_writel(prcm_sleep_save[5], OMAP34XX_GPIO1_IRQENABLE1); + omap_writel(prcm_sleep_save[6], OMAP34XX_GPIO1_WAKEUPEN); + cm_write_mod_reg(prcm_sleep_save[7], OMAP3430_IVA2_MOD, CM_CLKSEL2); + __raw_writel(prcm_sleep_save[8], OMAP3430_CM_SYSCONFIG); + cm_write_mod_reg(prcm_sleep_save[9], OMAP3430ES2_SGX_MOD, CM_CLKSEL); + cm_write_mod_reg(prcm_sleep_save[10], WKUP_MOD, CM_CLKSEL); + cm_write_mod_reg(prcm_sleep_save[11], OMAP3430_DSS_MOD, CM_CLKSEL); + cm_write_mod_reg(prcm_sleep_save[12], OMAP3430_CAM_MOD, CM_CLKSEL); + cm_write_mod_reg(prcm_sleep_save[13], OMAP3430_PER_MOD, CM_CLKSEL); + cm_write_mod_reg(prcm_sleep_save[14], OMAP3430_EMU_MOD, CM_CLKSEL1); + cm_write_mod_reg(prcm_sleep_save[15], OMAP3430_EMU_MOD, CM_CLKSTCTRL); + cm_write_mod_reg(prcm_sleep_save[16], PLL_MOD, CM_AUTOIDLE2); + cm_write_mod_reg(prcm_sleep_save[17], PLL_MOD, OMAP3430ES2_CM_CLKSEL5); + __raw_writel(prcm_sleep_save[18], OMAP3430_CM_POLCTRL); + cm_write_mod_reg(prcm_sleep_save[19], OMAP3430_IVA2_MOD, CM_FCLKEN); + cm_write_mod_reg(prcm_sleep_save[20], CORE_MOD, CM_FCLKEN1); + cm_write_mod_reg(prcm_sleep_save[21], CORE_MOD, OMAP3430ES2_CM_FCLKEN3); + cm_write_mod_reg(prcm_sleep_save[22], OMAP3430ES2_SGX_MOD, CM_FCLKEN); + cm_write_mod_reg(prcm_sleep_save[23], WKUP_MOD, CM_FCLKEN); + cm_write_mod_reg(prcm_sleep_save[24], OMAP3430_DSS_MOD, CM_FCLKEN); + cm_write_mod_reg(prcm_sleep_save[25], OMAP3430_CAM_MOD, CM_FCLKEN); + cm_write_mod_reg(prcm_sleep_save[26], OMAP3430_PER_MOD, CM_FCLKEN); + cm_write_mod_reg(prcm_sleep_save[27], OMAP3430ES2_USBHOST_MOD, + CM_FCLKEN); + cm_write_mod_reg(prcm_sleep_save[28], CORE_MOD, CM_ICLKEN1); + cm_write_mod_reg(prcm_sleep_save[29], CORE_MOD, CM_ICLKEN2); + cm_write_mod_reg(prcm_sleep_save[30], CORE_MOD, CM_ICLKEN3); + cm_write_mod_reg(prcm_sleep_save[31], OMAP3430ES2_SGX_MOD, CM_ICLKEN); + cm_write_mod_reg(prcm_sleep_save[32], WKUP_MOD, CM_ICLKEN); + cm_write_mod_reg(prcm_sleep_save[33], OMAP3430_DSS_MOD, CM_ICLKEN); + cm_write_mod_reg(prcm_sleep_save[34], OMAP3430_CAM_MOD, CM_ICLKEN); + cm_write_mod_reg(prcm_sleep_save[35], OMAP3430_PER_MOD, CM_ICLKEN); + cm_write_mod_reg(prcm_sleep_save[36], OMAP3430ES2_USBHOST_MOD, + CM_ICLKEN); + cm_write_mod_reg(prcm_sleep_save[37], OMAP3430_IVA2_MOD, CM_AUTOIDLE2); + cm_write_mod_reg(prcm_sleep_save[38], MPU_MOD, CM_AUTOIDLE2); + cm_write_mod_reg(prcm_sleep_save[39], PLL_MOD, CM_AUTOIDLE); + cm_write_mod_reg(prcm_sleep_save[40], OMAP3430_IVA2_MOD, CM_CLKSTCTRL); + cm_write_mod_reg(prcm_sleep_save[41], MPU_MOD, CM_CLKSTCTRL); + cm_write_mod_reg(prcm_sleep_save[42], CORE_MOD, CM_CLKSTCTRL); + cm_write_mod_reg(prcm_sleep_save[43], OMAP3430ES2_SGX_MOD, + CM_CLKSTCTRL); + cm_write_mod_reg(prcm_sleep_save[44], OMAP3430_DSS_MOD, CM_CLKSTCTRL); + cm_write_mod_reg(prcm_sleep_save[45], OMAP3430_CAM_MOD, CM_CLKSTCTRL); + cm_write_mod_reg(prcm_sleep_save[46], OMAP3430_PER_MOD, CM_CLKSTCTRL); + cm_write_mod_reg(prcm_sleep_save[47], OMAP3430_NEON_MOD, CM_CLKSTCTRL); + cm_write_mod_reg(prcm_sleep_save[48], OMAP3430ES2_USBHOST_MOD, + CM_CLKSTCTRL); + cm_write_mod_reg(prcm_sleep_save[49], CORE_MOD, CM_AUTOIDLE1); + cm_write_mod_reg(prcm_sleep_save[50], CORE_MOD, CM_AUTOIDLE2); + cm_write_mod_reg(prcm_sleep_save[51], CORE_MOD, CM_AUTOIDLE3); + cm_write_mod_reg(prcm_sleep_save[52], WKUP_MOD, CM_AUTOIDLE); + cm_write_mod_reg(prcm_sleep_save[53], OMAP3430_DSS_MOD, CM_AUTOIDLE); + cm_write_mod_reg(prcm_sleep_save[54], OMAP3430_CAM_MOD, CM_AUTOIDLE); + cm_write_mod_reg(prcm_sleep_save[55], OMAP3430_PER_MOD, CM_AUTOIDLE); + cm_write_mod_reg(prcm_sleep_save[56], OMAP3430ES2_USBHOST_MOD, + CM_AUTOIDLE); + cm_write_mod_reg(prcm_sleep_save[57], OMAP3430ES2_SGX_MOD, + OMAP3430_CM_SLEEPDEP); + cm_write_mod_reg(prcm_sleep_save[58], OMAP3430_DSS_MOD, + OMAP3430_CM_SLEEPDEP); + cm_write_mod_reg(prcm_sleep_save[59], OMAP3430_CAM_MOD, + OMAP3430_CM_SLEEPDEP); + cm_write_mod_reg(prcm_sleep_save[60], OMAP3430_PER_MOD, + OMAP3430_CM_SLEEPDEP); + cm_write_mod_reg(prcm_sleep_save[61], OMAP3430ES2_USBHOST_MOD, + OMAP3430_CM_SLEEPDEP); + __raw_writel(prcm_sleep_save[62], OMAP3430_CM_CLKOUT_CTRL); + __raw_writel(prcm_sleep_save[63], OMAP3430_PRM_CLKOUT_CTRL); + prm_write_mod_reg(prcm_sleep_save[64], OMAP3430ES2_SGX_MOD, PM_WKDEP); + prm_write_mod_reg(prcm_sleep_save[65], OMAP3430_DSS_MOD, PM_WKDEP); + prm_write_mod_reg(prcm_sleep_save[66], OMAP3430_CAM_MOD, PM_WKDEP); + prm_write_mod_reg(prcm_sleep_save[67], OMAP3430_PER_MOD, PM_WKDEP); + prm_write_mod_reg(prcm_sleep_save[68], OMAP3430_NEON_MOD, PM_WKDEP); + prm_write_mod_reg(prcm_sleep_save[69], OMAP3430ES2_USBHOST_MOD, + PM_WKDEP); + prm_write_mod_reg(prcm_sleep_save[70], CORE_MOD, + OMAP3430_PM_MPUGRPSEL1); + prm_write_mod_reg(prcm_sleep_save[71], OMAP3430_IVA2_MOD, + OMAP3430_PM_IVAGRPSEL1); + prm_write_mod_reg(prcm_sleep_save[72], CORE_MOD, + OMAP3430ES2_PM_MPUGRPSEL3); + prm_write_mod_reg(prcm_sleep_save[73], CORE_MOD, + OMAP3430ES2_PM_IVAGRPSEL3); + prm_write_mod_reg(prcm_sleep_save[74], WKUP_MOD, + OMAP3430_PM_MPUGRPSEL); + prm_write_mod_reg(prcm_sleep_save[75], WKUP_MOD, + OMAP3430_PM_IVAGRPSEL); + prm_write_mod_reg(prcm_sleep_save[76], OMAP3430_PER_MOD, + OMAP3430_PM_MPUGRPSEL); + prm_write_mod_reg(prcm_sleep_save[77], OMAP3430_PER_MOD, + OMAP3430_PM_IVAGRPSEL); + prm_write_mod_reg(prcm_sleep_save[78], WKUP_MOD, PM_WKEN); + return; +} + +static void omap_save_intc_ctx(void) +{ + int ind = 0; + intc_context.sysconfig = omap_readl(INTCPS_SYSCONFIG); + intc_context.protection = omap_readl(INTCPS_PROTECTION); + intc_context.idle = omap_readl(INTCPS_IDLE); + intc_context.threshold = omap_readl(INTCPS_THRESHOLD); + for (ind = 0; ind < 96; ind++) + intc_context.ilr[ind] = + omap_readl(INTC_BASE + (0x100 + 0x4*ind)); + /* MIRs are saved and restore with other PRCM registers */ +} + +static void omap_restore_intc_ctx(void) +{ + int ind = 0; + omap_writel(intc_context.sysconfig, INTCPS_SYSCONFIG); + omap_writel(intc_context.protection, INTCPS_PROTECTION); + omap_writel(intc_context.idle, INTCPS_IDLE); + omap_writel(intc_context.threshold, INTCPS_THRESHOLD); + for (ind = 0; ind < 96; ind++) + omap_writel(intc_context.ilr[ind], + INTC_BASE + (0x100 + 0x4*ind)); + /* MIRs are saved and restore with other PRCM registers */ +} + +static void omap_save_control_ctx(void) +{ + control_ctx.sysconfig = omap_ctrl_readl(OMAP2_CONTROL_SYSCONFIG); + control_ctx.devconf0 = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); + control_ctx.mem_dftrw0 = omap_ctrl_readl(OMAP343X_CONTROL_MEM_DFTRW0); + control_ctx.mem_dftrw1 = omap_ctrl_readl(OMAP343X_CONTROL_MEM_DFTRW1); + control_ctx.msuspendmux_0 = + omap_ctrl_readl(OMAP2_CONTROL_MSUSPENDMUX_0); + control_ctx.msuspendmux_1 = + omap_ctrl_readl(OMAP2_CONTROL_MSUSPENDMUX_1); + control_ctx.msuspendmux_2 = + omap_ctrl_readl(OMAP2_CONTROL_MSUSPENDMUX_2); + control_ctx.msuspendmux_3 = + omap_ctrl_readl(OMAP2_CONTROL_MSUSPENDMUX_3); + control_ctx.msuspendmux_4 = + omap_ctrl_readl(OMAP2_CONTROL_MSUSPENDMUX_4); + control_ctx.msuspendmux_5 = + omap_ctrl_readl(OMAP2_CONTROL_MSUSPENDMUX_5); + control_ctx.sec_ctrl = omap_ctrl_readl(OMAP2_CONTROL_SEC_CTRL); + control_ctx.devconf1 = omap_ctrl_readl(OMAP343X_CONTROL_DEVCONF1); + control_ctx.csirxfe = omap_ctrl_readl(OMAP343X_CONTROL_CSIRXFE); + control_ctx.iva2_bootaddr = + omap_ctrl_readl(OMAP343X_CONTROL_IVA2_BOOTADDR); + control_ctx.iva2_bootmod = + omap_ctrl_readl(OMAP343X_CONTROL_IVA2_BOOTMOD); + control_ctx.debobs_0 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS_0); + control_ctx.debobs_1 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS_1); + control_ctx.debobs_2 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS_2); + control_ctx.debobs_3 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS_3); + control_ctx.debobs_4 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS_4); + control_ctx.debobs_5 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS_5); + control_ctx.debobs_6 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS_6); + control_ctx.debobs_7 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS_7); + control_ctx.debobs_8 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS_8); + control_ctx.prog_io0 = omap_ctrl_readl(OMAP343X_CONTROL_PROG_IO0); + control_ctx.prog_io1 = omap_ctrl_readl(OMAP343X_CONTROL_PROG_IO1); + control_ctx.dss_dpll_spreading = + omap_ctrl_readl(OMAP343X_CONTROL_DSS_DPLL_SPREADING); + control_ctx.core_dpll_spreading = + omap_ctrl_readl(OMAP343X_CONTROL_CORE_DPLL_SPREADING); + control_ctx.per_dpll_spreading = + omap_ctrl_readl(OMAP343X_CONTROL_PER_DPLL_SPREADING); + control_ctx.usbhost_dpll_spreading = + omap_ctrl_readl(OMAP343X_CONTROL_USBHOST_DPLL_SPREADING); + control_ctx.pbias_lite = omap_ctrl_readl(OMAP343X_CONTROL_PBIAS_LITE); + control_ctx.temp_sensor = omap_ctrl_readl(OMAP343X_CONTROL_TEMP_SENSOR); + control_ctx.sramldo4 = omap_ctrl_readl(OMAP343X_CONTROL_SRAMLDO4); + control_ctx.sramldo5 = omap_ctrl_readl(OMAP343X_CONTROL_SRAMLDO5); + control_ctx.csi = omap_ctrl_readl(OMAP343X_CONTROL_CSI); + return; +} + +static void omap_restore_control_ctx(void) +{ + omap_ctrl_writel(control_ctx.sysconfig, OMAP2_CONTROL_SYSCONFIG); + omap_ctrl_writel(control_ctx.devconf0, OMAP2_CONTROL_DEVCONF0); + omap_ctrl_writel(control_ctx.mem_dftrw0, OMAP343X_CONTROL_MEM_DFTRW0); + omap_ctrl_writel(control_ctx.mem_dftrw1, OMAP343X_CONTROL_MEM_DFTRW1); + omap_ctrl_writel(control_ctx.msuspendmux_0, + OMAP2_CONTROL_MSUSPENDMUX_0); + omap_ctrl_writel(control_ctx.msuspendmux_1, + OMAP2_CONTROL_MSUSPENDMUX_1); + omap_ctrl_writel(control_ctx.msuspendmux_2, + OMAP2_CONTROL_MSUSPENDMUX_2); + omap_ctrl_writel(control_ctx.msuspendmux_3, + OMAP2_CONTROL_MSUSPENDMUX_3); + omap_ctrl_writel(control_ctx.msuspendmux_4, + OMAP2_CONTROL_MSUSPENDMUX_4); + omap_ctrl_writel(control_ctx.msuspendmux_5, + OMAP2_CONTROL_MSUSPENDMUX_5); + omap_ctrl_writel(control_ctx.sec_ctrl, OMAP2_CONTROL_SEC_CTRL); + omap_ctrl_writel(control_ctx.devconf1, OMAP343X_CONTROL_DEVCONF1); + omap_ctrl_writel(control_ctx.csirxfe, OMAP343X_CONTROL_CSIRXFE); + omap_ctrl_writel(control_ctx.iva2_bootaddr, + OMAP343X_CONTROL_IVA2_BOOTADDR); + omap_ctrl_writel(control_ctx.iva2_bootmod, + OMAP343X_CONTROL_IVA2_BOOTMOD); + omap_ctrl_writel(control_ctx.debobs_0, OMAP343X_CONTROL_DEBOBS_0); + omap_ctrl_writel(control_ctx.debobs_1, OMAP343X_CONTROL_DEBOBS_1); + omap_ctrl_writel(control_ctx.debobs_2, OMAP343X_CONTROL_DEBOBS_2); + omap_ctrl_writel(control_ctx.debobs_3, OMAP343X_CONTROL_DEBOBS_3); + omap_ctrl_writel(control_ctx.debobs_4, OMAP343X_CONTROL_DEBOBS_4); + omap_ctrl_writel(control_ctx.debobs_5, OMAP343X_CONTROL_DEBOBS_5); + omap_ctrl_writel(control_ctx.debobs_6, OMAP343X_CONTROL_DEBOBS_6); + omap_ctrl_writel(control_ctx.debobs_7, OMAP343X_CONTROL_DEBOBS_7); + omap_ctrl_writel(control_ctx.debobs_8, OMAP343X_CONTROL_DEBOBS_8); + omap_ctrl_writel(control_ctx.prog_io0, OMAP343X_CONTROL_PROG_IO0); + omap_ctrl_writel(control_ctx.prog_io1, OMAP343X_CONTROL_PROG_IO1); + omap_ctrl_writel(control_ctx.dss_dpll_spreading, + OMAP343X_CONTROL_DSS_DPLL_SPREADING); + omap_ctrl_writel(control_ctx.core_dpll_spreading, + OMAP343X_CONTROL_CORE_DPLL_SPREADING); + omap_ctrl_writel(control_ctx.per_dpll_spreading, + OMAP343X_CONTROL_PER_DPLL_SPREADING); + omap_ctrl_writel(control_ctx.usbhost_dpll_spreading, + OMAP343X_CONTROL_USBHOST_DPLL_SPREADING); + omap_ctrl_writel(control_ctx.pbias_lite, OMAP343X_CONTROL_PBIAS_LITE); + omap_ctrl_writel(control_ctx.temp_sensor, OMAP343X_CONTROL_TEMP_SENSOR); + omap_ctrl_writel(control_ctx.sramldo4, OMAP343X_CONTROL_SRAMLDO4); + omap_ctrl_writel(control_ctx.sramldo5, OMAP343X_CONTROL_SRAMLDO5); + omap_ctrl_writel(control_ctx.csi, OMAP343X_CONTROL_CSI); + return; +} + +void omap3_save_core_ctx(void) +{ + u32 control_padconf_off; + + if (!padconf_saved) { + /* Save the padconf registers */ + control_padconf_off = omap_readl(CONTROL_PADCONF_OFF); + control_padconf_off |= 2; + omap_writel(control_padconf_off, CONTROL_PADCONF_OFF); + /* wait for the save to complete */ + while (!omap_readl(CONTROL_GENERAL_PURPOSE_STATUS) & 0x1); + padconf_saved = 1; + } + /* Save the Interrupt controller context */ + omap_save_intc_ctx(); + /* Save the GPMC context */ + omap_save_gpmc_ctx(); + /* Save the system control module context, padconf already save above*/ + omap_save_control_ctx(); +} + +void omap3_restore_core_ctx(void) +{ + /* Restore the control module context, padconf restored by h/w */ + omap_restore_control_ctx(); + /* Restore the GPMC context */ + omap_restore_gpmc_ctx(); + /* Restore the interrupt controller context */ + omap_restore_intc_ctx(); + padconf_saved = 0; +} #ifdef CONFIG_CPU_IDLE @@ -42,6 +417,8 @@ static int omap3_idle_bm_check(void) return 0; } + +int set_pwrdm_state(struct powerdomain *pwrdm, u32 state); /* omap3_enter_idle - Programs OMAP3 to enter the specified state. * returns the total time during which the system was idle. */ @@ -50,8 +427,7 @@ static int omap3_enter_idle(struct cpuidle_device *dev, { struct omap3_processor_cx *cx = cpuidle_get_statedata(state); struct timespec ts_preidle, ts_postidle, ts_idle; - struct powerdomain *mpu_pd, *core_pd, *per_pd, *neon_pd; - int per_pwrst, neon_pwrst; + struct powerdomain *mpu_pd, *core_pd; current_cx_state = *cx; @@ -60,79 +436,37 @@ static int omap3_enter_idle(struct cpuidle_device *dev, return 0; } + local_irq_disable(); + local_fiq_disable(); + /* Used to keep track of the total time in idle */ getnstimeofday(&ts_preidle); + if (cx->type > OMAP3_STATE_C1) + sched_clock_idle_sleep_event(); /* about to enter deep idle */ + mpu_pd = pwrdm_lookup("mpu_pwrdm"); core_pd = pwrdm_lookup("core_pwrdm"); - per_pd = pwrdm_lookup("per_pwrdm"); - neon_pd = pwrdm_lookup("neon_pwrdm"); - /* Reset previous power state registers */ - pwrdm_clear_all_prev_pwrst(mpu_pd); - pwrdm_clear_all_prev_pwrst(neon_pd); - pwrdm_clear_all_prev_pwrst(core_pd); - pwrdm_clear_all_prev_pwrst(per_pd); + set_pwrdm_state(mpu_pd, cx->mpu_state); + set_pwrdm_state(core_pd, cx->core_state); if (omap_irq_pending()) - return 0; - - per_pwrst = pwrdm_read_pwrst(per_pd); - neon_pwrst = pwrdm_read_pwrst(neon_pd); - - /* Program MPU to target state */ - if (cx->mpu_state < PWRDM_POWER_ON) { - if (neon_pwrst == PWRDM_POWER_ON) { - if (cx->mpu_state == PWRDM_POWER_RET) - pwrdm_set_next_pwrst(neon_pd, PWRDM_POWER_RET); - else if (cx->mpu_state == PWRDM_POWER_OFF) - pwrdm_set_next_pwrst(neon_pd, PWRDM_POWER_OFF); - } - pwrdm_set_next_pwrst(mpu_pd, cx->mpu_state); - } - - /* Program CORE and PER to target state */ - if (cx->core_state < PWRDM_POWER_ON) { - if (per_pwrst == PWRDM_POWER_ON) { - omap2_gpio_prepare_for_retention(); - per_gpio_clk_disable(); - omap_serial_enable_clocks(0); - } - pwrdm_set_next_pwrst(core_pd, cx->core_state); - } - - *(scratchpad_restore_addr) = restore_pointer_address; + goto return_sleep_time; /* Execute ARM wfi */ omap_sram_idle(); - *(scratchpad_restore_addr) = 0x0; - - /* Program MPU/NEON to ON */ - if (cx->mpu_state < PWRDM_POWER_ON) { - if (neon_pwrst == PWRDM_POWER_ON) - pwrdm_set_next_pwrst(neon_pd, PWRDM_POWER_ON); - pwrdm_set_next_pwrst(mpu_pd, PWRDM_POWER_ON); - } +return_sleep_time: + getnstimeofday(&ts_postidle); + ts_idle = timespec_sub(ts_postidle, ts_preidle); - if (cx->core_state < PWRDM_POWER_ON) { - if (per_pwrst == PWRDM_POWER_ON) { - omap_serial_enable_clocks(1); - per_gpio_clk_enable(); - omap2_gpio_resume_after_retention(); - } - pwrdm_set_next_pwrst(core_pd, PWRDM_POWER_ON); - } + if (cx->type > OMAP3_STATE_C1) + sched_clock_idle_wakeup_event(timespec_to_ns(&ts_idle)); - pr_debug("MPU prev st:%x,NEON prev st:%x\n", - pwrdm_read_prev_pwrst(mpu_pd), - pwrdm_read_prev_pwrst(neon_pd)); - pr_debug("PER prev st:%x,CORE prev st:%x\n", - pwrdm_read_prev_pwrst(per_pd), - pwrdm_read_prev_pwrst(core_pd)); + local_irq_enable(); + local_fiq_enable(); - getnstimeofday(&ts_postidle); - ts_idle = timespec_sub(ts_postidle, ts_preidle); return (u32)timespec_to_ns(&ts_idle)/1000; } @@ -143,25 +477,28 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev, int i, j; if ((state->flags & CPUIDLE_FLAG_CHECK_BM) && omap3_idle_bm_check()) { - - /* Find current state in list */ - for (i = 0; i < OMAP3_MAX_STATES; i++) - if (state == &dev->states[i]) - break; - BUG_ON(i == OMAP3_MAX_STATES); - - /* Back up to non 'CHECK_BM' state */ - for (j = i - 1; j > 0; j--) { - struct cpuidle_state *s = &dev->states[j]; - - if (!(s->flags & CPUIDLE_FLAG_CHECK_BM)) { - new_state = s; - break; + if (dev->safe_state) + return dev->safe_state->enter(dev, dev->safe_state); + else { + /* Find current state in list */ + for (i = 0; i < OMAP3_MAX_STATES; i++) + if (state == &dev->states[i]) + break; + BUG_ON(i == OMAP3_MAX_STATES); + + /* Back up to non 'CHECK_BM' state */ + for (j = i - 1; j >= 0; j--) { + struct cpuidle_state *s = &dev->states[j]; + + if (!(s->flags & CPUIDLE_FLAG_CHECK_BM)) { + new_state = s; + break; + } } + pr_debug("%s: Bus activity: Entering %s\ + (instead of %s)\n", __func__, + new_state->name, state->name); } - - pr_debug("%s: Bus activity: Entering %s (instead of %s)\n", - __func__, new_state->name, state->name); } return omap3_enter_idle(dev, new_state ? : state); @@ -183,79 +520,79 @@ DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev); void omap_init_power_states(void) { /* C0 . System executing code */ - omap3_power_states[0].valid = 1; - omap3_power_states[0].type = OMAP3_STATE_C0; - omap3_power_states[0].sleep_latency = 0; - omap3_power_states[0].wakeup_latency = 0; - omap3_power_states[0].threshold = 0; - omap3_power_states[0].mpu_state = PWRDM_POWER_ON; - omap3_power_states[0].core_state = PWRDM_POWER_ON; - omap3_power_states[0].flags = CPUIDLE_FLAG_SHALLOW; + omap3_power_states[OMAP3_STATE_C0].valid = 1; + omap3_power_states[OMAP3_STATE_C0].type = OMAP3_STATE_C0; + omap3_power_states[OMAP3_STATE_C0].sleep_latency = 0; + omap3_power_states[OMAP3_STATE_C0].wakeup_latency = 0; + omap3_power_states[OMAP3_STATE_C0].threshold = 0; + omap3_power_states[OMAP3_STATE_C0].mpu_state = PWRDM_POWER_ON; + omap3_power_states[OMAP3_STATE_C0].core_state = PWRDM_POWER_ON; + omap3_power_states[OMAP3_STATE_C0].flags = CPUIDLE_FLAG_SHALLOW; /* C1 . MPU WFI + Core active */ - omap3_power_states[1].valid = 1; - omap3_power_states[1].type = OMAP3_STATE_C1; - omap3_power_states[1].sleep_latency = 10; - omap3_power_states[1].wakeup_latency = 10; - omap3_power_states[1].threshold = 30; - omap3_power_states[1].mpu_state = PWRDM_POWER_ON; - omap3_power_states[1].core_state = PWRDM_POWER_ON; - omap3_power_states[1].flags = CPUIDLE_FLAG_TIME_VALID | + omap3_power_states[OMAP3_STATE_C1].valid = 1; + omap3_power_states[OMAP3_STATE_C1].type = OMAP3_STATE_C1; + omap3_power_states[OMAP3_STATE_C1].sleep_latency = 10; + omap3_power_states[OMAP3_STATE_C1].wakeup_latency = 10; + omap3_power_states[OMAP3_STATE_C1].threshold = 30; + omap3_power_states[OMAP3_STATE_C1].mpu_state = PWRDM_POWER_ON; + omap3_power_states[OMAP3_STATE_C1].core_state = PWRDM_POWER_ON; + omap3_power_states[OMAP3_STATE_C1].flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_SHALLOW; /* C2 . MPU CSWR + Core active */ - omap3_power_states[2].valid = 1; - omap3_power_states[2].type = OMAP3_STATE_C2; - omap3_power_states[2].sleep_latency = 50; - omap3_power_states[2].wakeup_latency = 50; - omap3_power_states[2].threshold = 300; - omap3_power_states[2].mpu_state = PWRDM_POWER_RET; - omap3_power_states[2].core_state = PWRDM_POWER_ON; - omap3_power_states[2].flags = CPUIDLE_FLAG_TIME_VALID | + omap3_power_states[OMAP3_STATE_C2].valid = 1; + omap3_power_states[OMAP3_STATE_C2].type = OMAP3_STATE_C2; + omap3_power_states[OMAP3_STATE_C2].sleep_latency = 50; + omap3_power_states[OMAP3_STATE_C2].wakeup_latency = 50; + omap3_power_states[OMAP3_STATE_C2].threshold = 300; + omap3_power_states[OMAP3_STATE_C2].mpu_state = PWRDM_POWER_RET; + omap3_power_states[OMAP3_STATE_C2].core_state = PWRDM_POWER_ON; + omap3_power_states[OMAP3_STATE_C2].flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_BALANCED; /* C3 . MPU OFF + Core active */ - omap3_power_states[3].valid = 1; - omap3_power_states[3].type = OMAP3_STATE_C3; - omap3_power_states[3].sleep_latency = 1500; - omap3_power_states[3].wakeup_latency = 1800; - omap3_power_states[3].threshold = 4000; - omap3_power_states[3].mpu_state = PWRDM_POWER_OFF; - omap3_power_states[3].core_state = PWRDM_POWER_ON; - omap3_power_states[3].flags = CPUIDLE_FLAG_TIME_VALID | - CPUIDLE_FLAG_BALANCED | CPUIDLE_FLAG_CHECK_BM; + omap3_power_states[OMAP3_STATE_C3].valid = 1; + omap3_power_states[OMAP3_STATE_C3].type = OMAP3_STATE_C3; + omap3_power_states[OMAP3_STATE_C3].sleep_latency = 1500; + omap3_power_states[OMAP3_STATE_C3].wakeup_latency = 1800; + omap3_power_states[OMAP3_STATE_C3].threshold = 4000; + omap3_power_states[OMAP3_STATE_C3].mpu_state = PWRDM_POWER_OFF; + omap3_power_states[OMAP3_STATE_C3].core_state = PWRDM_POWER_ON; + omap3_power_states[OMAP3_STATE_C3].flags = CPUIDLE_FLAG_TIME_VALID | + CPUIDLE_FLAG_BALANCED; /* C4 . MPU CSWR + Core CSWR*/ - omap3_power_states[4].valid = 1; - omap3_power_states[4].type = OMAP3_STATE_C4; - omap3_power_states[4].sleep_latency = 2500; - omap3_power_states[4].wakeup_latency = 7500; - omap3_power_states[4].threshold = 12000; - omap3_power_states[4].mpu_state = PWRDM_POWER_RET; - omap3_power_states[4].core_state = PWRDM_POWER_RET; - omap3_power_states[4].flags = CPUIDLE_FLAG_TIME_VALID | + omap3_power_states[OMAP3_STATE_C4].valid = 1; + omap3_power_states[OMAP3_STATE_C4].type = OMAP3_STATE_C4; + omap3_power_states[OMAP3_STATE_C4].sleep_latency = 2500; + omap3_power_states[OMAP3_STATE_C4].wakeup_latency = 7500; + omap3_power_states[OMAP3_STATE_C4].threshold = 12000; + omap3_power_states[OMAP3_STATE_C4].mpu_state = PWRDM_POWER_RET; + omap3_power_states[OMAP3_STATE_C4].core_state = PWRDM_POWER_RET; + omap3_power_states[OMAP3_STATE_C4].flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_BALANCED | CPUIDLE_FLAG_CHECK_BM; /* C5 . MPU OFF + Core CSWR */ - omap3_power_states[5].valid = 1; - omap3_power_states[5].type = OMAP3_STATE_C5; - omap3_power_states[5].sleep_latency = 3000; - omap3_power_states[5].wakeup_latency = 8500; - omap3_power_states[5].threshold = 15000; - omap3_power_states[5].mpu_state = PWRDM_POWER_OFF; - omap3_power_states[5].core_state = PWRDM_POWER_RET; - omap3_power_states[5].flags = CPUIDLE_FLAG_TIME_VALID | + omap3_power_states[OMAP3_STATE_C5].valid = 1; + omap3_power_states[OMAP3_STATE_C5].type = OMAP3_STATE_C5; + omap3_power_states[OMAP3_STATE_C5].sleep_latency = 3000; + omap3_power_states[OMAP3_STATE_C5].wakeup_latency = 8500; + omap3_power_states[OMAP3_STATE_C5].threshold = 15000; + omap3_power_states[OMAP3_STATE_C5].mpu_state = PWRDM_POWER_OFF; + omap3_power_states[OMAP3_STATE_C5].core_state = PWRDM_POWER_RET; + omap3_power_states[OMAP3_STATE_C5].flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_BALANCED | CPUIDLE_FLAG_CHECK_BM; /* C6 . MPU OFF + Core OFF */ - omap3_power_states[6].valid = 0; - omap3_power_states[6].type = OMAP3_STATE_C6; - omap3_power_states[6].sleep_latency = 10000; - omap3_power_states[6].wakeup_latency = 30000; - omap3_power_states[6].threshold = 300000; - omap3_power_states[6].mpu_state = PWRDM_POWER_OFF; - omap3_power_states[6].core_state = PWRDM_POWER_OFF; - omap3_power_states[6].flags = CPUIDLE_FLAG_TIME_VALID | + omap3_power_states[OMAP3_STATE_C6].valid = 1; + omap3_power_states[OMAP3_STATE_C6].type = OMAP3_STATE_C6; + omap3_power_states[OMAP3_STATE_C6].sleep_latency = 10000; + omap3_power_states[OMAP3_STATE_C6].wakeup_latency = 30000; + omap3_power_states[OMAP3_STATE_C6].threshold = 300000; + omap3_power_states[OMAP3_STATE_C6].mpu_state = PWRDM_POWER_OFF; + omap3_power_states[OMAP3_STATE_C6].core_state = PWRDM_POWER_OFF; + omap3_power_states[OMAP3_STATE_C6].flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_DEEP | CPUIDLE_FLAG_CHECK_BM; } @@ -273,6 +610,7 @@ int omap3_idle_init(void) struct omap3_processor_cx *cx; struct cpuidle_state *state; struct cpuidle_device *dev; + char clk_name[11]; clear_scratchpad_contents(); save_scratchpad_contents(); @@ -294,6 +632,8 @@ int omap3_idle_init(void) state->flags = cx->flags; state->enter = (state->flags & CPUIDLE_FLAG_CHECK_BM) ? omap3_enter_idle_bm : omap3_enter_idle; + if (cx->type == OMAP3_STATE_C1) + dev->safe_state = state; sprintf(state->name, "C%d", count+1); count++; } diff --git a/arch/arm/mach-omap2/cpuidle34xx.h b/arch/arm/mach-omap2/cpuidle34xx.h index f2ebe68..a2036cf 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.h +++ b/arch/arm/mach-omap2/cpuidle34xx.h @@ -30,20 +30,42 @@ #define OMAP3_STATE_C5 5 /* C5 - MPU OFF + Core RET */ #define OMAP3_STATE_C6 6 /* C6 - MPU OFF + Core OFF */ -/* Currently, we support only upto C2 */ -#define MAX_SUPPORTED_STATES 3 +/* Interrupt Controller registers */ +#define INTC_BASE 0x48200000 +#define INTC_MIR_0 0x48200084 +#define INTC_MIR_1 0x482000A4 +#define INTC_MIR_2 0x482000C4 +#define INTCPS_SYSCONFIG 0x48200010 +#define INTCPS_PROTECTION 0x4820004C +#define INTCPS_IDLE 0x48200050 +#define INTCPS_THRESHOLD 0x48200068 + +#define CONTROL_PADCONF_SYS_NIRQ 0x480021E0 +#define CONTROL_PADCONF_OFF 0x48002270 +#define CONTROL_GENERAL_PURPOSE_STATUS 0x480022F4 + +#define OMAP34XX_GPIO1_IRQENABLE1 0x4831001c +#define OMAP34XX_GPIO1_WAKEUPEN 0x48310020 +#define OMAP34XX_GPIO1_FALLINGDETECT 0x4831004c extern unsigned short clocks_off_while_idle; extern void omap_sram_idle(void); extern int omap_irq_pending(void); extern void per_gpio_clk_enable(void); extern void per_gpio_clk_disable(void); -extern void omap_serial_enable_clocks(int enable); +extern void omap_serial_enable_clocks(int enable, int unum); extern int omap3_can_sleep(); extern void clear_scratchpad_contents(void); extern void save_scratchpad_contents(void); extern u32 *scratchpad_restore_addr; extern u32 restore_pointer_address; +extern void omap3_save_per_ctx(); +extern void omap3_restore_per_ctx(); +extern void omap_save_uart_ctx(int); +extern void omap_restore_uart_ctx(int); +extern void omap3_restore_sram_ctx(); +extern int omap3_can_sleep(); +extern int omap_serial_can_sleep(); struct omap3_processor_cx { u8 valid; @@ -59,5 +81,10 @@ struct omap3_processor_cx { void omap_init_power_states(void); int omap3_idle_init(void); +/* TODO fix the size:100 */ +static unsigned int prcm_sleep_save[100]; +static struct int_controller_context intc_context; +static struct control_module_context control_ctx; + #endif /* ARCH_ARM_MACH_OMAP2_CPUIDLE_34XX */ diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index acfca0b..da6eae1 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -65,6 +65,20 @@ static void (*_omap_sram_idle)(u32 *addr, int save_state); static void (*saved_idle)(void); static struct powerdomain *mpu_pwrdm; +static struct powerdomain *neon_pwrdm, *per_pwrdm; +static struct powerdomain *core_pwrdm; + +void omap3_save_per_ctx(void); +void omap3_restore_per_ctx(void); +void omap3_save_core_ctx(void); +void omap3_restore_core_ctx(void); +void omap3_save_sram_ctx(void); +void omap3_restore_sram_ctx(void); +void omap3_save_prcm_ctx(void); +void omap3_restore_prcm_ctx(void); +void omap_save_uart_ctx(int unum); +void omap_restore_uart_ctx(int unum); +int set_pwrdm_state(struct powerdomain *pwrdm, u32 state); /* Dynamic GPIO clock handling for sleep routines. * omap_sram_idle() will call these functions and they will dynamically @@ -163,7 +177,6 @@ static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id) cm_write_mod_reg(iclk, OMAP3430_PER_MOD, CM_ICLKEN); cm_write_mod_reg(fclk, OMAP3430_PER_MOD, CM_FCLKEN); } - if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0)) { /* USBHOST */ wkst = prm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, PM_WKST); @@ -234,11 +247,19 @@ void omap_sram_idle(void) /* save_state = 1 => Only L1 and logic lost */ /* save_state = 2 => Only L2 lost */ /* save_state = 3 => L1, L2 and logic lost */ - int save_state = 0, mpu_next_state; + int save_state = 0; + int mpu_next_state = PWRDM_POWER_ON, core_next_state = PWRDM_POWER_ON, + per_next_state = PWRDM_POWER_ON; + int mpu_prev_state, core_prev_state, per_prev_state; if (!_omap_sram_idle) return; + pwrdm_clear_all_prev_pwrst(mpu_pwrdm); + pwrdm_clear_all_prev_pwrst(neon_pwrdm); + pwrdm_clear_all_prev_pwrst(core_pwrdm); + pwrdm_clear_all_prev_pwrst(per_pwrdm); + mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm); switch (mpu_next_state) { case PWRDM_POWER_ON: @@ -257,11 +278,76 @@ void omap_sram_idle(void) pm_dbg_pre_suspend(); + /* NEON control */ + if (pwrdm_read_pwrst(neon_pwrdm) == PWRDM_POWER_ON) + set_pwrdm_state(neon_pwrdm, mpu_next_state); + + /* CORE & PER */ + core_next_state = pwrdm_read_next_pwrst(core_pwrdm); + if (core_next_state < PWRDM_POWER_ON) { + omap2_gpio_prepare_for_retention(); + /* PER changes only with core */ + per_next_state = pwrdm_read_next_pwrst(per_pwrdm); + if (per_next_state < PWRDM_POWER_ON) { + if (per_next_state == PWRDM_POWER_OFF) { + omap3_save_per_ctx(); + omap_save_uart_ctx(2); + } + per_gpio_clk_disable(); + omap_serial_enable_clocks(0, 2); + } + if (core_next_state == PWRDM_POWER_OFF) { + omap3_save_core_ctx(); + omap3_save_prcm_ctx(); + omap_save_uart_ctx(0); + omap_save_uart_ctx(1); + } + omap_serial_enable_clocks(0, 0); + omap_serial_enable_clocks(0, 1); + if (core_next_state == PWRDM_POWER_OFF) + omap3_save_prcm_ctx(); + /* Enable IO-PAD wakeup */ + prm_set_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN); + } + + *(scratchpad_restore_addr) = restore_pointer_address; + _omap_sram_idle(context_mem, save_state); + + *(scratchpad_restore_addr) = 0x0; + /* Restore table entry modified during MMU restoration */ if (pwrdm_read_prev_pwrst(mpu_pwrdm) == 0x0) restore_table_entry(); + if (core_next_state < PWRDM_POWER_ON) { + /* Disable IO-PAD wakeup */ + prm_clear_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN); + core_prev_state = pwrdm_read_prev_pwrst(core_pwrdm); + if (core_prev_state == PWRDM_POWER_OFF) + omap3_restore_prcm_ctx(); + omap_serial_enable_clocks(1, 0); + omap_serial_enable_clocks(1, 1); + if (core_prev_state == PWRDM_POWER_OFF) { + omap3_restore_core_ctx(); + omap3_restore_sram_ctx(); + omap_restore_uart_ctx(0); + omap_restore_uart_ctx(1); + } + if (per_next_state < PWRDM_POWER_ON) { + per_gpio_clk_enable(); + /* This would be actually more effective */ + omap_serial_enable_clocks(1, 2); + per_prev_state = pwrdm_read_prev_pwrst(per_pwrdm); + if (per_prev_state == PWRDM_POWER_OFF) { + omap3_restore_per_ctx(); + /* This would be actually more effective */ + omap_restore_uart_ctx(2); + } + } + omap2_gpio_resume_after_retention(); + } + pm_dbg_post_suspend(); } @@ -394,12 +480,16 @@ static void omap3_pm_idle(void) omap2_gpio_prepare_for_retention(); - omap_serial_enable_clocks(0); + omap_serial_enable_clocks(0, 0); + omap_serial_enable_clocks(0, 1); + omap_serial_enable_clocks(0, 2); per_gpio_clk_disable(); omap_sram_idle(); - omap_serial_enable_clocks(1); + omap_serial_enable_clocks(1, 0); + omap_serial_enable_clocks(1, 1); + omap_serial_enable_clocks(1, 2); per_gpio_clk_enable(); omap2_gpio_resume_after_retention(); @@ -437,12 +527,16 @@ static int omap3_pm_suspend(void) omap2_gpio_prepare_for_retention(); - omap_serial_enable_clocks(0); + omap_serial_enable_clocks(0, 0); + omap_serial_enable_clocks(0, 1); + omap_serial_enable_clocks(0, 2); per_gpio_clk_disable(); omap_sram_idle(); - omap_serial_enable_clocks(1); + omap_serial_enable_clocks(1, 0); + omap_serial_enable_clocks(1, 1); + omap_serial_enable_clocks(1, 2); per_gpio_clk_enable(); omap2_gpio_resume_after_retention(); @@ -653,6 +747,16 @@ static void __init prcm_setup_regs(void) OCP_MOD, OMAP2_PRM_IRQENABLE_MPU_OFFSET); } +void omap3_save_per_ctx(void) +{ + omap_gpio_save(); +} + +void omap3_restore_per_ctx(void) +{ + omap_gpio_restore(); +} + static struct power_state *get_pwrst_node(const char *name) { struct powerdomain *pwrdm; @@ -722,8 +826,10 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm) if (!pwrst) return -ENOMEM; pwrst->pwrdm = pwrdm; - if (!strcmp(pwrst->pwrdm->name, "core_pwrdm")) - pwrst->next_state = PWRDM_POWER_RET; + if (!strcmp(pwrst->pwrdm->name, "core_pwrdm") || + !strcmp(pwrst->pwrdm->name, "mpu_pwrdm") || + !strcmp(pwrst->pwrdm->name, "mpu_pwrdm")) + pwrst->next_state = PWRDM_POWER_ON; else pwrst->next_state = PWRDM_POWER_OFF; list_add(&pwrst->node, &pwrst_list); @@ -746,6 +852,12 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm) return set_pwrdm_state(pwrst->pwrdm, pwrst->next_state); } +void omap_push_sram_idle() +{ + _omap_sram_idle = omap_sram_push(omap34xx_cpu_suspend, + omap34xx_cpu_suspend_sz); +} + int __init omap3_pm_init(void) { struct power_state *pwrst; @@ -757,6 +869,7 @@ int __init omap3_pm_init(void) /* XXX prcm_setup_regs needs to be before enabling hw * supervised mode for powerdomains */ prcm_setup_regs(); + save_scratchpad_contents(); ret = request_irq(INT_34XX_PRCM_MPU_IRQ, (irq_handler_t)prcm_interrupt_handler, @@ -784,10 +897,11 @@ int __init omap3_pm_init(void) printk(KERN_ERR "Failed to get mpu_pwrdm\n"); goto err2; } + neon_pwrdm = pwrdm_lookup("neon_pwrdm"); + per_pwrdm = pwrdm_lookup("per_pwrdm"); + core_pwrdm = pwrdm_lookup("core_pwrdm"); - _omap_sram_idle = omap_sram_push(omap34xx_cpu_suspend, - omap34xx_cpu_suspend_sz); - + omap_push_sram_idle(); suspend_set_ops(&omap_pm_ops); #ifndef CONFIG_CPU_IDLE @@ -801,6 +915,9 @@ int __init omap3_pm_init(void) gpio_fcks[i-1] = clk_get(NULL, clk_name); } + pwrdm_add_wkdep(neon_pwrdm, mpu_pwrdm); + pwrdm_add_wkdep(per_pwrdm, core_pwrdm); + err1: return ret; err2: @@ -878,8 +995,11 @@ void save_scratchpad_contents(void) *(scratchpad_address++) = __raw_readl(OMAP3430_PRM_CLKSEL); *(scratchpad_address++) = cm_read_mod_reg(CORE_MOD, CM_CLKSEL); *(scratchpad_address++) = cm_read_mod_reg(WKUP_MOD, CM_CLKSEL); + /* TODO OMAP3430_CM_CLKEN_PLL is defined 0x4 */ + /**(scratchpad_address++) = cm_read_mod_reg(PLL_MOD, + OMAP3430_CM_CLKEN_PLL);*/ *(scratchpad_address++) = cm_read_mod_reg(PLL_MOD, - OMAP3430_CM_CLKEN_PLL); + 0x0); *(scratchpad_address++) = cm_read_mod_reg(PLL_MOD, OMAP3430_CM_AUTOIDLE_PLL); *(scratchpad_address++) = cm_read_mod_reg(PLL_MOD, diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h index 3c6418e..a344e40 100644 --- a/arch/arm/mach-omap2/prm.h +++ b/arch/arm/mach-omap2/prm.h @@ -137,9 +137,11 @@ #define OMAP3430_PM_MPUGRPSEL 0x00a4 #define OMAP3430_PM_MPUGRPSEL1 OMAP3430_PM_MPUGRPSEL +#define OMAP3430ES2_PM_MPUGRPSEL3 0x00f8 #define OMAP3430_PM_IVAGRPSEL 0x00a8 #define OMAP3430_PM_IVAGRPSEL1 OMAP3430_PM_IVAGRPSEL +#define OMAP3430ES2_PM_IVAGRPSEL3 0x00f4 #define OMAP3430_PM_PREPWSTST 0x00e8 diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 879d7c1..c189cc9 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -157,20 +157,17 @@ static void omap_serial_kick(void) NSEC_PER_MSEC); } -void omap_serial_enable_clocks(int enable) +void omap_serial_enable_clocks(int enable, int unum) { - int i; if (uart_clocks_off_while_idle == 0) return; - for (i = 0; i < OMAP_MAX_NR_PORTS; i++) { - if (uart_ick[i] && uart_fck[i]) { - if (enable) { - clk_enable(uart_ick[i]); - clk_enable(uart_fck[i]); - } else { - clk_disable(uart_ick[i]); - clk_disable(uart_fck[i]); - } + if (uart_ick[unum] && uart_fck[unum]) { + if (enable) { + clk_enable(uart_ick[unum]); + clk_enable(uart_fck[unum]); + } else { + clk_disable(uart_ick[unum]); + clk_disable(uart_fck[unum]); } } } diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S index 7cce8ef..efafa7e 100644 --- a/arch/arm/mach-omap2/sleep34xx.S +++ b/arch/arm/mach-omap2/sleep34xx.S @@ -457,10 +457,12 @@ loop2: mov r9, r4 /* create working copy of max way size*/ loop3: - /* factor way and cache number into r11 */ - orr r11, r10, r9, lsl r5 - /* factor index number into r11 */ - orr r11, r11, r7, lsl r2 + orr r11, r10, r9, lsl r5 @ factor way and cache number into r11 + orr r11, r11, r7, lsl r2 @ factor index number into r11 + lsl r6, r9, r5 + orr r11, r10, r6 @ factor way and cache number into r11 + lsl r6, r7, r2 + orr r11, r11, r6 @ factor index number into r11 /*clean & invalidate by set/way */ mcr p15, 0, r11, c7, c10, 2 /* decrement the way*/ @@ -475,7 +477,7 @@ skip: cmp r3, r10 bgt loop1 finished: - /*swith back to cache level 0 */ + /*switch back to cache level 0 */ mov r10, #0 /* select current cache level in cssr */ mcr p15, 2, r10, c0, c0, 0 diff --git a/arch/arm/plat-omap/include/mach/common.h b/arch/arm/plat-omap/include/mach/common.h index 489add6..faba335 100644 --- a/arch/arm/plat-omap/include/mach/common.h +++ b/arch/arm/plat-omap/include/mach/common.h @@ -34,7 +34,7 @@ struct sys_timer; extern void omap_map_common_io(void); extern struct sys_timer omap_timer; extern void omap_serial_init(void); -extern void omap_serial_enable_clocks(int enable); +extern void omap_serial_enable_clocks(int enable, int unum); extern int omap_serial_can_sleep(void); extern void omap_gpio_save(void); extern void omap_gpio_restore(void); diff --git a/arch/arm/plat-omap/include/mach/control.h b/arch/arm/plat-omap/include/mach/control.h index 9ca0e08..ef8cf12 100644 --- a/arch/arm/plat-omap/include/mach/control.h +++ b/arch/arm/plat-omap/include/mach/control.h @@ -149,7 +149,27 @@ #define OMAP343X_CONTROL_FUSE_SR (OMAP2_CONTROL_GENERAL + 0x0130) #define OMAP343X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190) #define OMAP343X_CONTROL_IVA2_BOOTMOD (OMAP2_CONTROL_GENERAL + 0x0194) -#define OMAP343X_CONTROL_TEMP_SENSOR (OMAP2_CONTROL_GENERAL + 0x02b4) +#define OMAP343X_CONTROL_DEBOBS_0 (OMAP2_CONTROL_GENERAL + 0x01B0) +#define OMAP343X_CONTROL_DEBOBS_1 (OMAP2_CONTROL_GENERAL + 0x01B4) +#define OMAP343X_CONTROL_DEBOBS_2 (OMAP2_CONTROL_GENERAL + 0x01B8) +#define OMAP343X_CONTROL_DEBOBS_3 (OMAP2_CONTROL_GENERAL + 0x01BC) +#define OMAP343X_CONTROL_DEBOBS_4 (OMAP2_CONTROL_GENERAL + 0x01C0) +#define OMAP343X_CONTROL_DEBOBS_5 (OMAP2_CONTROL_GENERAL + 0x01C4) +#define OMAP343X_CONTROL_DEBOBS_6 (OMAP2_CONTROL_GENERAL + 0x01C8) +#define OMAP343X_CONTROL_DEBOBS_7 (OMAP2_CONTROL_GENERAL + 0x01CC) +#define OMAP343X_CONTROL_DEBOBS_8 (OMAP2_CONTROL_GENERAL + 0x01D0) +#define OMAP343X_CONTROL_PROG_IO0 (OMAP2_CONTROL_GENERAL + 0x01D4) +#define OMAP343X_CONTROL_PROG_IO1 (OMAP2_CONTROL_GENERAL + 0x01D8) +#define OMAP343X_CONTROL_DSS_DPLL_SPREADING (OMAP2_CONTROL_GENERAL + 0x01E0) +#define OMAP343X_CONTROL_CORE_DPLL_SPREADING (OMAP2_CONTROL_GENERAL + 0x01E4) +#define OMAP343X_CONTROL_PER_DPLL_SPREADING (OMAP2_CONTROL_GENERAL + 0x01E8) +#define OMAP343X_CONTROL_USBHOST_DPLL_SPREADING (OMAP2_CONTROL_GENERAL + 0x01EC) +#define OMAP343X_CONTROL_PBIAS_LITE (OMAP2_CONTROL_GENERAL + 0x02B0) +#define OMAP343X_CONTROL_TEMP_SENSOR (OMAP2_CONTROL_GENERAL + 0x02B4) +#define OMAP343X_CONTROL_SRAMLDO4 (OMAP2_CONTROL_GENERAL + 0x02B8) +#define OMAP343X_CONTROL_SRAMLDO5 (OMAP2_CONTROL_GENERAL + 0x02C0) +#define OMAP343X_CONTROL_CSI (OMAP2_CONTROL_GENERAL + 0x02b4) + /* * REVISIT: This list of registers is not comprehensive - there are more diff --git a/arch/arm/plat-omap/include/mach/prcm.h b/arch/arm/plat-omap/include/mach/prcm.h index 80dddcb..f5fe518 100644 --- a/arch/arm/plat-omap/include/mach/prcm.h +++ b/arch/arm/plat-omap/include/mach/prcm.h @@ -30,9 +30,57 @@ void cm_write_mod_reg(u32 val, s16 module, u16 idx); u32 cm_read_mod_reg(s16 module, u16 idx); u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx); -#endif - - - +#ifdef CONFIG_ARCH_OMAP3 +/* Structure to save interrupt controller context */ +struct int_controller_context { + u32 sysconfig; + u32 protection; + u32 idle; + u32 threshold; + u32 ilr[96]; + u32 mir_0; + u32 mir_1; + u32 mir_2; +}; +/* Structure to save control module context */ +struct control_module_context { + u32 sysconfig; + u32 devconf0; + u32 mem_dftrw0; + u32 mem_dftrw1; + u32 msuspendmux_0; + u32 msuspendmux_1; + u32 msuspendmux_2; + u32 msuspendmux_3; + u32 msuspendmux_4; + u32 msuspendmux_5; + u32 sec_ctrl; + u32 devconf1; + u32 csirxfe; + u32 iva2_bootaddr; + u32 iva2_bootmod; + u32 debobs_0; + u32 debobs_1; + u32 debobs_2; + u32 debobs_3; + u32 debobs_4; + u32 debobs_5; + u32 debobs_6; + u32 debobs_7; + u32 debobs_8; + u32 prog_io0; + u32 prog_io1; + u32 dss_dpll_spreading; + u32 core_dpll_spreading; + u32 per_dpll_spreading; + u32 usbhost_dpll_spreading; + u32 pbias_lite; + u32 temp_sensor; + u32 sramldo4; + u32 sramldo5; + u32 csi; +}; +#endif /* CONFIG_ARCH_OMAP3 */ +#endif /* __ASM_ARM_ARCH_OMAP_PRCM_H */ diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index 853048d..9cfb77f 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c @@ -26,6 +26,7 @@ #include <mach/board.h> #include <mach/control.h> +#include <mach/pm.h> #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) # include "../mach-omap2/prm.h" @@ -75,6 +76,8 @@ extern unsigned long omapfb_reserve_sram(unsigned long sram_pstart, unsigned long sram_size, unsigned long pstart_avail, unsigned long size_avail); +extern void (*_omap_sram_idle)(u32 *addr, int save_state, int disable_clocks); +extern void omap_push_sram_idle(); /* * Depending on the target RAMFS firewall setup, the public usable amount of @@ -108,6 +111,7 @@ static int is_sram_locked(void) return 1; /* assume locked with no PPA or security driver */ } + /* * The amount of SRAM depends on the core type. * Note that we cannot try to test for SRAM here because writes @@ -368,13 +372,14 @@ u32 omap3_configure_core_dpll(u32 sdrc_rfr_ctrl, u32 sdrc_actim_ctrla, } /* REVISIT: Should this be same as omap34xx_sram_init() after off-idle? */ -void restore_sram_functions(void) +void omap3_restore_sram_ctx(void) { omap_sram_ceil = omap_sram_base + omap_sram_size; _omap3_sram_configure_core_dpll = omap_sram_push(omap3_sram_configure_core_dpll, omap3_sram_configure_core_dpll_sz); + omap_push_sram_idle(); } int __init omap3_sram_init(void) @@ -382,6 +387,8 @@ int __init omap3_sram_init(void) _omap3_sram_configure_core_dpll = omap_sram_push(omap3_sram_configure_core_dpll, omap3_sram_configure_core_dpll_sz); + _omap_sram_idle = omap_sram_push(omap34xx_cpu_suspend, + omap34xx_cpu_suspend_sz); return 0; } diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 39aca22..aa21e12 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -1214,6 +1214,15 @@ static inline void __stop_tx(struct uart_8250_port *p) p->ier &= ~UART_IER_THRI; serial_out(p, UART_IER, p->ier); } +#ifdef CONFIG_ARCH_OMAP3 + { + unsigned int tmp; + /* Allow dynamic handshake to allow OCP bus idle. RX events + * can do async wake */ + tmp = (serial_in(p, UART_OMAP_SYSC) & 0x7) | (2 << 3); + serial_out(p, UART_OMAP_SYSC, tmp); /* smart-idle */ + } +#endif } static void serial8250_stop_tx(struct uart_port *port) @@ -1261,6 +1270,17 @@ static void serial8250_start_tx(struct uart_port *port) up->acr &= ~UART_ACR_TXDIS; serial_icr_write(up, UART_ACR, up->acr); } +#ifdef CONFIG_ARCH_OMAP3 + { + unsigned int tmp; + /* Disallow OCP bus idle. UART TX irqs are not seen during + * bus idle. Alternative is to set kernel timer at fifo + * drain rate. + */ + tmp = (serial_in(up, UART_OMAP_SYSC) & 0x7) | (1 << 3); + serial_out(up, UART_OMAP_SYSC, tmp); /* no-idle */ + } +#endif } static void serial8250_stop_rx(struct uart_port *port) -- 1.6.0 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 15/29] OMAP3: PM: Move serial console check from omap3_can_sleep to idle loop 2008-09-11 12:33 ` [PATCH 14/29] CORE " Kevin Hilman @ 2008-09-11 12:33 ` Kevin Hilman 2008-09-11 12:34 ` [PATCH 16/29] OMAP3: PM: Remove static keyword from _omap_sram_idle declaration Kevin Hilman 2008-09-11 14:38 ` [PATCH 15/29] OMAP3: PM: Move serial console check from omap3_can_sleep to idle loop Daniel Stone 0 siblings, 2 replies; 37+ messages in thread From: Kevin Hilman @ 2008-09-11 12:33 UTC (permalink / raw) To: linux-omap; +Cc: Jouni Hogander, Git administrator From: Jouni Hogander <jouni.hogander@nokia.com> This fixes sluggish serial console. Signed-off-by: Git administrator <gitowner@stego.research.nokia.com> --- arch/arm/mach-omap2/cpuidle34xx.c | 2 +- arch/arm/mach-omap2/pm34xx.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c index a02da6d..b19d2eb 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c @@ -431,7 +431,7 @@ static int omap3_enter_idle(struct cpuidle_device *dev, current_cx_state = *cx; - if (cx->type == OMAP3_STATE_C0) { + if (cx->type == OMAP3_STATE_C0 || !omap_serial_can_sleep()) { /* Do nothing for C0, not even a wfi */ return 0; } diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index da6eae1..42fa546 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -398,8 +398,6 @@ int omap3_can_sleep(void) return 0; if (atomic_read(&sleep_block) > 0) return 0; - if (!omap_serial_can_sleep()) - return 0; return 1; } @@ -478,6 +476,9 @@ static void omap3_pm_idle(void) if (omap_irq_pending()) goto out; + if (!omap_serial_can_sleep()) + goto out; + omap2_gpio_prepare_for_retention(); omap_serial_enable_clocks(0, 0); -- 1.6.0 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 16/29] OMAP3: PM: Remove static keyword from _omap_sram_idle declaration 2008-09-11 12:33 ` [PATCH 15/29] OMAP3: PM: Move serial console check from omap3_can_sleep to idle loop Kevin Hilman @ 2008-09-11 12:34 ` Kevin Hilman 2008-09-11 12:34 ` [PATCH 17/29] OMAP3: PM: Remove unneeded code from traditional pm_idle loop Kevin Hilman 2008-09-11 14:38 ` [PATCH 15/29] OMAP3: PM: Move serial console check from omap3_can_sleep to idle loop Daniel Stone 1 sibling, 1 reply; 37+ messages in thread From: Kevin Hilman @ 2008-09-11 12:34 UTC (permalink / raw) To: linux-omap; +Cc: Jouni Hogander, Git administrator From: Jouni Hogander <jouni.hogander@nokia.com> _omap_sram_idle is shared between cpuidle34xx.c and pm34xx.c so static keyword needs to be removed. Signed-off-by: Git administrator <gitowner@stego.research.nokia.com> --- arch/arm/mach-omap2/pm34xx.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 42fa546..73f32a0 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -60,7 +60,7 @@ u32 restore_pointer_address; static LIST_HEAD(pwrst_list); -static void (*_omap_sram_idle)(u32 *addr, int save_state); +void (*_omap_sram_idle)(u32 *addr, int save_state); static void (*saved_idle)(void); -- 1.6.0 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 17/29] OMAP3: PM: Remove unneeded code from traditional pm_idle loop 2008-09-11 12:34 ` [PATCH 16/29] OMAP3: PM: Remove static keyword from _omap_sram_idle declaration Kevin Hilman @ 2008-09-11 12:34 ` Kevin Hilman 2008-09-11 12:34 ` [PATCH 18/29] OMAP3: PM: Do not build pm_idle loop if cpuidle is used Kevin Hilman 0 siblings, 1 reply; 37+ messages in thread From: Kevin Hilman @ 2008-09-11 12:34 UTC (permalink / raw) To: linux-omap; +Cc: Jouni Hogander, Git administrator From: Jouni Hogander <jouni.hogander@nokia.com> Remove code from traditional pm_idle loop. Removed code is in omap_sram_idle which is shared between cpuidle and pm_idle. Signed-off-by: Git administrator <gitowner@stego.research.nokia.com> --- arch/arm/mach-omap2/pm34xx.c | 14 -------------- 1 files changed, 0 insertions(+), 14 deletions(-) diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 73f32a0..ae324b4 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -479,21 +479,7 @@ static void omap3_pm_idle(void) if (!omap_serial_can_sleep()) goto out; - omap2_gpio_prepare_for_retention(); - - omap_serial_enable_clocks(0, 0); - omap_serial_enable_clocks(0, 1); - omap_serial_enable_clocks(0, 2); - per_gpio_clk_disable(); - omap_sram_idle(); - - omap_serial_enable_clocks(1, 0); - omap_serial_enable_clocks(1, 1); - omap_serial_enable_clocks(1, 2); - per_gpio_clk_enable(); - - omap2_gpio_resume_after_retention(); out: local_fiq_enable(); local_irq_enable(); -- 1.6.0 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 18/29] OMAP3: PM: Do not build pm_idle loop if cpuidle is used 2008-09-11 12:34 ` [PATCH 17/29] OMAP3: PM: Remove unneeded code from traditional pm_idle loop Kevin Hilman @ 2008-09-11 12:34 ` Kevin Hilman 2008-09-11 12:34 ` [PATCH 19/29] OMAP3: Do not set mpu, core, neon states " Kevin Hilman 0 siblings, 1 reply; 37+ messages in thread From: Kevin Hilman @ 2008-09-11 12:34 UTC (permalink / raw) To: linux-omap; +Cc: Jouni Hogander, Git administrator From: Jouni Hogander <jouni.hogander@nokia.com> Signed-off-by: Git administrator <gitowner@stego.research.nokia.com> --- arch/arm/mach-omap2/pm34xx.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index ae324b4..d696dde 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -465,6 +465,7 @@ err: return ret; } +#ifndef CONFIG_CPU_IDLE static void omap3_pm_idle(void) { local_irq_disable(); @@ -484,6 +485,7 @@ out: local_fiq_enable(); local_irq_enable(); } +#endif /* CONFIG_CPU_IDLE */ static int omap3_pm_prepare(void) { -- 1.6.0 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 19/29] OMAP3: Do not set mpu, core, neon states if cpuidle is used 2008-09-11 12:34 ` [PATCH 18/29] OMAP3: PM: Do not build pm_idle loop if cpuidle is used Kevin Hilman @ 2008-09-11 12:34 ` Kevin Hilman 2008-09-11 12:34 ` [PATCH 20/29] OMAP3: PM: Fixed header paths in include statements Kevin Hilman 0 siblings, 1 reply; 37+ messages in thread From: Kevin Hilman @ 2008-09-11 12:34 UTC (permalink / raw) To: linux-omap; +Cc: Jouni Hogander, Git administrator From: Jouni Hogander <jouni.hogander@nokia.com> Let the cpuidle do the selection. Signed-off-by: Git administrator <gitowner@stego.research.nokia.com> --- arch/arm/mach-omap2/pm34xx.c | 17 ++++++++++------- 1 files changed, 10 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index d696dde..d6acf6c 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -815,12 +815,7 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm) if (!pwrst) return -ENOMEM; pwrst->pwrdm = pwrdm; - if (!strcmp(pwrst->pwrdm->name, "core_pwrdm") || - !strcmp(pwrst->pwrdm->name, "mpu_pwrdm") || - !strcmp(pwrst->pwrdm->name, "mpu_pwrdm")) - pwrst->next_state = PWRDM_POWER_ON; - else - pwrst->next_state = PWRDM_POWER_OFF; + pwrst->next_state = PWRDM_POWER_RET; list_add(&pwrst->node, &pwrst_list); if (pwrdm_has_hdwr_sar(pwrdm)) @@ -838,7 +833,15 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm) if (sysfs_create_file(suspend_dir_kobj, &(attr->attr))) return -ENOMEM; - return set_pwrdm_state(pwrst->pwrdm, pwrst->next_state); +#ifdef CONFIG_CPU_IDLE + /* Let cpuidle do selection here */ + if (!strcmp(pwrst->pwrdm->name, "core_pwrdm") || + !strcmp(pwrst->pwrdm->name, "mpu_pwrdm") || + !strcmp(pwrst->pwrdm->name, "neon_pwrdm")) + return set_pwrdm_state(pwrst->pwrdm, PWRDM_POWER_ON); + else +#endif + return set_pwrdm_state(pwrst->pwrdm, pwrst->next_state); } void omap_push_sram_idle() -- 1.6.0 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 20/29] OMAP3: PM: Fixed header paths in include statements 2008-09-11 12:34 ` [PATCH 19/29] OMAP3: Do not set mpu, core, neon states " Kevin Hilman @ 2008-09-11 12:34 ` Kevin Hilman 2008-09-11 12:34 ` [PATCH 21/29] OMAP3: PM: Remove unneeded code from suspend Kevin Hilman 0 siblings, 1 reply; 37+ messages in thread From: Kevin Hilman @ 2008-09-11 12:34 UTC (permalink / raw) To: linux-omap; +Cc: Jouni Hogander From: Jouni Hogander <jouni.hogander@nokia.com> Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com> --- arch/arm/mach-omap2/cpuidle34xx.c | 14 +++++++------- arch/arm/mach-omap2/pm34xx.c | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c index b19d2eb..11ff573 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c @@ -23,13 +23,13 @@ */ #include <linux/cpuidle.h> -#include <asm/arch/pm.h> -#include <asm/arch/prcm.h> -#include <asm/arch/powerdomain.h> -#include <asm/arch/clockdomain.h> -#include <asm/arch/gpio.h> -#include <asm/arch/gpmc.h> -#include <asm/arch/control.h> +#include <mach/pm.h> +#include <mach/prcm.h> +#include <mach/powerdomain.h> +#include <mach/clockdomain.h> +#include <mach/gpio.h> +#include <mach/gpmc.h> +#include <mach/control.h> #include <linux/sched.h> #include "cpuidle34xx.h" #include "cm.h" diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index d6acf6c..46b0b20 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -31,7 +31,7 @@ #include <mach/powerdomain.h> #include <mach/common.h> #include <mach/sdrc.h> -#include <mach/tlbflush.h> +#include <asm/tlbflush.h> #include "sdrc.h" #include "cm.h" -- 1.6.0 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 21/29] OMAP3: PM: Remove unneeded code from suspend 2008-09-11 12:34 ` [PATCH 20/29] OMAP3: PM: Fixed header paths in include statements Kevin Hilman @ 2008-09-11 12:34 ` Kevin Hilman 2008-09-11 12:34 ` [PATCH 22/29] DMA context save / restore Kevin Hilman 0 siblings, 1 reply; 37+ messages in thread From: Kevin Hilman @ 2008-09-11 12:34 UTC (permalink / raw) To: linux-omap; +Cc: Jouni Hogander From: Jouni Hogander <jouni.hogander@nokia.com> Removed code is in omap_sram_idle which is shared between cpuidle, pm_idle and suspend. Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com> --- arch/arm/mach-omap2/pm34xx.c | 14 -------------- 1 files changed, 0 insertions(+), 14 deletions(-) diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 46b0b20..fc7da5a 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -514,21 +514,7 @@ static int omap3_pm_suspend(void) goto restore; } - omap2_gpio_prepare_for_retention(); - - omap_serial_enable_clocks(0, 0); - omap_serial_enable_clocks(0, 1); - omap_serial_enable_clocks(0, 2); - per_gpio_clk_disable(); - omap_sram_idle(); - - omap_serial_enable_clocks(1, 0); - omap_serial_enable_clocks(1, 1); - omap_serial_enable_clocks(1, 2); - per_gpio_clk_enable(); - - omap2_gpio_resume_after_retention(); restore: /* Restore next_pwrsts */ list_for_each_entry(pwrst, &pwrst_list, node) { -- 1.6.0 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 22/29] DMA context save / restore 2008-09-11 12:34 ` [PATCH 21/29] OMAP3: PM: Remove unneeded code from suspend Kevin Hilman @ 2008-09-11 12:34 ` Kevin Hilman 2008-09-11 12:34 ` [PATCH 23/29] OMAP3: PM: Add new Kconfig option to enable/disable off mode Kevin Hilman 0 siblings, 1 reply; 37+ messages in thread From: Kevin Hilman @ 2008-09-11 12:34 UTC (permalink / raw) To: linux-omap; +Cc: Tero Kristo From: Tero Kristo <tero.kristo@nokia.com> Signed-off-by: Tero Kristo <tero.kristo@nokia.com> --- arch/arm/mach-omap2/cpuidle34xx.c | 3 +++ arch/arm/plat-omap/dma.c | 26 ++++++++++++++++++++++++++ arch/arm/plat-omap/include/mach/dma.h | 3 +++ 3 files changed, 32 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c index 11ff573..c970a06 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c @@ -30,6 +30,7 @@ #include <mach/gpio.h> #include <mach/gpmc.h> #include <mach/control.h> +#include <mach/dma.h> #include <linux/sched.h> #include "cpuidle34xx.h" #include "cm.h" @@ -392,6 +393,7 @@ void omap3_save_core_ctx(void) omap_save_gpmc_ctx(); /* Save the system control module context, padconf already save above*/ omap_save_control_ctx(); + omap_dma_global_context_save(); } void omap3_restore_core_ctx(void) @@ -402,6 +404,7 @@ void omap3_restore_core_ctx(void) omap_restore_gpmc_ctx(); /* Restore the interrupt controller context */ omap_restore_intc_ctx(); + omap_dma_global_context_restore(); padconf_saved = 0; } diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index eaea12a..38c57ce 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -51,6 +51,12 @@ enum { DMA_CHAIN_STARTED, DMA_CHAIN_NOTSTARTED }; static int enable_1510_mode; +static struct omap_dma_global_context_registers { + u32 dma_irqenable_l0; + u32 dma_ocp_sysconfig; + u32 dma_gcr; +} omap_dma_global_context; + struct omap_dma_lch { int next_lch; int dev_id; @@ -2291,6 +2297,26 @@ void omap_stop_lcd_dma(void) } EXPORT_SYMBOL(omap_stop_lcd_dma); +void omap_dma_global_context_save(void) +{ + omap_dma_global_context.dma_irqenable_l0 = + dma_read(IRQENABLE_L0); + omap_dma_global_context.dma_ocp_sysconfig = + dma_read(OCP_SYSCONFIG); + omap_dma_global_context.dma_gcr = dma_read(GCR); +} +EXPORT_SYMBOL(omap_dma_global_context_save); + +void omap_dma_global_context_restore(void) +{ + dma_write(omap_dma_global_context.dma_gcr, GCR); + dma_write(omap_dma_global_context.dma_ocp_sysconfig, + OCP_SYSCONFIG); + dma_write(omap_dma_global_context.dma_irqenable_l0, + IRQENABLE_L0); +} +EXPORT_SYMBOL(omap_dma_global_context_restore); + /*----------------------------------------------------------------------------*/ static int __init omap_init_dma(void) diff --git a/arch/arm/plat-omap/include/mach/dma.h b/arch/arm/plat-omap/include/mach/dma.h index 54fe966..f1f588a 100644 --- a/arch/arm/plat-omap/include/mach/dma.h +++ b/arch/arm/plat-omap/include/mach/dma.h @@ -528,6 +528,9 @@ extern void omap_set_dma_dst_endian_type(int lch, enum end_type etype); extern void omap_set_dma_src_endian_type(int lch, enum end_type etype); extern int omap_get_dma_index(int lch, int *ei, int *fi); +void omap_dma_global_context_save(void); +void omap_dma_global_context_restore(void); + /* Chaining APIs */ #ifndef CONFIG_ARCH_OMAP1 extern int omap_request_dma_chain(int dev_id, const char *dev_name, -- 1.6.0 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 23/29] OMAP3: PM: Add new Kconfig option to enable/disable off mode 2008-09-11 12:34 ` [PATCH 22/29] DMA context save / restore Kevin Hilman @ 2008-09-11 12:34 ` Kevin Hilman 2008-09-11 12:34 ` [PATCH 24/29] OMAP3SDP: Add new config for off mode testing Kevin Hilman 0 siblings, 1 reply; 37+ messages in thread From: Kevin Hilman @ 2008-09-11 12:34 UTC (permalink / raw) To: linux-omap; +Cc: Jouni Hogander From: Jouni Hogander <jouni.hogander@nokia.com> Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com> --- arch/arm/mach-omap2/Kconfig | 6 ++++++ arch/arm/mach-omap2/cpuidle34xx.c | 12 ++++++++++++ arch/arm/mach-omap2/pm34xx.c | 4 ++++ 3 files changed, 22 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 362edfa..5c0eafc 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -142,3 +142,9 @@ config OMAP_TICK_GPTIMER due to hardware sensitivity to glitches on the OMAP 32kHz clock input. +config OMAP3_OFF_MODE + bool "OMAP 3430 OFF mode support" + depends on ARCH_OMAP3 + default n + help + Use off mode for powerdomains. \ No newline at end of file diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c index c970a06..248b365 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c @@ -555,7 +555,11 @@ void omap_init_power_states(void) CPUIDLE_FLAG_BALANCED; /* C3 . MPU OFF + Core active */ +#ifdef CONFIG_OMAP3_OFF_MODE omap3_power_states[OMAP3_STATE_C3].valid = 1; +#else + omap3_power_states[OMAP3_STATE_C3].valid = 0; +#endif omap3_power_states[OMAP3_STATE_C3].type = OMAP3_STATE_C3; omap3_power_states[OMAP3_STATE_C3].sleep_latency = 1500; omap3_power_states[OMAP3_STATE_C3].wakeup_latency = 1800; @@ -577,7 +581,11 @@ void omap_init_power_states(void) CPUIDLE_FLAG_BALANCED | CPUIDLE_FLAG_CHECK_BM; /* C5 . MPU OFF + Core CSWR */ +#ifdef CONFIG_OMAP3_OFF_MODE omap3_power_states[OMAP3_STATE_C5].valid = 1; +#else + omap3_power_states[OMAP3_STATE_C5].valid = 0; +#endif omap3_power_states[OMAP3_STATE_C5].type = OMAP3_STATE_C5; omap3_power_states[OMAP3_STATE_C5].sleep_latency = 3000; omap3_power_states[OMAP3_STATE_C5].wakeup_latency = 8500; @@ -588,7 +596,11 @@ void omap_init_power_states(void) CPUIDLE_FLAG_BALANCED | CPUIDLE_FLAG_CHECK_BM; /* C6 . MPU OFF + Core OFF */ +#ifdef CONFIG_OMAP3_OFF_MODE omap3_power_states[OMAP3_STATE_C6].valid = 1; +#else + omap3_power_states[OMAP3_STATE_C6].valid = 0; +#endif omap3_power_states[OMAP3_STATE_C6].type = OMAP3_STATE_C6; omap3_power_states[OMAP3_STATE_C6].sleep_latency = 10000; omap3_power_states[OMAP3_STATE_C6].wakeup_latency = 30000; diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index fc7da5a..53814b6 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -801,7 +801,11 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm) if (!pwrst) return -ENOMEM; pwrst->pwrdm = pwrdm; +#ifdef CONFIG_OMAP3_OFF_MODE + pwrst->next_state = PWRDM_POWER_OFF; +#else pwrst->next_state = PWRDM_POWER_RET; +#endif list_add(&pwrst->node, &pwrst_list); if (pwrdm_has_hdwr_sar(pwrdm)) -- 1.6.0 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 24/29] OMAP3SDP: Add new config for off mode testing 2008-09-11 12:34 ` [PATCH 23/29] OMAP3: PM: Add new Kconfig option to enable/disable off mode Kevin Hilman @ 2008-09-11 12:34 ` Kevin Hilman 2008-09-11 12:34 ` [PATCH 25/29] OMAP3: Remove CONFIG_OMAP_SYSOFFMODE flag Kevin Hilman 0 siblings, 1 reply; 37+ messages in thread From: Kevin Hilman @ 2008-09-11 12:34 UTC (permalink / raw) To: linux-omap; +Cc: Jouni Hogander From: Jouni Hogander <jouni.hogander@nokia.com> Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com> --- arch/arm/configs/omap_3430sdp_offmode_defconfig | 1073 +++++++++++++++++++++++ 1 files changed, 1073 insertions(+), 0 deletions(-) create mode 100644 arch/arm/configs/omap_3430sdp_offmode_defconfig diff --git a/arch/arm/configs/omap_3430sdp_offmode_defconfig b/arch/arm/configs/omap_3430sdp_offmode_defconfig new file mode 100644 index 0000000..0d8ee50 --- /dev/null +++ b/arch/arm/configs/omap_3430sdp_offmode_defconfig @@ -0,0 +1,1073 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.27-rc3-omap1 +# Fri Aug 22 11:46:52 2008 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_MMU=y +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ARCH_SUPPORTS_AOUT=y +CONFIG_ZONE_DMA=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_GROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +CONFIG_KALLSYMS_EXTRA_PASS=y +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_COMPAT_BRK=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set +# CONFIG_HAVE_IOREMAP_PROT is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +# CONFIG_HAVE_ARCH_TRACEHOOK is not set +# CONFIG_HAVE_DMA_ATTRS is not set +# CONFIG_USE_GENERIC_SMP_HELPERS is not set +CONFIG_HAVE_CLK=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_KMOD=y +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_CLASSIC_RCU=y + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_LOKI is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_DAVINCI is not set +CONFIG_ARCH_OMAP=y +# CONFIG_ARCH_MSM7X00A is not set + +# +# TI OMAP Implementations +# +CONFIG_ARCH_OMAP_OTG=y +# CONFIG_ARCH_OMAP1 is not set +# CONFIG_ARCH_OMAP2 is not set +CONFIG_ARCH_OMAP3=y + +# +# OMAP Feature Selections +# +# CONFIG_OMAP_DEBUG_POWERDOMAIN is not set +# CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set +CONFIG_OMAP_SMARTREFLEX=y +CONFIG_OMAP_SMARTREFLEX_TESTING=y +CONFIG_OMAP_RESET_CLOCKS=y +CONFIG_OMAP_BOOT_TAG=y +CONFIG_OMAP_BOOT_REASON=y +# CONFIG_OMAP_COMPONENT_VERSION is not set +# CONFIG_OMAP_GPIO_SWITCH is not set +CONFIG_OMAP_MUX=y +CONFIG_OMAP_MUX_DEBUG=y +CONFIG_OMAP_MUX_WARNINGS=y +# CONFIG_OMAP_MCBSP is not set +# CONFIG_OMAP_MMU_FWK is not set +# CONFIG_OMAP_MBOX_FWK is not set +# CONFIG_OMAP_MPU_TIMER is not set +CONFIG_OMAP_32K_TIMER=y +CONFIG_OMAP_32K_TIMER_HZ=128 +CONFIG_OMAP_DM_TIMER=y +CONFIG_OMAP_LL_DEBUG_UART1=y +# CONFIG_OMAP_LL_DEBUG_UART2 is not set +# CONFIG_OMAP_LL_DEBUG_UART3 is not set +CONFIG_OMAP_SERIAL_WAKE=y +CONFIG_ARCH_OMAP34XX=y +CONFIG_ARCH_OMAP3430=y + +# +# OMAP Board Type +# +# CONFIG_MACH_OMAP_LDP is not set +CONFIG_MACH_OMAP_3430SDP=y +# CONFIG_MACH_OMAP3EVM is not set +# CONFIG_MACH_OMAP3_BEAGLE is not set +CONFIG_OMAP_TICK_GPTIMER=1 +CONFIG_OMAP3_OFF_MODE=y + +# +# Boot options +# + +# +# Power management +# + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_32v6K=y +CONFIG_CPU_V7=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +CONFIG_CPU_PABRT_IFAR=y +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_ARM_THUMBEE is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_BPREDICT_DISABLE is not set +CONFIG_HAS_TLS_REG=y +# CONFIG_OUTER_CACHE is not set + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +# CONFIG_PREEMPT is not set +CONFIG_HZ=128 +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y +# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +# CONFIG_LEDS is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="root=/dev/nfs nfsroot=192.168.0.1:/home/user/buildroot ip=192.168.0.2:192.168.0.1:192.168.0.1:255.255.255.0:tgt:eth0:off rw console=ttyS2,115200n8" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# CPUIdle +# + +# +# CPU idle PM support +# +CONFIG_CPU_IDLE=y + +# +# Governors +# +# CONFIG_CPU_IDLE_GOV_LADDER is not set +CONFIG_CPU_IDLE_GOV_MENU=y + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_FPE_NWFPE is not set +# CONFIG_FPE_FASTFPE is not set +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_MISC=y + +# +# Power management options +# +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +# CONFIG_APM_EMULATION is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +CONFIG_NET_KEY=y +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +# CONFIG_MTD is not set +# CONFIG_PARPORT is not set +# CONFIG_BLK_DEV is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_DH is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +CONFIG_SMC91X=y +# CONFIG_DM9000 is not set +# CONFIG_SMC911X is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_B44 is not set +CONFIG_NETDEV_1000=y +CONFIG_NETDEV_10000=y + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS is not set +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_DEVKMEM is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=32 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_8250_DETECT_IRQ=y +CONFIG_SERIAL_8250_RSA=y + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_IPMI_HANDLER is not set +CONFIG_HW_RANDOM=y +# CONFIG_NVRAM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_HELPER_AUTO=y + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_OCORES is not set +CONFIG_I2C_OMAP=y +# CONFIG_I2C_SIMTEC is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_STUB is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_DS1682 is not set +# CONFIG_AT24 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_PCF8575 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_ISP1301_OMAP is not set +# CONFIG_TPS65010 is not set +# CONFIG_SENSORS_TLV320AIC23 is not set +CONFIG_TWL4030_CORE=y +CONFIG_TWL4030_GPIO=y +# CONFIG_TWL4030_MADC is not set +CONFIG_TWL4030_USB=y +CONFIG_TWL4030_USB_HS_ULPI=y +# CONFIG_TWL4030_PWRBUTTON is not set +# CONFIG_TWL4030_POWEROFF is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_LP5521 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +# CONFIG_SPI is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +# CONFIG_GPIO_SYSFS is not set + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_WATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set + +# +# Multimedia devices +# + +# +# Multimedia core support +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set +# CONFIG_VIDEO_MEDIA is not set + +# +# Multimedia drivers +# +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_SOUND is not set +# CONFIG_HID_SUPPORT is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_MMC is not set +# CONFIG_NEW_LEDS is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set +# CONFIG_DMADEVICES is not set + +# +# Voltage and Current regulators +# +# CONFIG_REGULATOR is not set +# CONFIG_REGULATOR_FIXED_VOLTAGE is not set +# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set +# CONFIG_REGULATOR_BQ24022 is not set +# CONFIG_UIO is not set + +# +# CBUS support +# +# CONFIG_CBUS is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_FS_XATTR is not set +# CONFIG_EXT4DEV_FS is not set +CONFIG_JBD=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_OCFS2_FS is not set +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_QUOTA=y +# CONFIG_QUOTA_NETLINK_INTERFACE is not set +CONFIG_PRINT_QUOTA_WARNING=y +# CONFIG_QFMT_V1 is not set +CONFIG_QFMT_V2=y +CONFIG_QUOTACTL=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set +# CONFIG_DLM is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +CONFIG_FRAME_POINTER=y +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +CONFIG_HAVE_FTRACE=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +# CONFIG_FTRACE is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_ERRORS is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_LL is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_MANAGER=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=m +# CONFIG_CRYPTO_LRW is not set +CONFIG_CRYPTO_PCBC=m +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_LZO is not set +CONFIG_CRYPTO_HW=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set +# CONFIG_GENERIC_FIND_NEXT_BIT is not set +CONFIG_CRC_CCITT=y +# CONFIG_CRC16 is not set +CONFIG_CRC_T10DIF=y +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +CONFIG_LIBCRC32C=y +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y -- 1.6.0 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 25/29] OMAP3: Remove CONFIG_OMAP_SYSOFFMODE flag 2008-09-11 12:34 ` [PATCH 24/29] OMAP3SDP: Add new config for off mode testing Kevin Hilman @ 2008-09-11 12:34 ` Kevin Hilman 2008-09-11 12:34 ` [PATCH 26/29] OMAP: Sysfs interface for enabling voltage off in idle Kevin Hilman 0 siblings, 1 reply; 37+ messages in thread From: Kevin Hilman @ 2008-09-11 12:34 UTC (permalink / raw) To: linux-omap; +Cc: Kalle Jokiniemi From: Kalle Jokiniemi <ext-kalle.jokiniemi@nokia.com> Remove CONFIG_OMAP_SYSOFFMODE flag and do the full initialization of voltage controller . Enabling automatic sending of OFF command and selecting wether SYS_OFF_MODE signal is used should be determined dynamically. Hence they are now not set in the initialization. The sleep voltage for OFF mode is changed to default 1,2V for VDD1 and 1,15V for VDD2. Using the 0,9V setting causes hangup. Signed-off-by: Kalle Jokiniemi <ext-kalle.jokiniemi@nokia.com> --- arch/arm/mach-omap2/pm34xx.c | 10 +--------- arch/arm/mach-omap2/prm-regbits-34xx.h | 4 ++-- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 53814b6..0267959 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -1060,10 +1060,7 @@ static void __init configure_vc(void) OMAP3_PRM_VC_I2C_CFG_OFFSET); /* Setup voltctrl and other setup times */ - -#ifdef CONFIG_OMAP_SYSOFFMODE - prm_write_mod_reg(OMAP3430_AUTO_OFF | OMAP3430_AUTO_RET | - OMAP3430_SEL_OFF, OMAP3430_GR_MOD, + prm_write_mod_reg(OMAP3430_AUTO_RET, OMAP3430_GR_MOD, OMAP3_PRM_VOLTCTRL_OFFSET); prm_write_mod_reg(OMAP3430_CLKSETUP_DURATION, OMAP3430_GR_MOD, @@ -1078,11 +1075,6 @@ static void __init configure_vc(void) OMAP3_PRM_VOLTOFFSET_OFFSET); prm_write_mod_reg(OMAP3430_VOLTSETUP2_DURATION, OMAP3430_GR_MOD, OMAP3_PRM_VOLTSETUP2_OFFSET); -#else - prm_set_mod_reg_bits(OMAP3430_AUTO_RET, OMAP3430_GR_MOD, - OMAP3_PRM_VOLTCTRL_OFFSET); -#endif - } static int __init omap3_pm_early_init(void) diff --git a/arch/arm/mach-omap2/prm-regbits-34xx.h b/arch/arm/mach-omap2/prm-regbits-34xx.h index f82b5a7..d73eee8 100644 --- a/arch/arm/mach-omap2/prm-regbits-34xx.h +++ b/arch/arm/mach-omap2/prm-regbits-34xx.h @@ -466,13 +466,13 @@ #define OMAP3430_VC_CMD_VAL0_ON (0x3 << 4) #define OMAP3430_VC_CMD_VAL0_ONLP (0x3 << 3) #define OMAP3430_VC_CMD_VAL0_RET (0x3 << 3) -#define OMAP3430_VC_CMD_VAL0_OFF (0x3 << 3) +#define OMAP3430_VC_CMD_VAL0_OFF (0x3 << 4) /* PRM_VC_CMD_VAL_1 specific bits */ #define OMAP3430_VC_CMD_VAL1_ON (0xB << 2) #define OMAP3430_VC_CMD_VAL1_ONLP (0x3 << 3) #define OMAP3430_VC_CMD_VAL1_RET (0x3 << 3) -#define OMAP3430_VC_CMD_VAL1_OFF (0x3 << 3) +#define OMAP3430_VC_CMD_VAL1_OFF (0xB << 2) /* PRM_VC_CH_CONF */ #define OMAP3430_CMD1 (1 << 20) -- 1.6.0 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 26/29] OMAP: Sysfs interface for enabling voltage off in idle 2008-09-11 12:34 ` [PATCH 25/29] OMAP3: Remove CONFIG_OMAP_SYSOFFMODE flag Kevin Hilman @ 2008-09-11 12:34 ` Kevin Hilman 2008-09-11 12:34 ` [PATCH 27/29] OMAP3: OFF command integration Kevin Hilman 0 siblings, 1 reply; 37+ messages in thread From: Kevin Hilman @ 2008-09-11 12:34 UTC (permalink / raw) To: linux-omap; +Cc: Kalle Jokiniemi From: Kalle Jokiniemi <ext-kalle.jokiniemi@nokia.com> This patch creates a sysfs interface (/sys/power/voltage_off_while_idle) to set or clear a variable which can be used in determining wether voltage regulators should be shut down in idle. Signed-off-by: Kalle Jokiniemi <ext-kalle.jokiniemi@nokia.com> --- arch/arm/mach-omap2/pm.c | 21 ++++++++++++++++++++- arch/arm/mach-omap2/pm.h | 1 + 2 files changed, 21 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index c063565..c89de1e 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -36,6 +36,7 @@ unsigned short enable_dyn_sleep; unsigned short gpio_clocks_off_while_idle; unsigned short uart_clocks_off_while_idle; +unsigned short voltage_off_while_idle; atomic_t sleep_block = ATOMIC_INIT(0); static ssize_t idle_show(struct kobject *, struct kobj_attribute *, char *); @@ -51,6 +52,9 @@ static struct kobj_attribute gpio_clocks_off_while_idle_attr = static struct kobj_attribute uart_clocks_off_while_idle_attr = __ATTR(uart_clocks_off_while_idle, 0644, idle_show, idle_store); +static struct kobj_attribute voltage_off_while_idle_attr = + __ATTR(voltage_off_while_idle, 0644, idle_show, idle_store); + static ssize_t idle_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { @@ -60,6 +64,8 @@ static ssize_t idle_show(struct kobject *kobj, struct kobj_attribute *attr, return sprintf(buf, "%hu\n", gpio_clocks_off_while_idle); else if (attr == &uart_clocks_off_while_idle_attr) return sprintf(buf, "%hu\n", uart_clocks_off_while_idle); + else if (attr == &voltage_off_while_idle_attr) + return sprintf(buf, "%hu\n", voltage_off_while_idle); else return -EINVAL; } @@ -81,6 +87,8 @@ static ssize_t idle_store(struct kobject *kobj, struct kobj_attribute *attr, gpio_clocks_off_while_idle = value; else if (attr == &uart_clocks_off_while_idle_attr) uart_clocks_off_while_idle = value; + else if (attr == &voltage_off_while_idle_attr) + voltage_off_while_idle = value; else return -EINVAL; @@ -129,9 +137,20 @@ static int __init omap_pm_init(void) error = sysfs_create_file(power_kobj, &gpio_clocks_off_while_idle_attr.attr); - if (error) + if (error) { printk(KERN_ERR "sysfs_create_file failed: %d\n", error); + return error; + } + voltage_off_while_idle = 0; + /* Going to 0V on anything under ES2.1 will eventually cause a crash */ + if (is_sil_rev_greater_than(OMAP3430_REV_ES2_0)) { + error = sysfs_create_file(power_kobj, + &voltage_off_while_idle_attr.attr); + if (error) + printk(KERN_ERR "sysfs_create_file failed: %d\n", + error); + } return error; } diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index 7776cdb..aad4aeb 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h @@ -19,6 +19,7 @@ extern int omap3_pm_init(void); extern unsigned short enable_dyn_sleep; extern unsigned short gpio_clocks_off_while_idle; extern unsigned short uart_clocks_off_while_idle; +extern unsigned short voltage_off_while_idle; extern atomic_t sleep_block; extern void omap2_block_sleep(void); -- 1.6.0 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 27/29] OMAP3: OFF command integration 2008-09-11 12:34 ` [PATCH 26/29] OMAP: Sysfs interface for enabling voltage off in idle Kevin Hilman @ 2008-09-11 12:34 ` Kevin Hilman 2008-09-11 12:34 ` [PATCH 28/29] PM FIX: convert TI io_p2v() usage to OMAP2_IO_ADDRESS() Kevin Hilman 0 siblings, 1 reply; 37+ messages in thread From: Kevin Hilman @ 2008-09-11 12:34 UTC (permalink / raw) To: linux-omap; +Cc: Kalle Jokiniemi From: Kalle Jokiniemi <ext-kalle.jokiniemi@nokia.com> This patch detects wether device is going into off mode and sets the appropriate off command to be sent to voltage controller on WFI. By default only I2C voltage lowering is used, but if user has enabled the voltage_off_while_idle sysfs switch, SYS_OFFMODE signal is used. Signed-off-by: Kalle Jokiniemi <ext-kalle.jokiniemi@nokia.com> --- arch/arm/mach-omap2/pm.c | 12 ++++++++++-- arch/arm/mach-omap2/pm34xx.c | 7 +++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index c89de1e..386e6c6 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -31,6 +31,7 @@ #include <mach/powerdomain.h> #include <mach/pm.h> +#include "prm-regbits-34xx.h" #include "pm.h" unsigned short enable_dyn_sleep; @@ -87,9 +88,16 @@ static ssize_t idle_store(struct kobject *kobj, struct kobj_attribute *attr, gpio_clocks_off_while_idle = value; else if (attr == &uart_clocks_off_while_idle_attr) uart_clocks_off_while_idle = value; - else if (attr == &voltage_off_while_idle_attr) + else if (attr == &voltage_off_while_idle_attr) { voltage_off_while_idle = value; - else + if (voltage_off_while_idle) + prm_set_mod_reg_bits(OMAP3430_SEL_OFF, OMAP3430_GR_MOD, + OMAP3_PRM_VOLTCTRL_OFFSET); + else + prm_clear_mod_reg_bits(OMAP3430_SEL_OFF, + OMAP3430_GR_MOD, + OMAP3_PRM_VOLTCTRL_OFFSET); + } else return -EINVAL; return n; diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 0267959..5242ba0 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -297,6 +297,9 @@ void omap_sram_idle(void) omap_serial_enable_clocks(0, 2); } if (core_next_state == PWRDM_POWER_OFF) { + prm_set_mod_reg_bits(OMAP3430_AUTO_OFF, + OMAP3430_GR_MOD, + OMAP3_PRM_VOLTCTRL_OFFSET); omap3_save_core_ctx(); omap3_save_prcm_ctx(); omap_save_uart_ctx(0); @@ -334,6 +337,10 @@ void omap_sram_idle(void) omap_restore_uart_ctx(0); omap_restore_uart_ctx(1); } + if (core_next_state == PWRDM_POWER_OFF) + prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF, + OMAP3430_GR_MOD, + OMAP3_PRM_VOLTCTRL_OFFSET); if (per_next_state < PWRDM_POWER_ON) { per_gpio_clk_enable(); /* This would be actually more effective */ -- 1.6.0 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 28/29] PM FIX: convert TI io_p2v() usage to OMAP2_IO_ADDRESS() 2008-09-11 12:34 ` [PATCH 27/29] OMAP3: OFF command integration Kevin Hilman @ 2008-09-11 12:34 ` Kevin Hilman 2008-09-11 12:34 ` [PATCH 29/29] PM: serial: ensure padconf wake-enable bits are set for UARTs Kevin Hilman 2008-09-11 13:05 ` [PATCH 28/29] PM FIX: convert TI io_p2v() usage to OMAP2_IO_ADDRESS() Russell King - ARM Linux 0 siblings, 2 replies; 37+ messages in thread From: Kevin Hilman @ 2008-09-11 12:34 UTC (permalink / raw) To: linux-omap; +Cc: Kevin Hilman Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com> --- arch/arm/mach-omap2/pm34xx.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 5242ba0..7436332 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -222,7 +222,7 @@ static void restore_table_entry(void) u32 previous_value, control_reg_value; u32 *address; /* Get virtual address of SCRATCHPAD */ - scratchpad_address = (u32 *) io_p2v(SCRATCHPAD); + scratchpad_address = (u32 *) OMAP2_IO_ADDRESS(SCRATCHPAD); /* Get address of entry that was modified */ address = (u32 *) *(scratchpad_address + TABLE_ADDRESS_OFFSET); /* Get the previous value which needs to be restored */ @@ -924,7 +924,7 @@ void clear_scratchpad_contents(void) u32 max_offset = SCRATHPAD_ROM_OFFSET; u32 offset = 0; u32 v; - u32 v_addr = io_p2v(SCRATCHPAD_ROM); + u32 v_addr = OMAP2_IO_ADDRESS(SCRATCHPAD_ROM); if (__raw_readl(OMAP3430_PRM_RSTST) & 0x1) { for ( ; offset <= max_offset; offset += 0x4) __raw_writel(0x0, (v_addr + offset)); @@ -942,7 +942,7 @@ void save_scratchpad_contents(void) u32 *sdram_context_address; /* Get virtual address of SCRATCHPAD */ - scratchpad_address = (u32 *) io_p2v(SCRATCHPAD); + scratchpad_address = (u32 *) OMAP2_IO_ADDRESS(SCRATCHPAD); /* Get Restore pointer to jump to while waking up from OFF */ restore_address = get_restore_pointer(); /* Convert it to physical address */ -- 1.6.0 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 29/29] PM: serial: ensure padconf wake-enable bits are set for UARTs 2008-09-11 12:34 ` [PATCH 28/29] PM FIX: convert TI io_p2v() usage to OMAP2_IO_ADDRESS() Kevin Hilman @ 2008-09-11 12:34 ` Kevin Hilman 2008-09-11 13:05 ` [PATCH 28/29] PM FIX: convert TI io_p2v() usage to OMAP2_IO_ADDRESS() Russell King - ARM Linux 1 sibling, 0 replies; 37+ messages in thread From: Kevin Hilman @ 2008-09-11 12:34 UTC (permalink / raw) To: linux-omap; +Cc: Kevin Hilman FIXME: there needs to be a platform specific way to set which padconf regs are actually used, as the current ones are specific to 3430SDP. Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com> --- arch/arm/mach-omap2/serial.c | 9 +++++++++ 1 files changed, 9 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index c189cc9..96e3165 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -298,6 +298,15 @@ void __init omap_serial_init(void) v = __raw_readl(omap_uart_wk_en[i]); v |= omap_uart_wk_bit[i]; __raw_writel(v, omap_uart_wk_en[i]); + + /* Ensure PADCONF wake-enables are set */ + if (cpu_is_omap34xx() && omap34xx_uart_padconf[i]) { + u16 w; + + w = omap_ctrl_readw(omap34xx_uart_padconf[i]); + w |= 0x4000; + omap_ctrl_writew(w, omap34xx_uart_padconf[i]); + } } omap_serial_kick(); -- 1.6.0 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [PATCH 28/29] PM FIX: convert TI io_p2v() usage to OMAP2_IO_ADDRESS() 2008-09-11 12:34 ` [PATCH 28/29] PM FIX: convert TI io_p2v() usage to OMAP2_IO_ADDRESS() Kevin Hilman 2008-09-11 12:34 ` [PATCH 29/29] PM: serial: ensure padconf wake-enable bits are set for UARTs Kevin Hilman @ 2008-09-11 13:05 ` Russell King - ARM Linux 1 sibling, 0 replies; 37+ messages in thread From: Russell King - ARM Linux @ 2008-09-11 13:05 UTC (permalink / raw) To: Kevin Hilman; +Cc: linux-omap On Thu, Sep 11, 2008 at 03:34:12PM +0300, Kevin Hilman wrote: > Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com> > --- > arch/arm/mach-omap2/pm34xx.c | 6 +++--- > 1 files changed, 3 insertions(+), 3 deletions(-) > > diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c > index 5242ba0..7436332 100644 > --- a/arch/arm/mach-omap2/pm34xx.c > +++ b/arch/arm/mach-omap2/pm34xx.c > @@ -222,7 +222,7 @@ static void restore_table_entry(void) > u32 previous_value, control_reg_value; > u32 *address; > /* Get virtual address of SCRATCHPAD */ > - scratchpad_address = (u32 *) io_p2v(SCRATCHPAD); > + scratchpad_address = (u32 *) OMAP2_IO_ADDRESS(SCRATCHPAD); scratchpad_address should be u32 __iomem *, and that cast shouldn't be there. > /* Get address of entry that was modified */ > address = (u32 *) *(scratchpad_address + TABLE_ADDRESS_OFFSET); > /* Get the previous value which needs to be restored */ > @@ -924,7 +924,7 @@ void clear_scratchpad_contents(void) > u32 max_offset = SCRATHPAD_ROM_OFFSET; > u32 offset = 0; > u32 v; > - u32 v_addr = io_p2v(SCRATCHPAD_ROM); > + u32 v_addr = OMAP2_IO_ADDRESS(SCRATCHPAD_ROM); Ditto. > if (__raw_readl(OMAP3430_PRM_RSTST) & 0x1) { > for ( ; offset <= max_offset; offset += 0x4) > __raw_writel(0x0, (v_addr + offset)); > @@ -942,7 +942,7 @@ void save_scratchpad_contents(void) > u32 *sdram_context_address; > > /* Get virtual address of SCRATCHPAD */ > - scratchpad_address = (u32 *) io_p2v(SCRATCHPAD); > + scratchpad_address = (u32 *) OMAP2_IO_ADDRESS(SCRATCHPAD); Ditto. ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH 15/29] OMAP3: PM: Move serial console check from omap3_can_sleep to idle loop 2008-09-11 12:33 ` [PATCH 15/29] OMAP3: PM: Move serial console check from omap3_can_sleep to idle loop Kevin Hilman 2008-09-11 12:34 ` [PATCH 16/29] OMAP3: PM: Remove static keyword from _omap_sram_idle declaration Kevin Hilman @ 2008-09-11 14:38 ` Daniel Stone 1 sibling, 0 replies; 37+ messages in thread From: Daniel Stone @ 2008-09-11 14:38 UTC (permalink / raw) To: ext Kevin Hilman; +Cc: linux-omap, Jouni Hogander [-- Attachment #1: Type: text/plain, Size: 163 bytes --] On Thu, Sep 11, 2008 at 03:33:59PM +0300, ext Kevin Hilman wrote: > Signed-off-by: Git administrator <gitowner@stego.research.nokia.com> Oops. :) Cheers, Daniel [-- Attachment #2: Digital signature --] [-- Type: application/pgp-signature, Size: 197 bytes --] ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH 0/29] PM: proposed branch for PM collaboration 2008-09-11 12:31 [PATCH 0/29] PM: proposed branch for PM collaboration Kevin Hilman 2008-09-11 12:33 ` [PATCH 01/29] PM: Dynamic GPIO clock handling Kevin Hilman @ 2008-09-11 17:40 ` Tony Lindgren 2008-09-12 3:44 ` Rajendra Nayak 2008-09-16 13:14 ` Kevin Hilman 3 siblings, 0 replies; 37+ messages in thread From: Tony Lindgren @ 2008-09-11 17:40 UTC (permalink / raw) To: Kevin Hilman; +Cc: linux-omap * Kevin Hilman <khilman@deeprootsystems.com> [080911 05:32]: > Hello, > > The following patchset is an attempt to collect the various PM patches > that have been flowing around, and organize them into one branch to be > used for further collaboration on PM development, in particular > OFF-mode support. > > It is currently a collection of proposed patches[1] from TI and > various other patches from Nokia and others to get retention, > OFF-mode, CPUidle etc. working in the linux-omap tree. > > This series is nowhere near ready for merging into linux-omap, but > will be useful for discussion and collaboration on getting the various > PM features working at the head of the linux-omap tree, and a place > where cleanup and rework efforts can be focused. > > If there are no major objections, I will create a branch in linux-omap > git and commit this series there. As collaboration continues, I will > continue to collect and update patches, fix problems and rebase onto > the HEAD of linux-omap. > > The goal of this branch is only to facilitate the rework and cleanup > of the PM code so it can be merged into linux-omap. Then, the branch > will disappear and work can be focused again on the HEAD of > linux-omap. Sounds good to me. It also makes it easier for people to test it. Tony > It has currently been tested with a minimal config on 3430SDP, and > OFF-mode is hit in suspend. In order to hit suspend: > > echo 1 > /sys/power/voltage_off_while_idle > echo 1 > /sys/power/gpio_clocks_off_while_idle > echo 1 > /sys/power/uart_clocks_off_while_idle > echo mem > /sys/power/state > > Kevin > > > [1] This series is roughly based on the following: > > Jouni Hogander, Tero Kristo > [PATCH 0/4] Refreshed PM workaround patches 2 -- 15 Aug > > Rajendra Nayak: > [PATCH 00/11] OMAP3 CPUidle patches - ver 2 -- 18 July > > As well as several patches/hacks/cleanups that have not yet been > posted to the list. > > Also, there have been newer versions of the CPUidle patches that have > been reviewed on the list, but do not apply for various reasons. As > soon as they are rebased and updated versions of those are available, > I will integrate them. > -- > To unsubscribe from this list: send the line "unsubscribe linux-omap" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 37+ messages in thread
* RE: [PATCH 0/29] PM: proposed branch for PM collaboration 2008-09-11 12:31 [PATCH 0/29] PM: proposed branch for PM collaboration Kevin Hilman 2008-09-11 12:33 ` [PATCH 01/29] PM: Dynamic GPIO clock handling Kevin Hilman 2008-09-11 17:40 ` [PATCH 0/29] PM: proposed branch for PM collaboration Tony Lindgren @ 2008-09-12 3:44 ` Rajendra Nayak 2008-09-16 13:14 ` Kevin Hilman 3 siblings, 0 replies; 37+ messages in thread From: Rajendra Nayak @ 2008-09-12 3:44 UTC (permalink / raw) To: 'Kevin Hilman', linux-omap I don't see this patch from Tero/Jouni as part of this set.. [PATCH 4/4] 34XX: PM: Workaround to enable autoidle for clocks and plls. Was this patch dropped? or is it now part of some other patch? > -----Original Message----- > From: linux-omap-owner@vger.kernel.org > [mailto:linux-omap-owner@vger.kernel.org] On Behalf Of Kevin Hilman > Sent: Thursday, September 11, 2008 6:02 PM > To: linux-omap@vger.kernel.org > Subject: [PATCH 0/29] PM: proposed branch for PM collaboration > > Hello, > > The following patchset is an attempt to collect the various PM patches > that have been flowing around, and organize them into one branch to be > used for further collaboration on PM development, in particular > OFF-mode support. > > It is currently a collection of proposed patches[1] from TI and > various other patches from Nokia and others to get retention, > OFF-mode, CPUidle etc. working in the linux-omap tree. > > This series is nowhere near ready for merging into linux-omap, but > will be useful for discussion and collaboration on getting the various > PM features working at the head of the linux-omap tree, and a place > where cleanup and rework efforts can be focused. > > If there are no major objections, I will create a branch in linux-omap > git and commit this series there. As collaboration continues, I will > continue to collect and update patches, fix problems and rebase onto > the HEAD of linux-omap. > > The goal of this branch is only to facilitate the rework and cleanup > of the PM code so it can be merged into linux-omap. Then, the branch > will disappear and work can be focused again on the HEAD of > linux-omap. > > It has currently been tested with a minimal config on 3430SDP, and > OFF-mode is hit in suspend. In order to hit suspend: > > echo 1 > /sys/power/voltage_off_while_idle > echo 1 > /sys/power/gpio_clocks_off_while_idle > echo 1 > /sys/power/uart_clocks_off_while_idle > echo mem > /sys/power/state > > Kevin > > > [1] This series is roughly based on the following: > > Jouni Hogander, Tero Kristo > [PATCH 0/4] Refreshed PM workaround patches 2 -- 15 Aug > > Rajendra Nayak: > [PATCH 00/11] OMAP3 CPUidle patches - ver 2 -- 18 July > > As well as several patches/hacks/cleanups that have not yet been > posted to the list. > > Also, there have been newer versions of the CPUidle patches that have > been reviewed on the list, but do not apply for various reasons. As > soon as they are rebased and updated versions of those are available, > I will integrate them. > -- > To unsubscribe from this list: send the line "unsubscribe > linux-omap" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > > ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH 0/29] PM: proposed branch for PM collaboration 2008-09-11 12:31 [PATCH 0/29] PM: proposed branch for PM collaboration Kevin Hilman ` (2 preceding siblings ...) 2008-09-12 3:44 ` Rajendra Nayak @ 2008-09-16 13:14 ` Kevin Hilman 2008-09-16 18:17 ` Koen Kooi 3 siblings, 1 reply; 37+ messages in thread From: Kevin Hilman @ 2008-09-16 13:14 UTC (permalink / raw) To: linux-omap Kevin Hilman wrote: > Hello, > > The following patchset is an attempt to collect the various PM patches > that have been flowing around, and organize them into one branch to be > used for further collaboration on PM development, in particular > OFF-mode support. This series has been rebased onto today's OMAP git, and pushed as branch pm-0. I will now start collecting more recent versions of these patches and newer patches sent to the list for the next version of the branch. Kevin > It is currently a collection of proposed patches[1] from TI and > various other patches from Nokia and others to get retention, > OFF-mode, CPUidle etc. working in the linux-omap tree. > > This series is nowhere near ready for merging into linux-omap, but > will be useful for discussion and collaboration on getting the various > PM features working at the head of the linux-omap tree, and a place > where cleanup and rework efforts can be focused. > > If there are no major objections, I will create a branch in linux-omap > git and commit this series there. As collaboration continues, I will > continue to collect and update patches, fix problems and rebase onto > the HEAD of linux-omap. > > The goal of this branch is only to facilitate the rework and cleanup > of the PM code so it can be merged into linux-omap. Then, the branch > will disappear and work can be focused again on the HEAD of > linux-omap. > > It has currently been tested with a minimal config on 3430SDP, and > OFF-mode is hit in suspend. In order to hit suspend: > > echo 1 > /sys/power/voltage_off_while_idle > echo 1 > /sys/power/gpio_clocks_off_while_idle > echo 1 > /sys/power/uart_clocks_off_while_idle > echo mem > /sys/power/state > > Kevin > > > [1] This series is roughly based on the following: > > Jouni Hogander, Tero Kristo > [PATCH 0/4] Refreshed PM workaround patches 2 -- 15 Aug > > Rajendra Nayak: > [PATCH 00/11] OMAP3 CPUidle patches - ver 2 -- 18 July > > As well as several patches/hacks/cleanups that have not yet been > posted to the list. > > Also, there have been newer versions of the CPUidle patches that have > been reviewed on the list, but do not apply for various reasons. As > soon as they are rebased and updated versions of those are available, > I will integrate them. ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH 0/29] PM: proposed branch for PM collaboration 2008-09-16 13:14 ` Kevin Hilman @ 2008-09-16 18:17 ` Koen Kooi 2008-09-17 13:18 ` Kevin Hilman 0 siblings, 1 reply; 37+ messages in thread From: Koen Kooi @ 2008-09-16 18:17 UTC (permalink / raw) To: Kevin Hilman; +Cc: linux-omap [-- Attachment #1: Type: text/plain, Size: 2738 bytes --] Op 16 sep 2008, om 15:14 heeft Kevin Hilman het volgende geschreven: > Kevin Hilman wrote: >> Hello, >> The following patchset is an attempt to collect the various PM >> patches >> that have been flowing around, and organize them into one branch to >> be >> used for further collaboration on PM development, in particular >> OFF-mode support. > > This series has been rebased onto today's OMAP git, and pushed as > branch pm-0. > > I will now start collecting more recent versions of these patches > and newer patches sent to the list for the next version of the branch. What are your plans for including the omap3 cpufreq patchset? regards, Koen > > > Kevin > >> It is currently a collection of proposed patches[1] from TI and >> various other patches from Nokia and others to get retention, >> OFF-mode, CPUidle etc. working in the linux-omap tree. >> This series is nowhere near ready for merging into linux-omap, but >> will be useful for discussion and collaboration on getting the >> various >> PM features working at the head of the linux-omap tree, and a place >> where cleanup and rework efforts can be focused. If there are no >> major objections, I will create a branch in linux-omap >> git and commit this series there. As collaboration continues, I will >> continue to collect and update patches, fix problems and rebase onto >> the HEAD of linux-omap. The goal of this branch is only to >> facilitate the rework and cleanup >> of the PM code so it can be merged into linux-omap. Then, the branch >> will disappear and work can be focused again on the HEAD of >> linux-omap. >> It has currently been tested with a minimal config on 3430SDP, and >> OFF-mode is hit in suspend. In order to hit suspend: >> echo 1 > /sys/power/voltage_off_while_idle >> echo 1 > /sys/power/gpio_clocks_off_while_idle echo >> 1 > /sys/power/uart_clocks_off_while_idle echo mem > /sys/power/ >> state >> Kevin >> [1] This series is roughly based on the following: >> Jouni Hogander, Tero Kristo >> [PATCH 0/4] Refreshed PM workaround patches 2 -- 15 Aug >> Rajendra Nayak: >> [PATCH 00/11] OMAP3 CPUidle patches - ver 2 -- 18 July >> As well as several patches/hacks/cleanups that have not yet been >> posted to the list. >> Also, there have been newer versions of the CPUidle patches that have >> been reviewed on the list, but do not apply for various reasons. As >> soon as they are rebased and updated versions of those are available, >> I will integrate them. > > -- > To unsubscribe from this list: send the line "unsubscribe linux- > omap" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > [-- Attachment #2: This is a digitally signed message part --] [-- Type: application/pgp-signature, Size: 186 bytes --] ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH 0/29] PM: proposed branch for PM collaboration 2008-09-16 18:17 ` Koen Kooi @ 2008-09-17 13:18 ` Kevin Hilman 0 siblings, 0 replies; 37+ messages in thread From: Kevin Hilman @ 2008-09-17 13:18 UTC (permalink / raw) To: Koen Kooi; +Cc: linux-omap Koen Kooi <k.kooi@student.utwente.nl> writes: > Op 16 sep 2008, om 15:14 heeft Kevin Hilman het volgende geschreven: > >> Kevin Hilman wrote: >>> Hello, >>> The following patchset is an attempt to collect the various PM >>> patches >>> that have been flowing around, and organize them into one branch to >>> be >>> used for further collaboration on PM development, in particular >>> OFF-mode support. >> >> This series has been rebased onto today's OMAP git, and pushed as >> branch pm-0. >> >> I will now start collecting more recent versions of these patches >> and newer patches sent to the list for the next version of the >> branch. > > What are your plans for including the omap3 cpufreq patchset? > The current CPUfreq patcheset has dependencies TI's shared resource framework (SRF), which in turn depends on the new OMAP PM layer. Neither of which are included in the current PM branch. My current plan is to get off-mode in suspend and dynamic idle stabilized along with CPUidle before integrating the new PM layer and SRF. Kevin > >> >> >> Kevin >> >>> It is currently a collection of proposed patches[1] from TI and >>> various other patches from Nokia and others to get retention, >>> OFF-mode, CPUidle etc. working in the linux-omap tree. >>> This series is nowhere near ready for merging into linux-omap, but >>> will be useful for discussion and collaboration on getting the >>> various >>> PM features working at the head of the linux-omap tree, and a place >>> where cleanup and rework efforts can be focused. If there are no >>> major objections, I will create a branch in linux-omap >>> git and commit this series there. As collaboration continues, I will >>> continue to collect and update patches, fix problems and rebase onto >>> the HEAD of linux-omap. The goal of this branch is only to >>> facilitate the rework and cleanup >>> of the PM code so it can be merged into linux-omap. Then, the branch >>> will disappear and work can be focused again on the HEAD of >>> linux-omap. >>> It has currently been tested with a minimal config on 3430SDP, and >>> OFF-mode is hit in suspend. In order to hit suspend: >>> echo 1 > /sys/power/voltage_off_while_idle >>> echo 1 > /sys/power/gpio_clocks_off_while_idle echo >>> 1 > /sys/power/uart_clocks_off_while_idle echo mem > /sys/power/ >>> state >>> Kevin >>> [1] This series is roughly based on the following: >>> Jouni Hogander, Tero Kristo >>> [PATCH 0/4] Refreshed PM workaround patches 2 -- 15 Aug >>> Rajendra Nayak: >>> [PATCH 00/11] OMAP3 CPUidle patches - ver 2 -- 18 July >>> As well as several patches/hacks/cleanups that have not yet been >>> posted to the list. >>> Also, there have been newer versions of the CPUidle patches that have >>> been reviewed on the list, but do not apply for various reasons. As >>> soon as they are rebased and updated versions of those are available, >>> I will integrate them. >> >> -- >> To unsubscribe from this list: send the line "unsubscribe linux- >> omap" in >> the body of a message to majordomo@vger.kernel.org >> More majordomo info at http://vger.kernel.org/majordomo-info.html >> ^ permalink raw reply [flat|nested] 37+ messages in thread
end of thread, other threads:[~2008-09-17 13:18 UTC | newest] Thread overview: 37+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-09-11 12:31 [PATCH 0/29] PM: proposed branch for PM collaboration Kevin Hilman 2008-09-11 12:33 ` [PATCH 01/29] PM: Dynamic GPIO clock handling Kevin Hilman 2008-09-11 12:33 ` [PATCH 02/29] Added sleep support to UART Kevin Hilman 2008-09-11 12:33 ` [PATCH 03/29] PM debug support for 34xx Kevin Hilman 2008-09-11 12:33 ` [PATCH 04/29] Sysfs interface for controlling suspend states + set_pwrdm_state fix Kevin Hilman 2008-09-11 12:33 ` [PATCH 05/29] Basic cpuidle driver Kevin Hilman 2008-09-11 12:33 ` [PATCH 06/29] per/neon and core handling in idle Kevin Hilman 2008-09-11 12:33 ` [PATCH 07/29] menuconfig updates for cpuidle Kevin Hilman 2008-09-11 12:33 ` [PATCH 08/29] scratchpad contents Kevin Hilman 2008-09-11 12:33 ` [PATCH 09/29] mpu off state enabled Kevin Hilman 2008-09-11 12:33 ` [PATCH 10/29] gpmc context save/restore Kevin Hilman 2008-09-11 12:33 ` [PATCH 11/29] serial " Kevin Hilman 2008-09-11 12:33 ` [PATCH 12/29] gpio " Kevin Hilman 2008-09-11 12:33 ` [PATCH 13/29] i2c " Kevin Hilman 2008-09-11 12:33 ` [PATCH 14/29] CORE " Kevin Hilman 2008-09-11 12:33 ` [PATCH 15/29] OMAP3: PM: Move serial console check from omap3_can_sleep to idle loop Kevin Hilman 2008-09-11 12:34 ` [PATCH 16/29] OMAP3: PM: Remove static keyword from _omap_sram_idle declaration Kevin Hilman 2008-09-11 12:34 ` [PATCH 17/29] OMAP3: PM: Remove unneeded code from traditional pm_idle loop Kevin Hilman 2008-09-11 12:34 ` [PATCH 18/29] OMAP3: PM: Do not build pm_idle loop if cpuidle is used Kevin Hilman 2008-09-11 12:34 ` [PATCH 19/29] OMAP3: Do not set mpu, core, neon states " Kevin Hilman 2008-09-11 12:34 ` [PATCH 20/29] OMAP3: PM: Fixed header paths in include statements Kevin Hilman 2008-09-11 12:34 ` [PATCH 21/29] OMAP3: PM: Remove unneeded code from suspend Kevin Hilman 2008-09-11 12:34 ` [PATCH 22/29] DMA context save / restore Kevin Hilman 2008-09-11 12:34 ` [PATCH 23/29] OMAP3: PM: Add new Kconfig option to enable/disable off mode Kevin Hilman 2008-09-11 12:34 ` [PATCH 24/29] OMAP3SDP: Add new config for off mode testing Kevin Hilman 2008-09-11 12:34 ` [PATCH 25/29] OMAP3: Remove CONFIG_OMAP_SYSOFFMODE flag Kevin Hilman 2008-09-11 12:34 ` [PATCH 26/29] OMAP: Sysfs interface for enabling voltage off in idle Kevin Hilman 2008-09-11 12:34 ` [PATCH 27/29] OMAP3: OFF command integration Kevin Hilman 2008-09-11 12:34 ` [PATCH 28/29] PM FIX: convert TI io_p2v() usage to OMAP2_IO_ADDRESS() Kevin Hilman 2008-09-11 12:34 ` [PATCH 29/29] PM: serial: ensure padconf wake-enable bits are set for UARTs Kevin Hilman 2008-09-11 13:05 ` [PATCH 28/29] PM FIX: convert TI io_p2v() usage to OMAP2_IO_ADDRESS() Russell King - ARM Linux 2008-09-11 14:38 ` [PATCH 15/29] OMAP3: PM: Move serial console check from omap3_can_sleep to idle loop Daniel Stone 2008-09-11 17:40 ` [PATCH 0/29] PM: proposed branch for PM collaboration Tony Lindgren 2008-09-12 3:44 ` Rajendra Nayak 2008-09-16 13:14 ` Kevin Hilman 2008-09-16 18:17 ` Koen Kooi 2008-09-17 13:18 ` Kevin Hilman
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox