Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/i915/scaler: Add scaler prefill helpers

Add helpers to compute the required prefill line count and
adjustment factors for the scalers.

The "1st" variants hand out numbers for the first scaler stage
in the pipeline (pipe scaler if no plane scalers are enabled,
or the max from all the plane scaler). The "2nd" variants deal
with second scaler stage (pipe scaler when plane scaling is also
enabled, otherwise there is no second stage).

The _worst() variants give out worst case estimates, meant for
guardband sizing. The other variants are meant for the actual
vblank/guardband length check vs. prefill+pkgc/sagv latency.

The returned numbers are in .16 binary fixed point.

TODO: pretty rough, should check the actual scaler max scaling
factors instead of just assuming 3x everywhere
TODO: Reorder scaler assignment vs. vblank length check to get
the actual scale factors

v2: Drop debugs
v3: Ignore scale factors for the vblank length check for now
since we don't have the scalers assigned yet

Reviewed-by: Uma Shankar <uma.shankar@intel.com> #v1
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20251015125645.11230-1-ville.syrjala@linux.intel.com

+122
+111
drivers/gpu/drm/i915/display/skl_scaler.c
··· 968 968 1); 969 969 intel_de_write(display, XELPD_DISPLAY_ERR_FATAL_MASK, 0); 970 970 } 971 + 972 + unsigned int skl_scaler_1st_prefill_adjustment(const struct intel_crtc_state *crtc_state) 973 + { 974 + /* 975 + * FIXME don't have scalers assigned yet 976 + * so can't look up the scale factors 977 + */ 978 + return 0x10000; 979 + } 980 + 981 + unsigned int skl_scaler_2nd_prefill_adjustment(const struct intel_crtc_state *crtc_state) 982 + { 983 + /* 984 + * FIXME don't have scalers assigned yet 985 + * so can't look up the scale factors 986 + */ 987 + return 0x10000; 988 + } 989 + 990 + unsigned int skl_scaler_1st_prefill_lines(const struct intel_crtc_state *crtc_state) 991 + { 992 + const struct intel_crtc_scaler_state *scaler_state = 993 + &crtc_state->scaler_state; 994 + int num_scalers = hweight32(scaler_state->scaler_users); 995 + 996 + if (num_scalers > 0) 997 + return 4 << 16; 998 + 999 + return 0; 1000 + } 1001 + 1002 + unsigned int skl_scaler_2nd_prefill_lines(const struct intel_crtc_state *crtc_state) 1003 + { 1004 + const struct intel_crtc_scaler_state *scaler_state = 1005 + &crtc_state->scaler_state; 1006 + int num_scalers = hweight32(scaler_state->scaler_users); 1007 + 1008 + if (num_scalers > 1 && crtc_state->pch_pfit.enabled) 1009 + return 4 << 16; 1010 + 1011 + return 0; 1012 + } 1013 + 1014 + static unsigned int _skl_scaler_max_scale(const struct intel_crtc_state *crtc_state, 1015 + unsigned int max_scale) 1016 + { 1017 + struct intel_display *display = to_intel_display(crtc_state); 1018 + 1019 + /* 1020 + * Downscaling requires increasing cdclk, so max scale 1021 + * factor is limited to the max_dotclock/dotclock ratio. 1022 + * 1023 + * FIXME find out the max downscale factors properly 1024 + */ 1025 + return min(max_scale, DIV_ROUND_UP_ULL((u64)display->cdclk.max_dotclk_freq << 16, 1026 + crtc_state->hw.pipe_mode.crtc_clock)); 1027 + } 1028 + 1029 + static unsigned int skl_scaler_max_scale(const struct intel_crtc_state *crtc_state) 1030 + { 1031 + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 1032 + unsigned int max_scale; 1033 + 1034 + if (crtc->num_scalers < 1) 1035 + return 0x10000; 1036 + 1037 + /* FIXME find out the max downscale factors properly */ 1038 + max_scale = 9 << 16; 1039 + 1040 + return _skl_scaler_max_scale(crtc_state, max_scale); 1041 + } 1042 + 1043 + unsigned int skl_scaler_1st_prefill_adjustment_worst(const struct intel_crtc_state *crtc_state) 1044 + { 1045 + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 1046 + 1047 + if (crtc->num_scalers > 0) 1048 + return skl_scaler_max_scale(crtc_state); 1049 + else 1050 + return 0x10000; 1051 + } 1052 + 1053 + unsigned int skl_scaler_2nd_prefill_adjustment_worst(const struct intel_crtc_state *crtc_state) 1054 + { 1055 + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 1056 + 1057 + if (crtc->num_scalers > 1) 1058 + return skl_scaler_max_scale(crtc_state); 1059 + else 1060 + return 0x10000; 1061 + } 1062 + 1063 + unsigned int skl_scaler_1st_prefill_lines_worst(const struct intel_crtc_state *crtc_state) 1064 + { 1065 + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 1066 + 1067 + if (crtc->num_scalers > 0) 1068 + return 4 << 16; 1069 + else 1070 + return 0; 1071 + } 1072 + 1073 + unsigned int skl_scaler_2nd_prefill_lines_worst(const struct intel_crtc_state *crtc_state) 1074 + { 1075 + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 1076 + 1077 + if (crtc->num_scalers > 1) 1078 + return 4 << 16; 1079 + else 1080 + return 0; 1081 + }
+11
drivers/gpu/drm/i915/display/skl_scaler.h
··· 45 45 void adl_scaler_ecc_mask(const struct intel_crtc_state *crtc_state); 46 46 47 47 void adl_scaler_ecc_unmask(const struct intel_crtc_state *crtc_state); 48 + 49 + unsigned int skl_scaler_1st_prefill_adjustment_worst(const struct intel_crtc_state *crtc_state); 50 + unsigned int skl_scaler_2nd_prefill_adjustment_worst(const struct intel_crtc_state *crtc_state); 51 + unsigned int skl_scaler_1st_prefill_lines_worst(const struct intel_crtc_state *crtc_state); 52 + unsigned int skl_scaler_2nd_prefill_lines_worst(const struct intel_crtc_state *crtc_state); 53 + 54 + unsigned int skl_scaler_1st_prefill_adjustment(const struct intel_crtc_state *crtc_state); 55 + unsigned int skl_scaler_2nd_prefill_adjustment(const struct intel_crtc_state *crtc_state); 56 + unsigned int skl_scaler_1st_prefill_lines(const struct intel_crtc_state *crtc_state); 57 + unsigned int skl_scaler_2nd_prefill_lines(const struct intel_crtc_state *crtc_state); 58 + 48 59 #endif