2019-05-24 15:36:14 +00:00
|
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
/*
|
|
|
|
* Copyright © 2019 Intel Corporation
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <drm/drm_atomic_state_helper.h>
|
|
|
|
|
2022-01-27 23:43:34 +00:00
|
|
|
#include "i915_reg.h"
|
2022-03-29 09:02:04 +00:00
|
|
|
#include "i915_utils.h"
|
2020-05-22 13:18:43 +00:00
|
|
|
#include "intel_atomic.h"
|
2019-05-24 15:36:14 +00:00
|
|
|
#include "intel_bw.h"
|
2020-05-22 13:18:43 +00:00
|
|
|
#include "intel_cdclk.h"
|
2019-08-06 11:39:33 +00:00
|
|
|
#include "intel_display_types.h"
|
2022-02-15 06:13:42 +00:00
|
|
|
#include "intel_mchbar_regs.h"
|
2021-10-14 10:28:57 +00:00
|
|
|
#include "intel_pcode.h"
|
drm/i915: Restrict qgv points which don't have enough bandwidth.
According to BSpec 53998, we should try to
restrict qgv points, which can't provide
enough bandwidth for desired display configuration.
Currently we are just comparing against all of
those and take minimum(worst case).
v2: Fixed wrong PCode reply mask, removed hardcoded
values.
v3: Forbid simultaneous legacy SAGV PCode requests and
restricting qgv points. Put the actual restriction
to commit function, added serialization(thanks to Ville)
to prevent commit being applied out of order in case of
nonblocking and/or nomodeset commits.
v4:
- Minor code refactoring, fixed few typos(thanks to James Ausmus)
- Change the naming of qgv point
masking/unmasking functions(James Ausmus).
- Simplify the masking/unmasking operation itself,
as we don't need to mask only single point per request(James Ausmus)
- Reject and stick to highest bandwidth point if SAGV
can't be enabled(BSpec)
v5:
- Add new mailbox reply codes, which seems to happen during boot
time for TGL and indicate that QGV setting is not yet available.
v6:
- Increase number of supported QGV points to be in sync with BSpec.
v7: - Rebased and resolved conflict to fix build failure.
- Fix NUM_QGV_POINTS to 8 and moved that to header file(James Ausmus)
v8: - Don't report an error if we can't restrict qgv points, as SAGV
can be disabled by BIOS, which is completely legal. So don't
make CI panic. Instead if we detect that there is only 1 QGV
point accessible just analyze if we can fit the required bandwidth
requirements, but no need in restricting.
v9: - Fix wrong QGV transition if we have 0 planes and no SAGV
simultaneously.
v10: - Fix CDCLK corruption, because of global state getting serialized
without modeset, which caused copying of non-calculated cdclk
to be copied to dev_priv(thanks to Ville for the hint).
v11: - Remove unneeded headers and spaces(Matthew Roper)
- Remove unneeded intel_qgv_info qi struct from bw check and zero
out the needed one(Matthew Roper)
- Changed QGV error message to have more clear meaning(Matthew Roper)
- Use state->modeset_set instead of any_ms(Matthew Roper)
- Moved NUM_SAGV_POINTS from i915_reg.h to i915_drv.h where it's used
- Keep using crtc_state->hw.active instead of .enable(Matthew Roper)
- Moved unrelated changes to other patch(using latency as parameter
for plane wm calculation, moved to SAGV refactoring patch)
v12: - Fix rebase conflict with own temporary SAGV/QGV fix.
- Remove unnecessary mask being zero check when unmasking
qgv points as this is completely legal(Matt Roper)
- Check if we are setting the same mask as already being set
in hardware to prevent error from PCode.
- Fix error message when restricting/unrestricting qgv points
to "mask/unmask" which sounds more accurate(Matt Roper)
- Move sagv status setting to icl_get_bw_info from atomic check
as this should be calculated only once.(Matt Roper)
- Edited comments for the case when we can't enable SAGV and
use only 1 QGV point with highest bandwidth to be more
understandable.(Matt Roper)
v13: - Moved max_data_rate in bw check to closer scope(Ville Syrjälä)
- Changed comment for zero new_mask in qgv points masking function
to better reflect reality(Ville Syrjälä)
- Simplified bit mask operation in qgv points masking function
(Ville Syrjälä)
- Moved intel_qgv_points_mask closer to gen11 SAGV disabling,
however this still can't be under modeset condition(Ville Syrjälä)
- Packed qgv_points_mask as u8 and moved closer to pipe_sagv_mask
(Ville Syrjälä)
- Extracted PCode changes to separate patch.(Ville Syrjälä)
- Now treat num_planes 0 same as 1 to avoid confusion and
returning max_bw as 0, which would prevent choosing QGV
point having max bandwidth in case if SAGV is not allowed,
as per BSpec(Ville Syrjälä)
- Do the actual qgv_points_mask swap in the same place as
all other global state parts like cdclk are swapped.
In the next patch, this all will be moved to bw state as
global state, once new global state patch series from Ville
lands
v14: - Now using global state to serialize access to qgv points
- Added global state locking back, otherwise we seem to read
bw state in a wrong way.
v15: - Added TODO comment for near atomic global state locking in
bw code.
v16: - Fixed intel_atomic_bw_* functions to be intel_bw_* as discussed
with Jani Nikula.
- Take bw_state_changed flag into use.
v17: - Moved qgv point related manipulations next to SAGV code, as
those are semantically related(Ville Syrjälä)
- Renamed those into intel_sagv_(pre)|(post)_plane_update
(Ville Syrjälä)
v18: - Move sagv related calls from commit tail into
intel_sagv_(pre)|(post)_plane_update(Ville Syrjälä)
v19: - Use intel_atomic_get_bw_(old)|(new)_state which is intended
for commit tail stage.
v20: - Return max bandwidth for 0 planes(Ville)
- Constify old_bw_state in bw_atomic_check(Ville)
- Removed some debugs(Ville)
- Added data rate to debug print when no QGV points(Ville)
- Removed some comments(Ville)
v21, v22, v23: - Fixed rebase conflict
v24: - Changed PCode mask to use ICL_ prefix
v25: - Resolved rebase conflict
v26: - Removed redundant NULL checks(Ville)
- Removed redundant error prints(Ville)
v27: - Use device specific drm_err(Ville)
- Fixed parenthesis ident reported by checkpatch
Line over 100 warns to be fixed together with
existing code style.
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Ville Syrjälä <ville.syrjala@intel.com>
Cc: James Ausmus <james.ausmus@intel.com>
[vsyrjala: Drop duplicate intel_sagv_{pre,post}_plane_update() prototypes
and drop unused NUM_SAGV_POINTS define]
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200514074853.9508-3-stanislav.lisovskiy@intel.com
2020-05-14 07:48:52 +00:00
|
|
|
#include "intel_pm.h"
|
2019-05-24 15:36:14 +00:00
|
|
|
|
|
|
|
/* Parameters for Qclk Geyserville (QGV) */
|
|
|
|
struct intel_qgv_point {
|
|
|
|
u16 dclk, t_rp, t_rdpre, t_rc, t_ras, t_rcd;
|
|
|
|
};
|
|
|
|
|
drm/i915: Implement PSF GV point support
PSF GV points are an additional factor that can limit the
bandwidth available to display, separate from the traditional
QGV points. Whereas traditional QGV points represent possible
memory clock frequencies, PSF GV points reflect possible
frequencies of the memory fabric.
Switching between PSF GV points has the advantage of incurring
almost no memory access block time and thus does not need to be
accounted for in watermark calculations.
This patch adds support for those on top of regular QGV points.
Those are supposed to be used simultaneously, i.e we are always
at some QGV and some PSF GV point, based on the current video
mode requirements.
Bspec: 64631, 53998
v2: Seems that initial assumption made during ml conversation
was wrong, PCode rejects any masks containing points beyond
the ones returned, so even though BSpec says we have around
8 points theoretically, we can mask/unmask only those which
are returned, trying to manipulate those beyond causes a
failure from PCode. So switched back to generating mask
from 1 - num_qgv_points, where num_qgv_points is the actual
amount of points, advertised by PCode.
v3: - Extended restricted qgv point mask to 0xf, as we have now
3:2 bits for PSF GV points(Matt Roper)
- Replaced val2 with NULL from PCode request, since its not being
used(Matt Roper)
- Replaced %d to 0x%x for better readability(thanks for spotting)
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210531064845.4389-2-stanislav.lisovskiy@intel.com
2021-05-31 06:48:45 +00:00
|
|
|
struct intel_psf_gv_point {
|
|
|
|
u8 clk; /* clock in multiples of 16.6666 MHz */
|
|
|
|
};
|
|
|
|
|
2019-05-24 15:36:14 +00:00
|
|
|
struct intel_qgv_info {
|
2019-11-25 16:08:00 +00:00
|
|
|
struct intel_qgv_point points[I915_NUM_QGV_POINTS];
|
drm/i915: Implement PSF GV point support
PSF GV points are an additional factor that can limit the
bandwidth available to display, separate from the traditional
QGV points. Whereas traditional QGV points represent possible
memory clock frequencies, PSF GV points reflect possible
frequencies of the memory fabric.
Switching between PSF GV points has the advantage of incurring
almost no memory access block time and thus does not need to be
accounted for in watermark calculations.
This patch adds support for those on top of regular QGV points.
Those are supposed to be used simultaneously, i.e we are always
at some QGV and some PSF GV point, based on the current video
mode requirements.
Bspec: 64631, 53998
v2: Seems that initial assumption made during ml conversation
was wrong, PCode rejects any masks containing points beyond
the ones returned, so even though BSpec says we have around
8 points theoretically, we can mask/unmask only those which
are returned, trying to manipulate those beyond causes a
failure from PCode. So switched back to generating mask
from 1 - num_qgv_points, where num_qgv_points is the actual
amount of points, advertised by PCode.
v3: - Extended restricted qgv point mask to 0xf, as we have now
3:2 bits for PSF GV points(Matt Roper)
- Replaced val2 with NULL from PCode request, since its not being
used(Matt Roper)
- Replaced %d to 0x%x for better readability(thanks for spotting)
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210531064845.4389-2-stanislav.lisovskiy@intel.com
2021-05-31 06:48:45 +00:00
|
|
|
struct intel_psf_gv_point psf_points[I915_NUM_PSF_GV_POINTS];
|
2019-05-24 15:36:14 +00:00
|
|
|
u8 num_points;
|
drm/i915: Implement PSF GV point support
PSF GV points are an additional factor that can limit the
bandwidth available to display, separate from the traditional
QGV points. Whereas traditional QGV points represent possible
memory clock frequencies, PSF GV points reflect possible
frequencies of the memory fabric.
Switching between PSF GV points has the advantage of incurring
almost no memory access block time and thus does not need to be
accounted for in watermark calculations.
This patch adds support for those on top of regular QGV points.
Those are supposed to be used simultaneously, i.e we are always
at some QGV and some PSF GV point, based on the current video
mode requirements.
Bspec: 64631, 53998
v2: Seems that initial assumption made during ml conversation
was wrong, PCode rejects any masks containing points beyond
the ones returned, so even though BSpec says we have around
8 points theoretically, we can mask/unmask only those which
are returned, trying to manipulate those beyond causes a
failure from PCode. So switched back to generating mask
from 1 - num_qgv_points, where num_qgv_points is the actual
amount of points, advertised by PCode.
v3: - Extended restricted qgv point mask to 0xf, as we have now
3:2 bits for PSF GV points(Matt Roper)
- Replaced val2 with NULL from PCode request, since its not being
used(Matt Roper)
- Replaced %d to 0x%x for better readability(thanks for spotting)
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210531064845.4389-2-stanislav.lisovskiy@intel.com
2021-05-31 06:48:45 +00:00
|
|
|
u8 num_psf_points;
|
2019-05-24 15:36:14 +00:00
|
|
|
u8 t_bl;
|
2021-10-15 21:00:41 +00:00
|
|
|
u8 max_numchannels;
|
|
|
|
u8 channel_width;
|
|
|
|
u8 deinterleave;
|
2019-05-24 15:36:14 +00:00
|
|
|
};
|
|
|
|
|
2021-07-08 17:52:26 +00:00
|
|
|
static int dg1_mchbar_read_qgv_point_info(struct drm_i915_private *dev_priv,
|
|
|
|
struct intel_qgv_point *sp,
|
|
|
|
int point)
|
|
|
|
{
|
|
|
|
u32 dclk_ratio, dclk_reference;
|
|
|
|
u32 val;
|
|
|
|
|
|
|
|
val = intel_uncore_read(&dev_priv->uncore, SA_PERF_STATUS_0_0_0_MCHBAR_PC);
|
|
|
|
dclk_ratio = REG_FIELD_GET(DG1_QCLK_RATIO_MASK, val);
|
|
|
|
if (val & DG1_QCLK_REFERENCE)
|
|
|
|
dclk_reference = 6; /* 6 * 16.666 MHz = 100 MHz */
|
|
|
|
else
|
|
|
|
dclk_reference = 8; /* 8 * 16.666 MHz = 133 MHz */
|
2021-10-15 21:00:41 +00:00
|
|
|
sp->dclk = DIV_ROUND_UP((16667 * dclk_ratio * dclk_reference) + 500, 1000);
|
2021-07-08 17:52:26 +00:00
|
|
|
|
|
|
|
val = intel_uncore_read(&dev_priv->uncore, SKL_MC_BIOS_DATA_0_0_0_MCHBAR_PCU);
|
|
|
|
if (val & DG1_GEAR_TYPE)
|
|
|
|
sp->dclk *= 2;
|
|
|
|
|
|
|
|
if (sp->dclk == 0)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
val = intel_uncore_read(&dev_priv->uncore, MCHBAR_CH0_CR_TC_PRE_0_0_0_MCHBAR);
|
|
|
|
sp->t_rp = REG_FIELD_GET(DG1_DRAM_T_RP_MASK, val);
|
|
|
|
sp->t_rdpre = REG_FIELD_GET(DG1_DRAM_T_RDPRE_MASK, val);
|
|
|
|
|
|
|
|
val = intel_uncore_read(&dev_priv->uncore, MCHBAR_CH0_CR_TC_PRE_0_0_0_MCHBAR_HIGH);
|
|
|
|
sp->t_rcd = REG_FIELD_GET(DG1_DRAM_T_RCD_MASK, val);
|
|
|
|
sp->t_ras = REG_FIELD_GET(DG1_DRAM_T_RAS_MASK, val);
|
|
|
|
|
|
|
|
sp->t_rc = sp->t_rp + sp->t_ras;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-05-24 15:36:14 +00:00
|
|
|
static int icl_pcode_read_qgv_point_info(struct drm_i915_private *dev_priv,
|
|
|
|
struct intel_qgv_point *sp,
|
|
|
|
int point)
|
|
|
|
{
|
2019-07-10 13:49:37 +00:00
|
|
|
u32 val = 0, val2 = 0;
|
2021-10-15 21:00:41 +00:00
|
|
|
u16 dclk;
|
2019-05-24 15:36:14 +00:00
|
|
|
int ret;
|
|
|
|
|
2022-01-12 11:17:40 +00:00
|
|
|
ret = snb_pcode_read(dev_priv, ICL_PCODE_MEM_SUBSYSYSTEM_INFO |
|
|
|
|
ICL_PCODE_MEM_SS_READ_QGV_POINT_INFO(point),
|
|
|
|
&val, &val2);
|
2019-05-24 15:36:14 +00:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
2021-10-15 21:00:41 +00:00
|
|
|
dclk = val & 0xffff;
|
|
|
|
sp->dclk = DIV_ROUND_UP((16667 * dclk) + (DISPLAY_VER(dev_priv) > 11 ? 500 : 0), 1000);
|
2019-05-24 15:36:14 +00:00
|
|
|
sp->t_rp = (val & 0xff0000) >> 16;
|
|
|
|
sp->t_rcd = (val & 0xff000000) >> 24;
|
|
|
|
|
|
|
|
sp->t_rdpre = val2 & 0xff;
|
|
|
|
sp->t_ras = (val2 & 0xff00) >> 8;
|
|
|
|
|
|
|
|
sp->t_rc = sp->t_rp + sp->t_ras;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
drm/i915: Implement PSF GV point support
PSF GV points are an additional factor that can limit the
bandwidth available to display, separate from the traditional
QGV points. Whereas traditional QGV points represent possible
memory clock frequencies, PSF GV points reflect possible
frequencies of the memory fabric.
Switching between PSF GV points has the advantage of incurring
almost no memory access block time and thus does not need to be
accounted for in watermark calculations.
This patch adds support for those on top of regular QGV points.
Those are supposed to be used simultaneously, i.e we are always
at some QGV and some PSF GV point, based on the current video
mode requirements.
Bspec: 64631, 53998
v2: Seems that initial assumption made during ml conversation
was wrong, PCode rejects any masks containing points beyond
the ones returned, so even though BSpec says we have around
8 points theoretically, we can mask/unmask only those which
are returned, trying to manipulate those beyond causes a
failure from PCode. So switched back to generating mask
from 1 - num_qgv_points, where num_qgv_points is the actual
amount of points, advertised by PCode.
v3: - Extended restricted qgv point mask to 0xf, as we have now
3:2 bits for PSF GV points(Matt Roper)
- Replaced val2 with NULL from PCode request, since its not being
used(Matt Roper)
- Replaced %d to 0x%x for better readability(thanks for spotting)
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210531064845.4389-2-stanislav.lisovskiy@intel.com
2021-05-31 06:48:45 +00:00
|
|
|
static int adls_pcode_read_psf_gv_point_info(struct drm_i915_private *dev_priv,
|
|
|
|
struct intel_psf_gv_point *points)
|
|
|
|
{
|
|
|
|
u32 val = 0;
|
|
|
|
int ret;
|
|
|
|
int i;
|
|
|
|
|
2022-01-12 11:17:40 +00:00
|
|
|
ret = snb_pcode_read(dev_priv, ICL_PCODE_MEM_SUBSYSYSTEM_INFO |
|
|
|
|
ADL_PCODE_MEM_SS_READ_PSF_GV_INFO, &val, NULL);
|
drm/i915: Implement PSF GV point support
PSF GV points are an additional factor that can limit the
bandwidth available to display, separate from the traditional
QGV points. Whereas traditional QGV points represent possible
memory clock frequencies, PSF GV points reflect possible
frequencies of the memory fabric.
Switching between PSF GV points has the advantage of incurring
almost no memory access block time and thus does not need to be
accounted for in watermark calculations.
This patch adds support for those on top of regular QGV points.
Those are supposed to be used simultaneously, i.e we are always
at some QGV and some PSF GV point, based on the current video
mode requirements.
Bspec: 64631, 53998
v2: Seems that initial assumption made during ml conversation
was wrong, PCode rejects any masks containing points beyond
the ones returned, so even though BSpec says we have around
8 points theoretically, we can mask/unmask only those which
are returned, trying to manipulate those beyond causes a
failure from PCode. So switched back to generating mask
from 1 - num_qgv_points, where num_qgv_points is the actual
amount of points, advertised by PCode.
v3: - Extended restricted qgv point mask to 0xf, as we have now
3:2 bits for PSF GV points(Matt Roper)
- Replaced val2 with NULL from PCode request, since its not being
used(Matt Roper)
- Replaced %d to 0x%x for better readability(thanks for spotting)
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210531064845.4389-2-stanislav.lisovskiy@intel.com
2021-05-31 06:48:45 +00:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
for (i = 0; i < I915_NUM_PSF_GV_POINTS; i++) {
|
|
|
|
points[i].clk = val & 0xff;
|
|
|
|
val >>= 8;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
drm/i915: Restrict qgv points which don't have enough bandwidth.
According to BSpec 53998, we should try to
restrict qgv points, which can't provide
enough bandwidth for desired display configuration.
Currently we are just comparing against all of
those and take minimum(worst case).
v2: Fixed wrong PCode reply mask, removed hardcoded
values.
v3: Forbid simultaneous legacy SAGV PCode requests and
restricting qgv points. Put the actual restriction
to commit function, added serialization(thanks to Ville)
to prevent commit being applied out of order in case of
nonblocking and/or nomodeset commits.
v4:
- Minor code refactoring, fixed few typos(thanks to James Ausmus)
- Change the naming of qgv point
masking/unmasking functions(James Ausmus).
- Simplify the masking/unmasking operation itself,
as we don't need to mask only single point per request(James Ausmus)
- Reject and stick to highest bandwidth point if SAGV
can't be enabled(BSpec)
v5:
- Add new mailbox reply codes, which seems to happen during boot
time for TGL and indicate that QGV setting is not yet available.
v6:
- Increase number of supported QGV points to be in sync with BSpec.
v7: - Rebased and resolved conflict to fix build failure.
- Fix NUM_QGV_POINTS to 8 and moved that to header file(James Ausmus)
v8: - Don't report an error if we can't restrict qgv points, as SAGV
can be disabled by BIOS, which is completely legal. So don't
make CI panic. Instead if we detect that there is only 1 QGV
point accessible just analyze if we can fit the required bandwidth
requirements, but no need in restricting.
v9: - Fix wrong QGV transition if we have 0 planes and no SAGV
simultaneously.
v10: - Fix CDCLK corruption, because of global state getting serialized
without modeset, which caused copying of non-calculated cdclk
to be copied to dev_priv(thanks to Ville for the hint).
v11: - Remove unneeded headers and spaces(Matthew Roper)
- Remove unneeded intel_qgv_info qi struct from bw check and zero
out the needed one(Matthew Roper)
- Changed QGV error message to have more clear meaning(Matthew Roper)
- Use state->modeset_set instead of any_ms(Matthew Roper)
- Moved NUM_SAGV_POINTS from i915_reg.h to i915_drv.h where it's used
- Keep using crtc_state->hw.active instead of .enable(Matthew Roper)
- Moved unrelated changes to other patch(using latency as parameter
for plane wm calculation, moved to SAGV refactoring patch)
v12: - Fix rebase conflict with own temporary SAGV/QGV fix.
- Remove unnecessary mask being zero check when unmasking
qgv points as this is completely legal(Matt Roper)
- Check if we are setting the same mask as already being set
in hardware to prevent error from PCode.
- Fix error message when restricting/unrestricting qgv points
to "mask/unmask" which sounds more accurate(Matt Roper)
- Move sagv status setting to icl_get_bw_info from atomic check
as this should be calculated only once.(Matt Roper)
- Edited comments for the case when we can't enable SAGV and
use only 1 QGV point with highest bandwidth to be more
understandable.(Matt Roper)
v13: - Moved max_data_rate in bw check to closer scope(Ville Syrjälä)
- Changed comment for zero new_mask in qgv points masking function
to better reflect reality(Ville Syrjälä)
- Simplified bit mask operation in qgv points masking function
(Ville Syrjälä)
- Moved intel_qgv_points_mask closer to gen11 SAGV disabling,
however this still can't be under modeset condition(Ville Syrjälä)
- Packed qgv_points_mask as u8 and moved closer to pipe_sagv_mask
(Ville Syrjälä)
- Extracted PCode changes to separate patch.(Ville Syrjälä)
- Now treat num_planes 0 same as 1 to avoid confusion and
returning max_bw as 0, which would prevent choosing QGV
point having max bandwidth in case if SAGV is not allowed,
as per BSpec(Ville Syrjälä)
- Do the actual qgv_points_mask swap in the same place as
all other global state parts like cdclk are swapped.
In the next patch, this all will be moved to bw state as
global state, once new global state patch series from Ville
lands
v14: - Now using global state to serialize access to qgv points
- Added global state locking back, otherwise we seem to read
bw state in a wrong way.
v15: - Added TODO comment for near atomic global state locking in
bw code.
v16: - Fixed intel_atomic_bw_* functions to be intel_bw_* as discussed
with Jani Nikula.
- Take bw_state_changed flag into use.
v17: - Moved qgv point related manipulations next to SAGV code, as
those are semantically related(Ville Syrjälä)
- Renamed those into intel_sagv_(pre)|(post)_plane_update
(Ville Syrjälä)
v18: - Move sagv related calls from commit tail into
intel_sagv_(pre)|(post)_plane_update(Ville Syrjälä)
v19: - Use intel_atomic_get_bw_(old)|(new)_state which is intended
for commit tail stage.
v20: - Return max bandwidth for 0 planes(Ville)
- Constify old_bw_state in bw_atomic_check(Ville)
- Removed some debugs(Ville)
- Added data rate to debug print when no QGV points(Ville)
- Removed some comments(Ville)
v21, v22, v23: - Fixed rebase conflict
v24: - Changed PCode mask to use ICL_ prefix
v25: - Resolved rebase conflict
v26: - Removed redundant NULL checks(Ville)
- Removed redundant error prints(Ville)
v27: - Use device specific drm_err(Ville)
- Fixed parenthesis ident reported by checkpatch
Line over 100 warns to be fixed together with
existing code style.
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Ville Syrjälä <ville.syrjala@intel.com>
Cc: James Ausmus <james.ausmus@intel.com>
[vsyrjala: Drop duplicate intel_sagv_{pre,post}_plane_update() prototypes
and drop unused NUM_SAGV_POINTS define]
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200514074853.9508-3-stanislav.lisovskiy@intel.com
2020-05-14 07:48:52 +00:00
|
|
|
int icl_pcode_restrict_qgv_points(struct drm_i915_private *dev_priv,
|
|
|
|
u32 points_mask)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
/* bspec says to keep retrying for at least 1 ms */
|
|
|
|
ret = skl_pcode_request(dev_priv, ICL_PCODE_SAGV_DE_MEM_SS_CONFIG,
|
|
|
|
points_mask,
|
2022-03-09 16:49:48 +00:00
|
|
|
ICL_PCODE_REP_QGV_MASK | ADLS_PCODE_REP_PSF_MASK,
|
|
|
|
ICL_PCODE_REP_QGV_SAFE | ADLS_PCODE_REP_PSF_SAFE,
|
drm/i915: Restrict qgv points which don't have enough bandwidth.
According to BSpec 53998, we should try to
restrict qgv points, which can't provide
enough bandwidth for desired display configuration.
Currently we are just comparing against all of
those and take minimum(worst case).
v2: Fixed wrong PCode reply mask, removed hardcoded
values.
v3: Forbid simultaneous legacy SAGV PCode requests and
restricting qgv points. Put the actual restriction
to commit function, added serialization(thanks to Ville)
to prevent commit being applied out of order in case of
nonblocking and/or nomodeset commits.
v4:
- Minor code refactoring, fixed few typos(thanks to James Ausmus)
- Change the naming of qgv point
masking/unmasking functions(James Ausmus).
- Simplify the masking/unmasking operation itself,
as we don't need to mask only single point per request(James Ausmus)
- Reject and stick to highest bandwidth point if SAGV
can't be enabled(BSpec)
v5:
- Add new mailbox reply codes, which seems to happen during boot
time for TGL and indicate that QGV setting is not yet available.
v6:
- Increase number of supported QGV points to be in sync with BSpec.
v7: - Rebased and resolved conflict to fix build failure.
- Fix NUM_QGV_POINTS to 8 and moved that to header file(James Ausmus)
v8: - Don't report an error if we can't restrict qgv points, as SAGV
can be disabled by BIOS, which is completely legal. So don't
make CI panic. Instead if we detect that there is only 1 QGV
point accessible just analyze if we can fit the required bandwidth
requirements, but no need in restricting.
v9: - Fix wrong QGV transition if we have 0 planes and no SAGV
simultaneously.
v10: - Fix CDCLK corruption, because of global state getting serialized
without modeset, which caused copying of non-calculated cdclk
to be copied to dev_priv(thanks to Ville for the hint).
v11: - Remove unneeded headers and spaces(Matthew Roper)
- Remove unneeded intel_qgv_info qi struct from bw check and zero
out the needed one(Matthew Roper)
- Changed QGV error message to have more clear meaning(Matthew Roper)
- Use state->modeset_set instead of any_ms(Matthew Roper)
- Moved NUM_SAGV_POINTS from i915_reg.h to i915_drv.h where it's used
- Keep using crtc_state->hw.active instead of .enable(Matthew Roper)
- Moved unrelated changes to other patch(using latency as parameter
for plane wm calculation, moved to SAGV refactoring patch)
v12: - Fix rebase conflict with own temporary SAGV/QGV fix.
- Remove unnecessary mask being zero check when unmasking
qgv points as this is completely legal(Matt Roper)
- Check if we are setting the same mask as already being set
in hardware to prevent error from PCode.
- Fix error message when restricting/unrestricting qgv points
to "mask/unmask" which sounds more accurate(Matt Roper)
- Move sagv status setting to icl_get_bw_info from atomic check
as this should be calculated only once.(Matt Roper)
- Edited comments for the case when we can't enable SAGV and
use only 1 QGV point with highest bandwidth to be more
understandable.(Matt Roper)
v13: - Moved max_data_rate in bw check to closer scope(Ville Syrjälä)
- Changed comment for zero new_mask in qgv points masking function
to better reflect reality(Ville Syrjälä)
- Simplified bit mask operation in qgv points masking function
(Ville Syrjälä)
- Moved intel_qgv_points_mask closer to gen11 SAGV disabling,
however this still can't be under modeset condition(Ville Syrjälä)
- Packed qgv_points_mask as u8 and moved closer to pipe_sagv_mask
(Ville Syrjälä)
- Extracted PCode changes to separate patch.(Ville Syrjälä)
- Now treat num_planes 0 same as 1 to avoid confusion and
returning max_bw as 0, which would prevent choosing QGV
point having max bandwidth in case if SAGV is not allowed,
as per BSpec(Ville Syrjälä)
- Do the actual qgv_points_mask swap in the same place as
all other global state parts like cdclk are swapped.
In the next patch, this all will be moved to bw state as
global state, once new global state patch series from Ville
lands
v14: - Now using global state to serialize access to qgv points
- Added global state locking back, otherwise we seem to read
bw state in a wrong way.
v15: - Added TODO comment for near atomic global state locking in
bw code.
v16: - Fixed intel_atomic_bw_* functions to be intel_bw_* as discussed
with Jani Nikula.
- Take bw_state_changed flag into use.
v17: - Moved qgv point related manipulations next to SAGV code, as
those are semantically related(Ville Syrjälä)
- Renamed those into intel_sagv_(pre)|(post)_plane_update
(Ville Syrjälä)
v18: - Move sagv related calls from commit tail into
intel_sagv_(pre)|(post)_plane_update(Ville Syrjälä)
v19: - Use intel_atomic_get_bw_(old)|(new)_state which is intended
for commit tail stage.
v20: - Return max bandwidth for 0 planes(Ville)
- Constify old_bw_state in bw_atomic_check(Ville)
- Removed some debugs(Ville)
- Added data rate to debug print when no QGV points(Ville)
- Removed some comments(Ville)
v21, v22, v23: - Fixed rebase conflict
v24: - Changed PCode mask to use ICL_ prefix
v25: - Resolved rebase conflict
v26: - Removed redundant NULL checks(Ville)
- Removed redundant error prints(Ville)
v27: - Use device specific drm_err(Ville)
- Fixed parenthesis ident reported by checkpatch
Line over 100 warns to be fixed together with
existing code style.
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Ville Syrjälä <ville.syrjala@intel.com>
Cc: James Ausmus <james.ausmus@intel.com>
[vsyrjala: Drop duplicate intel_sagv_{pre,post}_plane_update() prototypes
and drop unused NUM_SAGV_POINTS define]
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200514074853.9508-3-stanislav.lisovskiy@intel.com
2020-05-14 07:48:52 +00:00
|
|
|
1);
|
|
|
|
|
|
|
|
if (ret < 0) {
|
drm/i915: Implement PSF GV point support
PSF GV points are an additional factor that can limit the
bandwidth available to display, separate from the traditional
QGV points. Whereas traditional QGV points represent possible
memory clock frequencies, PSF GV points reflect possible
frequencies of the memory fabric.
Switching between PSF GV points has the advantage of incurring
almost no memory access block time and thus does not need to be
accounted for in watermark calculations.
This patch adds support for those on top of regular QGV points.
Those are supposed to be used simultaneously, i.e we are always
at some QGV and some PSF GV point, based on the current video
mode requirements.
Bspec: 64631, 53998
v2: Seems that initial assumption made during ml conversation
was wrong, PCode rejects any masks containing points beyond
the ones returned, so even though BSpec says we have around
8 points theoretically, we can mask/unmask only those which
are returned, trying to manipulate those beyond causes a
failure from PCode. So switched back to generating mask
from 1 - num_qgv_points, where num_qgv_points is the actual
amount of points, advertised by PCode.
v3: - Extended restricted qgv point mask to 0xf, as we have now
3:2 bits for PSF GV points(Matt Roper)
- Replaced val2 with NULL from PCode request, since its not being
used(Matt Roper)
- Replaced %d to 0x%x for better readability(thanks for spotting)
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210531064845.4389-2-stanislav.lisovskiy@intel.com
2021-05-31 06:48:45 +00:00
|
|
|
drm_err(&dev_priv->drm, "Failed to disable qgv points (%d) points: 0x%x\n", ret, points_mask);
|
drm/i915: Restrict qgv points which don't have enough bandwidth.
According to BSpec 53998, we should try to
restrict qgv points, which can't provide
enough bandwidth for desired display configuration.
Currently we are just comparing against all of
those and take minimum(worst case).
v2: Fixed wrong PCode reply mask, removed hardcoded
values.
v3: Forbid simultaneous legacy SAGV PCode requests and
restricting qgv points. Put the actual restriction
to commit function, added serialization(thanks to Ville)
to prevent commit being applied out of order in case of
nonblocking and/or nomodeset commits.
v4:
- Minor code refactoring, fixed few typos(thanks to James Ausmus)
- Change the naming of qgv point
masking/unmasking functions(James Ausmus).
- Simplify the masking/unmasking operation itself,
as we don't need to mask only single point per request(James Ausmus)
- Reject and stick to highest bandwidth point if SAGV
can't be enabled(BSpec)
v5:
- Add new mailbox reply codes, which seems to happen during boot
time for TGL and indicate that QGV setting is not yet available.
v6:
- Increase number of supported QGV points to be in sync with BSpec.
v7: - Rebased and resolved conflict to fix build failure.
- Fix NUM_QGV_POINTS to 8 and moved that to header file(James Ausmus)
v8: - Don't report an error if we can't restrict qgv points, as SAGV
can be disabled by BIOS, which is completely legal. So don't
make CI panic. Instead if we detect that there is only 1 QGV
point accessible just analyze if we can fit the required bandwidth
requirements, but no need in restricting.
v9: - Fix wrong QGV transition if we have 0 planes and no SAGV
simultaneously.
v10: - Fix CDCLK corruption, because of global state getting serialized
without modeset, which caused copying of non-calculated cdclk
to be copied to dev_priv(thanks to Ville for the hint).
v11: - Remove unneeded headers and spaces(Matthew Roper)
- Remove unneeded intel_qgv_info qi struct from bw check and zero
out the needed one(Matthew Roper)
- Changed QGV error message to have more clear meaning(Matthew Roper)
- Use state->modeset_set instead of any_ms(Matthew Roper)
- Moved NUM_SAGV_POINTS from i915_reg.h to i915_drv.h where it's used
- Keep using crtc_state->hw.active instead of .enable(Matthew Roper)
- Moved unrelated changes to other patch(using latency as parameter
for plane wm calculation, moved to SAGV refactoring patch)
v12: - Fix rebase conflict with own temporary SAGV/QGV fix.
- Remove unnecessary mask being zero check when unmasking
qgv points as this is completely legal(Matt Roper)
- Check if we are setting the same mask as already being set
in hardware to prevent error from PCode.
- Fix error message when restricting/unrestricting qgv points
to "mask/unmask" which sounds more accurate(Matt Roper)
- Move sagv status setting to icl_get_bw_info from atomic check
as this should be calculated only once.(Matt Roper)
- Edited comments for the case when we can't enable SAGV and
use only 1 QGV point with highest bandwidth to be more
understandable.(Matt Roper)
v13: - Moved max_data_rate in bw check to closer scope(Ville Syrjälä)
- Changed comment for zero new_mask in qgv points masking function
to better reflect reality(Ville Syrjälä)
- Simplified bit mask operation in qgv points masking function
(Ville Syrjälä)
- Moved intel_qgv_points_mask closer to gen11 SAGV disabling,
however this still can't be under modeset condition(Ville Syrjälä)
- Packed qgv_points_mask as u8 and moved closer to pipe_sagv_mask
(Ville Syrjälä)
- Extracted PCode changes to separate patch.(Ville Syrjälä)
- Now treat num_planes 0 same as 1 to avoid confusion and
returning max_bw as 0, which would prevent choosing QGV
point having max bandwidth in case if SAGV is not allowed,
as per BSpec(Ville Syrjälä)
- Do the actual qgv_points_mask swap in the same place as
all other global state parts like cdclk are swapped.
In the next patch, this all will be moved to bw state as
global state, once new global state patch series from Ville
lands
v14: - Now using global state to serialize access to qgv points
- Added global state locking back, otherwise we seem to read
bw state in a wrong way.
v15: - Added TODO comment for near atomic global state locking in
bw code.
v16: - Fixed intel_atomic_bw_* functions to be intel_bw_* as discussed
with Jani Nikula.
- Take bw_state_changed flag into use.
v17: - Moved qgv point related manipulations next to SAGV code, as
those are semantically related(Ville Syrjälä)
- Renamed those into intel_sagv_(pre)|(post)_plane_update
(Ville Syrjälä)
v18: - Move sagv related calls from commit tail into
intel_sagv_(pre)|(post)_plane_update(Ville Syrjälä)
v19: - Use intel_atomic_get_bw_(old)|(new)_state which is intended
for commit tail stage.
v20: - Return max bandwidth for 0 planes(Ville)
- Constify old_bw_state in bw_atomic_check(Ville)
- Removed some debugs(Ville)
- Added data rate to debug print when no QGV points(Ville)
- Removed some comments(Ville)
v21, v22, v23: - Fixed rebase conflict
v24: - Changed PCode mask to use ICL_ prefix
v25: - Resolved rebase conflict
v26: - Removed redundant NULL checks(Ville)
- Removed redundant error prints(Ville)
v27: - Use device specific drm_err(Ville)
- Fixed parenthesis ident reported by checkpatch
Line over 100 warns to be fixed together with
existing code style.
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Ville Syrjälä <ville.syrjala@intel.com>
Cc: James Ausmus <james.ausmus@intel.com>
[vsyrjala: Drop duplicate intel_sagv_{pre,post}_plane_update() prototypes
and drop unused NUM_SAGV_POINTS define]
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200514074853.9508-3-stanislav.lisovskiy@intel.com
2020-05-14 07:48:52 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-05-24 15:36:14 +00:00
|
|
|
static int icl_get_qgv_points(struct drm_i915_private *dev_priv,
|
2021-10-15 21:00:41 +00:00
|
|
|
struct intel_qgv_info *qi,
|
|
|
|
bool is_y_tile)
|
2019-05-24 15:36:14 +00:00
|
|
|
{
|
2021-01-28 16:43:11 +00:00
|
|
|
const struct dram_info *dram_info = &dev_priv->dram_info;
|
2019-05-24 15:36:14 +00:00
|
|
|
int i, ret;
|
|
|
|
|
2021-01-28 16:43:11 +00:00
|
|
|
qi->num_points = dram_info->num_qgv_points;
|
drm/i915: Implement PSF GV point support
PSF GV points are an additional factor that can limit the
bandwidth available to display, separate from the traditional
QGV points. Whereas traditional QGV points represent possible
memory clock frequencies, PSF GV points reflect possible
frequencies of the memory fabric.
Switching between PSF GV points has the advantage of incurring
almost no memory access block time and thus does not need to be
accounted for in watermark calculations.
This patch adds support for those on top of regular QGV points.
Those are supposed to be used simultaneously, i.e we are always
at some QGV and some PSF GV point, based on the current video
mode requirements.
Bspec: 64631, 53998
v2: Seems that initial assumption made during ml conversation
was wrong, PCode rejects any masks containing points beyond
the ones returned, so even though BSpec says we have around
8 points theoretically, we can mask/unmask only those which
are returned, trying to manipulate those beyond causes a
failure from PCode. So switched back to generating mask
from 1 - num_qgv_points, where num_qgv_points is the actual
amount of points, advertised by PCode.
v3: - Extended restricted qgv point mask to 0xf, as we have now
3:2 bits for PSF GV points(Matt Roper)
- Replaced val2 with NULL from PCode request, since its not being
used(Matt Roper)
- Replaced %d to 0x%x for better readability(thanks for spotting)
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210531064845.4389-2-stanislav.lisovskiy@intel.com
2021-05-31 06:48:45 +00:00
|
|
|
qi->num_psf_points = dram_info->num_psf_gv_points;
|
2021-01-28 16:43:11 +00:00
|
|
|
|
2021-11-06 00:37:14 +00:00
|
|
|
if (DISPLAY_VER(dev_priv) >= 12)
|
2021-02-04 20:04:58 +00:00
|
|
|
switch (dram_info->type) {
|
|
|
|
case INTEL_DRAM_DDR4:
|
2021-10-15 21:00:41 +00:00
|
|
|
qi->t_bl = is_y_tile ? 8 : 4;
|
|
|
|
qi->max_numchannels = 2;
|
|
|
|
qi->channel_width = 64;
|
|
|
|
qi->deinterleave = is_y_tile ? 1 : 2;
|
2021-02-04 20:04:58 +00:00
|
|
|
break;
|
|
|
|
case INTEL_DRAM_DDR5:
|
2021-10-15 21:00:41 +00:00
|
|
|
qi->t_bl = is_y_tile ? 16 : 8;
|
|
|
|
qi->max_numchannels = 4;
|
|
|
|
qi->channel_width = 32;
|
|
|
|
qi->deinterleave = is_y_tile ? 1 : 2;
|
|
|
|
break;
|
|
|
|
case INTEL_DRAM_LPDDR4:
|
|
|
|
if (IS_ROCKETLAKE(dev_priv)) {
|
|
|
|
qi->t_bl = 8;
|
|
|
|
qi->max_numchannels = 4;
|
|
|
|
qi->channel_width = 32;
|
|
|
|
qi->deinterleave = 2;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
fallthrough;
|
|
|
|
case INTEL_DRAM_LPDDR5:
|
|
|
|
qi->t_bl = 16;
|
|
|
|
qi->max_numchannels = 8;
|
|
|
|
qi->channel_width = 16;
|
|
|
|
qi->deinterleave = is_y_tile ? 2 : 4;
|
2021-02-04 20:04:58 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
qi->t_bl = 16;
|
2021-10-15 21:00:41 +00:00
|
|
|
qi->max_numchannels = 1;
|
2021-02-04 20:04:58 +00:00
|
|
|
break;
|
|
|
|
}
|
2021-10-15 21:00:41 +00:00
|
|
|
else if (DISPLAY_VER(dev_priv) == 11) {
|
2021-01-28 16:43:11 +00:00
|
|
|
qi->t_bl = dev_priv->dram_info.type == INTEL_DRAM_DDR4 ? 4 : 8;
|
2021-10-15 21:00:41 +00:00
|
|
|
qi->max_numchannels = 1;
|
|
|
|
}
|
2019-05-24 15:36:14 +00:00
|
|
|
|
drm/i915/display: Make WARN* drm specific where drm_device ptr is available
drm specific WARN* calls include device information in the
backtrace, so we know what device the warnings originate from.
Covert all the calls of WARN* with device specific drm_WARN*
variants in functions where drm_device or drm_i915_private struct
pointer is readily available.
The conversion was done automatically with below coccinelle semantic
patch. checkpatch errors/warnings are fixed manually.
@rule1@
identifier func, T;
@@
func(...) {
...
struct drm_device *T = ...;
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule2@
identifier func, T;
@@
func(struct drm_device *T,...) {
<...
(
-WARN(
+drm_WARN(T,
...)
|
-WARN_ON(
+drm_WARN_ON(T,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(T,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(T,
...)
)
...>
}
@rule3@
identifier func, T;
@@
func(...) {
...
struct drm_i915_private *T = ...;
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
@rule4@
identifier func, T;
@@
func(struct drm_i915_private *T,...) {
<+...
(
-WARN(
+drm_WARN(&T->drm,
...)
|
-WARN_ON(
+drm_WARN_ON(&T->drm,
...)
|
-WARN_ONCE(
+drm_WARN_ONCE(&T->drm,
...)
|
-WARN_ON_ONCE(
+drm_WARN_ON_ONCE(&T->drm,
...)
)
...+>
}
Signed-off-by: Pankaj Bharadiya <pankaj.laxminarayan.bharadiya@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200128181603.27767-20-pankaj.laxminarayan.bharadiya@intel.com
2020-01-28 18:16:01 +00:00
|
|
|
if (drm_WARN_ON(&dev_priv->drm,
|
|
|
|
qi->num_points > ARRAY_SIZE(qi->points)))
|
2019-05-24 15:36:14 +00:00
|
|
|
qi->num_points = ARRAY_SIZE(qi->points);
|
|
|
|
|
|
|
|
for (i = 0; i < qi->num_points; i++) {
|
|
|
|
struct intel_qgv_point *sp = &qi->points[i];
|
|
|
|
|
2021-07-08 17:52:26 +00:00
|
|
|
if (IS_DG1(dev_priv))
|
|
|
|
ret = dg1_mchbar_read_qgv_point_info(dev_priv, sp, i);
|
|
|
|
else
|
|
|
|
ret = icl_pcode_read_qgv_point_info(dev_priv, sp, i);
|
|
|
|
|
2019-05-24 15:36:14 +00:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
drm/i915/bw: convert to drm_device based logging macros
This replaces the printk based logging macros with the struct drm_based
macros in i915/display/intel_bw.c
This transformation was achieved by using the following coccinelle
script that matches based on the existence of a struct drm_i915_private
device in the functions:
@rule1@
identifier fn, T;
@@
fn(struct drm_i915_private *T,...) {
<+...
(
-DRM_INFO(
+drm_info(&T->drm,
...)
|
-DRM_ERROR(
+drm_err(&T->drm,
...)
|
-DRM_WARN(
+drm_warn(&T->drm,
...)
|
-DRM_DEBUG(
+drm_dbg(&T->drm,
...)
|
-DRM_DEBUG_DRIVER(
+drm_dbg(&T->drm,
...)
|
-DRM_DEBUG_KMS(
+drm_dbg_kms(&T->drm,
...)
)
...+>
}
@rule2@
identifier fn, T;
@@
fn(...) {
...
struct drm_i915_private *T = ...;
<+...
(
-DRM_INFO(
+drm_info(&T->drm,
...)
|
-DRM_ERROR(
+drm_err(&T->drm,
...)
|
-DRM_WARN(
+drm_warn(&T->drm,
...)
|
-DRM_DEBUG(
+drm_dbg(&T->drm,
...)
|
-DRM_DEBUG_KMS(
+drm_dbg_kms(&T->drm,
...)
|
-DRM_DEBUG_DRIVER(
+drm_dbg(&T->drm,
...)
)
...+>
}
Resulting checkpatch warnings were addressed manually.
Signed-off-by: Wambui Karuga <wambui.karugax@gmail.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200121134559.17355-5-wambui.karugax@gmail.com
2020-01-21 13:45:58 +00:00
|
|
|
drm_dbg_kms(&dev_priv->drm,
|
|
|
|
"QGV %d: DCLK=%d tRP=%d tRDPRE=%d tRAS=%d tRCD=%d tRC=%d\n",
|
|
|
|
i, sp->dclk, sp->t_rp, sp->t_rdpre, sp->t_ras,
|
|
|
|
sp->t_rcd, sp->t_rc);
|
2019-05-24 15:36:14 +00:00
|
|
|
}
|
|
|
|
|
drm/i915: Implement PSF GV point support
PSF GV points are an additional factor that can limit the
bandwidth available to display, separate from the traditional
QGV points. Whereas traditional QGV points represent possible
memory clock frequencies, PSF GV points reflect possible
frequencies of the memory fabric.
Switching between PSF GV points has the advantage of incurring
almost no memory access block time and thus does not need to be
accounted for in watermark calculations.
This patch adds support for those on top of regular QGV points.
Those are supposed to be used simultaneously, i.e we are always
at some QGV and some PSF GV point, based on the current video
mode requirements.
Bspec: 64631, 53998
v2: Seems that initial assumption made during ml conversation
was wrong, PCode rejects any masks containing points beyond
the ones returned, so even though BSpec says we have around
8 points theoretically, we can mask/unmask only those which
are returned, trying to manipulate those beyond causes a
failure from PCode. So switched back to generating mask
from 1 - num_qgv_points, where num_qgv_points is the actual
amount of points, advertised by PCode.
v3: - Extended restricted qgv point mask to 0xf, as we have now
3:2 bits for PSF GV points(Matt Roper)
- Replaced val2 with NULL from PCode request, since its not being
used(Matt Roper)
- Replaced %d to 0x%x for better readability(thanks for spotting)
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210531064845.4389-2-stanislav.lisovskiy@intel.com
2021-05-31 06:48:45 +00:00
|
|
|
if (qi->num_psf_points > 0) {
|
|
|
|
ret = adls_pcode_read_psf_gv_point_info(dev_priv, qi->psf_points);
|
|
|
|
if (ret) {
|
|
|
|
drm_err(&dev_priv->drm, "Failed to read PSF point data; PSF points will not be considered in bandwidth calculations.\n");
|
|
|
|
qi->num_psf_points = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < qi->num_psf_points; i++)
|
|
|
|
drm_dbg_kms(&dev_priv->drm,
|
|
|
|
"PSF GV %d: CLK=%d \n",
|
|
|
|
i, qi->psf_points[i].clk);
|
|
|
|
}
|
|
|
|
|
2019-05-24 15:36:14 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
drm/i915: Implement PSF GV point support
PSF GV points are an additional factor that can limit the
bandwidth available to display, separate from the traditional
QGV points. Whereas traditional QGV points represent possible
memory clock frequencies, PSF GV points reflect possible
frequencies of the memory fabric.
Switching between PSF GV points has the advantage of incurring
almost no memory access block time and thus does not need to be
accounted for in watermark calculations.
This patch adds support for those on top of regular QGV points.
Those are supposed to be used simultaneously, i.e we are always
at some QGV and some PSF GV point, based on the current video
mode requirements.
Bspec: 64631, 53998
v2: Seems that initial assumption made during ml conversation
was wrong, PCode rejects any masks containing points beyond
the ones returned, so even though BSpec says we have around
8 points theoretically, we can mask/unmask only those which
are returned, trying to manipulate those beyond causes a
failure from PCode. So switched back to generating mask
from 1 - num_qgv_points, where num_qgv_points is the actual
amount of points, advertised by PCode.
v3: - Extended restricted qgv point mask to 0xf, as we have now
3:2 bits for PSF GV points(Matt Roper)
- Replaced val2 with NULL from PCode request, since its not being
used(Matt Roper)
- Replaced %d to 0x%x for better readability(thanks for spotting)
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210531064845.4389-2-stanislav.lisovskiy@intel.com
2021-05-31 06:48:45 +00:00
|
|
|
static int adl_calc_psf_bw(int clk)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* clk is multiples of 16.666MHz (100/6)
|
|
|
|
* According to BSpec PSF GV bandwidth is
|
|
|
|
* calculated as BW = 64 * clk * 16.666Mhz
|
|
|
|
*/
|
|
|
|
return DIV_ROUND_CLOSEST(64 * clk * 100, 6);
|
|
|
|
}
|
|
|
|
|
2019-05-24 15:36:14 +00:00
|
|
|
static int icl_sagv_max_dclk(const struct intel_qgv_info *qi)
|
|
|
|
{
|
|
|
|
u16 dclk = 0;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < qi->num_points; i++)
|
|
|
|
dclk = max(dclk, qi->points[i].dclk);
|
|
|
|
|
|
|
|
return dclk;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct intel_sa_info {
|
2019-09-20 08:37:54 +00:00
|
|
|
u16 displayrtids;
|
2021-09-14 22:07:44 +00:00
|
|
|
u8 deburst, deprogbwlimit, derating;
|
2019-05-24 15:36:14 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const struct intel_sa_info icl_sa_info = {
|
|
|
|
.deburst = 8,
|
|
|
|
.deprogbwlimit = 25, /* GB/s */
|
|
|
|
.displayrtids = 128,
|
2021-09-14 22:07:44 +00:00
|
|
|
.derating = 10,
|
2019-05-24 15:36:14 +00:00
|
|
|
};
|
|
|
|
|
2019-09-20 08:37:54 +00:00
|
|
|
static const struct intel_sa_info tgl_sa_info = {
|
|
|
|
.deburst = 16,
|
|
|
|
.deprogbwlimit = 34, /* GB/s */
|
|
|
|
.displayrtids = 256,
|
2021-09-14 22:07:44 +00:00
|
|
|
.derating = 10,
|
2019-09-20 08:37:54 +00:00
|
|
|
};
|
|
|
|
|
2020-05-04 22:52:11 +00:00
|
|
|
static const struct intel_sa_info rkl_sa_info = {
|
2021-10-15 21:00:41 +00:00
|
|
|
.deburst = 8,
|
2020-05-04 22:52:11 +00:00
|
|
|
.deprogbwlimit = 20, /* GB/s */
|
|
|
|
.displayrtids = 128,
|
2021-09-14 22:07:44 +00:00
|
|
|
.derating = 10,
|
2020-05-04 22:52:11 +00:00
|
|
|
};
|
|
|
|
|
2021-01-29 18:29:43 +00:00
|
|
|
static const struct intel_sa_info adls_sa_info = {
|
|
|
|
.deburst = 16,
|
|
|
|
.deprogbwlimit = 38, /* GB/s */
|
|
|
|
.displayrtids = 256,
|
2021-09-14 22:07:44 +00:00
|
|
|
.derating = 10,
|
|
|
|
};
|
|
|
|
|
|
|
|
static const struct intel_sa_info adlp_sa_info = {
|
|
|
|
.deburst = 16,
|
|
|
|
.deprogbwlimit = 38, /* GB/s */
|
|
|
|
.displayrtids = 256,
|
|
|
|
.derating = 20,
|
2021-01-29 18:29:43 +00:00
|
|
|
};
|
|
|
|
|
2019-09-20 08:37:54 +00:00
|
|
|
static int icl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel_sa_info *sa)
|
2019-05-24 15:36:14 +00:00
|
|
|
{
|
|
|
|
struct intel_qgv_info qi = {};
|
|
|
|
bool is_y_tile = true; /* assume y tile may be used */
|
2021-05-24 21:48:03 +00:00
|
|
|
int num_channels = max_t(u8, 1, dev_priv->dram_info.num_channels);
|
2021-10-15 21:00:41 +00:00
|
|
|
int ipqdepth, ipqdepthpch = 16;
|
2019-05-24 15:36:14 +00:00
|
|
|
int dclk_max;
|
|
|
|
int maxdebw;
|
2021-10-15 21:00:41 +00:00
|
|
|
int num_groups = ARRAY_SIZE(dev_priv->max_bw);
|
2019-05-24 15:36:14 +00:00
|
|
|
int i, ret;
|
|
|
|
|
2021-10-15 21:00:41 +00:00
|
|
|
ret = icl_get_qgv_points(dev_priv, &qi, is_y_tile);
|
2019-05-24 15:36:14 +00:00
|
|
|
if (ret) {
|
drm/i915/bw: convert to drm_device based logging macros
This replaces the printk based logging macros with the struct drm_based
macros in i915/display/intel_bw.c
This transformation was achieved by using the following coccinelle
script that matches based on the existence of a struct drm_i915_private
device in the functions:
@rule1@
identifier fn, T;
@@
fn(struct drm_i915_private *T,...) {
<+...
(
-DRM_INFO(
+drm_info(&T->drm,
...)
|
-DRM_ERROR(
+drm_err(&T->drm,
...)
|
-DRM_WARN(
+drm_warn(&T->drm,
...)
|
-DRM_DEBUG(
+drm_dbg(&T->drm,
...)
|
-DRM_DEBUG_DRIVER(
+drm_dbg(&T->drm,
...)
|
-DRM_DEBUG_KMS(
+drm_dbg_kms(&T->drm,
...)
)
...+>
}
@rule2@
identifier fn, T;
@@
fn(...) {
...
struct drm_i915_private *T = ...;
<+...
(
-DRM_INFO(
+drm_info(&T->drm,
...)
|
-DRM_ERROR(
+drm_err(&T->drm,
...)
|
-DRM_WARN(
+drm_warn(&T->drm,
...)
|
-DRM_DEBUG(
+drm_dbg(&T->drm,
...)
|
-DRM_DEBUG_KMS(
+drm_dbg_kms(&T->drm,
...)
|
-DRM_DEBUG_DRIVER(
+drm_dbg(&T->drm,
...)
)
...+>
}
Resulting checkpatch warnings were addressed manually.
Signed-off-by: Wambui Karuga <wambui.karugax@gmail.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200121134559.17355-5-wambui.karugax@gmail.com
2020-01-21 13:45:58 +00:00
|
|
|
drm_dbg_kms(&dev_priv->drm,
|
|
|
|
"Failed to get memory subsystem information, ignoring bandwidth limits");
|
2019-05-24 15:36:14 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
dclk_max = icl_sagv_max_dclk(&qi);
|
2021-10-15 21:00:41 +00:00
|
|
|
maxdebw = min(sa->deprogbwlimit * 1000, dclk_max * 16 * 6 / 10);
|
|
|
|
ipqdepth = min(ipqdepthpch, sa->displayrtids / num_channels);
|
|
|
|
qi.deinterleave = DIV_ROUND_UP(num_channels, is_y_tile ? 4 : 2);
|
|
|
|
|
|
|
|
for (i = 0; i < num_groups; i++) {
|
|
|
|
struct intel_bw_info *bi = &dev_priv->max_bw[i];
|
|
|
|
int clpchgroup;
|
|
|
|
int j;
|
|
|
|
|
|
|
|
clpchgroup = (sa->deburst * qi.deinterleave / num_channels) << i;
|
|
|
|
bi->num_planes = (ipqdepth - clpchgroup) / clpchgroup + 1;
|
|
|
|
|
|
|
|
bi->num_qgv_points = qi.num_points;
|
|
|
|
bi->num_psf_gv_points = qi.num_psf_points;
|
|
|
|
|
|
|
|
for (j = 0; j < qi.num_points; j++) {
|
|
|
|
const struct intel_qgv_point *sp = &qi.points[j];
|
|
|
|
int ct, bw;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Max row cycle time
|
|
|
|
*
|
|
|
|
* FIXME what is the logic behind the
|
|
|
|
* assumed burst length?
|
|
|
|
*/
|
|
|
|
ct = max_t(int, sp->t_rc, sp->t_rp + sp->t_rcd +
|
|
|
|
(clpchgroup - 1) * qi.t_bl + sp->t_rdpre);
|
|
|
|
bw = DIV_ROUND_UP(sp->dclk * clpchgroup * 32 * num_channels, ct);
|
2019-05-24 15:36:14 +00:00
|
|
|
|
2021-10-15 21:00:41 +00:00
|
|
|
bi->deratedbw[j] = min(maxdebw,
|
|
|
|
bw * (100 - sa->derating) / 100);
|
|
|
|
|
|
|
|
drm_dbg_kms(&dev_priv->drm,
|
|
|
|
"BW%d / QGV %d: num_planes=%d deratedbw=%u\n",
|
|
|
|
i, j, bi->num_planes, bi->deratedbw[j]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* In case if SAGV is disabled in BIOS, we always get 1
|
|
|
|
* SAGV point, but we can't send PCode commands to restrict it
|
|
|
|
* as it will fail and pointless anyway.
|
|
|
|
*/
|
|
|
|
if (qi.num_points == 1)
|
|
|
|
dev_priv->sagv_status = I915_SAGV_NOT_CONTROLLED;
|
|
|
|
else
|
|
|
|
dev_priv->sagv_status = I915_SAGV_ENABLED;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int tgl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel_sa_info *sa)
|
|
|
|
{
|
|
|
|
struct intel_qgv_info qi = {};
|
|
|
|
const struct dram_info *dram_info = &dev_priv->dram_info;
|
|
|
|
bool is_y_tile = true; /* assume y tile may be used */
|
|
|
|
int num_channels = max_t(u8, 1, dev_priv->dram_info.num_channels);
|
|
|
|
int ipqdepth, ipqdepthpch = 16;
|
|
|
|
int dclk_max;
|
|
|
|
int maxdebw, peakbw;
|
|
|
|
int clperchgroup;
|
|
|
|
int num_groups = ARRAY_SIZE(dev_priv->max_bw);
|
|
|
|
int i, ret;
|
|
|
|
|
|
|
|
ret = icl_get_qgv_points(dev_priv, &qi, is_y_tile);
|
|
|
|
if (ret) {
|
|
|
|
drm_dbg_kms(&dev_priv->drm,
|
|
|
|
"Failed to get memory subsystem information, ignoring bandwidth limits");
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dram_info->type == INTEL_DRAM_LPDDR4 || dram_info->type == INTEL_DRAM_LPDDR5)
|
|
|
|
num_channels *= 2;
|
|
|
|
|
|
|
|
qi.deinterleave = qi.deinterleave ? : DIV_ROUND_UP(num_channels, is_y_tile ? 4 : 2);
|
|
|
|
|
|
|
|
if (num_channels < qi.max_numchannels && DISPLAY_VER(dev_priv) >= 12)
|
|
|
|
qi.deinterleave = max(DIV_ROUND_UP(qi.deinterleave, 2), 1);
|
|
|
|
|
|
|
|
if (DISPLAY_VER(dev_priv) > 11 && num_channels > qi.max_numchannels)
|
|
|
|
drm_warn(&dev_priv->drm, "Number of channels exceeds max number of channels.");
|
|
|
|
if (qi.max_numchannels != 0)
|
|
|
|
num_channels = min_t(u8, num_channels, qi.max_numchannels);
|
|
|
|
|
|
|
|
dclk_max = icl_sagv_max_dclk(&qi);
|
|
|
|
|
|
|
|
peakbw = num_channels * DIV_ROUND_UP(qi.channel_width, 8) * dclk_max;
|
|
|
|
maxdebw = min(sa->deprogbwlimit * 1000, peakbw * 6 / 10); /* 60% */
|
2019-05-24 15:36:14 +00:00
|
|
|
|
|
|
|
ipqdepth = min(ipqdepthpch, sa->displayrtids / num_channels);
|
2021-10-15 21:00:41 +00:00
|
|
|
/*
|
|
|
|
* clperchgroup = 4kpagespermempage * clperchperblock,
|
|
|
|
* clperchperblock = 8 / num_channels * interleave
|
|
|
|
*/
|
|
|
|
clperchgroup = 4 * DIV_ROUND_UP(8, num_channels) * qi.deinterleave;
|
2019-05-24 15:36:14 +00:00
|
|
|
|
2021-10-15 21:00:41 +00:00
|
|
|
for (i = 0; i < num_groups; i++) {
|
2019-05-24 15:36:14 +00:00
|
|
|
struct intel_bw_info *bi = &dev_priv->max_bw[i];
|
2021-10-15 21:00:41 +00:00
|
|
|
struct intel_bw_info *bi_next;
|
2019-05-24 15:36:14 +00:00
|
|
|
int clpchgroup;
|
|
|
|
int j;
|
|
|
|
|
2021-10-15 21:00:41 +00:00
|
|
|
if (i < num_groups - 1)
|
|
|
|
bi_next = &dev_priv->max_bw[i + 1];
|
|
|
|
|
|
|
|
clpchgroup = (sa->deburst * qi.deinterleave / num_channels) << i;
|
|
|
|
|
|
|
|
if (i < num_groups - 1 && clpchgroup < clperchgroup)
|
|
|
|
bi_next->num_planes = (ipqdepth - clpchgroup) / clpchgroup + 1;
|
|
|
|
else
|
|
|
|
bi_next->num_planes = 0;
|
2019-05-24 15:36:14 +00:00
|
|
|
|
2019-06-06 12:42:10 +00:00
|
|
|
bi->num_qgv_points = qi.num_points;
|
drm/i915: Implement PSF GV point support
PSF GV points are an additional factor that can limit the
bandwidth available to display, separate from the traditional
QGV points. Whereas traditional QGV points represent possible
memory clock frequencies, PSF GV points reflect possible
frequencies of the memory fabric.
Switching between PSF GV points has the advantage of incurring
almost no memory access block time and thus does not need to be
accounted for in watermark calculations.
This patch adds support for those on top of regular QGV points.
Those are supposed to be used simultaneously, i.e we are always
at some QGV and some PSF GV point, based on the current video
mode requirements.
Bspec: 64631, 53998
v2: Seems that initial assumption made during ml conversation
was wrong, PCode rejects any masks containing points beyond
the ones returned, so even though BSpec says we have around
8 points theoretically, we can mask/unmask only those which
are returned, trying to manipulate those beyond causes a
failure from PCode. So switched back to generating mask
from 1 - num_qgv_points, where num_qgv_points is the actual
amount of points, advertised by PCode.
v3: - Extended restricted qgv point mask to 0xf, as we have now
3:2 bits for PSF GV points(Matt Roper)
- Replaced val2 with NULL from PCode request, since its not being
used(Matt Roper)
- Replaced %d to 0x%x for better readability(thanks for spotting)
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210531064845.4389-2-stanislav.lisovskiy@intel.com
2021-05-31 06:48:45 +00:00
|
|
|
bi->num_psf_gv_points = qi.num_psf_points;
|
2019-06-06 12:42:10 +00:00
|
|
|
|
2019-05-24 15:36:14 +00:00
|
|
|
for (j = 0; j < qi.num_points; j++) {
|
|
|
|
const struct intel_qgv_point *sp = &qi.points[j];
|
|
|
|
int ct, bw;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Max row cycle time
|
|
|
|
*
|
|
|
|
* FIXME what is the logic behind the
|
|
|
|
* assumed burst length?
|
|
|
|
*/
|
|
|
|
ct = max_t(int, sp->t_rc, sp->t_rp + sp->t_rcd +
|
|
|
|
(clpchgroup - 1) * qi.t_bl + sp->t_rdpre);
|
2021-10-15 21:00:41 +00:00
|
|
|
bw = DIV_ROUND_UP(sp->dclk * clpchgroup * 32 * num_channels, ct);
|
2019-05-24 15:36:14 +00:00
|
|
|
|
|
|
|
bi->deratedbw[j] = min(maxdebw,
|
2021-09-14 22:07:44 +00:00
|
|
|
bw * (100 - sa->derating) / 100);
|
2019-05-24 15:36:14 +00:00
|
|
|
|
drm/i915/bw: convert to drm_device based logging macros
This replaces the printk based logging macros with the struct drm_based
macros in i915/display/intel_bw.c
This transformation was achieved by using the following coccinelle
script that matches based on the existence of a struct drm_i915_private
device in the functions:
@rule1@
identifier fn, T;
@@
fn(struct drm_i915_private *T,...) {
<+...
(
-DRM_INFO(
+drm_info(&T->drm,
...)
|
-DRM_ERROR(
+drm_err(&T->drm,
...)
|
-DRM_WARN(
+drm_warn(&T->drm,
...)
|
-DRM_DEBUG(
+drm_dbg(&T->drm,
...)
|
-DRM_DEBUG_DRIVER(
+drm_dbg(&T->drm,
...)
|
-DRM_DEBUG_KMS(
+drm_dbg_kms(&T->drm,
...)
)
...+>
}
@rule2@
identifier fn, T;
@@
fn(...) {
...
struct drm_i915_private *T = ...;
<+...
(
-DRM_INFO(
+drm_info(&T->drm,
...)
|
-DRM_ERROR(
+drm_err(&T->drm,
...)
|
-DRM_WARN(
+drm_warn(&T->drm,
...)
|
-DRM_DEBUG(
+drm_dbg(&T->drm,
...)
|
-DRM_DEBUG_KMS(
+drm_dbg_kms(&T->drm,
...)
|
-DRM_DEBUG_DRIVER(
+drm_dbg(&T->drm,
...)
)
...+>
}
Resulting checkpatch warnings were addressed manually.
Signed-off-by: Wambui Karuga <wambui.karugax@gmail.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200121134559.17355-5-wambui.karugax@gmail.com
2020-01-21 13:45:58 +00:00
|
|
|
drm_dbg_kms(&dev_priv->drm,
|
|
|
|
"BW%d / QGV %d: num_planes=%d deratedbw=%u\n",
|
|
|
|
i, j, bi->num_planes, bi->deratedbw[j]);
|
2019-05-24 15:36:14 +00:00
|
|
|
}
|
|
|
|
|
drm/i915: Implement PSF GV point support
PSF GV points are an additional factor that can limit the
bandwidth available to display, separate from the traditional
QGV points. Whereas traditional QGV points represent possible
memory clock frequencies, PSF GV points reflect possible
frequencies of the memory fabric.
Switching between PSF GV points has the advantage of incurring
almost no memory access block time and thus does not need to be
accounted for in watermark calculations.
This patch adds support for those on top of regular QGV points.
Those are supposed to be used simultaneously, i.e we are always
at some QGV and some PSF GV point, based on the current video
mode requirements.
Bspec: 64631, 53998
v2: Seems that initial assumption made during ml conversation
was wrong, PCode rejects any masks containing points beyond
the ones returned, so even though BSpec says we have around
8 points theoretically, we can mask/unmask only those which
are returned, trying to manipulate those beyond causes a
failure from PCode. So switched back to generating mask
from 1 - num_qgv_points, where num_qgv_points is the actual
amount of points, advertised by PCode.
v3: - Extended restricted qgv point mask to 0xf, as we have now
3:2 bits for PSF GV points(Matt Roper)
- Replaced val2 with NULL from PCode request, since its not being
used(Matt Roper)
- Replaced %d to 0x%x for better readability(thanks for spotting)
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210531064845.4389-2-stanislav.lisovskiy@intel.com
2021-05-31 06:48:45 +00:00
|
|
|
for (j = 0; j < qi.num_psf_points; j++) {
|
|
|
|
const struct intel_psf_gv_point *sp = &qi.psf_points[j];
|
|
|
|
|
|
|
|
bi->psf_bw[j] = adl_calc_psf_bw(sp->clk);
|
|
|
|
|
|
|
|
drm_dbg_kms(&dev_priv->drm,
|
|
|
|
"BW%d / PSF GV %d: num_planes=%d bw=%u\n",
|
|
|
|
i, j, bi->num_planes, bi->psf_bw[j]);
|
|
|
|
}
|
2019-05-24 15:36:14 +00:00
|
|
|
}
|
|
|
|
|
drm/i915: Restrict qgv points which don't have enough bandwidth.
According to BSpec 53998, we should try to
restrict qgv points, which can't provide
enough bandwidth for desired display configuration.
Currently we are just comparing against all of
those and take minimum(worst case).
v2: Fixed wrong PCode reply mask, removed hardcoded
values.
v3: Forbid simultaneous legacy SAGV PCode requests and
restricting qgv points. Put the actual restriction
to commit function, added serialization(thanks to Ville)
to prevent commit being applied out of order in case of
nonblocking and/or nomodeset commits.
v4:
- Minor code refactoring, fixed few typos(thanks to James Ausmus)
- Change the naming of qgv point
masking/unmasking functions(James Ausmus).
- Simplify the masking/unmasking operation itself,
as we don't need to mask only single point per request(James Ausmus)
- Reject and stick to highest bandwidth point if SAGV
can't be enabled(BSpec)
v5:
- Add new mailbox reply codes, which seems to happen during boot
time for TGL and indicate that QGV setting is not yet available.
v6:
- Increase number of supported QGV points to be in sync with BSpec.
v7: - Rebased and resolved conflict to fix build failure.
- Fix NUM_QGV_POINTS to 8 and moved that to header file(James Ausmus)
v8: - Don't report an error if we can't restrict qgv points, as SAGV
can be disabled by BIOS, which is completely legal. So don't
make CI panic. Instead if we detect that there is only 1 QGV
point accessible just analyze if we can fit the required bandwidth
requirements, but no need in restricting.
v9: - Fix wrong QGV transition if we have 0 planes and no SAGV
simultaneously.
v10: - Fix CDCLK corruption, because of global state getting serialized
without modeset, which caused copying of non-calculated cdclk
to be copied to dev_priv(thanks to Ville for the hint).
v11: - Remove unneeded headers and spaces(Matthew Roper)
- Remove unneeded intel_qgv_info qi struct from bw check and zero
out the needed one(Matthew Roper)
- Changed QGV error message to have more clear meaning(Matthew Roper)
- Use state->modeset_set instead of any_ms(Matthew Roper)
- Moved NUM_SAGV_POINTS from i915_reg.h to i915_drv.h where it's used
- Keep using crtc_state->hw.active instead of .enable(Matthew Roper)
- Moved unrelated changes to other patch(using latency as parameter
for plane wm calculation, moved to SAGV refactoring patch)
v12: - Fix rebase conflict with own temporary SAGV/QGV fix.
- Remove unnecessary mask being zero check when unmasking
qgv points as this is completely legal(Matt Roper)
- Check if we are setting the same mask as already being set
in hardware to prevent error from PCode.
- Fix error message when restricting/unrestricting qgv points
to "mask/unmask" which sounds more accurate(Matt Roper)
- Move sagv status setting to icl_get_bw_info from atomic check
as this should be calculated only once.(Matt Roper)
- Edited comments for the case when we can't enable SAGV and
use only 1 QGV point with highest bandwidth to be more
understandable.(Matt Roper)
v13: - Moved max_data_rate in bw check to closer scope(Ville Syrjälä)
- Changed comment for zero new_mask in qgv points masking function
to better reflect reality(Ville Syrjälä)
- Simplified bit mask operation in qgv points masking function
(Ville Syrjälä)
- Moved intel_qgv_points_mask closer to gen11 SAGV disabling,
however this still can't be under modeset condition(Ville Syrjälä)
- Packed qgv_points_mask as u8 and moved closer to pipe_sagv_mask
(Ville Syrjälä)
- Extracted PCode changes to separate patch.(Ville Syrjälä)
- Now treat num_planes 0 same as 1 to avoid confusion and
returning max_bw as 0, which would prevent choosing QGV
point having max bandwidth in case if SAGV is not allowed,
as per BSpec(Ville Syrjälä)
- Do the actual qgv_points_mask swap in the same place as
all other global state parts like cdclk are swapped.
In the next patch, this all will be moved to bw state as
global state, once new global state patch series from Ville
lands
v14: - Now using global state to serialize access to qgv points
- Added global state locking back, otherwise we seem to read
bw state in a wrong way.
v15: - Added TODO comment for near atomic global state locking in
bw code.
v16: - Fixed intel_atomic_bw_* functions to be intel_bw_* as discussed
with Jani Nikula.
- Take bw_state_changed flag into use.
v17: - Moved qgv point related manipulations next to SAGV code, as
those are semantically related(Ville Syrjälä)
- Renamed those into intel_sagv_(pre)|(post)_plane_update
(Ville Syrjälä)
v18: - Move sagv related calls from commit tail into
intel_sagv_(pre)|(post)_plane_update(Ville Syrjälä)
v19: - Use intel_atomic_get_bw_(old)|(new)_state which is intended
for commit tail stage.
v20: - Return max bandwidth for 0 planes(Ville)
- Constify old_bw_state in bw_atomic_check(Ville)
- Removed some debugs(Ville)
- Added data rate to debug print when no QGV points(Ville)
- Removed some comments(Ville)
v21, v22, v23: - Fixed rebase conflict
v24: - Changed PCode mask to use ICL_ prefix
v25: - Resolved rebase conflict
v26: - Removed redundant NULL checks(Ville)
- Removed redundant error prints(Ville)
v27: - Use device specific drm_err(Ville)
- Fixed parenthesis ident reported by checkpatch
Line over 100 warns to be fixed together with
existing code style.
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Ville Syrjälä <ville.syrjala@intel.com>
Cc: James Ausmus <james.ausmus@intel.com>
[vsyrjala: Drop duplicate intel_sagv_{pre,post}_plane_update() prototypes
and drop unused NUM_SAGV_POINTS define]
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200514074853.9508-3-stanislav.lisovskiy@intel.com
2020-05-14 07:48:52 +00:00
|
|
|
/*
|
|
|
|
* In case if SAGV is disabled in BIOS, we always get 1
|
|
|
|
* SAGV point, but we can't send PCode commands to restrict it
|
|
|
|
* as it will fail and pointless anyway.
|
|
|
|
*/
|
|
|
|
if (qi.num_points == 1)
|
|
|
|
dev_priv->sagv_status = I915_SAGV_NOT_CONTROLLED;
|
|
|
|
else
|
|
|
|
dev_priv->sagv_status = I915_SAGV_ENABLED;
|
|
|
|
|
2019-05-24 15:36:14 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-07-21 22:30:43 +00:00
|
|
|
static void dg2_get_bw_info(struct drm_i915_private *i915)
|
|
|
|
{
|
2022-03-28 23:00:00 +00:00
|
|
|
unsigned int deratedbw = IS_DG2_G11(i915) ? 38000 : 50000;
|
|
|
|
int num_groups = ARRAY_SIZE(i915->max_bw);
|
|
|
|
int i;
|
2021-07-21 22:30:43 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* DG2 doesn't have SAGV or QGV points, just a constant max bandwidth
|
2022-03-28 23:00:00 +00:00
|
|
|
* that doesn't depend on the number of planes enabled. So fill all the
|
|
|
|
* plane group with constant bw information for uniformity with other
|
|
|
|
* platforms. DG2-G10 platforms have a constant 50 GB/s bandwidth,
|
|
|
|
* whereas DG2-G11 platforms have 38 GB/s.
|
2021-07-21 22:30:43 +00:00
|
|
|
*/
|
2022-03-28 23:00:00 +00:00
|
|
|
for (i = 0; i < num_groups; i++) {
|
|
|
|
struct intel_bw_info *bi = &i915->max_bw[i];
|
|
|
|
|
|
|
|
bi->num_planes = 1;
|
|
|
|
/* Need only one dummy QGV point per group */
|
|
|
|
bi->num_qgv_points = 1;
|
|
|
|
bi->deratedbw[0] = deratedbw;
|
|
|
|
}
|
2021-07-21 22:30:43 +00:00
|
|
|
|
|
|
|
i915->sagv_status = I915_SAGV_NOT_CONTROLLED;
|
|
|
|
}
|
|
|
|
|
2019-05-24 15:36:14 +00:00
|
|
|
static unsigned int icl_max_bw(struct drm_i915_private *dev_priv,
|
|
|
|
int num_planes, int qgv_point)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
drm/i915: Restrict qgv points which don't have enough bandwidth.
According to BSpec 53998, we should try to
restrict qgv points, which can't provide
enough bandwidth for desired display configuration.
Currently we are just comparing against all of
those and take minimum(worst case).
v2: Fixed wrong PCode reply mask, removed hardcoded
values.
v3: Forbid simultaneous legacy SAGV PCode requests and
restricting qgv points. Put the actual restriction
to commit function, added serialization(thanks to Ville)
to prevent commit being applied out of order in case of
nonblocking and/or nomodeset commits.
v4:
- Minor code refactoring, fixed few typos(thanks to James Ausmus)
- Change the naming of qgv point
masking/unmasking functions(James Ausmus).
- Simplify the masking/unmasking operation itself,
as we don't need to mask only single point per request(James Ausmus)
- Reject and stick to highest bandwidth point if SAGV
can't be enabled(BSpec)
v5:
- Add new mailbox reply codes, which seems to happen during boot
time for TGL and indicate that QGV setting is not yet available.
v6:
- Increase number of supported QGV points to be in sync with BSpec.
v7: - Rebased and resolved conflict to fix build failure.
- Fix NUM_QGV_POINTS to 8 and moved that to header file(James Ausmus)
v8: - Don't report an error if we can't restrict qgv points, as SAGV
can be disabled by BIOS, which is completely legal. So don't
make CI panic. Instead if we detect that there is only 1 QGV
point accessible just analyze if we can fit the required bandwidth
requirements, but no need in restricting.
v9: - Fix wrong QGV transition if we have 0 planes and no SAGV
simultaneously.
v10: - Fix CDCLK corruption, because of global state getting serialized
without modeset, which caused copying of non-calculated cdclk
to be copied to dev_priv(thanks to Ville for the hint).
v11: - Remove unneeded headers and spaces(Matthew Roper)
- Remove unneeded intel_qgv_info qi struct from bw check and zero
out the needed one(Matthew Roper)
- Changed QGV error message to have more clear meaning(Matthew Roper)
- Use state->modeset_set instead of any_ms(Matthew Roper)
- Moved NUM_SAGV_POINTS from i915_reg.h to i915_drv.h where it's used
- Keep using crtc_state->hw.active instead of .enable(Matthew Roper)
- Moved unrelated changes to other patch(using latency as parameter
for plane wm calculation, moved to SAGV refactoring patch)
v12: - Fix rebase conflict with own temporary SAGV/QGV fix.
- Remove unnecessary mask being zero check when unmasking
qgv points as this is completely legal(Matt Roper)
- Check if we are setting the same mask as already being set
in hardware to prevent error from PCode.
- Fix error message when restricting/unrestricting qgv points
to "mask/unmask" which sounds more accurate(Matt Roper)
- Move sagv status setting to icl_get_bw_info from atomic check
as this should be calculated only once.(Matt Roper)
- Edited comments for the case when we can't enable SAGV and
use only 1 QGV point with highest bandwidth to be more
understandable.(Matt Roper)
v13: - Moved max_data_rate in bw check to closer scope(Ville Syrjälä)
- Changed comment for zero new_mask in qgv points masking function
to better reflect reality(Ville Syrjälä)
- Simplified bit mask operation in qgv points masking function
(Ville Syrjälä)
- Moved intel_qgv_points_mask closer to gen11 SAGV disabling,
however this still can't be under modeset condition(Ville Syrjälä)
- Packed qgv_points_mask as u8 and moved closer to pipe_sagv_mask
(Ville Syrjälä)
- Extracted PCode changes to separate patch.(Ville Syrjälä)
- Now treat num_planes 0 same as 1 to avoid confusion and
returning max_bw as 0, which would prevent choosing QGV
point having max bandwidth in case if SAGV is not allowed,
as per BSpec(Ville Syrjälä)
- Do the actual qgv_points_mask swap in the same place as
all other global state parts like cdclk are swapped.
In the next patch, this all will be moved to bw state as
global state, once new global state patch series from Ville
lands
v14: - Now using global state to serialize access to qgv points
- Added global state locking back, otherwise we seem to read
bw state in a wrong way.
v15: - Added TODO comment for near atomic global state locking in
bw code.
v16: - Fixed intel_atomic_bw_* functions to be intel_bw_* as discussed
with Jani Nikula.
- Take bw_state_changed flag into use.
v17: - Moved qgv point related manipulations next to SAGV code, as
those are semantically related(Ville Syrjälä)
- Renamed those into intel_sagv_(pre)|(post)_plane_update
(Ville Syrjälä)
v18: - Move sagv related calls from commit tail into
intel_sagv_(pre)|(post)_plane_update(Ville Syrjälä)
v19: - Use intel_atomic_get_bw_(old)|(new)_state which is intended
for commit tail stage.
v20: - Return max bandwidth for 0 planes(Ville)
- Constify old_bw_state in bw_atomic_check(Ville)
- Removed some debugs(Ville)
- Added data rate to debug print when no QGV points(Ville)
- Removed some comments(Ville)
v21, v22, v23: - Fixed rebase conflict
v24: - Changed PCode mask to use ICL_ prefix
v25: - Resolved rebase conflict
v26: - Removed redundant NULL checks(Ville)
- Removed redundant error prints(Ville)
v27: - Use device specific drm_err(Ville)
- Fixed parenthesis ident reported by checkpatch
Line over 100 warns to be fixed together with
existing code style.
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Ville Syrjälä <ville.syrjala@intel.com>
Cc: James Ausmus <james.ausmus@intel.com>
[vsyrjala: Drop duplicate intel_sagv_{pre,post}_plane_update() prototypes
and drop unused NUM_SAGV_POINTS define]
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200514074853.9508-3-stanislav.lisovskiy@intel.com
2020-05-14 07:48:52 +00:00
|
|
|
/*
|
|
|
|
* Let's return max bw for 0 planes
|
|
|
|
*/
|
|
|
|
num_planes = max(1, num_planes);
|
|
|
|
|
2019-05-24 15:36:14 +00:00
|
|
|
for (i = 0; i < ARRAY_SIZE(dev_priv->max_bw); i++) {
|
|
|
|
const struct intel_bw_info *bi =
|
|
|
|
&dev_priv->max_bw[i];
|
|
|
|
|
2019-06-06 12:42:10 +00:00
|
|
|
/*
|
|
|
|
* Pcode will not expose all QGV points when
|
|
|
|
* SAGV is forced to off/min/med/max.
|
|
|
|
*/
|
|
|
|
if (qgv_point >= bi->num_qgv_points)
|
|
|
|
return UINT_MAX;
|
|
|
|
|
2019-05-24 15:36:14 +00:00
|
|
|
if (num_planes >= bi->num_planes)
|
|
|
|
return bi->deratedbw[qgv_point];
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-10-15 21:00:41 +00:00
|
|
|
static unsigned int tgl_max_bw(struct drm_i915_private *dev_priv,
|
|
|
|
int num_planes, int qgv_point)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Let's return max bw for 0 planes
|
|
|
|
*/
|
|
|
|
num_planes = max(1, num_planes);
|
|
|
|
|
|
|
|
for (i = ARRAY_SIZE(dev_priv->max_bw) - 1; i >= 0; i--) {
|
|
|
|
const struct intel_bw_info *bi =
|
|
|
|
&dev_priv->max_bw[i];
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Pcode will not expose all QGV points when
|
|
|
|
* SAGV is forced to off/min/med/max.
|
|
|
|
*/
|
|
|
|
if (qgv_point >= bi->num_qgv_points)
|
|
|
|
return UINT_MAX;
|
|
|
|
|
|
|
|
if (num_planes <= bi->num_planes)
|
|
|
|
return bi->deratedbw[qgv_point];
|
|
|
|
}
|
|
|
|
|
|
|
|
return dev_priv->max_bw[0].deratedbw[qgv_point];
|
|
|
|
}
|
|
|
|
|
drm/i915: Implement PSF GV point support
PSF GV points are an additional factor that can limit the
bandwidth available to display, separate from the traditional
QGV points. Whereas traditional QGV points represent possible
memory clock frequencies, PSF GV points reflect possible
frequencies of the memory fabric.
Switching between PSF GV points has the advantage of incurring
almost no memory access block time and thus does not need to be
accounted for in watermark calculations.
This patch adds support for those on top of regular QGV points.
Those are supposed to be used simultaneously, i.e we are always
at some QGV and some PSF GV point, based on the current video
mode requirements.
Bspec: 64631, 53998
v2: Seems that initial assumption made during ml conversation
was wrong, PCode rejects any masks containing points beyond
the ones returned, so even though BSpec says we have around
8 points theoretically, we can mask/unmask only those which
are returned, trying to manipulate those beyond causes a
failure from PCode. So switched back to generating mask
from 1 - num_qgv_points, where num_qgv_points is the actual
amount of points, advertised by PCode.
v3: - Extended restricted qgv point mask to 0xf, as we have now
3:2 bits for PSF GV points(Matt Roper)
- Replaced val2 with NULL from PCode request, since its not being
used(Matt Roper)
- Replaced %d to 0x%x for better readability(thanks for spotting)
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210531064845.4389-2-stanislav.lisovskiy@intel.com
2021-05-31 06:48:45 +00:00
|
|
|
static unsigned int adl_psf_bw(struct drm_i915_private *dev_priv,
|
|
|
|
int psf_gv_point)
|
|
|
|
{
|
|
|
|
const struct intel_bw_info *bi =
|
|
|
|
&dev_priv->max_bw[0];
|
|
|
|
|
|
|
|
return bi->psf_bw[psf_gv_point];
|
|
|
|
}
|
|
|
|
|
2019-05-24 15:36:14 +00:00
|
|
|
void intel_bw_init_hw(struct drm_i915_private *dev_priv)
|
|
|
|
{
|
2019-11-20 01:10:16 +00:00
|
|
|
if (!HAS_DISPLAY(dev_priv))
|
|
|
|
return;
|
|
|
|
|
2021-07-21 22:30:43 +00:00
|
|
|
if (IS_DG2(dev_priv))
|
|
|
|
dg2_get_bw_info(dev_priv);
|
2021-09-14 22:07:44 +00:00
|
|
|
else if (IS_ALDERLAKE_P(dev_priv))
|
2021-10-15 21:00:41 +00:00
|
|
|
tgl_get_bw_info(dev_priv, &adlp_sa_info);
|
2021-09-14 22:07:44 +00:00
|
|
|
else if (IS_ALDERLAKE_S(dev_priv))
|
2021-10-15 21:00:41 +00:00
|
|
|
tgl_get_bw_info(dev_priv, &adls_sa_info);
|
2021-01-29 18:29:43 +00:00
|
|
|
else if (IS_ROCKETLAKE(dev_priv))
|
2021-10-15 21:00:41 +00:00
|
|
|
tgl_get_bw_info(dev_priv, &rkl_sa_info);
|
drm/i915/display: rename display version macros
While converting the rest of the driver to use GRAPHICS_VER() and
MEDIA_VER(), following what was done for display, some discussions went
back on what we did for display:
1) Why is the == comparison special that deserves a separate
macro instead of just getting the version and comparing directly
like is done for >, >=, <=?
2) IS_DISPLAY_RANGE() is weird in that it omits the "_VER" for
brevity. If we remove the current users of IS_DISPLAY_VER(), we
could actually repurpose it for a range check
With (1) there could be an advantage if we used gen_mask since multiple
conditionals be combined by the compiler in a single and instruction and
check the result. However a) INTEL_GEN() doesn't use the mask since it
would make the code bigger everywhere else and b) in the cases it made
sense, it also made sense to convert to the _RANGE() variant.
So here we repurpose IS_DISPLAY_VER() to work with a [ from, to ] range
like was the IS_DISPLAY_RANGE() and convert the current IS_DISPLAY_VER()
users to use == and != operators. Aside from the definition changes,
this was done by the following semantic patch:
@@ expression dev_priv, E1; @@
- !IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) != E1
@@ expression dev_priv, E1; @@
- IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) == E1
@@ expression dev_priv, from, until; @@
- IS_DISPLAY_RANGE(dev_priv, from, until)
+ IS_DISPLAY_VER(dev_priv, from, until)
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
[Jani: Minor conflict resolve while applying.]
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20210413051002.92589-4-lucas.demarchi@intel.com
2021-04-13 05:09:53 +00:00
|
|
|
else if (DISPLAY_VER(dev_priv) == 12)
|
2021-10-15 21:00:41 +00:00
|
|
|
tgl_get_bw_info(dev_priv, &tgl_sa_info);
|
drm/i915/display: rename display version macros
While converting the rest of the driver to use GRAPHICS_VER() and
MEDIA_VER(), following what was done for display, some discussions went
back on what we did for display:
1) Why is the == comparison special that deserves a separate
macro instead of just getting the version and comparing directly
like is done for >, >=, <=?
2) IS_DISPLAY_RANGE() is weird in that it omits the "_VER" for
brevity. If we remove the current users of IS_DISPLAY_VER(), we
could actually repurpose it for a range check
With (1) there could be an advantage if we used gen_mask since multiple
conditionals be combined by the compiler in a single and instruction and
check the result. However a) INTEL_GEN() doesn't use the mask since it
would make the code bigger everywhere else and b) in the cases it made
sense, it also made sense to convert to the _RANGE() variant.
So here we repurpose IS_DISPLAY_VER() to work with a [ from, to ] range
like was the IS_DISPLAY_RANGE() and convert the current IS_DISPLAY_VER()
users to use == and != operators. Aside from the definition changes,
this was done by the following semantic patch:
@@ expression dev_priv, E1; @@
- !IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) != E1
@@ expression dev_priv, E1; @@
- IS_DISPLAY_VER(dev_priv, E1)
+ DISPLAY_VER(dev_priv) == E1
@@ expression dev_priv, from, until; @@
- IS_DISPLAY_RANGE(dev_priv, from, until)
+ IS_DISPLAY_VER(dev_priv, from, until)
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
[Jani: Minor conflict resolve while applying.]
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20210413051002.92589-4-lucas.demarchi@intel.com
2021-04-13 05:09:53 +00:00
|
|
|
else if (DISPLAY_VER(dev_priv) == 11)
|
2019-09-20 08:37:54 +00:00
|
|
|
icl_get_bw_info(dev_priv, &icl_sa_info);
|
2019-05-24 15:36:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned int intel_bw_crtc_num_active_planes(const struct intel_crtc_state *crtc_state)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* We assume cursors are small enough
|
|
|
|
* to not not cause bandwidth problems.
|
|
|
|
*/
|
|
|
|
return hweight8(crtc_state->active_planes & ~BIT(PLANE_CURSOR));
|
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned int intel_bw_crtc_data_rate(const struct intel_crtc_state *crtc_state)
|
|
|
|
{
|
2019-10-31 11:26:03 +00:00
|
|
|
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
2022-03-03 19:12:00 +00:00
|
|
|
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
|
2019-05-24 15:36:14 +00:00
|
|
|
unsigned int data_rate = 0;
|
|
|
|
enum plane_id plane_id;
|
|
|
|
|
|
|
|
for_each_plane_id_on_crtc(crtc, plane_id) {
|
|
|
|
/*
|
|
|
|
* We assume cursors are small enough
|
|
|
|
* to not not cause bandwidth problems.
|
|
|
|
*/
|
|
|
|
if (plane_id == PLANE_CURSOR)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
data_rate += crtc_state->data_rate[plane_id];
|
2022-03-03 19:12:00 +00:00
|
|
|
|
|
|
|
if (DISPLAY_VER(i915) < 11)
|
|
|
|
data_rate += crtc_state->data_rate_y[plane_id];
|
2019-05-24 15:36:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return data_rate;
|
|
|
|
}
|
2020-05-22 13:18:43 +00:00
|
|
|
|
2022-03-03 19:12:07 +00:00
|
|
|
/* "Maximum Pipe Read Bandwidth" */
|
|
|
|
static int intel_bw_crtc_min_cdclk(const struct intel_crtc_state *crtc_state)
|
|
|
|
{
|
|
|
|
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
|
|
|
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
|
|
|
|
|
|
|
|
if (DISPLAY_VER(i915) < 12)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return DIV_ROUND_UP_ULL(mul_u32_u32(intel_bw_crtc_data_rate(crtc_state), 10), 512);
|
|
|
|
}
|
|
|
|
|
2019-05-24 15:36:14 +00:00
|
|
|
void intel_bw_crtc_update(struct intel_bw_state *bw_state,
|
|
|
|
const struct intel_crtc_state *crtc_state)
|
|
|
|
{
|
2019-10-31 11:26:03 +00:00
|
|
|
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
2020-04-02 11:48:09 +00:00
|
|
|
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
|
2019-05-24 15:36:14 +00:00
|
|
|
|
|
|
|
bw_state->data_rate[crtc->pipe] =
|
|
|
|
intel_bw_crtc_data_rate(crtc_state);
|
|
|
|
bw_state->num_active_planes[crtc->pipe] =
|
|
|
|
intel_bw_crtc_num_active_planes(crtc_state);
|
|
|
|
|
2020-04-02 11:48:09 +00:00
|
|
|
drm_dbg_kms(&i915->drm, "pipe %c data rate %u num active planes %u\n",
|
|
|
|
pipe_name(crtc->pipe),
|
|
|
|
bw_state->data_rate[crtc->pipe],
|
|
|
|
bw_state->num_active_planes[crtc->pipe]);
|
2019-05-24 15:36:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned int intel_bw_num_active_planes(struct drm_i915_private *dev_priv,
|
|
|
|
const struct intel_bw_state *bw_state)
|
|
|
|
{
|
|
|
|
unsigned int num_active_planes = 0;
|
|
|
|
enum pipe pipe;
|
|
|
|
|
|
|
|
for_each_pipe(dev_priv, pipe)
|
|
|
|
num_active_planes += bw_state->num_active_planes[pipe];
|
|
|
|
|
|
|
|
return num_active_planes;
|
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned int intel_bw_data_rate(struct drm_i915_private *dev_priv,
|
|
|
|
const struct intel_bw_state *bw_state)
|
|
|
|
{
|
|
|
|
unsigned int data_rate = 0;
|
|
|
|
enum pipe pipe;
|
|
|
|
|
|
|
|
for_each_pipe(dev_priv, pipe)
|
|
|
|
data_rate += bw_state->data_rate[pipe];
|
|
|
|
|
2022-03-29 09:02:04 +00:00
|
|
|
if (DISPLAY_VER(dev_priv) >= 13 && i915_vtd_active(dev_priv))
|
2022-03-03 19:12:04 +00:00
|
|
|
data_rate = DIV_ROUND_UP(data_rate * 105, 100);
|
2021-05-12 04:21:41 +00:00
|
|
|
|
2019-05-24 15:36:14 +00:00
|
|
|
return data_rate;
|
|
|
|
}
|
|
|
|
|
2020-04-15 14:39:02 +00:00
|
|
|
struct intel_bw_state *
|
|
|
|
intel_atomic_get_old_bw_state(struct intel_atomic_state *state)
|
|
|
|
{
|
|
|
|
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
|
|
|
|
struct intel_global_state *bw_state;
|
|
|
|
|
|
|
|
bw_state = intel_atomic_get_old_global_obj_state(state, &dev_priv->bw_obj);
|
|
|
|
|
|
|
|
return to_intel_bw_state(bw_state);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct intel_bw_state *
|
|
|
|
intel_atomic_get_new_bw_state(struct intel_atomic_state *state)
|
|
|
|
{
|
|
|
|
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
|
|
|
|
struct intel_global_state *bw_state;
|
|
|
|
|
|
|
|
bw_state = intel_atomic_get_new_global_obj_state(state, &dev_priv->bw_obj);
|
|
|
|
|
|
|
|
return to_intel_bw_state(bw_state);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct intel_bw_state *
|
2019-08-06 10:07:25 +00:00
|
|
|
intel_atomic_get_bw_state(struct intel_atomic_state *state)
|
|
|
|
{
|
|
|
|
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
|
2020-01-20 17:47:25 +00:00
|
|
|
struct intel_global_state *bw_state;
|
2019-08-06 10:07:25 +00:00
|
|
|
|
2020-01-20 17:47:25 +00:00
|
|
|
bw_state = intel_atomic_get_global_obj_state(state, &dev_priv->bw_obj);
|
2019-08-06 10:07:25 +00:00
|
|
|
if (IS_ERR(bw_state))
|
|
|
|
return ERR_CAST(bw_state);
|
|
|
|
|
|
|
|
return to_intel_bw_state(bw_state);
|
|
|
|
}
|
|
|
|
|
2022-03-03 19:12:05 +00:00
|
|
|
static bool intel_bw_state_changed(struct drm_i915_private *i915,
|
|
|
|
const struct intel_bw_state *old_bw_state,
|
|
|
|
const struct intel_bw_state *new_bw_state)
|
|
|
|
{
|
|
|
|
enum pipe pipe;
|
|
|
|
|
|
|
|
for_each_pipe(i915, pipe) {
|
|
|
|
const struct intel_dbuf_bw *old_crtc_bw =
|
|
|
|
&old_bw_state->dbuf_bw[pipe];
|
|
|
|
const struct intel_dbuf_bw *new_crtc_bw =
|
|
|
|
&new_bw_state->dbuf_bw[pipe];
|
|
|
|
enum dbuf_slice slice;
|
|
|
|
|
|
|
|
for_each_dbuf_slice(i915, slice) {
|
2022-03-03 19:12:06 +00:00
|
|
|
if (old_crtc_bw->max_bw[slice] != new_crtc_bw->max_bw[slice] ||
|
|
|
|
old_crtc_bw->active_planes[slice] != new_crtc_bw->active_planes[slice])
|
2022-03-03 19:12:05 +00:00
|
|
|
return true;
|
|
|
|
}
|
2022-03-03 19:12:07 +00:00
|
|
|
|
|
|
|
if (old_bw_state->min_cdclk[pipe] != new_bw_state->min_cdclk[pipe])
|
|
|
|
return true;
|
2022-03-03 19:12:05 +00:00
|
|
|
}
|
|
|
|
|
2022-03-03 19:12:06 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void skl_plane_calc_dbuf_bw(struct intel_bw_state *bw_state,
|
|
|
|
struct intel_crtc *crtc,
|
|
|
|
enum plane_id plane_id,
|
|
|
|
const struct skl_ddb_entry *ddb,
|
|
|
|
unsigned int data_rate)
|
|
|
|
{
|
|
|
|
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
|
|
|
|
struct intel_dbuf_bw *crtc_bw = &bw_state->dbuf_bw[crtc->pipe];
|
|
|
|
unsigned int dbuf_mask = skl_ddb_dbuf_slice_mask(i915, ddb);
|
|
|
|
enum dbuf_slice slice;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The arbiter can only really guarantee an
|
|
|
|
* equal share of the total bw to each plane.
|
|
|
|
*/
|
|
|
|
for_each_dbuf_slice_in_mask(i915, slice, dbuf_mask) {
|
|
|
|
crtc_bw->max_bw[slice] = max(crtc_bw->max_bw[slice], data_rate);
|
|
|
|
crtc_bw->active_planes[slice] |= BIT(plane_id);
|
|
|
|
}
|
2022-03-03 19:12:05 +00:00
|
|
|
}
|
|
|
|
|
2022-01-18 09:23:45 +00:00
|
|
|
static void skl_crtc_calc_dbuf_bw(struct intel_bw_state *bw_state,
|
|
|
|
const struct intel_crtc_state *crtc_state)
|
|
|
|
{
|
|
|
|
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
|
|
|
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
|
|
|
|
struct intel_dbuf_bw *crtc_bw = &bw_state->dbuf_bw[crtc->pipe];
|
|
|
|
enum plane_id plane_id;
|
|
|
|
|
2022-03-03 19:12:06 +00:00
|
|
|
memset(crtc_bw, 0, sizeof(*crtc_bw));
|
2022-01-18 09:23:45 +00:00
|
|
|
|
|
|
|
if (!crtc_state->hw.active)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for_each_plane_id_on_crtc(crtc, plane_id) {
|
2022-03-03 19:12:06 +00:00
|
|
|
/*
|
|
|
|
* We assume cursors are small enough
|
|
|
|
* to not cause bandwidth problems.
|
|
|
|
*/
|
|
|
|
if (plane_id == PLANE_CURSOR)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
skl_plane_calc_dbuf_bw(bw_state, crtc, plane_id,
|
|
|
|
&crtc_state->wm.skl.plane_ddb[plane_id],
|
|
|
|
crtc_state->data_rate[plane_id]);
|
2022-01-18 09:23:45 +00:00
|
|
|
|
2022-03-03 19:12:06 +00:00
|
|
|
if (DISPLAY_VER(i915) < 11)
|
|
|
|
skl_plane_calc_dbuf_bw(bw_state, crtc, plane_id,
|
|
|
|
&crtc_state->wm.skl.plane_ddb_y[plane_id],
|
|
|
|
crtc_state->data_rate[plane_id]);
|
2022-03-03 19:12:00 +00:00
|
|
|
}
|
2022-03-03 19:12:06 +00:00
|
|
|
}
|
2022-03-03 19:12:00 +00:00
|
|
|
|
2022-03-03 19:12:06 +00:00
|
|
|
/* "Maximum Data Buffer Bandwidth" */
|
|
|
|
static int
|
|
|
|
intel_bw_dbuf_min_cdclk(struct drm_i915_private *i915,
|
|
|
|
const struct intel_bw_state *bw_state)
|
|
|
|
{
|
|
|
|
unsigned int total_max_bw = 0;
|
|
|
|
enum dbuf_slice slice;
|
2022-03-03 19:12:00 +00:00
|
|
|
|
2022-03-03 19:12:06 +00:00
|
|
|
for_each_dbuf_slice(i915, slice) {
|
|
|
|
int num_active_planes = 0;
|
|
|
|
unsigned int max_bw = 0;
|
|
|
|
enum pipe pipe;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The arbiter can only really guarantee an
|
|
|
|
* equal share of the total bw to each plane.
|
|
|
|
*/
|
|
|
|
for_each_pipe(i915, pipe) {
|
|
|
|
const struct intel_dbuf_bw *crtc_bw = &bw_state->dbuf_bw[pipe];
|
|
|
|
|
|
|
|
max_bw = max(crtc_bw->max_bw[slice], max_bw);
|
|
|
|
num_active_planes += hweight8(crtc_bw->active_planes[slice]);
|
|
|
|
}
|
|
|
|
max_bw *= num_active_planes;
|
2022-01-18 09:23:45 +00:00
|
|
|
|
2022-03-03 19:12:06 +00:00
|
|
|
total_max_bw = max(total_max_bw, max_bw);
|
2022-01-18 09:23:45 +00:00
|
|
|
}
|
2022-03-03 19:12:06 +00:00
|
|
|
|
|
|
|
return DIV_ROUND_UP(total_max_bw, 64);
|
|
|
|
}
|
|
|
|
|
|
|
|
int intel_bw_min_cdclk(struct drm_i915_private *i915,
|
|
|
|
const struct intel_bw_state *bw_state)
|
|
|
|
{
|
2022-03-03 19:12:07 +00:00
|
|
|
enum pipe pipe;
|
|
|
|
int min_cdclk;
|
|
|
|
|
|
|
|
min_cdclk = intel_bw_dbuf_min_cdclk(i915, bw_state);
|
|
|
|
|
|
|
|
for_each_pipe(i915, pipe)
|
|
|
|
min_cdclk = max(bw_state->min_cdclk[pipe], min_cdclk);
|
|
|
|
|
|
|
|
return min_cdclk;
|
2022-01-18 09:23:45 +00:00
|
|
|
}
|
|
|
|
|
2022-03-03 19:12:06 +00:00
|
|
|
int intel_bw_calc_min_cdclk(struct intel_atomic_state *state,
|
|
|
|
bool *need_cdclk_calc)
|
2020-05-20 15:00:58 +00:00
|
|
|
{
|
|
|
|
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
|
2020-05-22 13:18:43 +00:00
|
|
|
struct intel_bw_state *new_bw_state = NULL;
|
2022-03-03 19:12:06 +00:00
|
|
|
const struct intel_bw_state *old_bw_state = NULL;
|
|
|
|
const struct intel_cdclk_state *cdclk_state;
|
2020-05-20 15:00:58 +00:00
|
|
|
const struct intel_crtc_state *crtc_state;
|
2022-03-03 19:12:06 +00:00
|
|
|
int old_min_cdclk, new_min_cdclk;
|
2020-05-20 15:00:58 +00:00
|
|
|
struct intel_crtc *crtc;
|
2020-05-22 13:18:43 +00:00
|
|
|
int i;
|
2020-05-20 15:00:58 +00:00
|
|
|
|
2022-03-03 19:12:03 +00:00
|
|
|
if (DISPLAY_VER(dev_priv) < 9)
|
|
|
|
return 0;
|
|
|
|
|
2020-05-20 15:00:58 +00:00
|
|
|
for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
|
|
|
|
new_bw_state = intel_atomic_get_bw_state(state);
|
|
|
|
if (IS_ERR(new_bw_state))
|
|
|
|
return PTR_ERR(new_bw_state);
|
|
|
|
|
2020-06-01 17:30:58 +00:00
|
|
|
old_bw_state = intel_atomic_get_old_bw_state(state);
|
|
|
|
|
2022-01-18 09:23:45 +00:00
|
|
|
skl_crtc_calc_dbuf_bw(new_bw_state, crtc_state);
|
2022-03-03 19:12:07 +00:00
|
|
|
|
|
|
|
new_bw_state->min_cdclk[crtc->pipe] =
|
|
|
|
intel_bw_crtc_min_cdclk(crtc_state);
|
2020-06-01 17:30:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!old_bw_state)
|
|
|
|
return 0;
|
|
|
|
|
2022-03-03 19:12:05 +00:00
|
|
|
if (intel_bw_state_changed(dev_priv, old_bw_state, new_bw_state)) {
|
2020-05-20 15:00:58 +00:00
|
|
|
int ret = intel_atomic_lock_global_state(&new_bw_state->base);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2022-03-03 19:12:06 +00:00
|
|
|
old_min_cdclk = intel_bw_min_cdclk(dev_priv, old_bw_state);
|
|
|
|
new_min_cdclk = intel_bw_min_cdclk(dev_priv, new_bw_state);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* No need to check against the cdclk state if
|
2022-03-03 19:12:07 +00:00
|
|
|
* the min cdclk doesn't increase.
|
2022-03-03 19:12:06 +00:00
|
|
|
*
|
2022-03-03 19:12:07 +00:00
|
|
|
* Ie. we only ever increase the cdclk due to bandwidth
|
2022-03-03 19:12:06 +00:00
|
|
|
* requirements. This can reduce back and forth
|
|
|
|
* display blinking due to constant cdclk changes.
|
|
|
|
*/
|
|
|
|
if (new_min_cdclk <= old_min_cdclk)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
cdclk_state = intel_atomic_get_cdclk_state(state);
|
|
|
|
if (IS_ERR(cdclk_state))
|
|
|
|
return PTR_ERR(cdclk_state);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* No need to recalculate the cdclk state if
|
2022-03-03 19:12:07 +00:00
|
|
|
* the min cdclk doesn't increase.
|
2022-03-03 19:12:06 +00:00
|
|
|
*
|
2022-03-03 19:12:07 +00:00
|
|
|
* Ie. we only ever increase the cdclk due to bandwidth
|
2022-03-03 19:12:06 +00:00
|
|
|
* requirements. This can reduce back and forth
|
|
|
|
* display blinking due to constant cdclk changes.
|
|
|
|
*/
|
|
|
|
if (new_min_cdclk <= cdclk_state->bw_min_cdclk)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
drm_dbg_kms(&dev_priv->drm,
|
|
|
|
"new bandwidth min cdclk (%d kHz) > old min cdclk (%d kHz)\n",
|
|
|
|
new_min_cdclk, cdclk_state->bw_min_cdclk);
|
|
|
|
*need_cdclk_calc = true;
|
|
|
|
|
2020-05-20 15:00:58 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-02-18 06:40:38 +00:00
|
|
|
static u16 icl_qgv_points_mask(struct drm_i915_private *i915)
|
|
|
|
{
|
|
|
|
unsigned int num_psf_gv_points = i915->max_bw[0].num_psf_gv_points;
|
|
|
|
unsigned int num_qgv_points = i915->max_bw[0].num_qgv_points;
|
2022-03-09 16:49:47 +00:00
|
|
|
u16 qgv_points = 0, psf_points = 0;
|
2022-02-18 06:40:38 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* We can _not_ use the whole ADLS_QGV_PT_MASK here, as PCode rejects
|
|
|
|
* it with failure if we try masking any unadvertised points.
|
|
|
|
* So need to operate only with those returned from PCode.
|
|
|
|
*/
|
|
|
|
if (num_qgv_points > 0)
|
2022-03-09 16:49:47 +00:00
|
|
|
qgv_points = GENMASK(num_qgv_points - 1, 0);
|
2022-02-18 06:40:38 +00:00
|
|
|
|
|
|
|
if (num_psf_gv_points > 0)
|
2022-03-09 16:49:47 +00:00
|
|
|
psf_points = GENMASK(num_psf_gv_points - 1, 0);
|
2022-02-18 06:40:38 +00:00
|
|
|
|
2022-03-09 16:49:48 +00:00
|
|
|
return ICL_PCODE_REQ_QGV_PT(qgv_points) | ADLS_PCODE_REQ_PSF_PT(psf_points);
|
2022-02-18 06:40:38 +00:00
|
|
|
}
|
|
|
|
|
2022-02-18 06:40:39 +00:00
|
|
|
static int intel_bw_check_data_rate(struct intel_atomic_state *state, bool *changed)
|
2019-05-24 15:36:14 +00:00
|
|
|
{
|
2022-02-18 06:40:39 +00:00
|
|
|
struct drm_i915_private *i915 = to_i915(state->base.dev);
|
|
|
|
const struct intel_crtc_state *new_crtc_state, *old_crtc_state;
|
2019-05-24 15:36:14 +00:00
|
|
|
struct intel_crtc *crtc;
|
2022-02-18 06:40:39 +00:00
|
|
|
int i;
|
2019-05-24 15:36:14 +00:00
|
|
|
|
|
|
|
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
|
|
|
|
new_crtc_state, i) {
|
|
|
|
unsigned int old_data_rate =
|
|
|
|
intel_bw_crtc_data_rate(old_crtc_state);
|
|
|
|
unsigned int new_data_rate =
|
|
|
|
intel_bw_crtc_data_rate(new_crtc_state);
|
|
|
|
unsigned int old_active_planes =
|
|
|
|
intel_bw_crtc_num_active_planes(old_crtc_state);
|
|
|
|
unsigned int new_active_planes =
|
|
|
|
intel_bw_crtc_num_active_planes(new_crtc_state);
|
2022-02-18 06:40:39 +00:00
|
|
|
struct intel_bw_state *new_bw_state;
|
2019-05-24 15:36:14 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Avoid locking the bw state when
|
|
|
|
* nothing significant has changed.
|
|
|
|
*/
|
|
|
|
if (old_data_rate == new_data_rate &&
|
|
|
|
old_active_planes == new_active_planes)
|
|
|
|
continue;
|
|
|
|
|
2020-04-23 07:59:00 +00:00
|
|
|
new_bw_state = intel_atomic_get_bw_state(state);
|
|
|
|
if (IS_ERR(new_bw_state))
|
|
|
|
return PTR_ERR(new_bw_state);
|
2019-05-24 15:36:14 +00:00
|
|
|
|
2020-04-23 07:59:00 +00:00
|
|
|
new_bw_state->data_rate[crtc->pipe] = new_data_rate;
|
|
|
|
new_bw_state->num_active_planes[crtc->pipe] = new_active_planes;
|
2019-05-24 15:36:14 +00:00
|
|
|
|
2022-02-18 06:40:39 +00:00
|
|
|
*changed = true;
|
2022-02-18 06:40:35 +00:00
|
|
|
|
2022-02-18 06:40:39 +00:00
|
|
|
drm_dbg_kms(&i915->drm,
|
|
|
|
"[CRTC:%d:%s] data rate %u num active planes %u\n",
|
|
|
|
crtc->base.base.id, crtc->base.name,
|
2020-04-23 07:59:00 +00:00
|
|
|
new_bw_state->data_rate[crtc->pipe],
|
|
|
|
new_bw_state->num_active_planes[crtc->pipe]);
|
2019-05-24 15:36:14 +00:00
|
|
|
}
|
|
|
|
|
2022-02-18 06:40:39 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int intel_bw_atomic_check(struct intel_atomic_state *state)
|
|
|
|
{
|
|
|
|
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
|
|
|
|
const struct intel_bw_state *old_bw_state;
|
|
|
|
struct intel_bw_state *new_bw_state;
|
|
|
|
unsigned int data_rate;
|
|
|
|
unsigned int num_active_planes;
|
|
|
|
int i, ret;
|
2022-03-09 16:49:47 +00:00
|
|
|
u16 qgv_points = 0, psf_points = 0;
|
2022-02-18 06:40:39 +00:00
|
|
|
unsigned int max_bw_point = 0, max_bw = 0;
|
|
|
|
unsigned int num_qgv_points = dev_priv->max_bw[0].num_qgv_points;
|
|
|
|
unsigned int num_psf_gv_points = dev_priv->max_bw[0].num_psf_gv_points;
|
|
|
|
bool changed = false;
|
|
|
|
|
|
|
|
/* FIXME earlier gens need some checks too */
|
|
|
|
if (DISPLAY_VER(dev_priv) < 11)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
ret = intel_bw_check_data_rate(state, &changed);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
2022-02-18 06:40:35 +00:00
|
|
|
old_bw_state = intel_atomic_get_old_bw_state(state);
|
|
|
|
new_bw_state = intel_atomic_get_new_bw_state(state);
|
|
|
|
|
|
|
|
if (new_bw_state &&
|
|
|
|
intel_can_enable_sagv(dev_priv, old_bw_state) !=
|
|
|
|
intel_can_enable_sagv(dev_priv, new_bw_state))
|
|
|
|
changed = true;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If none of our inputs (data rates, number of active
|
|
|
|
* planes, SAGV yes/no) changed then nothing to do here.
|
|
|
|
*/
|
|
|
|
if (!changed)
|
2019-05-24 15:36:14 +00:00
|
|
|
return 0;
|
|
|
|
|
2020-04-23 07:59:00 +00:00
|
|
|
ret = intel_atomic_lock_global_state(&new_bw_state->base);
|
2020-01-20 17:47:25 +00:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
2020-04-23 07:59:00 +00:00
|
|
|
data_rate = intel_bw_data_rate(dev_priv, new_bw_state);
|
drm/i915: Restrict qgv points which don't have enough bandwidth.
According to BSpec 53998, we should try to
restrict qgv points, which can't provide
enough bandwidth for desired display configuration.
Currently we are just comparing against all of
those and take minimum(worst case).
v2: Fixed wrong PCode reply mask, removed hardcoded
values.
v3: Forbid simultaneous legacy SAGV PCode requests and
restricting qgv points. Put the actual restriction
to commit function, added serialization(thanks to Ville)
to prevent commit being applied out of order in case of
nonblocking and/or nomodeset commits.
v4:
- Minor code refactoring, fixed few typos(thanks to James Ausmus)
- Change the naming of qgv point
masking/unmasking functions(James Ausmus).
- Simplify the masking/unmasking operation itself,
as we don't need to mask only single point per request(James Ausmus)
- Reject and stick to highest bandwidth point if SAGV
can't be enabled(BSpec)
v5:
- Add new mailbox reply codes, which seems to happen during boot
time for TGL and indicate that QGV setting is not yet available.
v6:
- Increase number of supported QGV points to be in sync with BSpec.
v7: - Rebased and resolved conflict to fix build failure.
- Fix NUM_QGV_POINTS to 8 and moved that to header file(James Ausmus)
v8: - Don't report an error if we can't restrict qgv points, as SAGV
can be disabled by BIOS, which is completely legal. So don't
make CI panic. Instead if we detect that there is only 1 QGV
point accessible just analyze if we can fit the required bandwidth
requirements, but no need in restricting.
v9: - Fix wrong QGV transition if we have 0 planes and no SAGV
simultaneously.
v10: - Fix CDCLK corruption, because of global state getting serialized
without modeset, which caused copying of non-calculated cdclk
to be copied to dev_priv(thanks to Ville for the hint).
v11: - Remove unneeded headers and spaces(Matthew Roper)
- Remove unneeded intel_qgv_info qi struct from bw check and zero
out the needed one(Matthew Roper)
- Changed QGV error message to have more clear meaning(Matthew Roper)
- Use state->modeset_set instead of any_ms(Matthew Roper)
- Moved NUM_SAGV_POINTS from i915_reg.h to i915_drv.h where it's used
- Keep using crtc_state->hw.active instead of .enable(Matthew Roper)
- Moved unrelated changes to other patch(using latency as parameter
for plane wm calculation, moved to SAGV refactoring patch)
v12: - Fix rebase conflict with own temporary SAGV/QGV fix.
- Remove unnecessary mask being zero check when unmasking
qgv points as this is completely legal(Matt Roper)
- Check if we are setting the same mask as already being set
in hardware to prevent error from PCode.
- Fix error message when restricting/unrestricting qgv points
to "mask/unmask" which sounds more accurate(Matt Roper)
- Move sagv status setting to icl_get_bw_info from atomic check
as this should be calculated only once.(Matt Roper)
- Edited comments for the case when we can't enable SAGV and
use only 1 QGV point with highest bandwidth to be more
understandable.(Matt Roper)
v13: - Moved max_data_rate in bw check to closer scope(Ville Syrjälä)
- Changed comment for zero new_mask in qgv points masking function
to better reflect reality(Ville Syrjälä)
- Simplified bit mask operation in qgv points masking function
(Ville Syrjälä)
- Moved intel_qgv_points_mask closer to gen11 SAGV disabling,
however this still can't be under modeset condition(Ville Syrjälä)
- Packed qgv_points_mask as u8 and moved closer to pipe_sagv_mask
(Ville Syrjälä)
- Extracted PCode changes to separate patch.(Ville Syrjälä)
- Now treat num_planes 0 same as 1 to avoid confusion and
returning max_bw as 0, which would prevent choosing QGV
point having max bandwidth in case if SAGV is not allowed,
as per BSpec(Ville Syrjälä)
- Do the actual qgv_points_mask swap in the same place as
all other global state parts like cdclk are swapped.
In the next patch, this all will be moved to bw state as
global state, once new global state patch series from Ville
lands
v14: - Now using global state to serialize access to qgv points
- Added global state locking back, otherwise we seem to read
bw state in a wrong way.
v15: - Added TODO comment for near atomic global state locking in
bw code.
v16: - Fixed intel_atomic_bw_* functions to be intel_bw_* as discussed
with Jani Nikula.
- Take bw_state_changed flag into use.
v17: - Moved qgv point related manipulations next to SAGV code, as
those are semantically related(Ville Syrjälä)
- Renamed those into intel_sagv_(pre)|(post)_plane_update
(Ville Syrjälä)
v18: - Move sagv related calls from commit tail into
intel_sagv_(pre)|(post)_plane_update(Ville Syrjälä)
v19: - Use intel_atomic_get_bw_(old)|(new)_state which is intended
for commit tail stage.
v20: - Return max bandwidth for 0 planes(Ville)
- Constify old_bw_state in bw_atomic_check(Ville)
- Removed some debugs(Ville)
- Added data rate to debug print when no QGV points(Ville)
- Removed some comments(Ville)
v21, v22, v23: - Fixed rebase conflict
v24: - Changed PCode mask to use ICL_ prefix
v25: - Resolved rebase conflict
v26: - Removed redundant NULL checks(Ville)
- Removed redundant error prints(Ville)
v27: - Use device specific drm_err(Ville)
- Fixed parenthesis ident reported by checkpatch
Line over 100 warns to be fixed together with
existing code style.
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Ville Syrjälä <ville.syrjala@intel.com>
Cc: James Ausmus <james.ausmus@intel.com>
[vsyrjala: Drop duplicate intel_sagv_{pre,post}_plane_update() prototypes
and drop unused NUM_SAGV_POINTS define]
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200514074853.9508-3-stanislav.lisovskiy@intel.com
2020-05-14 07:48:52 +00:00
|
|
|
data_rate = DIV_ROUND_UP(data_rate, 1000);
|
|
|
|
|
2020-04-23 07:59:00 +00:00
|
|
|
num_active_planes = intel_bw_num_active_planes(dev_priv, new_bw_state);
|
2019-05-24 15:36:14 +00:00
|
|
|
|
drm/i915: Restrict qgv points which don't have enough bandwidth.
According to BSpec 53998, we should try to
restrict qgv points, which can't provide
enough bandwidth for desired display configuration.
Currently we are just comparing against all of
those and take minimum(worst case).
v2: Fixed wrong PCode reply mask, removed hardcoded
values.
v3: Forbid simultaneous legacy SAGV PCode requests and
restricting qgv points. Put the actual restriction
to commit function, added serialization(thanks to Ville)
to prevent commit being applied out of order in case of
nonblocking and/or nomodeset commits.
v4:
- Minor code refactoring, fixed few typos(thanks to James Ausmus)
- Change the naming of qgv point
masking/unmasking functions(James Ausmus).
- Simplify the masking/unmasking operation itself,
as we don't need to mask only single point per request(James Ausmus)
- Reject and stick to highest bandwidth point if SAGV
can't be enabled(BSpec)
v5:
- Add new mailbox reply codes, which seems to happen during boot
time for TGL and indicate that QGV setting is not yet available.
v6:
- Increase number of supported QGV points to be in sync with BSpec.
v7: - Rebased and resolved conflict to fix build failure.
- Fix NUM_QGV_POINTS to 8 and moved that to header file(James Ausmus)
v8: - Don't report an error if we can't restrict qgv points, as SAGV
can be disabled by BIOS, which is completely legal. So don't
make CI panic. Instead if we detect that there is only 1 QGV
point accessible just analyze if we can fit the required bandwidth
requirements, but no need in restricting.
v9: - Fix wrong QGV transition if we have 0 planes and no SAGV
simultaneously.
v10: - Fix CDCLK corruption, because of global state getting serialized
without modeset, which caused copying of non-calculated cdclk
to be copied to dev_priv(thanks to Ville for the hint).
v11: - Remove unneeded headers and spaces(Matthew Roper)
- Remove unneeded intel_qgv_info qi struct from bw check and zero
out the needed one(Matthew Roper)
- Changed QGV error message to have more clear meaning(Matthew Roper)
- Use state->modeset_set instead of any_ms(Matthew Roper)
- Moved NUM_SAGV_POINTS from i915_reg.h to i915_drv.h where it's used
- Keep using crtc_state->hw.active instead of .enable(Matthew Roper)
- Moved unrelated changes to other patch(using latency as parameter
for plane wm calculation, moved to SAGV refactoring patch)
v12: - Fix rebase conflict with own temporary SAGV/QGV fix.
- Remove unnecessary mask being zero check when unmasking
qgv points as this is completely legal(Matt Roper)
- Check if we are setting the same mask as already being set
in hardware to prevent error from PCode.
- Fix error message when restricting/unrestricting qgv points
to "mask/unmask" which sounds more accurate(Matt Roper)
- Move sagv status setting to icl_get_bw_info from atomic check
as this should be calculated only once.(Matt Roper)
- Edited comments for the case when we can't enable SAGV and
use only 1 QGV point with highest bandwidth to be more
understandable.(Matt Roper)
v13: - Moved max_data_rate in bw check to closer scope(Ville Syrjälä)
- Changed comment for zero new_mask in qgv points masking function
to better reflect reality(Ville Syrjälä)
- Simplified bit mask operation in qgv points masking function
(Ville Syrjälä)
- Moved intel_qgv_points_mask closer to gen11 SAGV disabling,
however this still can't be under modeset condition(Ville Syrjälä)
- Packed qgv_points_mask as u8 and moved closer to pipe_sagv_mask
(Ville Syrjälä)
- Extracted PCode changes to separate patch.(Ville Syrjälä)
- Now treat num_planes 0 same as 1 to avoid confusion and
returning max_bw as 0, which would prevent choosing QGV
point having max bandwidth in case if SAGV is not allowed,
as per BSpec(Ville Syrjälä)
- Do the actual qgv_points_mask swap in the same place as
all other global state parts like cdclk are swapped.
In the next patch, this all will be moved to bw state as
global state, once new global state patch series from Ville
lands
v14: - Now using global state to serialize access to qgv points
- Added global state locking back, otherwise we seem to read
bw state in a wrong way.
v15: - Added TODO comment for near atomic global state locking in
bw code.
v16: - Fixed intel_atomic_bw_* functions to be intel_bw_* as discussed
with Jani Nikula.
- Take bw_state_changed flag into use.
v17: - Moved qgv point related manipulations next to SAGV code, as
those are semantically related(Ville Syrjälä)
- Renamed those into intel_sagv_(pre)|(post)_plane_update
(Ville Syrjälä)
v18: - Move sagv related calls from commit tail into
intel_sagv_(pre)|(post)_plane_update(Ville Syrjälä)
v19: - Use intel_atomic_get_bw_(old)|(new)_state which is intended
for commit tail stage.
v20: - Return max bandwidth for 0 planes(Ville)
- Constify old_bw_state in bw_atomic_check(Ville)
- Removed some debugs(Ville)
- Added data rate to debug print when no QGV points(Ville)
- Removed some comments(Ville)
v21, v22, v23: - Fixed rebase conflict
v24: - Changed PCode mask to use ICL_ prefix
v25: - Resolved rebase conflict
v26: - Removed redundant NULL checks(Ville)
- Removed redundant error prints(Ville)
v27: - Use device specific drm_err(Ville)
- Fixed parenthesis ident reported by checkpatch
Line over 100 warns to be fixed together with
existing code style.
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Ville Syrjälä <ville.syrjala@intel.com>
Cc: James Ausmus <james.ausmus@intel.com>
[vsyrjala: Drop duplicate intel_sagv_{pre,post}_plane_update() prototypes
and drop unused NUM_SAGV_POINTS define]
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200514074853.9508-3-stanislav.lisovskiy@intel.com
2020-05-14 07:48:52 +00:00
|
|
|
for (i = 0; i < num_qgv_points; i++) {
|
|
|
|
unsigned int max_data_rate;
|
2019-05-24 15:36:14 +00:00
|
|
|
|
2021-10-15 21:00:41 +00:00
|
|
|
if (DISPLAY_VER(dev_priv) > 11)
|
|
|
|
max_data_rate = tgl_max_bw(dev_priv, num_active_planes, i);
|
|
|
|
else
|
|
|
|
max_data_rate = icl_max_bw(dev_priv, num_active_planes, i);
|
drm/i915: Restrict qgv points which don't have enough bandwidth.
According to BSpec 53998, we should try to
restrict qgv points, which can't provide
enough bandwidth for desired display configuration.
Currently we are just comparing against all of
those and take minimum(worst case).
v2: Fixed wrong PCode reply mask, removed hardcoded
values.
v3: Forbid simultaneous legacy SAGV PCode requests and
restricting qgv points. Put the actual restriction
to commit function, added serialization(thanks to Ville)
to prevent commit being applied out of order in case of
nonblocking and/or nomodeset commits.
v4:
- Minor code refactoring, fixed few typos(thanks to James Ausmus)
- Change the naming of qgv point
masking/unmasking functions(James Ausmus).
- Simplify the masking/unmasking operation itself,
as we don't need to mask only single point per request(James Ausmus)
- Reject and stick to highest bandwidth point if SAGV
can't be enabled(BSpec)
v5:
- Add new mailbox reply codes, which seems to happen during boot
time for TGL and indicate that QGV setting is not yet available.
v6:
- Increase number of supported QGV points to be in sync with BSpec.
v7: - Rebased and resolved conflict to fix build failure.
- Fix NUM_QGV_POINTS to 8 and moved that to header file(James Ausmus)
v8: - Don't report an error if we can't restrict qgv points, as SAGV
can be disabled by BIOS, which is completely legal. So don't
make CI panic. Instead if we detect that there is only 1 QGV
point accessible just analyze if we can fit the required bandwidth
requirements, but no need in restricting.
v9: - Fix wrong QGV transition if we have 0 planes and no SAGV
simultaneously.
v10: - Fix CDCLK corruption, because of global state getting serialized
without modeset, which caused copying of non-calculated cdclk
to be copied to dev_priv(thanks to Ville for the hint).
v11: - Remove unneeded headers and spaces(Matthew Roper)
- Remove unneeded intel_qgv_info qi struct from bw check and zero
out the needed one(Matthew Roper)
- Changed QGV error message to have more clear meaning(Matthew Roper)
- Use state->modeset_set instead of any_ms(Matthew Roper)
- Moved NUM_SAGV_POINTS from i915_reg.h to i915_drv.h where it's used
- Keep using crtc_state->hw.active instead of .enable(Matthew Roper)
- Moved unrelated changes to other patch(using latency as parameter
for plane wm calculation, moved to SAGV refactoring patch)
v12: - Fix rebase conflict with own temporary SAGV/QGV fix.
- Remove unnecessary mask being zero check when unmasking
qgv points as this is completely legal(Matt Roper)
- Check if we are setting the same mask as already being set
in hardware to prevent error from PCode.
- Fix error message when restricting/unrestricting qgv points
to "mask/unmask" which sounds more accurate(Matt Roper)
- Move sagv status setting to icl_get_bw_info from atomic check
as this should be calculated only once.(Matt Roper)
- Edited comments for the case when we can't enable SAGV and
use only 1 QGV point with highest bandwidth to be more
understandable.(Matt Roper)
v13: - Moved max_data_rate in bw check to closer scope(Ville Syrjälä)
- Changed comment for zero new_mask in qgv points masking function
to better reflect reality(Ville Syrjälä)
- Simplified bit mask operation in qgv points masking function
(Ville Syrjälä)
- Moved intel_qgv_points_mask closer to gen11 SAGV disabling,
however this still can't be under modeset condition(Ville Syrjälä)
- Packed qgv_points_mask as u8 and moved closer to pipe_sagv_mask
(Ville Syrjälä)
- Extracted PCode changes to separate patch.(Ville Syrjälä)
- Now treat num_planes 0 same as 1 to avoid confusion and
returning max_bw as 0, which would prevent choosing QGV
point having max bandwidth in case if SAGV is not allowed,
as per BSpec(Ville Syrjälä)
- Do the actual qgv_points_mask swap in the same place as
all other global state parts like cdclk are swapped.
In the next patch, this all will be moved to bw state as
global state, once new global state patch series from Ville
lands
v14: - Now using global state to serialize access to qgv points
- Added global state locking back, otherwise we seem to read
bw state in a wrong way.
v15: - Added TODO comment for near atomic global state locking in
bw code.
v16: - Fixed intel_atomic_bw_* functions to be intel_bw_* as discussed
with Jani Nikula.
- Take bw_state_changed flag into use.
v17: - Moved qgv point related manipulations next to SAGV code, as
those are semantically related(Ville Syrjälä)
- Renamed those into intel_sagv_(pre)|(post)_plane_update
(Ville Syrjälä)
v18: - Move sagv related calls from commit tail into
intel_sagv_(pre)|(post)_plane_update(Ville Syrjälä)
v19: - Use intel_atomic_get_bw_(old)|(new)_state which is intended
for commit tail stage.
v20: - Return max bandwidth for 0 planes(Ville)
- Constify old_bw_state in bw_atomic_check(Ville)
- Removed some debugs(Ville)
- Added data rate to debug print when no QGV points(Ville)
- Removed some comments(Ville)
v21, v22, v23: - Fixed rebase conflict
v24: - Changed PCode mask to use ICL_ prefix
v25: - Resolved rebase conflict
v26: - Removed redundant NULL checks(Ville)
- Removed redundant error prints(Ville)
v27: - Use device specific drm_err(Ville)
- Fixed parenthesis ident reported by checkpatch
Line over 100 warns to be fixed together with
existing code style.
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Ville Syrjälä <ville.syrjala@intel.com>
Cc: James Ausmus <james.ausmus@intel.com>
[vsyrjala: Drop duplicate intel_sagv_{pre,post}_plane_update() prototypes
and drop unused NUM_SAGV_POINTS define]
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200514074853.9508-3-stanislav.lisovskiy@intel.com
2020-05-14 07:48:52 +00:00
|
|
|
/*
|
|
|
|
* We need to know which qgv point gives us
|
|
|
|
* maximum bandwidth in order to disable SAGV
|
|
|
|
* if we find that we exceed SAGV block time
|
|
|
|
* with watermarks. By that moment we already
|
|
|
|
* have those, as it is calculated earlier in
|
|
|
|
* intel_atomic_check,
|
|
|
|
*/
|
|
|
|
if (max_data_rate > max_bw) {
|
|
|
|
max_bw_point = i;
|
|
|
|
max_bw = max_data_rate;
|
|
|
|
}
|
|
|
|
if (max_data_rate >= data_rate)
|
2022-03-09 16:49:47 +00:00
|
|
|
qgv_points |= BIT(i);
|
drm/i915: Implement PSF GV point support
PSF GV points are an additional factor that can limit the
bandwidth available to display, separate from the traditional
QGV points. Whereas traditional QGV points represent possible
memory clock frequencies, PSF GV points reflect possible
frequencies of the memory fabric.
Switching between PSF GV points has the advantage of incurring
almost no memory access block time and thus does not need to be
accounted for in watermark calculations.
This patch adds support for those on top of regular QGV points.
Those are supposed to be used simultaneously, i.e we are always
at some QGV and some PSF GV point, based on the current video
mode requirements.
Bspec: 64631, 53998
v2: Seems that initial assumption made during ml conversation
was wrong, PCode rejects any masks containing points beyond
the ones returned, so even though BSpec says we have around
8 points theoretically, we can mask/unmask only those which
are returned, trying to manipulate those beyond causes a
failure from PCode. So switched back to generating mask
from 1 - num_qgv_points, where num_qgv_points is the actual
amount of points, advertised by PCode.
v3: - Extended restricted qgv point mask to 0xf, as we have now
3:2 bits for PSF GV points(Matt Roper)
- Replaced val2 with NULL from PCode request, since its not being
used(Matt Roper)
- Replaced %d to 0x%x for better readability(thanks for spotting)
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210531064845.4389-2-stanislav.lisovskiy@intel.com
2021-05-31 06:48:45 +00:00
|
|
|
|
drm/i915: Restrict qgv points which don't have enough bandwidth.
According to BSpec 53998, we should try to
restrict qgv points, which can't provide
enough bandwidth for desired display configuration.
Currently we are just comparing against all of
those and take minimum(worst case).
v2: Fixed wrong PCode reply mask, removed hardcoded
values.
v3: Forbid simultaneous legacy SAGV PCode requests and
restricting qgv points. Put the actual restriction
to commit function, added serialization(thanks to Ville)
to prevent commit being applied out of order in case of
nonblocking and/or nomodeset commits.
v4:
- Minor code refactoring, fixed few typos(thanks to James Ausmus)
- Change the naming of qgv point
masking/unmasking functions(James Ausmus).
- Simplify the masking/unmasking operation itself,
as we don't need to mask only single point per request(James Ausmus)
- Reject and stick to highest bandwidth point if SAGV
can't be enabled(BSpec)
v5:
- Add new mailbox reply codes, which seems to happen during boot
time for TGL and indicate that QGV setting is not yet available.
v6:
- Increase number of supported QGV points to be in sync with BSpec.
v7: - Rebased and resolved conflict to fix build failure.
- Fix NUM_QGV_POINTS to 8 and moved that to header file(James Ausmus)
v8: - Don't report an error if we can't restrict qgv points, as SAGV
can be disabled by BIOS, which is completely legal. So don't
make CI panic. Instead if we detect that there is only 1 QGV
point accessible just analyze if we can fit the required bandwidth
requirements, but no need in restricting.
v9: - Fix wrong QGV transition if we have 0 planes and no SAGV
simultaneously.
v10: - Fix CDCLK corruption, because of global state getting serialized
without modeset, which caused copying of non-calculated cdclk
to be copied to dev_priv(thanks to Ville for the hint).
v11: - Remove unneeded headers and spaces(Matthew Roper)
- Remove unneeded intel_qgv_info qi struct from bw check and zero
out the needed one(Matthew Roper)
- Changed QGV error message to have more clear meaning(Matthew Roper)
- Use state->modeset_set instead of any_ms(Matthew Roper)
- Moved NUM_SAGV_POINTS from i915_reg.h to i915_drv.h where it's used
- Keep using crtc_state->hw.active instead of .enable(Matthew Roper)
- Moved unrelated changes to other patch(using latency as parameter
for plane wm calculation, moved to SAGV refactoring patch)
v12: - Fix rebase conflict with own temporary SAGV/QGV fix.
- Remove unnecessary mask being zero check when unmasking
qgv points as this is completely legal(Matt Roper)
- Check if we are setting the same mask as already being set
in hardware to prevent error from PCode.
- Fix error message when restricting/unrestricting qgv points
to "mask/unmask" which sounds more accurate(Matt Roper)
- Move sagv status setting to icl_get_bw_info from atomic check
as this should be calculated only once.(Matt Roper)
- Edited comments for the case when we can't enable SAGV and
use only 1 QGV point with highest bandwidth to be more
understandable.(Matt Roper)
v13: - Moved max_data_rate in bw check to closer scope(Ville Syrjälä)
- Changed comment for zero new_mask in qgv points masking function
to better reflect reality(Ville Syrjälä)
- Simplified bit mask operation in qgv points masking function
(Ville Syrjälä)
- Moved intel_qgv_points_mask closer to gen11 SAGV disabling,
however this still can't be under modeset condition(Ville Syrjälä)
- Packed qgv_points_mask as u8 and moved closer to pipe_sagv_mask
(Ville Syrjälä)
- Extracted PCode changes to separate patch.(Ville Syrjälä)
- Now treat num_planes 0 same as 1 to avoid confusion and
returning max_bw as 0, which would prevent choosing QGV
point having max bandwidth in case if SAGV is not allowed,
as per BSpec(Ville Syrjälä)
- Do the actual qgv_points_mask swap in the same place as
all other global state parts like cdclk are swapped.
In the next patch, this all will be moved to bw state as
global state, once new global state patch series from Ville
lands
v14: - Now using global state to serialize access to qgv points
- Added global state locking back, otherwise we seem to read
bw state in a wrong way.
v15: - Added TODO comment for near atomic global state locking in
bw code.
v16: - Fixed intel_atomic_bw_* functions to be intel_bw_* as discussed
with Jani Nikula.
- Take bw_state_changed flag into use.
v17: - Moved qgv point related manipulations next to SAGV code, as
those are semantically related(Ville Syrjälä)
- Renamed those into intel_sagv_(pre)|(post)_plane_update
(Ville Syrjälä)
v18: - Move sagv related calls from commit tail into
intel_sagv_(pre)|(post)_plane_update(Ville Syrjälä)
v19: - Use intel_atomic_get_bw_(old)|(new)_state which is intended
for commit tail stage.
v20: - Return max bandwidth for 0 planes(Ville)
- Constify old_bw_state in bw_atomic_check(Ville)
- Removed some debugs(Ville)
- Added data rate to debug print when no QGV points(Ville)
- Removed some comments(Ville)
v21, v22, v23: - Fixed rebase conflict
v24: - Changed PCode mask to use ICL_ prefix
v25: - Resolved rebase conflict
v26: - Removed redundant NULL checks(Ville)
- Removed redundant error prints(Ville)
v27: - Use device specific drm_err(Ville)
- Fixed parenthesis ident reported by checkpatch
Line over 100 warns to be fixed together with
existing code style.
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Ville Syrjälä <ville.syrjala@intel.com>
Cc: James Ausmus <james.ausmus@intel.com>
[vsyrjala: Drop duplicate intel_sagv_{pre,post}_plane_update() prototypes
and drop unused NUM_SAGV_POINTS define]
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200514074853.9508-3-stanislav.lisovskiy@intel.com
2020-05-14 07:48:52 +00:00
|
|
|
drm_dbg_kms(&dev_priv->drm, "QGV point %d: max bw %d required %d\n",
|
|
|
|
i, max_data_rate, data_rate);
|
|
|
|
}
|
2019-05-24 15:36:14 +00:00
|
|
|
|
drm/i915: Implement PSF GV point support
PSF GV points are an additional factor that can limit the
bandwidth available to display, separate from the traditional
QGV points. Whereas traditional QGV points represent possible
memory clock frequencies, PSF GV points reflect possible
frequencies of the memory fabric.
Switching between PSF GV points has the advantage of incurring
almost no memory access block time and thus does not need to be
accounted for in watermark calculations.
This patch adds support for those on top of regular QGV points.
Those are supposed to be used simultaneously, i.e we are always
at some QGV and some PSF GV point, based on the current video
mode requirements.
Bspec: 64631, 53998
v2: Seems that initial assumption made during ml conversation
was wrong, PCode rejects any masks containing points beyond
the ones returned, so even though BSpec says we have around
8 points theoretically, we can mask/unmask only those which
are returned, trying to manipulate those beyond causes a
failure from PCode. So switched back to generating mask
from 1 - num_qgv_points, where num_qgv_points is the actual
amount of points, advertised by PCode.
v3: - Extended restricted qgv point mask to 0xf, as we have now
3:2 bits for PSF GV points(Matt Roper)
- Replaced val2 with NULL from PCode request, since its not being
used(Matt Roper)
- Replaced %d to 0x%x for better readability(thanks for spotting)
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210531064845.4389-2-stanislav.lisovskiy@intel.com
2021-05-31 06:48:45 +00:00
|
|
|
for (i = 0; i < num_psf_gv_points; i++) {
|
|
|
|
unsigned int max_data_rate = adl_psf_bw(dev_priv, i);
|
|
|
|
|
|
|
|
if (max_data_rate >= data_rate)
|
2022-03-09 16:49:47 +00:00
|
|
|
psf_points |= BIT(i);
|
drm/i915: Implement PSF GV point support
PSF GV points are an additional factor that can limit the
bandwidth available to display, separate from the traditional
QGV points. Whereas traditional QGV points represent possible
memory clock frequencies, PSF GV points reflect possible
frequencies of the memory fabric.
Switching between PSF GV points has the advantage of incurring
almost no memory access block time and thus does not need to be
accounted for in watermark calculations.
This patch adds support for those on top of regular QGV points.
Those are supposed to be used simultaneously, i.e we are always
at some QGV and some PSF GV point, based on the current video
mode requirements.
Bspec: 64631, 53998
v2: Seems that initial assumption made during ml conversation
was wrong, PCode rejects any masks containing points beyond
the ones returned, so even though BSpec says we have around
8 points theoretically, we can mask/unmask only those which
are returned, trying to manipulate those beyond causes a
failure from PCode. So switched back to generating mask
from 1 - num_qgv_points, where num_qgv_points is the actual
amount of points, advertised by PCode.
v3: - Extended restricted qgv point mask to 0xf, as we have now
3:2 bits for PSF GV points(Matt Roper)
- Replaced val2 with NULL from PCode request, since its not being
used(Matt Roper)
- Replaced %d to 0x%x for better readability(thanks for spotting)
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210531064845.4389-2-stanislav.lisovskiy@intel.com
2021-05-31 06:48:45 +00:00
|
|
|
|
|
|
|
drm_dbg_kms(&dev_priv->drm, "PSF GV point %d: max bw %d"
|
|
|
|
" required %d\n",
|
|
|
|
i, max_data_rate, data_rate);
|
|
|
|
}
|
|
|
|
|
drm/i915: Restrict qgv points which don't have enough bandwidth.
According to BSpec 53998, we should try to
restrict qgv points, which can't provide
enough bandwidth for desired display configuration.
Currently we are just comparing against all of
those and take minimum(worst case).
v2: Fixed wrong PCode reply mask, removed hardcoded
values.
v3: Forbid simultaneous legacy SAGV PCode requests and
restricting qgv points. Put the actual restriction
to commit function, added serialization(thanks to Ville)
to prevent commit being applied out of order in case of
nonblocking and/or nomodeset commits.
v4:
- Minor code refactoring, fixed few typos(thanks to James Ausmus)
- Change the naming of qgv point
masking/unmasking functions(James Ausmus).
- Simplify the masking/unmasking operation itself,
as we don't need to mask only single point per request(James Ausmus)
- Reject and stick to highest bandwidth point if SAGV
can't be enabled(BSpec)
v5:
- Add new mailbox reply codes, which seems to happen during boot
time for TGL and indicate that QGV setting is not yet available.
v6:
- Increase number of supported QGV points to be in sync with BSpec.
v7: - Rebased and resolved conflict to fix build failure.
- Fix NUM_QGV_POINTS to 8 and moved that to header file(James Ausmus)
v8: - Don't report an error if we can't restrict qgv points, as SAGV
can be disabled by BIOS, which is completely legal. So don't
make CI panic. Instead if we detect that there is only 1 QGV
point accessible just analyze if we can fit the required bandwidth
requirements, but no need in restricting.
v9: - Fix wrong QGV transition if we have 0 planes and no SAGV
simultaneously.
v10: - Fix CDCLK corruption, because of global state getting serialized
without modeset, which caused copying of non-calculated cdclk
to be copied to dev_priv(thanks to Ville for the hint).
v11: - Remove unneeded headers and spaces(Matthew Roper)
- Remove unneeded intel_qgv_info qi struct from bw check and zero
out the needed one(Matthew Roper)
- Changed QGV error message to have more clear meaning(Matthew Roper)
- Use state->modeset_set instead of any_ms(Matthew Roper)
- Moved NUM_SAGV_POINTS from i915_reg.h to i915_drv.h where it's used
- Keep using crtc_state->hw.active instead of .enable(Matthew Roper)
- Moved unrelated changes to other patch(using latency as parameter
for plane wm calculation, moved to SAGV refactoring patch)
v12: - Fix rebase conflict with own temporary SAGV/QGV fix.
- Remove unnecessary mask being zero check when unmasking
qgv points as this is completely legal(Matt Roper)
- Check if we are setting the same mask as already being set
in hardware to prevent error from PCode.
- Fix error message when restricting/unrestricting qgv points
to "mask/unmask" which sounds more accurate(Matt Roper)
- Move sagv status setting to icl_get_bw_info from atomic check
as this should be calculated only once.(Matt Roper)
- Edited comments for the case when we can't enable SAGV and
use only 1 QGV point with highest bandwidth to be more
understandable.(Matt Roper)
v13: - Moved max_data_rate in bw check to closer scope(Ville Syrjälä)
- Changed comment for zero new_mask in qgv points masking function
to better reflect reality(Ville Syrjälä)
- Simplified bit mask operation in qgv points masking function
(Ville Syrjälä)
- Moved intel_qgv_points_mask closer to gen11 SAGV disabling,
however this still can't be under modeset condition(Ville Syrjälä)
- Packed qgv_points_mask as u8 and moved closer to pipe_sagv_mask
(Ville Syrjälä)
- Extracted PCode changes to separate patch.(Ville Syrjälä)
- Now treat num_planes 0 same as 1 to avoid confusion and
returning max_bw as 0, which would prevent choosing QGV
point having max bandwidth in case if SAGV is not allowed,
as per BSpec(Ville Syrjälä)
- Do the actual qgv_points_mask swap in the same place as
all other global state parts like cdclk are swapped.
In the next patch, this all will be moved to bw state as
global state, once new global state patch series from Ville
lands
v14: - Now using global state to serialize access to qgv points
- Added global state locking back, otherwise we seem to read
bw state in a wrong way.
v15: - Added TODO comment for near atomic global state locking in
bw code.
v16: - Fixed intel_atomic_bw_* functions to be intel_bw_* as discussed
with Jani Nikula.
- Take bw_state_changed flag into use.
v17: - Moved qgv point related manipulations next to SAGV code, as
those are semantically related(Ville Syrjälä)
- Renamed those into intel_sagv_(pre)|(post)_plane_update
(Ville Syrjälä)
v18: - Move sagv related calls from commit tail into
intel_sagv_(pre)|(post)_plane_update(Ville Syrjälä)
v19: - Use intel_atomic_get_bw_(old)|(new)_state which is intended
for commit tail stage.
v20: - Return max bandwidth for 0 planes(Ville)
- Constify old_bw_state in bw_atomic_check(Ville)
- Removed some debugs(Ville)
- Added data rate to debug print when no QGV points(Ville)
- Removed some comments(Ville)
v21, v22, v23: - Fixed rebase conflict
v24: - Changed PCode mask to use ICL_ prefix
v25: - Resolved rebase conflict
v26: - Removed redundant NULL checks(Ville)
- Removed redundant error prints(Ville)
v27: - Use device specific drm_err(Ville)
- Fixed parenthesis ident reported by checkpatch
Line over 100 warns to be fixed together with
existing code style.
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Ville Syrjälä <ville.syrjala@intel.com>
Cc: James Ausmus <james.ausmus@intel.com>
[vsyrjala: Drop duplicate intel_sagv_{pre,post}_plane_update() prototypes
and drop unused NUM_SAGV_POINTS define]
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200514074853.9508-3-stanislav.lisovskiy@intel.com
2020-05-14 07:48:52 +00:00
|
|
|
/*
|
|
|
|
* BSpec states that we always should have at least one allowed point
|
|
|
|
* left, so if we couldn't - simply reject the configuration for obvious
|
|
|
|
* reasons.
|
|
|
|
*/
|
2022-03-09 16:49:47 +00:00
|
|
|
if (qgv_points == 0) {
|
drm/i915: Restrict qgv points which don't have enough bandwidth.
According to BSpec 53998, we should try to
restrict qgv points, which can't provide
enough bandwidth for desired display configuration.
Currently we are just comparing against all of
those and take minimum(worst case).
v2: Fixed wrong PCode reply mask, removed hardcoded
values.
v3: Forbid simultaneous legacy SAGV PCode requests and
restricting qgv points. Put the actual restriction
to commit function, added serialization(thanks to Ville)
to prevent commit being applied out of order in case of
nonblocking and/or nomodeset commits.
v4:
- Minor code refactoring, fixed few typos(thanks to James Ausmus)
- Change the naming of qgv point
masking/unmasking functions(James Ausmus).
- Simplify the masking/unmasking operation itself,
as we don't need to mask only single point per request(James Ausmus)
- Reject and stick to highest bandwidth point if SAGV
can't be enabled(BSpec)
v5:
- Add new mailbox reply codes, which seems to happen during boot
time for TGL and indicate that QGV setting is not yet available.
v6:
- Increase number of supported QGV points to be in sync with BSpec.
v7: - Rebased and resolved conflict to fix build failure.
- Fix NUM_QGV_POINTS to 8 and moved that to header file(James Ausmus)
v8: - Don't report an error if we can't restrict qgv points, as SAGV
can be disabled by BIOS, which is completely legal. So don't
make CI panic. Instead if we detect that there is only 1 QGV
point accessible just analyze if we can fit the required bandwidth
requirements, but no need in restricting.
v9: - Fix wrong QGV transition if we have 0 planes and no SAGV
simultaneously.
v10: - Fix CDCLK corruption, because of global state getting serialized
without modeset, which caused copying of non-calculated cdclk
to be copied to dev_priv(thanks to Ville for the hint).
v11: - Remove unneeded headers and spaces(Matthew Roper)
- Remove unneeded intel_qgv_info qi struct from bw check and zero
out the needed one(Matthew Roper)
- Changed QGV error message to have more clear meaning(Matthew Roper)
- Use state->modeset_set instead of any_ms(Matthew Roper)
- Moved NUM_SAGV_POINTS from i915_reg.h to i915_drv.h where it's used
- Keep using crtc_state->hw.active instead of .enable(Matthew Roper)
- Moved unrelated changes to other patch(using latency as parameter
for plane wm calculation, moved to SAGV refactoring patch)
v12: - Fix rebase conflict with own temporary SAGV/QGV fix.
- Remove unnecessary mask being zero check when unmasking
qgv points as this is completely legal(Matt Roper)
- Check if we are setting the same mask as already being set
in hardware to prevent error from PCode.
- Fix error message when restricting/unrestricting qgv points
to "mask/unmask" which sounds more accurate(Matt Roper)
- Move sagv status setting to icl_get_bw_info from atomic check
as this should be calculated only once.(Matt Roper)
- Edited comments for the case when we can't enable SAGV and
use only 1 QGV point with highest bandwidth to be more
understandable.(Matt Roper)
v13: - Moved max_data_rate in bw check to closer scope(Ville Syrjälä)
- Changed comment for zero new_mask in qgv points masking function
to better reflect reality(Ville Syrjälä)
- Simplified bit mask operation in qgv points masking function
(Ville Syrjälä)
- Moved intel_qgv_points_mask closer to gen11 SAGV disabling,
however this still can't be under modeset condition(Ville Syrjälä)
- Packed qgv_points_mask as u8 and moved closer to pipe_sagv_mask
(Ville Syrjälä)
- Extracted PCode changes to separate patch.(Ville Syrjälä)
- Now treat num_planes 0 same as 1 to avoid confusion and
returning max_bw as 0, which would prevent choosing QGV
point having max bandwidth in case if SAGV is not allowed,
as per BSpec(Ville Syrjälä)
- Do the actual qgv_points_mask swap in the same place as
all other global state parts like cdclk are swapped.
In the next patch, this all will be moved to bw state as
global state, once new global state patch series from Ville
lands
v14: - Now using global state to serialize access to qgv points
- Added global state locking back, otherwise we seem to read
bw state in a wrong way.
v15: - Added TODO comment for near atomic global state locking in
bw code.
v16: - Fixed intel_atomic_bw_* functions to be intel_bw_* as discussed
with Jani Nikula.
- Take bw_state_changed flag into use.
v17: - Moved qgv point related manipulations next to SAGV code, as
those are semantically related(Ville Syrjälä)
- Renamed those into intel_sagv_(pre)|(post)_plane_update
(Ville Syrjälä)
v18: - Move sagv related calls from commit tail into
intel_sagv_(pre)|(post)_plane_update(Ville Syrjälä)
v19: - Use intel_atomic_get_bw_(old)|(new)_state which is intended
for commit tail stage.
v20: - Return max bandwidth for 0 planes(Ville)
- Constify old_bw_state in bw_atomic_check(Ville)
- Removed some debugs(Ville)
- Added data rate to debug print when no QGV points(Ville)
- Removed some comments(Ville)
v21, v22, v23: - Fixed rebase conflict
v24: - Changed PCode mask to use ICL_ prefix
v25: - Resolved rebase conflict
v26: - Removed redundant NULL checks(Ville)
- Removed redundant error prints(Ville)
v27: - Use device specific drm_err(Ville)
- Fixed parenthesis ident reported by checkpatch
Line over 100 warns to be fixed together with
existing code style.
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Ville Syrjälä <ville.syrjala@intel.com>
Cc: James Ausmus <james.ausmus@intel.com>
[vsyrjala: Drop duplicate intel_sagv_{pre,post}_plane_update() prototypes
and drop unused NUM_SAGV_POINTS define]
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200514074853.9508-3-stanislav.lisovskiy@intel.com
2020-05-14 07:48:52 +00:00
|
|
|
drm_dbg_kms(&dev_priv->drm, "No QGV points provide sufficient memory"
|
|
|
|
" bandwidth %d for display configuration(%d active planes).\n",
|
|
|
|
data_rate, num_active_planes);
|
2019-05-24 15:36:14 +00:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2022-03-09 16:49:47 +00:00
|
|
|
if (num_psf_gv_points > 0 && psf_points == 0) {
|
|
|
|
drm_dbg_kms(&dev_priv->drm, "No PSF GV points provide sufficient memory"
|
|
|
|
" bandwidth %d for display configuration(%d active planes).\n",
|
|
|
|
data_rate, num_active_planes);
|
|
|
|
return -EINVAL;
|
drm/i915: Implement PSF GV point support
PSF GV points are an additional factor that can limit the
bandwidth available to display, separate from the traditional
QGV points. Whereas traditional QGV points represent possible
memory clock frequencies, PSF GV points reflect possible
frequencies of the memory fabric.
Switching between PSF GV points has the advantage of incurring
almost no memory access block time and thus does not need to be
accounted for in watermark calculations.
This patch adds support for those on top of regular QGV points.
Those are supposed to be used simultaneously, i.e we are always
at some QGV and some PSF GV point, based on the current video
mode requirements.
Bspec: 64631, 53998
v2: Seems that initial assumption made during ml conversation
was wrong, PCode rejects any masks containing points beyond
the ones returned, so even though BSpec says we have around
8 points theoretically, we can mask/unmask only those which
are returned, trying to manipulate those beyond causes a
failure from PCode. So switched back to generating mask
from 1 - num_qgv_points, where num_qgv_points is the actual
amount of points, advertised by PCode.
v3: - Extended restricted qgv point mask to 0xf, as we have now
3:2 bits for PSF GV points(Matt Roper)
- Replaced val2 with NULL from PCode request, since its not being
used(Matt Roper)
- Replaced %d to 0x%x for better readability(thanks for spotting)
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210531064845.4389-2-stanislav.lisovskiy@intel.com
2021-05-31 06:48:45 +00:00
|
|
|
}
|
|
|
|
|
drm/i915: Restrict qgv points which don't have enough bandwidth.
According to BSpec 53998, we should try to
restrict qgv points, which can't provide
enough bandwidth for desired display configuration.
Currently we are just comparing against all of
those and take minimum(worst case).
v2: Fixed wrong PCode reply mask, removed hardcoded
values.
v3: Forbid simultaneous legacy SAGV PCode requests and
restricting qgv points. Put the actual restriction
to commit function, added serialization(thanks to Ville)
to prevent commit being applied out of order in case of
nonblocking and/or nomodeset commits.
v4:
- Minor code refactoring, fixed few typos(thanks to James Ausmus)
- Change the naming of qgv point
masking/unmasking functions(James Ausmus).
- Simplify the masking/unmasking operation itself,
as we don't need to mask only single point per request(James Ausmus)
- Reject and stick to highest bandwidth point if SAGV
can't be enabled(BSpec)
v5:
- Add new mailbox reply codes, which seems to happen during boot
time for TGL and indicate that QGV setting is not yet available.
v6:
- Increase number of supported QGV points to be in sync with BSpec.
v7: - Rebased and resolved conflict to fix build failure.
- Fix NUM_QGV_POINTS to 8 and moved that to header file(James Ausmus)
v8: - Don't report an error if we can't restrict qgv points, as SAGV
can be disabled by BIOS, which is completely legal. So don't
make CI panic. Instead if we detect that there is only 1 QGV
point accessible just analyze if we can fit the required bandwidth
requirements, but no need in restricting.
v9: - Fix wrong QGV transition if we have 0 planes and no SAGV
simultaneously.
v10: - Fix CDCLK corruption, because of global state getting serialized
without modeset, which caused copying of non-calculated cdclk
to be copied to dev_priv(thanks to Ville for the hint).
v11: - Remove unneeded headers and spaces(Matthew Roper)
- Remove unneeded intel_qgv_info qi struct from bw check and zero
out the needed one(Matthew Roper)
- Changed QGV error message to have more clear meaning(Matthew Roper)
- Use state->modeset_set instead of any_ms(Matthew Roper)
- Moved NUM_SAGV_POINTS from i915_reg.h to i915_drv.h where it's used
- Keep using crtc_state->hw.active instead of .enable(Matthew Roper)
- Moved unrelated changes to other patch(using latency as parameter
for plane wm calculation, moved to SAGV refactoring patch)
v12: - Fix rebase conflict with own temporary SAGV/QGV fix.
- Remove unnecessary mask being zero check when unmasking
qgv points as this is completely legal(Matt Roper)
- Check if we are setting the same mask as already being set
in hardware to prevent error from PCode.
- Fix error message when restricting/unrestricting qgv points
to "mask/unmask" which sounds more accurate(Matt Roper)
- Move sagv status setting to icl_get_bw_info from atomic check
as this should be calculated only once.(Matt Roper)
- Edited comments for the case when we can't enable SAGV and
use only 1 QGV point with highest bandwidth to be more
understandable.(Matt Roper)
v13: - Moved max_data_rate in bw check to closer scope(Ville Syrjälä)
- Changed comment for zero new_mask in qgv points masking function
to better reflect reality(Ville Syrjälä)
- Simplified bit mask operation in qgv points masking function
(Ville Syrjälä)
- Moved intel_qgv_points_mask closer to gen11 SAGV disabling,
however this still can't be under modeset condition(Ville Syrjälä)
- Packed qgv_points_mask as u8 and moved closer to pipe_sagv_mask
(Ville Syrjälä)
- Extracted PCode changes to separate patch.(Ville Syrjälä)
- Now treat num_planes 0 same as 1 to avoid confusion and
returning max_bw as 0, which would prevent choosing QGV
point having max bandwidth in case if SAGV is not allowed,
as per BSpec(Ville Syrjälä)
- Do the actual qgv_points_mask swap in the same place as
all other global state parts like cdclk are swapped.
In the next patch, this all will be moved to bw state as
global state, once new global state patch series from Ville
lands
v14: - Now using global state to serialize access to qgv points
- Added global state locking back, otherwise we seem to read
bw state in a wrong way.
v15: - Added TODO comment for near atomic global state locking in
bw code.
v16: - Fixed intel_atomic_bw_* functions to be intel_bw_* as discussed
with Jani Nikula.
- Take bw_state_changed flag into use.
v17: - Moved qgv point related manipulations next to SAGV code, as
those are semantically related(Ville Syrjälä)
- Renamed those into intel_sagv_(pre)|(post)_plane_update
(Ville Syrjälä)
v18: - Move sagv related calls from commit tail into
intel_sagv_(pre)|(post)_plane_update(Ville Syrjälä)
v19: - Use intel_atomic_get_bw_(old)|(new)_state which is intended
for commit tail stage.
v20: - Return max bandwidth for 0 planes(Ville)
- Constify old_bw_state in bw_atomic_check(Ville)
- Removed some debugs(Ville)
- Added data rate to debug print when no QGV points(Ville)
- Removed some comments(Ville)
v21, v22, v23: - Fixed rebase conflict
v24: - Changed PCode mask to use ICL_ prefix
v25: - Resolved rebase conflict
v26: - Removed redundant NULL checks(Ville)
- Removed redundant error prints(Ville)
v27: - Use device specific drm_err(Ville)
- Fixed parenthesis ident reported by checkpatch
Line over 100 warns to be fixed together with
existing code style.
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Ville Syrjälä <ville.syrjala@intel.com>
Cc: James Ausmus <james.ausmus@intel.com>
[vsyrjala: Drop duplicate intel_sagv_{pre,post}_plane_update() prototypes
and drop unused NUM_SAGV_POINTS define]
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200514074853.9508-3-stanislav.lisovskiy@intel.com
2020-05-14 07:48:52 +00:00
|
|
|
/*
|
|
|
|
* Leave only single point with highest bandwidth, if
|
|
|
|
* we can't enable SAGV due to the increased memory latency it may
|
|
|
|
* cause.
|
|
|
|
*/
|
|
|
|
if (!intel_can_enable_sagv(dev_priv, new_bw_state)) {
|
2022-03-09 16:49:47 +00:00
|
|
|
qgv_points = BIT(max_bw_point);
|
drm/i915: Restrict qgv points which don't have enough bandwidth.
According to BSpec 53998, we should try to
restrict qgv points, which can't provide
enough bandwidth for desired display configuration.
Currently we are just comparing against all of
those and take minimum(worst case).
v2: Fixed wrong PCode reply mask, removed hardcoded
values.
v3: Forbid simultaneous legacy SAGV PCode requests and
restricting qgv points. Put the actual restriction
to commit function, added serialization(thanks to Ville)
to prevent commit being applied out of order in case of
nonblocking and/or nomodeset commits.
v4:
- Minor code refactoring, fixed few typos(thanks to James Ausmus)
- Change the naming of qgv point
masking/unmasking functions(James Ausmus).
- Simplify the masking/unmasking operation itself,
as we don't need to mask only single point per request(James Ausmus)
- Reject and stick to highest bandwidth point if SAGV
can't be enabled(BSpec)
v5:
- Add new mailbox reply codes, which seems to happen during boot
time for TGL and indicate that QGV setting is not yet available.
v6:
- Increase number of supported QGV points to be in sync with BSpec.
v7: - Rebased and resolved conflict to fix build failure.
- Fix NUM_QGV_POINTS to 8 and moved that to header file(James Ausmus)
v8: - Don't report an error if we can't restrict qgv points, as SAGV
can be disabled by BIOS, which is completely legal. So don't
make CI panic. Instead if we detect that there is only 1 QGV
point accessible just analyze if we can fit the required bandwidth
requirements, but no need in restricting.
v9: - Fix wrong QGV transition if we have 0 planes and no SAGV
simultaneously.
v10: - Fix CDCLK corruption, because of global state getting serialized
without modeset, which caused copying of non-calculated cdclk
to be copied to dev_priv(thanks to Ville for the hint).
v11: - Remove unneeded headers and spaces(Matthew Roper)
- Remove unneeded intel_qgv_info qi struct from bw check and zero
out the needed one(Matthew Roper)
- Changed QGV error message to have more clear meaning(Matthew Roper)
- Use state->modeset_set instead of any_ms(Matthew Roper)
- Moved NUM_SAGV_POINTS from i915_reg.h to i915_drv.h where it's used
- Keep using crtc_state->hw.active instead of .enable(Matthew Roper)
- Moved unrelated changes to other patch(using latency as parameter
for plane wm calculation, moved to SAGV refactoring patch)
v12: - Fix rebase conflict with own temporary SAGV/QGV fix.
- Remove unnecessary mask being zero check when unmasking
qgv points as this is completely legal(Matt Roper)
- Check if we are setting the same mask as already being set
in hardware to prevent error from PCode.
- Fix error message when restricting/unrestricting qgv points
to "mask/unmask" which sounds more accurate(Matt Roper)
- Move sagv status setting to icl_get_bw_info from atomic check
as this should be calculated only once.(Matt Roper)
- Edited comments for the case when we can't enable SAGV and
use only 1 QGV point with highest bandwidth to be more
understandable.(Matt Roper)
v13: - Moved max_data_rate in bw check to closer scope(Ville Syrjälä)
- Changed comment for zero new_mask in qgv points masking function
to better reflect reality(Ville Syrjälä)
- Simplified bit mask operation in qgv points masking function
(Ville Syrjälä)
- Moved intel_qgv_points_mask closer to gen11 SAGV disabling,
however this still can't be under modeset condition(Ville Syrjälä)
- Packed qgv_points_mask as u8 and moved closer to pipe_sagv_mask
(Ville Syrjälä)
- Extracted PCode changes to separate patch.(Ville Syrjälä)
- Now treat num_planes 0 same as 1 to avoid confusion and
returning max_bw as 0, which would prevent choosing QGV
point having max bandwidth in case if SAGV is not allowed,
as per BSpec(Ville Syrjälä)
- Do the actual qgv_points_mask swap in the same place as
all other global state parts like cdclk are swapped.
In the next patch, this all will be moved to bw state as
global state, once new global state patch series from Ville
lands
v14: - Now using global state to serialize access to qgv points
- Added global state locking back, otherwise we seem to read
bw state in a wrong way.
v15: - Added TODO comment for near atomic global state locking in
bw code.
v16: - Fixed intel_atomic_bw_* functions to be intel_bw_* as discussed
with Jani Nikula.
- Take bw_state_changed flag into use.
v17: - Moved qgv point related manipulations next to SAGV code, as
those are semantically related(Ville Syrjälä)
- Renamed those into intel_sagv_(pre)|(post)_plane_update
(Ville Syrjälä)
v18: - Move sagv related calls from commit tail into
intel_sagv_(pre)|(post)_plane_update(Ville Syrjälä)
v19: - Use intel_atomic_get_bw_(old)|(new)_state which is intended
for commit tail stage.
v20: - Return max bandwidth for 0 planes(Ville)
- Constify old_bw_state in bw_atomic_check(Ville)
- Removed some debugs(Ville)
- Added data rate to debug print when no QGV points(Ville)
- Removed some comments(Ville)
v21, v22, v23: - Fixed rebase conflict
v24: - Changed PCode mask to use ICL_ prefix
v25: - Resolved rebase conflict
v26: - Removed redundant NULL checks(Ville)
- Removed redundant error prints(Ville)
v27: - Use device specific drm_err(Ville)
- Fixed parenthesis ident reported by checkpatch
Line over 100 warns to be fixed together with
existing code style.
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Ville Syrjälä <ville.syrjala@intel.com>
Cc: James Ausmus <james.ausmus@intel.com>
[vsyrjala: Drop duplicate intel_sagv_{pre,post}_plane_update() prototypes
and drop unused NUM_SAGV_POINTS define]
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200514074853.9508-3-stanislav.lisovskiy@intel.com
2020-05-14 07:48:52 +00:00
|
|
|
drm_dbg_kms(&dev_priv->drm, "No SAGV, using single QGV point %d\n",
|
|
|
|
max_bw_point);
|
|
|
|
}
|
2022-03-09 16:49:47 +00:00
|
|
|
|
drm/i915: Restrict qgv points which don't have enough bandwidth.
According to BSpec 53998, we should try to
restrict qgv points, which can't provide
enough bandwidth for desired display configuration.
Currently we are just comparing against all of
those and take minimum(worst case).
v2: Fixed wrong PCode reply mask, removed hardcoded
values.
v3: Forbid simultaneous legacy SAGV PCode requests and
restricting qgv points. Put the actual restriction
to commit function, added serialization(thanks to Ville)
to prevent commit being applied out of order in case of
nonblocking and/or nomodeset commits.
v4:
- Minor code refactoring, fixed few typos(thanks to James Ausmus)
- Change the naming of qgv point
masking/unmasking functions(James Ausmus).
- Simplify the masking/unmasking operation itself,
as we don't need to mask only single point per request(James Ausmus)
- Reject and stick to highest bandwidth point if SAGV
can't be enabled(BSpec)
v5:
- Add new mailbox reply codes, which seems to happen during boot
time for TGL and indicate that QGV setting is not yet available.
v6:
- Increase number of supported QGV points to be in sync with BSpec.
v7: - Rebased and resolved conflict to fix build failure.
- Fix NUM_QGV_POINTS to 8 and moved that to header file(James Ausmus)
v8: - Don't report an error if we can't restrict qgv points, as SAGV
can be disabled by BIOS, which is completely legal. So don't
make CI panic. Instead if we detect that there is only 1 QGV
point accessible just analyze if we can fit the required bandwidth
requirements, but no need in restricting.
v9: - Fix wrong QGV transition if we have 0 planes and no SAGV
simultaneously.
v10: - Fix CDCLK corruption, because of global state getting serialized
without modeset, which caused copying of non-calculated cdclk
to be copied to dev_priv(thanks to Ville for the hint).
v11: - Remove unneeded headers and spaces(Matthew Roper)
- Remove unneeded intel_qgv_info qi struct from bw check and zero
out the needed one(Matthew Roper)
- Changed QGV error message to have more clear meaning(Matthew Roper)
- Use state->modeset_set instead of any_ms(Matthew Roper)
- Moved NUM_SAGV_POINTS from i915_reg.h to i915_drv.h where it's used
- Keep using crtc_state->hw.active instead of .enable(Matthew Roper)
- Moved unrelated changes to other patch(using latency as parameter
for plane wm calculation, moved to SAGV refactoring patch)
v12: - Fix rebase conflict with own temporary SAGV/QGV fix.
- Remove unnecessary mask being zero check when unmasking
qgv points as this is completely legal(Matt Roper)
- Check if we are setting the same mask as already being set
in hardware to prevent error from PCode.
- Fix error message when restricting/unrestricting qgv points
to "mask/unmask" which sounds more accurate(Matt Roper)
- Move sagv status setting to icl_get_bw_info from atomic check
as this should be calculated only once.(Matt Roper)
- Edited comments for the case when we can't enable SAGV and
use only 1 QGV point with highest bandwidth to be more
understandable.(Matt Roper)
v13: - Moved max_data_rate in bw check to closer scope(Ville Syrjälä)
- Changed comment for zero new_mask in qgv points masking function
to better reflect reality(Ville Syrjälä)
- Simplified bit mask operation in qgv points masking function
(Ville Syrjälä)
- Moved intel_qgv_points_mask closer to gen11 SAGV disabling,
however this still can't be under modeset condition(Ville Syrjälä)
- Packed qgv_points_mask as u8 and moved closer to pipe_sagv_mask
(Ville Syrjälä)
- Extracted PCode changes to separate patch.(Ville Syrjälä)
- Now treat num_planes 0 same as 1 to avoid confusion and
returning max_bw as 0, which would prevent choosing QGV
point having max bandwidth in case if SAGV is not allowed,
as per BSpec(Ville Syrjälä)
- Do the actual qgv_points_mask swap in the same place as
all other global state parts like cdclk are swapped.
In the next patch, this all will be moved to bw state as
global state, once new global state patch series from Ville
lands
v14: - Now using global state to serialize access to qgv points
- Added global state locking back, otherwise we seem to read
bw state in a wrong way.
v15: - Added TODO comment for near atomic global state locking in
bw code.
v16: - Fixed intel_atomic_bw_* functions to be intel_bw_* as discussed
with Jani Nikula.
- Take bw_state_changed flag into use.
v17: - Moved qgv point related manipulations next to SAGV code, as
those are semantically related(Ville Syrjälä)
- Renamed those into intel_sagv_(pre)|(post)_plane_update
(Ville Syrjälä)
v18: - Move sagv related calls from commit tail into
intel_sagv_(pre)|(post)_plane_update(Ville Syrjälä)
v19: - Use intel_atomic_get_bw_(old)|(new)_state which is intended
for commit tail stage.
v20: - Return max bandwidth for 0 planes(Ville)
- Constify old_bw_state in bw_atomic_check(Ville)
- Removed some debugs(Ville)
- Added data rate to debug print when no QGV points(Ville)
- Removed some comments(Ville)
v21, v22, v23: - Fixed rebase conflict
v24: - Changed PCode mask to use ICL_ prefix
v25: - Resolved rebase conflict
v26: - Removed redundant NULL checks(Ville)
- Removed redundant error prints(Ville)
v27: - Use device specific drm_err(Ville)
- Fixed parenthesis ident reported by checkpatch
Line over 100 warns to be fixed together with
existing code style.
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Ville Syrjälä <ville.syrjala@intel.com>
Cc: James Ausmus <james.ausmus@intel.com>
[vsyrjala: Drop duplicate intel_sagv_{pre,post}_plane_update() prototypes
and drop unused NUM_SAGV_POINTS define]
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200514074853.9508-3-stanislav.lisovskiy@intel.com
2020-05-14 07:48:52 +00:00
|
|
|
/*
|
|
|
|
* We store the ones which need to be masked as that is what PCode
|
|
|
|
* actually accepts as a parameter.
|
|
|
|
*/
|
2022-03-09 16:49:47 +00:00
|
|
|
new_bw_state->qgv_points_mask =
|
2022-03-09 16:49:48 +00:00
|
|
|
~(ICL_PCODE_REQ_QGV_PT(qgv_points) |
|
|
|
|
ADLS_PCODE_REQ_PSF_PT(psf_points)) &
|
2022-02-18 06:40:38 +00:00
|
|
|
icl_qgv_points_mask(dev_priv);
|
drm/i915: Restrict qgv points which don't have enough bandwidth.
According to BSpec 53998, we should try to
restrict qgv points, which can't provide
enough bandwidth for desired display configuration.
Currently we are just comparing against all of
those and take minimum(worst case).
v2: Fixed wrong PCode reply mask, removed hardcoded
values.
v3: Forbid simultaneous legacy SAGV PCode requests and
restricting qgv points. Put the actual restriction
to commit function, added serialization(thanks to Ville)
to prevent commit being applied out of order in case of
nonblocking and/or nomodeset commits.
v4:
- Minor code refactoring, fixed few typos(thanks to James Ausmus)
- Change the naming of qgv point
masking/unmasking functions(James Ausmus).
- Simplify the masking/unmasking operation itself,
as we don't need to mask only single point per request(James Ausmus)
- Reject and stick to highest bandwidth point if SAGV
can't be enabled(BSpec)
v5:
- Add new mailbox reply codes, which seems to happen during boot
time for TGL and indicate that QGV setting is not yet available.
v6:
- Increase number of supported QGV points to be in sync with BSpec.
v7: - Rebased and resolved conflict to fix build failure.
- Fix NUM_QGV_POINTS to 8 and moved that to header file(James Ausmus)
v8: - Don't report an error if we can't restrict qgv points, as SAGV
can be disabled by BIOS, which is completely legal. So don't
make CI panic. Instead if we detect that there is only 1 QGV
point accessible just analyze if we can fit the required bandwidth
requirements, but no need in restricting.
v9: - Fix wrong QGV transition if we have 0 planes and no SAGV
simultaneously.
v10: - Fix CDCLK corruption, because of global state getting serialized
without modeset, which caused copying of non-calculated cdclk
to be copied to dev_priv(thanks to Ville for the hint).
v11: - Remove unneeded headers and spaces(Matthew Roper)
- Remove unneeded intel_qgv_info qi struct from bw check and zero
out the needed one(Matthew Roper)
- Changed QGV error message to have more clear meaning(Matthew Roper)
- Use state->modeset_set instead of any_ms(Matthew Roper)
- Moved NUM_SAGV_POINTS from i915_reg.h to i915_drv.h where it's used
- Keep using crtc_state->hw.active instead of .enable(Matthew Roper)
- Moved unrelated changes to other patch(using latency as parameter
for plane wm calculation, moved to SAGV refactoring patch)
v12: - Fix rebase conflict with own temporary SAGV/QGV fix.
- Remove unnecessary mask being zero check when unmasking
qgv points as this is completely legal(Matt Roper)
- Check if we are setting the same mask as already being set
in hardware to prevent error from PCode.
- Fix error message when restricting/unrestricting qgv points
to "mask/unmask" which sounds more accurate(Matt Roper)
- Move sagv status setting to icl_get_bw_info from atomic check
as this should be calculated only once.(Matt Roper)
- Edited comments for the case when we can't enable SAGV and
use only 1 QGV point with highest bandwidth to be more
understandable.(Matt Roper)
v13: - Moved max_data_rate in bw check to closer scope(Ville Syrjälä)
- Changed comment for zero new_mask in qgv points masking function
to better reflect reality(Ville Syrjälä)
- Simplified bit mask operation in qgv points masking function
(Ville Syrjälä)
- Moved intel_qgv_points_mask closer to gen11 SAGV disabling,
however this still can't be under modeset condition(Ville Syrjälä)
- Packed qgv_points_mask as u8 and moved closer to pipe_sagv_mask
(Ville Syrjälä)
- Extracted PCode changes to separate patch.(Ville Syrjälä)
- Now treat num_planes 0 same as 1 to avoid confusion and
returning max_bw as 0, which would prevent choosing QGV
point having max bandwidth in case if SAGV is not allowed,
as per BSpec(Ville Syrjälä)
- Do the actual qgv_points_mask swap in the same place as
all other global state parts like cdclk are swapped.
In the next patch, this all will be moved to bw state as
global state, once new global state patch series from Ville
lands
v14: - Now using global state to serialize access to qgv points
- Added global state locking back, otherwise we seem to read
bw state in a wrong way.
v15: - Added TODO comment for near atomic global state locking in
bw code.
v16: - Fixed intel_atomic_bw_* functions to be intel_bw_* as discussed
with Jani Nikula.
- Take bw_state_changed flag into use.
v17: - Moved qgv point related manipulations next to SAGV code, as
those are semantically related(Ville Syrjälä)
- Renamed those into intel_sagv_(pre)|(post)_plane_update
(Ville Syrjälä)
v18: - Move sagv related calls from commit tail into
intel_sagv_(pre)|(post)_plane_update(Ville Syrjälä)
v19: - Use intel_atomic_get_bw_(old)|(new)_state which is intended
for commit tail stage.
v20: - Return max bandwidth for 0 planes(Ville)
- Constify old_bw_state in bw_atomic_check(Ville)
- Removed some debugs(Ville)
- Added data rate to debug print when no QGV points(Ville)
- Removed some comments(Ville)
v21, v22, v23: - Fixed rebase conflict
v24: - Changed PCode mask to use ICL_ prefix
v25: - Resolved rebase conflict
v26: - Removed redundant NULL checks(Ville)
- Removed redundant error prints(Ville)
v27: - Use device specific drm_err(Ville)
- Fixed parenthesis ident reported by checkpatch
Line over 100 warns to be fixed together with
existing code style.
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: Ville Syrjälä <ville.syrjala@intel.com>
Cc: James Ausmus <james.ausmus@intel.com>
[vsyrjala: Drop duplicate intel_sagv_{pre,post}_plane_update() prototypes
and drop unused NUM_SAGV_POINTS define]
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200514074853.9508-3-stanislav.lisovskiy@intel.com
2020-05-14 07:48:52 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If the actual mask had changed we need to make sure that
|
|
|
|
* the commits are serialized(in case this is a nomodeset, nonblocking)
|
|
|
|
*/
|
|
|
|
if (new_bw_state->qgv_points_mask != old_bw_state->qgv_points_mask) {
|
|
|
|
ret = intel_atomic_serialize_global_state(&new_bw_state->base);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2019-05-24 15:36:14 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-01-20 17:47:25 +00:00
|
|
|
static struct intel_global_state *
|
|
|
|
intel_bw_duplicate_state(struct intel_global_obj *obj)
|
2019-05-24 15:36:14 +00:00
|
|
|
{
|
|
|
|
struct intel_bw_state *state;
|
|
|
|
|
|
|
|
state = kmemdup(obj->state, sizeof(*state), GFP_KERNEL);
|
|
|
|
if (!state)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return &state->base;
|
|
|
|
}
|
|
|
|
|
2020-01-20 17:47:25 +00:00
|
|
|
static void intel_bw_destroy_state(struct intel_global_obj *obj,
|
|
|
|
struct intel_global_state *state)
|
2019-05-24 15:36:14 +00:00
|
|
|
{
|
|
|
|
kfree(state);
|
|
|
|
}
|
|
|
|
|
2020-01-20 17:47:25 +00:00
|
|
|
static const struct intel_global_state_funcs intel_bw_funcs = {
|
2019-05-24 15:36:14 +00:00
|
|
|
.atomic_duplicate_state = intel_bw_duplicate_state,
|
|
|
|
.atomic_destroy_state = intel_bw_destroy_state,
|
|
|
|
};
|
|
|
|
|
|
|
|
int intel_bw_init(struct drm_i915_private *dev_priv)
|
|
|
|
{
|
|
|
|
struct intel_bw_state *state;
|
|
|
|
|
|
|
|
state = kzalloc(sizeof(*state), GFP_KERNEL);
|
|
|
|
if (!state)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
2020-01-20 17:47:25 +00:00
|
|
|
intel_atomic_global_obj_init(dev_priv, &dev_priv->bw_obj,
|
|
|
|
&state->base, &intel_bw_funcs);
|
2019-05-24 15:36:14 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|