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

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

Merge "ARM: dts: msm: Add regs offsets for uidle feature for Kona"

parents 5e281f4d 1a82bbcd
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -194,6 +194,9 @@ Optional properties:
				vbif blocks. These offsets will be calculated from
				register "vbif_phys" defined in reg property.
- qcom,sde-vbif-size:		A u32 value indicates the vbif block address range.
- qcom,sde-uidle-off:           A u32 value with the offset for the uidle
                                block, from the "mdp_phys".
- qcom,sde-uidle-size:          A u32 value indicates the uidle block address range.
- qcom,sde-te-off:		A u32 offset indicates the te block offset on pingpong.
				This offset is 0x0 by default.
- qcom,sde-te2-off:		A u32 offset indicates the te2 block offset on pingpong.
@@ -683,6 +686,9 @@ Example:
    qcom,sde-vbif-memtype-0 = <3 3 3 3 3 3 3 3>;
    qcom,sde-vbif-memtype-1 = <3 3 3 3 3 3>;

    qcom,sde-uidle-off = <0x80000>;
    qcom,sde-uidle-size = <0x70>;

    qcom,sde-dram-channels = <2>;
    qcom,sde-num-nrt-paths = <1>;

+3 −0
Original line number Diff line number Diff line
@@ -152,6 +152,9 @@
		/* offsets are based off dspp 0 and dspp 1 */
		qcom,sde-dspp-ltm-off = <0x2a000 0x28100>;

		qcom,sde-uidle-off = <0x80000>;
		qcom,sde-uidle-size = <0x70>;

		qcom,sde-vbif-off = <0>;
		qcom,sde-vbif-size = <0x1040>;
		qcom,sde-vbif-id = <0>;
+1 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ msm_drm-$(CONFIG_DRM_MSM_SDE) += sde/sde_crtc.o \
	sde/sde_hw_reg_dma_v1_color_proc.o \
	sde/sde_hw_color_proc_v4.o \
	sde/sde_hw_ad4.o \
	sde/sde_hw_uidle.o \
	sde_edid_parser.o \
	sde_hdcp_1x.o \
	sde_hdcp_2x.o
+168 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include "sde_kms.h"
#include "sde_trace.h"
#include "sde_crtc.h"
#include "sde_encoder.h"
#include "sde_core_perf.h"

#define SDE_PERF_MODE_STRING_SIZE	128
@@ -400,6 +401,173 @@ static void _sde_core_perf_crtc_update_llcc(struct sde_kms *kms,
			total_llcc_active ? true : false);
}

static void _sde_core_uidle_setup_wd(struct sde_kms *kms,
	bool enable)
{
	struct sde_uidle_wd_cfg wd;
	struct sde_hw_uidle *uidle;

	uidle = kms->hw_uidle;
	wd.enable = enable;
	wd.clear = false;
	wd.granularity = SDE_UIDLE_WD_GRANULARITY;
	wd.heart_beat = SDE_UIDLE_WD_HEART_BEAT;
	wd.load_value = SDE_UIDLE_WD_LOAD_VAL;

	if (uidle->ops.setup_wd_timer)
		uidle->ops.setup_wd_timer(uidle, &wd);
}

static void _sde_core_uidle_setup_cfg(struct sde_kms *kms,
	bool enable)
{
	struct sde_uidle_ctl_cfg cfg;
	struct sde_hw_uidle *uidle;

	uidle = kms->hw_uidle;
	cfg.uidle_enable = enable;
	cfg.fal10_danger =
		kms->catalog->uidle_cfg.fal10_danger;
	cfg.fal10_exit_cnt =
		kms->catalog->uidle_cfg.fal10_exit_cnt;
	cfg.fal10_exit_danger =
		kms->catalog->uidle_cfg.fal10_exit_danger;

	SDE_DEBUG("fal10_danger:%d fal10_exit_cnt:%d fal10_exit_danger:%d\n",
		cfg.fal10_danger, cfg.fal10_exit_cnt, cfg.fal10_exit_danger);
	SDE_EVT32(enable, cfg.fal10_danger, cfg.fal10_exit_cnt,
		cfg.fal10_exit_danger);

	if (uidle->ops.set_uidle_ctl)
		uidle->ops.set_uidle_ctl(uidle, &cfg);
}

static void _sde_core_uidle_setup_ctl(struct drm_crtc *crtc,
	bool enable)
{
	struct drm_encoder *drm_enc;

	/* Disable uidle in the CTL */
	drm_for_each_encoder(drm_enc, crtc->dev) {
		if (drm_enc->crtc != crtc)
			continue;

		sde_encoder_uidle_enable(drm_enc, enable);
	}
}

static int _sde_core_perf_enable_uidle(struct sde_kms *kms,
	struct drm_crtc *crtc, bool enable)
{
	int rc = 0;

