Loading drivers/gpu/drm/msm/msm_drv.h +3 −0 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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; }; /** Loading drivers/gpu/drm/msm/sde/sde_connector.c +104 −1 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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, Loading Loading @@ -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, Loading Loading @@ -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) { Loading Loading @@ -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"); Loading @@ -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 Loading Loading @@ -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); Loading drivers/gpu/drm/msm/sde/sde_connector.h +4 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; }; /** Loading include/uapi/drm/msm_drm.h +38 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading
drivers/gpu/drm/msm/msm_drv.h +3 −0 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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; }; /** Loading
drivers/gpu/drm/msm/sde/sde_connector.c +104 −1 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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, Loading Loading @@ -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, Loading Loading @@ -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) { Loading Loading @@ -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"); Loading @@ -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 Loading Loading @@ -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); Loading
drivers/gpu/drm/msm/sde/sde_connector.h +4 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; }; /** Loading
include/uapi/drm/msm_drm.h +38 −0 Original line number Diff line number Diff line Loading @@ -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 Loading