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

Commit b168adbc authored by Jordan Crouse's avatar Jordan Crouse Committed by Stephen Boyd
Browse files

msm: kgsl: Remove msm-dcvs pwrscale driver



The msm-dcvs pwrscale driver is no longer in development. Remove it to
avoid bitrot and simplify future target development.

Change-Id: Ic0dedbad81c2afb4bfbb377ee1a2330e115c0e71
Signed-off-by: default avatarJordan Crouse <jcrouse@codeaurora.org>
parent 8efdb49a
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@ msm_kgsl_core-$(CONFIG_MSM_KGSL_CFF_DUMP) += kgsl_cffdump.o
msm_kgsl_core-$(CONFIG_MSM_KGSL_DRM) += kgsl_drm.o
msm_kgsl_core-$(CONFIG_MSM_SCM) += kgsl_pwrscale_trustzone.o
msm_kgsl_core-$(CONFIG_MSM_SLEEP_STATS_DEVICE) += kgsl_pwrscale_idlestats.o
msm_kgsl_core-$(CONFIG_MSM_DCVS) += kgsl_pwrscale_msm.o
msm_kgsl_core-$(CONFIG_SYNC) += kgsl_sync.o

msm_adreno-y += \
+0 −178
Original line number Diff line number Diff line
@@ -23,8 +23,6 @@
#include <mach/socinfo.h>
#include <mach/msm_bus_board.h>
#include <mach/msm_bus.h>
#include <mach/msm_dcvs.h>
#include <mach/msm_dcvs_scm.h>

#include "kgsl.h"
#include "kgsl_pwrscale.h"
@@ -1281,172 +1279,6 @@ done:

}

static struct msm_dcvs_core_info *adreno_of_get_dcvs(struct device_node *parent)
{
	struct device_node *node, *child;
	struct msm_dcvs_core_info *info = NULL;
	int count = 0;
	int ret = -EINVAL;

	node = adreno_of_find_subnode(parent, "qcom,dcvs-core-info");
	if (node == NULL)
		return ERR_PTR(-EINVAL);

	info = kzalloc(sizeof(*info), GFP_KERNEL);

	if (info == NULL) {
		KGSL_CORE_ERR("kzalloc(%d) failed\n", sizeof(*info));
		ret = -ENOMEM;
		goto err;
	}

	for_each_child_of_node(node, child)
		count++;

	info->power_param.num_freq = count;

	info->freq_tbl = kzalloc(info->power_param.num_freq *
			sizeof(struct msm_dcvs_freq_entry),
			GFP_KERNEL);

	if (info->freq_tbl == NULL) {
		KGSL_CORE_ERR("kzalloc(%d) failed\n",
			info->power_param.num_freq *
			sizeof(struct msm_dcvs_freq_entry));
		ret = -ENOMEM;
		goto err;
	}

	for_each_child_of_node(node, child) {
		unsigned int index;

		if (adreno_of_read_property(child, "reg", &index))
			goto err;

		if (index >= info->power_param.num_freq) {
			KGSL_CORE_ERR("DCVS freq entry %d is out of range\n",
				index);
			continue;
		}

		if (adreno_of_read_property(child, "qcom,freq",
			&info->freq_tbl[index].freq))
			goto err;

		if (adreno_of_read_property(child, "qcom,voltage",
			&info->freq_tbl[index].voltage))
			info->freq_tbl[index].voltage = 0;

		if (adreno_of_read_property(child, "qcom,is_trans_level",
			&info->freq_tbl[index].is_trans_level))
			info->freq_tbl[index].is_trans_level = 0;

		if (adreno_of_read_property(child, "qcom,active-energy-offset",
			&info->freq_tbl[index].active_energy_offset))
			info->freq_tbl[index].active_energy_offset = 0;

		if (adreno_of_read_property(child, "qcom,leakage-energy-offset",
			&info->freq_tbl[index].leakage_energy_offset))
			info->freq_tbl[index].leakage_energy_offset = 0;
	}

	if (adreno_of_read_property(node, "qcom,num-cores", &info->num_cores))
		goto err;

	info->sensors = kzalloc(info->num_cores *
			sizeof(int),
			GFP_KERNEL);

	for (count = 0; count < info->num_cores; count++) {
		if (adreno_of_read_property(node, "qcom,sensors",
			&(info->sensors[count])))
			goto err;
	}

	if (adreno_of_read_property(node, "qcom,core-core-type",
		&info->core_param.core_type))
		goto err;

