Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
eaa22b7
dt-bindings: i3c: Add mipi-i3c-static-method to support SETAASA
akhilr-nv Jul 28, 2026
09a82f0
i3c: master: Use unified device property interface
akhilr-nv Jul 28, 2026
699c085
ACPICA: Add LVR to acrestyp.h
akhilr-nv May 27, 2026
46d8c0c
ACPICA: Fetch LVR I2C resource descriptor
akhilr-nv May 27, 2026
aca5628
ACPICA: Change LVR to 8 bit value
akhilr-nv May 27, 2026
3bf2c0d
ACPICA: Mention the LVR bits
akhilr-nv May 27, 2026
6f89f17
ACPICA: fix I2C LVR item count in the conversion table
akhilr-nv May 27, 2026
53ef026
i3c: master: Support ACPI enumeration of child devices
akhilr-nv Jul 28, 2026
b7697ab
i3c: master: Add support for devices using SETAASA
akhilr-nv Jul 28, 2026
b7bb5bd
i3c: master: Add support for devices without PID
akhilr-nv Jul 28, 2026
c4caffb
i3c: master: match I3C device through DT and ACPI
akhilr-nv Jul 28, 2026
29e42d0
i3c: dw-i3c-master: Add SETAASA as supported CCC
akhilr-nv Jul 28, 2026
9aea7d0
i3c: dw-i3c-master: Add ACPI core clock frequency quirk
akhilr-nv Jul 28, 2026
16f4b0d
i3c: dw-i3c-master: Add ACPI ID for Tegra410
akhilr-nv Jul 28, 2026
c34f141
hwmon: spd5118: Remove 16-bit addressing
akhilr-nv Jul 28, 2026
3e14f60
hwmon: spd5118: Add I3C support
akhilr-nv Jul 28, 2026
6b28c85
NVIDIA: VR: SAUCE: [Config] Pin I3C and SPD5118 module policies for a…
nirmoy Aug 3, 2026
66f2b15
i3c: master: Fix info leak and UAF in device unregister path
ahunter6 Jul 23, 2026
95ef2ec
NVIDIA: VR: SAUCE: i3c: master: Emit firmware modalias for SETAASA de…
nirmoy Aug 10, 2026
2c4120f
NVIDIA: VR: SAUCE: i3c: master: Propagate SETAASA early device-add fa…
nirmoy Aug 10, 2026
01bde9a
i3c: dw: avoid shift-out-of-bounds when DAA assigns no devices
kuba-moo Jun 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 31 additions & 5 deletions Documentation/devicetree/bindings/i3c/i3c.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,12 @@ properties:
described in the device tree, which in turn means we have to describe
I3C devices.

