i2c_imc: New driver, at long last
v3 cover i2c_imc: New driver, at long last
A few weeks ago, hch reminded me that there are lots of real live production users of iMC's SMBUS. They're currently using low-quality userspace hacks or low-quality non-public kernels drivers. Let's fix that.
This adds i2c_imc, a driver for the SMBUS lines on DIMM slots on modern Intel server chips. Conceptually, I like it a lot -- it's a driver for a bus for which we know the exact topology a priori. That means that we can actually enumerate the things on the bus reasonably cleanly.
This driver is a bit weird, but I don't think that merging it will cause problems, and there are Real Users (tm) of this hardware on Linux, many of whom would benefit from using a reasonably high-quality in-tree driver over the various awful userspace hacks that are floating around.
It has two caveats.
Big caveat: Lots of things like to touch this bus, such as a BMC, the memory controller power management stuff, and maybe even SMM code. Intel forgot to define a way to arbitrate between them, nor are the SMBUS master regs designed to be poked by multiple things at once. The upshot is that loading this driver is generally unsafe. The driver takes some measures to detect contention for the registers and shut itself down, but no one should rely on that.
My understanding is that there is or was work in ACPI land to define an arbitration mechanism. Once this happens, we can support it in this driver. In the mean time, this driver has actual users, and there are motherboards specifically designed to be used with a driver like this. (I have such a board, and you can even buy them on regular online shopping sutes.)
Therefore, I added a module parameter called allow_unsafe_access. If unset, the driver will refuse to load with an informative message. If set, the driver will pr_warn and load.
Little caveat: This submission only supposts Sandy Bridge. I'd rather get it merged without Ivy Bridge and Haswell support and add them later (should be easy) rather than trying to make the driver support all possible hardware before merging it.
Changes from v2:
- Rebased and re-tested.
Changes from v1:
- Fix checkpatch license nits.
- Fix MODULE_LICENSE.
- Add missing parentheses to macros.
- Tidy up imc_wait_not_busy.
- Clean up post-transaction-completion handling code.
- Downgrade a bunch of message severities.
- Misc checkpatch stuff.
- Move select I2C_DIMM_BUS where it belongs.
- Improve comments.
Changes from much earlier:
- This was an updated resubmission after about a year of thumb twiddling.
Andy Lutomirski (2):
i2c_imc: New driver for Intel's iMC, found on LGA2011 SNB chips i2c, i2c_imc: Add DIMM bus code
drivers/i2c/busses/Kconfig | 23 ++ drivers/i2c/busses/Makefile | 5 + drivers/i2c/busses/dimm-bus.c | 107 ++++++++ drivers/i2c/busses/i2c-imc.c | 570 ++++++++++++++++++++++++++++++++++++++++++ include/linux/i2c/dimm-bus.h | 20 ++ 5 files changed, 725 insertions(+) create mode 100644 drivers/i2c/busses/dimm-bus.c create mode 100644 drivers/i2c/busses/i2c-imc.c create mode 100644 include/linux/i2c/dimm-bus.h
Signature · 1 line
2.5.5
PATCH v3 1/2 i2c_imc: New driver for Intel's iMC, found on LGA2011 SNB chips
Sandy Bridge Xeon and Extreme chips have integrated memory controllers with (rather limited) onboard SMBUS masters. This driver gives access to the bus.
There were various groups working on standardizing a way to arbitrate access to the bus between the OS, SMM firmware, a BMC, hardware thermal control, etc. In the mean time, running this driver is unsafe except under special circumstances. Nonetheless, this driver has real use deployed use cases: there are many Sandy Bridge systems with pre-NFIT ADR NVDIMMs installed, and many of these NVDIMMs are designed to be programmed over SMBUS.
As a compromise, the driver will refuse to load unless i2c_imc.allow_unsafe_access=Y. When safe access becomes available, we can leave this option as a way for legacy users to run the driver, and we'll allow the driver to load by default if safe bus access is available.
This driver currently only supports SNB. It should be straightforward to extend it to all newer CPUs, but I don't have the hardware to test it.
--- drivers/i2c/busses/Kconfig | 18 ++ drivers/i2c/busses/Makefile | 1 + drivers/i2c/busses/i2c-imc.c | 567 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 586 insertions(+) create mode 100644 drivers/i2c/busses/i2c-imc.c
drivers/i2c/busses/Kconfig +18 -0
@@ -152,6 +152,24 @@ config I2C_ISMT This driver can also be built as a module. If so, the module will be called i2c-ismt. +config I2C_IMC + tristate "Intel iMC (LGA 2011) SMBus Controller" + depends on PCI && X86 + help + If you say yes to this option, support will be included for the Intel + Integrated Memory Controller SMBus host controller interface. This + controller is found on LGA 2011 Sandy Bridge Xeons and Core i7 + Extremes. + + There are currently no systems on which the kernel knows that it can + safely enable this driver. For now, you need to pass this driver a + scary module parameter, and you should only pass that parameter if you + have a special motherboard and know exactly what you are doing. + Special motherboards include the Supermicro X9DRH-iF-NV. + + This driver can also be built as a module. If so, the module will be + called i2c-imc. + config I2C_PIIX4 tristate "Intel PIIX4 and compatible (ATI/AMD/Serverworks/Broadcom/SMSC)" depends on PCI
drivers/i2c/busses/Makefile +1 -0
@@ -15,6 +15,7 @@ obj-$(CONFIG_I2C_AMD8111) += i2c-amd8111.o obj-$(CONFIG_I2C_I801) += i2c-i801.o obj-$(CONFIG_I2C_ISCH) += i2c-isch.o obj-$(CONFIG_I2C_ISMT) += i2c-ismt.o +obj-$(CONFIG_I2C_IMC) += i2c-imc.o obj-$(CONFIG_I2C_NFORCE2) += i2c-nforce2.o obj-$(CONFIG_I2C_NFORCE2_S4985) += i2c-nforce2-s4985.o obj-$(CONFIG_I2C_PIIX4) += i2c-piix4.o
drivers/i2c/busses/i2c-imc.c new file +567 -0
567 lines not on this page · raw message
Signature · 1 line
2.5.5
PATCH v3 2/2 i2c, i2c_imc: Add DIMM bus code
In reply to Andy LutomirskiAdd i2c_scan_dimm_bus to declare that a particular i2c_adapter contains DIMMs. This will probe (and autoload modules!) for useful SMBUS devices that live on DIMMs. i2c_imc calls it.
As more SMBUS-addressable DIMM components become supported, this code can be extended to probe for them.
--- drivers/i2c/busses/Kconfig | 5 ++ drivers/i2c/busses/Makefile | 4 ++ drivers/i2c/busses/dimm-bus.c | 107 ++++++++++++++++++++++++++++++++++++++++++ drivers/i2c/busses/i2c-imc.c | 3 ++ include/linux/i2c/dimm-bus.h | 20 ++++++++ 5 files changed, 139 insertions(+) create mode 100644 drivers/i2c/busses/dimm-bus.c create mode 100644 include/linux/i2c/dimm-bus.h
drivers/i2c/busses/Kconfig +5 -0
@@ -152,9 +152,14 @@ config I2C_ISMT This driver can also be built as a module. If so, the module will be called i2c-ismt. +config I2C_DIMM_BUS + tristate + default n + config I2C_IMC tristate "Intel iMC (LGA 2011) SMBus Controller" depends on PCI && X86 + select I2C_DIMM_BUS help If you say yes to this option, support will be included for the Intel Integrated Memory Controller SMBus host controller interface. This
drivers/i2c/busses/Makefile +4 -0
@@ -25,6 +25,10 @@ obj-$(CONFIG_I2C_SIS96X) += i2c-sis96x.o obj-$(CONFIG_I2C_VIA) += i2c-via.o obj-$(CONFIG_I2C_VIAPRO) += i2c-viapro.o +# DIMM busses +obj-$(CONFIG_I2C_DIMM_BUS) += dimm-bus.o +obj-$(CONFIG_I2C_IMC) += i2c-imc.o + # Mac SMBus host controller drivers obj-$(CONFIG_I2C_HYDRA) += i2c-hydra.o obj-$(CONFIG_I2C_POWERMAC) += i2c-powermac.o
drivers/i2c/busses/dimm-bus.c new file +107 -0
107 lines not on this page · raw message
drivers/i2c/busses/i2c-imc.c +3 -0
@@ -19,6 +19,7 @@#include <linux/pci.h> #include <linux/ratelimit.h> #include <linux/i2c.h> +#include <linux/i2c/dimm-bus.h> /* * The datasheet can be found here, for example:
@@ -416,6 +417,8 @@ static int imc_init_channel(struct imc_priv *priv, int i, int socket)return err; } +i2c_scan_dimm_bus (&ch->adapter); +return 0 ; }
include/linux/i2c/dimm-bus.h new file +20 -0
@@ -0,0 +1,20 @@ +/* +* Copyright (c) 2013-2016 Andrew Lutomirski <[email protected]> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 +* as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ + +#ifndef _I2C_DIMM_BUS +#define _I2C_DIMM_BUS + +struct i2c_adapter ; +void i2c_scan_dimm_bus (struct i2c_adapter *adapter); + +#endif /* _I2C_DIMM_BUS */
Signature · 1 line
2.5.5
RE: [PATCH v3 2/2] i2c, i2c_imc: Add DIMM bus code
Quoted 93 lines
-----Original Message-----
From: Andy Lutomirski [mailto:[email protected]]
Sent: Thursday, April 28, 2016 8:03 PM
To: Wolfram Sang <[email protected]>; Christoph Hellwig <[email protected]>
Cc: Boaz Harrosh <[email protected]>; One Thousand Gnomes <[email protected]>; Rui Wang <[email protected]>; Jean Delvare <[email protected]>; Alun Evans <[email protected]>; Robert Elliott <[email protected]>; [email protected]; Mauro Carvalho Chehab <[email protected]>; Paul Bolle <[email protected]>; Tony Luck <[email protected]>; [email protected]; Guenter Roeck <[email protected]>; Andy Lutomirski <[email protected]>
Subject: [PATCH v3 2/2] i2c,i2c_imc: Add DIMM bus codeAdd
i2c_scan_dimm_busto declare that a particulari2c_adaptercontains DIMMs. This will probe (and autoload modules!) for useful SMBUS devices that live on DIMMs.i2c_imccalls it.As more SMBUS-addressable DIMM components become supported, this code can be extended to probe for them.
Signed-off-by Andy Lutomirski <[email protected]>--- drivers/i2c/busses/Kconfig | 5 ++ drivers/i2c/busses/Makefile | 4 ++ drivers/i2c/busses/dimm-bus.c | 107 ++++++++++++++++++++++++++++++++++++++++++ drivers/i2c/busses/i2c-imc.c | 3 ++ include/linux/i2c/dimm-bus.h | 20 ++++++++ 5 files changed, 139 insertions(+) create mode 100644 drivers/i2c/busses/dimm-bus.c create mode 100644 include/linux/i2c/dimm-bus.hdrivers/i2c/busses/Kconfig +0
-0@@ -152,9 +152,14 @@ config I2C_ISMT This driver can also be built as a module. If so, the module willbe
drivers/i2c/busses/Kconfig +5
-0called i2c-ismt. +config I2C_DIMM_BUS + tristate + default n + config I2C_IMC tristate "Intel iMC (LGA 2011) SMBus Controller" depends on PCI && X86 + select I2C_DIMM_BUS help If you say yes to this option, support will be included for theIntel
drivers/i2c/busses/Kconfig +0
-0Integrated Memory Controller SMBus host controller interface. Thisdrivers/i2c/busses/Makefile +4
-0@@ -25,6 +25,10 @@ obj-$(CONFIG_I2C_SIS96X) += i2c-sis96x.o obj-$(CONFIG_I2C_VIA) += i2c-via.o obj-$(CONFIG_I2C_VIAPRO) += i2c-viapro.o +# DIMM busses +obj-$(CONFIG_I2C_DIMM_BUS) += dimm-bus.o +obj-$(CONFIG_I2C_IMC) += i2c-imc.o + # Mac SMBus host controller drivers obj-$(CONFIG_I2C_HYDRA) += i2c-hydra.o obj-$(CONFIG_I2C_POWERMAC) += i2c-powermac.odrivers/i2c/busses/dimm-bus.c new file +17
-0@@ -0,0 +1,107 @@ +/* +* Copyright (c) 2013-2016 Andrew Lutomirski <[email protected]> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 +* as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ + +#include <linux/i2c.h> +#include <linux/bug.h> +#include <linux/module.h> +#include <linux/i2c/dimm-bus.h>
drivers/i2c/busses/dimm-bus.c line 27
Quoted 10 lines
drivers/i2c/busses/dimm-bus.c new file +10
-0+ +static bool probe_addr (struct i2c_adapter *adapter,int addr) +{ +/* +* So far, all known devices that live on DIMMs can be safely +* and reliably detected by trying to read a byte at address +* zero. (The exception is the SPD write protection control, +* which can't be probed and requires special hardware and/or +* quick writes to access, and has no driver.) +*/
If the bus is in the middle of any other kind of access or sequence of accesses, it's hard to predict what this will do.
If it's a 512 byte SPD EEPROM and the last page select was to page 1, this will read byte 256 rather than byte 0. The thread needs to do its own set page 0 write to ensure it knows what it is reading.
Quoted 34 lines
drivers/i2c/busses/dimm-bus.c new file +34
-0+union i2c_smbus_data dummy; + +return i2c_smbus_xfer (adapter, addr,0 ,I2C_SMBUS_READ ,0 , +I2C_SMBUS_BYTE_DATA , &dummy) >=0 ; +} + +/** +* i2c_scan_dimm_bus() - Scans an SMBUS segment known to contain DIMMs +* @adapter: The SMBUS adapter to scan +* +* This function tells the DIMM-bus code that the adapter is known to +* contain DIMMs. i2c_scan_dimm_bus will probe for devices known to +* live on DIMMs. +* +* Do NOT call this function on general-purpose system SMBUS segments +* unless you know that the only things on the bus are DIMMs. +* Otherwise is it very likely to mis-identify other things on the +* bus. +* +* Callers are advised not to set adapter->class = I2C_CLASS_SPD to +* avoid having two separate mechanisms trying to automatically claim +* devices on the bus. +*/ +void i2c_scan_dimm_bus (struct i2c_adapter *adapter) +{ +struct i2c_board_info info = {}; +int slot; + +/* +* We probe with "read byte data". If any DIMM SMBUS driver can't +* support that access type, this function should be updated. +*/ +if (WARN_ON (!i2c_check_functionality (adapter, +I2C_FUNC_SMBUS_READ_BYTE_DATA )))
drivers/i2c/busses/dimm-bus.c line 71
Quoted 10 lines
drivers/i2c/busses/dimm-bus.c new file +10
-0+return ; + +/* +* Addresses on DIMMs use the three low bits to identify the slot +* and the four high bits to identify the device type. Known +* devices are: +* +* - 0x50 - 0x57: SPD (Serial Presence Detect) EEPROM +* - 0x30 - 0x37: SPD WP control -- not easy to probe +* - 0x18 - 0x1f: TSOD (Temperature Sensor on DIMM)
In DDR4, you might also encounter:
* 0x10 - 0x17 NVDIMM controller (pre-standard)
* 0x40 - 0x47 NVDIMM controller (JESD245 Byte Addressable Energy Backed Interface)
* 0x58 - 0x5F Registering Clock Driver (RCD) (JEDEC DDR4RCD01)
drivers/i2c/busses/dimm-bus.c line 78
Quoted 7 lines
drivers/i2c/busses/dimm-bus.c new file +7
-0+* +* There's no point in trying to probe the SPD WP control: we'd +* want to probe using quick reads, which i2c-imc doesn't +* support, we don't have a driver for it, we can't really use +* it without special hardware (it's not a normal i2c slave -- +* see the JEDEC docs), and using it risks bricking the DIMM +* it's on anyway.
You do need to write to 0x36 and 0x37 a lot while accessing SPD EEPROMs in DDR4:
* 0x36 selects SPD page 0 (bytes 0-255) on all DIMMs
* 0x37 selects SPD page 1 (bytes 256-511) on all DIMMs
Since the page selects are broadcast, you cannot have independent threads talking to different DIMM SPD EEPROMs unless they're very coordinated.
Quoted 9 lines
drivers/i2c/busses/dimm-bus.c new file +9
-0+* +* NB: There's no need to save the return value from +* i2c_new_device, as the core code will unregister it for us +* when the adapter is removed. If users want to bind a +* different driver, nothing stops them from unbinding the +* drivers we request here. +*/ +for (slot =0 ; slot <8 ; slot++) { +/* If there's no SPD, then assume there's no DIMM here. */
drivers/i2c/busses/dimm-bus.c line 97
Quoted 10 lines
drivers/i2c/busses/dimm-bus.c new file +10
-0+if (!probe_addr (adapter,0x50 | slot)) +continue ; + +strcpy (info.type,"spd" ); + info.addr =0x50 | slot; +i2c_new_device (adapter, &info); + +if (probe_addr (adapter,0x18 | slot)) { +/* This is a temperature sensor. */ +strcpy (info.type,"jc42" );
JC-42 is the name of a JEDEC committee. TSE2004av is "the family of" "Serial Presence Detect (SPD) EEPROMs and Temperature Sensor (TS) as used for memory module applications" in DDR4, defined by JEDEC standard No. 21-C section 4.1.6. The earlier TSE2002av only supported 256 bytes of SPD EEPROM. Since the driver is already called jc42.c, maybe add a comment with the actual standards references.
Re: [PATCH v3 2/2] i2c, i2c_imc: Add DIMM bus code
Quoted 107 lines · Robert (Persistent Memory)
Quoted 93 lines
-----Original Message-----
From: Andy Lutomirski [mailto:[email protected]]
Sent: Thursday, April 28, 2016 8:03 PM
To: Wolfram Sang <[email protected]>; Christoph Hellwig <[email protected]>
Cc: Boaz Harrosh <[email protected]>; One Thousand Gnomes <[email protected]>; Rui Wang <[email protected]>; Jean Delvare <[email protected]>; Alun Evans <[email protected]>; Robert Elliott <[email protected]>; [email protected]; Mauro Carvalho Chehab <[email protected]>; Paul Bolle <[email protected]>; Tony Luck <[email protected]>; [email protected]; Guenter Roeck <[email protected]>; Andy Lutomirski <[email protected]>
Subject: [PATCH v3 2/2] i2c,i2c_imc: Add DIMM bus codeAdd
i2c_scan_dimm_busto declare that a particulari2c_adaptercontains DIMMs. This will probe (and autoload modules!) for useful SMBUS devices that live on DIMMs.i2c_imccalls it.As more SMBUS-addressable DIMM components become supported, this code can be extended to probe for them.
Signed-off-by Andy Lutomirski <[email protected]>--- drivers/i2c/busses/Kconfig | 5 ++ drivers/i2c/busses/Makefile | 4 ++ drivers/i2c/busses/dimm-bus.c | 107 ++++++++++++++++++++++++++++++++++++++++++ drivers/i2c/busses/i2c-imc.c | 3 ++ include/linux/i2c/dimm-bus.h | 20 ++++++++ 5 files changed, 139 insertions(+) create mode 100644 drivers/i2c/busses/dimm-bus.c create mode 100644 include/linux/i2c/dimm-bus.hdrivers/i2c/busses/Kconfig +0
-0@@ -152,9 +152,14 @@ config I2C_ISMT This driver can also be built as a module. If so, the module willbe
called i2c-ismt.drivers/i2c/busses/Kconfig +5
-0+config I2C_DIMM_BUS + tristate + default n + config I2C_IMC tristate "Intel iMC (LGA 2011) SMBus Controller" depends on PCI && X86 + select I2C_DIMM_BUS help If you say yes to this option, support will be included for theIntel
Integrated Memory Controller SMBus host controller interface. Thisdrivers/i2c/busses/Makefile +4
-0@@ -25,6 +25,10 @@ obj-$(CONFIG_I2C_SIS96X) += i2c-sis96x.o obj-$(CONFIG_I2C_VIA) += i2c-via.o obj-$(CONFIG_I2C_VIAPRO) += i2c-viapro.o +# DIMM busses +obj-$(CONFIG_I2C_DIMM_BUS) += dimm-bus.o +obj-$(CONFIG_I2C_IMC) += i2c-imc.o + # Mac SMBus host controller drivers obj-$(CONFIG_I2C_HYDRA) += i2c-hydra.o obj-$(CONFIG_I2C_POWERMAC) += i2c-powermac.odrivers/i2c/busses/dimm-bus.c new file +17
-0@@ -0,0 +1,107 @@ +/* +* Copyright (c) 2013-2016 Andrew Lutomirski <[email protected]> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 +* as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ + +#include <linux/i2c.h> +#include <linux/bug.h> +#include <linux/module.h> +#include <linux/i2c/dimm-bus.h> drivers/i2c/busses/dimm-bus.c line 27
Quoted 10 lines
drivers/i2c/busses/dimm-bus.c new file +10
-0+ +static bool probe_addr (struct i2c_adapter *adapter,int addr) +{ +/* +* So far, all known devices that live on DIMMs can be safely +* and reliably detected by trying to read a byte at address +* zero. (The exception is the SPD write protection control, +* which can't be probed and requires special hardware and/or +* quick writes to access, and has no driver.) +*/ If the bus is in the middle of any other kind of access or sequence of accesses, it's hard to predict what this will do.
Quoted 3 lines
If it's a 512 byte SPD EEPROM and the last page select was to page 1, this will read byte 256 rather than byte 0. The thread needs to do its own set page 0 write to ensure it knows what it is reading.
I'm slightly confused here. Are you saying that this could interfere with a concurrent access or that a concurrent access could interfere with this check? All I'm trying to do is detect whether there's a DIMM in the slot -- I don't particularly care *which* byte of SPD data I end up reading.
In theory, i2c_imc could possibly interrogate the chipset to figure out which slots are populated, but that's tedious and this code seems to work fine, at least on DDR3 systems.
Quoted 16 lines
Quoted 16 lines
drivers/i2c/busses/dimm-bus.c new file +16
-0+void i2c_scan_dimm_bus (struct i2c_adapter *adapter) +{ +struct i2c_board_info info = {}; +int slot; + +/* +* We probe with "read byte data". If any DIMM SMBUS driver can't +* support that access type, this function should be updated. +*/ +if (WARN_ON (!i2c_check_functionality (adapter, +I2C_FUNC_SMBUS_READ_BYTE_DATA ))) +return ; + +/* +* Addresses on DIMMs use the three low bits to identify the slot +* and the four high bits to identify the device type. Known
Quoted 8 lines
drivers/i2c/busses/dimm-bus.c line 71
Quoted 5 lines
drivers/i2c/busses/dimm-bus.c new file +5
-0+* devices are: +* +* - 0x50 - 0x57: SPD (Serial Presence Detect) EEPROM +* - 0x30 - 0x37: SPD WP control -- not easy to probe +* - 0x18 - 0x1f: TSOD (Temperature Sensor on DIMM) In DDR4, you might also encounter:
*0x10-0x17NVDIMM controller (pre-standard)
I would prefer if someone else wrote those couple lines of code for NDA reasons. I could probably get permission to do it, but this doesn't seem worthwhile.
Quoted 1 line
*
0x40-0x47NVDIMM controller (JESD245 Byte Addressable Energy Backed Interface)
Is there an actual linux driver that we should try to bind? If not, we could wait for that driver to get written. From the spec, it looks like this should be found by reading the SPD, not by probing for the I2C slave address.
Given that this is now standard, has anyone figured out how bus arbitration should work? I know how it works on the legacy boards (BIOS gets out of the way; OS is in control, at least if properly configured), but I don't have access to a standards-compliant board.
I updated the comment for the next version.
Quoted 1 line
*
0x58-0x5FRegistering Clock Driver (RCD) (JEDEC DDR4RCD01)
Is this useful for Linux? I couldn't find the spec, maybe because I'm searching JEDEC's site wrong.
Quoted 9 lines
drivers/i2c/busses/dimm-bus.c line 78
Quoted 8 lines
drivers/i2c/busses/dimm-bus.c new file +7
-0+* +* There's no point in trying to probe the SPD WP control: we'd +* want to probe using quick reads, which i2c-imc doesn't +* support, we don't have a driver for it, we can't really use +* it without special hardware (it's not a normal i2c slave -- +* see the JEDEC docs), and using it risks bricking the DIMM +* it's on anyway.
Quoted 7 lines
You do need to write to
0x36and0x37a lot while accessing SPD EEPROMs in DDR4:
*0x36selects SPD page 0 (bytes 0-255) on all DIMMs
*0x37selects SPD page 1 (bytes 256-511) on all DIMMsSince the page selects are broadcast, you cannot have independent threads talking to different DIMM SPD EEPROMs unless they're very coordinated.
Are you talking about the SPD read interface or the SPD write interface? I'm intentionally not trying to probe for the write interface.
Quoted 19 lines
Quoted 19 lines
drivers/i2c/busses/dimm-bus.c new file +18
-0+* +* NB: There's no need to save the return value from +* i2c_new_device, as the core code will unregister it for us +* when the adapter is removed. If users want to bind a +* different driver, nothing stops them from unbinding the +* drivers we request here. +*/ +for (slot =0 ; slot <8 ; slot++) { +/* If there's no SPD, then assume there's no DIMM here. */ +if (!probe_addr (adapter,0x50 | slot)) +continue ; + +strcpy (info.type,"spd" ); + info.addr =0x50 | slot; +i2c_new_device (adapter, &info); + +if (probe_addr (adapter,0x18 | slot)) { +/* This is a temperature sensor. */
Quoted 9 lines
drivers/i2c/busses/dimm-bus.c line 97
Quoted 1 line
drivers/i2c/busses/dimm-bus.c new file +1
-0+strcpy (info.type,"jc42" );JC-42 is the name of a JEDEC committee. TSE2004av is "the family of" "Serial Presence Detect (SPD) EEPROMs and Temperature Sensor (TS) as used for memory module applications" in DDR4, defined by JEDEC standard No. 21-C section 4.1.6. The earlier TSE2002av only supported 256 bytes of SPD EEPROM. Since the driver is already called
jc42.c, maybe add a comment with the actual standards references.
I changed it to:
if (probe_addr(adapter, 0x18 | slot)) {
/*
* This is a temperature sensor. The interface is
* defined in the JEDEC TSE2004av specification.
* Linux's driver for this is called "jc42", which
* is a bit nonsensical (JC-42 is the name of the
* committee, not the sensor).
*/
strcpy(info.type, "jc42");
info.addr = 0x18 | slot;
i2c_new_device(adapter, &info);
}for the next version.
Aside from the comments, are you okay with the code in this file? FWIW, it's not currently possible to use this code with DDR4 AFAIK because there aren't any systems that support both the current incarnation of i2c_imc and DDR4. This could easily change, of course, once someone adds support for newer CPUs.