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

Commit 87f5eca6 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge changes I63392417,I6ca0188d into display-kernel.lnx.5.4

* changes:
  disp: msm: add trace logs in display early wakeup function
  disp: msm: add support for display early wakeup
parents 69829bc5 ff4f5306
Loading
Loading
Loading
Loading
+53 −0
Original line number Diff line number Diff line
@@ -1626,6 +1626,57 @@ int msm_ioctl_power_ctrl(struct drm_device *dev, void *data,
	return rc;
}

/**
 * msm_ioctl_display_early_wakeup - early wakeup display.
 * @dev: drm device for the ioctl
 * @data: data pointer for the ioctl
 * @file_priv: drm file for the ioctl call
 *
 */
int msm_ioctl_display_hint_ops(struct drm_device *dev, void *data,
			struct drm_file *file_priv)
{
	struct drm_msm_display_hint *display_hint = data;
	struct drm_msm_early_wakeup early_wakeup;
	void __user *early_wakeup_usr;
	struct msm_drm_private *priv;
	struct msm_kms *kms;

	priv = dev->dev_private;
	kms = priv->kms;

	if (unlikely(!display_hint)) {
		DRM_ERROR("invalid ioctl data\n");
		return -EINVAL;
	}

	SDE_EVT32(display_hint->hint_flags);

	if (display_hint->hint_flags == DRM_MSM_DISPLAY_EARLY_WAKEUP_HINT) {
		if (!display_hint->data) {
			DRM_ERROR("early_wakeup: wrong parameter\n");
			return -EINVAL;
		}

		early_wakeup_usr =
			(void __user *)((uintptr_t)display_hint->data);

		if (copy_from_user(&early_wakeup, early_wakeup_usr,
				sizeof(early_wakeup))) {
			DRM_ERROR("early_wakeup: copy from user failed\n");
			return -EINVAL;
		}

		SDE_EVT32(early_wakeup.wakeup_hint);
		if (kms && kms->funcs && kms->funcs->display_early_wakeup
						&& early_wakeup.wakeup_hint)
			kms->funcs->display_early_wakeup(dev,
					early_wakeup.connector_id);
	}

	return 0;
}

