diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_quirks.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_quirks.c | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/intel_quirks.c b/drivers/gpu/drm/i915/intel_quirks.c new file mode 100644 index 000000000000..ec2b0fc92b8b --- /dev/null +++ b/drivers/gpu/drm/i915/intel_quirks.c | |||
@@ -0,0 +1,169 @@ | |||
1 | // SPDX-License-Identifier: MIT | ||
2 | /* | ||
3 | * Copyright © 2018 Intel Corporation | ||
4 | */ | ||
5 | |||
6 | #include <linux/dmi.h> | ||
7 | |||
8 | #include "intel_drv.h" | ||
9 | |||
10 | /* | ||
11 | * Some machines (Lenovo U160) do not work with SSC on LVDS for some reason | ||
12 | */ | ||
13 | static void quirk_ssc_force_disable(struct drm_i915_private *i915) | ||
14 | { | ||
15 | i915->quirks |= QUIRK_LVDS_SSC_DISABLE; | ||
16 | DRM_INFO("applying lvds SSC disable quirk\n"); | ||
17 | } | ||
18 | |||
19 | /* | ||
20 | * A machine (e.g. Acer Aspire 5734Z) may need to invert the panel backlight | ||
21 | * brightness value | ||
22 | */ | ||
23 | static void quirk_invert_brightness(struct drm_i915_private *i915) | ||
24 | { | ||
25 | i915->quirks |= QUIRK_INVERT_BRIGHTNESS; | ||
26 | DRM_INFO("applying inverted panel brightness quirk\n"); | ||
27 | } | ||
28 | |||
29 | /* Some VBT's incorrectly indicate no backlight is present */ | ||
30 | static void quirk_backlight_present(struct drm_i915_private *i915) | ||
31 | { | ||
32 | i915->quirks |= QUIRK_BACKLIGHT_PRESENT; | ||
33 | DRM_INFO("applying backlight present quirk\n"); | ||
34 | } | ||
35 | |||
36 | /* Toshiba Satellite P50-C-18C requires T12 delay to be min 800ms | ||
37 | * which is 300 ms greater than eDP spec T12 min. | ||
38 | */ | ||
39 | static void quirk_increase_t12_delay(struct drm_i915_private *i915) | ||
40 | { | ||
41 | i915->quirks |= QUIRK_INCREASE_T12_DELAY; | ||
42 | DRM_INFO("Applying T12 delay quirk\n"); | ||
43 | } | ||
44 | |||
45 | /* | ||
46 | * GeminiLake NUC HDMI outputs require additional off time | ||
47 | * this allows the onboard retimer to correctly sync to signal | ||
48 | */ | ||
49 | static void quirk_increase_ddi_disabled_time(struct drm_i915_private *i915) | ||
50 | { | ||
51 | i915->quirks |= QUIRK_INCREASE_DDI_DISABLED_TIME; | ||
52 | DRM_INFO("Applying Increase DDI Disabled quirk\n"); | ||
53 | } | ||
54 | |||
55 | struct intel_quirk { | ||
56 | int device; | ||
57 | int subsystem_vendor; | ||
58 | int subsystem_device; | ||
59 | void (*hook)(struct drm_i915_private *i915); | ||
60 | }; | ||
61 | |||
62 | /* For systems that don't have a meaningful PCI subdevice/subvendor ID */ | ||
63 | struct intel_dmi_quirk { | ||
64 | void (*hook)(struct drm_i915_private *i915); | ||
65 | const struct dmi_system_id (*dmi_id_list)[]; | ||
66 | }; | ||
67 | |||
68 | static int intel_dmi_reverse_brightness(const struct dmi_system_id *id) | ||
69 | { | ||
70 | DRM_INFO("Backlight polarity reversed on %s\n", id->ident); | ||
71 | return 1; | ||
72 | } | ||
73 | |||
74 | static const struct intel_dmi_quirk intel_dmi_quirks[] = { | ||
75 | { | ||
76 | .dmi_id_list = &(const struct dmi_system_id[]) { | ||
77 | { | ||
78 | .callback = intel_dmi_reverse_brightness, | ||
79 | .ident = "NCR Corporation", | ||
80 | .matches = {DMI_MATCH(DMI_SYS_VENDOR, "NCR Corporation"), | ||
81 | DMI_MATCH(DMI_PRODUCT_NAME, ""), | ||
82 | }, | ||
83 | }, | ||
84 | { } /* terminating entry */ | ||
85 | }, | ||
86 | .hook = quirk_invert_brightness, | ||
87 | }, | ||
88 | }; | ||
89 | |||
90 | static struct intel_quirk intel_quirks[] = { | ||
91 | /* Lenovo U160 cannot use SSC on LVDS */ | ||
92 | { 0x0046, 0x17aa, 0x3920, quirk_ssc_force_disable }, | ||
93 | |||
94 | /* Sony Vaio Y cannot use SSC on LVDS */ | ||
95 | { 0x0046, 0x104d, 0x9076, quirk_ssc_force_disable }, | ||
96 | |||
97 | /* Acer Aspire 5734Z must invert backlight brightness */ | ||
98 | { 0x2a42, 0x1025, 0x0459, quirk_invert_brightness }, | ||
99 | |||
100 | /* Acer/eMachines G725 */ | ||
101 | { 0x2a42, 0x1025, 0x0210, quirk_invert_brightness }, | ||
102 | |||
103 | /* Acer/eMachines e725 */ | ||
104 | { 0x2a42, 0x1025, 0x0212, quirk_invert_brightness }, | ||
105 | |||
106 | /* Acer/Packard Bell NCL20 */ | ||
107 | { 0x2a42, 0x1025, 0x034b, quirk_invert_brightness }, | ||
108 | |||
109 | /* Acer Aspire 4736Z */ | ||
110 | { 0x2a42, 0x1025, 0x0260, quirk_invert_brightness }, | ||
111 | |||
112 | /* Acer Aspire 5336 */ | ||
113 | { 0x2a42, 0x1025, 0x048a, quirk_invert_brightness }, | ||
114 | |||
115 | /* Acer C720 and C720P Chromebooks (Celeron 2955U) have backlights */ | ||
116 | { 0x0a06, 0x1025, 0x0a11, quirk_backlight_present }, | ||
117 | |||
118 | /* Acer C720 Chromebook (Core i3 4005U) */ | ||
119 | { 0x0a16, 0x1025, 0x0a11, quirk_backlight_present }, | ||
120 | |||
121 | /* Apple Macbook 2,1 (Core 2 T7400) */ | ||
122 | { 0x27a2, 0x8086, 0x7270, quirk_backlight_present }, | ||
123 | |||
124 | /* Apple Macbook 4,1 */ | ||
125 | { 0x2a02, 0x106b, 0x00a1, quirk_backlight_present }, | ||
126 | |||
127 | /* Toshiba CB35 Chromebook (Celeron 2955U) */ | ||
128 | { 0x0a06, 0x1179, 0x0a88, quirk_backlight_present }, | ||
129 | |||
130 | /* HP Chromebook 14 (Celeron 2955U) */ | ||
131 | { 0x0a06, 0x103c, 0x21ed, quirk_backlight_present }, | ||
132 | |||
133 | /* Dell Chromebook 11 */ | ||
134 | { 0x0a06, 0x1028, 0x0a35, quirk_backlight_present }, | ||
135 | |||
136 | /* Dell Chromebook 11 (2015 version) */ | ||
137 | { 0x0a16, 0x1028, 0x0a35, quirk_backlight_present }, | ||
138 | |||
139 | /* Toshiba Satellite P50-C-18C */ | ||
140 | { 0x191B, 0x1179, 0xF840, quirk_increase_t12_delay }, | ||
141 | |||
142 | /* GeminiLake NUC */ | ||
143 | { 0x3185, 0x8086, 0x2072, quirk_increase_ddi_disabled_time }, | ||
144 | { 0x3184, 0x8086, 0x2072, quirk_increase_ddi_disabled_time }, | ||
145 | /* ASRock ITX*/ | ||
146 | { 0x3185, 0x1849, 0x2212, quirk_increase_ddi_disabled_time }, | ||
147 | { 0x3184, 0x1849, 0x2212, quirk_increase_ddi_disabled_time }, | ||
148 | }; | ||
149 | |||
150 | void intel_init_quirks(struct drm_i915_private *i915) | ||
151 | { | ||
152 | struct pci_dev *d = i915->drm.pdev; | ||
153 | int i; | ||
154 | |||
155 | for (i = 0; i < ARRAY_SIZE(intel_quirks); i++) { | ||
156 | struct intel_quirk *q = &intel_quirks[i]; | ||
157 | |||
158 | if (d->device == q->device && | ||
159 | (d->subsystem_vendor == q->subsystem_vendor || | ||
160 | q->subsystem_vendor == PCI_ANY_ID) && | ||
161 | (d->subsystem_device == q->subsystem_device || | ||
162 | q->subsystem_device == PCI_ANY_ID)) | ||
163 | q->hook(i915); | ||
164 | } | ||
165 | for (i = 0; i < ARRAY_SIZE(intel_dmi_quirks); i++) { | ||
166 | if (dmi_check_system(*intel_dmi_quirks[i].dmi_id_list) != 0) | ||
167 | intel_dmi_quirks[i].hook(i915); | ||
168 | } | ||
169 | } | ||