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

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

Merge "msm: vidc: retain clock rate across power suspend/resume"

parents 041974cf e7a609b0
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -106,6 +106,7 @@ struct clock_info {
	u32 count;
	u32 count;
	bool has_scaling;
	bool has_scaling;
	bool has_mem_retention;
	bool has_mem_retention;
	unsigned long rate_on_enable;
};
};


struct clock_set {
struct clock_set {
+41 −0
Original line number Original line Diff line number Diff line
@@ -1574,6 +1574,7 @@ static int __scale_clocks(struct venus_hfi_device *device,


	return rc;
	return rc;
}
}

static int venus_hfi_scale_clocks(void *dev, int load,
static int venus_hfi_scale_clocks(void *dev, int load,
					struct vidc_clk_scale_data *data,
					struct vidc_clk_scale_data *data,
					unsigned long instant_bitrate)
					unsigned long instant_bitrate)
@@ -1600,6 +1601,41 @@ exit:
	return rc;
	return rc;
}
}


static void __save_clock_rate(struct venus_hfi_device *device, bool reset)
{
	struct clock_info *cl;

	venus_hfi_for_each_clock(device, cl) {
		if (cl->has_scaling) {
			cl->rate_on_enable =
				reset ? 0 : clk_get_rate(cl->clk);
			dprintk(VIDC_PROF, "Saved clock %s rate %lu\n",
					cl->name, cl->rate_on_enable);
		}
	}
}

static void __restore_clock_rate(struct venus_hfi_device *device)
{
	struct clock_info *cl;

	venus_hfi_for_each_clock(device, cl) {
		if (cl->has_scaling && cl->rate_on_enable) {
			int rc;

			rc = __set_clk_rate(device, cl, cl->rate_on_enable);
			if (rc)
				dprintk(VIDC_ERR,
				"Failed to restore clock %s rate %lu\n",
					cl->name, cl->rate_on_enable);
			else
				dprintk(VIDC_DBG,
					"Restored clock %s rate %lu\n",
					cl->name, cl->rate_on_enable);
		}
	}
}

/* Writes into cmdq without raising an interrupt */
/* Writes into cmdq without raising an interrupt */
static int __iface_cmdq_write_relaxed(struct venus_hfi_device *device,
static int __iface_cmdq_write_relaxed(struct venus_hfi_device *device,
		void *pkt, bool *requires_interrupt)
		void *pkt, bool *requires_interrupt)
@@ -4316,6 +4352,7 @@ static inline int __suspend(struct venus_hfi_device *device)
		goto err_tzbsp_suspend;
		goto err_tzbsp_suspend;
	}
	}


	__save_clock_rate(device, false);
	__venus_power_off(device, true);
	__venus_power_off(device, true);
	dprintk(VIDC_PROF, "Venus power collapsed\n");
	dprintk(VIDC_PROF, "Venus power collapsed\n");
	return rc;
	return rc;
@@ -4345,6 +4382,7 @@ static inline int __resume(struct venus_hfi_device *device)
		dprintk(VIDC_ERR, "Failed to power on venus\n");
		dprintk(VIDC_ERR, "Failed to power on venus\n");
		goto err_venus_power_on;
		goto err_venus_power_on;
	}
	}
	__restore_clock_rate(device);


	/* Reboot the firmware */
	/* Reboot the firmware */
	rc = __tzbsp_set_video_state(TZBSP_VIDEO_STATE_RESUME);
	rc = __tzbsp_set_video_state(TZBSP_VIDEO_STATE_RESUME);
@@ -4382,6 +4420,7 @@ exit:
err_reset_core:
err_reset_core:
	__tzbsp_set_video_state(TZBSP_VIDEO_STATE_SUSPEND);
	__tzbsp_set_video_state(TZBSP_VIDEO_STATE_SUSPEND);
err_set_video_state:
err_set_video_state:
	__save_clock_rate(device, true);
	__venus_power_off(device, true);
	__venus_power_off(device, true);
err_venus_power_on:
err_venus_power_on:
	dprintk(VIDC_ERR, "Failed to resume from power collapse\n");
	dprintk(VIDC_ERR, "Failed to resume from power collapse\n");
@@ -4440,6 +4479,7 @@ fail_protect_mem:
		subsystem_put(device->resources.fw.cookie);
		subsystem_put(device->resources.fw.cookie);
	device->resources.fw.cookie = NULL;
	device->resources.fw.cookie = NULL;
fail_load_fw:
fail_load_fw:
	__save_clock_rate(device, true);
	__venus_power_off(device, true);
	__venus_power_off(device, true);
fail_venus_power_on:
fail_venus_power_on:
fail_init_pkt:
fail_init_pkt:
@@ -4461,6 +4501,7 @@ static void __unload_fw(struct venus_hfi_device *device)
	__vote_buses(device, NULL, 0);
	__vote_buses(device, NULL, 0);
	subsystem_put(device->resources.fw.cookie);
	subsystem_put(device->resources.fw.cookie);
	__interface_queues_release(device);
	__interface_queues_release(device);
	__save_clock_rate(device, true);
	__venus_power_off(device, false);
	__venus_power_off(device, false);
	device->resources.fw.cookie = NULL;
	device->resources.fw.cookie = NULL;
	__deinit_resources(device);
	__deinit_resources(device);