Commit 4c859574 authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-intel-fixes-2024-04-04' of...

Merge tag 'drm-intel-fixes-2024-04-04' of https://anongit.freedesktop.org/git/drm/drm-intel into drm-fixes

Display fixes:
- A few DisplayPort related fixes (Imre, Arun, Ankit, Ville)
- eDP PSR fixes (Jouni)

Core/GT fixes:
- Remove some VM space restrictions on older platforms (Andi)
- Disable automatic load CCS load balancing (Andi)
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/Zg7nSK5oTmWfKPPI@intel.com
parents a5b5ab33 99f85508
......@@ -118,6 +118,7 @@ gt-y += \
gt/intel_ggtt_fencing.o \
gt/intel_gt.o \
gt/intel_gt_buffer_pool.o \
gt/intel_gt_ccs_mode.o \
gt/intel_gt_clock_utils.o \
gt/intel_gt_debugfs.o \
gt/intel_gt_engines_debugfs.o \
......
......@@ -2709,15 +2709,6 @@ static void intel_set_pipe_src_size(const struct intel_crtc_state *crtc_state)
*/
intel_de_write(dev_priv, PIPESRC(pipe),
PIPESRC_WIDTH(width - 1) | PIPESRC_HEIGHT(height - 1));
if (!crtc_state->enable_psr2_su_region_et)
return;
width = drm_rect_width(&crtc_state->psr2_su_area);
height = drm_rect_height(&crtc_state->psr2_su_area);
intel_de_write(dev_priv, PIPE_SRCSZ_ERLY_TPT(pipe),
PIPESRC_WIDTH(width - 1) | PIPESRC_HEIGHT(height - 1));
}
static bool intel_pipe_is_interlaced(const struct intel_crtc_state *crtc_state)
......
......@@ -47,6 +47,7 @@ struct drm_printer;
#define HAS_DPT(i915) (DISPLAY_VER(i915) >= 13)
#define HAS_DSB(i915) (DISPLAY_INFO(i915)->has_dsb)
#define HAS_DSC(__i915) (DISPLAY_RUNTIME_INFO(__i915)->has_dsc)
#define HAS_DSC_MST(__i915) (DISPLAY_VER(__i915) >= 12 && HAS_DSC(__i915))
#define HAS_FBC(i915) (DISPLAY_RUNTIME_INFO(i915)->fbc_mask != 0)
#define HAS_FPGA_DBG_UNCLAIMED(i915) (DISPLAY_INFO(i915)->has_fpga_dbg)
#define HAS_FW_BLC(i915) (DISPLAY_VER(i915) >= 3)
......
......@@ -1423,6 +1423,8 @@ struct intel_crtc_state {
u32 psr2_man_track_ctl;
u32 pipe_srcsz_early_tpt;
struct drm_rect psr2_su_area;
/* Variable Refresh Rate state */
......
......@@ -499,7 +499,7 @@ intel_dp_set_source_rates(struct intel_dp *intel_dp)
/* The values must be in increasing order */
static const int mtl_rates[] = {
162000, 216000, 243000, 270000, 324000, 432000, 540000, 675000,
810000, 1000000, 1350000, 2000000,
810000, 1000000, 2000000,
};
static const int icl_rates[] = {
162000, 216000, 270000, 324000, 432000, 540000, 648000, 810000,
......@@ -1422,7 +1422,8 @@ static bool intel_dp_source_supports_fec(struct intel_dp *intel_dp,
if (DISPLAY_VER(dev_priv) >= 12)
return true;
if (DISPLAY_VER(dev_priv) == 11 && encoder->port != PORT_A)
if (DISPLAY_VER(dev_priv) == 11 && encoder->port != PORT_A &&
!intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DP_MST))
return true;
return false;
......@@ -1917,8 +1918,9 @@ icl_dsc_compute_link_config(struct intel_dp *intel_dp,
dsc_max_bpp = min(dsc_max_bpp, pipe_bpp - 1);
for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp); i++) {
if (valid_dsc_bpp[i] < dsc_min_bpp ||
valid_dsc_bpp[i] > dsc_max_bpp)
if (valid_dsc_bpp[i] < dsc_min_bpp)
continue;
if (valid_dsc_bpp[i] > dsc_max_bpp)
break;
ret = dsc_compute_link_config(intel_dp,
......@@ -6557,6 +6559,7 @@ intel_dp_init_connector(struct intel_digital_port *dig_port,
intel_connector->get_hw_state = intel_ddi_connector_get_hw_state;
else
intel_connector->get_hw_state = intel_connector_get_hw_state;
intel_connector->sync_state = intel_dp_connector_sync_state;
if (!intel_edp_init_connector(intel_dp, intel_connector)) {
intel_dp_aux_fini(intel_dp);
......
......@@ -1355,7 +1355,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector,
return 0;
}
if (DISPLAY_VER(dev_priv) >= 10 &&
if (HAS_DSC_MST(dev_priv) &&
drm_dp_sink_supports_dsc(intel_connector->dp.dsc_dpcd)) {
/*
* TBD pass the connector BPC,
......
......@@ -1994,6 +1994,7 @@ static void psr_force_hw_tracking_exit(struct intel_dp *intel_dp)
void intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
struct intel_encoder *encoder;
......@@ -2013,6 +2014,12 @@ void intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state *crtc_st
intel_de_write(dev_priv, PSR2_MAN_TRK_CTL(cpu_transcoder),
crtc_state->psr2_man_track_ctl);
if (!crtc_state->enable_psr2_su_region_et)
return;
intel_de_write(dev_priv, PIPE_SRCSZ_ERLY_TPT(crtc->pipe),
crtc_state->pipe_srcsz_early_tpt);
}
static void psr2_man_trk_ctl_calc(struct intel_crtc_state *crtc_state,
......@@ -2051,6 +2058,20 @@ static void psr2_man_trk_ctl_calc(struct intel_crtc_state *crtc_state,
crtc_state->psr2_man_track_ctl = val;
}
static u32 psr2_pipe_srcsz_early_tpt_calc(struct intel_crtc_state *crtc_state,
bool full_update)
{
int width, height;
if (!crtc_state->enable_psr2_su_region_et || full_update)
return 0;
width = drm_rect_width(&crtc_state->psr2_su_area);
height = drm_rect_height(&crtc_state->psr2_su_area);
return PIPESRC_WIDTH(width - 1) | PIPESRC_HEIGHT(height - 1);
}
static void clip_area_update(struct drm_rect *overlap_damage_area,
struct drm_rect *damage_area,
struct drm_rect *pipe_src)
......@@ -2095,21 +2116,36 @@ static void intel_psr2_sel_fetch_pipe_alignment(struct intel_crtc_state *crtc_st
* cursor fully when cursor is in SU area.
*/
static void
intel_psr2_sel_fetch_et_alignment(struct intel_crtc_state *crtc_state,
struct intel_plane_state *cursor_state)
intel_psr2_sel_fetch_et_alignment(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
struct drm_rect inter;
struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
struct intel_plane_state *new_plane_state;
struct intel_plane *plane;
int i;
if (!crtc_state->enable_psr2_su_region_et ||
!cursor_state->uapi.visible)
if (!crtc_state->enable_psr2_su_region_et)
return;
for_each_new_intel_plane_in_state(state, plane, new_plane_state, i) {
struct drm_rect inter;
if (new_plane_state->uapi.crtc != crtc_state->uapi.crtc)
continue;
if (plane->id != PLANE_CURSOR)
continue;
if (!new_plane_state->uapi.visible)
continue;
inter = crtc_state->psr2_su_area;
if (!drm_rect_intersect(&inter, &cursor_state->uapi.dst))
return;
if (!drm_rect_intersect(&inter, &new_plane_state->uapi.dst))
continue;
clip_area_update(&crtc_state->psr2_su_area, &cursor_state->uapi.dst,
clip_area_update(&crtc_state->psr2_su_area, &new_plane_state->uapi.dst,
&crtc_state->pipe_src);
}
}
/*
......@@ -2152,8 +2188,7 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
{
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
struct intel_plane_state *new_plane_state, *old_plane_state,
*cursor_plane_state = NULL;
struct intel_plane_state *new_plane_state, *old_plane_state;
struct intel_plane *plane;
bool full_update = false;
int i, ret;
......@@ -2238,13 +2273,6 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
damaged_area.x2 += new_plane_state->uapi.dst.x1 - src.x1;
clip_area_update(&crtc_state->psr2_su_area, &damaged_area, &crtc_state->pipe_src);
/*
* Cursor plane new state is stored to adjust su area to cover
* cursor are fully.
*/
if (plane->id == PLANE_CURSOR)
cursor_plane_state = new_plane_state;
}
/*
......@@ -2273,9 +2301,13 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
if (ret)
return ret;
/* Adjust su area to cover cursor fully as necessary */
if (cursor_plane_state)
intel_psr2_sel_fetch_et_alignment(crtc_state, cursor_plane_state);
/*
* Adjust su area to cover cursor fully as necessary (early
* transport). This needs to be done after
* drm_atomic_add_affected_planes to ensure visible cursor is added into
* affected planes even when cursor is not updated by itself.
*/
intel_psr2_sel_fetch_et_alignment(state, crtc);
intel_psr2_sel_fetch_pipe_alignment(crtc_state);
......@@ -2338,6 +2370,8 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
skip_sel_fetch_set_loop:
psr2_man_trk_ctl_calc(crtc_state, full_update);
crtc_state->pipe_srcsz_early_tpt =
psr2_pipe_srcsz_early_tpt_calc(crtc_state, full_update);
return 0;
}
......
......@@ -961,6 +961,9 @@ static int gen8_init_rsvd(struct i915_address_space *vm)
struct i915_vma *vma;
int ret;
if (!intel_gt_needs_wa_16018031267(vm->gt))
return 0;
/* The memory will be used only by GPU. */
obj = i915_gem_object_create_lmem(i915, PAGE_SIZE,
I915_BO_ALLOC_VOLATILE |
......
......@@ -908,6 +908,23 @@ static intel_engine_mask_t init_engine_mask(struct intel_gt *gt)
info->engine_mask &= ~BIT(GSC0);
}
/*
* Do not create the command streamer for CCS slices beyond the first.
* All the workload submitted to the first engine will be shared among
* all the slices.
*
* Once the user will be allowed to customize the CCS mode, then this
* check needs to be removed.
*/
if (IS_DG2(gt->i915)) {
u8 first_ccs = __ffs(CCS_MASK(gt));
/* Mask off all the CCS engine */
info->engine_mask &= ~GENMASK(CCS3, CCS0);
/* Put back in the first CCS engine */
info->engine_mask |= BIT(_CCS(first_ccs));
}
return info->engine_mask;
}
......
......@@ -1024,6 +1024,12 @@ enum i915_map_type intel_gt_coherent_map_type(struct intel_gt *gt,
return I915_MAP_WC;
}
bool intel_gt_needs_wa_16018031267(struct intel_gt *gt)
{
/* Wa_16018031267, Wa_16018063123 */
return IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 55), IP_VER(12, 71));
}
bool intel_gt_needs_wa_22016122933(struct intel_gt *gt)
{
return MEDIA_VER_FULL(gt->i915) == IP_VER(13, 0) && gt->type == GT_MEDIA;
......
......@@ -82,17 +82,18 @@ struct drm_printer;
##__VA_ARGS__); \
} while (0)
#define NEEDS_FASTCOLOR_BLT_WABB(engine) ( \
IS_GFX_GT_IP_RANGE(engine->gt, IP_VER(12, 55), IP_VER(12, 71)) && \
engine->class == COPY_ENGINE_CLASS && engine->instance == 0)
static inline bool gt_is_root(struct intel_gt *gt)
{
return !gt->info.id;
}
bool intel_gt_needs_wa_16018031267(struct intel_gt *gt);
bool intel_gt_needs_wa_22016122933(struct intel_gt *gt);
#define NEEDS_FASTCOLOR_BLT_WABB(engine) ( \
intel_gt_needs_wa_16018031267(engine->gt) && \
engine->class == COPY_ENGINE_CLASS && engine->instance == 0)
static inline struct intel_gt *uc_to_gt(struct intel_uc *uc)
{
return container_of(uc, struct intel_gt, uc);
......
// SPDX-License-Identifier: MIT
/*
* Copyright © 2024 Intel Corporation
*/
#include "i915_drv.h"
#include "intel_gt.h"
#include "intel_gt_ccs_mode.h"
#include "intel_gt_regs.h"
void intel_gt_apply_ccs_mode(struct intel_gt *gt)
{
int cslice;
u32 mode = 0;
int first_ccs = __ffs(CCS_MASK(gt));
if (!IS_DG2(gt->i915))
return;
/* Build the value for the fixed CCS load balancing */
for (cslice = 0; cslice < I915_MAX_CCS; cslice++) {
if (CCS_MASK(gt) & BIT(cslice))
/*
* If available, assign the cslice
* to the first available engine...
*/
mode |= XEHP_CCS_MODE_CSLICE(cslice, first_ccs);
else
/*
* ... otherwise, mark the cslice as
* unavailable if no CCS dispatches here
*/
mode |= XEHP_CCS_MODE_CSLICE(cslice,
XEHP_CCS_MODE_CSLICE_MASK);
}
intel_uncore_write(gt->uncore, XEHP_CCS_MODE, mode);
}
/* SPDX-License-Identifier: MIT */
/*
* Copyright © 2024 Intel Corporation
*/
#ifndef __INTEL_GT_CCS_MODE_H__
#define __INTEL_GT_CCS_MODE_H__
struct intel_gt;
void intel_gt_apply_ccs_mode(struct intel_gt *gt);
#endif /* __INTEL_GT_CCS_MODE_H__ */
......@@ -1477,8 +1477,14 @@
#define ECOBITS_PPGTT_CACHE4B (0 << 8)
#define GEN12_RCU_MODE _MMIO(0x14800)
#define XEHP_RCU_MODE_FIXED_SLICE_CCS_MODE REG_BIT(1)
#define GEN12_RCU_MODE_CCS_ENABLE REG_BIT(0)
#define XEHP_CCS_MODE _MMIO(0x14804)
#define XEHP_CCS_MODE_CSLICE_MASK REG_GENMASK(2, 0) /* CCS0-3 + rsvd */
#define XEHP_CCS_MODE_CSLICE_WIDTH ilog2(XEHP_CCS_MODE_CSLICE_MASK + 1)
#define XEHP_CCS_MODE_CSLICE(cslice, ccs) (ccs << (cslice * XEHP_CCS_MODE_CSLICE_WIDTH))
#define CHV_FUSE_GT _MMIO(VLV_GUNIT_BASE + 0x2168)
#define CHV_FGT_DISABLE_SS0 (1 << 10)
#define CHV_FGT_DISABLE_SS1 (1 << 11)
......
......@@ -10,6 +10,7 @@
#include "intel_engine_regs.h"
#include "intel_gpu_commands.h"
#include "intel_gt.h"
#include "intel_gt_ccs_mode.h"
#include "intel_gt_mcr.h"
#include "intel_gt_print.h"
#include "intel_gt_regs.h"
......@@ -51,7 +52,8 @@
* registers belonging to BCS, VCS or VECS should be implemented in
* xcs_engine_wa_init(). Workarounds for registers not belonging to a specific
* engine's MMIO range but that are part of of the common RCS/CCS reset domain
* should be implemented in general_render_compute_wa_init().
* should be implemented in general_render_compute_wa_init(). The settings
* about the CCS load balancing should be added in ccs_engine_wa_mode().
*
* - GT workarounds: the list of these WAs is applied whenever these registers
* revert to their default values: on GPU reset, suspend/resume [1]_, etc.
......@@ -2854,6 +2856,28 @@ add_render_compute_tuning_settings(struct intel_gt *gt,
wa_write_clr(wal, GEN8_GARBCNTL, GEN12_BUS_HASH_CTL_BIT_EXC);
}
static void ccs_engine_wa_mode(struct intel_engine_cs *engine, struct i915_wa_list *wal)
{
struct intel_gt *gt = engine->gt;
if (!IS_DG2(gt->i915))
return;
/*
* Wa_14019159160: This workaround, along with others, leads to
* significant challenges in utilizing load balancing among the
* CCS slices. Consequently, an architectural decision has been
* made to completely disable automatic CCS load balancing.
*/
wa_masked_en(wal, GEN12_RCU_MODE, XEHP_RCU_MODE_FIXED_SLICE_CCS_MODE);
/*
* After having disabled automatic load balancing we need to
* assign all slices to a single CCS. We will call it CCS mode 1
*/
intel_gt_apply_ccs_mode(gt);
}
/*
* The workarounds in this function apply to shared registers in
* the general render reset domain that aren't tied to a
......@@ -3004,8 +3028,10 @@ engine_init_workarounds(struct intel_engine_cs *engine, struct i915_wa_list *wal
* to a single RCS/CCS engine's workaround list since
* they're reset as part of the general render domain reset.
*/
if (engine->flags & I915_ENGINE_FIRST_RENDER_COMPUTE)
if (engine->flags & I915_ENGINE_FIRST_RENDER_COMPUTE) {
general_render_compute_wa_init(engine, wal);
ccs_engine_wa_mode(engine, wal);
}
if (engine->class == COMPUTE_CLASS)
ccs_engine_wa_init(engine, wal);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment