From patchwork Tue Jan 29 10:14:39 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: srinidhi kasagar X-Patchwork-Id: 2060851 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 279C540106 for ; Tue, 29 Jan 2013 10:18: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 1U08DX-0000LQ-0R; Tue, 29 Jan 2013 10:15:03 +0000 Received: from eu1sys200aog103.obsmtp.com ([207.126.144.115]) by merlin.infradead.org with smtps (Exim 4.76 #1 (Red Hat Linux)) id 1U08DN-0000Ez-QI for linux-arm-kernel@lists.infradead.org; Tue, 29 Jan 2013 10:14:55 +0000 Received: from beta.dmz-us.st.com ([167.4.1.35]) (using TLSv1) by eu1sys200aob103.postini.com ([207.126.147.11]) with SMTP ID DSNKUQehFXmmKlhOQoPjLJ9pRtMVaiNjWnep@postini.com; Tue, 29 Jan 2013 10:14:53 UTC Received: from zeta.dmz-us.st.com (ns4.st.com [167.4.16.71]) by beta.dmz-us.st.com (STMicroelectronics) with ESMTP id 42D4B4D for ; Tue, 29 Jan 2013 10:13:59 +0000 (GMT) Received: from relay2.stm.gmessaging.net (unknown [10.230.100.18]) by zeta.dmz-us.st.com (STMicroelectronics) with ESMTP id E945D91 for ; Tue, 29 Jan 2013 04:27:34 +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 44570A8081 for ; Tue, 29 Jan 2013 11:14:39 +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; Tue, 29 Jan 2013 11:14:42 +0100 Date: Tue, 29 Jan 2013 15:44:39 +0530 From: srinidhi kasagar To: Subject: [PATCH v2 2/5] ARM: cache-l2x0: Manage the errata at run time Message-ID: <20130129101432.GA16507@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-20130129_051454_232663_1752005C X-CRM114-Status: GOOD ( 22.66 ) 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.115 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 | 1 + arch/arm/mm/cache-l2x0.c | 72 +++++++++++++-------------- 2 files changed, 36 insertions(+), 37 deletions(-) diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h index 49ac638..ab76131 100644 --- a/arch/arm/include/asm/hardware/cache-l2x0.h +++ b/arch/arm/include/asm/hardware/cache-l2x0.h @@ -134,6 +134,7 @@ struct l2x0_regs { }; extern struct l2x0_regs l2x0_saved_regs; +extern u32 l2x0_revision; #endif /* __ASSEMBLY__ */ diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index 432fef0..4f66e64 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c @@ -38,8 +38,10 @@ static unsigned long sync_reg_offset = L2X0_CACHE_SYNC; /* Aurora don't have the cache ID register available, so we have to * pass it though the device tree */ static u32 cache_id_part_number_from_dt; +static u32 cache_rtl_number_from_dt; struct l2x0_regs l2x0_saved_regs; +u32 l2x0_revision; struct l2x0_of_data { void (*setup)(const struct device_node *, u32 *, u32 *); @@ -87,7 +89,6 @@ 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) { if (outer_cache.set_debug) @@ -96,37 +97,31 @@ static inline void debug_writel(unsigned long 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) -{ + /* manage ERRATA_588369 and ERRATA_727915 */ + if (l2x0_revision == L2X0_CACHE_ID_RTL_R0P0 || + l2x0_revision == L2X0_CACHE_ID_RTL_R1P0 || + l2x0_revision == L2X0_CACHE_ID_RTL_R2P0 || + l2x0_revision == L2X0_CACHE_ID_RTL_R3P0) + writel_relaxed(val, l2x0_base + L2X0_DEBUG_CTRL); } -#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); + /* manage the ERRATA_588369 */ + 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) { @@ -330,11 +325,15 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask, bool smc) const char *type; l2x0_base = base; - if (cache_id_part_number_from_dt) + if (cache_id_part_number_from_dt) { cache_id = cache_id_part_number_from_dt; - else + l2x0_revision = cache_rtl_number_from_dt; + } else { cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID) & L2X0_CACHE_ID_PART_MASK; + l2x0_revision = readl_relaxed(l2x0_base + L2X0_CACHE_ID) + & L2X0_CACHE_ID_RTL_MASK; + } aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL); aux &= aux_mask; @@ -348,10 +347,13 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask, bool smc) else ways = 8; type = "L310"; -#ifdef CONFIG_PL310_ERRATA_753970 - /* Unmapped register. */ - sync_reg_offset = L2X0_DUMMY_REG; -#endif + + /* handle ERRATA_753970 */ + if (l2x0_revision == L2X0_CACHE_ID_RTL_R3P0) { + /* Unmapped register. */ + sync_reg_offset = L2X0_DUMMY_REG; + } + if (smc) outer_cache.set_debug = pl310_set_debug; else @@ -605,8 +607,6 @@ 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; l2x0_saved_regs.tag_latency = readl_relaxed(l2x0_base + L2X0_TAG_LATENCY_CTRL); @@ -655,7 +655,6 @@ static void l2x0_resume(void) static void pl310_resume(void) { - u32 l2x0_revision; if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) { /* restore pl310 setup */ @@ -668,9 +667,6 @@ 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; - if (l2x0_revision >= L2X0_CACHE_ID_RTL_R2P0) { writel_relaxed(l2x0_saved_regs.prefetch_ctrl, l2x0_base + L2X0_PREFETCH_CTRL); @@ -710,6 +706,8 @@ static void __init aurora_of_setup(const struct device_node *np, of_property_read_u32(np, "cache-id-part", &cache_id_part_number_from_dt); + of_property_read_u32(np, "cache-id-rtl", + &cache_rtl_number_from_dt); /* Determine and save the write policy */ l2_wt_override = of_property_read_bool(np, "wt-override");