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

Commit 55987b0d authored by Lloyd Atkinson's avatar Lloyd Atkinson Committed by Narendra Muppalla
Browse files

drm/msm/sde: dual pipe use case support



Add support for cases with two pipes, merged together via 3D mux
into one output display

Change-Id: Ic1e16af72e8cc45a8fd9ad706b37f5b69d30f0ef
Signed-off-by: default avatarLloyd Atkinson <latkinso@codeaurora.org>
parent a34014f7
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -238,6 +238,20 @@ struct sde_connector_state {
#define sde_connector_get_out_fb(S) \
	((S) ? to_sde_connector_state((S))->out_fb : 0)

/**
 * sde_connector_get_topology_name - helper accessor to retrieve topology_name
 * @connector: pointer to drm connector
 * Returns: value of the CONNECTOR_PROP_TOPOLOGY_NAME property or 0
 */
static inline uint64_t sde_connector_get_topology_name(
		struct drm_connector *connector)
{
	if (!connector || !connector->state)
		return 0;
	return sde_connector_get_property(connector->state,
			CONNECTOR_PROP_TOPOLOGY_NAME);
}

/**
 * sde_connector_init - create drm connector object for a given display
 * @dev: Pointer to drm device struct
+12 −7
Original line number Diff line number Diff line
@@ -350,6 +350,9 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc,
	if (!conn) {
		SDE_ERROR_ENC(sde_enc, "failed to find attached connector\n");
		return;
	} else if (!conn->state) {
		SDE_ERROR_ENC(sde_enc, "invalid connector state\n");
		return;
	}

	/* Reserve dynamic resources now. Indicating non-AtomicTest phase */
@@ -364,10 +367,13 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc,
	for (i = 0; i < sde_enc->num_phys_encs; i++) {
		struct sde_encoder_phys *phys = sde_enc->phys_encs[i];

		if (phys && phys->ops.mode_set)
		if (phys) {
			phys->connector = conn->state->connector;
			if (phys->ops.mode_set)
				phys->ops.mode_set(phys, mode, adj_mode);
		}
	}
}

