static int intel_dp_mst_atomic_check(struct drm_connector *connector, struct drm_connector_state *new_conn_state) { struct drm_atomic_state *state = new_conn_state->state; struct drm_connector_state *old_conn_state; struct drm_crtc *old_crtc; struct drm_crtc_state *crtc_state; int slots, ret = 0; old_conn_state = drm_atomic_get_old_connector_state(state, connector); old_crtc = old_conn_state->crtc; if (!old_crtc) return ret; crtc_state = drm_atomic_get_new_crtc_state(state, old_crtc); slots = to_intel_crtc_state(crtc_state)->dp_m_n.tu; if (drm_atomic_crtc_needs_modeset(crtc_state) && slots > 0) { struct drm_dp_mst_topology_mgr *mgr; struct drm_encoder *old_encoder; old_encoder = old_conn_state->best_encoder; mgr = &enc_to_mst(old_encoder)->primary->dp.mst_mgr; ret = drm_dp_atomic_release_vcpi_slots(state, mgr, slots); if (ret) DRM_DEBUG_KMS("failed releasing %d vcpi slots:%d\n", slots, ret); else to_intel_crtc_state(crtc_state)->dp_m_n.tu = 0; } return ret; }
static int intel_plane_atomic_check(struct drm_plane *plane, struct drm_plane_state *new_plane_state) { struct drm_atomic_state *state = new_plane_state->state; const struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane); struct drm_crtc *crtc = new_plane_state->crtc ?: old_plane_state->crtc; const struct drm_crtc_state *old_crtc_state; struct drm_crtc_state *new_crtc_state; if (!crtc) return 0; old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc); new_crtc_state = drm_atomic_get_new_crtc_state(state, crtc); return intel_plane_atomic_check_with_state(to_intel_crtc_state(old_crtc_state), to_intel_crtc_state(new_crtc_state), to_intel_plane_state(old_plane_state), to_intel_plane_state(new_plane_state)); }
/** * intel_fbc_choose_crtc - select a CRTC to enable FBC on * @dev_priv: i915 device instance * @state: the atomic state structure * * This function looks at the proposed state for CRTCs and planes, then chooses * which pipe is going to have FBC by setting intel_crtc_state->enable_fbc to * true. * * Later, intel_fbc_enable is going to look for state->enable_fbc and then maybe * enable FBC for the chosen CRTC. If it does, it will set dev_priv->fbc.crtc. */ void intel_fbc_choose_crtc(struct drm_i915_private *dev_priv, struct drm_atomic_state *state) { struct intel_fbc *fbc = &dev_priv->fbc; struct drm_crtc *crtc; struct drm_crtc_state *crtc_state; struct drm_plane *plane; struct drm_plane_state *plane_state; bool fbc_crtc_present = false; int i, j; mutex_lock(&fbc->lock); for_each_crtc_in_state(state, crtc, crtc_state, i) { if (fbc->crtc == to_intel_crtc(crtc)) { fbc_crtc_present = true; break; } } /* This atomic commit doesn't involve the CRTC currently tied to FBC. */ if (!fbc_crtc_present && fbc->crtc != NULL) goto out; /* Simply choose the first CRTC that is compatible and has a visible * plane. We could go for fancier schemes such as checking the plane * size, but this would just affect the few platforms that don't tie FBC * to pipe or plane A. */ for_each_plane_in_state(state, plane, plane_state, i) { struct intel_plane_state *intel_plane_state = to_intel_plane_state(plane_state); if (!intel_plane_state->visible) continue; for_each_crtc_in_state(state, crtc, crtc_state, j) { struct intel_crtc_state *intel_crtc_state = to_intel_crtc_state(crtc_state); if (plane_state->crtc != crtc) continue; if (!intel_fbc_can_choose(to_intel_crtc(crtc))) break; intel_crtc_state->enable_fbc = true; goto out; } } out: mutex_unlock(&fbc->lock); }
static void intel_plane_atomic_update(struct drm_plane *plane, struct drm_plane_state *old_state) { struct intel_plane *intel_plane = to_intel_plane(plane); struct intel_plane_state *intel_state = to_intel_plane_state(plane->state); struct drm_crtc *crtc = plane->state->crtc ?: old_state->crtc; if (intel_state->visible) intel_plane->update_plane(plane, to_intel_crtc_state(crtc->state), intel_state); else intel_plane->disable_plane(plane, crtc); }
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; }
static int intel_plane_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) { struct drm_crtc *crtc = state->crtc; struct intel_crtc *intel_crtc; struct intel_crtc_state *crtc_state; struct intel_plane *intel_plane = to_intel_plane(plane); struct intel_plane_state *intel_state = to_intel_plane_state(state); struct drm_crtc_state *drm_crtc_state; int ret; crtc = crtc ? crtc : plane->state->crtc; intel_crtc = to_intel_crtc(crtc); /* * Both crtc and plane->crtc could be NULL if we're updating a * property while the plane is disabled. We don't actually have * anything driver-specific we need to test in that case, so * just return success. */ if (!crtc) return 0; drm_crtc_state = drm_atomic_get_existing_crtc_state(state->state, crtc); if (WARN_ON(!drm_crtc_state)) return -EINVAL; crtc_state = to_intel_crtc_state(drm_crtc_state); /* * The original src/dest coordinates are stored in state->base, but * we want to keep another copy internal to our driver that we can * clip/modify ourselves. */ intel_state->src.x1 = state->src_x; intel_state->src.y1 = state->src_y; intel_state->src.x2 = state->src_x + state->src_w; intel_state->src.y2 = state->src_y + state->src_h; intel_state->dst.x1 = state->crtc_x; intel_state->dst.y1 = state->crtc_y; intel_state->dst.x2 = state->crtc_x + state->crtc_w; intel_state->dst.y2 = state->crtc_y + state->crtc_h; /* Clip all planes to CRTC size, or 0x0 if CRTC is disabled */ intel_state->clip.x1 = 0; intel_state->clip.y1 = 0; intel_state->clip.x2 = crtc_state->base.enable ? crtc_state->pipe_src_w : 0; intel_state->clip.y2 = crtc_state->base.enable ? crtc_state->pipe_src_h : 0; if (state->fb && intel_rotation_90_or_270(state->rotation)) { if (!(state->fb->modifier[0] == I915_FORMAT_MOD_Y_TILED || state->fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED)) { DRM_DEBUG_KMS("Y/Yf tiling required for 90/270!\n"); return -EINVAL; } /* * 90/270 is not allowed with RGB64 16:16:16:16, * RGB 16-bit 5:6:5, and Indexed 8-bit. * TBD: Add RGB64 case once its added in supported format list. */ switch (state->fb->pixel_format) { case DRM_FORMAT_C8: case DRM_FORMAT_RGB565: DRM_DEBUG_KMS("Unsupported pixel format %s for 90/270!\n", drm_get_format_name(state->fb->pixel_format)); return -EINVAL; default: break; } } intel_state->visible = false; ret = intel_plane->check_plane(plane, crtc_state, intel_state); if (ret) return ret; return intel_plane_atomic_calc_changes(&crtc_state->base, state); }