diff options
author | Lucas Stach <dev@lynxeye.de> | 2014-02-17 21:27:41 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2014-02-27 10:42:09 +0100 |
commit | df1d5326a995e65f3c1fe86f66a04d18f68244cf (patch) | |
tree | 5e31066697fca53df06f51c0ed8b4d4c57262b67 /arch/arm/mach-tegra/tegra_avp_init.c | |
parent | 880869e55ff170cd13f1ceb0fcda57dcdffba63c (diff) | |
download | barebox-df1d5326a995e65f3c1fe86f66a04d18f68244cf.tar.gz barebox-df1d5326a995e65f3c1fe86f66a04d18f68244cf.tar.xz |
tegra: add Tegra3 startup
Sets up MSELECT to let main CPUs talk to peripheral devices and starts
high performance A9 CPU cluster.
Signed-off-by: Lucas Stach <dev@lynxeye.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch/arm/mach-tegra/tegra_avp_init.c')
-rw-r--r-- | arch/arm/mach-tegra/tegra_avp_init.c | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/arch/arm/mach-tegra/tegra_avp_init.c b/arch/arm/mach-tegra/tegra_avp_init.c index 4dd13306c7..3314db4572 100644 --- a/arch/arm/mach-tegra/tegra_avp_init.c +++ b/arch/arm/mach-tegra/tegra_avp_init.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Lucas Stach <l.stach@pengutronix.de> + * Copyright (C) 2013-2014 Lucas Stach <l.stach@pengutronix.de> * * Partly based on code (C) Copyright 2010-2011 * NVIDIA Corporation <www.nvidia.com> @@ -23,6 +23,8 @@ #include <mach/lowlevel.h> #include <mach/tegra20-car.h> #include <mach/tegra20-pmc.h> +#include <mach/tegra30-car.h> +#include <mach/tegra30-flow.h> /* instruct the PMIC to enable the CPU power rail */ static void enable_maincomplex_powerrail(void) @@ -84,6 +86,12 @@ static struct pll_config pllx_config_table[][4] = { {1000, 12, 0, 12}, /* OSC 12.0 MHz */ {1000, 26, 0, 12}, /* OSC 26.0 MHz */ }, /* TEGRA 20 */ + { + {862, 8, 0, 8}, + {583, 8, 0, 4}, + {700, 6, 0, 8}, + {700, 13, 0, 8}, + }, /* TEGRA 30 */ }; static void init_pllx(void) @@ -152,6 +160,20 @@ static void start_cpu0_clocks(void) writel(1 << CRC_CLK_SYSTEM_RATE_AHB_SHIFT, TEGRA_CLK_RESET_BASE + CRC_CLK_SYSTEM_RATE); + if (tegra_get_chiptype() >= TEGRA30) { + /* init MSELECT */ + writel(CRC_RST_DEV_V_MSELECT, + TEGRA_CLK_RESET_BASE + CRC_RST_DEV_V_SET); + writel((CRC_CLK_SOURCE_MSEL_SRC_PLLP << + CRC_CLK_SOURCE_MSEL_SRC_SHIFT) | 2, + TEGRA_CLK_RESET_BASE + CRC_CLK_SOURCE_MSEL); + writel(CRC_CLK_OUT_ENB_V_MSELECT, + TEGRA_CLK_RESET_BASE + CRC_CLK_OUT_ENB_V); + tegra_ll_delay_usec(3); + writel(CRC_RST_DEV_V_MSELECT, + TEGRA_CLK_RESET_BASE + CRC_RST_DEV_V_CLR); + } + /* deassert clock stop for cpu 0 */ reg = readl(TEGRA_CLK_RESET_BASE + CRC_CLK_CPU_CMPLX); reg &= ~CRC_CLK_CPU_CMPLX_CPU0_CLK_STP; @@ -185,10 +207,24 @@ static void maincomplex_powerup(void) tegra_ll_delay_usec(1000); } } + +static void tegra_cluster_switch_hp(void) +{ + u32 reg; + + reg = readl(TEGRA_FLOW_CTRL_BASE + FLOW_CLUSTER_CONTROL); + reg &= ~FLOW_CLUSTER_CONTROL_ACTIVE_LP; + writel(reg, TEGRA_FLOW_CTRL_BASE + FLOW_CLUSTER_CONTROL); +} + void tegra_avp_reset_vector(uint32_t boarddata) { int num_cores; + /* we want to bring up the high performance CPU complex */ + if (tegra_get_chiptype() == TEGRA30) + tegra_cluster_switch_hp(); + /* get the number of cores in the main CPU complex of the current SoC */ num_cores = tegra_get_num_cores(); |