1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * AMD Platform Management Framework Test Tool 4 * 5 * Copyright (c) 2026, Advanced Micro Devices, Inc. 6 * All Rights Reserved. 7 * 8 * Authors: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> 9 * Sanket Goswami <Sanket.Goswami@amd.com> 10 */ 11 12 #include <errno.h> 13 #include <fcntl.h> 14 #include <inttypes.h> 15 #include <stdbool.h> 16 #include <stdint.h> 17 #include <stdio.h> 18 #include <string.h> 19 #include <sys/ioctl.h> 20 #include <unistd.h> 21 22 #include <linux/amd-pmf.h> 23 #include <linux/kernel.h> 24 25 #define DEVICE_NODE "/dev/amdpmf_interface" 26 27 /* Feature flag names */ 28 static const char * const feature_names[] = { 29 "Auto Mode", 30 "Static Power Slider", 31 "Policy Builder (Smart PC)", 32 "Dynamic Power Slider AC", 33 "Dynamic Power Slider DC", 34 }; 35 36 static const char *banner = 37 "====================================================\n" 38 " AMD PMF Metrics info and Feature Status\n" 39 "====================================================\n\n"; 40 41 /* Print feature flags */ 42 static void pmf_print_features(uint32_t flags) 43 { 44 size_t i; 45 46 for (i = 0; i < ARRAY_SIZE(feature_names); i++) 47 printf(" [%c] %s\n", (flags & (1U << i)) ? 'x' : ' ', feature_names[i]); 48 } 49 50 /* Print BIOS parameters */ 51 static void pmf_print_bios_params(const char *type, const __u32 *params) 52 { 53 int i; 54 55 for (i = 0; i < AMD_PMF_BIOS_PARAMS_MAX; i++) 56 printf(" Custom BIOS %s%d: %u\n", type, i + 1, params[i]); 57 } 58 59 /* Open the PMF device */ 60 static int pmf_open_device(void) 61 { 62 int fd; 63 64 fd = open(DEVICE_NODE, O_RDONLY); 65 if (fd < 0) 66 fprintf(stderr, "Error: Cannot open %s: %s\n", DEVICE_NODE, strerror(errno)); 67 68 return fd; 69 } 70 71 /* Query PMF info using the single IOCTL */ 72 static int pmf_get_info(int fd, struct amd_pmf_info *info) 73 { 74 int ret; 75 76 /* Zero-initialize and set size for versioning */ 77 memset(info, 0, sizeof(*info)); 78 info->size = sizeof(*info); 79 80 ret = ioctl(fd, IOCTL_AMD_PMF_POPULATE_DATA, info); 81 if (ret < 0) { 82 fprintf(stderr, "Error: IOCTL_AMD_PMF_POPULATE_DATA failed: %s\n", strerror(errno)); 83 return ret; 84 } 85 86 return 0; 87 } 88 89 static void pmf_print_info(const struct amd_pmf_info *info) 90 { 91 printf("%s", banner); 92 93 /* Feature status */ 94 printf("Feature Status:\n"); 95 pmf_print_features(info->features_supported); 96 97 /* Device states */ 98 printf("\nDevice States:\n"); 99 printf(" Platform Type: %s\n", amd_pmf_get_platform_type(info->platform_type)); 100 printf(" Laptop Placement: %s\n", amd_pmf_get_laptop_placement(info->laptop_placement)); 101 printf(" Lid State: %s\n", info->lid_state ? "Closed" : "Open"); 102 printf(" User Presence: %s\n", info->user_presence ? "Present" : "Away"); 103 printf(" Slider Position: %s\n", amd_pmf_get_slider_position(info->slider_position)); 104 105 /* Thermal and power metrics */ 106 printf("\nThermal/Power Metrics:\n"); 107 printf(" Skin Temperature: %d\n", info->skin_temp / 100); 108 printf(" GFX Busy: %u\n", info->gfx_busy); 109 printf(" Ambient Light: %d\n", info->ambient_light); 110 printf(" Avg C0 Residency: %u\n", info->avg_c0_residency); 111 printf(" Max C0 Residency: %u\n", info->max_c0_residency); 112 printf(" Socket Power: %u\n", info->socket_power); 113 114 /* BIOS parameters */ 115 printf("\nCustom BIOS Input Parameters:\n"); 116 pmf_print_bios_params("Input", info->bios_input); 117 printf("\nCustom BIOS Output Parameters:\n"); 118 pmf_print_bios_params("Output", info->bios_output); 119 120 printf("\n=================================================\n"); 121 } 122 123 int main(void) 124 { 125 struct amd_pmf_info info; 126 int fd, ret; 127 128 fd = pmf_open_device(); 129 if (fd < 0) 130 return -1; 131 132 /* Query all info with single IOCTL */ 133 ret = pmf_get_info(fd, &info); 134 close(fd); 135 136 if (ret < 0) 137 return -1; 138 139 pmf_print_info(&info); 140 141 return 0; 142 } 143