From nobody Sun Feb 8 05:04:01 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 81A9EC43217 for ; Mon, 28 Nov 2022 12:43:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231296AbiK1MnC (ORCPT ); Mon, 28 Nov 2022 07:43:02 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49162 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230120AbiK1Mm4 (ORCPT ); Mon, 28 Nov 2022 07:42:56 -0500 Received: from mail.marcansoft.com (marcansoft.com [212.63.210.85]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7CBC564E4; Mon, 28 Nov 2022 04:42:55 -0800 (PST) Received: from [127.0.0.1] (localhost [127.0.0.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: sendonly@marcansoft.com) by mail.marcansoft.com (Postfix) with ESMTPSA id 6D18041EF0; Mon, 28 Nov 2022 12:42:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=marcan.st; s=default; t=1669639373; bh=SBgcElhpUc4MT68tmx19BwGELoM0ZF5BGvjBw82P0Lw=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=LlSo0LLK/GsVEe6+DBiT8NcAytsR2UudjTgh9acnYnEyUabkhJ+mZ+svmXw7LgnEl hp6vDjGU/6K6tY1huXuVXQnozw9yPLlpeX+uCOHCwnO3OI2dEx+PJtBrO/cxX5M1Zs 0ZxFM+pvN4NW+uWXDu+i02mtom7wZ19PiRvGjmUkKA1ic7eTfq1P2ZtdQ6B1pnIUo5 rYV3Z76CPMSBeZU3LTpC2iUEEKxM4JBjcujO3RAacq5VsAyN7aVR8gbNRLSYrZqHRC GGah8sFk3F+B7K2Ip9QMLkPVrwABoaAPu1neD8KVflwEUYLQZ0Y29zdVbvL8RoJK2o 55P4JeG11UeDQ== From: Hector Martin To: "Rafael J. Wysocki" , Viresh Kumar , Matthias Brugger Cc: Hector Martin , Sven Peter , Alyssa Rosenzweig , Rob Herring , Krzysztof Kozlowski , Stephen Boyd , Ulf Hansson , Marc Zyngier , Mark Kettenis , asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 1/4] MAINTAINERS: Add entries for Apple SoC cpufreq driver Date: Mon, 28 Nov 2022 21:42:13 +0900 Message-Id: <20221128124216.13477-2-marcan@marcan.st> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20221128124216.13477-1-marcan@marcan.st> References: <20221128124216.13477-1-marcan@marcan.st> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This MAINTAINERS update is split, as usual, to facilitate merges via the SoC tree and avoid conflicts. Acked-by: Marc Zyngier Signed-off-by: Hector Martin --- MAINTAINERS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 379945f82a64..52df511ad87c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1897,6 +1897,7 @@ T: git https://github.com/AsahiLinux/linux.git F: Documentation/devicetree/bindings/arm/apple.yaml F: Documentation/devicetree/bindings/arm/apple/* F: Documentation/devicetree/bindings/clock/apple,nco.yaml +F: Documentation/devicetree/bindings/cpufreq/apple,cluster-cpufreq.yaml F: Documentation/devicetree/bindings/dma/apple,admac.yaml F: Documentation/devicetree/bindings/i2c/apple,i2c.yaml F: Documentation/devicetree/bindings/interrupt-controller/apple,* @@ -1911,6 +1912,7 @@ F: Documentation/devicetree/bindings/power/apple* F: Documentation/devicetree/bindings/watchdog/apple,wdt.yaml F: arch/arm64/boot/dts/apple/ F: drivers/clk/clk-apple-nco.c +F: drivers/cpufreq/apple-soc-cpufreq.c F: drivers/dma/apple-admac.c F: drivers/i2c/busses/i2c-pasemi-core.c F: drivers/i2c/busses/i2c-pasemi-platform.c --=20 2.35.1 From nobody Sun Feb 8 05:04:01 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6FC76C43217 for ; Mon, 28 Nov 2022 12:43:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231307AbiK1MnE (ORCPT ); Mon, 28 Nov 2022 07:43:04 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49240 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231263AbiK1MnB (ORCPT ); Mon, 28 Nov 2022 07:43:01 -0500 Received: from mail.marcansoft.com (marcansoft.com [212.63.210.85]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5A7A06568; Mon, 28 Nov 2022 04:43:00 -0800 (PST) Received: from [127.0.0.1] (localhost [127.0.0.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: sendonly@marcansoft.com) by mail.marcansoft.com (Postfix) with ESMTPSA id 6ABAB41F4A; Mon, 28 Nov 2022 12:42:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=marcan.st; s=default; t=1669639378; bh=IJcTfOUw3TRQPkHgu7ZsA5CG0etWrehb7Gr/4xG5dl8=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=BHP4mz5jOvw3yuKiPXOrO9ybm4tuE9FwfYaHMZERvXi/hHVuRT9ulIgNLV9rsbYAf c8ex0Cja+HKk1a05f+8tgLGafDZgwam7RpV1EzSqt4VN5PFrm3INaLZkfY3t+dYzjV EEU38ddQmj4vq9kCSjmxP4XnLZSpSQSFHqrmjmKbPWfztv+Qx9wnRpLn9i4bFXzgBr lBq2Wt/3AnfgvYtqOJ25F9MCFxt3GFV00a8W0kch/RLYdvjuf7qPj1q6lnoEWf8Y41 yEI7yRNKHsP6lHtO0xI5FyNEwhlOZo/N0A0xC/p8L0wwCAtuY0h8HZyeIZbdSXyuzA r/nrZarCA0XKg== From: Hector Martin To: "Rafael J. Wysocki" , Viresh Kumar , Matthias Brugger Cc: Hector Martin , Sven Peter , Alyssa Rosenzweig , Rob Herring , Krzysztof Kozlowski , Stephen Boyd , Ulf Hansson , Marc Zyngier , Mark Kettenis , asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 2/4] dt-bindings: cpufreq: apple,soc-cpufreq: Add binding for Apple SoC cpufreq Date: Mon, 28 Nov 2022 21:42:14 +0900 Message-Id: <20221128124216.13477-3-marcan@marcan.st> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20221128124216.13477-1-marcan@marcan.st> References: <20221128124216.13477-1-marcan@marcan.st> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This binding represents the cpufreq/DVFS hardware present in Apple SoCs. The hardware has an independent controller per CPU cluster, and we represent them as unique nodes in order to accurately describe the hardware. The driver is responsible for binding them as a single cpufreq device (in the Linux cpufreq model). Acked-by: Marc Zyngier Signed-off-by: Hector Martin --- .../cpufreq/apple,cluster-cpufreq.yaml | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 Documentation/devicetree/bindings/cpufreq/apple,cluster= -cpufreq.yaml diff --git a/Documentation/devicetree/bindings/cpufreq/apple,cluster-cpufre= q.yaml b/Documentation/devicetree/bindings/cpufreq/apple,cluster-cpufreq.ya= ml new file mode 100644 index 000000000000..a21271f73fc1 --- /dev/null +++ b/Documentation/devicetree/bindings/cpufreq/apple,cluster-cpufreq.yaml @@ -0,0 +1,117 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/cpufreq/apple,cluster-cpufreq.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Apple SoC cluster cpufreq device + +maintainers: + - Hector Martin + +description: | + Apple SoCs (e.g. M1) have a per-cpu-cluster DVFS controller that is part= of + the cluster management register block. This binding uses the standard + operating-points-v2 table to define the CPU performance states, with the + opp-level property specifying the hardware p-state index for that level. + +properties: + compatible: + oneOf: + - items: + - oneOf: + - apple,t8103-cluster-cpufreq + - apple,t8112-cluster-cpufreq + - const: apple,cluster-cpufreq + - items: + - const: apple,t6000-cluster-cpufreq + - const: apple,t8103-cluster-cpufreq + - const: apple,cluster-cpufreq + + reg: + maxItems: 1 + + '#performance-domain-cells': + const: 0 + +required: + - compatible + - reg + - '#performance-domain-cells' + +additionalProperties: false + +examples: + - | + // This example shows a single CPU per domain and 2 domains, + // with two p-states per domain. + // Shipping hardware has 2-4 CPUs per domain and 2-6 domains. + cpus { + #address-cells =3D <2>; + #size-cells =3D <0>; + + cpu@0 { + compatible =3D "apple,icestorm"; + device_type =3D "cpu"; + reg =3D <0x0 0x0>; + operating-points-v2 =3D <&ecluster_opp>; + performance-domains =3D <&cpufreq_e>; + }; + + cpu@10100 { + compatible =3D "apple,firestorm"; + device_type =3D "cpu"; + reg =3D <0x0 0x10100>; + operating-points-v2 =3D <&pcluster_opp>; + performance-domains =3D <&cpufreq_p>; + }; + }; + + ecluster_opp: opp-table-0 { + compatible =3D "operating-points-v2"; + opp-shared; + + opp01 { + opp-hz =3D /bits/ 64 <600000000>; + opp-level =3D <1>; + clock-latency-ns =3D <7500>; + }; + opp02 { + opp-hz =3D /bits/ 64 <972000000>; + opp-level =3D <2>; + clock-latency-ns =3D <22000>; + }; + }; + + pcluster_opp: opp-table-1 { + compatible =3D "operating-points-v2"; + opp-shared; + + opp01 { + opp-hz =3D /bits/ 64 <600000000>; + opp-level =3D <1>; + clock-latency-ns =3D <8000>; + }; + opp02 { + opp-hz =3D /bits/ 64 <828000000>; + opp-level =3D <2>; + clock-latency-ns =3D <19000>; + }; + }; + + soc { + #address-cells =3D <2>; + #size-cells =3D <2>; + + cpufreq_e: performance-controller@210e20000 { + compatible =3D "apple,t8103-cluster-cpufreq", "apple,cluster-cpufr= eq"; + reg =3D <0x2 0x10e20000 0 0x1000>; + #performance-domain-cells =3D <0>; + }; + + cpufreq_p: performance-controller@211e20000 { + compatible =3D "apple,t8103-cluster-cpufreq", "apple,cluster-cpufr= eq"; + reg =3D <0x2 0x11e20000 0 0x1000>; + #performance-domain-cells =3D <0>; + }; + }; --=20 2.35.1 From nobody Sun Feb 8 05:04:01 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4026DC46467 for ; Mon, 28 Nov 2022 12:43:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231461AbiK1MnP (ORCPT ); Mon, 28 Nov 2022 07:43:15 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49440 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231403AbiK1MnJ (ORCPT ); Mon, 28 Nov 2022 07:43:09 -0500 Received: from mail.marcansoft.com (marcansoft.com [212.63.210.85]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 718CCA187; Mon, 28 Nov 2022 04:43:05 -0800 (PST) Received: from [127.0.0.1] (localhost [127.0.0.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: sendonly@marcansoft.com) by mail.marcansoft.com (Postfix) with ESMTPSA id 694B641F5F; Mon, 28 Nov 2022 12:42:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=marcan.st; s=default; t=1669639384; bh=xu+M6kzAgmGaqxFmqGvu6onPy0TJsA1BV56P0fanJXc=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=eTM3zq8DbsjBS009RhuxOa4tjYtommczCPGSpaDiNK0SuqmfhZk2TgCasMeO6DMDF ndUkQHX2yBuirYTZrWCv5JHijmvimwcqYHOl2Kb9BwKlDSON3KdAtrBp1ppO8ZCOu9 63RrZulwwtHJXKG61oruGMgTNjzBOKJKwdh5Gay+KUqURlz3gwqv0wk8UvSdzUVV7V Obn6nFVrR9C36KfFrVJAoa8RPa7KZRBGco4/kGXgcFVzlcTtvzwQYWu0JOeiXirDyz Xq6I0urOGdJ0Th9Oh71ZgNzIssZvd4WpZNqI+CwV2EGcXqmhb73FhNW+HntIiAQPJ7 swW3RClEIjgCA== From: Hector Martin To: "Rafael J. Wysocki" , Viresh Kumar , Matthias Brugger Cc: Hector Martin , Sven Peter , Alyssa Rosenzweig , Rob Herring , Krzysztof Kozlowski , Stephen Boyd , Ulf Hansson , Marc Zyngier , Mark Kettenis , asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 3/4] cpufreq: apple-soc: Add new driver to control Apple SoC CPU P-states Date: Mon, 28 Nov 2022 21:42:15 +0900 Message-Id: <20221128124216.13477-4-marcan@marcan.st> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20221128124216.13477-1-marcan@marcan.st> References: <20221128124216.13477-1-marcan@marcan.st> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This driver implements CPU frequency scaling for Apple Silicon SoCs, including M1 (t8103), M1 Max/Pro/Ultra (t600x), and M2 (t8112). Each CPU cluster has its own register set, and frequency management is fully automated by the hardware; the driver only has to write one register. There is boost frequency support, but the hardware will only allow their use if only a subset of cores in a cluster are in non-deep-idle. Since we don't support deep idle yet, these frequencies are not achievable, but the driver supports them. They will remain disabled in the device tree until deep idle is implemented, to avoid confusing users. This driver does not yet implement the memory controller performance state tuning that usually accompanies higher CPU p-states. This will be done in a future patch. Acked-by: Marc Zyngier Signed-off-by: Hector Martin --- drivers/cpufreq/Kconfig.arm | 9 + drivers/cpufreq/Makefile | 1 + drivers/cpufreq/apple-soc-cpufreq.c | 352 +++++++++++++++++++++++++++ drivers/cpufreq/cpufreq-dt-platdev.c | 2 + 4 files changed, 364 insertions(+) create mode 100644 drivers/cpufreq/apple-soc-cpufreq.c diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm index be590f498e6a..0a0352d8fa45 100644 --- a/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm @@ -41,6 +41,15 @@ config ARM_ALLWINNER_SUN50I_CPUFREQ_NVMEM To compile this driver as a module, choose M here: the module will be called sun50i-cpufreq-nvmem. =20 +config ARM_APPLE_SOC_CPUFREQ + tristate "Apple Silicon SoC CPUFreq support" + depends on ARCH_APPLE || (COMPILE_TEST && 64BIT) + select PM_OPP + default ARCH_APPLE + help + This adds the CPUFreq driver for Apple Silicon machines + (e.g. Apple M1). + config ARM_ARMADA_37XX_CPUFREQ tristate "Armada 37xx CPUFreq support" depends on ARCH_MVEBU && CPUFREQ_DT diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile index 49b98c62c5af..32a7029e25ed 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile @@ -52,6 +52,7 @@ obj-$(CONFIG_X86_AMD_FREQ_SENSITIVITY) +=3D amd_freq_sens= itivity.o =20 ##########################################################################= ######## # ARM SoC drivers +obj-$(CONFIG_ARM_APPLE_SOC_CPUFREQ) +=3D apple-soc-cpufreq.o obj-$(CONFIG_ARM_ARMADA_37XX_CPUFREQ) +=3D armada-37xx-cpufreq.o obj-$(CONFIG_ARM_ARMADA_8K_CPUFREQ) +=3D armada-8k-cpufreq.o obj-$(CONFIG_ARM_BRCMSTB_AVS_CPUFREQ) +=3D brcmstb-avs-cpufreq.o diff --git a/drivers/cpufreq/apple-soc-cpufreq.c b/drivers/cpufreq/apple-so= c-cpufreq.c new file mode 100644 index 000000000000..d1801281cdd9 --- /dev/null +++ b/drivers/cpufreq/apple-soc-cpufreq.c @@ -0,0 +1,352 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Apple SoC CPU cluster performance state driver + * + * Copyright The Asahi Linux Contributors + * + * Based on scpi-cpufreq.c + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define APPLE_DVFS_CMD 0x20 +#define APPLE_DVFS_CMD_BUSY BIT(31) +#define APPLE_DVFS_CMD_SET BIT(25) +#define APPLE_DVFS_CMD_PS2 GENMASK(16, 12) +#define APPLE_DVFS_CMD_PS1 GENMASK(4, 0) + +/* Same timebase as CPU counter (24MHz) */ +#define APPLE_DVFS_LAST_CHG_TIME 0x38 + +/* + * Apple ran out of bits and had to shift this in T8112... + */ +#define APPLE_DVFS_STATUS 0x50 +#define APPLE_DVFS_STATUS_CUR_PS_T8103 GENMASK(7, 4) +#define APPLE_DVFS_STATUS_CUR_PS_SHIFT_T8103 4 +#define APPLE_DVFS_STATUS_TGT_PS_T8103 GENMASK(3, 0) +#define APPLE_DVFS_STATUS_CUR_PS_T8112 GENMASK(9, 5) +#define APPLE_DVFS_STATUS_CUR_PS_SHIFT_T8112 5 +#define APPLE_DVFS_STATUS_TGT_PS_T8112 GENMASK(4, 0) + +/* + * Div is +1, base clock is 12MHz on existing SoCs. + * For documentation purposes. We use the OPP table to + * get the frequency. + */ +#define APPLE_DVFS_PLL_STATUS 0xc0 +#define APPLE_DVFS_PLL_FACTOR 0xc8 +#define APPLE_DVFS_PLL_FACTOR_MULT GENMASK(31, 16) +#define APPLE_DVFS_PLL_FACTOR_DIV GENMASK(15, 0) + +#define APPLE_DVFS_TRANSITION_TIMEOUT 100 + +struct apple_soc_cpufreq_info { + u64 max_pstate; + u64 cur_pstate_mask; + u64 cur_pstate_shift; +}; + +struct apple_cpu_priv { + struct device *cpu_dev; + void __iomem *reg_base; + const struct apple_soc_cpufreq_info *info; +}; + +static struct cpufreq_driver apple_soc_cpufreq_driver; + +static const struct apple_soc_cpufreq_info soc_t8103_info =3D { + .max_pstate =3D 15, + .cur_pstate_mask =3D APPLE_DVFS_STATUS_CUR_PS_T8103, + .cur_pstate_shift =3D APPLE_DVFS_STATUS_CUR_PS_SHIFT_T8103, +}; + +static const struct apple_soc_cpufreq_info soc_t8112_info =3D { + .max_pstate =3D 31, + .cur_pstate_mask =3D APPLE_DVFS_STATUS_CUR_PS_T8112, + .cur_pstate_shift =3D APPLE_DVFS_STATUS_CUR_PS_SHIFT_T8112, +}; + +static const struct apple_soc_cpufreq_info soc_default_info =3D { + .max_pstate =3D 15, + .cur_pstate_mask =3D 0, /* fallback */ +}; + +static const struct of_device_id apple_soc_cpufreq_of_match[] =3D { + { + .compatible =3D "apple,t8103-cluster-cpufreq", + .data =3D &soc_t8103_info, + }, + { + .compatible =3D "apple,t8112-cluster-cpufreq", + .data =3D &soc_t8112_info, + }, + { + .compatible =3D "apple,cluster-cpufreq", + .data =3D &soc_default_info, + }, + {} +}; + +static unsigned int apple_soc_cpufreq_get_rate(unsigned int cpu) +{ + struct cpufreq_policy *policy =3D cpufreq_cpu_get_raw(cpu); + struct apple_cpu_priv *priv =3D policy->driver_data; + struct cpufreq_frequency_table *p; + unsigned int pstate; + + if (priv->info->cur_pstate_mask) { + u64 reg =3D readq_relaxed(priv->reg_base + APPLE_DVFS_STATUS); + + pstate =3D (reg & priv->info->cur_pstate_mask) >> priv->info->cur_pstat= e_shift; + } else { + /* + * For the fallback case we might not know the layout of DVFS_STATUS, + * so just use the command register value (which ignores boost limitatio= ns). + */ + u64 reg =3D readq_relaxed(priv->reg_base + APPLE_DVFS_CMD); + + pstate =3D FIELD_GET(APPLE_DVFS_CMD_PS1, reg); + } + + cpufreq_for_each_valid_entry(p, policy->freq_table) + if (p->driver_data =3D=3D pstate) + return p->frequency; + + dev_err(priv->cpu_dev, "could not find frequency for pstate %d\n", + pstate); + return 0; +} + +static int apple_soc_cpufreq_set_target(struct cpufreq_policy *policy, + unsigned int index) +{ + struct apple_cpu_priv *priv =3D policy->driver_data; + unsigned int pstate =3D policy->freq_table[index].driver_data; + u64 reg; + + /* Fallback for newer SoCs */ + if (index > priv->info->max_pstate) + index =3D priv->info->max_pstate; + + if (readq_poll_timeout_atomic(priv->reg_base + APPLE_DVFS_CMD, reg, + !(reg & APPLE_DVFS_CMD_BUSY), 2, + APPLE_DVFS_TRANSITION_TIMEOUT)) { + return -EIO; + } + + reg &=3D ~(APPLE_DVFS_CMD_PS1 | APPLE_DVFS_CMD_PS2); + reg |=3D FIELD_PREP(APPLE_DVFS_CMD_PS1, pstate); + reg |=3D FIELD_PREP(APPLE_DVFS_CMD_PS2, pstate); + reg |=3D APPLE_DVFS_CMD_SET; + + writeq_relaxed(reg, priv->reg_base + APPLE_DVFS_CMD); + + return 0; +} + +static unsigned int apple_soc_cpufreq_fast_switch(struct cpufreq_policy *p= olicy, + unsigned int target_freq) +{ + if (apple_soc_cpufreq_set_target(policy, policy->cached_resolved_idx) < 0) + return 0; + + return policy->freq_table[policy->cached_resolved_idx].frequency; +} + +static int apple_soc_cpufreq_find_cluster(struct cpufreq_policy *policy, + void __iomem **reg_base, + const struct apple_soc_cpufreq_info **info) +{ + struct of_phandle_args args; + const struct of_device_id *match; + int ret =3D 0; + + ret =3D of_perf_domain_get_sharing_cpumask(policy->cpu, "performance-doma= ins", + "#performance-domain-cells", + policy->cpus, &args); + if (ret < 0) + return ret; + + match =3D of_match_node(apple_soc_cpufreq_of_match, args.np); + of_node_put(args.np); + if (!match) + return -ENODEV; + + *info =3D match->data; + + *reg_base =3D of_iomap(args.np, 0); + if (IS_ERR(*reg_base)) + return PTR_ERR(*reg_base); + + return 0; +} + +static struct freq_attr *apple_soc_cpufreq_hw_attr[] =3D { + &cpufreq_freq_attr_scaling_available_freqs, + NULL, /* Filled in below if boost is enabled */ + NULL, +}; + +static int apple_soc_cpufreq_init(struct cpufreq_policy *policy) +{ + int ret, i; + unsigned int transition_latency; + void __iomem *reg_base; + struct device *cpu_dev; + struct apple_cpu_priv *priv; + const struct apple_soc_cpufreq_info *info; + struct cpufreq_frequency_table *freq_table; + + cpu_dev =3D get_cpu_device(policy->cpu); + if (!cpu_dev) { + pr_err("failed to get cpu%d device\n", policy->cpu); + return -ENODEV; + } + + ret =3D dev_pm_opp_of_add_table(cpu_dev); + if (ret < 0) { + dev_err(cpu_dev, "%s: failed to add OPP table: %d\n", __func__, ret); + return ret; + } + + ret =3D apple_soc_cpufreq_find_cluster(policy, ®_base, &info); + if (ret) { + dev_err(cpu_dev, "%s: failed to get cluster info: %d\n", __func__, ret); + return ret; + } + + ret =3D dev_pm_opp_set_sharing_cpus(cpu_dev, policy->cpus); + if (ret) { + dev_err(cpu_dev, "%s: failed to mark OPPs as shared: %d\n", __func__, re= t); + goto out_iounmap; + } + + ret =3D dev_pm_opp_get_opp_count(cpu_dev); + if (ret <=3D 0) { + dev_dbg(cpu_dev, "OPP table is not ready, deferring probe\n"); + ret =3D -EPROBE_DEFER; + goto out_free_opp; + } + + priv =3D kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) { + ret =3D -ENOMEM; + goto out_free_opp; + } + + ret =3D dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table); + if (ret) { + dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret); + goto out_free_priv; + } + + /* Get OPP levels (p-state indexes) and stash them in driver_data */ + for (i =3D 0; freq_table[i].frequency !=3D CPUFREQ_TABLE_END; i++) { + unsigned long rate =3D freq_table[i].frequency * 1000 + 999; + struct dev_pm_opp *opp =3D dev_pm_opp_find_freq_floor(cpu_dev, &rate); + + if (IS_ERR(opp)) { + ret =3D PTR_ERR(opp); + goto out_free_cpufreq_table; + } + freq_table[i].driver_data =3D dev_pm_opp_get_level(opp); + dev_pm_opp_put(opp); + } + + priv->cpu_dev =3D cpu_dev; + priv->reg_base =3D reg_base; + priv->info =3D info; + policy->driver_data =3D priv; + policy->freq_table =3D freq_table; + + transition_latency =3D dev_pm_opp_get_max_transition_latency(cpu_dev); + if (!transition_latency) + transition_latency =3D CPUFREQ_ETERNAL; + + policy->cpuinfo.transition_latency =3D transition_latency; + policy->dvfs_possible_from_any_cpu =3D true; + policy->fast_switch_possible =3D true; + + if (policy_has_boost_freq(policy)) { + ret =3D cpufreq_enable_boost_support(); + if (ret) { + dev_warn(cpu_dev, "failed to enable boost: %d\n", ret); + } else { + apple_soc_cpufreq_hw_attr[1] =3D &cpufreq_freq_attr_scaling_boost_freqs; + apple_soc_cpufreq_driver.boost_enabled =3D true; + } + } + + return 0; + +out_free_cpufreq_table: + dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table); +out_free_priv: + kfree(priv); +out_free_opp: + dev_pm_opp_remove_all_dynamic(cpu_dev); +out_iounmap: + iounmap(reg_base); + return ret; +} + +static int apple_soc_cpufreq_exit(struct cpufreq_policy *policy) +{ + struct apple_cpu_priv *priv =3D policy->driver_data; + + dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table); + dev_pm_opp_remove_all_dynamic(priv->cpu_dev); + iounmap(priv->reg_base); + kfree(priv); + + return 0; +} + +static struct cpufreq_driver apple_soc_cpufreq_driver =3D { + .name =3D "apple-cpufreq", + .flags =3D CPUFREQ_HAVE_GOVERNOR_PER_POLICY | + CPUFREQ_NEED_INITIAL_FREQ_CHECK | CPUFREQ_IS_COOLING_DEV, + .verify =3D cpufreq_generic_frequency_table_verify, + .attr =3D cpufreq_generic_attr, + .get =3D apple_soc_cpufreq_get_rate, + .init =3D apple_soc_cpufreq_init, + .exit =3D apple_soc_cpufreq_exit, + .target_index =3D apple_soc_cpufreq_set_target, + .fast_switch =3D apple_soc_cpufreq_fast_switch, + .register_em =3D cpufreq_register_em_with_opp, + .attr =3D apple_soc_cpufreq_hw_attr, +}; + +static int __init apple_soc_cpufreq_module_init(void) +{ + if (!of_machine_is_compatible("apple,arm-platform")) + return -ENODEV; + + return cpufreq_register_driver(&apple_soc_cpufreq_driver); +} +module_init(apple_soc_cpufreq_module_init); + +static void __exit apple_soc_cpufreq_module_exit(void) +{ + cpufreq_unregister_driver(&apple_soc_cpufreq_driver); +} +module_exit(apple_soc_cpufreq_module_exit); + +MODULE_DEVICE_TABLE(of, apple_soc_cpufreq_of_match); +MODULE_AUTHOR("Hector Martin "); +MODULE_DESCRIPTION("Apple SoC CPU cluster DVFS driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq= -dt-platdev.c index 85ee11f79840..8ab672883043 100644 --- a/drivers/cpufreq/cpufreq-dt-platdev.c +++ b/drivers/cpufreq/cpufreq-dt-platdev.c @@ -103,6 +103,8 @@ static const struct of_device_id allowlist[] __initcons= t =3D { static const struct of_device_id blocklist[] __initconst =3D { { .compatible =3D "allwinner,sun50i-h6", }, =20 + { .compatible =3D "apple,arm-platform", }, + { .compatible =3D "arm,vexpress", }, =20 { .compatible =3D "calxeda,highbank", }, --=20 2.35.1 From nobody Sun Feb 8 05:04:01 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C89B5C43217 for ; Mon, 28 Nov 2022 12:43:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230131AbiK1MnV (ORCPT ); Mon, 28 Nov 2022 07:43:21 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49556 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229827AbiK1MnM (ORCPT ); Mon, 28 Nov 2022 07:43:12 -0500 Received: from mail.marcansoft.com (marcansoft.com [212.63.210.85]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 75CE212610; Mon, 28 Nov 2022 04:43:10 -0800 (PST) Received: from [127.0.0.1] (localhost [127.0.0.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: sendonly@marcansoft.com) by mail.marcansoft.com (Postfix) with ESMTPSA id 9F0FD41EF0; Mon, 28 Nov 2022 12:43:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=marcan.st; s=default; t=1669639389; bh=59CSFOX97npsoJgTAQusPWIZ1PoRhHaim0uMHhjm+K0=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=eiMgEvH9Gq8Evo/7/2aD1YTMc//vmh2UlB75CxJZe8yPAhlqeMOX65BtRHA7RS3gR RF6SmulVZ7379M01zIYQK+we7QY4+32QW5azjIvmH654SCqgE3aFquhaiKPuIoqi3q glGPkEHk2QEb8NGNM9zD8zx24Zp0Amqdz2M4MWdD1KEBf90CtBdCnKHMNG2lWPBZke 0QbGu96ynP7gpB3blDErbjBQHWhE3t7HW9S7RjbH82CxTaRl6X01uZ5qLDeow9lzhB eBQqY0XMuwjmITWRqd27iCuBMUuA6MjmO4hvf5JrdJSiSSF9wqEEKOHX9kZ1sUaClk /7F+LfvdfABsQ== From: Hector Martin To: "Rafael J. Wysocki" , Viresh Kumar , Matthias Brugger Cc: Hector Martin , Sven Peter , Alyssa Rosenzweig , Rob Herring , Krzysztof Kozlowski , Stephen Boyd , Ulf Hansson , Marc Zyngier , Mark Kettenis , asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 4/4] arm64: dts: apple: Add CPU topology & cpufreq nodes for t8103 Date: Mon, 28 Nov 2022 21:42:16 +0900 Message-Id: <20221128124216.13477-5-marcan@marcan.st> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20221128124216.13477-1-marcan@marcan.st> References: <20221128124216.13477-1-marcan@marcan.st> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add the missing CPU topology/capacity information and the cpufreq nodes, so we can have CPU frequency scaling and the scheduler has the information it needs to make the correct decisions. Boost states are commented out, as they are not yet available (that requires CPU deep sleep support, to be eventually done via PSCI). The driver supports them fine; the hardware will just refuse to ever go into them at this time, so don't expose them to users until that's done. Acked-by: Marc Zyngier Signed-off-by: Hector Martin --- arch/arm64/boot/dts/apple/t8103.dtsi | 204 +++++++++++++++++++++++++-- 1 file changed, 194 insertions(+), 10 deletions(-) diff --git a/arch/arm64/boot/dts/apple/t8103.dtsi b/arch/arm64/boot/dts/app= le/t8103.dtsi index 51a63b29d404..d56708038d05 100644 --- a/arch/arm64/boot/dts/apple/t8103.dtsi +++ b/arch/arm64/boot/dts/apple/t8103.dtsi @@ -22,71 +22,243 @@ cpus { #address-cells =3D <2>; #size-cells =3D <0>; =20 - cpu0: cpu@0 { + cpu-map { + cluster0 { + core0 { + cpu =3D <&cpu_e0>; + }; + core1 { + cpu =3D <&cpu_e1>; + }; + core2 { + cpu =3D <&cpu_e2>; + }; + core3 { + cpu =3D <&cpu_e3>; + }; + }; + + cluster1 { + core0 { + cpu =3D <&cpu_p0>; + }; + core1 { + cpu =3D <&cpu_p1>; + }; + core2 { + cpu =3D <&cpu_p2>; + }; + core3 { + cpu =3D <&cpu_p3>; + }; + }; + }; + + cpu_e0: cpu@0 { compatible =3D "apple,icestorm"; device_type =3D "cpu"; reg =3D <0x0 0x0>; enable-method =3D "spin-table"; cpu-release-addr =3D <0 0>; /* To be filled by loader */ + operating-points-v2 =3D <&ecluster_opp>; + capacity-dmips-mhz =3D <714>; + performance-domains =3D <&cpufreq_e>; }; =20 - cpu1: cpu@1 { + cpu_e1: cpu@1 { compatible =3D "apple,icestorm"; device_type =3D "cpu"; reg =3D <0x0 0x1>; enable-method =3D "spin-table"; cpu-release-addr =3D <0 0>; /* To be filled by loader */ + operating-points-v2 =3D <&ecluster_opp>; + capacity-dmips-mhz =3D <714>; + performance-domains =3D <&cpufreq_e>; }; =20 - cpu2: cpu@2 { + cpu_e2: cpu@2 { compatible =3D "apple,icestorm"; device_type =3D "cpu"; reg =3D <0x0 0x2>; enable-method =3D "spin-table"; cpu-release-addr =3D <0 0>; /* To be filled by loader */ + operating-points-v2 =3D <&ecluster_opp>; + capacity-dmips-mhz =3D <714>; + performance-domains =3D <&cpufreq_e>; }; =20 - cpu3: cpu@3 { + cpu_e3: cpu@3 { compatible =3D "apple,icestorm"; device_type =3D "cpu"; reg =3D <0x0 0x3>; enable-method =3D "spin-table"; cpu-release-addr =3D <0 0>; /* To be filled by loader */ + operating-points-v2 =3D <&ecluster_opp>; + capacity-dmips-mhz =3D <714>; + performance-domains =3D <&cpufreq_e>; }; =20 - cpu4: cpu@10100 { + cpu_p0: cpu@10100 { compatible =3D "apple,firestorm"; device_type =3D "cpu"; reg =3D <0x0 0x10100>; enable-method =3D "spin-table"; cpu-release-addr =3D <0 0>; /* To be filled by loader */ + operating-points-v2 =3D <&pcluster_opp>; + capacity-dmips-mhz =3D <1024>; + performance-domains =3D <&cpufreq_p>; }; =20 - cpu5: cpu@10101 { + cpu_p1: cpu@10101 { compatible =3D "apple,firestorm"; device_type =3D "cpu"; reg =3D <0x0 0x10101>; enable-method =3D "spin-table"; cpu-release-addr =3D <0 0>; /* To be filled by loader */ + operating-points-v2 =3D <&pcluster_opp>; + capacity-dmips-mhz =3D <1024>; + performance-domains =3D <&cpufreq_p>; }; =20 - cpu6: cpu@10102 { + cpu_p2: cpu@10102 { compatible =3D "apple,firestorm"; device_type =3D "cpu"; reg =3D <0x0 0x10102>; enable-method =3D "spin-table"; cpu-release-addr =3D <0 0>; /* To be filled by loader */ + operating-points-v2 =3D <&pcluster_opp>; + capacity-dmips-mhz =3D <1024>; + performance-domains =3D <&cpufreq_p>; }; =20 - cpu7: cpu@10103 { + cpu_p3: cpu@10103 { compatible =3D "apple,firestorm"; device_type =3D "cpu"; reg =3D <0x0 0x10103>; enable-method =3D "spin-table"; cpu-release-addr =3D <0 0>; /* To be filled by loader */ + operating-points-v2 =3D <&pcluster_opp>; + capacity-dmips-mhz =3D <1024>; + performance-domains =3D <&cpufreq_p>; }; }; =20 + ecluster_opp: opp-table-0 { + compatible =3D "operating-points-v2"; + + opp01 { + opp-hz =3D /bits/ 64 <600000000>; + opp-level =3D <1>; + clock-latency-ns =3D <7500>; + }; + opp02 { + opp-hz =3D /bits/ 64 <972000000>; + opp-level =3D <2>; + clock-latency-ns =3D <22000>; + }; + opp03 { + opp-hz =3D /bits/ 64 <1332000000>; + opp-level =3D <3>; + clock-latency-ns =3D <27000>; + }; + opp04 { + opp-hz =3D /bits/ 64 <1704000000>; + opp-level =3D <4>; + clock-latency-ns =3D <33000>; + }; + opp05 { + opp-hz =3D /bits/ 64 <2064000000>; + opp-level =3D <5>; + clock-latency-ns =3D <50000>; + }; + }; + + pcluster_opp: opp-table-1 { + compatible =3D "operating-points-v2"; + + opp01 { + opp-hz =3D /bits/ 64 <600000000>; + opp-level =3D <1>; + clock-latency-ns =3D <8000>; + }; + opp02 { + opp-hz =3D /bits/ 64 <828000000>; + opp-level =3D <2>; + clock-latency-ns =3D <19000>; + }; + opp03 { + opp-hz =3D /bits/ 64 <1056000000>; + opp-level =3D <3>; + clock-latency-ns =3D <21000>; + }; + opp04 { + opp-hz =3D /bits/ 64 <1284000000>; + opp-level =3D <4>; + clock-latency-ns =3D <23000>; + }; + opp05 { + opp-hz =3D /bits/ 64 <1500000000>; + opp-level =3D <5>; + clock-latency-ns =3D <24000>; + }; + opp06 { + opp-hz =3D /bits/ 64 <1728000000>; + opp-level =3D <6>; + clock-latency-ns =3D <29000>; + }; + opp07 { + opp-hz =3D /bits/ 64 <1956000000>; + opp-level =3D <7>; + clock-latency-ns =3D <31000>; + }; + opp08 { + opp-hz =3D /bits/ 64 <2184000000>; + opp-level =3D <8>; + clock-latency-ns =3D <34000>; + }; + opp09 { + opp-hz =3D /bits/ 64 <2388000000>; + opp-level =3D <9>; + clock-latency-ns =3D <36000>; + }; + opp10 { + opp-hz =3D /bits/ 64 <2592000000>; + opp-level =3D <10>; + clock-latency-ns =3D <51000>; + }; + opp11 { + opp-hz =3D /bits/ 64 <2772000000>; + opp-level =3D <11>; + clock-latency-ns =3D <54000>; + }; + opp12 { + opp-hz =3D /bits/ 64 <2988000000>; + opp-level =3D <12>; + clock-latency-ns =3D <55000>; + }; +#if 0 + /* Not available until CPU deep sleep is implemented */ + opp13 { + opp-hz =3D /bits/ 64 <3096000000>; + opp-level =3D <13>; + clock-latency-ns =3D <55000>; + turbo-mode; + }; + opp14 { + opp-hz =3D /bits/ 64 <3144000000>; + opp-level =3D <14>; + clock-latency-ns =3D <56000>; + turbo-mode; + }; + opp15 { + opp-hz =3D /bits/ 64 <3204000000>; + opp-level =3D <15>; + clock-latency-ns =3D <56000>; + turbo-mode; + }; +#endif + }; + timer { compatible =3D "arm,armv8-timer"; interrupt-parent =3D <&aic>; @@ -124,6 +296,18 @@ soc { ranges; nonposted-mmio; =20 + cpufreq_e: performance-controller@210e20000 { + compatible =3D "apple,t8103-cluster-cpufreq", "apple,cluster-cpufreq"; + reg =3D <0x2 0x10e20000 0 0x1000>; + #performance-domain-cells =3D <0>; + }; + + cpufreq_p: performance-controller@211e20000 { + compatible =3D "apple,t8103-cluster-cpufreq", "apple,cluster-cpufreq"; + reg =3D <0x2 0x11e20000 0 0x1000>; + #performance-domain-cells =3D <0>; + }; + i2c0: i2c@235010000 { compatible =3D "apple,t8103-i2c", "apple,i2c"; reg =3D <0x2 0x35010000 0x0 0x4000>; @@ -229,12 +413,12 @@ aic: interrupt-controller@23b100000 { affinities { e-core-pmu-affinity { apple,fiq-index =3D ; - cpus =3D <&cpu0 &cpu1 &cpu2 &cpu3>; + cpus =3D <&cpu_e0 &cpu_e1 &cpu_e2 &cpu_e3>; }; =20 p-core-pmu-affinity { apple,fiq-index =3D ; - cpus =3D <&cpu4 &cpu5 &cpu6 &cpu7>; + cpus =3D <&cpu_p0 &cpu_p1 &cpu_p2 &cpu_p3>; }; }; }; --=20 2.35.1