Browse Source

nvapi: sample i2c rvb led color (gigabyte)

you can now use --led=0xFF00FF to change the color/level (windows only)

for non-rvb standard nvidia devices, you can use a level value (0 to 100)

ps: i really need to find how to turn them off on linux, not found yet...
2upstream
Tanguy Pruvot 9 years ago
parent
commit
d3976cf38d
  1. 19
      ccminer.cpp
  2. 24
      compat/nvapi/nvapi_ccminer.h
  3. 22
      nvapi.cpp
  4. 82
      nvml.cpp

19
ccminer.cpp

@ -130,6 +130,7 @@ uint32_t device_mem_clocks[MAX_GPUS] = { 0 };
uint32_t device_plimit[MAX_GPUS] = { 0 }; uint32_t device_plimit[MAX_GPUS] = { 0 };
uint8_t device_tlimit[MAX_GPUS] = { 0 }; uint8_t device_tlimit[MAX_GPUS] = { 0 };
int8_t device_pstate[MAX_GPUS] = { -1, -1 }; int8_t device_pstate[MAX_GPUS] = { -1, -1 };
int32_t device_led[MAX_GPUS] = { -1, -1 };
int opt_cudaschedule = -1; int opt_cudaschedule = -1;
static bool opt_keep_clocks = false; static bool opt_keep_clocks = false;
@ -307,7 +308,8 @@ Options:\n\
--mem-clock=3505 Set the gpu memory boost clock\n\ --mem-clock=3505 Set the gpu memory boost clock\n\
--gpu-clock=1150 Set the gpu engine boost clock\n\ --gpu-clock=1150 Set the gpu engine boost clock\n\
--plimit=100 Set the gpu power limit in percentage\n\ --plimit=100 Set the gpu power limit in percentage\n\
--tlimit=80 Set the gpu thermal limit in degrees\n" --tlimit=80 Set the gpu thermal limit in degrees\n\
--led=100 Set the logo led level (0=disable, 0xFF00FF for RVB)\n"
#endif #endif
#ifdef HAVE_SYSLOG_H #ifdef HAVE_SYSLOG_H
"\ "\
@ -385,6 +387,7 @@ struct option options[] = {
{ "plimit", 1, NULL, 1073 }, { "plimit", 1, NULL, 1073 },
{ "keep-clocks", 0, NULL, 1074 }, { "keep-clocks", 0, NULL, 1074 },
{ "tlimit", 1, NULL, 1075 }, { "tlimit", 1, NULL, 1075 },
{ "led", 1, NULL, 1080 },
#ifdef HAVE_SYSLOG_H #ifdef HAVE_SYSLOG_H
{ "syslog", 0, NULL, 'S' }, { "syslog", 0, NULL, 'S' },
{ "syslog-prefix", 1, NULL, 1018 }, { "syslog-prefix", 1, NULL, 1018 },
@ -2693,6 +2696,7 @@ void parse_arg(int key, char *arg)
hnvml = nvml_create(); hnvml = nvml_create();
#ifdef WIN32 #ifdef WIN32
nvapi_init(); nvapi_init();
cuda_devicenames(); // req for leds
nvapi_init_settings(); nvapi_init_settings();
#endif #endif
#endif #endif
@ -2948,6 +2952,18 @@ void parse_arg(int key, char *arg)
} }
} }
break; break;
case 1080: /* --led */
{
char *pch = strtok(arg,",");
int n = 0;
while (pch != NULL && n < MAX_GPUS) {
int dev_id = device_map[n++];
char * p = strstr(pch, "0x");
device_led[dev_id] = p ? (int32_t) strtoul(p, NULL, 16) : atoi(arg);
pch = strtok(NULL, ",");
}
}
break;
case 1005: case 1005:
opt_benchmark = true; opt_benchmark = true;
want_longpoll = false; want_longpoll = false;
@ -3320,6 +3336,7 @@ int main(int argc, char *argv[])
device_texturecache[i] = -1; device_texturecache[i] = -1;
device_singlememory[i] = -1; device_singlememory[i] = -1;
device_pstate[i] = -1; device_pstate[i] = -1;
device_led[i] = -1;
} }
cuda_devicenames(); cuda_devicenames();

24
compat/nvapi/nvapi_ccminer.h

