From patchwork Tue Jun 12 12:02:03 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vincent Guittot X-Patchwork-Id: 9222 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 33BEC23E56 for ; Tue, 12 Jun 2012 12:02:54 +0000 (UTC) Received: from mail-gh0-f180.google.com (mail-gh0-f180.google.com [209.85.160.180]) by fiordland.canonical.com (Postfix) with ESMTP id E27F7A18289 for ; Tue, 12 Jun 2012 12:02:53 +0000 (UTC) Received: by ghbz12 with SMTP id z12so3593951ghb.11 for ; Tue, 12 Jun 2012 05:02:53 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf:from:to:cc :subject:date:message-id:x-mailer:in-reply-to:references :x-gm-message-state; bh=HbfHPp+aJQxyyE3+SBRCM41n5VV/zP+Ur97rqpLX/DM=; b=WwN00TLERXkhZ2ZSzCVR217auSxmDn/zOwBx9rVLS+/acDDZznjBA1WQGnvHTg9u1m X4rHTnY70ZhseYVrHh4Erd7H6u2gPGmaenngF9HRPSUYqYX49laKibU5ZQxwOLvTq1Ba b2n+k6IhhQX3wUGkloiLkooWUn7prZNL0eV4c8YuRjWK+tLGL3JGKOjo5t0Ep0h/vrhU aBTRL/1rPJS5OMX1ep6DZt6/ccql5TTw8NwPIioW3tsTOeMRhsdF1poXmOwAmSOqNPK5 rg41DhKboJk7u3t5B6hAw6A56q89pf7trrLLkzuftqpZJgvDS+ZblClxpqS5tslGXqDz jZ5g== Received: by 10.50.57.167 with SMTP id j7mr7879927igq.53.1339502572966; Tue, 12 Jun 2012 05:02:52 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.231.24.148 with SMTP id v20csp162824ibb; Tue, 12 Jun 2012 05:02:52 -0700 (PDT) Received: by 10.216.143.146 with SMTP id l18mr8236633wej.56.1339502571834; Tue, 12 Jun 2012 05:02:51 -0700 (PDT) Received: from mail-wi0-f178.google.com (mail-wi0-f178.google.com [209.85.212.178]) by mx.google.com with ESMTPS id en3si3990752wib.31.2012.06.12.05.02.51 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 12 Jun 2012 05:02:51 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.212.178 is neither permitted nor denied by best guess record for domain of vincent.guittot@linaro.org) client-ip=209.85.212.178; Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.212.178 is neither permitted nor denied by best guess record for domain of vincent.guittot@linaro.org) smtp.mail=vincent.guittot@linaro.org Received: by mail-wi0-f178.google.com with SMTP id hn6so3287199wib.13 for ; Tue, 12 Jun 2012 05:02:51 -0700 (PDT) Received: by 10.180.79.166 with SMTP id k6mr28698282wix.8.1339502571215; Tue, 12 Jun 2012 05:02:51 -0700 (PDT) Received: from localhost.localdomain (LPuteaux-156-14-44-212.w82-127.abo.wanadoo.fr. [82.127.83.212]) by mx.google.com with ESMTPS id gb9sm5060217wib.8.2012.06.12.05.02.48 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 12 Jun 2012 05:02:49 -0700 (PDT) From: Vincent Guittot To: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linaro-dev@lists.linaro.org, devicetree-discuss@lists.ozlabs.org Cc: linux@arm.linux.org.uk, peterz@infradead.org, grant.likely@secretlab.ca, rob.herring@calxeda.com, Vincent Guittot Subject: [RFC 3/4] ARM: topology: Update cpu_power according to DT information Date: Tue, 12 Jun 2012 14:02:03 +0200 Message-Id: <1339502524-10265-4-git-send-email-vincent.guittot@linaro.org> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1339502524-10265-1-git-send-email-vincent.guittot@linaro.org> References: <1339502524-10265-1-git-send-email-vincent.guittot@linaro.org> X-Gm-Message-State: ALoCoQnqS/DO+gLxIkQgdoXNB06cRT+PNOs1ZgYkmjBY/XJ0QpD6A6Rfe7V0CVc6AoArGcahivrm Use cpu compatibility field and clock-frequency field of DT to estimate the capacity of each core of the system Signed-off-by: Vincent Guittot --- arch/arm/kernel/topology.c | 122 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c index 2f85a64..0c2aee4 100644 --- a/arch/arm/kernel/topology.c +++ b/arch/arm/kernel/topology.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -47,6 +48,122 @@ void set_power_scale(unsigned int cpu, unsigned long power) per_cpu(cpu_scale, cpu) = power; } +#ifdef CONFIG_OF +struct cpu_efficiency { + const char *compatible; + unsigned long efficiency; +}; + +/* + * Table of relative efficiency of each processors + * The efficiency value must fit in 20bit. The final + * cpu_scale value must be in the range [1:2048[. + * Processors that are not defined in the table, + * use the default SCHED_POWER_SCALE value for cpu_scale. + */ +struct cpu_efficiency table_efficiency[] = { + {"arm,cortex-a15", 3891}, + {"arm,cortex-a7", 2048}, + {NULL, }, +}; + +struct cpu_capacity { + unsigned long hwid; + unsigned long capacity; +}; + +struct cpu_capacity cpu_capacity[NR_CPUS]; + +unsigned long middle_capacity = 1; + +static void __init parse_dt_topology(void) +{ + struct cpu_efficiency *cpu_eff; + struct device_node *cn = NULL; + unsigned long min_capacity = (unsigned long)(-1); + unsigned long max_capacity = 0; + unsigned long capacity = 0; + int cpu = 0; + + while ((cn = of_find_node_by_type(cn, "cpu"))) { + const u32 *rate, *reg; + char *compatible; + int len; + + if (cpu >= num_possible_cpus()) + break; + + compatible = of_get_property(cn, "compatible", &len); + + for (cpu_eff = table_efficiency; cpu_eff->compatible; cpu_eff++) + if (of_device_is_compatible(cn, cpu_eff->compatible)) + break; + + if (cpu_eff->compatible == NULL) + continue; + + rate = of_get_property(cn, "clock-frequency", &len); + if (!rate || len != 4) { + pr_err("%s missing clock-frequency property\n", + cn->full_name); + continue; + } + + reg = of_get_property(cn, "reg", &len); + if (!reg || len != 4) { + pr_err("%s missing reg property\n", cn->full_name); + continue; + } + + capacity = ((be32_to_cpup(rate)) >> 20) + * cpu_eff->efficiency; + + /* Save min capacity of the system */ + if (capacity < min_capacity) + min_capacity = capacity; + + /* Save max capacity of the system */ + if (capacity > max_capacity) + max_capacity = capacity; + + cpu_capacity[cpu].capacity = capacity; + cpu_capacity[cpu++].hwid = be32_to_cpup(reg); + } + + if (cpu < num_possible_cpus()) + cpu_capacity[cpu].hwid = (unsigned long)(-1); + + middle_capacity = (min_capacity + max_capacity) >> 11; +} + +void update_cpu_power(unsigned int cpu, unsigned long hwid) +{ + unsigned int idx = 0; + + /* look for the cpu's hwid in the cpu capacity table */ + for (idx = 0; idx < num_possible_cpus(); idx++) { + if (cpu_capacity[idx].hwid == hwid) + break; + + if (cpu_capacity[idx].hwid == -1) + return; + } + + if (idx == num_possible_cpus()) + return; + + set_power_scale(cpu, cpu_capacity[idx].capacity / middle_capacity); + + printk(KERN_INFO "CPU%u: update cpu_power %lu\n", + cpu, arch_scale_freq_power(NULL, cpu)); +} + +#else +static inline void parse_dt_topology(void) {} +static inline void update_cpu_power(unsigned int cpuid, unsigned int mpidr) {} +#endif + + /* * cpu topology management */ @@ -60,6 +177,7 @@ void set_power_scale(unsigned int cpu, unsigned long power) * These masks reflect the current use of the affinity levels. * The affinity level can be up to 16 bits according to ARM ARM */ +#define MPIDR_HWID_BITMASK 0xFFFFFF #define MPIDR_LEVEL0_MASK 0x3 #define MPIDR_LEVEL0_SHIFT 0 @@ -157,6 +275,8 @@ void store_cpu_topology(unsigned int cpuid) update_siblings_masks(cpuid); + update_cpu_power(cpuid, mpidr & MPIDR_HWID_BITMASK); + printk(KERN_INFO "CPU%u: thread %d, cpu %d, socket %d, mpidr %x\n", cpuid, cpu_topology[cpuid].thread_id, cpu_topology[cpuid].core_id, @@ -184,4 +304,6 @@ void init_cpu_topology(void) per_cpu(cpu_scale, cpu) = SCHED_POWER_SCALE; } smp_wmb(); + + parse_dt_topology(); }