Loading drivers/video/msm/mdss/mdss_mdp.h +2 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ #define HORSCALER_NUM_FILTER_TAPS 8 #define HORSCALER_COEFF_NUM 17 #define MDP_MIN_VBP 4 #define MDP_MIN_FETCH 9 #define MAX_FREE_LIST_SIZE 12 #define C3_ALPHA 3 /* alpha */ Loading Loading @@ -230,6 +231,7 @@ struct mdss_mdp_ctl { void *priv_data; u32 wb_type; bool prg_fet; }; struct mdss_mdp_mixer { Loading drivers/video/msm/mdss/mdss_mdp_ctl.c +5 −0 Original line number Diff line number Diff line Loading @@ -650,6 +650,9 @@ static u32 mdss_mdp_get_vbp_factor(struct mdss_mdp_ctl *ctl) fps = mdss_panel_get_framerate(pinfo); v_total = mdss_panel_get_vtotal(pinfo); vbp = pinfo->lcdc.v_back_porch + pinfo->lcdc.v_pulse_width; if (ctl->prg_fet) vbp += mdss_mdp_max_fetch_lines(pinfo); vbp_fac = (vbp) ? fps * v_total / vbp : 0; pr_debug("vbp_fac=%d vbp=%d v_total=%d\n", vbp_fac, vbp, v_total); Loading Loading @@ -732,6 +735,8 @@ static void __mdss_mdp_perf_calc_ctl_helper(struct mdss_mdp_ctl *ctl, } perf->bw_ctl = max(perf->bw_prefill, perf->bw_overlap); pr_debug("ctl=%d, prefill bw=%llu, overlap bw=%llu\n", ctl->num, perf->bw_prefill, perf->bw_overlap); } int mdss_mdp_perf_bw_check(struct mdss_mdp_ctl *ctl, Loading drivers/video/msm/mdss/mdss_mdp_hwio.h +1 −0 Original line number Diff line number Diff line Loading @@ -538,6 +538,7 @@ enum mdss_mpd_intf_index { #define MDSS_MDP_REG_INTF_TPG_INITIAL_VALUE 0x114 #define MDSS_MDP_REG_INTF_TPG_BLK_WHITE_PATTERN_FRAMES 0x118 #define MDSS_MDP_REG_INTF_TPG_RGB_MAPPING 0x11C #define MDSS_MDP_REG_INTF_PROG_FETCH_START 0x170 #define MDSS_MDP_REG_INTF_FRAME_LINE_COUNT_EN 0x0A8 #define MDSS_MDP_REG_INTF_FRAME_COUNT 0x0AC Loading drivers/video/msm/mdss/mdss_mdp_intf_video.c +57 −0 Original line number Diff line number Diff line Loading @@ -854,6 +854,62 @@ int mdss_mdp_video_reconfigure_splash_done(struct mdss_mdp_ctl *ctl, return ret; } static bool mdss_mdp_fetch_programable(struct mdss_mdp_ctl *ctl) { struct mdss_panel_info *pinfo = &ctl->panel_data->panel_info; struct mdss_data_type *mdata; bool ret; mdata = ctl->mdata; if (mdata->mdp_rev >= MDSS_MDP_HW_REV_105) { if ((pinfo->lcdc.v_back_porch + pinfo->lcdc.v_front_porch) < MDP_MIN_FETCH) { pr_warn("low vbp+vfp may lead to perf issues in some cases\n"); } ret = true; if (pinfo->lcdc.v_back_porch > MDP_MIN_FETCH) ret = false; } else { if (pinfo->lcdc.v_back_porch < MDP_MIN_FETCH) pr_warn("low vbp may lead to display performance issues"); ret = false; } return ret; } static void mdss_mdp_fetch_start_config(struct mdss_mdp_video_ctx *ctx, struct mdss_mdp_ctl *ctl) { int fetch_start, fetch_enable, v_total, h_total; struct mdss_data_type *mdata; struct mdss_panel_info *pinfo = &ctl->panel_data->panel_info; mdata = ctl->mdata; if (!mdss_mdp_fetch_programable(ctl)) { pr_debug("programmable fetch is not needed/supported\n"); ctl->prg_fet = false; return; } /* * Fetch should always be outside the active lines. If the fetching * is programmed within active region, hardware behavior is unknown. */ v_total = mdss_panel_get_vtotal(pinfo); h_total = mdss_panel_get_htotal(pinfo, true); fetch_start = (v_total - mdss_mdp_max_fetch_lines(pinfo)) * h_total; fetch_enable = BIT(31); ctl->prg_fet = true; pr_debug("ctl:%d, fetch start=%d\n", ctl->num, fetch_start); mdp_video_write(ctx, MDSS_MDP_REG_INTF_PROG_FETCH_START, fetch_start); mdp_video_write(ctx, MDSS_MDP_REG_INTF_CONFIG, fetch_enable); } static int mdss_mdp_video_intfs_setup(struct mdss_mdp_ctl *ctl, struct mdss_panel_data *pdata, int inum) { Loading Loading @@ -935,6 +991,7 @@ static int mdss_mdp_video_intfs_setup(struct mdss_mdp_ctl *ctl, return -EINVAL; } mdss_mdp_fetch_start_config(ctx, ctl); mdp_video_write(ctx, MDSS_MDP_REG_INTF_PANEL_FORMAT, ctl->dst_format); return 0; Loading drivers/video/msm/mdss/mdss_panel.h +28 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ struct panel_id { #define DEFAULT_FRAME_RATE 60 #define DEFAULT_ROTATOR_FRAME_RATE 120 #define MDSS_DSI_RST_SEQ_LEN 10 #define MDSS_MDP_MAX_FETCH 12 /* panel type list */ #define NO_PANEL 0xffff /* No Panel */ Loading Loading @@ -495,6 +496,33 @@ static inline int mdss_panel_get_htotal(struct mdss_panel_info *pinfo, bool pinfo->lcdc.h_pulse_width; } /** * mdss_mdp_max_fetch_lines: - Number of fetch lines in vertical front porch * @pinfo: Pointer to panel info containing all panel information * * Returns the number of fetch lines in vertical front porch at which mdp * can start fetching the next frame. * * In some cases, vertical front porch is too high. In such cases limit * the mdp fetch lines as the last 12 lines of vertical front porch. */ static inline int mdss_mdp_max_fetch_lines(struct mdss_panel_info *pinfo) { int fetch_lines; int v_total, vfp_start; v_total = mdss_panel_get_vtotal(pinfo); vfp_start = (pinfo->lcdc.v_back_porch + pinfo->lcdc.v_pulse_width + pinfo->yres + 1); fetch_lines = v_total - vfp_start; if (fetch_lines > MDSS_MDP_MAX_FETCH) fetch_lines = MDSS_MDP_MAX_FETCH; return fetch_lines; } int mdss_register_panel(struct platform_device *pdev, struct mdss_panel_data *pdata); Loading Loading
drivers/video/msm/mdss/mdss_mdp.h +2 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ #define HORSCALER_NUM_FILTER_TAPS 8 #define HORSCALER_COEFF_NUM 17 #define MDP_MIN_VBP 4 #define MDP_MIN_FETCH 9 #define MAX_FREE_LIST_SIZE 12 #define C3_ALPHA 3 /* alpha */ Loading Loading @@ -230,6 +231,7 @@ struct mdss_mdp_ctl { void *priv_data; u32 wb_type; bool prg_fet; }; struct mdss_mdp_mixer { Loading
drivers/video/msm/mdss/mdss_mdp_ctl.c +5 −0 Original line number Diff line number Diff line Loading @@ -650,6 +650,9 @@ static u32 mdss_mdp_get_vbp_factor(struct mdss_mdp_ctl *ctl) fps = mdss_panel_get_framerate(pinfo); v_total = mdss_panel_get_vtotal(pinfo); vbp = pinfo->lcdc.v_back_porch + pinfo->lcdc.v_pulse_width; if (ctl->prg_fet) vbp += mdss_mdp_max_fetch_lines(pinfo); vbp_fac = (vbp) ? fps * v_total / vbp : 0; pr_debug("vbp_fac=%d vbp=%d v_total=%d\n", vbp_fac, vbp, v_total); Loading Loading @@ -732,6 +735,8 @@ static void __mdss_mdp_perf_calc_ctl_helper(struct mdss_mdp_ctl *ctl, } perf->bw_ctl = max(perf->bw_prefill, perf->bw_overlap); pr_debug("ctl=%d, prefill bw=%llu, overlap bw=%llu\n", ctl->num, perf->bw_prefill, perf->bw_overlap); } int mdss_mdp_perf_bw_check(struct mdss_mdp_ctl *ctl, Loading
drivers/video/msm/mdss/mdss_mdp_hwio.h +1 −0 Original line number Diff line number Diff line Loading @@ -538,6 +538,7 @@ enum mdss_mpd_intf_index { #define MDSS_MDP_REG_INTF_TPG_INITIAL_VALUE 0x114 #define MDSS_MDP_REG_INTF_TPG_BLK_WHITE_PATTERN_FRAMES 0x118 #define MDSS_MDP_REG_INTF_TPG_RGB_MAPPING 0x11C #define MDSS_MDP_REG_INTF_PROG_FETCH_START 0x170 #define MDSS_MDP_REG_INTF_FRAME_LINE_COUNT_EN 0x0A8 #define MDSS_MDP_REG_INTF_FRAME_COUNT 0x0AC Loading
drivers/video/msm/mdss/mdss_mdp_intf_video.c +57 −0 Original line number Diff line number Diff line Loading @@ -854,6 +854,62 @@ int mdss_mdp_video_reconfigure_splash_done(struct mdss_mdp_ctl *ctl, return ret; } static bool mdss_mdp_fetch_programable(struct mdss_mdp_ctl *ctl) { struct mdss_panel_info *pinfo = &ctl->panel_data->panel_info; struct mdss_data_type *mdata; bool ret; mdata = ctl->mdata; if (mdata->mdp_rev >= MDSS_MDP_HW_REV_105) { if ((pinfo->lcdc.v_back_porch + pinfo->lcdc.v_front_porch) < MDP_MIN_FETCH) { pr_warn("low vbp+vfp may lead to perf issues in some cases\n"); } ret = true; if (pinfo->lcdc.v_back_porch > MDP_MIN_FETCH) ret = false; } else { if (pinfo->lcdc.v_back_porch < MDP_MIN_FETCH) pr_warn("low vbp may lead to display performance issues"); ret = false; } return ret; } static void mdss_mdp_fetch_start_config(struct mdss_mdp_video_ctx *ctx, struct mdss_mdp_ctl *ctl) { int fetch_start, fetch_enable, v_total, h_total; struct mdss_data_type *mdata; struct mdss_panel_info *pinfo = &ctl->panel_data->panel_info; mdata = ctl->mdata; if (!mdss_mdp_fetch_programable(ctl)) { pr_debug("programmable fetch is not needed/supported\n"); ctl->prg_fet = false; return; } /* * Fetch should always be outside the active lines. If the fetching * is programmed within active region, hardware behavior is unknown. */ v_total = mdss_panel_get_vtotal(pinfo); h_total = mdss_panel_get_htotal(pinfo, true); fetch_start = (v_total - mdss_mdp_max_fetch_lines(pinfo)) * h_total; fetch_enable = BIT(31); ctl->prg_fet = true; pr_debug("ctl:%d, fetch start=%d\n", ctl->num, fetch_start); mdp_video_write(ctx, MDSS_MDP_REG_INTF_PROG_FETCH_START, fetch_start); mdp_video_write(ctx, MDSS_MDP_REG_INTF_CONFIG, fetch_enable); } static int mdss_mdp_video_intfs_setup(struct mdss_mdp_ctl *ctl, struct mdss_panel_data *pdata, int inum) { Loading Loading @@ -935,6 +991,7 @@ static int mdss_mdp_video_intfs_setup(struct mdss_mdp_ctl *ctl, return -EINVAL; } mdss_mdp_fetch_start_config(ctx, ctl); mdp_video_write(ctx, MDSS_MDP_REG_INTF_PANEL_FORMAT, ctl->dst_format); return 0; Loading
drivers/video/msm/mdss/mdss_panel.h +28 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ struct panel_id { #define DEFAULT_FRAME_RATE 60 #define DEFAULT_ROTATOR_FRAME_RATE 120 #define MDSS_DSI_RST_SEQ_LEN 10 #define MDSS_MDP_MAX_FETCH 12 /* panel type list */ #define NO_PANEL 0xffff /* No Panel */ Loading Loading @@ -495,6 +496,33 @@ static inline int mdss_panel_get_htotal(struct mdss_panel_info *pinfo, bool pinfo->lcdc.h_pulse_width; } /** * mdss_mdp_max_fetch_lines: - Number of fetch lines in vertical front porch * @pinfo: Pointer to panel info containing all panel information * * Returns the number of fetch lines in vertical front porch at which mdp * can start fetching the next frame. * * In some cases, vertical front porch is too high. In such cases limit * the mdp fetch lines as the last 12 lines of vertical front porch. */ static inline int mdss_mdp_max_fetch_lines(struct mdss_panel_info *pinfo) { int fetch_lines; int v_total, vfp_start; v_total = mdss_panel_get_vtotal(pinfo); vfp_start = (pinfo->lcdc.v_back_porch + pinfo->lcdc.v_pulse_width + pinfo->yres + 1); fetch_lines = v_total - vfp_start; if (fetch_lines > MDSS_MDP_MAX_FETCH) fetch_lines = MDSS_MDP_MAX_FETCH; return fetch_lines; } int mdss_register_panel(struct platform_device *pdev, struct mdss_panel_data *pdata); Loading