mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
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:
parent
f675bfaac7
commit
fc9cab72cb
5 changed files with 192 additions and 5 deletions
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 \
|
||||
|
|
Loading…
Reference in a new issue