diff options
author | Andrew Wong <andrew.wong1@amd.com> | 2016-12-22 15:41:30 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2017-09-26 17:07:29 -0400 |
commit | 1646a6fe746d7e923774994d2020e1707dcda884 (patch) | |
tree | c544d0e7178f481c0d2f5eb2ceec70b9c0f2be54 /drivers/gpu/drm/amd/display/dc/core | |
parent | c89a58cd0d1cc940a29a00cc03e441f97fab56e1 (diff) | |
download | op-kernel-dev-1646a6fe746d7e923774994d2020e1707dcda884.zip op-kernel-dev-1646a6fe746d7e923774994d2020e1707dcda884.tar.gz |
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>
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/core')
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 115 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc_surface.c | 2 |
4 files changed, 123 insertions, 2 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; } |