tegra124: Base early UART on CLK_M to enable debugging of PLL init code
This patch enables the UART first thing in the bootblock, without even depending on a programmable clock source. This depends on being able to divide CLK_M correctly, which may not be possible for all oscillator frequencies, but it works for 12MHz. BUG=None TEST=Put a printk at the top of clock_init() and see it's output (also put one after clock_config() and make sure that works as well). Change-Id: Ided01a569fb3d141347992776970601042cb4402 Signed-off-by: Julius Werner <jwerner@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/174339 Reviewed-by: Gabe Black <gabeblack@chromium.org>
This commit is contained in:
parent
0fdc9a83a4
commit
8d9387432f
4 changed files with 53 additions and 22 deletions
|
|
@ -30,9 +30,7 @@ void main(void)
|
|||
{
|
||||
void *entry;
|
||||
|
||||
clock_init();
|
||||
|
||||
clock_uart_config();
|
||||
clock_early_uart();
|
||||
|
||||
// Serial out, tristate off.
|
||||
pinmux_set_config(PINMUX_KB_ROW9_INDEX, PINMUX_KB_ROW9_FUNC_UA3);
|
||||
|
|
@ -44,6 +42,8 @@ void main(void)
|
|||
if (CONFIG_BOOTBLOCK_CONSOLE)
|
||||
console_init();
|
||||
|
||||
clock_init();
|
||||
|
||||
bootblock_mainboard_init();
|
||||
|
||||
pinmux_set_config(PINMUX_CORE_PWR_REQ_INDEX,
|
||||
|
|
|
|||
|
|
@ -443,17 +443,19 @@ enum {
|
|||
* get_periph_clock_source()) but it does not seem worth it since the code
|
||||
* already checks the ranges of values it is writing, in clk_get_divider().
|
||||
*/
|
||||
#define OUT_CLK_DIVISOR_SHIFT 0
|
||||
#define OUT_CLK_DIVISOR_MASK (0xffff << OUT_CLK_DIVISOR_SHIFT)
|
||||
#define CLK_DIVISOR_SHIFT 0
|
||||
#define CLK_DIVISOR_MASK (0xffff << CLK_DIVISOR_SHIFT)
|
||||
|
||||
#define OUT_CLK_SOURCE_SHIFT 30
|
||||
#define OUT_CLK_SOURCE_MASK (3U << OUT_CLK_SOURCE_SHIFT)
|
||||
#define CLK_SOURCE_SHIFT 30
|
||||
#define CLK_SOURCE_MASK (3U << CLK_SOURCE_SHIFT)
|
||||
|
||||
#define OUT_CLK_SOURCE3_SHIFT 29
|
||||
#define OUT_CLK_SOURCE3_MASK (7U << OUT_CLK_SOURCE3_SHIFT)
|
||||
#define CLK_SOURCE3_SHIFT 29
|
||||
#define CLK_SOURCE3_MASK (7U << CLK_SOURCE3_SHIFT)
|
||||
|
||||
#define OUT_CLK_SOURCE4_SHIFT 28
|
||||
#define OUT_CLK_SOURCE4_MASK (15U << OUT_CLK_SOURCE4_SHIFT)
|
||||
#define CLK_SOURCE4_SHIFT 28
|
||||
#define CLK_SOURCE4_MASK (15U << CLK_SOURCE4_SHIFT)
|
||||
|
||||
#define CLK_UART_DIV_OVERRIDE (1 << 24)
|
||||
|
||||
/* CLK_RST_CONTROLLER_SCLK_BURST_POLICY */
|
||||
#define SCLK_SYS_STATE_SHIFT 28U
|
||||
|
|
|
|||
|
|
@ -60,11 +60,11 @@ void clock_ll_set_source_divisor(u32 *reg, u32 source, u32 divisor)
|
|||
|
||||
value = readl(reg);
|
||||
|
||||
value &= ~OUT_CLK_SOURCE_MASK;
|
||||
value |= source << OUT_CLK_SOURCE_SHIFT;
|
||||
value &= ~CLK_SOURCE_MASK;
|
||||
value |= source << CLK_SOURCE_SHIFT;
|
||||
|
||||
value &= ~OUT_CLK_DIVISOR_MASK;
|
||||
value |= divisor << OUT_CLK_DIVISOR_SHIFT;
|
||||
value &= ~CLK_DIVISOR_MASK;
|
||||
value |= divisor << CLK_DIVISOR_SHIFT;
|
||||
|
||||
writel(value, reg);
|
||||
}
|
||||
|
|
@ -81,6 +81,28 @@ static int clock_get_osc_freq(void)
|
|||
return reg;
|
||||
}
|
||||
|
||||
int clock_get_osc_khz(void)
|
||||
{
|
||||
/* Implemented better in the next patch, sorry, hard to split this up */
|
||||
switch (clock_get_osc_freq()) {
|
||||
case OSC_FREQ_OSC13:
|
||||
return 13000;
|
||||
case OSC_FREQ_OSC19P2:
|
||||
return 19200;
|
||||
default:
|
||||
case OSC_FREQ_OSC12:
|
||||
return 12000;
|
||||
case OSC_FREQ_OSC26:
|
||||
return 26000;
|
||||
case OSC_FREQ_OSC16P8:
|
||||
return 16800;
|
||||
case OSC_FREQ_OSC38P4:
|
||||
return 38400;
|
||||
case OSC_FREQ_OSC48:
|
||||
return 48000;
|
||||
}
|
||||
}
|
||||
|
||||
static void adjust_pllp_out_freqs(void)
|
||||
{
|
||||
u32 reg;
|
||||
|
|
@ -146,14 +168,17 @@ static void init_pllx(void)
|
|||
adjust_pllp_out_freqs();
|
||||
}
|
||||
|
||||
void clock_uart_config(void)
|
||||
/* Initialize the UART and put it on CLK_M so we can use it during clock_init().
|
||||
* Will later move it to PLLP in clock_config(). The divisor must be very small
|
||||
* to accomodate 12KHz OSCs, so we override the 16.0 UART divider with the 15.1
|
||||
* CLK_SOURCE divider to get more precision. (This might still not be enough for
|
||||
* some OSCs... if you use 13KHz, be prepared to have a bad time.) The 1800 has
|
||||
* been determined through trial and error (must lead to div 13 at 24MHz). */
|
||||
void clock_early_uart(void)
|
||||
{
|
||||
/* Enable clocks to required peripherals. TBD - minimize this list */
|
||||
/* The UART is super special so Just Do It right here. */
|
||||
|
||||
setbits_le32(&clk_rst->rst_dev_l, CLK_L_UARTA);
|
||||
clock_ll_set_source_divisor(&clk_rst->clk_src_uarta, 3,
|
||||
CLK_UART_DIV_OVERRIDE | CLK_DIVIDER(clock_get_osc_khz(), 1800));
|
||||
setbits_le32(&clk_rst->clk_out_enb_l, CLK_L_UARTA);
|
||||
clock_ll_set_source_divisor(&clk_rst->clk_src_uarta, 0, 2);
|
||||
udelay(2);
|
||||
clrbits_le32(&clk_rst->rst_dev_l, CLK_L_UARTA);
|
||||
}
|
||||
|
|
@ -285,6 +310,9 @@ void clock_config(void)
|
|||
/* I2C5 (PMU) gets CLK_M and a divisor of 17 */
|
||||
clock_ll_set_source_divisor(&clk_rst->clk_src_i2c5, 3, 16);
|
||||
|
||||
/* UARTA gets PLLP, deactivate CLK_UART_DIV_OVERRIDE */
|
||||
writel(0 << CLK_SOURCE_SHIFT, &clk_rst->clk_src_uarta);
|
||||
|
||||
/* Give clock time to stabilize. */
|
||||
udelay(IO_STABILIZATION_DELAY);
|
||||
|
||||
|
|
|
|||
|
|
@ -160,7 +160,8 @@ enum {
|
|||
#define NVBL_PLLC_KHZ (600000)
|
||||
#define NVBL_PLLD_KHZ (925000)
|
||||
|
||||
void clock_uart_config(void);
|
||||
int clock_get_osc_khz(void);
|
||||
void clock_early_uart(void);
|
||||
void clock_cpu0_config_and_reset(void * entry);
|
||||
void clock_config(void);
|
||||
void clock_init(void);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue