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

Commit 79d9dc2c authored by Abhinav Kumar's avatar Abhinav Kumar
Browse files

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



Use metadata information sent from userspace to configure sink.

This info shall be used later on to program the HDMI specific
infoframe registers.

Change-Id: I26634452d8c3ab7ab49a65e89ad52a3961c64855
Signed-off-by: default avatarAbhinav Kumar <abhinavk@codeaurora.org>
parent fbb8507e
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