aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2019-06-05 22:16:17 -0400
committerDave Airlie <airlied@redhat.com>2019-06-05 22:16:25 -0400
commit141de1d46fc8bbab8cdddcd894f8ee1b8c4e8662 (patch)
treef33c3947016221aabf1480b01a6394e9d657be20 /drivers/gpu/drm/amd
parent91c1ead6aee22d4595f50ba66070b94a4a8f84a9 (diff)
parentf5b07b04e5f090a85d1e96938520f2b2b58e4a8e (diff)
Merge tag 'drm-misc-next-2019-06-05' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
drm-misc-next for v5.3: UAPI Changes: Cross-subsystem Changes: - Add devicetree bindings for new panels. - Convert allwinner's DT bindings to a schema. - Drop video/hdmi static functions from kernel docs. - Discard old fence when reserving space in reservation_object_get_fences_rcu. Core Changes: - Add missing -ENOMEM handling in edid loading. - Fix null pointer deref in scheduler. - Header cleanups, making them self-contained. - Remove drmP.h inclusion from core. - Fix make htmldocs warning in scheduler and HDR metadata. - Fix a few warnings in the uapi header and add a doc section for it. - Small MST sideband error handling fix. - Clarify userspace review requirements. - Clarify implicit/explicit fencing in docs. - Flush output polling on shutdown. Driver Changes: - Small cleanups to stm. - Add new driver for ST-Ericsson MCDE - Kconfig fix for meson HDMI. - Add support for Armadeus ST0700 Adapt panel. - Add KOE tx14d24vm1bpa panel. - Update timings for st7701. - Fix compile error in mcde. - Big series of tc358767 fixes, and enabling support for IRQ and HPD handling. - Assorted fixes to sii902x, and implementing HDMI audio support. - Enable HDR metadata support on amdgpu. - Assorted fixes to atmel-hlcdc, and add sam9x60 LCD controller support. Signed-off-by: Dave Airlie <airlied@redhat.com> From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/6c43ffa9-11ff-5354-d772-c20fd4d1e3d9@linux.intel.com
Diffstat (limited to 'drivers/gpu/drm/amd')
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c155
1 files changed, 151 insertions, 4 deletions
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 53b76e0de940..d52efe1da02e 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3875,6 +3875,128 @@ fail:
3875 return result; 3875 return result;
3876} 3876}
3877 3877
3878static int fill_hdr_info_packet(const struct drm_connector_state *state,
3879 struct dc_info_packet *out)
3880{
3881 struct hdmi_drm_infoframe frame;
3882 unsigned char buf[30]; /* 26 + 4 */
3883 ssize_t len;
3884 int ret, i;
3885
3886 memset(out, 0, sizeof(*out));
3887
3888 if (!state->hdr_output_metadata)
3889 return 0;
3890
3891 ret = drm_hdmi_infoframe_set_hdr_metadata(&frame, state);
3892 if (ret)
3893 return ret;
3894
3895 len = hdmi_drm_infoframe_pack_only(&frame, buf, sizeof(buf));
3896 if (len < 0)
3897 return (int)len;
3898
3899 /* Static metadata is a fixed 26 bytes + 4 byte header. */
3900 if (len != 30)
3901 return -EINVAL;
3902
3903 /* Prepare the infopacket for DC. */
3904 switch (state->connector->connector_type) {
3905 case DRM_MODE_CONNECTOR_HDMIA:
3906 out->hb0 = 0x87; /* type */
3907 out->hb1 = 0x01; /* version */
3908 out->hb2 = 0x1A; /* length */
3909 out->sb[0] = buf[3]; /* checksum */
3910 i = 1;
3911 break;
3912
3913 case DRM_MODE_CONNECTOR_DisplayPort:
3914 case DRM_MODE_CONNECTOR_eDP:
3915 out->hb0 = 0x00; /* sdp id, zero */
3916 out->hb1 = 0x87; /* type */
3917 out->hb2 = 0x1D; /* payload len - 1 */
3918 out->hb3 = (0x13 << 2); /* sdp version */
3919 out->sb[0] = 0x01; /* version */
3920 out->sb[1] = 0x1A; /* length */
3921 i = 2;
3922 break;
3923
3924 default:
3925 return -EINVAL;
3926 }
3927
3928 memcpy(&out->sb[i], &buf[4], 26);
3929 out->valid = true;
3930
3931 print_hex_dump(KERN_DEBUG, "HDR SB:", DUMP_PREFIX_NONE, 16, 1, out->sb,
3932 sizeof(out->sb), false);
3933
3934 return 0;
3935}
3936
3937static bool
3938is_hdr_metadata_different(const struct drm_connector_state *old_state,
3939 const struct drm_connector_state *new_state)
3940{
3941 struct drm_property_blob *old_blob = old_state->hdr_output_metadata;
3942 struct drm_property_blob *new_blob = new_state->hdr_output_metadata;
3943
3944 if (old_blob != new_blob) {
3945 if (old_blob && new_blob &&
3946 old_blob->length == new_blob->length)
3947 return memcmp(old_blob->data, new_blob->data,
3948 old_blob->length);
3949
3950 return true;
3951 }
3952
3953 return false;
3954}
3955
3956static int
3957amdgpu_dm_connector_atomic_check(struct drm_connector *conn,
3958 struct drm_connector_state *new_con_state)
3959{
3960 struct drm_atomic_state *state = new_con_state->state;
3961 struct drm_connector_state *old_con_state =
3962 drm_atomic_get_old_connector_state(state, conn);
3963 struct drm_crtc *crtc = new_con_state->crtc;
3964 struct drm_crtc_state *new_crtc_state;
3965 int ret;
3966
3967 if (!crtc)
3968 return 0;
3969
3970 if (is_hdr_metadata_different(old_con_state, new_con_state)) {
3971 struct dc_info_packet hdr_infopacket;
3972
3973 ret = fill_hdr_info_packet(new_con_state, &hdr_infopacket);
3974 if (ret)
3975 return ret;
3976
3977 new_crtc_state = drm_atomic_get_crtc_state(state, crtc);
3978 if (IS_ERR(new_crtc_state))
3979 return PTR_ERR(new_crtc_state);
3980
3981 /*
3982 * DC considers the stream backends changed if the
3983 * static metadata changes. Forcing the modeset also
3984 * gives a simple way for userspace to switch from
3985 * 8bpc to 10bpc when setting the metadata to enter
3986 * or exit HDR.
3987 *
3988 * Changing the static metadata after it's been
3989 * set is permissible, however. So only force a
3990 * modeset if we're entering or exiting HDR.
3991 */
3992 new_crtc_state->mode_changed =
3993 !old_con_state->hdr_output_metadata ||
3994 !new_con_state->hdr_output_metadata;
3995 }
3996
3997 return 0;
3998}
3999
3878static const struct drm_connector_helper_funcs 4000static const struct drm_connector_helper_funcs
3879amdgpu_dm_connector_helper_funcs = { 4001amdgpu_dm_connector_helper_funcs = {
3880 /* 4002 /*
@@ -3885,6 +4007,7 @@ amdgpu_dm_connector_helper_funcs = {
3885 */ 4007 */
3886 .get_modes = get_modes, 4008 .get_modes = get_modes,
3887 .mode_valid = amdgpu_dm_connector_mode_valid, 4009 .mode_valid = amdgpu_dm_connector_mode_valid,
4010 .atomic_check = amdgpu_dm_connector_atomic_check,
3888}; 4011};
3889 4012
3890static void dm_crtc_helper_disable(struct drm_crtc *crtc) 4013static void dm_crtc_helper_disable(struct drm_crtc *crtc)
@@ -4693,6 +4816,10 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm,
4693 if (connector_type == DRM_MODE_CONNECTOR_HDMIA || 4816 if (connector_type == DRM_MODE_CONNECTOR_HDMIA ||
4694 connector_type == DRM_MODE_CONNECTOR_DisplayPort || 4817 connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
4695 connector_type == DRM_MODE_CONNECTOR_eDP) { 4818 connector_type == DRM_MODE_CONNECTOR_eDP) {
4819 drm_object_attach_property(
4820 &aconnector->base.base,
4821 dm->ddev->mode_config.hdr_output_metadata_property, 0);
4822
4696 drm_connector_attach_vrr_capable_property( 4823 drm_connector_attach_vrr_capable_property(
4697 &aconnector->base); 4824 &aconnector->base);
4698 } 4825 }
@@ -5781,7 +5908,9 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
5781 struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc); 5908 struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc);
5782 struct dc_surface_update dummy_updates[MAX_SURFACES]; 5909 struct dc_surface_update dummy_updates[MAX_SURFACES];
5783 struct dc_stream_update stream_update; 5910 struct dc_stream_update stream_update;
5911 struct dc_info_packet hdr_packet;
5784 struct dc_stream_status *status = NULL; 5912 struct dc_stream_status *status = NULL;
5913 bool abm_changed, hdr_changed, scaling_changed;
5785 5914
5786 memset(&dummy_updates, 0, sizeof(dummy_updates)); 5915 memset(&dummy_updates, 0, sizeof(dummy_updates));
5787 memset(&stream_update, 0, sizeof(stream_update)); 5916 memset(&stream_update, 0, sizeof(stream_update));
@@ -5798,11 +5927,19 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
5798 dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); 5927 dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
5799 dm_old_crtc_state = to_dm_crtc_state(old_crtc_state); 5928 dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
5800 5929
5801 if (!is_scaling_state_different(dm_new_con_state, dm_old_con_state) && 5930 scaling_changed = is_scaling_state_different(dm_new_con_state,
5802 (dm_new_crtc_state->abm_level == dm_old_crtc_state->abm_level)) 5931 dm_old_con_state);
5932
5933 abm_changed = dm_new_crtc_state->abm_level !=
5934 dm_old_crtc_state->abm_level;
5935
5936 hdr_changed =
5937 is_hdr_metadata_different(old_con_state, new_con_state);
5938
5939 if (!scaling_changed && !abm_changed && !hdr_changed)
5803 continue; 5940 continue;
5804 5941
5805 if (is_scaling_state_different(dm_new_con_state, dm_old_con_state)) { 5942 if (scaling_changed) {
5806 update_stream_scaling_settings(&dm_new_con_state->base.crtc->mode, 5943 update_stream_scaling_settings(&dm_new_con_state->base.crtc->mode,
5807 dm_new_con_state, (struct dc_stream_state *)dm_new_crtc_state->stream); 5944 dm_new_con_state, (struct dc_stream_state *)dm_new_crtc_state->stream);
5808 5945
@@ -5810,12 +5947,17 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
5810 stream_update.dst = dm_new_crtc_state->stream->dst; 5947 stream_update.dst = dm_new_crtc_state->stream->dst;
5811 } 5948 }
5812 5949
5813 if (dm_new_crtc_state->abm_level != dm_old_crtc_state->abm_level) { 5950 if (abm_changed) {
5814 dm_new_crtc_state->stream->abm_level = dm_new_crtc_state->abm_level; 5951 dm_new_crtc_state->stream->abm_level = dm_new_crtc_state->abm_level;
5815 5952
5816 stream_update.abm_level = &dm_new_crtc_state->abm_level; 5953 stream_update.abm_level = &dm_new_crtc_state->abm_level;
5817 } 5954 }
5818 5955
5956 if (hdr_changed) {
5957 fill_hdr_info_packet(new_con_state, &hdr_packet);
5958 stream_update.hdr_static_metadata = &hdr_packet;
5959 }
5960
5819 status = dc_stream_get_status(dm_new_crtc_state->stream); 5961 status = dc_stream_get_status(dm_new_crtc_state->stream);
5820 WARN_ON(!status); 5962 WARN_ON(!status);
5821 WARN_ON(!status->plane_count); 5963 WARN_ON(!status->plane_count);
@@ -6161,6 +6303,11 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
6161 6303
6162 dm_new_crtc_state->abm_level = dm_new_conn_state->abm_level; 6304 dm_new_crtc_state->abm_level = dm_new_conn_state->abm_level;
6163 6305
6306 ret = fill_hdr_info_packet(drm_new_conn_state,
6307 &new_stream->hdr_static_metadata);
6308 if (ret)
6309 goto fail;
6310
6164 if (dc_is_stream_unchanged(new_stream, dm_old_crtc_state->stream) && 6311 if (dc_is_stream_unchanged(new_stream, dm_old_crtc_state->stream) &&
6165 dc_is_stream_scaling_unchanged(new_stream, dm_old_crtc_state->stream)) { 6312 dc_is_stream_scaling_unchanged(new_stream, dm_old_crtc_state->stream)) {
6166 new_crtc_state->mode_changed = false; 6313 new_crtc_state->mode_changed = false;