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

Commit 52152018 authored by Shiju Mathew's avatar Shiju Mathew Committed by Gerrit - the friendly Code Review server
Browse files

msm: vidc: Add support for hibernation



Add freeze to pm_op to unload firmware for hibernation,
with a debugfs node trigger_ssr for testing and markers.

Change-Id: I101369b447f83cac33667cde191e66fed4c549a8
Signed-off-by: default avatarShiju Mathew <shijum@codeaurora.org>
parent df3d8915
Loading
Loading
Loading
Loading
+81 −1
Original line number Diff line number Diff line
@@ -781,12 +781,92 @@ static int msm_vidc_pm_suspend(struct device *dev)

static int msm_vidc_pm_resume(struct device *dev)
{
	place_marker("vidc resumed");
	dprintk(VIDC_INFO, "%s\n", __func__);
	return 0;
}

int msm_vidc_freeze_core(struct msm_vidc_core *core)
{
	int rc = 0;
	int max_retry = 300;
	struct hfi_device *hdev;

	hdev = core->device;

	mutex_lock(&core->lock);

	dprintk(VIDC_WARN, "%s: fatal SSR intended to dismantle vidc\n",
			__func__);

	core->ssr_type = SSR_ERR_FATAL;

	if (core->state == VIDC_CORE_INIT_DONE) {
		dprintk(VIDC_INFO, "%s: ssr type %d\n", __func__,
			core->ssr_type);
		/*
		 * In current implementation user-initiated SSR triggers
		 * a fatal error from hardware. However, there is no way
		 * to know if fatal error is due to SSR or not. Handle
		 * user SSR as non-fatal.
		 */

		core->trigger_ssr = true;
		rc = call_hfi_op(hdev, core_trigger_ssr,
				hdev->hfi_device_data, core->ssr_type);

		if (rc) {
			dprintk(VIDC_ERR, "%s: trigger_ssr failed\n", __func__);
			core->trigger_ssr = false;
		}

	} else {
		dprintk(VIDC_WARN, "%s: video core %pK not initialized\n",
			__func__, core);
	}
	mutex_unlock(&core->lock);

	while ((core->state != VIDC_CORE_UNINIT) && (max_retry > 0)) {
		msleep(20);
		max_retry--;
	}

	mutex_lock(&core->lock);
	core->trigger_ssr = false;
	mutex_unlock(&core->lock);

	return rc;
}

static int msm_vidc_pm_freeze(struct device *dev)
{
	int rc = 0;
	struct msm_vidc_core *core;

	if (!dev || !dev->driver)
		return 0;

	core = dev_get_drvdata(dev);
	if (!core)
		return 0;

	if (of_device_is_compatible(dev->of_node, "qcom,msm-vidc")) {
		place_marker("vidc hibernation start");

		rc = msm_vidc_freeze_core(core);

		place_marker("vidc hibernation end");
	}

	dprintk(VIDC_INFO, "%s: done\n", __func__);

	return rc;
}

static const struct dev_pm_ops msm_vidc_pm_ops = {
	SET_SYSTEM_SLEEP_PM_OPS(msm_vidc_pm_suspend, msm_vidc_pm_resume)
	.suspend = msm_vidc_pm_suspend,
	.resume = msm_vidc_pm_resume,
	.freeze = msm_vidc_pm_freeze,
};

MODULE_DEVICE_TABLE(of, msm_vidc_dt_match);
+1 −0
Original line number Diff line number Diff line
@@ -513,6 +513,7 @@ struct msm_vidc_ctrl {
void handle_cmd_response(enum hal_command_response cmd, void *data);
int msm_vidc_trigger_ssr(struct msm_vidc_core *core,
	enum hal_ssr_trigger_type type);
int msm_vidc_freeze_core(struct msm_vidc_core *core);
int msm_vidc_noc_error_info(struct msm_vidc_core *core);
bool heic_encode_session_supported(struct msm_vidc_inst *inst);
int msm_vidc_check_session_supported(struct msm_vidc_inst *inst);