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

Commit e35463ff authored by Krishna Chaitanya Devarakonda's avatar Krishna Chaitanya Devarakonda
Browse files

msm: mdss: add support for dedicated WB mixer



In some MDP revisions, the layermixer which is
attached to writeback block, is dedicated. It cannot
be used for interfaces. Adding support to take care
of mixer allocations for WB and rotator paths,
for such MDP hardware.

Change-Id: I9df51cf419c1dae3d2ce10597017a05dca1023a8
Signed-off-by: default avatarKrishna Chaitanya Devarakonda <kdevarak@codeaurora.org>
parent b6a638f8
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -165,6 +165,7 @@ enum mdss_hw_capabilities {
	MDSS_CAPS_YUV_CONFIG,
	MDSS_CAPS_SCM_RESTORE_NOT_REQUIRED,
	MDSS_CAPS_3D_MUX_UNDERRUN_RECOVERY_SUPPORTED,
	MDSS_CAPS_MIXER_1_FOR_WB,
	MDSS_CAPS_MAX,
};

+20 −7
Original line number Diff line number Diff line
@@ -1336,17 +1336,12 @@ static void mdss_mdp_hw_rev_caps_init(struct mdss_data_type *mdata)
		set_bit(MDSS_QOS_OTLIM, mdata->mdss_qos_map);
		break;
	case MDSS_MDP_HW_REV_114:
	case MDSS_MDP_HW_REV_115:
	case MDSS_MDP_HW_REV_116:
		mdata->max_target_zorder = 4; /* excluding base layer */
		mdata->max_cursor_size = 128;
		mdata->min_prefill_lines = 14;
		mdata->has_ubwc =
			(mdata->mdp_rev == MDSS_MDP_HW_REV_115) ?
			false : true;
		mdata->pixel_ram_size =
			(mdata->mdp_rev == MDSS_MDP_HW_REV_115) ?
			(16 * 1024) : (40 * 1024);
		mdata->has_ubwc = true;
		mdata->pixel_ram_size = 40 * 1024;
		mdata->apply_post_scale_bytes = false;
		mdata->hflip_buffer_reused = false;
		set_bit(MDSS_QOS_OVERHEAD_FACTOR, mdata->mdss_qos_map);
@@ -1359,6 +1354,24 @@ static void mdss_mdp_hw_rev_caps_init(struct mdss_data_type *mdata)
		mdss_set_quirk(mdata, MDSS_QUIRK_DMA_BI_DIR);
		mdss_set_quirk(mdata, MDSS_QUIRK_MIN_BUS_VOTE);
		break;
	case MDSS_MDP_HW_REV_115:
		mdata->max_target_zorder = 4; /* excluding base layer */
		mdata->max_cursor_size = 128;
		mdata->min_prefill_lines = 14;
		mdata->has_ubwc = false;
		mdata->pixel_ram_size = 16 * 1024;
		mdata->apply_post_scale_bytes = false;
		mdata->hflip_buffer_reused = false;
		set_bit(MDSS_QOS_CDP, mdata->mdss_qos_map);
		set_bit(MDSS_QOS_PER_PIPE_LUT, mdata->mdss_qos_map);
		set_bit(MDSS_QOS_SIMPLIFIED_PREFILL, mdata->mdss_qos_map);
		set_bit(MDSS_CAPS_YUV_CONFIG, mdata->mdss_caps_map);
		set_bit(MDSS_CAPS_MIXER_1_FOR_WB, mdata->mdss_caps_map);
		mdss_mdp_init_default_prefill_factors(mdata);
		set_bit(MDSS_QOS_OTLIM, mdata->mdss_qos_map);
		mdss_set_quirk(mdata, MDSS_QUIRK_DMA_BI_DIR);
		mdss_set_quirk(mdata, MDSS_QUIRK_MIN_BUS_VOTE);
		break;
	default:
		mdata->max_target_zorder = 4; /* excluding base layer */
		mdata->max_cursor_size = 64;
+3 −2
Original line number Diff line number Diff line
@@ -1110,7 +1110,8 @@ static inline int mdss_mdp_is_cdm_supported(struct mdss_data_type *mdata,
	 */
	return support && ((intf_type == MDSS_INTF_HDMI) ||
			   ((intf_type == MDSS_MDP_NO_INTF) &&
			    (mixer_type == MDSS_MDP_MIXER_TYPE_INTF)));
			    ((mixer_type == MDSS_MDP_MIXER_TYPE_INTF) ||
			     (mixer_type == MDSS_MDP_MIXER_TYPE_WRITEBACK))));
}

static inline u32 mdss_mdp_get_cursor_frame_size(struct mdss_data_type *mdata)
@@ -1496,7 +1497,7 @@ struct mdss_mdp_ctl *mdss_mdp_ctl_alloc(struct mdss_data_type *mdata,
					       u32 off);
int mdss_mdp_ctl_free(struct mdss_mdp_ctl *ctl);

struct mdss_mdp_mixer *mdss_mdp_mixer_assign(u32 id, bool wb);
struct mdss_mdp_mixer *mdss_mdp_mixer_assign(u32 id, bool wb, bool rot);
struct mdss_mdp_mixer *mdss_mdp_mixer_alloc(
		struct mdss_mdp_ctl *ctl, u32 type, int mux, int rotator);
