msm: mdss: add support to configure per pipe panic luts

Starting in MDPv1.7, configuration of the panic signal
is per pipe. This needs some specific luts to be
programmed on each pipe. Adding support to configure
these luts, which are enabled and tuned through
device tree.

Change-Id: I8af08e8458f8136e9767ccfea27489ce2976a437
Signed-off-by: Ingrid Gallardo <ingridg@codeaurora.org>
This commit is contained in:
Ingrid Gallardo 2015-02-20 20:18:04 -08:00 committed by David Keitel
parent 54528ec56c
commit d7e19e0da2
7 changed files with 93 additions and 18 deletions

View file

@ -415,6 +415,12 @@ Fudge Factors: Fudge factors are used to boost demand for
Number of signal offsets should match the
number of offsets defined in property:
qcom,mdss-pipe-dma-off
- qcom,mdss-per-pipe-panic-luts: Array to configure the panic/robust luts for
each rt and nrt clients. This property is
for the MDPv1.7 and above, which configures
the panic independently on each client.
First element on the array is for the panic
configuration, second element for robust.
- qcom,mdss-has-dst-split: Boolean property to indicate if destination
split feature is available or not in the target.
- qcom,mdss-cdm-off: Array of offset addresses for the available

View file

@ -216,10 +216,15 @@ struct mdss_data_type {
DECLARE_BITMAP(mmb_alloc_map, MAX_DRV_SUP_MMB_BLKS);
u32 has_bwc;
/* values used when HW has a common panic/robust LUT */
u32 default_panic_lut0;
u32 default_panic_lut1;
u32 default_robust_lut;
/* values used when HW has panic/robust LUTs per pipe */
u32 default_panic_lut_per_pipe;
u32 default_robust_lut_per_pipe;
u32 has_decimation;
bool has_fixed_qos_arbiter_enabled;
bool has_panic_ctrl;

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2009-2014, The Linux Foundation. All rights reserved.
/* Copyright (c) 2009-2015, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -462,7 +462,7 @@ static int mdss_debug_set_panic_signal(struct mdss_mdp_pipe *pipe_pool,
for (i = 0; i < pool_size; i++) {
pipe = pipe_pool + i;
if (pipe && (atomic_read(&pipe->kref.refcount) != 0) &&
mdss_mdp_panic_signal_support_mode(mdata, pipe)) {
mdss_mdp_panic_signal_support_mode(mdata)) {
mdss_mdp_pipe_panic_signal_ctrl(pipe, enable);
pr_debug("pnum:%d count:%d img:%dx%d ",
pipe->num, pipe->play_cnt, pipe->img_width,
@ -475,7 +475,7 @@ static int mdss_debug_set_panic_signal(struct mdss_mdp_pipe *pipe_pool,
} else if (pipe) {
pr_debug("Inactive pipe num:%d supported:%d\n",
atomic_read(&pipe->kref.refcount),
mdss_mdp_panic_signal_support_mode(mdata, pipe));
mdss_mdp_panic_signal_support_mode(mdata));
}
}
return cnt;

View file

@ -1083,6 +1083,8 @@ void mdss_hw_init(struct mdss_data_type *mdata)
mdata->nmax_concurrent_ad_hw =
(mdata->mdp_rev < MDSS_MDP_HW_REV_103) ? 1 : 2;
mdss_mdp_config_pipe_panic_lut(mdata);
pr_debug("MDP hw init done\n");
}
@ -1834,6 +1836,7 @@ static int mdss_mdp_parse_dt_pipe(struct platform_device *pdev)
u32 nfids = 0, setup_cnt = 0, len, nxids = 0;
u32 *offsets = NULL, *ftch_id = NULL, *xin_id = NULL;
u32 sw_reset_offset = 0;
u32 data[2];
struct mdss_data_type *mdata = platform_get_drvdata(pdev);
@ -2084,6 +2087,18 @@ static int mdss_mdp_parse_dt_pipe(struct platform_device *pdev)
mdata->dma_pipes, mdata->ndma_pipes);
}
len = mdss_mdp_parse_dt_prop_len(pdev, "qcom,mdss-per-pipe-panic-luts");
if (len != 2) {
pr_debug("Unable to read per-pipe-panic-luts\n");
} else {
rc = mdss_mdp_parse_dt_handler(pdev,
"qcom,mdss-per-pipe-panic-luts", data, len);
mdata->default_panic_lut_per_pipe = data[0];
mdata->default_robust_lut_per_pipe = data[1];
pr_debug("per pipe panic lut [0]:0x%x [1]:0x%x\n",
data[0], data[1]);
}
if (mdata->ncursor_pipes) {
mdata->cursor_pipes = devm_kzalloc(&mdata->pdev->dev,
sizeof(struct mdss_mdp_pipe) * mdata->nvig_pipes,

View file

@ -711,23 +711,20 @@ static inline int mdss_mdp_line_buffer_width(void)
}
static inline int mdss_mdp_panic_signal_support_mode(
struct mdss_data_type *mdata, struct mdss_mdp_pipe *pipe)
struct mdss_data_type *mdata)
{
uint32_t signal_mode = MDSS_MDP_PANIC_NONE;
if (pipe && pipe->mixer_left &&
pipe->mixer_left->type == MDSS_MDP_MIXER_TYPE_INTF) {
if (IS_MDSS_MAJOR_MINOR_SAME(mdata->mdp_rev,
MDSS_MDP_HW_REV_105) ||
IS_MDSS_MAJOR_MINOR_SAME(mdata->mdp_rev,
MDSS_MDP_HW_REV_108) ||
IS_MDSS_MAJOR_MINOR_SAME(mdata->mdp_rev,
MDSS_MDP_HW_REV_109))
signal_mode = MDSS_MDP_PANIC_COMMON_REG_CFG;
else if (IS_MDSS_MAJOR_MINOR_SAME(mdata->mdp_rev,
MDSS_MDP_HW_REV_107))
signal_mode = MDSS_MDP_PANIC_PER_PIPE_CFG;
}
if (IS_MDSS_MAJOR_MINOR_SAME(mdata->mdp_rev,
MDSS_MDP_HW_REV_105) ||
IS_MDSS_MAJOR_MINOR_SAME(mdata->mdp_rev,
MDSS_MDP_HW_REV_108) ||
IS_MDSS_MAJOR_MINOR_SAME(mdata->mdp_rev,
MDSS_MDP_HW_REV_109))
signal_mode = MDSS_MDP_PANIC_COMMON_REG_CFG;
else if (IS_MDSS_MAJOR_MINOR_SAME(mdata->mdp_rev,
MDSS_MDP_HW_REV_107))
signal_mode = MDSS_MDP_PANIC_PER_PIPE_CFG;
return signal_mode;
}
@ -1050,6 +1047,7 @@ int mdss_mdp_wb_addr_setup(struct mdss_data_type *mdata,
int mdss_mdp_pipe_fetch_halt(struct mdss_mdp_pipe *pipe);
int mdss_mdp_pipe_panic_signal_ctrl(struct mdss_mdp_pipe *pipe, bool enable);
void mdss_mdp_config_pipe_panic_lut(struct mdss_data_type *mdata);
void mdss_mdp_bwcpanic_ctrl(struct mdss_data_type *mdata, bool enable);
int mdss_mdp_pipe_destroy(struct mdss_mdp_pipe *pipe);
int mdss_mdp_pipe_queue_data(struct mdss_mdp_pipe *pipe,

View file

@ -200,6 +200,8 @@ enum mdss_mdp_sspp_chroma_samp_type {
#define MDSS_MDP_REG_SSPP_REQPRIO_FIFO_WM_0 0x050
#define MDSS_MDP_REG_SSPP_REQPRIO_FIFO_WM_1 0x054
#define MDSS_MDP_REG_SSPP_REQPRIO_FIFO_WM_2 0x058
#define MDSS_MDP_REG_SSPP_DANGER_LUT 0x060
#define MDSS_MDP_REG_SSPP_SAFE_LUT 0x064
#define MDSS_MDP_REG_SSPP_CREQ_LUT 0x068
#define MDSS_MDP_REG_SSPP_QOS_CTRL 0x06C
#define MDSS_MDP_REG_SSPP_UBWC_ERROR_STATUS 0x138

View file

@ -83,6 +83,52 @@ end:
return 0;
}
bool is_rt_pipe(struct mdss_mdp_pipe *pipe)
{
return pipe && pipe->mixer_left &&
pipe->mixer_left->type == MDSS_MDP_MIXER_TYPE_INTF;
}
void mdss_mdp_config_pipe_panic_lut(struct mdss_data_type *mdata)
{
u32 panic_lut, robust_lut;
struct mdss_mdp_pipe *pipe;
int i;
if ((mdss_mdp_panic_signal_support_mode(mdata) ==
MDSS_MDP_PANIC_PER_PIPE_CFG) &&
(mdata->default_panic_lut_per_pipe > 0) &&
(mdata->default_robust_lut_per_pipe > 0)) {
panic_lut = mdata->default_panic_lut_per_pipe;
robust_lut = mdata->default_robust_lut_per_pipe;
for (i = 0; i < mdata->nvig_pipes; i++) {
pipe = &mdata->vig_pipes[i];
mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_DANGER_LUT,
panic_lut);
mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_SAFE_LUT,
robust_lut);
}
for (i = 0; i < mdata->nrgb_pipes; i++) {
pipe = &mdata->rgb_pipes[i];
mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_DANGER_LUT,
panic_lut);
mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_SAFE_LUT,
robust_lut);
}
for (i = 0; i < mdata->ndma_pipes; i++) {
pipe = &mdata->dma_pipes[i];
mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_DANGER_LUT,
panic_lut);
mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_SAFE_LUT,
robust_lut);
}
}
}
int mdss_mdp_pipe_panic_signal_ctrl(struct mdss_mdp_pipe *pipe, bool enable)
{
uint32_t panic_robust_ctrl;
@ -91,8 +137,11 @@ int mdss_mdp_pipe_panic_signal_ctrl(struct mdss_mdp_pipe *pipe, bool enable)
if (!mdata->has_panic_ctrl)
goto end;
if (!is_rt_pipe(pipe))
goto end;
mutex_lock(&mdata->reg_lock);
switch (mdss_mdp_panic_signal_support_mode(mdata, pipe)) {
switch (mdss_mdp_panic_signal_support_mode(mdata)) {
case MDSS_MDP_PANIC_COMMON_REG_CFG:
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON);
panic_robust_ctrl = readl_relaxed(mdata->mdp_base +