msm: vidc: Handle mgen2maxi interrupt in video driver

Handle interrupt generated by mgen2maxi h/w and
avoid unknown interrupts storm which results in
target reset issues.

Change-Id: Ida24cb2dde15c9cd4a4c1d9ca336b1a4b662c4d1
Signed-off-by: Maheshwar Ajja <majja@codeaurora.org>
Signed-off-by: Sridhar Gujje <sgujje@codeaurora.org>
This commit is contained in:
Maheshwar Ajja 2013-06-06 19:23:50 +05:30 committed by Artem Borisov
parent f675bfaac7
commit fc9cab72cb
5 changed files with 192 additions and 5 deletions

View file

@ -880,7 +880,7 @@ static void ddl_edfu_callback(struct ddl_context *ddl_context)
struct ddl_client_context *ddl;
u32 channel_inst_id;
DDL_MSG_MED("ddl_edfu_callback");
DDL_MSG_ERROR("ddl_edfu_callback");
vidc_1080p_get_returned_channel_inst_id(&channel_inst_id);
vidc_1080p_clear_returned_channel_inst_id();
ddl = ddl_get_current_ddl_client_for_channel_id(ddl_context,
@ -960,6 +960,39 @@ static u32 ddl_slice_done_callback(struct ddl_context *ddl_context)
return return_status;
}
static u32 ddl_handle_mgen2axi_error(struct ddl_context *ddl_context)
{
u32 axi_error_info_a;
u32 axi_error_info_b;
struct vidc_1080P_axi_status axi_a_status;
struct vidc_1080P_axi_status axi_b_status;
struct vidc_1080P_axi_ctrl axi_ctrl;
u32 status = false;
vidc_1080p_get_mgenaxi_error_info(&axi_error_info_a,
&axi_error_info_b);
vidc_1080p_get_mgen2axi_status(&axi_a_status,
&axi_b_status);
if (axi_a_status.axi_error_interrupt ||
axi_a_status.axi_watchdog_error_interrupt ||
axi_b_status.axi_error_interrupt ||
axi_b_status.axi_watchdog_error_interrupt) {
vidc_1080p_get_mgen2maxi_ctrl(&axi_ctrl);
axi_ctrl.axi_interrupt_clr = 1;
vidc_1080p_set_mgen2maxi_ctrl(&axi_ctrl);
DDL_MSG_HIGH("%s: Wait for 20ms to clear mgen2axi intr",
__func__);
usleep(20*1000);
axi_ctrl.axi_interrupt_clr = 0;
vidc_1080p_set_mgen2maxi_ctrl(&axi_ctrl);
vidc_1080p_get_mgen2axi_status(&axi_a_status,
&axi_b_status);
status = true;
}
return status;
}
static u32 ddl_process_intr_status(struct ddl_context *ddl_context,
u32 intr_status)
{
@ -1003,7 +1036,12 @@ static u32 ddl_process_intr_status(struct ddl_context *ddl_context,
ddl_dpb_buffers_set_done_callback(ddl_context);
break;
default:
DDL_MSG_LOW("UNKWN_INTR");
return_status = ddl_handle_mgen2axi_error(ddl_context);
if (return_status) {
return_status = false;
DDL_MSG_ERROR("Cleared Mgen2axi interrupt");
} else
DDL_MSG_ERROR("UNKWN_INTR");
break;
}
return return_status;

View file

@ -316,22 +316,41 @@
#define VIDC_SM_ENC_EXT_CTRL_CLOSED_GOP_ENABLE_BMSK 0x40
#define VIDC_SM_ENC_EXT_CTRL_CLOSED_GOP_ENABLE_SHFT 6
#define DDL_SHARED_MEM_11BIT_RIGHT_SHIFT 11
#ifdef VIDC_REGISTER_LOG
static void DDL_MEM_WRITE_32(struct ddl_buf_addr *shared_mem, u32 offset,
u32 val)
{
u32 *addr;
VIDC_REG_OUT("\nShared mem write :REG 0x%08x: write 0x%08x",
offset, val);
addr = (u32 *)((u8 *)(shared_mem)->align_virtual_addr + (offset));
*addr = val;
}
static u32 DDL_MEM_READ_32(struct ddl_buf_addr *shared_mem, u32 offset)
{
u32 val;
val = *((u32 *)((u8 *)(shared_mem)->align_virtual_addr + (offset)));
VIDC_REG_IN("\nShared mem read :REG 0x%08x: read 0x%08x",
offset, val);
return val;
}
#else
#define DDL_MEM_WRITE_32(base, offset, val) ddl_mem_write_32(\
(u32 *) ((u8 *) (base)->align_virtual_addr + (offset)), (val))
#define DDL_MEM_READ_32(base, offset) ddl_mem_read_32(\
(u32 *) ((u8 *) (base)->align_virtual_addr + (offset)))
#define DDL_SHARED_MEM_11BIT_RIGHT_SHIFT 11
static void ddl_mem_write_32(u32 *addr, u32 data)
{
*addr = data;
}
static u32 ddl_mem_read_32(u32 *addr)
{
return *addr;
}
#endif
void vidc_sm_get_extended_decode_status(struct ddl_buf_addr *shared_mem,
u32 *more_field_needed,

View file

@ -194,6 +194,95 @@ void vidc_1080p_get_risc2host_cmd_status(u32 err_status,
}
void vidc_1080p_get_mgenaxi_error_info(u32 *axi_error_info_a,
u32 *axi_error_info_b)
{
VIDC_HWIO_IN(REG_736158, axi_error_info_a);
VIDC_HWIO_IN(REG_598415, axi_error_info_b);
}
void vidc_1080p_get_mgen2axi_status(struct vidc_1080P_axi_status *axi_a_status,
struct vidc_1080P_axi_status *axi_b_status)
{
u32 status;
VIDC_HWIO_IN(REG_437878, &status);
axi_a_status->axi_error_interrupt = VIDC_GETFIELD(status,
HWIO_REG_437878_AXI_A_ERR_INTR_BMSK,
HWIO_REG_437878_AXI_A_ERR_INTR_SHFT);
axi_a_status->axi_halt_ack = VIDC_GETFIELD(status,
HWIO_REG_437878_AXI_A_HALT_ACK_BMSK,
HWIO_REG_437878_AXI_A_HALT_ACK_SHFT);
axi_a_status->axi_idle = VIDC_GETFIELD(status,
HWIO_REG_437878_AXI_A_IDLE_BMSK,
HWIO_REG_437878_AXI_A_IDLE_SHFT);
axi_a_status->axi_watchdog_error_interrupt = VIDC_GETFIELD(status,
HWIO_REG_437878_AXI_A_WDTIMEOUT_INTR_BMSK,
HWIO_REG_437878_AXI_A_WDTIMEOUT_INTR_SHFT);
axi_b_status->axi_error_interrupt = VIDC_GETFIELD(status,
HWIO_REG_437878_AXI_B_ERR_INTR_BMSK,
HWIO_REG_437878_AXI_B_ERR_INTR_SHFT);
axi_b_status->axi_halt_ack = VIDC_GETFIELD(status,
HWIO_REG_437878_AXI_B_HALT_ACK_BMSK,
HWIO_REG_437878_AXI_B_HALT_ACK_SHFT);
axi_b_status->axi_idle = VIDC_GETFIELD(status,
HWIO_REG_437878_AXI_B_IDLE_BMSK,
HWIO_REG_437878_AXI_B_IDLE_SHFT);
axi_b_status->axi_watchdog_error_interrupt = VIDC_GETFIELD(status,
HWIO_REG_437878_AXI_B_WDTIMEOUT_INTR_BMSK,
HWIO_REG_437878_AXI_B_WDTIMEOUT_INTR_SHFT);
}
void vidc_1080p_get_mgen2maxi_ctrl(struct vidc_1080P_axi_ctrl *ctrl)
{
u32 ctrl_value;
VIDC_HWIO_IN(REG_471159, &ctrl_value);
ctrl->axi_halt_req = VIDC_GETFIELD(ctrl_value,
HWIO_REG_471159_AXI_HALT_REQ_BMSK,
HWIO_REG_471159_AXI_HALT_REQ_SHFT);
ctrl->axi_reset = VIDC_GETFIELD(ctrl_value,
HWIO_REG_471159_AXI_RESET_BMSK,
HWIO_REG_471159_AXI_RESET_SHFT);
ctrl->axi_halt_on_readerror = VIDC_GETFIELD(ctrl_value,
HWIO_REG_471159_AXI_HALT_ON_RD_ERR_BMSK,
HWIO_REG_471159_AXI_HALT_ON_RD_ERR_SHFT);
ctrl->axi_halt_on_writeerror = VIDC_GETFIELD(ctrl_value,
HWIO_REG_471159_AXI_HALT_ON_WR_ERR_BMSK,
HWIO_REG_471159_AXI_HALT_ON_WR_ERR_SHFT);
ctrl->axi_halt_on_watchdog_timeout = VIDC_GETFIELD(ctrl_value,
HWIO_REG_471159_AXI_HALT_ON_WDTIMEOUT_BMSK,
HWIO_REG_471159_AXI_HALT_ON_WDTIMEOUT_SHFT);
ctrl->axi_watchdog_timeout_value = VIDC_GETFIELD(ctrl_value,
HWIO_REG_471159_AXI_WDTIMEOUT_LOG2_BMSK,
HWIO_REG_471159_AXI_WDTIMEOUT_LOG2_SHFT);
ctrl->axi_interrupt_clr = VIDC_GETFIELD(ctrl_value,
HWIO_REG_471159_AXI_INTR_CLR_BMSK,
HWIO_REG_471159_AXI_INTR_CLR_SHFT);
}
void vidc_1080p_set_mgen2maxi_ctrl(struct vidc_1080P_axi_ctrl *ctrl)
{
u32 ctrl_value;
ctrl_value = VIDC_SETFIELD(ctrl->axi_halt_req,
HWIO_REG_471159_AXI_HALT_REQ_SHFT,
HWIO_REG_471159_AXI_HALT_REQ_BMSK);
ctrl_value |= VIDC_SETFIELD(ctrl->axi_reset,
HWIO_REG_471159_AXI_RESET_SHFT,
HWIO_REG_471159_AXI_RESET_BMSK);
ctrl_value |= VIDC_SETFIELD(ctrl->axi_halt_on_readerror,
HWIO_REG_471159_AXI_HALT_ON_RD_ERR_SHFT,
HWIO_REG_471159_AXI_HALT_ON_RD_ERR_BMSK);
ctrl_value |= VIDC_SETFIELD(ctrl->axi_halt_on_writeerror,
HWIO_REG_471159_AXI_HALT_ON_WR_ERR_SHFT,
HWIO_REG_471159_AXI_HALT_ON_WR_ERR_BMSK);
ctrl_value |= VIDC_SETFIELD(ctrl->axi_halt_on_watchdog_timeout,
HWIO_REG_471159_AXI_HALT_ON_WDTIMEOUT_SHFT,
HWIO_REG_471159_AXI_HALT_ON_WDTIMEOUT_BMSK);
ctrl_value |= VIDC_SETFIELD(ctrl->axi_interrupt_clr,
HWIO_REG_471159_AXI_INTR_CLR_SHFT,
HWIO_REG_471159_AXI_INTR_CLR_BMSK);
VIDC_HWIO_OUT(REG_471159, ctrl_value);
}
void vidc_1080p_clear_risc2host_cmd(void)
{
VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY);

View file

@ -429,6 +429,23 @@ struct vidc_1080p_enc_slice_batch_out_param {
struct vidc_1080p_enc_slice_info slice_info
[VIDC_1080P_SLICE_BATCH_MAX_STRM_BFR];
};
struct vidc_1080P_axi_ctrl {
u32 axi_halt_req;
u32 axi_reset;
u32 axi_halt_on_readerror;
u32 axi_halt_on_writeerror;
u32 axi_halt_on_watchdog_timeout;
u32 axi_watchdog_timeout_value;
u32 axi_interrupt_clr;
};
struct vidc_1080P_axi_status {
u32 axi_halt_ack;
u32 axi_idle;
u32 axi_error_interrupt;
u32 axi_watchdog_error_interrupt;
};
struct vidc_1080p_dec_disp_info{
u32 disp_resl_change;
u32 dec_resl_change;
@ -473,6 +490,12 @@ void vidc_1080p_get_risc2host_cmd(u32 *pn_risc2host_command,
u32 *pn_risc2host_arg3, u32 *pn_risc2host_arg4);
void vidc_1080p_get_risc2host_cmd_status(u32 err_status,
u32 *dec_err_status, u32 *disp_err_status);
void vidc_1080p_get_mgen2maxi_ctrl(struct vidc_1080P_axi_ctrl *ctrl);
void vidc_1080p_set_mgen2maxi_ctrl(struct vidc_1080P_axi_ctrl *ctrl);
void vidc_1080p_get_mgenaxi_error_info(u32 *axi_error_info_a,
u32 *axi_error_info_b);
void vidc_1080p_get_mgen2axi_status(struct vidc_1080P_axi_status *axi_a_status,
struct vidc_1080P_axi_status *axi_b_status);
void vidc_1080p_clear_risc2host_cmd(void);
void vidc_1080p_get_fw_version(u32 *pn_fw_version);
void vidc_1080p_get_fw_status(u32 *pn_fw_status);

View file

@ -3993,6 +3993,7 @@ extern u8 *VIDC_BASE_PTR;
HWIO_REG_437878_ADDR, HWIO_REG_437878_RMSK)
#define HWIO_REG_437878_INM(m) \
in_dword_masked(HWIO_REG_437878_ADDR, m)
#define HWIO_REG_437878_AXI_WDTIMEOUT_INTR_BMSK 0x3000
#define HWIO_REG_437878_AXI_WDTIMEOUT_INTR_SHFT 0xc
#define HWIO_REG_437878_AXI_ERR_INTR_BMSK 0x300
@ -4002,6 +4003,23 @@ extern u8 *VIDC_BASE_PTR;
#define HWIO_REG_437878_AXI_HALT_ACK_BMSK 0x3
#define HWIO_REG_437878_AXI_HALT_ACK_SHFT 0
#define HWIO_REG_437878_AXI_B_WDTIMEOUT_INTR_BMSK 0x2000
#define HWIO_REG_437878_AXI_B_WDTIMEOUT_INTR_SHFT 0xd
#define HWIO_REG_437878_AXI_A_WDTIMEOUT_INTR_BMSK 0x1000
#define HWIO_REG_437878_AXI_A_WDTIMEOUT_INTR_SHFT 0xc
#define HWIO_REG_437878_AXI_B_ERR_INTR_BMSK 0x200
#define HWIO_REG_437878_AXI_B_ERR_INTR_SHFT 0x9
#define HWIO_REG_437878_AXI_A_ERR_INTR_BMSK 0x100
#define HWIO_REG_437878_AXI_A_ERR_INTR_SHFT 0x8
#define HWIO_REG_437878_AXI_B_IDLE_BMSK 0x20
#define HWIO_REG_437878_AXI_B_IDLE_SHFT 0x5
#define HWIO_REG_437878_AXI_A_IDLE_BMSK 0x10
#define HWIO_REG_437878_AXI_A_IDLE_SHFT 0x4
#define HWIO_REG_437878_AXI_B_HALT_ACK_BMSK 0x2
#define HWIO_REG_437878_AXI_B_HALT_ACK_SHFT 0x1
#define HWIO_REG_437878_AXI_A_HALT_ACK_BMSK 0x1
#define HWIO_REG_437878_AXI_A_HALT_ACK_SHFT 0
#define HWIO_REG_736158_ADDR \
(VIDC_MGEN2MAXI_REG_BASE + 0x0000001c)
#define HWIO_REG_736158_PHYS \