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/cdclk: Add prefill helpers for CDCLK

Add helpers to compute the CDCLKl adjustment factor for prefill
calculations. The adjustment factor is always <= 1.0. That is,
a faster CDCLK speeds up the pipe prefill.

intel_cdclk_prefill_adjustment_worst() gives out a worst case estimate,
meant to be used during guardband sizing. We can actually do better
than 1.0 here because the absolute minimum CDCLK is limited by the
dotclock. This will still allow planes, pfit, etc. to be changed any
which way without having to resize the guardband yet again.

intel_cdclk_prefill_adjustment() is supposed to give a more accurate
value based on the current min cdclk for the pipe, but currently that
is not yet available when this gets called. So for now use the same
worst case estimate here.

The returned numbers are in .16 binary fixed point.

TODO: the intel_cdclk_prefill_adjustment_worst() approach here
can result in guardband changes for DRRS. But I'm thinking
that is fine since M/N changes will always happen on the
legacy timing generator so guardband doesn't actually matter.
May need to think about this a bit more though...

v2: Use the worst case estimate always for now

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/20251014191808.12326-4-ville.syrjala@linux.intel.com

+69 -2
+66 -2
drivers/gpu/drm/i915/display/intel_cdclk.c
··· 2806 2806 return 90; 2807 2807 } 2808 2808 2809 - static int intel_pixel_rate_to_cdclk(const struct intel_crtc_state *crtc_state) 2809 + static int _intel_pixel_rate_to_cdclk(const struct intel_crtc_state *crtc_state, int pixel_rate) 2810 2810 { 2811 2811 struct intel_display *display = to_intel_display(crtc_state); 2812 2812 int ppc = intel_cdclk_ppc(display, crtc_state->double_wide); 2813 2813 int guardband = intel_cdclk_guardband(display); 2814 - int pixel_rate = crtc_state->pixel_rate; 2815 2814 2816 2815 return DIV_ROUND_UP(pixel_rate * 100, guardband * ppc); 2816 + } 2817 + 2818 + static int intel_pixel_rate_to_cdclk(const struct intel_crtc_state *crtc_state) 2819 + { 2820 + return _intel_pixel_rate_to_cdclk(crtc_state, crtc_state->pixel_rate); 2817 2821 } 2818 2822 2819 2823 static int intel_planes_min_cdclk(const struct intel_crtc_state *crtc_state) ··· 4059 4055 intel_cdclk_dump_config(display, &display->cdclk.hw, "Current CDCLK"); 4060 4056 cdclk_state->actual = display->cdclk.hw; 4061 4057 cdclk_state->logical = display->cdclk.hw; 4058 + } 4059 + 4060 + static int calc_cdclk(const struct intel_crtc_state *crtc_state, int min_cdclk) 4061 + { 4062 + struct intel_display *display = to_intel_display(crtc_state); 4063 + 4064 + if (DISPLAY_VER(display) >= 10 || display->platform.broxton) { 4065 + return bxt_calc_cdclk(display, min_cdclk); 4066 + } else if (DISPLAY_VER(display) == 9) { 4067 + int vco; 4068 + 4069 + vco = display->cdclk.skl_preferred_vco_freq; 4070 + if (vco == 0) 4071 + vco = 8100000; 4072 + 4073 + return skl_calc_cdclk(min_cdclk, vco); 4074 + } else if (display->platform.broadwell) { 4075 + return bdw_calc_cdclk(min_cdclk); 4076 + } else if (display->platform.cherryview || display->platform.valleyview) { 4077 + return vlv_calc_cdclk(display, min_cdclk); 4078 + } else { 4079 + return display->cdclk.max_cdclk_freq; 4080 + } 4081 + } 4082 + 4083 + static unsigned int _intel_cdclk_prefill_adj(const struct intel_crtc_state *crtc_state, 4084 + int clock, int min_cdclk) 4085 + { 4086 + struct intel_display *display = to_intel_display(crtc_state); 4087 + int ppc = intel_cdclk_ppc(display, crtc_state->double_wide); 4088 + int cdclk = calc_cdclk(crtc_state, min_cdclk); 4089 + 4090 + return min(0x10000, DIV_ROUND_UP_ULL((u64)clock << 16, ppc * cdclk)); 4091 + } 4092 + 4093 + unsigned int intel_cdclk_prefill_adjustment(const struct intel_crtc_state *crtc_state) 4094 + { 4095 + /* FIXME use the actual min_cdclk for the pipe here */ 4096 + return intel_cdclk_prefill_adjustment_worst(crtc_state); 4097 + } 4098 + 4099 + unsigned int intel_cdclk_prefill_adjustment_worst(const struct intel_crtc_state *crtc_state) 4100 + { 4101 + int clock = crtc_state->hw.pipe_mode.crtc_clock; 4102 + int min_cdclk; 4103 + 4104 + /* 4105 + * FIXME could perhaps consider a few more of the factors 4106 + * that go the per-crtc min_cdclk. Namely anything that 4107 + * only changes during full modesets. 4108 + * 4109 + * FIXME this assumes 1:1 scaling, but the other _worst() stuff 4110 + * assumes max downscaling, so the final result will be 4111 + * unrealistically bad. Figure out where the actual maximum value 4112 + * lies and use that to compute a more realistic worst case 4113 + * estimate... 4114 + */ 4115 + min_cdclk = _intel_pixel_rate_to_cdclk(crtc_state, clock); 4116 + 4117 + return _intel_cdclk_prefill_adj(crtc_state, clock, min_cdclk); 4062 4118 }
+3
drivers/gpu/drm/i915/display/intel_cdclk.h
··· 70 70 void intel_cdclk_force_min_cdclk(struct intel_cdclk_state *cdclk_state, int force_min_cdclk); 71 71 void intel_cdclk_read_hw(struct intel_display *display); 72 72 73 + unsigned int intel_cdclk_prefill_adjustment(const struct intel_crtc_state *crtc_state); 74 + unsigned int intel_cdclk_prefill_adjustment_worst(const struct intel_crtc_state *crtc_state); 75 + 73 76 #endif /* __INTEL_CDCLK_H__ */