* [PATCH v2 1/6] misc: amd-sbi: Add helper function to prepare I3C support
@ 2025-09-15 10:36 Akshay Gupta
2025-09-15 10:36 ` [PATCH v2 2/6] misc: amd-sbi: Add support for SB-RMI over I3C Akshay Gupta
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Akshay Gupta @ 2025-09-15 10:36 UTC (permalink / raw)
To: linux-kernel, linux-hwmon
Cc: gregkh, arnd, linux, Anand.Umarji, Akshay Gupta,
Naveen Krishna Chatradhi
New AMD processors support APML connection over I3C.
Move the code, common for both I2C and I3C to new helper
function, "sbrmi_common_probe()"
While at it, renaming the static structure regmap_config "sbrmi_i2c_regmap_config"
to "sbrmi_regmap_config" to avoid confusion.
Reviewed-by: Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
Signed-off-by: Akshay Gupta <akshay.gupta@amd.com>
---
Changes from v1:
- New patch, as per suggestion to use same module for i2c and i3c
- Patch series is applied over "char-misc-next", commit ID: e2258cfd9b9809002ad52f1f763ff192e612a1fe
drivers/misc/amd-sbi/rmi-i2c.c | 32 +++++++++++++++++++++-----------
1 file changed, 21 insertions(+), 11 deletions(-)
diff --git a/drivers/misc/amd-sbi/rmi-i2c.c b/drivers/misc/amd-sbi/rmi-i2c.c
index f891f5af4bc6..d41457a52376 100644
--- a/drivers/misc/amd-sbi/rmi-i2c.c
+++ b/drivers/misc/amd-sbi/rmi-i2c.c
@@ -50,26 +50,18 @@ static int sbrmi_get_max_pwr_limit(struct sbrmi_data *data)
return ret;
}
-static int sbrmi_i2c_probe(struct i2c_client *client)
+static int sbrmi_common_probe(struct device *dev, struct regmap *regmap, uint8_t address)
{
- struct device *dev = &client->dev;
struct sbrmi_data *data;
- struct regmap_config sbrmi_i2c_regmap_config = {
- .reg_bits = 8,
- .val_bits = 8,
- };
int ret;
data = devm_kzalloc(dev, sizeof(struct sbrmi_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
+ data->regmap = regmap;
mutex_init(&data->lock);
- data->regmap = devm_regmap_init_i2c(client, &sbrmi_i2c_regmap_config);
- if (IS_ERR(data->regmap))
- return PTR_ERR(data->regmap);
-
/* Enable alert for SB-RMI sequence */
ret = sbrmi_enable_alert(data);
if (ret < 0)
@@ -80,7 +72,8 @@ static int sbrmi_i2c_probe(struct i2c_client *client)
if (ret < 0)
return ret;
- data->dev_static_addr = client->addr;
+ data->dev_static_addr = address;
+
dev_set_drvdata(dev, data);
ret = create_hwmon_sensor_device(dev, data);
@@ -89,6 +82,23 @@ static int sbrmi_i2c_probe(struct i2c_client *client)
return create_misc_rmi_device(data, dev);
}
+static struct regmap_config sbrmi_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+};
+
+static int sbrmi_i2c_probe(struct i2c_client *client)
+{
+ struct device *dev = &client->dev;
+ struct regmap *regmap;
+
+ regmap = devm_regmap_init_i2c(client, &sbrmi_regmap_config);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
+ return sbrmi_common_probe(dev, regmap, client->addr);
+}
+
static void sbrmi_i2c_remove(struct i2c_client *client)
{
struct sbrmi_data *data = dev_get_drvdata(&client->dev);
--
2.25.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 2/6] misc: amd-sbi: Add support for SB-RMI over I3C
2025-09-15 10:36 [PATCH v2 1/6] misc: amd-sbi: Add helper function to prepare I3C support Akshay Gupta
@ 2025-09-15 10:36 ` Akshay Gupta
2025-09-15 10:36 ` [PATCH v2 3/6] misc: amd-sbi: Add support for Turin platform Akshay Gupta
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Akshay Gupta @ 2025-09-15 10:36 UTC (permalink / raw)
To: linux-kernel, linux-hwmon
Cc: gregkh, arnd, linux, Anand.Umarji, Akshay Gupta,
Naveen Krishna Chatradhi
AMD EPYC platforms with zen5 and later support APML(SB-RMI)
connection to the BMC over I3C bus for faster data transfer
up to 12.5 Mhz.
I2C and I3C is supported in same file using module_i3c_i2c_driver()
with probe based on dts entry.
AMD APML I3C devices support static address for backward compatibility to I2C.
I3C static address can be used to assign I3C device dynamic address.
Reviewed-by: Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
Signed-off-by: Akshay Gupta <akshay.gupta@amd.com>
---
Changes from v1:
- Address reviewer's comment
- Single module file for both i2c and i3c,
hence no change in common function
drivers/misc/amd-sbi/Kconfig | 4 ++-
drivers/misc/amd-sbi/rmi-i2c.c | 45 +++++++++++++++++++++++++++++++++-
2 files changed, 47 insertions(+), 2 deletions(-)
diff --git a/drivers/misc/amd-sbi/Kconfig b/drivers/misc/amd-sbi/Kconfig
index 4aae0733d0fc..acf0450ba220 100644
--- a/drivers/misc/amd-sbi/Kconfig
+++ b/drivers/misc/amd-sbi/Kconfig
@@ -3,8 +3,10 @@ config AMD_SBRMI_I2C
tristate "AMD side band RMI support"
depends on I2C
select REGMAP_I2C
+ depends on I3C || !I3C
+ select REGMAP_I3C if I3C
help
- Side band RMI over I2C support for AMD out of band management.
+ Side band RMI over I2C/I3C support for AMD out of band management.
This driver can also be built as a module. If so, the module will
be called sbrmi-i2c.
diff --git a/drivers/misc/amd-sbi/rmi-i2c.c b/drivers/misc/amd-sbi/rmi-i2c.c
index d41457a52376..087c57bb0f37 100644
--- a/drivers/misc/amd-sbi/rmi-i2c.c
+++ b/drivers/misc/amd-sbi/rmi-i2c.c
@@ -9,6 +9,8 @@
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/i2c.h>
+#include <linux/i3c/device.h>
+#include <linux/i3c/master.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/mutex.h>
@@ -135,7 +137,48 @@ static struct i2c_driver sbrmi_driver = {
.id_table = sbrmi_id,
};
-module_i2c_driver(sbrmi_driver);
+static int sbrmi_i3c_probe(struct i3c_device *i3cdev)
+{
+ struct device *dev = i3cdev_to_dev(i3cdev);
+ struct regmap *regmap;
+
+ regmap = devm_regmap_init_i3c(i3cdev, &sbrmi_regmap_config);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
+ /*
+ * AMD APML I3C devices support static address.
+ * If static address is defined, dynamic address is same as static address.
+ * In case static address is not defined, I3C master controller defined
+ * dynamic address is used.
+ */
+ return sbrmi_common_probe(dev, regmap, i3cdev->desc->info.dyn_addr);
+}
+
+static void sbrmi_i3c_remove(struct i3c_device *i3cdev)
+{
+ struct sbrmi_data *data = dev_get_drvdata(&i3cdev->dev);
+
+ misc_deregister(&data->sbrmi_misc_dev);
+}
+
+static const struct i3c_device_id sbrmi_i3c_id[] = {
+ /* PID for AMD SBRMI device */
+ I3C_DEVICE_EXTRA_INFO(0x112, 0x0, 0x2, NULL),
+ {}
+};
+MODULE_DEVICE_TABLE(i3c, sbrmi_i3c_id);
+
+static struct i3c_driver sbrmi_i3c_driver = {
+ .driver = {
+ .name = "sbrmi-i3c",
+ },
+ .probe = sbrmi_i3c_probe,
+ .remove = sbrmi_i3c_remove,
+ .id_table = sbrmi_i3c_id,
+};
+
+module_i3c_i2c_driver(sbrmi_i3c_driver, &sbrmi_driver);
MODULE_AUTHOR("Akshay Gupta <akshay.gupta@amd.com>");
MODULE_AUTHOR("Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>");
--
2.25.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 3/6] misc: amd-sbi: Add support for Turin platform
2025-09-15 10:36 [PATCH v2 1/6] misc: amd-sbi: Add helper function to prepare I3C support Akshay Gupta
2025-09-15 10:36 ` [PATCH v2 2/6] misc: amd-sbi: Add support for SB-RMI over I3C Akshay Gupta
@ 2025-09-15 10:36 ` Akshay Gupta
2025-09-15 10:36 ` [PATCH v2 4/6] misc: amd-sbi: CPUID/MCAMSR protocol for Revision 0x21 Akshay Gupta
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Akshay Gupta @ 2025-09-15 10:36 UTC (permalink / raw)
To: linux-kernel, linux-hwmon
Cc: gregkh, arnd, linux, Anand.Umarji, Akshay Gupta,
Naveen Krishna Chatradhi
- RMI registers addresses in AMD new platforms are 2 bytes,
on previous processors the address size is 1 byte.
- Implement logic to identify register address size at runtime.
- The identification is done in first transaction using the
Revision register.
- The revision register can be read using 1 byte in both, older and
newer platforms.
- However, sending 1 byte on later platform can cause unrecoverable error.
Reviewed-by: Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
Signed-off-by: Akshay Gupta <akshay.gupta@amd.com>
---
Changes since v1:
- New patch
drivers/misc/amd-sbi/rmi-i2c.c | 47 ++++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/drivers/misc/amd-sbi/rmi-i2c.c b/drivers/misc/amd-sbi/rmi-i2c.c
index 087c57bb0f37..f0cc99000b69 100644
--- a/drivers/misc/amd-sbi/rmi-i2c.c
+++ b/drivers/misc/amd-sbi/rmi-i2c.c
@@ -18,6 +18,8 @@
#include <linux/regmap.h>
#include "rmi-core.h"
+#define REV_TWO_BYTE_ADDR 0x21
+
static int sbrmi_enable_alert(struct sbrmi_data *data)
{
int ctrl, ret;
@@ -89,15 +91,40 @@ static struct regmap_config sbrmi_regmap_config = {
.val_bits = 8,
};
+static struct regmap_config sbrmi_regmap_config_ext = {
+ .reg_bits = 16,
+ .val_bits = 8,
+ .reg_format_endian = REGMAP_ENDIAN_LITTLE,
+};
+
static int sbrmi_i2c_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct regmap *regmap;
+ int rev, ret;
regmap = devm_regmap_init_i2c(client, &sbrmi_regmap_config);
if (IS_ERR(regmap))
return PTR_ERR(regmap);
+ ret = regmap_read(regmap, SBRMI_REV, &rev);
+ if (ret)
+ return ret;
+
+ /*
+ * For Turin and newer platforms, revision is 0x21 or later. This is
+ * to identify the two byte register address size. However, one
+ * byte transaction can be successful.
+ * Verify if revision is 0x21 or later, if yes, switch to 2 byte
+ * address size.
+ * Continuously using 1 byte address for revision 0x21 or later can lead
+ * to bus corruption.
+ */
+ if (rev >= REV_TWO_BYTE_ADDR) {
+ regmap = devm_regmap_init_i2c(client, &sbrmi_regmap_config_ext);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+ }
return sbrmi_common_probe(dev, regmap, client->addr);
}
@@ -141,11 +168,31 @@ static int sbrmi_i3c_probe(struct i3c_device *i3cdev)
{
struct device *dev = i3cdev_to_dev(i3cdev);
struct regmap *regmap;
+ int rev, ret;
regmap = devm_regmap_init_i3c(i3cdev, &sbrmi_regmap_config);
if (IS_ERR(regmap))
return PTR_ERR(regmap);
+ ret = regmap_read(regmap, SBRMI_REV, &rev);
+ if (ret)
+ return ret;
+
+ /*
+ * For Turin and newer platforms, revision is 0x21 or later. This is
+ * to identify the two byte register address size. However, one
+ * byte transaction can be successful.
+ * Verify if revision is 0x21 or later, if yes, switch to 2 byte
+ * address size.
+ * Continuously using 1 byte address for revision 0x21 or later can lead
+ * to bus corruption.
+ */
+ if (rev >= REV_TWO_BYTE_ADDR) {
+ regmap = devm_regmap_init_i3c(i3cdev, &sbrmi_regmap_config_ext);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+ }
+
/*
* AMD APML I3C devices support static address.
* If static address is defined, dynamic address is same as static address.
--
2.25.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 4/6] misc: amd-sbi: CPUID/MCAMSR protocol for Revision 0x21
2025-09-15 10:36 [PATCH v2 1/6] misc: amd-sbi: Add helper function to prepare I3C support Akshay Gupta
2025-09-15 10:36 ` [PATCH v2 2/6] misc: amd-sbi: Add support for SB-RMI over I3C Akshay Gupta
2025-09-15 10:36 ` [PATCH v2 3/6] misc: amd-sbi: Add support for Turin platform Akshay Gupta
@ 2025-09-15 10:36 ` Akshay Gupta
2025-09-15 10:36 ` [PATCH v2 5/6] misc: amd-sbi: Extend support for CPUID protocol for rev 0x21 Akshay Gupta
2025-09-15 10:36 ` [PATCH v2 6/6] misc: amd-sbi: Extend support for MCAMSR " Akshay Gupta
4 siblings, 0 replies; 6+ messages in thread
From: Akshay Gupta @ 2025-09-15 10:36 UTC (permalink / raw)
To: linux-kernel, linux-hwmon
Cc: gregkh, arnd, linux, Anand.Umarji, Akshay Gupta,
Naveen Krishna Chatradhi
- CPUID and MCAMSR protocol for newer platform with revision
0x21 and later is modified as per two byte register address size.
- Modify the CPUID and MCAMSR protocol to return error, "-EOPNOTSUPP",
for revision 0x21.
- Next set of patches will add support for CPUID and MCAMSR for Turin and
later platforms.
Reviewed-by: Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
Signed-off-by: Akshay Gupta <akshay.gupta@amd.com>
---
Changes since v1:
- New patch
drivers/misc/amd-sbi/rmi-core.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/misc/amd-sbi/rmi-core.c b/drivers/misc/amd-sbi/rmi-core.c
index 3dec2fc00124..bf534ba757db 100644
--- a/drivers/misc/amd-sbi/rmi-core.c
+++ b/drivers/misc/amd-sbi/rmi-core.c
@@ -122,8 +122,8 @@ static int rmi_cpuid_read(struct sbrmi_data *data,
if (ret < 0)
goto exit_unlock;
}
- /* CPUID protocol for REV 0x10 is not supported*/
- if (data->rev == 0x10) {
+ /* CPUID protocol for REV 0x20 is only supported*/
+ if (data->rev != 0x20) {
ret = -EOPNOTSUPP;
goto exit_unlock;
}
@@ -203,8 +203,8 @@ static int rmi_mca_msr_read(struct sbrmi_data *data,
if (ret < 0)
goto exit_unlock;
}
- /* MCA MSR protocol for REV 0x10 is not supported*/
- if (data->rev == 0x10) {
+ /* MCA MSR protocol for REV 0x20 is supported*/
+ if (data->rev != 0x20) {
ret = -EOPNOTSUPP;
goto exit_unlock;
}
--
2.25.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 5/6] misc: amd-sbi: Extend support for CPUID protocol for rev 0x21
2025-09-15 10:36 [PATCH v2 1/6] misc: amd-sbi: Add helper function to prepare I3C support Akshay Gupta
` (2 preceding siblings ...)
2025-09-15 10:36 ` [PATCH v2 4/6] misc: amd-sbi: CPUID/MCAMSR protocol for Revision 0x21 Akshay Gupta
@ 2025-09-15 10:36 ` Akshay Gupta
2025-09-15 10:36 ` [PATCH v2 6/6] misc: amd-sbi: Extend support for MCAMSR " Akshay Gupta
4 siblings, 0 replies; 6+ messages in thread
From: Akshay Gupta @ 2025-09-15 10:36 UTC (permalink / raw)
To: linux-kernel, linux-hwmon
Cc: gregkh, arnd, linux, Anand.Umarji, Akshay Gupta,
Naveen Krishna Chatradhi
- 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>
---
Changes since v1:
- New patch
drivers/misc/amd-sbi/rmi-core.c | 106 +++++++++++++++++++++++++-------
1 file changed, 84 insertions(+), 22 deletions(-)
diff --git a/drivers/misc/amd-sbi/rmi-core.c b/drivers/misc/amd-sbi/rmi-core.c
index bf534ba757db..ef93dce7e038 100644
--- a/drivers/misc/amd-sbi/rmi-core.c
+++ b/drivers/misc/amd-sbi/rmi-core.c
@@ -28,8 +28,10 @@
/* CPUID */
#define CPUID_RD_DATA_LEN 0x8
#define CPUID_WR_DATA_LEN 0x8
+#define CPUID_WR_DATA_LEN_EXT 0x9
#define CPUID_RD_REG_LEN 0xa
#define CPUID_WR_REG_LEN 0x9
+#define CPUID_WR_REG_LEN_EXT 0xa
/* MSR */
#define MSR_RD_REG_LEN 0xa
#define MSR_WR_REG_LEN 0x8
@@ -59,6 +61,20 @@ struct cpu_msr_indata {
u8 ext; /* extended function */
};
+/* input for bulk write to CPUID protocol for REV 0x21 */
+struct cpu_msr_indata_ext {
+ u8 wr_len; /* const value */
+ u8 rd_len; /* const value */
+ u8 proto_cmd; /* const value */
+ u8 thread_lo; /* thread number low */
+ u8 thread_hi; /* thread number high */
+ union {
+ u8 reg_offset[4]; /* input value */
+ u32 value;
+ } __packed;
+ u8 ext; /* extended function */
+};
+
/* output for bulk read from CPUID protocol */
struct cpu_msr_outdata {
u8 num_bytes; /* number of bytes return */
@@ -81,6 +97,19 @@ static inline void prepare_cpuid_input_message(struct cpu_msr_indata *input,
input->ext = ext_func;
}
+static inline void prepare_cpuid_input_message_ext(struct cpu_msr_indata_ext *input,
+ u16 thread_id, u32 func,
+ u8 ext_func)
+{
+ input->rd_len = CPUID_RD_DATA_LEN;
+ input->wr_len = CPUID_WR_DATA_LEN_EXT;
+ input->proto_cmd = RD_CPUID_CMD;
+ input->thread_lo = (thread_id & 0xFF) << 1;
+ input->thread_hi = thread_id >> 8;
+ input->value = func;
+ input->ext = ext_func;
+}
+
static inline void prepare_mca_msr_input_message(struct cpu_msr_indata *input,
u8 thread_id, u32 data_in)
{
@@ -105,13 +134,48 @@ static int sbrmi_get_rev(struct sbrmi_data *data)
return 0;
}
+static int rmi_cpuid_input(struct sbrmi_data *data, struct apml_cpuid_msg *msg,
+ u16 thread)
+{
+ struct cpu_msr_indata input = {0};
+ int val = 0, ret;
+
+ /* Thread > 127, Thread128 CS register, 1'b1 needs to be set to 1 */
+ if (thread > 127) {
+ thread -= 128;
+ val = 1;
+ }
+
+ ret = regmap_write(data->regmap, SBRMI_THREAD128CS, val);
+ if (ret < 0)
+ return ret;
+
+ prepare_cpuid_input_message(&input, thread,
+ msg->cpu_in_out & CPUID_MCA_FUNC_MASK,
+ msg->cpu_in_out >> CPUID_EXT_FUNC_INDEX);
+
+ return regmap_bulk_write(data->regmap, CPUID_MCA_CMD,
+ &input, CPUID_WR_REG_LEN);
+}
+
+static int rmi_cpuid_input_ext(struct sbrmi_data *data, struct apml_cpuid_msg *msg,
+ u16 thread)
+{
+ struct cpu_msr_indata_ext input = {0};
+
+ prepare_cpuid_input_message_ext(&input, thread,
+ msg->cpu_in_out & CPUID_MCA_FUNC_MASK,
+ msg->cpu_in_out >> CPUID_EXT_FUNC_INDEX);
+
+ return regmap_bulk_write(data->regmap, CPUID_MCA_CMD,
+ &input, CPUID_WR_REG_LEN_EXT);
+}
+
/* Read CPUID function protocol */
static int rmi_cpuid_read(struct sbrmi_data *data,
struct apml_cpuid_msg *msg)
{
- struct cpu_msr_indata input = {0};
struct cpu_msr_outdata output = {0};
- int val = 0;
int ret, hw_status;
u16 thread;
@@ -122,31 +186,29 @@ static int rmi_cpuid_read(struct sbrmi_data *data,
if (ret < 0)
goto exit_unlock;
}
- /* CPUID protocol for REV 0x20 is only supported*/
- if (data->rev != 0x20) {
- ret = -EOPNOTSUPP;
- goto exit_unlock;
- }
+ /* Extract thread from the input msg structure */
thread = msg->cpu_in_out >> CPUID_MCA_THRD_INDEX;
- /* Thread > 127, Thread128 CS register, 1'b1 needs to be set to 1 */
- if (thread > 127) {
- thread -= 128;
- val = 1;
- }
- ret = regmap_write(data->regmap, SBRMI_THREAD128CS, val);
- if (ret < 0)
+ switch (data->rev) {
+ case 0x10:
+ /* CPUID protocol for REV 0x10 is not supported*/
+ ret = -EOPNOTSUPP;
goto exit_unlock;
-
- prepare_cpuid_input_message(&input, thread,
- msg->cpu_in_out & CPUID_MCA_FUNC_MASK,
- msg->cpu_in_out >> CPUID_EXT_FUNC_INDEX);
-
- ret = regmap_bulk_write(data->regmap, CPUID_MCA_CMD,
- &input, CPUID_WR_REG_LEN);
- if (ret < 0)
+ case 0x20:
+ ret = rmi_cpuid_input(data, msg, thread);
+ if (ret)
+ goto exit_unlock;
+ break;
+ case 0x21:
+ ret = rmi_cpuid_input_ext(data, msg, thread);
+ if (ret)
+ goto exit_unlock;
+ break;
+ default:
+ ret = -EOPNOTSUPP;
goto exit_unlock;
+ }
/*
* For RMI Rev 0x20, new h/w status bit is introduced. which is used
--
2.25.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 6/6] misc: amd-sbi: Extend support for MCAMSR protocol for rev 0x21
2025-09-15 10:36 [PATCH v2 1/6] misc: amd-sbi: Add helper function to prepare I3C support Akshay Gupta
` (3 preceding siblings ...)
2025-09-15 10:36 ` [PATCH v2 5/6] misc: amd-sbi: Extend support for CPUID protocol for rev 0x21 Akshay Gupta
@ 2025-09-15 10:36 ` Akshay Gupta
4 siblings, 0 replies; 6+ messages in thread
From: Akshay Gupta @ 2025-09-15 10:36 UTC (permalink / raw)
To: linux-kernel, linux-hwmon
Cc: gregkh, arnd, linux, Anand.Umarji, Akshay Gupta,
Naveen Krishna Chatradhi
- MCAMSR 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>
---
Changes since v1:
- New patch
drivers/misc/amd-sbi/rmi-core.c | 88 +++++++++++++++++++++++++--------
1 file changed, 67 insertions(+), 21 deletions(-)
diff --git a/drivers/misc/amd-sbi/rmi-core.c b/drivers/misc/amd-sbi/rmi-core.c
index ef93dce7e038..c3a58912d6db 100644
--- a/drivers/misc/amd-sbi/rmi-core.c
+++ b/drivers/misc/amd-sbi/rmi-core.c
@@ -35,8 +35,10 @@
/* MSR */
#define MSR_RD_REG_LEN 0xa
#define MSR_WR_REG_LEN 0x8
+#define MSR_WR_REG_LEN_EXT 0x9
#define MSR_RD_DATA_LEN 0x8
#define MSR_WR_DATA_LEN 0x7
+#define MSR_WR_DATA_LEN_EXT 0x8
/* CPUID MSR Command Ids */
#define CPUID_MCA_CMD 0x73
@@ -120,6 +122,17 @@ static inline void prepare_mca_msr_input_message(struct cpu_msr_indata *input,
input->value = data_in;
}
+static inline void prepare_mca_msr_input_message_ext(struct cpu_msr_indata_ext *input,
+ u16 thread_id, u32 data_in)
+{
+ input->rd_len = MSR_RD_DATA_LEN;
+ input->wr_len = MSR_WR_DATA_LEN_EXT;
+ input->proto_cmd = RD_MCA_CMD;
+ input->thread_lo = (thread_id & 0xFF) << 1;
+ input->thread_hi = thread_id >> 8;
+ input->value = data_in;
+}
+
static int sbrmi_get_rev(struct sbrmi_data *data)
{
unsigned int rev;
@@ -248,13 +261,47 @@ static int rmi_cpuid_read(struct sbrmi_data *data,
return ret;
}
+static int rmi_mcamsr_input(struct sbrmi_data *data, struct apml_mcamsr_msg *msg,
+ u16 thread)
+{
+ struct cpu_msr_indata input = {0};
+ int val = 0, ret;
+
+ /* Thread > 127, Thread128 CS register, 1'b1 needs to be set to 1 */
+ if (thread > 127) {
+ thread -= 128;
+ val = 1;
+ }
+
+ ret = regmap_write(data->regmap, SBRMI_THREAD128CS, val);
+ if (ret < 0)
+ return ret;
+
+ prepare_mca_msr_input_message(&input, thread,
+ msg->mcamsr_in_out & CPUID_MCA_FUNC_MASK);
+
+ return regmap_bulk_write(data->regmap, CPUID_MCA_CMD,
+ &input, MSR_WR_REG_LEN);
+}
+
+static int rmi_mcamsr_input_ext(struct sbrmi_data *data, struct apml_mcamsr_msg *msg,
+ u16 thread)
+{
+ struct cpu_msr_indata_ext input = {0};
+
+ prepare_mca_msr_input_message_ext(&input, thread,
+ msg->mcamsr_in_out & CPUID_MCA_FUNC_MASK);
+
+ return regmap_bulk_write(data->regmap, CPUID_MCA_CMD,
+ &input, MSR_WR_REG_LEN_EXT);
+}
+
/* MCA MSR protocol */
static int rmi_mca_msr_read(struct sbrmi_data *data,
struct apml_mcamsr_msg *msg)
{
struct cpu_msr_outdata output = {0};
- struct cpu_msr_indata input = {0};
- int ret, val = 0;
+ int ret;
int hw_status;
u16 thread;
@@ -265,30 +312,29 @@ static int rmi_mca_msr_read(struct sbrmi_data *data,
if (ret < 0)
goto exit_unlock;
}
- /* MCA MSR protocol for REV 0x20 is supported*/
- if (data->rev != 0x20) {
- ret = -EOPNOTSUPP;
- goto exit_unlock;
- }
+ /* Extract thread from the input msg structure */
thread = msg->mcamsr_in_out >> CPUID_MCA_THRD_INDEX;
- /* Thread > 127, Thread128 CS register, 1'b1 needs to be set to 1 */
- if (thread > 127) {
- thread -= 128;
- val = 1;
- }
- ret = regmap_write(data->regmap, SBRMI_THREAD128CS, val);
- if (ret < 0)
+ switch (data->rev) {
+ case 0x10:
+ /* MCAMSR protocol for REV 0x10 is not supported*/
+ ret = -EOPNOTSUPP;
goto exit_unlock;
-
- prepare_mca_msr_input_message(&input, thread,
- msg->mcamsr_in_out & CPUID_MCA_FUNC_MASK);
-
- ret = regmap_bulk_write(data->regmap, CPUID_MCA_CMD,
- &input, MSR_WR_REG_LEN);
- if (ret < 0)
+ case 0x20:
+ ret = rmi_mcamsr_input(data, msg, thread);
+ if (ret)
+ goto exit_unlock;
+ break;
+ case 0x21:
+ ret = rmi_mcamsr_input_ext(data, msg, thread);
+ if (ret)
+ goto exit_unlock;
+ break;
+ default:
+ ret = -EOPNOTSUPP;
goto exit_unlock;
+ }
/*
* For RMI Rev 0x20, new h/w status bit is introduced. which is used
--
2.25.1
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2025-09-15 10:37 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-09-15 10:36 [PATCH v2 1/6] misc: amd-sbi: Add helper function to prepare I3C support Akshay Gupta
2025-09-15 10:36 ` [PATCH v2 2/6] misc: amd-sbi: Add support for SB-RMI over I3C Akshay Gupta
2025-09-15 10:36 ` [PATCH v2 3/6] misc: amd-sbi: Add support for Turin platform Akshay Gupta
2025-09-15 10:36 ` [PATCH v2 4/6] misc: amd-sbi: CPUID/MCAMSR protocol for Revision 0x21 Akshay Gupta
2025-09-15 10:36 ` [PATCH v2 5/6] misc: amd-sbi: Extend support for CPUID protocol for rev 0x21 Akshay Gupta
2025-09-15 10:36 ` [PATCH v2 6/6] misc: amd-sbi: Extend support for MCAMSR " Akshay Gupta
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®