	if (!kms->dev || !kms->dev->dev || !kms->hw_uidle) {
		SDE_ERROR("wrong params won't enable uidlen");
		rc = -EINVAL;
		goto exit;
	}

	/* if no status change, just return */
	if ((enable && kms->perf.uidle_enabled) ||
		(!enable && !kms->perf.uidle_enabled)) {
		SDE_DEBUG("no status change enable:%d uidle:%d\n",
			enable, kms->perf.uidle_enabled);
		goto exit;
	}

	SDE_EVT32(enable);
	_sde_core_uidle_setup_wd(kms, enable);
	_sde_core_uidle_setup_cfg(kms, enable);
	_sde_core_uidle_setup_ctl(crtc, enable);

	kms->perf.uidle_enabled = enable;

exit:
	return rc;
}

static inline bool _sde_core_perf_is_wb(struct drm_crtc *crtc)
{
	enum sde_intf_mode if_mode = INTF_MODE_NONE;

	if_mode = sde_crtc_get_intf_mode(crtc);
	if (if_mode == INTF_MODE_WB_BLOCK ||
		if_mode == INTF_MODE_WB_LINE)
		return true;

	return false;
}

static bool _sde_core_perf_is_cwb(struct drm_crtc *crtc)
{
	struct drm_encoder *encoder;

	/* if any other encoder is connected to same crtc in clone mode */
	drm_for_each_encoder(encoder, crtc->dev) {
		if (encoder->crtc == crtc &&
				sde_encoder_in_clone_mode(encoder)) {
			return true;
		}
	}

	return false;
}

void sde_core_perf_crtc_update_uidle(struct drm_crtc *crtc,
	bool enable)
{
	struct drm_crtc *tmp_crtc;
	struct sde_kms *kms;
	bool disable_uidle = false;
	u32 fps;

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

	kms = _sde_crtc_get_kms(crtc);
	if (!kms || !kms->catalog) {
		SDE_ERROR("invalid kms\n");
		return;
	}

	mutex_lock(&sde_core_perf_lock);

	if (!kms->perf.catalog->uidle_cfg.uidle_rev ||
		!kms->perf.catalog->uidle_cfg.debugfs_ctrl) {
		SDE_DEBUG("uidle is not enabled %d %d\n",
			kms->perf.catalog->uidle_cfg.uidle_rev,
			kms->perf.catalog->uidle_cfg.debugfs_ctrl);
		goto exit;
	}

	drm_for_each_crtc(tmp_crtc, crtc->dev) {
		if (_sde_core_perf_crtc_is_power_on(tmp_crtc)) {

			fps = sde_crtc_get_fps_mode(tmp_crtc);

			SDE_DEBUG("crtc=%d fps:%d wb:%d cwb:%d dis:%d en:%d\n",
				tmp_crtc->base.id, fps,
				_sde_core_perf_is_wb(tmp_crtc),
				_sde_core_perf_is_cwb(tmp_crtc),
				disable_uidle, enable);

			if (_sde_core_perf_is_wb(tmp_crtc) ||
				_sde_core_perf_is_cwb(tmp_crtc) || (!fps ||
				 fps > kms->perf.catalog->uidle_cfg.max_fps)) {
				disable_uidle = true;
				break;
			}
		}
	}

	_sde_core_perf_enable_uidle(kms, crtc,
		(enable && !disable_uidle) ? true : false);
exit:
	mutex_unlock(&sde_core_perf_lock);
}

static void _sde_core_perf_crtc_update_bus(struct sde_kms *kms,
		struct drm_crtc *crtc, u32 bus_id)
{
+9 −0
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ struct sde_core_perf_tune {
 * @sde_rsc_available: is display rsc available
 * @bw_vote_mode_updated: bandwidth vote mode update
 * @llcc_active: status of the llcc, true if active.
 * @uidle_enabled: indicates if uidle is already enabled
 */
struct sde_core_perf {
	struct drm_device *dev;
@@ -82,6 +83,7 @@ struct sde_core_perf {
	bool sde_rsc_available;
	bool bw_vote_mode_updated;
	bool llcc_active;
	bool uidle_enabled;
};

/**
@@ -108,6 +110,13 @@ void sde_core_perf_crtc_update(struct drm_crtc *crtc,
 */
void sde_core_perf_crtc_release_bw(struct drm_crtc *crtc);

/**
 * sde_core_perf_crtc_update_uidle - attempts to enable uidle of the given crtc
 * @crtc: Pointer to crtc
 * @enable: enable/disable uidle
 */
void sde_core_perf_crtc_update_uidle(struct drm_crtc *crtc, bool enable);

/**
 * sde_core_perf_destroy - destroy the given core performance context
 * @perf: Pointer to core performance context
Loading