From patchwork Mon Jan 21 13:14:53 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: srinidhi kasagar X-Patchwork-Id: 2012271 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork1.kernel.org (Postfix) with ESMTP id C9B433FDD2 for ; Mon, 21 Jan 2013 13:19:01 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TxHDb-0001yt-8F; Mon, 21 Jan 2013 13:15:19 +0000 Received: from eu1sys200aog116.obsmtp.com ([207.126.144.141]) by merlin.infradead.org with smtps (Exim 4.76 #1 (Red Hat Linux)) id 1TxHDX-0001xh-6w for linux-arm-kernel@lists.infradead.org; Mon, 21 Jan 2013 13:15:16 +0000 Received: from beta.dmz-eu.st.com ([164.129.1.35]) (using TLSv1) by eu1sys200aob116.postini.com ([207.126.147.11]) with SMTP ID DSNKUP0/YaiJ51bxgchmIENPmpDLNcj7cnWj@postini.com; Mon, 21 Jan 2013 13:15:15 UTC Received: from zeta.dmz-eu.st.com (zeta.dmz-eu.st.com [164.129.230.9]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 06CAB1E2 for ; Mon, 21 Jan 2013 13:14:56 +0000 (GMT) Received: from relay2.stm.gmessaging.net (unknown [10.230.100.18]) by zeta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 7DCD64AF1 for ; Mon, 21 Jan 2013 13:14:56 +0000 (GMT) Received: from exdcvycastm022.EQ1STM.local (alteon-source-exch [10.230.100.61]) (using TLSv1 with cipher RC4-MD5 (128/128 bits)) (Client CN "exdcvycastm022", Issuer "exdcvycastm022" (not verified)) by relay2.stm.gmessaging.net (Postfix) with ESMTPS id 1D710A8072 for ; Mon, 21 Jan 2013 14:14:51 +0100 (CET) Received: from localhost (10.201.54.34) by exdcvycastm022.EQ1STM.local (10.230.100.30) with Microsoft SMTP Server (TLS) id 8.3.83.0; Mon, 21 Jan 2013 14:14:55 +0100 Date: Mon, 21 Jan 2013 18:44:53 +0530 From: srinidhi kasagar To: Subject: [PATCH 1/4] ARM: cache-l2x0: Manage the errata at run time Message-ID: <20130121131451.GA29855@bnru10> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-06-14) X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130121_081515_574125_343070D6 X-CRM114-Status: GOOD ( 22.34 ) X-Spam-Score: -4.2 (----) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-4.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at http://www.dnswl.org/, medium trust [207.126.144.141 listed in list.dnswl.org] -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Make it possible to manage the errata by its own by using the l2x0 ID register. This relieves the platforms from choosing the Errata's at compile time Signed-off-by: srinidhi kasagar --- arch/arm/include/asm/hardware/cache-l2x0.h | 2 + arch/arm/mm/cache-l2x0.c | 77 +++++++++++++++------------- 2 files changed, 43 insertions(+), 36 deletions(-) diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h index 3b2c40b..d5994ac 100644 --- a/arch/arm/include/asm/hardware/cache-l2x0.h +++ b/arch/arm/include/asm/hardware/cache-l2x0.h @@ -117,6 +117,8 @@ static inline int l2x0_of_init(u32 aux_val, u32 aux_mask) } #endif +asmlinkage u32 l2x0_get_rtl_release(void); + struct l2x0_regs { unsigned long phy_base; unsigned long aux_ctrl; diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index c2f3739..49058ac 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c @@ -49,6 +49,16 @@ struct l2x0_of_data { static bool of_init = false; +/* + * Identify ther RTL releases of l2x0 - This might help in applying + * the l2x0 errata's dynamically rather compile time options + */ +asmlinkage u32 l2x0_get_rtl_release(void) +{ + return readl_relaxed(l2x0_base + L2X0_CACHE_ID) & + L2X0_CACHE_ID_RTL_MASK; +} + static inline void cache_wait_way(void __iomem *reg, unsigned long mask) { /* wait for cache operation by line or way to complete */ @@ -87,46 +97,41 @@ static inline void l2x0_inv_line(unsigned long addr) writel_relaxed(addr, base + L2X0_INV_LINE_PA); } -#if defined(CONFIG_PL310_ERRATA_588369) || defined(CONFIG_PL310_ERRATA_727915) -static inline void debug_writel(unsigned long val) +static void debug_writel(unsigned long val) { - if (outer_cache.set_debug) - outer_cache.set_debug(val); + u32 l2x0_revision = l2x0_get_rtl_release(); + + if (l2x0_revision == L2X0_CACHE_ID_RTL_R3P0 || + l2x0_revision == L2X0_CACHE_ID_RTL_R2P0 || + l2x0_revision == L2X0_CACHE_ID_RTL_R1P0 || + l2x0_revision == L2X0_CACHE_ID_RTL_R0P0) + if (outer_cache.set_debug) + outer_cache.set_debug(val); } static void pl310_set_debug(unsigned long val) { writel_relaxed(val, l2x0_base + L2X0_DEBUG_CTRL); } -#else -/* Optimised out for non-errata case */ -static inline void debug_writel(unsigned long val) -{ -} - -#define pl310_set_debug NULL -#endif - -#ifdef CONFIG_PL310_ERRATA_588369 -static inline void l2x0_flush_line(unsigned long addr) -{ - void __iomem *base = l2x0_base; - - /* Clean by PA followed by Invalidate by PA */ - cache_wait(base + L2X0_CLEAN_LINE_PA, 1); - writel_relaxed(addr, base + L2X0_CLEAN_LINE_PA); - cache_wait(base + L2X0_INV_LINE_PA, 1); - writel_relaxed(addr, base + L2X0_INV_LINE_PA); -} -#else static inline void l2x0_flush_line(unsigned long addr) { void __iomem *base = l2x0_base; - cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1); - writel_relaxed(addr, base + L2X0_CLEAN_INV_LINE_PA); + u32 l2x0_revision = l2x0_get_rtl_release(); + + if (l2x0_revision == L2X0_CACHE_ID_RTL_R0P0 || + l2x0_revision == L2X0_CACHE_ID_RTL_R1P0) + { + /* Clean by PA followed by Invalidate by PA */ + cache_wait(base + L2X0_CLEAN_LINE_PA, 1); + writel_relaxed(addr, base + L2X0_CLEAN_LINE_PA); + cache_wait(base + L2X0_INV_LINE_PA, 1); + writel_relaxed(addr, base + L2X0_INV_LINE_PA); + } else { + cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1); + writel_relaxed(addr, base + L2X0_CLEAN_INV_LINE_PA); + } } -#endif static void l2x0_cache_sync(void) { @@ -328,6 +333,7 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask) int ways; int way_size_shift = L2X0_WAY_SIZE_SHIFT; const char *type; + u32 l2x0_revision = l2x0_get_rtl_release(); l2x0_base = base; if (cache_id_part_number_from_dt) @@ -348,10 +354,11 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask) else ways = 8; type = "L310"; -#ifdef CONFIG_PL310_ERRATA_753970 - /* Unmapped register. */ - sync_reg_offset = L2X0_DUMMY_REG; -#endif + + if (l2x0_revision == L2X0_CACHE_ID_RTL_R3P0) + /* Unmapped register. */ + sync_reg_offset = L2X0_DUMMY_REG; + if ((cache_id & L2X0_CACHE_ID_RTL_MASK) <= L2X0_CACHE_ID_RTL_R3P0) outer_cache.set_debug = pl310_set_debug; break; @@ -594,8 +601,7 @@ static void __init pl310_of_setup(const struct device_node *np, static void __init pl310_save(void) { - u32 l2x0_revision = readl_relaxed(l2x0_base + L2X0_CACHE_ID) & - L2X0_CACHE_ID_RTL_MASK; + u32 l2x0_revision = l2x0_get_rtl_release(); l2x0_saved_regs.tag_latency = readl_relaxed(l2x0_base + L2X0_TAG_LATENCY_CTRL); @@ -657,8 +663,7 @@ static void pl310_resume(void) writel_relaxed(l2x0_saved_regs.filter_start, l2x0_base + L2X0_ADDR_FILTER_START); - l2x0_revision = readl_relaxed(l2x0_base + L2X0_CACHE_ID) & - L2X0_CACHE_ID_RTL_MASK; + l2x0_revision = l2x0_get_rtl_release(); if (l2x0_revision >= L2X0_CACHE_ID_RTL_R2P0) { writel_relaxed(l2x0_saved_regs.prefetch_ctrl,