Skip to content

Commit

Permalink
drm/i915: Make sure we have enough memory bandwidth on ICL
Browse files Browse the repository at this point in the history
ICL has so many planes that it can easily exceed the maximum
effective memory bandwidth of the system. We must therefore check
that we don't exceed that limit.

The algorithm is very magic number heavy and lacks sufficient
explanation for now. We also have no sane way to query the
memory clock and timings, so we must rely on a combination of
raw readout from the memory controller and hardcoded assumptions.
The memory controller values obviously change as the system
jumps between the different SAGV points, so we try to stabilize
it first by disabling SAGV for the duration of the readout.

The utilized bandwidth is tracked via a device wide atomic
private object. That is actually not robust because we can't
afford to enforce strict global ordering between the pipes.
Thus I think I'll need to change this to simply chop up the
available bandwidth between all the active pipes. Each pipe
can then do whatever it wants as long as it doesn't exceed
its budget. That scheme will also require that we assume that
any number of planes could be active at any time.

TODO: make it robust and deal with all the open questions

v2: Sleep longer after disabling SAGV
v3: Poll for the dclk to get raised (seen it take 250ms!)
    If the system has 2133MT/s memory then we pointlessly
    wait one full second :(
v4: Use the new pcode interface to get the qgv points rather
    that using hardcoded numbers
v5: Move the pcode stuff into intel_bw.c (Matt)
    s/intel_sagv_info/intel_qgv_info/
    Do the NV12/P010 as per spec for now (Matt)
    s/IS_ICELAKE/IS_GEN11/
v6: Ignore bandwidth limits if the pcode query fails

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Acked-by: Clint Taylor <Clinton.A.Taylor@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190524153614.32410-1-ville.syrjala@linux.intel.com
  • Loading branch information
vsyrjala committed May 27, 2019
1 parent d284d51 commit c457d9c
Show file tree
Hide file tree
Showing 10 changed files with 552 additions and 1 deletion.
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ i915-y += intel_audio.o \
intel_atomic.o \
intel_atomic_plane.o \
intel_bios.o \
intel_bw.o \
intel_cdclk.o \
intel_color.o \
intel_combo_phy.o \
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/i915/i915_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
#include "i915_vgpu.h"
#include "intel_acpi.h"
#include "intel_audio.h"
#include "intel_bw.h"
#include "intel_cdclk.h"
#include "intel_csr.h"
#include "intel_dp.h"
Expand Down Expand Up @@ -1657,6 +1658,7 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
*/
intel_get_dram_info(dev_priv);

intel_bw_init_hw(dev_priv);

return 0;

Expand Down
8 changes: 8 additions & 0 deletions drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
#include <drm/drm_cache.h>
#include <drm/drm_util.h>
#include <drm/drm_dsc.h>
#include <drm/drm_atomic.h>
#include <drm/drm_connector.h>
#include <drm/i915_mei_hdcp_interface.h>

Expand Down Expand Up @@ -1841,6 +1842,13 @@ struct drm_i915_private {
} type;
} dram_info;

struct intel_bw_info {
int num_planes;
int deratedbw[3];
} max_bw[6];

struct drm_private_obj bw_obj;

struct i915_runtime_pm runtime_pm;

struct {
Expand Down
3 changes: 3 additions & 0 deletions drivers/gpu/drm/i915/i915_reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -8780,6 +8780,9 @@ enum {
#define GEN6_PCODE_WRITE_MIN_FREQ_TABLE 0x8
#define GEN6_PCODE_READ_MIN_FREQ_TABLE 0x9
#define GEN6_READ_OC_PARAMS 0xc
#define ICL_PCODE_MEM_SUBSYSYSTEM_INFO 0xd
#define ICL_PCODE_MEM_SS_READ_GLOBAL_INFO (0x0 << 8)
#define ICL_PCODE_MEM_SS_READ_QGV_POINT_INFO(point) (((point) << 16) | (0x1 << 8))
#define GEN6_PCODE_READ_D_COMP 0x10
#define GEN6_PCODE_WRITE_D_COMP 0x11
#define HSW_PCODE_DE_WRITE_FREQ_REQ 0x17
Expand Down
27 changes: 27 additions & 0 deletions drivers/gpu/drm/i915/intel_atomic_plane.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,29 @@ intel_plane_destroy_state(struct drm_plane *plane,
drm_atomic_helper_plane_destroy_state(plane, state);
}

unsigned int intel_plane_data_rate(const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
{
const struct drm_framebuffer *fb = plane_state->base.fb;
unsigned int cpp;

if (!plane_state->base.visible)
return 0;

cpp = fb->format->cpp[0];

/*
* Based on HSD#:1408715493
* NV12 cpp == 4, P010 cpp == 8
*
* FIXME what is the logic behind this?
*/
if (fb->format->is_yuv && fb->format->num_planes > 1)
cpp *= 4;

return cpp * crtc_state->pixel_rate;
}

int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_state,
struct intel_crtc_state *new_crtc_state,
const struct intel_plane_state *old_plane_state,
Expand All @@ -125,6 +148,7 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
new_crtc_state->active_planes &= ~BIT(plane->id);
new_crtc_state->nv12_planes &= ~BIT(plane->id);
new_crtc_state->c8_planes &= ~BIT(plane->id);
new_crtc_state->data_rate[plane->id] = 0;
new_plane_state->base.visible = false;

if (!new_plane_state->base.crtc && !old_plane_state->base.crtc)
Expand All @@ -149,6 +173,9 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
if (new_plane_state->base.visible || old_plane_state->base.visible)
new_crtc_state->update_planes |= BIT(plane->id);

new_crtc_state->data_rate[plane->id] =
intel_plane_data_rate(new_crtc_state, new_plane_state);

return intel_plane_atomic_calc_changes(old_crtc_state,
&new_crtc_state->base,
old_plane_state,
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/i915/intel_atomic_plane.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ struct intel_plane_state;

extern const struct drm_plane_helper_funcs intel_plane_helper_funcs;

unsigned int intel_plane_data_rate(const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state);
void intel_update_plane(struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state);
Expand Down
Loading

0 comments on commit c457d9c

Please sign in to comment.