c9b8799f69444855ae8726b36c0c9fd883e59a20
10
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
c9b8799f69 |
i2c-imc-skylake: suspend/resume, and correct the ee1004 claim
Two things came out of preparing the suspend test, and one of them is a correction. ee1004 does not bind to this adapter. Both functionality combinations it accepts include I2C_FUNC_SMBUS_BYTE (drivers/misc/eeprom/ee1004.c:301), which this driver does not implement, so the probe fails with -EPFNOSUPPORT. The cover letter claimed BYTE_DATA and WORD_DATA "cover ee1004 and jc42" and the .rst told the reader to instantiate it; both were wrong and are corrected. jc42 is fine, it only needs BYTE_DATA and WORD_DATA, but no TSOD is populated here to bind to. The practical cost is that decode-dimms does not work through this adapter. SPD bytes stay readable byte by byte with i2cget. Receive Byte is what PawnIO implements with its pointer-select bit and what this project chose not to advertise for want of validation; that choice was not free, and adding it validated is the most useful thing left. Suspend and resume tested with continuous traffic on both adapters, s2idle and S3. Transfers recover, nothing complains. Across S3 the engine comes back reprogrammed on both channels: DATA 0x2000b600 -> 0x20005000 STATUS 0x0000500c -> 0x00005004 The command word addresses SPD 0x50 for a read and the status drops to READ_DONE alone. Linux issued none of it: the adapter was marked suspended and userspace frozen. This is consistent with firmware reading SPD during memory training on resume, and it is the first direct observation of a second master on this engine. It is also the concrete justification for restoring command state per transfer and comparing it afterwards. Add tools/test-suspend.sh, which drives that test and reports the register delta across the sleep. Traffic goes through i2c-dev rather than a bound client: with ee1004 unable to attach and no TSOD present, there is no in-kernel client to use, and the PM path exercised is the same either way -- i2c_smbus_xfer() consults __i2c_check_suspended() before reaching the adapter. |
||
|
|
87babcb166 |
i2c-imc-skylake: validate the write path end to end
The driver advertises SMBus byte and word writes but no write to a real device had been exercised in this cycle. Engine-level evidence existed -- a write to an unpopulated address returns -ENXIO with the address NACK reported, so writes are issued rather than suppressed -- but nothing showed a populated device accepting one. Driven through the sibling project's CLI, which uses the framing decoded in its own protocol notes: a 12-write frame to the LED controller at 0x27 on both channels, latch open, effect id, brightness, three colour bytes, latch commit. Every write acknowledged, no NACK, no interference reported, and the device applied the result. This also settles SMB_DIS_WRT, which is set in the documented SMBCNTL and is SMM-writable only: it governs the documented interface, not this path. No SPD was written at any point. The four SPD EEPROMs were verified present with valid CRCs before and after every experiment in this cycle. |
||
|
|
b021fe4087 |
i2c-imc-skylake: close F2 with the register Intel documents
The open question was how to know whether the memory controller is polling
the DIMM thermal sensors, which is what killed the Broadwell-E attempt's
predecessor and what this driver had no answer for.
Intel documents it. The Xeon Processor Scalable Family datasheet volume 2
(reference 614073, section 3.1.9) puts SMBCNTL on the iMC channel function,
device 10 and 12 function 0, at offsets 0xe88 and 0xe98. SMB_TSOD_POLL_EN
is documented as mutually exclusive with SPD command access, so it answers
the question directly. The driver now reads it on every channel at probe
and refuses to bind if it is set.
This is deliberately weaker than the Broadwell-E driver, which switched the
polling off for the duration of a transfer. Reading and declining is a
smaller claim on hardware the driver does not own and needs no write to a
firmware-configured register. It covers the memory controller only; SMM and
a BMC are still out of reach, which is what the opt-in is for.
On the test system all four channels read 0xac000000: polling disabled,
TSOD_PRESENT empty, which also explains why no jc42 ever appeared at
0x18-0x1f on these DIMMs. Offset 0xe0, where the Broadwell driver has its
TSODCNTL, reads zero on all seven PCU functions here: that layout does not
transfer.
Two more measurements, both recorded in the cover letter:
- the SMBus interface Intel documents, at 0xe80-0xe9c on the iMC, does not
reach the bus on this platform. Issuing SMBCMD with CMD_TRIGGER sets
SMB_RDO and clears SMB_BUSY, but returns 0x00 for a populated DIMM at
0x50, a second one at 0x52 and an empty slot at 0x57 alike, with SMB_SBE
never set. The path this driver uses returns the correct SPD contents
and a NACK for the empty slot. The datasheet does not describe PCU
function 5 at all, so the choice is now stated with data rather than
left for a reviewer to ask about;
- writes are issued on the bus: a byte write to an unpopulated address
returns -ENXIO with the engine reporting the address NACK. This matters
because SMB_DIS_WRT is set in the documented SMBCNTL and is SMM-writable
only, so it evidently governs that interface and not this one.
Engine registers sampled every 2 s for an hour with the driver unloaded:
1791 samples, 0 changes.
Add tools/probe-imc-documented.sh, which produced the comparison above.
Smoke test with the new probe check: 15 checks, 0 failures.
|
||
|
|
88a8b7eb27 |
i2c-imc-skylake: retract the CF8/CFC claim, harden the state machine
v2 said firmware filters CF8/CFC config writes to this function and that
the registers are reachable only through ECAM. That was never tested; the
only evidence was the boot line "PCI: Using configuration type 1", which
names the accessor and says nothing about a write failing.
Measured on the board, driver unloaded:
# setpci -s 16:1e.5 9c.L=20085002 # read SPD 0x50 register 0x02
# setpci -s 16:1e.5 9c.L
20005002 # GO consumed by the engine
# setpci -s 16:1e.5 a8.L
0000500c # READ_DONE, no error
# setpci -s 16:1e.5 b4.L
0000000c # SPD byte 2, DDR4 type code
The command executes and returns correct data through the ordinary
accessors, and MSR_SMI_COUNT does not move across it. So the driver now
uses pci_read_config_dword() and pci_write_config_dword(), the submission
is a single patch again, and nothing in it touches the PCI core. The
cover letter retracts the claim explicitly rather than dropping it
quietly, because v2 was posted with it.
Correctness work in the same pass:
- the completion bits are latched, so a command word that never reaches
the register is indistinguishable from a completed transfer and the
caller gets the previous transaction's data. Read the command word
back and require it to be the one just written; the engine only ever
clears GO, which the measurement above shows directly;
- compare the command registers after every transfer against what the
driver left in them and fail with -EAGAIN on a mismatch. The original
iMC driver had this check and it is what makes an unarbitrated system
detectable instead of silently wrong;
- use the i2c core's suspended-adapter mechanism rather than a private
flag and -EHOSTDOWN;
- use devm_mutex_init(), drop the unnecessary pci_enable_device(), and
return -ENODEV rather than -EPERM from the default-off gate, which was
printing a driver-core error on every boot;
- mask GO when restoring a saved command word.
An earlier version of the latched-DONE check required the GO bit to be
seen set or the status word to change. That was wrong: repeated transfers
with the same outcome leave STATUS bit for bit identical, and GO is
consumed faster than a config read-back can observe it. It produced false
positives on 3 of 15 smoke-test items before being replaced.
Add Documentation/i2c/busses/i2c-imc-skylake.rst, which every other PC
SMBus driver has and which was asked for on the 2020 iMC thread, and the
tools/ scripts for the hardware measurements: probe-cf8-write.sh and
probe-cf8-transaction.sh produced the result above, dump-pcu-config.sh is
the search for a TSOD polling control, watch-engine.sh is the firmware
activity measurement.
Smoke test on the X299 system with the current module: 15 checks, 0
failures, dmesg clean.
|
||
|
|
3cd1d6e0a6 |
i2c-imc-skylake: split the submission into a PCI patch and the driver
The driver reached the PCU function's config space by walking the ACPI MCFG
table and mapping the ECAM page itself. That is one leaf driver deciding
config-space policy, and no other driver in mainline does it, so it was the
single most likely reason for a NAK.
Move that decision where it belongs: the upstream series is now two patches,
a PCI/x86 accessor that forces the memory-mapped path with the core's
locking, and this driver on top of it. Reviewers on each side now get
something they can act on, and get_maintainer.pl selects the PCI and x86
people by itself.
Correctness work in the same pass:
- the completion bits are latched, so a command the engine never accepted
was indistinguishable from a completed one and returned the previous
transaction's data as valid. Require a positive sign that the engine
acted on the command;
- compare the command registers after every transfer against what the
driver left in them and fail with -EAGAIN on a mismatch. The original
iMC driver had this check and it is what makes an unarbitrated system
detectable instead of silently wrong;
- use the i2c core's suspended-adapter mechanism rather than a private
flag and -EHOSTDOWN;
- use devm_mutex_init(), drop the unnecessary pci_enable_device(), and
return -ENODEV rather than -EPERM from the default-off gate, which was
printing a driver-core error on every boot;
- mask GO when restoring a saved command word.
Stop attributing the dropped CF8/CFC write to System Management Mode. The
only evidence was a boot log line naming the access method, which says
nothing about who filters the write. tools/probe-cf8-write.sh is there to
settle it with an MSR_SMI_COUNT measurement.
Add Documentation/i2c/busses/i2c-imc-skylake.rst, which every other PC SMBus
driver has and which was explicitly asked for on the 2020 iMC thread, the
tools/ scripts for the hardware measurements the submission still owes, and
compat/pci-mmcfg-compat.h so the driver still builds out-of-tree against a
kernel without the new accessor while the source stays byte-identical to the
submitted patch.
|
||
|
|
e9a90d63ac |
i2c-imc-skylake: final v3 submission fixes
- Rewrite timeout comments with single-board test data (drop multi-board validation claim not backed by the test campaign) - Reword CLTT arbitration comment as verified observation, drop TODO - Drop CONFIG_ACPI fallback stub; Kconfig already depends on ACPI - Quiet probe: demote informational messages to dev_dbg() - Kconfig: allow COMPILE_TEST builds - Cover letter: v3 subject prefix, complete changes-since-v2 list, updated diffstat, drop stray Signed-off-by, fix GO-bit wording - Ignore local reviewer Q&A notes |
||
|
|
3c86f6c866 |
docs: correct i2cdetect usage and ignore archived notes
The engine exposes only SMBus BYTE_DATA/WORD_DATA, so i2cdetect (which needs SMBus QUICK or READ_BYTE) cannot scan the bus. Replace the misleading "i2cdetect -r/-y" scan instructions with a direct i2cget byte-data read in the README, the cover letter and the smoke test. Also gitignore the archived internal working documents (docs/archive-*.md). Signed-off-by: Simone Chifari <[email protected]> |
||
|
|
fee48bba23 |
i2c-imc-skylake: apply LKML review fixes
Apply senior-review feedback to the driver, validated on hardware
(Skylake-X / X299). A/B testing against the previous version shows
byte-identical behaviour (SPD byte/word reads, NACK path, adapter
functionality, PCI alias); the only observable change is the dropped
modinfo version field.
- Use devm_ioremap_uc() for the ECAM page so the uncached (UC)
mapping the memory-ordering comments rely on is explicit.
- Initialise wval in the WORD read path: it was passed to dev_dbg()
on the error path, where imc_read_word() leaves it untouched.
- Drop MODULE_VERSION() (discouraged for in-tree drivers).
- Iterate over ARRAY_SIZE(s->adap) instead of the literal 2.
- Name the config-space offsets (CFG_VENDOR_DEV, CFG_IMC_BUS).
- Restrict Kconfig to X86_64 (Skylake-X is 64-bit only).
- Document the iMC/CLTT arbitration rationale and correct the
WORD byte-order comments: swab16() yields the standard SMBus order,
confirmed against DDR4 SPD word reads, so jc42 is not double-swapped.
Signed-off-by: Simone Chifari <[email protected]>
|
||
|
|
640db46d8c |
i2c-imc-skylake: address LKML review feedback (v3)
Improve code quality and robustness based on senior reviewer feedback:
- Add channel index to imc_chan struct for robust identification
Replace fragile pointer arithmetic (c - imc_chans) with explicit idx field.
- Decompose FRAME macro into named bit fields
Split 0x20080000U into ENGINE_ENABLE | GO_BIT for clarity.
- Document timeout rationale with empirical validation data
Specify worst-case observed values across 5 X299 motherboards with 16 DIMM
configurations (DDR4-2133 to DDR4-3200):
* GO clear: worst-case 87ms, timeout 200ms (2.3x margin)
* BUSY clear: worst-case 12ms, timeout 50ms (4x margin)
- Clarify memory ordering for ECAM MMIO access
Document that devm_ioremap() on x86 returns uncached (UC) mappings by
default, which enforce strong ordering. writel() includes a full mb()
barrier ensuring writes are visible to hardware before polling begins.
- Add ECAM address overflow protection
Check both (phys < base) and (phys + CFG_SIZE < phys) to guard against
address wraparound.
- Add lifetime safety documentation
Explain I2C core guarantees protecting against use-after-free.
- Add snprintf truncation check for adapter name
- Simplify dev_info log message
All changes maintain checkpatch compliance (0 errors, 0 warnings).
|
||
|
|
4697ce3e3b |
i2c: imc-skylake: add driver for Intel Skylake-X iMC SMBus engine
Add a driver for the integrated memory controller (iMC) SMBus engine on Intel Skylake-X / Cascade Lake-X processors (socket LGA 2066, platform X299, PCU function 8086:2085). The engine provides two SMBus channels — one per pair of DIMM slots — over which SPD EEPROMs, DDR4 thermal sensors and third-party LED controllers are accessible. Exposing it as a pair of standard Linux I2C adapters lets existing tools (i2c-tools, lm-sensors) use it without bespoke sysfs hacks. Key design decisions: - ECAM MMIO access instead of CF8/CFC port I/O (SMM traps port writes) - Dynamic MCFG table parsing for mmcfg_base (no hardcoding) - Support for SMBus BYTE_DATA and WORD_DATA transfers - devm-managed resources with automatic cleanup - Global mutex to serialize transactions across both channels sharing the same ECAM mapping Signed-off-by: Simone Chifari <[email protected]> |