summaryrefslogtreecommitdiff
path: root/src/soc/nvidia/tegra132/include
diff options
context:
space:
mode:
authorFurquan Shaikh <furquan@google.com>2014-06-09 13:20:04 -0700
committerMarc Jones <marc.jones@se-eng.com>2015-03-02 21:17:21 +0100
commit732b83ed3667d7c3066d2c16406ab6acdd8f32b9 (patch)
treec8b7252aeab5fe29c175b50e17201e23340daa33 /src/soc/nvidia/tegra132/include
parent280a29d5bb5ea53ae92380a95cf8eb4543f96749 (diff)
downloadcoreboot-732b83ed3667d7c3066d2c16406ab6acdd8f32b9.tar.xz
tegra132: Enable bootblock support in tegra132 including UART support
BUG=None BRANCH=None TEST=Compiles successfully Original-Change-Id: Ia9420cfec5333dd5477f04cf080bdad8a37db025 Original-Signed-off-by: Furquan Shaikh <furquan@google.com> Original-Reviewed-on: https://chromium-review.googlesource.com/203143 Original-Tested-by: Furquan Shaikh <furquan@chromium.org> Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org> Original-Commit-Queue: Aaron Durbin <adurbin@chromium.org> (cherry picked from commit a1037f203c6a07cb116eeb1632cb7200ad022cd3) This cherry-pick was modified to match the tegra124 uart.c, which uses the idx and base address calculations instead of Kconfig settings. This driver could use the 8250MEM driver when the ARM vs x86 IO calling convention is worked out. Change-Id: I6e439359b8bb541db4679ac144c519cf251ffed6 Signed-off-by: Marc Jones <marc.jones@se-eng.com> Reviewed-on: http://review.coreboot.org/8517 Tested-by: build bot (Jenkins) Reviewed-by: Kyösti Mälkki <kyosti.malkki@gmail.com> Reviewed-by: Aaron Durbin <adurbin@google.com>
Diffstat (limited to 'src/soc/nvidia/tegra132/include')
-rw-r--r--src/soc/nvidia/tegra132/include/soc/clock.h43
1 files changed, 35 insertions, 8 deletions
diff --git a/src/soc/nvidia/tegra132/include/soc/clock.h b/src/soc/nvidia/tegra132/include/soc/clock.h
index 5fc10c3ca4..6f69fefbc6 100644
--- a/src/soc/nvidia/tegra132/include/soc/clock.h
+++ b/src/soc/nvidia/tegra132/include/soc/clock.h
@@ -18,7 +18,12 @@
#ifndef __SOC_NVIDIA_TEGRA132_CLOCK_H__
#define __SOC_NVIDIA_TEGRA132_CLOCK_H__
+#include <arch/hlt.h>
+#include <arch/io.h>
+#include <console/console.h>
+#include <soc/nvidia/tegra132/clk_rst.h>
#include <stdint.h>
+#include <stdlib.h>
enum {
CLK_L_CPU = 0x1 << 0,
@@ -174,6 +179,7 @@ enum {
#define CLOCK_PLL_STABLE_DELAY_US 300
#define IO_STABILIZATION_DELAY (2)
+
/* Calculate clock fractional divider value from ref and target frequencies.
* This is for a U7.1 format. This is not well written up in the book and
* there have been some questions about this macro, so here we go.
@@ -195,7 +201,7 @@ enum {
* and voila, upper 7 bits are (ref/freq-1), and lowest bit is h. Since you
* will assign this to a u8, it gets nicely truncated for you.
*/
-#define CLK_DIVIDER(REF, FREQ) ((((REF) * 2) / (FREQ)) - 2)
+#define CLK_DIVIDER(REF, FREQ) (div_round_up(((REF) * 2), (FREQ)) - 2)
/* Calculate clock frequency value from reference and clock divider value
* The discussion in the book is pretty lacking.
@@ -216,11 +222,23 @@ enum {
*/
#define CLK_FREQUENCY(REF, REG) (((REF) * 2) / ((REG) + 2))
+static inline void _clock_set_div(u32 *reg, const char *name, u32 div,
+ u32 div_mask, u32 src)
+{
+ // The I2C and UART divisors are 16 bit while all the others are 8 bit.
+ // The I2C clocks are handled by the specialized macro below, but the
+ // UART clocks aren't. Don't use this function on UART clocks.
+ if (div & ~div_mask) {
+ printk(BIOS_ERR, "%s clock divisor overflow!", name);
+ hlt();
+ }
+ clrsetbits_le32(reg, CLK_SOURCE_MASK | CLK_DIVISOR_MASK,
+ src << CLK_SOURCE_SHIFT | div);
+}
+
#define clock_configure_irregular_source(device, src, freq, src_id) \
- clrsetbits_le32(&clk_rst->clk_src_##device, \
- CLK_SOURCE_MASK | CLK_DIVISOR_MASK, \
- src_id << CLK_SOURCE_SHIFT | \
- CLK_DIVIDER(TEGRA_##src##_KHZ, freq))
+ _clock_set_div(&clk_rst->clk_src_##device, #device, \
+ CLK_DIVIDER(TEGRA_##src##_KHZ, freq), 0xff, src_id)
/* Warning: Some devices just use different bits for the same sources for no
* apparent reason. *Always* double-check the TRM before trusting this macro. */
@@ -232,11 +250,12 @@ enum {
* We can deal with those here and make it easier to select what the actual
* bus frequency will be. The 0x19 value is the default divisor in the
* clk_divisor register in the controller, and 8 is just a magic number in the
- * documentation. Multiplying by 2 compensates for the different format of the
- * divisor.
+ * documentation.
*/
#define clock_configure_i2c_scl_freq(device, src, freq) \
- clock_configure_source(device, src, (freq) * (0x19 + 1) * 8 * 2)
+ _clock_set_div(&clk_rst->clk_src_##device, #device, \
+ div_round_up(TEGRA_##src##_KHZ, (freq) * (0x19 + 1) * 8) - 1, \
+ 0xffff, src)
enum clock_source { /* Careful: Not true for all sources, always check TRM! */
PLLP = 0,
@@ -259,6 +278,8 @@ enum clock_source { /* Careful: Not true for all sources, always check TRM! */
#define TEGRA_PLLU_KHZ (960000)
int clock_get_osc_khz(void);
+int clock_get_pll_input_khz(void);
+int clock_display(u32 frequency);
void clock_early_uart(void);
void clock_external_output(int clk_id);
void clock_sdram(u32 m, u32 n, u32 p, u32 setup, u32 ph45, u32 ph90,
@@ -267,6 +288,12 @@ void clock_sdram(u32 m, u32 n, u32 p, u32 setup, u32 ph45, u32 ph90,
void clock_cpu0_config_and_reset(void * entry);
void clock_halt_avp(void);
void clock_enable_clear_reset(u32 l, u32 h, u32 u, u32 v, u32 w, u32 x);
+void clock_reset_l(u32 l);
+void clock_reset_h(u32 h);
+void clock_reset_u(u32 u);
+void clock_reset_v(u32 v);
+void clock_reset_w(u32 w);
+void clock_reset_x(u32 x);
void clock_init(void);
void clock_init_arm_generic_timer(void);
void sor_clock_stop(void);