1-- 2-- Copyright 2024 The Android Open Source Project 3-- 4-- Licensed under the Apache License, Version 2.0 (the "License"); 5-- you may not use this file except in compliance with the License. 6-- You may obtain a copy of the License at 7-- 8-- https://www.apache.org/licenses/LICENSE-2.0 9-- 10-- Unless required by applicable law or agreed to in writing, software 11-- distributed under the License is distributed on an "AS IS" BASIS, 12-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13-- See the License for the specific language governing permissions and 14-- limitations under the License. 15 16INCLUDE PERFETTO MODULE time.conversion; 17INCLUDE PERFETTO MODULE wattson.arm_dsu; 18INCLUDE PERFETTO MODULE wattson.cpu_split; 19INCLUDE PERFETTO MODULE wattson.curves.utils; 20INCLUDE PERFETTO MODULE wattson.device_infos; 21 22-- System state table with LUT for CPUs and intermediate values for calculations 23CREATE PERFETTO TABLE _w_independent_cpus_calc 24AS 25SELECT 26 ts, 27 dur, 28 cast_int!(l3_hit_rate * dur) as l3_hit_count, 29 cast_int!(l3_miss_rate * dur) as l3_miss_count, 30 freq_0, 31 idle_0, 32 freq_1, 33 idle_1, 34 freq_2, 35 idle_2, 36 freq_3, 37 idle_3, 38 freq_4, 39 idle_4, 40 freq_5, 41 idle_5, 42 freq_6, 43 idle_6, 44 freq_7, 45 idle_7, 46 policy_4, 47 policy_5, 48 policy_6, 49 policy_7, 50 IIF( 51 suspended = 1, 52 1, 53 MIN( 54 IFNULL(idle_0, 1), 55 IFNULL(idle_1, 1), 56 IFNULL(idle_2, 1), 57 IFNULL(idle_3, 1) 58 ) 59 ) as no_static, 60 IIF(suspended = 1, 0, cpu0_curve) as cpu0_curve, 61 IIF(suspended = 1, 0, cpu1_curve) as cpu1_curve, 62 IIF(suspended = 1, 0, cpu2_curve) as cpu2_curve, 63 IIF(suspended = 1, 0, cpu3_curve) as cpu3_curve, 64 IIF(suspended = 1, 0, cpu4_curve) as cpu4_curve, 65 IIF(suspended = 1, 0, cpu5_curve) as cpu5_curve, 66 IIF(suspended = 1, 0, cpu6_curve) as cpu6_curve, 67 IIF(suspended = 1, 0, cpu7_curve) as cpu7_curve, 68 -- If dependency CPUs are active, then that CPU could contribute static power 69 IIF(idle_4 = -1, lut4.curve_value, -1) as static_4, 70 IIF(idle_5 = -1, lut5.curve_value, -1) as static_5, 71 IIF(idle_6 = -1, lut6.curve_value, -1) as static_6, 72 IIF(idle_7 = -1, lut7.curve_value, -1) as static_7 73FROM _idle_freq_l3_hit_l3_miss_slice as base 74LEFT JOIN _filtered_curves_2d lut4 ON 75 base.freq_0 = lut4.freq_khz AND 76 base.freq_4 = lut4.other_freq_khz AND 77 base.policy_4 = lut4.other_policy AND 78 lut4.idle = 255 79LEFT JOIN _filtered_curves_2d lut5 ON 80 base.freq_0 = lut5.freq_khz AND 81 base.freq_5 = lut5.other_freq_khz AND 82 base.policy_5 = lut5.other_policy AND 83 lut5.idle = 255 84LEFT JOIN _filtered_curves_2d lut6 ON 85 base.freq_0 = lut6.freq_khz AND 86 base.freq_6 = lut6.other_freq_khz AND 87 base.policy_6 = lut6.other_policy AND 88 lut6.idle = 255 89LEFT JOIN _filtered_curves_2d lut7 ON 90 base.freq_0 = lut7.freq_khz AND 91 base.freq_7 = lut7.other_freq_khz AND 92 base.policy_7 = lut7.other_policy AND 93 lut7.idle = 255 94-- Needs to be at least 1us to reduce inconsequential rows. 95WHERE dur > time_from_us(1); 96 97-- Find the CPU states creating the max vote 98CREATE PERFETTO TABLE _get_max_vote 99AS 100WITH max_power_tbl AS ( 101 SELECT 102 *, 103 -- Indicates if all CPUs are in deep idle 104 MIN( 105 no_static, 106 IFNULL(idle_4, 1), 107 IFNULL(idle_5, 1), 108 IFNULL(idle_6, 1), 109 IFNULL(idle_7, 1) 110 ) as all_cpu_deep_idle, 111 -- Determines which CPU has highest vote 112 MAX( 113 static_4, 114 static_5, 115 static_6, 116 static_7 117 ) as max_static_vote 118 FROM _w_independent_cpus_calc 119) 120SELECT 121 *, 122 CASE max_static_vote 123 WHEN -1 THEN _get_min_freq_vote() 124 WHEN static_4 THEN freq_4 125 WHEN static_5 THEN freq_5 126 WHEN static_6 THEN freq_6 127 WHEN static_7 THEN freq_7 128 ELSE 400000 129 END max_freq_vote, 130 CASE max_static_vote 131 WHEN -1 THEN _get_min_policy_vote() 132 WHEN static_4 THEN policy_4 133 WHEN static_5 THEN policy_5 134 WHEN static_6 THEN policy_6 135 WHEN static_7 THEN policy_7 136 ELSE 4 137 END max_policy_vote 138FROM max_power_tbl; 139 140-- Final table showing the curves per CPU per slice 141CREATE PERFETTO TABLE _system_state_curves 142AS 143SELECT 144 base.ts, 145 base.dur, 146 COALESCE(lut0.curve_value, cpu0_curve) as cpu0_curve, 147 COALESCE(lut1.curve_value, cpu1_curve) as cpu1_curve, 148 COALESCE(lut2.curve_value, cpu2_curve) as cpu2_curve, 149 COALESCE(lut3.curve_value, cpu3_curve) as cpu3_curve, 150 COALESCE(base.cpu4_curve, 0.0) as cpu4_curve, 151 COALESCE(base.cpu5_curve, 0.0) as cpu5_curve, 152 COALESCE(base.cpu6_curve, 0.0) as cpu6_curve, 153 COALESCE(base.cpu7_curve, 0.0) as cpu7_curve, 154 IIF( 155 no_static = 1, 156 0.0, 157 COALESCE(static_1d.curve_value, static_2d.curve_value) 158 ) as static_curve, 159 IIF( 160 all_cpu_deep_idle = 1, 161 0, 162 base.l3_hit_count * l3_hit_lut.curve_value 163 ) as l3_hit_value, 164 IIF( 165 all_cpu_deep_idle = 1, 166 0, 167 base.l3_miss_count * l3_miss_lut.curve_value 168 ) as l3_miss_value 169FROM _get_max_vote as base 170-- LUT for 2D dependencies 171LEFT JOIN _filtered_curves_2d lut0 ON 172 lut0.idle = base.idle_0 AND 173 lut0.freq_khz = base.freq_0 AND 174 lut0.other_freq_khz = base.max_freq_vote AND 175 lut0.other_policy = base.max_policy_vote 176LEFT JOIN _filtered_curves_2d lut1 ON 177 lut1.idle = base.idle_1 AND 178 lut1.freq_khz = base.freq_1 AND 179 lut1.other_freq_khz = base.max_freq_vote AND 180 lut1.other_policy = base.max_policy_vote 181LEFT JOIN _filtered_curves_2d lut2 ON 182 lut2.idle = base.idle_2 AND 183 lut2.freq_khz = base.freq_2 AND 184 lut2.other_freq_khz = base.max_freq_vote AND 185 lut2.other_policy = base.max_policy_vote 186LEFT JOIN _filtered_curves_2d lut3 ON 187 lut3.idle = base.idle_3 AND 188 lut3.freq_khz = base.freq_3 AND 189 lut3.other_freq_khz = base.max_freq_vote AND 190 lut3.other_policy = base.max_policy_vote 191-- LUT for static curve lookup 192LEFT JOIN _filtered_curves_2d static_2d ON 193 static_2d.freq_khz = base.freq_0 AND 194 static_2d.other_freq_khz = base.max_freq_vote AND 195 static_2d.other_policy = base.max_policy_vote AND 196 static_2d.idle = 255 197LEFT JOIN _filtered_curves_1d static_1d ON 198 static_1d.freq_khz = base.freq_0 AND 199 static_1d.policy = 0 AND 200 static_1d.idle = 255 201-- LUT joins for L3 cache 202LEFT JOIN _filtered_curves_l3 l3_hit_lut ON 203 l3_hit_lut.action= 'hit' AND 204 l3_hit_lut.freq_khz = base.freq_0 AND 205 l3_hit_lut.other_freq_khz = base.max_freq_vote AND 206 l3_hit_lut.other_policy = base.max_policy_vote 207LEFT JOIN _filtered_curves_l3 l3_miss_lut ON 208 l3_miss_lut.action = 'miss' AND 209 l3_miss_lut.freq_khz = base.freq_0 AND 210 l3_miss_lut.other_freq_khz = base.max_freq_vote AND 211 l3_miss_lut.other_policy = base.max_policy_vote; 212 213