	if (adreno_of_read_property(node, "qcom,algo-disable-pc-threshold",
		&info->algo_param.disable_pc_threshold))
		goto err;
	if (adreno_of_read_property(node, "qcom,algo-em-win-size-min-us",
		&info->algo_param.em_win_size_min_us))
		goto err;
	if (adreno_of_read_property(node, "qcom,algo-em-win-size-max-us",
		&info->algo_param.em_win_size_max_us))
		goto err;
	if (adreno_of_read_property(node, "qcom,algo-em-max-util-pct",
		&info->algo_param.em_max_util_pct))
		goto err;
	if (adreno_of_read_property(node, "qcom,algo-group-id",
		&info->algo_param.group_id))
		goto err;
	if (adreno_of_read_property(node, "qcom,algo-max-freq-chg-time-us",
		&info->algo_param.max_freq_chg_time_us))
		goto err;
	if (adreno_of_read_property(node, "qcom,algo-slack-mode-dynamic",
		&info->algo_param.slack_mode_dynamic))
		goto err;
	if (adreno_of_read_property(node, "qcom,algo-slack-weight-thresh-pct",
		&info->algo_param.slack_weight_thresh_pct))
		goto err;
	if (adreno_of_read_property(node, "qcom,algo-slack-time-min-us",
		&info->algo_param.slack_time_min_us))
		goto err;
	if (adreno_of_read_property(node, "qcom,algo-slack-time-max-us",
		&info->algo_param.slack_time_max_us))
		goto err;
	if (adreno_of_read_property(node, "qcom,algo-ss-win-size-min-us",
		&info->algo_param.ss_win_size_min_us))
		goto err;
	if (adreno_of_read_property(node, "qcom,algo-ss-win-size-max-us",
		&info->algo_param.ss_win_size_max_us))
		goto err;
	if (adreno_of_read_property(node, "qcom,algo-ss-util-pct",
		&info->algo_param.ss_util_pct))
		goto err;
	if (adreno_of_read_property(node, "qcom,algo-ss-no-corr-below-freq",
		&info->algo_param.ss_no_corr_below_freq))
		goto err;

	if (adreno_of_read_property(node, "qcom,energy-active-coeff-a",
		&info->energy_coeffs.active_coeff_a))
		goto err;
	if (adreno_of_read_property(node, "qcom,energy-active-coeff-b",
		&info->energy_coeffs.active_coeff_b))
		goto err;
	if (adreno_of_read_property(node, "qcom,energy-active-coeff-c",
		&info->energy_coeffs.active_coeff_c))
		goto err;
	if (adreno_of_read_property(node, "qcom,energy-leakage-coeff-a",
		&info->energy_coeffs.leakage_coeff_a))
		goto err;
	if (adreno_of_read_property(node, "qcom,energy-leakage-coeff-b",
		&info->energy_coeffs.leakage_coeff_b))
		goto err;
	if (adreno_of_read_property(node, "qcom,energy-leakage-coeff-c",
		&info->energy_coeffs.leakage_coeff_c))
		goto err;
	if (adreno_of_read_property(node, "qcom,energy-leakage-coeff-d",
		&info->energy_coeffs.leakage_coeff_d))
		goto err;

	if (adreno_of_read_property(node, "qcom,power-current-temp",
		&info->power_param.current_temp))
		goto err;

	return info;

err:
	if (info)
		kfree(info->freq_tbl);

	kfree(info);

	return ERR_PTR(ret);
}

static int adreno_of_get_iommu(struct device_node *parent,
	struct kgsl_device_platform_data *pdata)
{
@@ -1588,12 +1420,6 @@ static int adreno_of_get_pdata(struct platform_device *pdev)
		goto err;
	}

	pdata->core_info = adreno_of_get_dcvs(pdev->dev.of_node);
	if (IS_ERR_OR_NULL(pdata->core_info)) {
		ret = PTR_ERR(pdata->core_info);
		goto err;
	}

	ret = adreno_of_get_iommu(pdev->dev.of_node, pdata);
	if (ret)
		goto err;
@@ -1606,10 +1432,6 @@ static int adreno_of_get_pdata(struct platform_device *pdev)

