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

Commit 2078a866 authored by Clarence Ip's avatar Clarence Ip Committed by Gerrit - the friendly Code Review server
Browse files

drm/msm/sde: delay inline rotation clock drops by one commit



Avoid acting on reduced rotator clocks for inline rotation
use cases until the next commit cycle. This allows the
hardware to complete the current commit using the previous,
higher, clock setting and avoids potential underruns due
to prematurely reduced rotator clock speeds.

Change-Id: If85905ef9a3f67dc71288aeabaf2b52d5dd5b768
Signed-off-by: default avatarClarence Ip <cip@codeaurora.org>
parent 9ca8558d
Loading
Loading
Loading
Loading
+39 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved.
 * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved.
 * Copyright (C) 2013 Red Hat
 * Author: Rob Clark <robdclark@gmail.com>
 *
@@ -1426,6 +1426,35 @@ static u32 _sde_crtc_calc_inline_prefill(struct drm_crtc *crtc)
	return sde_kms->catalog->sbuf_prefill + sde_kms->catalog->sbuf_headroom;
}

uint64_t sde_crtc_get_sbuf_clk(struct drm_crtc_state *state)
{
	struct sde_crtc_state *cstate;
	u64 tmp;

	if (!state) {
		SDE_ERROR("invalid crtc state\n");
		return 0;
	}
	cstate = to_sde_crtc_state(state);

	/*
	 * Select the max of the current and previous frame's user mode
	 * clock setting so that reductions in clock voting don't take effect
	 * until the current frame has completed.
	 *
	 * If the sbuf_clk_rate[] FIFO hasn't yet been updated in this commit
	 * cycle (as part of the CRTC's atomic check), compare the current
	 * clock value against sbuf_clk_rate[1] instead of comparing the
	 * sbuf_clk_rate[0]/sbuf_clk_rate[1] values.
	 */
	if (cstate->sbuf_clk_shifted)
		tmp = cstate->sbuf_clk_rate[0];
	else
		tmp = sde_crtc_get_property(cstate, CRTC_PROP_ROT_CLK);

	return max_t(u64, cstate->sbuf_clk_rate[1], tmp);
}

static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc,
		struct drm_crtc_state *old_state, struct sde_crtc *sde_crtc,
		struct sde_crtc_mixer *mixer)
@@ -4030,6 +4059,9 @@ static struct drm_crtc_state *sde_crtc_duplicate_state(struct drm_crtc *crtc)
	/* clear destination scaler dirty bit */
	cstate->ds_dirty = false;

	/* record whether or not the sbuf_clk_rate fifo has been shifted */
	cstate->sbuf_clk_shifted = false;

	/* duplicate base helper */
	__drm_atomic_helper_crtc_duplicate_state(crtc, &cstate->base);

@@ -4672,6 +4704,12 @@ static int sde_crtc_atomic_check(struct drm_crtc *crtc,
	_sde_crtc_setup_is_ppsplit(state);
	_sde_crtc_setup_lm_bounds(crtc, state);

	/* record current/previous sbuf clock rate for later */
	cstate->sbuf_clk_rate[0] = cstate->sbuf_clk_rate[1];
	cstate->sbuf_clk_rate[1] = sde_crtc_get_property(
			cstate, CRTC_PROP_ROT_CLK);
	cstate->sbuf_clk_shifted = true;

	 /* get plane state for all drm planes associated with crtc state */
	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, state) {
		if (IS_ERR_OR_NULL(pstate)) {
+13 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2015-2017 The Linux Foundation. All rights reserved.
 * Copyright (c) 2015-2018 The Linux Foundation. All rights reserved.
 * Copyright (C) 2013 Red Hat
 * Author: Rob Clark <robdclark@gmail.com>
 *
@@ -391,6 +391,9 @@ struct sde_crtc_respool {
 * @new_perf: new performance state being requested
 * @sbuf_cfg: stream buffer configuration
 * @sbuf_prefill_line: number of line for inline rotator prefetch
 * @sbuf_clk_rate : previous and current user specified inline rotator clock
 * @sbuf_clk_shifted : whether or not sbuf_clk_rate has been shifted as part
 *	of crtc atomic check
 */
struct sde_crtc_state {
	struct drm_crtc_state base;
@@ -422,6 +425,8 @@ struct sde_crtc_state {
	struct sde_core_perf_params new_perf;
	struct sde_ctl_sbuf_cfg sbuf_cfg;
	u32 sbuf_prefill_line;
	u64 sbuf_clk_rate[2];
	bool sbuf_clk_shifted;

	struct sde_crtc_respool rp;
};
@@ -769,4 +774,11 @@ void sde_crtc_timeline_status(struct drm_crtc *crtc);
void sde_crtc_update_cont_splash_mixer_settings(
		struct drm_crtc *crtc);

/**
 * sde_crtc_get_sbuf_clk - get user specified sbuf clock settings
 * @state: Pointer to DRM crtc state object
 * Returns: Filtered sbuf clock setting from user space
 */
uint64_t sde_crtc_get_sbuf_clk(struct drm_crtc_state *state);

#endif /* _SDE_CRTC_H_ */
+2 −3
Original line number Diff line number Diff line
/*
 * Copyright (C) 2014-2017 The Linux Foundation. All rights reserved.
 * Copyright (C) 2014-2018 The Linux Foundation. All rights reserved.
 * Copyright (C) 2013 Red Hat
 * Author: Rob Clark <robdclark@gmail.com>
 *
@@ -1857,8 +1857,7 @@ static int sde_plane_rot_submit_command(struct drm_plane *plane,

	rot_cmd->prefill_bw = sde_crtc_get_property(sde_cstate,
			CRTC_PROP_ROT_PREFILL_BW);
	rot_cmd->clkrate = sde_crtc_get_property(sde_cstate,
			CRTC_PROP_ROT_CLK);
	rot_cmd->clkrate = sde_crtc_get_sbuf_clk(cstate);
	rot_cmd->dst_writeback = psde->sbuf_writeback;

	if (sde_crtc_get_intf_mode(state->crtc) == INTF_MODE_VIDEO)