From b9d3d48591c2e0d5a77ec165fc5066293bbd6345 Mon Sep 17 00:00:00 2001 From: Ayoung Sim Date: Mon, 20 Aug 2018 16:20:13 +0900 Subject: [PATCH] [COMMON] media: mfc: detect the specific condition for QoS weight We add lower weight at both specific 10bit condition and 4 tiles or more. Change-Id: I2d6f1f1198f2805d977c09a0b788b3dfc29afb23 Signed-off-by: Ayoung Sim --- drivers/media/platform/exynos/mfc/mfc.c | 1 + .../media/platform/exynos/mfc/mfc_common.h | 2 + .../platform/exynos/mfc/mfc_data_struct.h | 2 + drivers/media/platform/exynos/mfc/mfc_isr.c | 10 ++++- drivers/media/platform/exynos/mfc/mfc_nal_q.c | 14 +++++++ drivers/media/platform/exynos/mfc/mfc_qos.c | 42 +++++++++++-------- .../media/platform/exynos/mfc/mfc_reg_api.h | 2 + drivers/media/platform/exynos/mfc/mfc_regs.h | 4 ++ 8 files changed, 58 insertions(+), 19 deletions(-) diff --git a/drivers/media/platform/exynos/mfc/mfc.c b/drivers/media/platform/exynos/mfc/mfc.c index 2ee1250fc052..1ee52a53be3d 100644 --- a/drivers/media/platform/exynos/mfc/mfc.c +++ b/drivers/media/platform/exynos/mfc/mfc.c @@ -1073,6 +1073,7 @@ static void __mfc_parse_dt(struct device_node *np, struct mfc_dev *mfc) of_property_read_u32(np, "qos_weight_num_of_ref", &pdata->qos_weight.weight_num_of_ref); of_property_read_u32(np, "qos_weight_gpb", &pdata->qos_weight.weight_gpb); of_property_read_u32(np, "qos_weight_num_of_tile", &pdata->qos_weight.weight_num_of_tile); + of_property_read_u32(np, "qos_weight_super64_bframe", &pdata->qos_weight.weight_super64_bframe); #endif } diff --git a/drivers/media/platform/exynos/mfc/mfc_common.h b/drivers/media/platform/exynos/mfc/mfc_common.h index c0b99cb885be..99f0d8218a11 100644 --- a/drivers/media/platform/exynos/mfc/mfc_common.h +++ b/drivers/media/platform/exynos/mfc/mfc_common.h @@ -156,6 +156,8 @@ ((ctx)->type == MFCINST_ENCODER) && \ ((ctx)->framerate / 1000) >= 60) +#define IS_SUPER64_BFRAME(ctx, size, type) ((ctx->is_10bit) && (size >= 2) && (type == 3)) + /* Extra information for Decoder */ #define DEC_SET_DUAL_DPB (1 << 0) #define DEC_SET_DYNAMIC_DPB (1 << 1) diff --git a/drivers/media/platform/exynos/mfc/mfc_data_struct.h b/drivers/media/platform/exynos/mfc/mfc_data_struct.h index 953370b20e6b..ac55858e4e2e 100644 --- a/drivers/media/platform/exynos/mfc/mfc_data_struct.h +++ b/drivers/media/platform/exynos/mfc/mfc_data_struct.h @@ -415,6 +415,7 @@ struct mfc_qos_weight { unsigned int weight_num_of_ref; unsigned int weight_gpb; unsigned int weight_num_of_tile; + unsigned int weight_super64_bframe; }; #endif @@ -1352,6 +1353,7 @@ struct mfc_dec { unsigned int dec_only_release_flag; unsigned int num_of_tile_over_4; + unsigned int super64_bframe; unsigned int color_range; unsigned int color_space; diff --git a/drivers/media/platform/exynos/mfc/mfc_isr.c b/drivers/media/platform/exynos/mfc/mfc_isr.c index aa8677bb22fd..c9470fec711c 100644 --- a/drivers/media/platform/exynos/mfc/mfc_isr.c +++ b/drivers/media/platform/exynos/mfc/mfc_isr.c @@ -703,8 +703,16 @@ static void __mfc_handle_frame(struct mfc_ctx *ctx, } } - if (mfc_get_num_of_tile() >= 4) + /* Detection for QoS weight */ + if (!dec->num_of_tile_over_4 && mfc_get_num_of_tile() >= 4) { dec->num_of_tile_over_4 = 1; + mfc_qos_on(ctx); + } + if (!dec->super64_bframe && IS_SUPER64_BFRAME(ctx, mfc_get_lcu_size(), + mfc_get_dec_frame_type())) { + dec->super64_bframe = 1; + mfc_qos_on(ctx); + } switch (dst_frame_status) { case MFC_REG_DEC_STATUS_DECODING_DISPLAY: diff --git a/drivers/media/platform/exynos/mfc/mfc_nal_q.c b/drivers/media/platform/exynos/mfc/mfc_nal_q.c index 7ae70ae9fdb8..0bc18f782f4e 100644 --- a/drivers/media/platform/exynos/mfc/mfc_nal_q.c +++ b/drivers/media/platform/exynos/mfc/mfc_nal_q.c @@ -1685,6 +1685,20 @@ void __mfc_nal_q_handle_frame(struct mfc_ctx *ctx, DecoderOutputStr *pOutStr) goto leave_handle_frame; } + /* Detection for QoS weight */ + if (!dec->num_of_tile_over_4 && (((pOutStr->DisplayStatus + >> MFC_REG_DEC_STATUS_NUM_OF_TILE_SHIFT) + & MFC_REG_DEC_STATUS_NUM_OF_TILE_MASK) >= 4)) { + dec->num_of_tile_over_4 = 1; + mfc_qos_on(ctx); + } + if (!dec->super64_bframe && IS_SUPER64_BFRAME(ctx, + (pOutStr->HevcInfo & MFC_REG_D_HEVC_INFO_LCU_SIZE_MASK), + (pOutStr->DecodedFrameType & MFC_REG_DECODED_FRAME_MASK))) { + dec->super64_bframe = 1; + mfc_qos_on(ctx); + } + switch (dst_frame_status) { case MFC_REG_DEC_STATUS_DECODING_DISPLAY: __mfc_nal_q_handle_ref_frame(ctx, pOutStr); diff --git a/drivers/media/platform/exynos/mfc/mfc_qos.c b/drivers/media/platform/exynos/mfc/mfc_qos.c index 43aec5a97f58..e4de71aa226a 100644 --- a/drivers/media/platform/exynos/mfc/mfc_qos.c +++ b/drivers/media/platform/exynos/mfc/mfc_qos.c @@ -248,6 +248,7 @@ static void __mfc_qos_set(struct mfc_ctx *ctx, int i) static inline unsigned long __mfc_qos_get_weighted_mb(struct mfc_ctx *ctx, unsigned long mb) { + struct mfc_dev *dev = ctx->dev; struct mfc_enc *enc = ctx->enc_priv; struct mfc_dec *dec = ctx->dec_priv; struct mfc_enc_params *p; @@ -262,20 +263,20 @@ static inline unsigned long __mfc_qos_get_weighted_mb(struct mfc_ctx *ctx, case MFC_REG_CODEC_H264_ENC: case MFC_REG_CODEC_H264_MVC_ENC: weight = (weight * 100) / qos_weight->weight_h264_hevc; - mfc_debug(3, "[QoS] weight: h264, hevc codec, weight: %d\n", weight / 10); + mfc_debug(3, "[QoS] h264, hevc codec, weight: %d\n", weight / 10); if (num_planes == 3) { weight = (weight * 100) / qos_weight->weight_3plane; - mfc_debug(3, "[QoS] weight: 3 plane, weight: %d\n", weight / 10); + mfc_debug(3, "[QoS] 3 plane, weight: %d\n", weight / 10); } break; case MFC_REG_CODEC_VP8_DEC: case MFC_REG_CODEC_VP8_ENC: weight = (weight * 100) / qos_weight->weight_vp8_vp9; - mfc_debug(3, "[QoS] weight: vp8, vp9 codec, weight: %d\n", weight / 10); + mfc_debug(3, "[QoS] vp8, vp9 codec, weight: %d\n", weight / 10); if (num_planes == 3) { weight = (weight * 100) / qos_weight->weight_3plane; - mfc_debug(3, "[QoS] weight: 3 plane, weight: %d\n", weight / 10); + mfc_debug(3, "[QoS] 3 plane, weight: %d\n", weight / 10); } break; @@ -284,17 +285,22 @@ static inline unsigned long __mfc_qos_get_weighted_mb(struct mfc_ctx *ctx, case MFC_REG_CODEC_BPG_DEC: case MFC_REG_CODEC_BPG_ENC: weight = (weight * 100) / qos_weight->weight_h264_hevc; - mfc_debug(3, "[QoS] weight: h264, hevc codec, weight: %d\n", weight / 10); + mfc_debug(3, "[QoS] h264, hevc codec, weight: %d\n", weight / 10); if (num_planes == 3) { weight = (weight * 100) / qos_weight->weight_3plane; - mfc_debug(3, "[QoS] weight: 3 plane, weight: %d\n", weight / 10); + mfc_debug(3, "[QoS] 3 plane, weight: %d\n", weight / 10); } else { if (ctx->is_422) { weight = (weight * 100) / qos_weight->weight_422; - mfc_debug(3, "[QoS] weight: 422foramt, weight: %d\n", weight / 10); + mfc_debug(3, "[QoS] 422foramt, weight: %d\n", weight / 10); } else if (ctx->is_10bit) { - weight = (weight * 100) / qos_weight->weight_10bit; - mfc_debug(3, "[QoS] weight: 10bit, weight: %d\n", weight / 10); + if (!dev->pdata->P010_decoding && dec && dec->super64_bframe) { + weight = (weight * 100) / qos_weight->weight_super64_bframe; + mfc_debug(3, "[QoS] super64 B frame, weight: %d\n", weight / 10); + } else { + weight = (weight * 100) / qos_weight->weight_10bit; + mfc_debug(3, "[QoS] 10bit, weight: %d\n", weight / 10); + } } } break; @@ -302,18 +308,18 @@ static inline unsigned long __mfc_qos_get_weighted_mb(struct mfc_ctx *ctx, case MFC_REG_CODEC_VP9_DEC: case MFC_REG_CODEC_VP9_ENC: weight = (weight * 100) / qos_weight->weight_vp8_vp9; - mfc_debug(3, "[QoS] weight: vp8, vp9 codec, weight: %d\n", weight / 10); + mfc_debug(3, "[QoS] vp8, vp9 codec, weight: %d\n", weight / 10); if (num_planes == 3) { weight = (weight * 100) / qos_weight->weight_3plane; - mfc_debug(3, "[QoS] weight: 3 plane, weight: %d\n", weight / 10); + mfc_debug(3, "[QoS] 3 plane, weight: %d\n", weight / 10); } else { if (ctx->is_422) { weight = (weight * 100) / qos_weight->weight_422; - mfc_debug(3, "[QoS] weight: 422foramt, weight: %d\n", weight / 10); + mfc_debug(3, "[QoS] 422foramt, weight: %d\n", weight / 10); } else if (ctx->is_10bit) { weight = (weight * 100) / qos_weight->weight_10bit; - mfc_debug(3, "[QoS] weight: 10bit, weight: %d\n", weight / 10); + mfc_debug(3, "[QoS] 10bit, weight: %d\n", weight / 10); } } break; @@ -330,7 +336,7 @@ static inline unsigned long __mfc_qos_get_weighted_mb(struct mfc_ctx *ctx, case MFC_REG_CODEC_MPEG4_ENC: case MFC_REG_CODEC_H263_ENC: weight = (weight * 100) / qos_weight->weight_other_codec; - mfc_debug(3, "[QoS] weight: other codec, weight: %d\n", weight / 10); + mfc_debug(3, "[QoS] other codec, weight: %d\n", weight / 10); break; default: @@ -341,20 +347,20 @@ static inline unsigned long __mfc_qos_get_weighted_mb(struct mfc_ctx *ctx, p = &enc->params; if ((IS_H264_ENC(ctx) || IS_HEVC_ENC(ctx)) && p->num_b_frame) { weight = (weight * 100) / qos_weight->weight_bframe; - mfc_debug(3, "[QoS] weight: B frame encoding, weight: %d\n", weight / 10); + mfc_debug(3, "[QoS] B frame encoding, weight: %d\n", weight / 10); } else if ((IS_H264_ENC(ctx) || IS_HEVC_ENC(ctx) || IS_VP8_ENC(ctx) || IS_VP9_ENC(ctx)) && (p->num_refs_for_p >= 2)) { weight = (weight * 100) / qos_weight->weight_num_of_ref; - mfc_debug(3, "[QoS] weight: num of ref >= 2, weight: %d\n", weight / 10); + mfc_debug(3, "[QoS] num of ref >= 2, weight: %d\n", weight / 10); } else if (IS_HEVC_ENC(ctx) && p->codec.hevc.general_pb_enable) { weight = (weight * 100) / qos_weight->weight_gpb; - mfc_debug(3, "[QoS] weight: Genaral PB, weight: %d\n", weight / 10); + mfc_debug(3, "[QoS] Genaral PB, weight: %d\n", weight / 10); } } if (dec) { if (dec->num_of_tile_over_4) { weight = (weight * 100) / qos_weight->weight_num_of_tile; - mfc_debug(3, "[QoS] weight: num of tile >= 4, weight: %d\n", weight / 10); + mfc_debug(3, "[QoS] num of tile >= 4, weight: %d\n", weight / 10); } } diff --git a/drivers/media/platform/exynos/mfc/mfc_reg_api.h b/drivers/media/platform/exynos/mfc/mfc_reg_api.h index 15d1209d2111..30b2b46e53ed 100644 --- a/drivers/media/platform/exynos/mfc/mfc_reg_api.h +++ b/drivers/media/platform/exynos/mfc/mfc_reg_api.h @@ -168,6 +168,8 @@ #define mfc_get_num_of_tile() ((MFC_READL(MFC_REG_D_DECODED_STATUS) \ >> MFC_REG_DEC_STATUS_NUM_OF_TILE_SHIFT) \ & MFC_REG_DEC_STATUS_NUM_OF_TILE_MASK) +#define mfc_get_lcu_size() (MFC_READL(MFC_REG_D_HEVC_INFO) \ + & MFC_REG_D_HEVC_INFO_LCU_SIZE_MASK) /* nal queue information */ diff --git a/drivers/media/platform/exynos/mfc/mfc_regs.h b/drivers/media/platform/exynos/mfc/mfc_regs.h index be36d326b118..792316370290 100644 --- a/drivers/media/platform/exynos/mfc/mfc_regs.h +++ b/drivers/media/platform/exynos/mfc/mfc_regs.h @@ -732,6 +732,10 @@ #define MFC_REG_D_H264_INFO_MBAFF_FRAME_FLAG_MASK 0x1 +/* 0xF6A0: MFC_REG_D_HEVC_INFO */ +#define MFC_REG_D_HEVC_INFO_LCU_SIZE_MASK 0x3 + + /* 0xF6D8: MFC_REG_D_MVC_VIEW_ID */ #define MFC_REG_D_MVC_VIEW_ID_DISP_MASK 0xFFFF -- 2.20.1