/** * drm_warn_on_modeset_not_all_locked - check that all modeset locks are locked * @dev: device * * Useful as a debug assert. */ void drm_warn_on_modeset_not_all_locked(struct drm_device *dev) { struct drm_crtc *crtc; /* Locking is currently fubar in the panic handler. */ if (oops_in_progress) return; drm_for_each_crtc(crtc, dev) WARN_ON(!drm_modeset_is_locked(&crtc->mutex)); WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); WARN_ON(!mutex_is_locked(&dev->mode_config.mutex)); }
/* * Returns the connectors currently associated with a CRTC. This function * should be called twice: once with a NULL connector list to retrieve * the list size, and once with the properly allocated list to be filled in. */ static int get_connectors_for_crtc(struct drm_crtc *crtc, struct drm_connector **connector_list, int num_connectors) { struct drm_device *dev = crtc->dev; struct drm_connector *connector; int count = 0; /* * Note: Once we change the plane hooks to more fine-grained locking we * need to grab the connection_mutex here to be able to make these * checks. */ WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); drm_for_each_connector(connector, dev) { if (connector->encoder && connector->encoder->crtc == crtc) { if (connector_list != NULL && count < num_connectors) *(connector_list++) = connector; count++; } } return count; }
static void intel_fbc_update_state_cache(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; struct intel_fbc *fbc = &dev_priv->fbc; struct intel_fbc_state_cache *cache = &fbc->state_cache; struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); struct intel_plane_state *plane_state = to_intel_plane_state(crtc->base.primary->state); struct drm_framebuffer *fb = plane_state->base.fb; struct drm_i915_gem_object *obj; WARN_ON(!drm_modeset_is_locked(&crtc->base.mutex)); WARN_ON(!drm_modeset_is_locked(&crtc->base.primary->mutex)); cache->crtc.mode_flags = crtc_state->base.adjusted_mode.flags; if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) cache->crtc.hsw_bdw_pixel_rate = ilk_pipe_pixel_rate(crtc_state); cache->plane.rotation = plane_state->base.rotation; cache->plane.src_w = drm_rect_width(&plane_state->src) >> 16; cache->plane.src_h = drm_rect_height(&plane_state->src) >> 16; cache->plane.visible = plane_state->visible; if (!cache->plane.visible) return; obj = intel_fb_obj(fb); /* FIXME: We lack the proper locking here, so only run this on the * platforms that need. */ if (INTEL_INFO(dev_priv)->gen >= 5 && INTEL_INFO(dev_priv)->gen < 7) cache->fb.ilk_ggtt_offset = i915_gem_obj_ggtt_offset(obj); cache->fb.pixel_format = fb->pixel_format; cache->fb.stride = fb->pitches[0]; cache->fb.fence_reg = obj->fence_reg; cache->fb.tiling_mode = obj->tiling_mode; }
struct intel_shared_dpll_config * intel_atomic_get_shared_dpll_state(struct drm_atomic_state *s) { struct intel_atomic_state *state = to_intel_atomic_state(s); WARN_ON(!drm_modeset_is_locked(&s->dev->mode_config.connection_mutex)); if (!state->dpll_set) { state->dpll_set = true; intel_atomic_duplicate_dpll_state(to_i915(s->dev), state->shared_dpll); } return state->shared_dpll; }
/** * drm_atomic_state_clear - clear state object * @state: atomic state * * When the w/w mutex algorithm detects a deadlock we need to back off and drop * all locks. So someone else could sneak in and change the current modeset * configuration. Which means that all the state assembled in @state is no * longer an atomic update to the current state, but to some arbitrary earlier * state. Which could break assumptions the driver's ->atomic_check likely * relies on. * * Hence we must clear all cached state and completely start over, using this * function. */ void drm_atomic_state_clear(struct drm_atomic_state *state) { struct drm_device *dev = state->dev; struct drm_mode_config *config = &dev->mode_config; int i; DRM_DEBUG_ATOMIC("Clearing atomic state %p\n", state); for (i = 0; i < state->num_connector; i++) { struct drm_connector *connector = state->connectors[i]; if (!connector) continue; WARN_ON(!drm_modeset_is_locked(&config->connection_mutex)); connector->funcs->atomic_destroy_state(connector, state->connector_states[i]); state->connectors[i] = NULL; state->connector_states[i] = NULL; } for (i = 0; i < config->num_crtc; i++) { struct drm_crtc *crtc = state->crtcs[i]; if (!crtc) continue; crtc->funcs->atomic_destroy_state(crtc, state->crtc_states[i]); state->crtcs[i] = NULL; state->crtc_states[i] = NULL; } for (i = 0; i < config->num_total_plane; i++) { struct drm_plane *plane = state->planes[i]; if (!plane) continue; plane->funcs->atomic_destroy_state(plane, state->plane_states[i]); state->planes[i] = NULL; state->plane_states[i] = NULL; } }
static bool multiple_pipes_ok(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; struct drm_plane *primary = crtc->base.primary; struct intel_fbc *fbc = &dev_priv->fbc; enum pipe pipe = crtc->pipe; /* Don't even bother tracking anything we don't need. */ if (!no_fbc_on_multiple_pipes(dev_priv)) return true; WARN_ON(!drm_modeset_is_locked(&primary->mutex)); if (to_intel_plane_state(primary->state)->visible) fbc->visible_pipes_mask |= (1 << pipe); else fbc->visible_pipes_mask &= ~(1 << pipe); return (fbc->visible_pipes_mask & ~(1 << pipe)) != 0; }