From patchwork Tue Sep 9 07:10:33 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 37025 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-oi0-f71.google.com (mail-oi0-f71.google.com [209.85.218.71]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 93C5320491 for ; Tue, 9 Sep 2014 07:10:47 +0000 (UTC) Received: by mail-oi0-f71.google.com with SMTP id e131sf24476956oig.6 for ; Tue, 09 Sep 2014 00:10:47 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:sender:precedence:list-id:x-original-sender :x-original-authentication-results:mailing-list:list-post:list-help :list-archive:list-unsubscribe; bh=E6S/wDfcP2RyPrCmqwChYn4DAWBnUkXgtmFtKAJdi/g=; b=U0KDfrcFtap/PN47lyz7WA6XMtvSijFrmlTZu+JAu4VODimNxJNJpqQPFhUwCJL7jJ v8UN1Bsn98j42Aqvb6tLOfr5ZCXM5t+weqb4eSSwa4S3rjXIM5IBNUtTXYzERNdIiJkR 79Jlwi4gxHSrHgNTREYg5wZMQVoe4X2f6yeWpbdrA6eFs24UwNQ6t+G3DQQ+U6Mmrr1C 1PeBhRODB80Pcpx5G2ineIFWrdpJ58ZrB5Gk7aDDoo3BpGNGNvU1f6PRxSEhb4C5/AA+ l0F52mnh4N4A/ze3babRk0LgddQ/C7U5sbmObgU3S20wDz7cOSM2Rw+pwqGwQk0gEOVk jzvg== X-Gm-Message-State: ALoCoQkEYcHMMxzzN/zvyE7wh4HW02e5KdHGuq28WKn4WsEJn3t5iqCHhQDAHYphAv0aKI9CkK0I X-Received: by 10.42.188.210 with SMTP id db18mr18173181icb.9.1410246647111; Tue, 09 Sep 2014 00:10:47 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.50.225 with SMTP id s88ls2006866qga.59.gmail; Tue, 09 Sep 2014 00:10:47 -0700 (PDT) X-Received: by 10.52.33.1 with SMTP id n1mr17633183vdi.28.1410246646978; Tue, 09 Sep 2014 00:10:46 -0700 (PDT) Received: from mail-vc0-f182.google.com (mail-vc0-f182.google.com [209.85.220.182]) by mx.google.com with ESMTPS id op4si4908941vcb.43.2014.09.09.00.10.46 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 09 Sep 2014 00:10:46 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.182 as permitted sender) client-ip=209.85.220.182; Received: by mail-vc0-f182.google.com with SMTP id le20so2469298vcb.41 for ; Tue, 09 Sep 2014 00:10:46 -0700 (PDT) X-Received: by 10.52.148.2 with SMTP id to2mr11279518vdb.38.1410246646848; Tue, 09 Sep 2014 00:10:46 -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.221.45.67 with SMTP id uj3csp242030vcb; Tue, 9 Sep 2014 00:10:46 -0700 (PDT) X-Received: by 10.70.61.231 with SMTP id t7mr17544813pdr.15.1410246645889; Tue, 09 Sep 2014 00:10:45 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id dj9si21428006pad.241.2014.09.09.00.10.45 for ; Tue, 09 Sep 2014 00:10:45 -0700 (PDT) Received-SPF: none (google.com: linux-leds-owner@vger.kernel.org does not designate permitted sender hosts) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755464AbaIIHKp (ORCPT ); Tue, 9 Sep 2014 03:10:45 -0400 Received: from mail-wi0-f175.google.com ([209.85.212.175]:34196 "EHLO mail-wi0-f175.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755322AbaIIHKn (ORCPT ); Tue, 9 Sep 2014 03:10:43 -0400 Received: by mail-wi0-f175.google.com with SMTP id ex7so3704937wid.2 for ; Tue, 09 Sep 2014 00:10:42 -0700 (PDT) X-Received: by 10.194.179.73 with SMTP id de9mr40584037wjc.87.1410246641946; Tue, 09 Sep 2014 00:10:41 -0700 (PDT) Received: from localhost.localdomain ([85.235.11.236]) by mx.google.com with ESMTPSA id pc6sm13710398wjb.43.2014.09.09.00.10.40 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 09 Sep 2014 00:10:41 -0700 (PDT) From: Linus Walleij To: linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, linux-leds@vger.kernel.org, linux-pm@vger.kernel.org, Arnd Bergmann Cc: Pawel Moll , Mark Rutland , Marc Zyngier , Will Deacon , Rob Herring , Linus Walleij , Florian Fainelli Subject: [PATCH v2] ARM: l2c: parse cache properties from ePAPR definitions Date: Tue, 9 Sep 2014 09:10:33 +0200 Message-Id: <1410246633-23407-1-git-send-email-linus.walleij@linaro.org> X-Mailer: git-send-email 1.9.3 Sender: linux-leds-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-leds@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: linus.walleij@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.182 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 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , When both 'cache-size' and 'cache-sets' are specified for a L2 cache controller node, parse those properties and set up the set size based on which type of L2 cache controller we are using. Update the L2 cache controller Device Tree binding with the optional 'cache-size', 'cache-sets', 'cache-block-size' and 'cache-line-size' properties. These come from the ePAPR specification. Using the cache size, number of sets and cache line size we can calculate desired associativity of the L2 cache. This is done by the calculation: set size = cache size / sets ways = set size / line size way size = cache size / ways associativity = way size / line size This patch is an extended version based on the initial patch by Florian Fainelli. Signed-off-by: Florian Fainelli Signed-off-by: Linus Walleij --- Documentation/devicetree/bindings/arm/l2cc.txt | 6 ++ arch/arm/mm/cache-l2x0.c | 134 +++++++++++++++++++++++++ 2 files changed, 140 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/l2cc.txt b/Documentation/devicetree/bindings/arm/l2cc.txt index af527ee111c2..b77343914c66 100644 --- a/Documentation/devicetree/bindings/arm/l2cc.txt +++ b/Documentation/devicetree/bindings/arm/l2cc.txt @@ -44,6 +44,12 @@ Optional properties: I/O coherent mode. Valid only when the arm,pl310-cache compatible string is used. - interrupts : 1 combined interrupt. +- cache-size : specifies the size in bytes of the cache +- cache-sets : specifies the number of associativity sets of the cache +- cache-block-size : specifies the size in bytes of a cache block +- cache-line-size : specifies the size in bytes of a line in the cache, + if this is not specified, the line size is assumed to be equal to the + cache block size - cache-id-part: cache id part number to be used if it is not present on hardware - wt-override: If present then L2 is forced to Write through mode diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index 5f2c988a06ac..8157b913f3f3 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c @@ -945,6 +945,134 @@ static int l2_wt_override; * pass it though the device tree */ static u32 cache_id_part_number_from_dt; +static void __init l2x0_cache_size_of_parse(const struct device_node *np, + u32 *aux_val, u32 *aux_mask, + u32 max_set_size, + u32 max_associativity) +{ + u32 mask = 0, val = 0; + u32 cache_size = 0, sets = 0; + u32 set_size = 0, set_size_bits = 1; + u32 ways = 0, way_size = 0; + u32 blocksize = 0; + u32 linesize = 0; + u32 assoc = 0; + + of_property_read_u32(np, "cache-size", &cache_size); + of_property_read_u32(np, "cache-sets", &sets); + of_property_read_u32(np, "cache-block-size", &blocksize); + of_property_read_u32(np, "cache-line-size", &linesize); + + if (!cache_size || !sets) + return; + + /* All these l2 caches have the same line = block size actually */ + if (!linesize) { + if (blocksize) { + /* If linesize if not given, it is equal to blocksize */ + linesize = blocksize; + } else { + /* Fall back to known size */ + linesize = CACHE_LINE_SIZE; + } + } + + if (linesize != CACHE_LINE_SIZE) + pr_warn("L2C OF: DT supplied line size %d bytes does " + "not match hardware line size of %d bytes\n", + linesize, + CACHE_LINE_SIZE); + + set_size = cache_size / sets; + ways = set_size / linesize; + way_size = cache_size / ways; + + if (set_size > max_set_size) { + pr_warn("L2C: set size %dKB is too large\n", set_size >> 10); + return; + } + + /* + * This cache is set associative. By increasing associativity + * we increase the number of blocks per set. + */ + assoc = way_size / linesize; + if (assoc > max_associativity) { + pr_err("L2C OF: cache setting yield too high associativity\n"); + pr_err("L2C OF: %d calculated, max %d\n", + assoc, max_associativity); + return; + } + /* This is the PL3x0 case */ + if (max_associativity == 16 && (assoc != 8 && assoc != 16)) { + pr_err("L2C OF: cache setting yield illegal associativity\n"); + pr_err("L2C OF: %d calculated, only 8 and 16 legal\n", assoc); + return; + } + + mask |= L2X0_AUX_CTRL_ASSOC_MASK; + + /* + * Special checks for the PL310 that only has two settings and + * cannot be set to fully associative. + */ + if (max_associativity == 16) { + if (assoc == 16) + val |= L310_AUX_CTRL_ASSOCIATIVITY_16; + /* Else bit is left zero == 8 way associativity */ + } else { + val |= (assoc << L2X0_AUX_CTRL_ASSOC_SHIFT); + } + + pr_debug("L2C OF: cache size: %d bytes (%dKB)\n", + cache_size, cache_size >> 10); + pr_debug("L2C OF: set size: %d bytes (%d KB)\n", + set_size, set_size >> 10); + pr_debug("L2C OF: line size: %d bytes\n", linesize); + pr_debug("L2C OF: ways: %d ways\n", ways); + pr_debug("L2C OF: way size: %d bytes\n", way_size); + pr_debug("L2C OF: associativity: %d\n", assoc); + + switch (set_size >> 10) { + case 512: + set_size_bits = 6; + break; + case 256: + set_size_bits = 5; + break; + case 128: + set_size_bits = 4; + break; + case 64: + set_size_bits = 3; + break; + case 32: + set_size_bits = 2; + break; + case 16: + set_size_bits = 1; + break; + default: + pr_err("L2C OF: cache way size: %d KB is not mapped\n", + way_size); + break; + } + + /* + * The l2x0 TRMs call this size "way size" but that is incorrect: + * the thing being configured in these register bits is actually + * the cache set size, so the variable here has the right name + * but the register bit definitions following the TRM are not + * in archaic naming. + */ + mask |= L2C_AUX_CTRL_WAY_SIZE_MASK; + val |= (set_size_bits << L2C_AUX_CTRL_WAY_SIZE_SHIFT); + + *aux_val &= ~mask; + *aux_val |= val; + *aux_mask &= ~mask; +} + static void __init l2x0_of_parse(const struct device_node *np, u32 *aux_val, u32 *aux_mask) { @@ -974,6 +1102,8 @@ static void __init l2x0_of_parse(const struct device_node *np, val |= (dirty - 1) << L2X0_AUX_CTRL_DIRTY_LATENCY_SHIFT; } + l2x0_cache_size_of_parse(np, aux_val, aux_mask, SZ_256K, 8); + *aux_val &= ~mask; *aux_val |= val; *aux_mask &= ~mask; @@ -1047,6 +1177,8 @@ static void __init l2c310_of_parse(const struct device_node *np, writel_relaxed((filter[0] & ~(SZ_1M - 1)) | L310_ADDR_FILTER_EN, l2x0_base + L310_ADDR_FILTER_START); } + + l2x0_cache_size_of_parse(np, aux_val, aux_mask, SZ_512K, 16); } static const struct l2c_init_data of_l2c310_data __initconst = { @@ -1253,6 +1385,8 @@ static void __init aurora_of_parse(const struct device_node *np, *aux_val &= ~mask; *aux_val |= val; *aux_mask &= ~mask; + + l2x0_cache_size_of_parse(np, aux_val, aux_mask, SZ_256K, 8); } static const struct l2c_init_data of_aurora_with_outer_data __initconst = {