diff options
| author | Mark Brown <broonie@kernel.org> | 2026-07-27 14:36:35 +0100 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2026-07-27 14:36:37 +0100 |
| commit | 4f349f4e3101c7b4c94fa2c0e530eb5374f46916 (patch) | |
| tree | d38288cbb2fea9fc40b67542e4cada15ab5dd39a /tools | |
| parent | 02f7e6eababf8692577530c69e80f3624d5c265b (diff) | |
| parent | c7acedb2db001160b1ec41cdcc759dd664150666 (diff) | |
| download | linux-next-4f349f4e3101c7b4c94fa2c0e530eb5374f46916.tar.gz linux-next-4f349f4e3101c7b4c94fa2c0e530eb5374f46916.zip | |
Merge branch 'for-next' of https://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86.git
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/platform/x86/amd/Makefile | 60 | ||||
| -rw-r--r-- | tools/platform/x86/amd/test-pmf.c | 142 |
2 files changed, 202 insertions, 0 deletions
diff --git a/tools/platform/x86/amd/Makefile b/tools/platform/x86/amd/Makefile new file mode 100644 index 000000000000..5d820df5871f --- /dev/null +++ b/tools/platform/x86/amd/Makefile @@ -0,0 +1,60 @@ +# SPDX-License-Identifier: GPL-2.0 +ifeq ($(srctree),) +srctree := $(patsubst %/,%,$(dir $(CURDIR))) +srctree := $(patsubst %/,%,$(dir $(srctree))) +srctree := $(patsubst %/,%,$(dir $(srctree))) +srctree := $(patsubst %/,%,$(dir $(srctree))) +endif + +# Include common tools build infrastructure +include $(srctree)/tools/scripts/Makefile.include + +CC = $(CROSS_COMPILE)gcc +BUILD_OUTPUT := $(CURDIR) +PREFIX ?= /usr +DESTDIR ?= + +ifeq ("$(origin O)", "command line") + BUILD_OUTPUT := $(O) +endif + +# Include paths: tools/include has linux/kernel.h with ARRAY_SIZE +INCLUDES = -I$(srctree)/tools/include +INCLUDES += -I$(srctree)/tools/include/uapi +INCLUDES += -I$(srctree)/include/uapi +INCLUDES += -I$(srctree)/include + +override CFLAGS += -O2 -Wall -Wextra -D_GNU_SOURCE $(INCLUDES) +override CFLAGS += -D_FILE_OFFSET_BITS=64 +override CFLAGS += -D__EXPORTED_HEADERS__ + +TARGETS = test_amd_pmf + +all: $(TARGETS) + +test_amd_pmf: test-pmf.c + $(QUIET_CC)$(CC) $(CFLAGS) $< -o $(BUILD_OUTPUT)/$@ $(LDFLAGS) + +.PHONY: clean +clean: + $(call QUIET_CLEAN, test_amd_pmf)$(RM) $(BUILD_OUTPUT)/test_amd_pmf + +.PHONY: install +install: $(TARGETS) + $(INSTALL) -d $(DESTDIR)$(PREFIX)/bin + $(INSTALL) $(BUILD_OUTPUT)/test_amd_pmf $(DESTDIR)$(PREFIX)/bin/test_amd_pmf + +.PHONY: help +help: + @echo "AMD Platform Tools Makefile" + @echo "" + @echo "Targets:" + @echo " all - Build all tools (default)" + @echo " test_amd_pmf - Build the PMF test tool" + @echo " clean - Remove built files" + @echo " install - Install tools to $(PREFIX)/bin" + @echo "" + @echo "Variables:" + @echo " O=<dir> - Build output directory" + @echo " PREFIX - Installation prefix (default: /usr)" + @echo " DESTDIR - Destination directory for install" diff --git a/tools/platform/x86/amd/test-pmf.c b/tools/platform/x86/amd/test-pmf.c new file mode 100644 index 000000000000..82978afa6e1b --- /dev/null +++ b/tools/platform/x86/amd/test-pmf.c @@ -0,0 +1,142 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * AMD Platform Management Framework Test Tool + * + * Copyright (c) 2026, Advanced Micro Devices, Inc. + * All Rights Reserved. + * + * Authors: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> + * Sanket Goswami <Sanket.Goswami@amd.com> + */ + +#include <errno.h> +#include <fcntl.h> +#include <inttypes.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> +#include <sys/ioctl.h> +#include <unistd.h> + +#include <linux/amd-pmf.h> +#include <linux/kernel.h> + +#define DEVICE_NODE "/dev/amdpmf_interface" + +/* Feature flag names */ +static const char * const feature_names[] = { + "Auto Mode", + "Static Power Slider", + "Policy Builder (Smart PC)", + "Dynamic Power Slider AC", + "Dynamic Power Slider DC", +}; + +static const char *banner = + "====================================================\n" + " AMD PMF Metrics info and Feature Status\n" + "====================================================\n\n"; + +/* Print feature flags */ +static void pmf_print_features(uint32_t flags) +{ + size_t i; + + for (i = 0; i < ARRAY_SIZE(feature_names); i++) + printf(" [%c] %s\n", (flags & (1U << i)) ? 'x' : ' ', feature_names[i]); +} + +/* Print BIOS parameters */ +static void pmf_print_bios_params(const char *type, const __u32 *params) +{ + int i; + + for (i = 0; i < AMD_PMF_BIOS_PARAMS_MAX; i++) + printf(" Custom BIOS %s%d: %u\n", type, i + 1, params[i]); +} + +/* Open the PMF device */ +static int pmf_open_device(void) +{ + int fd; + + fd = open(DEVICE_NODE, O_RDONLY); + if (fd < 0) + fprintf(stderr, "Error: Cannot open %s: %s\n", DEVICE_NODE, strerror(errno)); + + return fd; +} + +/* Query PMF info using the single IOCTL */ +static int pmf_get_info(int fd, struct amd_pmf_info *info) +{ + int ret; + + /* Zero-initialize and set size for versioning */ + memset(info, 0, sizeof(*info)); + info->size = sizeof(*info); + + ret = ioctl(fd, IOCTL_AMD_PMF_POPULATE_DATA, info); + if (ret < 0) { + fprintf(stderr, "Error: IOCTL_AMD_PMF_POPULATE_DATA failed: %s\n", strerror(errno)); + return ret; + } + + return 0; +} + +static void pmf_print_info(const struct amd_pmf_info *info) +{ + printf("%s", banner); + + /* Feature status */ + printf("Feature Status:\n"); + pmf_print_features(info->features_supported); + + /* Device states */ + printf("\nDevice States:\n"); + printf(" Platform Type: %s\n", amd_pmf_get_platform_type(info->platform_type)); + printf(" Laptop Placement: %s\n", amd_pmf_get_laptop_placement(info->laptop_placement)); + printf(" Lid State: %s\n", info->lid_state ? "Closed" : "Open"); + printf(" User Presence: %s\n", info->user_presence ? "Present" : "Away"); + printf(" Slider Position: %s\n", amd_pmf_get_slider_position(info->slider_position)); + + /* Thermal and power metrics */ + printf("\nThermal/Power Metrics:\n"); + printf(" Skin Temperature: %d\n", info->skin_temp / 100); + printf(" GFX Busy: %u\n", info->gfx_busy); + printf(" Ambient Light: %d\n", info->ambient_light); + printf(" Avg C0 Residency: %u\n", info->avg_c0_residency); + printf(" Max C0 Residency: %u\n", info->max_c0_residency); + printf(" Socket Power: %u\n", info->socket_power); + + /* BIOS parameters */ + printf("\nCustom BIOS Input Parameters:\n"); + pmf_print_bios_params("Input", info->bios_input); + printf("\nCustom BIOS Output Parameters:\n"); + pmf_print_bios_params("Output", info->bios_output); + + printf("\n=================================================\n"); +} + +int main(void) +{ + struct amd_pmf_info info; + int fd, ret; + + fd = pmf_open_device(); + if (fd < 0) + return -1; + + /* Query all info with single IOCTL */ + ret = pmf_get_info(fd, &info); + close(fd); + + if (ret < 0) + return -1; + + pmf_print_info(&info); + + return 0; +} |