int mdss_mdp_mixer_free(struct mdss_mdp_mixer *mixer);
+48 −14
Original line number Diff line number Diff line
@@ -52,6 +52,16 @@ 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;
@@ -74,28 +84,32 @@ static void __mdss_mdp_reset_mixercfg(struct mdss_mdp_ctl *ctl)

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 {
		return MDSS_MDP_REG_CTL_LAYER(mixer->num +
				MDSS_MDP_INTF_LAYERMIXER3);
		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 {
		return MDSS_MDP_REG_CTL_LAYER_EXTN(mixer->num +
				MDSS_MDP_INTF_LAYERMIXER3);
		wb_mixer_num = __mdss_mdp_get_wb_mixer(mixer);
		return MDSS_MDP_REG_CTL_LAYER_EXTN(wb_mixer_num);
	}
}

@@ -2220,6 +2234,8 @@ struct mdss_mdp_mixer *mdss_mdp_mixer_alloc(
	case MDSS_MDP_MIXER_TYPE_WRITEBACK:
		mixer_pool = ctl->mdata->mixer_wb;
		nmixers = nmixers_wb;
		if ((ctl->mdata->wfd_mode == MDSS_MDP_WFD_DEDICATED) && rotator)
			mixer_pool = mixer_pool + nmixers;
		break;

	default:
@@ -2257,14 +2273,16 @@ struct mdss_mdp_mixer *mdss_mdp_mixer_alloc(
	return mixer;
}

struct mdss_mdp_mixer *mdss_mdp_mixer_assign(u32 id, bool wb)
struct mdss_mdp_mixer *mdss_mdp_mixer_assign(u32 id, bool wb, bool rot)
{
	struct mdss_mdp_mixer *mixer = NULL;
	struct mdss_data_type *mdata = mdss_mdp_get_mdata();

	mutex_lock(&mdss_mdp_ctl_lock);

	if (wb && id < mdata->nmixers_wb)
	if (rot && (mdata->wfd_mode == MDSS_MDP_WFD_DEDICATED))
		mixer = mdata->mixer_wb + mdata->nmixers_wb;
	else if (wb && id < mdata->nmixers_wb)
		mixer = mdata->mixer_wb + id;
	else if (!wb && id < mdata->nmixers_intf)
		mixer = mdata->mixer_intf + id;
@@ -3022,6 +3040,11 @@ static int mdss_mdp_ctl_fbc_enable(int enable,

	fbc = &pdata->fbc;

	if (!fbc->enabled) {
		pr_debug("FBC not enabled\n");
		return -EINVAL;
	}

	if (mixer->num == MDSS_MDP_INTF_LAYERMIXER0 ||
			mixer->num == MDSS_MDP_INTF_LAYERMIXER1) {
		pr_debug("Mixer supports FBC.\n");
@@ -3780,17 +3803,23 @@ int mdss_mdp_ctl_stop(struct mdss_mdp_ctl *ctl, int power_state)

	if (ctl->ops.stop_fnc) {
		ret = ctl->ops.stop_fnc(ctl, power_state);
		if (ctl->panel_data->panel_info.compression_mode ==
				COMPRESSION_FBC) {
			mdss_mdp_ctl_fbc_enable(0, ctl->mixer_left,
					&ctl->panel_data->panel_info);
		}
	} else {
		pr_warn("no stop func for ctl=%d\n", ctl->num);
	}

	if (sctl && sctl->ops.stop_fnc) {
		ret = sctl->ops.stop_fnc(sctl, power_state);
		if (sctl->panel_data->panel_info.compression_mode ==
				COMPRESSION_FBC) {
			mdss_mdp_ctl_fbc_enable(0, sctl->mixer_left,
					&sctl->panel_data->panel_info);
		}
	}
	if (ret) {
		pr_warn("error powering off intf ctl=%d\n", ctl->num);
		goto end;
@@ -4299,12 +4328,17 @@ static void mdss_mdp_mixer_setup(struct mdss_mdp_ctl *master_ctl,
		mixercfg |= MDSS_MDP_LM_CURSOR_OUT;

update_mixer:
	if (mixer_hw->num == MDSS_MDP_INTF_LAYERMIXER3)
	if (mixer_hw->num == MDSS_MDP_INTF_LAYERMIXER3) {
		ctl_hw->flush_bits |= BIT(20);
	else if (mixer_hw->type == MDSS_MDP_MIXER_TYPE_WRITEBACK)
		ctl_hw->flush_bits |= BIT(9) << mixer_hw->num;
	} 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;
	}

	/* Read GC enable/disable status on LM */
	mixer_op_mode |=
+12 −2
Original line number Diff line number Diff line
/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2016, 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
@@ -826,6 +826,7 @@ int mdss_mdp_writeback_start(struct mdss_mdp_ctl *ctl)
	struct mdss_mdp_writeback *wb;
	u32 mem_sel;
	u32 mixer_type = MDSS_MDP_MIXER_TYPE_UNUSED;
	bool is_rot;

	pr_debug("start ctl=%d\n", ctl->num);

@@ -848,8 +849,17 @@ int mdss_mdp_writeback_start(struct mdss_mdp_ctl *ctl)
		return -EINVAL;
	}

	if (ctl->mixer_left)
	is_rot = (ctx->type == MDSS_MDP_WRITEBACK_TYPE_ROTATOR) ? true : false;

	if (ctl->mixer_left) {
		mixer_type = ctl->mixer_left->type;
		/*
		 * If the WB mixer is dedicated, the rotator uses a virtual
		 * mixer. Mark the mixer_type as UNUSED in such cases.
		 */
		if ((mixer_type == MDSS_MDP_MIXER_TYPE_WRITEBACK) && is_rot)
			mixer_type = MDSS_MDP_MIXER_TYPE_UNUSED;
	}

	if (mdss_mdp_is_cdm_supported(ctl->mdata, ctl->intf_type,
				mixer_type)) {
Loading