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

Commit 1318077c authored by Deva Ramasubramanian's avatar Deva Ramasubramanian
Browse files

msm: vidc: Cache bus votes properly when client votes



On targets with ocmem, for each client vote, we cache two copies of
the vote in device->bus_load.  As a result, when triggering an internal
vote (e.g. coming out of power collapse), we aggregate the entries in
device->bus_load and end up voting for double the required bandwidth.

The hfi layer just needs to mirror the client's previous vote.  So just
copy and cache the votes without modification.

Change-Id: Iacca9fb846a05a41630392d9a0c38b40e44a2ad9
Signed-off-by: default avatarDeva Ramasubramanian <dramasub@codeaurora.org>
parent bacf292c
Loading
Loading
Loading
Loading
+31 −20
Original line number Diff line number Diff line
@@ -864,6 +864,7 @@ static int venus_hfi_vote_buses(void *dev, struct vidc_bus_vote_data *data,
	int rc = 0, i = 0, num_bus = 0;
	struct venus_hfi_device *device = dev;
	struct bus_info *bus = NULL;
	struct vidc_bus_vote_data *cached_vote_data = NULL;

	if (!dev) {
		dprintk(VIDC_ERR, "Invalid device\n");
@@ -876,7 +877,17 @@ static int venus_hfi_vote_buses(void *dev, struct vidc_bus_vote_data *data,
		return -EINVAL;
	}

	/* alloc & init the load table */
	/* (Re-)alloc memory to store the new votes (in case we internally
	 * re-vote after power collapse, which is transparent to client) */
	cached_vote_data = krealloc(device->bus_load.vote_data, num_data *
			sizeof(*cached_vote_data), GFP_KERNEL);
	if (!cached_vote_data) {
		dprintk(VIDC_ERR, "Can't alloc memory to cache bus votes\n");
		rc = -ENOMEM;
		goto err_no_mem;
	}

	/* Alloc & init the load table */
	num_bus = device->res->bus_set.count;
	aggregate_load_table = kzalloc(sizeof(*aggregate_load_table) * num_bus,
			GFP_TEMPORARY);
@@ -890,7 +901,7 @@ static int venus_hfi_vote_buses(void *dev, struct vidc_bus_vote_data *data,
	venus_hfi_for_each_bus(device, bus)
		aggregate_load_table[i++].bus = bus;

	/* aggregate the loads for each bus */
	/* Aggregate the loads for each bus */
	for (i = 0; i < num_data; ++i) {
		int j = 0;

@@ -947,11 +958,15 @@ static int venus_hfi_vote_buses(void *dev, struct vidc_bus_vote_data *data,
					"Voting bus %s to vector %d with load %d\n",
					bus->pdata->name, bus_vector, load);
		}

		device->bus_load[i].session = bus->sessions_supported;
		device->bus_load[i].load = load;
	}

	/* Cache the votes */
	for (i = 0; i < num_data; ++i)
		cached_vote_data[i] = data[i];

	device->bus_load.vote_data = cached_vote_data;
	device->bus_load.vote_data_count = num_data;

	kfree(aggregate_load_table);
err_no_mem:
	return rc;
@@ -1157,8 +1172,8 @@ static int __alloc_ocmem(void *dev, unsigned long size, bool locked)
			goto ocmem_set_failed;
		}

		rc = venus_hfi_vote_buses(device, device->bus_load,
				device->res->bus_set.count, 0);
		rc = venus_hfi_vote_buses(device, device->bus_load.vote_data,
			device->bus_load.vote_data_count, 0);
		if (rc) {
			dprintk(VIDC_ERR,
					"Failed to scale buses after setting ocmem: %d\n",
@@ -1483,8 +1498,8 @@ static inline int venus_hfi_power_on(struct venus_hfi_device *device)
		return 0;

	dprintk(VIDC_DBG, "Resuming from power collapse\n");
	rc = venus_hfi_vote_buses(device, device->bus_load,
			device->res->bus_set.count, 0);
	rc = venus_hfi_vote_buses(device, device->bus_load.vote_data,
			device->bus_load.vote_data_count, 0);
	if (rc) {
		dprintk(VIDC_ERR, "Failed to scale buses\n");
		goto err_vote_buses;
@@ -3518,8 +3533,9 @@ static void venus_hfi_deinit_bus(struct venus_hfi_device *device)
		}
	}

	kfree(device->bus_load);
	device->bus_load = NULL;
	kfree(device->bus_load.vote_data);
	device->bus_load.vote_data = NULL;
	device->bus_load.vote_data_count = 0;
}

static int venus_hfi_init_bus(struct venus_hfi_device *device)
@@ -3553,13 +3569,8 @@ static int venus_hfi_init_bus(struct venus_hfi_device *device)
		dprintk(VIDC_DBG, "Registered bus client %s\n", name);
	}

	device->bus_load = kzalloc(sizeof(*device->bus_load) *
			device->res->bus_set.count, GFP_KERNEL);
	if (!device->bus_load) {
		dprintk(VIDC_ERR, "Failed to allocate memory\n");
		rc = -ENOMEM;
		goto err_init_bus;
	}
	device->bus_load.vote_data = NULL;
	device->bus_load.vote_data_count = 0;

	return rc;
err_init_bus:
@@ -4012,8 +4023,8 @@ static int venus_hfi_resurrect_fw(void *dev)
	venus_hfi_unload_fw(device);


	rc = venus_hfi_vote_buses(device, device->bus_load,
			device->res->bus_set.count, 0);
	rc = venus_hfi_vote_buses(device, device->bus_load.vote_data,
			device->bus_load.vote_data_count, 0);
	if (rc) {
		dprintk(VIDC_ERR, "Failed to scale buses\n");
		goto exit;
+4 −1
Original line number Diff line number Diff line
@@ -178,7 +178,10 @@ struct venus_hfi_device {
	u32 clk_load;
	u32 codecs_enabled;
	u32 last_packet_type;
	struct vidc_bus_vote_data *bus_load;
	struct {
		struct vidc_bus_vote_data *vote_data;
		u32 vote_data_count;
	} bus_load;
	enum clock_state clk_state;
	bool power_enabled;
	struct mutex read_lock;