OSDN Git Service

Merge tag 'topic/drm-misc-2015-03-31' of git://anongit.freedesktop.org/drm-intel...
authorDave Airlie <airlied@redhat.com>
Tue, 31 Mar 2015 22:23:25 +0000 (08:23 +1000)
committerDave Airlie <airlied@redhat.com>
Tue, 31 Mar 2015 22:23:25 +0000 (08:23 +1000)
Final drm-misc pull for 4.0, just various things all over, including a few
more important atomic fixes. btw I didn't pick up the vmwgfx patch from
Ville's series, but one patch has one hunk touching vmwgfx and
Thomas/Jakob didn't get around to ack it. I figured it's simple enough to
be ok though.

* tag 'topic/drm-misc-2015-03-31' of git://anongit.freedesktop.org/drm-intel:
  drm: line wrap DRM_IOCTL_DEF* macros
  drm/atomic: Don't try to free a NULL state
  drm/atomic: Clear crtcs, connectors and planes when clearing state
  drm: Rewrite drm_ioctl_flags() to resemble the new drm_ioctl() code
  drm: Use max() to make the ioctl alloc size code cleaner
  drm: Simplify core vs. drv ioctl handling
  drm: Drop ioctl->cmd_drv
  drm: Fix DRM_IOCTL_DEF_DRV()
  drm/atomic-helpers: Properly avoid full modeset dance
  drm: atomic: Allow setting CRTC active property
  drm: atomic: Expose CRTC active property
  drm: crtc_helper: Update hwmode before mode_set call
  drm: mode: Allow NULL modes for equality check
  drm: fb_helper: Simplify exit condition
  drm: mode: Fix typo in kerneldoc
  drm/dp: Print the number of bytes processed for aux nacks

drivers/gpu/drm/drm_atomic.c
drivers/gpu/drm/drm_atomic_helper.c
drivers/gpu/drm/drm_crtc_helper.c
drivers/gpu/drm/drm_dp_helper.c
drivers/gpu/drm/drm_fb_helper.c
drivers/gpu/drm/drm_ioctl.c
drivers/gpu/drm/drm_modes.c
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
include/drm/drmP.h

index a6caaae..57efdbe 100644 (file)
@@ -134,6 +134,7 @@ void drm_atomic_state_clear(struct drm_atomic_state *state)
 
                connector->funcs->atomic_destroy_state(connector,
                                                       state->connector_states[i]);
+               state->connectors[i] = NULL;
                state->connector_states[i] = NULL;
        }
 
@@ -145,6 +146,7 @@ void drm_atomic_state_clear(struct drm_atomic_state *state)
 
                crtc->funcs->atomic_destroy_state(crtc,
                                                  state->crtc_states[i]);
+               state->crtcs[i] = NULL;
                state->crtc_states[i] = NULL;
        }
 
@@ -156,6 +158,7 @@ void drm_atomic_state_clear(struct drm_atomic_state *state)
 
                plane->funcs->atomic_destroy_state(plane,
                                                   state->plane_states[i]);
+               state->planes[i] = NULL;
                state->plane_states[i] = NULL;
        }
 }
