summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc_common.c121
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc_common.h1
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc_res_parse.c52
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc_res_parse.h1
-rw-r--r--drivers/media/platform/msm/vidc/venus_hfi.c27
5 files changed, 145 insertions, 57 deletions
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index 566441e9c546..f0a3875a8f28 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -90,6 +90,7 @@ 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);
+static void msm_comm_print_debug_info(struct msm_vidc_inst *inst);
bool msm_comm_turbo_session(struct msm_vidc_inst *inst)
{
@@ -905,7 +906,7 @@ static int wait_for_sess_signal_receipt(struct msm_vidc_inst *inst,
call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data);
dprintk(VIDC_ERR,
"sess resp timeout can potentially crash the system\n");
-
+ msm_comm_print_debug_info(inst);
BUG_ON(inst->core->resources.debug_timeout);
rc = -EIO;
} else {
@@ -1601,6 +1602,7 @@ static void handle_sys_error(enum hal_command_response cmd, void *data)
struct msm_vidc_cb_cmd_done *response = data;
struct msm_vidc_core *core = NULL;
struct hfi_device *hdev = NULL;
+ struct msm_vidc_inst *inst = NULL;
int rc = 0;
subsystem_crashed("venus");
@@ -1640,6 +1642,19 @@ static void handle_sys_error(enum hal_command_response cmd, void *data)
dprintk(VIDC_ERR,
"SYS_ERROR can potentially crash the system\n");
+ /*
+ * For SYS_ERROR, there will not be any inst pointer.
+ * Just grab one of the inst from instances list and
+ * use it.
+ */
+
+ mutex_lock(&core->lock);
+ inst = list_first_entry(&core->instances,
+ struct msm_vidc_inst, list);
+ mutex_unlock(&core->lock);
+
+ msm_comm_print_debug_info(inst);
+
BUG_ON(core->resources.debug_timeout);
}
@@ -2450,6 +2465,7 @@ static int msm_comm_session_abort(struct msm_vidc_inst *inst)
call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data);
dprintk(VIDC_ERR,
"ABORT timeout can potentially crash the system\n");
+ msm_comm_print_debug_info(inst);
BUG_ON(inst->core->resources.debug_timeout);
rc = -EBUSY;
@@ -2522,6 +2538,7 @@ int msm_comm_check_core_init(struct msm_vidc_core *core)
{
int rc = 0;
struct hfi_device *hdev;
+ struct msm_vidc_inst *inst = NULL;
mutex_lock(&core->lock);
if (core->state >= VIDC_CORE_INIT_DONE) {
@@ -2540,6 +2557,17 @@ int msm_comm_check_core_init(struct msm_vidc_core *core)
call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data);
dprintk(VIDC_ERR,
"SYS_INIT timeout can potentially crash the system\n");
+ /*
+ * For SYS_INIT, there will not be any inst pointer.
+ * Just grab one of the inst from instances list and
+ * use it.
+ */
+ inst = list_first_entry(&core->instances,
+ struct msm_vidc_inst, list);
+
+ mutex_unlock(&core->lock);
+ msm_comm_print_debug_info(inst);
+ mutex_lock(&core->lock);
BUG_ON(core->resources.debug_timeout);
rc = -EIO;
@@ -4017,6 +4045,8 @@ int msm_comm_try_get_prop(struct msm_vidc_inst *inst, enum hal_property ptype,
call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data);
dprintk(VIDC_ERR,
"SESS_PROP timeout can potentially crash the system\n");
+ if (inst->core->resources.debug_timeout)
+ msm_comm_print_debug_info(inst);
BUG_ON(inst->core->resources.debug_timeout);
rc = -ETIMEDOUT;
@@ -5232,3 +5262,92 @@ int msm_vidc_comm_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a)
exit:
return rc;
}
+
+void msm_comm_print_inst_info(struct msm_vidc_inst *inst)
+{
+ struct buffer_info *temp;
+ struct internal_buf *buf;
+ int i = 0;
+ bool is_decode = false;
+ enum vidc_ports port;
+
+ if (!inst) {
+ dprintk(VIDC_ERR, "%s - invalid param %p\n",
+ __func__, inst);
+ return;
+ }
+
+ is_decode = inst->session_type == MSM_VIDC_DECODER;
+ port = is_decode ? OUTPUT_PORT : CAPTURE_PORT;
+ dprintk(VIDC_ERR,
+ "%s session, Codec type: %s HxW: %d x %d fps: %d bitrate: %d bit-depth: %s\n",
+ is_decode ? "Decode" : "Encode", inst->fmts[port]->name,
+ inst->prop.height[port], inst->prop.width[port],
+ inst->prop.fps, inst->prop.bitrate,
+ !inst->bit_depth ? "8" : "10");
+
+ dprintk(VIDC_ERR,
+ "---Buffer details for inst: %p of type: %d---\n",
+ inst, inst->session_type);
+ mutex_lock(&inst->registeredbufs.lock);
+ dprintk(VIDC_ERR, "registered buffer list:\n");
+ list_for_each_entry(temp, &inst->registeredbufs.list, list)
+ for (i = 0; i < temp->num_planes; i++)
+ dprintk(VIDC_ERR,
+ "type: %d plane: %d addr: %pa size: %d\n",
+ temp->type, i, &temp->device_addr[i],
+ temp->size[i]);
+
+ mutex_unlock(&inst->registeredbufs.lock);
+
+ mutex_lock(&inst->scratchbufs.lock);
+ dprintk(VIDC_ERR, "scratch buffer list:\n");
+ list_for_each_entry(buf, &inst->scratchbufs.list, list)
+ dprintk(VIDC_ERR, "type: %d addr: %pa size: %zu\n",
+ buf->buffer_type, &buf->handle->device_addr,
+ buf->handle->size);
+ mutex_unlock(&inst->scratchbufs.lock);
+
+ mutex_lock(&inst->persistbufs.lock);
+ dprintk(VIDC_ERR, "persist buffer list:\n");
+ list_for_each_entry(buf, &inst->persistbufs.list, list)
+ dprintk(VIDC_ERR, "type: %d addr: %pa size: %zu\n",
+ buf->buffer_type, &buf->handle->device_addr,
+ buf->handle->size);
+ mutex_unlock(&inst->persistbufs.lock);
+
+ mutex_lock(&inst->outputbufs.lock);
+ dprintk(VIDC_ERR, "dpb buffer list:\n");
+ list_for_each_entry(buf, &inst->outputbufs.list, list)
+ dprintk(VIDC_ERR, "type: %d addr: %pa size: %zu\n",
+ buf->buffer_type, &buf->handle->device_addr,
+ buf->handle->size);
+ mutex_unlock(&inst->outputbufs.lock);
+}
+
+static void msm_comm_print_debug_info(struct msm_vidc_inst *inst)
+{
+ struct msm_vidc_core *core = NULL;
+ struct msm_vidc_inst *temp = NULL;
+
+ if (!inst || !inst->core) {
+ dprintk(VIDC_ERR, "%s - invalid param %p %p\n",
+ __func__, inst, core);
+ return;
+ }
+ core = inst->core;
+
+ dprintk(VIDC_ERR, "Venus core frequency = %lu",
+ msm_comm_get_clock_rate(core));
+ dprintk(VIDC_ERR, "Printing instance info that caused Error\n");
+ msm_comm_print_inst_info(inst);
+ dprintk(VIDC_ERR, "Printing remaining instances info\n");
+ mutex_lock(&core->lock);
+ list_for_each_entry(temp, &core->instances, list) {
+ /* inst already printed above. Hence don't repeat.*/
+ if (temp == inst)
+ continue;
+ msm_comm_print_inst_info(temp);
+ }
+ mutex_unlock(&core->lock);
+}
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.h b/drivers/media/platform/msm/vidc/msm_vidc_common.h
index 337760508eb1..eac7f658eb31 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.h
@@ -98,4 +98,5 @@ int msm_comm_ctrl_deinit(struct msm_vidc_inst *inst);
void msm_comm_cleanup_internal_buffers(struct msm_vidc_inst *inst);
int msm_vidc_comm_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a);
bool msm_comm_turbo_session(struct msm_vidc_inst *inst);
+void msm_comm_print_inst_info(struct msm_vidc_inst *inst);
#endif
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 1bdc5bf2c93d..25fccab99fb3 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_res_parse.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_res_parse.c
@@ -1238,11 +1238,6 @@ int msm_vidc_smmu_fault_handler(struct iommu_domain *domain,
{
struct msm_vidc_core *core = token;
struct msm_vidc_inst *inst;
- struct buffer_info *temp;
- struct internal_buf *buf;
- int i = 0;
- bool is_decode = false;
- enum vidc_ports port;
if (!domain || !core) {
dprintk(VIDC_ERR, "%s - invalid param %pK %pK\n",
@@ -1257,52 +1252,7 @@ int msm_vidc_smmu_fault_handler(struct iommu_domain *domain,
mutex_lock(&core->lock);
list_for_each_entry(inst, &core->instances, list) {
- is_decode = inst->session_type == MSM_VIDC_DECODER;
- port = is_decode ? OUTPUT_PORT : CAPTURE_PORT;
- dprintk(VIDC_ERR,
- "%s session, Codec type: %s HxW: %d x %d fps: %d bitrate: %d bit-depth: %s\n",
- is_decode ? "Decode" : "Encode", inst->fmts[port]->name,
- inst->prop.height[port], inst->prop.width[port],
- inst->prop.fps, inst->prop.bitrate,
- !inst->bit_depth ? "8" : "10");
-
- dprintk(VIDC_ERR,
- "---Buffer details for inst: %pK of type: %d---\n",
- inst, inst->session_type);
- mutex_lock(&inst->registeredbufs.lock);
- dprintk(VIDC_ERR, "registered buffer list:\n");
- list_for_each_entry(temp, &inst->registeredbufs.list, list)
- for (i = 0; i < temp->num_planes; i++)
- dprintk(VIDC_ERR,
- "type: %d plane: %d addr: %pa size: %d\n",
- temp->type, i, &temp->device_addr[i],
- temp->size[i]);
-
- mutex_unlock(&inst->registeredbufs.lock);
-
- mutex_lock(&inst->scratchbufs.lock);
- dprintk(VIDC_ERR, "scratch buffer list:\n");
- list_for_each_entry(buf, &inst->scratchbufs.list, list)
- dprintk(VIDC_ERR, "type: %d addr: %pa size: %zu\n",
- buf->buffer_type, &buf->handle->device_addr,
- buf->handle->size);
- mutex_unlock(&inst->scratchbufs.lock);
-
- mutex_lock(&inst->persistbufs.lock);
- dprintk(VIDC_ERR, "persist buffer list:\n");
- list_for_each_entry(buf, &inst->persistbufs.list, list)
- dprintk(VIDC_ERR, "type: %d addr: %pa size: %zu\n",
- buf->buffer_type, &buf->handle->device_addr,
- buf->handle->size);
- mutex_unlock(&inst->persistbufs.lock);
-
- mutex_lock(&inst->outputbufs.lock);
- dprintk(VIDC_ERR, "dpb buffer list:\n");
- list_for_each_entry(buf, &inst->outputbufs.list, list)
- dprintk(VIDC_ERR, "type: %d addr: %pa size: %zu\n",
- buf->buffer_type, &buf->handle->device_addr,
- buf->handle->size);
- mutex_unlock(&inst->outputbufs.lock);
+ msm_comm_print_inst_info(inst);
}
core->smmu_fault_handled = true;
mutex_unlock(&core->lock);
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_res_parse.h b/drivers/media/platform/msm/vidc/msm_vidc_res_parse.h
index 23d84e9f7f7a..f6120dc7d1d5 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_res_parse.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_res_parse.h
@@ -16,6 +16,7 @@
#define DT_PARSE
#include <linux/of.h>
#include "msm_vidc_resources.h"
+#include "msm_vidc_common.h"
void msm_vidc_free_platform_resources(
struct msm_vidc_platform_resources *res);
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
index 5a51fbcf9318..e0fb31de38ff 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc/venus_hfi.c
@@ -119,7 +119,7 @@ static inline bool __core_in_valid_state(struct venus_hfi_device *device)
return device->state != VENUS_STATE_DEINIT;
}
-static void __dump_packet(u8 *packet)
+static void __dump_packet(u8 *packet, enum vidc_msg_prio log_level)
{
u32 c = 0, packet_size = *(u32 *)packet;
const int row_size = 32;
@@ -132,7 +132,7 @@ static void __dump_packet(u8 *packet)
packet_size % row_size : row_size;
hex_dump_to_buffer(packet + c * row_size, bytes_to_read,
row_size, 4, row, sizeof(row), false);
- dprintk(VIDC_PKT, "%s\n", row);
+ dprintk(log_level, "%s\n", row);
}
}
@@ -342,7 +342,7 @@ static int __write_queue(struct vidc_iface_q_info *qinfo, u8 *packet,
if (msm_vidc_debug & VIDC_PKT) {
dprintk(VIDC_PKT, "%s: %pK\n", __func__, qinfo);
- __dump_packet(packet);
+ __dump_packet(packet, VIDC_PKT);
}
packet_size_in_words = (*(u32 *)packet) >> 2;
@@ -548,7 +548,7 @@ static int __read_queue(struct vidc_iface_q_info *qinfo, u8 *packet,
if (msm_vidc_debug & VIDC_PKT) {
dprintk(VIDC_PKT, "%s: %pK\n", __func__, qinfo);
- __dump_packet(packet);
+ __dump_packet(packet, VIDC_PKT);
}
return rc;
@@ -2517,7 +2517,6 @@ static int venus_hfi_session_clean(void *session)
mutex_lock(&device->lock);
__session_clean(sess_close);
- __flush_debug_queue(device, NULL);
mutex_unlock(&device->lock);
return 0;
@@ -3337,6 +3336,7 @@ static void __flush_debug_queue(struct venus_hfi_device *device, u8 *packet)
{
bool local_packet = false;
enum vidc_msg_prio log_level = VIDC_FW;
+ unsigned int pending_packet_count = 0;
if (!device) {
dprintk(VIDC_ERR, "%s: Invalid params\n", __func__);
@@ -3361,6 +3361,23 @@ static void __flush_debug_queue(struct venus_hfi_device *device, u8 *packet)
log_level = VIDC_ERR;
}
+ /*
+ * In FATAL situation, print all the pending messages in msg
+ * queue. This is useful for debugging. At this time, message
+ * queues may be corrupted. Hence don't trust them and just print
+ * first max_packets packets.
+ */
+
+ if (local_packet) {
+ dprintk(VIDC_ERR,
+ "Printing all pending messages in message Queue\n");
+ while (!__iface_msgq_read(device, packet) &&
+ pending_packet_count < max_packets) {
+ __dump_packet(packet, log_level);
+ pending_packet_count++;
+ }
+ }
+
while (!__iface_dbgq_read(device, packet)) {
struct hfi_msg_sys_coverage_packet *pkt =
(struct hfi_msg_sys_coverage_packet *) packet;