msm: mdss: specify HFlip and VFlip per pipe BW limit
Apply per pipe BW limit check based on HFlip/VFlip. Some targets have different limits for BW based on usecase. Change-Id: Ie23dba396b47ffb3fb910e746e4a992fe6d78ab9 Signed-off-by: Anusha Koduru <kanusha@codeaurora.org>
This commit is contained in:
parent
0bbece9015
commit
97746a102c
4 changed files with 139 additions and 8 deletions
|
@ -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.
|
||||
|
@ -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>,
|
||||
|
|
|
@ -433,6 +433,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;
|
||||
|
|
|
@ -2995,6 +2995,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);
|
||||
|
@ -3123,11 +3180,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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
||||
threshold = mdata->max_bw_per_pipe;
|
||||
|
||||
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…
Add table
Reference in a new issue