Skip to content

Commit ce7a3d2

Browse files
committed
Merge tag 'drm-intel-fixes-2023-03-30' of git://anongit.freedesktop.org/drm/drm-intel into drm-fixes
drm/i915 fixes for v6.3-rc5: - Fix PMU support by reusing functions with sysfs - Fix a number of issues related to color, PSR and arm/noarm - Fix state check related to ICL PHY ownership check in TC-cold state - Flush lmem contents after construction - Fix hibernate oops related to DPT BO - Fix perf stream error path wakeref balance Signed-off-by: Daniel Vetter <[email protected]> From: Jani Nikula <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
2 parents 197b6b6 + 5c95b2d commit ce7a3d2

File tree

13 files changed

+177
-42
lines changed

13 files changed

+177
-42
lines changed

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

Lines changed: 97 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ struct intel_color_funcs {
4646
* registers involved with the same commit.
4747
*/
4848
void (*color_commit_arm)(const struct intel_crtc_state *crtc_state);
49+
/*
50+
* Perform any extra tasks needed after all the
51+
* double buffered registers have been latched.
52+
*/
53+
void (*color_post_update)(const struct intel_crtc_state *crtc_state);
4954
/*
5055
* Load LUTs (and other single buffered color management
5156
* registers). Will (hopefully) be called during the vblank
@@ -614,9 +619,33 @@ static void ilk_lut_12p4_pack(struct drm_color_lut *entry, u32 ldw, u32 udw)
614619

615620
static void icl_color_commit_noarm(const struct intel_crtc_state *crtc_state)
616621
{
622+
/*
623+
* Despite Wa_1406463849, ICL no longer suffers from the SKL
624+
* DC5/PSR CSC black screen issue (see skl_color_commit_noarm()).
625+
* Possibly due to the extra sticky CSC arming
626+
* (see icl_color_post_update()).
627+
*
628+
* On TGL+ all CSC arming issues have been properly fixed.
629+
*/
617630
icl_load_csc_matrix(crtc_state);
618631
}
619632

633+
static void skl_color_commit_noarm(const struct intel_crtc_state *crtc_state)
634+
{
635+
/*
636+
* Possibly related to display WA #1184, SKL CSC loses the latched
637+
* CSC coeff/offset register values if the CSC registers are disarmed
638+
* between DC5 exit and PSR exit. This will cause the plane(s) to
639+
* output all black (until CSC_MODE is rearmed and properly latched).
640+
* Once PSR exit (and proper register latching) has occurred the
641+
* danger is over. Thus when PSR is enabled the CSC coeff/offset
642+
* register programming will be peformed from skl_color_commit_arm()
643+
* which is called after PSR exit.
644+
*/
645+
if (!crtc_state->has_psr)
646+
ilk_load_csc_matrix(crtc_state);
647+
}
648+
620649
static void ilk_color_commit_noarm(const struct intel_crtc_state *crtc_state)
621650
{
622651
ilk_load_csc_matrix(crtc_state);
@@ -659,6 +688,9 @@ static void skl_color_commit_arm(const struct intel_crtc_state *crtc_state)
659688
enum pipe pipe = crtc->pipe;
660689
u32 val = 0;
661690

691+
if (crtc_state->has_psr)
692+
ilk_load_csc_matrix(crtc_state);
693+
662694
/*
663695
* We don't (yet) allow userspace to control the pipe background color,
664696
* so force it to black, but apply pipe gamma and CSC appropriately
@@ -677,6 +709,47 @@ static void skl_color_commit_arm(const struct intel_crtc_state *crtc_state)
677709
crtc_state->csc_mode);
678710
}
679711

712+
static void icl_color_commit_arm(const struct intel_crtc_state *crtc_state)
713+
{
714+
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
715+
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
716+
enum pipe pipe = crtc->pipe;
717+
718+
/*
719+
* We don't (yet) allow userspace to control the pipe background color,
720+
* so force it to black.
721+
*/
722+
intel_de_write(i915, SKL_BOTTOM_COLOR(pipe), 0);
723+
724+
intel_de_write(i915, GAMMA_MODE(crtc->pipe),
725+
crtc_state->gamma_mode);
726+
727+
intel_de_write_fw(i915, PIPE_CSC_MODE(crtc->pipe),
728+
crtc_state->csc_mode);
729+
}
730+
731+
static void icl_color_post_update(const struct intel_crtc_state *crtc_state)
732+
{
733+
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
734+
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
735+
736+
/*
737+
* Despite Wa_1406463849, ICL CSC is no longer disarmed by
738+
* coeff/offset register *writes*. Instead, once CSC_MODE
739+
* is armed it stays armed, even after it has been latched.
740+
* Afterwards the coeff/offset registers become effectively
741+
* self-arming. That self-arming must be disabled before the
742+
* next icl_color_commit_noarm() tries to write the next set
743+
* of coeff/offset registers. Fortunately register *reads*
744+
* do still disarm the CSC. Naturally this must not be done
745+
* until the previously written CSC registers have actually
746+
* been latched.
747+
*
748+
* TGL+ no longer need this workaround.
749+
*/
750+
intel_de_read_fw(i915, PIPE_CSC_PREOFF_HI(crtc->pipe));
751+
}
752+
680753
static struct drm_property_blob *
681754
create_linear_lut(struct drm_i915_private *i915, int lut_size)
682755
{
@@ -1373,6 +1446,14 @@ void intel_color_commit_arm(const struct intel_crtc_state *crtc_state)
13731446
i915->display.funcs.color->color_commit_arm(crtc_state);
13741447
}
13751448