static const struct drm_ioctl_desc msm_ioctls[] = {
	DRM_IOCTL_DEF_DRV(MSM_GEM_NEW,      msm_ioctl_gem_new,      DRM_AUTH|DRM_RENDER_ALLOW),
	DRM_IOCTL_DEF_DRV(MSM_GEM_CPU_PREP, msm_ioctl_gem_cpu_prep, DRM_AUTH|DRM_RENDER_ALLOW),
@@ -1639,6 +1690,8 @@ static const struct drm_ioctl_desc msm_ioctls[] = {
	DRM_IOCTL_DEF_DRV(MSM_RMFB2, msm_ioctl_rmfb2, DRM_UNLOCKED),
	DRM_IOCTL_DEF_DRV(MSM_POWER_CTRL, msm_ioctl_power_ctrl,
			DRM_RENDER_ALLOW),
	DRM_IOCTL_DEF_DRV(MSM_DISPLAY_HINT, msm_ioctl_display_hint_ops,
			DRM_UNLOCKED),
};

static const struct vm_operations_struct vm_ops = {
+2 −0
Original line number Diff line number Diff line
@@ -100,6 +100,8 @@ struct msm_kms_funcs {
	void (*set_encoder_mode)(struct msm_kms *kms,
				 struct drm_encoder *encoder,
				 bool cmd_mode);
	void (*display_early_wakeup)(struct drm_device *dev,
				const int32_t connector_id);
	/* pm suspend/resume hooks */
	int (*pm_suspend)(struct device *dev);
	int (*pm_resume)(struct device *dev);
+50 −0
Original line number Diff line number Diff line
@@ -3690,6 +3690,53 @@ static void sde_encoder_input_event_work_handler(struct kthread_work *work)
			SDE_ENC_RC_EVENT_EARLY_WAKEUP);
}

static void sde_encoder_early_wakeup_work_handler(struct kthread_work *work)
{
	struct sde_encoder_virt *sde_enc = container_of(work,
			struct sde_encoder_virt, early_wakeup_work);

	if (!sde_enc) {
		SDE_ERROR("invalid sde encoder\n");
		return;
	}

	SDE_ATRACE_BEGIN("encoder_early_wakeup");
	sde_encoder_resource_control(&sde_enc->base,
			SDE_ENC_RC_EVENT_EARLY_WAKEUP);
	SDE_ATRACE_END("encoder_early_wakeup");
}

void sde_encoder_early_wakeup(struct drm_encoder *drm_enc)
{
	struct sde_encoder_virt *sde_enc = NULL;
	struct msm_drm_thread *disp_thread = NULL;
	struct msm_drm_private *priv = NULL;

	priv = drm_enc->dev->dev_private;
	sde_enc = to_sde_encoder_virt(drm_enc);

	if (!sde_encoder_check_curr_mode(drm_enc, MSM_DISPLAY_CMD_MODE)) {
		SDE_DEBUG_ENC(sde_enc,
			"should only early wake up command mode display\n");
		return;
	}

	if (!sde_enc->crtc || (sde_enc->crtc->index
			>= ARRAY_SIZE(priv->event_thread))) {
		SDE_ERROR("invalid CRTC: %d or crtc index: %d\n",
			sde_enc->crtc == NULL,
			sde_enc->crtc ? sde_enc->crtc->index : -EINVAL);
		return;
	}

	disp_thread = &priv->disp_thread[sde_enc->crtc->index];

	SDE_ATRACE_BEGIN("queue_early_wakeup_work");
	kthread_queue_work(&disp_thread->worker,
				&sde_enc->early_wakeup_work);
	SDE_ATRACE_END("queue_early_wakeup_work");
}

int sde_encoder_poll_line_counts(struct drm_encoder *drm_enc)
{
	static const uint64_t timeout_us = 50000;
@@ -4812,6 +4859,9 @@ struct drm_encoder *sde_encoder_init_with_ops(
	kthread_init_work(&sde_enc->input_event_work,
			sde_encoder_input_event_work_handler);

	kthread_init_work(&sde_enc->early_wakeup_work,
			sde_encoder_early_wakeup_work_handler);

	kthread_init_work(&sde_enc->esd_trigger_work,
			sde_encoder_esd_trigger_work_handler);

+8 −0
Original line number Diff line number Diff line
@@ -168,6 +168,7 @@ struct sde_encoder_ops {
 * @rc_state:			resource controller state
 * @delayed_off_work:		delayed worker to schedule disabling of
 *				clks and resources after IDLE_TIMEOUT time.
 * @early_wakeup_work:		worker to handle early wakeup event
 * @input_event_work:		worker to handle input device touch events
 * @esd_trigger_work:		worker to handle esd trigger events
 * @input_handler:			handler for input device events
@@ -234,6 +235,7 @@ struct sde_encoder_virt {
	struct mutex rc_lock;
	enum sde_enc_rc_states rc_state;
	struct kthread_delayed_work delayed_off_work;
	struct kthread_work early_wakeup_work;
	struct kthread_work input_event_work;
	struct kthread_work esd_trigger_work;
	struct input_handler *input_handler;
@@ -267,6 +269,12 @@ void sde_encoder_get_hw_resources(struct drm_encoder *encoder,
		struct sde_encoder_hw_resources *hw_res,
		struct drm_connector_state *conn_state);

/**
 * sde_encoder_early_wakeup - early wake up display
 * @encoder:	encoder pointer
 */
void sde_encoder_early_wakeup(struct drm_encoder *drm_enc);

/**
 * sde_encoder_register_vblank_callback - provide callback to encoder that
 *	will be called on the next vblank.
+27 −0
Original line number Diff line number Diff line
@@ -3134,6 +3134,32 @@ static void _sde_kms_null_commit(struct drm_device *dev,
	drm_modeset_acquire_fini(&ctx);
}


void sde_kms_display_early_wakeup(struct drm_device *dev,
				const int32_t connector_id)
{
	struct drm_connector_list_iter conn_iter;
	struct drm_connector *conn;
	struct drm_encoder *drm_enc;

	drm_connector_list_iter_begin(dev, &conn_iter);

	drm_for_each_connector_iter(conn, &conn_iter) {
		if (connector_id != DRM_MSM_WAKE_UP_ALL_DISPLAYS &&
			connector_id != conn->base.id)
			continue;

		if (conn->state && conn->state->best_encoder)
			drm_enc = conn->state->best_encoder;
		else
			drm_enc = conn->encoder;

		sde_encoder_early_wakeup(drm_enc);
	}

	drm_connector_list_iter_end(&conn_iter);
}

static void _sde_kms_pm_suspend_idle_helper(struct sde_kms *sde_kms,
	struct device *dev)
{
@@ -3408,6 +3434,7 @@ static const struct msm_kms_funcs kms_funcs = {
	.atomic_check = sde_kms_atomic_check,
	.get_format      = sde_get_msm_format,
	.round_pixclk    = sde_kms_round_pixclk,
	.display_early_wakeup = sde_kms_display_early_wakeup,
	.pm_suspend      = sde_kms_pm_suspend,
	.pm_resume       = sde_kms_pm_resume,
	.destroy         = sde_kms_destroy,