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

Commit c79eb49f authored by Kyle Yan's avatar Kyle Yan Committed by Gerrit - the friendly Code Review server
Browse files

Merge "drm/msm/sde: enable display and apps rsc voting" into msm-4.9

parents 4f3179eb 82c8dbcc
Loading
Loading
Loading
Loading
+19 −1
Original line number Diff line number Diff line
@@ -867,10 +867,12 @@ static void sde_crtc_atomic_begin(struct drm_crtc *crtc,
static void sde_crtc_atomic_flush(struct drm_crtc *crtc,
		struct drm_crtc_state *old_crtc_state)
{
	struct drm_encoder *encoder;
	struct sde_crtc *sde_crtc;
	struct drm_device *dev;
	struct drm_plane *plane;
	unsigned long flags;
	struct sde_crtc_state *cstate;

	if (!crtc) {
		SDE_ERROR("invalid crtc\n");
@@ -886,7 +888,7 @@ static void sde_crtc_atomic_flush(struct drm_crtc *crtc,
	SDE_DEBUG("crtc%d\n", crtc->base.id);

	sde_crtc = to_sde_crtc(crtc);

	cstate = to_sde_crtc_state(crtc->state);
	dev = crtc->dev;

	if (sde_crtc->event) {
@@ -908,6 +910,17 @@ static void sde_crtc_atomic_flush(struct drm_crtc *crtc,
	/* wait for acquire fences before anything else is done */
	_sde_crtc_wait_for_fences(crtc);

	if (!cstate->rsc_update) {
		drm_for_each_encoder(encoder, dev) {
			if (encoder->crtc != crtc)
				continue;

			cstate->rsc_client =
				sde_encoder_update_rsc_client(encoder, true);
		}
		cstate->rsc_update = true;
	}

	/* update performance setting before crtc kickoff */
	sde_core_perf_crtc_update(crtc, 1, false);

@@ -1078,6 +1091,7 @@ static void sde_crtc_disable(struct drm_crtc *crtc)
{
	struct msm_drm_private *priv;
	struct sde_crtc *sde_crtc;
	struct sde_crtc_state *cstate;
	struct drm_encoder *encoder;
	struct sde_kms *sde_kms;

@@ -1086,6 +1100,7 @@ static void sde_crtc_disable(struct drm_crtc *crtc)
		return;
	}
	sde_crtc = to_sde_crtc(crtc);
	cstate = to_sde_crtc_state(crtc->state);
	sde_kms = _sde_crtc_get_kms(crtc);
	priv = sde_kms->dev->dev_private;

@@ -1122,6 +1137,9 @@ static void sde_crtc_disable(struct drm_crtc *crtc)
		if (encoder->crtc != crtc)
			continue;
		sde_encoder_register_frame_event_callback(encoder, NULL, NULL);
		sde_encoder_update_rsc_client(encoder, false);
		cstate->rsc_client = NULL;
		cstate->rsc_update = false;
	}

	memset(sde_crtc->mixers, 0, sizeof(sde_crtc->mixers));
+8 −5
Original line number Diff line number Diff line
@@ -151,7 +151,6 @@ struct sde_crtc {
 * @connectors    : Currently associated drm connectors
 * @num_connectors: Number of associated drm connectors
 * @intf_mode     : Interface mode of the primary connector
 * @rsc_mode      : Client vote through sde rsc
 * @rsc_client    : sde rsc client when mode is valid
 * @property_values: Current crtc property values
 * @input_fence_timeout_ns : Cached input fence timeout, in ns
@@ -167,8 +166,8 @@ struct sde_crtc_state {
	struct drm_connector *connectors[MAX_CONNECTORS];
	int num_connectors;
	enum sde_intf_mode intf_mode;
	bool rsc_mode;
	struct sde_rsc_client *rsc_client;
	bool rsc_update;

	uint64_t property_values[CRTC_PROP_COUNT];
	uint64_t input_fence_timeout_ns;
@@ -286,13 +285,17 @@ static inline enum sde_intf_mode sde_crtc_get_intf_mode(struct drm_crtc *crtc)
 * sde_crtc_get_client_type - check the crtc type- rt, nrt, rsc, etc.
 * @crtc: Pointer to crtc
 */
static inline bool sde_crtc_get_client_type(struct drm_crtc *crtc)
static inline enum sde_crtc_client_type sde_crtc_get_client_type(
						struct drm_crtc *crtc)
{
	struct sde_crtc_state *cstate =
			crtc ? to_sde_crtc_state(crtc->state) : NULL;

	return cstate && (cstate->intf_mode == INTF_MODE_WB_LINE) ? NRT_CLIENT
		: cstate && cstate->rsc_mode ? RT_RSC_CLIENT : RT_CLIENT;
	if (!cstate)
		return NRT_CLIENT;

	return cstate->rsc_client ? RT_RSC_CLIENT :
	    (cstate->intf_mode == INTF_MODE_WB_LINE ? NRT_CLIENT : RT_CLIENT);
}

/**
+47 −42
Original line number Diff line number Diff line
@@ -117,6 +117,7 @@ struct sde_encoder_virt {

	struct sde_rsc_client *rsc_client;
	struct msm_display_info disp_info;
	bool rsc_state_update;
};

#define to_sde_encoder_virt(x) container_of(x, struct sde_encoder_virt, base)
@@ -375,8 +376,7 @@ static void sde_encoder_virt_enable(struct drm_encoder *drm_enc)
	struct sde_encoder_virt *sde_enc = NULL;
	struct msm_drm_private *priv;
	struct sde_kms *sde_kms;
	int i = 0, ret;
	enum sde_rsc_state rsc_state;
	int i = 0;

	if (!drm_enc) {
		SDE_ERROR("invalid encoder\n");
@@ -399,8 +399,6 @@ static void sde_encoder_virt_enable(struct drm_encoder *drm_enc)
	sde_power_resource_enable(&priv->phandle, sde_kms->core_client, true);

	sde_enc->cur_master = NULL;
	rsc_state = sde_enc->disp_info.capabilities & MSM_DISPLAY_CAP_CMD_MODE ?
				SDE_RSC_CMD_STATE : SDE_RSC_VID_STATE;

	for (i = 0; i < sde_enc->num_phys_encs; i++) {
		struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
@@ -423,19 +421,6 @@ static void sde_encoder_virt_enable(struct drm_encoder *drm_enc)
		SDE_ERROR("virt encoder has no master! num_phys %d\n", i);
	else if (sde_enc->cur_master->ops.enable)
		sde_enc->cur_master->ops.enable(sde_enc->cur_master);

	/**
	 * this should be after interface enable because interface enable api
	 * turns on panel, configure the TE for command mode and turns on
	 * timing engine for video mode. The RSC api call is going to wait
	 * for vsync after it switches the mode - that requires te/timing engine
	 * enabled.
	 */
	ret = sde_rsc_client_state_update(sde_enc->rsc_client, rsc_state, NULL,
			drm_enc->crtc ? drm_enc->crtc->index : -1);
	if (ret)
		SDE_ERROR("sde rsc client update failed ret:%d\n", ret);

}

static void sde_encoder_virt_disable(struct drm_encoder *drm_enc)
@@ -487,8 +472,6 @@ static void sde_encoder_virt_disable(struct drm_encoder *drm_enc)

	sde_rm_release(&sde_kms->rm, drm_enc);

	sde_rsc_client_state_update(sde_enc->rsc_client, SDE_RSC_IDLE_STATE,
						NULL, -1);
	sde_power_resource_enable(&priv->phandle, sde_kms->core_client, false);
}

@@ -586,6 +569,49 @@ void sde_encoder_register_vblank_callback(struct drm_encoder *drm_enc,
	}
}

struct sde_rsc_client *sde_encoder_update_rsc_client(
		struct drm_encoder *drm_enc, bool enable)
{
	struct sde_encoder_virt *sde_enc;
	enum sde_rsc_state rsc_state;
	struct sde_rsc_cmd_config rsc_config;
	int ret;

	if (!drm_enc) {
		SDE_ERROR("invalid encoder\n");
		return NULL;
	}

	sde_enc = to_sde_encoder_virt(drm_enc);
	if (!sde_enc->disp_info.is_primary)
		return NULL;

	rsc_state = enable ?
		(sde_enc->disp_info.capabilities & MSM_DISPLAY_CAP_CMD_MODE ?
		SDE_RSC_CMD_STATE : SDE_RSC_VID_STATE) : SDE_RSC_IDLE_STATE;

	if (rsc_state != SDE_RSC_IDLE_STATE && !sde_enc->rsc_state_update) {
		rsc_config.fps = sde_enc->disp_info.frame_rate;
		rsc_config.vtotal = sde_enc->disp_info.vtotal;
		rsc_config.prefill_lines = sde_enc->disp_info.prefill_lines;
		rsc_config.jitter = sde_enc->disp_info.jitter;
		sde_enc->rsc_state_update = true;

		ret = sde_rsc_client_state_update(sde_enc->rsc_client,
			rsc_state, &rsc_config,
			drm_enc->crtc ? drm_enc->crtc->index : -1);
	} else {
		ret = sde_rsc_client_state_update(sde_enc->rsc_client,
			rsc_state, NULL,
			drm_enc->crtc ? drm_enc->crtc->index : -1);
	}

	if (ret)
		SDE_ERROR("sde rsc client update failed ret:%d\n", ret);

	return sde_enc->rsc_client;
}

void sde_encoder_register_frame_event_callback(struct drm_encoder *drm_enc,
		void (*frame_event_cb)(void *, u32 event),
		void *frame_event_cb_data)
@@ -848,7 +874,6 @@ void sde_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc)
	struct sde_encoder_phys *phys;
	bool needs_hw_reset = false;
	unsigned int i;
	int ret;

	if (!drm_enc) {
		SDE_ERROR("invalid encoder\n");
@@ -859,14 +884,6 @@ void sde_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc)
	SDE_DEBUG_ENC(sde_enc, "\n");
	SDE_EVT32(DRMID(drm_enc));

	if (sde_enc->disp_info.is_primary) {
		ret = sde_rsc_client_vote(sde_enc->rsc_client,
			SDE_POWER_HANDLE_DATA_BUS_IB_QUOTA,
			SDE_POWER_HANDLE_DATA_BUS_AB_QUOTA);
		if (ret)
			SDE_ERROR("sde rsc client vote failed ret:%d\n", ret);
	}

	/* prepare for next kickoff, may include waiting on previous kickoff */
	for (i = 0; i < sde_enc->num_phys_encs; i++) {
		phys = sde_enc->phys_encs[i];
@@ -1380,6 +1397,7 @@ struct drm_encoder *sde_encoder_init(
						PTR_ERR(sde_enc->rsc_client));
		sde_enc->rsc_client = NULL;
	}

	memcpy(&sde_enc->disp_info, disp_info, sizeof(*disp_info));

	SDE_DEBUG_ENC(sde_enc, "created\n");
@@ -1446,16 +1464,3 @@ enum sde_intf_mode sde_encoder_get_intf_mode(struct drm_encoder *encoder)

	return INTF_MODE_NONE;
}

bool sde_encoder_get_intf_primary(struct drm_encoder *encoder)
{
	struct sde_encoder_virt *sde_enc = NULL;

	if (!encoder) {
		SDE_ERROR("invalid encoder\n");
		return INTF_MODE_NONE;
	}
	sde_enc = to_sde_encoder_virt(encoder);

	return sde_enc->disp_info.is_primary;
}
+9 −6
Original line number Diff line number Diff line
@@ -72,6 +72,15 @@ void sde_encoder_register_vblank_callback(struct drm_encoder *encoder,
void sde_encoder_register_frame_event_callback(struct drm_encoder *encoder,
		void (*cb)(void *, u32), void *data);

/**
 * sde_encoder_update_rsc_client - updates the rsc client state for primary
 *      for primary display.
 * @encoder:	encoder pointer
 * @enable:	enable/disable the client
 */
struct sde_rsc_client *sde_encoder_update_rsc_client(
		struct drm_encoder *encoder, bool enable);

/**
 * sde_encoder_prepare_for_kickoff - schedule double buffer flip of the ctl
 *	path (i.e. ctl flush and start) at next appropriate time.
@@ -104,12 +113,6 @@ int sde_encoder_wait_for_commit_done(struct drm_encoder *drm_encoder);
 */
enum sde_intf_mode sde_encoder_get_intf_mode(struct drm_encoder *encoder);

/*
 * sde_encoder_get_intf_primary - is primary display connected with encoder
 * @encoder: Pointer to drm encoder object
 */
bool sde_encoder_get_intf_primary(struct drm_encoder *encoder);

/**
 * sde_encoder_init - initialize virtual encoder object
 * @dev:        Pointer to drm device structure
+1 −1
Original line number Diff line number Diff line
@@ -2687,7 +2687,7 @@ struct drm_plane *sde_plane_init(struct drm_device *dev,

	_sde_plane_init_debugfs(psde, kms);

	DRM_INFO("%s created for pipe %u\n", psde->pipe_name, pipe);
	SDE_DEBUG("%s created for pipe %u\n", psde->pipe_name, pipe);
	return plane;

clean_sspp:
Loading