Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 399febd1 authored by Adrian Salido-Moreno's avatar Adrian Salido-Moreno Committed by Gerrit - the friendly Code Review server
Browse files

msm: mdss: refactor mixer configuration code



Current mixer configuration code is scattered across multiple places,
with the addition of extension registers and additional mixers, there
are some changes that are not properly handled in all places leading
to issues in configuration that are hard to debug.

Centralize the programming of mixer configuration into a few functions
that handle overall programming, making it easier to maintain.

CRs-Fixed: 987777
Change-Id: I76410ea8eb1ea42ad42613fdb844ce6a8eb8c3ff
Signed-off-by: default avatarAdrian Salido-Moreno <adrianm@codeaurora.org>
parent 0b20839e
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -1580,9 +1580,8 @@ int mdss_mdp_wb_kickoff(struct msm_fb_data_type *mfd,
int mdss_mdp_wb_ioctl_handler(struct msm_fb_data_type *mfd, u32 cmd, void *arg);

int mdss_mdp_get_ctl_mixers(u32 fb_num, u32 *mixer_id);
u32 mdss_mdp_get_mixer_mask(u32 pipe_num, u32 stage);
u32 mdss_mdp_get_mixer_extn_mask(u32 pipe_num, u32 stage);
u32 mdss_mdp_get_mixercfg(struct mdss_mdp_mixer *mixer, bool extn);
bool mdss_mdp_mixer_reg_has_pipe(struct mdss_mdp_mixer *mixer,
		struct mdss_mdp_pipe *pipe);
u32 mdss_mdp_fb_stride(u32 fb_index, u32 xres, int bpp);
void mdss_check_dsi_ctrl_status(struct work_struct *work, uint32_t interval);

+182 −162
Original line number Diff line number Diff line
@@ -27,7 +27,36 @@
#include "mdss_mdp_trace.h"
#include "mdss_debug.h"

#define NUM_MIXERCFG_REGS 2
#define MDSS_MDP_WB_OUTPUT_BPP	3
struct mdss_mdp_mixer_cfg {
	u32 config_masks[NUM_MIXERCFG_REGS];
	bool border_enabled;
	bool cursor_enabled;
};

static struct {
	u32 flush_bit;
	struct mdss_mdp_hwio_cfg base;
	struct mdss_mdp_hwio_cfg ext;
} mdp_pipe_hwio[MDSS_MDP_MAX_SSPP] = {
	[MDSS_MDP_SSPP_VIG0]    = {  0, {  0, 3, 0 }, {  0, 1, 3 } },
	[MDSS_MDP_SSPP_VIG1]    = {  1, {  3, 3, 0 }, {  2, 1, 3 } },
	[MDSS_MDP_SSPP_VIG2]    = {  2, {  6, 3, 0 }, {  4, 1, 3 } },
	[MDSS_MDP_SSPP_VIG3]    = { 18, { 26, 3, 0 }, {  4, 1, 3 } },
	[MDSS_MDP_SSPP_RGB0]    = {  3, {  9, 3, 0 }, {  8, 1, 3 } },
	[MDSS_MDP_SSPP_RGB1]    = {  4, { 12, 3, 0 }, { 10, 1, 3 } },
	[MDSS_MDP_SSPP_RGB2]    = {  5, { 15, 3, 0 }, { 12, 1, 3 } },
	[MDSS_MDP_SSPP_RGB3]    = { 19, { 29, 3, 0 }, { 14, 1, 3 } },
	[MDSS_MDP_SSPP_DMA0]    = { 11, { 18, 3, 0 }, { 16, 1, 3 } },
	[MDSS_MDP_SSPP_DMA1]    = { 12, { 21, 3, 0 }, { 18, 1, 3 } },
	[MDSS_MDP_SSPP_CURSOR0] = { 22, .ext  = { 20, 4, 0 } },
	[MDSS_MDP_SSPP_CURSOR1] = { 23, .ext  = { 26, 4, 0 } },
};

static void __mdss_mdp_mixer_write_cfg(struct mdss_mdp_mixer *mixer,
		struct mdss_mdp_mixer_cfg *cfg);
static void __mdss_mdp_reset_mixercfg(struct mdss_mdp_ctl *ctl);

static inline u64 fudge_factor(u64 val, u32 numer, u32 denom)
{
@@ -52,82 +81,6 @@ static DEFINE_MUTEX(mdss_mdp_ctl_lock);

static u32 mdss_mdp_get_vbp_factor_max(struct mdss_mdp_ctl *ctl);

static inline u32 __mdss_mdp_get_wb_mixer(struct mdss_mdp_mixer *mixer)
{
	/* Return the dedicated WB mixer. */
	if (test_bit(MDSS_CAPS_MIXER_1_FOR_WB,
				mixer->ctl->mdata->mdss_caps_map))
		return MDSS_MDP_INTF_LAYERMIXER1;
	else
		return MDSS_MDP_INTF_LAYERMIXER3;
}

static void __mdss_mdp_reset_mixercfg(struct mdss_mdp_ctl *ctl)
{
	u32 off;
	int i, nmixers;
	struct mdss_data_type *mdata = mdss_mdp_get_mdata();

	if (!ctl || !mdata)
		return;

	nmixers = mdata->nmixers_intf + mdata->nmixers_wb;

	for (i = 0; i < nmixers; i++) {
		off = MDSS_MDP_REG_CTL_LAYER(i);
		mdss_mdp_ctl_write(ctl, off, 0);

		off += MDSS_MDP_REG_CTL_LAYER_EXTN(i);
		mdss_mdp_ctl_write(ctl, off, 0);
	}
}

static inline int __mdss_mdp_ctl_get_mixer_off(struct mdss_mdp_mixer *mixer)
{
	u32 wb_mixer_num = 0;

	if (mixer->type == MDSS_MDP_MIXER_TYPE_INTF) {
		if (mixer->num == MDSS_MDP_INTF_LAYERMIXER3)
			return MDSS_MDP_CTL_X_LAYER_5;
		else
			return MDSS_MDP_REG_CTL_LAYER(mixer->num);
	} else {
		wb_mixer_num = __mdss_mdp_get_wb_mixer(mixer);
		return MDSS_MDP_REG_CTL_LAYER(mixer->num + wb_mixer_num);
	}
}

static inline int __mdss_mdp_ctl_get_mixer_extn_off(
	struct mdss_mdp_mixer *mixer)
{
	u32 wb_mixer_num = 0;

	if (mixer->type == MDSS_MDP_MIXER_TYPE_INTF) {
		if (mixer->num == MDSS_MDP_INTF_LAYERMIXER3)
			return MDSS_MDP_REG_CTL_LAYER_EXTN(5);
		else
			return MDSS_MDP_REG_CTL_LAYER_EXTN(mixer->num);
	} else {
		wb_mixer_num = __mdss_mdp_get_wb_mixer(mixer);
		return MDSS_MDP_REG_CTL_LAYER_EXTN(wb_mixer_num);
	}
}

u32 mdss_mdp_get_mixercfg(struct mdss_mdp_mixer *mixer, bool extn)
{
	u32 mixer_off;

	if (!mixer || !mixer->ctl)
		return 0;

	if (extn)
		mixer_off = __mdss_mdp_ctl_get_mixer_extn_off(mixer);
	else
		mixer_off = __mdss_mdp_ctl_get_mixer_off(mixer);

	return mdss_mdp_ctl_read(mixer->ctl, mixer_off);
}

static inline u32 mdss_mdp_get_pclk_rate(struct mdss_mdp_ctl *ctl)
{
	struct mdss_panel_info *pinfo = &ctl->panel_data->panel_info;
@@ -4079,56 +4032,155 @@ void mdss_mdp_set_roi(struct mdss_mdp_ctl *ctl,
	}
}

u32 mdss_mdp_get_mixer_mask(u32 pipe_num, u32 stage)
static void __mdss_mdp_mixer_update_cfg_masks(u32 pnum, u32 stage,
		struct mdss_mdp_mixer_cfg *cfg)
{
	u32 mask = 0;
	u32 masks[NUM_MIXERCFG_REGS] = { 0 };
	int i;

	if ((pipe_num == MDSS_MDP_SSPP_VIG3 ||
			pipe_num == MDSS_MDP_SSPP_RGB3)) {
		/* Add 2 to account for Cursor & Border bits */
		mask = stage << ((3 * pipe_num) + 2);
	} else {
		mask = stage << (3 * pipe_num);
	}
	return mask;
	if (pnum >= MDSS_MDP_MAX_SSPP)
		return;

	masks[0] = mdss_mdp_hwio_mask(&mdp_pipe_hwio[pnum].base, stage);
	masks[1] = mdss_mdp_hwio_mask(&mdp_pipe_hwio[pnum].ext, stage);

	for (i = 0; i < NUM_MIXERCFG_REGS; i++)
		cfg->config_masks[i] |= masks[i];

	pr_debug("pnum=%d stage=%d cfg=0x%08x ext=0x%08x\n",
			pnum, stage, masks[0], masks[1]);
}

u32 mdss_mdp_get_mixer_extn_mask(u32 pipe_num, u32 stage)
static void __mdss_mdp_mixer_get_offsets(u32 mixer_num,
		u32 *offsets, size_t count)
{
	u32 mask = 0;
	BUG_ON(count < NUM_MIXERCFG_REGS);

	offsets[0] = MDSS_MDP_REG_CTL_LAYER(mixer_num);
	offsets[1] = MDSS_MDP_REG_CTL_LAYER_EXTN(mixer_num);
}

static inline int __mdss_mdp_mixer_get_hw_num(struct mdss_mdp_mixer *mixer)
{
	/*
	 * The ctl layer extension bits are ordered
	 * VIG0-3, RGB0-3, DMA0-1
	 * mapping to hardware expectation of actual mixer programming to
	 * happen on following registers:
	 *  INTF: 0, 1, 2, 5
	 *  WB: 3, 4
	 * With some exceptions on certain revisions
	 */
	if (pipe_num < MDSS_MDP_SSPP_RGB0) {
		mask = BIT(pipe_num << 1);
	} else if (pipe_num >= MDSS_MDP_SSPP_RGB0 &&
			pipe_num < MDSS_MDP_SSPP_DMA0) {
		mask = BIT((pipe_num + 1) << 1);
	} else if (pipe_num >= MDSS_MDP_SSPP_DMA0 &&
			pipe_num < MDSS_MDP_SSPP_VIG3) {
		mask = BIT((pipe_num + 2) << 1);
	} else if (pipe_num >= MDSS_MDP_SSPP_CURSOR0 &&
			pipe_num <= MDSS_MDP_SSPP_CURSOR1) {
		mask = stage << (20 + (6 * (pipe_num - MDSS_MDP_SSPP_CURSOR0)));
	} else if (pipe_num == MDSS_MDP_SSPP_VIG3) {
		mask = BIT(6);
	} else if (pipe_num == MDSS_MDP_SSPP_RGB3) {
		mask = BIT(14);
	}

	return mask;
	if (mixer->type == MDSS_MDP_MIXER_TYPE_WRITEBACK) {
		u32 wb_offset;

		if (test_bit(MDSS_CAPS_MIXER_1_FOR_WB,
					mixer->ctl->mdata->mdss_caps_map))
			wb_offset = MDSS_MDP_INTF_LAYERMIXER1;
		else
			wb_offset = MDSS_MDP_INTF_LAYERMIXER3;

		return mixer->num + wb_offset;
	} else if (mixer->num == MDSS_MDP_INTF_LAYERMIXER3) {
		return 5;
	} else {
		return mixer->num;
	}
}

static inline void __mdss_mdp_mixer_write_layer(struct mdss_mdp_ctl *ctl,
		u32 mixer_num, u32 *values, size_t count)
{
	u32 off[NUM_MIXERCFG_REGS];
	int i;

	BUG_ON(!values || count < NUM_MIXERCFG_REGS);

	__mdss_mdp_mixer_get_offsets(mixer_num, off, ARRAY_SIZE(off));

	for (i = 0; i < count; i++)
		mdss_mdp_ctl_write(ctl, off[i], values[i]);
}

static void __mdss_mdp_mixer_write_cfg(struct mdss_mdp_mixer *mixer,
		struct mdss_mdp_mixer_cfg *cfg)
{
	u32 vals[NUM_MIXERCFG_REGS] = {0};
	int i, mixer_num;

	if (!mixer)
		return;

	mixer_num = __mdss_mdp_mixer_get_hw_num(mixer);

	if (cfg) {
		for (i = 0; i < NUM_MIXERCFG_REGS; i++)
			vals[i] = cfg->config_masks[i];

		if (cfg->border_enabled)
			vals[0] |= MDSS_MDP_LM_BORDER_COLOR;
		if (cfg->cursor_enabled)
			vals[0] |= MDSS_MDP_LM_CURSOR_OUT;
	}

	__mdss_mdp_mixer_write_layer(mixer->ctl, mixer_num,
			vals, ARRAY_SIZE(vals));

	pr_debug("mixer=%d cfg=0%08x cfg_extn=0x%08x\n",
		mixer->num, vals[0], vals[1]);
	MDSS_XLOG(mixer->num, vals[0], vals[1]);
}

static void __mdss_mdp_reset_mixercfg(struct mdss_mdp_ctl *ctl)
{
	u32 vals[NUM_MIXERCFG_REGS] = {0};
	int i, nmixers;

	if (!ctl)
		return;

	nmixers = MDSS_MDP_INTF_MAX_LAYERMIXER + MDSS_MDP_WB_MAX_LAYERMIXER;

	for (i = 0; i < nmixers; i++)
		__mdss_mdp_mixer_write_layer(ctl, i, vals, ARRAY_SIZE(vals));
}

bool mdss_mdp_mixer_reg_has_pipe(struct mdss_mdp_mixer *mixer,
		struct mdss_mdp_pipe *pipe)
{
	u32 offs[NUM_MIXERCFG_REGS];
	u32 cfgs[NUM_MIXERCFG_REGS];
	struct mdss_mdp_mixer_cfg mixercfg;
	int i, mixer_num;

	if (!mixer)
		return false;

	memset(&mixercfg, 0, sizeof(mixercfg));

	mixer_num = __mdss_mdp_mixer_get_hw_num(mixer);
	__mdss_mdp_mixer_get_offsets(mixer_num, offs, NUM_MIXERCFG_REGS);

	for (i = 0; i < NUM_MIXERCFG_REGS; i++)
		cfgs[i] = mdss_mdp_ctl_read(mixer->ctl, offs[i]);

	__mdss_mdp_mixer_update_cfg_masks(pipe->num, -1, &mixercfg);
	for (i = 0; i < NUM_MIXERCFG_REGS; i++) {
		if (cfgs[i] & mixercfg.config_masks[i]) {
			MDSS_XLOG(mixer->num, cfgs[0], cfgs[1]);
			return true;
		}
	}

	return false;
}

static void mdss_mdp_mixer_setup(struct mdss_mdp_ctl *master_ctl,
	int mixer_mux, bool lm_swap)
{
	int i;
	int i, mixer_num;
	int stage, screen_state, outsize;
	u32 off, blend_op, blend_stage;
	u32 mixercfg = 0, mixer_op_mode = 0, bg_alpha_enable = 0,
	    mixercfg_extn = 0;
	u32 mixer_op_mode = 0, bg_alpha_enable = 0;
	struct mdss_mdp_mixer_cfg mixercfg;
	u32 fg_alpha = 0, bg_alpha = 0;
	struct mdss_mdp_pipe *pipe;
	struct mdss_mdp_ctl *ctl, *ctl_hw;
@@ -4149,10 +4201,12 @@ static void mdss_mdp_mixer_setup(struct mdss_mdp_ctl *master_ctl,

	/* check if mixer setup for rotator is needed */
	if (mixer_hw->rotator_mode) {
		__mdss_mdp_reset_mixercfg(ctl_hw);
		__mdss_mdp_mixer_write_cfg(mixer_hw, NULL);
		return;
	}

	memset(&mixercfg, 0, sizeof(mixercfg));

	if (lm_swap) {
		if (mixer_mux == MDSS_MDP_MIXER_MUX_RIGHT)
			mixer = mdss_mdp_mixer_get(master_ctl,
@@ -4182,11 +4236,7 @@ static void mdss_mdp_mixer_setup(struct mdss_mdp_ctl *master_ctl,
		 * mode is MDP_DUAL_LM_SINGLE_DISPLAY but update is only on
		 * one side.
		 */
		off = __mdss_mdp_ctl_get_mixer_off(mixer_hw);
		mdss_mdp_ctl_write(ctl_hw, off, 0);
		/* Program ctl layer extension bits */
		off = __mdss_mdp_ctl_get_mixer_extn_off(mixer_hw);
		mdss_mdp_ctl_write(ctl_hw, off, 0);
		__mdss_mdp_mixer_write_cfg(mixer_hw, NULL);

		MDSS_XLOG(mixer->num, mixer_hw->num, XLOG_FUNC_EXIT);
		return;
@@ -4200,19 +4250,16 @@ static void mdss_mdp_mixer_setup(struct mdss_mdp_ctl *master_ctl,
	mdp_mixer_write(mixer_hw, MDSS_MDP_REG_LM_OUT_SIZE, outsize);

	if (screen_state == MDSS_SCREEN_FORCE_BLANK) {
		mixercfg = MDSS_MDP_LM_BORDER_COLOR;
		mixercfg.border_enabled = true;
		goto update_mixer;
	}

	pipe = mixer->stage_pipe[MDSS_MDP_STAGE_BASE * MAX_PIPES_PER_STAGE];
	if (pipe == NULL) {
		mixercfg = MDSS_MDP_LM_BORDER_COLOR;
		mixercfg.border_enabled = true;
	} else {
		if (pipe->type == MDSS_MDP_PIPE_TYPE_CURSOR)
			mixercfg_extn |= mdss_mdp_get_mixer_extn_mask(
						pipe->num, 1);
		else
			mixercfg  |= mdss_mdp_get_mixer_mask(pipe->num, 1);
		__mdss_mdp_mixer_update_cfg_masks(pipe->num,
				MDSS_MDP_STAGE_BASE, &mixercfg);

		if (pipe->src_fmt->alpha_enable)
			bg_alpha_enable = 1;
@@ -4313,12 +4360,7 @@ static void mdss_mdp_mixer_setup(struct mdss_mdp_ctl *master_ctl,
		if (!pipe->src_fmt->alpha_enable && bg_alpha_enable)
			mixer_op_mode = 0;

		if ((stage < MDSS_MDP_STAGE_6) &&
			(pipe->type != MDSS_MDP_PIPE_TYPE_CURSOR))
			mixercfg |= mdss_mdp_get_mixer_mask(pipe->num, stage);
		else
			mixercfg_extn |= mdss_mdp_get_mixer_extn_mask(
						pipe->num, stage);
		__mdss_mdp_mixer_update_cfg_masks(pipe->num, stage, &mixercfg);

		trace_mdp_sspp_change(pipe);

@@ -4333,20 +4375,11 @@ static void mdss_mdp_mixer_setup(struct mdss_mdp_ctl *master_ctl,
	}

	if (mixer->cursor_enabled)
		mixercfg |= MDSS_MDP_LM_CURSOR_OUT;
		mixercfg.cursor_enabled = true;

update_mixer:
	if (mixer_hw->num == MDSS_MDP_INTF_LAYERMIXER3) {
		ctl_hw->flush_bits |= BIT(20);
	} else if (mixer_hw->type == MDSS_MDP_MIXER_TYPE_WRITEBACK) {
		if (test_bit(MDSS_CAPS_MIXER_1_FOR_WB,
			 mdata->mdss_caps_map))
			ctl_hw->flush_bits |= BIT(7) << mixer_hw->num;
		else
			ctl_hw->flush_bits |= BIT(9) << mixer_hw->num;
	} else {
		ctl_hw->flush_bits |= BIT(6) << mixer_hw->num;
	}
	mixer_num = __mdss_mdp_mixer_get_hw_num(mixer_hw);
	ctl_hw->flush_bits |= BIT(mixer_num < 5 ? 6 + mixer_num : 20);

	/* Read GC enable/disable status on LM */
	mixer_op_mode |=
@@ -4362,18 +4395,14 @@ update_mixer:
	mdp_mixer_write(mixer_hw, MDSS_MDP_REG_LM_BORDER_COLOR_1,
		mdata->bcolor2 & 0xFFF);

	off = __mdss_mdp_ctl_get_mixer_off(mixer_hw);
	mdss_mdp_ctl_write(ctl_hw, off, mixercfg);
	/* Program ctl layer extension bits */
	off = __mdss_mdp_ctl_get_mixer_extn_off(mixer_hw);
	mdss_mdp_ctl_write(ctl_hw, off, mixercfg_extn);
	__mdss_mdp_mixer_write_cfg(mixer_hw, &mixercfg);

	pr_debug("mixer=%d hw=%d cfg=0%08x cfg_extn=0x%08x op_mode=0x%08x w=%d h=%d bc0=0x%x bc1=0x%x\n",
		mixer->num, mixer_hw->num, mixercfg, mixercfg_extn,
	pr_debug("mixer=%d hw=%d op_mode=0x%08x w=%d h=%d bc0=0x%x bc1=0x%x\n",
		mixer->num, mixer_hw->num,
		mixer_op_mode, mixer->roi.w, mixer->roi.h,
		(mdata->bcolor0 & 0xFFF) | ((mdata->bcolor1 & 0xFFF) << 16),
		mdata->bcolor2 & 0xFFF);
	MDSS_XLOG(mixer->num, mixer_hw->num, mixercfg, mixercfg_extn,
	MDSS_XLOG(mixer->num, mixer_hw->num,
		mixer_op_mode, mixer->roi.h, mixer->roi.w);
}

@@ -4567,19 +4596,10 @@ struct mdss_mdp_pipe *mdss_mdp_get_staged_pipe(struct mdss_mdp_ctl *ctl,

int mdss_mdp_get_pipe_flush_bits(struct mdss_mdp_pipe *pipe)
{
	u32 flush_bits;

	if (pipe->type == MDSS_MDP_PIPE_TYPE_DMA)
		flush_bits |= BIT(pipe->num) << 5;
	else if (pipe->num == MDSS_MDP_SSPP_VIG3 ||
			pipe->num == MDSS_MDP_SSPP_RGB3)
		flush_bits |= BIT(pipe->num) << 10;
	else if (pipe->type == MDSS_MDP_PIPE_TYPE_CURSOR)
		flush_bits |= BIT(22 + pipe->num - MDSS_MDP_SSPP_CURSOR0);
	else /* RGB/VIG 0-2 pipes */
		flush_bits |= BIT(pipe->num);
	if (WARN_ON(!pipe || pipe->num >= MDSS_MDP_MAX_SSPP))
		return 0;

	return flush_bits;
	return BIT(mdp_pipe_hwio[pipe->num].flush_bit);
}

int mdss_mdp_async_ctl_flush(struct msm_fb_data_type *mfd,
+26 −7
Original line number Diff line number Diff line
@@ -16,6 +16,23 @@

#include <linux/bitops.h>

/*
 * struct mdss_mdp_hwio_cfg - used to define a register bitfield
 * @start: bitfield offset start from lsb
 * @len: number of lsb bits that can be taken from field value
 * @shift: number of lsb bits to truncate from field value
 */
struct mdss_mdp_hwio_cfg {
	u32 start, len, shift;
};

static inline u32 mdss_mdp_hwio_mask(struct mdss_mdp_hwio_cfg *cfg, u32 val)
{
	u32 mask = (1 << cfg->len) - 1;

	return ((val >> cfg->shift) & mask) << cfg->start;
}

#define IGC_LUT_ENTRIES	256
#define GC_LUT_SEGMENTS	16
#define ENHIST_LUT_ENTRIES 256
@@ -141,16 +158,22 @@ enum mdss_mdp_ctl_index {
	MDSS_MDP_MAX_CTL
};


#define MDSS_MDP_REG_CTL_LAYER_EXTN_OFFSET		0x40
#define MDSS_MDP_CTL_X_LAYER_5				0x24

/* mixer 5 has different offset than others */
#define MDSS_MDP_REG_CTL_LAYER(lm)	\
			((lm == 5) ? (0x024) : ((lm) * 0x004))
	(((lm) == 5) ? MDSS_MDP_CTL_X_LAYER_5 : ((lm) * 0x004))

#define MDSS_MDP_REG_CTL_LAYER_EXTN(lm)	\
		((lm == 5) ? (0x54) : (MDSS_MDP_REG_CTL_LAYER(lm) + 0x40))
	 (MDSS_MDP_REG_CTL_LAYER_EXTN_OFFSET + ((lm) * 0x004))

#define MDSS_MDP_REG_CTL_TOP				0x014
#define MDSS_MDP_REG_CTL_FLUSH				0x018
#define MDSS_MDP_REG_CTL_START				0x01C
#define MDSS_MDP_REG_CTL_PACK_3D			0x020
#define MDSS_MDP_REG_CTL_SW_RESET			0x030
#define MDSS_MDP_REG_CTL_LAYER_EXTN_OFFSET		0x40

#define MDSS_MDP_CTL_OP_VIDEO_MODE		(0 << 17)
#define MDSS_MDP_CTL_OP_CMD_MODE		(1 << 17)
@@ -361,10 +384,6 @@ enum mdss_mdp_sspp_chroma_samp_type {
#define MDSS_MDP_SCALEX_EN			BIT(0)
#define MDSS_MDP_FMT_SOLID_FILL			0x4037FF

#define MDSS_MDP_NUM_REG_MIXERS 3
#define MDSS_MDP_NUM_WB_MIXERS 2
#define MDSS_MDP_CTL_X_LAYER_5 0x24

#define MDSS_MDP_INTF_EDP_SEL	(BIT(3) | BIT(1))
#define MDSS_MDP_INTF_HDMI_SEL	(BIT(25) | BIT(24))
#define MDSS_MDP_INTF_DSI0_SEL	BIT(8)
+9 −22
Original line number Diff line number Diff line
@@ -1394,46 +1394,33 @@ static void mdss_mdp_pipe_free(struct kref *kref)
static bool mdss_mdp_check_pipe_in_use(struct mdss_mdp_pipe *pipe)
{
	int i;
	u32 mixercfg, mixercfg_extn, stage_off_mask, stage_off_extn_mask;
	u32 stage = BIT(0) | BIT(1) | BIT(2);
	bool in_use = false;
	struct mdss_data_type *mdata = mdss_mdp_get_mdata();
	struct mdss_mdp_ctl *ctl;
	struct mdss_mdp_mixer *mixer;

	stage_off_mask = mdss_mdp_get_mixer_mask(pipe->num, stage);
	stage_off_extn_mask = mdss_mdp_get_mixer_extn_mask(pipe->num, stage);

	for (i = 0; i < mdata->nctl; i++) {
		ctl = mdata->ctl_off + i;
		if (!ctl || !ctl->ref_cnt)
			continue;

		mixer = ctl->mixer_left;
		if (mixer && mixer->rotator_mode)
		if (!mixer || mixer->rotator_mode)
			continue;

		mixercfg = mdss_mdp_get_mixercfg(mixer, false);
		mixercfg_extn = mdss_mdp_get_mixercfg(mixer, true);
		if ((mixercfg & stage_off_mask) ||
			(mixercfg_extn & stage_off_extn_mask)) {
			pr_err("IN USE: mixer=%d pipe=%d mcfg:0x%x mask:0x%x mcfg_extn:0x%x mask_ext:0x%x\n",
				mixer->num, pipe->num,
				mixercfg, stage_off_mask,
				mixercfg_extn, stage_off_extn_mask);
		if (mdss_mdp_mixer_reg_has_pipe(mixer, pipe)) {
			in_use = true;
			pr_err("IN USE: pipe=%d mixer=%d\n",
					pipe->num, mixer->num);
			MDSS_XLOG_TOUT_HANDLER("mdp", "vbif", "vbif_nrt",
				"dbg_bus", "vbif_dbg_bus", "panic");
		}

		mixer = ctl->mixer_right;
		mixercfg = mdss_mdp_get_mixercfg(mixer, false);
		mixercfg_extn = mdss_mdp_get_mixercfg(mixer, true);
		if ((mixercfg & stage_off_mask) ||
			(mixercfg_extn & stage_off_extn_mask)) {
			pr_err("IN USE: mixer=%d pipe=%d mcfg:0x%x mask:0x%x mcfg_extn:0x%x mask_ext:0x%x\n",
				mixer->num, pipe->num,
				mixercfg, stage_off_mask,
				mixercfg_extn, stage_off_extn_mask);
		if (mixer && mdss_mdp_mixer_reg_has_pipe(mixer, pipe)) {
			in_use = true;
			pr_err("IN USE: pipe=%d mixer=%d\n",
					pipe->num, mixer->num);
			MDSS_XLOG_TOUT_HANDLER("mdp", "vbif", "vbif_nrt",
				"dbg_bus", "vbif_dbg_bus", "panic");
		}