GCC Code Coverage Report


Directory: ./
File: src/ppd-action-amdgpu-dpm.c
Date: 2024-09-13 00:56:02
Exec Total Coverage
Lines: 63 69 91.3%
Functions: 10 10 100.0%
Branches: 20 28 71.4%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2024 Advanced Micro Devices
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3 as published by
6 * the Free Software Foundation.
7 *
8 */
9
10 #define G_LOG_DOMAIN "AmdgpuDpm"
11
12 #include "config.h"
13
14 #include <gudev/gudev.h>
15
16 #include "ppd-action-amdgpu-dpm.h"
17 #include "ppd-profile.h"
18 #include "ppd-utils.h"
19
20 #define DPM_SYSFS_NAME "device/power_dpm_force_performance_level"
21
22 /**
23 * SECTION:ppd-action-amdgpu-dpm
24 * @Short_description: Power savings for GPU clocks
25 * @Title: AMDGPU DPM clock control
26 *
27 * The AMDGPU DPM clock control action utilizes the sysfs attribute present on some DRM
28 * connectors for amdgpu called "power_dpm_force_performance_level".
29 */
30
31 struct _PpdActionAmdgpuDpm
32 {
33 PpdAction parent_instance;
34 PpdProfile last_profile;
35
36 GUdevClient *client;
37 };
38
39
4/5
✓ Branch 0 taken 130 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 130 times.
✓ Branch 3 taken 130 times.
✗ Branch 4 not taken.
788 G_DEFINE_TYPE (PpdActionAmdgpuDpm, ppd_action_amdgpu_dpm, PPD_TYPE_ACTION)
40
41 static GObject*
42 134 ppd_action_amdgpu_dpm_constructor (GType type,
43 guint n_construct_params,
44 GObjectConstructParam *construct_params)
45 {
46 134 GObject *object;
47
48 134 object = G_OBJECT_CLASS (ppd_action_amdgpu_dpm_parent_class)->constructor (type,
49 n_construct_params,
50 construct_params);
51 134 g_object_set (object,
52 "action-name", "amdgpu_dpm",
53 NULL);
54
55 134 return object;
56 }
57
58 static gboolean
59 16 ppd_action_amdgpu_dpm_update_target (PpdActionAmdgpuDpm *self, GError **error)
60 {
61 32 g_autolist (GUdevDevice) devices = NULL;
62 16 const gchar *target;
63
64
2/3
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
16 switch (self->last_profile) {
65 case PPD_PROFILE_POWER_SAVER:
66 target = "low";
67 break;
68 10 case PPD_PROFILE_BALANCED:
69 case PPD_PROFILE_PERFORMANCE:
70 10 target = "auto";
71 10 break;
72 default:
73 g_assert_not_reached ();
74 }
75
76 16 devices = g_udev_client_query_by_subsystem (self->client, "drm");
77
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (devices == NULL) {
78 g_set_error_literal (error,
79 G_IO_ERROR,
80 G_IO_ERROR_NOT_FOUND,
81 "no drm devices found");
82 return FALSE;
83 }
84
85
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
32 for (GList *l = devices; l != NULL; l = l->next) {
86 16 GUdevDevice *dev = l->data;
87 16 const char *value;
88
89 16 value = g_udev_device_get_devtype (dev);
90
2/2
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 8 times.
16 if (g_strcmp0 (value, "drm_minor") != 0)
91 8 continue;
92
93 8 value = g_udev_device_get_sysfs_attr_uncached (dev, DPM_SYSFS_NAME);
94
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (!value)
95 continue;
96
97
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 6 times.
8 if (g_strcmp0 (value, target) == 0) {
98 2 g_info ("Device %s already set to %s", g_udev_device_get_sysfs_path (dev), target);
99 2 continue;
100 }
101
102
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 2 times.
6 if (g_strcmp0 (value, "manual") == 0) {
103 4 g_info ("Device %s is in manual mode, not changing", g_udev_device_get_sysfs_path (dev));
104 4 continue;
105 }
106
107 2 g_info ("Setting device %s to %s", g_udev_device_get_sysfs_path (dev), target);
108
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (!ppd_utils_write_sysfs (dev, DPM_SYSFS_NAME, target, error))
109 return FALSE;
110 }
111
112 return TRUE;
113 }
114
115 static gboolean
116 16 ppd_action_amdgpu_dpm_activate_profile (PpdAction *action,
117 PpdProfile profile,
118 GError **error)
119 {
120 16 PpdActionAmdgpuDpm *self = PPD_ACTION_AMDGPU_DPM (action);
121 16 self->last_profile = profile;
122
123 16 return ppd_action_amdgpu_dpm_update_target (self, error);
124 }
125
126 static void
127 4 udev_uevent_cb (GUdevClient *client,
128 gchar *action,
129 GUdevDevice *device,
130 gpointer user_data)
131 {
132 4 PpdActionAmdgpuDpm *self = user_data;
133
134 4 g_debug ("Device %s %s", g_udev_device_get_sysfs_path (device), action);
135
136
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (!g_str_equal (action, "add"))
137 return;
138
139
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 if (!g_udev_device_has_sysfs_attr (device, DPM_SYSFS_NAME))
140 return;
141
142 ppd_action_amdgpu_dpm_update_target (self, NULL);
143 }
144
145 static PpdProbeResult
146 134 ppd_action_amdgpu_dpm_probe (PpdAction *action)
147 {
148 134 return ppd_utils_match_cpu_vendor ("AuthenticAMD") ?
149 134 PPD_PROBE_RESULT_SUCCESS : PPD_PROBE_RESULT_FAIL;
150 }
151
152 static void
153 134 ppd_action_amdgpu_dpm_finalize (GObject *object)
154 {
155 134 PpdActionAmdgpuDpm *action;
156
157 134 action = PPD_ACTION_AMDGPU_DPM (object);
158
1/2
✓ Branch 0 taken 134 times.
✗ Branch 1 not taken.
134 g_clear_object (&action->client);
159 134 G_OBJECT_CLASS (ppd_action_amdgpu_dpm_parent_class)->finalize (object);
160 134 }
161
162 static void
163 130 ppd_action_amdgpu_dpm_class_init (PpdActionAmdgpuDpmClass *klass)
164 {
165 130 GObjectClass *object_class;
166 130 PpdActionClass *driver_class;
167
168 130 object_class = G_OBJECT_CLASS(klass);
169 130 object_class->constructor = ppd_action_amdgpu_dpm_constructor;
170 130 object_class->finalize = ppd_action_amdgpu_dpm_finalize;
171
172 130 driver_class = PPD_ACTION_CLASS(klass);
173 130 driver_class->probe = ppd_action_amdgpu_dpm_probe;
174 130 driver_class->activate_profile = ppd_action_amdgpu_dpm_activate_profile;
175 }
176
177 static void
178 134 ppd_action_amdgpu_dpm_init (PpdActionAmdgpuDpm *self)
179 {
180 134 const gchar * const subsystem[] = { "drm", NULL };
181
182 134 self->client = g_udev_client_new (subsystem);
183 134 g_signal_connect_object (G_OBJECT (self->client), "uevent",
184 G_CALLBACK (udev_uevent_cb), self, 0);
185 134 }
186