@ -224,7 +224,6 @@ typedef struct {
NVAPI_GPU_PERF_STATUS; // 1360 bytes (1-0550) NVAPI_GPU_PERF_STATUS; // 1360 bytes (1-0550)
#define NVAPI_GPU_PERF_STATUS_VER MAKE_NVAPI_VERSION(NVAPI_GPU_PERF_STATUS, 1) #define NVAPI_GPU_PERF_STATUS_VER MAKE_NVAPI_VERSION(NVAPI_GPU_PERF_STATUS, 1)
NvAPI_Status NvAPI_DLL_GetInterfaceVersionString(NvAPI_ShortString string); NvAPI_Status NvAPI_DLL_GetInterfaceVersionString(NvAPI_ShortString string);
NvAPI_Status NvAPI_DLL_PerfPoliciesGetInfo(NvPhysicalGpuHandle, NVAPI_GPU_PERF_INFO*); // 409D9841 1-004c NvAPI_Status NvAPI_DLL_PerfPoliciesGetInfo(NvPhysicalGpuHandle, NVAPI_GPU_PERF_INFO*); // 409D9841 1-004c
@ -260,7 +259,6 @@ NvAPI_Status NvAPI_DLL_GetSerialNumber(NvPhysicalGpuHandle handle, NvAPI_ShortSt
NvAPI_Status NvAPI_DLL_SetPstates20v1(NvPhysicalGpuHandle handle, NV_GPU_PERF_PSTATES20_INFO_V1 *pSet); NvAPI_Status NvAPI_DLL_SetPstates20v1(NvPhysicalGpuHandle handle, NV_GPU_PERF_PSTATES20_INFO_V1 *pSet);
NvAPI_Status NvAPI_DLL_SetPstates20v2(NvPhysicalGpuHandle handle, NV_GPU_PERF_PSTATES20_INFO_V2 *pSet); NvAPI_Status NvAPI_DLL_SetPstates20v2(NvPhysicalGpuHandle handle, NV_GPU_PERF_PSTATES20_INFO_V2 *pSet);
NvAPI_Status NvAPI_DLL_Unload(); NvAPI_Status NvAPI_DLL_Unload();
#define NV_ASSERT(x) { NvAPI_Status ret = x; if(ret != NVAPI_OK) return ret; } #define NV_ASSERT(x) { NvAPI_Status ret = x; if(ret != NVAPI_OK) return ret; }
@ -277,3 +275,25 @@ NvAPI_Status NvAPI_DLL_Unload();
var = (TYPE*) calloc(1, TYPE##_VER & 0xFFFF); \ var = (TYPE*) calloc(1, TYPE##_VER & 0xFFFF); \
if (var) var->version = TYPE##_VER; \ if (var) var->version = TYPE##_VER; \
} }
//! Used in NvAPI_I2CReadEx()
typedef struct
{
NvU32 version;
NvU32 displayMask; // Display Mask of the concerned display.
NvU8 bIsDDCPort; // indicates either the DDC port (TRUE) or the communication port (FALSE) of the concerned display.
NvU8 i2cDevAddress; // address of the I2C slave. The address should be shifted left by one. 0x50 -> 0xA0.
NvU8* pbI2cRegAddress; // I2C target register address. May be NULL, which indicates no register address should be sent.
NvU32 regAddrSize; // size in bytes of target register address. If pbI2cRegAddress is NULL, this field must be 0.
NvU8* pbData; // buffer of data which is to be read or written (depending on the command).
NvU32 cbRead; // bytes to read ??? seems required on write too
NvU32 cbSize; // full size of the data buffer, pbData, to be read or written.
NV_I2C_SPEED i2cSpeedKhz; // target speed of the transaction in (kHz) (Chosen from the enum NV_I2C_SPEED).
NvU8 portId; // portid on which device is connected (remember to set bIsPortIdSet if this value is set)
NvU32 bIsPortIdSet; // set this flag on if and only if portid value is set
} NV_I2C_INFO_EX;
#define NV_I2C_INFO_EX_VER MAKE_NVAPI_VERSION(NV_I2C_INFO_EX,3)
NvAPI_Status NvAPI_DLL_I2CReadEx(NvPhysicalGpuHandle, NV_I2C_INFO_EX*, NvU32*);
NvAPI_Status NvAPI_DLL_I2CWriteEx(NvPhysicalGpuHandle, NV_I2C_INFO_EX*, NvU32*);

22
nvapi.cpp

@ -347,6 +347,28 @@ NvAPI_Status NvAPI_DLL_GetVoltages(NvPhysicalGpuHandle handle, NVAPI_VOLTAGES_TA
return (*pointer)(handle, pInfo); return (*pointer)(handle, pInfo);
} }
#define NVAPI_ID_I2CREADEX 0x4D7B0709 // 3-002c
NvAPI_Status NvAPI_DLL_I2CReadEx(NvPhysicalGpuHandle handle, NV_I2C_INFO_EX *i2c, NvU32 *exData) {
static NvAPI_Status (*pointer)(NvPhysicalGpuHandle, NV_I2C_INFO_EX*, NvU32*) = NULL;
if(!nvapi_dll_loaded) return NVAPI_API_NOT_INITIALIZED;
if(!pointer) {
pointer = (NvAPI_Status (*)(NvPhysicalGpuHandle, NV_I2C_INFO_EX*, NvU32*))nvidia_handle->query(NVAPI_ID_I2CREADEX);
}
if(!pointer) return NVAPI_NO_IMPLEMENTATION;
return (*pointer)(handle, i2c, exData);
}
#define NVAPI_ID_I2CWRITEEX 0x283AC65A
NvAPI_Status NvAPI_DLL_I2CWriteEx(NvPhysicalGpuHandle handle, NV_I2C_INFO_EX *i2c, NvU32 *exData) {
static NvAPI_Status (*pointer)(NvPhysicalGpuHandle, NV_I2C_INFO_EX*, NvU32 *exData) = NULL;
if(!nvapi_dll_loaded) return NVAPI_API_NOT_INITIALIZED;
if(!pointer) {
pointer = (NvAPI_Status (*)(NvPhysicalGpuHandle, NV_I2C_INFO_EX*, NvU32 *exData))nvidia_handle->query(NVAPI_ID_I2CWRITEEX);
}
if(!pointer) return NVAPI_NO_IMPLEMENTATION;
return (*pointer)(handle, i2c, exData);
}
#define NVAPI_ID_UNLOAD 0xD22BDD7E #define NVAPI_ID_UNLOAD 0xD22BDD7E
NvAPI_Status NvAPI_DLL_Unload() { NvAPI_Status NvAPI_DLL_Unload() {
static NvAPI_Status (*pointer)() = NULL; static NvAPI_Status (*pointer)() = NULL;

82
nvml.cpp

@ -37,6 +37,7 @@ extern uint32_t device_mem_clocks[MAX_GPUS];
extern uint32_t device_plimit[MAX_GPUS]; extern uint32_t device_plimit[MAX_GPUS];
extern uint8_t device_tlimit[MAX_GPUS]; extern uint8_t device_tlimit[MAX_GPUS];
extern int8_t device_pstate[MAX_GPUS]; extern int8_t device_pstate[MAX_GPUS];
extern int32_t device_led[MAX_GPUS];
uint32_t clock_prev[MAX_GPUS] = { 0 }; uint32_t clock_prev[MAX_GPUS] = { 0 };
uint32_t clock_prev_mem[MAX_GPUS] = { 0 }; uint32_t clock_prev_mem[MAX_GPUS] = { 0 };
@ -954,6 +955,63 @@ int nvapi_getbios(unsigned int devNum, char *desc, unsigned int maxlen)
return 0; return 0;
} }
static int SetGigabyteRVBLogo(unsigned int devNum, uint32_t RVB)
{
NvAPI_Status ret;
NV_I2C_INFO_EX* i2cInfo;
NV_INIT_STRUCT_ALLOC(NV_I2C_INFO_EX, i2cInfo);
if (i2cInfo == NULL)
return -ENOMEM;
NvU32 readBuf[25] = { 0 };
NvU32 data[5] = { 0 };
data[0] = 1; // block count or i2c send ?
data[2] = swab32(RVB & 0xfcfcfcU) | 0x40;
i2cInfo->i2cDevAddress = 0x90;
i2cInfo->pbI2cRegAddress = (NvU8*) (&data[2]);
i2cInfo->regAddrSize = 4; // NVAPI_MAX_SIZEOF_I2C_REG_ADDRESS
i2cInfo->pbData = (NvU8*) readBuf;
i2cInfo->cbRead = 2;
i2cInfo->cbSize = sizeof(readBuf);
i2cInfo->portId = 1;
i2cInfo->bIsPortIdSet = 1;
//ret = NvAPI_DLL_I2CWriteEx(phys[devNum], i2cInfo, data);
ret = NvAPI_DLL_I2CReadEx(phys[devNum], i2cInfo, data);
free(i2cInfo);
return (int) ret;
}
int nvapi_set_led(unsigned int devNum, int32_t RVB, char *device_name)
{
uint16_t vid = 0, pid = 0;
NvAPI_Status ret;
if (strstr(device_name, "Gigabyte GTX 10")) {
return SetGigabyteRVBLogo(devNum, (uint32_t) RVB);
} else {
NV_GPU_QUERY_ILLUMINATION_SUPPORT_PARM* illu;
NV_INIT_STRUCT_ALLOC(NV_GPU_QUERY_ILLUMINATION_SUPPORT_PARM, illu);
illu->hPhysicalGpu = phys[devNum];
illu->Attribute = NV_GPU_IA_LOGO_BRIGHTNESS;
ret = NvAPI_GPU_QueryIlluminationSupport(illu);
if (!ret && illu->bSupported) {
NV_GPU_GET_ILLUMINATION_PARM *led;
NV_INIT_STRUCT_ALLOC(NV_GPU_GET_ILLUMINATION_PARM, led);
led->hPhysicalGpu = phys[devNum];
led->Attribute = NV_GPU_IA_LOGO_BRIGHTNESS;
NvAPI_GPU_GetIllumination(led);
if (opt_debug)
applog(LOG_DEBUG, " Led level was %u, set to %06x", RVB);
led->Value = (uint32_t) RVB;
ret = NvAPI_GPU_SetIllumination((NV_GPU_SET_ILLUMINATION_PARM*) led);
free(led);
}
free(illu);
return ret;
}
}
int nvapi_pstateinfo(unsigned int devNum) int nvapi_pstateinfo(unsigned int devNum)
{ {
uint32_t n; uint32_t n;
@ -1193,23 +1251,6 @@ int nvapi_pstateinfo(unsigned int devNum)
ret = NvAPI_DLL_PerfPoliciesGetStatus(phys[devNum], &ps); ret = NvAPI_DLL_PerfPoliciesGetStatus(phys[devNum], &ps);
applog(LOG_BLUE, "%llx %lld. %lld. %llx %llx %llx", ps.timeRef, ps.val1, ps.val2, ps.values[0], ps.values[1], ps.values[2]); applog(LOG_BLUE, "%llx %lld. %lld. %llx %llx %llx", ps.timeRef, ps.val1, ps.val2, ps.values[0], ps.values[1], ps.values[2]);
#endif #endif
// led test
NV_GPU_QUERY_ILLUMINATION_SUPPORT_PARM* illu;
NV_INIT_STRUCT_ON(NV_GPU_QUERY_ILLUMINATION_SUPPORT_PARM, illu, mem);
illu->hPhysicalGpu = phys[devNum];
illu->Attribute = NV_GPU_IA_LOGO_BRIGHTNESS;
ret = NvAPI_GPU_QueryIlluminationSupport(illu);
if (!ret && illu->bSupported) {
NV_GPU_GET_ILLUMINATION_PARM led = { 0 };
led.version = NV_GPU_GET_ILLUMINATION_PARM_VER;
led.hPhysicalGpu = phys[devNum];
led.Attribute = NV_GPU_IA_LOGO_BRIGHTNESS;
NvAPI_GPU_GetIllumination(&led);
applog(LOG_RAW, " Led level is %u", led.Value);
//applog(LOG_RAW, " Led level was %u, power off", led.Value);
//led.Value = 0;
//ret = NvAPI_GPU_SetIllumination((NV_GPU_SET_ILLUMINATION_PARM*) &led);
}
#endif #endif
free(mem); free(mem);
@ -1484,6 +1525,10 @@ int nvapi_init_settings()
if (ret != NVAPI_OK) if (ret != NVAPI_OK)
return ret; return ret;
if (!opt_n_threads) {
opt_n_threads = active_gpus;
}
for (int n=0; n < opt_n_threads; n++) { for (int n=0; n < opt_n_threads; n++) {
int dev_id = device_map[n % MAX_GPUS]; int dev_id = device_map[n % MAX_GPUS];
if (device_plimit[dev_id]) { if (device_plimit[dev_id]) {
@ -1514,6 +1559,9 @@ int nvapi_init_settings()
if (device_pstate[dev_id]) { if (device_pstate[dev_id]) {
// dunno how via nvapi or/and pascal // dunno how via nvapi or/and pascal
} }
if (device_led[dev_id] != -1) {
nvapi_set_led(nvapi_dev_map[dev_id], device_led[dev_id], device_name[dev_id]);
}
} }
return ret; return ret;

Loading…
Cancel
Save