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

Configure Feed

Select the types of activity you want to include in your feed.

misc: amd-sbi: Extend support for CPUID protocol for rev 0x21

- CPUID protocol for revision 0x21 is updated to include the
extended thread supported by the platform.
- This modifies the existing protocol to include additional byte
to provide high thread number.
- New input structure is defined to address this, as the hardware
protocol is tightly coupled with the input structure length

Reviewed-by: Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
Signed-off-by: Akshay Gupta <akshay.gupta@amd.com>
Link: https://patch.msgid.link/20250915103649.1705078-5-akshay.gupta@amd.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Akshay Gupta and committed by
Greg Kroah-Hartman
87816eb4 dd68c063

+86 -24
+86 -24
drivers/misc/amd-sbi/rmi-core.c
··· 28 28 /* CPUID */ 29 29 #define CPUID_RD_DATA_LEN 0x8 30 30 #define CPUID_WR_DATA_LEN 0x8 31 + #define CPUID_WR_DATA_LEN_EXT 0x9 31 32 #define CPUID_RD_REG_LEN 0xa 32 33 #define CPUID_WR_REG_LEN 0x9 34 + #define CPUID_WR_REG_LEN_EXT 0xa 33 35 /* MSR */ 34 36 #define MSR_RD_REG_LEN 0xa 35 37 #define MSR_WR_REG_LEN 0x8 ··· 61 59 u8 ext; /* extended function */ 62 60 }; 63 61 62 + /* input for bulk write to CPUID protocol for REV 0x21 */ 63 + struct cpu_msr_indata_ext { 64 + u8 wr_len; /* const value */ 65 + u8 rd_len; /* const value */ 66 + u8 proto_cmd; /* const value */ 67 + u8 thread_lo; /* thread number low */ 68 + u8 thread_hi; /* thread number high */ 69 + union { 70 + u8 reg_offset[4]; /* input value */ 71 + u32 value; 72 + } __packed; 73 + u8 ext; /* extended function */ 74 + }; 75 + 64 76 /* output for bulk read from CPUID protocol */ 65 77 struct cpu_msr_outdata { 66 78 u8 num_bytes; /* number of bytes return */ ··· 93 77 input->wr_len = CPUID_WR_DATA_LEN; 94 78 input->proto_cmd = RD_CPUID_CMD; 95 79 input->thread = thread_id << 1; 80 + input->value = func; 81 + input->ext = ext_func; 82 + } 83 + 84 + static inline void prepare_cpuid_input_message_ext(struct cpu_msr_indata_ext *input, 85 + u16 thread_id, u32 func, 86 + u8 ext_func) 87 + { 88 + input->rd_len = CPUID_RD_DATA_LEN; 89 + input->wr_len = CPUID_WR_DATA_LEN_EXT; 90 + input->proto_cmd = RD_CPUID_CMD; 91 + input->thread_lo = (thread_id & 0xFF) << 1; 92 + input->thread_hi = thread_id >> 8; 96 93 input->value = func; 97 94 input->ext = ext_func; 98 95 } ··· 134 105 return 0; 135 106 } 136 107 108 + static int rmi_cpuid_input(struct sbrmi_data *data, struct apml_cpuid_msg *msg, 109 + u16 thread) 110 + { 111 + struct cpu_msr_indata input = {0}; 112 + int val = 0, ret; 113 + 114 + /* Thread > 127, Thread128 CS register, 1'b1 needs to be set to 1 */ 115 + if (thread > 127) { 116 + thread -= 128; 117 + val = 1; 118 + } 119 + 120 + ret = regmap_write(data->regmap, SBRMI_THREAD128CS, val); 121 + if (ret < 0) 122 + return ret; 123 + 124 + prepare_cpuid_input_message(&input, thread, 125 + msg->cpu_in_out & CPUID_MCA_FUNC_MASK, 126 + msg->cpu_in_out >> CPUID_EXT_FUNC_INDEX); 127 + 128 + return regmap_bulk_write(data->regmap, CPUID_MCA_CMD, 129 + &input, CPUID_WR_REG_LEN); 130 + } 131 + 132 + static int rmi_cpuid_input_ext(struct sbrmi_data *data, struct apml_cpuid_msg *msg, 133 + u16 thread) 134 + { 135 + struct cpu_msr_indata_ext input = {0}; 136 + 137 + prepare_cpuid_input_message_ext(&input, thread, 138 + msg->cpu_in_out & CPUID_MCA_FUNC_MASK, 139 + msg->cpu_in_out >> CPUID_EXT_FUNC_INDEX); 140 + 141 + return regmap_bulk_write(data->regmap, CPUID_MCA_CMD, 142 + &input, CPUID_WR_REG_LEN_EXT); 143 + } 144 + 137 145 /* Read CPUID function protocol */ 138 146 static int rmi_cpuid_read(struct sbrmi_data *data, 139 147 struct apml_cpuid_msg *msg) 140 148 { 141 - struct cpu_msr_indata input = {0}; 142 149 struct cpu_msr_outdata output = {0}; 143 - int val = 0; 144 150 int ret, hw_status; 145 151 u16 thread; 146 152 ··· 186 122 if (ret < 0) 187 123 goto exit_unlock; 188 124 } 189 - /* CPUID protocol for REV 0x20 is only supported*/ 190 - if (data->rev != 0x20) { 125 + 126 + /* Extract thread from the input msg structure */ 127 + thread = msg->cpu_in_out >> CPUID_MCA_THRD_INDEX; 128 + 129 + switch (data->rev) { 130 + case 0x10: 131 + /* CPUID protocol for REV 0x10 is not supported*/ 132 + ret = -EOPNOTSUPP; 133 + goto exit_unlock; 134 + case 0x20: 135 + ret = rmi_cpuid_input(data, msg, thread); 136 + if (ret) 137 + goto exit_unlock; 138 + break; 139 + case 0x21: 140 + ret = rmi_cpuid_input_ext(data, msg, thread); 141 + if (ret) 142 + goto exit_unlock; 143 + break; 144 + default: 191 145 ret = -EOPNOTSUPP; 192 146 goto exit_unlock; 193 147 } 194 - 195 - thread = msg->cpu_in_out >> CPUID_MCA_THRD_INDEX; 196 - 197 - /* Thread > 127, Thread128 CS register, 1'b1 needs to be set to 1 */ 198 - if (thread > 127) { 199 - thread -= 128; 200 - val = 1; 201 - } 202 - ret = regmap_write(data->regmap, SBRMI_THREAD128CS, val); 203 - if (ret < 0) 204 - goto exit_unlock; 205 - 206 - prepare_cpuid_input_message(&input, thread, 207 - msg->cpu_in_out & CPUID_MCA_FUNC_MASK, 208 - msg->cpu_in_out >> CPUID_EXT_FUNC_INDEX); 209 - 210 - ret = regmap_bulk_write(data->regmap, CPUID_MCA_CMD, 211 - &input, CPUID_WR_REG_LEN); 212 - if (ret < 0) 213 - goto exit_unlock; 214 148 215 149 /* 216 150 * For RMI Rev 0x20, new h/w status bit is introduced. which is used