* [PATCH 05/11] scratchpad contents
@ 2008-07-01 14:16 Rajendra Nayak
2008-07-02 12:14 ` Högander Jouni
0 siblings, 1 reply; 4+ messages in thread
From: Rajendra Nayak @ 2008-07-01 14:16 UTC (permalink / raw)
To: linux-omap
This patch populates the scratchpad
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
---
arch/arm/mach-omap2/pm.h | 7 +
arch/arm/mach-omap2/pm34xx.c | 170 +++++++++++++++++++++++++++++++++++++++-
arch/arm/mach-omap2/sleep34xx.S | 8 -
include/asm-arm/arch-omap/pm.h | 4
4 files changed, 182 insertions(+), 7 deletions(-)
Index: linux-omap-2.6/arch/arm/mach-omap2/pm.h
===================================================================
--- linux-omap-2.6.orig/arch/arm/mach-omap2/pm.h 2008-07-01 17:21:12.738682737 +0530
+++ linux-omap-2.6/arch/arm/mach-omap2/pm.h 2008-07-01 17:21:12.783681306 +0530
@@ -20,6 +20,13 @@ extern unsigned short enable_dyn_sleep;
extern unsigned short clocks_off_while_idle;
extern atomic_t sleep_block;
+#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;
Index: linux-omap-2.6/arch/arm/mach-omap2/pm34xx.c
===================================================================
--- linux-omap-2.6.orig/arch/arm/mach-omap2/pm34xx.c 2008-07-01 17:21:12.761682006 +0530
+++ linux-omap-2.6/arch/arm/mach-omap2/pm34xx.c 2008-07-01 17:22:24.120412909 +0530
@@ -30,6 +30,9 @@
#include <asm/arch/clockdomain.h>
#include <asm/arch/powerdomain.h>
#include <asm/arch/common.h>
+#include <asm/arch/sdrc.h>
+#include <asm/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);
void (*_omap_sram_idle)(u32 *addr, int save_state, int disable_clocks);
@@ -176,6 +188,35 @@ static irqreturn_t prcm_interrupt_handle
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
@@ -196,13 +237,19 @@ 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");
return;
}
- _omap_sram_idle(NULL, save_state, clocks_off_while_idle);
+ _omap_sram_idle(context_mem, save_state, clocks_off_while_idle);
+ /* Restore table entry modified during MMU restoration */
+ if (pwrdm_read_prev_pwrst(mpu_pwrdm) == 0x0)
+ restore_table_entry();
}
static int omap3_fclks_active(void)
@@ -593,7 +640,10 @@ static int __init pwrdms_setup(struct po
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))
@@ -659,5 +709,121 @@ err2:
list_del(&pwrst->node);
kfree(pwrst);
}
+
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;
+}
+
Index: linux-omap-2.6/arch/arm/mach-omap2/sleep34xx.S
===================================================================
--- linux-omap-2.6.orig/arch/arm/mach-omap2/sleep34xx.S 2008-07-01 17:21:09.043800223 +0530
+++ linux-omap-2.6/arch/arm/mach-omap2/sleep34xx.S 2008-07-01 17:22:04.018052152 +0530
@@ -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 */
Index: linux-omap-2.6/include/asm-arm/arch-omap/pm.h
===================================================================
--- linux-omap-2.6.orig/include/asm-arm/arch-omap/pm.h 2008-07-01 17:21:09.043800223 +0530
+++ linux-omap-2.6/include/asm-arm/arch-omap/pm.h 2008-07-01 17:21:12.785681242 +0530
@@ -153,6 +153,10 @@ extern void omap1510_idle_loop_suspend(v
extern void omap1610_idle_loop_suspend(void);
extern void omap242x_idle_loop_suspend(void);
extern void omap243x_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;
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 05/11] scratchpad contents
2008-07-01 14:16 [PATCH 05/11] scratchpad contents Rajendra Nayak
@ 2008-07-02 12:14 ` Högander Jouni
0 siblings, 0 replies; 4+ messages in thread
From: Högander Jouni @ 2008-07-02 12:14 UTC (permalink / raw)
To: ext Rajendra Nayak; +Cc: linux-omap
"ext Rajendra Nayak" <rnayak@ti.com> writes:
> This patch populates the scratchpad
>
> Signed-off-by: Rajendra Nayak <rnayak@ti.com>
>
> ---
> arch/arm/mach-omap2/pm.h | 7 +
> arch/arm/mach-omap2/pm34xx.c | 170 +++++++++++++++++++++++++++++++++++++++-
> arch/arm/mach-omap2/sleep34xx.S | 8 -
> include/asm-arm/arch-omap/pm.h | 4
> 4 files changed, 182 insertions(+), 7 deletions(-)
>
> Index: linux-omap-2.6/arch/arm/mach-omap2/pm.h
> ===================================================================
> --- linux-omap-2.6.orig/arch/arm/mach-omap2/pm.h 2008-07-01 17:21:12.738682737 +0530
> +++ linux-omap-2.6/arch/arm/mach-omap2/pm.h 2008-07-01 17:21:12.783681306 +0530
> @@ -20,6 +20,13 @@ extern unsigned short enable_dyn_sleep;
> extern unsigned short clocks_off_while_idle;
> extern atomic_t sleep_block;
>
> +#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;
> Index: linux-omap-2.6/arch/arm/mach-omap2/pm34xx.c
> ===================================================================
> --- linux-omap-2.6.orig/arch/arm/mach-omap2/pm34xx.c 2008-07-01 17:21:12.761682006 +0530
> +++ linux-omap-2.6/arch/arm/mach-omap2/pm34xx.c 2008-07-01 17:22:24.120412909 +0530
> @@ -30,6 +30,9 @@
> #include <asm/arch/clockdomain.h>
> #include <asm/arch/powerdomain.h>
> #include <asm/arch/common.h>
> +#include <asm/arch/sdrc.h>
> +#include <asm/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);
>
> void (*_omap_sram_idle)(u32 *addr, int save_state, int disable_clocks);
> @@ -176,6 +188,35 @@ static irqreturn_t prcm_interrupt_handle
> 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
> @@ -196,13 +237,19 @@ 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");
> return;
> }
>
> - _omap_sram_idle(NULL, save_state, clocks_off_while_idle);
> + _omap_sram_idle(context_mem, save_state, clocks_off_while_idle);
> + /* Restore table entry modified during MMU restoration */
> + if (pwrdm_read_prev_pwrst(mpu_pwrdm) == 0x0)
> + restore_table_entry();
> }
>
> static int omap3_fclks_active(void)
> @@ -593,7 +640,10 @@ static int __init pwrdms_setup(struct po
> 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;
I think writing these states here should be behind #ifdef
CONFIG_CPU_IDLE at least what comest to mpu, neon and core. Then as we
have srf in l-o tree, rest of the pwrdm states should be written in
that code. This is basically for traditional pm_idle loop. Anyway
until srf is in tree you could write other than mpu, neon and core
states here.
> list_add(&pwrst->node, &pwrst_list);
>
> if (pwrdm_has_hdwr_sar(pwrdm))
> @@ -659,5 +709,121 @@ err2:
> list_del(&pwrst->node);
> kfree(pwrst);
> }
> +
> 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;
> +}
> +
> Index: linux-omap-2.6/arch/arm/mach-omap2/sleep34xx.S
> ===================================================================
> --- linux-omap-2.6.orig/arch/arm/mach-omap2/sleep34xx.S 2008-07-01 17:21:09.043800223 +0530
> +++ linux-omap-2.6/arch/arm/mach-omap2/sleep34xx.S 2008-07-01 17:22:04.018052152 +0530
> @@ -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 */
> Index: linux-omap-2.6/include/asm-arm/arch-omap/pm.h
> ===================================================================
> --- linux-omap-2.6.orig/include/asm-arm/arch-omap/pm.h 2008-07-01 17:21:09.043800223 +0530
> +++ linux-omap-2.6/include/asm-arm/arch-omap/pm.h 2008-07-01 17:21:12.785681242 +0530
> @@ -153,6 +153,10 @@ extern void omap1510_idle_loop_suspend(v
> extern void omap1610_idle_loop_suspend(void);
> extern void omap242x_idle_loop_suspend(void);
> extern void omap243x_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;
>
> --
> 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
>
>
--
Jouni Högander
--
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] 4+ messages in thread
* [PATCH 05/11] scratchpad contents
@ 2008-07-18 13:19 Rajendra Nayak
0 siblings, 0 replies; 4+ messages in thread
From: Rajendra Nayak @ 2008-07-18 13:19 UTC (permalink / raw)
To: linux-omap
This patch populates the scratchpad
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
---
arch/arm/mach-omap2/pm.h | 7 +
arch/arm/mach-omap2/pm34xx.c | 170 +++++++++++++++++++++++++++++++++++++++-
arch/arm/mach-omap2/sleep34xx.S | 8 -
include/asm-arm/arch-omap/pm.h | 4
4 files changed, 182 insertions(+), 7 deletions(-)
Index: linux-omap-2.6/arch/arm/mach-omap2/pm.h
===================================================================
--- linux-omap-2.6.orig/arch/arm/mach-omap2/pm.h 2008-07-01 17:21:12.738682737 +0530
+++ linux-omap-2.6/arch/arm/mach-omap2/pm.h 2008-07-01 17:21:12.783681306 +0530
@@ -20,6 +20,13 @@ extern unsigned short enable_dyn_sleep;
extern unsigned short clocks_off_while_idle;
extern atomic_t sleep_block;
+#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;
Index: linux-omap-2.6/arch/arm/mach-omap2/pm34xx.c
===================================================================
--- linux-omap-2.6.orig/arch/arm/mach-omap2/pm34xx.c 2008-07-01 17:21:12.761682006 +0530
+++ linux-omap-2.6/arch/arm/mach-omap2/pm34xx.c 2008-07-01 17:22:24.120412909 +0530
@@ -30,6 +30,9 @@
#include <asm/arch/clockdomain.h>
#include <asm/arch/powerdomain.h>
#include <asm/arch/common.h>
+#include <asm/arch/sdrc.h>
+#include <asm/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);
void (*_omap_sram_idle)(u32 *addr, int save_state, int disable_clocks);
@@ -176,6 +188,35 @@ static irqreturn_t prcm_interrupt_handle
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
@@ -196,13 +237,19 @@ 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");
return;
}
- _omap_sram_idle(NULL, save_state, clocks_off_while_idle);
+ _omap_sram_idle(context_mem, save_state, clocks_off_while_idle);
+ /* Restore table entry modified during MMU restoration */
+ if (pwrdm_read_prev_pwrst(mpu_pwrdm) == 0x0)
+ restore_table_entry();
}
static int omap3_fclks_active(void)
@@ -593,7 +640,10 @@ static int __init pwrdms_setup(struct po
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))
@@ -659,5 +709,121 @@ err2:
list_del(&pwrst->node);
kfree(pwrst);
}
+
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;
+}
+
Index: linux-omap-2.6/arch/arm/mach-omap2/sleep34xx.S
===================================================================
--- linux-omap-2.6.orig/arch/arm/mach-omap2/sleep34xx.S 2008-07-01 17:21:09.043800223 +0530
+++ linux-omap-2.6/arch/arm/mach-omap2/sleep34xx.S 2008-07-01 17:22:04.018052152 +0530
@@ -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 */
Index: linux-omap-2.6/include/asm-arm/arch-omap/pm.h
===================================================================
--- linux-omap-2.6.orig/include/asm-arm/arch-omap/pm.h 2008-07-01 17:21:09.043800223 +0530
+++ linux-omap-2.6/include/asm-arm/arch-omap/pm.h 2008-07-01 17:21:12.785681242 +0530
@@ -153,6 +153,10 @@ extern void omap1510_idle_loop_suspend(v
extern void omap1610_idle_loop_suspend(void);
extern void omap242x_idle_loop_suspend(void);
extern void omap243x_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;
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 05/11] scratchpad contents
@ 2008-08-06 13:14 Rajendra Nayak
0 siblings, 0 replies; 4+ messages in thread
From: Rajendra Nayak @ 2008-08-06 13:14 UTC (permalink / raw)
To: linux-omap
This patch populates the scratchpad
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
---
arch/arm/mach-omap2/pm.h | 7 +
arch/arm/mach-omap2/pm34xx.c | 168 +++++++++++++++++++++++++++++++++++++++-
arch/arm/mach-omap2/sleep34xx.S | 8 -
include/asm-arm/arch-omap/pm.h | 4
4 files changed, 180 insertions(+), 7 deletions(-)
Index: linux-omap-2.6/arch/arm/mach-omap2/pm.h
===================================================================
--- linux-omap-2.6.orig/arch/arm/mach-omap2/pm.h 2008-08-06 18:08:02.000000000
+0530
+++ linux-omap-2.6/arch/arm/mach-omap2/pm.h 2008-08-06 18:10:48.000000000 +0530
@@ -24,6 +24,13 @@ 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;
Index: linux-omap-2.6/arch/arm/mach-omap2/pm34xx.c
===================================================================
--- linux-omap-2.6.orig/arch/arm/mach-omap2/pm34xx.c 2008-08-06
18:09:48.000000000 +0530
+++ linux-omap-2.6/arch/arm/mach-omap2/pm34xx.c 2008-08-06 18:10:48.000000000
+0530
@@ -30,6 +30,9 @@
#include <asm/arch/clockdomain.h>
#include <asm/arch/powerdomain.h>
#include <asm/arch/common.h>
+#include <asm/arch/sdrc.h>
+#include <asm/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);
void (*_omap_sram_idle)(u32 *addr, int save_state, int disable_clocks);
@@ -176,6 +188,35 @@ static irqreturn_t prcm_interrupt_handle
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
@@ -196,13 +237,19 @@ 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");
return;
}
- _omap_sram_idle(NULL, save_state, clocks_off_while_idle);
+ _omap_sram_idle(context_mem, save_state, clocks_off_while_idle);
+ /* Restore table entry modified during MMU restoration */
+ if (pwrdm_read_prev_pwrst(mpu_pwrdm) == 0x0)
+ restore_table_entry();
}
static int omap3_fclks_active(void)
@@ -591,7 +638,10 @@ static int __init pwrdms_setup(struct po
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))
@@ -660,6 +710,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) |
Index: linux-omap-2.6/arch/arm/mach-omap2/sleep34xx.S
===================================================================
--- linux-omap-2.6.orig/arch/arm/mach-omap2/sleep34xx.S 2008-08-06
18:07:31.000000000 +0530
+++ linux-omap-2.6/arch/arm/mach-omap2/sleep34xx.S 2008-08-06
18:10:48.000000000 +0530
@@ -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 */
Index: linux-omap-2.6/include/asm-arm/arch-omap/pm.h
===================================================================
--- linux-omap-2.6.orig/include/asm-arm/arch-omap/pm.h 2008-08-06
18:07:31.000000000 +0530
+++ linux-omap-2.6/include/asm-arm/arch-omap/pm.h 2008-08-06 18:10:48.000000000
+0530
@@ -153,6 +153,10 @@ extern void omap1510_idle_loop_suspend(v
extern void omap1610_idle_loop_suspend(void);
extern void omap242x_idle_loop_suspend(void);
extern void omap243x_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;
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2008-08-06 13:15 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-07-01 14:16 [PATCH 05/11] scratchpad contents Rajendra Nayak
2008-07-02 12:14 ` Högander Jouni
-- strict thread matches above, loose matches on Subject: below --
2008-07-18 13:19 Rajendra Nayak
2008-08-06 13:14 Rajendra Nayak
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox