| 1 | /* SPDX-License-Identifier: GPL-2.0-or-later WITH Linux-syscall-note */ |
| 2 | /* |
| 3 | * AMD Platform Management Framework (PMF) UAPI Header |
| 4 | * |
| 5 | * Copyright (c) 2026, Advanced Micro Devices, Inc. |
| 6 | * All Rights Reserved. |
| 7 | * |
| 8 | * This file defines the user-space API for interacting with the AMD PMF |
| 9 | * driver. It provides ioctl interfaces to query platform-specific metrics |
| 10 | * such as power source, slider position, platform type, laptop placement, |
| 11 | * and various BIOS input/output parameters. |
| 12 | */ |
| 13 | |
| 14 | #ifndef _LINUX_AMD_PMF_H |
| 15 | #define _LINUX_AMD_PMF_H |
| 16 | |
| 17 | #include <linux/bits.h> |
| 18 | #include <linux/ioctl.h> |
| 19 | #include <linux/types.h> |
| 20 | |
| 21 | /** |
| 22 | * AMD_PMF_IOC_MAGIC - Magic number for AMD PMF ioctl commands |
| 23 | * |
| 24 | * This magic number uniquely identifies AMD PMF ioctl operations. |
| 25 | */ |
| 26 | #define AMD_PMF_IOC_MAGIC	'p' |
| 27 | |
| 28 | /** |
| 29 | * IOCTL_AMD_PMF_POPULATE_DATA - ioctl command to retrieve PMF metrics data |
| 30 | * |
| 31 | * This ioctl command is used to populate the amd_pmf_info structure |
| 32 | * with the requested PMF metrics information. |
| 33 | */ |
| 34 | #define IOCTL_AMD_PMF_POPULATE_DATA		_IOWR(AMD_PMF_IOC_MAGIC, 0x00, __u64) |
| 35 | |
| 36 | #define AMD_PMF_BIOS_PARAMS_MAX		10 |
| 37 | |
| 38 | /* AMD PMF feature flags - bitmask indicating supported features */ |
| 39 | #define AMD_PMF_FEAT_AUTO_MODE			BIT(0) |
| 40 | #define AMD_PMF_FEAT_STATIC_POWER_SLIDER	BIT(1) |
| 41 | #define AMD_PMF_FEAT_POLICY_BUILDER		BIT(2) |
| 42 | #define AMD_PMF_FEAT_DYNAMIC_POWER_SLIDER_AC	BIT(3) |
| 43 | #define AMD_PMF_FEAT_DYNAMIC_POWER_SLIDER_DC	BIT(4) |
| 44 | |
| 45 | /** |
| 46 | * enum amd_pmf_laptop_placement - Describes the physical placement of the laptop |
| 47 | * @AMD_PMF_LP_UNKNOWN: Placement cannot be determined |
| 48 | * @AMD_PMF_ON_TABLE: Laptop is placed on a stable surface like a table or desk |
| 49 | * @AMD_PMF_ON_LAP_MOTION: Laptop is on a lap with detected motion |
| 50 | * @AMD_PMF_IN_BAG: Laptop is detected to be inside a bag or case |
| 51 | * @AMD_PMF_OUT_OF_BAG: Laptop has been removed from bag or case |
| 52 | * @AMD_PMF_LP_UNDEFINED: Placement state is undefined |
| 53 | * |
| 54 | * This enumeration represents the physical placement state of the laptop |
| 55 | * as detected by platform sensors. Used for adaptive power management |
| 56 | * and thermal policies. |
| 57 | */ |
| 58 | enum amd_pmf_laptop_placement { |
| 59 | 	AMD_PMF_LP_UNKNOWN, |
| 60 | 	AMD_PMF_ON_TABLE, |
| 61 | 	AMD_PMF_ON_LAP_MOTION, |
| 62 | 	AMD_PMF_IN_BAG, |
| 63 | 	AMD_PMF_OUT_OF_BAG, |
| 64 | 	AMD_PMF_LP_UNDEFINED, |
| 65 | }; |
| 66 | |
| 67 | /** |
| 68 | * enum amd_pmf_ta_slider - Trusted Application power slider positions |
| 69 | * @AMD_PMF_TA_BEST_BATTERY: Maximum battery savings, minimal performance |
| 70 | * @AMD_PMF_TA_BETTER_BATTERY: Balanced towards battery life |
| 71 | * @AMD_PMF_TA_BETTER_PERFORMANCE: Balanced towards performance |
| 72 | * @AMD_PMF_TA_BEST_PERFORMANCE: Maximum performance, higher power consumption |
| 73 | * @AMD_PMF_TA_MAX: Sentinel value indicating maximum enum value |
| 74 | * |
| 75 | * This enumeration defines the power slider positions used by the |
| 76 | * AMD PMF Trusted Application for dynamic power management decisions. |
| 77 | * These correspond to the Windows power slider UI positions. |
| 78 | */ |
| 79 | enum amd_pmf_ta_slider { |
| 80 | 	AMD_PMF_TA_BEST_BATTERY, |
| 81 | 	AMD_PMF_TA_BETTER_BATTERY, |
| 82 | 	AMD_PMF_TA_BETTER_PERFORMANCE, |
| 83 | 	AMD_PMF_TA_BEST_PERFORMANCE, |
| 84 | 	AMD_PMF_TA_MAX, |
| 85 | }; |
| 86 | |
| 87 | /** |
| 88 | * enum amd_pmf_platform_type - Describes the physical form factor orientation |
| 89 | * @AMD_PMF_PTYPE_UNKNOWN: Platform type cannot be determined |
| 90 | * @AMD_PMF_LID_CLOSE: Laptop lid is closed |
| 91 | * @AMD_PMF_CLAMSHELL: Traditional laptop mode with keyboard and screen |
| 92 | * @AMD_PMF_FLAT: Device is lying flat on a surface |
| 93 | * @AMD_PMF_TENT: Device is in tent mode (keyboard folded back, standing) |
| 94 | * @AMD_PMF_STAND: Device is propped up in stand orientation |
| 95 | * @AMD_PMF_TABLET: Device is in tablet mode with keyboard hidden |
| 96 | * @AMD_PMF_BOOK: Device is in book reading orientation |
| 97 | * @AMD_PMF_PRESENTATION: Device is in presentation mode |
| 98 | * @AMD_PMF_PULL_FWD: Screen is pulled forward towards user |
| 99 | * @AMD_PMF_PTYPE_INVALID: Invalid platform type marker |
| 100 | * |
| 101 | * This enumeration describes the current physical orientation or form |
| 102 | * factor of convertible/2-in-1 devices. Used for optimizing power and |
| 103 | * thermal management based on device posture. |
| 104 | */ |
| 105 | enum amd_pmf_platform_type { |
| 106 | 	AMD_PMF_PTYPE_UNKNOWN, |
| 107 | 	AMD_PMF_LID_CLOSE, |
| 108 | 	AMD_PMF_CLAMSHELL, |
| 109 | 	AMD_PMF_FLAT, |
| 110 | 	AMD_PMF_TENT, |
| 111 | 	AMD_PMF_STAND, |
| 112 | 	AMD_PMF_TABLET, |
| 113 | 	AMD_PMF_BOOK, |
| 114 | 	AMD_PMF_PRESENTATION, |
| 115 | 	AMD_PMF_PULL_FWD, |
| 116 | 	AMD_PMF_PTYPE_INVALID = 0xf, |
| 117 | }; |
| 118 | |
| 119 | static __inline__ const char *amd_pmf_get_platform_type(unsigned int platform_type) |
| 120 | { |
| 121 | 	switch (platform_type) { |
| 122 | 	case AMD_PMF_CLAMSHELL: |
| 123 | 		return "CLAMSHELL"; |
| 124 | 	case AMD_PMF_LID_CLOSE: |
| 125 | 		return "LID_CLOSE"; |
| 126 | 	case AMD_PMF_FLAT: |
| 127 | 		return "FLAT"; |
| 128 | 	case AMD_PMF_TENT: |
| 129 | 		return "TENT"; |
| 130 | 	case AMD_PMF_STAND: |
| 131 | 		return "STAND"; |
| 132 | 	case AMD_PMF_TABLET: |
| 133 | 		return "TABLET"; |
| 134 | 	case AMD_PMF_BOOK: |
| 135 | 		return "BOOK"; |
| 136 | 	case AMD_PMF_PRESENTATION: |
| 137 | 		return "PRESENTATION"; |
| 138 | 	case AMD_PMF_PULL_FWD: |
| 139 | 		return "PULL_FWD"; |
| 140 | 	default: |
| 141 | 		return "UNKNOWN"; |
| 142 | 	} |
| 143 | } |
| 144 | |
| 145 | static __inline__ const char *amd_pmf_get_laptop_placement(unsigned int device_state) |
| 146 | { |
| 147 | 	switch (device_state) { |
| 148 | 	case AMD_PMF_ON_TABLE: |
| 149 | 		return "ON_TABLE"; |
| 150 | 	case AMD_PMF_ON_LAP_MOTION: |
| 151 | 		return "ON_LAP_MOTION"; |
| 152 | 	case AMD_PMF_IN_BAG: |
| 153 | 		return "IN_BAG"; |
| 154 | 	case AMD_PMF_OUT_OF_BAG: |
| 155 | 		return "OUT_OF_BAG"; |
| 156 | 	default: |
| 157 | 		return "UNKNOWN"; |
| 158 | 	} |
| 159 | } |
| 160 | |
| 161 | static __inline__ const char *amd_pmf_get_slider_position(unsigned int state) |
| 162 | { |
| 163 | 	switch (state) { |
| 164 | 	case AMD_PMF_TA_BEST_PERFORMANCE: |
| 165 | 		return "PERFORMANCE"; |
| 166 | 	case AMD_PMF_TA_BETTER_PERFORMANCE: |
| 167 | 		return "BALANCED"; |
| 168 | 	case AMD_PMF_TA_BEST_BATTERY: |
| 169 | 		return "POWER_SAVER"; |
| 170 | 	case AMD_PMF_TA_BETTER_BATTERY: |
| 171 | 		return "BALANCED_BATTERY"; |
| 172 | 	default: |
| 173 | 		return "Unknown TA Slider State"; |
| 174 | 	} |
| 175 | } |
| 176 | |
| 177 | struct amd_pmf_info { |
| 178 | 	__u64 size; |
| 179 | |
| 180 | 	/* Feature info */ |
| 181 | 	__u32 features_supported; |
| 182 | |
| 183 | 	/* Power and state info */ |
| 184 | 	__u32 platform_type; |
| 185 | 	__u32 power_source; |
| 186 | 	__u32 laptop_placement; |
| 187 | 	__u32 lid_state; |
| 188 | 	__u32 user_presence; |
| 189 | 	__u32 slider_position; |
| 190 | |
| 191 | 	/* Thermal and power metrics */ |
| 192 | 	__s32 skin_temp; |
| 193 | 	__u32 gfx_busy; |
| 194 | 	__s32 ambient_light; |
| 195 | 	__u32 avg_c0_residency; |
| 196 | 	__u32 max_c0_residency; |
| 197 | 	__u32 socket_power; |
| 198 | |
| 199 | 	/* BIOS parameters */ |
| 200 | 	__u32 bios_input[AMD_PMF_BIOS_PARAMS_MAX]; |
| 201 | 	__u32 bios_output[AMD_PMF_BIOS_PARAMS_MAX]; |
| 202 | }; |
| 203 | |
| 204 | #endif /* _LINUX_AMD_PMF_H */ |