summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPraneeth Paladugu <ppaladug@codeaurora.org>2016-04-06 12:43:41 -0700
committerChinmay Sawarkar <chinmays@codeaurora.org>2016-07-26 19:28:20 -0700
commitbfd0b8ce6e359722dca4e6c68afa9832bb9aaf1d (patch)
tree59afcba3781f32e90487d140589a0b8bcda3ff72
parentbb02457c09a7e64ac886a8063c8728c8ce6f1d07 (diff)
msm: vidc: Handle FW errors as Fatal
Currently video driver handles all FW errors such as SYS_ERROR, SESSION_ERROR and timeouts as non-fatal. This suppresses FW issues and makes it difficult to root cause. Hence treat FW errors as Fatal based on dtsi entry. When FATAL error occurred, print FW messages by default. CRs-Fixed: 1037031 Change-Id: Ifffceb30e9abcaced977438526ceeef4e7f9324e Signed-off-by: Praneeth Paladugu <ppaladug@codeaurora.org>
-rw-r--r--Documentation/devicetree/bindings/media/video/msm-vidc.txt2
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc_common.c36
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc_res_parse.c5
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc_resources.h1
-rw-r--r--drivers/media/platform/msm/vidc/venus_hfi.c34
-rw-r--r--drivers/media/platform/msm/vidc/vidc_hfi_api.h1
6 files changed, 74 insertions, 5 deletions
diff --git a/Documentation/devicetree/bindings/media/video/msm-vidc.txt b/Documentation/devicetree/bindings/media/video/msm-vidc.txt
index 1c90f98c2954..b1869803d345 100644
--- a/Documentation/devicetree/bindings/media/video/msm-vidc.txt
+++ b/Documentation/devicetree/bindings/media/video/msm-vidc.txt
@@ -130,6 +130,8 @@ value is typically max(latencies of every cluster at all power levels) + 1
- qcom,max-secure-instances = An int containing max number of concurrent secure
instances supported, accounting for venus and system wide limitations like
memory, performance etc.
+- qcom,debug-timeout = A bool indicating that FW errors such as SYS_ERROR,
+ SESSION_ERROR and timeouts will be treated as Fatal.
[Second level nodes]
Context Banks
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index 05bfabce2bb2..40be56e874c3 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -86,6 +86,7 @@ struct getprop_buf {
static void msm_comm_generate_session_error(struct msm_vidc_inst *inst);
static void msm_comm_generate_sys_error(struct msm_vidc_inst *inst);
static void handle_session_error(enum hal_command_response cmd, void *data);
+static void msm_vidc_print_running_insts(struct msm_vidc_core *core);
bool msm_comm_turbo_session(struct msm_vidc_inst *inst)
{
@@ -879,11 +880,13 @@ static int wait_for_sess_signal_receipt(struct msm_vidc_inst *inst,
enum hal_command_response cmd)
{
int rc = 0;
+ struct hfi_device *hdev;
if (!IS_HAL_SESSION_CMD(cmd)) {
dprintk(VIDC_ERR, "Invalid inst cmd response: %d\n", cmd);
return -EINVAL;
}
+ hdev = (struct hfi_device *)(inst->core->device);
rc = wait_for_completion_timeout(
&inst->completions[SESSION_MSG_INDEX(cmd)],
msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
@@ -891,7 +894,11 @@ static int wait_for_sess_signal_receipt(struct msm_vidc_inst *inst,
dprintk(VIDC_ERR, "Wait interrupted or timed out: %d\n",
SESSION_MSG_INDEX(cmd));
msm_comm_kill_session(inst);
- BUG_ON(msm_vidc_debug_timeout);
+ call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data);
+ dprintk(VIDC_ERR,
+ "sess resp timeout can potentially crash the system\n");
+
+ BUG_ON(inst->core->resources.debug_timeout);
rc = -EIO;
} else {
rc = 0;
@@ -1623,6 +1630,13 @@ static void handle_sys_error(enum hal_command_response cmd, void *data)
core->state = VIDC_CORE_UNINIT;
}
mutex_unlock(&core->lock);
+
+ msm_vidc_print_running_insts(core);
+ call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data);
+ dprintk(VIDC_ERR,
+ "SYS_ERROR can potentially crash the system\n");
+
+ BUG_ON(core->resources.debug_timeout);
}
void msm_comm_session_clean(struct msm_vidc_inst *inst)
@@ -2393,7 +2407,11 @@ static int msm_comm_session_abort(struct msm_vidc_inst *inst)
dprintk(VIDC_ERR,
"%s: Wait interrupted or timed out [%p]: %d\n",
__func__, inst, abort_completion);
- BUG_ON(msm_vidc_debug_timeout);
+ call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data);
+ dprintk(VIDC_ERR,
+ "ABORT timeout can potentially crash the system\n");
+
+ BUG_ON(inst->core->resources.debug_timeout);
rc = -EBUSY;
} else {
rc = 0;
@@ -2463,6 +2481,7 @@ void msm_comm_handle_thermal_event()
int msm_comm_check_core_init(struct msm_vidc_core *core)
{
int rc = 0;
+ struct hfi_device *hdev;
mutex_lock(&core->lock);
if (core->state >= VIDC_CORE_INIT_DONE) {
@@ -2471,13 +2490,18 @@ int msm_comm_check_core_init(struct msm_vidc_core *core)
goto exit;
}
dprintk(VIDC_DBG, "Waiting for SYS_INIT_DONE\n");
+ hdev = (struct hfi_device *)core->device;
rc = wait_for_completion_timeout(
&core->completions[SYS_MSG_INDEX(HAL_SYS_INIT_DONE)],
msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
if (!rc) {
dprintk(VIDC_ERR, "%s: Wait interrupted or timed out: %d\n",
__func__, SYS_MSG_INDEX(HAL_SYS_INIT_DONE));
- BUG_ON(msm_vidc_debug_timeout);
+ call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data);
+ dprintk(VIDC_ERR,
+ "SYS_INIT timeout can potentially crash the system\n");
+
+ BUG_ON(core->resources.debug_timeout);
rc = -EIO;
goto exit;
} else {
@@ -3944,7 +3968,11 @@ int msm_comm_try_get_prop(struct msm_vidc_inst *inst, enum hal_property ptype,
SESSION_MSG_INDEX(HAL_SESSION_PROPERTY_INFO));
inst->state = MSM_VIDC_CORE_INVALID;
msm_comm_kill_session(inst);
- BUG_ON(msm_vidc_debug_timeout);
+ call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data);
+ dprintk(VIDC_ERR,
+ "SESS_PROP timeout can potentially crash the system\n");
+
+ BUG_ON(inst->core->resources.debug_timeout);
rc = -ETIMEDOUT;
goto exit;
} else {
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_res_parse.c b/drivers/media/platform/msm/vidc/msm_vidc_res_parse.c
index 4503e46b044d..2bb91ccc6c26 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_res_parse.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_res_parse.c
@@ -1103,6 +1103,11 @@ int read_platform_resources_from_dt(
res->never_unload_fw = of_property_read_bool(pdev->dev.of_node,
"qcom,never-unload-fw");
+ res->debug_timeout = of_property_read_bool(pdev->dev.of_node,
+ "qcom,debug-timeout");
+
+ res->debug_timeout |= msm_vidc_debug_timeout;
+
of_property_read_u32(pdev->dev.of_node,
"qcom,pm-qos-latency-us", &res->pm_qos_latency_us);
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_resources.h b/drivers/media/platform/msm/vidc/msm_vidc_resources.h
index 1fc1888e81c6..c61605c7e405 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_resources.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_resources.h
@@ -185,6 +185,7 @@ struct msm_vidc_platform_resources {
const char *fw_name;
const char *hfi_version;
bool never_unload_fw;
+ bool debug_timeout;
uint32_t pm_qos_latency_us;
uint32_t max_inst_count;
uint32_t max_secure_inst_count;
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
index ac53b3bcb4ed..20e217cc0445 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc/venus_hfi.c
@@ -1311,6 +1311,29 @@ static int venus_hfi_suspend(void *dev)
return rc;
}
+static int venus_hfi_flush_debug_queue(void *dev)
+{
+ int rc = 0;
+ struct venus_hfi_device *device = (struct venus_hfi_device *) dev;
+
+ if (!device) {
+ dprintk(VIDC_ERR, "%s invalid device\n", __func__);
+ return -EINVAL;
+ }
+
+ mutex_lock(&device->lock);
+
+ if (device->power_enabled) {
+ dprintk(VIDC_DBG, "Venus is busy\n");
+ rc = -EBUSY;
+ goto exit;
+ }
+ __flush_debug_queue(device, NULL);
+exit:
+ mutex_unlock(&device->lock);
+ return rc;
+}
+
static enum hal_default_properties venus_hfi_get_default_properties(void *dev)
{
enum hal_default_properties prop = 0;
@@ -3322,6 +3345,7 @@ static void __process_sys_error(struct venus_hfi_device *device)
static void __flush_debug_queue(struct venus_hfi_device *device, u8 *packet)
{
bool local_packet = false;
+ enum vidc_msg_prio log_level = VIDC_FW;
if (!device) {
dprintk(VIDC_ERR, "%s: Invalid params\n", __func__);
@@ -3337,6 +3361,13 @@ static void __flush_debug_queue(struct venus_hfi_device *device, u8 *packet)
}
local_packet = true;
+
+ /*
+ * Local packek is used when something FATAL occurred.
+ * It is good to print these logs by default.
+ */
+
+ log_level = VIDC_ERR;
}
while (!__iface_dbgq_read(device, packet)) {
@@ -3353,7 +3384,7 @@ static void __flush_debug_queue(struct venus_hfi_device *device, u8 *packet)
} else {
struct hfi_msg_sys_debug_packet *pkt =
(struct hfi_msg_sys_debug_packet *) packet;
- dprintk(VIDC_FW, "%s", pkt->rg_msg_data);
+ dprintk(log_level, "%s", pkt->rg_msg_data);
}
}
@@ -4629,6 +4660,7 @@ static void venus_init_hfi_callbacks(struct hfi_device *hdev)
hdev->get_fw_info = venus_hfi_get_fw_info;
hdev->get_core_capabilities = venus_hfi_get_core_capabilities;
hdev->suspend = venus_hfi_suspend;
+ hdev->flush_debug_queue = venus_hfi_flush_debug_queue;
hdev->get_core_clock_rate = venus_hfi_get_core_clock_rate;
hdev->get_default_properties = venus_hfi_get_default_properties;
}
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_api.h b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
index 624fd53debe8..85bc3cac910c 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_api.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
@@ -1498,6 +1498,7 @@ struct hfi_device {
int (*session_clean)(void *sess);
int (*get_core_capabilities)(void *dev);
int (*suspend)(void *dev);
+ int (*flush_debug_queue)(void *dev);
unsigned long (*get_core_clock_rate)(void *dev, bool actual_rate);
enum hal_default_properties (*get_default_properties)(void *dev);
};