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

Commit dfc3e3dd authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "disp: msm: sde: add sys cache usage for static image"

parents 7928c8d0 83ee51cb
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -171,6 +171,7 @@ enum msm_mdp_crtc_property {
	CRTC_PROP_CAPTURE_OUTPUT,

	CRTC_PROP_IDLE_PC_STATE,
	CRTC_PROP_CACHE_STATE,

	/* total # of properties */
	CRTC_PROP_COUNT
+6 −1
Original line number Diff line number Diff line
@@ -1223,9 +1223,14 @@ int msm_gem_delayed_import(struct drm_gem_object *obj)
	if (msm_obj->flags & MSM_BO_SKIPSYNC)
		attach->dma_map_attrs |= DMA_ATTR_SKIP_CPU_SYNC;

	/*
	 * All SMMU mapping are generated with cache hint.
	 * SSPP cache hint will control the LLCC access.
	 */
	if (msm_obj->flags & MSM_BO_KEEPATTRS)
		attach->dma_map_attrs |=
				DMA_ATTR_IOMMU_USE_UPSTREAM_HINT;
				(DMA_ATTR_IOMMU_USE_UPSTREAM_HINT |
				DMA_ATTR_IOMMU_USE_LLC_NWA);

	/*
	 * dma_buf_map_attachment will call dma_map_sg for ion buffer
+3 −0
Original line number Diff line number Diff line
@@ -229,6 +229,9 @@ static int msm_smmu_map_dma_buf(struct msm_mmu *mmu, struct sg_table *sgt,
		return -ENOMEM;
	}

	if (flags & MSM_BO_KEEPATTRS)
		attrs |= DMA_ATTR_IOMMU_USE_LLC_NWA;

	/*
	 * For import buffer type, dma_map_sg_attrs is called during
	 * dma_buf_map_attachment and is not required to call again
+179 −127
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include "sde_trace.h"
#include "sde_crtc.h"
#include "sde_encoder.h"
#include "sde_hw_catalog.h"
#include "sde_core_perf.h"

#define SDE_PERF_MODE_STRING_SIZE	128
@@ -293,19 +294,20 @@ static inline enum sde_crtc_client_type _get_sde_client_type(
/**
 * @_sde_core_perf_activate_llcc() - Activates/deactivates the system llcc
 * @kms - pointer to the kms
 * @uid - ID for which the llcc would be activated
 * @type - llcc type to be activated
 * @activate - boolean to indicate if activate/deactivate the LLCC
 *
 * Function assumes that caller has already acquired the "sde_core_perf_lock",
 * which would protect from any race condition between CRTC's
 */
static int _sde_core_perf_activate_llcc(struct sde_kms *kms,
	u32 uid, bool activate)
	enum sde_sys_cache_type type, bool activate)
{
	struct llcc_slice_desc *slice;
	struct drm_device *drm_dev;
	struct device *dev;
	struct platform_device *pdev;
	u32 llcc_id[SDE_SYS_CACHE_MAX] = {LLCC_ROTATOR, LLCC_DISP};
	int rc = 0;

