From 5605de2e1851d005c226643af2040bffca9c6c39 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 3 Oct 2011 13:21:11 -0700 Subject: 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 Tested-by: Simon Glass --- arch/arm/cpu/armv7/tegra-common/ap20.c | 39 ++++++++++++++++++++++++++++----- arch/arm/cpu/armv7/tegra-common/clock.c | 8 +++++-- 2 files changed, 40 insertions(+), 7 deletions(-) (limited to 'arch/arm/cpu/armv7/tegra-common') 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 +#include #include #include #include @@ -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 */ -- cgit v1.2.3