Another use case for describing an I3C device in the device tree is when
this I3C device has a static I2C address and we want to assign it a
specific I3C dynamic address before the DAA takes place (so that other
devices on the bus can't take this dynamic address).
Other use-cases for describing an I3C device in the device tree are:
- When the I3C device has a static I2C address and we want to assign
it a specific I3C dynamic address before the DAA takes place (so
that other devices on the bus can't take this dynamic address).
- When the I3C device requires SETAASA for its discovery and uses a
pre-defined static address.

"#size-cells":
const: 0
Expand Down Expand Up @@ -145,7 +147,31 @@ patternProperties:
Dynamic address to be assigned to this device. In case static address is
present (first cell of the reg property != 0), this address is assigned
through SETDASA. If static address is not present, this address is assigned
through SETNEWDA after assigning a temporary address via ENTDAA.
through SETNEWDA after assigning a temporary address via ENTDAA. If
SETAASA is used, this property is not used, and the static address itself
becomes the dynamic address.

mipi-i3c-static-method:
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0x1
maximum: 0x7
default: 1
description: |
Bitmap describing which methods of Dynamic Address Assignment from a
static address are supported by this I3C Target. For each defined bit
position, a set bit indicates support for that method and a cleared
bit indicates lack of support.

Bit 0: SETDASA CCC (Direct)
Bit 1: SETAASA CCC (Broadcast)
Bit 2: Other CCC (vendor / standards extension)
All other bits are reserved.

This property follows the MIPI I3C specification. The primary use
of this property is to indicate support for SETAASA, i.e Bit 1, but
will allow other values mentioned in the specification so that it
mirrors the specification. SETDASA will remain as the default method
even if this property is not present.

required:
- reg
Expand Down
9 changes: 9 additions & 0 deletions debian.nvidia-bos/config/annotations
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ CONFIG_DRM_NOUVEAU_SIL164 note<'Disable nouveau for NVIDIA
CONFIG_DRM_NOUVEAU_SVM policy<{'amd64': '-', 'arm64': '-'}>
CONFIG_DRM_NOUVEAU_SVM note<'Disable nouveau for NVIDIA kernels'>

CONFIG_DW_I3C_MASTER policy<{'arm64': 'm'}>
CONFIG_DW_I3C_MASTER note<'Enable DesignWare I3C master controller for Tegra410'>

CONFIG_EFI_CAPSULE_LOADER policy<{'amd64': 'm', 'arm64': 'y'}>
CONFIG_EFI_CAPSULE_LOADER note<'LP: #2067111'>

Expand All @@ -186,6 +189,9 @@ CONFIG_GENERIC_CPU_CACHE_MAINTENANCE note<'Selected by arm64 via arch
CONFIG_GPIO_AAEON policy<{'amd64': '-'}>
CONFIG_GPIO_AAEON note<'Disable all Ubuntu ODM drivers'>

CONFIG_I3C policy<{'arm64': 'm'}>
CONFIG_I3C note<'Enable I3C bus support for Tegra410 and SPD5118 temperature sensors'>

CONFIG_IOMMUFD_VFIO_CONTAINER policy<{'arm64': 'y'}>
CONFIG_IOMMUFD_VFIO_CONTAINER note<'LP: #2095028'>

Expand Down Expand Up @@ -264,6 +270,9 @@ CONFIG_SAMPLE_CORESIGHT_SYSCFG note<'Required for Grace enablem
CONFIG_SENSORS_AAEON policy<{'amd64': '-'}>
CONFIG_SENSORS_AAEON note<'Disable all Ubuntu ODM drivers'>

CONFIG_SENSORS_SPD5118 policy<{'arm64': 'm'}>
CONFIG_SENSORS_SPD5118 note<'Enable SPD5118 temperature sensor support for DDR5 memory modules'>

CONFIG_SFC_CXL policy<{'amd64': 'n', 'arm64': 'n'}>
CONFIG_SFC_CXL note<'Solarflare SFC9100-family CXL Type-2 device support; not needed for NVIDIA platforms'>

Expand Down
7 changes: 6 additions & 1 deletion drivers/acpi/acpica/rsserial.c
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ struct acpi_rsconvert_info acpi_rs_convert_csi2_serial_bus[14] = {
*
******************************************************************************/

struct acpi_rsconvert_info acpi_rs_convert_i2c_serial_bus[17] = {
struct acpi_rsconvert_info acpi_rs_convert_i2c_serial_bus[18] = {
{ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_SERIAL_BUS,
ACPI_RS_SIZE(struct acpi_resource_i2c_serialbus),
ACPI_RSC_TABLE_SIZE(acpi_rs_convert_i2c_serial_bus)},
Expand Down Expand Up @@ -391,6 +391,11 @@ struct acpi_rsconvert_info acpi_rs_convert_i2c_serial_bus[17] = {
AML_OFFSET(i2c_serial_bus.type_specific_flags),
0},

/* Read LVR from Type Specific Flags, bits[15:8] */
{ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.i2c_serial_bus.lvr),
AML_OFFSET(i2c_serial_bus.type_specific_flags) + 1,
1},

{ACPI_RSC_MOVE32, ACPI_RS_OFFSET(data.i2c_serial_bus.connection_speed),
AML_OFFSET(i2c_serial_bus.connection_speed),
1},
Expand Down
9 changes: 6 additions & 3 deletions drivers/hwmon/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -2320,12 +2320,15 @@ config SENSORS_INA3221

config SENSORS_SPD5118
tristate "SPD5118 Compliant Temperature Sensors"
depends on I2C
depends on I3C_OR_I2C
select REGMAP_I2C
select REGMAP_I3C if I3C
help
If you say yes here you get support for SPD5118 (JEDEC JESD300)
compliant temperature sensors. Such sensors are found on DDR5 memory
modules.
compliant temperature sensors using I2C or I3C bus interface.
Such sensors are found on DDR5 memory modules.

This driver supports both I2C and I3C interfaces.

This driver can also be built as a module. If so, the module
will be called spd5118.
Expand Down
119 changes: 52 additions & 67 deletions drivers/hwmon/spd5118.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <linux/bits.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/i3c/device.h>
#include <linux/hwmon.h>
#include <linux/module.h>
#include <linux/mutex.h>
Expand Down Expand Up @@ -66,9 +67,6 @@ static const unsigned short normal_i2c[] = {
#define SPD5118_EEPROM_BASE 0x80
#define SPD5118_EEPROM_SIZE (SPD5118_PAGE_SIZE * SPD5118_NUM_PAGES)

#define PAGE_ADDR0(page) (((page) & BIT(0)) << 6)
#define PAGE_ADDR1_4(page) (((page) & GENMASK(4, 1)) >> 1)

/* Temperature unit in millicelsius */
#define SPD5118_TEMP_UNIT (MILLIDEGREE_PER_DEGREE / 4)
/* Representable temperature range in millicelsius */
Expand All @@ -78,7 +76,6 @@ static const unsigned short normal_i2c[] = {
struct spd5118_data {
struct regmap *regmap;
struct mutex nvmem_lock;
bool is_16bit;
};

/* hwmon */
Expand Down Expand Up @@ -348,12 +345,7 @@ static ssize_t spd5118_nvmem_read_page(struct spd5118_data *data, char *buf,
if (offset + count > SPD5118_PAGE_SIZE)
count = SPD5118_PAGE_SIZE - offset;

if (data->is_16bit) {
addr = SPD5118_EEPROM_BASE | PAGE_ADDR0(page) |
(PAGE_ADDR1_4(page) << 8);
} else {
addr = page * 0x100 + SPD5118_EEPROM_BASE;
}
addr = page * 0x100 + SPD5118_EEPROM_BASE;
err = regmap_bulk_read(regmap, addr + offset, buf, count);
if (err)
return err;
Expand Down Expand Up @@ -473,10 +465,22 @@ static const struct regmap_config spd5118_regmap8_config = {
.num_ranges = ARRAY_SIZE(spd5118_i2c_regmap_range_cfg),
};

static const struct regmap_config spd5118_regmap16_config = {
/*
* SPD5118 2-byte register address format (JESD300-5, Tables 7 & 20):
* Byte 1 (on wire first): MemReg | BlkAddr[0] | Address[5:0]
* Byte 2 (on wire second): 0000 | BlkAddr[4:1]
*
* The address byte (with MemReg and lower address bits) must be sent first,
* followed by the upper block address byte. With regmap 16-bit register
* format, this maps to little-endian: the low byte of the 16-bit value is
* transmitted first. No range config is needed since I3C does not use MR11
* page switching.
*/
static const struct regmap_config spd5118_regmap_i3c_config = {
.reg_bits = 16,
.val_bits = 8,
.max_register = 0x7ff,
.reg_format_endian = REGMAP_ENDIAN_LITTLE,
.writeable_reg = spd5118_writeable_reg,
.volatile_reg = spd5118_volatile_reg,
.cache_type = REGCACHE_MAPLE,
Expand Down Expand Up @@ -519,8 +523,7 @@ static int spd5118_resume(struct device *dev)

static DEFINE_SIMPLE_DEV_PM_OPS(spd5118_pm_ops, spd5118_suspend, spd5118_resume);

static int spd5118_common_probe(struct device *dev, struct regmap *regmap,
bool is_16bit)
static int spd5118_common_probe(struct device *dev, struct regmap *regmap)
{
unsigned int capability, revision, vendor, bank;
struct spd5118_data *data;
Expand All @@ -537,8 +540,6 @@ static int spd5118_common_probe(struct device *dev, struct regmap *regmap,
if (!(capability & SPD5118_CAP_TS_SUPPORT))
return -ENODEV;

data->is_16bit = is_16bit;

err = regmap_read(regmap, SPD5118_REG_REVISION, &revision);
if (err)
return err;
Expand Down Expand Up @@ -680,69 +681,21 @@ static int spd5118_i2c_init(struct i2c_client *client)
return 0;
}

/*
* 16-bit addressing note:
*
* If I2C_FUNC_I2C is not supported by an I2C adapter driver, regmap uses
* SMBus operations as alternative. To simulate a read operation with a 16-bit
* address, it writes the address using i2c_smbus_write_byte_data(), followed
* by one or more calls to i2c_smbus_read_byte() to read the data.
* Per spd5118 standard, a read operation after writing the address must start
* with <Sr> (Repeat Start). However, a SMBus read byte operation starts with
* <S> (Start). This resets the register address in the spd5118 chip. As result,
* i2c_smbus_read_byte() always returns data from register address 0x00.
*
* A working alternative to access chips with 16-bit register addresses in the
* absence of I2C_FUNC_I2C support is not known.
*
* For this reason, 16-bit addressing can only be supported with I2C if the
* adapter supports I2C_FUNC_I2C.
*
* For I2C, the addressing mode selected by the BIOS must not be changed.
* Experiments show that at least some PC BIOS versions will not change the
* addressing mode on a soft reboot and end up in setup, claiming that some
* configuration change happened. This will happen again after a power cycle,
* which does reset the addressing mode. To prevent this from happening,
* detect if 16-bit addressing is enabled and always use the currently
* configured addressing mode.
*/

static int spd5118_i2c_probe(struct i2c_client *client)
{
const struct regmap_config *config;
struct device *dev = &client->dev;
struct regmap *regmap;
int err, mode;
bool is_16bit;
int err;

err = spd5118_i2c_init(client);
if (err)
return err;

mode = i2c_smbus_read_byte_data(client, SPD5118_REG_I2C_LEGACY_MODE);
if (mode < 0)
return mode;

is_16bit = mode & SPD5118_LEGACY_MODE_ADDR;
if (is_16bit) {
/*
* See 16-bit addressing note above explaining why it is
* necessary to check for I2C_FUNC_I2C support here.
*/
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
dev_err(dev, "Adapter does not support 16-bit register addresses\n");
return -ENODEV;
}
config = &spd5118_regmap16_config;
} else {
config = &spd5118_regmap8_config;
}

regmap = devm_regmap_init_i2c(client, config);
regmap = devm_regmap_init_i2c(client, &spd5118_regmap8_config);
if (IS_ERR(regmap))
return dev_err_probe(dev, PTR_ERR(regmap), "regmap init failed\n");

return spd5118_common_probe(dev, regmap, is_16bit);
return spd5118_common_probe(dev, regmap);
}

static const struct i2c_device_id spd5118_i2c_id[] = {
Expand Down Expand Up @@ -770,7 +723,39 @@ static struct i2c_driver spd5118_i2c_driver = {
.address_list = IS_ENABLED(CONFIG_SENSORS_SPD5118_DETECT) ? normal_i2c : NULL,
};

module_i2c_driver(spd5118_i2c_driver);
/* I3C */

static int spd5118_i3c_probe(struct i3c_device *i3cdev)
{
struct device *dev = i3cdev_to_dev(i3cdev);
struct regmap *regmap;
u8 regval[2];
int err;

regmap = devm_regmap_init_i3c(i3cdev, &spd5118_regmap_i3c_config);
if (IS_ERR(regmap))
return dev_err_probe(dev, PTR_ERR(regmap), "regmap init failed\n");

err = regmap_bulk_read(regmap, SPD5118_REG_TYPE, regval, 2);
if (err)
return dev_err_probe(dev, err, "failed to read device type\n");

if (regval[0] != 0x51 || regval[1] != 0x18)
return -ENODEV;

return spd5118_common_probe(dev, regmap);
}

static struct i3c_driver spd5118_i3c_driver = {
.driver = {
.name = "spd5118_i3c",
.of_match_table = spd5118_of_ids,
.pm = pm_sleep_ptr(&spd5118_pm_ops),
},
.probe = spd5118_i3c_probe,
};

module_i3c_i2c_driver(spd5118_i3c_driver, &spd5118_i2c_driver);

MODULE_AUTHOR("René Rebe <rene@exactcode.de>");
MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
Expand Down
Loading
Loading