]> Git Repo - J-linux.git/commitdiff
Merge tag 'drm-misc-next-fixes-2020-05-27' of git://anongit.freedesktop.org/drm/drm...
authorDave Airlie <[email protected]>
Thu, 28 May 2020 05:38:26 +0000 (15:38 +1000)
committerDave Airlie <[email protected]>
Thu, 28 May 2020 05:38:39 +0000 (15:38 +1000)
Short summary of fixes pull (less than what git shortlog provides):

There's a fix for panel brighness on Lenovo X13 Yoga devices and a fix for
-Wformat warnings on architectures where atomic-64 counters are not of
type unsigned long long.

Signed-off-by: Dave Airlie <[email protected]>
From: Thomas Zimmermann <[email protected]>
Link: https://patchwork.freedesktop.org/patch/msgid/20200527080123.GA8186@linux-uq9g
1  2 
drivers/gpu/drm/drm_dp_helper.c
drivers/gpu/drm/drm_vblank.c

index 43e57632b00a7c4fbaf7bfc977b8417a9bf2b536,41f0e797ce8cce0ad16563a5f84652d3495e5fff..19c99dddcb992c515dcf585a788ace22048887d0
@@@ -1238,8 -1238,6 +1238,8 @@@ static const struct dpcd_quirk dpcd_qui
        { OUI(0x00, 0x00, 0x00), DEVICE_ID('C', 'H', '7', '5', '1', '1'), false, BIT(DP_DPCD_QUIRK_NO_SINK_COUNT) },
        /* Synaptics DP1.4 MST hubs can support DSC without virtual DPCD */
        { OUI(0x90, 0xCC, 0x24), DEVICE_ID_ANY, true, BIT(DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD) },
 +      /* Apple MacBookPro 2017 15 inch eDP Retina panel reports too low DP_MAX_LINK_RATE */
 +      { OUI(0x00, 0x10, 0xfa), DEVICE_ID(101, 68, 21, 101, 98, 97), false, BIT(DP_DPCD_QUIRK_CAN_DO_MAX_LINK_RATE_3_24_GBPS) },
  };
  
  #undef OUI
@@@ -1315,6 -1313,7 +1315,7 @@@ static const struct edid_quirk edid_qui
        { MFG(0x06, 0xaf), PROD_ID(0xeb, 0x41), BIT(DP_QUIRK_FORCE_DPCD_BACKLIGHT) },
        { MFG(0x4d, 0x10), PROD_ID(0xc7, 0x14), BIT(DP_QUIRK_FORCE_DPCD_BACKLIGHT) },
        { MFG(0x4d, 0x10), PROD_ID(0xe6, 0x14), BIT(DP_QUIRK_FORCE_DPCD_BACKLIGHT) },
+       { MFG(0x4c, 0x83), PROD_ID(0x47, 0x41), BIT(DP_QUIRK_FORCE_DPCD_BACKLIGHT) },
  };
  
  #undef MFG
