aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2018-11-14 08:32:55 -0500
committerJoonas Lahtinen <joonas.lahtinen@linux.intel.com>2018-11-15 06:57:20 -0500
commit6e8adf6f4a4fa57dd3bef6b70de96e2b7b311204 (patch)
treec718f7455da456bf8eb64df62965c77b68a8d456
parent27971d613fcb5b6ad96320bc4f2c90f4d4fde768 (diff)
drm/i915: Account for scale factor when calculating initial phase
To get the initial phase correct we need to account for the scale factor as well. I forgot this initially and was mostly looking at heavily upscaled content where the minor difference between -0.5 and the proper initial phase was not readily apparent. And let's toss in a comment that tries to explain the formula a little bit. v2: The initial phase upper limit is 1.5, not 24.0! Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Fixes: 0a59952b24e2 ("drm/i915: Configure SKL+ scaler initial phase correctly") Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20181029181820.21956-1-ville.syrjala@linux.intel.com Tested-by: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com> Tested-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> #irc Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> #irc (cherry picked from commit e7a278a329dd8aa2c70c564849f164cb5673689c) Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
-rw-r--r--drivers/gpu/drm/i915/intel_display.c45
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h2
-rw-r--r--drivers/gpu/drm/i915/intel_sprite.c20
3 files changed, 57 insertions, 10 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 23d8008a93bb..a54843fdeb2f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4850,8 +4850,31 @@ static void cpt_verify_modeset(struct drm_device *dev, int pipe)
4850 * chroma samples for both of the luma samples, and thus we don't 4850 * chroma samples for both of the luma samples, and thus we don't
4851 * actually get the expected MPEG2 chroma siting convention :( 4851 * actually get the expected MPEG2 chroma siting convention :(
4852 * The same behaviour is observed on pre-SKL platforms as well. 4852 * The same behaviour is observed on pre-SKL platforms as well.
4853 *
4854 * Theory behind the formula (note that we ignore sub-pixel
4855 * source coordinates):
4856 * s = source sample position
4857 * d = destination sample position
4858 *
4859 * Downscaling 4:1:
4860 * -0.5
4861 * | 0.0
4862 * | | 1.5 (initial phase)
4863 * | | |
4864 * v v v
4865 * | s | s | s | s |
4866 * | d |
4867 *
4868 * Upscaling 1:4:
4869 * -0.5
4870 * | -0.375 (initial phase)
4871 * | | 0.0
4872 * | | |
4873 * v v v
4874 * | s |
4875 * | d | d | d | d |
4853 */ 4876 */
4854u16 skl_scaler_calc_phase(int sub, bool chroma_cosited) 4877u16 skl_scaler_calc_phase(int sub, int scale, bool chroma_cosited)
4855{ 4878{
4856 int phase = -0x8000; 4879 int phase = -0x8000;
4857 u16 trip = 0; 4880 u16 trip = 0;
@@ -4859,6 +4882,15 @@ u16 skl_scaler_calc_phase(int sub, bool chroma_cosited)
4859 if (chroma_cosited) 4882 if (chroma_cosited)
4860 phase += (sub - 1) * 0x8000 / sub; 4883 phase += (sub - 1) * 0x8000 / sub;
4861 4884
4885 phase += scale / (2 * sub);
4886
4887 /*
4888 * Hardware initial phase limited to [-0.5:1.5].
4889 * Since the max hardware scale factor is 3.0, we
4890 * should never actually excdeed 1.0 here.
4891 */
4892 WARN_ON(phase < -0x8000 || phase > 0x18000);
4893
4862 if (phase < 0) 4894 if (phase < 0)
4863 phase = 0x10000 + phase; 4895 phase = 0x10000 + phase;
4864 else 4896 else
@@ -5067,13 +5099,20 @@ static void skylake_pfit_enable(struct intel_crtc *crtc)
5067 5099
5068 if (crtc->config->pch_pfit.enabled) { 5100 if (crtc->config->pch_pfit.enabled) {
5069 u16 uv_rgb_hphase, uv_rgb_vphase; 5101 u16 uv_rgb_hphase, uv_rgb_vphase;
5102 int pfit_w, pfit_h, hscale, vscale;
5070 int id; 5103 int id;
5071 5104
5072 if (WARN_ON(crtc->config->scaler_state.scaler_id < 0)) 5105 if (WARN_ON(crtc->config->scaler_state.scaler_id < 0))
5073 return; 5106 return;
5074 5107
5075 uv_rgb_hphase = skl_scaler_calc_phase(1, false); 5108 pfit_w = (crtc->config->pch_pfit.size >> 16) & 0xFFFF;
5076 uv_rgb_vphase = skl_scaler_calc_phase(1, false); 5109 pfit_h = crtc->config->pch_pfit.size & 0xFFFF;
5110
5111 hscale = (crtc->config->pipe_src_w << 16) / pfit_w;
5112 vscale = (crtc->config->pipe_src_h << 16) / pfit_h;
5113
5114 uv_rgb_hphase = skl_scaler_calc_phase(1, hscale, false);
5115 uv_rgb_vphase = skl_scaler_calc_phase(1, vscale, false);
5077 5116
5078 id = scaler_state->scaler_id; 5117 id = scaler_state->scaler_id;
5079 I915_WRITE(SKL_PS_CTRL(pipe, id), PS_SCALER_EN | 5118 I915_WRITE(SKL_PS_CTRL(pipe, id), PS_SCALER_EN |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index f8dc84b2d2d3..8b298e5f012d 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1646,7 +1646,7 @@ void intel_mode_from_pipe_config(struct drm_display_mode *mode,
1646void intel_crtc_arm_fifo_underrun(struct intel_crtc *crtc, 1646void intel_crtc_arm_fifo_underrun(struct intel_crtc *crtc,
1647 struct intel_crtc_state *crtc_state); 1647 struct intel_crtc_state *crtc_state);
1648 1648
1649u16 skl_scaler_calc_phase(int sub, bool chroma_center); 1649u16 skl_scaler_calc_phase(int sub, int scale, bool chroma_center);
1650int skl_update_scaler_crtc(struct intel_crtc_state *crtc_state); 1650int skl_update_scaler_crtc(struct intel_crtc_state *crtc_state);
1651int skl_max_scale(const struct intel_crtc_state *crtc_state, 1651int skl_max_scale(const struct intel_crtc_state *crtc_state,
1652 u32 pixel_format); 1652 u32 pixel_format);
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index fa7eaace5f92..d3090a7537bb 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -318,22 +318,30 @@ skl_program_scaler(struct intel_plane *plane,
318 uint32_t crtc_h = drm_rect_height(&plane_state->base.dst); 318 uint32_t crtc_h = drm_rect_height(&plane_state->base.dst);
319 u16 y_hphase, uv_rgb_hphase; 319 u16 y_hphase, uv_rgb_hphase;
320 u16 y_vphase, uv_rgb_vphase; 320 u16 y_vphase, uv_rgb_vphase;
321 int hscale, vscale;
322
323 hscale = drm_rect_calc_hscale(&plane_state->base.src,
324 &plane_state->base.dst,
325 0, INT_MAX);
326 vscale = drm_rect_calc_vscale(&plane_state->base.src,
327 &plane_state->base.dst,
328 0, INT_MAX);
321 329
322 /* TODO: handle sub-pixel coordinates */ 330 /* TODO: handle sub-pixel coordinates */
323 if (plane_state->base.fb->format->format == DRM_FORMAT_NV12) { 331 if (plane_state->base.fb->format->format == DRM_FORMAT_NV12) {
324 y_hphase = skl_scaler_calc_phase(1, false); 332 y_hphase = skl_scaler_calc_phase(1, hscale, false);
325 y_vphase = skl_scaler_calc_phase(1, false); 333 y_vphase = skl_scaler_calc_phase(1, vscale, false);
326 334
327 /* MPEG2 chroma siting convention */ 335 /* MPEG2 chroma siting convention */
328 uv_rgb_hphase = skl_scaler_calc_phase(2, true); 336 uv_rgb_hphase = skl_scaler_calc_phase(2, hscale, true);
329 uv_rgb_vphase = skl_scaler_calc_phase(2, false); 337 uv_rgb_vphase = skl_scaler_calc_phase(2, vscale, false);
330 } else { 338 } else {
331 /* not used */ 339 /* not used */
332 y_hphase = 0; 340 y_hphase = 0;
333 y_vphase = 0; 341 y_vphase = 0;
334 342
335 uv_rgb_hphase = skl_scaler_calc_phase(1, false); 343 uv_rgb_hphase = skl_scaler_calc_phase(1, hscale, false);
336 uv_rgb_vphase = skl_scaler_calc_phase(1, false); 344 uv_rgb_vphase = skl_scaler_calc_phase(1, vscale, false);
337 } 345 }
338 346
339 I915_WRITE_FW(SKL_PS_CTRL(pipe, scaler_id), 347 I915_WRITE_FW(SKL_PS_CTRL(pipe, scaler_id),