Publish LumaOps source
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| DDR5DirectAccessor.cpp |
|
||||
| |
|
||||
| DDR5 SPD accessor implementation using direct i2c |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "DDR5DirectAccessor.h"
|
||||
#include "LogManager.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
DDR5DirectAccessor::DDR5DirectAccessor(i2c_smbus_interface *bus, uint8_t spd_addr)
|
||||
: DDR5Accessor(bus, spd_addr)
|
||||
{
|
||||
}
|
||||
|
||||
DDR5DirectAccessor::~DDR5DirectAccessor()
|
||||
{
|
||||
}
|
||||
|
||||
bool DDR5DirectAccessor::isAvailable(i2c_smbus_interface *bus, uint8_t spd_addr)
|
||||
{
|
||||
bool retry = true;
|
||||
|
||||
while(true)
|
||||
{
|
||||
std::this_thread::sleep_for(SPD_IO_DELAY);
|
||||
int ddr5Magic = bus->i2c_smbus_read_byte_data(spd_addr, 0x00);
|
||||
std::this_thread::sleep_for(SPD_IO_DELAY);
|
||||
int ddr5Sensor = bus->i2c_smbus_read_byte_data(spd_addr, 0x01);
|
||||
std::this_thread::sleep_for(SPD_IO_DELAY);
|
||||
|
||||
if(ddr5Magic < 0 || ddr5Sensor < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
LOG_TRACE("[DDR5DirectAccessor] SPD Hub Magic: 0x%02x 0x%02x", ddr5Magic, ddr5Sensor);
|
||||
|
||||
if(ddr5Magic == 0x51 && (ddr5Sensor & 0xEF) == 0x08)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int page = bus->i2c_smbus_read_byte_data(spd_addr, SPD_DDR5_MREG_VIRTUAL_PAGE);
|
||||
std::this_thread::sleep_for(SPD_IO_DELAY);
|
||||
|
||||
LOG_TRACE("[DDR5DirectAccessor] SPD Page: 0x%02x", page);
|
||||
if(page < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if(retry && page > 0 && page < (SPD_DDR5_EEPROM_LENGTH >> SPD_DDR5_EEPROM_PAGE_SHIFT))
|
||||
{
|
||||
// This still might be a DDR5 module, just the page is off
|
||||
bus->i2c_smbus_write_byte_data(spd_addr, SPD_DDR5_MREG_VIRTUAL_PAGE, 0);
|
||||
std::this_thread::sleep_for(SPD_IO_DELAY);
|
||||
retry = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
SPDAccessor *DDR5DirectAccessor::copy()
|
||||
{
|
||||
DDR5DirectAccessor *access = new DDR5DirectAccessor(bus, address);
|
||||
access->current_page = this->current_page;
|
||||
return access;
|
||||
}
|
||||
|
||||
uint8_t DDR5DirectAccessor::at(uint16_t addr)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Ensure address is valid |
|
||||
\*-----------------------------------------------------*/
|
||||
if(addr >= SPD_DDR5_EEPROM_LENGTH)
|
||||
{
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Switch to the page containing address |
|
||||
\*-----------------------------------------------------*/
|
||||
set_page(addr >> SPD_DDR5_EEPROM_PAGE_SHIFT);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Calculate offset |
|
||||
\*-----------------------------------------------------*/
|
||||
uint8_t offset = (uint8_t)(addr & SPD_DDR5_EEPROM_PAGE_MASK) | 0x80;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Read value at address |
|
||||
\*-----------------------------------------------------*/
|
||||
uint32_t value = bus->i2c_smbus_read_byte_data(address, offset);
|
||||
|
||||
std::this_thread::sleep_for(SPD_IO_DELAY);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Return value |
|
||||
\*-----------------------------------------------------*/
|
||||
return((uint8_t)value);
|
||||
}
|
||||
|
||||
void DDR5DirectAccessor::set_page(uint8_t page)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Switch page if not already active |
|
||||
\*-----------------------------------------------------*/
|
||||
if(current_page != page)
|
||||
{
|
||||
bus->i2c_smbus_write_byte_data(address, SPD_DDR5_MREG_VIRTUAL_PAGE, page);
|
||||
current_page = page;
|
||||
std::this_thread::sleep_for(SPD_IO_DELAY);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user