Skip to content

Commit a5819e5

Browse files
vgovind2Radhakrishna Sripada
authored andcommitted
drm/i915/mtl: find the best QGV point for the SAGV configuration
From MTL onwards, we need to find the best QGV point based on the required data rate and pass the peak BW of that point to the punit to lock the corresponding QGV point. v1: Fix for warning from kernel test robot v2: No need to serialize for the peakbw change as pmdemand code will do that (Imre) Bspec: 64636 Reported-by: kernel test robot <lkp@intel.com> Closes: https://lore.kernel.org/r/202305280253.Ab8bRV2w-lkp@intel.com/ Reported-by: Dan Carpenter <error27@gmail.com> Closes: https://lore.kernel.org/r/202305280253.Ab8bRV2w-lkp@intel.com/ Signed-off-by: Vinod Govindapillai <vinod.govindapillai@intel.com> Reviewed-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com> Signed-off-by: Radhakrishna Sripada <radhakrishna.sripada@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20230606093509.221709-7-vinod.govindapillai@intel.com
1 parent 6400c21 commit a5819e5

2 files changed

Lines changed: 83 additions & 2 deletions

File tree

drivers/gpu/drm/i915/display/intel_bw.c

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -803,6 +803,77 @@ intel_atomic_get_bw_state(struct intel_atomic_state *state)
803803
return to_intel_bw_state(bw_state);
804804
}
805805

806+
static int mtl_find_qgv_points(struct drm_i915_private *i915,
807+
unsigned int data_rate,
808+
unsigned int num_active_planes,
809+
struct intel_bw_state *new_bw_state)
810+
{
811+
unsigned int best_rate = UINT_MAX;
812+
unsigned int num_qgv_points = i915->display.bw.max[0].num_qgv_points;
813+
unsigned int qgv_peak_bw = 0;
814+
int i;
815+
int ret;
816+
817+
ret = intel_atomic_lock_global_state(&new_bw_state->base);
818+
if (ret)
819+
return ret;
820+
821+
/*
822+
* If SAGV cannot be enabled, disable the pcode SAGV by passing all 1's
823+
* for qgv peak bw in PM Demand request. So assign UINT_MAX if SAGV is
824+
* not enabled. PM Demand code will clamp the value for the register
825+
*/
826+
if (!intel_can_enable_sagv(i915, new_bw_state)) {
827+
new_bw_state->qgv_point_peakbw = U16_MAX;
828+
drm_dbg_kms(&i915->drm, "No SAGV, use UINT_MAX as peak bw.");
829+
return 0;
830+
}
831+
832+
/*
833+
* Find the best QGV point by comparing the data_rate with max data rate
834+
* offered per plane group
835+
*/
836+
for (i = 0; i < num_qgv_points; i++) {
837+
unsigned int bw_index =
838+
tgl_max_bw_index(i915, num_active_planes, i);
839+
unsigned int max_data_rate;
840+
841+
if (bw_index >= ARRAY_SIZE(i915->display.bw.max))
842+
continue;
843+
844+
max_data_rate = i915->display.bw.max[bw_index].deratedbw[i];
845+
846+
if (max_data_rate < data_rate)
847+
continue;
848+
849+
if (max_data_rate - data_rate < best_rate) {
850+
best_rate = max_data_rate - data_rate;
851+
qgv_peak_bw = i915->display.bw.max[bw_index].peakbw[i];
852+
}
853+
854+
drm_dbg_kms(&i915->drm, "QGV point %d: max bw %d required %d qgv_peak_bw: %d\n",
855+
i, max_data_rate, data_rate, qgv_peak_bw);
856+
}
857+
858+
drm_dbg_kms(&i915->drm, "Matching peaks QGV bw: %d for required data rate: %d\n",
859+
qgv_peak_bw, data_rate);
860+
861+
/*
862+
* The display configuration cannot be supported if no QGV point
863+
* satisfying the required data rate is found
864+
*/
865+
if (qgv_peak_bw == 0) {
866+
drm_dbg_kms(&i915->drm, "No QGV points for bw %d for display configuration(%d active planes).\n",
867+
data_rate, num_active_planes);
868+
return -EINVAL;
869+
}
870+
871+
/* MTL PM DEMAND expects QGV BW parameter in multiples of 100 mbps */
872+
new_bw_state->qgv_point_peakbw = DIV_ROUND_CLOSEST(qgv_peak_bw, 100);
873+
874+
return 0;
875+
}
876+
806877
static int icl_find_qgv_points(struct drm_i915_private *i915,
807878
unsigned int data_rate,
808879
unsigned int num_active_planes,
@@ -928,8 +999,12 @@ static int intel_bw_check_qgv_points(struct drm_i915_private *i915,
928999

9291000
data_rate = DIV_ROUND_UP(data_rate, 1000);
9301001

931-
return icl_find_qgv_points(i915, data_rate, num_active_planes,
932-
old_bw_state, new_bw_state);
1002+
if (DISPLAY_VER(i915) >= 14)
1003+
return mtl_find_qgv_points(i915, data_rate, num_active_planes,
1004+
new_bw_state);
1005+
else
1006+
return icl_find_qgv_points(i915, data_rate, num_active_planes,
1007+
old_bw_state, new_bw_state);
9331008
}
9341009

9351010
static bool intel_bw_state_changed(struct drm_i915_private *i915,

drivers/gpu/drm/i915/display/intel_bw.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ struct intel_bw_state {
3434
/* bitmask of active pipes */
3535
u8 active_pipes;
3636

37+
/*
38+
* From MTL onwards, to lock a QGV point, punit expects the peak BW of
39+
* the selected QGV point as the parameter in multiples of 100MB/s
40+
*/
41+
u16 qgv_point_peakbw;
42+
3743
/*
3844
* Current QGV points mask, which restricts
3945
* some particular SAGV states, not to confuse

0 commit comments

Comments
 (0)