summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/display/dc/core
diff options
context:
space:
mode:
authorAndrew Wong <andrew.wong1@amd.com>2016-12-22 15:41:30 -0500
committerAlex Deucher <alexander.deucher@amd.com>2017-09-26 17:07:29 -0400
commit1646a6fe746d7e923774994d2020e1707dcda884 (patch)
treec544d0e7178f481c0d2f5eb2ceec70b9c0f2be54 /drivers/gpu/drm/amd/display/dc/core
parentc89a58cd0d1cc940a29a00cc03e441f97fab56e1 (diff)
downloadop-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.c7
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_resource.c115
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_stream.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_surface.c2
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;
}
OpenPOWER on IntegriCloud