Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amd/pm: Add sysfs node for node power

Add sysfs node to expose node power limit for smu_v13_0_12

v2: Remove support check from visible function (Kevin)

v3: Update comments (Kevin)
Remove sysfs remove file, change format specifier
for sysfs_emit, use attribute_group.name (Lijo)

Signed-off-by: Asad Kamal <asad.kamal@amd.com>
Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
Reviewed-by: Yang Wang <kevinyang.wang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Asad Kamal and committed by
Alex Deucher
ef612f58 4072b16d

+153 -2
+4
drivers/gpu/drm/amd/include/kgd_pp_interface.h
··· 162 162 AMDGPU_PP_SENSOR_PEAK_PSTATE_SCLK, 163 163 AMDGPU_PP_SENSOR_PEAK_PSTATE_MCLK, 164 164 AMDGPU_PP_SENSOR_VCN_LOAD, 165 + AMDGPU_PP_SENSOR_NODEPOWERLIMIT, 166 + AMDGPU_PP_SENSOR_NODEPOWER, 167 + AMDGPU_PP_SENSOR_GPPTRESIDENCY, 168 + AMDGPU_PP_SENSOR_MAXNODEPOWERLIMIT, 165 169 }; 166 170 167 171 enum amd_pp_task {
+149 -2
drivers/gpu/drm/amd/pm/amdgpu_pm.c
··· 2081 2081 * for user application to monitor various board reated attributes. 2082 2082 * 2083 2083 * The amdgpu driver provides a sysfs API for reporting board attributes. Presently, 2084 - * only two types of attributes are reported, baseboard temperature and 2085 - * gpu board temperature. Both of them are reported as binary files. 2084 + * seven types of attributes are reported. Baseboard temperature and 2085 + * gpu board temperature are reported as binary files. Npm status, current node power limit, 2086 + * max node power limit, node power and global ppt residency is reported as ASCII text file. 2086 2087 * 2087 2088 * * .. code-block:: console 2088 2089 * ··· 2091 2090 * 2092 2091 * hexdump /sys/bus/pci/devices/.../board/gpuboard_temp 2093 2092 * 2093 + * hexdump /sys/bus/pci/devices/.../board/npm_status 2094 + * 2095 + * hexdump /sys/bus/pci/devices/.../board/cur_node_power_limit 2096 + * 2097 + * hexdump /sys/bus/pci/devices/.../board/max_node_power_limit 2098 + * 2099 + * hexdump /sys/bus/pci/devices/.../board/node_power 2100 + * 2101 + * hexdump /sys/bus/pci/devices/.../board/global_ppt_resid 2094 2102 */ 2095 2103 2096 2104 /** ··· 2178 2168 return size; 2179 2169 } 2180 2170 2171 + /** 2172 + * DOC: cur_node_power_limit 2173 + * 2174 + * The amdgpu driver provides a sysfs API for retrieving current node power limit. 2175 + * The file cur_node_power_limit is used for this. 2176 + */ 2177 + static ssize_t amdgpu_show_cur_node_power_limit(struct device *dev, 2178 + struct device_attribute *attr, char *buf) 2179 + { 2180 + struct drm_device *ddev = dev_get_drvdata(dev); 2181 + struct amdgpu_device *adev = drm_to_adev(ddev); 2182 + u32 nplimit; 2183 + int r; 2184 + 2185 + /* get the current node power limit */ 2186 + r = amdgpu_pm_get_sensor_generic(adev, AMDGPU_PP_SENSOR_NODEPOWERLIMIT, 2187 + (void *)&nplimit); 2188 + if (r) 2189 + return r; 2190 + 2191 + return sysfs_emit(buf, "%u\n", nplimit); 2192 + } 2193 + 2194 + /** 2195 + * DOC: node_power 2196 + * 2197 + * The amdgpu driver provides a sysfs API for retrieving current node power. 2198 + * The file node_power is used for this. 2199 + */ 2200 + static ssize_t amdgpu_show_node_power(struct device *dev, 2201 + struct device_attribute *attr, char *buf) 2202 + { 2203 + struct drm_device *ddev = dev_get_drvdata(dev); 2204 + struct amdgpu_device *adev = drm_to_adev(ddev); 2205 + u32 npower; 2206 + int r; 2207 + 2208 + /* get the node power */ 2209 + r = amdgpu_pm_get_sensor_generic(adev, AMDGPU_PP_SENSOR_NODEPOWER, 2210 + (void *)&npower); 2211 + if (r) 2212 + return r; 2213 + 2214 + return sysfs_emit(buf, "%u\n", npower); 2215 + } 2216 + 2217 + /** 2218 + * DOC: npm_status 2219 + * 2220 + * The amdgpu driver provides a sysfs API for retrieving current node power management status. 2221 + * The file npm_status is used for this. It shows the status as enabled or disabled based on 2222 + * current node power value. If node power is zero, status is disabled else enabled. 2223 + */ 2224 + static ssize_t amdgpu_show_npm_status(struct device *dev, 2225 + struct device_attribute *attr, char *buf) 2226 + { 2227 + struct drm_device *ddev = dev_get_drvdata(dev); 2228 + struct amdgpu_device *adev = drm_to_adev(ddev); 2229 + u32 npower; 2230 + int r; 2231 + 2232 + /* get the node power */ 2233 + r = amdgpu_pm_get_sensor_generic(adev, AMDGPU_PP_SENSOR_NODEPOWER, 2234 + (void *)&npower); 2235 + if (r) 2236 + return r; 2237 + 2238 + return sysfs_emit(buf, "%s\n", npower ? "enabled" : "disabled"); 2239 + } 2240 + 2241 + /** 2242 + * DOC: global_ppt_resid 2243 + * 2244 + * The amdgpu driver provides a sysfs API for retrieving global ppt residency. 2245 + * The file global_ppt_resid is used for this. 2246 + */ 2247 + static ssize_t amdgpu_show_global_ppt_resid(struct device *dev, 2248 + struct device_attribute *attr, char *buf) 2249 + { 2250 + struct drm_device *ddev = dev_get_drvdata(dev); 2251 + struct amdgpu_device *adev = drm_to_adev(ddev); 2252 + u32 gpptresid; 2253 + int r; 2254 + 2255 + /* get the global ppt residency */ 2256 + r = amdgpu_pm_get_sensor_generic(adev, AMDGPU_PP_SENSOR_GPPTRESIDENCY, 2257 + (void *)&gpptresid); 2258 + if (r) 2259 + return r; 2260 + 2261 + return sysfs_emit(buf, "%u\n", gpptresid); 2262 + } 2263 + 2264 + /** 2265 + * DOC: max_node_power_limit 2266 + * 2267 + * The amdgpu driver provides a sysfs API for retrieving maximum node power limit. 2268 + * The file max_node_power_limit is used for this. 2269 + */ 2270 + static ssize_t amdgpu_show_max_node_power_limit(struct device *dev, 2271 + struct device_attribute *attr, char *buf) 2272 + { 2273 + struct drm_device *ddev = dev_get_drvdata(dev); 2274 + struct amdgpu_device *adev = drm_to_adev(ddev); 2275 + u32 max_nplimit; 2276 + int r; 2277 + 2278 + /* get the max node power limit */ 2279 + r = amdgpu_pm_get_sensor_generic(adev, AMDGPU_PP_SENSOR_MAXNODEPOWERLIMIT, 2280 + (void *)&max_nplimit); 2281 + if (r) 2282 + return r; 2283 + 2284 + return sysfs_emit(buf, "%u\n", max_nplimit); 2285 + } 2286 + 2181 2287 static DEVICE_ATTR(baseboard_temp, 0444, amdgpu_get_baseboard_temp_metrics, NULL); 2182 2288 static DEVICE_ATTR(gpuboard_temp, 0444, amdgpu_get_gpuboard_temp_metrics, NULL); 2289 + static DEVICE_ATTR(cur_node_power_limit, 0444, amdgpu_show_cur_node_power_limit, NULL); 2290 + static DEVICE_ATTR(node_power, 0444, amdgpu_show_node_power, NULL); 2291 + static DEVICE_ATTR(global_ppt_resid, 0444, amdgpu_show_global_ppt_resid, NULL); 2292 + static DEVICE_ATTR(max_node_power_limit, 0444, amdgpu_show_max_node_power_limit, NULL); 2293 + static DEVICE_ATTR(npm_status, 0444, amdgpu_show_npm_status, NULL); 2183 2294 2184 2295 static struct attribute *board_attrs[] = { 2185 2296 &dev_attr_baseboard_temp.attr, ··· 4665 4534 { 4666 4535 enum amdgpu_sriov_vf_mode mode; 4667 4536 uint32_t mask = 0; 4537 + uint32_t tmp; 4668 4538 int ret; 4669 4539 4670 4540 if (adev->pm.sysfs_initialized) ··· 4732 4600 &amdgpu_board_attr_group); 4733 4601 if (ret) 4734 4602 goto err_out0; 4603 + if (amdgpu_pm_get_sensor_generic(adev, AMDGPU_PP_SENSOR_MAXNODEPOWERLIMIT, 4604 + (void *)&tmp) != -EOPNOTSUPP) { 4605 + sysfs_add_file_to_group(&adev->dev->kobj, 4606 + &dev_attr_cur_node_power_limit.attr, 4607 + amdgpu_board_attr_group.name); 4608 + sysfs_add_file_to_group(&adev->dev->kobj, &dev_attr_node_power.attr, 4609 + amdgpu_board_attr_group.name); 4610 + sysfs_add_file_to_group(&adev->dev->kobj, &dev_attr_global_ppt_resid.attr, 4611 + amdgpu_board_attr_group.name); 4612 + sysfs_add_file_to_group(&adev->dev->kobj, 4613 + &dev_attr_max_node_power_limit.attr, 4614 + amdgpu_board_attr_group.name); 4615 + sysfs_add_file_to_group(&adev->dev->kobj, &dev_attr_npm_status.attr, 4616 + amdgpu_board_attr_group.name); 4617 + } 4735 4618 } 4736 4619 4737 4620 adev->pm.sysfs_initialized = true;