mirror of
https://github.com/Lurkki14/tuxclocker.git
synced 2025-02-16 14:34:46 -06:00
Implement amd fancurve
This commit is contained in:
parent
192aa5403f
commit
cbce4b07a8
95
amd.cpp
95
amd.cpp
@ -2,6 +2,7 @@
|
||||
#include "gputypes.h"
|
||||
#include <tgmath.h>
|
||||
#include <string.h>
|
||||
#include "mainwindow.h"
|
||||
#include <QThread>
|
||||
#include <QSettings>
|
||||
|
||||
@ -206,6 +207,8 @@ void amd::calculateDisplayValues(int GPUIndex)
|
||||
}
|
||||
QString amd::applySettings(int GPUIndex)
|
||||
{
|
||||
currentGPUIndex = GPUIndex;
|
||||
|
||||
QSettings settings("tuxclocker");
|
||||
settings.beginGroup("General");
|
||||
//settings.setValue("latestUUID", GPUList[GPUIndex].pci_id);
|
||||
@ -223,56 +226,54 @@ QString amd::applySettings(int GPUIndex)
|
||||
bool hadErrors = false;
|
||||
QProcess proc;
|
||||
QString cmd = "pkexec /bin/sh -c \"";
|
||||
/*
|
||||
// Assign fan mode
|
||||
switch (fanModeComboBox->currentIndex()) {
|
||||
case 0:
|
||||
if (!assignGPUFanCtlMode(GPUIndex, false)) {
|
||||
hadErrors = true;
|
||||
errStr.append("Fan mode, ");
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (latestFanSlider != fanSlider->value()) {
|
||||
if (!assignGPUFanCtlMode(GPUIndex, true)) {
|
||||
hadErrors = true;
|
||||
errStr.append("Fan mode, ");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (GPUList[GPUIndex].manualFanCtrlAvailable && latestFanSlider != fanSlider->value()) {
|
||||
if (!assignGPUFanSpeed(GPUIndex, fanSlider->value())) {
|
||||
hadErrors = true;
|
||||
fanSlider->setValue(latestFanSlider);
|
||||
errStr.append("Fan speed, ");
|
||||
}
|
||||
}
|
||||
|
||||
if (GPUList[GPUIndex].powerLimitAvailable && latestpowerLimSlider != powerLimSlider->value()) {
|
||||
if (!assignGPUPowerLimit(GPUIndex, static_cast<uint>(powerLimSlider->value()*1000000))) {
|
||||
hadErrors = true;
|
||||
powerLimSlider->setValue(latestpowerLimSlider);
|
||||
errStr.append("Power limit, ");
|
||||
}
|
||||
}*/
|
||||
// To avoid asking for password in pkexec multiple times, apply everything at once and query what succeeded afterwards
|
||||
int cmdval = 0;
|
||||
int targetValue = 0;
|
||||
qDebug() << fanModeComboBox->currentIndex() << GPUList[GPUIndex].fanControlMode << "box index";
|
||||
// Apply fan settings
|
||||
if (fanModeComboBox->currentIndex() != GPUList[GPUIndex].fanControlMode) {
|
||||
// On custom mode, the mode needs to be set again to load the new points
|
||||
|
||||
if (fanModeComboBox->currentIndex() == 2 || fanModeComboBox->currentIndex() != GPUList[GPUIndex].fanControlMode) {
|
||||
switch (fanModeComboBox->currentIndex()) {
|
||||
case 0:
|
||||
cmd.append("echo '2' > "+GPUList[GPUIndex].hwmonpath+"/pwm1_enable & ");
|
||||
cmd.append("echo '0' > "+GPUList[GPUIndex].hwmonpath+"/pwm1_enable & ");
|
||||
// Disconnect fancurve timer
|
||||
disconnect(fanUpdateTimer, SIGNAL(timeout()), this, SLOT(tempUpdater()));
|
||||
|
||||
break;
|
||||
|
||||
case 1:
|
||||
cmd.append("echo '1' > "+GPUList[GPUIndex].hwmonpath+"/pwm1_enable & ");
|
||||
|
||||
int targetValue = fanSlider->value();
|
||||
targetValue = fanSlider->value();
|
||||
cmdval = static_cast<int>(ceil(targetValue*2.55));
|
||||
cmd.append("echo '"+QString::number(cmdval)+"' > "+GPUList[GPUIndex].hwmonpath+"/pwm1 & ");
|
||||
|
||||
// Disconnect fancurve timer
|
||||
disconnect(fanUpdateTimer, SIGNAL(timeout()), this, SLOT(tempUpdater()));
|
||||
break;
|
||||
|
||||
case 2:
|
||||
cmd.append("echo '1' > "+GPUList[GPUIndex].hwmonpath+"/pwm1_enable & ");
|
||||
// Load the curve points from settings
|
||||
|
||||
QSettings settings("tuxclocker");
|
||||
QString profile = settings.value("currentProfile").toString();
|
||||
QString UUID = settings.value("latestUUID").toString();
|
||||
settings.beginGroup(profile);
|
||||
settings.beginGroup(UUID);
|
||||
int size = settings.beginReadArray("curvepoints");
|
||||
for (int i=0; i<size; i++) {
|
||||
settings.setArrayIndex(i);
|
||||
xCurvePoints.append(settings.value("xpoints").toInt());
|
||||
yCurvePoints.append(settings.value("ypoints").toInt());
|
||||
}
|
||||
settings.endArray();
|
||||
|
||||
disconnect(fanUpdateTimer, SIGNAL(timeout()), this, SLOT(tempUpdater()));
|
||||
// Activate the fan updater
|
||||
connect(fanUpdateTimer, SIGNAL(timeout()), this, SLOT(tempUpdater()));
|
||||
fanUpdateTimer->start(2000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -284,10 +285,11 @@ QString amd::applySettings(int GPUIndex)
|
||||
}
|
||||
|
||||
// Apply power limit
|
||||
if (powerLimSlider->value() != latestpowerLimSlider) {
|
||||
cmd.append("echo '" + QString::number(powerLimSlider->value() * 1000000) +"' > " + GPUList[GPUIndex].hwmonpath + "/power1_cap & ");
|
||||
if (GPUList[GPUIndex].powerLimitAvailable) {
|
||||
if (powerLimSlider->value() != latestpowerLimSlider) {
|
||||
cmd.append("echo '" + QString::number(powerLimSlider->value() * 1000000) +"' > " + GPUList[GPUIndex].hwmonpath + "/power1_cap & ");
|
||||
}
|
||||
}
|
||||
|
||||
// Apply voltage/core clock (highest pstate)
|
||||
if (GPUList[GPUIndex].overClockAvailable) {
|
||||
if ((coreClockSlider->value() != GPUList[GPUIndex].coreclocks.last()) || (voltageSlider->value() != GPUList[GPUIndex].corevolts.last())) {
|
||||
@ -298,6 +300,7 @@ QString amd::applySettings(int GPUIndex)
|
||||
}
|
||||
|
||||
cmd.append("\"");
|
||||
qDebug() << "running cmd " << cmd;
|
||||
proc.start(cmd);
|
||||
proc.waitForFinished(-1);
|
||||
QThread::msleep(200);
|
||||
@ -364,6 +367,8 @@ QString amd::applySettings(int GPUIndex)
|
||||
|
||||
return errStr;
|
||||
} else {
|
||||
GPUList[GPUIndex].fanControlMode = fanModeComboBox->currentIndex();
|
||||
|
||||
latestFanSlider = fanSlider->value();
|
||||
latestMemClkSlider = memClockSlider->value();
|
||||
latestpowerLimSlider = powerLimSlider->value();
|
||||
@ -466,6 +471,7 @@ void amd::queryGPUFeatures()
|
||||
}*/
|
||||
// If the pstate vectors are empty after searching, set the features disabled
|
||||
if (!GPUList[i].corevolts.isEmpty()) GPUList[i].overVoltAvailable = true;
|
||||
else GPUList[i].overVoltAvailable = false;
|
||||
|
||||
if (!GPUList[i].coreclocks.isEmpty()) {
|
||||
GPUList[i].overClockAvailable = true;
|
||||
@ -817,4 +823,13 @@ bool amd::assignGPUPowerLimit(int GPUIndex, uint targetValue)
|
||||
return false;
|
||||
}
|
||||
|
||||
void amd::tempUpdater() {
|
||||
queryGPUTemp(currentGPUIndex);
|
||||
if (!xCurvePoints.isEmpty()) {
|
||||
int targetFanSpeed = generateFanPoint(GPUList[currentGPUIndex].temp / 1000, xCurvePoints, yCurvePoints);
|
||||
qDebug() << "fancurve: setting to" << targetFanSpeed << "%";
|
||||
assignGPUFanSpeed(currentGPUIndex, targetFanSpeed);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
26
gputypes.cpp
26
gputypes.cpp
@ -4,3 +4,29 @@ gputypes::gputypes()
|
||||
{}
|
||||
gputypes::~gputypes()
|
||||
{}
|
||||
|
||||
int gputypes::generateFanPoint(int temp, QVector <int> xPoints, QVector <int> yPoints) {
|
||||
// Calculate the value for fan speed based on temperature
|
||||
// First check if the fan speed should be y[0] or y[final]
|
||||
qDebug("temp: %d", temp);
|
||||
int index = 0;
|
||||
if (temp <= xPoints[0]) {
|
||||
qDebug("ret first point");
|
||||
return yPoints[0];
|
||||
} else if (temp >= xPoints.last()) {
|
||||
qDebug("ret last point %d", xPoints.last());
|
||||
return yPoints.last();
|
||||
} else {
|
||||
// Get the index of the leftmost point of the interpolated interval by comparing it to temperature
|
||||
for (int i=0; i<xPoints.size(); i++) {
|
||||
if (temp >= xPoints[i] && temp <= xPoints[i+1]) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Check if the change in x is zero to avoid dividing by it
|
||||
if (xPoints[index] - xPoints[index + 1] == 0) {
|
||||
return yPoints[index + 1];
|
||||
} else return (((yPoints[index + 1] - yPoints[index]) * (temp - xPoints[index])) / (xPoints[index + 1] - xPoints[index])) + yPoints[index];
|
||||
}
|
||||
}
|
||||
|
15
gputypes.h
15
gputypes.h
@ -147,6 +147,8 @@ public:
|
||||
QLabel *memVoltageLabel;
|
||||
|
||||
QComboBox *fanModeComboBox;
|
||||
|
||||
QTimer *fanUpdateTimer;
|
||||
// Variables to check if a slider has been changed
|
||||
int latestFanSlider;
|
||||
int latestVoltageSlider;
|
||||
@ -155,6 +157,10 @@ public:
|
||||
int latestCoreClkSlider;
|
||||
int latestMemVoltageSlider;
|
||||
|
||||
// Fancurve vectors
|
||||
QVector <int> xCurvePoints, yCurvePoints;
|
||||
// Latest GPU index for the fancurve
|
||||
int currentGPUIndex;
|
||||
#ifdef NVIDIA
|
||||
Display *dpy;
|
||||
nvmlDevice_t *device;
|
||||
@ -192,6 +198,10 @@ public:
|
||||
virtual bool assignGPUMemClockOffset(int GPUIndex, int targetValue) = 0;
|
||||
virtual bool assignGPUVoltageOffset(int GPUIndex, int targetValue) = 0;
|
||||
virtual bool assignGPUPowerLimit(int GPUIndex, uint targetValue) = 0;
|
||||
|
||||
virtual void tempUpdater() = 0;
|
||||
// Return the desired fan percentage
|
||||
int generateFanPoint(int temp, QVector <int> xPoints, QVector <int> yPoints);
|
||||
protected:
|
||||
~gputypes();
|
||||
|
||||
@ -239,6 +249,8 @@ public slots:
|
||||
bool assignGPUVoltageOffset(int GPUIndex, int targetValue);
|
||||
// NVML functions know the GPU index already based on the dev object passed in setupNVML()
|
||||
bool assignGPUPowerLimit(uint targetValue);
|
||||
|
||||
void tempUpdater();
|
||||
private slots:
|
||||
};
|
||||
#endif
|
||||
@ -285,6 +297,9 @@ public slots:
|
||||
bool assignGPUVoltageOffset(int GPUIndex, int targetValue);
|
||||
bool assignGPUPowerLimit(int GPUIndex, uint targetValue);
|
||||
void queryPstates();
|
||||
|
||||
void tempUpdater();
|
||||
|
||||
private slots:
|
||||
};
|
||||
#endif
|
||||
|
@ -50,6 +50,8 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
types->memClockLabel = ui->memClockLabel;
|
||||
|
||||
types->fanModeComboBox = ui->fanModeComboBox;
|
||||
|
||||
types->fanUpdateTimer = fanUpdateTimer;
|
||||
// This is for libxnvctrl
|
||||
types->setupGPU();
|
||||
// This is for NVML
|
||||
|
@ -96,6 +96,7 @@ public:
|
||||
|
||||
bool isRoot = false;
|
||||
public slots:
|
||||
void tempUpdater();
|
||||
|
||||
private slots:
|
||||
|
||||
@ -131,7 +132,6 @@ private slots:
|
||||
void getGPUDriver();
|
||||
void generateFanPoint();
|
||||
void checkForRoot();
|
||||
void tempUpdater();
|
||||
void resetChanges();
|
||||
void resetTimer();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user