	if (!kms || !kms->dev || !kms->dev->dev) {
@@ -319,51 +321,57 @@ static int _sde_core_perf_activate_llcc(struct sde_kms *kms,
	pdev = to_platform_device(dev);

	/* If LLCC is already in the requested state, skip */
	SDE_EVT32(activate, kms->perf.llcc_active);
	if ((activate && kms->perf.llcc_active) ||
		(!activate && !kms->perf.llcc_active)) {
		SDE_DEBUG("skip llcc request:%d state:%d\n",
			activate, kms->perf.llcc_active);
	SDE_EVT32(activate, type, kms->perf.llcc_active[type]);
	if ((activate && kms->perf.llcc_active[type]) ||
		(!activate && !kms->perf.llcc_active[type])) {
		SDE_DEBUG("skip llcc type:%d request:%d state:%d\n",
			type, activate, kms->perf.llcc_active[type]);
		goto exit;
	}

	SDE_DEBUG("activate/deactivate the llcc request:%d state:%d\n",
		activate, kms->perf.llcc_active);
	SDE_DEBUG("%sactivate the llcc type:%d state:%d\n",
		activate ? "" : "de",
		type, kms->perf.llcc_active[type]);

	slice = llcc_slice_getd(uid);
	slice = llcc_slice_getd(llcc_id[type]);
	if (IS_ERR_OR_NULL(slice))  {
		SDE_ERROR("failed to get llcc slice for uid:%d\n", uid);
		SDE_ERROR("failed to get llcc slice for uid:%d\n",
				llcc_id[type]);
		rc = -EINVAL;
		goto exit;
	}

	if (activate) {
		llcc_slice_activate(slice);
		kms->perf.llcc_active = true;
		kms->perf.llcc_active[type] = true;
	} else {
		llcc_slice_deactivate(slice);
		kms->perf.llcc_active = false;
		kms->perf.llcc_active[type] = false;
	}

exit:
	if (rc)
		SDE_ERROR("error activating llcc:%d rc:%d\n",
			activate, rc);
		SDE_ERROR("error %sactivating llcc type:%d rc:%d\n",
			activate ? "" : "de", type, rc);
	return rc;

}

static void _sde_core_perf_crtc_update_llcc(struct sde_kms *kms,
		struct drm_crtc *crtc)
static void _sde_core_perf_crtc_set_llcc_cache_type(struct sde_kms *kms,
		struct drm_crtc *crtc,
		enum sde_sys_cache_type type)
{
	struct drm_crtc *tmp_crtc;
	struct sde_crtc *sde_crtc;
	struct sde_sc_cfg *sc_cfg = kms->perf.catalog->sc_cfg;
	struct sde_core_perf_params *cur_perf;
	enum sde_crtc_client_type curr_client_type
					= sde_crtc_get_client_type(crtc);
	u32 total_llcc_active = 0;
	u32 llcc_active = 0;

	if (!kms->perf.catalog->sc_cfg.has_sys_cache) {
		SDE_DEBUG("System Cache is not enabled!. Won't use\n");
	if (!sc_cfg[type].has_sys_cache) {
		SDE_DEBUG("System Cache %d is not enabled!. Won't use\n",
				type);
		return;
	}

@@ -374,23 +382,72 @@ static void _sde_core_perf_crtc_update_llcc(struct sde_kms *kms,

			/* use current perf, which are the values voted */
			sde_crtc = to_sde_crtc(tmp_crtc);
			total_llcc_active |=
			  sde_crtc->cur_perf.llcc_active;
			cur_perf = &sde_crtc->cur_perf;
			llcc_active |= cur_perf->llcc_active[type];

			SDE_DEBUG("crtc=%d llcc:%u active:0x%x\n",
				tmp_crtc->base.id,
				sde_crtc->cur_perf.llcc_active,
				total_llcc_active);
			SDE_DEBUG("crtc=%d type:%d llcc:%u active:0x%x\n",
				tmp_crtc->base.id, type,
				cur_perf->llcc_active[type],
				llcc_active);
		}
	}

			if (total_llcc_active)
				break;
	_sde_core_perf_activate_llcc(kms, type,
			llcc_active ? true : false);
}

void sde_core_perf_crtc_update_llcc(struct drm_crtc *crtc)
{
	struct sde_kms *kms;
	struct sde_crtc *sde_crtc;
	struct sde_core_perf_params *old, *new;
	int update_llcc[SDE_SYS_CACHE_MAX] = {0, 0};
	int i;

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

	_sde_core_perf_activate_llcc(kms, LLCC_ROTATOR,
			total_llcc_active ? true : false);
	kms = _sde_crtc_get_kms(crtc);
	if (!kms || !kms->catalog) {
		SDE_ERROR("invalid kms\n");
		return;
	}

	sde_crtc = to_sde_crtc(crtc);

	old = &sde_crtc->cur_perf;
	new = &sde_crtc->new_perf;

	mutex_lock(&sde_core_perf_lock);

	if (_sde_core_perf_crtc_is_power_on(crtc)) {
		for (i = 0; i < SDE_SYS_CACHE_MAX; i++) {
			if (new->llcc_active[i] != old->llcc_active[i]) {
				SDE_DEBUG("crtc=%d llcc=%d new=%d old=%d",
						crtc->base.id, i,
						new->llcc_active[i],
						old->llcc_active[i]);

					old->llcc_active[i] =
							new->llcc_active[i];
					update_llcc[i] = 1;
			}
		}
	} else {
		for (i = 0; i < SDE_SYS_CACHE_MAX; i++)
			update_llcc[i] = 1;
	}

	for (i = 0; i < SDE_SYS_CACHE_MAX; i++) {
		if (update_llcc[i])
			_sde_core_perf_crtc_set_llcc_cache_type(kms, crtc, i);
	}

	mutex_unlock(&sde_core_perf_lock);
};

static void _sde_core_uidle_setup_wd(struct sde_kms *kms,
	bool enable)
{
@@ -749,71 +806,15 @@ static u64 _sde_core_perf_get_core_clk_rate(struct sde_kms *kms)
	return clk_rate;
}

void sde_core_perf_crtc_update(struct drm_crtc *crtc,
		int params_changed, bool stop_req)
static void _sde_core_perf_crtc_update_check(struct drm_crtc *crtc,
		int params_changed,
		int *update_bus, int *update_clk)
{
	struct sde_core_perf_params *new, *old;
	int update_bus = 0, update_clk = 0, update_llcc = 0;
	u64 clk_rate = 0;
	struct sde_crtc *sde_crtc;
	struct sde_crtc_state *sde_cstate;
	int ret, i;
	struct msm_drm_private *priv;
	struct sde_kms *kms;

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

	kms = _sde_crtc_get_kms(crtc);
	if (!kms || !kms->catalog) {
		SDE_ERROR("invalid kms\n");
		return;
	}
	priv = kms->dev->dev_private;
	sde_crtc = to_sde_crtc(crtc);
	sde_cstate = to_sde_crtc_state(crtc->state);

	SDE_DEBUG("crtc:%d stop_req:%d core_clk:%llu\n",
			crtc->base.id, stop_req, kms->perf.core_clk_rate);

	mutex_lock(&sde_core_perf_lock);

	/*
	 * cache the performance numbers in the crtc prior to the
	 * crtc kickoff, so the same numbers are used during the
	 * perf update that happens post kickoff.
	 */
	if (params_changed)
		memcpy(&sde_crtc->new_perf, &sde_cstate->new_perf,
			sizeof(struct sde_core_perf_params));

	old = &sde_crtc->cur_perf;
	new = &sde_crtc->new_perf;

	if (_sde_core_perf_crtc_is_power_on(crtc) && !stop_req) {

		/*
		 * cases for the llcc update.
		 * 1. llcc is transitioning: 'inactive->active' during kickoff,
		 *	for current request.
		 * 2. llcc is transitioning: 'active->inactive'at the end of the
		 *	commit or during stop
		 */

		if ((params_changed &&
			 new->llcc_active && !old->llcc_active) ||
		    (!params_changed &&
			!new->llcc_active && old->llcc_active)) {

			SDE_DEBUG("crtc=%d p=%d new_llcc=%d, old_llcc=%d\n",
				crtc->base.id, params_changed,
				new->llcc_active, old->llcc_active);

			old->llcc_active = new->llcc_active;
			update_llcc = 1;
		}
	struct sde_kms *kms = _sde_crtc_get_kms(crtc);
	struct sde_crtc *sde_crtc = to_sde_crtc(crtc);
	struct sde_core_perf_params *old = &sde_crtc->cur_perf;
	struct sde_core_perf_params *new = &sde_crtc->new_perf;
	int i;

	for (i = 0; i < SDE_POWER_HANDLE_DBUS_ID_MAX; i++) {
		/*
@@ -834,7 +835,7 @@ void sde_core_perf_crtc_update(struct drm_crtc *crtc,
				crtc->base.id, params_changed,
				new->bw_ctl[i], old->bw_ctl[i]);
			old->bw_ctl[i] = new->bw_ctl[i];
				update_bus |= BIT(i);
			*update_bus |= BIT(i);
		}

		if ((params_changed &&
@@ -851,7 +852,7 @@ void sde_core_perf_crtc_update(struct drm_crtc *crtc,
				old->max_per_pipe_ib[i]);
			old->max_per_pipe_ib[i] =
					new->max_per_pipe_ib[i];
				update_bus |= BIT(i);
			*update_bus |= BIT(i);
		}

		/* display rsc override during solver mode */
@@ -866,31 +867,84 @@ void sde_core_perf_crtc_update(struct drm_crtc *crtc,
				old->bw_ctl[i] = new->bw_ctl[i];
				old->max_per_pipe_ib[i] =
						new->max_per_pipe_ib[i];
					update_bus |= BIT(i);
				*update_bus |= BIT(i);
			/*
			 * reduce bw vote is not required in solver
			 * mode
			 */
			} else if (!params_changed) {
					update_bus &= ~BIT(i);
				*update_bus &= ~BIT(i);
			}
		}
	}

	if (kms->perf.perf_tune.mode_changed &&
			kms->perf.perf_tune.min_core_clk)
		new->core_clk_rate = kms->perf.perf_tune.min_core_clk;

	if ((params_changed &&
			(new->core_clk_rate > old->core_clk_rate)) ||
			(!params_changed && new->core_clk_rate &&
				(new->core_clk_rate < old->core_clk_rate))) {
			(new->core_clk_rate < old->core_clk_rate)) ||
			kms->perf.perf_tune.mode_changed) {
		old->core_clk_rate = new->core_clk_rate;
			update_clk = 1;
		*update_clk = 1;
		kms->perf.perf_tune.mode_changed = false;
	}
}

void sde_core_perf_crtc_update(struct drm_crtc *crtc,
		int params_changed, bool stop_req)
{
	struct sde_core_perf_params *new, *old;
	int update_bus = 0, update_clk = 0;
	u64 clk_rate = 0;
	struct sde_crtc *sde_crtc;
	struct sde_crtc_state *sde_cstate;
	int ret, i;
	struct msm_drm_private *priv;
	struct sde_kms *kms;

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

	kms = _sde_crtc_get_kms(crtc);
	if (!kms || !kms->catalog) {
		SDE_ERROR("invalid kms\n");
		return;
	}
	priv = kms->dev->dev_private;
	sde_crtc = to_sde_crtc(crtc);
	sde_cstate = to_sde_crtc_state(crtc->state);

	SDE_DEBUG("crtc:%d stop_req:%d core_clk:%llu\n",
			crtc->base.id, stop_req, kms->perf.core_clk_rate);

	mutex_lock(&sde_core_perf_lock);

	/*
	 * cache the performance numbers in the crtc prior to the
	 * crtc kickoff, so the same numbers are used during the
	 * perf update that happens post kickoff.
	 */
	if (params_changed)
		memcpy(&sde_crtc->new_perf, &sde_cstate->new_perf,
			sizeof(struct sde_core_perf_params));

	old = &sde_crtc->cur_perf;
	new = &sde_crtc->new_perf;

	if (_sde_core_perf_crtc_is_power_on(crtc) && !stop_req) {
		_sde_core_perf_crtc_update_check(crtc, params_changed,
				&update_bus, &update_clk);
	} else {
		SDE_DEBUG("crtc=%d disable\n", crtc->base.id);
		memset(old, 0, sizeof(*old));
		memset(new, 0, sizeof(*new));
		update_bus = ~0;
		update_clk = 1;
		update_llcc = 1;
	}
	trace_sde_perf_crtc_update(crtc->base.id,
		new->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_MNOC],
@@ -902,9 +956,6 @@ void sde_core_perf_crtc_update(struct drm_crtc *crtc,
		new->core_clk_rate, stop_req,
		update_bus, update_clk, params_changed);

	if (update_llcc)
		_sde_core_perf_crtc_update_llcc(kms, crtc);

	for (i = 0; i < SDE_POWER_HANDLE_DBUS_ID_MAX; i++) {
		if (update_bus & BIT(i))
			_sde_core_perf_crtc_update_bus(kms, crtc, i);
@@ -1056,6 +1107,7 @@ static ssize_t _sde_core_perf_mode_write(struct file *file,
		DRM_INFO("normal performance mode\n");
	}
	perf->perf_tune.mode = perf_mode;
	perf->perf_tune.mode_changed = true;

	return count;
}
+10 −2
Original line number Diff line number Diff line
@@ -39,7 +39,7 @@ struct sde_core_perf_params {
	u64 max_per_pipe_ib[SDE_POWER_HANDLE_DBUS_ID_MAX];
	u64 bw_ctl[SDE_POWER_HANDLE_DBUS_ID_MAX];
	u64 core_clk_rate;
	bool llcc_active;
	bool llcc_active[SDE_SYS_CACHE_MAX];
};

/**
@@ -47,11 +47,13 @@ struct sde_core_perf_params {
 * @mode: performance mode
 * @min_core_clk: minimum core clock
 * @min_bus_vote: minimum bus vote
 * @mode_changed: indicate if clock tuning strategy changed
 */
struct sde_core_perf_tune {
	u32 mode;
	u64 min_core_clk;
	u64 min_bus_vote;
	bool mode_changed;
};

/**
@@ -92,10 +94,16 @@ struct sde_core_perf {
	u32 bw_vote_mode;
	bool sde_rsc_available;
	bool bw_vote_mode_updated;
	bool llcc_active;
	bool llcc_active[SDE_SYS_CACHE_MAX];
	bool uidle_enabled;
};

/**
 * sde_core_perf_crtc_update_llcc - update llcc performance for crtc
 * @crtc: Pointer to crtc
 */
void sde_core_perf_crtc_update_llcc(struct drm_crtc *crtc);

/**
 * sde_core_perf_crtc_check - validate performance of the given crtc state
 * @crtc: Pointer to crtc
Loading