From patchwork Tue Mar 5 00:05:56 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Warren X-Patchwork-Id: 2215421 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork2.kernel.org (Postfix) with ESMTP id 4B02FDF2F2 for ; Tue, 5 Mar 2013 00:09:00 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1UCfOS-0007sT-Uw; Tue, 05 Mar 2013 00:06:08 +0000 Received: from avon.wwwdotorg.org ([2001:470:1f0f:bd7::2]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UCfOP-0007ri-Ng for linux-arm-kernel@lists.infradead.org; Tue, 05 Mar 2013 00:06:06 +0000 Received: from severn.wwwdotorg.org (unknown [192.168.65.5]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by avon.wwwdotorg.org (Postfix) with ESMTPS id 90CF96420; Mon, 4 Mar 2013 17:10:06 -0700 (MST) Received: from swarren-lx1.nvidia.com (localhost [127.0.0.1]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by severn.wwwdotorg.org (Postfix) with ESMTPSA id 92CC3E40FD; Mon, 4 Mar 2013 17:06:01 -0700 (MST) From: Stephen Warren To: Stephen Warren Subject: [PATCH 1/2] ARM: tegra: add CPU errata WARs to Tegra reset handler Date: Mon, 4 Mar 2013 17:05:56 -0700 Message-Id: <1362441957-22050-1-git-send-email-swarren@wwwdotorg.org> X-Mailer: git-send-email 1.7.10.4 X-NVConfidentiality: public X-Virus-Scanned: clamav-milter 0.96.5 at avon.wwwdotorg.org X-Virus-Status: Clean X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130304_190605_926663_A2341AA9 X-CRM114-Status: GOOD ( 12.01 ) X-Spam-Score: -2.5 (--) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-2.5 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record -0.6 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: Stephen Warren , Peter De Schrijver , Bo Yan , Joseph Lo , linux-tegra@vger.kernel.org, linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org From: Stephen Warren The CPU cores in Tegra contain some errata. Workarounds must be applied for these every time a CPU boots. Implement those workarounds directly in the Tegra-specific CPU reset vector. Many of these workarounds duplicate code in the core ARM kernel. However, the core ARM kernel cannot enable those workarounds when building a multi-platform kernel, since they require writing to secure- only registers, and a multi-platform kernel often does not run in secure mode, and also cannot generically/architecturally detect whether it is running in secure mode, and hence cannot either unconditionally or conditionally apply these workarounds. Instead, the workarounds must be applied in architecture-specific reset code, which is able to have more direct knowledge of the secure/normal state. On Tegra, we will be able to detect this using a non-architected register in the future, although we currently assume the kernel runs only in secure mode. Other SoCs may never run the kernel in secure mode, and hence always rely on a secure monitor to enable the workarounds, and hence never implement them in the kernel. Signed-off-by: Stephen Warren --- arch/arm/mach-tegra/reset-handler.S | 45 ++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-tegra/reset-handler.S b/arch/arm/mach-tegra/reset-handler.S index 54382ce..ff7b45c 100644 --- a/arch/arm/mach-tegra/reset-handler.S +++ b/arch/arm/mach-tegra/reset-handler.S @@ -99,6 +99,8 @@ ENTRY(__tegra_cpu_reset_handler_start) * * Register usage within the reset handler: * + * Others: scratch + * R6 = SoC ID << 8 * R7 = CPU present (to the OS) mask * R8 = CPU in LP1 state mask * R9 = CPU in LP2 state mask @@ -114,6 +116,40 @@ ENTRY(__tegra_cpu_reset_handler_start) ENTRY(__tegra_cpu_reset_handler) cpsid aif, 0x13 @ SVC mode, interrupts disabled + + mov32 r6, TEGRA_APB_MISC_BASE + ldr r6, [r6, #APB_MISC_GP_HIDREV] + and r6, r6, #0xff00 +#ifdef CONFIG_ARCH_TEGRA_2x_SOC +t20_check: + cmp r6, #(0x20 << 8) + bne after_t20_check +t20_errata: + # Tegra20 is a Cortex-A9 r1p1 + mrc p15, 0, r0, c1, c0, 0 @ read system control register + orr r0, r0, #1 << 14 @ erratum 716044 + mcr p15, 0, r0, c1, c0, 0 @ write system control register + mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register + orr r0, r0, #1 << 4 @ erratum 742230 + orr r0, r0, #1 << 11 @ erratum 751472 + mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register + b after_errata +after_t20_check: +#endif +#ifdef CONFIG_ARCH_TEGRA_3x_SOC +t30_check: + cmp r6, #(0x30 << 8) + bne after_t30_check +t30_errata: + # Tegra30 is a Cortex-A9 r2p9 + mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register + orr r0, r0, #1 << 6 @ erratum 743622 + orr r0, r0, #1 << 11 @ erratum 751472 + mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register + b after_errata +after_t30_check: +#endif +after_errata: mrc p15, 0, r10, c0, c0, 5 @ MPIDR and r10, r10, #0x3 @ R10 = CPU number mov r11, #1 @@ -129,16 +165,13 @@ ENTRY(__tegra_cpu_reset_handler) #ifdef CONFIG_ARCH_TEGRA_2x_SOC /* Are we on Tegra20? */ - mov32 r6, TEGRA_APB_MISC_BASE - ldr r0, [r6, #APB_MISC_GP_HIDREV] - and r0, r0, #0xff00 - cmp r0, #(0x20 << 8) + cmp r6, #(0x20 << 8) bne 1f /* If not CPU0, don't let CPU0 reset CPU1 now that CPU1 is coming up. */ - mov32 r6, TEGRA_PMC_BASE + mov32 r5, TEGRA_PMC_BASE mov r0, #0 cmp r10, #0 - strne r0, [r6, #PMC_SCRATCH41] + strne r0, [r5, #PMC_SCRATCH41] 1: #endif