[PATCH v7 1/5] platform/x86/amd/hsmp: Add HSMP messages for Family 1Ah, Model 50h-5Fh
Muralidhara M K <[email protected]> Mon, 27 Jul 2026 19:45:38 +0530
| Newsgroups | org.kernel.vger.platform-driver-x86,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
Family 1Ah Model 50h-5Fh firmware exposes new HSMP messages (0x29-0x2A, 0x33-0x3A) for PC6/CC6 control, CCD power/thermal monitoring, DIMM sideband access, floor- and SDPS-limit control, and command-enable discovery. The same firmware extends three existing SET-only messages (HSMP_SET_XGMI_LINK_WIDTH 0x0C, HSMP_SET_DF_PSTATE 0x0D, HSMP_SET_PSTATE_MAX_MIN 0x22) with a read-back path selected by bit[31] of args[0] (0 = set, 1 = get). Add the new IDs and convert the three messages to HSMP_SET_GET. Also add PQoS-related HSMP messages HSMP_PQOS_TRAFFIC_PRIORITY (0x3B) and HSMP_PQOS_FLOATING_BW (0x3C) with matching hsmp_msg_desc_table[] descriptors so userspace can reach the new functionality. Backward compatibility is preserved on prior platforms: new IDs previously occupied HSMP_RSVD slots, and existing userspace that leaves bit[31] = 0 continues to take a pure SET path. Converting the three SET messages to HSMP_SET_GET also keeps them accepted by validate_message(), which already applies a relaxed upper-bound check on response_sz for that type. Co-developed-by: Muthusamy Ramalingam <[email protected]> Signed-off-by: Muthusamy Ramalingam <[email protected]> Signed-off-by: Muralidhara M K <[email protected]> --- arch/x86/include/uapi/asm/amd_hsmp.h | 172 ++++++++++++++++++++++++--- 1 file changed, 158 insertions(+), 14 deletions(-) diff --git a/arch/x86/include/uapi/asm/amd_hsmp.h b/arch/x86/include/uapi/asm/amd_hsmp.h index 92d8f256d096..eff35c3c6ce0 100644 --- a/arch/x86/include/uapi/asm/amd_hsmp.h +++ b/arch/x86/include/uapi/asm/amd_hsmp.h @@ -53,9 +53,21 @@ enum hsmp_message_ids { HSMP_SET_XGMI_PSTATE_RANGE, /* 26h Set xGMI P-state range */ HSMP_CPU_RAIL_ISO_FREQ_POLICY, /* 27h Get/Set Cpu Iso frequency policy */ HSMP_DFC_ENABLE_CTRL, /* 28h Enable/Disable DF C-state */ + HSMP_PC6_ENABLE, /* 29h Get/Set PC6 enable/disable status */ + HSMP_CC6_ENABLE, /* 2Ah Get/Set CC6 enable/disable status */ HSMP_GET_RAPL_UNITS = 0x30, /* 30h Get scaling factor for energy */ HSMP_GET_RAPL_CORE_COUNTER, /* 31h Get core energy counter value */ HSMP_GET_RAPL_PACKAGE_COUNTER, /* 32h Get package energy counter value */ + HSMP_DIMM_SB_RD, /* 33h Get DIMM sideband data */ + HSMP_READ_CCD_POWER, /* 34h Get average CCD power */ + HSMP_READ_TDELTA, /* 35h Get thermal behaviour */ + HSMP_GET_SVI3_VR_CTRL_TEMP, /* 36h Get SVI3 VR controller rail temp */ + HSMP_GET_ENABLED_HSMP_CMDS, /* 37h Get supported HSMP commands */ + HSMP_SET_GET_FLOOR_LIMIT, /* 38h Get/Set core floor frequency limit */ + HSMP_DIMM_SB_WR, /* 39h Set DIMM sideband data */ + HSMP_SDPS_LIMIT, /* 3Ah Get/Set SDPS limit */ + HSMP_PQOS_TRAFFIC_PRIORITY, /* 3Bh Get/Set traffic priority */ + HSMP_PQOS_FLOATING_BW, /* 3Ch Get/Set max floating bandwidth */ HSMP_MSG_ID_MAX, }; @@ -170,16 +182,27 @@ static const struct hsmp_msg_desc hsmp_msg_desc_table[] {0, 1, HSMP_GET}, /* - * HSMP_SET_XGMI_LINK_WIDTH, num_args = 1, response_sz = 0 - * input: args[0] = min link width[15:8] + max link width[7:0] + * HSMP_SET_XGMI_LINK_WIDTH, num_args = 1, response_sz = 0/1 + * input: args[0] = set/get XGMI Link width[31] (0 = set, 1 = get) + + * min link width[15:8] + max link width[7:0] + * Link width encoding: 0 = x4, 1 = x8, 2 = x16. + * On SET, max must be >= min. On GET, [15:0] are reserved. + * output: args[0] = reserved[31:16] + min link width[15:8] + + * max link width[7:0] */ - {1, 0, HSMP_SET}, + {1, 1, HSMP_SET_GET}, /* - * HSMP_SET_DF_PSTATE, num_args = 1, response_sz = 0 - * input: args[0] = df pstate[7:0] + * HSMP_SET_DF_PSTATE (APBDisable), num_args = 1, response_sz = 0/1 + * input: args[0] = set APB_DISABLE / get APB state[31] + * (0 = set & lock DF P-state, 1 = get) + + * reserved[30:8] + + * DF P-state[7:0] (0..2; reserved on GET) + * output: args[0] = reserved[31:9] + + * APB state[8] (1 = disabled, 0 = enabled) + + * locked DF P-state[7:0] if [8] = 1, else reserved */ - {1, 0, HSMP_SET}, + {1, 1, HSMP_SET_GET}, /* HSMP_SET_AUTO_DF_PSTATE, num_args = 0, response_sz = 0 */ {0, 0, HSMP_SET}, @@ -305,16 +328,32 @@ static const struct hsmp_msg_desc hsmp_msg_desc_table[] {1, 1, HSMP_SET}, /* - * HSMP_SET_POWER_MODE, num_args = 1, response_sz = 0 - * input: args[0] = power efficiency mode[2:0] + * HSMP_SET_POWER_MODE (PwrEfficiencyModeSelection), + * num_args = 1, response_sz = 1 + * input: args[0] = set/get policy[31] (0 = set, 1 = get) + + * high util point[30:24] + + * low util point[23:17] + + * PPT limit[16:5] + + * reserved[4:3] + mode selection[2:0] + * [30:5] are valid only when [2:0] is a balanced core mode + * (4 or 5). [2:0] is reserved when getting (bit[31] = 1). + * output: args[0] same layout, [31] reserved, [2:0] = arbitrated + * current efficiency mode. */ {1, 1, HSMP_SET_GET}, /* - * HSMP_SET_PSTATE_MAX_MIN, num_args = 1, response_sz = 0 - * input: args[0] = min df pstate[15:8] + max df pstate[7:0] + * HSMP_SET_PSTATE_MAX_MIN (DfPstateRange), num_args = 1, response_sz = 0/1 + * input: args[0] = set/get DF P-state range[31] (0 = set, 1 = get) + + * reserved[30:16] + + * min DF P-state[15:8] + max DF P-state[7:0] + * DF P-state encoding: 0 = DFP0 (high performance), + * 1 = DFP1, 2 = DFP2 (low performance). + * [15:0] are reserved when getting (args[0] bit[31] = 1). + * output: args[0] = reserved[31:16] + min DF P-state[15:8] + + * max DF P-state[7:0] */ - {1, 0, HSMP_SET}, + {1, 1, HSMP_SET_GET}, /* * HSMP_GET_METRIC_TABLE_VER, num_args = 0, response_sz = 1 @@ -355,9 +394,31 @@ static const struct hsmp_msg_desc hsmp_msg_desc_table[] */ {1, 1, HSMP_SET_GET}, - /* RESERVED(0x29-0x2f) */ - {0, 0, HSMP_RSVD}, - {0, 0, HSMP_RSVD}, + /* + * HSMP_PC6_ENABLE (Pc6Enable), num_args = 1, response_sz = 0/1 + * input: args[0] = set/get PC6 control[31] (0 = set, 1 = get) + + * reserved[30:1] + + * enable PC6[0] (0 = disable, 1 = enable; + * reserved on GET) + * output: args[0] = reserved[31:1] + current PC6 control[0] + * (last value configured via HSMP or APML) + */ + {1, 1, HSMP_SET_GET}, + + /* + * HSMP_CC6_ENABLE (CC6Enable), num_args = 1, response_sz = 0/1 + * Configures CC6 enable for all cores; changing the setting does + * not by itself transition cores in or out of CC6. + * input: args[0] = set/get CC6 control[31] (0 = set, 1 = get) + + * reserved[30:1] + + * enable CC6[0] (0 = disable, 1 = enable; + * reserved on GET) + * output: args[0] = reserved[31:1] + current CC6 control[0] + * (last value configured via HSMP or APML) + */ + {1, 1, HSMP_SET_GET}, + + /* RESERVED(0x2B-0x2F) */ {0, 0, HSMP_RSVD}, {0, 0, HSMP_RSVD}, {0, 0, HSMP_RSVD}, @@ -385,6 +446,89 @@ static const struct hsmp_msg_desc hsmp_msg_desc_table[] */ {0, 2, HSMP_GET}, + /* + * HSMP_DIMM_SB_RD, num_args = 1, response_sz = 1 + * input: args[0] = reg space[23] + reg offset[22:12] + + * device LID[11:8] + DIMM address[7:0] + * output: args[0] = read data byte[3:0] + */ + {1, 1, HSMP_GET}, + + /* + * HSMP_READ_CCD_POWER, num_args = 1, response_sz = 1 + * input: args[0] = apic id of core[15:0] + * output: args[0] = CCD power(mWatts)[31:0] + */ + {1, 1, HSMP_GET}, + + /* + * HSMP_READ_TDELTA, num_args = 0, response_sz = 1 + * output: args[0] = thermal behaviour[31:0] + */ + {0, 1, HSMP_GET}, + + /* + * HSMP_GET_SVI3_VR_CTRL_TEMP, num_args = 1, response_sz = 1 + * input: args[0] = SVI3 rail index[3:1] + read temperature[0] + * output: args[0] = SVI3 rail index[30:28] + + * rail temperature in degree C[27:0] + */ + {1, 1, HSMP_GET}, + + /* + * HSMP_GET_ENABLED_HSMP_CMDS, num_args = 1, response_sz = 3 + * input: args[0] = HSMP command mask[0] + * output: status of HSMP command = args[0], args[1], args[2] + */ + {1, 3, HSMP_GET}, + + /* + * HSMP_SET_GET_FLOOR_LIMIT, num_args = 1, response_sz = 1 + * input: args[0] = op[31:30] + reserved[29:28] + + * apic id[27:16] + floor frequency MHz[15:0] + * op encoding: 00 = set per-core floor, + * 01 = set all-cores floor (apic id reserved), + * 10 = get per-core floor, + * 11 = get per-core effective floor. + * Floor frequency field is reserved on GET (bit[31] = 1). + * output: args[0] = floor frequency MHz[15:0] + * (effective for op 11, configured for op 10; + * reserved on SET) + */ + {1, 1, HSMP_SET_GET}, + + /* + * HSMP_DIMM_SB_WR, num_args = 1, response_sz = 0 + * input: args[0] = write data[31:24] + reg space[23] + + * reg offset[22:12] + device LID[11:8] + + * DIMM address[7:0] + */ + {1, 0, HSMP_SET}, + + /* + * HSMP_SDPS_LIMIT, num_args = 1, response_sz = 1 + * input: args[0] = set/get SDPS limit[31] (0 = set, 1 = get) + + * SDPS limit[30:0] + * output: args[0] = SDPS limit[30:0] + */ + {1, 1, HSMP_SET_GET}, + + /* + * HSMP_PQOS_TRAFFIC_PRIORITY, num_args = 1, response_sz = 1 + * input: args[0] = op[31:30] + priority sel[27:26] + + * priority val[21:20] + input[19:0] + * output: args[0] = supported priorities or priority val[1:0] + */ + {1, 1, HSMP_SET_GET}, + + /* + * HSMP_PQOS_FLOATING_BW, num_args = 1, response_sz = 2 + * input: args[0] = op[31] + sub-op[30:29] + params[28:0] + * output: args[0] = discovery bits or floating/global memory BW (Gbps) + * output: args[1] = reserved or config (drop adj, sampling delay, + * hysteresis) + */ + {1, 2, HSMP_SET_GET}, }; /* Metrics table (supported only with proto version 6) */ -- 2.34.1