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:
Julius Werner 2013-10-23 11:29:59 -07:00 committed by chrome-internal-fetch
commit 8d9387432f
4 changed files with 53 additions and 22 deletions

View file

@ -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,

View file

@ -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

View file

@ -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);

View file

@ -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);