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

Commit 9d86a549 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: kgsl: Use bw_vbif governor to vote for GPU msm bus bandwidth"

parents f53f8ea1 4febee78
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -56,6 +56,13 @@ Bus Scaling Data:
					ab: Represents aggregated bandwidth. This value is 0 for Graphics.
					ib: Represents instantaneous bandwidth. This value has a range <0 8000 MB/s>

- qcom,ocmem-bus-client: Container for another set of bus scaling properties
						qcom,msm-bus,name
						qcom,msm-bus,num-cases
						qcom,msm-bus,num-paths
						qcom,msm-bus,vectors-KBps
			to be used by ocmem msm bus scaling client.

GDSC Oxili Regulators:
- vddcx-supply:			Phandle for vddcx regulator device node.
- vdd-supply:			Phandle for vdd regulator device node.
+50 −5
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include <linux/msm-bus-board.h>
#include <linux/ktime.h>
#include <linux/delay.h>
#include <linux/msm_adreno_devfreq.h>

#include "kgsl.h"
#include "kgsl_pwrscale.h"
@@ -45,6 +46,8 @@
/* Number of jiffies for a full thermal cycle */
#define TH_HZ			20

#define KGSL_MAX_BUSLEVELS	20

struct clk_pair {
	const char *name;
	uint map;
@@ -89,6 +92,9 @@ static struct clk_pair clks[KGSL_MAX_CLKS] = {
	},
};

static unsigned int ib_votes[KGSL_MAX_BUSLEVELS];
static int last_vote_buslevel;

static void kgsl_pwrctrl_clk(struct kgsl_device *device, int state,
					int requested_state);
static void kgsl_pwrctrl_axi(struct kgsl_device *device, int state);
@@ -98,6 +104,14 @@ static void kgsl_pwrctrl_set_state(struct kgsl_device *device,
static void kgsl_pwrctrl_request_state(struct kgsl_device *device,
				unsigned int state);

/**
 * kgsl_get_bw() - Return latest msm bus IB vote
 */
static unsigned int kgsl_get_bw(void)
{
	return ib_votes[last_vote_buslevel];
}

/**
 * _adjust_pwrlevel() - Given a requested power level do bounds checking on the
 * constraints and return the nearest possible level
@@ -168,8 +182,12 @@ void kgsl_pwrctrl_buslevel_update(struct kgsl_device *device,
		/* If the bus is being turned off, reset to default level */
		pwr->bus_mod = 0;
	}
	msm_bus_scale_client_update_request(pwr->pcl, buslevel);
	trace_kgsl_buslevel(device, pwr->active_pwrlevel, buslevel);
	last_vote_buslevel = buslevel;
	/* vote for ocmem */
	msm_bus_scale_client_update_request(pwr->pcl, buslevel);
	/* ask a governor to vote on behalf of us */
	devfreq_vbif_update_bw();
}
EXPORT_SYMBOL(kgsl_pwrctrl_buslevel_update);

@@ -1190,6 +1208,8 @@ int kgsl_pwrctrl_init(struct kgsl_device *device)
	struct platform_device *pdev = device->pdev;
	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
	struct kgsl_device_platform_data *pdata = dev_get_platdata(&pdev->dev);
	struct device_node *ocmem_bus_node;
	struct msm_bus_scale_pdata *ocmem_scale_table = NULL;

	/*acquire clocks */
	for (i = 0; i < KGSL_MAX_CLKS; i++) {
@@ -1277,13 +1297,26 @@ int kgsl_pwrctrl_init(struct kgsl_device *device)
	if (pdata->bus_scale_table == NULL)
		return result;

	pwr->pcl = msm_bus_scale_register_client(pdata->
						bus_scale_table);
	ocmem_bus_node = of_find_node_by_name(
				device->pdev->dev.of_node,
				"qcom,ocmem-bus-client");
	/* If platform has splitted ocmem bus client - use it */
	if (ocmem_bus_node) {
		ocmem_scale_table = msm_bus_pdata_from_node
				(device->pdev, ocmem_bus_node);
		if (ocmem_scale_table)
			pwr->pcl = msm_bus_scale_register_client
					(ocmem_scale_table);
	} else
		pwr->pcl = msm_bus_scale_register_client
					(pdata->bus_scale_table);

	if (!pwr->pcl) {
		KGSL_PWR_ERR(device,
				"msm_bus_scale_register_client failed: "
				"id %d table %p", device->id,
				pdata->bus_scale_table);
				"id %d table %p %p", device->id,
				pdata->bus_scale_table,
				ocmem_scale_table);
		result = -EINVAL;
		goto done;
	}
@@ -1311,6 +1344,16 @@ int kgsl_pwrctrl_init(struct kgsl_device *device)
		struct msm_bus_vectors *vector = &usecase->vectors[0];
		if (vector->dst == MSM_BUS_SLAVE_EBI_CH0 &&
				vector->ib != 0) {
			if (i < KGSL_MAX_BUSLEVELS)
				/*
				 * Want to convert bytes to Mbytes,
				 * but msm_bus_of.c uses a strange macro
				 *  #define KBTOB(a) (a * 1000ULL)
				 * thats why 1024*1000, not 1024*1024
				 */
				ib_votes[i] =
					DIV_ROUND_UP_ULL(vector->ib, 1024000);

			for (k = 0; k < n; k++)
				if (vector->ib == pwr->bus_ib[k]) {
					static uint64_t last_ib = 0xFFFFFFFF;
@@ -1350,6 +1393,8 @@ int kgsl_pwrctrl_init(struct kgsl_device *device)
	setup_timer(&pwr->thermal_timer, kgsl_thermal_timer,
			(unsigned long) device);

	devfreq_vbif_register_callback(kgsl_get_bw);

	return result;

clk_err: