Skip to content

Commit f2064ae

Browse files
committed
Merge tag 'drm-intel-fixes-2024-09-05' of https://gitlab.freedesktop.org/drm/i915/kernel into drm-fixes
- drm/i915: Do not attempt to load the GSC multiple times (Daniele Ceraolo Spurio) - drm/i915: Fix readout degamma_lut mismatch on ilk/snb (Ville Syrjälä) - drm/i915/fence: Mark debug_fence_init_onstack() with __maybe_unused (Andy Shevchenko) - drm/i915/fence: Mark debug_fence_free() with __maybe_unused (Andy Shevchenko) - drm/i915/display: Add mechanism to use sink model when applying quirk [display] (Jouni Högander) - drm/i915/display: Increase Fast Wake Sync length as a quirk [display] (Jouni Högander) Signed-off-by: Dave Airlie <[email protected]> From: Tvrtko Ursulin <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/Ztlo2hVO4SBvfAnq@linux
2 parents 431c164 + a13494d commit f2064ae

File tree

11 files changed

+131
-17
lines changed

11 files changed

+131
-17
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ bool intel_alpm_compute_params(struct intel_dp *intel_dp,
228228
int tfw_exit_latency = 20; /* eDP spec */
229229
int phy_wake = 4; /* eDP spec */
230230
int preamble = 8; /* eDP spec */
231-
int precharge = intel_dp_aux_fw_sync_len() - preamble;
231+
int precharge = intel_dp_aux_fw_sync_len(intel_dp) - preamble;
232232
u8 max_wake_lines;
233233

234234
io_wake_time = max(precharge, io_buffer_wake_time(crtc_state)) +

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1885,6 +1885,10 @@ struct intel_dp {
18851885
} alpm_parameters;
18861886

18871887
u8 alpm_dpcd;
1888+
1889+
struct {
1890+
unsigned long mask;
1891+
} quirks;
18881892
};
18891893

18901894
enum lspcon_vendor {

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
#include "intel_pch_display.h"
8383
#include "intel_pps.h"
8484
#include "intel_psr.h"
85+
#include "intel_quirks.h"
8586
#include "intel_tc.h"
8687
#include "intel_vdsc.h"
8788
#include "intel_vrr.h"
@@ -3952,6 +3953,7 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp, struct intel_connector *connector
39523953

39533954
drm_dp_read_desc(&intel_dp->aux, &intel_dp->desc,
39543955
drm_dp_is_branch(intel_dp->dpcd));
3956+
intel_init_dpcd_quirks(intel_dp, &intel_dp->desc.ident);
39553957

39563958
/*
39573959
* Read the eDP display control registers.
@@ -4064,6 +4066,8 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
40644066
drm_dp_read_desc(&intel_dp->aux, &intel_dp->desc,
40654067
drm_dp_is_branch(intel_dp->dpcd));
40664068

4069+
intel_init_dpcd_quirks(intel_dp, &intel_dp->desc.ident);
4070+
40674071
intel_dp_update_sink_caps(intel_dp);
40684072
}
40694073

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

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "intel_dp_aux.h"
1414
#include "intel_dp_aux_regs.h"
1515
#include "intel_pps.h"
16+
#include "intel_quirks.h"
1617
#include "intel_tc.h"
1718

1819
#define AUX_CH_NAME_BUFSIZE 6
@@ -142,16 +143,21 @@ static int intel_dp_aux_sync_len(void)
142143
return precharge + preamble;
143144
}
144145

145-
int intel_dp_aux_fw_sync_len(void)
146+
int intel_dp_aux_fw_sync_len(struct intel_dp *intel_dp)
146147
{
148+
int precharge = 10; /* 10-16 */
149+
int preamble = 8;
150+
147151
/*
148152
* We faced some glitches on Dell Precision 5490 MTL laptop with panel:
149153
* "Manufacturer: AUO, Model: 63898" when using HW default 18. Using 20
150154
* is fixing these problems with the panel. It is still within range
151-
* mentioned in eDP specification.
155+
* mentioned in eDP specification. Increasing Fast Wake sync length is
156+
* causing problems with other panels: increase length as a quirk for
157+
* this specific laptop.
152158
*/
153-
int precharge = 12; /* 10-16 */
154-
int preamble = 8;
159+
if (intel_has_dpcd_quirk(intel_dp, QUIRK_FW_SYNC_LEN))
160+
precharge += 2;
155161

156162
return precharge + preamble;
157163
}
@@ -211,7 +217,7 @@ static u32 skl_get_aux_send_ctl(struct intel_dp *intel_dp,
211217
DP_AUX_CH_CTL_TIME_OUT_MAX |
212218
DP_AUX_CH_CTL_RECEIVE_ERROR |
213219
DP_AUX_CH_CTL_MESSAGE_SIZE(send_bytes) |
214-
DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL(intel_dp_aux_fw_sync_len()) |
220+
DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL(intel_dp_aux_fw_sync_len(intel_dp)) |
215221
DP_AUX_CH_CTL_SYNC_PULSE_SKL(intel_dp_aux_sync_len());
216222

217223
if (intel_tc_port_in_tbt_alt_mode(dig_port))

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,6 @@ enum aux_ch intel_dp_aux_ch(struct intel_encoder *encoder);
2020

2121
void intel_dp_aux_irq_handler(struct drm_i915_private *i915);
2222
u32 intel_dp_aux_pack(const u8 *src, int src_bytes);
23-
int intel_dp_aux_fw_sync_len(void);
23+
int intel_dp_aux_fw_sync_len(struct intel_dp *intel_dp);
2424

2525
#endif /* __INTEL_DP_AUX_H__ */

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

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,8 @@ static void intel_modeset_update_connector_atomic_state(struct drm_i915_private
326326

327327
static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state)
328328
{
329+
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
330+
329331
if (intel_crtc_is_joiner_secondary(crtc_state))
330332
return;
331333

@@ -337,11 +339,30 @@ static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state
337339
crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
338340
crtc_state->uapi.scaling_filter = crtc_state->hw.scaling_filter;
339341

340-
/* assume 1:1 mapping */
341-
drm_property_replace_blob(&crtc_state->hw.degamma_lut,
342-
crtc_state->pre_csc_lut);
343-
drm_property_replace_blob(&crtc_state->hw.gamma_lut,
344-
crtc_state->post_csc_lut);
342+
if (DISPLAY_INFO(i915)->color.degamma_lut_size) {
343+
/* assume 1:1 mapping */
344+
drm_property_replace_blob(&crtc_state->hw.degamma_lut,
345+
crtc_state->pre_csc_lut);
346+
drm_property_replace_blob(&crtc_state->hw.gamma_lut,
347+
crtc_state->post_csc_lut);
348+
} else {
349+
/*
350+
* ilk/snb hw may be configured for either pre_csc_lut
351+
* or post_csc_lut, but we don't advertise degamma_lut as
352+
* being available in the uapi since there is only one
353+
* hardware LUT. Always assign the result of the readout
354+
* to gamma_lut as that is the only valid source of LUTs
355+
* in the uapi.
356+
*/
357+
drm_WARN_ON(&i915->drm, crtc_state->post_csc_lut &&
358+
crtc_state->pre_csc_lut);
359+
360+
drm_property_replace_blob(&crtc_state->hw.degamma_lut,
361+
NULL);
362+
drm_property_replace_blob(&crtc_state->hw.gamma_lut,
363+
crtc_state->post_csc_lut ?:
364+
crtc_state->pre_csc_lut);
365+
}
345366

346367
drm_property_replace_blob(&crtc_state->uapi.degamma_lut,
347368
crtc_state->hw.degamma_lut);

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

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ static void intel_set_quirk(struct intel_display *display, enum intel_quirk_id q
1414
display->quirks.mask |= BIT(quirk);
1515
}
1616

17+
static void intel_set_dpcd_quirk(struct intel_dp *intel_dp, enum intel_quirk_id quirk)
18+
{
19+
intel_dp->quirks.mask |= BIT(quirk);
20+
}
21+
1722
/*
1823
* Some machines (Lenovo U160) do not work with SSC on LVDS for some reason
1924
*/
@@ -65,13 +70,36 @@ static void quirk_no_pps_backlight_power_hook(struct intel_display *display)
6570
drm_info(display->drm, "Applying no pps backlight power quirk\n");
6671
}
6772

73+
static void quirk_fw_sync_len(struct intel_dp *intel_dp)
74+
{
75+
struct intel_display *display = to_intel_display(intel_dp);
76+
77+
intel_set_dpcd_quirk(intel_dp, QUIRK_FW_SYNC_LEN);
78+
drm_info(display->drm, "Applying Fast Wake sync pulse count quirk\n");
79+
}
80+
6881
struct intel_quirk {
6982
int device;
7083
int subsystem_vendor;
7184
int subsystem_device;
7285
void (*hook)(struct intel_display *display);
7386
};
7487

88+
struct intel_dpcd_quirk {
89+
int device;
90+
int subsystem_vendor;
91+
int subsystem_device;
92+
u8 sink_oui[3];
93+
u8 sink_device_id[6];
94+
void (*hook)(struct intel_dp *intel_dp);
95+
};
96+
97+
#define SINK_OUI(first, second, third) { (first), (second), (third) }
98+
#define SINK_DEVICE_ID(first, second, third, fourth, fifth, sixth) \
99+
{ (first), (second), (third), (fourth), (fifth), (sixth) }
100+
101+
#define SINK_DEVICE_ID_ANY SINK_DEVICE_ID(0, 0, 0, 0, 0, 0)
102+
75103
/* For systems that don't have a meaningful PCI subdevice/subvendor ID */
76104
struct intel_dmi_quirk {
77105
void (*hook)(struct intel_display *display);
@@ -203,6 +231,18 @@ static struct intel_quirk intel_quirks[] = {
203231
{ 0x0f31, 0x103c, 0x220f, quirk_invert_brightness },
204232
};
205233

234+
static struct intel_dpcd_quirk intel_dpcd_quirks[] = {
235+
/* Dell Precision 5490 */
236+
{
237+
.device = 0x7d55,
238+
.subsystem_vendor = 0x1028,
239+
.subsystem_device = 0x0cc7,
240+
.sink_oui = SINK_OUI(0x38, 0xec, 0x11),
241+
.hook = quirk_fw_sync_len,
242+
},
243+
244+
};
245+
206246
void intel_init_quirks(struct intel_display *display)
207247
{
208248
struct pci_dev *d = to_pci_dev(display->drm->dev);
@@ -224,7 +264,35 @@ void intel_init_quirks(struct intel_display *display)
224264
}
225265
}
226266

267+
void intel_init_dpcd_quirks(struct intel_dp *intel_dp,
268+
const struct drm_dp_dpcd_ident *ident)
269+
{
270+
struct intel_display *display = to_intel_display(intel_dp);
271+
struct pci_dev *d = to_pci_dev(display->drm->dev);
272+
int i;
273+
274+
for (i = 0; i < ARRAY_SIZE(intel_dpcd_quirks); i++) {
275+
struct intel_dpcd_quirk *q = &intel_dpcd_quirks[i];
276+
277+
if (d->device == q->device &&
278+
(d->subsystem_vendor == q->subsystem_vendor ||
279+
q->subsystem_vendor == PCI_ANY_ID) &&
280+
(d->subsystem_device == q->subsystem_device ||
281+
q->subsystem_device == PCI_ANY_ID) &&
282+
!memcmp(q->sink_oui, ident->oui, sizeof(ident->oui)) &&
283+
(!memcmp(q->sink_device_id, ident->device_id,
284+
sizeof(ident->device_id)) ||
285+
!memchr_inv(q->sink_device_id, 0, sizeof(q->sink_device_id))))
286+
q->hook(intel_dp);
287+
}
288+
}
289+
227290
bool intel_has_quirk(struct intel_display *display, enum intel_quirk_id quirk)
228291
{
229292
return display->quirks.mask & BIT(quirk);
230293
}
294+
295+
bool intel_has_dpcd_quirk(struct intel_dp *intel_dp, enum intel_quirk_id quirk)
296+
{
297+
return intel_dp->quirks.mask & BIT(quirk);
298+
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#include <linux/types.h>
1010

1111
struct intel_display;
12+
struct intel_dp;
13+
struct drm_dp_dpcd_ident;
1214

1315
enum intel_quirk_id {
1416
QUIRK_BACKLIGHT_PRESENT,
@@ -17,9 +19,13 @@ enum intel_quirk_id {
1719
QUIRK_INVERT_BRIGHTNESS,
1820
QUIRK_LVDS_SSC_DISABLE,
1921
QUIRK_NO_PPS_BACKLIGHT_POWER_HOOK,
22+
QUIRK_FW_SYNC_LEN,
2023
};
2124

2225
void intel_init_quirks(struct intel_display *display);
26+
void intel_init_dpcd_quirks(struct intel_dp *intel_dp,
27+
const struct drm_dp_dpcd_ident *ident);
2328
bool intel_has_quirk(struct intel_display *display, enum intel_quirk_id quirk);
29+
bool intel_has_dpcd_quirk(struct intel_dp *intel_dp, enum intel_quirk_id quirk);
2430

2531
#endif /* __INTEL_QUIRKS_H__ */

drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ void intel_gsc_uc_load_start(struct intel_gsc_uc *gsc)
302302
{
303303
struct intel_gt *gt = gsc_uc_to_gt(gsc);
304304

305-
if (!intel_uc_fw_is_loadable(&gsc->fw))
305+
if (!intel_uc_fw_is_loadable(&gsc->fw) || intel_uc_fw_is_in_error(&gsc->fw))
306306
return;
307307

308308
if (intel_gsc_uc_fw_init_done(gsc))

drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,11 @@ static inline bool intel_uc_fw_is_running(struct intel_uc_fw *uc_fw)
258258
return __intel_uc_fw_status(uc_fw) == INTEL_UC_FIRMWARE_RUNNING;
259259
}
260260

261+
static inline bool intel_uc_fw_is_in_error(struct intel_uc_fw *uc_fw)
262+
{
263+
return intel_uc_fw_status_to_error(__intel_uc_fw_status(uc_fw)) != 0;
264+
}
265+
261266
static inline bool intel_uc_fw_is_overridden(const struct intel_uc_fw *uc_fw)
262267
{
263268
return uc_fw->user_overridden;

0 commit comments

Comments
 (0)