@@ -170,6 +173,9 @@ EXPORT_SYMBOL(drm_atomic_state_clear);
  */
 void drm_atomic_state_free(struct drm_atomic_state *state)
 {
+       if (!state)
+               return;
+
        drm_atomic_state_clear(state);
 
        DRM_DEBUG_ATOMIC("Freeing atomic state %p\n", state);
@@ -248,11 +254,14 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
        struct drm_mode_config *config = &dev->mode_config;
 
        /* FIXME: Mode prop is missing, which also controls ->enable. */
-       if (property == config->prop_active) {
+       if (property == config->prop_active)
                state->active = val;
-       else if (crtc->funcs->atomic_set_property)
+       else if (crtc->funcs->atomic_set_property)
                return crtc->funcs->atomic_set_property(crtc, state, property, val);
-       return -EINVAL;
+       else
+               return -EINVAL;
+
+       return 0;
 }
 EXPORT_SYMBOL(drm_atomic_crtc_set_property);
 
@@ -266,9 +275,17 @@ int drm_atomic_crtc_get_property(struct drm_crtc *crtc,
                const struct drm_crtc_state *state,
                struct drm_property *property, uint64_t *val)
 {
-       if (crtc->funcs->atomic_get_property)
+       struct drm_device *dev = crtc->dev;
+       struct drm_mode_config *config = &dev->mode_config;
+
+       if (property == config->prop_active)
+               *val = state->active;
+       else if (crtc->funcs->atomic_get_property)
                return crtc->funcs->atomic_get_property(crtc, state, property, val);
-       return -EINVAL;
+       else
+               return -EINVAL;
+
+       return 0;
 }
 
 /**
index d9ed9a5..e67d4d6 100644 (file)
@@ -587,7 +587,8 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
 
                old_crtc_state = old_state->crtc_states[drm_crtc_index(old_conn_state->crtc)];
 
-               if (!old_crtc_state->active)
+               if (!old_crtc_state->active ||
+                   !needs_modeset(old_conn_state->crtc->state))
                        continue;
 
                encoder = old_conn_state->best_encoder;
@@ -847,7 +848,8 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
                if (!connector || !connector->state->best_encoder)
                        continue;
 
-               if (!connector->state->crtc->state->active)
+               if (!connector->state->crtc->state->active ||
+                   !needs_modeset(connector->state->crtc->state))
                        continue;
 
                encoder = connector->state->best_encoder;
index 3053aab..dd895c4 100644 (file)
@@ -270,7 +270,7 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
                              struct drm_framebuffer *old_fb)
 {
        struct drm_device *dev = crtc->dev;
-       struct drm_display_mode *adjusted_mode, saved_mode;
+       struct drm_display_mode *adjusted_mode, saved_mode, saved_hwmode;
        struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
        struct drm_encoder_helper_funcs *encoder_funcs;
        int saved_x, saved_y;
@@ -292,6 +292,7 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
        }
 
        saved_mode = crtc->mode;
+       saved_hwmode = crtc->hwmode;
        saved_x = crtc->x;
        saved_y = crtc->y;
 
@@ -334,6 +335,8 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
        }
        DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
 
+       crtc->hwmode = *adjusted_mode;
+
        /* Prepare the encoders and CRTCs before setting the mode. */
        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
 
@@ -396,9 +399,6 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
                        encoder->bridge->funcs->enable(encoder->bridge);
        }
 
-       /* Store real post-adjustment hardware mode. */
-       crtc->hwmode = *adjusted_mode;
-
        /* Calculate and store various constants which
         * are later needed by vblank and swap-completion
         * timestamping. They are derived from true hwmode.
@@ -411,6 +411,7 @@ done:
        if (!ret) {
                crtc->enabled = saved_enabled;
                crtc->mode = saved_mode;
+               crtc->hwmode = saved_hwmode;
                crtc->x = saved_x;
                crtc->y = saved_y;
        }
index d5368ea..71dcbc6 100644 (file)
@@ -462,7 +462,7 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
                        break;
 
                case DP_AUX_NATIVE_REPLY_NACK:
-                       DRM_DEBUG_KMS("native nack\n");
+                       DRM_DEBUG_KMS("native nack (result=%d, size=%zu)\n", ret, msg->size);
                        return -EREMOTEIO;
 
                case DP_AUX_NATIVE_REPLY_DEFER:
@@ -493,7 +493,7 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
                        return ret;
 
                case DP_AUX_I2C_REPLY_NACK:
-                       DRM_DEBUG_KMS("I2C nack\n");
+                       DRM_DEBUG_KMS("I2C nack (result=%d, size=%zu\n", ret, msg->size);
                        aux->i2c_nack_count++;
                        return -EREMOTEIO;
 
index 1a20db7..309b947 100644 (file)
@@ -1283,12 +1283,12 @@ struct drm_display_mode *drm_pick_cmdline_mode(struct drm_fb_helper_connector *f
                                                      int width, int height)
 {
        struct drm_cmdline_mode *cmdline_mode;
-       struct drm_display_mode *mode = NULL;
+       struct drm_display_mode *mode;
        bool prefer_non_interlace;
 
        cmdline_mode = &fb_helper_conn->connector->cmdline_mode;
        if (cmdline_mode->specified == false)
-               return mode;
+               return NULL;
 
        /* attempt to find a matching mode in the list of modes
         *  we have gotten so far, if not add a CVT mode that conforms
@@ -1297,7 +1297,7 @@ struct drm_display_mode *drm_pick_cmdline_mode(struct drm_fb_helper_connector *f
                goto create_mode;
 
        prefer_non_interlace = !cmdline_mode->interlace;
- again:
+again:
        list_for_each_entry(mode, &fb_helper_conn->connector->modes, head) {
                /* check width/height */
                if (mode->hdisplay != cmdline_mode->xres ||
index a6d773a..266dcd6 100644 (file)
@@ -524,8 +524,13 @@ static int drm_ioctl_permit(u32 flags, struct drm_file *file_priv)
        return 0;
 }
 
