diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index c2e9c5283136bc62f9b4baf18f46d204c41bc6d9..321e098ddf04091c29605c5d9ca725007f8d6d2e 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -92,7 +92,7 @@ drm_atomic_state_alloc(struct drm_device *dev) state->dev = dev; - DRM_DEBUG_KMS("Allocate atomic state %p\n", state); + DRM_DEBUG_ATOMIC("Allocate atomic state %p\n", state); return state; fail: @@ -122,7 +122,7 @@ void drm_atomic_state_clear(struct drm_atomic_state *state) struct drm_mode_config *config = &dev->mode_config; int i; - DRM_DEBUG_KMS("Clearing atomic state %p\n", state); + DRM_DEBUG_ATOMIC("Clearing atomic state %p\n", state); for (i = 0; i < state->num_connector; i++) { struct drm_connector *connector = state->connectors[i]; @@ -172,7 +172,7 @@ void drm_atomic_state_free(struct drm_atomic_state *state) { drm_atomic_state_clear(state); - DRM_DEBUG_KMS("Freeing atomic state %p\n", state); + DRM_DEBUG_ATOMIC("Freeing atomic state %p\n", state); kfree_state(state); } @@ -217,8 +217,8 @@ drm_atomic_get_crtc_state(struct drm_atomic_state *state, state->crtcs[index] = crtc; crtc_state->state = state; - DRM_DEBUG_KMS("Added [CRTC:%d] %p state to %p\n", - crtc->base.id, crtc_state, state); + DRM_DEBUG_ATOMIC("Added [CRTC:%d] %p state to %p\n", + crtc->base.id, crtc_state, state); return crtc_state; } @@ -293,8 +293,8 @@ static int drm_atomic_crtc_check(struct drm_crtc *crtc, */ if (state->active && !state->enable) { - DRM_DEBUG_KMS("[CRTC:%d] active without enabled\n", - crtc->base.id); + DRM_DEBUG_ATOMIC("[CRTC:%d] active without enabled\n", + crtc->base.id); return -EINVAL; } @@ -340,8 +340,8 @@ drm_atomic_get_plane_state(struct drm_atomic_state *state, state->planes[index] = plane; plane_state->state = state; - DRM_DEBUG_KMS("Added [PLANE:%d] %p state to %p\n", - plane->base.id, plane_state, state); + DRM_DEBUG_ATOMIC("Added [PLANE:%d] %p state to %p\n", + plane->base.id, plane_state, state); if (plane_state->crtc) { struct drm_crtc_state *crtc_state; @@ -477,10 +477,10 @@ static int drm_atomic_plane_check(struct drm_plane *plane, /* either *both* CRTC and FB must be set, or neither */ if (WARN_ON(state->crtc && !state->fb)) { - DRM_DEBUG_KMS("CRTC set but no FB\n"); + DRM_DEBUG_ATOMIC("CRTC set but no FB\n"); return -EINVAL; } else if (WARN_ON(state->fb && !state->crtc)) { - DRM_DEBUG_KMS("FB set but no CRTC\n"); + DRM_DEBUG_ATOMIC("FB set but no CRTC\n"); return -EINVAL; } @@ -490,7 +490,7 @@ static int drm_atomic_plane_check(struct drm_plane *plane, /* Check whether this plane is usable on this CRTC */ if (!(plane->possible_crtcs & drm_crtc_mask(state->crtc))) { - DRM_DEBUG_KMS("Invalid crtc for plane\n"); + DRM_DEBUG_ATOMIC("Invalid crtc for plane\n"); return -EINVAL; } @@ -499,8 +499,8 @@ static int drm_atomic_plane_check(struct drm_plane *plane, if (state->fb->pixel_format == plane->format_types[i]) break; if (i == plane->format_count) { - DRM_DEBUG_KMS("Invalid pixel format %s\n", - drm_get_format_name(state->fb->pixel_format)); + DRM_DEBUG_ATOMIC("Invalid pixel format %s\n", + drm_get_format_name(state->fb->pixel_format)); return -EINVAL; } @@ -509,9 +509,9 @@ static int drm_atomic_plane_check(struct drm_plane *plane, state->crtc_x > INT_MAX - (int32_t) state->crtc_w || state->crtc_h > INT_MAX || state->crtc_y > INT_MAX - (int32_t) state->crtc_h) { - DRM_DEBUG_KMS("Invalid CRTC coordinates %ux%u+%d+%d\n", - state->crtc_w, state->crtc_h, - state->crtc_x, state->crtc_y); + DRM_DEBUG_ATOMIC("Invalid CRTC coordinates %ux%u+%d+%d\n", + state->crtc_w, state->crtc_h, + state->crtc_x, state->crtc_y); return -ERANGE; } @@ -523,12 +523,12 @@ static int drm_atomic_plane_check(struct drm_plane *plane, state->src_x > fb_width - state->src_w || state->src_h > fb_height || state->src_y > fb_height - state->src_h) { - DRM_DEBUG_KMS("Invalid source coordinates " - "%u.%06ux%u.%06u+%u.%06u+%u.%06u\n", - state->src_w >> 16, ((state->src_w & 0xffff) * 15625) >> 10, - state->src_h >> 16, ((state->src_h & 0xffff) * 15625) >> 10, - state->src_x >> 16, ((state->src_x & 0xffff) * 15625) >> 10, - state->src_y >> 16, ((state->src_y & 0xffff) * 15625) >> 10); + DRM_DEBUG_ATOMIC("Invalid source coordinates " + "%u.%06ux%u.%06u+%u.%06u+%u.%06u\n", + state->src_w >> 16, ((state->src_w & 0xffff) * 15625) >> 10, + state->src_h >> 16, ((state->src_h & 0xffff) * 15625) >> 10, + state->src_x >> 16, ((state->src_x & 0xffff) * 15625) >> 10, + state->src_y >> 16, ((state->src_y & 0xffff) * 15625) >> 10); return -ENOSPC; } @@ -575,7 +575,7 @@ drm_atomic_get_connector_state(struct drm_atomic_state *state, * at most the array is a bit too large. */ if (index >= state->num_connector) { - DRM_DEBUG_KMS("Hot-added connector would overflow state array, restarting\n"); + DRM_DEBUG_ATOMIC("Hot-added connector would overflow state array, restarting\n"); return ERR_PTR(-EAGAIN); } @@ -590,8 +590,8 @@ drm_atomic_get_connector_state(struct drm_atomic_state *state, state->connectors[index] = connector; connector_state->state = state; - DRM_DEBUG_KMS("Added [CONNECTOR:%d] %p state to %p\n", - connector->base.id, connector_state, state); + DRM_DEBUG_ATOMIC("Added [CONNECTOR:%d] %p state to %p\n", + connector->base.id, connector_state, state); if (connector_state->crtc) { struct drm_crtc_state *crtc_state; @@ -752,10 +752,11 @@ drm_atomic_set_crtc_for_plane(struct drm_plane_state *plane_state, } if (crtc) - DRM_DEBUG_KMS("Link plane state %p to [CRTC:%d]\n", - plane_state, crtc->base.id); + DRM_DEBUG_ATOMIC("Link plane state %p to [CRTC:%d]\n", + plane_state, crtc->base.id); else - DRM_DEBUG_KMS("Link plane state %p to [NOCRTC]\n", plane_state); + DRM_DEBUG_ATOMIC("Link plane state %p to [NOCRTC]\n", + plane_state); return 0; } @@ -782,10 +783,11 @@ drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state, plane_state->fb = fb; if (fb) - DRM_DEBUG_KMS("Set [FB:%d] for plane state %p\n", - fb->base.id, plane_state); + DRM_DEBUG_ATOMIC("Set [FB:%d] for plane state %p\n", + fb->base.id, plane_state); else - DRM_DEBUG_KMS("Set [NOFB] for plane state %p\n", plane_state); + DRM_DEBUG_ATOMIC("Set [NOFB] for plane state %p\n", + plane_state); } EXPORT_SYMBOL(drm_atomic_set_fb_for_plane); @@ -818,11 +820,11 @@ drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state, conn_state->crtc = crtc; if (crtc) - DRM_DEBUG_KMS("Link connector state %p to [CRTC:%d]\n", - conn_state, crtc->base.id); + DRM_DEBUG_ATOMIC("Link connector state %p to [CRTC:%d]\n", + conn_state, crtc->base.id); else - DRM_DEBUG_KMS("Link connector state %p to [NOCRTC]\n", - conn_state); + DRM_DEBUG_ATOMIC("Link connector state %p to [NOCRTC]\n", + conn_state); return 0; } @@ -858,8 +860,8 @@ drm_atomic_add_affected_connectors(struct drm_atomic_state *state, if (ret) return ret; - DRM_DEBUG_KMS("Adding all current connectors for [CRTC:%d] to %p\n", - crtc->base.id, state); + DRM_DEBUG_ATOMIC("Adding all current connectors for [CRTC:%d] to %p\n", + crtc->base.id, state); /* * Changed connectors are already in @state, so only need to look at the @@ -901,8 +903,8 @@ drm_atomic_connectors_for_crtc(struct drm_atomic_state *state, num_connected_connectors++; } - DRM_DEBUG_KMS("State %p has %i connectors for [CRTC:%d]\n", - state, num_connected_connectors, crtc->base.id); + DRM_DEBUG_ATOMIC("State %p has %i connectors for [CRTC:%d]\n", + state, num_connected_connectors, crtc->base.id); return num_connected_connectors; } @@ -953,7 +955,7 @@ int drm_atomic_check_only(struct drm_atomic_state *state) int ncrtcs = config->num_crtc; int i, ret = 0; - DRM_DEBUG_KMS("checking %p\n", state); + DRM_DEBUG_ATOMIC("checking %p\n", state); for (i = 0; i < nplanes; i++) { struct drm_plane *plane = state->planes[i]; @@ -963,8 +965,8 @@ int drm_atomic_check_only(struct drm_atomic_state *state) ret = drm_atomic_plane_check(plane, state->plane_states[i]); if (ret) { - DRM_DEBUG_KMS("[PLANE:%d] atomic core check failed\n", - plane->base.id); + DRM_DEBUG_ATOMIC("[PLANE:%d] atomic core check failed\n", + plane->base.id); return ret; } } @@ -977,8 +979,8 @@ int drm_atomic_check_only(struct drm_atomic_state *state) ret = drm_atomic_crtc_check(crtc, state->crtc_states[i]); if (ret) { - DRM_DEBUG_KMS("[CRTC:%d] atomic core check failed\n", - crtc->base.id); + DRM_DEBUG_ATOMIC("[CRTC:%d] atomic core check failed\n", + crtc->base.id); return ret; } } @@ -996,8 +998,8 @@ int drm_atomic_check_only(struct drm_atomic_state *state) if (crtc_state->mode_changed || crtc_state->active_changed) { - DRM_DEBUG_KMS("[CRTC:%d] requires full modeset\n", - crtc->base.id); + DRM_DEBUG_ATOMIC("[CRTC:%d] requires full modeset\n", + crtc->base.id); return -EINVAL; } } @@ -1032,7 +1034,7 @@ int drm_atomic_commit(struct drm_atomic_state *state) if (ret) return ret; - DRM_DEBUG_KMS("commiting %p\n", state); + DRM_DEBUG_ATOMIC("commiting %p\n", state); return config->funcs->atomic_commit(state->dev, state, false); } @@ -1063,7 +1065,7 @@ int drm_atomic_async_commit(struct drm_atomic_state *state) if (ret) return ret; - DRM_DEBUG_KMS("commiting %p asynchronously\n", state); + DRM_DEBUG_ATOMIC("commiting %p asynchronously\n", state); return config->funcs->atomic_commit(state->dev, state, true); } diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 7e3a52b97c7d4154b82870f2c2d2ebb04298a5e0..28aa875105510b788b0b1f78d78aac916ee70913 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -116,9 +116,9 @@ steal_encoder(struct drm_atomic_state *state, */ WARN_ON(!drm_modeset_is_locked(&config->connection_mutex)); - DRM_DEBUG_KMS("[ENCODER:%d:%s] in use on [CRTC:%d], stealing it\n", - encoder->base.id, encoder->name, - encoder_crtc->base.id); + DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] in use on [CRTC:%d], stealing it\n", + encoder->base.id, encoder->name, + encoder_crtc->base.id); crtc_state = drm_atomic_get_crtc_state(state, encoder_crtc); if (IS_ERR(crtc_state)) @@ -130,9 +130,9 @@ steal_encoder(struct drm_atomic_state *state, if (connector->state->best_encoder != encoder) continue; - DRM_DEBUG_KMS("Stealing encoder from [CONNECTOR:%d:%s]\n", - connector->base.id, - connector->name); + DRM_DEBUG_ATOMIC("Stealing encoder from [CONNECTOR:%d:%s]\n", + connector->base.id, + connector->name); connector_state = drm_atomic_get_connector_state(state, connector); @@ -165,9 +165,9 @@ update_connector_routing(struct drm_atomic_state *state, int conn_idx) if (!connector) return 0; - DRM_DEBUG_KMS("Updating routing for [CONNECTOR:%d:%s]\n", - connector->base.id, - connector->name); + DRM_DEBUG_ATOMIC("Updating routing for [CONNECTOR:%d:%s]\n", + connector->base.id, + connector->name); if (connector->state->crtc != connector_state->crtc) { if (connector->state->crtc) { @@ -186,7 +186,7 @@ update_connector_routing(struct drm_atomic_state *state, int conn_idx) } if (!connector_state->crtc) { - DRM_DEBUG_KMS("Disabling [CONNECTOR:%d:%s]\n", + DRM_DEBUG_ATOMIC("Disabling [CONNECTOR:%d:%s]\n", connector->base.id, connector->name); @@ -199,19 +199,19 @@ update_connector_routing(struct drm_atomic_state *state, int conn_idx) new_encoder = funcs->best_encoder(connector); if (!new_encoder) { - DRM_DEBUG_KMS("No suitable encoder found for [CONNECTOR:%d:%s]\n", - connector->base.id, - connector->name); + DRM_DEBUG_ATOMIC("No suitable encoder found for [CONNECTOR:%d:%s]\n", + connector->base.id, + connector->name); return -EINVAL; } if (new_encoder == connector_state->best_encoder) { - DRM_DEBUG_KMS("[CONNECTOR:%d:%s] keeps [ENCODER:%d:%s], now on [CRTC:%d]\n", - connector->base.id, - connector->name, - new_encoder->base.id, - new_encoder->name, - connector_state->crtc->base.id); + DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] keeps [ENCODER:%d:%s], now on [CRTC:%d]\n", + connector->base.id, + connector->name, + new_encoder->base.id, + new_encoder->name, + connector_state->crtc->base.id); return 0; } @@ -222,9 +222,9 @@ update_connector_routing(struct drm_atomic_state *state, int conn_idx) if (encoder_crtc) { ret = steal_encoder(state, new_encoder, encoder_crtc); if (ret) { - DRM_DEBUG_KMS("Encoder stealing failed for [CONNECTOR:%d:%s]\n", - connector->base.id, - connector->name); + DRM_DEBUG_ATOMIC("Encoder stealing failed for [CONNECTOR:%d:%s]\n", + connector->base.id, + connector->name); return ret; } } @@ -235,12 +235,12 @@ update_connector_routing(struct drm_atomic_state *state, int conn_idx) crtc_state = state->crtc_states[idx]; crtc_state->mode_changed = true; - DRM_DEBUG_KMS("[CONNECTOR:%d:%s] using [ENCODER:%d:%s] on [CRTC:%d]\n", - connector->base.id, - connector->name, - new_encoder->base.id, - new_encoder->name, - connector_state->crtc->base.id); + DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] using [ENCODER:%d:%s] on [CRTC:%d]\n", + connector->base.id, + connector->name, + new_encoder->base.id, + new_encoder->name, + connector_state->crtc->base.id); return 0; } @@ -292,7 +292,7 @@ mode_fixup(struct drm_atomic_state *state) encoder->bridge, &crtc_state->mode, &crtc_state->adjusted_mode); if (!ret) { - DRM_DEBUG_KMS("Bridge fixup failed\n"); + DRM_DEBUG_ATOMIC("Bridge fixup failed\n"); return -EINVAL; } } @@ -301,16 +301,16 @@ mode_fixup(struct drm_atomic_state *state) ret = funcs->atomic_check(encoder, crtc_state, conn_state); if (ret) { - DRM_DEBUG_KMS("[ENCODER:%d:%s] check failed\n", - encoder->base.id, encoder->name); + DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] check failed\n", + encoder->base.id, encoder->name); return ret; } } else { ret = funcs->mode_fixup(encoder, &crtc_state->mode, &crtc_state->adjusted_mode); if (!ret) { - DRM_DEBUG_KMS("[ENCODER:%d:%s] fixup failed\n", - encoder->base.id, encoder->name); + DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] fixup failed\n", + encoder->base.id, encoder->name); return -EINVAL; } } @@ -330,8 +330,8 @@ mode_fixup(struct drm_atomic_state *state) ret = funcs->mode_fixup(crtc, &crtc_state->mode, &crtc_state->adjusted_mode); if (!ret) { - DRM_DEBUG_KMS("[CRTC:%d] fixup failed\n", - crtc->base.id); + DRM_DEBUG_ATOMIC("[CRTC:%d] fixup failed\n", + crtc->base.id); return -EINVAL; } } @@ -384,14 +384,14 @@ drm_atomic_helper_check_modeset(struct drm_device *dev, continue; if (!drm_mode_equal(&crtc->state->mode, &crtc_state->mode)) { - DRM_DEBUG_KMS("[CRTC:%d] mode changed\n", - crtc->base.id); + DRM_DEBUG_ATOMIC("[CRTC:%d] mode changed\n", + crtc->base.id); crtc_state->mode_changed = true; } if (crtc->state->enable != crtc_state->enable) { - DRM_DEBUG_KMS("[CRTC:%d] enable changed\n", - crtc->base.id); + DRM_DEBUG_ATOMIC("[CRTC:%d] enable changed\n", + crtc->base.id); crtc_state->mode_changed = true; } } @@ -428,17 +428,17 @@ drm_atomic_helper_check_modeset(struct drm_device *dev, * a full modeset because update_connector_routing force that. */ if (crtc->state->active != crtc_state->active) { - DRM_DEBUG_KMS("[CRTC:%d] active changed\n", - crtc->base.id); + DRM_DEBUG_ATOMIC("[CRTC:%d] active changed\n", + crtc->base.id); crtc_state->active_changed = true; } if (!needs_modeset(crtc_state)) continue; - DRM_DEBUG_KMS("[CRTC:%d] needs all connectors, enable: %c, active: %c\n", - crtc->base.id, - crtc_state->enable ? 'y' : 'n', + DRM_DEBUG_ATOMIC("[CRTC:%d] needs all connectors, enable: %c, active: %c\n", + crtc->base.id, + crtc_state->enable ? 'y' : 'n', crtc_state->active ? 'y' : 'n'); ret = drm_atomic_add_affected_connectors(state, crtc); @@ -449,8 +449,8 @@ drm_atomic_helper_check_modeset(struct drm_device *dev, crtc); if (crtc_state->enable != !!num_connectors) { - DRM_DEBUG_KMS("[CRTC:%d] enabled/connectors mismatch\n", - crtc->base.id); + DRM_DEBUG_ATOMIC("[CRTC:%d] enabled/connectors mismatch\n", + crtc->base.id); return -EINVAL; } @@ -497,8 +497,8 @@ drm_atomic_helper_check_planes(struct drm_device *dev, ret = funcs->atomic_check(plane, plane_state); if (ret) { - DRM_DEBUG_KMS("[PLANE:%d] atomic driver check failed\n", - plane->base.id); + DRM_DEBUG_ATOMIC("[PLANE:%d] atomic driver check failed\n", + plane->base.id); return ret; } } @@ -517,8 +517,8 @@ drm_atomic_helper_check_planes(struct drm_device *dev, ret = funcs->atomic_check(crtc, state->crtc_states[i]); if (ret) { - DRM_DEBUG_KMS("[CRTC:%d] atomic driver check failed\n", - crtc->base.id); + DRM_DEBUG_ATOMIC("[CRTC:%d] atomic driver check failed\n", + crtc->base.id); return ret; } } @@ -600,8 +600,8 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) funcs = encoder->helper_private; - DRM_DEBUG_KMS("disabling [ENCODER:%d:%s]\n", - encoder->base.id, encoder->name); + DRM_DEBUG_ATOMIC("disabling [ENCODER:%d:%s]\n", + encoder->base.id, encoder->name); /* * Each encoder has at most one connector (since we always steal @@ -639,8 +639,8 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) funcs = crtc->helper_private; - DRM_DEBUG_KMS("disabling [CRTC:%d]\n", - crtc->base.id); + DRM_DEBUG_ATOMIC("disabling [CRTC:%d]\n", + crtc->base.id); /* Right function depends upon target state. */ @@ -723,9 +723,9 @@ crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state) funcs = crtc->helper_private; - if (crtc->state->enable) { - DRM_DEBUG_KMS("modeset on [CRTC:%d]\n", - crtc->base.id); + if (crtc->state->enable && funcs->mode_set_nofb) { + DRM_DEBUG_ATOMIC("modeset on [CRTC:%d]\n", + crtc->base.id); funcs->mode_set_nofb(crtc); } @@ -752,14 +752,15 @@ crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state) if (!new_crtc_state->mode_changed) continue; - DRM_DEBUG_KMS("modeset on [ENCODER:%d:%s]\n", - encoder->base.id, encoder->name); + DRM_DEBUG_ATOMIC("modeset on [ENCODER:%d:%s]\n", + encoder->base.id, encoder->name); /* * Each encoder has at most one connector (since we always steal * it away), so we won't call call mode_set hooks twice. */ - funcs->mode_set(encoder, mode, adjusted_mode); + if (funcs->mode_set) + funcs->mode_set(encoder, mode, adjusted_mode); if (encoder->bridge && encoder->bridge->funcs->mode_set) encoder->bridge->funcs->mode_set(encoder->bridge, @@ -768,34 +769,44 @@ crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state) } /** - * drm_atomic_helper_commit_pre_planes - modeset commit before plane updates + * drm_atomic_helper_commit_modeset_disables - modeset commit to disable outputs * @dev: DRM device - * @state: atomic state + * @old_state: atomic state object with old state structures * - * This function commits the modeset changes that need to be committed before - * updating planes. It shuts down all the outputs that need to be shut down and + * This function shuts down all the outputs that need to be shut down and * prepares them (if required) with the new mode. + * + * For compatability with legacy crtc helpers this should be called before + * drm_atomic_helper_commit_planes(), which is what the default commit function + * does. But drivers with different needs can group the modeset commits together + * and do the plane commits at the end. This is useful for drivers doing runtime + * PM since planes updates then only happen when the CRTC is actually enabled. */ -void drm_atomic_helper_commit_pre_planes(struct drm_device *dev, - struct drm_atomic_state *state) +void drm_atomic_helper_commit_modeset_disables(struct drm_device *dev, + struct drm_atomic_state *old_state) { - disable_outputs(dev, state); - set_routing_links(dev, state); - crtc_set_mode(dev, state); + disable_outputs(dev, old_state); + set_routing_links(dev, old_state); + crtc_set_mode(dev, old_state); } -EXPORT_SYMBOL(drm_atomic_helper_commit_pre_planes); +EXPORT_SYMBOL(drm_atomic_helper_commit_modeset_disables); /** - * drm_atomic_helper_commit_post_planes - modeset commit after plane updates + * drm_atomic_helper_commit_modeset_enables - modeset commit to enable outputs * @dev: DRM device * @old_state: atomic state object with old state structures * - * This function commits the modeset changes that need to be committed after - * updating planes: It enables all the outputs with the new configuration which - * had to be turned off for the update. + * This function enables all the outputs with the new configuration which had to + * be turned off for the update. + * + * For compatability with legacy crtc helpers this should be called after + * drm_atomic_helper_commit_planes(), which is what the default commit function + * does. But drivers with different needs can group the modeset commits together + * and do the plane commits at the end. This is useful for drivers doing runtime + * PM since planes updates then only happen when the CRTC is actually enabled. */ -void drm_atomic_helper_commit_post_planes(struct drm_device *dev, - struct drm_atomic_state *old_state) +void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev, + struct drm_atomic_state *old_state) { int ncrtcs = old_state->dev->mode_config.num_crtc; int i; @@ -816,8 +827,8 @@ void drm_atomic_helper_commit_post_planes(struct drm_device *dev, funcs = crtc->helper_private; if (crtc->state->enable) { - DRM_DEBUG_KMS("enabling [CRTC:%d]\n", - crtc->base.id); + DRM_DEBUG_ATOMIC("enabling [CRTC:%d]\n", + crtc->base.id); if (funcs->enable) funcs->enable(crtc); @@ -842,8 +853,8 @@ void drm_atomic_helper_commit_post_planes(struct drm_device *dev, encoder = connector->state->best_encoder; funcs = encoder->helper_private; - DRM_DEBUG_KMS("enabling [ENCODER:%d:%s]\n", - encoder->base.id, encoder->name); + DRM_DEBUG_ATOMIC("enabling [ENCODER:%d:%s]\n", + encoder->base.id, encoder->name); /* * Each encoder has at most one connector (since we always steal @@ -861,7 +872,7 @@ void drm_atomic_helper_commit_post_planes(struct drm_device *dev, encoder->bridge->funcs->enable(encoder->bridge); } } -EXPORT_SYMBOL(drm_atomic_helper_commit_post_planes); +EXPORT_SYMBOL(drm_atomic_helper_commit_modeset_enables); static void wait_for_fences(struct drm_device *dev, struct drm_atomic_state *state) @@ -1030,11 +1041,11 @@ int drm_atomic_helper_commit(struct drm_device *dev, wait_for_fences(dev, state); - drm_atomic_helper_commit_pre_planes(dev, state); + drm_atomic_helper_commit_modeset_disables(dev, state); drm_atomic_helper_commit_planes(dev, state); - drm_atomic_helper_commit_post_planes(dev, state); + drm_atomic_helper_commit_modeset_enables(dev, state); drm_atomic_helper_wait_for_vblanks(dev, state); @@ -1678,12 +1689,13 @@ int drm_atomic_helper_set_config(struct drm_mode_set *set) EXPORT_SYMBOL(drm_atomic_helper_set_config); /** - * drm_atomic_helper_crtc_set_property - helper for crtc prorties + * drm_atomic_helper_crtc_set_property - helper for crtc properties * @crtc: DRM crtc * @property: DRM property * @val: value of property * - * Provides a default plane disablle handler using the atomic driver interface. + * Provides a default crtc set_property handler using the atomic driver + * interface. * * RETURNS: * Zero on success, error code on failure @@ -1737,12 +1749,13 @@ drm_atomic_helper_crtc_set_property(struct drm_crtc *crtc, EXPORT_SYMBOL(drm_atomic_helper_crtc_set_property); /** - * drm_atomic_helper_plane_set_property - helper for plane prorties + * drm_atomic_helper_plane_set_property - helper for plane properties * @plane: DRM plane * @property: DRM property * @val: value of property * - * Provides a default plane disable handler using the atomic driver interface. + * Provides a default plane set_property handler using the atomic driver + * interface. * * RETURNS: * Zero on success, error code on failure @@ -1796,12 +1809,13 @@ drm_atomic_helper_plane_set_property(struct drm_plane *plane, EXPORT_SYMBOL(drm_atomic_helper_plane_set_property); /** - * drm_atomic_helper_connector_set_property - helper for connector prorties + * drm_atomic_helper_connector_set_property - helper for connector properties * @connector: DRM connector * @property: DRM property * @val: value of property * - * Provides a default plane disablle handler using the atomic driver interface. + * Provides a default connector set_property handler using the atomic driver + * interface. * * RETURNS: * Zero on success, error code on failure diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 6b00173d1be4fd6c96f749a803dd23ab5495de88..4dacee645153c6346300b8c465f9c6181940eacf 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -2009,21 +2009,32 @@ int drm_mode_getcrtc(struct drm_device *dev, return -ENOENT; drm_modeset_lock_crtc(crtc, crtc->primary); - crtc_resp->x = crtc->x; - crtc_resp->y = crtc->y; crtc_resp->gamma_size = crtc->gamma_size; if (crtc->primary->fb) crtc_resp->fb_id = crtc->primary->fb->base.id; else crtc_resp->fb_id = 0; - if (crtc->enabled) { - - drm_crtc_convert_to_umode(&crtc_resp->mode, &crtc->mode); - crtc_resp->mode_valid = 1; + if (crtc->state) { + crtc_resp->x = crtc->primary->state->src_x >> 16; + crtc_resp->y = crtc->primary->state->src_y >> 16; + if (crtc->state->enable) { + drm_crtc_convert_to_umode(&crtc_resp->mode, &crtc->state->mode); + crtc_resp->mode_valid = 1; + } else { + crtc_resp->mode_valid = 0; + } } else { - crtc_resp->mode_valid = 0; + crtc_resp->x = crtc->x; + crtc_resp->y = crtc->y; + if (crtc->enabled) { + drm_crtc_convert_to_umode(&crtc_resp->mode, &crtc->mode); + crtc_resp->mode_valid = 1; + + } else { + crtc_resp->mode_valid = 0; + } } drm_modeset_unlock_crtc(crtc); diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 10574a0c3a55127cae5fb3e90d7b309defdcc681..c9f5453f20e7f94eca35e2989a6fd7f369bc490f 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -1052,7 +1052,7 @@ EXPORT_SYMBOL(drm_vblank_get); * Acquire a reference count on vblank events to avoid having them disabled * while in use. * - * This is the native kms version of drm_vblank_off(). + * This is the native kms version of drm_vblank_get(). * * Returns: * Zero on success, nonzero on failure. diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c index 19a9dd5408f35ee14998c6aeef9a9bf2af50aa51..011b8960fd75baab5fda39d768257625345bde7a 100644 --- a/drivers/gpu/drm/i915/intel_atomic.c +++ b/drivers/gpu/drm/i915/intel_atomic.c @@ -134,9 +134,9 @@ int intel_atomic_commit(struct drm_device *dev, * FIXME: The proper sequence here will eventually be: * * drm_atomic_helper_swap_state(dev, state) - * drm_atomic_helper_commit_pre_planes(dev, state); + * drm_atomic_helper_commit_modeset_disables(dev, state); * drm_atomic_helper_commit_planes(dev, state); - * drm_atomic_helper_commit_post_planes(dev, state); + * drm_atomic_helper_commit_modeset_enables(dev, state); * drm_atomic_helper_wait_for_vblanks(dev, state); * drm_atomic_helper_cleanup_planes(dev, state); * drm_atomic_state_free(state); diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c index 871aa2108dc694795e74f2b308031c849ad1a966..7c412292a0ffc66861a1115f9aa590ace903c5f6 100644 --- a/drivers/gpu/drm/msm/msm_atomic.c +++ b/drivers/gpu/drm/msm/msm_atomic.c @@ -96,11 +96,11 @@ static void complete_commit(struct msm_commit *c) kms->funcs->prepare_commit(kms, state); - drm_atomic_helper_commit_pre_planes(dev, state); + drm_atomic_helper_commit_modeset_disables(dev, state); drm_atomic_helper_commit_planes(dev, state); - drm_atomic_helper_commit_post_planes(dev, state); + drm_atomic_helper_commit_modeset_enables(dev, state); /* NOTE: _wait_for_vblanks() only waits for vblank on * enabled CRTCs. So we end up faulting when disabling diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index 7dd328d77996f77101d77e43f41049c66202bfcd..5f1880766110455034db47d1e21f4e89c7d13e3e 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -55,9 +55,9 @@ static void tegra_atomic_complete(struct tegra_drm *tegra, * current layout. */ - drm_atomic_helper_commit_pre_planes(drm, state); + drm_atomic_helper_commit_modeset_disables(drm, state); drm_atomic_helper_commit_planes(drm, state); - drm_atomic_helper_commit_post_planes(drm, state); + drm_atomic_helper_commit_modeset_enables(drm, state); drm_atomic_helper_wait_for_vblanks(drm, state); diff --git a/include/drm/drmP.h b/include/drm/drmP.h index e928625a9da0be41b7b03508a19f3df2cfb8acb5..52999ba9fbafe063df040ffa761c5ae7d9ca0b65 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -104,6 +104,9 @@ struct dma_buf_attachment; * PRIME: used in the prime code. * This is the category used by the DRM_DEBUG_PRIME() macro. * + * ATOMIC: used in the atomic code. + * This is the category used by the DRM_DEBUG_ATOMIC() macro. + * * Enabling verbose debug messages is done through the drm.debug parameter, * each category being enabled by a bit. * @@ -121,6 +124,7 @@ struct dma_buf_attachment; #define DRM_UT_DRIVER 0x02 #define DRM_UT_KMS 0x04 #define DRM_UT_PRIME 0x08 +#define DRM_UT_ATOMIC 0x10 extern __printf(2, 3) void drm_ut_debug_printk(const char *function_name, @@ -207,6 +211,11 @@ void drm_err(const char *format, ...); if (unlikely(drm_debug & DRM_UT_PRIME)) \ drm_ut_debug_printk(__func__, fmt, ##args); \ } while (0) +#define DRM_DEBUG_ATOMIC(fmt, args...) \ + do { \ + if (unlikely(drm_debug & DRM_UT_ATOMIC)) \ + drm_ut_debug_printk(__func__, fmt, ##args); \ + } while (0) /*@}*/ diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h index 8039d54a7441276f8fb529d42c0c0bfc35bfb192..829280b56874a4057f8c509739bb04f6466d4272 100644 --- a/include/drm/drm_atomic_helper.h +++ b/include/drm/drm_atomic_helper.h @@ -43,9 +43,9 @@ int drm_atomic_helper_commit(struct drm_device *dev, void drm_atomic_helper_wait_for_vblanks(struct drm_device *dev, struct drm_atomic_state *old_state); -void drm_atomic_helper_commit_pre_planes(struct drm_device *dev, - struct drm_atomic_state *state); -void drm_atomic_helper_commit_post_planes(struct drm_device *dev, +void drm_atomic_helper_commit_modeset_disables(struct drm_device *dev, + struct drm_atomic_state *state); +void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev, struct drm_atomic_state *old_state); int drm_atomic_helper_prepare_planes(struct drm_device *dev, diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h index c250a22b39aba09a58aa4d7843e6ae4e7033c524..92d5135b55d214e54cdff5bf83a33ceea7e83e2f 100644 --- a/include/drm/drm_crtc_helper.h +++ b/include/drm/drm_crtc_helper.h @@ -89,6 +89,7 @@ struct drm_crtc_helper_funcs { int (*mode_set)(struct drm_crtc *crtc, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode, int x, int y, struct drm_framebuffer *old_fb); + /* Actually set the mode for atomic helpers, optional */ void (*mode_set_nofb)(struct drm_crtc *crtc); /* Move the crtc on the current fb to the given position *optional* */ @@ -119,7 +120,7 @@ struct drm_crtc_helper_funcs { * @mode_fixup: try to fixup proposed mode for this connector * @prepare: part of the disable sequence, called before the CRTC modeset * @commit: called after the CRTC modeset - * @mode_set: set this mode + * @mode_set: set this mode, optional for atomic helpers * @get_crtc: return CRTC that the encoder is currently attached to * @detect: connection status detection * @disable: disable encoder when not in use (overrides DPMS off) diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 7e25030a6aa296e0eae8968e784abf963b7b5aa3..d4803224028f37311e8ed4299e62b9de0e3cfb33 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -92,6 +92,9 @@ # define DP_MSA_TIMING_PAR_IGNORED (1 << 6) /* eDP */ # define DP_OUI_SUPPORT (1 << 7) +#define DP_SUPPORTED_LINK_RATES 0x010 /*eDP 1.4*/ +#define DP_MAX_SUPPORTED_RATES 0x8 + #define DP_I2C_SPEED_CAP 0x00c /* DPI */ # define DP_I2C_SPEED_1K 0x01 # define DP_I2C_SPEED_5K 0x02 @@ -101,6 +104,7 @@ # define DP_I2C_SPEED_1M 0x20 #define DP_EDP_CONFIGURATION_CAP 0x00d /* XXX 1.2? */ +# define DP_DPCD_DISPLAY_CONTROL_CAPABLE (1 << 3) /* edp v1.2 or higher */ #define DP_TRAINING_AUX_RD_INTERVAL 0x00e /* XXX 1.2? */ /* Multiple stream transport */ @@ -221,6 +225,8 @@ # define DP_UP_REQ_EN (1 << 1) # define DP_UPSTREAM_IS_SRC (1 << 2) +#define DP_LINK_RATE_SET 0x115 + #define DP_PSR_EN_CFG 0x170 /* XXX 1.2? */ # define DP_PSR_ENABLE (1 << 0) # define DP_PSR_MAIN_LINK_ACTIVE (1 << 1) @@ -332,6 +338,8 @@ # define DP_SET_POWER_D3 0x2 # define DP_SET_POWER_MASK 0x3 +#define DP_EDP_DPCD_REV 0x700 + #define DP_SIDEBAND_MSG_DOWN_REQ_BASE 0x1000 /* 1.2 MST */ #define DP_SIDEBAND_MSG_UP_REP_BASE 0x1200 /* 1.2 MST */ #define DP_SIDEBAND_MSG_DOWN_REP_BASE 0x1400 /* 1.2 MST */ diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h index d92f6dd1fb11fdfc5f1f648e21b9a8e9dc6f9322..0616188c7801c1f90e07bbd94f380a8233afb48d 100644 --- a/include/drm/drm_modes.h +++ b/include/drm/drm_modes.h @@ -92,7 +92,7 @@ enum drm_mode_status { #define CRTC_STEREO_DOUBLE (1 << 1) /* adjust timings for stereo modes */ #define CRTC_NO_DBLSCAN (1 << 2) /* don't adjust doublescan */ #define CRTC_NO_VSCAN (1 << 3) /* don't adjust doublescan */ -#define CRTC_STEREO_DOUBLE_ONLY (CRTC_NO_DBLSCAN | CRTC_NO_VSCAN) +#define CRTC_STEREO_DOUBLE_ONLY (CRTC_STEREO_DOUBLE | CRTC_NO_DBLSCAN | CRTC_NO_VSCAN) #define DRM_MODE_FLAG_3D_MAX DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF