diff --git a/arch/arm/cpu/armv7/omap5/dra7xx_iodelay.c b/arch/arm/cpu/armv7/omap5/dra7xx_iodelay.c index 9fa6e6991f..744950f01b 100644 --- a/arch/arm/cpu/armv7/omap5/dra7xx_iodelay.c +++ b/arch/arm/cpu/armv7/omap5/dra7xx_iodelay.c @@ -166,16 +166,14 @@ static int do_set_iodelay(u32 base, struct iodelay_cfg_entry const *array, return 0; } -void __recalibrate_iodelay(struct pad_conf_entry const *pad, int npads, - struct iodelay_cfg_entry const *iodelay, - int niodelays) +int __recalibrate_iodelay_start(void) { int ret = 0; /* IO recalibration should be done only from SRAM */ if (OMAP_INIT_CONTEXT_SPL != omap_hw_init_context()) { puts("IODELAY recalibration called from invalid context - use only from SPL in SRAM\n"); - return; + return -1; } /* unlock IODELAY CONFIG registers */ @@ -191,23 +189,27 @@ void __recalibrate_iodelay(struct pad_conf_entry const *pad, int npads, goto err; ret = update_delay_mechanism((*ctrl)->iodelay_config_base); - if (ret) - goto err; - - /* Configure Mux settings */ - do_set_mux32((*ctrl)->control_padconf_core_base, pad, npads); - - /* Configure Manual IO timing modes */ - ret = do_set_iodelay((*ctrl)->iodelay_config_base, iodelay, niodelays); - if (ret) - goto err; - - ret = isolate_io(DEISOLATE_IO); err: + return ret; +} + +void __recalibrate_iodelay_end(int ret) +{ + + /* IO recalibration should be done only from SRAM */ + if (OMAP_INIT_CONTEXT_SPL != omap_hw_init_context()) { + puts("IODELAY recalibration called from invalid context - use only from SPL in SRAM\n"); + return; + } + + if (!ret) + ret = isolate_io(DEISOLATE_IO); + /* lock IODELAY CONFIG registers */ writel(CFG_IODELAY_LOCK_KEY, (*ctrl)->iodelay_config_base + CFG_REG_8_OFFSET); + /* * UART cannot be used during IO recalibration sequence as IOs are in * isolation. So error handling and debug prints are done after @@ -232,7 +234,41 @@ err: case ERR_FPDE: puts("IODELAY: FPDE calculation failed\n"); break; + case -1: + puts("IODELAY: Wrong Context call?\n"); + break; default: debug("IODELAY: IO delay recalibration successfully completed\n"); } + + return; +} + +void __recalibrate_iodelay(struct pad_conf_entry const *pad, int npads, + struct iodelay_cfg_entry const *iodelay, + int niodelays) +{ + int ret = 0; + + /* IO recalibration should be done only from SRAM */ + if (OMAP_INIT_CONTEXT_SPL != omap_hw_init_context()) { + puts("IODELAY recalibration called from invalid context - use only from SPL in SRAM\n"); + return; + } + + ret = __recalibrate_iodelay_start(); + if (ret) + goto err; + + /* Configure Mux settings */ + do_set_mux32((*ctrl)->control_padconf_core_base, pad, npads); + + /* Configure Manual IO timing modes */ + ret = do_set_iodelay((*ctrl)->iodelay_config_base, iodelay, niodelays); + if (ret) + goto err; + +err: + __recalibrate_iodelay_end(ret); + } diff --git a/arch/arm/include/asm/arch-omap5/dra7xx_iodelay.h b/arch/arm/include/asm/arch-omap5/dra7xx_iodelay.h index 4cd0a3cc80..0de8a800c1 100644 --- a/arch/arm/include/asm/arch-omap5/dra7xx_iodelay.h +++ b/arch/arm/include/asm/arch-omap5/dra7xx_iodelay.h @@ -83,5 +83,7 @@ void __recalibrate_iodelay(struct pad_conf_entry const *pad, int npads, struct iodelay_cfg_entry const *iodelay, int niodelays); +int __recalibrate_iodelay_start(void); +void __recalibrate_iodelay_end(int ret); #endif