diff options
Diffstat (limited to 'meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0103-drm-amd-display-DAL3-HDR10-Infoframe-encoding.patch')
-rw-r--r-- | meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0103-drm-amd-display-DAL3-HDR10-Infoframe-encoding.patch | 472 |
1 files changed, 472 insertions, 0 deletions
diff --git a/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0103-drm-amd-display-DAL3-HDR10-Infoframe-encoding.patch b/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0103-drm-amd-display-DAL3-HDR10-Infoframe-encoding.patch new file mode 100644 index 00000000..87fdc3d3 --- /dev/null +++ b/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0103-drm-amd-display-DAL3-HDR10-Infoframe-encoding.patch @@ -0,0 +1,472 @@ +From 0254325ac3a0bfd6013577871b7224e5f4e4abec Mon Sep 17 00:00:00 2001 +From: Andrew Wong <andrew.wong1@amd.com> +Date: Thu, 22 Dec 2016 15:41:30 -0500 +Subject: [PATCH 0103/4131] drm/amd/display: DAL3: HDR10 Infoframe encoding + +- Add HDR metadata struct +- Add register programming calculations +- Added HDR metadata to surface and update_surface +- Add HDR info packet programming for DP port + +Signed-off-by: Andrew Wong <andrew.wong1@amd.com> +Reviewed-by: Aric Cyr <Aric.Cyr@amd.com> +Acked-by: Harry Wentland <Harry.Wentland@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/amd/display/dc/core/dc.c | 7 ++ + drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 115 ++++++++++++++++++++- + drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 1 - + drivers/gpu/drm/amd/display/dc/core/dc_surface.c | 2 + + drivers/gpu/drm/amd/display/dc/dc.h | 23 ++++- + .../drm/amd/display/dc/dce/dce_stream_encoder.c | 20 +++- + .../gpu/drm/amd/display/dc/inc/hw/stream_encoder.h | 2 + + .../drm/amd/display/include/hw_sequencer_types.h | 3 +- + drivers/gpu/drm/amd/display/modules/color/color.c | 16 +-- + .../gpu/drm/amd/display/modules/inc/mod_color.h | 20 +--- + 10 files changed, 176 insertions(+), 33 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c +index 5e60640..e368d66 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c +@@ -1489,6 +1489,9 @@ void dc_update_surfaces_for_target(struct dc *dc, struct dc_surface_update *upda + stream->public.out_transfer_func = + updates[i].out_transfer_func; + } ++ if (updates[i].hdr_static_metadata) ++ surface->public.hdr_static_ctx = ++ *(updates[i].hdr_static_metadata); + } + } + +@@ -1522,6 +1525,10 @@ void dc_update_surfaces_for_target(struct dc *dc, struct dc_surface_update *upda + } + } + ++ if (updates[i].hdr_static_metadata) { ++ resource_build_info_frame(pipe_ctx); ++ core_dc->hwss.update_info_frame(pipe_ctx); ++ } + if (is_new_pipe_surface[j] || + updates[i].in_transfer_func) + core_dc->hwss.set_input_transfer_func( +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +index 386b3cc..2b08f5a 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +@@ -32,7 +32,6 @@ + #include "timing_generator.h" + #include "transform.h" + #include "set_mode_types.h" +- + #include "virtual/virtual_stream_encoder.h" + + #include "dce80/dce80_resource.h" +@@ -1303,6 +1302,13 @@ static void translate_info_frame(const struct hw_info_frame *hw_info_frame, + &hw_info_frame->vsc_packet, + sizeof(struct hw_info_packet)); + } ++ ++ if (hw_info_frame->hdrsmd_packet.valid) { ++ memmove( ++ &encoder_info_frame->hdrsmd, ++ &hw_info_frame->hdrsmd_packet, ++ sizeof(struct hw_info_packet)); ++ } + } + + static void set_avi_info_frame( +@@ -1720,6 +1726,108 @@ static void set_spd_info_packet(struct core_stream *stream, + info_packet->valid = true; + } + ++static void set_hdr_static_info_packet( ++ struct core_surface *surface, ++ struct core_stream *stream, ++ struct hw_info_packet *info_packet) ++{ ++ uint16_t i; ++ enum signal_type signal = stream->signal; ++ ++ if (!surface) ++ return; ++ ++ struct dc_hdr_static_metadata hdr_metadata = ++ surface->public.hdr_static_ctx; ++ ++ if (dc_is_hdmi_signal(signal)) { ++ info_packet->valid = true; ++ ++ info_packet->hb0 = 0x87; ++ info_packet->hb1 = 0x01; ++ info_packet->hb2 = 0x1A; ++ i = 1; ++ } else if (dc_is_dp_signal(signal)) { ++ info_packet->valid = true; ++ ++ info_packet->hb0 = 0x00; ++ info_packet->hb1 = 0x87; ++ info_packet->hb2 = 0x1D; ++ info_packet->hb3 = (0x13 << 2); ++ i = 2; ++ } ++ ++ uint32_t data; ++ ++ data = hdr_metadata.is_hdr; ++ info_packet->sb[i++] = data ? 0x02 : 0x00; ++ info_packet->sb[i++] = 0x00; ++ ++ data = hdr_metadata.chromaticity_green_x / 2; ++ info_packet->sb[i++] = data & 0xFF; ++ info_packet->sb[i++] = (data & 0xFF00) >> 8; ++ ++ data = hdr_metadata.chromaticity_green_y / 2; ++ info_packet->sb[i++] = data & 0xFF; ++ info_packet->sb[i++] = (data & 0xFF00) >> 8; ++ ++ data = hdr_metadata.chromaticity_blue_x / 2; ++ info_packet->sb[i++] = data & 0xFF; ++ info_packet->sb[i++] = (data & 0xFF00) >> 8; ++ ++ data = hdr_metadata.chromaticity_blue_y / 2; ++ info_packet->sb[i++] = data & 0xFF; ++ info_packet->sb[i++] = (data & 0xFF00) >> 8; ++ ++ data = hdr_metadata.chromaticity_red_x / 2; ++ info_packet->sb[i++] = data & 0xFF; ++ info_packet->sb[i++] = (data & 0xFF00) >> 8; ++ ++ data = hdr_metadata.chromaticity_red_y / 2; ++ info_packet->sb[i++] = data & 0xFF; ++ info_packet->sb[i++] = (data & 0xFF00) >> 8; ++ ++ data = hdr_metadata.chromaticity_white_point_x / 2; ++ info_packet->sb[i++] = data & 0xFF; ++ info_packet->sb[i++] = (data & 0xFF00) >> 8; ++ ++ data = hdr_metadata.chromaticity_white_point_y / 2; ++ info_packet->sb[i++] = data & 0xFF; ++ info_packet->sb[i++] = (data & 0xFF00) >> 8; ++ ++ data = hdr_metadata.max_luminance; ++ info_packet->sb[i++] = data & 0xFF; ++ info_packet->sb[i++] = (data & 0xFF00) >> 8; ++ ++ data = hdr_metadata.min_luminance; ++ info_packet->sb[i++] = data & 0xFF; ++ info_packet->sb[i++] = (data & 0xFF00) >> 8; ++ ++ data = hdr_metadata.maximum_content_light_level; ++ info_packet->sb[i++] = data & 0xFF; ++ info_packet->sb[i++] = (data & 0xFF00) >> 8; ++ ++ data = hdr_metadata.maximum_frame_average_light_level; ++ info_packet->sb[i++] = data & 0xFF; ++ info_packet->sb[i++] = (data & 0xFF00) >> 8; ++ ++ if (dc_is_hdmi_signal(signal)) { ++ uint32_t checksum = 0; ++ ++ checksum += info_packet->hb0; ++ checksum += info_packet->hb1; ++ checksum += info_packet->hb2; ++ ++ for (i = 1; i <= info_packet->hb2; i++) ++ checksum += info_packet->sb[i]; ++ ++ info_packet->sb[0] = 0x100 - checksum; ++ } else if (dc_is_dp_signal(signal)) { ++ info_packet->sb[0] = 0x01; ++ info_packet->sb[1] = 0x1A; ++ } ++} ++ + static void set_vsc_info_packet(struct core_stream *stream, + struct hw_info_packet *info_packet) + { +@@ -1830,6 +1938,7 @@ void resource_build_info_frame(struct pipe_ctx *pipe_ctx) + info_frame.vendor_info_packet.valid = false; + info_frame.spd_packet.valid = false; + info_frame.vsc_packet.valid = false; ++ info_frame.hdrsmd_packet.valid = false; + + signal = pipe_ctx->stream->signal; + +@@ -1840,9 +1949,13 @@ void resource_build_info_frame(struct pipe_ctx *pipe_ctx) + set_vendor_info_packet( + pipe_ctx->stream, &info_frame.vendor_info_packet); + set_spd_info_packet(pipe_ctx->stream, &info_frame.spd_packet); ++ set_hdr_static_info_packet(pipe_ctx->surface, ++ pipe_ctx->stream, &info_frame.hdrsmd_packet); + } else if (dc_is_dp_signal(signal)) { + set_vsc_info_packet(pipe_ctx->stream, &info_frame.vsc_packet); + set_spd_info_packet(pipe_ctx->stream, &info_frame.spd_packet); ++ set_hdr_static_info_packet(pipe_ctx->surface, ++ pipe_ctx->stream, &info_frame.hdrsmd_packet); + } + + translate_info_frame(&info_frame, +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +index 39a6124..cda67a7 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +@@ -82,7 +82,6 @@ static bool construct(struct core_stream *stream, + stream->public.timing.flags.LTE_340MCSC_SCRAMBLE = dc_sink_data->edid_caps.lte_340mcsc_scramble; + + stream->status.link = &stream->sink->link->public; +- + return true; + } + +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c +index 6b4c75a..d962baa 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c +@@ -66,6 +66,8 @@ struct transfer_func { + static bool construct(struct dc_context *ctx, struct surface *surface) + { + surface->protected.ctx = ctx; ++ memset(&surface->protected.public.hdr_static_ctx, ++ 0, sizeof(struct dc_hdr_static_metadata)); + return true; + } + +diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h +index 0ee6f41..ef9a697 100644 +--- a/drivers/gpu/drm/amd/display/dc/dc.h ++++ b/drivers/gpu/drm/amd/display/dc/dc.h +@@ -186,6 +186,25 @@ enum { + TRANSFER_FUNC_POINTS = 1025 + }; + ++struct dc_hdr_static_metadata { ++ bool is_hdr; ++ ++ /* display chromaticities and white point in units of 0.00001 */ ++ unsigned int chromaticity_green_x; ++ unsigned int chromaticity_green_y; ++ unsigned int chromaticity_blue_x; ++ unsigned int chromaticity_blue_y; ++ unsigned int chromaticity_red_x; ++ unsigned int chromaticity_red_y; ++ unsigned int chromaticity_white_point_x; ++ unsigned int chromaticity_white_point_y; ++ ++ uint32_t min_luminance; ++ uint32_t max_luminance; ++ uint32_t maximum_content_light_level; ++ uint32_t maximum_frame_average_light_level; ++}; ++ + enum dc_transfer_func_type { + TF_TYPE_PREDEFINED, + TF_TYPE_DISTRIBUTED_POINTS, +@@ -232,6 +251,8 @@ struct dc_surface { + bool horizontal_mirror; + enum plane_stereo_format stereo_format; + ++ struct dc_hdr_static_metadata hdr_static_ctx; ++ + const struct dc_gamma *gamma_correction; + const struct dc_transfer_func *in_transfer_func; + }; +@@ -267,7 +288,7 @@ struct dc_surface_update { + */ + /* gamma TO BE REMOVED */ + struct dc_gamma *gamma; +- ++ struct dc_hdr_static_metadata *hdr_static_metadata; + struct dc_transfer_func *in_transfer_func; + struct dc_transfer_func *out_transfer_func; + +diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c +index b74a29b..82133ab 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c ++++ b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c +@@ -518,6 +518,7 @@ static void dce110_stream_encoder_update_hdmi_info_packets( + dce110_update_hdmi_info_packet(enc110, 0, &info_frame->vendor); + dce110_update_hdmi_info_packet(enc110, 1, &info_frame->gamut); + dce110_update_hdmi_info_packet(enc110, 2, &info_frame->spd); ++ dce110_update_hdmi_info_packet(enc110, 3, &info_frame->hdrsmd); + } + + } +@@ -554,16 +555,25 @@ static void dce110_stream_encoder_update_dp_info_packets( + struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc); + uint32_t value = REG_READ(DP_SEC_CNTL); + +- if (info_frame->vsc.valid) +- dce110_update_generic_info_packet( ++ dce110_update_generic_info_packet( ++ enc110, ++ 0, /* packetIndex */ ++ &info_frame->vsc); ++ dce110_update_generic_info_packet( ++ enc110, ++ 2, /* packetIndex */ ++ &info_frame->spd); ++ dce110_update_generic_info_packet( + enc110, +- 0, /* packetIndex */ +- &info_frame->vsc); ++ 3, /* packetIndex */ ++ &info_frame->hdrsmd); + + /* enable/disable transmission of packet(s). + * If enabled, packet transmission begins on the next frame + */ +- REG_UPDATE(DP_SEC_CNTL, DP_SEC_GSP0_ENABLE, info_frame->vsc.valid); ++ REG_UPDATE(DP_SEC_CNTL, DP_SEC_GSP0_ENABLE, info_frame->vsc.valid); ++ REG_UPDATE(DP_SEC_CNTL, DP_SEC_GSP2_ENABLE, info_frame->spd.valid); ++ REG_UPDATE(DP_SEC_CNTL, DP_SEC_GSP3_ENABLE, info_frame->hdrsmd.valid); + + /* This bit is the master enable bit. + * When enabling secondary stream engine, +diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h b/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h +index 9caf2b3..8b4a304 100644 +--- a/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h ++++ b/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h +@@ -31,6 +31,8 @@ struct encoder_info_frame { + struct encoder_info_packet spd; + /* video stream configuration */ + struct encoder_info_packet vsc; ++ /* HDR Static MetaData */ ++ struct encoder_info_packet hdrsmd; + }; + + struct encoder_unblank_param { +diff --git a/drivers/gpu/drm/amd/display/include/hw_sequencer_types.h b/drivers/gpu/drm/amd/display/include/hw_sequencer_types.h +index 9a78097..6bbca1b 100644 +--- a/drivers/gpu/drm/amd/display/include/hw_sequencer_types.h ++++ b/drivers/gpu/drm/amd/display/include/hw_sequencer_types.h +@@ -88,7 +88,7 @@ struct hw_info_packet { + uint8_t hb1; + uint8_t hb2; + uint8_t hb3; +- uint8_t sb[28]; ++ uint8_t sb[32]; + }; + + struct hw_info_frame { +@@ -100,6 +100,7 @@ struct hw_info_frame { + struct hw_info_packet spd_packet; + /* Video Stream Configuration */ + struct hw_info_packet vsc_packet; ++ struct hw_info_packet hdrsmd_packet; + }; + + #endif +diff --git a/drivers/gpu/drm/amd/display/modules/color/color.c b/drivers/gpu/drm/amd/display/modules/color/color.c +index 5c578aec..599d9f9 100644 +--- a/drivers/gpu/drm/amd/display/modules/color/color.c ++++ b/drivers/gpu/drm/amd/display/modules/color/color.c +@@ -74,7 +74,7 @@ struct color_state { + struct color_gamut_data destination_gamut; + enum color_transfer_func input_transfer_function; + enum color_transfer_func output_transfer_function; +- struct color_mastering_info mastering_info; ++ struct dc_hdr_static_metadata mastering_info; + }; + + struct core_color { +@@ -1970,7 +1970,7 @@ bool mod_color_set_white_point(struct mod_color *mod_color, + + bool mod_color_set_mastering_info(struct mod_color *mod_color, + const struct dc_stream **streams, int num_streams, +- struct color_mastering_info *mastering_info) ++ const struct dc_hdr_static_metadata *mastering_info) + { + struct core_color *core_color = MOD_COLOR_TO_CORE(mod_color); + unsigned int stream_index, sink_index; +@@ -1980,14 +1980,14 @@ bool mod_color_set_mastering_info(struct mod_color *mod_color, + streams[stream_index]->sink); + memcpy(&core_color->state[sink_index].mastering_info, + mastering_info, +- sizeof(struct color_mastering_info)); ++ sizeof(struct dc_hdr_static_metadata)); + } + return true; + } + + bool mod_color_get_mastering_info(struct mod_color *mod_color, + const struct dc_sink *sink, +- struct color_mastering_info *mastering_info) ++ struct dc_hdr_static_metadata *mastering_info) + { + struct core_color *core_color = + MOD_COLOR_TO_CORE(mod_color); +@@ -1995,7 +1995,7 @@ bool mod_color_get_mastering_info(struct mod_color *mod_color, + unsigned int sink_index = sink_index_from_sink(core_color, sink); + + memcpy(mastering_info, &core_color->state[sink_index].mastering_info, +- sizeof(struct color_mastering_info)); ++ sizeof(struct dc_hdr_static_metadata)); + + return true; + } +@@ -2756,8 +2756,10 @@ bool mod_color_update_gamut_info(struct mod_color *mod_color, + else + output_tf->tf = TRANSFER_FUNCTION_SRGB; + } ++ /* 5. ---- POPULATE HDR METADATA ---- */ ++ core_color->state[sink_index].mastering_info.is_hdr = is_hdr; + +- /* 5. ---- TODO: UPDATE INFOPACKETS ---- */ ++ /* 6. ---- TODO: UPDATE INFOPACKETS ---- */ + + if (!mod_color_update_gamut_to_stream( + mod_color, streams, num_streams)) +@@ -2769,6 +2771,8 @@ bool mod_color_update_gamut_info(struct mod_color *mod_color, + updates[0].gamma = core_color->state[sink_index].gamma; + updates[0].in_transfer_func = input_tf; + updates[0].out_transfer_func = output_tf; ++ updates[0].hdr_static_metadata = ++ &core_color->state[sink_index].mastering_info; + + dc_update_surfaces_for_target(core_color->dc, updates, 1, NULL); + +diff --git a/drivers/gpu/drm/amd/display/modules/inc/mod_color.h b/drivers/gpu/drm/amd/display/modules/inc/mod_color.h +index 670b87fb..70349a8 100644 +--- a/drivers/gpu/drm/amd/display/modules/inc/mod_color.h ++++ b/drivers/gpu/drm/amd/display/modules/inc/mod_color.h +@@ -87,22 +87,6 @@ enum hdr_tf_support_flag { + smpte_st2084 = 0x04 + }; + +-struct color_mastering_info { +- unsigned int chromaticity_green_x; +- unsigned int chromaticity_green_y; +- unsigned int chromaticity_blue_x; +- unsigned int chromaticity_blue_y; +- unsigned int chromaticity_red_x; +- unsigned int chromaticity_red_y; +- unsigned int chromaticity_white_point_x; +- unsigned int chromaticity_white_point_y; +- +- unsigned int min_luminance; +- unsigned int max_luminance; +- unsigned int maximum_content_light_level; +- unsigned int maximum_frame_average_light_level; +-}; +- + struct mod_color { + int dummy; + }; +@@ -206,11 +190,11 @@ bool mod_color_get_user_enable(struct mod_color *mod_color, + + bool mod_color_set_mastering_info(struct mod_color *mod_color, + const struct dc_stream **streams, int num_streams, +- struct color_mastering_info *mastering_info); ++ const struct dc_hdr_static_metadata *mastering_info); + + bool mod_color_get_mastering_info(struct mod_color *mod_color, + const struct dc_sink *sink, +- struct color_mastering_info *mastering_info); ++ struct dc_hdr_static_metadata *mastering_info); + + bool mod_color_set_user_enable(struct mod_color *mod_color, + const struct dc_stream **streams, int num_streams, +-- +2.7.4 + |