@@@ -1535,271 -1534,3 +1536,271 @@@ int drm_dp_dsc_sink_supported_input_bpc
        return num_bpc;
  }
  EXPORT_SYMBOL(drm_dp_dsc_sink_supported_input_bpcs);
 +
 +/**
 + * drm_dp_get_phy_test_pattern() - get the requested pattern from the sink.
 + * @aux: DisplayPort AUX channel
 + * @data: DP phy compliance test parameters.
 + *
 + * Returns 0 on success or a negative error code on failure.
 + */
 +int drm_dp_get_phy_test_pattern(struct drm_dp_aux *aux,
 +                              struct drm_dp_phy_test_params *data)
 +{
 +      int err;
 +      u8 rate, lanes;
 +
 +      err = drm_dp_dpcd_readb(aux, DP_TEST_LINK_RATE, &rate);
 +      if (err < 0)
 +              return err;
 +      data->link_rate = drm_dp_bw_code_to_link_rate(rate);
 +
 +      err = drm_dp_dpcd_readb(aux, DP_TEST_LANE_COUNT, &lanes);
 +      if (err < 0)
 +              return err;
 +      data->num_lanes = lanes & DP_MAX_LANE_COUNT_MASK;
 +
 +      if (lanes & DP_ENHANCED_FRAME_CAP)
 +              data->enhanced_frame_cap = true;
 +
 +      err = drm_dp_dpcd_readb(aux, DP_PHY_TEST_PATTERN, &data->phy_pattern);
 +      if (err < 0)
 +              return err;
 +
 +      switch (data->phy_pattern) {
 +      case DP_PHY_TEST_PATTERN_80BIT_CUSTOM:
 +              err = drm_dp_dpcd_read(aux, DP_TEST_80BIT_CUSTOM_PATTERN_7_0,
 +                                     &data->custom80, sizeof(data->custom80));
 +              if (err < 0)
 +                      return err;
 +
 +              break;
 +      case DP_PHY_TEST_PATTERN_CP2520:
 +              err = drm_dp_dpcd_read(aux, DP_TEST_HBR2_SCRAMBLER_RESET,
 +                                     &data->hbr2_reset,
 +                                     sizeof(data->hbr2_reset));
 +              if (err < 0)
 +                      return err;
 +      }
 +
 +      return 0;
 +}
 +EXPORT_SYMBOL(drm_dp_get_phy_test_pattern);
 +
 +/**
 + * drm_dp_set_phy_test_pattern() - set the pattern to the sink.
 + * @aux: DisplayPort AUX channel
 + * @data: DP phy compliance test parameters.
 + *
 + * Returns 0 on success or a negative error code on failure.
 + */
 +int drm_dp_set_phy_test_pattern(struct drm_dp_aux *aux,
 +                              struct drm_dp_phy_test_params *data, u8 dp_rev)
 +{
 +      int err, i;
 +      u8 link_config[2];
 +      u8 test_pattern;
 +
 +      link_config[0] = drm_dp_link_rate_to_bw_code(data->link_rate);
 +      link_config[1] = data->num_lanes;
 +      if (data->enhanced_frame_cap)
 +              link_config[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
 +      err = drm_dp_dpcd_write(aux, DP_LINK_BW_SET, link_config, 2);
 +      if (err < 0)
 +              return err;
 +
 +      test_pattern = data->phy_pattern;
 +      if (dp_rev < 0x12) {
 +              test_pattern = (test_pattern << 2) &
 +                             DP_LINK_QUAL_PATTERN_11_MASK;
 +              err = drm_dp_dpcd_writeb(aux, DP_TRAINING_PATTERN_SET,
 +                                       test_pattern);
 +              if (err < 0)
 +                      return err;
 +      } else {
 +              for (i = 0; i < data->num_lanes; i++) {
 +                      err = drm_dp_dpcd_writeb(aux,
 +                                               DP_LINK_QUAL_LANE0_SET + i,
 +                                               test_pattern);
 +                      if (err < 0)
 +                              return err;
 +              }
 +      }
 +
 +      return 0;
 +}
 +EXPORT_SYMBOL(drm_dp_set_phy_test_pattern);
 +
 +static const char *dp_pixelformat_get_name(enum dp_pixelformat pixelformat)
 +{
 +      if (pixelformat < 0 || pixelformat > DP_PIXELFORMAT_RESERVED)
 +              return "Invalid";
 +
 +      switch (pixelformat) {
 +      case DP_PIXELFORMAT_RGB:
 +              return "RGB";
 +      case DP_PIXELFORMAT_YUV444:
 +              return "YUV444";
 +      case DP_PIXELFORMAT_YUV422:
 +              return "YUV422";
 +      case DP_PIXELFORMAT_YUV420:
 +              return "YUV420";
 +      case DP_PIXELFORMAT_Y_ONLY:
 +              return "Y_ONLY";
 +      case DP_PIXELFORMAT_RAW:
 +              return "RAW";
 +      default:
 +              return "Reserved";
 +      }
 +}
 +
 +static const char *dp_colorimetry_get_name(enum dp_pixelformat pixelformat,
 +                                         enum dp_colorimetry colorimetry)
 +{
 +      if (pixelformat < 0 || pixelformat > DP_PIXELFORMAT_RESERVED)
 +              return "Invalid";
 +
 +      switch (colorimetry) {
 +      case DP_COLORIMETRY_DEFAULT:
 +              switch (pixelformat) {
 +              case DP_PIXELFORMAT_RGB:
 +                      return "sRGB";
 +              case DP_PIXELFORMAT_YUV444:
 +              case DP_PIXELFORMAT_YUV422:
 +              case DP_PIXELFORMAT_YUV420:
 +                      return "BT.601";
 +              case DP_PIXELFORMAT_Y_ONLY:
 +                      return "DICOM PS3.14";
 +              case DP_PIXELFORMAT_RAW:
 +                      return "Custom Color Profile";
 +              default:
 +                      return "Reserved";
 +              }
 +      case DP_COLORIMETRY_RGB_WIDE_FIXED: /* and DP_COLORIMETRY_BT709_YCC */
 +              switch (pixelformat) {
 +              case DP_PIXELFORMAT_RGB:
 +                      return "Wide Fixed";
 +              case DP_PIXELFORMAT_YUV444:
 +              case DP_PIXELFORMAT_YUV422:
 +              case DP_PIXELFORMAT_YUV420:
 +                      return "BT.709";
 +              default:
 +                      return "Reserved";
 +              }
 +      case DP_COLORIMETRY_RGB_WIDE_FLOAT: /* and DP_COLORIMETRY_XVYCC_601 */
 +              switch (pixelformat) {
 +              case DP_PIXELFORMAT_RGB:
 +                      return "Wide Float";
 +              case DP_PIXELFORMAT_YUV444:
 +              case DP_PIXELFORMAT_YUV422:
 +              case DP_PIXELFORMAT_YUV420:
 +                      return "xvYCC 601";
 +              default:
 +                      return "Reserved";
 +              }
 +      case DP_COLORIMETRY_OPRGB: /* and DP_COLORIMETRY_XVYCC_709 */
 +              switch (pixelformat) {
 +              case DP_PIXELFORMAT_RGB:
 +                      return "OpRGB";
 +              case DP_PIXELFORMAT_YUV444:
 +              case DP_PIXELFORMAT_YUV422:
 +              case DP_PIXELFORMAT_YUV420:
 +                      return "xvYCC 709";
 +              default:
 +                      return "Reserved";
 +              }
 +      case DP_COLORIMETRY_DCI_P3_RGB: /* and DP_COLORIMETRY_SYCC_601 */
 +              switch (pixelformat) {
 +              case DP_PIXELFORMAT_RGB:
 +                      return "DCI-P3";
 +              case DP_PIXELFORMAT_YUV444:
 +              case DP_PIXELFORMAT_YUV422:
 +              case DP_PIXELFORMAT_YUV420:
 +                      return "sYCC 601";
 +              default:
 +                      return "Reserved";
 +              }
 +      case DP_COLORIMETRY_RGB_CUSTOM: /* and DP_COLORIMETRY_OPYCC_601 */
 +              switch (pixelformat) {
 +              case DP_PIXELFORMAT_RGB:
 +                      return "Custom Profile";
 +              case DP_PIXELFORMAT_YUV444:
 +              case DP_PIXELFORMAT_YUV422:
 +              case DP_PIXELFORMAT_YUV420:
 +                      return "OpYCC 601";
 +              default:
 +                      return "Reserved";
 +              }
 +      case DP_COLORIMETRY_BT2020_RGB: /* and DP_COLORIMETRY_BT2020_CYCC */
 +              switch (pixelformat) {
 +              case DP_PIXELFORMAT_RGB:
 +                      return "BT.2020 RGB";
 +              case DP_PIXELFORMAT_YUV444:
 +              case DP_PIXELFORMAT_YUV422:
 +              case DP_PIXELFORMAT_YUV420:
 +                      return "BT.2020 CYCC";
 +              default:
 +                      return "Reserved";
 +              }
 +      case DP_COLORIMETRY_BT2020_YCC:
 +              switch (pixelformat) {
 +              case DP_PIXELFORMAT_YUV444:
 +              case DP_PIXELFORMAT_YUV422:
 +              case DP_PIXELFORMAT_YUV420:
 +                      return "BT.2020 YCC";
 +              default:
 +                      return "Reserved";
 +              }
 +      default:
 +              return "Invalid";
 +      }
 +}
 +
 +static const char *dp_dynamic_range_get_name(enum dp_dynamic_range dynamic_range)
 +{
 +      switch (dynamic_range) {
 +      case DP_DYNAMIC_RANGE_VESA:
 +              return "VESA range";
 +      case DP_DYNAMIC_RANGE_CTA:
 +              return "CTA range";
 +      default:
 +              return "Invalid";
 +      }
 +}
 +
 +static const char *dp_content_type_get_name(enum dp_content_type content_type)
 +{
 +      switch (content_type) {
 +      case DP_CONTENT_TYPE_NOT_DEFINED:
 +              return "Not defined";
 +      case DP_CONTENT_TYPE_GRAPHICS:
 +              return "Graphics";
 +      case DP_CONTENT_TYPE_PHOTO:
 +              return "Photo";
 +      case DP_CONTENT_TYPE_VIDEO:
 +              return "Video";
 +      case DP_CONTENT_TYPE_GAME:
 +              return "Game";
 +      default:
 +              return "Reserved";
 +      }
 +}
 +
 +void drm_dp_vsc_sdp_log(const char *level, struct device *dev,
 +                      const struct drm_dp_vsc_sdp *vsc)
 +{
 +#define DP_SDP_LOG(fmt, ...) dev_printk(level, dev, fmt, ##__VA_ARGS__)
 +      DP_SDP_LOG("DP SDP: %s, revision %u, length %u\n", "VSC",
 +                 vsc->revision, vsc->length);
 +      DP_SDP_LOG("    pixelformat: %s\n",
 +                 dp_pixelformat_get_name(vsc->pixelformat));
 +      DP_SDP_LOG("    colorimetry: %s\n",
 +                 dp_colorimetry_get_name(vsc->pixelformat, vsc->colorimetry));
 +      DP_SDP_LOG("    bpc: %u\n", vsc->bpc);
 +      DP_SDP_LOG("    dynamic range: %s\n",
 +                 dp_dynamic_range_get_name(vsc->dynamic_range));
 +      DP_SDP_LOG("    content type: %s\n",
 +                 dp_content_type_get_name(vsc->content_type));
 +#undef DP_SDP_LOG
 +}
 +EXPORT_SYMBOL(drm_dp_vsc_sdp_log);
index 758bf74e1cabef7195d80ca02b4fe3f38c896871,a3766bf04aee5b2c2bdac45fc5545bda4fce46ae..2d5ce690d214b4835c395603ec3267e4e019eddb
@@@ -30,7 -30,6 +30,7 @@@
  #include <drm/drm_crtc.h>
  #include <drm/drm_drv.h>
  #include <drm/drm_framebuffer.h>
 +#include <drm/drm_managed.h>
  #include <drm/drm_modeset_helper_vtables.h>
  #include <drm/drm_print.h>
  #include <drm/drm_vblank.h>
  /**
   * DOC: vblank handling
   *
 + * From the computer's perspective, every time the monitor displays
 + * a new frame the scanout engine has "scanned out" the display image
 + * from top to bottom, one row of pixels at a time. The current row
 + * of pixels is referred to as the current scanline.
 + *
 + * In addition to the display's visible area, there's usually a couple of
 + * extra scanlines which aren't actually displayed on the screen.
 + * These extra scanlines don't contain image data and are occasionally used
 + * for features like audio and infoframes. The region made up of these
 + * scanlines is referred to as the vertical blanking region, or vblank for
 + * short.
 + *
 + * For historical reference, the vertical blanking period was designed to
 + * give the electron gun (on CRTs) enough time to move back to the top of
 + * the screen to start scanning out the next frame. Similar for horizontal
 + * blanking periods. They were designed to give the electron gun enough
 + * time to move back to the other side of the screen to start scanning the
 + * next scanline.
 + *
 + * ::
 + *
 + *
 + *    physical →   ⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽
 + *    top of      |                                        |
 + *    display     |                                        |
 + *                |               New frame                |
 + *                |                                        |
 + *                |↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓|
 + *                |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| ← Scanline,
 + *                |↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓|   updates the
 + *                |                                        |   frame as it
 + *                |                                        |   travels down
 + *                |                                        |   ("sacn out")
 + *                |               Old frame                |
 + *                |                                        |
 + *                |                                        |
 + *                |                                        |
 + *                |                                        |   physical
 + *                |                                        |   bottom of
 + *    vertical    |⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽| ← display
 + *    blanking    ┆xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx┆
 + *    region   →  ┆xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx┆
 + *                ┆xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx┆
 + *    start of →   ⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽
 + *    new frame
 + *
 + * "Physical top of display" is the reference point for the high-precision/
 + * corrected timestamp.
 + *
 + * On a lot of display hardware, programming needs to take effect during the
 + * vertical blanking period so that settings like gamma, the image buffer
 + * buffer to be scanned out, etc. can safely be changed without showing
 + * any visual artifacts on the screen. In some unforgiving hardware, some of
 + * this programming has to both start and end in the same vblank. To help
 + * with the timing of the hardware programming, an interrupt is usually
 + * available to notify the driver when it can start the updating of registers.
 + * The interrupt is in this context named the vblank interrupt.
 + *
 + * The vblank interrupt may be fired at different points depending on the
 + * hardware. Some hardware implementations will fire the interrupt when the
 + * new frame start, other implementations will fire the interrupt at different
 + * points in time.
 + *
   * Vertical blanking plays a major role in graphics rendering. To achieve
   * tear-free display, users must synchronize page flips and/or rendering to
   * vertical blanking. The DRM API offers ioctls to perform page flips
@@@ -342,8 -278,8 +342,8 @@@ static void drm_update_vblank_count(str
  
        DRM_DEBUG_VBL("updating vblank count on crtc %u:"
                      " current=%llu, diff=%u, hw=%u hw_last=%u\n",
-                     pipe, atomic64_read(&vblank->count), diff,
-                     cur_vblank, vblank->last);
+                     pipe, (unsigned long long)atomic64_read(&vblank->count),
+                     diff, cur_vblank, vblank->last);
  
        if (diff == 0) {
                WARN_ON_ONCE(cur_vblank != vblank->last);
@@@ -489,10 -425,14 +489,10 @@@ static void vblank_disable_fn(struct ti
        spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
  }
  
 -void drm_vblank_cleanup(struct drm_device *dev)
 +static void drm_vblank_init_release(struct drm_device *dev, void *ptr)
  {
        unsigned int pipe;
  
 -      /* Bail if the driver didn't call drm_vblank_init() */
 -      if (dev->num_crtcs == 0)
 -              return;
 -
        for (pipe = 0; pipe < dev->num_crtcs; pipe++) {
                struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
  
  
                del_timer_sync(&vblank->disable_timer);
        }
 -
 -      kfree(dev->vblank);
 -
 -      dev->num_crtcs = 0;
  }
  
  /**
   * @num_crtcs: number of CRTCs supported by @dev
   *
   * This function initializes vblank support for @num_crtcs display pipelines.
 - * Cleanup is handled by the DRM core, or through calling drm_dev_fini() for
 - * drivers with a &drm_driver.release callback.
 + * Cleanup is handled automatically through a cleanup function added with
 + * drmm_add_action().
   *
   * Returns:
   * Zero on success or a negative error code on failure.
   */
  int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs)
  {
 -      int ret = -ENOMEM;
 +      int ret;
        unsigned int i;
  
        spin_lock_init(&dev->vbl_lock);
        spin_lock_init(&dev->vblank_time_lock);
  
 +      dev->vblank = drmm_kcalloc(dev, num_crtcs, sizeof(*dev->vblank), GFP_KERNEL);
 +      if (!dev->vblank)
 +              return -ENOMEM;
 +
        dev->num_crtcs = num_crtcs;
  
 -      dev->vblank = kcalloc(num_crtcs, sizeof(*dev->vblank), GFP_KERNEL);
 -      if (!dev->vblank)
 -              goto err;
 +      ret = drmm_add_action(dev, drm_vblank_init_release, NULL);
 +      if (ret)
 +              return ret;
  
        for (i = 0; i < num_crtcs; i++) {
                struct drm_vblank_crtc *vblank = &dev->vblank[i];
        DRM_INFO("Supports vblank timestamp caching Rev 2 (21.10.2013).\n");
  
        return 0;
 -
 -err:
 -      dev->num_crtcs = 0;
 -      return ret;
  }
  EXPORT_SYMBOL(drm_vblank_init);
  
This page took 0.074146 seconds and 4 git commands to generate.