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

Commit 72ea3ec4 authored by Kalyan Thota's avatar Kalyan Thota Committed by Jayant Shekhar
Browse files

drm:msm:sde add support to handle 4 mixers per crtc



Extend the crtc to carry 4 mixers so as to handle
VR usecases, where each L/R config needs 2 mixers.

Change-Id: I74deb275ad4e3dc8a7bbf9d25e87cdf9f9b8f2e1
Signed-off-by: default avatarKalyan Thota <kalyant@codeaurora.org>
parent 83d88163
Loading
Loading
Loading
Loading
+27 −12
Original line number Diff line number Diff line
/*
 * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved.
 * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved.
 * Copyright (C) 2013 Red Hat
 * Author: Rob Clark <robdclark@gmail.com>
 *
@@ -1229,7 +1229,7 @@ static int _sde_crtc_check_rois_centered_and_symmetric(struct drm_crtc *crtc,
{
	struct sde_crtc *sde_crtc;
	struct sde_crtc_state *crtc_state;
	const struct sde_rect *roi[CRTC_DUAL_MIXERS];
	const struct sde_rect *roi[MAX_MIXERS_PER_CRTC];

	if (!crtc || !state)
		return -EINVAL;
@@ -1237,7 +1237,7 @@ static int _sde_crtc_check_rois_centered_and_symmetric(struct drm_crtc *crtc,
	sde_crtc = to_sde_crtc(crtc);
	crtc_state = to_sde_crtc_state(state);

	if (sde_crtc->num_mixers > CRTC_DUAL_MIXERS) {
	if (sde_crtc->num_mixers > MAX_MIXERS_PER_CRTC) {
		SDE_ERROR("%s: unsupported number of mixers: %d\n",
				sde_crtc->name, sde_crtc->num_mixers);
		return -EINVAL;
@@ -1429,7 +1429,7 @@ static void _sde_crtc_program_lm_output_roi(struct drm_crtc *crtc)
	struct sde_crtc_state *crtc_state;
	const struct sde_rect *lm_roi;
	struct sde_hw_mixer *hw_lm;
	int lm_idx, lm_horiz_position;
	int lm_idx;

	if (!crtc)
		return;
@@ -1437,7 +1437,6 @@ static void _sde_crtc_program_lm_output_roi(struct drm_crtc *crtc)
	sde_crtc = to_sde_crtc(crtc);
	crtc_state = to_sde_crtc_state(crtc->state);

	lm_horiz_position = 0;
	for (lm_idx = 0; lm_idx < sde_crtc->num_mixers; lm_idx++) {
		struct sde_hw_mixer_cfg cfg;

@@ -1452,11 +1451,10 @@ static void _sde_crtc_program_lm_output_roi(struct drm_crtc *crtc)

		hw_lm->cfg.out_width = lm_roi->w;
		hw_lm->cfg.out_height = lm_roi->h;
		hw_lm->cfg.right_mixer = lm_horiz_position;

		cfg.out_width = lm_roi->w;
		cfg.out_height = lm_roi->h;
		cfg.right_mixer = lm_horiz_position++;
		cfg.right_mixer = hw_lm->cfg.right_mixer;
		cfg.flags = 0;
		hw_lm->ops.setup_mixer_out(hw_lm, &cfg);
	}
@@ -1724,7 +1722,7 @@ static void _sde_crtc_blend_setup(struct drm_crtc *crtc,

	SDE_DEBUG("%s\n", sde_crtc->name);

	if (sde_crtc->num_mixers > CRTC_DUAL_MIXERS) {
	if (sde_crtc->num_mixers > MAX_MIXERS_PER_CRTC) {
		SDE_ERROR("invalid number mixers: %d\n", sde_crtc->num_mixers);
		return;
	}
@@ -2068,7 +2066,7 @@ static int _sde_validate_hw_resources(struct sde_crtc *sde_crtc)
	}

	if (!sde_crtc->num_mixers ||
		sde_crtc->num_mixers > CRTC_DUAL_MIXERS) {
		sde_crtc->num_mixers > MAX_MIXERS_PER_CRTC) {
		SDE_ERROR("%s: invalid number mixers: %d\n",
			sde_crtc->name, sde_crtc->num_mixers);
		SDE_EVT32(DRMID(&sde_crtc->base), sde_crtc->num_mixers,
@@ -2961,14 +2959,25 @@ static void _sde_crtc_setup_mixer_for_encoder(
	struct sde_rm *rm = &sde_kms->rm;
	struct sde_crtc_mixer *mixer;
	struct sde_hw_ctl *last_valid_ctl = NULL;
	int i;
	struct sde_rm_hw_iter lm_iter, ctl_iter, dspp_iter, ds_iter;
	u64 mixer_per_ctl = 0;
	u32 reuse_ctl = 0;
	int i;

	sde_rm_init_hw_iter(&lm_iter, enc->base.id, SDE_HW_BLK_LM);
	sde_rm_init_hw_iter(&ctl_iter, enc->base.id, SDE_HW_BLK_CTL);
	sde_rm_init_hw_iter(&dspp_iter, enc->base.id, SDE_HW_BLK_DSPP);
	sde_rm_init_hw_iter(&ds_iter, enc->base.id, SDE_HW_BLK_DS);

	reuse_ctl = sde_rm_get_hw_count(rm, enc->base.id, SDE_HW_BLK_CTL);
	mixer_per_ctl = sde_rm_get_hw_count(rm, enc->base.id, SDE_HW_BLK_LM);

	do_div(mixer_per_ctl, reuse_ctl);
	if (!mixer_per_ctl) {
		SDE_DEBUG("no valid lm/ctl count:%d\n", reuse_ctl);
		return;
	}
	reuse_ctl = 0;
	/* Set up all the mixers and ctls reserved by this encoder */
	for (i = sde_crtc->num_mixers; i < ARRAY_SIZE(sde_crtc->mixers); i++) {
		mixer = &sde_crtc->mixers[i];
@@ -2978,14 +2987,17 @@ static void _sde_crtc_setup_mixer_for_encoder(
		mixer->hw_lm = (struct sde_hw_mixer *)lm_iter.hw;

		/* CTL may be <= LMs, if <, multiple LMs controlled by 1 CTL */
		if (!sde_rm_get_hw(rm, &ctl_iter)) {
			SDE_DEBUG("no ctl assigned to lm %d, using previous\n",
		if (reuse_ctl || !sde_rm_get_hw(rm, &ctl_iter)) {
			SDE_DEBUG("no ctl assigned to lm %d using previous\n",
					mixer->hw_lm->idx - LM_0);
			mixer->hw_ctl = last_valid_ctl;
		} else {
			mixer->hw_ctl = (struct sde_hw_ctl *)ctl_iter.hw;
			last_valid_ctl = mixer->hw_ctl;
			reuse_ctl = mixer_per_ctl;
		}
		if (reuse_ctl)
			reuse_ctl--;

		/* Shouldn't happen, mixers are always >= ctls */
		if (!mixer->hw_ctl) {
@@ -2994,6 +3006,9 @@ static void _sde_crtc_setup_mixer_for_encoder(
			return;
		}

		mixer->hw_lm->cfg.right_mixer =
			(sde_crtc->num_mixers & 1) ? true : false;

		/* Dspp may be null */
		(void) sde_rm_get_hw(rm, &dspp_iter);
		mixer->hw_dspp = (struct sde_hw_dspp *)dspp_iter.hw;
+5 −6
Original line number Diff line number Diff line
@@ -230,7 +230,7 @@ struct sde_crtc {
	u32 num_ctls;
	u32 num_mixers;
	bool mixers_swapped;
	struct sde_crtc_mixer mixers[CRTC_DUAL_MIXERS];
	struct sde_crtc_mixer mixers[MAX_MIXERS_PER_CRTC];

	struct drm_pending_vblank_event *event;
	u32 vsync_count;
@@ -280,7 +280,7 @@ struct sde_crtc {
	spinlock_t event_lock;
	bool misr_enable;
	u32 misr_frame_count;
	u32 misr_data[CRTC_DUAL_MIXERS];
	u32 misr_data[MAX_MIXERS_PER_CRTC];

	bool enable_sui_enhancement;

@@ -405,8 +405,8 @@ struct sde_crtc_state {

	bool is_ppsplit;
	struct sde_rect crtc_roi;
	struct sde_rect lm_bounds[CRTC_DUAL_MIXERS];
	struct sde_rect lm_roi[CRTC_DUAL_MIXERS];
	struct sde_rect lm_bounds[MAX_MIXERS_PER_CRTC];
	struct sde_rect lm_roi[MAX_MIXERS_PER_CRTC];
	struct msm_roi_list user_roi_list;

	struct msm_property_state property_state;
@@ -483,8 +483,7 @@ static inline int sde_crtc_get_mixer_width(struct sde_crtc *sde_crtc,
	if (cstate->num_ds_enabled)
		mixer_width = cstate->ds_cfg[0].lm_width;
	else
		mixer_width = (sde_crtc->num_mixers == CRTC_DUAL_MIXERS ?
			mode->hdisplay / CRTC_DUAL_MIXERS : mode->hdisplay);
		mixer_width = mode->hdisplay / sde_crtc->num_mixers;

	return mixer_width;
}
+2 −2
Original line number Diff line number Diff line
/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2017-2019, 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
@@ -293,7 +293,7 @@ static int ad4_params_check(struct sde_hw_dspp *dspp,
	}

	if (!cfg->hw_cfg->num_of_mixers ||
	    cfg->hw_cfg->num_of_mixers > CRTC_DUAL_MIXERS) {
	    cfg->hw_cfg->num_of_mixers > MAX_MIXERS_PER_CRTC) {
		DRM_ERROR("invalid mixer cnt %d\n",
				cfg->hw_cfg->num_of_mixers);
		return -EINVAL;
+3 −3
Original line number Diff line number Diff line
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2019, 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
@@ -523,7 +523,7 @@ struct sde_prop_type mixer_blend_prop[] = {
static struct sde_prop_type mixer_prop[] = {
	{MIXER_OFF, "qcom,sde-mixer-off", true, PROP_TYPE_U32_ARRAY},
	{MIXER_LEN, "qcom,sde-mixer-size", false, PROP_TYPE_U32},
	{MIXER_PAIR_MASK, "qcom,sde-mixer-pair-mask", true,
	{MIXER_PAIR_MASK, "qcom,sde-mixer-pair-mask", false,
		PROP_TYPE_U32_ARRAY},
	{MIXER_BLOCKS, "qcom,sde-mixer-blocks", false, PROP_TYPE_NODE},
	{MIXER_DISP, "qcom,sde-mixer-display-pref", false,
@@ -1460,7 +1460,7 @@ static int sde_mixer_parse_dt(struct device_node *np,
			goto end;
		}
		mixer->sblk = sblk;

		mixer->lm_pair_mask = 0xFFFFFFFF;
		mixer->base = mixer_base;
		mixer->len = PROP_VALUE_ACCESS(prop_value, MIXER_LEN, 0);
		mixer->id = LM_0 + i;
+2 −1
Original line number Diff line number Diff line
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2019, 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
@@ -59,6 +59,7 @@
#define MAX_IMG_HEIGHT 0x3fff

#define CRTC_DUAL_MIXERS	2
#define MAX_MIXERS_PER_CRTC	4

#define SDE_COLOR_PROCESS_VER(MAJOR, MINOR) \
		((((MAJOR) & 0xFFFF) << 16) | (((MINOR) & 0xFFFF)))
Loading