static IMG_VOID DvfsChange(int freq /* MHz */) { PVRSRV_ERROR err; if(freq == GetCurrentFreq()) { return; } mutex_lock(&private_data.dvfs_lock); err = PVRSRVDevicePreClockSpeedChange(0, IMG_TRUE, NULL); if(err == PVRSRV_OK) { if(GetCurrentFreq() <= vf_data.normal.freq) { if(freq <= vf_data.normal.freq) { if(GetCurrentVol() != vf_data.normal.vol) { SetGpuVol(vf_data.normal.vol); } } else { if(GetCurrentVol() != vf_data.extreme.vol) { SetGpuVol(vf_data.extreme.vol); } } SetClkVal(freq); } else { if(freq <= vf_data.normal.freq) { SetClkVal(freq); if(GetCurrentVol() != vf_data.normal.vol) { SetGpuVol(vf_data.normal.vol); } } else { if(GetCurrentVol() != vf_data.extreme.vol) { SetGpuVol(vf_data.extreme.vol); } SetClkVal(freq); } } PVRSRVDevicePostClockSpeedChange(0, IMG_TRUE, NULL); } mutex_unlock(&private_data.dvfs_lock); }
IMG_VOID RgxSunxiInit(IMG_VOID) { ParseFexPara(); rgx_regulator = regulator_get(NULL, "axp22_dcdc2"); if (IS_ERR(rgx_regulator)) { printk(KERN_ERR "Failed to get rgx regulator \n"); rgx_regulator = NULL; } gpu_core_clk = clk_get(NULL, GPUCORE_CLK); gpu_mem_clk = clk_get(NULL, GPUMEM_CLK); gpu_axi_clk = clk_get(NULL, GPUAXI_CLK); gpu_pll_clk = clk_get(NULL, PLL9_CLK); SetGpuVol(min_vf_level_val); SetClkVal("pll", vf_table[min_vf_level_val][1]); SetClkVal("core", vf_table[min_vf_level_val][1]); SetClkVal("mem", vf_table[min_vf_level_val][1]); SetClkVal("axi", AXI_CLK_FREQ); RgxResume(); #ifdef CONFIG_CPU_BUDGET_THERMAL register_budget_cooling_notifier(&rgx_throttle_notifier); #endif /* CONFIG_CPU_BUDGET_THERMAL */ printk(KERN_INFO "Sunxi init successfully\n"); }
IMG_VOID RgxSunxiInit(IMG_VOID) { ParseFexPara(); rgx_regulator = regulator_get(NULL, regulator_id); if (IS_ERR(rgx_regulator)) { PVR_DPF((PVR_DBG_ERROR, "Failed to get rgx regulator!")); rgx_regulator = NULL; return; } gpu_core_clk = clk_get(NULL, GPUCORE_CLK); gpu_mem_clk = clk_get(NULL, GPUMEM_CLK); gpu_axi_clk = clk_get(NULL, GPUAXI_CLK); gpu_pll_clk = clk_get(NULL, PLL9_CLK); gpu_ctrl_clk = clk_get(NULL, GPU_CTRL); SetGpuVol(min_vf_level_val); SetClkVal("pll", vf_table[min_vf_level_val][1]); SetClkVal("core", vf_table[min_vf_level_val][1]); SetClkVal("mem", vf_table[min_vf_level_val][1]); SetClkVal("axi", AXI_CLK_FREQ); RgxResume(); #ifdef CONFIG_CPU_BUDGET_THERMAL register_budget_cooling_notifier(&rgx_throttle_notifier); #endif /* CONFIG_CPU_BUDGET_THERMAL */ }
static IMG_VOID RgxDvfsChange(int vf_level, int up_flag) { PVRSRVDevicePreClockSpeedChange(0, IMG_TRUE, NULL); printk(KERN_INFO "RGX DVFS begin\n"); if(up_flag == 1) { SetGpuVol(vf_level); SetClkVal("pll", vf_table[vf_level][1]); } else { SetClkVal("pll", vf_table[vf_level][1]); SetGpuVol(vf_level); } printk(KERN_INFO "RGX DVFS end\n"); PVRSRVDevicePostClockSpeedChange(0, IMG_TRUE, NULL); }
static IMG_VOID RgxDvfsChange(int vf_level, int up_flag) { PVRSRV_ERROR err; err = PVRSRVDevicePreClockSpeedChange(0, IMG_TRUE, NULL); if(err == PVRSRV_OK) { if(up_flag == 1) { SetGpuVol(vf_level); SetClkVal("pll", vf_table[vf_level][1]); } else { SetClkVal("pll", vf_table[vf_level][1]); SetGpuVol(vf_level); } PVRSRVDevicePostClockSpeedChange(0, IMG_TRUE, NULL); } }
static void SGXDvfsChange(u32 vf_level) { PVRSRV_ERROR err; err = PVRSRVDevicePreClockSpeedChange(0, IMG_TRUE, NULL); if(err == PVRSRV_OK) { if(vf_level < dvfs_level) { /* if changing to a lower level, reduce frequency firstly and then reduce voltage */ if(SetGpuFreq(vf_level)) { goto post; } if(SetGpuVol(vf_level)) { SetGpuFreq(dvfs_level); goto post; } } else if(vf_level > dvfs_level) { /* if changing to a higher level, reduce voltage firstly and then reduce frequency */ if(SetGpuVol(vf_level)) { goto post; } if(SetGpuFreq(vf_level)) { SetGpuVol(dvfs_level); goto post; } } else { /* here means the level to be is the same as dvfs_level, just do noting */ goto post; } dvfs_level = vf_level; post: PVRSRVDevicePostClockSpeedChange(0, IMG_TRUE, NULL); } }
static ssize_t VoltageStore(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { PVRSRV_ERROR err; unsigned long vol; err = strict_strtoul(buf, 10, &vol); if (err) { PVR_DPF((PVR_DBG_ERROR, "Invalid parameter!\n")); goto out; } mutex_lock(&private_data.dvfs_lock); err = PVRSRVDevicePreClockSpeedChange(0, IMG_TRUE, NULL); if(err == PVRSRV_OK) { SetGpuVol(vol); PVRSRVDevicePostClockSpeedChange(0, IMG_TRUE, NULL); } mutex_unlock(&private_data.dvfs_lock); out: return count; }
/*! ****************************************************************************** @Function EnableSystemClocks @Description Setup up the clocks for the graphics device to work. @Return PVRSRV_ERROR ******************************************************************************/ PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData) { SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; PVR_TRACE(("EnableSystemClocks: Enabling System Clocks")); if (!psSysSpecData->bSysClocksOneTimeInit) { if(NULL != private_data.regulator_id) { private_data.regulator = regulator_get(NULL,private_data.regulator_id); if (IS_ERR(private_data.regulator)) { PVR_DPF((PVR_DBG_ERROR, "Failed to get gpu regulator!")); } } if(regulator_enable(private_data.regulator)) { PVR_DPF((PVR_DBG_ERROR, "Failed to enable gpu external power!")); } #ifdef CONFIG_CPU_BUDGET_THERMAL private_data.tempctrl_data.count = sizeof(tf_table)/sizeof(tf_table[0]); #endif /* CONFIG_CPU_BUDGET_THERMAL */ ParseFex(); private_data.max_freq = vf_data.extreme.freq; GetGpuClk(); SetGpuClkParent(); SetGpuVol(vf_data.normal.vol); SetClkVal(vf_data.normal.freq); mutex_init(&psSysSpecData->sPowerLock); atomic_set(&psSysSpecData->sSGXClocksEnabled, 0); psSysSpecData->bSysClocksOneTimeInit = IMG_TRUE; mutex_init(&private_data.dvfs_lock); sysfs_create_group(&gpsPVRLDMDev->dev.kobj, &gpu_attribute_group); #ifdef CONFIG_CPU_BUDGET_THERMAL register_budget_cooling_notifier(&gpu_throttle_notifier); #endif /* CONFIG_CPU_BUDGET_THERMAL */ } EnableGpuPower(); /* Delay for gpu power stability */ mdelay(2); /* Set gpu power off gating invalid */ SetBit(private_data.poweroff_gate.bit, 0, private_data.poweroff_gate.addr); DeAssertGpuResetSignal(); return PVRSRV_OK; }