diff options
author | Simon Glass <sjg@chromium.org> | 2011-10-03 13:21:11 -0700 |
---|---|---|
committer | Simon Glass <sjg@chromium.org> | 2011-10-06 19:24:30 -0700 |
commit | 5605de2e1851d005c226643af2040bffca9c6c39 (patch) | |
tree | 8453e0a549f447ef76307c888b901d0703230b97 /arch/arm/cpu/armv7/tegra-common | |
parent | 4a4703b398df9a3e5d29623e5e3dcf1d99336ebc (diff) |
tegra: Detect the number of CPUs
This adds ap20_get_num_cpus() which returns the number of CPUs in the
system, and adjusts a clock function to use it.
BUG=chromium-os:19004
TEST=build and boot on Seaboard
Change-Id: If7b56a2cecfb3d856308cac43dfcb32d3f1fef14
Reviewed-on: http://gerrit.chromium.org/gerrit/8688
Reviewed-by: Simon Glass <sjg@chromium.org>
Tested-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'arch/arm/cpu/armv7/tegra-common')
-rw-r--r-- | arch/arm/cpu/armv7/tegra-common/ap20.c | 39 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/tegra-common/clock.c | 8 |
2 files changed, 40 insertions, 7 deletions
diff --git a/arch/arm/cpu/armv7/tegra-common/ap20.c b/arch/arm/cpu/armv7/tegra-common/ap20.c index cc3afaa77a..3a7e402b0c 100644 --- a/arch/arm/cpu/armv7/tegra-common/ap20.c +++ b/arch/arm/cpu/armv7/tegra-common/ap20.c @@ -64,6 +64,32 @@ static struct clk_pll_table tegra_pll_x_table[TEGRA_SOC_COUNT] }, }; +enum tegra_family_t { + TEGRA_FAMILY_T2x, + TEGRA_FAMILY_T3x, +}; + +#define GP_HIDREV 0x804 + +static enum tegra_family_t ap20_get_family(void) +{ + u32 reg, chip_id; + + reg = readl(NV_PA_APB_MISC_BASE + GP_HIDREV); + + chip_id = reg >> 8; + chip_id &= 0xff; + if (chip_id == 0x30) + return TEGRA_FAMILY_T3x; + else + return TEGRA_FAMILY_T2x; +} + +int ap20_get_num_cpus(void) +{ + return ap20_get_family() == TEGRA_FAMILY_T3x ? 4 : 2; +} + int ap20_cpu_is_cortexa9(void) { u32 id = readb(NV_PA_PG_UP_BASE + PG_UP_TAG_0); @@ -239,11 +265,14 @@ static void reset_A9_cpu(int reset) * AVP only talks to the master. The AVP does not know that there * are multiple processors in the CPU complex. */ - - /* Hold CPU 1 in reset, and CPU 0 if asked */ - reset_cmplx_set_enable(1, crc_rst_cpu | crc_rst_de | crc_rst_debug, 1); - reset_cmplx_set_enable(0, crc_rst_cpu | crc_rst_de | crc_rst_debug, - reset); + int mask = crc_rst_cpu | crc_rst_de | crc_rst_debug; + int num_cpus = ap20_get_num_cpus(); + int cpu; + + /* Hold CPUs 1 onwards in reset, and CPU 0 if asked */ + for (cpu = 1; cpu < num_cpus; cpu++) + reset_cmplx_set_enable(cpu, mask, 1); + reset_cmplx_set_enable(0, mask, reset); /* Enable/Disable master CPU reset */ reset_set_enable(PERIPH_ID_CPU, reset); diff --git a/arch/arm/cpu/armv7/tegra-common/clock.c b/arch/arm/cpu/armv7/tegra-common/clock.c index 23573b1080..0aa4ef33ec 100644 --- a/arch/arm/cpu/armv7/tegra-common/clock.c +++ b/arch/arm/cpu/armv7/tegra-common/clock.c @@ -22,6 +22,7 @@ /* Tegra2 Clock control functions */ #include <asm/io.h> +#include <asm/arch-tegra/ap20.h> #include <asm/arch-tegra/bitfield.h> #include <asm/arch-tegra/clk_rst.h> #include <asm/arch/clock.h> @@ -788,8 +789,11 @@ void reset_cmplx_set_enable(int cpu, int which, int reset) (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; u32 mask; - /* Form the mask, which depends on the cpu chosen. Tegra2 has 2 */ - assert(cpu >= 0 && cpu < 2); + /* + * Form the mask, which depends on the cpu chosen. Tegra2 has 2, + * Tegra3 has 4. + */ + assert(cpu >= 0 && cpu < ap20_get_num_cpus()); mask = which << cpu; /* either enable or disable those reset for that CPU */ |