Merge "video: driver: kill session and core deinit support"
This commit is contained in:

zatwierdzone przez
Gerrit - the friendly Code Review server

commit
11556af3f4
@@ -1861,6 +1861,34 @@ int msm_vdec_g_param(struct msm_vidc_inst *inst,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_vdec_check_colorformat_supported(struct msm_vidc_inst* inst,
|
||||
enum msm_vidc_colorformat_type colorformat)
|
||||
{
|
||||
bool supported = true;
|
||||
|
||||
/* do not reject coloformats before streamon */
|
||||
if (!inst->vb2q[INPUT_PORT].streaming)
|
||||
return true;
|
||||
|
||||
/*
|
||||
* bit_depth 8 bit supports 8 bit colorformats only
|
||||
* bit_depth 10 bit supports 10 bit colorformats only
|
||||
* interlace supports ubwc colorformats only
|
||||
*/
|
||||
if (inst->capabilities->cap[BIT_DEPTH].value == BIT_DEPTH_8 &&
|
||||
!is_8bit_colorformat(colorformat))
|
||||
supported = false;
|
||||
if (inst->capabilities->cap[BIT_DEPTH].value == BIT_DEPTH_10 &&
|
||||
!is_10bit_colorformat(colorformat))
|
||||
supported = false;
|
||||
if (inst->capabilities->cap[CODED_FRAMES].value ==
|
||||
CODED_FRAMES_ADAPTIVE_FIELDS &&
|
||||
!is_ubwc_colorformat(colorformat))
|
||||
supported = false;
|
||||
|
||||
return supported;
|
||||
}
|
||||
|
||||
int msm_vdec_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f)
|
||||
{
|
||||
int rc = 0;
|
||||
@@ -1900,8 +1928,11 @@ int msm_vdec_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f)
|
||||
if (idx > 31)
|
||||
break;
|
||||
if (formats & BIT(i)) {
|
||||
array[idx] = formats & BIT(i);
|
||||
idx++;
|
||||
if (msm_vdec_check_colorformat_supported(inst,
|
||||
formats & BIT(i))) {
|
||||
array[idx] = formats & BIT(i);
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
formats >>= 1;
|
||||
|
@@ -700,18 +700,9 @@ void *msm_vidc_open(void *vidc_core, u32 session_type)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (core->state == MSM_VIDC_CORE_ERROR) {
|
||||
d_vpr_e("%s: core invalid state\n", __func__);
|
||||
rc = msm_vidc_core_init(core);
|
||||
if (rc)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (core->state == MSM_VIDC_CORE_DEINIT) {
|
||||
rc = msm_vidc_core_init(core);
|
||||
if (rc) {
|
||||
msm_vidc_core_deinit(core);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
inst = kzalloc(sizeof(*inst), GFP_KERNEL);
|
||||
if (!inst) {
|
||||
|
@@ -5,7 +5,7 @@
|
||||
|
||||
#include "msm_vidc_debug.h"
|
||||
|
||||
int msm_vidc_debug = VIDC_HIGH | VIDC_LOW | VIDC_PKT | VIDC_ERR | VIDC_PRINTK |
|
||||
int msm_vidc_debug = VIDC_HIGH | VIDC_PKT | VIDC_ERR | VIDC_PRINTK |
|
||||
FW_ERROR | FW_FATAL | FW_FTRACE | FW_LOW | FW_MED | FW_HIGH |
|
||||
FW_PERF | FW_PRINTK;
|
||||
EXPORT_SYMBOL(msm_vidc_debug);
|
||||
@@ -18,3 +18,20 @@ EXPORT_SYMBOL(msm_vidc_syscache_disable);
|
||||
|
||||
int msm_vidc_clock_voting = !1;
|
||||
|
||||
const char *level_str(u32 level)
|
||||
{
|
||||
if (level & VIDC_ERR)
|
||||
return "err ";
|
||||
else if (level & VIDC_HIGH)
|
||||
return "high";
|
||||
else if (level & VIDC_LOW)
|
||||
return "low ";
|
||||
else if (level & VIDC_PERF)
|
||||
return "perf";
|
||||
else if (level & VIDC_PKT)
|
||||
return "pkt ";
|
||||
else if (level & VIDC_BUS)
|
||||
return "bus ";
|
||||
else
|
||||
return "????";
|
||||
}
|
@@ -415,6 +415,45 @@ struct msm_vidc_allocations *msm_vidc_get_allocations(
|
||||
}
|
||||
}
|
||||
|
||||
const char *core_state_name(enum msm_vidc_core_state state)
|
||||
{
|
||||
const char* name = "UNKNOWN";
|
||||
|
||||
switch (state) {
|
||||
case MSM_VIDC_CORE_INIT:
|
||||
name = "CORE_INIT";
|
||||
break;
|
||||
case MSM_VIDC_CORE_DEINIT:
|
||||
name = "CORE_DEINIT";
|
||||
break;
|
||||
default:
|
||||
name = "UNKNOWN";
|
||||
break;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
int msm_vidc_change_core_state(struct msm_vidc_core *core,
|
||||
enum msm_vidc_core_state request_state, const char *func)
|
||||
{
|
||||
if (!core) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!request_state) {
|
||||
d_vpr_e("%s: invalid core request state\n", func);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
d_vpr_h("%s: core state changed from %s to %s\n",
|
||||
func, core_state_name(core->state),
|
||||
core_state_name(request_state));
|
||||
core->state = request_state;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *state_name(enum msm_vidc_inst_state state)
|
||||
{
|
||||
const char *name = "UNKNOWN";
|
||||
@@ -1097,29 +1136,31 @@ int msm_vidc_get_fps(struct msm_vidc_inst *inst)
|
||||
return fps;
|
||||
}
|
||||
|
||||
int msm_vidc_num_queued_bufs(struct msm_vidc_inst *inst, u32 type)
|
||||
int msm_vidc_num_buffers(struct msm_vidc_inst *inst,
|
||||
enum msm_vidc_buffer_type type, enum msm_vidc_buffer_attributes attr)
|
||||
{
|
||||
int count = 0;
|
||||
struct msm_vidc_buffer *vbuf;
|
||||
struct msm_vidc_buffers* buffers;
|
||||
struct msm_vidc_buffers *buffers;
|
||||
|
||||
if (!inst) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return 0;
|
||||
return count;
|
||||
}
|
||||
if (type == OUTPUT_MPLANE) {
|
||||
if (type == MSM_VIDC_BUF_OUTPUT) {
|
||||
buffers = &inst->buffers.output;
|
||||
} else if (type == INPUT_MPLANE) {
|
||||
} else if (type == MSM_VIDC_BUF_INPUT) {
|
||||
buffers = &inst->buffers.input;
|
||||
} else {
|
||||
s_vpr_e(inst->sid, "%s: invalid buffer type %#x\n", __func__, type);
|
||||
return -EINVAL;
|
||||
s_vpr_e(inst->sid, "%s: invalid buffer type %#x\n",
|
||||
__func__, type);
|
||||
return count;
|
||||
}
|
||||
|
||||
list_for_each_entry(vbuf, &buffers->list, list) {
|
||||
if (vbuf->type != type)
|
||||
continue;
|
||||
if (!(vbuf->attr & MSM_VIDC_ATTR_QUEUED))
|
||||
if (!(vbuf->attr & attr))
|
||||
continue;
|
||||
count++;
|
||||
}
|
||||
@@ -1561,7 +1602,6 @@ int msm_vidc_create_internal_buffer(struct msm_vidc_inst *inst,
|
||||
struct msm_vidc_alloc *alloc;
|
||||
struct msm_vidc_map *map;
|
||||
|
||||
d_vpr_h("%s()\n", __func__);
|
||||
if (!inst || !inst->core) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
@@ -1646,7 +1686,6 @@ int msm_vidc_create_internal_buffers(struct msm_vidc_inst *inst,
|
||||
struct msm_vidc_buffers *buffers;
|
||||
int i;
|
||||
|
||||
d_vpr_h("%s()\n", __func__);
|
||||
if (!inst || !inst->core) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
@@ -1675,7 +1714,6 @@ int msm_vidc_queue_internal_buffers(struct msm_vidc_inst *inst,
|
||||
struct msm_vidc_buffers *buffers;
|
||||
struct msm_vidc_buffer *buffer, *dummy;
|
||||
|
||||
d_vpr_h("%s()\n", __func__);
|
||||
if (!inst || !inst->core) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
@@ -1723,7 +1761,6 @@ int msm_vidc_release_internal_buffers(struct msm_vidc_inst *inst,
|
||||
struct msm_vidc_buffers *buffers;
|
||||
struct msm_vidc_buffer *buffer, *dummy;
|
||||
|
||||
d_vpr_h("%s()\n", __func__);
|
||||
if (!inst || !inst->core) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
@@ -1995,8 +2032,22 @@ int msm_vidc_session_open(struct msm_vidc_inst *inst)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = venus_hfi_session_open(inst);
|
||||
inst->packet_size = 4096;
|
||||
inst->packet = kzalloc(inst->packet_size, GFP_KERNEL);
|
||||
if (!inst->packet) {
|
||||
s_vpr_e(inst->sid, "%s(): inst packet allocation failed\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rc = venus_hfi_session_open(inst);
|
||||
if (rc)
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
error:
|
||||
s_vpr_e(inst->sid, "%s(): session open failed\n", __func__);
|
||||
kfree(inst->packet);
|
||||
inst->packet = NULL;
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -2039,8 +2090,10 @@ int msm_vidc_session_streamoff(struct msm_vidc_inst *inst,
|
||||
enum msm_vidc_port_type port)
|
||||
{
|
||||
int rc = 0;
|
||||
int count = 0;
|
||||
struct msm_vidc_core *core;
|
||||
enum signal_session_response signal_type;
|
||||
enum msm_vidc_buffer_type buffer_type;
|
||||
|
||||
if (!inst || !inst->core) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
@@ -2049,8 +2102,10 @@ int msm_vidc_session_streamoff(struct msm_vidc_inst *inst,
|
||||
|
||||
if (port == INPUT_PORT) {
|
||||
signal_type = SIGNAL_CMD_STOP_INPUT;
|
||||
buffer_type = MSM_VIDC_BUF_INPUT;
|
||||
} else if (port == OUTPUT_PORT) {
|
||||
signal_type = SIGNAL_CMD_STOP_OUTPUT;
|
||||
buffer_type = MSM_VIDC_BUF_OUTPUT;
|
||||
} else {
|
||||
s_vpr_e(inst->sid, "%s: invalid port: %d\n", __func__, port);
|
||||
return -EINVAL;
|
||||
@@ -2068,19 +2123,31 @@ int msm_vidc_session_streamoff(struct msm_vidc_inst *inst,
|
||||
&inst->completions[signal_type],
|
||||
msecs_to_jiffies(
|
||||
core->capabilities[HW_RESPONSE_TIMEOUT].value));
|
||||
mutex_lock(&inst->lock);
|
||||
if (!rc) {
|
||||
s_vpr_e(inst->sid, "%s: session stop timed out for port: %d\n",
|
||||
__func__, port);
|
||||
//msm_comm_kill_session(inst);
|
||||
rc = -EIO;
|
||||
rc = -ETIMEDOUT;
|
||||
msm_vidc_core_timeout(inst->core);
|
||||
} else {
|
||||
rc = 0;
|
||||
s_vpr_h(inst->sid, "%s: stop successful on port: %d\n",
|
||||
__func__, port);
|
||||
}
|
||||
mutex_lock(&inst->lock);
|
||||
|
||||
return rc;
|
||||
/* no more queued buffers after streamoff */
|
||||
count = msm_vidc_num_buffers(inst, buffer_type, MSM_VIDC_ATTR_QUEUED);
|
||||
if (count) {
|
||||
s_vpr_e(inst->sid, "%s: %d buffers pending on port: %d\n",
|
||||
__func__, count, port);
|
||||
msm_vidc_kill_session(inst);
|
||||
}
|
||||
rc = msm_vidc_flush_buffers(inst, buffer_type);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
s_vpr_h(inst->sid, "%s: stop successful on port: %d\n",
|
||||
__func__, port);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msm_vidc_session_close(struct msm_vidc_inst *inst)
|
||||
@@ -2105,19 +2172,43 @@ int msm_vidc_session_close(struct msm_vidc_inst *inst)
|
||||
&inst->completions[SIGNAL_CMD_CLOSE],
|
||||
msecs_to_jiffies(
|
||||
core->capabilities[HW_RESPONSE_TIMEOUT].value));
|
||||
mutex_lock(&inst->lock);
|
||||
if (!rc) {
|
||||
s_vpr_e(inst->sid, "%s: session close timed out\n", __func__);
|
||||
//msm_comm_kill_session(inst);
|
||||
rc = -EIO;
|
||||
rc = -ETIMEDOUT;
|
||||
msm_vidc_core_timeout(inst->core);
|
||||
} else {
|
||||
rc = 0;
|
||||
s_vpr_h(inst->sid, "%s: close successful\n", __func__);
|
||||
}
|
||||
mutex_lock(&inst->lock);
|
||||
|
||||
msm_vidc_remove_session(inst);
|
||||
|
||||
s_vpr_h(inst->sid, "%s: free session packet data\n", __func__);
|
||||
kfree(inst->packet);
|
||||
inst->packet = NULL;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int msm_vidc_kill_session(struct msm_vidc_inst *inst)
|
||||
{
|
||||
if (!inst) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!inst->session_id) {
|
||||
s_vpr_e(inst->sid, "%s: already killed\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
s_vpr_e(inst->sid, "%s: killing session\n", __func__);
|
||||
msm_vidc_session_close(inst);
|
||||
msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msm_vidc_get_inst_capability(struct msm_vidc_inst *inst)
|
||||
{
|
||||
int rc = 0;
|
||||
@@ -2363,16 +2454,28 @@ error:
|
||||
int msm_vidc_core_deinit(struct msm_vidc_core *core)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_vidc_inst *inst, *dummy;
|
||||
|
||||
d_vpr_h("%s()\n", __func__);
|
||||
if (!core) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
mutex_lock(&core->lock);
|
||||
d_vpr_h("%s()\n", __func__);
|
||||
if (core->state == MSM_VIDC_CORE_DEINIT)
|
||||
goto unlock;
|
||||
|
||||
venus_hfi_core_deinit(core);
|
||||
msm_vidc_deinit_instance_caps(core);
|
||||
msm_vidc_deinit_core_caps(core);
|
||||
/* unlink all sessions from core, if any */
|
||||
list_for_each_entry_safe(inst, dummy, &core->instances, list) {
|
||||
msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
|
||||
list_del(&inst->list);
|
||||
}
|
||||
msm_vidc_change_core_state(core, MSM_VIDC_CORE_DEINIT, __func__);
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&core->lock);
|
||||
return rc;
|
||||
}
|
||||
@@ -2381,18 +2484,12 @@ int msm_vidc_core_init(struct msm_vidc_core *core)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
d_vpr_h("%s()\n", __func__);
|
||||
if (!core || !core->platform) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&core->lock);
|
||||
if (core->state == MSM_VIDC_CORE_ERROR) {
|
||||
d_vpr_e("%s: core invalid state\n", __func__);
|
||||
rc = -EINVAL;
|
||||
goto unlock;
|
||||
}
|
||||
if (core->state == MSM_VIDC_CORE_INIT) {
|
||||
rc = 0;
|
||||
goto unlock;
|
||||
@@ -2405,7 +2502,7 @@ int msm_vidc_core_init(struct msm_vidc_core *core)
|
||||
if (rc)
|
||||
goto unlock;
|
||||
|
||||
core->state = MSM_VIDC_CORE_INIT;
|
||||
msm_vidc_change_core_state(core, MSM_VIDC_CORE_INIT, __func__);
|
||||
init_completion(&core->init_done);
|
||||
core->smmu_fault_handled = false;
|
||||
core->ssr.trigger = false;
|
||||
@@ -2413,7 +2510,6 @@ int msm_vidc_core_init(struct msm_vidc_core *core)
|
||||
rc = venus_hfi_core_init(core);
|
||||
if (rc) {
|
||||
d_vpr_e("%s: core init failed\n", __func__);
|
||||
core->state = MSM_VIDC_CORE_DEINIT;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
@@ -2422,20 +2518,27 @@ int msm_vidc_core_init(struct msm_vidc_core *core)
|
||||
mutex_unlock(&core->lock);
|
||||
rc = wait_for_completion_timeout(&core->init_done, msecs_to_jiffies(
|
||||
core->capabilities[HW_RESPONSE_TIMEOUT].value));
|
||||
mutex_lock(&core->lock);
|
||||
if (!rc) {
|
||||
d_vpr_e("%s: system init timed out\n", __func__);
|
||||
d_vpr_e("%s: core init timed out\n", __func__);
|
||||
rc = -ETIMEDOUT;
|
||||
} else {
|
||||
d_vpr_h("%s: system init wait completed\n", __func__);
|
||||
rc = 0;
|
||||
}
|
||||
mutex_lock(&core->lock);
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&core->lock);
|
||||
if (rc)
|
||||
msm_vidc_core_init(core);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int msm_vidc_core_timeout(struct msm_vidc_core *core)
|
||||
{
|
||||
return msm_vidc_core_deinit(core);
|
||||
}
|
||||
|
||||
int msm_vidc_smmu_fault_handler(struct iommu_domain *domain,
|
||||
struct device *dev, unsigned long iova, int flags, void *data)
|
||||
{
|
||||
@@ -2464,6 +2567,50 @@ void msm_vidc_batch_handler(struct work_struct *work)
|
||||
{
|
||||
}
|
||||
|
||||
int msm_vidc_flush_buffers(struct msm_vidc_inst* inst,
|
||||
enum msm_vidc_buffer_type type)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_vidc_buffers *buffers;
|
||||
struct msm_vidc_buffer *buf, *dummy;
|
||||
enum msm_vidc_buffer_type buffer_type[2];
|
||||
int i;
|
||||
|
||||
if (!inst) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (type == MSM_VIDC_BUF_INPUT) {
|
||||
buffer_type[0] = MSM_VIDC_BUF_INPUT_META;
|
||||
buffer_type[1] = MSM_VIDC_BUF_INPUT;
|
||||
} else if (type == MSM_VIDC_BUF_OUTPUT) {
|
||||
buffer_type[0] = MSM_VIDC_BUF_OUTPUT_META;
|
||||
buffer_type[1] = MSM_VIDC_BUF_OUTPUT;
|
||||
} else {
|
||||
s_vpr_h(inst->sid, "%s: invalid buffer type %d\n",
|
||||
__func__, type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(buffer_type); i++) {
|
||||
buffers = msm_vidc_get_buffers(inst, buffer_type[i], __func__);
|
||||
if (!buffers)
|
||||
return -EINVAL;
|
||||
|
||||
list_for_each_entry_safe(buf, dummy, &buffers->list, list) {
|
||||
if (buf->attr & MSM_VIDC_ATTR_QUEUED ||
|
||||
buf->attr & MSM_VIDC_ATTR_DEFERRED) {
|
||||
print_vidc_buffer(VIDC_ERR, "flushing buffer", inst, buf);
|
||||
msm_vidc_vb2_buffer_done(inst, buf);
|
||||
msm_vidc_put_driver_buf(inst, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void msm_vidc_destroy_buffers(struct msm_vidc_inst *inst)
|
||||
{
|
||||
struct msm_vidc_buffers *buffers;
|
||||
@@ -2484,6 +2631,11 @@ void msm_vidc_destroy_buffers(struct msm_vidc_inst *inst)
|
||||
};
|
||||
int i;
|
||||
|
||||
if (!inst) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(buf_types); i++) {
|
||||
buffers = msm_vidc_get_buffers(inst, buf_types[i], __func__);
|
||||
if (!buffers)
|
||||
@@ -2573,6 +2725,11 @@ void put_inst(struct msm_vidc_inst *inst)
|
||||
kref_put(&inst->kref, msm_vidc_close_helper);
|
||||
}
|
||||
|
||||
bool core_lock_check(struct msm_vidc_core *core, const char* func)
|
||||
{
|
||||
return mutex_is_locked(&core->lock);
|
||||
}
|
||||
|
||||
void core_lock(struct msm_vidc_core *core, const char *function)
|
||||
{
|
||||
mutex_lock(&core->lock);
|
||||
@@ -2583,6 +2740,11 @@ void core_unlock(struct msm_vidc_core *core, const char *function)
|
||||
mutex_unlock(&core->lock);
|
||||
}
|
||||
|
||||
bool inst_lock_check(struct msm_vidc_inst *inst, const char* func)
|
||||
{
|
||||
return mutex_is_locked(&inst->lock);
|
||||
}
|
||||
|
||||
void inst_lock(struct msm_vidc_inst *inst, const char *function)
|
||||
{
|
||||
mutex_lock(&inst->lock);
|
||||
|
@@ -425,9 +425,11 @@ static int msm_vidc_apply_dcvs(struct msm_vidc_inst *inst)
|
||||
power = &inst->power;
|
||||
|
||||
if (is_decode_session(inst)) {
|
||||
bufs_with_fw = msm_vidc_num_queued_bufs(inst, OUTPUT_MPLANE);
|
||||
bufs_with_fw = msm_vidc_num_buffers(inst,
|
||||
MSM_VIDC_BUF_OUTPUT, MSM_VIDC_ATTR_QUEUED);
|
||||
} else {
|
||||
bufs_with_fw = msm_vidc_num_queued_bufs(inst, INPUT_MPLANE);
|
||||
bufs_with_fw = msm_vidc_num_buffers(inst,
|
||||
MSM_VIDC_BUF_INPUT, MSM_VIDC_ATTR_QUEUED);
|
||||
}
|
||||
|
||||
/* +1 as one buffer is going to be queued after the function */
|
||||
|
@@ -178,7 +178,7 @@ static int msm_vidc_deinitialize_core(struct msm_vidc_core *core)
|
||||
d_vpr_h("%s()\n", __func__);
|
||||
|
||||
mutex_destroy(&core->lock);
|
||||
core->state = MSM_VIDC_CORE_DEINIT;
|
||||
msm_vidc_change_core_state(core, MSM_VIDC_CORE_DEINIT, __func__);
|
||||
|
||||
if (core->pm_workq)
|
||||
destroy_workqueue(core->pm_workq);
|
||||
@@ -199,7 +199,7 @@ static int msm_vidc_initialize_core(struct msm_vidc_core *core)
|
||||
}
|
||||
d_vpr_h("%s()\n", __func__);
|
||||
|
||||
core->state = MSM_VIDC_CORE_DEINIT;
|
||||
msm_vidc_change_core_state(core, MSM_VIDC_CORE_DEINIT, __func__);
|
||||
|
||||
core->device_workq = create_singlethread_workqueue("device_workq");
|
||||
if (!core->device_workq) {
|
||||
|
@@ -12,7 +12,7 @@
|
||||
|
||||
static struct msm_vidc_inst *get_vidc_inst(struct file *filp, void *fh)
|
||||
{
|
||||
if (!filp->private_data)
|
||||
if (!filp || !filp->private_data)
|
||||
return NULL;
|
||||
return container_of(filp->private_data,
|
||||
struct msm_vidc_inst, event_handler);
|
||||
|
@@ -33,6 +33,8 @@
|
||||
|
||||
#define MAX_FIRMWARE_NAME_SIZE 128
|
||||
|
||||
extern struct msm_vidc_core *g_core;
|
||||
|
||||
static int __resume(struct msm_vidc_core *core);
|
||||
static int __suspend(struct msm_vidc_core *core);
|
||||
|
||||
@@ -161,7 +163,7 @@ static void __strict_check(struct msm_vidc_core *core)
|
||||
|
||||
bool __core_in_valid_state(struct msm_vidc_core *core)
|
||||
{
|
||||
return core->state != MSM_VIDC_CORE_ERROR;
|
||||
return core->state == MSM_VIDC_CORE_INIT;
|
||||
}
|
||||
|
||||
static bool is_sys_cache_present(struct msm_vidc_core *core)
|
||||
@@ -169,6 +171,30 @@ static bool is_sys_cache_present(struct msm_vidc_core *core)
|
||||
return core->dt->sys_cache_present;
|
||||
}
|
||||
|
||||
static bool valdiate_session(struct msm_vidc_inst* inst, const char *func)
|
||||
{
|
||||
bool valid = false;
|
||||
struct msm_vidc_inst *temp;
|
||||
struct msm_vidc_core *core = g_core;
|
||||
|
||||
if (!core)
|
||||
return false;
|
||||
|
||||
mutex_lock(&core->lock);
|
||||
list_for_each_entry(temp, &core->instances, list) {
|
||||
if (temp == inst) {
|
||||
valid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&core->lock);
|
||||
|
||||
if (!valid)
|
||||
s_vpr_e(inst->sid, "%s: invalid session\n", func);
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
void __write_register(struct msm_vidc_core *core,
|
||||
u32 reg, u32 value)
|
||||
{
|
||||
@@ -879,8 +905,12 @@ int __iface_msgq_read(struct msm_vidc_core *core, void *pkt)
|
||||
}
|
||||
|
||||
if (!__read_queue(q_info, (u8 *)pkt, &tx_req_is_set)) {
|
||||
if (tx_req_is_set)
|
||||
call_venus_op(core, raise_interrupt, core);
|
||||
if (tx_req_is_set) {
|
||||
//call_venus_op(core, raise_interrupt, core);
|
||||
d_vpr_e("%s: queue is full\n", __func__);
|
||||
rc = -EINVAL;
|
||||
goto read_error_null;
|
||||
}
|
||||
rc = 0;
|
||||
} else {
|
||||
rc = -ENODATA;
|
||||
@@ -911,11 +941,16 @@ int __iface_dbgq_read(struct msm_vidc_core *core, void *pkt)
|
||||
}
|
||||
|
||||
if (!__read_queue(q_info, (u8 *)pkt, &tx_req_is_set)) {
|
||||
if (tx_req_is_set)
|
||||
call_venus_op(core, raise_interrupt, core);
|
||||
if (tx_req_is_set) {
|
||||
d_vpr_e("%s: queue is full\n", __func__);
|
||||
//call_venus_op(core, raise_interrupt, core);
|
||||
rc = -EINVAL;
|
||||
goto dbg_error_null;
|
||||
}
|
||||
rc = 0;
|
||||
} else
|
||||
} else {
|
||||
rc = -ENODATA;
|
||||
}
|
||||
|
||||
dbg_error_null:
|
||||
return rc;
|
||||
@@ -1906,6 +1941,24 @@ static int __set_ubwc_config(struct msm_vidc_core *core)
|
||||
return rc;
|
||||
}
|
||||
*/
|
||||
|
||||
static int __venus_power_off(struct msm_vidc_core* core)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (!core->power_enabled)
|
||||
return 0;
|
||||
|
||||
rc = call_venus_op(core, power_off, core);
|
||||
if (rc) {
|
||||
d_vpr_e("Failed to power off, err: %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
core->power_enabled = false;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int __venus_power_on(struct msm_vidc_core *core)
|
||||
{
|
||||
int rc = 0;
|
||||
@@ -2006,7 +2059,7 @@ static int __resume(struct msm_vidc_core *core)
|
||||
} else if (core->power_enabled) {
|
||||
goto exit;
|
||||
} else if (!__core_in_valid_state(core)) {
|
||||
d_vpr_e("%s: core in deinit state\n", __func__);
|
||||
d_vpr_e("%s: core not in valid state\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -2391,9 +2444,7 @@ static void __unload_fw(struct msm_vidc_core *core)
|
||||
qcom_scm_pas_shutdown(core->dt->fw_cookie);
|
||||
core->dt->fw_cookie = 0;
|
||||
|
||||
__interface_queues_deinit(core);
|
||||
call_venus_op(core, power_off, core);
|
||||
|
||||
__venus_power_off(core);
|
||||
__deinit_resources(core);
|
||||
|
||||
d_vpr_h("Firmware unloaded successfully\n");
|
||||
@@ -2444,16 +2495,15 @@ void venus_hfi_work_handler(struct work_struct *work)
|
||||
mutex_lock(&core->lock);
|
||||
if (__resume(core)) {
|
||||
d_vpr_e("%s: Power on failed\n", __func__);
|
||||
mutex_unlock(&core->lock);
|
||||
goto err_no_work;
|
||||
}
|
||||
|
||||
call_venus_op(core, clear_interrupt, core);
|
||||
mutex_unlock(&core->lock);
|
||||
|
||||
num_responses = __response_handler(core);
|
||||
|
||||
err_no_work:
|
||||
mutex_unlock(&core->lock);
|
||||
if (!call_venus_op(core, watchdog, core, core->intr_status))
|
||||
enable_irq(core->dt->irq);
|
||||
}
|
||||
@@ -2611,6 +2661,7 @@ int venus_hfi_core_deinit(struct msm_vidc_core *core)
|
||||
return -EINVAL;
|
||||
}
|
||||
d_vpr_h("%s(): core %pK\n", __func__, core);
|
||||
__flush_debug_queue(core, core->packet, core->packet_size);
|
||||
__disable_subcaches(core);
|
||||
__interface_queues_deinit(core);
|
||||
__unload_fw(core);
|
||||
@@ -2652,13 +2703,6 @@ int venus_hfi_session_open(struct msm_vidc_inst *inst)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
inst->packet_size = 4096;
|
||||
inst->packet = kzalloc(inst->packet_size, GFP_KERNEL);
|
||||
if (!inst->packet) {
|
||||
d_vpr_e("%s(): inst packet allocation failed\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rc = hfi_packet_session_command(inst,
|
||||
HFI_CMD_OPEN,
|
||||
(HFI_HOST_FLAGS_RESPONSE_REQUIRED |
|
||||
@@ -2669,13 +2713,13 @@ int venus_hfi_session_open(struct msm_vidc_inst *inst)
|
||||
&inst->session_id, /* payload */
|
||||
sizeof(u32));
|
||||
if (rc)
|
||||
goto error;
|
||||
return rc;
|
||||
|
||||
rc = __iface_cmdq_write(inst->core, inst->packet);
|
||||
if (rc)
|
||||
goto error;
|
||||
error:
|
||||
return rc;
|
||||
return rc;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int venus_hfi_session_set_codec(struct msm_vidc_inst *inst)
|
||||
@@ -2687,6 +2731,8 @@ int venus_hfi_session_set_codec(struct msm_vidc_inst *inst)
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!valdiate_session(inst, __func__))
|
||||
return -EINVAL;
|
||||
|
||||
codec = get_hfi_codec(inst);
|
||||
rc = venus_hfi_session_property(inst,
|
||||
@@ -2716,6 +2762,9 @@ int venus_hfi_session_property(struct msm_vidc_inst *inst,
|
||||
}
|
||||
core = inst->core;
|
||||
|
||||
if (!valdiate_session(inst, __func__))
|
||||
return -EINVAL;
|
||||
|
||||
rc = hfi_create_header(inst->packet, inst->packet_size,
|
||||
inst->session_id, core->header_id++);
|
||||
if (rc)
|
||||
@@ -2750,6 +2799,8 @@ int venus_hfi_session_close(struct msm_vidc_inst *inst)
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!valdiate_session(inst, __func__))
|
||||
return -EINVAL;
|
||||
|
||||
rc = hfi_packet_session_command(inst,
|
||||
HFI_CMD_CLOSE,
|
||||
@@ -2764,8 +2815,6 @@ int venus_hfi_session_close(struct msm_vidc_inst *inst)
|
||||
if (!rc)
|
||||
__iface_cmdq_write(inst->core, inst->packet);
|
||||
|
||||
kfree(inst->packet);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -2777,6 +2826,9 @@ int venus_hfi_start(struct msm_vidc_inst *inst, enum msm_vidc_port_type port)
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!valdiate_session(inst, __func__))
|
||||
return -EINVAL;
|
||||
|
||||
if (port != INPUT_PORT && port != OUTPUT_PORT) {
|
||||
s_vpr_e(inst->sid, "%s: invalid port %d\n", __func__, port);
|
||||
return -EINVAL;
|
||||
@@ -2809,6 +2861,9 @@ int venus_hfi_stop(struct msm_vidc_inst *inst, enum msm_vidc_port_type port)
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!valdiate_session(inst, __func__))
|
||||
return -EINVAL;
|
||||
|
||||
if (port != INPUT_PORT && port != OUTPUT_PORT) {
|
||||
s_vpr_e(inst->sid, "%s: invalid port %d\n", __func__, port);
|
||||
return -EINVAL;
|
||||
@@ -2847,6 +2902,9 @@ int venus_hfi_session_command(struct msm_vidc_inst *inst,
|
||||
}
|
||||
core = inst->core;
|
||||
|
||||
if (!valdiate_session(inst, __func__))
|
||||
return -EINVAL;
|
||||
|
||||
rc = hfi_create_header(inst->packet, inst->packet_size,
|
||||
inst->session_id,
|
||||
core->header_id++);
|
||||
@@ -2889,6 +2947,9 @@ int venus_hfi_queue_buffer(struct msm_vidc_inst *inst,
|
||||
}
|
||||
core = inst->core;
|
||||
|
||||
if (!valdiate_session(inst, __func__))
|
||||
return -EINVAL;
|
||||
|
||||
rc = get_hfi_buffer(inst, buffer, &hfi_buffer);
|
||||
if (rc)
|
||||
return rc;
|
||||
@@ -2945,6 +3006,9 @@ int venus_hfi_release_buffer(struct msm_vidc_inst *inst,
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!valdiate_session(inst, __func__))
|
||||
return -EINVAL;
|
||||
|
||||
if (!is_internal_buffer(buffer->type)) {
|
||||
s_vpr_e(inst->sid, "release not allowed for buffer type %d\n",
|
||||
buffer->type);
|
||||
|
@@ -229,16 +229,8 @@ static int handle_session_error(struct msm_vidc_inst *inst,
|
||||
static int handle_system_error(struct msm_vidc_core *core,
|
||||
struct hfi_packet *pkt)
|
||||
{
|
||||
mutex_lock(&core->lock);
|
||||
if (core->state == MSM_VIDC_CORE_DEINIT) {
|
||||
d_vpr_e("%s: core already deinitialized\n", __func__);
|
||||
mutex_unlock(&core->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
d_vpr_e("%s: system error received\n", __func__);
|
||||
core->state = MSM_VIDC_CORE_DEINIT;
|
||||
mutex_unlock(&core->lock);
|
||||
msm_vidc_core_deinit(core);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -264,6 +256,7 @@ static int handle_session_open(struct msm_vidc_inst *inst,
|
||||
if (pkt->flags & HFI_FW_FLAGS_SESSION_ERROR) {
|
||||
s_vpr_e(inst->sid, "%s: received session error\n", __func__);
|
||||
msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pkt->flags & HFI_FW_FLAGS_SUCCESS)
|
||||
@@ -293,6 +286,7 @@ static int handle_session_start(struct msm_vidc_inst *inst,
|
||||
if (pkt->flags & HFI_FW_FLAGS_SESSION_ERROR) {
|
||||
s_vpr_e(inst->sid, "%s: received session error\n", __func__);
|
||||
msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pkt->flags & HFI_FW_FLAGS_SUCCESS)
|
||||
@@ -351,6 +345,7 @@ static int handle_session_drain(struct msm_vidc_inst *inst,
|
||||
if (pkt->flags & HFI_FW_FLAGS_SESSION_ERROR) {
|
||||
s_vpr_e(inst->sid, "%s: received session error\n", __func__);
|
||||
msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pkt->flags & HFI_FW_FLAGS_SUCCESS)
|
||||
|
Reference in New Issue
Block a user