From: Akshay Gupta Date: Mon, 15 Sep 2025 10:36:46 +0000 (+0000) Subject: misc: amd-sbi: Add support for Turin platform X-Git-Tag: v6.19-rc1~65^2~68 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=45392fd4394cb8d4b39ba0f144651aba05b7b2a7;p=thirdparty%2Fkernel%2Flinux.git misc: amd-sbi: Add support for Turin platform - 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 Signed-off-by: Akshay Gupta Link: https://patch.msgid.link/20250915103649.1705078-3-akshay.gupta@amd.com Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/misc/amd-sbi/rmi-i2c.c b/drivers/misc/amd-sbi/rmi-i2c.c index 087c57bb0f372..f0cc99000b695 100644 --- a/drivers/misc/amd-sbi/rmi-i2c.c +++ b/drivers/misc/amd-sbi/rmi-i2c.c @@ -18,6 +18,8 @@ #include #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.