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

Commit 1a5f534d authored by Vikash Garodia's avatar Vikash Garodia
Browse files

msm: vidc: Fix scale clocks based on cycles/mb



Existing video driver scales Venus clocks either based
on a static load-freq table or it determines the load
from cycles/mb and computes the freq. Scalability of
Venus clock was decided based on the number of entries
in static load-freq table. So incases when the load-freq
table is not present, the driver assumes that the
clocks are not scalable. Due to this, all the Venus
clocks were prepared for lowest frequency and were
not scaled later during the video session.
The code fixes the scaling of Venus clock and makes
both the scaling approach mutually exclusive.

Change-Id: Ia8e4bea236d5f94e717041a3517d35c69c0e4619
Signed-off-by: default avatarVikash Garodia <vgarodia@codeaurora.org>
parent 37c8e26b
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -886,11 +886,13 @@ static int msm_vidc_load_clock_table(
				"clock-names", c, &vc->name);

		if (clock_props[c] & CLOCK_PROP_HAS_SCALING) {
			vc->has_scaling = true;
			vc->count = res->load_freq_tbl_size;
			vc->load_freq_tbl = res->load_freq_tbl;
		} else {
			vc->count = 0;
			vc->load_freq_tbl = NULL;
			vc->has_scaling = false;
		}

		dprintk(VIDC_DBG, "Found clock %s: scale-able = %s\n", vc->name,
+2 −2
Original line number Diff line number Diff line
@@ -98,8 +98,8 @@ struct clock_info {
	const char *name;
	struct clk *clk;
	struct load_freq_table *load_freq_tbl;
	u32 count; /* == has_scaling iff count != 0 */
	bool has_gating;
	u32 count;
	bool has_scaling;
};

struct clock_set {
+28 −18
Original line number Diff line number Diff line
@@ -85,7 +85,7 @@ static int __disable_regulators(struct venus_hfi_device *device);
static int __enable_regulators(struct venus_hfi_device *device);
static inline int __prepare_enable_clks(struct venus_hfi_device *device);
static inline void __disable_unprepare_clks(struct venus_hfi_device *device);
static int __scale_clocks(struct venus_hfi_device *device, int load,
static int __scale_clocks_load(struct venus_hfi_device *device, int load,
		struct vidc_clk_scale_data *data,
		unsigned long instant_bitrate);
static void __flush_debug_queue(struct venus_hfi_device *device, u8 *packet);
@@ -1384,15 +1384,15 @@ static int __scale_clocks_cycles_per_mb(struct venus_hfi_device *device,
	struct clock_profile_entry *entry = NULL;
	u64 total_freq = 0, rate = 0;

	clk_freq_tbl = &device->res->clock_freq_tbl;
	allowed_clks_tbl = device->res->allowed_clks_tbl;

	if (!data) {
		dprintk(VIDC_DBG, "%s: NULL scale data\n", __func__);
		total_freq = device->clk_freq;
		goto get_clock_freq;
	}

	clk_freq_tbl = &device->res->clock_freq_tbl;
	allowed_clks_tbl = device->res->allowed_clks_tbl;

	device->clk_bitrate = instant_bitrate;

	for (i = 0; i < data->num_sessions; i++) {
@@ -1444,7 +1444,7 @@ get_clock_freq:
	}

	venus_hfi_for_each_clock(device, cl) {
		if (!cl->count) /* does not has_scaling */
		if (!cl->has_scaling)
			continue;

		device->clk_freq = rate;
@@ -1466,7 +1466,7 @@ get_clock_freq:
	return rc;
}

static int __scale_clocks(struct venus_hfi_device *device, int load,
static int __scale_clocks_load(struct venus_hfi_device *device, int load,
		struct vidc_clk_scale_data *data, unsigned long instant_bitrate)
{
	struct clock_info *cl;
@@ -1474,7 +1474,7 @@ static int __scale_clocks(struct venus_hfi_device *device, int load,
	device->clk_bitrate = instant_bitrate;

	venus_hfi_for_each_clock(device, cl) {
		if (cl->count) {/* has_scaling */
		if (cl->has_scaling) {

			unsigned long rate = 0;
			int rc;
@@ -1515,6 +1515,23 @@ static int __scale_clocks(struct venus_hfi_device *device, int load,
	return 0;
}

static int __scale_clocks(struct venus_hfi_device *device,
		int load, struct vidc_clk_scale_data *data,
		unsigned long instant_bitrate)
{
	int rc = 0;

	if (device->res->clock_freq_tbl.clk_prof_entries &&
			device->res->allowed_clks_tbl)
		rc = __scale_clocks_cycles_per_mb(device,
				data, instant_bitrate);
	else if (device->res->load_freq_tbl)
		rc = __scale_clocks_load(device, load, data, instant_bitrate);
	else
		dprintk(VIDC_DBG, "Clock scaling is not supported\n");

	return rc;
}
static int venus_hfi_scale_clocks(void *dev, int load,
					struct vidc_clk_scale_data *data,
					unsigned long instant_bitrate)
@@ -1528,14 +1545,7 @@ static int venus_hfi_scale_clocks(void *dev, int load,
	}

	mutex_lock(&device->lock);
	if (device->res->clock_freq_tbl.clk_prof_entries &&
			device->res->allowed_clks_tbl)
		rc = __scale_clocks_cycles_per_mb(device,
				data, instant_bitrate);
	else if (device->res->load_freq_tbl)
	rc = __scale_clocks(device, load, data, instant_bitrate);
	else
		dprintk(VIDC_DBG, "Clock scaling is not supported\n");
	mutex_unlock(&device->lock);

	return rc;
@@ -3681,8 +3691,8 @@ static inline int __init_clocks(struct venus_hfi_device *device)
	venus_hfi_for_each_clock(device, cl) {
		int i = 0;

		dprintk(VIDC_DBG, "%s: scalable? %d\n",
				cl->name, !!cl->count);
		dprintk(VIDC_DBG, "%s: scalable? %d, count %d\n",
				cl->name, cl->has_scaling, cl->count);
		for (i = 0; i < cl->count; ++i) {
			dprintk(VIDC_DBG,
				"\tload = %d, freq = %d codecs supported %#x\n",
@@ -3745,7 +3755,7 @@ static inline int __prepare_enable_clks(struct venus_hfi_device *device)
		 * them.  Since we don't really have a load at this point, scale
		 * it to the lowest frequency possible
		 */
		if (cl->count)
		if (cl->has_scaling)
			clk_set_rate(cl->clk, clk_round_rate(cl->clk, 0));

		rc = clk_prepare_enable(cl->clk);