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

drm/i915: Try to program PKG_C_LATENCY more correctly

The current PKG_C_LATENCY stuff looks busted in several ways:
- doesn't account for multiple pipes from different commits
correctly
- WM_LINETIME is in units of 0.125usec, PKG_C_LATENCY wants
units on 1 usec
- weird VRR state stuff being checked
- use of pointless RMW

Fix it all up. Note that it's still a bit unclear how all this
works, especially how the added_wake_time ties into the flipq
triggers in DMC, and how we need to sequence updates to
PKG_C_LATENCY when enabling/disabling pipes/etc. We may also
need to think what to about the WM1+ disabling and the related
PSR chicken bits when we can use PKG_C_LATENCY for early wake...

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

+61 -43
+1
drivers/gpu/drm/i915/display/intel_display.c
··· 7393 7393 /* Now enable the clocks, plane, pipe, and connectors that we set up. */ 7394 7394 display->funcs.display->commit_modeset_enables(state); 7395 7395 7396 + /* FIXME probably need to sequence this properly */ 7396 7397 intel_program_dpkgc_latency(state); 7397 7398 7398 7399 intel_wait_for_vblank_workers(state);
+6
drivers/gpu/drm/i915/display/intel_display_core.h
··· 480 480 } irq; 481 481 482 482 struct { 483 + /* protected by wm.wm_mutex */ 484 + u16 linetime[I915_MAX_PIPES]; 485 + bool disable[I915_MAX_PIPES]; 486 + } pkgc; 487 + 488 + struct { 483 489 wait_queue_head_t waitqueue; 484 490 485 491 /* mutex to protect pmdemand programming sequence */
+54 -43
drivers/gpu/drm/i915/display/skl_watermark.c
··· 2857 2857 return 0; 2858 2858 } 2859 2859 2860 - /* 2861 - * If Fixed Refresh Rate or For VRR case Vmin = Vmax = Flipline: 2862 - * Program DEEP PKG_C_LATENCY Pkg C with highest valid latency from 2863 - * watermark level1 and up and above. If watermark level 1 is 2864 - * invalid program it with all 1's. 2865 - * Program PKG_C_LATENCY Added Wake Time = DSB execution time 2866 - * If Variable Refresh Rate where Vmin != Vmax != Flipline: 2867 - * Program DEEP PKG_C_LATENCY Pkg C with all 1's. 2868 - * Program PKG_C_LATENCY Added Wake Time = 0 2869 - */ 2860 + static int pkgc_max_linetime(struct intel_atomic_state *state) 2861 + { 2862 + struct intel_display *display = to_intel_display(state); 2863 + const struct intel_crtc_state *crtc_state; 2864 + struct intel_crtc *crtc; 2865 + int i, max_linetime; 2866 + 2867 + /* 2868 + * Apparenty the hardware uses WM_LINETIME internally for 2869 + * this stuff, compute everything based on that. 2870 + */ 2871 + for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) { 2872 + display->pkgc.disable[crtc->pipe] = crtc_state->vrr.enable; 2873 + display->pkgc.linetime[crtc->pipe] = DIV_ROUND_UP(crtc_state->linetime, 8); 2874 + } 2875 + 2876 + max_linetime = 0; 2877 + for_each_intel_crtc(display->drm, crtc) { 2878 + if (display->pkgc.disable[crtc->pipe]) 2879 + return 0; 2880 + 2881 + max_linetime = max(display->pkgc.linetime[crtc->pipe], max_linetime); 2882 + } 2883 + 2884 + return max_linetime; 2885 + } 2886 + 2870 2887 void 2871 2888 intel_program_dpkgc_latency(struct intel_atomic_state *state) 2872 2889 { 2873 2890 struct intel_display *display = to_intel_display(state); 2874 - struct intel_crtc *crtc; 2875 - struct intel_crtc_state *new_crtc_state; 2876 - u32 latency = LNL_PKG_C_LATENCY_MASK; 2877 - u32 added_wake_time = 0; 2878 - u32 max_linetime = 0; 2879 - u32 clear, val; 2880 - bool fixed_refresh_rate = false; 2881 - int i; 2891 + int max_linetime, latency, added_wake_time = 0; 2882 2892 2883 2893 if (DISPLAY_VER(display) < 20) 2884 2894 return; 2885 2895 2886 - for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) { 2887 - if (!new_crtc_state->vrr.enable || 2888 - (new_crtc_state->vrr.vmin == new_crtc_state->vrr.vmax && 2889 - new_crtc_state->vrr.vmin == new_crtc_state->vrr.flipline)) 2890 - fixed_refresh_rate = true; 2896 + mutex_lock(&display->wm.wm_mutex); 2891 2897 2892 - max_linetime = max(new_crtc_state->linetime, max_linetime); 2898 + latency = skl_watermark_max_latency(display, 1); 2899 + 2900 + /* 2901 + * Wa_22020432604 2902 + * "PKG_C_LATENCY Added Wake Time field is not working" 2903 + */ 2904 + if (latency && (DISPLAY_VER(display) == 20 || DISPLAY_VER(display) == 30)) { 2905 + latency += added_wake_time; 2906 + added_wake_time = 0; 2893 2907 } 2894 2908 2895 - if (fixed_refresh_rate) { 2896 - latency = skl_watermark_max_latency(display, 1); 2909 + max_linetime = pkgc_max_linetime(state); 2897 2910 2898 - /* Wa_22020432604 */ 2899 - if ((DISPLAY_VER(display) == 20 || DISPLAY_VER(display) == 30) && !latency) { 2900 - latency += added_wake_time; 2901 - added_wake_time = 0; 2902 - } 2903 - 2904 - /* Wa_22020299601 */ 2905 - if ((latency && max_linetime) && 2906 - (DISPLAY_VER(display) == 20 || DISPLAY_VER(display) == 30)) { 2907 - latency = max_linetime * DIV_ROUND_UP(latency, max_linetime); 2908 - } else if (!latency) { 2909 - latency = LNL_PKG_C_LATENCY_MASK; 2910 - } 2911 + if (max_linetime == 0 || latency == 0) { 2912 + latency = REG_FIELD_GET(LNL_PKG_C_LATENCY_MASK, 2913 + LNL_PKG_C_LATENCY_MASK); 2914 + added_wake_time = 0; 2915 + } else { 2916 + /* 2917 + * Wa_22020299601 2918 + * "Increase the latency programmed in PKG_C_LATENCY Pkg C Latency to be a 2919 + * multiple of the pipeline time from WM_LINETIME" 2920 + */ 2921 + latency = roundup(latency, max_linetime); 2911 2922 } 2912 2923 2913 - clear = LNL_ADDED_WAKE_TIME_MASK | LNL_PKG_C_LATENCY_MASK; 2914 - val = REG_FIELD_PREP(LNL_PKG_C_LATENCY_MASK, latency) | 2915 - REG_FIELD_PREP(LNL_ADDED_WAKE_TIME_MASK, added_wake_time); 2924 + intel_de_write(display, LNL_PKG_C_LATENCY, 2925 + REG_FIELD_PREP(LNL_ADDED_WAKE_TIME_MASK, added_wake_time) | 2926 + REG_FIELD_PREP(LNL_PKG_C_LATENCY_MASK, latency)); 2916 2927 2917 - intel_de_rmw(display, LNL_PKG_C_LATENCY, clear, val); 2928 + mutex_unlock(&display->wm.wm_mutex); 2918 2929 } 2919 2930 2920 2931 static int