aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPer Fransson <per.xx.fransson@stericsson.com>2011-03-29 16:17:38 +0200
committerMichael BRANDT <michael.brandt@stericsson.com>2011-03-31 17:16:53 +0200
commit2f99a160060654d34c9914dd8b5a38a8c69e220d (patch)
tree79d3a120365d99d1f74d1805ce1c0828c10fb2dc
parent36af4ccc12ab702d4f164bf7d5306064bb10468d (diff)
U8500: Save and restore PRCMU registers for crashdump
ST-Ericsson ID: 329489 Change-Id: I237179f59453385d9b20fc3d83c91a8fea0a1979 Signed-off-by: Per Fransson <per.xx.fransson@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/19395 Reviewed-by: Michael BRANDT <michael.brandt@stericsson.com> Reviewed-by: Joakim AXELSSON <joakim.axelsson@stericsson.com>
-rw-r--r--board/st-ericsson/u8500/u8500.c23
-rw-r--r--cpu/arm_cortexa9/db8500/prcmu.c54
2 files changed, 41 insertions, 36 deletions
diff --git a/board/st-ericsson/u8500/u8500.c b/board/st-ericsson/u8500/u8500.c
index 0007759b5..da50c3f86 100644
--- a/board/st-ericsson/u8500/u8500.c
+++ b/board/st-ericsson/u8500/u8500.c
@@ -157,14 +157,6 @@ static int mcde_error;
*/
static volatile int data_init_flag = -1; /* -1 to get it into .data section */
-/*
- * Save the reset value of SDMMCCLK_REG to reuse it when
- * u-boot is restarted as crash kernel. Force it in .data
- * section by setting non-zero init value, to avoid overwriting the
- * value before we reuse it.
- */
-static volatile u32 sdmmcclk_init_value = 0xFFFFFFFF;
-
/* Get hold of gd pointer */
DECLARE_GLOBAL_DATA_PTR;
@@ -190,7 +182,6 @@ int board_init(void)
extern char _data_start[];
extern char _data_end[];
unsigned long data_len;
- u32 sdmmc_reg_val;
data_len = _data_end - _data_start;
if (++data_init_flag == 0) {
@@ -200,8 +191,6 @@ int board_init(void)
*/
memcpy(_idata_start, _data_start, data_len);
} else {
- /* save current sdmmc register value */
- sdmmc_reg_val = sdmmcclk_init_value;
/*
* restart, e.g. by kexec
* copy back .data section
@@ -209,8 +198,6 @@ int board_init(void)
memcpy(_data_start, _idata_start, data_len);
/* memcpy set data_init_flag back to zero */
++data_init_flag;
- /* restore sdmmc register value */
- sdmmcclk_init_value = sdmmc_reg_val;
}
/*
@@ -272,16 +259,6 @@ int board_mmc_init(bd_t *bis)
(void) bis; /* Parameter not used! */
- if (restarted()) {
- /*
- * SDMMCCLK might have been stopped before crash.
- * Reinitialize to boot value.
- */
- writel(sdmmcclk_init_value, PRCM_SDMMCCLK_MGT_REG);
- } else {
- sdmmcclk_init_value = readl(PRCM_SDMMCCLK_MGT_REG);
- }
-
dev = u8500_alloc_mmc_struct();
if (!dev)
return -1;
diff --git a/cpu/arm_cortexa9/db8500/prcmu.c b/cpu/arm_cortexa9/db8500/prcmu.c
index efc3fabf3..731cedfb8 100644
--- a/cpu/arm_cortexa9/db8500/prcmu.c
+++ b/cpu/arm_cortexa9/db8500/prcmu.c
@@ -237,6 +237,26 @@ int prcmu_i2c_write(u8 reg, u16 slave, u8 reg_data)
return -1;
}
+static int restarted = -1; /* -1 to get it into .data section */
+
+static struct clk_mgt_regs {
+ uint32_t addr;
+ uint32_t val;
+} clk_mgt_regs[] = {
+ {PRCM_PER1CLK_MGT_REG, 0},
+ {PRCM_PER2CLK_MGT_REG, 0},
+ {PRCM_PER3CLK_MGT_REG, 0},
+ /* PER4CLK does not exist */
+ {PRCM_PER5CLK_MGT_REG, 0},
+ {PRCM_PER6CLK_MGT_REG, 0},
+ /* Only exists in ED but is always ok to write to */
+ {PRCM_PER7CLK_MGT_REG, 0},
+ {PRCM_UARTCLK_MGT_REG, 0},
+ {PRCM_I2CCLK_MGT_REG, 0},
+ {PRCM_SDMMCCLK_MGT_REG, 0},
+ {0, 0}
+};
+
static void prcmu_enable(u32 *reg)
{
writel(readl(reg) | (1 << 8), reg);
@@ -244,22 +264,30 @@ static void prcmu_enable(u32 *reg)
void db8500_prcmu_init(void)
{
+ struct clk_mgt_regs *clks;
+
/* Enable timers */
writel(1 << 17, PRCM_TCR);
- prcmu_enable((u32 *)PRCM_PER1CLK_MGT_REG);
- prcmu_enable((u32 *)PRCM_PER2CLK_MGT_REG);
- prcmu_enable((u32 *)PRCM_PER3CLK_MGT_REG);
- /* PER4CLK does not exist */
- prcmu_enable((u32 *)PRCM_PER5CLK_MGT_REG);
- prcmu_enable((u32 *)PRCM_PER6CLK_MGT_REG);
- /* Only exists in ED but is always ok to write to */
- prcmu_enable((u32 *)PRCM_PER7CLK_MGT_REG);
-
- prcmu_enable((u32 *)PRCM_UARTCLK_MGT_REG);
- prcmu_enable((u32 *)PRCM_I2CCLK_MGT_REG);
-
- prcmu_enable((u32 *)PRCM_SDMMCCLK_MGT_REG);
+ clks = clk_mgt_regs;
+ if (++restarted == 0) {
+ /* Tuck values away */
+ while (clks->addr) {
+ clks->val = readl(clks->addr);
+ clks++;
+ }
+ } else {
+ /* Restore clock registers */
+ while (clks->addr) {
+ writel(clks->val, clks->addr);
+ clks++;
+ }
+ }
+ clks = clk_mgt_regs;
+ while (clks->addr) {
+ prcmu_enable((u32 *)clks->addr);
+ clks++;
+ }
/* Clean up the mailbox interrupts after pre-u-boot code. */
writel(I2C_MBOX_BIT, PRCM_ARM_IT1_CLEAR);