1449+
void intel_color_post_update(const struct intel_crtc_state *crtc_state)
1450+
{
1451+
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
1452+
1453+
if (i915->display.funcs.color->color_post_update)
1454+
i915->display.funcs.color->color_post_update(crtc_state);
1455+
}
1456+
13761457
void intel_color_prepare_commit(struct intel_crtc_state *crtc_state)
13771458
{
13781459
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
@@ -3064,18 +3145,28 @@ static const struct intel_color_funcs i9xx_color_funcs = {
30643145
.lut_equal = i9xx_lut_equal,
30653146
};
30663147

3148+
static const struct intel_color_funcs tgl_color_funcs = {
3149+
.color_check = icl_color_check,
3150+
.color_commit_noarm = icl_color_commit_noarm,
3151+
.color_commit_arm = icl_color_commit_arm,
3152+
.load_luts = icl_load_luts,
3153+
.read_luts = icl_read_luts,
3154+
.lut_equal = icl_lut_equal,
3155+
};
3156+
30673157
static const struct intel_color_funcs icl_color_funcs = {
30683158
.color_check = icl_color_check,
30693159
.color_commit_noarm = icl_color_commit_noarm,
3070-
.color_commit_arm = skl_color_commit_arm,
3160+
.color_commit_arm = icl_color_commit_arm,
3161+
.color_post_update = icl_color_post_update,
30713162
.load_luts = icl_load_luts,
30723163
.read_luts = icl_read_luts,
30733164
.lut_equal = icl_lut_equal,
30743165
};
30753166

30763167
static const struct intel_color_funcs glk_color_funcs = {
30773168
.color_check = glk_color_check,
3078-
.color_commit_noarm = ilk_color_commit_noarm,
3169+
.color_commit_noarm = skl_color_commit_noarm,
30793170
.color_commit_arm = skl_color_commit_arm,
30803171
.load_luts = glk_load_luts,
30813172
.read_luts = glk_read_luts,
@@ -3084,7 +3175,7 @@ static const struct intel_color_funcs glk_color_funcs = {
30843175

30853176
static const struct intel_color_funcs skl_color_funcs = {
30863177
.color_check = ivb_color_check,
3087-
.color_commit_noarm = ilk_color_commit_noarm,
3178+
.color_commit_noarm = skl_color_commit_noarm,
30883179
.color_commit_arm = skl_color_commit_arm,
30893180
.load_luts = bdw_load_luts,
30903181
.read_luts = bdw_read_luts,
@@ -3180,7 +3271,9 @@ void intel_color_init_hooks(struct drm_i915_private *i915)
31803271
else
31813272
i915->display.funcs.color = &i9xx_color_funcs;
31823273
} else {
3183-
if (DISPLAY_VER(i915) >= 11)
3274+
if (DISPLAY_VER(i915) >= 12)
3275+
i915->display.funcs.color = &tgl_color_funcs;
3276+
else if (DISPLAY_VER(i915) == 11)
31843277
i915->display.funcs.color = &icl_color_funcs;
31853278
else if (DISPLAY_VER(i915) == 10)
31863279
i915->display.funcs.color = &glk_color_funcs;

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ void intel_color_prepare_commit(struct intel_crtc_state *crtc_state);
2121
void intel_color_cleanup_commit(struct intel_crtc_state *crtc_state);
2222
void intel_color_commit_noarm(const struct intel_crtc_state *crtc_state);
2323
void intel_color_commit_arm(const struct intel_crtc_state *crtc_state);
24+
void intel_color_post_update(const struct intel_crtc_state *crtc_state);
2425
void intel_color_load_luts(const struct intel_crtc_state *crtc_state);
2526
void intel_color_get_config(struct intel_crtc_state *crtc_state);
2627
bool intel_color_lut_equal(const struct intel_crtc_state *crtc_state,

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

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,6 +1209,9 @@ static void intel_post_plane_update(struct intel_atomic_state *state,
12091209
if (needs_cursorclk_wa(old_crtc_state) &&
12101210
!needs_cursorclk_wa(new_crtc_state))
12111211
icl_wa_cursorclkgating(dev_priv, pipe, false);
1212+
1213+
if (intel_crtc_needs_color_update(new_crtc_state))
1214+
intel_color_post_update(new_crtc_state);
12121215
}
12131216

12141217
static void intel_crtc_enable_flip_done(struct intel_atomic_state *state,
@@ -7091,6 +7094,8 @@ static void intel_update_crtc(struct intel_atomic_state *state,
70917094

70927095
intel_fbc_update(state, crtc);
70937096

7097+
drm_WARN_ON(&i915->drm, !intel_display_power_is_enabled(i915, POWER_DOMAIN_DC_OFF));
7098+
70947099
if (!modeset &&
70957100
intel_crtc_needs_color_update(new_crtc_state))
70967101
intel_color_commit_noarm(new_crtc_state);
@@ -7458,8 +7463,28 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
74587463
drm_atomic_helper_wait_for_dependencies(&state->base);
74597464
drm_dp_mst_atomic_wait_for_dependencies(&state->base);
74607465

7461-
if (state->modeset)
7462-
wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_MODESET);
7466+
/*
7467+
* During full modesets we write a lot of registers, wait
7468+
* for PLLs, etc. Doing that while DC states are enabled
7469+
* is not a good idea.
7470+
*
7471+
* During fastsets and other updates we also need to
7472+
* disable DC states due to the following scenario:
7473+
* 1. DC5 exit and PSR exit happen
7474+
* 2. Some or all _noarm() registers are written
7475+
* 3. Due to some long delay PSR is re-entered
7476+
* 4. DC5 entry -> DMC saves the already written new
7477+
* _noarm() registers and the old not yet written
7478+
* _arm() registers
7479+
* 5. DC5 exit -> DMC restores a mixture of old and
7480+
* new register values and arms the update
7481+
* 6. PSR exit -> hardware latches a mixture of old and
7482+
* new register values -> corrupted frame, or worse
7483+
* 7. New _arm() registers are finally written
7484+
* 8. Hardware finally latches a complete set of new
7485+
* register values, and subsequent frames will be OK again
7486+
*/
7487+
wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_DC_OFF);
74637488

74647489
intel_atomic_prepare_plane_clear_colors(state);
74657490

@@ -7608,8 +7633,8 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
76087633
* the culprit.
76097634
*/
76107635
intel_uncore_arm_unclaimed_mmio_detection(&dev_priv->uncore);
7611-
intel_display_power_put(dev_priv, POWER_DOMAIN_MODESET, wakeref);
76127636
}
7637+
intel_display_power_put(dev_priv, POWER_DOMAIN_DC_OFF, wakeref);
76137638
intel_runtime_pm_put(&dev_priv->runtime_pm, state->wakeref);
76147639

76157640
/*

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@ intel_dpt_create(struct intel_framebuffer *fb)
301301
vm->pte_encode = gen8_ggtt_pte_encode;
302302

303303
dpt->obj = dpt_obj;
304+
dpt->obj->is_dpt = true;
304305

305306
return &dpt->vm;
306307
}
@@ -309,5 +310,6 @@ void intel_dpt_destroy(struct i915_address_space *vm)
309310
{
310311
struct i915_dpt *dpt = i915_vm_to_dpt(vm);
311312

313+
dpt->obj->is_dpt = false;
312314
i915_vm_put(&dpt->vm);
313315
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -418,9 +418,9 @@ static bool icl_tc_phy_is_owned(struct intel_digital_port *dig_port)
418418
val = intel_de_read(i915, PORT_TX_DFLEXDPCSSS(dig_port->tc_phy_fia));
419419
if (val == 0xffffffff) {
420420
drm_dbg_kms(&i915->drm,
421-
"Port %s: PHY in TCCOLD, assume safe mode\n",
421+
"Port %s: PHY in TCCOLD, assume not owned\n",
422422
dig_port->tc_port_name);
423-
return true;
423+
return false;
424424
}
425425

426426
return val & DP_PHY_MODE_STATUS_NOT_SAFE(dig_port->tc_phy_fia_idx);

drivers/gpu/drm/i915/gem/i915_gem_lmem.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,8 @@ i915_gem_object_create_lmem_from_data(struct drm_i915_private *i915,
127127

128128
memcpy(map, data, size);
129129

130-
i915_gem_object_unpin_map(obj);
130+
i915_gem_object_flush_map(obj);
131+
__i915_gem_object_release_map(obj);
131132

132133
return obj;
133134
}

drivers/gpu/drm/i915/gem/i915_gem_object.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ i915_gem_object_never_mmap(const struct drm_i915_gem_object *obj)
303303
static inline bool
304304
i915_gem_object_is_framebuffer(const struct drm_i915_gem_object *obj)
305305
{
306-
return READ_ONCE(obj->frontbuffer);
306+
return READ_ONCE(obj->frontbuffer) || obj->is_dpt;
307307
}
308308

309309
static inline unsigned int

drivers/gpu/drm/i915/gem/i915_gem_object_types.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,9 @@ struct drm_i915_gem_object {
491491
*/
492492
unsigned int cache_dirty:1;
493493

494+
/* @is_dpt: Object houses a display page table (DPT) */
495+
unsigned int is_dpt:1;
496+
494497
/**
495498
* @read_domains: Read memory domains.
496499
*

drivers/gpu/drm/i915/gt/intel_rps.c

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2075,16 +2075,6 @@ void intel_rps_sanitize(struct intel_rps *rps)
20752075
rps_disable_interrupts(rps);
20762076
}
20772077

2078-
u32 intel_rps_read_rpstat_fw(struct intel_rps *rps)
2079-
{
2080-
struct drm_i915_private *i915 = rps_to_i915(rps);
2081-
i915_reg_t rpstat;
2082-
2083-
rpstat = (GRAPHICS_VER(i915) >= 12) ? GEN12_RPSTAT1 : GEN6_RPSTAT1;
2084-
2085-
return intel_uncore_read_fw(rps_to_gt(rps)->uncore, rpstat);
2086-
}
2087-
20882078
u32 intel_rps_read_rpstat(struct intel_rps *rps)
20892079
{
20902080
struct drm_i915_private *i915 = rps_to_i915(rps);
@@ -2095,7 +2085,7 @@ u32 intel_rps_read_rpstat(struct intel_rps *rps)
20952085
return intel_uncore_read(rps_to_gt(rps)->uncore, rpstat);
20962086
}
20972087

2098-
u32 intel_rps_get_cagf(struct intel_rps *rps, u32 rpstat)
2088+
static u32 intel_rps_get_cagf(struct intel_rps *rps, u32 rpstat)
20992089
{
21002090
struct drm_i915_private *i915 = rps_to_i915(rps);
21012091
u32 cagf;
@@ -2118,33 +2108,42 @@ u32 intel_rps_get_cagf(struct intel_rps *rps, u32 rpstat)
21182108
return cagf;
21192109
}
21202110

2121-
static u32 read_cagf(struct intel_rps *rps)
2111+
static u32 __read_cagf(struct intel_rps *rps, bool take_fw)
21222112
{
21232113
struct drm_i915_private *i915 = rps_to_i915(rps);
21242114
struct intel_uncore *uncore = rps_to_uncore(rps);
2115+
i915_reg_t r = INVALID_MMIO_REG;
21252116
u32 freq;
21262117

21272118
/*
21282119
* For Gen12+ reading freq from HW does not need a forcewake and
21292120
* registers will return 0 freq when GT is in RC6
21302121
*/
21312122
if (GRAPHICS_VER_FULL(i915) >= IP_VER(12, 70)) {
2132-
freq = intel_uncore_read(uncore, MTL_MIRROR_TARGET_WP1);
2123+
r = MTL_MIRROR_TARGET_WP1;
21332124
} else if (GRAPHICS_VER(i915) >= 12) {
2134-
freq = intel_uncore_read(uncore, GEN12_RPSTAT1);
2125+
r = GEN12_RPSTAT1;
21352126
} else if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) {
21362127
vlv_punit_get(i915);
21372128
freq = vlv_punit_read(i915, PUNIT_REG_GPU_FREQ_STS);
21382129
vlv_punit_put(i915);
21392130
} else if (GRAPHICS_VER(i915) >= 6) {
2140-
freq = intel_uncore_read(uncore, GEN6_RPSTAT1);
2131+
r = GEN6_RPSTAT1;
21412132
} else {
2142-
freq = intel_uncore_read(uncore, MEMSTAT_ILK);
2133+
r = MEMSTAT_ILK;
21432134
}
21442135

2136+
if (i915_mmio_reg_valid(r))
2137+
freq = take_fw ? intel_uncore_read(uncore, r) : intel_uncore_read_fw(uncore, r);
2138+
21452139
return intel_rps_get_cagf(rps, freq);
21462140
}
21472141

2142+
static u32 read_cagf(struct intel_rps *rps)
2143+
{
2144+
return __read_cagf(rps, true);
2145+
}
2146+
21482147
u32 intel_rps_read_actual_frequency(struct intel_rps *rps)
21492148
{
21502149
struct intel_runtime_pm *rpm = rps_to_uncore(rps)->rpm;
@@ -2157,7 +2156,12 @@ u32 intel_rps_read_actual_frequency(struct intel_rps *rps)
21572156
return freq;
21582157
}
21592158

2160-
u32 intel_rps_read_punit_req(struct intel_rps *rps)
2159+
u32 intel_rps_read_actual_frequency_fw(struct intel_rps *rps)
2160+
{
2161+
return intel_gpu_freq(rps, __read_cagf(rps, false));
2162+
}
2163+
2164+
static u32 intel_rps_read_punit_req(struct intel_rps *rps)
21612165
{
21622166
struct intel_uncore *uncore = rps_to_uncore(rps);
21632167
struct intel_runtime_pm *rpm = rps_to_uncore(rps)->rpm;

0 commit comments

Comments
 (0)