diff options
author | Dave Airlie <airlied@redhat.com> | 2019-06-05 22:16:17 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2019-06-05 22:16:25 -0400 |
commit | 141de1d46fc8bbab8cdddcd894f8ee1b8c4e8662 (patch) | |
tree | f33c3947016221aabf1480b01a6394e9d657be20 /drivers/gpu/drm/amd | |
parent | 91c1ead6aee22d4595f50ba66070b94a4a8f84a9 (diff) | |
parent | f5b07b04e5f090a85d1e96938520f2b2b58e4a8e (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.c | 155 |
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 | ||
3878 | static 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 | |||
3937 | static bool | ||
3938 | is_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 | |||
3956 | static int | ||
3957 | amdgpu_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 | |||
3878 | static const struct drm_connector_helper_funcs | 4000 | static const struct drm_connector_helper_funcs |
3879 | amdgpu_dm_connector_helper_funcs = { | 4001 | amdgpu_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 | ||
3890 | static void dm_crtc_helper_disable(struct drm_crtc *crtc) | 4013 | static 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; |