]> Git Repo - linux.git/commitdiff
Merge tag 'drm-misc-next-2019-06-05' of git://anongit.freedesktop.org/drm/drm-misc...
authorDave Airlie <[email protected]>
Thu, 6 Jun 2019 02:16:17 +0000 (12:16 +1000)
committerDave Airlie <[email protected]>
Thu, 6 Jun 2019 02:16:25 +0000 (12:16 +1000)
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 <[email protected]>
From: Maarten Lankhorst <[email protected]>
Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1  2 
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c

index 53b76e0de9403572fac9f69c0f65bf11c693d025,443b13ec268d0df3daecf5c2c94fe53fe9332de8..d52efe1da02efc1af41ff83073d6018a674c36f3
@@@ -29,7 -29,6 +29,7 @@@
  #include "dm_services_types.h"
  #include "dc.h"
  #include "dc/inc/core_types.h"
 +#include "dal_asic_id.h"
  
  #include "vid.h"
  #include "amdgpu.h"
@@@ -616,10 -615,6 +616,10 @@@ error
  static void amdgpu_dm_fini(struct amdgpu_device *adev)
  {
        amdgpu_dm_destroy_drm_device(&adev->dm);
 +
 +      /* DC Destroy TODO: Replace destroy DAL */
 +      if (adev->dm.dc)
 +              dc_destroy(&adev->dm.dc);
        /*
         * TODO: pageflip, vlank interrupt
         *
                mod_freesync_destroy(adev->dm.freesync_module);
                adev->dm.freesync_module = NULL;
        }
 -      /* DC Destroy TODO: Replace destroy DAL */
 -      if (adev->dm.dc)
 -              dc_destroy(&adev->dm.dc);
  
        mutex_destroy(&adev->dm.dc_lock);
  
  
  static int load_dmcu_fw(struct amdgpu_device *adev)
  {
 -      const char *fw_name_dmcu;
 +      const char *fw_name_dmcu = NULL;
        int r;
        const struct dmcu_firmware_header_v1_0 *hdr;
  
        case CHIP_VEGA20:
                return 0;
        case CHIP_RAVEN:
 -              fw_name_dmcu = FIRMWARE_RAVEN_DMCU;
 +#if defined(CONFIG_DRM_AMD_DC_DCN1_01)
 +              if (ASICREV_IS_PICASSO(adev->external_rev_id))
 +                      fw_name_dmcu = FIRMWARE_RAVEN_DMCU;
 +              else if (ASICREV_IS_RAVEN2(adev->external_rev_id))
 +                      fw_name_dmcu = FIRMWARE_RAVEN_DMCU;
 +              else
 +#endif
 +                      return 0;
                break;
        default:
                DRM_ERROR("Unsupported ASIC type: 0x%X\n", adev->asic_type);
@@@ -2593,7 -2584,7 +2593,7 @@@ fill_plane_buffer_attributes(struct amd
                address->type = PLN_ADDR_TYPE_GRAPHICS;
                address->grph.addr.low_part = lower_32_bits(afb->address);
                address->grph.addr.high_part = upper_32_bits(afb->address);
 -      } else {
 +      } else if (format < SURFACE_PIXEL_FORMAT_INVALID) {
                uint64_t chroma_addr = afb->address + fb->offsets[1];
  
                plane_size->video.luma_size.x = 0;
@@@ -2968,16 -2959,16 +2968,16 @@@ static void update_stream_scaling_setti
  }
  
  static enum dc_color_depth
 -convert_color_depth_from_display_info(const struct drm_connector *connector)
 +convert_color_depth_from_display_info(const struct drm_connector *connector,
 +                                    const struct drm_connector_state *state)
  {
 -      struct dm_connector_state *dm_conn_state =
 -              to_dm_connector_state(connector->state);
        uint32_t bpc = connector->display_info.bpc;
  
 -      /* TODO: Remove this when there's support for max_bpc in drm */
 -      if (dm_conn_state && bpc > dm_conn_state->max_bpc)
 -              /* Round down to nearest even number. */
 -              bpc = dm_conn_state->max_bpc - (dm_conn_state->max_bpc & 1);
 +      if (state) {
 +              bpc = state->max_bpc;
 +              /* Round down to the nearest even number. */
 +              bpc = bpc - (bpc & 1);
 +      }
  
        switch (bpc) {
        case 0:
@@@ -3095,12 -3086,11 +3095,12 @@@ static void adjust_colour_depth_from_di
  
  }
  
 -static void
 -fill_stream_properties_from_drm_display_mode(struct dc_stream_state *stream,
 -                                           const struct drm_display_mode *mode_in,
 -                                           const struct drm_connector *connector,
 -                                           const struct dc_stream_state *old_stream)
 +static void fill_stream_properties_from_drm_display_mode(
 +      struct dc_stream_state *stream,
 +      const struct drm_display_mode *mode_in,
 +      const struct drm_connector *connector,
 +      const struct drm_connector_state *connector_state,
 +      const struct dc_stream_state *old_stream)
  {
        struct dc_crtc_timing *timing_out = &stream->timing;
        const struct drm_display_info *info = &connector->display_info;
  
        timing_out->timing_3d_format = TIMING_3D_FORMAT_NONE;
        timing_out->display_color_depth = convert_color_depth_from_display_info(
 -                      connector);
 +              connector, connector_state);
        timing_out->scan_type = SCANNING_TYPE_NODATA;
        timing_out->hdmi_vic = 0;
  
@@@ -3320,8 -3310,6 +3320,8 @@@ create_stream_for_sink(struct amdgpu_dm
  {
        struct drm_display_mode *preferred_mode = NULL;
        struct drm_connector *drm_connector;
 +      const struct drm_connector_state *con_state =
 +              dm_state ? &dm_state->base : NULL;
        struct dc_stream_state *stream = NULL;
        struct drm_display_mode mode = *drm_mode;
        bool native_mode_found = false;
        */
        if (!scale || mode_refresh != preferred_refresh)
                fill_stream_properties_from_drm_display_mode(stream,
 -                      &mode, &aconnector->base, NULL);
 +                      &mode, &aconnector->base, con_state, NULL);
        else
                fill_stream_properties_from_drm_display_mode(stream,
 -                      &mode, &aconnector->base, old_stream);
 +                      &mode, &aconnector->base, con_state, old_stream);
  
        update_stream_scaling_settings(&mode, dm_state, stream);
  
@@@ -3622,6 -3610,9 +3622,6 @@@ int amdgpu_dm_connector_atomic_set_prop
        } else if (property == adev->mode_info.underscan_property) {
                dm_new_state->underscan_enable = val;
                ret = 0;
 -      } else if (property == adev->mode_info.max_bpc_property) {
 -              dm_new_state->max_bpc = val;
 -              ret = 0;
        } else if (property == adev->mode_info.abm_level_property) {
                dm_new_state->abm_level = val;
                ret = 0;
@@@ -3667,6 -3658,9 +3667,6 @@@ int amdgpu_dm_connector_atomic_get_prop
        } else if (property == adev->mode_info.underscan_property) {
                *val = dm_state->underscan_enable;
                ret = 0;
 -      } else if (property == adev->mode_info.max_bpc_property) {
 -              *val = dm_state->max_bpc;
 -              ret = 0;
        } else if (property == adev->mode_info.abm_level_property) {
                *val = dm_state->abm_level;
                ret = 0;
@@@ -3723,6 -3717,7 +3723,6 @@@ void amdgpu_dm_connector_funcs_reset(st
                state->underscan_enable = false;
                state->underscan_hborder = 0;
                state->underscan_vborder = 0;
 -              state->max_bpc = 8;
  
                __drm_atomic_helper_connector_reset(connector, &state->base);
        }
@@@ -3748,6 -3743,7 +3748,6 @@@ amdgpu_dm_connector_atomic_duplicate_st
        new_state->underscan_enable = state->underscan_enable;
        new_state->underscan_hborder = state->underscan_hborder;
        new_state->underscan_vborder = state->underscan_vborder;
 -      new_state->max_bpc = state->max_bpc;
  
        return &new_state->base;
  }
        return result;
  }
  
+ static int fill_hdr_info_packet(const struct drm_connector_state *state,
+                               struct dc_info_packet *out)
+ {
+       struct hdmi_drm_infoframe frame;
+       unsigned char buf[30]; /* 26 + 4 */
+       ssize_t len;
+       int ret, i;
+       memset(out, 0, sizeof(*out));
+       if (!state->hdr_output_metadata)
+               return 0;
+       ret = drm_hdmi_infoframe_set_hdr_metadata(&frame, state);
+       if (ret)
+               return ret;
+       len = hdmi_drm_infoframe_pack_only(&frame, buf, sizeof(buf));
+       if (len < 0)
+               return (int)len;
+       /* Static metadata is a fixed 26 bytes + 4 byte header. */
+       if (len != 30)
+               return -EINVAL;
+       /* Prepare the infopacket for DC. */
+       switch (state->connector->connector_type) {
+       case DRM_MODE_CONNECTOR_HDMIA:
+               out->hb0 = 0x87; /* type */
+               out->hb1 = 0x01; /* version */
+               out->hb2 = 0x1A; /* length */
+               out->sb[0] = buf[3]; /* checksum */
+               i = 1;
+               break;
+       case DRM_MODE_CONNECTOR_DisplayPort:
+       case DRM_MODE_CONNECTOR_eDP:
+               out->hb0 = 0x00; /* sdp id, zero */
+               out->hb1 = 0x87; /* type */
+               out->hb2 = 0x1D; /* payload len - 1 */
+               out->hb3 = (0x13 << 2); /* sdp version */
+               out->sb[0] = 0x01; /* version */
+               out->sb[1] = 0x1A; /* length */
+               i = 2;
+               break;
+       default:
+               return -EINVAL;
+       }
+       memcpy(&out->sb[i], &buf[4], 26);
+       out->valid = true;
+       print_hex_dump(KERN_DEBUG, "HDR SB:", DUMP_PREFIX_NONE, 16, 1, out->sb,
+                      sizeof(out->sb), false);
+       return 0;
+ }
+ static bool
+ is_hdr_metadata_different(const struct drm_connector_state *old_state,
+                         const struct drm_connector_state *new_state)
+ {
+       struct drm_property_blob *old_blob = old_state->hdr_output_metadata;
+       struct drm_property_blob *new_blob = new_state->hdr_output_metadata;
+       if (old_blob != new_blob) {
+               if (old_blob && new_blob &&
+                   old_blob->length == new_blob->length)
+                       return memcmp(old_blob->data, new_blob->data,
+                                     old_blob->length);
+               return true;
+       }
+       return false;
+ }
+ static int
+ amdgpu_dm_connector_atomic_check(struct drm_connector *conn,
+                                struct drm_connector_state *new_con_state)
+ {
+       struct drm_atomic_state *state = new_con_state->state;
+       struct drm_connector_state *old_con_state =
+               drm_atomic_get_old_connector_state(state, conn);
+       struct drm_crtc *crtc = new_con_state->crtc;
+       struct drm_crtc_state *new_crtc_state;
+       int ret;
+       if (!crtc)
+               return 0;
+       if (is_hdr_metadata_different(old_con_state, new_con_state)) {
+               struct dc_info_packet hdr_infopacket;
+               ret = fill_hdr_info_packet(new_con_state, &hdr_infopacket);
+               if (ret)
+                       return ret;
+               new_crtc_state = drm_atomic_get_crtc_state(state, crtc);
+               if (IS_ERR(new_crtc_state))
+                       return PTR_ERR(new_crtc_state);
+               /*
+                * DC considers the stream backends changed if the
+                * static metadata changes. Forcing the modeset also
+                * gives a simple way for userspace to switch from
+                * 8bpc to 10bpc when setting the metadata to enter
+                * or exit HDR.
+                *
+                * Changing the static metadata after it's been
+                * set is permissible, however. So only force a
+                * modeset if we're entering or exiting HDR.
+                */
+               new_crtc_state->mode_changed =
+                       !old_con_state->hdr_output_metadata ||
+                       !new_con_state->hdr_output_metadata;
+       }
+       return 0;
+ }
  static const struct drm_connector_helper_funcs
  amdgpu_dm_connector_helper_funcs = {
        /*
         */
        .get_modes = get_modes,
        .mode_valid = amdgpu_dm_connector_mode_valid,
+       .atomic_check = amdgpu_dm_connector_atomic_check,
  };
  
  static void dm_crtc_helper_disable(struct drm_crtc *crtc)
@@@ -4589,15 -4708,6 +4712,15 @@@ static void amdgpu_dm_connector_ddc_get
                amdgpu_dm_connector->num_modes =
                                drm_add_edid_modes(connector, edid);
  
 +              /* sorting the probed modes before calling function
 +               * amdgpu_dm_get_native_mode() since EDID can have
 +               * more than one preferred mode. The modes that are
 +               * later in the probed mode list could be of higher
 +               * and preferred resolution. For example, 3840x2160
 +               * resolution in base EDID preferred timing and 4096x2160
 +               * preferred resolution in DID extension block later.
 +               */
 +              drm_mode_sort(&connector->probed_modes);
                amdgpu_dm_get_native_mode(connector);
        } else {
                amdgpu_dm_connector->num_modes = 0;
@@@ -4677,12 -4787,9 +4800,12 @@@ void amdgpu_dm_connector_init_helper(st
        drm_object_attach_property(&aconnector->base.base,
                                adev->mode_info.underscan_vborder_property,
                                0);
 -      drm_object_attach_property(&aconnector->base.base,
 -                              adev->mode_info.max_bpc_property,
 -                              0);
 +
 +      drm_connector_attach_max_bpc_property(&aconnector->base, 8, 16);
 +
 +      /* This defaults to the max in the range, but we want 8bpc. */
 +      aconnector->base.state->max_bpc = 8;
 +      aconnector->base.state->max_requested_bpc = 8;
  
        if (connector_type == DRM_MODE_CONNECTOR_eDP &&
            dc_is_dmcu_initialized(adev->dm.dc)) {
        if (connector_type == DRM_MODE_CONNECTOR_HDMIA ||
            connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
            connector_type == DRM_MODE_CONNECTOR_eDP) {
+               drm_object_attach_property(
+                       &aconnector->base.base,
+                       dm->ddev->mode_config.hdr_output_metadata_property, 0);
                drm_connector_attach_vrr_capable_property(
                        &aconnector->base);
        }
@@@ -4961,12 -5072,12 +5088,12 @@@ static int get_cursor_position(struct d
        int x, y;
        int xorigin = 0, yorigin = 0;
  
 -      if (!crtc || !plane->state->fb) {
 -              position->enable = false;
 -              position->x = 0;
 -              position->y = 0;
 +      position->enable = false;
 +      position->x = 0;
 +      position->y = 0;
 +
 +      if (!crtc || !plane->state->fb)
                return 0;
 -      }
  
        if ((plane->state->crtc_w > amdgpu_crtc->max_cursor_width) ||
            (plane->state->crtc_h > amdgpu_crtc->max_cursor_height)) {
        x = plane->state->crtc_x;
        y = plane->state->crtc_y;
  
 +      if (x <= -amdgpu_crtc->max_cursor_width ||
 +          y <= -amdgpu_crtc->max_cursor_height)
 +              return 0;
 +
        if (crtc->primary->state) {
                /* avivo cursor are offset into the total surface */
                x += crtc->primary->state->src_x >> 16;
@@@ -5781,7 -5888,9 +5908,9 @@@ static void amdgpu_dm_atomic_commit_tai
                struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc);
                struct dc_surface_update dummy_updates[MAX_SURFACES];
                struct dc_stream_update stream_update;
+               struct dc_info_packet hdr_packet;
                struct dc_stream_status *status = NULL;
+               bool abm_changed, hdr_changed, scaling_changed;
  
                memset(&dummy_updates, 0, sizeof(dummy_updates));
                memset(&stream_update, 0, sizeof(stream_update));
                dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
                dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
  
-               if (!is_scaling_state_different(dm_new_con_state, dm_old_con_state) &&
-                               (dm_new_crtc_state->abm_level == dm_old_crtc_state->abm_level))
+               scaling_changed = is_scaling_state_different(dm_new_con_state,
+                                                            dm_old_con_state);
+               abm_changed = dm_new_crtc_state->abm_level !=
+                             dm_old_crtc_state->abm_level;
+               hdr_changed =
+                       is_hdr_metadata_different(old_con_state, new_con_state);
+               if (!scaling_changed && !abm_changed && !hdr_changed)
                        continue;
  
-               if (is_scaling_state_different(dm_new_con_state, dm_old_con_state)) {
+               if (scaling_changed) {
                        update_stream_scaling_settings(&dm_new_con_state->base.crtc->mode,
                                        dm_new_con_state, (struct dc_stream_state *)dm_new_crtc_state->stream);
  
                        stream_update.dst = dm_new_crtc_state->stream->dst;
                }
  
-               if (dm_new_crtc_state->abm_level != dm_old_crtc_state->abm_level) {
+               if (abm_changed) {
                        dm_new_crtc_state->stream->abm_level = dm_new_crtc_state->abm_level;
  
                        stream_update.abm_level = &dm_new_crtc_state->abm_level;
                }
  
+               if (hdr_changed) {
+                       fill_hdr_info_packet(new_con_state, &hdr_packet);
+                       stream_update.hdr_static_metadata = &hdr_packet;
+               }
                status = dc_stream_get_status(dm_new_crtc_state->stream);
                WARN_ON(!status);
                WARN_ON(!status->plane_count);
@@@ -6161,6 -6283,11 +6303,11 @@@ static int dm_update_crtc_state(struct 
  
                dm_new_crtc_state->abm_level = dm_new_conn_state->abm_level;
  
+               ret = fill_hdr_info_packet(drm_new_conn_state,
+                                          &new_stream->hdr_static_metadata);
+               if (ret)
+                       goto fail;
                if (dc_is_stream_unchanged(new_stream, dm_old_crtc_state->stream) &&
                    dc_is_stream_scaling_unchanged(new_stream, dm_old_crtc_state->stream)) {
                        new_crtc_state->mode_changed = false;
This page took 0.091408 seconds and 4 git commands to generate.