Skip to content

Commit 43cf50e

Browse files
hoganderjlahtine-intel
authored andcommitted
drm/i915/display: Add mechanism to use sink model when applying quirk
Currently there is no way to apply quirk on device only if certain panel model is installed. This patch implements such mechanism by adding new quirk type intel_dpcd_quirk which contains also sink_oui and sink_device_id fields and using also them to figure out if applying quirk is needed. New intel_init_dpcd_quirks is added and called after drm_dp_read_desc with proper sink device identity read from dpcdc. v3: - !mem_is_zero fixed to mem_is_zero v2: - instead of using struct intel_quirk add new struct intel_dpcd_quirk Signed-off-by: Jouni Högander <[email protected]> Reviewed-by: Jani Nikula <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] (cherry picked from commit b3b9136) Signed-off-by: Joonas Lahtinen <[email protected]>
1 parent f999995 commit 43cf50e

File tree

4 files changed

+64
-0
lines changed

4 files changed

+64
-0
lines changed

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_quirks.c

Lines changed: 51 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
*/
@@ -72,6 +77,21 @@ struct intel_quirk {
7277
void (*hook)(struct intel_display *display);
7378
};
7479

80+
struct intel_dpcd_quirk {
81+
int device;
82+
int subsystem_vendor;
83+
int subsystem_device;
84+
u8 sink_oui[3];
85+
u8 sink_device_id[6];
86+
void (*hook)(struct intel_dp *intel_dp);
87+
};
88+
89+
#define SINK_OUI(first, second, third) { (first), (second), (third) }
90+
#define SINK_DEVICE_ID(first, second, third, fourth, fifth, sixth) \
91+
{ (first), (second), (third), (fourth), (fifth), (sixth) }
92+
93+
#define SINK_DEVICE_ID_ANY SINK_DEVICE_ID(0, 0, 0, 0, 0, 0)
94+
7595
/* For systems that don't have a meaningful PCI subdevice/subvendor ID */
7696
struct intel_dmi_quirk {
7797
void (*hook)(struct intel_display *display);
@@ -203,6 +223,9 @@ static struct intel_quirk intel_quirks[] = {
203223
{ 0x0f31, 0x103c, 0x220f, quirk_invert_brightness },
204224
};
205225

226+
static struct intel_dpcd_quirk intel_dpcd_quirks[] = {
227+
};
228+
206229
void intel_init_quirks(struct intel_display *display)
207230
{
208231
struct pci_dev *d = to_pci_dev(display->drm->dev);
@@ -224,7 +247,35 @@ void intel_init_quirks(struct intel_display *display)
224247
}
225248
}
226249

250+
void intel_init_dpcd_quirks(struct intel_dp *intel_dp,
251+
const struct drm_dp_dpcd_ident *ident)
252+
{
253+
struct intel_display *display = to_intel_display(intel_dp);
254+
struct pci_dev *d = to_pci_dev(display->drm->dev);
255+
int i;
256+
257+
for (i = 0; i < ARRAY_SIZE(intel_dpcd_quirks); i++) {
258+
struct intel_dpcd_quirk *q = &intel_dpcd_quirks[i];
259+
260+
if (d->device == q->device &&
261+
(d->subsystem_vendor == q->subsystem_vendor ||
262+
q->subsystem_vendor == PCI_ANY_ID) &&
263+
(d->subsystem_device == q->subsystem_device ||
264+
q->subsystem_device == PCI_ANY_ID) &&
265+
!memcmp(q->sink_oui, ident->oui, sizeof(ident->oui)) &&
266+
(!memcmp(q->sink_device_id, ident->device_id,
267+
sizeof(ident->device_id)) ||
268+
mem_is_zero(q->sink_device_id, sizeof(q->sink_device_id))))
269+
q->hook(intel_dp);
270+
}
271+
}
272+
227273
bool intel_has_quirk(struct intel_display *display, enum intel_quirk_id quirk)
228274
{
229275
return display->quirks.mask & BIT(quirk);
230276
}
277+
278+
bool intel_has_dpcd_quirk(struct intel_dp *intel_dp, enum intel_quirk_id quirk)
279+
{
280+
return intel_dp->quirks.mask & BIT(quirk);
281+
}

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

Lines changed: 5 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,
@@ -20,6 +22,9 @@ enum intel_quirk_id {
2022
};
2123

2224
void intel_init_quirks(struct intel_display *display);
25+
void intel_init_dpcd_quirks(struct intel_dp *intel_dp,
26+
const struct drm_dp_dpcd_ident *ident);
2327
bool intel_has_quirk(struct intel_display *display, enum intel_quirk_id quirk);
28+
bool intel_has_dpcd_quirk(struct intel_dp *intel_dp, enum intel_quirk_id quirk);
2429

2530
#endif /* __INTEL_QUIRKS_H__ */

0 commit comments

Comments
 (0)