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 intervals.intersect; 17 18INCLUDE PERFETTO MODULE wattson.cpu_freq; 19 20INCLUDE PERFETTO MODULE wattson.cpu_hotplug; 21 22INCLUDE PERFETTO MODULE wattson.cpu_idle; 23 24INCLUDE PERFETTO MODULE wattson.curves.utils; 25 26INCLUDE PERFETTO MODULE wattson.device_infos; 27 28-- Helper macro for using Perfetto table with interval intersect 29CREATE PERFETTO MACRO _ii_subquery( 30 tab TableOrSubquery 31) 32RETURNS TableOrSubquery AS 33( 34 SELECT 35 _auto_id AS id, 36 * 37 FROM $tab 38); 39 40-- Wattson estimation is valid from when first CPU0 frequency appears 41CREATE PERFETTO TABLE _valid_window AS 42WITH 43 window_start AS ( 44 SELECT 45 ts AS start_ts 46 FROM _adjusted_cpu_freq 47 WHERE 48 cpu = 0 AND freq IS NOT NULL 49 ORDER BY 50 ts ASC 51 LIMIT 1 52 ), 53 window AS ( 54 SELECT 55 start_ts AS ts, 56 trace_end() - start_ts AS dur 57 FROM window_start 58 ) 59SELECT 60 *, 61 0 AS cpu 62FROM window 63UNION ALL 64SELECT 65 *, 66 1 AS cpu 67FROM window 68UNION ALL 69SELECT 70 *, 71 2 AS cpu 72FROM window 73UNION ALL 74SELECT 75 *, 76 3 AS cpu 77FROM window 78UNION ALL 79SELECT 80 *, 81 4 AS cpu 82FROM window 83UNION ALL 84SELECT 85 *, 86 5 AS cpu 87FROM window 88UNION ALL 89SELECT 90 *, 91 6 AS cpu 92FROM window 93UNION ALL 94SELECT 95 *, 96 7 AS cpu 97FROM window; 98 99-- Start matching CPUs with 1D curves based on combination of freq and idle 100CREATE PERFETTO TABLE _idle_freq_materialized AS 101SELECT 102 ii.ts, 103 ii.dur, 104 ii.cpu, 105 freq.policy, 106 freq.freq, 107 -- Set idle since subsequent calculations are based on number of idle/active 108 -- CPUs. If offline/suspended, set the CPU to the device specific deepest idle 109 -- state. 110 iif( 111 suspend.suspended OR hotplug.offline, 112 ( 113 SELECT 114 idle 115 FROM _deepest_idle 116 ), 117 idle.idle 118 ) AS idle, 119 -- If CPU is suspended or offline, set power estimate to 0 120 iif(suspend.suspended OR hotplug.offline, 0, lut.curve_value) AS curve_value 121FROM _interval_intersect!( 122 ( 123 _ii_subquery!(_valid_window), 124 _ii_subquery!(_adjusted_cpu_freq), 125 _ii_subquery!(_adjusted_deep_idle), 126 _ii_subquery!(_gapless_hotplug_slices), 127 _ii_subquery!(_gapless_suspend_slices) 128 ), 129 (cpu) 130) AS ii 131JOIN _adjusted_cpu_freq AS freq 132 ON freq._auto_id = id_1 133JOIN _adjusted_deep_idle AS idle 134 ON idle._auto_id = id_2 135JOIN _gapless_hotplug_slices AS hotplug 136 ON hotplug._auto_id = id_3 137JOIN _gapless_suspend_slices AS suspend 138 ON suspend._auto_id = id_4 139-- Left join since some CPUs may only match the 2D LUT 140LEFT JOIN _filtered_curves_1d AS lut 141 ON freq.policy = lut.policy AND freq.freq = lut.freq_khz AND idle.idle = lut.idle; 142