diff options
author | Chandra Konduru <chandra.konduru@intel.com> | 2018-04-08 23:41:13 -0400 |
---|---|---|
committer | Maarten Lankhorst <maarten.lankhorst@linux.intel.com> | 2018-04-09 07:40:24 -0400 |
commit | 77224cd59eae67acfc1259f0756957b10ec7c3b5 (patch) | |
tree | 730629dabdde6d90f29cc257ba389feab6c43c9d | |
parent | a589b1384593c6a9df8b808e5a0aa4280de5edc2 (diff) |
drm/i915: Upscale scaler max scale for NV12
This patch updates scaler max limit support for NV12
v2: Rebased (me)
v3: Rebased (me)
v4: Missed the Tested-by/Reviewed-by in the previous series
Adding the same to commit message in this version.
v5: Addressed review comments from Ville and rebased
- calculation of max_scale to be made
less convoluted by splitting it up a bit
- Indentation errors to be fixed in the series
v6: Rebased (me)
Fixed review comments from Paauwe, Bob J
Previous version, where a split of calculation
was done, was wrong. Fixed that issue here.
v7: Rebased (me)
v8: Rebased (me)
v9: Rebased (me)
v10: Rebased (me)
v11: Addressed review comments from Shashank Sharma
Alignment issues fixed.
When call to skl_update_scaler is made, 0 was being
sent instead of pixel_format.
When crtc update scaler is called, we dont have the
fb to derive the pixel format. Added the function
parameter bool plane_scaler_check to account for this.
v12: Fixed failure in IGT debugfs_test.
fb is NULL in skl_update_scaler_plane
Due to this, accessing fb->format caused failure.
Patch checks fb before using.
v13: In the previous version there was a flaw.
In skl_update_scaler during plane_scaler_check
if the format was non-NV12, it would set need_scaling
to false. This could reset the previously set need_scaling
from a previous condition check. Patch fixes this.
Patch also adds minimum src height for YUV 420 formats
to 16 (as defined in BSpec) and adds for checking this
range.
v14: Addressed review comments from Maarten
Just add a check for NV12 min src height in
skl_update_scaler and retain the remaining checks
as is. Added Reviewed By from Juha-Pekka Heikkila.
v15: Rebased the series.
v16: Changed fb height restriction to be >= 16 as per
Bspec. Earlier it was > 16.
v17: Adding src width and height to be mult of 4 restriction
to avoid pipe fifo underruns for NV12.
Credits-to: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Tested-by: Clinton Taylor <clinton.a.taylor@intel.com>
Reviewed-by: Clinton Taylor <clinton.a.taylor@intel.com>
Reviewed-by: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
Signed-off-by: Chandra Konduru <chandra.konduru@intel.com>
Signed-off-by: Nabendu Maiti <nabendu.bikash.maiti@intel.com>
Signed-off-by: Vidya Srinivas <vidya.srinivas@intel.com>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/1523245273-30264-15-git-send-email-vidya.srinivas@intel.com
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 48 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_sprite.c | 6 |
3 files changed, 46 insertions, 13 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index eb9d4e7f9160..fec3d6dd5c60 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -3483,6 +3483,8 @@ static u32 skl_plane_ctl_format(uint32_t pixel_format) | |||
3483 | return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_UYVY; | 3483 | return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_UYVY; |
3484 | case DRM_FORMAT_VYUY: | 3484 | case DRM_FORMAT_VYUY: |
3485 | return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_VYUY; | 3485 | return PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_VYUY; |
3486 | case DRM_FORMAT_NV12: | ||
3487 | return PLANE_CTL_FORMAT_NV12; | ||
3486 | default: | 3488 | default: |
3487 | MISSING_CASE(pixel_format); | 3489 | MISSING_CASE(pixel_format); |
3488 | } | 3490 | } |
@@ -4724,7 +4726,9 @@ static void cpt_verify_modeset(struct drm_device *dev, int pipe) | |||
4724 | static int | 4726 | static int |
4725 | skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach, | 4727 | skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach, |
4726 | unsigned int scaler_user, int *scaler_id, | 4728 | unsigned int scaler_user, int *scaler_id, |
4727 | int src_w, int src_h, int dst_w, int dst_h) | 4729 | int src_w, int src_h, int dst_w, int dst_h, |
4730 | bool plane_scaler_check, | ||
4731 | uint32_t pixel_format) | ||
4728 | { | 4732 | { |
4729 | struct intel_crtc_scaler_state *scaler_state = | 4733 | struct intel_crtc_scaler_state *scaler_state = |
4730 | &crtc_state->scaler_state; | 4734 | &crtc_state->scaler_state; |
@@ -4742,6 +4746,10 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach, | |||
4742 | */ | 4746 | */ |
4743 | need_scaling = src_w != dst_w || src_h != dst_h; | 4747 | need_scaling = src_w != dst_w || src_h != dst_h; |
4744 | 4748 | ||
4749 | if (plane_scaler_check) | ||
4750 | if (pixel_format == DRM_FORMAT_NV12) | ||
4751 | need_scaling = true; | ||
4752 | |||
4745 | if (crtc_state->ycbcr420 && scaler_user == SKL_CRTC_INDEX) | 4753 | if (crtc_state->ycbcr420 && scaler_user == SKL_CRTC_INDEX) |
4746 | need_scaling = true; | 4754 | need_scaling = true; |
4747 | 4755 | ||
@@ -4781,6 +4789,13 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach, | |||
4781 | return 0; | 4789 | return 0; |
4782 | } | 4790 | } |
4783 | 4791 | ||
4792 | if (plane_scaler_check && pixel_format == DRM_FORMAT_NV12 && | ||
4793 | (src_h < SKL_MIN_YUV_420_SRC_H || (src_w % 4) != 0 || | ||
4794 | (src_h % 4) != 0)) { | ||
4795 | DRM_DEBUG_KMS("NV12: src dimensions not met\n"); | ||
4796 | return -EINVAL; | ||
4797 | } | ||
4798 | |||
4784 | /* range checks */ | 4799 | /* range checks */ |
4785 | if (src_w < SKL_MIN_SRC_W || src_h < SKL_MIN_SRC_H || | 4800 | if (src_w < SKL_MIN_SRC_W || src_h < SKL_MIN_SRC_H || |
4786 | dst_w < SKL_MIN_DST_W || dst_h < SKL_MIN_DST_H || | 4801 | dst_w < SKL_MIN_DST_W || dst_h < SKL_MIN_DST_H || |
@@ -4820,9 +4835,10 @@ int skl_update_scaler_crtc(struct intel_crtc_state *state) | |||
4820 | const struct drm_display_mode *adjusted_mode = &state->base.adjusted_mode; | 4835 | const struct drm_display_mode *adjusted_mode = &state->base.adjusted_mode; |
4821 | 4836 | ||
4822 | return skl_update_scaler(state, !state->base.active, SKL_CRTC_INDEX, | 4837 | return skl_update_scaler(state, !state->base.active, SKL_CRTC_INDEX, |
4823 | &state->scaler_state.scaler_id, | 4838 | &state->scaler_state.scaler_id, |
4824 | state->pipe_src_w, state->pipe_src_h, | 4839 | state->pipe_src_w, state->pipe_src_h, |
4825 | adjusted_mode->crtc_hdisplay, adjusted_mode->crtc_vdisplay); | 4840 | adjusted_mode->crtc_hdisplay, |
4841 | adjusted_mode->crtc_vdisplay, false, 0); | ||
4826 | } | 4842 | } |
4827 | 4843 | ||
4828 | /** | 4844 | /** |
@@ -4851,7 +4867,8 @@ static int skl_update_scaler_plane(struct intel_crtc_state *crtc_state, | |||
4851 | drm_rect_width(&plane_state->base.src) >> 16, | 4867 | drm_rect_width(&plane_state->base.src) >> 16, |
4852 | drm_rect_height(&plane_state->base.src) >> 16, | 4868 | drm_rect_height(&plane_state->base.src) >> 16, |
4853 | drm_rect_width(&plane_state->base.dst), | 4869 | drm_rect_width(&plane_state->base.dst), |
4854 | drm_rect_height(&plane_state->base.dst)); | 4870 | drm_rect_height(&plane_state->base.dst), |
4871 | fb ? true : false, fb ? fb->format->format : 0); | ||
4855 | 4872 | ||
4856 | if (ret || plane_state->scaler_id < 0) | 4873 | if (ret || plane_state->scaler_id < 0) |
4857 | return ret; | 4874 | return ret; |
@@ -4877,6 +4894,7 @@ static int skl_update_scaler_plane(struct intel_crtc_state *crtc_state, | |||
4877 | case DRM_FORMAT_YVYU: | 4894 | case DRM_FORMAT_YVYU: |
4878 | case DRM_FORMAT_UYVY: | 4895 | case DRM_FORMAT_UYVY: |
4879 | case DRM_FORMAT_VYUY: | 4896 | case DRM_FORMAT_VYUY: |
4897 | case DRM_FORMAT_NV12: | ||
4880 | break; | 4898 | break; |
4881 | default: | 4899 | default: |
4882 | DRM_DEBUG_KMS("[PLANE:%d:%s] FB:%d unsupported scaling format 0x%x\n", | 4900 | DRM_DEBUG_KMS("[PLANE:%d:%s] FB:%d unsupported scaling format 0x%x\n", |
@@ -12877,11 +12895,13 @@ intel_cleanup_plane_fb(struct drm_plane *plane, | |||
12877 | } | 12895 | } |
12878 | 12896 | ||
12879 | int | 12897 | int |
12880 | skl_max_scale(struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state) | 12898 | skl_max_scale(struct intel_crtc *intel_crtc, |
12899 | struct intel_crtc_state *crtc_state, | ||
12900 | uint32_t pixel_format) | ||
12881 | { | 12901 | { |
12882 | struct drm_i915_private *dev_priv; | 12902 | struct drm_i915_private *dev_priv; |
12883 | int max_scale; | 12903 | int max_scale, mult; |
12884 | int crtc_clock, max_dotclk; | 12904 | int crtc_clock, max_dotclk, tmpclk1, tmpclk2; |
12885 | 12905 | ||
12886 | if (!intel_crtc || !crtc_state->base.enable) | 12906 | if (!intel_crtc || !crtc_state->base.enable) |
12887 | return DRM_PLANE_HELPER_NO_SCALING; | 12907 | return DRM_PLANE_HELPER_NO_SCALING; |
@@ -12903,8 +12923,10 @@ skl_max_scale(struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state | |||
12903 | * or | 12923 | * or |
12904 | * cdclk/crtc_clock | 12924 | * cdclk/crtc_clock |
12905 | */ | 12925 | */ |
12906 | max_scale = min((1 << 16) * 3 - 1, | 12926 | mult = pixel_format == DRM_FORMAT_NV12 ? 2 : 3; |
12907 | (1 << 8) * ((max_dotclk << 8) / crtc_clock)); | 12927 | tmpclk1 = (1 << 16) * mult - 1; |
12928 | tmpclk2 = (1 << 8) * ((max_dotclk << 8) / crtc_clock); | ||
12929 | max_scale = min(tmpclk1, tmpclk2); | ||
12908 | 12930 | ||
12909 | return max_scale; | 12931 | return max_scale; |
12910 | } | 12932 | } |
@@ -12920,12 +12942,16 @@ intel_check_primary_plane(struct intel_plane *plane, | |||
12920 | int max_scale = DRM_PLANE_HELPER_NO_SCALING; | 12942 | int max_scale = DRM_PLANE_HELPER_NO_SCALING; |
12921 | bool can_position = false; | 12943 | bool can_position = false; |
12922 | int ret; | 12944 | int ret; |
12945 | uint32_t pixel_format = 0; | ||
12923 | 12946 | ||
12924 | if (INTEL_GEN(dev_priv) >= 9) { | 12947 | if (INTEL_GEN(dev_priv) >= 9) { |
12925 | /* use scaler when colorkey is not required */ | 12948 | /* use scaler when colorkey is not required */ |
12926 | if (!state->ckey.flags) { | 12949 | if (!state->ckey.flags) { |
12927 | min_scale = 1; | 12950 | min_scale = 1; |
12928 | max_scale = skl_max_scale(to_intel_crtc(crtc), crtc_state); | 12951 | if (state->base.fb) |
12952 | pixel_format = state->base.fb->format->format; | ||
12953 | max_scale = skl_max_scale(to_intel_crtc(crtc), | ||
12954 | crtc_state, pixel_format); | ||
12929 | } | 12955 | } |
12930 | can_position = true; | 12956 | can_position = true; |
12931 | } | 12957 | } |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index a6d7d856ea62..b2e0fa04ef5b 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -552,6 +552,8 @@ struct intel_initial_plane_config { | |||
552 | #define ICL_MAX_SRC_H 4096 | 552 | #define ICL_MAX_SRC_H 4096 |
553 | #define ICL_MAX_DST_W 5120 | 553 | #define ICL_MAX_DST_W 5120 |
554 | #define ICL_MAX_DST_H 4096 | 554 | #define ICL_MAX_DST_H 4096 |
555 | #define SKL_MIN_YUV_420_SRC_W 16 | ||
556 | #define SKL_MIN_YUV_420_SRC_H 16 | ||
555 | 557 | ||
556 | struct intel_scaler { | 558 | struct intel_scaler { |
557 | int in_use; | 559 | int in_use; |
@@ -1597,7 +1599,8 @@ void intel_mode_from_pipe_config(struct drm_display_mode *mode, | |||
1597 | struct intel_crtc_state *pipe_config); | 1599 | struct intel_crtc_state *pipe_config); |
1598 | 1600 | ||
1599 | int skl_update_scaler_crtc(struct intel_crtc_state *crtc_state); | 1601 | int skl_update_scaler_crtc(struct intel_crtc_state *crtc_state); |
1600 | int skl_max_scale(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state); | 1602 | int skl_max_scale(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, |
1603 | uint32_t pixel_format); | ||
1601 | 1604 | ||
1602 | static inline u32 intel_plane_ggtt_offset(const struct intel_plane_state *state) | 1605 | static inline u32 intel_plane_ggtt_offset(const struct intel_plane_state *state) |
1603 | { | 1606 | { |
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 0652e583b03d..aa1dfaa692b9 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c | |||
@@ -947,6 +947,7 @@ intel_check_sprite_plane(struct intel_plane *plane, | |||
947 | int max_scale, min_scale; | 947 | int max_scale, min_scale; |
948 | bool can_scale; | 948 | bool can_scale; |
949 | int ret; | 949 | int ret; |
950 | uint32_t pixel_format = 0; | ||
950 | 951 | ||
951 | *src = drm_plane_state_src(&state->base); | 952 | *src = drm_plane_state_src(&state->base); |
952 | *dst = drm_plane_state_dest(&state->base); | 953 | *dst = drm_plane_state_dest(&state->base); |
@@ -970,11 +971,14 @@ intel_check_sprite_plane(struct intel_plane *plane, | |||
970 | 971 | ||
971 | /* setup can_scale, min_scale, max_scale */ | 972 | /* setup can_scale, min_scale, max_scale */ |
972 | if (INTEL_GEN(dev_priv) >= 9) { | 973 | if (INTEL_GEN(dev_priv) >= 9) { |
974 | if (state->base.fb) | ||
975 | pixel_format = state->base.fb->format->format; | ||
973 | /* use scaler when colorkey is not required */ | 976 | /* use scaler when colorkey is not required */ |
974 | if (!state->ckey.flags) { | 977 | if (!state->ckey.flags) { |
975 | can_scale = 1; | 978 | can_scale = 1; |
976 | min_scale = 1; | 979 | min_scale = 1; |
977 | max_scale = skl_max_scale(crtc, crtc_state); | 980 | max_scale = |
981 | skl_max_scale(crtc, crtc_state, pixel_format); | ||
978 | } else { | 982 | } else { |
979 | can_scale = 0; | 983 | can_scale = 0; |
980 | min_scale = DRM_PLANE_HELPER_NO_SCALING; | 984 | min_scale = DRM_PLANE_HELPER_NO_SCALING; |