Lines Matching +full:pre +full:- +full:scaler
1 // SPDX-License-Identifier: MIT
14 * -0.5. That matches how the hardware calculates the scaling
15 * factors (from top-left of the first pixel to bottom-right
26 * The same behaviour is observed on pre-SKL platforms as well.
28 * Theory behind the formula (note that we ignore sub-pixel
34 * -0.5
43 * -0.5
44 * | -0.375 (initial phase)
53 int phase = -0x8000; in skl_scaler_calc_phase()
57 phase += (sub - 1) * 0x8000 / sub; in skl_scaler_calc_phase()
62 * Hardware initial phase limited to [-0.5:1.5]. in skl_scaler_calc_phase()
66 WARN_ON(phase < -0x8000 || phase > 0x18000); in skl_scaler_calc_phase()
99 &crtc_state->scaler_state; in skl_update_scaler()
100 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); in skl_update_scaler()
101 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); in skl_update_scaler()
103 &crtc_state->hw.adjusted_mode; in skl_update_scaler()
114 * Scaling/fitting not supported in IF-ID mode in GEN9+ in skl_update_scaler()
116 * Once NV12 is enabled, handle it here while allocating scaler in skl_update_scaler()
119 if (DISPLAY_VER(dev_priv) >= 9 && crtc_state->hw.enable && in skl_update_scaler()
120 need_scaler && adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { in skl_update_scaler()
121 drm_dbg_kms(&dev_priv->drm, in skl_update_scaler()
122 "Pipe/Plane scaling not supported with IF-ID mode\n"); in skl_update_scaler()
123 return -EINVAL; in skl_update_scaler()
127 * if plane is being disabled or scaler is no more required or force detach in skl_update_scaler()
128 * - free scaler binded to this plane/crtc in skl_update_scaler()
129 * - in order to do this, update crtc->scaler_usage in skl_update_scaler()
131 * Here scaler state in crtc_state is set free so that in skl_update_scaler()
132 * scaler can be assigned to other user. Actual register in skl_update_scaler()
133 * update to free the scaler is done in plane/panel-fit programming. in skl_update_scaler()
134 * For this purpose crtc/plane_state->scaler_id isn't reset here. in skl_update_scaler()
138 scaler_state->scaler_users &= ~(1 << scaler_user); in skl_update_scaler()
139 scaler_state->scalers[*scaler_id].in_use = 0; in skl_update_scaler()
141 drm_dbg_kms(&dev_priv->drm, in skl_update_scaler()
143 "Staged freeing scaler id %d scaler_users = 0x%x\n", in skl_update_scaler()
144 crtc->pipe, scaler_user, *scaler_id, in skl_update_scaler()
145 scaler_state->scaler_users); in skl_update_scaler()
146 *scaler_id = -1; in skl_update_scaler()
153 drm_dbg_kms(&dev_priv->drm, in skl_update_scaler()
155 return -EINVAL; in skl_update_scaler()
167 drm_dbg_kms(&dev_priv->drm, in skl_update_scaler()
169 "size is out of scaler range\n", in skl_update_scaler()
170 crtc->pipe, scaler_user, src_w, src_h, in skl_update_scaler()
172 return -EINVAL; in skl_update_scaler()
175 /* mark this plane as a scaler user in crtc_state */ in skl_update_scaler()
176 scaler_state->scaler_users |= (1 << scaler_user); in skl_update_scaler()
177 drm_dbg_kms(&dev_priv->drm, "scaler_user index %u.%u: " in skl_update_scaler()
178 "staged scaling request for %ux%u->%ux%u scaler_users = 0x%x\n", in skl_update_scaler()
179 crtc->pipe, scaler_user, src_w, src_h, dst_w, dst_h, in skl_update_scaler()
180 scaler_state->scaler_users); in skl_update_scaler()
187 const struct drm_display_mode *pipe_mode = &crtc_state->hw.pipe_mode; in skl_update_scaler_crtc()
190 if (crtc_state->pch_pfit.enabled) { in skl_update_scaler_crtc()
191 width = drm_rect_width(&crtc_state->pch_pfit.dst); in skl_update_scaler_crtc()
192 height = drm_rect_height(&crtc_state->pch_pfit.dst); in skl_update_scaler_crtc()
194 width = pipe_mode->crtc_hdisplay; in skl_update_scaler_crtc()
195 height = pipe_mode->crtc_vdisplay; in skl_update_scaler_crtc()
197 return skl_update_scaler(crtc_state, !crtc_state->hw.active, in skl_update_scaler_crtc()
199 &crtc_state->scaler_state.scaler_id, in skl_update_scaler_crtc()
200 drm_rect_width(&crtc_state->pipe_src), in skl_update_scaler_crtc()
201 drm_rect_height(&crtc_state->pipe_src), in skl_update_scaler_crtc()
203 crtc_state->pch_pfit.enabled); in skl_update_scaler_crtc()
207 * skl_update_scaler_plane - Stages update to scaler state for a given plane.
208 * @crtc_state: crtc's scaler state
212 * 0 - scaler_usage updated successfully
213 * error - requested scaling cannot be supported or other error condition
219 to_intel_plane(plane_state->uapi.plane); in skl_update_scaler_plane()
220 struct drm_i915_private *dev_priv = to_i915(intel_plane->base.dev); in skl_update_scaler_plane()
221 struct drm_framebuffer *fb = plane_state->hw.fb; in skl_update_scaler_plane()
223 bool force_detach = !fb || !plane_state->uapi.visible; in skl_update_scaler_plane()
226 /* Pre-gen11 and SDR planes always need a scaler for planar formats. */ in skl_update_scaler_plane()
227 if (!icl_is_hdr_plane(dev_priv, intel_plane->id) && in skl_update_scaler_plane()
228 fb && intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier)) in skl_update_scaler_plane()
232 drm_plane_index(&intel_plane->base), in skl_update_scaler_plane()
233 &plane_state->scaler_id, in skl_update_scaler_plane()
234 drm_rect_width(&plane_state->uapi.src) >> 16, in skl_update_scaler_plane()
235 drm_rect_height(&plane_state->uapi.src) >> 16, in skl_update_scaler_plane()
236 drm_rect_width(&plane_state->uapi.dst), in skl_update_scaler_plane()
237 drm_rect_height(&plane_state->uapi.dst), in skl_update_scaler_plane()
238 fb ? fb->format : NULL, in skl_update_scaler_plane()
239 fb ? fb->modifier : 0, in skl_update_scaler_plane()
242 if (ret || plane_state->scaler_id < 0) in skl_update_scaler_plane()
246 if (plane_state->ckey.flags) { in skl_update_scaler_plane()
247 drm_dbg_kms(&dev_priv->drm, in skl_update_scaler_plane()
249 intel_plane->base.base.id, in skl_update_scaler_plane()
250 intel_plane->base.name); in skl_update_scaler_plane()
251 return -EINVAL; in skl_update_scaler_plane()
255 switch (fb->format->format) { in skl_update_scaler_plane()
289 drm_dbg_kms(&dev_priv->drm, in skl_update_scaler_plane()
291 intel_plane->base.base.id, intel_plane->base.name, in skl_update_scaler_plane()
292 fb->base.id, fb->format->format); in skl_update_scaler_plane()
293 return -EINVAL; in skl_update_scaler_plane()
310 * Theory behind setting nearest-neighbor integer scaling:
314 * represents the coefficient set for a phase (0-16).
316 * +------------+------------------------+------------------------+
318 * +------------+------------------------+------------------------+
320 * +------------+------------------------+------------------------+
322 * +------------+------------------------+------------------------+
324 * +------------+------------------------+------------------------+
326 * +------------+------------------------+------------------------+
328 * +------------+------------------------+------------------------+
330 * +------------+------------------------+------------------------+
332 * +------------+------------------------+------------------------+
334 * +------------+------------------------+------------------------+
336 * +------------+------------------------+------------------------+
338 * +------------+------------------------+------------------------+
340 * To enable nearest-neighbor scaling: program scaler coefficents with
400 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); in skl_pfit_enable()
401 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); in skl_pfit_enable()
403 &crtc_state->scaler_state; in skl_pfit_enable()
404 const struct drm_rect *dst = &crtc_state->pch_pfit.dst; in skl_pfit_enable()
406 enum pipe pipe = crtc->pipe; in skl_pfit_enable()
409 int x = dst->x1; in skl_pfit_enable()
410 int y = dst->y1; in skl_pfit_enable()
416 if (!crtc_state->pch_pfit.enabled) in skl_pfit_enable()
419 if (drm_WARN_ON(&dev_priv->drm, in skl_pfit_enable()
420 crtc_state->scaler_state.scaler_id < 0)) in skl_pfit_enable()
424 drm_rect_width(&crtc_state->pipe_src) << 16, in skl_pfit_enable()
425 drm_rect_height(&crtc_state->pipe_src) << 16); in skl_pfit_enable()
433 id = scaler_state->scaler_id; in skl_pfit_enable()
435 ps_ctrl = skl_scaler_get_filter_select(crtc_state->hw.scaling_filter, 0); in skl_pfit_enable()
436 ps_ctrl |= PS_SCALER_EN | scaler_state->scalers[id].mode; in skl_pfit_enable()
439 crtc_state->hw.scaling_filter); in skl_pfit_enable()
458 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); in skl_program_plane_scaler()
459 const struct drm_framebuffer *fb = plane_state->hw.fb; in skl_program_plane_scaler()
460 enum pipe pipe = plane->pipe; in skl_program_plane_scaler()
461 int scaler_id = plane_state->scaler_id; in skl_program_plane_scaler()
462 const struct intel_scaler *scaler = in skl_program_plane_scaler() local
463 &crtc_state->scaler_state.scalers[scaler_id]; in skl_program_plane_scaler()
464 int crtc_x = plane_state->uapi.dst.x1; in skl_program_plane_scaler()
465 int crtc_y = plane_state->uapi.dst.y1; in skl_program_plane_scaler()
466 u32 crtc_w = drm_rect_width(&plane_state->uapi.dst); in skl_program_plane_scaler()
467 u32 crtc_h = drm_rect_height(&plane_state->uapi.dst); in skl_program_plane_scaler()
473 hscale = drm_rect_calc_hscale(&plane_state->uapi.src, in skl_program_plane_scaler()
474 &plane_state->uapi.dst, in skl_program_plane_scaler()
476 vscale = drm_rect_calc_vscale(&plane_state->uapi.src, in skl_program_plane_scaler()
477 &plane_state->uapi.dst, in skl_program_plane_scaler()
480 /* TODO: handle sub-pixel coordinates */ in skl_program_plane_scaler()
481 if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) && in skl_program_plane_scaler()
482 !icl_is_hdr_plane(dev_priv, plane->id)) { in skl_program_plane_scaler()
498 ps_ctrl = skl_scaler_get_filter_select(plane_state->hw.scaling_filter, 0); in skl_program_plane_scaler()
499 ps_ctrl |= PS_SCALER_EN | PS_PLANE_SEL(plane->id) | scaler->mode; in skl_program_plane_scaler()
502 plane_state->hw.scaling_filter); in skl_program_plane_scaler()
517 struct drm_device *dev = crtc->base.dev; in skl_detach_scaler()
520 intel_de_write_fw(dev_priv, SKL_PS_CTRL(crtc->pipe, id), 0); in skl_detach_scaler()
521 intel_de_write_fw(dev_priv, SKL_PS_WIN_POS(crtc->pipe, id), 0); in skl_detach_scaler()
522 intel_de_write_fw(dev_priv, SKL_PS_WIN_SZ(crtc->pipe, id), 0); in skl_detach_scaler()
530 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); in skl_detach_scalers()
532 &crtc_state->scaler_state; in skl_detach_scalers()
536 for (i = 0; i < crtc->num_scalers; i++) { in skl_detach_scalers()
537 if (!scaler_state->scalers[i].in_use) in skl_detach_scalers()
544 struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc); in skl_scaler_disable()
547 for (i = 0; i < crtc->num_scalers; i++) in skl_scaler_disable()