diff options
author | Ville Syrjälä <ville.syrjala@linux.intel.com> | 2018-11-14 08:32:55 -0500 |
---|---|---|
committer | Joonas Lahtinen <joonas.lahtinen@linux.intel.com> | 2018-11-15 06:57:20 -0500 |
commit | 6e8adf6f4a4fa57dd3bef6b70de96e2b7b311204 (patch) | |
tree | c718f7455da456bf8eb64df62965c77b68a8d456 | |
parent | 27971d613fcb5b6ad96320bc4f2c90f4d4fde768 (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.c | 45 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_sprite.c | 20 |
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 | */ |
4854 | u16 skl_scaler_calc_phase(int sub, bool chroma_cosited) | 4877 | u16 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, | |||
1646 | void intel_crtc_arm_fifo_underrun(struct intel_crtc *crtc, | 1646 | void 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 | ||
1649 | u16 skl_scaler_calc_phase(int sub, bool chroma_center); | 1649 | u16 skl_scaler_calc_phase(int sub, int scale, bool chroma_center); |
1650 | int skl_update_scaler_crtc(struct intel_crtc_state *crtc_state); | 1650 | int skl_update_scaler_crtc(struct intel_crtc_state *crtc_state); |
1651 | int skl_max_scale(const struct intel_crtc_state *crtc_state, | 1651 | int 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), |