mirror of
https://github.com/CalcProgrammer1/OpenRGB.git
synced 2025-12-23 23:37:48 -05:00
141 lines
5.0 KiB
C++
141 lines
5.0 KiB
C++
/*---------------------------------------------------------*\
|
|
| SPDDetector.cpp |
|
|
| |
|
|
| Detector for DRAM modules using SPD information |
|
|
| |
|
|
| This file is part of the OpenRGB project |
|
|
| SPDX-License-Identifier: GPL-2.0-or-later |
|
|
\*---------------------------------------------------------*/
|
|
|
|
#include "DDR4DirectAccessor.h"
|
|
#include "DDR5DirectAccessor.h"
|
|
#include "LogManager.h"
|
|
#include "SPDDetector.h"
|
|
|
|
#ifdef __linux__
|
|
#include "EE1004Accessor_Linux.h"
|
|
#include "SPD5118Accessor_Linux.h"
|
|
#endif
|
|
|
|
SPDDetector::SPDDetector(i2c_smbus_interface *bus, uint8_t address, SPDMemoryType mem_type = SPD_RESERVED)
|
|
: bus(bus), address(address), mem_type(mem_type), valid(false)
|
|
{
|
|
detect_memory_type();
|
|
}
|
|
|
|
bool SPDDetector::is_valid() const
|
|
{
|
|
return(valid);
|
|
}
|
|
|
|
SPDMemoryType SPDDetector::memory_type() const
|
|
{
|
|
return(mem_type);
|
|
}
|
|
|
|
void SPDDetector::detect_memory_type()
|
|
{
|
|
SPDAccessor *accessor;
|
|
|
|
/*---------------------------------------------------------*\
|
|
| On Linux, attempt to use the ee1004 or spd5118 drivers to |
|
|
| access SPD on DDR4 and DDR5, respectively |
|
|
\*---------------------------------------------------------*/
|
|
#ifdef __linux__
|
|
if(EE1004Accessor::isAvailable(bus, address))
|
|
{
|
|
LOG_DEBUG("[SPDDetector] Probing DRAM using EE1004 Accessor on bus %d, address 0x%02x", bus->bus_id, address);
|
|
accessor = new EE1004Accessor(bus, address);
|
|
}
|
|
else if(SPD5118Accessor::isAvailable(bus, address))
|
|
{
|
|
LOG_DEBUG("[SPDDetector] Probing DRAM using SPD5118 Accessor on bus %d, address 0x%02x", bus->bus_id, address);
|
|
accessor = new SPD5118Accessor(bus, address);
|
|
}
|
|
else
|
|
#endif
|
|
/*---------------------------------------------------------*\
|
|
| Otherwise, access the SPD using a direct accessor using |
|
|
| i2c for DDR4 and DDR5 |
|
|
\*---------------------------------------------------------*/
|
|
if((mem_type == SPD_RESERVED
|
|
|| mem_type == SPD_DDR4_SDRAM
|
|
|| mem_type == SPD_DDR4E_SDRAM
|
|
|| mem_type == SPD_LPDDR4_SDRAM
|
|
|| mem_type == SPD_LPDDR4X_SDRAM)
|
|
&& DDR4DirectAccessor::isAvailable(bus, address))
|
|
{
|
|
LOG_DEBUG("[SPDDetector] Probing DRAM using DDR4 Direct Accessor on bus %d, address 0x%02x", bus->bus_id, address);
|
|
accessor = new DDR4DirectAccessor(bus, address);
|
|
}
|
|
else if((mem_type == SPD_RESERVED
|
|
|| mem_type == SPD_DDR5_SDRAM
|
|
|| mem_type == SPD_LPDDR5_SDRAM)
|
|
&& DDR5DirectAccessor::isAvailable(bus, address))
|
|
{
|
|
LOG_DEBUG("[SPDDetector] Probing DRAM using DDR5 Direct Accessor on bus %d, address 0x%02x", bus->bus_id, address);
|
|
accessor = new DDR5DirectAccessor(bus, address);
|
|
}
|
|
/*---------------------------------------------------------*\
|
|
| Otherwise, probe the SPD directly using i2c, probably an |
|
|
| older system than DDR4 |
|
|
\*---------------------------------------------------------*/
|
|
else if(mem_type == SPD_RESERVED)
|
|
{
|
|
LOG_DEBUG("[SPDDetector] Probing DRAM older than DDR4 on bus %d, address 0x%02x", bus->bus_id, address);
|
|
|
|
int value = bus->i2c_smbus_read_byte_data(address, 0x02);
|
|
|
|
if(value < 0)
|
|
{
|
|
valid = false;
|
|
}
|
|
else
|
|
{
|
|
mem_type = (SPDMemoryType)value;
|
|
|
|
/*-------------------------------------------------*\
|
|
| We are only interested in DDR4 and DDR5 systems |
|
|
\*-------------------------------------------------*/
|
|
valid = (mem_type == SPD_DDR4_SDRAM
|
|
|| mem_type == SPD_DDR4E_SDRAM
|
|
|| mem_type == SPD_LPDDR4_SDRAM
|
|
|| mem_type == SPD_LPDDR4X_SDRAM
|
|
|| mem_type == SPD_DDR5_SDRAM
|
|
|| mem_type == SPD_LPDDR5_SDRAM);
|
|
}
|
|
|
|
return;
|
|
}
|
|
/*---------------------------------------------------------*\
|
|
| If memory type could not be determined, detection failed |
|
|
\*---------------------------------------------------------*/
|
|
else
|
|
{
|
|
LOG_DEBUG("[SPDDetector] Memory type could not be determined for bus %d, address 0x%02x", bus->bus_id, address);
|
|
valid = false;
|
|
return;
|
|
}
|
|
|
|
/*---------------------------------------------------------*\
|
|
| If an accessor was created, save the memory type |
|
|
\*---------------------------------------------------------*/
|
|
valid = true;
|
|
mem_type = accessor->memory_type();
|
|
|
|
/*---------------------------------------------------------*\
|
|
| Delete the accessor |
|
|
\*---------------------------------------------------------*/
|
|
delete accessor;
|
|
}
|
|
|
|
uint8_t SPDDetector::spd_address() const
|
|
{
|
|
return(this->address);
|
|
}
|
|
|
|
i2c_smbus_interface *SPDDetector::smbus() const
|
|
{
|
|
return(this->bus);
|
|
}
|