Commit 53d8858b authored by Dave Airlie's avatar Dave Airlie

Merge tag 'topic/drm-misc-2015-03-31' of git://anongit.freedesktop.org/drm-intel into drm-next

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