0001
0002
0003
0004
0005
0006 #include <linux/dmi.h>
0007
0008 #include "i915_drv.h"
0009 #include "intel_display_types.h"
0010 #include "intel_quirks.h"
0011
0012
0013
0014
0015 static void quirk_ssc_force_disable(struct drm_i915_private *i915)
0016 {
0017 i915->quirks |= QUIRK_LVDS_SSC_DISABLE;
0018 drm_info(&i915->drm, "applying lvds SSC disable quirk\n");
0019 }
0020
0021
0022
0023
0024
0025 static void quirk_invert_brightness(struct drm_i915_private *i915)
0026 {
0027 i915->quirks |= QUIRK_INVERT_BRIGHTNESS;
0028 drm_info(&i915->drm, "applying inverted panel brightness quirk\n");
0029 }
0030
0031
0032 static void quirk_backlight_present(struct drm_i915_private *i915)
0033 {
0034 i915->quirks |= QUIRK_BACKLIGHT_PRESENT;
0035 drm_info(&i915->drm, "applying backlight present quirk\n");
0036 }
0037
0038
0039
0040
0041 static void quirk_increase_t12_delay(struct drm_i915_private *i915)
0042 {
0043 i915->quirks |= QUIRK_INCREASE_T12_DELAY;
0044 drm_info(&i915->drm, "Applying T12 delay quirk\n");
0045 }
0046
0047
0048
0049
0050
0051 static void quirk_increase_ddi_disabled_time(struct drm_i915_private *i915)
0052 {
0053 i915->quirks |= QUIRK_INCREASE_DDI_DISABLED_TIME;
0054 drm_info(&i915->drm, "Applying Increase DDI Disabled quirk\n");
0055 }
0056
0057 static void quirk_no_pps_backlight_power_hook(struct drm_i915_private *i915)
0058 {
0059 i915->quirks |= QUIRK_NO_PPS_BACKLIGHT_POWER_HOOK;
0060 drm_info(&i915->drm, "Applying no pps backlight power quirk\n");
0061 }
0062
0063 struct intel_quirk {
0064 int device;
0065 int subsystem_vendor;
0066 int subsystem_device;
0067 void (*hook)(struct drm_i915_private *i915);
0068 };
0069
0070
0071 struct intel_dmi_quirk {
0072 void (*hook)(struct drm_i915_private *i915);
0073 const struct dmi_system_id (*dmi_id_list)[];
0074 };
0075
0076 static int intel_dmi_reverse_brightness(const struct dmi_system_id *id)
0077 {
0078 DRM_INFO("Backlight polarity reversed on %s\n", id->ident);
0079 return 1;
0080 }
0081
0082 static int intel_dmi_no_pps_backlight(const struct dmi_system_id *id)
0083 {
0084 DRM_INFO("No pps backlight support on %s\n", id->ident);
0085 return 1;
0086 }
0087
0088 static const struct intel_dmi_quirk intel_dmi_quirks[] = {
0089 {
0090 .dmi_id_list = &(const struct dmi_system_id[]) {
0091 {
0092 .callback = intel_dmi_reverse_brightness,
0093 .ident = "NCR Corporation",
0094 .matches = {DMI_MATCH(DMI_SYS_VENDOR, "NCR Corporation"),
0095 DMI_MATCH(DMI_PRODUCT_NAME, ""),
0096 },
0097 },
0098 {
0099 .callback = intel_dmi_reverse_brightness,
0100 .ident = "Thundersoft TST178 tablet",
0101
0102 .matches = {DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
0103 DMI_EXACT_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
0104 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "To be filled by O.E.M."),
0105 DMI_EXACT_MATCH(DMI_BIOS_DATE, "04/15/2014"),
0106 },
0107 },
0108 { }
0109 },
0110 .hook = quirk_invert_brightness,
0111 },
0112 {
0113 .dmi_id_list = &(const struct dmi_system_id[]) {
0114 {
0115 .callback = intel_dmi_no_pps_backlight,
0116 .ident = "Google Lillipup sku524294",
0117 .matches = {DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Google"),
0118 DMI_EXACT_MATCH(DMI_BOARD_NAME, "Lindar"),
0119 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "sku524294"),
0120 },
0121 },
0122 {
0123 .callback = intel_dmi_no_pps_backlight,
0124 .ident = "Google Lillipup sku524295",
0125 .matches = {DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Google"),
0126 DMI_EXACT_MATCH(DMI_BOARD_NAME, "Lindar"),
0127 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "sku524295"),
0128 },
0129 },
0130 { }
0131 },
0132 .hook = quirk_no_pps_backlight_power_hook,
0133 },
0134 };
0135
0136 static struct intel_quirk intel_quirks[] = {
0137
0138 { 0x0046, 0x17aa, 0x3920, quirk_ssc_force_disable },
0139
0140
0141 { 0x0046, 0x104d, 0x9076, quirk_ssc_force_disable },
0142
0143
0144 { 0x2a42, 0x1025, 0x0459, quirk_invert_brightness },
0145
0146
0147 { 0x2a42, 0x1025, 0x0210, quirk_invert_brightness },
0148
0149
0150 { 0x2a42, 0x1025, 0x0212, quirk_invert_brightness },
0151
0152
0153 { 0x2a42, 0x1025, 0x034b, quirk_invert_brightness },
0154
0155
0156 { 0x2a42, 0x1025, 0x0260, quirk_invert_brightness },
0157
0158
0159 { 0x2a42, 0x1025, 0x048a, quirk_invert_brightness },
0160
0161
0162 { 0x0a06, 0x1025, 0x0a11, quirk_backlight_present },
0163
0164
0165 { 0x0a16, 0x1025, 0x0a11, quirk_backlight_present },
0166
0167
0168 { 0x27a2, 0x8086, 0x7270, quirk_backlight_present },
0169
0170
0171 { 0x2a02, 0x106b, 0x00a1, quirk_backlight_present },
0172
0173
0174 { 0x0a06, 0x1179, 0x0a88, quirk_backlight_present },
0175
0176
0177 { 0x0a06, 0x103c, 0x21ed, quirk_backlight_present },
0178
0179
0180 { 0x0a06, 0x1028, 0x0a35, quirk_backlight_present },
0181
0182
0183 { 0x0a16, 0x1028, 0x0a35, quirk_backlight_present },
0184
0185
0186 { 0x191B, 0x1179, 0xF840, quirk_increase_t12_delay },
0187
0188
0189 { 0x3185, 0x8086, 0x2072, quirk_increase_ddi_disabled_time },
0190 { 0x3184, 0x8086, 0x2072, quirk_increase_ddi_disabled_time },
0191
0192 { 0x3185, 0x1849, 0x2212, quirk_increase_ddi_disabled_time },
0193 { 0x3184, 0x1849, 0x2212, quirk_increase_ddi_disabled_time },
0194
0195 { 0x3185, 0x1019, 0xa94d, quirk_increase_ddi_disabled_time },
0196 { 0x3184, 0x1019, 0xa94d, quirk_increase_ddi_disabled_time },
0197 };
0198
0199 void intel_init_quirks(struct drm_i915_private *i915)
0200 {
0201 struct pci_dev *d = to_pci_dev(i915->drm.dev);
0202 int i;
0203
0204 for (i = 0; i < ARRAY_SIZE(intel_quirks); i++) {
0205 struct intel_quirk *q = &intel_quirks[i];
0206
0207 if (d->device == q->device &&
0208 (d->subsystem_vendor == q->subsystem_vendor ||
0209 q->subsystem_vendor == PCI_ANY_ID) &&
0210 (d->subsystem_device == q->subsystem_device ||
0211 q->subsystem_device == PCI_ANY_ID))
0212 q->hook(i915);
0213 }
0214 for (i = 0; i < ARRAY_SIZE(intel_dmi_quirks); i++) {
0215 if (dmi_check_system(*intel_dmi_quirks[i].dmi_id_list) != 0)
0216 intel_dmi_quirks[i].hook(i915);
0217 }
0218 }