Skip to content

Commit 463cc94

Browse files
vgovind2Radhakrishna Sripada
authored andcommitted
drm/i915: extract intel_bw_check_qgv_points()
Extract intel_bw_check_qgv_points() from intel_bw_atomic_check to facilitate future platform variations in handling SAGV configurations. 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-5-vinod.govindapillai@intel.com
1 parent 88d0ecb commit 463cc94

1 file changed

Lines changed: 130 additions & 105 deletions

File tree

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

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

806+
static int icl_find_qgv_points(struct drm_i915_private *i915,
807+
unsigned int data_rate,
808+
unsigned int num_active_planes,
809+
const struct intel_bw_state *old_bw_state,
810+
struct intel_bw_state *new_bw_state)
811+
{
812+
unsigned int max_bw_point = 0;
813+
unsigned int max_bw = 0;
814+
unsigned int num_psf_gv_points = i915->display.bw.max[0].num_psf_gv_points;
815+
unsigned int num_qgv_points = i915->display.bw.max[0].num_qgv_points;
816+
u16 psf_points = 0;
817+
u16 qgv_points = 0;
818+
int i;
819+
int ret;
820+
821+
ret = intel_atomic_lock_global_state(&new_bw_state->base);
822+
if (ret)
823+
return ret;
824+
825+
for (i = 0; i < num_qgv_points; i++) {
826+
unsigned int max_data_rate;
827+
828+
if (DISPLAY_VER(i915) > 11)
829+
max_data_rate = tgl_max_bw(i915, num_active_planes, i);
830+
else
831+
max_data_rate = icl_max_bw(i915, num_active_planes, i);
832+
/*
833+
* We need to know which qgv point gives us
834+
* maximum bandwidth in order to disable SAGV
835+
* if we find that we exceed SAGV block time
836+
* with watermarks. By that moment we already
837+
* have those, as it is calculated earlier in
838+
* intel_atomic_check,
839+
*/
840+
if (max_data_rate > max_bw) {
841+
max_bw_point = i;
842+
max_bw = max_data_rate;
843+
}
844+
if (max_data_rate >= data_rate)
845+
qgv_points |= BIT(i);
846+
847+
drm_dbg_kms(&i915->drm, "QGV point %d: max bw %d required %d\n",
848+
i, max_data_rate, data_rate);
849+
}
850+
851+
for (i = 0; i < num_psf_gv_points; i++) {
852+
unsigned int max_data_rate = adl_psf_bw(i915, i);
853+
854+
if (max_data_rate >= data_rate)
855+
psf_points |= BIT(i);
856+
857+
drm_dbg_kms(&i915->drm, "PSF GV point %d: max bw %d"
858+
" required %d\n",
859+
i, max_data_rate, data_rate);
860+
}
861+
862+
/*
863+
* BSpec states that we always should have at least one allowed point
864+
* left, so if we couldn't - simply reject the configuration for obvious
865+
* reasons.
866+
*/
867+
if (qgv_points == 0) {
868+
drm_dbg_kms(&i915->drm, "No QGV points provide sufficient memory"
869+
" bandwidth %d for display configuration(%d active planes).\n",
870+
data_rate, num_active_planes);
871+
return -EINVAL;
872+
}
873+
874+
if (num_psf_gv_points > 0 && psf_points == 0) {
875+
drm_dbg_kms(&i915->drm, "No PSF GV points provide sufficient memory"
876+
" bandwidth %d for display configuration(%d active planes).\n",
877+
data_rate, num_active_planes);
878+
return -EINVAL;
879+
}
880+
881+
/*
882+
* Leave only single point with highest bandwidth, if
883+
* we can't enable SAGV due to the increased memory latency it may
884+
* cause.
885+
*/
886+
if (!intel_can_enable_sagv(i915, new_bw_state)) {
887+
qgv_points = BIT(max_bw_point);
888+
drm_dbg_kms(&i915->drm, "No SAGV, using single QGV point %d\n",
889+
max_bw_point);
890+
}
891+
892+
/*
893+
* We store the ones which need to be masked as that is what PCode
894+
* actually accepts as a parameter.
895+
*/
896+
new_bw_state->qgv_points_mask =
897+
~(ICL_PCODE_REQ_QGV_PT(qgv_points) |
898+
ADLS_PCODE_REQ_PSF_PT(psf_points)) &
899+
icl_qgv_points_mask(i915);
900+
901+
/*
902+
* If the actual mask had changed we need to make sure that
903+
* the commits are serialized(in case this is a nomodeset, nonblocking)
904+
*/
905+
if (new_bw_state->qgv_points_mask != old_bw_state->qgv_points_mask) {
906+
ret = intel_atomic_serialize_global_state(&new_bw_state->base);
907+
if (ret)
908+
return ret;
909+
}
910+
911+
return 0;
912+
}
913+
914+
static int intel_bw_check_qgv_points(struct drm_i915_private *i915,
915+
const struct intel_bw_state *old_bw_state,
916+
struct intel_bw_state *new_bw_state)
917+
{
918+
unsigned int data_rate = intel_bw_data_rate(i915, new_bw_state);
919+
unsigned int num_active_planes =
920+
intel_bw_num_active_planes(i915, new_bw_state);
921+
922+
data_rate = DIV_ROUND_UP(data_rate, 1000);
923+
924+
return icl_find_qgv_points(i915, data_rate, num_active_planes,
925+
old_bw_state, new_bw_state);
926+
}
927+
806928
static bool intel_bw_state_changed(struct drm_i915_private *i915,
807929
const struct intel_bw_state *old_bw_state,
808930
const struct intel_bw_state *new_bw_state)
@@ -1049,20 +1171,14 @@ static int intel_bw_check_data_rate(struct intel_atomic_state *state, bool *chan
10491171

10501172
int intel_bw_atomic_check(struct intel_atomic_state *state)
10511173
{
1052-
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
1053-
const struct intel_bw_state *old_bw_state;
1054-
struct intel_bw_state *new_bw_state;
1055-
unsigned int data_rate;
1056-
unsigned int num_active_planes;
1057-
int i, ret;
1058-
u16 qgv_points = 0, psf_points = 0;
1059-
unsigned int max_bw_point = 0, max_bw = 0;
1060-
unsigned int num_qgv_points = dev_priv->display.bw.max[0].num_qgv_points;
1061-
unsigned int num_psf_gv_points = dev_priv->display.bw.max[0].num_psf_gv_points;
10621174
bool changed = false;
1175+
struct drm_i915_private *i915 = to_i915(state->base.dev);
1176+
struct intel_bw_state *new_bw_state;
1177+
const struct intel_bw_state *old_bw_state;
1178+
int ret;
10631179

10641180
/* FIXME earlier gens need some checks too */
1065-
if (DISPLAY_VER(dev_priv) < 11)
1181+
if (DISPLAY_VER(i915) < 11)
10661182
return 0;
10671183

10681184
ret = intel_bw_check_data_rate(state, &changed);
@@ -1073,8 +1189,8 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
10731189
new_bw_state = intel_atomic_get_new_bw_state(state);
10741190

10751191
if (new_bw_state &&
1076-
intel_can_enable_sagv(dev_priv, old_bw_state) !=
1077-
intel_can_enable_sagv(dev_priv, new_bw_state))
1192+
intel_can_enable_sagv(i915, old_bw_state) !=
1193+
intel_can_enable_sagv(i915, new_bw_state))
10781194
changed = true;
10791195

10801196
/*
@@ -1084,101 +1200,10 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
10841200
if (!changed)
10851201
return 0;
10861202

1087-
ret = intel_atomic_lock_global_state(&new_bw_state->base);
1203+
ret = intel_bw_check_qgv_points(i915, old_bw_state, new_bw_state);
10881204
if (ret)
10891205
return ret;
10901206

1091-
data_rate = intel_bw_data_rate(dev_priv, new_bw_state);
1092-
data_rate = DIV_ROUND_UP(data_rate, 1000);
1093-
1094-
num_active_planes = intel_bw_num_active_planes(dev_priv, new_bw_state);
1095-
1096-
for (i = 0; i < num_qgv_points; i++) {
1097-
unsigned int max_data_rate;
1098-
1099-
if (DISPLAY_VER(dev_priv) > 11)
1100-
max_data_rate = tgl_max_bw(dev_priv, num_active_planes, i);
1101-
else
1102-
max_data_rate = icl_max_bw(dev_priv, num_active_planes, i);
1103-
/*
1104-
* We need to know which qgv point gives us
1105-
* maximum bandwidth in order to disable SAGV
1106-
* if we find that we exceed SAGV block time
1107-
* with watermarks. By that moment we already
1108-
* have those, as it is calculated earlier in
1109-
* intel_atomic_check,
1110-
*/
1111-
if (max_data_rate > max_bw) {
1112-
max_bw_point = i;
1113-
max_bw = max_data_rate;
1114-
}
1115-
if (max_data_rate >= data_rate)
1116-
qgv_points |= BIT(i);
1117-
1118-
drm_dbg_kms(&dev_priv->drm, "QGV point %d: max bw %d required %d\n",
1119-
i, max_data_rate, data_rate);
1120-
}
1121-
1122-
for (i = 0; i < num_psf_gv_points; i++) {
1123-
unsigned int max_data_rate = adl_psf_bw(dev_priv, i);
1124-
1125-
if (max_data_rate >= data_rate)
1126-
psf_points |= BIT(i);
1127-
1128-
drm_dbg_kms(&dev_priv->drm, "PSF GV point %d: max bw %d"
1129-
" required %d\n",
1130-
i, max_data_rate, data_rate);
1131-
}
1132-
1133-
/*
1134-
* BSpec states that we always should have at least one allowed point
1135-
* left, so if we couldn't - simply reject the configuration for obvious
1136-
* reasons.
1137-
*/
1138-
if (qgv_points == 0) {
1139-
drm_dbg_kms(&dev_priv->drm, "No QGV points provide sufficient memory"
1140-
" bandwidth %d for display configuration(%d active planes).\n",
1141-
data_rate, num_active_planes);
1142-
return -EINVAL;
1143-
}
1144-
1145-
if (num_psf_gv_points > 0 && psf_points == 0) {
1146-
drm_dbg_kms(&dev_priv->drm, "No PSF GV points provide sufficient memory"
1147-
" bandwidth %d for display configuration(%d active planes).\n",
1148-
data_rate, num_active_planes);
1149-
return -EINVAL;
1150-
}
1151-
1152-
/*
1153-
* Leave only single point with highest bandwidth, if
1154-
* we can't enable SAGV due to the increased memory latency it may
1155-
* cause.
1156-
*/
1157-
if (!intel_can_enable_sagv(dev_priv, new_bw_state)) {
1158-
qgv_points = BIT(max_bw_point);
1159-
drm_dbg_kms(&dev_priv->drm, "No SAGV, using single QGV point %d\n",
1160-
max_bw_point);
1161-
}
1162-
1163-
/*
1164-
* We store the ones which need to be masked as that is what PCode
1165-
* actually accepts as a parameter.
1166-
*/
1167-
new_bw_state->qgv_points_mask =
1168-
~(ICL_PCODE_REQ_QGV_PT(qgv_points) |
1169-
ADLS_PCODE_REQ_PSF_PT(psf_points)) &
1170-
icl_qgv_points_mask(dev_priv);
1171-
1172-
/*
1173-
* If the actual mask had changed we need to make sure that
1174-
* the commits are serialized(in case this is a nomodeset, nonblocking)
1175-
*/
1176-
if (new_bw_state->qgv_points_mask != old_bw_state->qgv_points_mask) {
1177-
ret = intel_atomic_serialize_global_state(&new_bw_state->base);
1178-
if (ret)
1179-
return ret;
1180-
}
1181-
11821207
return 0;
11831208
}
11841209

0 commit comments

Comments
 (0)