aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLokesh Vutla2013-04-17 15:49:40 -0500
committerTom Rini2013-05-10 07:25:55 -0500
commit0b1b60c77954df19b5a601e2ba87614f2d0bbb8b (patch)
tree3dff44e2598611673743d56bd3480d9acf97b3f5
parent15191c91a240bd8683ca40e6c4b8b8c44b98412f (diff)
downloadu-boot-0b1b60c77954df19b5a601e2ba87614f2d0bbb8b.tar.gz
u-boot-0b1b60c77954df19b5a601e2ba87614f2d0bbb8b.tar.xz
u-boot-0b1b60c77954df19b5a601e2ba87614f2d0bbb8b.zip
ARM: OMAP5: Fix warm reset with USB cable connected
Warm reset on OMAP5 freezes when USB cable is connected. Fix requires PRM_RSTTIME.RSTTIME1 to be programmed with the time for which reset should be held low for the voltages and the oscillator to reach stable state. There are 3 parameters to be considered for calculating the time, which are mostly board and PMIC dependent. -1- Time taken by the Oscillator to shut + restart -2- PMIC OTP times -3- Voltage rail ramp times, which inturn depends on the PMIC slew rate and value of the voltage ramp needed. In order to keep the code in u-boot simple, have a way for boards to specify a pre computed time directly using the 'CONFIG_OMAP_PLATFORM_RESET_TIME_MAX_USEC' option. If boards fail to specify the time, use a default as specified by 'CONFIG_DEFAULT_OMAP_RESET_TIME_MAX_USEC' instead. Using the default value translates into some ~22ms and should work in all cases. However in order to avoid this large delay hiding other bugs, its recommended that all boards look at their respective data sheets and specify a pre computed and optimal value using 'CONFIG_OMAP_PLATFORM_RESET_TIME_MAX_USEC' In order to help future board additions to compute this config option value, add a README at doc/README.omap-reset-time which explains how to compute the value. Also update the toplevel README with the additional option and pointers to doc/README.omap-reset-time. Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com> [rnayak@ti.com: Updated changelog and added the README] Signed-off-by: Rajendra Nayak <rnayak@ti.com>
-rw-r--r--README4
-rw-r--r--arch/arm/cpu/armv7/omap-common/clocks-common.c1
-rw-r--r--arch/arm/cpu/armv7/omap-common/reset.c4
-rw-r--r--arch/arm/cpu/armv7/omap5/hwinit.c19
-rw-r--r--arch/arm/cpu/armv7/omap5/prcm-regs.c2
-rw-r--r--arch/arm/include/asm/arch-omap4/sys_proto.h1
-rw-r--r--arch/arm/include/asm/arch-omap5/clocks.h10
-rw-r--r--arch/arm/include/asm/arch-omap5/sys_proto.h10
-rw-r--r--arch/arm/include/asm/omap_common.h1
-rw-r--r--doc/README.omap-reset-time20
-rw-r--r--include/configs/omap5_uevm.h1
11 files changed, 73 insertions, 0 deletions
diff --git a/README b/README
index 0bc0af5700..453189156c 100644
--- a/README
+++ b/README
@@ -3323,6 +3323,10 @@ Configuration Settings:
3323 offset _bss_start_ofs from CONFIG_SYS_TEXT_BASE, rather than 3323 offset _bss_start_ofs from CONFIG_SYS_TEXT_BASE, rather than
3324 directly. You should not need to touch this setting. 3324 directly. You should not need to touch this setting.
3325 3325
3326- CONFIG_OMAP_PLATFORM_RESET_TIME_MAX_USEC (OMAP only)
3327 This is set by OMAP boards for the max time that reset should
3328 be asserted. See doc/README.omap-reset-time for details on how
3329 the value can be calulated on a given board.
3326 3330
3327The following definitions that deal with the placement and management 3331The following definitions that deal with the placement and management
3328of environment data (variable area); in general, we support the 3332of environment data (variable area); in general, we support the
diff --git a/arch/arm/cpu/armv7/omap-common/clocks-common.c b/arch/arm/cpu/armv7/omap-common/clocks-common.c
index 2b955c7c00..99910cdcb0 100644
--- a/arch/arm/cpu/armv7/omap-common/clocks-common.c
+++ b/arch/arm/cpu/armv7/omap-common/clocks-common.c
@@ -716,6 +716,7 @@ void prcm_init(void)
716 setup_non_essential_dplls(); 716 setup_non_essential_dplls();
717 enable_non_essential_clocks(); 717 enable_non_essential_clocks();
718#endif 718#endif
719 setup_warmreset_time();
719 break; 720 break;
720 default: 721 default:
721 break; 722 break;
diff --git a/arch/arm/cpu/armv7/omap-common/reset.c b/arch/arm/cpu/armv7/omap-common/reset.c
index 587bb47745..57ea9d9999 100644
--- a/arch/arm/cpu/armv7/omap-common/reset.c
+++ b/arch/arm/cpu/armv7/omap-common/reset.c
@@ -39,3 +39,7 @@ u32 __weak warm_reset(void)
39{ 39{
40 return (readl(PRM_RSTST) & PRM_RSTST_WARM_RESET_MASK); 40 return (readl(PRM_RSTST) & PRM_RSTST_WARM_RESET_MASK);
41} 41}
42
43void __weak setup_warmreset_time(void)
44{
45}
diff --git a/arch/arm/cpu/armv7/omap5/hwinit.c b/arch/arm/cpu/armv7/omap5/hwinit.c
index 2f4b24752b..d29df78720 100644
--- a/arch/arm/cpu/armv7/omap5/hwinit.c
+++ b/arch/arm/cpu/armv7/omap5/hwinit.c
@@ -363,3 +363,22 @@ u32 warm_reset(void)
363{ 363{
364 return readl((*prcm)->prm_rstst) & PRM_RSTST_WARM_RESET_MASK; 364 return readl((*prcm)->prm_rstst) & PRM_RSTST_WARM_RESET_MASK;
365} 365}
366
367void setup_warmreset_time(void)
368{
369 u32 rst_time, rst_val;
370
371#ifndef CONFIG_OMAP_PLATFORM_RESET_TIME_MAX_USEC
372 rst_time = CONFIG_DEFAULT_OMAP_RESET_TIME_MAX_USEC;
373#else
374 rst_time = CONFIG_OMAP_PLATFORM_RESET_TIME_MAX_USEC;
375#endif
376 rst_time = usec_to_32k(rst_time) << RSTTIME1_SHIFT;
377
378 if (rst_time > RSTTIME1_MASK)
379 rst_time = RSTTIME1_MASK;
380
381 rst_val = readl((*prcm)->prm_rsttime) & ~RSTTIME1_MASK;
382 rst_val |= rst_time;
383 writel(rst_val, (*prcm)->prm_rsttime);
384}
diff --git a/arch/arm/cpu/armv7/omap5/prcm-regs.c b/arch/arm/cpu/armv7/omap5/prcm-regs.c
index b8a61fe881..e9f6a32653 100644
--- a/arch/arm/cpu/armv7/omap5/prcm-regs.c
+++ b/arch/arm/cpu/armv7/omap5/prcm-regs.c
@@ -729,6 +729,7 @@ struct prcm_regs const omap5_es2_prcm = {
729 .cm_wkupaon_io_srcomp_clkctrl = 0x4ae07998, 729 .cm_wkupaon_io_srcomp_clkctrl = 0x4ae07998,
730 .prm_rstctrl = 0x4ae07c00, 730 .prm_rstctrl = 0x4ae07c00,
731 .prm_rstst = 0x4ae07c04, 731 .prm_rstst = 0x4ae07c04,
732 .prm_rsttime = 0x4ae07c08,
732 .prm_vc_val_bypass = 0x4ae07ca0, 733 .prm_vc_val_bypass = 0x4ae07ca0,
733 .prm_vc_cfg_i2c_mode = 0x4ae07cb4, 734 .prm_vc_cfg_i2c_mode = 0x4ae07cb4,
734 .prm_vc_cfg_i2c_clk = 0x4ae07cb8, 735 .prm_vc_cfg_i2c_clk = 0x4ae07cb8,
@@ -952,6 +953,7 @@ struct prcm_regs const dra7xx_prcm = {
952 .cm_wkupaon_scrm_clkctrl = 0x4ae07890, 953 .cm_wkupaon_scrm_clkctrl = 0x4ae07890,
953 .prm_rstctrl = 0x4ae07d00, 954 .prm_rstctrl = 0x4ae07d00,
954 .prm_rstst = 0x4ae07d04, 955 .prm_rstst = 0x4ae07d04,
956 .prm_rsttime = 0x4ae07d08,
955 .prm_vc_val_bypass = 0x4ae07da0, 957 .prm_vc_val_bypass = 0x4ae07da0,
956 .prm_vc_cfg_i2c_mode = 0x4ae07db4, 958 .prm_vc_cfg_i2c_mode = 0x4ae07db4,
957 .prm_vc_cfg_i2c_clk = 0x4ae07db8, 959 .prm_vc_cfg_i2c_clk = 0x4ae07db8,
diff --git a/arch/arm/include/asm/arch-omap4/sys_proto.h b/arch/arm/include/asm/arch-omap4/sys_proto.h
index d5f1868eee..ac9c1f83ed 100644
--- a/arch/arm/include/asm/arch-omap4/sys_proto.h
+++ b/arch/arm/include/asm/arch-omap4/sys_proto.h
@@ -58,6 +58,7 @@ void omap_vc_init(u16 speed_khz);
58int omap_vc_bypass_send_value(u8 sa, u8 reg_addr, u8 reg_data); 58int omap_vc_bypass_send_value(u8 sa, u8 reg_addr, u8 reg_data);
59u32 warm_reset(void); 59u32 warm_reset(void);
60void force_emif_self_refresh(void); 60void force_emif_self_refresh(void);
61void setup_warmreset_time(void);
61/* 62/*
62 * This is used to verify if the configuration header 63 * This is used to verify if the configuration header
63 * was executed by Romcode prior to control of transfer 64 * was executed by Romcode prior to control of transfer
diff --git a/arch/arm/include/asm/arch-omap5/clocks.h b/arch/arm/include/asm/arch-omap5/clocks.h
index cfde374333..68afa76696 100644
--- a/arch/arm/include/asm/arch-omap5/clocks.h
+++ b/arch/arm/include/asm/arch-omap5/clocks.h
@@ -190,6 +190,10 @@
190#define OPTFCLKEN_SRCOMP_FCLK_SHIFT 8 190#define OPTFCLKEN_SRCOMP_FCLK_SHIFT 8
191#define OPTFCLKEN_SRCOMP_FCLK_MASK (1 << 8) 191#define OPTFCLKEN_SRCOMP_FCLK_MASK (1 << 8)
192 192
193/* PRM_RSTTIME */
194#define RSTTIME1_SHIFT 0
195#define RSTTIME1_MASK (0x3ff << 0)
196
193/* Clock frequencies */ 197/* Clock frequencies */
194#define OMAP_SYS_CLK_FREQ_38_4_MHZ 38400000 198#define OMAP_SYS_CLK_FREQ_38_4_MHZ 38400000
195#define OMAP_SYS_CLK_IND_38_4_MHZ 6 199#define OMAP_SYS_CLK_IND_38_4_MHZ 6
@@ -251,4 +255,10 @@
251#define DPLL_NO_LOCK 0 255#define DPLL_NO_LOCK 0
252#define DPLL_LOCK 1 256#define DPLL_LOCK 1
253 257
258/*
259 * MAX value for PRM_RSTTIME[9:0]RSTTIME1 stored is 0x3ff.
260 * 0x3ff is in the no of FUNC_32K_CLK cycles. Converting cycles
261 * into microsec and passing the value.
262 */
263#define CONFIG_DEFAULT_OMAP_RESET_TIME_MAX_USEC 31219
254#endif /* _CLOCKS_OMAP5_H_ */ 264#endif /* _CLOCKS_OMAP5_H_ */
diff --git a/arch/arm/include/asm/arch-omap5/sys_proto.h b/arch/arm/include/asm/arch-omap5/sys_proto.h
index e66ab44341..393c8bfdb7 100644
--- a/arch/arm/include/asm/arch-omap5/sys_proto.h
+++ b/arch/arm/include/asm/arch-omap5/sys_proto.h
@@ -64,6 +64,7 @@ u32 warm_reset(void);
64void force_emif_self_refresh(void); 64void force_emif_self_refresh(void);
65void get_ioregs(const struct ctrl_ioregs **regs); 65void get_ioregs(const struct ctrl_ioregs **regs);
66void srcomp_enable(void); 66void srcomp_enable(void);
67void setup_warmreset_time(void);
67 68
68/* 69/*
69 * This is used to verify if the configuration header 70 * This is used to verify if the configuration header
@@ -122,4 +123,13 @@ static inline u32 omap_hw_init_context(void)
122#endif 123#endif
123} 124}
124 125
126static inline u32 div_round_up(u32 num, u32 den)
127{
128 return (num + den - 1)/den;
129}
130
131static inline u32 usec_to_32k(u32 usec)
132{
133 return div_round_up(32768 * usec, 1000000);
134}
125#endif 135#endif
diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h
index 091ddb508d..6d377d5b59 100644
--- a/arch/arm/include/asm/omap_common.h
+++ b/arch/arm/include/asm/omap_common.h
@@ -316,6 +316,7 @@ struct prcm_regs {
316 u32 cm_wkupaon_io_srcomp_clkctrl; 316 u32 cm_wkupaon_io_srcomp_clkctrl;
317 u32 prm_rstctrl; 317 u32 prm_rstctrl;
318 u32 prm_rstst; 318 u32 prm_rstst;
319 u32 prm_rsttime;
319 u32 prm_vc_val_bypass; 320 u32 prm_vc_val_bypass;
320 u32 prm_vc_cfg_i2c_mode; 321 u32 prm_vc_cfg_i2c_mode;
321 u32 prm_vc_cfg_i2c_clk; 322 u32 prm_vc_cfg_i2c_clk;
diff --git a/doc/README.omap-reset-time b/doc/README.omap-reset-time
new file mode 100644
index 0000000000..0c974bacae
--- /dev/null
+++ b/doc/README.omap-reset-time
@@ -0,0 +1,20 @@
1README on how reset time on OMAPs should be calculated
2
3CONFIG_OMAP_PLATFORM_RESET_TIME_MAX_USEC:
4Most OMAPs' provide a way to specify the time for
5which the reset should be held low while the voltages
6and Oscillator outputs stabilize.
7
8This time is mostly board and PMIC dependent. Hence the
9boards are expected to specify a pre-computed time
10using the above option, (the details on how to compute
11the value are given below) without which a default time
12as specified by CONFIG_DEFAULT_OMAP_RESET_TIME_MAX_USEC
13is used.
14
15The value for CONFIG_OMAP_PLATFORM_RESET_TIME_MAX_USEC
16can be computed using a summation of the below 3 parameters
17-1- Time taken by the Osciallator to stop and restart
18-2- PMIC OTP time
19-3- Voltage ramp time, which can be derived using the
20PMIC slew rate and value of voltage ramp needed.
diff --git a/include/configs/omap5_uevm.h b/include/configs/omap5_uevm.h
index c5bf51d9c9..c791789cb7 100644
--- a/include/configs/omap5_uevm.h
+++ b/include/configs/omap5_uevm.h
@@ -54,4 +54,5 @@
54 54
55#define CONFIG_SYS_PROMPT "OMAP5430 EVM # " 55#define CONFIG_SYS_PROMPT "OMAP5430 EVM # "
56 56
57#define CONFIG_OMAP_PLATFORM_RESET_TIME_MAX_USEC 16296
57#endif /* __CONFIG_OMAP5_EVM_H */ 58#endif /* __CONFIG_OMAP5_EVM_H */