Message ID | 20241016143134.26903-3-ville.syrjala@linux.intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | drm/i915/pfit: Panel fitter stuff | expand |
On Wed, 16 Oct 2024, Ville Syrjala <ville.syrjala@linux.intel.com> wrote: > From: Ville Syrjälä <ville.syrjala@linux.intel.com> > > Make sure we're not exceeding the max scaling factors for the panel > fitter on ILK-BDW. SKL+ is skipped here since this is all supposed to > be handled by the unified scaler code. > > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Jani Nikula <jani.nikula@intel.com> > --- > drivers/gpu/drm/i915/display/intel_panel.c | 39 ++++++++++++++++++++++ > 1 file changed, 39 insertions(+) > > diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c > index b77017144818..fb7def772376 100644 > --- a/drivers/gpu/drm/i915/display/intel_panel.c > +++ b/drivers/gpu/drm/i915/display/intel_panel.c > @@ -421,6 +421,41 @@ static int intel_pch_pfit_check_src_size(const struct intel_crtc_state *crtc_sta > return 0; > } > > +static int intel_pch_pfit_check_scaling(const struct intel_crtc_state *crtc_state) > +{ > + struct intel_display *display = to_intel_display(crtc_state); > + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); > + const struct drm_rect *dst = &crtc_state->pch_pfit.dst; > + int pipe_src_w = drm_rect_width(&crtc_state->pipe_src); > + int pipe_src_h = drm_rect_height(&crtc_state->pipe_src); > + int hscale, vscale, max_scale = 0x12000; /* 1.125 */ > + struct drm_rect src; > + > + drm_rect_init(&src, 0, 0, pipe_src_w << 16, pipe_src_h << 16); > + > + hscale = drm_rect_calc_hscale(&src, dst, 0, max_scale); > + if (hscale < 0) { > + drm_dbg_kms(display->drm, > + "[CRTC:%d:%s] pfit horizontal downscaling (%d->%d) exceeds max (0x%x)\n", > + crtc->base.base.id, crtc->base.name, > + pipe_src_w, drm_rect_width(dst), > + max_scale); > + return hscale; > + } > + > + vscale = drm_rect_calc_vscale(&src, dst, 0, max_scale); > + if (vscale < 0) { > + drm_dbg_kms(display->drm, > + "[CRTC:%d:%s] pfit vertical downscaling (%d->%d) exceeds max (0x%x)\n", > + crtc->base.base.id, crtc->base.name, > + pipe_src_h, drm_rect_height(dst), > + max_scale); > + return vscale; > + } > + > + return 0; > +} > + > /* adjusted_mode has been preset to be the panel's fixed mode */ > static int pch_panel_fitting(struct intel_crtc_state *crtc_state, > const struct drm_connector_state *conn_state) > @@ -503,6 +538,10 @@ static int pch_panel_fitting(struct intel_crtc_state *crtc_state, > if (ret) > return ret; > > + ret = intel_pch_pfit_check_scaling(crtc_state); > + if (ret) > + return ret; > + > return 0; > }
diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c index b77017144818..fb7def772376 100644 --- a/drivers/gpu/drm/i915/display/intel_panel.c +++ b/drivers/gpu/drm/i915/display/intel_panel.c @@ -421,6 +421,41 @@ static int intel_pch_pfit_check_src_size(const struct intel_crtc_state *crtc_sta return 0; } +static int intel_pch_pfit_check_scaling(const struct intel_crtc_state *crtc_state) +{ + struct intel_display *display = to_intel_display(crtc_state); + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + const struct drm_rect *dst = &crtc_state->pch_pfit.dst; + int pipe_src_w = drm_rect_width(&crtc_state->pipe_src); + int pipe_src_h = drm_rect_height(&crtc_state->pipe_src); + int hscale, vscale, max_scale = 0x12000; /* 1.125 */ + struct drm_rect src; + + drm_rect_init(&src, 0, 0, pipe_src_w << 16, pipe_src_h << 16); + + hscale = drm_rect_calc_hscale(&src, dst, 0, max_scale); + if (hscale < 0) { + drm_dbg_kms(display->drm, + "[CRTC:%d:%s] pfit horizontal downscaling (%d->%d) exceeds max (0x%x)\n", + crtc->base.base.id, crtc->base.name, + pipe_src_w, drm_rect_width(dst), + max_scale); + return hscale; + } + + vscale = drm_rect_calc_vscale(&src, dst, 0, max_scale); + if (vscale < 0) { + drm_dbg_kms(display->drm, + "[CRTC:%d:%s] pfit vertical downscaling (%d->%d) exceeds max (0x%x)\n", + crtc->base.base.id, crtc->base.name, + pipe_src_h, drm_rect_height(dst), + max_scale); + return vscale; + } + + return 0; +} + /* adjusted_mode has been preset to be the panel's fixed mode */ static int pch_panel_fitting(struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state) @@ -503,6 +538,10 @@ static int pch_panel_fitting(struct intel_crtc_state *crtc_state, if (ret) return ret; + ret = intel_pch_pfit_check_scaling(crtc_state); + if (ret) + return ret; + return 0; }