ARM: DRA: Add io recalibration delay sequence

If changing to AVS0 voltage is required for development purpose,
there will be some IO timing error versus datasheet. The below
sequence is required to recalibrate the IOs after AVS is done.

Signed-off-by: Sricharan R <r.sricharan@ti.com>
This commit is contained in:
Sricharan R 2014-01-31 21:22:14 +05:30 committed by Tom Rini
parent f6b8de6dd9
commit 027946a8be
5 changed files with 103 additions and 1 deletions

View File

@ -750,6 +750,16 @@ void do_enable_clocks(u32 const *clk_domains,
}
}
void recalibrate_io(struct vcores_data const *vcores)
{
void (*recalib)(void);
if (vcores->core.pmic->recalib) {
recalib = vcores->core.pmic->recalib;
recalib();
}
}
void prcm_init(void)
{
switch (omap_hw_init_context()) {
@ -759,6 +769,7 @@ void prcm_init(void)
enable_basic_clocks();
timer_init();
scale_vcores(*omap_vcores);
recalibrate_io(*omap_vcores);
setup_dplls();
#ifdef CONFIG_SYS_CLOCKS_ENABLE_ALL
setup_non_essential_dplls();

View File

@ -157,6 +157,7 @@ void s_init(void)
#endif
init_omap_revision();
hw_data_init();
prcm_init();
#ifdef CONFIG_SPL_BUILD
if (warm_reset() && (omap_revision() <= OMAP5430_ES1_0))
@ -173,7 +174,7 @@ void s_init(void)
preloader_console_init();
do_io_settings();
#endif
prcm_init();
#ifdef CONFIG_SPL_BUILD
/* For regular u-boot sdram_init() is called from dram_init() */
sdram_init();

View File

@ -299,6 +299,72 @@ struct pmic_data palmas = {
.pmic_write = omap_vc_bypass_send_value,
};
/**
* \brief scale_iodelay function implements IODelay Recalibration.
* IODelay calibration is required if changing to AVS0 voltage,
* otherwise there will be some IO timing error versus datasheet.
*
* \param None.
*
*
* \return none.
*
**/
void recalibrate_io_delay(void)
{
int temp, period, mhz = 1000000;
/* Unlock the global lock to write to the MMRs */
writel(0x0000AAAA, (*ctrl)->iodelay_config_reg_8);
/* Unlock the MMR_LOCK1 */
writel(0x2FF1AC2B, (*ctrl)->control_core_mmr_lock1);
temp = readl((*ctrl)->iodelay_config_reg_2) & ~(0xFFFF);
period = get_sys_clk_freq();
/* period in ps */
period = mhz / (period/mhz);
writel(temp | period, (*ctrl)->iodelay_config_reg_2);
/*
* Isolate all the IO. Do dummy read to
* ensure t > 10ns between two steps
*/
clrsetbits_le32((*prcm)->prm_io_pmctrl, (1 << 0), 0x1);
readl((*prcm)->prm_io_pmctrl);
clrsetbits_le32((*ctrl)->ctrl_core_sma_sw_0, (1 << 3), (1 << 3));
readl((*ctrl)->ctrl_core_sma_sw_0);
clrsetbits_le32((*prcm)->prm_io_pmctrl, (1 << 0), 0x0);
/* Trigger the recalibration and update the delay values accordingly */
clrsetbits_le32((*ctrl)->iodelay_config_reg_0, (1 << 0), 0x1);
while (readl((*ctrl)->iodelay_config_reg_0) & 1)
;
/* wait for rom read to complete */
clrsetbits_le32((*ctrl)->iodelay_config_reg_0, (1 << 1), (1 << 1));
while (readl((*ctrl)->iodelay_config_reg_0) & 2)
;
clrsetbits_le32((*prcm)->prm_io_pmctrl, (1 << 0), 0x1);
readl((*prcm)->prm_io_pmctrl);
clrsetbits_le32((*ctrl)->ctrl_core_sma_sw_0, (1 << 3), 0x0);
readl((*ctrl)->ctrl_core_sma_sw_0);
clrsetbits_le32((*prcm)->prm_io_pmctrl, (1 << 0), 0x0);
/* Lock the MMR_LOCK1 */
writel(0x1A1C8144, (*ctrl)->control_core_mmr_lock1);
/* Lock the global lock to write to the MMRs */
writel(0x0000AAAB, (*ctrl)->iodelay_config_reg_8);
}
struct pmic_data tps659038 = {
.base_offset = PALMAS_SMPS_BASE_VOLT_UV,
.step = 10000, /* 10 mV represented in uV */
@ -310,6 +376,7 @@ struct pmic_data tps659038 = {
.i2c_slave_addr = TPS659038_I2C_SLAVE_ADDR,
.pmic_bus_init = gpi2c_init,
.pmic_write = palmas_i2c_write_u8,
.recalib = recalibrate_io_delay,
};
struct vcores_data omap5430_volts = {

View File

@ -450,6 +450,16 @@ struct omap_sys_ctrl_regs const dra7xx_ctrl = {
.control_efuse_3 = 0x4AE0C5C8,
.control_efuse_4 = 0x4AE0C5CC,
.control_efuse_13 = 0x4AE0C5F0,
.iodelay_config_reg_0 = 0x4844A00C,
.iodelay_config_reg_1 = 0x4844A010,
.iodelay_config_reg_2 = 0x4844A014,
.iodelay_config_reg_3 = 0x4844A018,
.iodelay_config_reg_4 = 0x4844A01C,
.iodelay_config_reg_5 = 0x4844A020,
.iodelay_config_reg_6 = 0x4844A024,
.iodelay_config_reg_7 = 0x4844A028,
.iodelay_config_reg_8 = 0x4844A02C,
.ctrl_core_sma_sw_0 = 0x4A0023FC,
};
struct prcm_regs const omap5_es2_prcm = {
@ -964,6 +974,7 @@ struct prcm_regs const dra7xx_prcm = {
.prm_rstctrl = 0x4ae07d00,
.prm_rstst = 0x4ae07d04,
.prm_rsttime = 0x4ae07d08,
.prm_io_pmctrl = 0x4ae07d20,
.prm_vc_val_bypass = 0x4ae07da0,
.prm_vc_cfg_i2c_mode = 0x4ae07db4,
.prm_vc_cfg_i2c_clk = 0x4ae07db8,

View File

@ -344,6 +344,7 @@ struct prcm_regs {
/* GMAC Clk Ctrl */
u32 cm_gmac_gmac_clkctrl;
u32 cm_gmac_clkstctrl;
u32 prm_io_pmctrl;
};
struct omap_sys_ctrl_regs {
@ -451,6 +452,16 @@ struct omap_sys_ctrl_regs {
u32 control_efuse_12;
u32 control_efuse_13;
u32 control_padconf_wkup_base;
u32 iodelay_config_reg_0;
u32 iodelay_config_reg_1;
u32 iodelay_config_reg_2;
u32 iodelay_config_reg_3;
u32 iodelay_config_reg_4;
u32 iodelay_config_reg_5;
u32 iodelay_config_reg_6;
u32 iodelay_config_reg_7;
u32 iodelay_config_reg_8;
u32 ctrl_core_sma_sw_0;
};
struct dpll_params {
@ -506,6 +517,7 @@ struct pmic_data {
u32 i2c_slave_addr;
void (*pmic_bus_init)(void);
int (*pmic_write)(u8 sa, u8 reg_addr, u8 reg_data);
void (*recalib)(void);
};
/**