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

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

Merge "drm/msm: pass the HDR metadata sent from userspace to sink"

parents 35589846 79d9dc2c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -144,6 +144,7 @@ enum msm_mdp_conn_property {
	/* blob properties, always put these first */
	CONNECTOR_PROP_SDE_INFO,
	CONNECTOR_PROP_HDR_INFO,
	CONNECTOR_PROP_HDR_METADATA,

	/* # of blob properties */
	CONNECTOR_PROP_BLOBCOUNT,
+78 −0
Original line number Diff line number Diff line
@@ -17,6 +17,12 @@
#include "sde_connector.h"
#include "sde_backlight.h"

#define SDE_DEBUG_CONN(c, fmt, ...) SDE_DEBUG("conn%d " fmt,\
		(c) ? (c)->base.base.id : -1, ##__VA_ARGS__)

#define SDE_ERROR_CONN(c, fmt, ...) SDE_ERROR("conn%d " fmt,\
		(c) ? (c)->base.base.id : -1, ##__VA_ARGS__)

static const struct drm_prop_enum_list e_topology_name[] = {
	{SDE_RM_TOPOLOGY_UNKNOWN,	"sde_unknown"},
	{SDE_RM_TOPOLOGY_SINGLEPIPE,	"sde_singlepipe"},
@@ -205,6 +211,68 @@ sde_connector_atomic_duplicate_state(struct drm_connector *connector)
	return &c_state->base;
}

static int _sde_connector_set_hdr_info(
	struct sde_connector *c_conn,
	struct sde_connector_state *c_state,
	void *usr_ptr)
{
	struct drm_connector *connector;
	struct drm_msm_ext_panel_hdr_metadata *hdr_meta;
	int i;

	if (!c_conn || !c_state) {
		SDE_ERROR_CONN(c_conn, "invalid args\n");
		return -EINVAL;
	}

	connector = &c_conn->base;

	if (!connector->hdr_supported) {
		SDE_ERROR_CONN(c_conn, "sink doesn't support HDR\n");
		return -ENOTSUPP;
	}

	memset(&c_state->hdr_meta, 0, sizeof(c_state->hdr_meta));

	if (!usr_ptr) {
		SDE_DEBUG_CONN(c_conn, "hdr metadata cleared\n");
		return 0;
	}

	if (copy_from_user(&c_state->hdr_meta,
		(void __user *)usr_ptr,
			sizeof(*hdr_meta))) {
		SDE_ERROR_CONN(c_conn, "failed to copy hdr metadata\n");
		return -EFAULT;
	}

	hdr_meta = &c_state->hdr_meta;

	SDE_DEBUG_CONN(c_conn, "hdr_supported %d\n",
				   hdr_meta->hdr_supported);
	SDE_DEBUG_CONN(c_conn, "eotf %d\n",
				   hdr_meta->eotf);
	SDE_DEBUG_CONN(c_conn, "white_point_x %d\n",
				   hdr_meta->white_point_x);
	SDE_DEBUG_CONN(c_conn, "white_point_y %d\n",
				   hdr_meta->white_point_y);
	SDE_DEBUG_CONN(c_conn, "max_luminance %d\n",
				   hdr_meta->max_luminance);
	SDE_DEBUG_CONN(c_conn, "max_content_light_level %d\n",
				   hdr_meta->max_content_light_level);
	SDE_DEBUG_CONN(c_conn, "max_average_light_level %d\n",
				   hdr_meta->max_average_light_level);

	for (i = 0; i < HDR_PRIMARIES_COUNT; i++) {
		SDE_DEBUG_CONN(c_conn, "display_primaries_x [%d]\n",
				   hdr_meta->display_primaries_x[i]);
		SDE_DEBUG_CONN(c_conn, "display_primaries_y [%d]\n",
				   hdr_meta->display_primaries_y[i]);
	}

	return 0;
}

static int sde_connector_atomic_set_property(struct drm_connector *connector,
		struct drm_connector_state *state,
		struct drm_property *property,
@@ -264,6 +332,12 @@ static int sde_connector_atomic_set_property(struct drm_connector *connector,
			SDE_ERROR("invalid topology_control: 0x%llX\n", val);
	}

	if (idx == CONNECTOR_PROP_HDR_METADATA) {
		rc = _sde_connector_set_hdr_info(c_conn, c_state, (void *)val);
		if (rc)
			SDE_ERROR_CONN(c_conn, "cannot set hdr info %d\n", rc);
	}

	/* check for custom property handling */
	if (!rc && c_conn->ops.set_property) {
		rc = c_conn->ops.set_property(connector,
@@ -613,6 +687,10 @@ struct drm_connector *sde_connector_init(struct drm_device *dev,
				CONNECTOR_PROP_HDR_INFO);
	}

	msm_property_install_volatile_range(&c_conn->property_info,
		"hdr_metadata", 0x0, 0, ~0, 0,
		CONNECTOR_PROP_HDR_METADATA);

	msm_property_install_range(&c_conn->property_info, "RETIRE_FENCE",
			0x0, 0, INR_OPEN_MAX, 0, CONNECTOR_PROP_RETIRE_FENCE);

+2 −0
Original line number Diff line number Diff line
@@ -208,12 +208,14 @@ struct sde_connector {
 * @out_fb: Pointer to output frame buffer, if applicable
 * @aspace: Address space for accessing frame buffer objects, if applicable
 * @property_values: Local cache of current connector property values
 * @hdr_meta: HDR metadata info passed from userspace
 */
struct sde_connector_state {
	struct drm_connector_state base;
	struct drm_framebuffer *out_fb;
	struct msm_gem_address_space *aspace;
	uint64_t property_values[CONNECTOR_PROP_COUNT];
	struct drm_msm_ext_panel_hdr_metadata hdr_meta;
};

/**
+21 −0
Original line number Diff line number Diff line
@@ -62,6 +62,27 @@ struct drm_msm_timespec {
	__s64 tv_nsec;         /* nanoseconds */
};

/*
 * HDR Metadata
 * These are defined as per EDID spec and shall be used by the sink
 * to set the HDR metadata for playback from userspace.
 */

#define HDR_PRIMARIES_COUNT   3

struct drm_msm_ext_panel_hdr_metadata {
	__u32 eotf;             /* electro optical transfer function */
	__u32 hdr_supported;    /* HDR supported */
	__u32 display_primaries_x[HDR_PRIMARIES_COUNT]; /* Primaries x */
	__u32 display_primaries_y[HDR_PRIMARIES_COUNT]; /* Primaries y */
	__u32 white_point_x;    /* white_point_x */
	__u32 white_point_y;    /* white_point_y */
	__u32 max_luminance;    /* Max luminance */
	__u32 min_luminance;    /* Min Luminance */
	__u32 max_content_light_level; /* max content light level */
	__u32 max_average_light_level; /* max average light level */
};

/**
 * HDR sink properties
 * These are defined as per EDID spec and shall be used by the userspace