summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-11-16 07:42:10 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2017-11-16 07:42:10 +0300
commite60e1ee60630cafef5e430c2ae364877e061d980 (patch)
tree816aeef8fe8d4a2c6a1ebbc7a350839bac8dd4c2 /drivers/gpu/drm/etnaviv/etnaviv_perfmon.c
parent5d352e69c60e54b5f04d6e337a1d2bf0dbf3d94a (diff)
parentf150891fd9878ef0d9197c4e8451ce67c3bdd014 (diff)
downloadlinux-e60e1ee60630cafef5e430c2ae364877e061d980.tar.xz
Merge tag 'drm-for-v4.15' of git://people.freedesktop.org/~airlied/linux
Pull drm updates from Dave Airlie: "This is the main drm pull request for v4.15. Core: - Atomic object lifetime fixes - Atomic iterator improvements - Sparse/smatch fixes - Legacy kms ioctls to be interruptible - EDID override improvements - fb/gem helper cleanups - Simple outreachy patches - Documentation improvements - Fix dma-buf rcu races - DRM mode object leasing for improving VR use cases. - vgaarb improvements for non-x86 platforms. New driver: - tve200: Faraday Technology TVE200 block. This "TV Encoder" encodes a ITU-T BT.656 stream and can be found in the StorLink SL3516 (later Cortina Systems CS3516) as well as the Grain Media GM8180. New bridges: - SiI9234 support New panels: - S6E63J0X03, OTM8009A, Seiko 43WVF1G, 7" rpi touch panel, Toshiba LT089AC19000, Innolux AT043TN24 i915: - Remove Coffeelake from alpha support - Cannonlake workarounds - Infoframe refactoring for DisplayPort - VBT updates - DisplayPort vswing/emph/buffer translation refactoring - CCS fixes - Restore GPU clock boost on missed vblanks - Scatter list updates for userptr allocations - Gen9+ transition watermarks - Display IPC (Isochronous Priority Control) - Private PAT management - GVT: improved error handling and pci config sanitizing - Execlist refactoring - Transparent Huge Page support - User defined priorities support - HuC/GuC firmware refactoring - DP MST fixes - eDP power sequencing fixes - Use RCU instead of stop_machine - PSR state tracking support - Eviction fixes - BDW DP aux channel timeout fixes - LSPCON fixes - Cannonlake PLL fixes amdgpu: - Per VM BO support - Powerplay cleanups - CI powerplay support - PASID mgr for kfd - SR-IOV fixes - initial GPU reset for vega10 - Prime mmap support - TTM updates - Clock query interface for Raven - Fence to handle ioctl - UVD encode ring support on Polaris - Transparent huge page DMA support - Compute LRU pipe tweaks - BO flag to allow buffers to opt out of implicit sync - CTX priority setting API - VRAM lost infrastructure plumbing qxl: - fix flicker since atomic rework amdkfd: - Further improvements from internal AMD tree - Usermode events - Drop radeon support nouveau: - Pascal temperature sensor support - Improved BAR2 handling - MMU rework to support Pascal MMU exynos: - Improved HDMI/mixer support - HDMI audio interface support tegra: - Prep work for tegra186 - Cleanup/fixes msm: - Preemption support for a5xx - Display fixes for 8x96 (snapdragon 820) - Async cursor plane fixes - FW loading rework - GPU debugging improvements vc4: - Prep for DSI panels - fix T-format tiling scanout - New madvise ioctl Rockchip: - LVDS support omapdrm: - omap4 HDMI CEC support etnaviv: - GPU performance counters groundwork sun4i: - refactor driver load + TCON backend - HDMI improvements - A31 support - Misc fixes udl: - Probe/EDID read fixes. tilcdc: - Misc fixes. pl111: - Support more variants adv7511: - Improve EDID handling. - HDMI CEC support sii8620: - Add remote control support" * tag 'drm-for-v4.15' of git://people.freedesktop.org/~airlied/linux: (1480 commits) drm/rockchip: analogix_dp: Use mutex rather than spinlock drm/mode_object: fix documentation for object lookups. drm/i915: Reorder context-close to avoid calling i915_vma_close() under RCU drm/i915: Move init_clock_gating() back to where it was drm/i915: Prune the reservation shared fence array drm/i915: Idle the GPU before shinking everything drm/i915: Lock llist_del_first() vs llist_del_all() drm/i915: Calculate ironlake intermediate watermarks correctly, v2. drm/i915: Disable lazy PPGTT page table optimization for vGPU drm/i915/execlists: Remove the priority "optimisation" drm/i915: Filter out spurious execlists context-switch interrupts drm/amdgpu: use irq-safe lock for kiq->ring_lock drm/amdgpu: bypass lru touch for KIQ ring submission drm/amdgpu: Potential uninitialized variable in amdgpu_vm_update_directories() drm/amdgpu: potential uninitialized variable in amdgpu_vce_ring_parse_cs() drm/amd/powerplay: initialize a variable before using it drm/amd/powerplay: suppress KASAN out of bounds warning in vega10_populate_all_memory_levels drm/amd/amdgpu: fix evicted VRAM bo adjudgement condition drm/vblank: Tune drm_crtc_accurate_vblank_count() WARN down to a debug drm/rockchip: add CONFIG_OF dependency for lvds ...
Diffstat (limited to 'drivers/gpu/drm/etnaviv/etnaviv_perfmon.c')
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_perfmon.c495
1 files changed, 495 insertions, 0 deletions
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c
new file mode 100644
index 000000000000..768f5aafdd18
--- /dev/null
+++ b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c
@@ -0,0 +1,495 @@
+/*
+ * Copyright (C) 2017 Etnaviv Project
+ * Copyright (C) 2017 Zodiac Inflight Innovations
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "etnaviv_gpu.h"
+#include "etnaviv_perfmon.h"
+#include "state_hi.xml.h"
+
+struct etnaviv_pm_domain;
+
+struct etnaviv_pm_signal {
+ char name[64];
+ u32 data;
+
+ u32 (*sample)(struct etnaviv_gpu *gpu,
+ const struct etnaviv_pm_domain *domain,
+ const struct etnaviv_pm_signal *signal);
+};
+
+struct etnaviv_pm_domain {
+ char name[64];
+
+ /* profile register */
+ u32 profile_read;
+ u32 profile_config;
+
+ u8 nr_signals;
+ const struct etnaviv_pm_signal *signal;
+};
+
+struct etnaviv_pm_domain_meta {
+ const struct etnaviv_pm_domain *domains;
+ u32 nr_domains;
+};
+
+static u32 simple_reg_read(struct etnaviv_gpu *gpu,
+ const struct etnaviv_pm_domain *domain,
+ const struct etnaviv_pm_signal *signal)
+{
+ return gpu_read(gpu, signal->data);
+}
+
+static u32 perf_reg_read(struct etnaviv_gpu *gpu,
+ const struct etnaviv_pm_domain *domain,
+ const struct etnaviv_pm_signal *signal)
+{
+ gpu_write(gpu, domain->profile_config, signal->data);
+
+ return gpu_read(gpu, domain->profile_read);
+}
+
+static u32 pipe_reg_read(struct etnaviv_gpu *gpu,
+ const struct etnaviv_pm_domain *domain,
+ const struct etnaviv_pm_signal *signal)
+{
+ u32 clock = gpu_read(gpu, VIVS_HI_CLOCK_CONTROL);
+ u32 value = 0;
+ unsigned i;
+
+ for (i = 0; i < gpu->identity.pixel_pipes; i++) {
+ clock &= ~(VIVS_HI_CLOCK_CONTROL_DEBUG_PIXEL_PIPE__MASK);
+ clock |= VIVS_HI_CLOCK_CONTROL_DEBUG_PIXEL_PIPE(i);
+ gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, clock);
+ gpu_write(gpu, domain->profile_config, signal->data);
+ value += gpu_read(gpu, domain->profile_read);
+ }
+
+ /* switch back to pixel pipe 0 to prevent GPU hang */
+ clock &= ~(VIVS_HI_CLOCK_CONTROL_DEBUG_PIXEL_PIPE__MASK);
+ clock |= VIVS_HI_CLOCK_CONTROL_DEBUG_PIXEL_PIPE(0);
+ gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, clock);
+
+ return value;
+}
+
+static const struct etnaviv_pm_domain doms_3d[] = {
+ {
+ .name = "HI",
+ .profile_read = VIVS_MC_PROFILE_HI_READ,
+ .profile_config = VIVS_MC_PROFILE_CONFIG2,
+ .nr_signals = 5,
+ .signal = (const struct etnaviv_pm_signal[]) {
+ {
+ "TOTAL_CYCLES",
+ VIVS_HI_PROFILE_TOTAL_CYCLES,
+ &simple_reg_read
+ },
+ {
+ "IDLE_CYCLES",
+ VIVS_HI_PROFILE_IDLE_CYCLES,
+ &simple_reg_read
+ },
+ {
+ "AXI_CYCLES_READ_REQUEST_STALLED",
+ VIVS_MC_PROFILE_CONFIG2_HI_AXI_CYCLES_READ_REQUEST_STALLED,
+ &perf_reg_read
+ },
+ {
+ "AXI_CYCLES_WRITE_REQUEST_STALLED",
+ VIVS_MC_PROFILE_CONFIG2_HI_AXI_CYCLES_WRITE_REQUEST_STALLED,
+ &perf_reg_read
+ },
+ {
+ "AXI_CYCLES_WRITE_DATA_STALLED",
+ VIVS_MC_PROFILE_CONFIG2_HI_AXI_CYCLES_WRITE_DATA_STALLED,
+ &perf_reg_read
+ }
+ }
+ },
+ {
+ .name = "PE",
+ .profile_read = VIVS_MC_PROFILE_PE_READ,
+ .profile_config = VIVS_MC_PROFILE_CONFIG0,
+ .nr_signals = 5,
+ .signal = (const struct etnaviv_pm_signal[]) {
+ {
+ "PIXEL_COUNT_KILLED_BY_COLOR_PIPE",
+ VIVS_MC_PROFILE_CONFIG0_PE_PIXEL_COUNT_KILLED_BY_COLOR_PIPE,
+ &pipe_reg_read
+ },
+ {
+ "PIXEL_COUNT_KILLED_BY_DEPTH_PIPE",
+ VIVS_MC_PROFILE_CONFIG0_PE_PIXEL_COUNT_KILLED_BY_DEPTH_PIPE,
+ &pipe_reg_read
+ },
+ {
+ "PIXEL_COUNT_DRAWN_BY_COLOR_PIPE",
+ VIVS_MC_PROFILE_CONFIG0_PE_PIXEL_COUNT_DRAWN_BY_COLOR_PIPE,
+ &pipe_reg_read
+ },
+ {
+ "PIXEL_COUNT_DRAWN_BY_DEPTH_PIPE",
+ VIVS_MC_PROFILE_CONFIG0_PE_PIXEL_COUNT_DRAWN_BY_DEPTH_PIPE,
+ &pipe_reg_read
+ }
+ }
+ },
+ {
+ .name = "SH",
+ .profile_read = VIVS_MC_PROFILE_SH_READ,
+ .profile_config = VIVS_MC_PROFILE_CONFIG0,
+ .nr_signals = 9,
+ .signal = (const struct etnaviv_pm_signal[]) {
+ {
+ "SHADER_CYCLES",
+ VIVS_MC_PROFILE_CONFIG0_SH_SHADER_CYCLES,
+ &perf_reg_read
+ },
+ {
+ "PS_INST_COUNTER",
+ VIVS_MC_PROFILE_CONFIG0_SH_PS_INST_COUNTER,
+ &perf_reg_read
+ },
+ {
+ "RENDERED_PIXEL_COUNTER",
+ VIVS_MC_PROFILE_CONFIG0_SH_RENDERED_PIXEL_COUNTER,
+ &perf_reg_read
+ },
+ {
+ "VS_INST_COUNTER",
+ VIVS_MC_PROFILE_CONFIG0_SH_VS_INST_COUNTER,
+ &pipe_reg_read
+ },
+ {
+ "RENDERED_VERTICE_COUNTER",
+ VIVS_MC_PROFILE_CONFIG0_SH_RENDERED_VERTICE_COUNTER,
+ &pipe_reg_read
+ },
+ {
+ "VTX_BRANCH_INST_COUNTER",
+ VIVS_MC_PROFILE_CONFIG0_SH_VTX_BRANCH_INST_COUNTER,
+ &pipe_reg_read
+ },
+ {
+ "VTX_TEXLD_INST_COUNTER",
+ VIVS_MC_PROFILE_CONFIG0_SH_VTX_TEXLD_INST_COUNTER,
+ &pipe_reg_read
+ },
+ {
+ "PXL_BRANCH_INST_COUNTER",
+ VIVS_MC_PROFILE_CONFIG0_SH_PXL_BRANCH_INST_COUNTER,
+ &pipe_reg_read
+ },
+ {
+ "PXL_TEXLD_INST_COUNTER",
+ VIVS_MC_PROFILE_CONFIG0_SH_PXL_TEXLD_INST_COUNTER,
+ &pipe_reg_read
+ }
+ }
+ },
+ {
+ .name = "PA",
+ .profile_read = VIVS_MC_PROFILE_PA_READ,
+ .profile_config = VIVS_MC_PROFILE_CONFIG1,
+ .nr_signals = 6,
+ .signal = (const struct etnaviv_pm_signal[]) {
+ {
+ "INPUT_VTX_COUNTER",
+ VIVS_MC_PROFILE_CONFIG1_PA_INPUT_VTX_COUNTER,
+ &perf_reg_read
+ },
+ {
+ "INPUT_PRIM_COUNTER",
+ VIVS_MC_PROFILE_CONFIG1_PA_INPUT_PRIM_COUNTER,
+ &perf_reg_read
+ },
+ {
+ "OUTPUT_PRIM_COUNTER",
+ VIVS_MC_PROFILE_CONFIG1_PA_OUTPUT_PRIM_COUNTER,
+ &perf_reg_read
+ },
+ {
+ "DEPTH_CLIPPED_COUNTER",
+ VIVS_MC_PROFILE_CONFIG1_PA_DEPTH_CLIPPED_COUNTER,
+ &pipe_reg_read
+ },
+ {
+ "TRIVIAL_REJECTED_COUNTER",
+ VIVS_MC_PROFILE_CONFIG1_PA_TRIVIAL_REJECTED_COUNTER,
+ &pipe_reg_read
+ },
+ {
+ "CULLED_COUNTER",
+ VIVS_MC_PROFILE_CONFIG1_PA_CULLED_COUNTER,
+ &pipe_reg_read
+ }
+ }
+ },
+ {
+ .name = "SE",
+ .profile_read = VIVS_MC_PROFILE_SE_READ,
+ .profile_config = VIVS_MC_PROFILE_CONFIG1,
+ .nr_signals = 2,
+ .signal = (const struct etnaviv_pm_signal[]) {
+ {
+ "CULLED_TRIANGLE_COUNT",
+ VIVS_MC_PROFILE_CONFIG1_SE_CULLED_TRIANGLE_COUNT,
+ &perf_reg_read
+ },
+ {
+ "CULLED_LINES_COUNT",
+ VIVS_MC_PROFILE_CONFIG1_SE_CULLED_LINES_COUNT,
+ &perf_reg_read
+ }
+ }
+ },
+ {
+ .name = "RA",
+ .profile_read = VIVS_MC_PROFILE_RA_READ,
+ .profile_config = VIVS_MC_PROFILE_CONFIG1,
+ .nr_signals = 7,
+ .signal = (const struct etnaviv_pm_signal[]) {
+ {
+ "VALID_PIXEL_COUNT",
+ VIVS_MC_PROFILE_CONFIG1_RA_VALID_PIXEL_COUNT,
+ &perf_reg_read
+ },
+ {
+ "TOTAL_QUAD_COUNT",
+ VIVS_MC_PROFILE_CONFIG1_RA_TOTAL_QUAD_COUNT,
+ &perf_reg_read
+ },
+ {
+ "VALID_QUAD_COUNT_AFTER_EARLY_Z",
+ VIVS_MC_PROFILE_CONFIG1_RA_VALID_QUAD_COUNT_AFTER_EARLY_Z,
+ &perf_reg_read
+ },
+ {
+ "TOTAL_PRIMITIVE_COUNT",
+ VIVS_MC_PROFILE_CONFIG1_RA_TOTAL_PRIMITIVE_COUNT,
+ &perf_reg_read
+ },
+ {
+ "PIPE_CACHE_MISS_COUNTER",
+ VIVS_MC_PROFILE_CONFIG1_RA_PIPE_CACHE_MISS_COUNTER,
+ &perf_reg_read
+ },
+ {
+ "PREFETCH_CACHE_MISS_COUNTER",
+ VIVS_MC_PROFILE_CONFIG1_RA_PREFETCH_CACHE_MISS_COUNTER,
+ &perf_reg_read
+ },
+ {
+ "CULLED_QUAD_COUNT",
+ VIVS_MC_PROFILE_CONFIG1_RA_CULLED_QUAD_COUNT,
+ &perf_reg_read
+ }
+ }
+ },
+ {
+ .name = "TX",
+ .profile_read = VIVS_MC_PROFILE_TX_READ,
+ .profile_config = VIVS_MC_PROFILE_CONFIG1,
+ .nr_signals = 9,
+ .signal = (const struct etnaviv_pm_signal[]) {
+ {
+ "TOTAL_BILINEAR_REQUESTS",
+ VIVS_MC_PROFILE_CONFIG1_TX_TOTAL_BILINEAR_REQUESTS,
+ &perf_reg_read
+ },
+ {
+ "TOTAL_TRILINEAR_REQUESTS",
+ VIVS_MC_PROFILE_CONFIG1_TX_TOTAL_TRILINEAR_REQUESTS,
+ &perf_reg_read
+ },
+ {
+ "TOTAL_DISCARDED_TEXTURE_REQUESTS",
+ VIVS_MC_PROFILE_CONFIG1_TX_TOTAL_DISCARDED_TEXTURE_REQUESTS,
+ &perf_reg_read
+ },
+ {
+ "TOTAL_TEXTURE_REQUESTS",
+ VIVS_MC_PROFILE_CONFIG1_TX_TOTAL_TEXTURE_REQUESTS,
+ &perf_reg_read
+ },
+ {
+ "MEM_READ_COUNT",
+ VIVS_MC_PROFILE_CONFIG1_TX_MEM_READ_COUNT,
+ &perf_reg_read
+ },
+ {
+ "MEM_READ_IN_8B_COUNT",
+ VIVS_MC_PROFILE_CONFIG1_TX_MEM_READ_IN_8B_COUNT,
+ &perf_reg_read
+ },
+ {
+ "CACHE_MISS_COUNT",
+ VIVS_MC_PROFILE_CONFIG1_TX_CACHE_MISS_COUNT,
+ &perf_reg_read
+ },
+ {
+ "CACHE_HIT_TEXEL_COUNT",
+ VIVS_MC_PROFILE_CONFIG1_TX_CACHE_HIT_TEXEL_COUNT,
+ &perf_reg_read
+ },
+ {
+ "CACHE_MISS_TEXEL_COUNT",
+ VIVS_MC_PROFILE_CONFIG1_TX_CACHE_MISS_TEXEL_COUNT,
+ &perf_reg_read
+ }
+ }
+ },
+ {
+ .name = "MC",
+ .profile_read = VIVS_MC_PROFILE_MC_READ,
+ .profile_config = VIVS_MC_PROFILE_CONFIG2,
+ .nr_signals = 3,
+ .signal = (const struct etnaviv_pm_signal[]) {
+ {
+ "TOTAL_READ_REQ_8B_FROM_PIPELINE",
+ VIVS_MC_PROFILE_CONFIG2_MC_TOTAL_READ_REQ_8B_FROM_PIPELINE,
+ &perf_reg_read
+ },
+ {
+ "TOTAL_READ_REQ_8B_FROM_IP",
+ VIVS_MC_PROFILE_CONFIG2_MC_TOTAL_READ_REQ_8B_FROM_IP,
+ &perf_reg_read
+ },
+ {
+ "TOTAL_WRITE_REQ_8B_FROM_PIPELINE",
+ VIVS_MC_PROFILE_CONFIG2_MC_TOTAL_WRITE_REQ_8B_FROM_PIPELINE,
+ &perf_reg_read
+ }
+ }
+ }
+};
+
+static const struct etnaviv_pm_domain doms_2d[] = {
+ {
+ .name = "PE",
+ .profile_read = VIVS_MC_PROFILE_PE_READ,
+ .profile_config = VIVS_MC_PROFILE_CONFIG0,
+ .nr_signals = 1,
+ .signal = (const struct etnaviv_pm_signal[]) {
+ {
+ "PIXELS_RENDERED_2D",
+ VIVS_MC_PROFILE_CONFIG0_PE_PIXELS_RENDERED_2D,
+ &pipe_reg_read
+ }
+ }
+ }
+};
+
+static const struct etnaviv_pm_domain doms_vg[] = {
+};
+
+static const struct etnaviv_pm_domain_meta doms_meta[] = {
+ {
+ .nr_domains = ARRAY_SIZE(doms_3d),
+ .domains = &doms_3d[0]
+ },
+ {
+ .nr_domains = ARRAY_SIZE(doms_2d),
+ .domains = &doms_2d[0]
+ },
+ {
+ .nr_domains = ARRAY_SIZE(doms_vg),
+ .domains = &doms_vg[0]
+ }
+};
+
+int etnaviv_pm_query_dom(struct etnaviv_gpu *gpu,
+ struct drm_etnaviv_pm_domain *domain)
+{
+ const struct etnaviv_pm_domain_meta *meta = &doms_meta[domain->pipe];
+ const struct etnaviv_pm_domain *dom;
+
+ if (domain->iter >= meta->nr_domains)
+ return -EINVAL;
+
+ dom = meta->domains + domain->iter;
+
+ domain->id = domain->iter;
+ domain->nr_signals = dom->nr_signals;
+ strncpy(domain->name, dom->name, sizeof(domain->name));
+
+ domain->iter++;
+ if (domain->iter == meta->nr_domains)
+ domain->iter = 0xff;
+
+ return 0;
+}
+
+int etnaviv_pm_query_sig(struct etnaviv_gpu *gpu,
+ struct drm_etnaviv_pm_signal *signal)
+{
+ const struct etnaviv_pm_domain_meta *meta = &doms_meta[signal->pipe];
+ const struct etnaviv_pm_domain *dom;
+ const struct etnaviv_pm_signal *sig;
+
+ if (signal->domain >= meta->nr_domains)
+ return -EINVAL;
+
+ dom = meta->domains + signal->domain;
+
+ if (signal->iter > dom->nr_signals)
+ return -EINVAL;
+
+ sig = &dom->signal[signal->iter];
+
+ signal->id = signal->iter;
+ strncpy(signal->name, sig->name, sizeof(signal->name));
+
+ signal->iter++;
+ if (signal->iter == dom->nr_signals)
+ signal->iter = 0xffff;
+
+ return 0;
+}
+
+int etnaviv_pm_req_validate(const struct drm_etnaviv_gem_submit_pmr *r,
+ u32 exec_state)
+{
+ const struct etnaviv_pm_domain_meta *meta = &doms_meta[exec_state];
+ const struct etnaviv_pm_domain *dom;
+
+ if (r->domain >= meta->nr_domains)
+ return -EINVAL;
+
+ dom = meta->domains + r->domain;
+
+ if (r->signal > dom->nr_signals)
+ return -EINVAL;
+
+ return 0;
+}
+
+void etnaviv_perfmon_process(struct etnaviv_gpu *gpu,
+ const struct etnaviv_perfmon_request *pmr)
+{
+ const struct etnaviv_pm_domain_meta *meta = &doms_meta[gpu->exec_state];
+ const struct etnaviv_pm_domain *dom;
+ const struct etnaviv_pm_signal *sig;
+ u32 *bo = pmr->bo_vma;
+ u32 val;
+
+ dom = meta->domains + pmr->domain;
+ sig = &dom->signal[pmr->signal];
+ val = sig->sample(gpu, dom, sig);
+
+ *(bo + pmr->offset) = val;
+}