-#define DRM_IOCTL_DEF(ioctl, _func, _flags) \
-       [DRM_IOCTL_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, .cmd_drv = 0, .name = #ioctl}
+#define DRM_IOCTL_DEF(ioctl, _func, _flags)    \
+       [DRM_IOCTL_NR(ioctl)] = {               \
+               .cmd = ioctl,                   \
+               .func = _func,                  \
+               .flags = _flags,                \
+               .name = #ioctl                  \
+       }
 
 /** Ioctl table */
 static const struct drm_ioctl_desc drm_ioctls[] = {
@@ -663,39 +668,29 @@ long drm_ioctl(struct file *filp,
        int retcode = -EINVAL;
        char stack_kdata[128];
        char *kdata = NULL;
-       unsigned int usize, asize;
+       unsigned int usize, asize, drv_size;
 
        dev = file_priv->minor->dev;
 
        if (drm_device_is_unplugged(dev))
                return -ENODEV;
 
-       if ((nr >= DRM_CORE_IOCTL_COUNT) &&
-           ((nr < DRM_COMMAND_BASE) || (nr >= DRM_COMMAND_END)))
-               goto err_i1;
-       if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) &&
-           (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) {
-               u32 drv_size;
+       if (nr >= DRM_COMMAND_BASE && nr < DRM_COMMAND_END) {
+               /* driver ioctl */
+               if (nr - DRM_COMMAND_BASE >= dev->driver->num_ioctls)
+                       goto err_i1;
                ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE];
-               drv_size = _IOC_SIZE(ioctl->cmd_drv);
-               usize = asize = _IOC_SIZE(cmd);
-               if (drv_size > asize)
-                       asize = drv_size;
-               cmd = ioctl->cmd_drv;
-       }
-       else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE)) {
-               u32 drv_size;
-
+       } else {
+               /* core ioctl */
+               if (nr >= DRM_CORE_IOCTL_COUNT)
+                       goto err_i1;
                ioctl = &drm_ioctls[nr];
+       }
 
