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

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

Merge "drm/dp: handle power state transitions"

parents ebedb9c8 ffa57525
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -411,6 +411,30 @@ int drm_dp_link_power_down(struct drm_dp_aux *aux, struct drm_dp_link *link)
}
EXPORT_SYMBOL(drm_dp_link_power_down);

int drm_dp_link_power_down_aux_up(struct drm_dp_aux *aux,
						struct drm_dp_link *link)
{
	u8 value;
	int err;

	if (link->revision < 0x11)
		return 0;

	err = drm_dp_dpcd_readb(aux, DP_SET_POWER, &value);
	if (err < 0)
		return err;

	value &= ~DP_SET_POWER_MASK;
	value |= DP_SET_POWER_D5;

	err = drm_dp_dpcd_writeb(aux, DP_SET_POWER, value);
	if (err < 0)
		return err;

	return 0;
}
EXPORT_SYMBOL(drm_dp_link_power_down_aux_up);

/**
 * drm_dp_link_configure() - configure a DisplayPort link
 * @aux: DisplayPort AUX channel
+54 −0
Original line number Diff line number Diff line
@@ -1414,6 +1414,60 @@ static int dp_display_get_modes(struct dp_display *dp,
	return ret;
}

int dp_display_set_power(struct drm_connector *connector,
			int power_mode, void *disp)
{
	struct dp_display *dp = disp;
	struct dp_display_private *dp_priv =
			container_of(dp, struct dp_display_private, dp_display);
	int rc = 0;

	if (!dp) {
		pr_err("invalid display\n");
		return -EINVAL;
	}

	if (!dp_priv) {
		pr_err("invalid display private\n");
		return -EINVAL;
	}

	if (!dp_priv->panel) {
		pr_err("invalid link_info\n");
		return -EINVAL;
	}

	if (!dp_priv->aux->drm_aux) {
		pr_err("Invalid drm_aux");
		return -EINVAL;
	}

	if (!dp_priv->link) {
		pr_err("invalid dp_link\n");
		return -EINVAL;
	}

	switch (power_mode) {
	case SDE_MODE_DPMS_STANDBY:
		dp_priv->link->power_mode = DRM_MODE_DPMS_STANDBY;
		rc = dp_priv->link->psm_config(dp_priv->link,
				&dp_priv->panel->link_info, true);
		dp_priv->ctrl->push_idle(dp_priv->ctrl);
		break;
	case SDE_MODE_DPMS_SUSPEND:
		dp_priv->link->power_mode = DRM_MODE_DPMS_SUSPEND;
		rc = dp_priv->link->psm_config(dp_priv->link,
				&dp_priv->panel->link_info, true);
		dp_priv->ctrl->push_idle(dp_priv->ctrl);
		break;
	default:
		pr_err("conn %d dpms set to unrecognized mode %d\n",
		connector->base.id, power_mode);
		break;
	}
	return rc;
}

static int dp_display_config_hdr(struct dp_display *dp_display,
			struct drm_msm_ext_hdr_metadata *hdr)
{
+2 −0
Original line number Diff line number Diff line
@@ -63,4 +63,6 @@ bool dp_connector_mode_needs_full_range(void *display);
bool dp_connector_mode_is_cea_mode(void *display);
enum sde_csc_type dp_connector_get_csc_type(struct drm_connector *conn,
	void *data);
int dp_display_set_power(struct drm_connector *connector,
	int power_mode, void *display);
#endif /* _DP_DISPLAY_H_ */
+11 −3
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@
#include "dp_link.h"
#include "dp_panel.h"

#include <uapi/drm/drm_mode.h>

enum dynamic_range {
	DP_DYNAMIC_RANGE_RGB_VESA = 0x00,
	DP_DYNAMIC_RANGE_RGB_CEA = 0x01,
@@ -961,9 +963,15 @@ static int dp_link_psm_config(struct dp_link *dp_link,

	link = container_of(dp_link, struct dp_link_private, dp_link);

	if (enable)
		ret = drm_dp_link_power_down(link->aux->drm_aux, link_info);
	if (enable) {
		if (dp_link->power_mode != DRM_MODE_DPMS_STANDBY
				&& dp_link->power_mode != DRM_MODE_DPMS_SUSPEND)
			ret = drm_dp_link_power_down(link->aux->drm_aux,
					link_info);
		else
			ret = drm_dp_link_power_down_aux_up(link->aux->drm_aux,
					link_info);
	} else
		ret = drm_dp_link_power_up(link->aux->drm_aux, link_info);

	if (ret)
+1 −0
Original line number Diff line number Diff line
@@ -109,6 +109,7 @@ static inline char *dp_link_get_test_name(u32 test_requested)
struct dp_link {
	u32 sink_request;
	u32 test_response;
	int power_mode;

	struct dp_link_sink_count sink_count;
	struct dp_link_test_video test_video;
Loading