static void sde_encoder_virt_enable(struct drm_encoder *drm_enc)
{
@@ -452,11 +458,10 @@ static void sde_encoder_virt_disable(struct drm_encoder *drm_enc)
	for (i = 0; i < sde_enc->num_phys_encs; i++) {
		struct sde_encoder_phys *phys = sde_enc->phys_encs[i];

		if (phys && phys->ops.disable && !phys->ops.is_master(phys)) {
		if (phys) {
			if (phys->ops.disable && !phys->ops.is_master(phys))
				phys->ops.disable(phys);

			atomic_set(&phys->vsync_cnt, 0);
			atomic_set(&phys->underrun_cnt, 0);
			phys->connector = NULL;
		}
	}

+16 −2
Original line number Diff line number Diff line
@@ -147,6 +147,7 @@ enum sde_intr_idx {
 *	tied to a specific panel / sub-panel. Abstract type, sub-classed by
 *	phys_vid or phys_cmd for video mode or command mode encs respectively.
 * @parent:		Pointer to the containing virtual encoder
 * @connector:		If a mode is set, cached pointer to the active connector
 * @ops:		Operations exposed to the virtual encoder
 * @parent_ops:		Callbacks exposed by the parent to the phys_enc
 * @hw_mdptop:		Hardware interface to the top registers
@@ -160,7 +161,6 @@ enum sde_intr_idx {
 * @intf_mode:		Interface mode
 * @intf_idx:		Interface index on sde hardware
 * @spin_lock:		Lock for IRQ purposes
 * @mode_3d:		3D mux configuration
 * @enable_state:	Enable state tracking
 * @vblank_refcount:	Reference count of vblank request
 * @vsync_cnt:		Vsync count for the physical encoder
@@ -168,6 +168,7 @@ enum sde_intr_idx {
 */
struct sde_encoder_phys {
	struct drm_encoder *parent;
	struct drm_connector *connector;
	struct sde_encoder_phys_ops ops;
	struct sde_encoder_virt_ops parent_ops;
	struct sde_hw_mdp *hw_mdptop;
@@ -180,7 +181,6 @@ struct sde_encoder_phys {
	enum sde_intf_mode intf_mode;
	enum sde_intf intf_idx;
	spinlock_t spin_lock;
	enum sde_3d_blend_mode mode_3d;
	enum sde_enc_enable_state enable_state;
	atomic_t vblank_refcount;
	atomic_t vsync_cnt;
@@ -338,4 +338,18 @@ void sde_encoder_phys_setup_cdm(struct sde_encoder_phys *phys_enc,
 */
void sde_encoder_helper_trigger_start(struct sde_encoder_phys *phys_enc);


static inline enum sde_3d_blend_mode sde_encoder_helper_get_3d_blend_mode(
		struct sde_encoder_phys *phys_enc)
{
	enum sde_rm_topology_name topology;

	topology = sde_connector_get_topology_name(phys_enc->connector);
	if (phys_enc->split_role == ENC_ROLE_SOLO &&
			topology == SDE_RM_TOPOLOGY_DUALPIPEMERGE)
		return BLEND_3D_H_ROW_INT;

	return BLEND_3D_NONE;
}

#endif /* __sde_encoder_phys_H__ */
+2 −2
Original line number Diff line number Diff line
@@ -341,9 +341,10 @@ static void sde_encoder_phys_cmd_pingpong_config(
	drm_mode_debug_printmodeline(&phys_enc->cached_mode);

	intf_cfg.intf = cmd_enc->intf_idx;
	intf_cfg.mode_3d = phys_enc->mode_3d;
	intf_cfg.intf_mode_sel = SDE_CTL_MODE_SEL_CMD;
	intf_cfg.stream_sel = cmd_enc->stream_sel;
	intf_cfg.mode_3d = sde_encoder_helper_get_3d_blend_mode(phys_enc);

	phys_enc->hw_ctl->ops.setup_intf_cfg(phys_enc->hw_ctl, &intf_cfg);

	sde_encoder_phys_cmd_tearcheck_config(phys_enc);
@@ -649,7 +650,6 @@ struct sde_encoder_phys *sde_encoder_phys_cmd_init(
	phys_enc->split_role = p->split_role;
	phys_enc->intf_mode = INTF_MODE_CMD;
	spin_lock_init(&phys_enc->spin_lock);
	phys_enc->mode_3d = BLEND_3D_NONE;
	cmd_enc->stream_sel = 0;
	phys_enc->enable_state = SDE_ENC_DISABLED;
	atomic_set(&cmd_enc->pending_cnt, 0);
+1 −7
Original line number Diff line number Diff line
@@ -286,10 +286,9 @@ static void sde_encoder_phys_vid_setup_timing_engine(
	SDE_DEBUG_VIDENC(vid_enc, "fmt_fourcc 0x%X\n", fmt_fourcc);

	intf_cfg.intf = vid_enc->hw_intf->idx;
	intf_cfg.wb = SDE_NONE;
	intf_cfg.mode_3d = phys_enc->mode_3d;
	intf_cfg.intf_mode_sel = SDE_CTL_MODE_SEL_VID;
	intf_cfg.stream_sel = 0; /* Don't care value for video mode */
	intf_cfg.mode_3d = sde_encoder_helper_get_3d_blend_mode(phys_enc);

	spin_lock_irqsave(&phys_enc->spin_lock, lock_flags);
	vid_enc->hw_intf->ops.setup_timing_gen(vid_enc->hw_intf,
@@ -802,11 +801,6 @@ struct sde_encoder_phys *sde_encoder_phys_vid_init(
	spin_lock_init(&phys_enc->spin_lock);
	init_completion(&vid_enc->vblank_completion);
	atomic_set(&phys_enc->vblank_refcount, 0);

	DRM_INFO_ONCE("intf %d: 3d blend modes not yet supported\n",
			vid_enc->hw_intf->idx);
	phys_enc->mode_3d = BLEND_3D_NONE;

	phys_enc->enable_state = SDE_ENC_DISABLED;

	SDE_DEBUG_VIDENC(vid_enc, "created intf idx:%d\n", p->intf_idx);
Loading