/* * Copyright (C) 2011-2012 sakuramilk <c.sakuramilk@gmail.com> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.sakuramilk.TweakGS2.GpuControl; import java.util.ArrayList; import android.content.Context; import net.sakuramilk.util.RootProcess; import net.sakuramilk.util.SettingManager; import net.sakuramilk.util.SysFs; public class GpuControlSetting extends SettingManager { public static final String KEY_ROOT_PREF = "root_pref"; public static final String KEY_GPU_FREQ_BASE = "gpu_freq_step"; public static final String KEY_GPU_VOLT_BASE = "gpu_volt_step"; public static final String KEY_GPU_THRESHOLD_BASE = "gpu_threshold_step"; public static final String KEY_GPU_SET_ON_BOOT = "gpu_set_on_boot"; public static final int FREQ_MIN = 10; public static final int FREQ_MAX = 800; public static final int THRESHOLD_MAX = 100; public static final int THRESHOLD_MIN = 1; public static final int VOLT_MIN = 800000 / 1000; public static final int VOLT_MAX = 1200000 / 1000; public static final int FREQ_STEP = 1; public static final int VOLT_STEP = 1; private final SysFs mSysFsClkCtrl = new SysFs("/sys/devices/virtual/misc/gpu_clock_control/gpu_control"); private final SysFs mSysFsVoltCtrl = new SysFs("/sys/devices/virtual/misc/gpu_voltage_control/gpu_control"); public GpuControlSetting(Context context, RootProcess rootProcess) { super(context, rootProcess); } public GpuControlSetting(Context context) { this(context, null); } public boolean isEnableFreqCtrl() { return mSysFsClkCtrl.exists(); } public Integer[] getFreqs() { ArrayList<Integer> ret = new ArrayList<Integer>(); String[] values = mSysFsClkCtrl.readMuitiLine(mRootProcess); for (String value : values) { if (value.indexOf("Step") >= 0) { String[] v = value.split(" "); ret.add(Integer.parseInt(v[1])); } } return ret.toArray(new Integer[0]); } public void setFreqs(Integer[] freqs) { String values = String.valueOf(freqs[0]); for (int i = 1; i < freqs.length; i++) { values += " " + String.valueOf(freqs[i]); } mSysFsClkCtrl.write(values, mRootProcess); } public Integer[] getThresholds() { ArrayList<Integer> ret = new ArrayList<Integer>(); String[] values = mSysFsClkCtrl.readMuitiLine(mRootProcess); for (String value : values) { if (value.indexOf("Threshold") >= 0) { String[] v = value.replace("%", "").split(" "); ret.add(Integer.parseInt(v[1])); ret.add(Integer.parseInt(v[2])); } } return ret.toArray(new Integer[0]); } public void setThresholds(Integer[] thresholds) { String values = String.valueOf(thresholds[0] == 100 ? thresholds[0] : thresholds[0] + 1) + "%"; for (int i = 1; i < thresholds.length; i++) { values += " " + String.valueOf(thresholds[i] == 100 ? thresholds[i] : thresholds[i] + 1) + "%"; } mSysFsClkCtrl.write(values, mRootProcess); } public Integer[] loadFreqs() { String value = null; int i = 0; ArrayList<Integer> ret = new ArrayList<Integer>(); while (true) { value = getStringValue(KEY_GPU_FREQ_BASE + i, null); if (value == null) { break; } ret.add(Integer.parseInt(value)); i++; } if (ret.size() > 0) { return ret.toArray(new Integer[0]); } return null; } public void saveFreqs(Integer[] freqs) { for (int i = 0; i < freqs.length ; i++) { setValue(KEY_GPU_FREQ_BASE + i, String.valueOf(freqs[i])); } } public Integer[] loadThresholds() { String value = null; int i = 0; ArrayList<Integer> ret = new ArrayList<Integer>(); while (true) { value = getStringValue(KEY_GPU_THRESHOLD_BASE + i, null); if (value == null) { break; } ret.add(Integer.parseInt(value)); i++; } if (ret.size() > 0) { return ret.toArray(new Integer[0]); } return null; } public void saveThresholds(Integer[] freqs) { for (int i = 0; i < freqs.length ; i++) { setValue(KEY_GPU_THRESHOLD_BASE + i, String.valueOf(freqs[i])); } } public boolean isEnableVoltageCtrl() { return mSysFsVoltCtrl.exists(); } public Integer[] getVolts() { ArrayList<Integer> ret = new ArrayList<Integer>(); String[] values = mSysFsVoltCtrl.readMuitiLine(mRootProcess); for (String value : values) { String[] v = value.split(" "); ret.add(Integer.parseInt(v[1]) / 1000); } return ret.toArray(new Integer[0]); } public void setVolts(Integer[] volts) { String values = String.valueOf(volts[0] * 1000); for (int i = 1; i < volts.length; i++) { values += " " + String.valueOf(volts[i] * 1000); } mSysFsVoltCtrl.write(values, mRootProcess); } public Integer[] loadVolts() { String value = null; int i = 0; ArrayList<Integer> ret = new ArrayList<Integer>(); while (true) { value = getStringValue(KEY_GPU_VOLT_BASE + i, null); if (value == null) { break; } ret.add(Integer.parseInt(value)); i++; } if (ret.size() > 0) { return ret.toArray(new Integer[0]); } return null; } public void saveVolts(Integer[] volts) { for (int i = 0; i < volts.length ; i++) { setValue(KEY_GPU_VOLT_BASE + i, String.valueOf(volts[i])); } } public boolean loadSetOnBoot() { return getBooleanValue(KEY_GPU_SET_ON_BOOT); } public void saveSetOnBoot(boolean setOnBoot) { setValue(KEY_GPU_SET_ON_BOOT, setOnBoot); } @Override public void setOnBoot() { if (!loadSetOnBoot()) { return; } if (isEnableVoltageCtrl()) { Integer[] volts = loadVolts(); if (volts != null) { Integer[] curVolts = getVolts(); if (curVolts.length != volts.length) { reset(); return; } setVolts(volts); } } if (isEnableFreqCtrl()) { Integer[] freqs = loadFreqs(); if (freqs != null) { setFreqs(freqs); } Integer[] thresholds = loadThresholds(); if (thresholds != null && thresholds.length != 0) { setThresholds(thresholds); } } } @Override public void setRecommend() { // noop } @Override public void reset() { int i = 0; while (true) { String value = getStringValue(KEY_GPU_FREQ_BASE + i, null); if (value == null) { break; } clearValue(KEY_GPU_FREQ_BASE + i); i++; } i = 0; while (true) { String value = getStringValue(KEY_GPU_VOLT_BASE + i, null); if (value == null) { break; } clearValue(KEY_GPU_VOLT_BASE + i); i++; } i = 0; while (true) { String value = getStringValue(KEY_GPU_THRESHOLD_BASE + i, null); if (value == null) { break; } clearValue(KEY_GPU_THRESHOLD_BASE + i); i++; } clearValue(KEY_GPU_SET_ON_BOOT); } }