Loading Documentation/devicetree/bindings/fb/mdss-mdp.txt +16 −2 Original line number Diff line number Diff line Loading @@ -427,8 +427,20 @@ Fudge Factors: Fudge factors are used to boost demand for applied in scenarios where panel interface can be more tolerant to memory latency such as command mode panels. - qcom,max-bandwidth-per-pipe-kbps: This value indicates the max bandwidth in KB that a single pipe can support without underflow. - qcom,max-bandwidth-per-pipe-kbps: A two dimensional array indicating the max bandwidth in KB that a single pipe can support without underflow for various usecases. The first parameter indicates the usecase and the second parameter gives the max bw allowed for the usecase. Following are the enum values for modes in different cases: For default case, mode = 1 camera usecase, mode = 2 hflip usecase, mode = 4 vflip usecase, mode = 8 First parameter/mode value need to match enum, mdss_mdp_max_bw_mode, present in include/uapi/linux/msm_mdp.h. - qcom,max-bw-settings: This two dimension array indicates the max bandwidth in KB that has to be supported when particular scenarios are involved such as camera, flip. Loading Loading @@ -612,6 +624,8 @@ Example: qcom,max-bandwidth-low-kbps = <2300000>; qcom,max-bandwidth-high-kbps = <3000000>; qcom,max-bandwidth-per-pipe-kbps = <4 2100000>, <8 1800000>; qcom,max-bw-settings = <1 2300000>, <2 1700000>, <4 2300000>, Loading drivers/video/msm/mdss/mdss.h +4 −0 Original line number Diff line number Diff line Loading @@ -432,6 +432,10 @@ struct mdss_data_type { u32 bw_mode_bitmap; u32 max_bw_settings_cnt; struct mdss_max_bw_settings *max_per_pipe_bw_settings; u32 mdss_per_pipe_bw_cnt; u32 min_bw_per_pipe; u32 bcolor0; u32 bcolor1; u32 bcolor2; Loading drivers/video/msm/mdss/mdss_mdp.c +58 −5 Original line number Diff line number Diff line Loading @@ -2992,6 +2992,63 @@ static void mdss_mdp_parse_max_bandwidth(struct platform_device *pdev) mdata->max_bw_settings_cnt = max_bw_settings_cnt; } static void mdss_mdp_parse_per_pipe_bandwidth(struct platform_device *pdev) { struct mdss_data_type *mdata = platform_get_drvdata(pdev); struct mdss_max_bw_settings *max_bw_per_pipe_settings; int max_bw_settings_cnt = 0; const u32 *max_bw_settings; u32 max_bw, min_bw, threshold, i = 0; max_bw_settings = of_get_property(pdev->dev.of_node, "qcom,max-bandwidth-per-pipe-kbps", &max_bw_settings_cnt); if (!max_bw_settings || !max_bw_settings_cnt) { pr_debug("MDSS per pipe max bandwidth settings not found\n"); return; } /* Support targets where a common per pipe max bw is provided */ if ((max_bw_settings_cnt / sizeof(u32)) == 1) { mdata->max_bw_per_pipe = be32_to_cpu(max_bw_settings[0]); mdata->max_per_pipe_bw_settings = NULL; pr_debug("Common per pipe max bandwidth provided\n"); return; } max_bw_settings_cnt /= 2 * sizeof(u32); max_bw_per_pipe_settings = devm_kzalloc(&pdev->dev, sizeof(struct mdss_max_bw_settings) * max_bw_settings_cnt, GFP_KERNEL); if (!max_bw_per_pipe_settings) { pr_err("Memory allocation failed for max_bw_settings\n"); return; } mdss_mdp_parse_max_bw_array(max_bw_settings, max_bw_per_pipe_settings, max_bw_settings_cnt); mdata->max_per_pipe_bw_settings = max_bw_per_pipe_settings; mdata->mdss_per_pipe_bw_cnt = max_bw_settings_cnt; /* Calculate min and max allowed per pipe BW */ min_bw = mdata->max_bw_high; max_bw = 0; while (i < max_bw_settings_cnt) { threshold = mdata->max_per_pipe_bw_settings[i].mdss_max_bw_val; if (threshold > max_bw) max_bw = threshold; if (threshold < min_bw) min_bw = threshold; ++i; } mdata->max_bw_per_pipe = max_bw; mdata->min_bw_per_pipe = min_bw; } static int mdss_mdp_parse_dt_misc(struct platform_device *pdev) { struct mdss_data_type *mdata = platform_get_drvdata(pdev); Loading Loading @@ -3120,11 +3177,7 @@ static int mdss_mdp_parse_dt_misc(struct platform_device *pdev) if (rc) pr_debug("max bandwidth (high) property not specified\n"); rc = of_property_read_u32(pdev->dev.of_node, "qcom,max-bandwidth-per-pipe-kbps", &mdata->max_bw_per_pipe); if (rc) pr_debug("max bandwidth (per pipe) property not specified\n"); mdss_mdp_parse_per_pipe_bandwidth(pdev); mdss_mdp_parse_max_bandwidth(pdev); Loading drivers/video/msm/mdss/mdss_mdp_ctl.c +61 −1 Original line number Diff line number Diff line Loading @@ -1402,6 +1402,61 @@ int mdss_mdp_perf_bw_check(struct mdss_mdp_ctl *ctl, return 0; } static u32 mdss_mdp_get_bw_by_mode(struct mdss_max_bw_settings *settings, int count, int key) { u32 value = 0, i = 0; while (i < count) { if (settings[i].mdss_max_bw_mode == key) { value = settings[i].mdss_max_bw_val; break; } ++i; } return value; } static u32 mdss_mdp_get_max_pipe_bw(struct mdss_mdp_pipe *pipe) { struct mdss_data_type *mdata = pipe->mixer_left->ctl->mdata; struct mdss_mdp_ctl *ctl = pipe->mixer_left->ctl; u32 flags = 0, threshold = 0, panel_orientation; panel_orientation = ctl->mfd->panel_orientation; /* Check for panel orienatation */ panel_orientation = ctl->mfd->panel_orientation; if (panel_orientation & MDP_FLIP_LR) flags |= MDSS_MAX_BW_LIMIT_HFLIP; if (panel_orientation & MDP_FLIP_UD) flags |= MDSS_MAX_BW_LIMIT_VFLIP; /* check for Hflip/Vflip in pipe */ if (pipe->flags & MDP_FLIP_LR) flags |= MDSS_MAX_BW_LIMIT_HFLIP; if (pipe->flags & MDP_FLIP_UD) flags |= MDSS_MAX_BW_LIMIT_VFLIP; if ((flags & MDSS_MAX_BW_LIMIT_HFLIP) && (flags & MDSS_MAX_BW_LIMIT_VFLIP)) { threshold = mdata->min_bw_per_pipe; } else if (flags & MDSS_MAX_BW_LIMIT_HFLIP) { threshold = mdss_mdp_get_bw_by_mode( mdata->max_per_pipe_bw_settings, mdata->mdss_per_pipe_bw_cnt, MDSS_MAX_BW_LIMIT_HFLIP); } else if (flags & MDSS_MAX_BW_LIMIT_VFLIP) { threshold = mdss_mdp_get_bw_by_mode( mdata->max_per_pipe_bw_settings, mdata->mdss_per_pipe_bw_cnt, MDSS_MAX_BW_LIMIT_VFLIP); } return threshold ? threshold : mdata->max_bw_per_pipe; } int mdss_mdp_perf_bw_check_pipe(struct mdss_mdp_perf_params *perf, struct mdss_mdp_pipe *pipe) { Loading @@ -1427,7 +1482,12 @@ int mdss_mdp_perf_bw_check_pipe(struct mdss_mdp_perf_params *perf, /* convert bandwidth to kb */ pipe_bw = DIV_ROUND_UP_ULL(pipe_bw, 1000); if (!mdata->max_per_pipe_bw_settings) threshold = mdata->max_bw_per_pipe; else threshold = mdss_mdp_get_max_pipe_bw(pipe); pr_debug("bw=%llu threshold=%u\n", pipe_bw, threshold); if (threshold && pipe_bw > threshold) { Loading Loading
Documentation/devicetree/bindings/fb/mdss-mdp.txt +16 −2 Original line number Diff line number Diff line Loading @@ -427,8 +427,20 @@ Fudge Factors: Fudge factors are used to boost demand for applied in scenarios where panel interface can be more tolerant to memory latency such as command mode panels. - qcom,max-bandwidth-per-pipe-kbps: This value indicates the max bandwidth in KB that a single pipe can support without underflow. - qcom,max-bandwidth-per-pipe-kbps: A two dimensional array indicating the max bandwidth in KB that a single pipe can support without underflow for various usecases. The first parameter indicates the usecase and the second parameter gives the max bw allowed for the usecase. Following are the enum values for modes in different cases: For default case, mode = 1 camera usecase, mode = 2 hflip usecase, mode = 4 vflip usecase, mode = 8 First parameter/mode value need to match enum, mdss_mdp_max_bw_mode, present in include/uapi/linux/msm_mdp.h. - qcom,max-bw-settings: This two dimension array indicates the max bandwidth in KB that has to be supported when particular scenarios are involved such as camera, flip. Loading Loading @@ -612,6 +624,8 @@ Example: qcom,max-bandwidth-low-kbps = <2300000>; qcom,max-bandwidth-high-kbps = <3000000>; qcom,max-bandwidth-per-pipe-kbps = <4 2100000>, <8 1800000>; qcom,max-bw-settings = <1 2300000>, <2 1700000>, <4 2300000>, Loading
drivers/video/msm/mdss/mdss.h +4 −0 Original line number Diff line number Diff line Loading @@ -432,6 +432,10 @@ struct mdss_data_type { u32 bw_mode_bitmap; u32 max_bw_settings_cnt; struct mdss_max_bw_settings *max_per_pipe_bw_settings; u32 mdss_per_pipe_bw_cnt; u32 min_bw_per_pipe; u32 bcolor0; u32 bcolor1; u32 bcolor2; Loading
drivers/video/msm/mdss/mdss_mdp.c +58 −5 Original line number Diff line number Diff line Loading @@ -2992,6 +2992,63 @@ static void mdss_mdp_parse_max_bandwidth(struct platform_device *pdev) mdata->max_bw_settings_cnt = max_bw_settings_cnt; } static void mdss_mdp_parse_per_pipe_bandwidth(struct platform_device *pdev) { struct mdss_data_type *mdata = platform_get_drvdata(pdev); struct mdss_max_bw_settings *max_bw_per_pipe_settings; int max_bw_settings_cnt = 0; const u32 *max_bw_settings; u32 max_bw, min_bw, threshold, i = 0; max_bw_settings = of_get_property(pdev->dev.of_node, "qcom,max-bandwidth-per-pipe-kbps", &max_bw_settings_cnt); if (!max_bw_settings || !max_bw_settings_cnt) { pr_debug("MDSS per pipe max bandwidth settings not found\n"); return; } /* Support targets where a common per pipe max bw is provided */ if ((max_bw_settings_cnt / sizeof(u32)) == 1) { mdata->max_bw_per_pipe = be32_to_cpu(max_bw_settings[0]); mdata->max_per_pipe_bw_settings = NULL; pr_debug("Common per pipe max bandwidth provided\n"); return; } max_bw_settings_cnt /= 2 * sizeof(u32); max_bw_per_pipe_settings = devm_kzalloc(&pdev->dev, sizeof(struct mdss_max_bw_settings) * max_bw_settings_cnt, GFP_KERNEL); if (!max_bw_per_pipe_settings) { pr_err("Memory allocation failed for max_bw_settings\n"); return; } mdss_mdp_parse_max_bw_array(max_bw_settings, max_bw_per_pipe_settings, max_bw_settings_cnt); mdata->max_per_pipe_bw_settings = max_bw_per_pipe_settings; mdata->mdss_per_pipe_bw_cnt = max_bw_settings_cnt; /* Calculate min and max allowed per pipe BW */ min_bw = mdata->max_bw_high; max_bw = 0; while (i < max_bw_settings_cnt) { threshold = mdata->max_per_pipe_bw_settings[i].mdss_max_bw_val; if (threshold > max_bw) max_bw = threshold; if (threshold < min_bw) min_bw = threshold; ++i; } mdata->max_bw_per_pipe = max_bw; mdata->min_bw_per_pipe = min_bw; } static int mdss_mdp_parse_dt_misc(struct platform_device *pdev) { struct mdss_data_type *mdata = platform_get_drvdata(pdev); Loading Loading @@ -3120,11 +3177,7 @@ static int mdss_mdp_parse_dt_misc(struct platform_device *pdev) if (rc) pr_debug("max bandwidth (high) property not specified\n"); rc = of_property_read_u32(pdev->dev.of_node, "qcom,max-bandwidth-per-pipe-kbps", &mdata->max_bw_per_pipe); if (rc) pr_debug("max bandwidth (per pipe) property not specified\n"); mdss_mdp_parse_per_pipe_bandwidth(pdev); mdss_mdp_parse_max_bandwidth(pdev); Loading
drivers/video/msm/mdss/mdss_mdp_ctl.c +61 −1 Original line number Diff line number Diff line Loading @@ -1402,6 +1402,61 @@ int mdss_mdp_perf_bw_check(struct mdss_mdp_ctl *ctl, return 0; } static u32 mdss_mdp_get_bw_by_mode(struct mdss_max_bw_settings *settings, int count, int key) { u32 value = 0, i = 0; while (i < count) { if (settings[i].mdss_max_bw_mode == key) { value = settings[i].mdss_max_bw_val; break; } ++i; } return value; } static u32 mdss_mdp_get_max_pipe_bw(struct mdss_mdp_pipe *pipe) { struct mdss_data_type *mdata = pipe->mixer_left->ctl->mdata; struct mdss_mdp_ctl *ctl = pipe->mixer_left->ctl; u32 flags = 0, threshold = 0, panel_orientation; panel_orientation = ctl->mfd->panel_orientation; /* Check for panel orienatation */ panel_orientation = ctl->mfd->panel_orientation; if (panel_orientation & MDP_FLIP_LR) flags |= MDSS_MAX_BW_LIMIT_HFLIP; if (panel_orientation & MDP_FLIP_UD) flags |= MDSS_MAX_BW_LIMIT_VFLIP; /* check for Hflip/Vflip in pipe */ if (pipe->flags & MDP_FLIP_LR) flags |= MDSS_MAX_BW_LIMIT_HFLIP; if (pipe->flags & MDP_FLIP_UD) flags |= MDSS_MAX_BW_LIMIT_VFLIP; if ((flags & MDSS_MAX_BW_LIMIT_HFLIP) && (flags & MDSS_MAX_BW_LIMIT_VFLIP)) { threshold = mdata->min_bw_per_pipe; } else if (flags & MDSS_MAX_BW_LIMIT_HFLIP) { threshold = mdss_mdp_get_bw_by_mode( mdata->max_per_pipe_bw_settings, mdata->mdss_per_pipe_bw_cnt, MDSS_MAX_BW_LIMIT_HFLIP); } else if (flags & MDSS_MAX_BW_LIMIT_VFLIP) { threshold = mdss_mdp_get_bw_by_mode( mdata->max_per_pipe_bw_settings, mdata->mdss_per_pipe_bw_cnt, MDSS_MAX_BW_LIMIT_VFLIP); } return threshold ? threshold : mdata->max_bw_per_pipe; } int mdss_mdp_perf_bw_check_pipe(struct mdss_mdp_perf_params *perf, struct mdss_mdp_pipe *pipe) { Loading @@ -1427,7 +1482,12 @@ int mdss_mdp_perf_bw_check_pipe(struct mdss_mdp_perf_params *perf, /* convert bandwidth to kb */ pipe_bw = DIV_ROUND_UP_ULL(pipe_bw, 1000); if (!mdata->max_per_pipe_bw_settings) threshold = mdata->max_bw_per_pipe; else threshold = mdss_mdp_get_max_pipe_bw(pipe); pr_debug("bw=%llu threshold=%u\n", pipe_bw, threshold); if (threshold && pipe_bw > threshold) { Loading