Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 992b2484 authored by DevelLevel's avatar DevelLevel Committed by Bernhard Thoben
Browse files

Voltage Control

parent d3b5d119
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -649,3 +649,4 @@ CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y
CONFIG_QMI_ENCDEC=y
CONFIG_STRICT_MEMORY_RWX=y
CONFIG_CPU_VOLTAGE_CONTROL=y
+83 −0
Original line number Diff line number Diff line
@@ -1084,6 +1084,89 @@ static struct mux_clk cpu_debug_mux = {
	},
};

#ifdef CONFIG_CPU_VOLTAGE_CONTROL
extern int cpr_regulator_get_corner_voltage(struct regulator *regulator,
		int corner);
extern int cpr_regulator_set_corner_voltage(struct regulator *regulator,
		int corner, int volt);

ssize_t cpu_clock_get_vdd(char *buf)
{
	ssize_t count = 0;
	int i, uv;

	if (!buf)
		return 0;

	for (i = 1; i < a53_clk.c.num_fmax; i++) {
		uv = cpr_regulator_get_corner_voltage(
					a53_clk.c.vdd_class->regulator[0],
					a53_clk.c.vdd_class->vdd_uv[i]);
		if (uv < 0)
			return 0;
		count += sprintf(buf + count, "A53: %lumhz: %d mV\n",
					a53_clk.c.fmax[i] / 1000000,
					uv / 1000);
	}

	for (i = 1; i < a57_clk.c.num_fmax; i++) {
		uv = cpr_regulator_get_corner_voltage(
					a57_clk.c.vdd_class->regulator[0],
					a57_clk.c.vdd_class->vdd_uv[i]);
		if (uv < 0)
			return 0;
		count += sprintf(buf + count, "A57: %lumhz: %d mV\n",
					a57_clk.c.fmax[i] / 1000000,
					uv / 1000);
	}

	return count;
}

ssize_t cpu_clock_set_vdd(const char *buf, size_t count)
{
	int i, mv, ret;
	char line[32];

	if (!buf)
		return -EINVAL;

	for (i = 1; i < a53_clk.c.num_fmax; i++) {
		ret = sscanf(buf, "%d", &mv);
		if (ret != 1)
			return -EINVAL;

		ret = cpr_regulator_set_corner_voltage(
					a53_clk.c.vdd_class->regulator[0],
					a53_clk.c.vdd_class->vdd_uv[i],
					mv * 1000);
        if (ret < 0)
			return ret;

        ret = sscanf(buf, "%s", line);
		buf += strlen(line) + 1;
	}

	for (i = 1; i < a57_clk.c.num_fmax; i++) {
		ret = sscanf(buf, "%d", &mv);
		if (ret != 1)
			return -EINVAL;

		ret = cpr_regulator_set_corner_voltage(
					a57_clk.c.vdd_class->regulator[0],
					a57_clk.c.vdd_class->vdd_uv[i],
					mv * 1000);
        if (ret < 0)
			return ret;

        ret = sscanf(buf, "%s", line);
		buf += strlen(line) + 1;
	}

	return count;
}
#endif

static struct clk *logical_cpu_to_clk(int cpu)
{
	struct device_node *cpu_node = of_get_cpu_node(cpu, NULL);
+23 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
#include <linux/slab.h>
#include <linux/syscore_ops.h>
#include <linux/tick.h>
#include <linux/pm_opp.h>
#include <trace/events/power.h>

/**
@@ -633,6 +634,22 @@ static ssize_t show_bios_limit(struct cpufreq_policy *policy, char *buf)
	return sprintf(buf, "%u\n", policy->cpuinfo.max_freq);
}

#ifdef CONFIG_CPU_VOLTAGE_CONTROL
extern ssize_t cpu_clock_get_vdd(char *buf);
extern ssize_t cpu_clock_set_vdd(const char *buf, size_t count);

static ssize_t show_UV_mV_table(struct cpufreq_policy *policy, char *buf)
{
	return cpu_clock_get_vdd(buf);
}

static ssize_t store_UV_mV_table(struct cpufreq_policy *policy,
	const char *buf, size_t count)
{
	return cpu_clock_set_vdd(buf, count);
}
#endif

cpufreq_freq_attr_ro_perm(cpuinfo_cur_freq, 0400);
cpufreq_freq_attr_ro(cpuinfo_min_freq);
cpufreq_freq_attr_ro(cpuinfo_max_freq);
@@ -647,6 +664,9 @@ cpufreq_freq_attr_rw(scaling_min_freq);
cpufreq_freq_attr_rw(scaling_max_freq);
cpufreq_freq_attr_rw(scaling_governor);
cpufreq_freq_attr_rw(scaling_setspeed);
#ifdef CONFIG_CPU_VOLTAGE_CONTROL
cpufreq_freq_attr_rw(UV_mV_table);
#endif

static struct attribute *default_attrs[] = {
	&cpuinfo_min_freq.attr,
@@ -660,6 +680,9 @@ static struct attribute *default_attrs[] = {
	&scaling_driver.attr,
	&scaling_available_governors.attr,
	&scaling_setspeed.attr,
#ifdef CONFIG_CPU_VOLTAGE_CONTROL
	&UV_mV_table.attr,
#endif
	NULL
};

+6 −0
Original line number Diff line number Diff line
@@ -629,5 +629,11 @@ config SOMC_LCD_OCP_ENABLED
	bool "enable SoMC LCD OCP function"
	help
	  Select this to enable SoMC LCD Over current protection function.
	  
config CPU_VOLTAGE_CONTROL
	bool "Enable CPU voltage control"
	help
	  Enable CPU voltage control for MSM8994.

endif
+30 −0
Original line number Diff line number Diff line
@@ -1096,6 +1096,36 @@ static struct regulator_ops cpr_corner_ops = {
	.get_voltage		= cpr_regulator_get_voltage,
};

#ifdef CONFIG_CPU_VOLTAGE_CONTROL
int cpr_regulator_get_corner_voltage(struct regulator *regulator,
		int corner)
{
	struct cpr_regulator *cpr_vreg = regulator_get_drvdata(regulator);

	if (corner >= CPR_CORNER_MIN && corner <= cpr_vreg->num_corners)
		return cpr_vreg->last_volt[corner];

	return -EINVAL;
}

int cpr_regulator_set_corner_voltage(struct regulator *regulator,
		int corner, int volt)
{
	struct cpr_regulator *cpr_vreg = regulator_get_drvdata(regulator);

	if (corner >= CPR_CORNER_MIN && corner <= cpr_vreg->num_corners) {
		mutex_lock(&cpr_vreg->cpr_mutex);
		cpr_vreg->last_volt[corner] = volt;
		cpr_vreg->ceiling_volt[corner] = volt;
		cpr_vreg->floor_volt[corner] = volt - 200000;
		mutex_unlock(&cpr_vreg->cpr_mutex);
		return 0;
	}

	return -EINVAL;
}
#endif

#ifdef CONFIG_PM
static int cpr_suspend(struct cpr_regulator *cpr_vreg)
{