From: seungmin.ahn Date: Fri, 18 Jan 2019 01:57:04 +0000 (+0900) Subject: [COMMON] media: mfc: expand the logging data X-Git-Tag: MMI-QSAS30.62-33-3~893 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=8d4cc7b98ec72be9249576fba9a0bc4081307196;p=GitHub%2FMotorolaMobilityLLC%2Fkernel-slsi.git [COMMON] media: mfc: expand the logging data Change-Id: Ia2bc0bd0eb2e1b3ea3a105f75a3cad8100430587 Signed-off-by: Ayoung Sim Signed-off-by: seungmin.ahn --- diff --git a/drivers/media/platform/exynos/mfc/mfc.c b/drivers/media/platform/exynos/mfc/mfc.c index adab73d812c0..73dae5d0c161 100644 --- a/drivers/media/platform/exynos/mfc/mfc.c +++ b/drivers/media/platform/exynos/mfc/mfc.c @@ -60,6 +60,7 @@ struct _mfc_trace g_mfc_trace[MFC_TRACE_COUNT_MAX]; struct _mfc_trace g_mfc_trace_longterm[MFC_TRACE_COUNT_MAX]; +struct _mfc_trace_logging g_mfc_trace_logging[MFC_TRACE_LOG_COUNT_MAX]; struct mfc_dev *g_mfc_dev; #ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION @@ -1308,8 +1309,10 @@ static int mfc_probe(struct platform_device *pdev) atomic_set(&dev->trace_ref, 0); atomic_set(&dev->trace_ref_longterm, 0); + atomic_set(&dev->trace_ref_log, 0); dev->mfc_trace = g_mfc_trace; dev->mfc_trace_longterm = g_mfc_trace_longterm; + dev->mfc_trace_logging = g_mfc_trace_logging; dma_set_mask(&pdev->dev, DMA_BIT_MASK(36)); diff --git a/drivers/media/platform/exynos/mfc/mfc_data_struct.h b/drivers/media/platform/exynos/mfc/mfc_data_struct.h index 525f936f7798..bce5837528e2 100644 --- a/drivers/media/platform/exynos/mfc/mfc_data_struct.h +++ b/drivers/media/platform/exynos/mfc/mfc_data_struct.h @@ -40,9 +40,10 @@ #define MFC_MAX_BUFFERS 32 #define MFC_MAX_EXTRA_BUF 10 #define MFC_TIME_INDEX 15 -#define MFC_SFR_LOGGING_COUNT_SET1 4 -#define MFC_SFR_LOGGING_COUNT_SET2 23 -#define MFC_LOGGING_DATA_SIZE 256 +#define MFC_SFR_LOGGING_COUNT_SET0 10 +#define MFC_SFR_LOGGING_COUNT_SET1 28 +#define MFC_SFR_LOGGING_COUNT_SET2 32 +#define MFC_LOGGING_DATA_SIZE 950 #define MFC_MAX_DEFAULT_PARAM 100 #define HWFC_MAX_BUF 10 @@ -191,6 +192,7 @@ enum mfc_vb_flag { struct mfc_ctx; enum mfc_debug_cause { + /* panic cause */ MFC_CAUSE_0WRITE_PAGE_FAULT = 0, MFC_CAUSE_0READ_PAGE_FAULT = 1, MFC_CAUSE_1WRITE_PAGE_FAULT = 2, @@ -205,15 +207,44 @@ enum mfc_debug_cause { MFC_CAUSE_FAIL_RISC_ON = 11, MFC_CAUSE_FAIL_DPB_FLUSH = 12, MFC_CAUSE_FAIL_CHACHE_FLUSH = 13, + /* last information */ + MFC_LAST_INFO_BLACK_BAR = 26, + MFC_LAST_INFO_NAL_QUEUE = 27, + MFC_LAST_INFO_CLOCK = 28, + MFC_LAST_INFO_POWER = 29, + MFC_LAST_INFO_SHUTDOWN = 30, + MFC_LAST_INFO_DRM = 31, }; struct mfc_debug { + u32 fw_version; u32 cause; u8 fault_status; u32 fault_trans_info; u32 fault_addr; - u8 SFRs_set1[MFC_SFR_LOGGING_COUNT_SET1]; + u32 SFRs_set0[MFC_SFR_LOGGING_COUNT_SET0]; + u32 SFRs_set1[MFC_SFR_LOGGING_COUNT_SET1]; u32 SFRs_set2[MFC_SFR_LOGGING_COUNT_SET2]; + u8 curr_ctx; + u8 state; + u8 last_cmd; + u32 last_cmd_sec; + u32 last_cmd_usec; + u8 last_int; + u32 last_int_sec; + u32 last_int_usec; + u32 frame_cnt; + u8 hwlock_dev; + u32 hwlock_ctx; + u8 num_inst; + u8 num_drm_inst; + u8 power_cnt; + u8 clock_cnt; + /* for decoder only */ + u32 dynamic_used; + u32 last_src_addr; + u32 last_dst_addr[MFC_MAX_PLANES]; + /* total logging data */ char errorinfo[MFC_LOGGING_DATA_SIZE]; }; @@ -821,6 +852,8 @@ struct mfc_dev { atomic_t trace_ref_longterm; struct _mfc_trace *mfc_trace_longterm; + atomic_t trace_ref_log; + struct _mfc_trace_logging *mfc_trace_logging; bool continue_clock_on; bool shutdown; @@ -837,6 +870,11 @@ struct mfc_dev { struct mfc_debugfs debugfs; struct mfc_dump_ops *dump_ops; + int last_cmd; + int last_int; + struct timeval last_cmd_time; + struct timeval last_int_time; + struct mfc_perf perf; struct mfc_mmcache mmcache; @@ -1514,6 +1552,10 @@ struct mfc_ctx { unsigned long raw_protect_flag; unsigned long stream_protect_flag; + int frame_cnt; + u32 last_src_addr; + u32 last_dst_addr[MFC_MAX_PLANES]; + int batch_mode; bool check_dump; bool mem_type_10bit; diff --git a/drivers/media/platform/exynos/mfc/mfc_debug.h b/drivers/media/platform/exynos/mfc/mfc_debug.h index b18b0a8788f7..9f76b7a55aec 100644 --- a/drivers/media/platform/exynos/mfc/mfc_debug.h +++ b/drivers/media/platform/exynos/mfc/mfc_debug.h @@ -72,12 +72,21 @@ extern unsigned int reg_test; #define MFC_TRACE_STR_LEN 80 #define MFC_TRACE_COUNT_MAX 1024 #define MFC_TRACE_COUNT_PRINT 30 +#define MFC_TRACE_LOG_STR_LEN 25 +#define MFC_TRACE_LOG_COUNT_MAX 256 +#define MFC_TRACE_LOG_COUNT_PRINT 20 + struct _mfc_trace { unsigned long long time; char str[MFC_TRACE_STR_LEN]; }; +struct _mfc_trace_logging { + unsigned long long time; + char str[MFC_TRACE_LOG_STR_LEN]; +}; + /* If there is no ctx structure */ #define MFC_TRACE_DEV(fmt, args...) \ do { \ @@ -123,5 +132,27 @@ struct _mfc_trace { "[c:%d] " fmt, ctx->num, ##args); \ } while (0) +/* If there is no ctx structure */ +#define MFC_TRACE_LOG_DEV(fmt, args...) \ + do { \ + int cpu = raw_smp_processor_id(); \ + int cnt; \ + cnt = atomic_inc_return(&dev->trace_ref_log) & (MFC_TRACE_LOG_COUNT_MAX - 1); \ + dev->mfc_trace_logging[cnt].time = cpu_clock(cpu); \ + snprintf(dev->mfc_trace_logging[cnt].str, MFC_TRACE_LOG_STR_LEN, \ + fmt, ##args); \ + } while (0) + +/* If there is ctx structure */ +#define MFC_TRACE_LOG_CTX(fmt, args...) \ + do { \ + int cpu = raw_smp_processor_id(); \ + int cnt; \ + cnt = atomic_inc_return(&dev->trace_ref_log) & (MFC_TRACE_LOG_COUNT_MAX - 1); \ + dev->mfc_trace_logging[cnt].time = cpu_clock(cpu); \ + snprintf(dev->mfc_trace_logging[cnt].str, MFC_TRACE_LOG_STR_LEN, \ + "%d:" fmt, ctx->num, ##args); \ + } while (0) + #endif /* __MFC_DEBUG_H */ diff --git a/drivers/media/platform/exynos/mfc/mfc_hw_reg_api.c b/drivers/media/platform/exynos/mfc/mfc_hw_reg_api.c index 7465a97e657d..47846e651dc2 100644 --- a/drivers/media/platform/exynos/mfc/mfc_hw_reg_api.c +++ b/drivers/media/platform/exynos/mfc/mfc_hw_reg_api.c @@ -59,6 +59,7 @@ void mfc_cmd_host2risc(struct mfc_dev *dev, int cmd) MFC_TRACE_DEV(">> CMD : %d, (dev:0x%lx, bits:%lx, owned:%d, wl:%d, trans:%d)\n", cmd, dev->hwlock.dev, dev->hwlock.bits, dev->hwlock.owned_by_irq, dev->hwlock.wl_count, dev->hwlock.transfer_owner); + MFC_TRACE_LOG_DEV("C%d", cmd); trace_mfc_frame_start(dev->curr_ctx, cmd, 0, 0); /* Reset RISC2HOST command except nal q stop command */ @@ -75,6 +76,9 @@ void mfc_cmd_host2risc(struct mfc_dev *dev, int cmd) mfc_dbg_enable(dev); } + dev->last_cmd = cmd; + dev->last_cmd_time = ktime_to_timeval(ktime_get()); + /* Issue the command */ MFC_WRITEL(cmd, MFC_REG_HOST2RISC_CMD); MFC_WRITEL(0x1, MFC_REG_HOST2RISC_INT); diff --git a/drivers/media/platform/exynos/mfc/mfc_isr.c b/drivers/media/platform/exynos/mfc/mfc_isr.c index 107dcf97397c..95a90f798663 100644 --- a/drivers/media/platform/exynos/mfc/mfc_isr.c +++ b/drivers/media/platform/exynos/mfc/mfc_isr.c @@ -1242,9 +1242,20 @@ irqreturn_t mfc_top_half_irq(int irq, void *priv) reason = mfc_get_int_reason(); err = mfc_get_int_err(); + + dev->last_int = reason; + dev->last_int_time = ktime_to_timeval(ktime_get()); + + if ((reason == MFC_REG_R2H_CMD_SEQ_DONE_RET) || + (reason == MFC_REG_R2H_CMD_INIT_BUFFERS_RET) || + (reason == MFC_REG_R2H_CMD_FRAME_DONE_RET) || + (reason == MFC_REG_R2H_CMD_QUEUE_DONE_RET)) + ctx->frame_cnt++; + mfc_debug(2, "[c:%d] Int reason: %d (err: %d)\n", dev->curr_ctx, reason, err); MFC_TRACE_CTX("<< INT(top): %d\n", reason); + MFC_TRACE_LOG_CTX("I%d", reason); mfc_perf_measure_off(dev); diff --git a/drivers/media/platform/exynos/mfc/mfc_nal_q.c b/drivers/media/platform/exynos/mfc/mfc_nal_q.c index 779e8ec102d5..12ce6b66d18f 100644 --- a/drivers/media/platform/exynos/mfc/mfc_nal_q.c +++ b/drivers/media/platform/exynos/mfc/mfc_nal_q.c @@ -944,6 +944,7 @@ static int __mfc_nal_q_run_in_buf_dec(struct mfc_ctx *ctx, DecoderInputStr *pInS pInStr->CpbBufferAddr = buf_addr; pInStr->CpbBufferSize = cpb_buf_size; pInStr->CpbBufferOffset = 0; + ctx->last_src_addr = buf_addr; MFC_TRACE_CTX("Set src[%d] fd: %d, %#llx\n", src_index, src_mb->vb.vb2_buf.planes[0].m.fd, buf_addr); @@ -956,6 +957,7 @@ static int __mfc_nal_q_run_in_buf_dec(struct mfc_ctx *ctx, DecoderInputStr *pInS for (i = 0; i < raw->num_planes; i++) { pInStr->FrameSize[i] = raw->plane_size[i]; pInStr->FrameAddr[i] = dst_mb->addr[0][i]; + ctx->last_dst_addr[i] = dst_mb->addr[0][i]; if (ctx->is_10bit) pInStr->Frame2BitSize[i] = raw->plane_size_2bits[i]; mfc_debug(2, "[NALQ][BUFINFO][DPB] ctx[%d] set dst index: %d, addr[%d]: 0x%08llx\n", @@ -1928,6 +1930,7 @@ int mfc_nal_q_enqueue_in_buf(struct mfc_dev *dev, struct mfc_ctx *ctx, if (input_diff == 0) mfc_watchdog_start_tick(dev); + MFC_TRACE_LOG_DEV("N%d", input_diff); spin_unlock_irqrestore(&nal_q_in_handle->nal_q_handle->lock, flags); diff --git a/drivers/media/platform/exynos/mfc/mfc_pm.c b/drivers/media/platform/exynos/mfc/mfc_pm.c index fcf4cd2682d0..0172fe72148f 100644 --- a/drivers/media/platform/exynos/mfc/mfc_pm.c +++ b/drivers/media/platform/exynos/mfc/mfc_pm.c @@ -94,6 +94,7 @@ int mfc_pm_clock_on(struct mfc_dev *dev) state = atomic_read(&dev->clk_ref); mfc_debug(2, "+ %d\n", state); MFC_TRACE_DEV("** clock_on end: ref state(%d)\n", state); + MFC_TRACE_LOG_DEV("c+%d", state); return 0; } @@ -160,6 +161,7 @@ void mfc_pm_clock_off(struct mfc_dev *dev) state = atomic_read(&dev->clk_ref); mfc_debug(2, "- %d\n", state); MFC_TRACE_DEV("** clock_off end: ref state(%d)\n", state); + MFC_TRACE_LOG_DEV("c-%d", state); } int mfc_pm_power_on(struct mfc_dev *dev) @@ -190,6 +192,7 @@ int mfc_pm_power_on(struct mfc_dev *dev) atomic_inc(&dev->pm.pwr_ref); MFC_TRACE_DEV("-- Power on: ret(%d)\n", ret); + MFC_TRACE_LOG_DEV("p+%d", mfc_pm_get_pwr_ref_cnt(dev)); return 0; @@ -222,6 +225,7 @@ int mfc_pm_power_off(struct mfc_dev *dev) atomic_dec(&dev->pm.pwr_ref); MFC_TRACE_DEV("-- Power off: ret(%d)\n", ret); + MFC_TRACE_LOG_DEV("p-%d", mfc_pm_get_pwr_ref_cnt(dev)); return ret; } diff --git a/drivers/media/platform/exynos/mfc/mfc_reg_api.c b/drivers/media/platform/exynos/mfc/mfc_reg_api.c index bf90c1b1990f..0bb0cd0cbccd 100644 --- a/drivers/media/platform/exynos/mfc/mfc_reg_api.c +++ b/drivers/media/platform/exynos/mfc/mfc_reg_api.c @@ -285,6 +285,7 @@ int mfc_set_dec_stream_buffer(struct mfc_ctx *ctx, struct mfc_buf *mfc_buf, MFC_WRITEL(addr, MFC_REG_D_CPB_BUFFER_ADDR); MFC_WRITEL(cpb_buf_size, MFC_REG_D_CPB_BUFFER_SIZE); MFC_WRITEL(start_num_byte, MFC_REG_D_CPB_BUFFER_OFFSET); + ctx->last_src_addr = addr; if (mfc_buf) MFC_TRACE_CTX("Set src[%d] fd: %d, %#llx\n", @@ -442,6 +443,7 @@ int mfc_set_dynamic_dpb(struct mfc_ctx *ctx, struct mfc_buf *dst_mb) MFC_REG_D_FIRST_PLANE_DPB_SIZE + i * 4); MFC_WRITEL(dst_mb->addr[0][i], MFC_REG_D_FIRST_PLANE_DPB0 + (i * 0x100 + dst_index * 4)); + ctx->last_dst_addr[i] = dst_mb->addr[0][i]; if (ctx->is_10bit) MFC_WRITEL(raw->plane_size_2bits[i], MFC_REG_D_FIRST_PLANE_2BIT_DPB_SIZE + (i * 4)); diff --git a/drivers/media/platform/exynos/mfc/mfc_watchdog.c b/drivers/media/platform/exynos/mfc/mfc_watchdog.c index d4ff678024d1..e539591501e1 100644 --- a/drivers/media/platform/exynos/mfc/mfc_watchdog.c +++ b/drivers/media/platform/exynos/mfc/mfc_watchdog.c @@ -9,7 +9,7 @@ * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ -#ifdef BIGDATA_LOGGING_ENABLE +#ifdef CONFIG_SEC_DEBUG_EXTRA_INFO #include #endif @@ -83,17 +83,26 @@ static void __mfc_dump_regs(struct mfc_dev *dev) } } +/* common register */ +const u32 mfc_logging_sfr_set0[MFC_SFR_LOGGING_COUNT_SET0] = { + 0x0070, 0x1000, 0x1004, 0x100C, 0x1010, 0x01B4, 0xF144, 0xF148, + 0xF088, 0xFFD0 +}; + +/* AxID: the other */ const u32 mfc_logging_sfr_set1[MFC_SFR_LOGGING_COUNT_SET1] = { - 0x1000, 0x1004, 0x100C, 0x1010 + 0x3000, 0x3004, 0x3010, 0x301C, 0x3110, 0x3140, 0x3144, 0x5068, + 0x506C, 0x5254, 0x5280, 0x529C, 0x52A0, 0x5A54, 0x5A80, 0x5A88, + 0x5A94, 0x5A9C, 0x6038, 0x603C, 0x6050, 0x6064, 0x6168, 0x616C, + 0x2020, 0x2028, 0x202C, 0x20B4 }; +/* AxID: 0 ~ 3 (READ): PX */ const u32 mfc_logging_sfr_set2[MFC_SFR_LOGGING_COUNT_SET2] = { - 0x0070, 0x10B4, 0x2020, 0x2028, - 0x204C, 0x20B4, 0x3000, 0x3004, - 0x3010, 0x301C, 0x3110, 0x5A54, - 0x5A80, 0x5A88, 0x5A94, 0x6038, - 0x6050, 0x6168, 0x7018, 0x7110, - 0x7114, 0xF088, 0xFFD0 + 0xA100, 0xA104, 0xA108, 0xA10C, 0xA110, 0xA114, 0xA118, 0xA11C, + 0xA120, 0xA124, 0xA128, 0xA12C, 0xA120, 0xA124, 0xA128, 0xA12C, + 0xA180, 0xA184, 0xA188, 0xA18C, 0xA190, 0xA194, 0xA198, 0xA19C, + 0xA1A0, 0xA1A4, 0xA1A8, 0xA1AC, 0xA1B0, 0xA1B4, 0xA1B8, 0xA1BC }; int __mfc_change_hex_to_ascii(u32 hex, u32 byte, char *ascii, int idx) @@ -122,34 +131,165 @@ int __mfc_change_hex_to_ascii(u32 hex, u32 byte, char *ascii, int idx) return ++idx; } -static void __mfc_save_logging_sfr(struct mfc_dev *dev) +static void mfc_merge_errorinfo_data(struct mfc_dev *dev, bool px_fault) { char *errorinfo; int i, idx = 0; + int trace_cnt, ret, cnt; - pr_err("-----------logging MFC error info-----------\n"); errorinfo = dev->logging_data->errorinfo; - for (i = 0; i < MFC_SFR_LOGGING_COUNT_SET1; i++) - dev->logging_data->SFRs_set1[i] = MFC_READL(mfc_logging_sfr_set1[i]); - for (i = 0; i < MFC_SFR_LOGGING_COUNT_SET2; i++) - dev->logging_data->SFRs_set2[i] = MFC_READL(mfc_logging_sfr_set2[i]); + /* FW info */ + idx = __mfc_change_hex_to_ascii(dev->logging_data->fw_version, 8, errorinfo, idx); idx = __mfc_change_hex_to_ascii(dev->logging_data->cause, 8, errorinfo, idx); idx = __mfc_change_hex_to_ascii(dev->logging_data->fault_status, 2, errorinfo, idx); idx = __mfc_change_hex_to_ascii(dev->logging_data->fault_trans_info, 8, errorinfo, idx); idx = __mfc_change_hex_to_ascii(dev->logging_data->fault_addr, 8, errorinfo, idx); - for (i = 0; i < MFC_SFR_LOGGING_COUNT_SET1; i++) - idx = __mfc_change_hex_to_ascii(dev->logging_data->SFRs_set1[i], 2, errorinfo, idx); - for (i = 0; i < MFC_SFR_LOGGING_COUNT_SET2; i++) - idx = __mfc_change_hex_to_ascii(dev->logging_data->SFRs_set2[i], 8, errorinfo, idx); + for (i = 0; i < MFC_SFR_LOGGING_COUNT_SET0; i++) + idx = __mfc_change_hex_to_ascii(dev->logging_data->SFRs_set0[i], 8, errorinfo, idx); + if (px_fault) { + for (i = 0; i < MFC_SFR_LOGGING_COUNT_SET2; i++) + idx = __mfc_change_hex_to_ascii(dev->logging_data->SFRs_set2[i], 8, errorinfo, idx); + } else { + for (i = 0; i < MFC_SFR_LOGGING_COUNT_SET1; i++) + idx = __mfc_change_hex_to_ascii(dev->logging_data->SFRs_set1[i], 8, errorinfo, idx); + } + + /* driver info */ + ret = snprintf(errorinfo + idx, 3, "/"); + idx += ret; + idx = __mfc_change_hex_to_ascii(dev->logging_data->curr_ctx, 2, errorinfo, idx); + idx = __mfc_change_hex_to_ascii(dev->logging_data->state, 2, errorinfo, idx); + idx = __mfc_change_hex_to_ascii(dev->logging_data->last_cmd, 2, errorinfo, idx); + idx = __mfc_change_hex_to_ascii(dev->logging_data->last_cmd_sec, 8, errorinfo, idx); + idx = __mfc_change_hex_to_ascii(dev->logging_data->last_cmd_usec, 8, errorinfo, idx); + idx = __mfc_change_hex_to_ascii(dev->logging_data->last_int, 2, errorinfo, idx); + idx = __mfc_change_hex_to_ascii(dev->logging_data->last_int_sec, 8, errorinfo, idx); + idx = __mfc_change_hex_to_ascii(dev->logging_data->last_int_usec, 8, errorinfo, idx); + idx = __mfc_change_hex_to_ascii(dev->logging_data->frame_cnt, 8, errorinfo, idx); + idx = __mfc_change_hex_to_ascii(dev->logging_data->hwlock_dev, 2, errorinfo, idx); + idx = __mfc_change_hex_to_ascii(dev->logging_data->hwlock_ctx, 8, errorinfo, idx); + idx = __mfc_change_hex_to_ascii(dev->logging_data->num_inst, 2, errorinfo, idx); + idx = __mfc_change_hex_to_ascii(dev->logging_data->num_drm_inst, 2, errorinfo, idx); + idx = __mfc_change_hex_to_ascii(dev->logging_data->power_cnt, 2, errorinfo, idx); + idx = __mfc_change_hex_to_ascii(dev->logging_data->clock_cnt, 2, errorinfo, idx); + idx = __mfc_change_hex_to_ascii(dev->logging_data->dynamic_used, 8, errorinfo, idx); + idx = __mfc_change_hex_to_ascii(dev->logging_data->last_src_addr, 8, errorinfo, idx); + for (i = 0; i < MFC_MAX_PLANES; i++) + idx = __mfc_change_hex_to_ascii(dev->logging_data->last_dst_addr[i], 8, errorinfo, idx); + + /* last trace info */ + ret = snprintf(errorinfo + idx, 3, "/"); + idx += ret; + + /* last processing is first printed */ + trace_cnt = atomic_read(&dev->trace_ref_log); + for (i = 0; i < MFC_TRACE_LOG_COUNT_PRINT; i++) { + if (idx >= (MFC_LOGGING_DATA_SIZE - MFC_TRACE_LOG_STR_LEN)) { + pr_err("logging data size exceed: %d\n", idx); + break; + } + cnt = ((trace_cnt + MFC_TRACE_LOG_COUNT_MAX) - i) % MFC_TRACE_LOG_COUNT_MAX; + ret = snprintf(errorinfo + idx, MFC_TRACE_LOG_STR_LEN, "%llu:%s ", + dev->mfc_trace_logging[cnt].time, + dev->mfc_trace_logging[cnt].str); + idx += ret; + } pr_err("%s\n", errorinfo); -#ifdef BIGDATA_LOGGING_ENABLE +#ifdef CONFIG_SEC_DEBUG_EXTRA_INFO sec_debug_set_extra_info_mfc_error(errorinfo); #endif } +static void __mfc_save_logging_sfr(struct mfc_dev *dev) +{ + struct mfc_ctx *ctx = NULL; + int i; + bool px_fault = false; + + pr_err("-----------logging MFC error info-----------\n"); + if (mfc_pm_get_pwr_ref_cnt(dev)) { + dev->logging_data->cause |= (1 << MFC_LAST_INFO_POWER); + dev->logging_data->fw_version = mfc_get_fw_ver_all(); + + for (i = 0; i < MFC_SFR_LOGGING_COUNT_SET0; i++) + dev->logging_data->SFRs_set0[i] = MFC_READL(mfc_logging_sfr_set0[i]); + for (i = 0; i < MFC_SFR_LOGGING_COUNT_SET1; i++) + dev->logging_data->SFRs_set1[i] = MFC_READL(mfc_logging_sfr_set1[i]); + + /* READ PAGE FAULT at AxID 0 ~ 3: PX */ + if ((dev->logging_data->cause & (1 << MFC_CAUSE_0READ_PAGE_FAULT)) || + (dev->logging_data->cause & (1 << MFC_CAUSE_1READ_PAGE_FAULT))) { + if (((dev->logging_data->fault_trans_info & 0xff) >= 0) && + ((dev->logging_data->fault_trans_info & 0xff) <= 3)) { + px_fault = true; + for (i = 0; i < MFC_SFR_LOGGING_COUNT_SET2; i++) + dev->logging_data->SFRs_set2[i] = MFC_READL(mfc_logging_sfr_set2[i]); + } + } + } + + if (mfc_pm_get_clk_ref_cnt(dev)) + dev->logging_data->cause |= (1 << MFC_LAST_INFO_CLOCK); + + if (dev->nal_q_handle && (dev->nal_q_handle->nal_q_state == NAL_Q_STATE_STARTED)) + dev->logging_data->cause |= (1 << MFC_LAST_INFO_NAL_QUEUE); + + dev->logging_data->cause |= (dev->shutdown << MFC_LAST_INFO_SHUTDOWN); + dev->logging_data->cause |= (dev->curr_ctx_is_drm << MFC_LAST_INFO_DRM); + + ctx = dev->ctx[dev->curr_ctx]; + if (!ctx) { + for (i = 0; i < MFC_NUM_CONTEXTS; i++) { + if (dev->ctx[i]) { + ctx = dev->ctx[i]; + /* It means that it is not ctx number of causes the problem */ + dev->curr_ctx = 0xaa; + break; + } + } + if (!ctx) { + /* It means that we couldn't believe information */ + dev->curr_ctx = 0xff; + } + } + + /* last information */ + dev->logging_data->curr_ctx = dev->curr_ctx; + dev->logging_data->last_cmd = dev->last_cmd; + dev->logging_data->last_cmd_sec = dev->last_cmd_time.tv_sec; + dev->logging_data->last_cmd_usec = dev->last_cmd_time.tv_usec; + dev->logging_data->last_int = dev->last_int; + dev->logging_data->last_int_sec = dev->last_int_time.tv_sec; + dev->logging_data->last_int_usec = dev->last_int_time.tv_usec; + dev->logging_data->hwlock_dev = dev->hwlock.dev; + dev->logging_data->hwlock_ctx = dev->hwlock.bits; + dev->logging_data->num_inst = dev->num_inst; + dev->logging_data->num_drm_inst = dev->num_drm_inst; + dev->logging_data->power_cnt = mfc_pm_get_pwr_ref_cnt(dev); + dev->logging_data->clock_cnt = mfc_pm_get_clk_ref_cnt(dev); + + if (ctx) { + dev->logging_data->state = ctx->state; + dev->logging_data->frame_cnt = ctx->frame_cnt; + if (ctx->type == MFCINST_DECODER) { + struct mfc_dec *dec = ctx->dec_priv; + + if (dec) { + dev->logging_data->dynamic_used = dec->dynamic_used; + dev->logging_data->cause |= (dec->detect_black_bar << MFC_LAST_INFO_BLACK_BAR); + } + dev->logging_data->last_src_addr = ctx->last_src_addr; + for (i = 0; i < MFC_MAX_PLANES; i++) + dev->logging_data->last_dst_addr[i] = ctx->last_dst_addr[i]; + } + } + + mfc_merge_errorinfo_data(dev, px_fault); +} + static int __mfc_get_curr_ctx(struct mfc_dev *dev) { nal_queue_handle *nal_q_handle = dev->nal_q_handle;