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

Commit 471dced0 authored by Xiaowen Wu's avatar Xiaowen Wu
Browse files

drm/msm/shp: add shared plane support



Create a driver to create shared planes to SDE driver. In DRM lease
plane can't be passed from one master to another master seamlessly,
and plane resource will be wasted if one plane has finished its
lifecycle in one master and couldn't be used by another master
when they're both running.

A shared plane model is introduced by creating multiple virtual
planes from the physical plane. Only one virtual plane (including
the physical one) can be activated at a time. When handoff from one
master to another master is needed, the previous active plane will
be detached and the new plane will be activated in the same atomic
commit.

Change-Id: I26d2ab574783af8d4c0a751bfd82642be97280fc
Signed-off-by: default avatarXiaowen Wu <wxiaowen@codeaurora.org>
parent 12334a72
Loading
Loading
Loading
Loading
+40 −0
Original line number Diff line number Diff line
QTI Snapdragon Display Engine (SDE) shared plane

This driver allows to create multiple virtual planes from the same
physical plane. Only one plane can be activated at a time.

Required properties:
- compatible:		"qcom,sde-shared-plane"
- qcom,add-planes:	Shared planes to add to the DRM system. Each child
			represents a new plane, which has the properties of:
	qcom,plane-parent: required string, name of parent plane
			where this plane is created from.
	qcom,plane-name: required string, name of the new plane.
	qcom,plane-virt-name: optional string, name of the new multi-rect plane.
	qcom,plane-init-handoff: optional boolean, if set, the plane is inited
			to handoff state at system bootup.
	qcom,plane-init-active: optional boolean, if set, the plane is inited to
			active state at system bootup.
	qcom,plane-detach-handoff: optional boolean, if set, the plane is set to
			handoff state whenever it is detached.


Example:

/ {
	...

	qcom,sde-shared-plane {
		compatible = "qcom,sde-shared-plane";
		qcom,add-planes {
			plane@0 {
				qcom,plane-name = "plane-0-splash";
				qcom,plane-parent = "plane-0";
			};
			plane@1 {
				qcom,plane-name = "plane-1-splash";
				qcom,plane-parent = "plane-1";
			};
		};
	};
};
+10 −0
Original line number Diff line number Diff line
@@ -162,6 +162,16 @@ config DRM_SDE_SHD
	  Each logical display will appear as different
	  connectors and report back to user.

config DRM_SDE_SHP
	bool "Enable Shared plane support in SDE DRM"
	depends on DRM_MSM
	help
	  Choose this option for shared plane support.
	  This option enables multiple logical planes
	  to share one base physical plane hardware.
	  Each logical plane will appear as different
	  planes and report back to user.

config DRM_MSM_DSI_14NM_PHY
	bool "Enable DSI 14nm PHY driver in MSM DRM (used by MSM8996/APQ8096)"
	depends on DRM_MSM_DSI
+3 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ ccflags-y += -Idrivers/gpu/drm/msm/sde
ccflags-y += -Idrivers/media/platform/msm/sde/rotator
ccflags-y += -Idrivers/gpu/drm/msm/hdmi
ccflags-$(CONFIG_DRM_SDE_SHD) += -Idrivers/gpu/drm/msm/shd
ccflags-$(CONFIG_DRM_SDE_SHP) += -Idrivers/gpu/drm/msm/shp

msm_drm-y := \
	dp/dp_usbpd.o \
@@ -193,6 +194,8 @@ msm_drm-$(CONFIG_DRM_SDE_SHD) += shd/shd_drm.o \
	shd/shd_hw.o \
	shd/sde_encoder_phys_shd.o

msm_drm-$(CONFIG_DRM_SDE_SHP) += shp/shp_drm.o

msm_drm-$(CONFIG_DRM_MSM) += \
	msm_atomic.o \
	msm_drv.o \
+59 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@
#include "sde_crtc.h"
#include "sde_plane.h"
#include "shd_drm.h"
#include "shd_hw.h"

static LIST_HEAD(g_base_list);

@@ -478,6 +479,64 @@ static int shd_crtc_atomic_set_property(struct drm_crtc *crtc,
		state, property, val);
}

u32 shd_get_shared_crtc_mask(struct drm_crtc *src_crtc)
{
	struct shd_crtc *shd_src_crtc, *shd_crtc;
	struct drm_crtc *crtc;
	u32 crtc_mask = 0;

	if (!src_crtc)
		return 0;

	if (src_crtc->helper_private->atomic_check != shd_crtc_atomic_check)
		return drm_crtc_mask(src_crtc);

	shd_src_crtc = to_sde_crtc(src_crtc)->priv_handle;

	drm_for_each_crtc(crtc, src_crtc->dev) {
		if (crtc->helper_private->atomic_check !=
				shd_crtc_atomic_check)
			continue;

		shd_crtc = to_sde_crtc(crtc)->priv_handle;

		if (shd_src_crtc->display->base == shd_crtc->display->base)
			crtc_mask |= drm_crtc_mask(crtc);
	}

	return crtc_mask;
}

void shd_skip_shared_plane_update(struct drm_plane *plane,
		struct drm_crtc *crtc)
{
	struct sde_crtc *sde_crtc;
	struct shd_crtc *shd_crtc;
	enum sde_sspp sspp;
	bool is_virtual;
	int i;

	if (!plane || !crtc) {
		SDE_ERROR("invalid plane or crtc\n");
		return;
	}

	if (crtc->funcs->atomic_set_property !=
		shd_crtc_atomic_set_property) {
		SDE_ERROR("not shared crtc\n");
		return;
	}

	sde_crtc = to_sde_crtc(crtc);
	shd_crtc = sde_crtc->priv_handle;
	sspp = sde_plane_pipe(plane);
	is_virtual = is_sde_plane_virtual(plane);

	for (i = 0; i < sde_crtc->num_ctls; i++)
		sde_shd_hw_skip_sspp_clear(
			sde_crtc->mixers[i].hw_ctl, sspp, is_virtual);
}

static void shd_display_prepare_commit(struct msm_kms *kms,
		struct drm_atomic_state *state)
{
+4 −0
Original line number Diff line number Diff line
@@ -80,5 +80,9 @@ void drm_minor_release(struct drm_minor *minor);
void *sde_encoder_phys_shd_init(enum sde_intf_type type,
			u32 controller_id, void *phys_init_params);

/* helper for seamless plane handoff */
u32 shd_get_shared_crtc_mask(struct drm_crtc *crtc);
void shd_skip_shared_plane_update(struct drm_plane *plane,
			struct drm_crtc *crtc);

#endif /* _SHD_DRM_H_ */
Loading