diff options
author | Per Fransson <per.xx.fransson@stericsson.com> | 2011-03-29 16:17:38 +0200 |
---|---|---|
committer | Michael BRANDT <michael.brandt@stericsson.com> | 2011-03-31 17:16:53 +0200 |
commit | 2f99a160060654d34c9914dd8b5a38a8c69e220d (patch) | |
tree | 79d3a120365d99d1f74d1805ce1c0828c10fb2dc | |
parent | 36af4ccc12ab702d4f164bf7d5306064bb10468d (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.c | 23 | ||||
-rw-r--r-- | cpu/arm_cortexa9/db8500/prcmu.c | 54 |
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); |