static ssize_t store_mutex (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int core, time, gpu_count, i; gceSTATUS status = gcvSTATUS_OK; gckHARDWARE hardware; /* count core numbers */ for (i = 0, gpu_count = 0; i < gcdMAX_GPU_COUNT; i++) if (galDevice->kernels[i] != gcvNULL) gpu_count++; /* scan input value and verify */ SYSFS_VERIFY_INPUT(sscanf(buf, "%d,%d", &core, &time), 2); SYSFS_VERIFY_INPUT_RANGE(core, 0, 1); SYSFS_VERIFY_INPUT_RANGE(time, 0, 1000); /* lock recMutexPower for some time */ printk("[pm_test] mutex lock %s core %d\n", (core == gcvCORE_MAJOR)?"3D":"2D", time); hardware = galDevice->kernels[core]->hardware; /* Grab the mutex. */ gcmkONERROR(gckOS_AcquireRecMutex(hardware->os, hardware->recMutexPower, gcvINFINITE)); /* sleep some time */ gcmkONERROR(gckOS_Delay(hardware->os, time)); /* Release the mutex */ gcmkONERROR(gckOS_ReleaseRecMutex(hardware->os, hardware->recMutexPower)); return count; OnError: return (ssize_t)-EINVAL; }
static ssize_t store_clk_rate (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { gceSTATUS status = gcvSTATUS_OK; int core, frequency, i, gpu_count; for (i = 0, gpu_count = 0; i < gcdMAX_GPU_COUNT; i++) if (galDevice->kernels[i] != gcvNULL) gpu_count++; /* read input and verify */ SYSFS_VERIFY_INPUT(sscanf(buf, "%d,%d", &core, &frequency), 2); SYSFS_VERIFY_INPUT_RANGE(core, 0, (gpu_count-1)); SYSFS_VERIFY_INPUT_RANGE(frequency, 156, 624); status = gckOS_SetClkRate(galDevice->os, core, frequency*1000*1000); if(gcmIS_ERROR(status)) { printk("fail to set core[%d] frequency to %d MHZ\n", core, frequency); } return count; }
static ssize_t store_pm_state (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int core, state, i, gpu_count; gceSTATUS status = gcvSTATUS_OK; /* count core numbers */ for (i = 0, gpu_count = 0; i < gcdMAX_GPU_COUNT; i++) if (galDevice->kernels[i] != gcvNULL) gpu_count++; /* read input and verify */ SYSFS_VERIFY_INPUT(sscanf(buf, "%d,%d", &core, &state), 2); SYSFS_VERIFY_INPUT_RANGE(core, 0, (gpu_count-1)); SYSFS_VERIFY_INPUT_RANGE(state, 0, 3); /* power state transition */ status = gckHARDWARE_SetPowerManagementState(galDevice->kernels[core]->hardware, state); if (gcmIS_ERROR(status)) { printk("[%d] failed in transfering power state to %d\n", core, state); } return count; }
static ssize_t store_reset (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int core, gpu_count, i; gceSTATUS status = gcvSTATUS_OK; /* count core numbers */ for (i = 0, gpu_count = 0; i < gcdMAX_GPU_COUNT; i++) if (galDevice->kernels[i] != gcvNULL) gpu_count++; /* scan input value and verify */ SYSFS_VERIFY_INPUT(sscanf(buf, "%d", &core), 1); SYSFS_VERIFY_INPUT_RANGE(core, 0, (gpu_count-1)); /* reset */ printk("[pm_test] reset %s core\n", (core == gcvCORE_MAJOR)?"3D":"2D"); gcmkONERROR(gckKERNEL_Recovery(galDevice->kernels[core])); return count; OnError: return (ssize_t)-EINVAL; }
static ssize_t store_register_stats (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { gctUINT32 core, offset, value; SYSFS_VERIFY_INPUT(sscanf(buf, "%d 0x%x", &core, &offset), 2); SYSFS_VERIFY_INPUT_RANGE(core, 0, gcdMAX_GPU_COUNT - 1); SYSFS_VERIFY_INPUT_RANGE(offset, 0, 0x30001); gcmkVERIFY_OK(gckOS_ReadRegisterEx(galDevice->os, core, offset, &value)); gcmkPRINT("Core(%d) Register[0x%x] value is 0x%08x\n", core, offset, value); return count; }
static ssize_t store_register_stats (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { gctCHAR type[10]; gctUINT32 offset, clkState = 0; gctINT t = ~0; SYSFS_VERIFY_INPUT(sscanf(buf, "%s 0x%x", type, &offset), 2); SYSFS_VERIFY_INPUT_RANGE(offset, 0, 0x30001); if(strstr(type, "default")) { t = 0; } else if(strstr(type, "offset")) { t = 1; } else { gcmkPRINT("Invalid Command~"); return count; } gcmkVERIFY_OK(gckOS_QueryRegisterStats( galDevice->os, t, offset, &clkState)); if(t && clkState) { gcmkPRINT("Some Registers can't be read because of %s disabled", (clkState&0x11)?("External/Internal clk"):((clkState&0x01)?"External":"Internal")); } return count; }
static ssize_t store_show_commands (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int value; SYSFS_VERIFY_INPUT(sscanf(buf, "%d", &value), 1); #if gcdENABLE_VG /* 3D, 2D, 2D&3D, VG. */ SYSFS_VERIFY_INPUT_RANGE(value, 0, 4); #else /* 3D, 2D, 2D&3D. */ SYSFS_VERIFY_INPUT_RANGE(value, 0, 3); #endif galDevice->printPID = value; return count; }
static ssize_t store_control (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned int option, value; SYSFS_VERIFY_INPUT(sscanf(buf, "%u,%u", &option, &value), 2); SYSFS_VERIFY_INPUT_RANGE(option, 0, 1); SYSFS_VERIFY_INPUT_RANGE(value, 0, 1); switch(option) { case 0: if(value == 0) { if(registered_debug) { __remove_sysfs_file_debug(); registered_debug = 0; } } else if(value == 1) { if(registered_debug == 0) { __create_sysfs_file_debug(); registered_debug = 1; } } break; /* case 1: if(value == 0) __disable_gpufreq(galDevice); else if(value == 1) __enable_gpufreq(galDevice); break; */ } return count; }
static ssize_t store_runtime_debug (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int value; SYSFS_VERIFY_INPUT(sscanf(buf, "%d", &value), 1); SYSFS_VERIFY_INPUT_RANGE(value, 0, 2); galDevice->pmrtDebug = value; return count; }
static ssize_t store_poweroff_timeout (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int core, timeout, i, gpu_count; /* count core numbers */ for (i = 0, gpu_count = 0; i < gcdMAX_GPU_COUNT; i++) if (galDevice->kernels[i] != gcvNULL) gpu_count++; /* read input and verify */ SYSFS_VERIFY_INPUT(sscanf(buf, "%d,%d", &core, &timeout), 2); SYSFS_VERIFY_INPUT_RANGE(core, 0, (gpu_count-1)); SYSFS_VERIFY_INPUT_RANGE(timeout, 0, 3600000); gcmkVERIFY_OK(gckHARDWARE_SetPowerOffTimeout( galDevice->kernels[core]->hardware, timeout)); return count; }
static ssize_t store_enable_dvfs (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int core, state, i, gpu_count; /* count core numbers */ for (i = 0, gpu_count = 0; i < gcdMAX_GPU_COUNT; i++) if (galDevice->kernels[i] != gcvNULL) gpu_count++; /* read input and verify */ SYSFS_VERIFY_INPUT(sscanf(buf, "%d,%d", &core, &state), 2); SYSFS_VERIFY_INPUT_RANGE(core, 0, (gpu_count-1)); SYSFS_VERIFY_INPUT_RANGE(state, 0, 2); /* double check kernel object */ if(galDevice->kernels[core] != gcvNULL) galDevice->kernels[core]->hardware->dvfs = state; return count; }
static ssize_t store_clk_rate (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { gceSTATUS status; int core, frequency, i, gpu_count; for (i = 0, gpu_count = 0; i < gcdMAX_GPU_COUNT; i++) if (galDevice->kernels[i] != gcvNULL) gpu_count++; #if MRVL_CONFIG_SHADER_CLK_CONTROL if(has_feat_gc_shader()) gpu_count++; #endif /* read input and verify */ SYSFS_VERIFY_INPUT(sscanf(buf, "%d,%d", &core, &frequency), 2); SYSFS_VERIFY_INPUT_RANGE(core, 0, (gpu_count-1)); SYSFS_VERIFY_INPUT_RANGE(frequency, 156, 624); #if MRVL_CONFIG_SHADER_CLK_CONTROL if(has_feat_gc_shader() && core == gcvCORE_SH) { status = gckOS_SetShClkRate(galDevice->os, frequency*1000*1000); } else #endif { status = gckOS_SetClkRate(galDevice->os, core, frequency*1000*1000); } if(gcmIS_ERROR(status)) { printk("fail to set core[%d] frequency to %d MHZ\n", core, frequency); } return count; }
static ssize_t store_profiling_stats (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int value_count = 0; SYSFS_VERIFY_INPUT(sscanf(buf, "%d", &value_count), 1); SYSFS_VERIFY_INPUT_RANGE(value_count, 5, 50); nodes_count = value_count; return count; }
static ssize_t store_fscale (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int core, fscale, i, gpu_count; for (i = 0, gpu_count = 0; i < gcdMAX_GPU_COUNT; i++) if (galDevice->kernels[i] != gcvNULL) gpu_count++; /* read input and verify */ SYSFS_VERIFY_INPUT(sscanf(buf, "%d,%d", &core, &fscale), 2); SYSFS_VERIFY_INPUT_RANGE(core, 0, (gpu_count-1)); SYSFS_VERIFY_INPUT_RANGE(fscale, 1, 64); #if gcdENABLE_FSCALE_VAL_ADJUST if(galDevice->kernels[core] != gcvNULL) gcmkVERIFY_OK(gckHARDWARE_SetFscaleValue( galDevice->kernels[core]->hardware, fscale)); #endif return count; }
static ssize_t store_dutycycle (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { #if MRVL_PULSE_EATER_COUNT_NUM if(has_feat_pulse_eater_profiler()) { gctBOOL start; gctUINT core; gctUINT32 busyRatio[4], totalTime[4], timeGap = 0; gcePulseEaterDomain domain = gcvPulse_Core; gceSTATUS status = gcvSTATUS_OK; SYSFS_VERIFY_INPUT(sscanf(buf, "%d %d", &start, &core), 2); SYSFS_VERIFY_INPUT_RANGE(start, 0, 1); #if gcdENABLE_VG SYSFS_VERIFY_INPUT_RANGE(core, 0, 2); #else SYSFS_VERIFY_INPUT_RANGE(core, 0, 1); #endif for(; domain < 2; domain++) { status = gckKERNEL_QueryPulseEaterIdleProfile(galDevice->kernels[core], start, domain, busyRatio, &timeGap, totalTime); if(!start && !status) { gctINT i = 0; gcmkPRINT("\n|Domain: %6s totalTime: %8d|", domain ==0 ?"Core":"Shader" ,timeGap); gcmkPRINT("|Freq RunTime| BusyRatio| DutyCycle|\n"); for(; i < gcmCOUNTOF(busyRatio); i++) { gcmkPRINT("|%dM %6u| %8u| %8d%%|\n", i==2?416: 156*(i+1), totalTime[i], busyRatio[i], totalTime[i]==0?0: ((100*((gctINT)busyRatio[i]))/(gctINT)totalTime[i])); } } else if(status) { switch(status) { case gcvSTATUS_INVALID_ARGUMENT: printk("Invalidate argument: %d, cat /sys/../dutycycle for more info\n", status); break; case gcvSTATUS_INVALID_REQUEST: printk("Statistics has started alreay, echo 0 x > /sys/.../dutycycle to stop it\n"); break; default: printk("cat /sys/../dutycycle for more info, status: %d\n", status); } } } } else #endif { printk("Oops, %s is under working\n", __func__); } return count; }
static ssize_t store_power_state (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int state, core, broadcast, gpu_count, i; gceSTATUS status = gcvSTATUS_OK; gctUINT32 tgid; /* count ocre numbers */ for (i=0, gpu_count = 0; i < gcdMAX_GPU_COUNT; i++) if (galDevice->kernels[i] != gcvNULL) gpu_count++; /* scan input value and verify */ SYSFS_VERIFY_INPUT(sscanf(buf, "%d,%d,%d", &state, &core, &broadcast), 3); SYSFS_VERIFY_INPUT_RANGE(state, 0, 2); SYSFS_VERIFY_INPUT_RANGE(core, 0, (gpu_count-1)); SYSFS_VERIFY_INPUT_RANGE(broadcast, 0, 1); gckOS_GetProcessID(&tgid); switch (state) { case 0: /* on */ printk("[pm_test %d] %s core power state on\n", tgid, (core == gcvCORE_MAJOR)?"3D":"2D"); if (broadcast) /* noting done here */ gcmkONERROR(gckOS_Broadcast(galDevice->kernels[core]->os, galDevice->kernels[core]->hardware, gcvBROADCAST_FIRST_PROCESS)); else gcmkONERROR(gckHARDWARE_SetPowerManagementState(galDevice->kernels[core]->hardware, gcvPOWER_ON)); printk("[pm_test %d] %s core power state on - done\n", tgid, (core == gcvCORE_MAJOR)?"3D":"2D"); break; case 1: /* off */ printk("[pm_test %d] %s core power state off\n", tgid, (core == gcvCORE_MAJOR)?"3D":"2D"); if (broadcast) gcmkONERROR(gckOS_Broadcast(galDevice->kernels[core]->os, galDevice->kernels[core]->hardware, gcvBROADCAST_LAST_PROCESS)); else gcmkONERROR(gckHARDWARE_SetPowerManagementState(galDevice->kernels[core]->hardware, gcvPOWER_OFF)); printk("[pm_test %d] %s core power state off - done\n", tgid, (core == gcvCORE_MAJOR)?"3D":"2D"); break; case 2: /* suspend */ printk("[pm_test %d] %s core power state suspend\n", tgid, (core == gcvCORE_MAJOR)?"3D":"2D"); if (broadcast) gcmkONERROR(gckOS_Broadcast(galDevice->kernels[core]->os, galDevice->kernels[core]->hardware, gcvBROADCAST_GPU_IDLE)); else gcmkONERROR(gckHARDWARE_SetPowerManagementState(galDevice->kernels[core]->hardware, gcvPOWER_SUSPEND)); printk("[pm_test %d] %s core power state suspend - done\n", tgid, (core == gcvCORE_MAJOR)?"3D":"2D"); break; default: break; } return count; OnError: printk("[pm_test %d] %s core power state %s - bail out\n", tgid, (core == gcvCORE_MAJOR)?"3D":"2D", (state==1)?"off":"on"); return (ssize_t)-EINVAL; }
static ssize_t store_freq (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int core, scale, gpu_count, i; gceSTATUS status = gcvSTATUS_OK; gckHARDWARE hardware; /* count core numbers */ for (i = 0, gpu_count = 0; i < gcdMAX_GPU_COUNT; i++) if (galDevice->kernels[i] != gcvNULL) gpu_count++; /* scan input value and verify */ SYSFS_VERIFY_INPUT(sscanf(buf, "%d,%d", &core, &scale), 2); SYSFS_VERIFY_INPUT_RANGE(core, 0, (gpu_count-1)); SYSFS_VERIFY_INPUT_RANGE(scale, 1, 64); /* internal frequency scaling */ printk("[pm_test] freq %s core 1/%d\n", (core == gcvCORE_MAJOR)?"3D":"2D", scale); hardware = galDevice->kernels[core]->hardware; switch (scale) { case 1: /* frequency change to full speed */ gcmkONERROR(gckOS_WriteRegisterEx(hardware->os, hardware->core, 0x00000, 0x300)); /* Loading the frequency scaler. */ gcmkONERROR(gckOS_WriteRegisterEx(hardware->os, hardware->core, 0x00000, 0x100)); break; case 2: /* frequency change to 1/2 speed */ gcmkONERROR(gckOS_WriteRegisterEx(hardware->os, hardware->core, 0x00000, 0x280)); /* Loading the frequency scaler. */ gcmkONERROR(gckOS_WriteRegisterEx(hardware->os, hardware->core, 0x00000, 0x080)); break; case 4: /* frequency change to 1/4 speed */ gcmkONERROR(gckOS_WriteRegisterEx(hardware->os, hardware->core, 0x00000, 0x240)); /* Loading the frequency scaler. */ gcmkONERROR(gckOS_WriteRegisterEx(hardware->os, hardware->core, 0x00000, 0x040)); break; case 8: /* frequency change to 1/8 speed */ gcmkONERROR(gckOS_WriteRegisterEx(hardware->os, hardware->core, 0x00000, 0x220)); /* Loading the frequency scaler. */ gcmkONERROR(gckOS_WriteRegisterEx(hardware->os, hardware->core, 0x00000, 0x020)); break; case 16: /* frequency change to 1/16 speed */ gcmkONERROR(gckOS_WriteRegisterEx(hardware->os, hardware->core, 0x00000, 0x210)); /* Loading the frequency scaler. */ gcmkONERROR(gckOS_WriteRegisterEx(hardware->os, hardware->core, 0x00000, 0x010)); break; case 32: /* frequency change to 1/32 speed */ gcmkONERROR(gckOS_WriteRegisterEx(hardware->os, hardware->core, 0x00000, 0x208)); /* Loading the frequency scaler. */ gcmkONERROR(gckOS_WriteRegisterEx(hardware->os, hardware->core, 0x00000, 0x008)); break; case 64: /* frequency change to 1/64 speed */ gcmkONERROR(gckOS_WriteRegisterEx(hardware->os, hardware->core, 0x00000, 0x204)); /* Loading the frequency scaler. */ gcmkONERROR(gckOS_WriteRegisterEx(hardware->os, hardware->core, 0x00000, 0x004)); break; default: gcmkPRINT("[pm_test]: freq unknown scaler\n"); break; } return count; OnError: return (ssize_t)-EINVAL; }