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

Commit 1676d30d 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 ad9a9e92 e927aa47
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -163,7 +163,9 @@ enum msm_mdp_conn_property {
	/* blob properties, always put these first */
	CONNECTOR_PROP_SDE_INFO,
	CONNECTOR_PROP_HDR_INFO,
	CONNECTOR_PROP_EXT_HDR_INFO,
	CONNECTOR_PROP_PP_DITHER,
	CONNECTOR_PROP_HDR_METADATA,

	/* # of blob properties */
	CONNECTOR_PROP_BLOBCOUNT,
@@ -482,6 +484,7 @@ struct msm_roi_list {
 */
struct msm_display_kickoff_params {
	struct msm_roi_list *rois;
	struct drm_msm_ext_hdr_metadata *hdr_meta;
};

/**
+104 −1
Original line number Diff line number Diff line
@@ -551,6 +551,7 @@ int sde_connector_pre_kickoff(struct drm_connector *connector)
		return 0;

	params.rois = &c_state->rois;
	params.hdr_meta = &c_state->hdr_meta;

	SDE_EVT32_VERBOSE(connector->base.id);

@@ -871,6 +872,64 @@ static int _sde_connector_set_roi_v1(
	return 0;
}

static int _sde_connector_set_ext_hdr_info(
	struct sde_connector *c_conn,
	struct sde_connector_state *c_state,
	void *usr_ptr)
{
	struct drm_connector *connector;
	struct drm_msm_ext_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_state %d\n", hdr_meta->hdr_state);
	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,
@@ -927,6 +986,13 @@ static int sde_connector_atomic_set_property(struct drm_connector *connector,
			SDE_ERROR_CONN(c_conn, "invalid roi_v1, rc: %d\n", rc);
	}

	if (idx == CONNECTOR_PROP_HDR_METADATA) {
		rc = _sde_connector_set_ext_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,
@@ -1025,6 +1091,29 @@ void sde_connector_commit_reset(struct drm_connector *connector, ktime_t ts)
	sde_fence_signal(&to_sde_connector(connector)->retire_fence, ts, true);
}

static void sde_connector_update_hdr_props(struct drm_connector *connector)
{
	struct sde_connector *c_conn = to_sde_connector(connector);
	struct drm_msm_ext_hdr_properties hdr = {};

	hdr.hdr_supported = connector->hdr_supported;

	if (hdr.hdr_supported) {
		hdr.hdr_eotf = connector->hdr_eotf;
		hdr.hdr_metadata_type_one = connector->hdr_metadata_type_one;
		hdr.hdr_max_luminance = connector->hdr_max_luminance;
		hdr.hdr_avg_luminance = connector->hdr_avg_luminance;
		hdr.hdr_min_luminance = connector->hdr_min_luminance;

		msm_property_set_blob(&c_conn->property_info,
			      &c_conn->blob_ext_hdr,
			      &hdr,
			      sizeof(hdr),
			      CONNECTOR_PROP_EXT_HDR_INFO);

	}
}

static enum drm_connector_status
sde_connector_detect(struct drm_connector *connector, bool force)
{
@@ -1251,6 +1340,7 @@ static const struct drm_connector_funcs sde_connector_ops = {
static int sde_connector_get_modes(struct drm_connector *connector)
{
	struct sde_connector *c_conn;
	int ret = 0;

	if (!connector) {
		SDE_ERROR("invalid connector\n");
@@ -1262,8 +1352,11 @@ static int sde_connector_get_modes(struct drm_connector *connector)
		SDE_DEBUG("missing get_modes callback\n");
		return 0;
	}
	ret = c_conn->ops.get_modes(connector, c_conn->display);
	if (ret)
		sde_connector_update_hdr_props(connector);

	return c_conn->ops.get_modes(connector, c_conn->display);
	return ret;
}

static enum drm_mode_status
@@ -1560,6 +1653,16 @@ struct drm_connector *sde_connector_init(struct drm_device *dev,
	/* install PP_DITHER properties */
	_sde_connector_install_dither_property(dev, sde_kms, c_conn);

	if (connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
		msm_property_install_blob(&c_conn->property_info,
				"ext_hdr_properties",
				DRM_MODE_PROP_IMMUTABLE,
				CONNECTOR_PROP_EXT_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);

+4 −0
Original line number Diff line number Diff line
@@ -266,6 +266,7 @@ struct sde_connector_evt {
 * @property_data: Array of private data for generic property handling
 * @blob_caps: Pointer to blob structure for 'capabilities' property
 * @blob_hdr: Pointer to blob structure for 'hdr_properties' property
 * @blob_ext_hdr: Pointer to blob structure for 'ext_hdr_properties' property
 * @blob_dither: Pointer to blob structure for default dither config
 * @fb_kmap: true if kernel mapping of framebuffer is requested
 * @event_table: Array of registered events
@@ -298,6 +299,7 @@ struct sde_connector {
	struct msm_property_data property_data[CONNECTOR_PROP_COUNT];
	struct drm_property_blob *blob_caps;
	struct drm_property_blob *blob_hdr;
	struct drm_property_blob *blob_ext_hdr;
	struct drm_property_blob *blob_dither;

	bool fb_kmap;
@@ -357,6 +359,7 @@ struct sde_connector {
 * @rois: Regions of interest structure for mapping CRTC to Connector output
 * @property_blobs: blob properties
 * @mode_info: local copy of msm_mode_info struct
 * @hdr_meta: HDR metadata info passed from userspace
 */
struct sde_connector_state {
	struct drm_connector_state base;
@@ -367,6 +370,7 @@ struct sde_connector_state {
	struct msm_roi_list rois;
	struct drm_property_blob *property_blobs[CONNECTOR_PROP_BLOBCOUNT];
	struct msm_mode_info mode_info;
	struct drm_msm_ext_hdr_metadata hdr_meta;
};

/**
+38 −0
Original line number Diff line number Diff line
@@ -61,6 +61,44 @@ 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

#define DRM_MSM_EXT_HDR_METADATA
struct drm_msm_ext_hdr_metadata {
	__u32 hdr_state;        /* HDR state */
	__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
 * to determine the HDR properties to be set to the sink.
 */
#define DRM_MSM_EXT_HDR_PROPERTIES
struct drm_msm_ext_hdr_properties {
	__u8 hdr_metadata_type_one;   /* static metadata type one */
	__u32 hdr_supported;          /* HDR supported */
	__u32 hdr_eotf;               /* electro optical transfer function */
	__u32 hdr_max_luminance;      /* Max luminance */
	__u32 hdr_avg_luminance;      /* Avg luminance */
	__u32 hdr_min_luminance;      /* Min Luminance */
};

#define MSM_PARAM_GPU_ID     0x01
#define MSM_PARAM_GMEM_SIZE  0x02
#define MSM_PARAM_CHIP_ID    0x03