Detect dual GPU cards by iterating through all GPUs, finding ones without fanspeed and matching twins with fanspeed one bus ID apart.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
diff --git a/adl.c b/adl.c
index 0470445..3c6450d 100644
--- a/adl.c
+++ b/adl.c
@@ -92,9 +92,22 @@ static inline void unlock_adl(void)
mutex_unlock(&adl_lock);
}
+/* This looks for the twin GPU that has the fanspeed control of a non fanspeed
+ * control GPU on dual GPU cards */
+static inline bool fanspeed_twin(struct gpu_adl *ga, struct gpu_adl *other_ga)
+{
+ if (!other_ga->has_fanspeed)
+ return false;
+ if (abs(ga->iBusNumber - other_ga->iBusNumber) != 1)
+ return false;
+ if (strcmp(ga->strAdapterName, other_ga->strAdapterName))
+ return false;
+ return true;
+}
+
void init_adl(int nDevs)
{
- int i, j, devices = 0, last_adapter = -1, gpu = 0, dummy = 0, prev_id = -1, prev_gpu = -1;
+ int i, j, devices = 0, last_adapter = -1, gpu = 0, dummy = 0;
#if defined (LINUX)
hDLL = dlopen( "libatiadlxx.so", RTLD_LAZY|RTLD_GLOBAL);
@@ -233,6 +246,7 @@ void init_adl(int nDevs)
ga->gpu = gpu;
ga->iAdapterIndex = iAdapterIndex;
ga->lpAdapterID = lpAdapterID;
+ strcpy(ga->strAdapterName, lpInfo[i].strAdapterName);
ga->DefPerfLev = NULL;
ga->twin = NULL;
@@ -307,21 +321,11 @@ void init_adl(int nDevs)
ga->iEngineClock = lpOdPerformanceLevels->aLevels[lev].iEngineClock;
ga->iMemoryClock = lpOdPerformanceLevels->aLevels[lev].iMemoryClock;
ga->iVddc = lpOdPerformanceLevels->aLevels[lev].iVddc;
+ ga->iBusNumber = lpInfo[i].iBusNumber;
- if (ADL_Overdrive5_FanSpeedInfo_Get(iAdapterIndex, 0, &ga->lpFanSpeedInfo) != ADL_OK) {
+ if (ADL_Overdrive5_FanSpeedInfo_Get(iAdapterIndex, 0, &ga->lpFanSpeedInfo) != ADL_OK)
applog(LOG_INFO, "Failed to ADL_Overdrive5_FanSpeedInfo_Get");
- /* This is our opportunity to detect the 2nd GPU in a
- * dual GPU device with a fan controller only on the
- * first */
- if (prev_id >= 0 &&
- !strcmp(lpInfo[i].strAdapterName, lpInfo[prev_id].strAdapterName) &&
- lpInfo[i].iBusNumber == lpInfo[prev_id].iBusNumber + 1 &&
- gpus[prev_gpu].adl.has_fanspeed) {
- applog(LOG_INFO, "2nd GPU of dual card device detected");
- ga->twin = &gpus[prev_gpu].adl;
- gpus[prev_gpu].adl.twin = ga;
- }
- } else
+ else
ga->has_fanspeed = true;
/* Save the fanspeed values as defaults in case we reset later */
@@ -358,9 +362,31 @@ void init_adl(int nDevs)
ga->managed = true;
}
ga->lasttemp = __gpu_temp(ga);
+ }
- prev_id = i;
- prev_gpu = gpu;
+ /* Search for twin GPUs on a single card. They will be separated by one
+ * bus id and one will have fanspeed while the other won't. */
+ for (gpu = 0; gpu < devices; gpu++) {
+ struct gpu_adl *ga = &gpus[gpu].adl;
+ int j;
+
+ if (ga->has_fanspeed)
+ continue;
+
+ for (j = 0; j < devices; j++) {
+ struct gpu_adl *other_ga;
+
+ if (j == gpu)
+ continue;
+ other_ga = &gpus[j].adl;
+ if (fanspeed_twin(ga, other_ga)) {
+ applog(LOG_INFO, "Dual GPUs detected: %d and %d",
+ ga->gpu, other_ga->gpu);
+ ga->twin = other_ga;
+ other_ga->twin = ga;
+ break;
+ }
+ }
}
}
diff --git a/miner.h b/miner.h
index 5006064..88a7fd3 100644
--- a/miner.h
+++ b/miner.h
@@ -197,6 +197,8 @@ struct gpu_adl {
ADLTemperature lpTemperature;
int iAdapterIndex;
int lpAdapterID;
+ int iBusNumber;
+ char strAdapterName[256];
ADLPMActivity lpActivity;
ADLODParameters lpOdParameters;