Lines Matching +full:pre +full:- +full:scaling
1 // SPDX-License-Identifier: MIT
13 * -0.5. That matches how the hardware calculates the scaling
14 * factors (from top-left of the first pixel to bottom-right
25 * The same behaviour is observed on pre-SKL platforms as well.
27 * Theory behind the formula (note that we ignore sub-pixel
33 * -0.5
42 * -0.5
43 * | -0.375 (initial phase)
52 int phase = -0x8000; in skl_scaler_calc_phase()
56 phase += (sub - 1) * 0x8000 / sub; in skl_scaler_calc_phase()
61 * Hardware initial phase limited to [-0.5:1.5]. in skl_scaler_calc_phase()
65 WARN_ON(phase < -0x8000 || phase > 0x18000); in skl_scaler_calc_phase()
98 &crtc_state->scaler_state; in skl_update_scaler()
99 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); in skl_update_scaler()
100 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); in skl_update_scaler()
102 &crtc_state->hw.adjusted_mode; in skl_update_scaler()
113 * Scaling/fitting not supported in IF-ID mode in GEN9+ in skl_update_scaler()
118 if (DISPLAY_VER(dev_priv) >= 9 && crtc_state->hw.enable && in skl_update_scaler()
119 need_scaler && adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { in skl_update_scaler()
120 drm_dbg_kms(&dev_priv->drm, in skl_update_scaler()
121 "Pipe/Plane scaling not supported with IF-ID mode\n"); in skl_update_scaler()
122 return -EINVAL; in skl_update_scaler()
127 * - free scaler binded to this plane/crtc in skl_update_scaler()
128 * - in order to do this, update crtc->scaler_usage in skl_update_scaler()
132 * update to free the scaler is done in plane/panel-fit programming. in skl_update_scaler()
133 * For this purpose crtc/plane_state->scaler_id isn't reset here. in skl_update_scaler()
137 scaler_state->scaler_users &= ~(1 << scaler_user); in skl_update_scaler()
138 scaler_state->scalers[*scaler_id].in_use = 0; in skl_update_scaler()
140 drm_dbg_kms(&dev_priv->drm, in skl_update_scaler()
143 crtc->pipe, scaler_user, *scaler_id, in skl_update_scaler()
144 scaler_state->scaler_users); in skl_update_scaler()
145 *scaler_id = -1; in skl_update_scaler()
152 drm_dbg_kms(&dev_priv->drm, in skl_update_scaler()
154 return -EINVAL; in skl_update_scaler()
166 drm_dbg_kms(&dev_priv->drm, in skl_update_scaler()
169 crtc->pipe, scaler_user, src_w, src_h, in skl_update_scaler()
171 return -EINVAL; in skl_update_scaler()
175 scaler_state->scaler_users |= (1 << scaler_user); in skl_update_scaler()
176 drm_dbg_kms(&dev_priv->drm, "scaler_user index %u.%u: " in skl_update_scaler()
177 "staged scaling request for %ux%u->%ux%u scaler_users = 0x%x\n", in skl_update_scaler()
178 crtc->pipe, scaler_user, src_w, src_h, dst_w, dst_h, in skl_update_scaler()
179 scaler_state->scaler_users); in skl_update_scaler()
186 const struct drm_display_mode *pipe_mode = &crtc_state->hw.pipe_mode; in skl_update_scaler_crtc()
189 if (crtc_state->pch_pfit.enabled) { in skl_update_scaler_crtc()
190 width = drm_rect_width(&crtc_state->pch_pfit.dst); in skl_update_scaler_crtc()
191 height = drm_rect_height(&crtc_state->pch_pfit.dst); in skl_update_scaler_crtc()
193 width = pipe_mode->crtc_hdisplay; in skl_update_scaler_crtc()
194 height = pipe_mode->crtc_vdisplay; in skl_update_scaler_crtc()
196 return skl_update_scaler(crtc_state, !crtc_state->hw.active, in skl_update_scaler_crtc()
198 &crtc_state->scaler_state.scaler_id, in skl_update_scaler_crtc()
199 crtc_state->pipe_src_w, crtc_state->pipe_src_h, in skl_update_scaler_crtc()
201 crtc_state->pch_pfit.enabled); in skl_update_scaler_crtc()
205 * skl_update_scaler_plane - Stages update to scaler state for a given plane.
210 * 0 - scaler_usage updated successfully
211 * error - requested scaling cannot be supported or other error condition
217 to_intel_plane(plane_state->uapi.plane); in skl_update_scaler_plane()
218 struct drm_i915_private *dev_priv = to_i915(intel_plane->base.dev); in skl_update_scaler_plane()
219 struct drm_framebuffer *fb = plane_state->hw.fb; in skl_update_scaler_plane()
221 bool force_detach = !fb || !plane_state->uapi.visible; in skl_update_scaler_plane()
224 /* Pre-gen11 and SDR planes always need a scaler for planar formats. */ in skl_update_scaler_plane()
225 if (!icl_is_hdr_plane(dev_priv, intel_plane->id) && in skl_update_scaler_plane()
226 fb && intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier)) in skl_update_scaler_plane()
230 drm_plane_index(&intel_plane->base), in skl_update_scaler_plane()
231 &plane_state->scaler_id, in skl_update_scaler_plane()
232 drm_rect_width(&plane_state->uapi.src) >> 16, in skl_update_scaler_plane()
233 drm_rect_height(&plane_state->uapi.src) >> 16, in skl_update_scaler_plane()
234 drm_rect_width(&plane_state->uapi.dst), in skl_update_scaler_plane()
235 drm_rect_height(&plane_state->uapi.dst), in skl_update_scaler_plane()
236 fb ? fb->format : NULL, in skl_update_scaler_plane()
237 fb ? fb->modifier : 0, in skl_update_scaler_plane()
240 if (ret || plane_state->scaler_id < 0) in skl_update_scaler_plane()
244 if (plane_state->ckey.flags) { in skl_update_scaler_plane()
245 drm_dbg_kms(&dev_priv->drm, in skl_update_scaler_plane()
246 "[PLANE:%d:%s] scaling with color key not allowed", in skl_update_scaler_plane()
247 intel_plane->base.base.id, in skl_update_scaler_plane()
248 intel_plane->base.name); in skl_update_scaler_plane()
249 return -EINVAL; in skl_update_scaler_plane()
253 switch (fb->format->format) { in skl_update_scaler_plane()
287 drm_dbg_kms(&dev_priv->drm, in skl_update_scaler_plane()
288 "[PLANE:%d:%s] FB:%d unsupported scaling format 0x%x\n", in skl_update_scaler_plane()
289 intel_plane->base.base.id, intel_plane->base.name, in skl_update_scaler_plane()
290 fb->base.id, fb->format->format); in skl_update_scaler_plane()
291 return -EINVAL; in skl_update_scaler_plane()
308 * Theory behind setting nearest-neighbor integer scaling:
312 * represents the coefficient set for a phase (0-16).
314 * +------------+------------------------+------------------------+
316 * +------------+------------------------+------------------------+
318 * +------------+------------------------+------------------------+
320 * +------------+------------------------+------------------------+
322 * +------------+------------------------+------------------------+
324 * +------------+------------------------+------------------------+
326 * +------------+------------------------+------------------------+
328 * +------------+------------------------+------------------------+
330 * +------------+------------------------+------------------------+
332 * +------------+------------------------+------------------------+
334 * +------------+------------------------+------------------------+
336 * +------------+------------------------+------------------------+
338 * To enable nearest-neighbor scaling: program scaler coefficents with
398 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); in skl_pfit_enable()
399 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); in skl_pfit_enable()
401 &crtc_state->scaler_state; in skl_pfit_enable()
403 .x2 = crtc_state->pipe_src_w << 16, in skl_pfit_enable()
404 .y2 = crtc_state->pipe_src_h << 16, in skl_pfit_enable()
406 const struct drm_rect *dst = &crtc_state->pch_pfit.dst; in skl_pfit_enable()
408 enum pipe pipe = crtc->pipe; in skl_pfit_enable()
411 int x = dst->x1; in skl_pfit_enable()
412 int y = dst->y1; in skl_pfit_enable()
418 if (!crtc_state->pch_pfit.enabled) in skl_pfit_enable()
421 if (drm_WARN_ON(&dev_priv->drm, in skl_pfit_enable()
422 crtc_state->scaler_state.scaler_id < 0)) in skl_pfit_enable()
431 id = scaler_state->scaler_id; in skl_pfit_enable()
433 ps_ctrl = skl_scaler_get_filter_select(crtc_state->hw.scaling_filter, 0); in skl_pfit_enable()
434 ps_ctrl |= PS_SCALER_EN | scaler_state->scalers[id].mode; in skl_pfit_enable()
436 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); in skl_pfit_enable()
439 crtc_state->hw.scaling_filter); in skl_pfit_enable()
452 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); in skl_pfit_enable()
460 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); in skl_program_plane_scaler()
461 const struct drm_framebuffer *fb = plane_state->hw.fb; in skl_program_plane_scaler()
462 enum pipe pipe = plane->pipe; in skl_program_plane_scaler()
463 int scaler_id = plane_state->scaler_id; in skl_program_plane_scaler()
465 &crtc_state->scaler_state.scalers[scaler_id]; in skl_program_plane_scaler()
466 int crtc_x = plane_state->uapi.dst.x1; in skl_program_plane_scaler()
467 int crtc_y = plane_state->uapi.dst.y1; in skl_program_plane_scaler()
468 u32 crtc_w = drm_rect_width(&plane_state->uapi.dst); in skl_program_plane_scaler()
469 u32 crtc_h = drm_rect_height(&plane_state->uapi.dst); in skl_program_plane_scaler()
475 hscale = drm_rect_calc_hscale(&plane_state->uapi.src, in skl_program_plane_scaler()
476 &plane_state->uapi.dst, in skl_program_plane_scaler()
478 vscale = drm_rect_calc_vscale(&plane_state->uapi.src, in skl_program_plane_scaler()
479 &plane_state->uapi.dst, in skl_program_plane_scaler()
482 /* TODO: handle sub-pixel coordinates */ in skl_program_plane_scaler()
483 if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) && in skl_program_plane_scaler()
484 !icl_is_hdr_plane(dev_priv, plane->id)) { in skl_program_plane_scaler()
500 ps_ctrl = skl_scaler_get_filter_select(plane_state->hw.scaling_filter, 0); in skl_program_plane_scaler()
501 ps_ctrl |= PS_SCALER_EN | PS_PLANE_SEL(plane->id) | scaler->mode; in skl_program_plane_scaler()
504 plane_state->hw.scaling_filter); in skl_program_plane_scaler()
519 struct drm_device *dev = crtc->base.dev; in skl_detach_scaler()
523 spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); in skl_detach_scaler()
525 intel_de_write_fw(dev_priv, SKL_PS_CTRL(crtc->pipe, id), 0); in skl_detach_scaler()
526 intel_de_write_fw(dev_priv, SKL_PS_WIN_POS(crtc->pipe, id), 0); in skl_detach_scaler()
527 intel_de_write_fw(dev_priv, SKL_PS_WIN_SZ(crtc->pipe, id), 0); in skl_detach_scaler()
529 spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); in skl_detach_scaler()
537 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); in skl_detach_scalers()
539 &crtc_state->scaler_state; in skl_detach_scalers()
543 for (i = 0; i < crtc->num_scalers; i++) { in skl_detach_scalers()
544 if (!scaler_state->scalers[i].in_use) in skl_detach_scalers()
551 struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc); in skl_scaler_disable()
554 for (i = 0; i < crtc->num_scalers; i++) in skl_scaler_disable()