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

Commit 83ee51cb authored by Nilaan Gunabalachandran's avatar Nilaan Gunabalachandran
Browse files

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



Store full or partial static image in system cache (L3 cache)
for video mode primary display. Added additional commit to
crtc commit thread to transition to read cache state.
The change also updates llcc APIs to support generic functionality.

Change-Id: I6b2a45da946d7e0e0b326da9d214be3f01a9420e
Signed-off-by: default avatarNilaan Gunabalachandran <ngunabal@codeaurora.org>
parent d423505a
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
@@ -1213,9 +1213,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
+91 −59
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)
{
@@ -751,7 +808,7 @@ static u64 _sde_core_perf_get_core_clk_rate(struct sde_kms *kms)

static void _sde_core_perf_crtc_update_check(struct drm_crtc *crtc,
		int params_changed,
		int *update_bus, int *update_clk, int *update_llcc)
		int *update_bus, int *update_clk)
{
	struct sde_kms *kms = _sde_crtc_get_kms(crtc);
	struct sde_crtc *sde_crtc = to_sde_crtc(crtc);
@@ -759,27 +816,6 @@ static void _sde_core_perf_crtc_update_check(struct drm_crtc *crtc,
	struct sde_core_perf_params *new = &sde_crtc->new_perf;
	int i;

	/*
	 * 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;
	}

	for (i = 0; i < SDE_POWER_HANDLE_DBUS_ID_MAX; i++) {
		/*
		 * cases for bus bandwidth update.
@@ -861,7 +897,7 @@ 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, update_llcc = 0;
	int update_bus = 0, update_clk = 0;
	u64 clk_rate = 0;
	struct sde_crtc *sde_crtc;
	struct sde_crtc_state *sde_cstate;
@@ -902,14 +938,13 @@ void sde_core_perf_crtc_update(struct drm_crtc *crtc,

	if (_sde_core_perf_crtc_is_power_on(crtc) && !stop_req) {
		_sde_core_perf_crtc_update_check(crtc, params_changed,
				&update_bus, &update_clk, &update_llcc);
				&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],
@@ -921,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);
+8 −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];
};

/**
@@ -94,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