-               drv_size = _IOC_SIZE(ioctl->cmd);
-               usize = asize = _IOC_SIZE(cmd);
-               if (drv_size > asize)
-                       asize = drv_size;
-
-               cmd = ioctl->cmd;
-       } else
-               goto err_i1;
+       drv_size = _IOC_SIZE(ioctl->cmd);
+       usize = _IOC_SIZE(cmd);
+       asize = max(usize, drv_size);
+       cmd = ioctl->cmd;
 
        DRM_DEBUG("pid=%d, dev=0x%lx, auth=%d, %s\n",
                  task_pid_nr(current),
@@ -776,12 +771,13 @@ EXPORT_SYMBOL(drm_ioctl);
  */
 bool drm_ioctl_flags(unsigned int nr, unsigned int *flags)
 {
-       if ((nr >= DRM_COMMAND_END && nr < DRM_CORE_IOCTL_COUNT) ||
-           (nr < DRM_COMMAND_BASE)) {
-               *flags = drm_ioctls[nr].flags;
-               return true;
-       }
+       if (nr >= DRM_COMMAND_BASE && nr < DRM_COMMAND_END)
+               return false;
+
+       if (nr >= DRM_CORE_IOCTL_COUNT)
+               return false;
 
-       return false;
+       *flags = drm_ioctls[nr].flags;
+       return true;
 }
 EXPORT_SYMBOL(drm_ioctl_flags);
index 2cca85f..213b11e 100644 (file)
@@ -903,6 +903,12 @@ EXPORT_SYMBOL(drm_mode_duplicate);
  */
 bool drm_mode_equal(const struct drm_display_mode *mode1, const struct drm_display_mode *mode2)
 {
+       if (!mode1 && !mode2)
+               return true;
+
+       if (!mode1 || !mode2)
+               return false;
+
        /* do clock check convert to PICOS so fb modes get matched
         * the same */
        if (mode1->clock && mode2->clock) {
@@ -1148,7 +1154,7 @@ EXPORT_SYMBOL(drm_mode_sort);
 /**
  * drm_mode_connector_list_update - update the mode list for the connector
  * @connector: the connector to update
- * @merge_type_bits: whether to merge or overright type bits.
+ * @merge_type_bits: whether to merge or overwrite type bits
  *
  * This moves the modes from the @connector probed_modes list
  * to the actual mode list. It compares the probed mode against the current
index e13b9cb..620bb5c 100644 (file)
  */
 
 #define VMW_IOCTL_DEF(ioctl, func, flags) \
-  [DRM_IOCTL_NR(DRM_IOCTL_##ioctl) - DRM_COMMAND_BASE] = {DRM_##ioctl, flags, func, DRM_IOCTL_##ioctl}
+  [DRM_IOCTL_NR(DRM_IOCTL_##ioctl) - DRM_COMMAND_BASE] = {DRM_IOCTL_##ioctl, flags, func}
 
 /**
  * Ioctl definitions.
@@ -1044,7 +1044,7 @@ static long vmw_generic_ioctl(struct file *filp, unsigned int cmd,
                const struct drm_ioctl_desc *ioctl =
                        &vmw_ioctls[nr - DRM_COMMAND_BASE];
 
-               if (unlikely(ioctl->cmd_drv != cmd)) {
+               if (unlikely(ioctl->cmd != cmd)) {
                        DRM_ERROR("Invalid command format, ioctl %d\n",
                                  nr - DRM_COMMAND_BASE);
                        return -EINVAL;
index 63c0b01..62c4077 100644 (file)
@@ -253,7 +253,6 @@ struct drm_ioctl_desc {
        unsigned int cmd;
        int flags;
        drm_ioctl_t *func;
-       unsigned int cmd_drv;
        const char *name;
 };
 
@@ -262,8 +261,13 @@ struct drm_ioctl_desc {
  * ioctl, for use by drm_ioctl().
  */
 
-#define DRM_IOCTL_DEF_DRV(ioctl, _func, _flags)                        \
-       [DRM_IOCTL_NR(DRM_##ioctl)] = {.cmd = DRM_##ioctl, .func = _func, .flags = _flags, .cmd_drv = DRM_IOCTL_##ioctl, .name = #ioctl}
+#define DRM_IOCTL_DEF_DRV(ioctl, _func, _flags)                                \
+       [DRM_IOCTL_NR(DRM_IOCTL_##ioctl) - DRM_COMMAND_BASE] = {        \
+               .cmd = DRM_IOCTL_##ioctl,                               \
+               .func = _func,                                          \
+               .flags = _flags,                                        \
+               .name = #ioctl                                          \
+        }
 
 /* Event queued up for userspace to read */
 struct drm_pending_event {