err:
	if (pdata) {
		if (pdata->core_info)
			kfree(pdata->core_info->freq_tbl);
		kfree(pdata->core_info);

		if (pdata->iommu_data)
			kfree(pdata->iommu_data->iommu_ctxs);

+0 −3
Original line number Diff line number Diff line
@@ -47,9 +47,6 @@ static struct kgsl_pwrscale_policy *kgsl_pwrscale_policies[] = {
#endif
#ifdef CONFIG_MSM_SLEEP_STATS_DEVICE
	&kgsl_pwrscale_policy_idlestats,
#endif
#ifdef CONFIG_MSM_DCVS
	&kgsl_pwrscale_policy_msm,
#endif
	NULL
};
+0 −269
Original line number Diff line number Diff line
/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */

#include <linux/slab.h>
#include <mach/msm_dcvs.h>
#include "kgsl.h"
#include "kgsl_pwrscale.h"
#include "kgsl_device.h"
#include "a2xx_reg.h"
#include "kgsl_trace.h"

struct msm_priv {
	struct kgsl_device		*device;
	int				enabled;
	unsigned int			cur_freq;
	unsigned int			req_level;
	int				floor_level;
	struct msm_dcvs_core_info	*core_info;
	int				gpu_busy;
	int				dcvs_core_id;
};

/* reference to be used in idle and freq callbacks */
static struct msm_priv *the_msm_priv;

static int msm_idle_enable(int type_core_num,
		enum msm_core_control_event event)
{
	struct msm_priv *priv = the_msm_priv;

	switch (event) {
	case MSM_DCVS_ENABLE_IDLE_PULSE:
		priv->enabled = true;
		break;
	case MSM_DCVS_DISABLE_IDLE_PULSE:
		priv->enabled = false;
		break;
	case MSM_DCVS_ENABLE_HIGH_LATENCY_MODES:
	case MSM_DCVS_DISABLE_HIGH_LATENCY_MODES:
		break;
	}
	return 0;
}

/* Set the requested frequency if it is within 5MHz (delta) of a
 * supported frequency.
 */
static int msm_set_freq(int core_num, unsigned int freq)
{
	int i, delta = 5000000;
	struct msm_priv *priv = the_msm_priv;
	struct kgsl_device *device = priv->device;
	struct kgsl_pwrctrl *pwr = &device->pwrctrl;

	/* msm_dcvs manager uses frequencies in kHz */
	freq *= 1000;
	for (i = 0; i < pwr->num_pwrlevels; i++)
		if (abs(pwr->pwrlevels[i].gpu_freq - freq) < delta)
			break;
	if (i == pwr->num_pwrlevels)
		return 0;

	mutex_lock(&device->mutex);
	priv->req_level = i;
	if (priv->req_level <= priv->floor_level) {
		kgsl_pwrctrl_pwrlevel_change(device, priv->req_level);
		priv->cur_freq = pwr->pwrlevels[pwr->active_pwrlevel].gpu_freq;
	}
	mutex_unlock(&device->mutex);

	/* return current frequency in kHz */
	return priv->cur_freq / 1000;
}

static int msm_set_min_freq(int core_num, unsigned int freq)
{
	int i, delta = 5000000;
	struct msm_priv *priv = the_msm_priv;
	struct kgsl_device *device = priv->device;
	struct kgsl_pwrctrl *pwr = &device->pwrctrl;

	/* msm_dcvs manager uses frequencies in kHz */
	freq *= 1000;
	for (i = 0; i < pwr->num_pwrlevels; i++)
		if (abs(pwr->pwrlevels[i].gpu_freq - freq) < delta)
			break;
	if (i == pwr->num_pwrlevels)
		return 0;

	mutex_lock(&device->mutex);
	priv->floor_level = i;
	if (priv->floor_level <= priv->req_level)
		kgsl_pwrctrl_pwrlevel_change(device, priv->floor_level);
	else if (priv->floor_level > priv->req_level)
		kgsl_pwrctrl_pwrlevel_change(device, priv->req_level);

	priv->cur_freq = pwr->pwrlevels[pwr->active_pwrlevel].gpu_freq;
	mutex_unlock(&device->mutex);

	/* return current frequency in kHz */
	return priv->cur_freq / 1000;
}

static unsigned int msm_get_freq(int core_num)
{
	struct msm_priv *priv = the_msm_priv;

	/* return current frequency in kHz */
	return priv->cur_freq / 1000;
}

static void msm_busy(struct kgsl_device *device,
			struct kgsl_pwrscale *pwrscale)
{
	struct msm_priv *priv = pwrscale->priv;
	if (priv->enabled && !priv->gpu_busy) {
		msm_dcvs_idle(priv->dcvs_core_id, MSM_DCVS_IDLE_EXIT, 0);
		trace_kgsl_mpdcvs(device, 1);
		priv->gpu_busy = 1;
	}
	return;
}

static void msm_idle(struct kgsl_device *device,
		struct kgsl_pwrscale *pwrscale)
{
	struct msm_priv *priv = pwrscale->priv;

	if (priv->enabled && priv->gpu_busy)
		if (device->ftbl->isidle(device)) {
			msm_dcvs_idle(priv->dcvs_core_id,
					MSM_DCVS_IDLE_ENTER, 0);
			trace_kgsl_mpdcvs(device, 0);
			priv->gpu_busy = 0;
		}
	return;
}

static void msm_sleep(struct kgsl_device *device,
			struct kgsl_pwrscale *pwrscale)
{
	struct msm_priv *priv = pwrscale->priv;

	if (priv->enabled && priv->gpu_busy) {
		msm_dcvs_idle(priv->dcvs_core_id, MSM_DCVS_IDLE_ENTER, 0);
		trace_kgsl_mpdcvs(device, 0);
		priv->gpu_busy = 0;
	}

	return;
}

static void msm_set_io_fraction(struct kgsl_device *device,
				unsigned int value)
{
	int i;
	struct kgsl_pwrctrl *pwr = &device->pwrctrl;

	for (i = 0; i < pwr->num_pwrlevels; i++)
		pwr->pwrlevels[i].io_fraction = value;

}

static void msm_restore_io_fraction(struct kgsl_device *device)
{
	int i;
	struct kgsl_device_platform_data *pdata =
				kgsl_device_get_drvdata(device);
	struct kgsl_pwrctrl *pwr = &device->pwrctrl;

	for (i = 0; i < pdata->num_levels; i++)
		pwr->pwrlevels[i].io_fraction =
			pdata->pwrlevel[i].io_fraction;
}

static int msm_init(struct kgsl_device *device,
		     struct kgsl_pwrscale *pwrscale)
{
	struct msm_priv *priv;
	struct msm_dcvs_freq_entry *tbl;
	int i, ret = -EINVAL, low_level;
	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
	struct platform_device *pdev =
		container_of(device->parentdev, struct platform_device, dev);
	struct kgsl_device_platform_data *pdata = pdev->dev.platform_data;

	if (the_msm_priv) {
		priv = pwrscale->priv = the_msm_priv;
	} else {
		priv = pwrscale->priv = kzalloc(sizeof(struct msm_priv),
			GFP_KERNEL);
		if (pwrscale->priv == NULL)
			return -ENOMEM;

		priv->core_info = pdata->core_info;
		tbl = priv->core_info->freq_tbl;
		priv->floor_level = pwr->num_pwrlevels - 1;
		/* Fill in frequency table from low to high, reversing order. */
		low_level = pwr->num_pwrlevels - KGSL_PWRLEVEL_LAST_OFFSET;
		for (i = 0; i <= low_level; i++)
			tbl[i].freq =
				pwr->pwrlevels[low_level - i].gpu_freq / 1000;
		priv->dcvs_core_id =
				msm_dcvs_register_core(MSM_DCVS_CORE_TYPE_GPU,
				0,
				priv->core_info,
				msm_set_freq, msm_get_freq, msm_idle_enable,
				msm_set_min_freq,
				priv->core_info->sensors[0]);
		if (priv->dcvs_core_id < 0) {
			KGSL_PWR_ERR(device, "msm_dcvs_register_core failed");
			goto err;
		}
		the_msm_priv = priv;
	}
	priv->device = device;
	ret = msm_dcvs_freq_sink_start(priv->dcvs_core_id);
	if (ret >= 0) {
		if (device->ftbl->isidle(device)) {
			priv->gpu_busy = 0;
			msm_dcvs_idle(priv->dcvs_core_id,
					MSM_DCVS_IDLE_ENTER, 0);
		} else {
			priv->gpu_busy = 1;
		}
		msm_set_io_fraction(device, 0);
		return 0;
	}

	KGSL_PWR_ERR(device, "msm_dcvs_freq_sink_register failed\n");

err:
	if (!the_msm_priv)
		kfree(pwrscale->priv);
	pwrscale->priv = NULL;

	return ret;
}

static void msm_close(struct kgsl_device *device,
		      struct kgsl_pwrscale *pwrscale)
{
	struct msm_priv *priv = pwrscale->priv;

	if (pwrscale->priv == NULL)
		return;
	msm_dcvs_freq_sink_stop(priv->dcvs_core_id);
	pwrscale->priv = NULL;
	msm_restore_io_fraction(device);
}

struct kgsl_pwrscale_policy kgsl_pwrscale_policy_msm = {
	.name = "msm",
	.init = msm_init,
	.idle = msm_idle,
	.busy = msm_busy,
	.sleep = msm_sleep,
	.close = msm_close,
};
+0 −23
Original line number Diff line number Diff line
@@ -262,29 +262,6 @@ TRACE_EVENT(kgsl_pwrlevel,
	)
);

TRACE_EVENT(kgsl_mpdcvs,

	TP_PROTO(struct kgsl_device *device, unsigned int state),

	TP_ARGS(device, state),

	TP_STRUCT__entry(
		__string(device_name, device->name)
		__field(unsigned int, state)
	),

	TP_fast_assign(
		__assign_str(device_name, device->name);
		__entry->state = state;
	),

	TP_printk(
		"d_name=%s %s",
		__get_str(device_name),
		__entry->state ? "BUSY" : "IDLE"
	)
);

TRACE_EVENT(kgsl_gpubusy,
	TP_PROTO(struct kgsl_device *device, unsigned int busy,
		unsigned int elapsed),