mirror of
https://github.com/smaeul/u-boot.git
synced 2025-10-18 14:48:17 +01:00
socfpga: arria10: Replace delays with busy waiting in cm_full_cfg
Using udelay while the clocks aren't fully configured causes the timer system to save the wrong clock rate. Use sdelay and wait_on_value instead (the values used in these functions were found experimentally). Signed-off-by: Paweł Anikiel <pan@semihalf.com> Reviewed-by: Tien Fong Chee <tien.fong.chee@intel.com>
This commit is contained in:
parent
9ebca7095b
commit
aea0e80a9f
@ -15,6 +15,10 @@
|
|||||||
|
|
||||||
#ifdef CONFIG_SPL_BUILD
|
#ifdef CONFIG_SPL_BUILD
|
||||||
|
|
||||||
|
void sdelay(unsigned long loops);
|
||||||
|
u32 wait_on_value(u32 read_bit_mask, u32 match_value, void *read_addr,
|
||||||
|
u32 bound);
|
||||||
|
|
||||||
static u32 eosc1_hz;
|
static u32 eosc1_hz;
|
||||||
static u32 cb_intosc_hz;
|
static u32 cb_intosc_hz;
|
||||||
static u32 f2s_free_hz;
|
static u32 f2s_free_hz;
|
||||||
@ -551,13 +555,13 @@ static void cm_pll_ramp_main(struct mainpll_cfg *main_cfg,
|
|||||||
CLKMGR_MAINPLL_VCO1_DENOM_LSB) |
|
CLKMGR_MAINPLL_VCO1_DENOM_LSB) |
|
||||||
cm_calc_safe_pll_numer(0, main_cfg, per_cfg, clk_hz),
|
cm_calc_safe_pll_numer(0, main_cfg, per_cfg, clk_hz),
|
||||||
socfpga_get_clkmgr_addr() + CLKMGR_A10_MAINPLL_VCO1);
|
socfpga_get_clkmgr_addr() + CLKMGR_A10_MAINPLL_VCO1);
|
||||||
mdelay(1);
|
sdelay(1000000); /* 1ms */
|
||||||
cm_wait_for_lock(LOCKED_MASK);
|
cm_wait_for_lock(LOCKED_MASK);
|
||||||
}
|
}
|
||||||
writel((main_cfg->vco1_denom << CLKMGR_MAINPLL_VCO1_DENOM_LSB) |
|
writel((main_cfg->vco1_denom << CLKMGR_MAINPLL_VCO1_DENOM_LSB) |
|
||||||
main_cfg->vco1_numer,
|
main_cfg->vco1_numer,
|
||||||
socfpga_get_clkmgr_addr() + CLKMGR_A10_MAINPLL_VCO1);
|
socfpga_get_clkmgr_addr() + CLKMGR_A10_MAINPLL_VCO1);
|
||||||
mdelay(1);
|
sdelay(1000000); /* 1ms */
|
||||||
cm_wait_for_lock(LOCKED_MASK);
|
cm_wait_for_lock(LOCKED_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -585,16 +589,25 @@ static void cm_pll_ramp_periph(struct mainpll_cfg *main_cfg,
|
|||||||
clk_hz),
|
clk_hz),
|
||||||
socfpga_get_clkmgr_addr() +
|
socfpga_get_clkmgr_addr() +
|
||||||
CLKMGR_A10_PERPLL_VCO1);
|
CLKMGR_A10_PERPLL_VCO1);
|
||||||
mdelay(1);
|
sdelay(1000000); /* 1ms */
|
||||||
cm_wait_for_lock(LOCKED_MASK);
|
cm_wait_for_lock(LOCKED_MASK);
|
||||||
}
|
}
|
||||||
writel((per_cfg->vco1_denom << CLKMGR_PERPLL_VCO1_DENOM_LSB) |
|
writel((per_cfg->vco1_denom << CLKMGR_PERPLL_VCO1_DENOM_LSB) |
|
||||||
per_cfg->vco1_numer,
|
per_cfg->vco1_numer,
|
||||||
socfpga_get_clkmgr_addr() + CLKMGR_A10_PERPLL_VCO1);
|
socfpga_get_clkmgr_addr() + CLKMGR_A10_PERPLL_VCO1);
|
||||||
mdelay(1);
|
sdelay(1000000); /* 1ms */
|
||||||
cm_wait_for_lock(LOCKED_MASK);
|
cm_wait_for_lock(LOCKED_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* function to poll in the fsm busy bit */
|
||||||
|
static int cm_busy_wait_for_fsm(void)
|
||||||
|
{
|
||||||
|
void *reg = (void *)(socfpga_get_clkmgr_addr() + CLKMGR_STAT);
|
||||||
|
|
||||||
|
/* 20s timeout */
|
||||||
|
return wait_on_value(CLKMGR_STAT_BUSY, 0, reg, 100000000);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup clocks while making no assumptions of the
|
* Setup clocks while making no assumptions of the
|
||||||
* previous state of the clocks.
|
* previous state of the clocks.
|
||||||
@ -727,7 +740,7 @@ static int cm_full_cfg(struct mainpll_cfg *main_cfg, struct perpll_cfg *per_cfg)
|
|||||||
socfpga_get_clkmgr_addr() + CLKMGR_A10_PERPLL_VCO1);
|
socfpga_get_clkmgr_addr() + CLKMGR_A10_PERPLL_VCO1);
|
||||||
|
|
||||||
/* Wait for at least 5 us */
|
/* Wait for at least 5 us */
|
||||||
udelay(5);
|
sdelay(5000);
|
||||||
|
|
||||||
/* Now deassert BGPWRDN and PWRDN */
|
/* Now deassert BGPWRDN and PWRDN */
|
||||||
clrbits_le32(socfpga_get_clkmgr_addr() + CLKMGR_A10_MAINPLL_VCO0,
|
clrbits_le32(socfpga_get_clkmgr_addr() + CLKMGR_A10_MAINPLL_VCO0,
|
||||||
@ -738,7 +751,7 @@ static int cm_full_cfg(struct mainpll_cfg *main_cfg, struct perpll_cfg *per_cfg)
|
|||||||
CLKMGR_PERPLL_VCO0_PWRDN_SET_MSK);
|
CLKMGR_PERPLL_VCO0_PWRDN_SET_MSK);
|
||||||
|
|
||||||
/* Wait for at least 7 us */
|
/* Wait for at least 7 us */
|
||||||
udelay(7);
|
sdelay(7000);
|
||||||
|
|
||||||
/* enable the VCO and disable the external regulator to PLL */
|
/* enable the VCO and disable the external regulator to PLL */
|
||||||
writel((readl(socfpga_get_clkmgr_addr() + CLKMGR_A10_MAINPLL_VCO0) &
|
writel((readl(socfpga_get_clkmgr_addr() + CLKMGR_A10_MAINPLL_VCO0) &
|
||||||
@ -878,19 +891,19 @@ static int cm_full_cfg(struct mainpll_cfg *main_cfg, struct perpll_cfg *per_cfg)
|
|||||||
writel(CLKMGR_MAINPLL_BYPASS_RESET,
|
writel(CLKMGR_MAINPLL_BYPASS_RESET,
|
||||||
socfpga_get_clkmgr_addr() + CLKMGR_A10_MAINPLL_BYPASSR);
|
socfpga_get_clkmgr_addr() + CLKMGR_A10_MAINPLL_BYPASSR);
|
||||||
/* wait till Clock Manager is not busy */
|
/* wait till Clock Manager is not busy */
|
||||||
cm_wait_for_fsm();
|
cm_busy_wait_for_fsm();
|
||||||
|
|
||||||
/* release perpll from bypass */
|
/* release perpll from bypass */
|
||||||
writel(CLKMGR_PERPLL_BYPASS_RESET,
|
writel(CLKMGR_PERPLL_BYPASS_RESET,
|
||||||
socfpga_get_clkmgr_addr() + CLKMGR_A10_PERPLL_BYPASSR);
|
socfpga_get_clkmgr_addr() + CLKMGR_A10_PERPLL_BYPASSR);
|
||||||
/* wait till Clock Manager is not busy */
|
/* wait till Clock Manager is not busy */
|
||||||
cm_wait_for_fsm();
|
cm_busy_wait_for_fsm();
|
||||||
|
|
||||||
/* clear boot mode */
|
/* clear boot mode */
|
||||||
clrbits_le32(socfpga_get_clkmgr_addr() + CLKMGR_A10_CTRL,
|
clrbits_le32(socfpga_get_clkmgr_addr() + CLKMGR_A10_CTRL,
|
||||||
CLKMGR_CLKMGR_CTL_BOOTMOD_SET_MSK);
|
CLKMGR_CLKMGR_CTL_BOOTMOD_SET_MSK);
|
||||||
/* wait till Clock Manager is not busy */
|
/* wait till Clock Manager is not busy */
|
||||||
cm_wait_for_fsm();
|
cm_busy_wait_for_fsm();
|
||||||
|
|
||||||
/* At here, we need to ramp to final value if needed */
|
/* At here, we need to ramp to final value if needed */
|
||||||
if (pll_ramp_main_hz != 0)
|
if (pll_ramp_main_hz != 0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user