From patchwork Tue Sep 30 13:48:32 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sudeep Holla X-Patchwork-Id: 38150 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-la0-f71.google.com (mail-la0-f71.google.com [209.85.215.71]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 3328B20549 for ; Tue, 30 Sep 2014 13:51:10 +0000 (UTC) Received: by mail-la0-f71.google.com with SMTP id gi9sf6355005lab.6 for ; Tue, 30 Sep 2014 06:51:09 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:subject:date:message-id :in-reply-to:references:cc:precedence:list-id:list-unsubscribe :list-archive:list-post:list-help:list-subscribe:mime-version:sender :errors-to:x-original-sender:x-original-authentication-results :mailing-list:content-type:content-transfer-encoding; bh=z/Y137PNDEO74Z76nofGffPs8bXPtKr+1JnZIvb+BB8=; b=W5RellyYSS+vYFZor0TIHvn7c89ShnxnVoClPTN+CclfMoJ/hgDyrleWzXJODNLv0x 0sSGsGBDwXZUFCuL+IyxmaR2qdyirhCaw5H1phHA2jGk2rWfZSQ7UVJYNl9cEPDfL/By BltMepezS6RpXzQ0CK1U5REhG2IKI1JEAmbIONe3dQswbmZIn4IDlVtK8NClVyp10guO MmhxT+o4zlsBlJYgDsF5dN6ARnUW1BS73WRW17gIrYjYJrat6cXGdrEJNxGHd/d7UGpc LV7VupmpYZ6e1i1BI4oMdSnb07eznRoxgA3bkvzYvuw4+xlb445QfoH0MBcGOOqiNnc/ 0vbw== X-Gm-Message-State: ALoCoQkc8cDcgns50GIUIqjOIlyZ7MRbHh7omocEpXuizQdMFzKhg+D3r1+UyoEGvgI5BFzcTJHh X-Received: by 10.180.109.67 with SMTP id hq3mr1282044wib.1.1412085069005; Tue, 30 Sep 2014 06:51:09 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.7.41 with SMTP id g9ls42857laa.93.gmail; Tue, 30 Sep 2014 06:51:08 -0700 (PDT) X-Received: by 10.112.83.235 with SMTP id t11mr10612681lby.101.1412085068814; Tue, 30 Sep 2014 06:51:08 -0700 (PDT) Received: from mail-la0-f50.google.com (mail-la0-f50.google.com [209.85.215.50]) by mx.google.com with ESMTPS id w2si22860245lbb.75.2014.09.30.06.51.07 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 30 Sep 2014 06:51:07 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.50 as permitted sender) client-ip=209.85.215.50; Received: by mail-la0-f50.google.com with SMTP id s18so4731586lam.9 for ; Tue, 30 Sep 2014 06:51:07 -0700 (PDT) X-Received: by 10.152.88.16 with SMTP id bc16mr27650892lab.56.1412085067417; Tue, 30 Sep 2014 06:51:07 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.130.169 with SMTP id of9csp350120lbb; Tue, 30 Sep 2014 06:51:06 -0700 (PDT) X-Received: by 10.67.15.172 with SMTP id fp12mr51997385pad.4.1412085065665; Tue, 30 Sep 2014 06:51:05 -0700 (PDT) Received: from bombadil.infradead.org (bombadil.infradead.org. [2001:1868:205::9]) by mx.google.com with ESMTPS id it5si22064816pbc.230.2014.09.30.06.51.04 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 30 Sep 2014 06:51:05 -0700 (PDT) Received-SPF: none (google.com: linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org does not designate permitted sender hosts) client-ip=2001:1868:205::9; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1XYxo8-0002Kf-UF; Tue, 30 Sep 2014 13:49:36 +0000 Received: from fw-tnat.cambridge.arm.com ([217.140.96.21] helo=cam-smtp0.cambridge.arm.com) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1XYxnd-0001jo-Bj for linux-arm-kernel@lists.infradead.org; Tue, 30 Sep 2014 13:49:06 +0000 Received: from e103737-lin.cambridge.arm.com (e103737-lin.cambridge.arm.com [10.1.207.153]) by cam-smtp0.cambridge.arm.com (8.13.8/8.13.8) with ESMTP id s8UDmMqP025876; Tue, 30 Sep 2014 14:48:28 +0100 From: Sudeep Holla To: LKML Subject: [PATCH v5 11/11] ARM: kernel: add outer cache support for cacheinfo implementation Date: Tue, 30 Sep 2014 14:48:32 +0100 Message-Id: <1412084912-2767-12-git-send-email-sudeep.holla@arm.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1412084912-2767-1-git-send-email-sudeep.holla@arm.com> References: <1412084912-2767-1-git-send-email-sudeep.holla@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140930_064905_955295_361B1361 X-CRM114-Status: GOOD ( 20.90 ) X-Spam-Score: -3.0 (---) X-Spam-Report: SpamAssassin version 3.4.0 on bombadil.infradead.org summary: Content analysis details: (-3.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at http://www.dnswl.org/, medium trust [217.140.96.21 listed in list.dnswl.org] -0.0 RCVD_IN_MSPIKE_H3 RBL: Good reputation (+3) [217.140.96.21 listed in wl.mailspike.net] -0.7 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -0.0 SPF_PASS SPF: sender matches SPF record -0.0 RCVD_IN_MSPIKE_WL Mailspike good senders Cc: Lorenzo Pieralisi , Russell King , Heiko Carstens , Greg Kroah-Hartman , Will Deacon , Sudeep Holla , linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 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+patch=linaro.org@lists.infradead.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: sudeep.holla@arm.com X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.50 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 In order to support outer cache in the cacheinfo infrastructure, a new function 'get_info' is added to outer_cache_fns. This function is used to get the outer cache information namely: line size, number of ways of associativity and number of sets. This patch adds 'get_info' supports to all L2 cache implementations on ARM except Marvell's Feroceon L2 cache. Signed-off-by: Sudeep Holla Cc: Russell King Cc: Will Deacon Cc: linux-arm-kernel@lists.infradead.org --- arch/arm/include/asm/outercache.h | 9 +++++++++ arch/arm/kernel/cacheinfo.c | 14 +++++++++++++- arch/arm/mm/cache-l2x0.c | 35 ++++++++++++++++++++++++++++++++++- arch/arm/mm/cache-tauros2.c | 36 ++++++++++++++++++++++++++++++++++++ arch/arm/mm/cache-xsc3l2.c | 17 +++++++++++++++++ 5 files changed, 109 insertions(+), 2 deletions(-) diff --git a/arch/arm/include/asm/outercache.h b/arch/arm/include/asm/outercache.h index 891a56b35bcf..e063d8c87077 100644 --- a/arch/arm/include/asm/outercache.h +++ b/arch/arm/include/asm/outercache.h @@ -23,7 +23,10 @@ #include +struct cacheinfo; + struct outer_cache_fns { + void (*get_info)(struct cacheinfo *); void (*inv_range)(unsigned long, unsigned long); void (*clean_range)(unsigned long, unsigned long); void (*flush_range)(unsigned long, unsigned long); @@ -112,6 +115,11 @@ static inline void outer_resume(void) outer_cache.resume(); } +static inline void outer_get_info(struct cacheinfo *this_leaf) +{ + if (outer_cache.get_info) + outer_cache.get_info(this_leaf); +} #else static inline void outer_inv_range(phys_addr_t start, phys_addr_t end) @@ -123,6 +131,7 @@ static inline void outer_flush_range(phys_addr_t start, phys_addr_t end) static inline void outer_flush_all(void) { } static inline void outer_disable(void) { } static inline void outer_resume(void) { } +static inline void outer_get_info(struct cacheinfo *this_leaf) { } #endif diff --git a/arch/arm/kernel/cacheinfo.c b/arch/arm/kernel/cacheinfo.c index 8e4f677741d8..2107e1d67914 100644 --- a/arch/arm/kernel/cacheinfo.c +++ b/arch/arm/kernel/cacheinfo.c @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -227,11 +228,19 @@ static inline enum cache_type get_cache_type(int level) return __get_cache_type(level); } +static inline void __outer_ci_leaf_init(struct cacheinfo *this_leaf) +{ + outer_get_info(this_leaf); + BUG_ON(this_leaf->type == CACHE_TYPE_SEPARATE); +} + static void ci_leaf_init(struct cacheinfo *this_leaf, enum cache_type type, unsigned int level) { this_leaf->level = level; - if (cache_is_armv7()) + if (type == CACHE_TYPE_NOCACHE) /* must be outer cache */ + __outer_ci_leaf_init(this_leaf); + else if (cache_is_armv7()) __armv7_ci_leaf_init(type, this_leaf); else __ci_leaf_init(type, this_leaf); @@ -255,6 +264,9 @@ static int __init_cache_level(unsigned int cpu) this_cpu_ci->num_levels = level; this_cpu_ci->num_leaves = leaves; + if (IS_ENABLED(CONFIG_OUTER_CACHE) && outer_cache.get_info) + this_cpu_ci->num_leaves++, this_cpu_ci->num_levels++; + return 0; } diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index 5f2c988a06ac..4114b1944807 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c @@ -17,6 +17,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include +#include #include #include #include @@ -105,6 +106,22 @@ static inline void l2c_unlock(void __iomem *base, unsigned num) } } +static void __l2x0_getinfo(struct cacheinfo *this_leaf) +{ + unsigned int assoc = get_count_order(l2x0_way_mask); + + this_leaf->size = l2x0_size; + this_leaf->coherency_line_size = CACHE_LINE_SIZE; + this_leaf->ways_of_associativity = assoc; + this_leaf->number_of_sets = l2x0_size / (assoc * CACHE_LINE_SIZE); +} + +static void l2x0_getinfo(struct cacheinfo *this_leaf) +{ + this_leaf->type = CACHE_TYPE_UNIFIED; + __l2x0_getinfo(this_leaf); +} + /* * Enable the L2 cache controller. This function must only be * called when the cache controller is known to be disabled. @@ -309,6 +326,7 @@ static const struct l2c_init_data l2c210_data __initconst = { .disable = l2c_disable, .sync = l2c210_sync, .resume = l2c210_resume, + .get_info = l2x0_getinfo, }, }; @@ -466,6 +484,7 @@ static const struct l2c_init_data l2c220_data = { .disable = l2c_disable, .sync = l2c220_sync, .resume = l2c210_resume, + .get_info = l2x0_getinfo, }, }; @@ -814,6 +833,7 @@ static const struct l2c_init_data l2c310_init_fns __initconst = { .disable = l2c310_disable, .sync = l2c210_sync, .resume = l2c310_resume, + .get_info = l2x0_getinfo, }, }; @@ -894,7 +914,6 @@ static void __init __l2c_init(const struct l2c_init_data *data, data->enable(l2x0_base, aux, data->num_lock); outer_cache = fns; - /* * It is strange to save the register state before initialisation, * but hey, this is what the DT implementations decided to do. @@ -994,6 +1013,7 @@ static const struct l2c_init_data of_l2c210_data __initconst = { .disable = l2c_disable, .sync = l2c210_sync, .resume = l2c210_resume, + .get_info = l2x0_getinfo, }, }; @@ -1012,6 +1032,7 @@ static const struct l2c_init_data of_l2c220_data __initconst = { .disable = l2c_disable, .sync = l2c220_sync, .resume = l2c210_resume, + .get_info = l2x0_getinfo, }, }; @@ -1065,6 +1086,7 @@ static const struct l2c_init_data of_l2c310_data __initconst = { .disable = l2c310_disable, .sync = l2c210_sync, .resume = l2c310_resume, + .get_info = l2x0_getinfo, }, }; @@ -1092,6 +1114,7 @@ static const struct l2c_init_data of_l2c310_coherent_data __initconst = { .flush_all = l2c210_flush_all, .disable = l2c310_disable, .resume = l2c310_resume, + .get_info = l2x0_getinfo, }, }; @@ -1255,6 +1278,12 @@ static void __init aurora_of_parse(const struct device_node *np, *aux_mask &= ~mask; } +static void aurora_no_outer_data_getinfo(struct cacheinfo *this_leaf) +{ + this_leaf->type = CACHE_TYPE_INST; + __l2x0_getinfo(this_leaf); +} + static const struct l2c_init_data of_aurora_with_outer_data __initconst = { .type = "Aurora", .way_size_0 = SZ_4K, @@ -1271,6 +1300,7 @@ static const struct l2c_init_data of_aurora_with_outer_data __initconst = { .disable = l2x0_disable, .sync = l2x0_cache_sync, .resume = aurora_resume, + .get_info = l2x0_getinfo, }, }; @@ -1284,6 +1314,7 @@ static const struct l2c_init_data of_aurora_no_outer_data __initconst = { .save = aurora_save, .outer_cache = { .resume = aurora_resume, + .get_info = aurora_no_outer_data_getinfo, }, }; @@ -1439,6 +1470,7 @@ static const struct l2c_init_data of_bcm_l2x0_data __initconst = { .disable = l2c310_disable, .sync = l2c210_sync, .resume = l2c310_resume, + .get_info = l2x0_getinfo, }, }; @@ -1475,6 +1507,7 @@ static const struct l2c_init_data of_tauros3_data __initconst = { /* Tauros3 broadcasts L1 cache operations to L2 */ .outer_cache = { .resume = tauros3_resume, + .get_info = l2x0_getinfo, }, }; diff --git a/arch/arm/mm/cache-tauros2.c b/arch/arm/mm/cache-tauros2.c index b273739e6359..0d4dd8ff6a56 100644 --- a/arch/arm/mm/cache-tauros2.c +++ b/arch/arm/mm/cache-tauros2.c @@ -14,6 +14,7 @@ * Document ID MV-S105190-00, Rev 0.7, March 14 2008. */ +#include #include #include #include @@ -60,6 +61,7 @@ static inline void tauros2_inv_pa(unsigned long addr) * noninclusive. */ #define CACHE_LINE_SIZE 32 +#define CACHE_LINE_SHIFT 5 static void tauros2_inv_range(unsigned long start, unsigned long end) { @@ -131,6 +133,39 @@ static void tauros2_resume(void) "mcr p15, 0, %0, c1, c0, 0 @Enable L2 Cache\n\t" : : "r" (0x0)); } + +/* + * +----------------------------------------+ + * | 11 10 9 8 | 7 6 5 4 3 | 2 | 1 0 | + * +----------------------------------------+ + * | way size | associativity | - |line_sz| + * +----------------------------------------+ + */ +#define L2CTR_ASSOCIAT_SHIFT 3 +#define L2CTR_ASSOCIAT_MASK 0x1F +#define L2CTR_WAYSIZE_SHIFT 8 +#define L2CTR_WAYSIZE_MASK 0xF +#define CACHE_WAY_PER_SET(l2ctr) \ + (((l2_ctr) >> L2CTR_ASSOCIAT_SHIFT) & L2CTR_ASSOCIAT_MASK) +#define CACHE_WAY_SIZE(l2ctr) \ + (8192 << (((l2ctr) >> L2CTR_WAYSIZE_SHIFT) & L2CTR_WAYSIZE_MASK)) +#define CACHE_SET_SIZE(l2ctr) (CACHE_WAY_SIZE(l2ctr) >> CACHE_LINE_SHIFT) + +static void tauros2_getinfo(struct cacheinfo *this_leaf) +{ + unsigned int l2_ctr; + + __asm__("mrc p15, 1, %0, c0, c0, 1" : "=r" (l2_ctr)); + + this_leaf->type = CACHE_TYPE_UNIFIED; + this_leaf->coherency_line_size = CACHE_LINE_SIZE; + this_leaf->ways_of_associativity = CACHE_WAY_PER_SET(l2_ctr); + this_leaf->number_of_sets = CACHE_SET_SIZE(l2_ctr); + this_leaf->size = this_leaf->coherency_line_size * + this_leaf->number_of_sets * + this_leaf->ways_of_associativity; +} + #endif static inline u32 __init read_extra_features(void) @@ -226,6 +261,7 @@ static void __init tauros2_internal_init(unsigned int features) outer_cache.flush_range = tauros2_flush_range; outer_cache.disable = tauros2_disable; outer_cache.resume = tauros2_resume; + outer_cache.get_info = tauros2_getinfo; } #endif diff --git a/arch/arm/mm/cache-xsc3l2.c b/arch/arm/mm/cache-xsc3l2.c index 6c3edeb66e74..175bf44eb039 100644 --- a/arch/arm/mm/cache-xsc3l2.c +++ b/arch/arm/mm/cache-xsc3l2.c @@ -16,6 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include #include #include #include @@ -201,6 +202,21 @@ static void xsc3_l2_flush_range(unsigned long start, unsigned long end) dsb(); } +static void xsc3_l2_getinfo(struct cacheinfo *this_leaf) +{ + unsigned long l2ctype; + + __asm__("mrc p15, 1, %0, c0, c0, 1" : "=r" (l2ctype)); + + this_leaf->type = CACHE_TYPE_UNIFIED; + this_leaf->coherency_line_size = CACHE_LINE_SIZE; + this_leaf->ways_of_associativity = CACHE_WAY_PER_SET; + this_leaf->number_of_sets = CACHE_SET_SIZE(l2ctype); + this_leaf->size = this_leaf->coherency_line_size * + this_leaf->number_of_sets * + this_leaf->ways_of_associativity; +} + static int __init xsc3_l2_init(void) { if (!cpu_is_xsc3() || !xsc3_l2_present()) @@ -213,6 +229,7 @@ static int __init xsc3_l2_init(void) outer_cache.inv_range = xsc3_l2_inv_range; outer_cache.clean_range = xsc3_l2_clean_range; outer_cache.flush_range = xsc3_l2_flush_range; + outer_cache.get_info = xsc3_l2_getinfo; } return 0;