diff --git a/arch/arm64/boot/dts/apple/t8122-j613.dts b/arch/arm64/boot/dts/apple/t8122-j613.dts index 330a02fe9c32a8..d895e44dcb9d3b 100644 --- a/arch/arm64/boot/dts/apple/t8122-j613.dts +++ b/arch/arm64/boot/dts/apple/t8122-j613.dts @@ -13,6 +13,7 @@ #include "t8122-usbpd-spmi.dtsi" #include "t8122-jxxx.dtsi" #include +#include / { compatible = "apple,j613", "apple,t8122", "apple,arm-platform"; @@ -33,6 +34,321 @@ default-state = "keep"; }; }; + + /* + * The J613 is fanless: the CPUs are the only cooling devices. As on + * the J700, every die sensor gets a zone that throttles both clusters, + * since they share one die and one heat spreader, and the power + * allocator splits the budget by the energy models, with the E cluster + * weighted three to one. The E maps stop at cooling state 3 (2004 MHz): + * the E cluster adds at most about 2 W, and the governor would + * otherwise send an idle E cluster to its lowest state. + * + * The trips are the J700's: switch-on 58 C (idle is 43-52 C), control + * 95 C, critical 110 C. sustainable-power comes from load tests with the + * gains derived from it: with the four P cores busy, the J700's 1.5 W + * held the hottest sensor at 72 C and the P cores at 2.1 GHz; 6 W held + * 90-95 C at 2.6-3.0 GHz (one 96.5 C peak); 7.5 W swung between 2.2 and + * 3.6 GHz with peaks of 98 C. With 6 W, all eight cores busy settled at + * 92 C with the P cores at 2.2-2.4 GHz and the E cores at full clock; + * the P cores with the GPU busy at 618 MHz peaked at 97 C (the GPU is + * not a cooling device here). + */ + thermal-zones { + cpu-e0-thermal { + polling-delay-passive = <500>; + polling-delay = <500>; + thermal-sensors = <&smc_hwmon 0>; /* Te05 */ + sustainable-power = <6000>; + + trips { + cpu_e0_alert: trip-alert { + temperature = <58000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu_e0_control: trip-control { + temperature = <95000>; + hysteresis = <2000>; + type = "passive"; + }; + + trip-critical { + temperature = <110000>; + hysteresis = <0>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu_e0_control>; + cooling-device = + <&cpu_p0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu_p1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu_p2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu_p3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + contribution = <1024>; + }; + + map1 { + trip = <&cpu_e0_control>; + cooling-device = + <&cpu_e0 THERMAL_NO_LIMIT 3>, + <&cpu_e1 THERMAL_NO_LIMIT 3>, + <&cpu_e2 THERMAL_NO_LIMIT 3>, + <&cpu_e3 THERMAL_NO_LIMIT 3>; + contribution = <3072>; + }; + }; + }; + + cpu-e1-thermal { + polling-delay-passive = <500>; + polling-delay = <500>; + thermal-sensors = <&smc_hwmon 1>; /* Te0P */ + sustainable-power = <6000>; + + trips { + cpu_e1_alert: trip-alert { + temperature = <58000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu_e1_control: trip-control { + temperature = <95000>; + hysteresis = <2000>; + type = "passive"; + }; + + trip-critical { + temperature = <110000>; + hysteresis = <0>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu_e1_control>; + cooling-device = + <&cpu_p0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu_p1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu_p2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu_p3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + contribution = <1024>; + }; + + map1 { + trip = <&cpu_e1_control>; + cooling-device = + <&cpu_e0 THERMAL_NO_LIMIT 3>, + <&cpu_e1 THERMAL_NO_LIMIT 3>, + <&cpu_e2 THERMAL_NO_LIMIT 3>, + <&cpu_e3 THERMAL_NO_LIMIT 3>; + contribution = <3072>; + }; + }; + }; + + cpu-p0-thermal { + polling-delay-passive = <500>; + polling-delay = <500>; + thermal-sensors = <&smc_hwmon 2>; /* Tp05 */ + sustainable-power = <6000>; + + trips { + cpu_p0_alert: trip-alert { + temperature = <58000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu_p0_control: trip-control { + temperature = <95000>; + hysteresis = <2000>; + type = "passive"; + }; + + trip-critical { + temperature = <110000>; + hysteresis = <0>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu_p0_control>; + cooling-device = + <&cpu_p0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu_p1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu_p2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu_p3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + contribution = <1024>; + }; + + map1 { + trip = <&cpu_p0_control>; + cooling-device = + <&cpu_e0 THERMAL_NO_LIMIT 3>, + <&cpu_e1 THERMAL_NO_LIMIT 3>, + <&cpu_e2 THERMAL_NO_LIMIT 3>, + <&cpu_e3 THERMAL_NO_LIMIT 3>; + contribution = <3072>; + }; + }; + }; + + cpu-p1-thermal { + polling-delay-passive = <500>; + polling-delay = <500>; + thermal-sensors = <&smc_hwmon 3>; /* Tp0L */ + sustainable-power = <6000>; + + trips { + cpu_p1_alert: trip-alert { + temperature = <58000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu_p1_control: trip-control { + temperature = <95000>; + hysteresis = <2000>; + type = "passive"; + }; + + trip-critical { + temperature = <110000>; + hysteresis = <0>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu_p1_control>; + cooling-device = + <&cpu_p0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu_p1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu_p2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu_p3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + contribution = <1024>; + }; + + map1 { + trip = <&cpu_p1_control>; + cooling-device = + <&cpu_e0 THERMAL_NO_LIMIT 3>, + <&cpu_e1 THERMAL_NO_LIMIT 3>, + <&cpu_e2 THERMAL_NO_LIMIT 3>, + <&cpu_e3 THERMAL_NO_LIMIT 3>; + contribution = <3072>; + }; + }; + }; + + cpu-p2-thermal { + polling-delay-passive = <500>; + polling-delay = <500>; + thermal-sensors = <&smc_hwmon 4>; /* Tp0b */ + sustainable-power = <6000>; + + trips { + cpu_p2_alert: trip-alert { + temperature = <58000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu_p2_control: trip-control { + temperature = <95000>; + hysteresis = <2000>; + type = "passive"; + }; + + trip-critical { + temperature = <110000>; + hysteresis = <0>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu_p2_control>; + cooling-device = + <&cpu_p0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu_p1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu_p2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu_p3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + contribution = <1024>; + }; + + map1 { + trip = <&cpu_p2_control>; + cooling-device = + <&cpu_e0 THERMAL_NO_LIMIT 3>, + <&cpu_e1 THERMAL_NO_LIMIT 3>, + <&cpu_e2 THERMAL_NO_LIMIT 3>, + <&cpu_e3 THERMAL_NO_LIMIT 3>; + contribution = <3072>; + }; + }; + }; + + cpu-p3-thermal { + polling-delay-passive = <500>; + polling-delay = <500>; + thermal-sensors = <&smc_hwmon 5>; /* Tp0r */ + sustainable-power = <6000>; + + trips { + cpu_p3_alert: trip-alert { + temperature = <58000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu_p3_control: trip-control { + temperature = <95000>; + hysteresis = <2000>; + type = "passive"; + }; + + trip-critical { + temperature = <110000>; + hysteresis = <0>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu_p3_control>; + cooling-device = + <&cpu_p0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu_p1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu_p2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu_p3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + contribution = <1024>; + }; + + map1 { + trip = <&cpu_p3_control>; + cooling-device = + <&cpu_e0 THERMAL_NO_LIMIT 3>, + <&cpu_e1 THERMAL_NO_LIMIT 3>, + <&cpu_e2 THERMAL_NO_LIMIT 3>, + <&cpu_e3 THERMAL_NO_LIMIT 3>; + contribution = <3072>; + }; + }; + }; + }; }; &dcp { diff --git a/arch/arm64/boot/dts/apple/t8122.dtsi b/arch/arm64/boot/dts/apple/t8122.dtsi index cf734e584dc9d3..a19e933f220b41 100644 --- a/arch/arm64/boot/dts/apple/t8122.dtsi +++ b/arch/arm64/boot/dts/apple/t8122.dtsi @@ -68,6 +68,7 @@ operating-points-v2 = <&sawtooth_opp>; capacity-dmips-mhz = <804>; performance-domains = <&cpufreq_e>; + #cooling-cells = <2>; }; cpu_e1: cpu@1 { @@ -82,6 +83,7 @@ operating-points-v2 = <&sawtooth_opp>; capacity-dmips-mhz = <804>; performance-domains = <&cpufreq_e>; + #cooling-cells = <2>; }; cpu_e2: cpu@2 { @@ -96,6 +98,7 @@ operating-points-v2 = <&sawtooth_opp>; capacity-dmips-mhz = <804>; performance-domains = <&cpufreq_e>; + #cooling-cells = <2>; }; cpu_e3: cpu@3 { @@ -110,6 +113,7 @@ operating-points-v2 = <&sawtooth_opp>; capacity-dmips-mhz = <804>; performance-domains = <&cpufreq_e>; + #cooling-cells = <2>; }; cpu_p0: cpu@10100 { @@ -124,6 +128,7 @@ operating-points-v2 = <&everest_opp>; capacity-dmips-mhz = <1024>; performance-domains = <&cpufreq_p>; + #cooling-cells = <2>; }; cpu_p1: cpu@10101 { @@ -138,6 +143,7 @@ operating-points-v2 = <&everest_opp>; capacity-dmips-mhz = <1024>; performance-domains = <&cpufreq_p>; + #cooling-cells = <2>; }; cpu_p2: cpu@10102 { @@ -152,6 +158,7 @@ operating-points-v2 = <&everest_opp>; capacity-dmips-mhz = <1024>; performance-domains = <&cpufreq_p>; + #cooling-cells = <2>; }; cpu_p3: cpu@10103 { @@ -166,6 +173,7 @@ operating-points-v2 = <&everest_opp>; capacity-dmips-mhz = <1024>; performance-domains = <&cpufreq_p>; + #cooling-cells = <2>; }; l2_cache_0: l2-cache-0 { @@ -183,6 +191,22 @@ }; }; + /* + * opp-microwatt is the power one busy CPU adds at each state, measured + * on a J613 with the SMC's cluster power keys (PPbb for the E cluster, + * PP0b for the P cluster): the cluster pinned to the state, all four of + * its CPUs busy minus the cluster idle, divided by four, starting + * below 60 C. The values are curves fitted to the measurements + * (rms deviation 31 mW for E, 22 mW for P), so that they rise + * monotonically: E P = 58 mW * f^1.842 (f in GHz), + * P ln(P/mW) = 5.394 + 1.164 ln f + 0.521 (ln f)^2. + * + * Above 3288 MHz the P cluster's power stops rising at about 11 W with + * all four CPUs busy, and the work done per clock at 4056 MHz is 8-10% + * lower than at 3420 MHz, also with one CPU busy: the hardware limits + * the top states by itself. Their values are the fitted curve + * extrapolated, the power these states would draw unlimited. + */ sawtooth_opp: opp-table-0 { compatible = "operating-points-v2"; opp-shared; @@ -191,36 +215,43 @@ opp-hz = /bits/ 64 <744000000>; opp-level = <1>; clock-latency-ns = <7800>; + opp-microwatt = <33600>; }; opp02 { opp-hz = /bits/ 64 <1044000000>; opp-level = <2>; clock-latency-ns = <19400>; + opp-microwatt = <62800>; }; opp03 { opp-hz = /bits/ 64 <1476000000>; opp-level = <3>; clock-latency-ns = <24800>; + opp-microwatt = <118800>; }; opp04 { opp-hz = /bits/ 64 <2004000000>; opp-level = <4>; clock-latency-ns = <43600>; + opp-microwatt = <208700>; }; opp05 { opp-hz = /bits/ 64 <2268000000>; opp-level = <5>; clock-latency-ns = <49200>; + opp-microwatt = <262100>; }; opp06 { opp-hz = /bits/ 64 <2556000000>; opp-level = <6>; clock-latency-ns = <53400>; + opp-microwatt = <326700>; }; opp07 { opp-hz = /bits/ 64 <2748000000>; opp-level = <7>; clock-latency-ns = <56800>; + opp-microwatt = <373300>; }; }; @@ -232,101 +263,121 @@ opp-hz = /bits/ 64 <696000000>; opp-level = <1>; clock-latency-ns = <9400>; + opp-microwatt = <154600>; }; opp02 { opp-hz = /bits/ 64 <1092000000>; opp-level = <2>; clock-latency-ns = <19800>; + opp-microwatt = <244800>; }; opp03 { opp-hz = /bits/ 64 <1356000000>; opp-level = <3>; clock-latency-ns = <23700>; + opp-microwatt = <329200>; }; opp04 { opp-hz = /bits/ 64 <1596000000>; opp-level = <4>; clock-latency-ns = <25000>; + opp-microwatt = <425000>; }; opp05 { opp-hz = /bits/ 64 <1884000000>; opp-level = <5>; clock-latency-ns = <28200>; + opp-microwatt = <567000>; }; opp06 { opp-hz = /bits/ 64 <2172000000>; opp-level = <6>; clock-latency-ns = <32300>; + opp-microwatt = <742700>; }; opp07 { opp-hz = /bits/ 64 <2424000000>; opp-level = <7>; clock-latency-ns = <35600>; + opp-microwatt = <928000>; }; opp08 { opp-hz = /bits/ 64 <2616000000>; opp-level = <8>; clock-latency-ns = <38200>; + opp-microwatt = <1091300>; }; opp09 { opp-hz = /bits/ 64 <2808000000>; opp-level = <9>; clock-latency-ns = <39700>; + opp-microwatt = <1275600>; }; opp10 { opp-hz = /bits/ 64 <2988000000>; opp-level = <10>; clock-latency-ns = <41700>; + opp-microwatt = <1469000>; }; opp11 { opp-hz = /bits/ 64 <3144000000>; opp-level = <11>; clock-latency-ns = <43700>; + opp-microwatt = <1654100>; }; opp12 { opp-hz = /bits/ 64 <3288000000>; opp-level = <12>; clock-latency-ns = <45000>; + opp-microwatt = <1840200>; }; opp13 { opp-hz = /bits/ 64 <3420000000>; opp-level = <13>; clock-latency-ns = <48700>; + opp-microwatt = <2024500>; }; opp14 { opp-hz = /bits/ 64 <3540000000>; opp-level = <14>; clock-latency-ns = <55700>; + opp-microwatt = <2204000>; }; opp15 { opp-hz = /bits/ 64 <3636000000>; opp-level = <15>; clock-latency-ns = <55900>; + opp-microwatt = <2356100>; }; opp16 { opp-hz = /bits/ 64 <3720000000>; opp-level = <16>; clock-latency-ns = <55900>; + opp-microwatt = <2495800>; }; opp17 { opp-hz = /bits/ 64 <3780000000>; opp-level = <17>; clock-latency-ns = <56000>; + opp-microwatt = <2599300>; }; opp18 { opp-hz = /bits/ 64 <3864000000>; opp-level = <18>; clock-latency-ns = <56000>; + opp-microwatt = <2749900>; }; opp19 { opp-hz = /bits/ 64 <3960000000>; opp-level = <19>; clock-latency-ns = <61800>; + opp-microwatt = <2930000>; }; opp20 { opp-hz = /bits/ 64 <4056000000>; opp-level = <20>; clock-latency-ns = <61900>; + opp-microwatt = <3119000>; }; }; @@ -923,6 +974,44 @@ smc_hwmon: hwmon { compatible = "apple,smc-hwmon"; + #thermal-sensor-cells = <1>; + + /* + * CPU die temperatures, one per E-cluster sensor + * group and one per P core (the key that rose most + * with only that core busy, on a J613). Board + * thermal zones refer to these by channel index, so + * keep them first and in this order. + */ + temperature-Te05 { + apple,key-id = "Te05"; + label = "E-cluster Temperature 1"; + }; + + temperature-Te0P { + apple,key-id = "Te0P"; + label = "E-cluster Temperature 2"; + }; + + temperature-Tp05 { + apple,key-id = "Tp05"; + label = "P-core 0 Temperature"; + }; + + temperature-Tp0L { + apple,key-id = "Tp0L"; + label = "P-core 1 Temperature"; + }; + + temperature-Tp0b { + apple,key-id = "Tp0b"; + label = "P-core 2 Temperature"; + }; + + temperature-Tp0r { + apple,key-id = "Tp0r"; + label = "P-core 3 Temperature"; + }; }; smc_reboot: reboot { diff --git a/drivers/hwmon/macsmc-hwmon.c b/drivers/hwmon/macsmc-hwmon.c index 06d2c6e2d0ac38..7e0a2312d2d292 100644 --- a/drivers/hwmon/macsmc-hwmon.c +++ b/drivers/hwmon/macsmc-hwmon.c @@ -106,6 +106,19 @@ static const struct macsmc_hwmon_board { .die_keys = "Tf04,Tf06,Tf09,Tf0A,Tf0B,Tf14,Tf16,Tf19,Tf1A,Tf1B,Tf24,Tf26,Tf29,Tf2A,Tf2B," "Tf34,Tf36,Tf39,Tf3A,Tf3B,Tf44,Tf46,Tf49,Tf4A,Tf4B", }, + /* + * MacBook Air (13-inch, M3): the base M3 has no Tf keys. With only + * the GPU busy, the six Tg keys below rose by about 50 C, the most + * of any key, and each has a twin about 4.5 C lower; they read 0 C + * or slightly below while the GPU is powered off. The others are the + * CPU die keys of the board's device tree (the E-cluster groups and + * one per P core), so the zone also follows a hot CPU. + */ + { + .compatible = "apple,j613", + .die_keys = "Tg0D,Tg0P,Tg0X,Tg0b,Tg0j,Tg0v,Te05,Te0P,Tp05,Tp0L,Tp0b,Tp0r", + .pressure_key = "mTPL", + }, }; static bool macsmc_hwmon_is_m3(void)