video: driver: enable session stability testing
Enable session stability test support. Clients can trigger session stability through debugfs as follows: echo <trigger_val> > /d/msm_vidc/core/trigger_stability u64 trigger_val provides: <payload><sub_client_id><stability_type> stability_type : 0-3 bits(one of the HFI_STABILITY_TYPE_*) sub_client_id : 4-7 bits(1 - CCE, 2 - VSP, 3 - VPP, 4 - CPUSS) reserved : 8-31 bits(Not used) payload : 32-63 bits(depends on stability_type) For e.x, to VCODEC_HUNG on CCE hardware module for 5 consequtive frames. adb shell "echo 0x500000011 > /d/msm_vidc/core/trigger_stability". Change-Id: I604f0430e3ab905504c4f0b7c84b157a5d464958 Signed-off-by: Govindaraj Rajagopal <quic_grajagop@quicinc.com>
This commit is contained in:
@@ -319,6 +319,10 @@ int msm_vidc_smmu_fault_handler(struct iommu_domain *domain,
|
||||
int msm_vidc_trigger_ssr(struct msm_vidc_core *core,
|
||||
u64 trigger_ssr_val);
|
||||
void msm_vidc_ssr_handler(struct work_struct *work);
|
||||
int msm_vidc_trigger_stability(struct msm_vidc_core *core,
|
||||
u64 trigger_stability_val);
|
||||
void msm_vidc_stability_handler(struct work_struct *work);
|
||||
int cancel_stability_work_sync(struct msm_vidc_inst *inst);
|
||||
void msm_vidc_fw_unload_handler(struct work_struct *work);
|
||||
int msm_vidc_suspend(struct msm_vidc_core *core);
|
||||
void msm_vidc_batch_handler(struct work_struct *work);
|
||||
|
@@ -129,6 +129,8 @@ struct msm_vidc_inst {
|
||||
struct msm_vidc_session_idle session_idle;
|
||||
struct delayed_work response_work;
|
||||
struct delayed_work stats_work;
|
||||
struct work_struct stability_work;
|
||||
struct msm_vidc_stability stability;
|
||||
struct workqueue_struct *response_workq;
|
||||
struct list_head response_works; /* list of struct response_work */
|
||||
struct list_head enc_input_crs;
|
||||
|
@@ -555,6 +555,11 @@ enum msm_vidc_ssr_trigger_type {
|
||||
SSR_HW_WDOG_IRQ,
|
||||
};
|
||||
|
||||
enum msm_vidc_stability_trigger_type {
|
||||
STABILITY_VCODEC_HUNG = 1,
|
||||
STABILITY_ENC_BUFFER_FULL,
|
||||
};
|
||||
|
||||
enum msm_vidc_cache_op {
|
||||
MSM_VIDC_CACHE_CLEAN,
|
||||
MSM_VIDC_CACHE_INVALIDATE,
|
||||
@@ -873,6 +878,12 @@ struct msm_vidc_ssr {
|
||||
u32 test_addr;
|
||||
};
|
||||
|
||||
struct msm_vidc_stability {
|
||||
enum msm_vidc_stability_trigger_type stability_type;
|
||||
u32 sub_client_id;
|
||||
u32 value;
|
||||
};
|
||||
|
||||
struct msm_vidc_sfr {
|
||||
u32 bufSize;
|
||||
u8 rg_data[1];
|
||||
|
@@ -52,6 +52,8 @@ int venus_hfi_noc_error_info(struct msm_vidc_core *core);
|
||||
int venus_hfi_suspend(struct msm_vidc_core *core);
|
||||
int venus_hfi_trigger_ssr(struct msm_vidc_core *core, u32 type,
|
||||
u32 client_id, u32 addr);
|
||||
int venus_hfi_trigger_stability(struct msm_vidc_inst *inst, u32 type,
|
||||
u32 client_id, u32 val);
|
||||
int venus_hfi_scale_clocks(struct msm_vidc_inst* inst, u64 freq);
|
||||
int venus_hfi_scale_buses(struct msm_vidc_inst* inst, u64 bw_ddr, u64 bw_llcc);
|
||||
|
||||
|
@@ -889,6 +889,7 @@ void *msm_vidc_open(void *vidc_core, u32 session_type)
|
||||
|
||||
INIT_DELAYED_WORK(&inst->response_work, handle_session_response_work_handler);
|
||||
INIT_DELAYED_WORK(&inst->stats_work, msm_vidc_stats_handler);
|
||||
INIT_WORK(&inst->stability_work, msm_vidc_stability_handler);
|
||||
|
||||
inst->capabilities = kzalloc(sizeof(struct msm_vidc_inst_capability), GFP_KERNEL);
|
||||
if (!inst->capabilities) {
|
||||
@@ -960,6 +961,7 @@ int msm_vidc_close(void *instance)
|
||||
msm_vidc_destroy_buffers(inst);
|
||||
inst_unlock(inst, __func__);
|
||||
cancel_response_work_sync(inst);
|
||||
cancel_stability_work_sync(inst);
|
||||
cancel_stats_work_sync(inst);
|
||||
msm_vidc_show_stats(inst);
|
||||
put_inst(inst);
|
||||
|
@@ -15,6 +15,7 @@
|
||||
extern struct msm_vidc_core *g_core;
|
||||
|
||||
#define MAX_SSR_STRING_LEN 64
|
||||
#define MAX_STABILITY_STRING_LEN 64
|
||||
#define MAX_DEBUG_LEVEL_STRING_LEN 15
|
||||
#define MSM_VIDC_MIN_STATS_DELAY_MS 200
|
||||
#define MSM_VIDC_MAX_STATS_DELAY_MS 10000
|
||||
@@ -296,6 +297,47 @@ static const struct file_operations ssr_fops = {
|
||||
.write = trigger_ssr_write,
|
||||
};
|
||||
|
||||
static ssize_t trigger_stability_write(struct file *filp, const char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
unsigned long stability_trigger_val = 0;
|
||||
int rc = 0;
|
||||
struct msm_vidc_core *core = filp->private_data;
|
||||
size_t size = MAX_STABILITY_STRING_LEN;
|
||||
char kbuf[MAX_STABILITY_STRING_LEN + 1] = { 0 };
|
||||
|
||||
if (!buf)
|
||||
return -EINVAL;
|
||||
|
||||
if (!count)
|
||||
goto exit;
|
||||
|
||||
if (count < size)
|
||||
size = count;
|
||||
|
||||
if (copy_from_user(kbuf, buf, size)) {
|
||||
d_vpr_e("%s: User memory fault\n", __func__);
|
||||
rc = -EFAULT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
rc = kstrtoul(kbuf, 0, &stability_trigger_val);
|
||||
if (rc) {
|
||||
d_vpr_e("%s: returning error err %d\n", __func__, rc);
|
||||
rc = -EINVAL;
|
||||
} else {
|
||||
msm_vidc_trigger_stability(core, stability_trigger_val);
|
||||
rc = count;
|
||||
}
|
||||
exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static const struct file_operations stability_fops = {
|
||||
.open = simple_open,
|
||||
.write = trigger_stability_write,
|
||||
};
|
||||
|
||||
struct dentry* msm_vidc_debugfs_init_drv()
|
||||
{
|
||||
struct dentry *dir = NULL;
|
||||
@@ -359,6 +401,10 @@ struct dentry *msm_vidc_debugfs_init_core(void *core_in)
|
||||
d_vpr_e("debugfs_create_file: fail\n");
|
||||
goto failed_create_dir;
|
||||
}
|
||||
if (!debugfs_create_file("trigger_stability", 0200, dir, core, &stability_fops)) {
|
||||
d_vpr_e("trigger_stability debugfs_create_file: fail\n");
|
||||
goto failed_create_dir;
|
||||
}
|
||||
if (!debugfs_create_file("stats_delay_ms", 0644, dir, core, &stats_delay_fops)) {
|
||||
d_vpr_e("debugfs_create_file: fail\n");
|
||||
goto failed_create_dir;
|
||||
|
@@ -42,6 +42,13 @@ extern struct msm_vidc_core *g_core;
|
||||
#define SSR_ADDR_ID 0xFFFFFFFF00000000
|
||||
#define SSR_ADDR_SHIFT 32
|
||||
|
||||
#define STABILITY_TYPE 0x0000000F
|
||||
#define STABILITY_TYPE_SHIFT 0
|
||||
#define STABILITY_SUB_CLIENT_ID 0x000000F0
|
||||
#define STABILITY_SUB_CLIENT_ID_SHIFT 4
|
||||
#define STABILITY_PAYLOAD_ID 0xFFFFFFFF00000000
|
||||
#define STABILITY_PAYLOAD_SHIFT 32
|
||||
|
||||
struct msm_vidc_cap_name {
|
||||
enum msm_vidc_inst_capability_type cap;
|
||||
char *name;
|
||||
@@ -4677,6 +4684,77 @@ void msm_vidc_ssr_handler(struct work_struct *work)
|
||||
core_unlock(core, __func__);
|
||||
}
|
||||
|
||||
int msm_vidc_trigger_stability(struct msm_vidc_core *core,
|
||||
u64 trigger_stability_val)
|
||||
{
|
||||
struct msm_vidc_inst *inst = NULL;
|
||||
struct msm_vidc_stability stability;
|
||||
|
||||
if (!core) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* <payload><sub_client_id><stability_type>
|
||||
* stability_type: 0-3 bits
|
||||
* sub_client_id: 4-7 bits
|
||||
* reserved: 8-31 bits
|
||||
* payload: 32-63 bits
|
||||
*/
|
||||
memset(&stability, 0, sizeof(struct msm_vidc_stability));
|
||||
stability.stability_type = (trigger_stability_val &
|
||||
(unsigned long)STABILITY_TYPE) >> STABILITY_TYPE_SHIFT;
|
||||
stability.sub_client_id = (trigger_stability_val &
|
||||
(unsigned long)STABILITY_SUB_CLIENT_ID) >> STABILITY_SUB_CLIENT_ID_SHIFT;
|
||||
stability.value = (trigger_stability_val &
|
||||
(unsigned long)STABILITY_PAYLOAD_ID) >> STABILITY_PAYLOAD_SHIFT;
|
||||
|
||||
core_lock(core, __func__);
|
||||
list_for_each_entry(inst, &core->instances, list) {
|
||||
memcpy(&inst->stability, &stability, sizeof(struct msm_vidc_stability));
|
||||
schedule_work(&inst->stability_work);
|
||||
}
|
||||
core_unlock(core, __func__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void msm_vidc_stability_handler(struct work_struct *work)
|
||||
{
|
||||
int rc;
|
||||
struct msm_vidc_inst *inst;
|
||||
struct msm_vidc_stability *stability;
|
||||
|
||||
inst = container_of(work, struct msm_vidc_inst, stability_work);
|
||||
inst = get_inst_ref(g_core, inst);
|
||||
if (!inst) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
inst_lock(inst, __func__);
|
||||
stability = &inst->stability;
|
||||
rc = venus_hfi_trigger_stability(inst, stability->stability_type,
|
||||
stability->sub_client_id, stability->value);
|
||||
if (rc)
|
||||
i_vpr_e(inst, "%s: trigger_stability failed\n", __func__);
|
||||
inst_unlock(inst, __func__);
|
||||
|
||||
put_inst(inst);
|
||||
}
|
||||
|
||||
int cancel_stability_work_sync(struct msm_vidc_inst *inst)
|
||||
{
|
||||
if (!inst) {
|
||||
d_vpr_e("%s: Invalid arguments\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
cancel_work_sync(&inst->stability_work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void msm_vidc_fw_unload_handler(struct work_struct *work)
|
||||
{
|
||||
struct msm_vidc_core *core = NULL;
|
||||
|
@@ -2871,6 +2871,53 @@ exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int venus_hfi_trigger_stability(struct msm_vidc_inst *inst, u32 type,
|
||||
u32 client_id, u32 val)
|
||||
{
|
||||
struct msm_vidc_core *core;
|
||||
u32 payload[2];
|
||||
int rc = 0;
|
||||
|
||||
if (!inst || !inst->core || !inst->packet) {
|
||||
d_vpr_e("%s: Invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
core = inst->core;
|
||||
core_lock(core, __func__);
|
||||
|
||||
if (!__valdiate_session(core, inst, __func__)) {
|
||||
rc = -EINVAL;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
payload[0] = client_id << 4 | type;
|
||||
payload[1] = val;
|
||||
rc = hfi_create_header(inst->packet, inst->packet_size,
|
||||
inst->session_id, core->header_id++);
|
||||
if (rc)
|
||||
goto unlock;
|
||||
|
||||
/* HFI_CMD_STABILITY */
|
||||
rc = hfi_create_packet(inst->packet, inst->packet_size,
|
||||
HFI_CMD_STABILITY,
|
||||
HFI_HOST_FLAGS_RESPONSE_REQUIRED |
|
||||
HFI_HOST_FLAGS_INTR_REQUIRED,
|
||||
HFI_PAYLOAD_U64,
|
||||
HFI_PORT_NONE,
|
||||
core->packet_id++,
|
||||
&payload, sizeof(u64));
|
||||
if (rc)
|
||||
goto unlock;
|
||||
|
||||
rc = __iface_cmdq_write(core, inst->packet);
|
||||
if (rc)
|
||||
goto unlock;
|
||||
|
||||
unlock:
|
||||
core_unlock(core, __func__);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int venus_hfi_session_open(struct msm_vidc_inst *inst)
|
||||
{
|
||||
int rc = 0;
|
||||
|
@@ -1254,6 +1254,14 @@ static int handle_session_resume(struct msm_vidc_inst *inst,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int handle_session_stability(struct msm_vidc_inst *inst,
|
||||
struct hfi_packet *pkt)
|
||||
{
|
||||
if (pkt->flags & HFI_FW_FLAGS_SUCCESS)
|
||||
i_vpr_h(inst, "%s: successful\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int handle_session_command(struct msm_vidc_inst *inst,
|
||||
struct hfi_packet *pkt)
|
||||
{
|
||||
@@ -1269,6 +1277,7 @@ static int handle_session_command(struct msm_vidc_inst *inst,
|
||||
{HFI_CMD_SUBSCRIBE_MODE, handle_session_subscribe_mode },
|
||||
{HFI_CMD_DELIVERY_MODE, handle_session_delivery_mode },
|
||||
{HFI_CMD_RESUME, handle_session_resume },
|
||||
{HFI_CMD_STABILITY, handle_session_stability },
|
||||
};
|
||||
|
||||
/* handle session pkt */
|
||||
|
Reference in New Issue
Block a user