tegra: Init clocks even when SPL did not run
authorSimon Glass <sjg@chromium.org>
Wed, 31 May 2017 23:57:16 +0000 (17:57 -0600)
committerSimon Glass <sjg@chromium.org>
Fri, 9 Jun 2017 19:39:32 +0000 (13:39 -0600)
At present early clock init happens in SPL. If SPL did not run (because
for example U-Boot is chain-loaded from another boot loader) then the
clocks are not set as U-Boot expects.

Add a function to detect this and call the early clock init in U-Boot
proper.

Signed-off-by: Simon Glass <sjg@chromium.org>
arch/arm/include/asm/arch-tegra/clock.h
arch/arm/mach-tegra/board2.c
arch/arm/mach-tegra/clock.c
arch/arm/mach-tegra/tegra124/clock.c

index 388afcb72316d29a4c09e4f70a53b8c9bae45f69..f62b2a43788fa7ee2798c42e6c9309fc5d9ffc4e 100644 (file)
@@ -288,6 +288,9 @@ void clock_init(void);
 /* Initialize the PLLs */
 void clock_early_init(void);
 
+/* @return true if hardware indicates that clock_early_init() was called */
+bool clock_early_init_done(void);
+
 /* Returns a pointer to the clock source register for a peripheral */
 u32 *get_periph_source_reg(enum periph_id periph_id);
 
index 84f1ee5035f6fa6c79d0a9420ac1ceabcb6e6675..1e627ba6037e4efb579ff3e8917cbf8925190d14 100644 (file)
@@ -191,6 +191,9 @@ void gpio_early_init(void) __attribute__((weak, alias("__gpio_early_init")));
 
 int board_early_init_f(void)
 {
+       if (!clock_early_init_done())
+               clock_early_init();
+
 #if defined(CONFIG_TEGRA_DISCONNECT_UDC_ON_BOOT)
 #define USBCMD_FS2 (1 << 15)
        {
index 3bb72331a4290b68916a3990aa73868a93b4ae87..76436d8d9112473d3c791bae4cab238fa9e31eee 100644 (file)
@@ -825,3 +825,8 @@ int clock_external_output(int clk_id)
 
        return 0;
 }
+
+__weak bool clock_early_init_done(void)
+{
+       return true;
+}
index 5e4406102f1f6bb1c7255a0010bacd1c715f51c1..5ae718b3426c3054a32427df405379ac95d6ff32 100644 (file)
@@ -891,6 +891,24 @@ void clock_early_init(void)
        udelay(2);
 }
 
+/*
+ * clock_early_init_done - Check if clock_early_init() has been called
+ *
+ * Check a register that we set up to see if clock_early_init() has already
+ * been called.
+ *
+ * @return true if clock_early_init() was called, false if not
+ */
+bool clock_early_init_done(void)
+{
+       struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+       u32 val;
+
+       val = readl(&clkrst->crc_sclk_brst_pol);
+
+       return val == 0x20002222;
+}
+
 void arch_timer_init(void)
 {
        struct sysctr_ctlr *sysctr = (struct sysctr_ctlr *)NV_PA_TSC_BASE;