tegra: add lowlevel delay function
For proper startup we need to give clocks and IO signals some time to stabilize. Tegra2 got away without them, but Tegra3 seems to be a bit pickier. Signed-off-by: Lucas Stach <dev@lynxeye.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
parent
0de758b2ee
commit
af155f74aa
|
@ -173,6 +173,49 @@ int tegra_get_osc_clock(void)
|
|||
}
|
||||
}
|
||||
|
||||
#define TIMER_CNTR_1US 0x00
|
||||
#define TIMER_USEC_CFG 0x04
|
||||
|
||||
static __always_inline
|
||||
void tegra_ll_delay_setup(void)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
/*
|
||||
* calibrate timer to run at 1MHz
|
||||
* TIMERUS_USEC_CFG selects the scale down factor with bits [0:7]
|
||||
* representing the divisor and bits [8:15] representing the dividend
|
||||
* each in n+1 form.
|
||||
*/
|
||||
switch (tegra_get_osc_clock()) {
|
||||
case 12000000:
|
||||
reg = 0x000b;
|
||||
break;
|
||||
case 13000000:
|
||||
reg = 0x000c;
|
||||
break;
|
||||
case 19200000:
|
||||
reg = 0x045f;
|
||||
break;
|
||||
case 26000000:
|
||||
reg = 0x0019;
|
||||
break;
|
||||
default:
|
||||
reg = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
writel(reg, TEGRA_TMRUS_BASE + TIMER_USEC_CFG);
|
||||
}
|
||||
|
||||
static __always_inline
|
||||
void tegra_ll_delay_usec(int delay)
|
||||
{
|
||||
int timeout = (int)readl(TEGRA_TMRUS_BASE + TIMER_CNTR_1US) + delay;
|
||||
|
||||
while ((int)readl(TEGRA_TMRUS_BASE + TIMER_CNTR_1US) - timeout < 0);
|
||||
}
|
||||
|
||||
static __always_inline
|
||||
void tegra_cpu_lowlevel_setup(void)
|
||||
{
|
||||
|
@ -183,6 +226,7 @@ void tegra_cpu_lowlevel_setup(void)
|
|||
r &= ~0x1f;
|
||||
r |= 0xd3;
|
||||
__asm__ __volatile__("msr cpsr, %0" : : "r"(r));
|
||||
tegra_ll_delay_setup();
|
||||
}
|
||||
|
||||
/* reset vector for the AVP, to be called from board reset vector */
|
||||
|
|
|
@ -158,6 +158,9 @@ static void start_cpu0_clocks(void)
|
|||
reg = readl(TEGRA_CLK_RESET_BASE + CRC_CLK_OUT_ENB_L);
|
||||
reg |= CRC_CLK_OUT_ENB_L_CPU;
|
||||
writel(reg, TEGRA_CLK_RESET_BASE + CRC_CLK_OUT_ENB_L);
|
||||
|
||||
/* give clocks some time to settle */
|
||||
tegra_ll_delay_usec(300);
|
||||
}
|
||||
|
||||
static void maincomplex_powerup(void)
|
||||
|
@ -175,6 +178,8 @@ static void maincomplex_powerup(void)
|
|||
reg = readl(TEGRA_PMC_BASE + PMC_REMOVE_CLAMPING_CMD);
|
||||
reg |= PMC_REMOVE_CLAMPING_CMD_CPU;
|
||||
writel(reg, TEGRA_PMC_BASE + PMC_REMOVE_CLAMPING_CMD);
|
||||
|
||||
tegra_ll_delay_usec(1000);
|
||||
}
|
||||
}
|
||||
void tegra_avp_reset_vector(uint32_t boarddata)
|
||||
|
|
Loading…
Reference in New Issue