Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: MIT
0002 /*
0003  * Copyright © 2018 Intel Corporation
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  * Some machines (Lenovo U160) do not work with SSC on LVDS for some reason
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  * A machine (e.g. Acer Aspire 5734Z) may need to invert the panel backlight
0023  * brightness value
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 /* Some VBT's incorrectly indicate no backlight is present */
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 /* Toshiba Satellite P50-C-18C requires T12 delay to be min 800ms
0039  * which is 300 ms greater than eDP spec T12 min.
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  * GeminiLake NUC HDMI outputs require additional off time
0049  * this allows the onboard retimer to correctly sync to signal
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 /* For systems that don't have a meaningful PCI subdevice/subvendor ID */
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                 /* DMI strings are too generic, also match on BIOS date */
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             { }  /* terminating entry */
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     /* Lenovo U160 cannot use SSC on LVDS */
0138     { 0x0046, 0x17aa, 0x3920, quirk_ssc_force_disable },
0139 
0140     /* Sony Vaio Y cannot use SSC on LVDS */
0141     { 0x0046, 0x104d, 0x9076, quirk_ssc_force_disable },
0142 
0143     /* Acer Aspire 5734Z must invert backlight brightness */
0144     { 0x2a42, 0x1025, 0x0459, quirk_invert_brightness },
0145 
0146     /* Acer/eMachines G725 */
0147     { 0x2a42, 0x1025, 0x0210, quirk_invert_brightness },
0148 
0149     /* Acer/eMachines e725 */
0150     { 0x2a42, 0x1025, 0x0212, quirk_invert_brightness },
0151 
0152     /* Acer/Packard Bell NCL20 */
0153     { 0x2a42, 0x1025, 0x034b, quirk_invert_brightness },
0154 
0155     /* Acer Aspire 4736Z */
0156     { 0x2a42, 0x1025, 0x0260, quirk_invert_brightness },
0157 
0158     /* Acer Aspire 5336 */
0159     { 0x2a42, 0x1025, 0x048a, quirk_invert_brightness },
0160 
0161     /* Acer C720 and C720P Chromebooks (Celeron 2955U) have backlights */
0162     { 0x0a06, 0x1025, 0x0a11, quirk_backlight_present },
0163 
0164     /* Acer C720 Chromebook (Core i3 4005U) */
0165     { 0x0a16, 0x1025, 0x0a11, quirk_backlight_present },
0166 
0167     /* Apple Macbook 2,1 (Core 2 T7400) */
0168     { 0x27a2, 0x8086, 0x7270, quirk_backlight_present },
0169 
0170     /* Apple Macbook 4,1 */
0171     { 0x2a02, 0x106b, 0x00a1, quirk_backlight_present },
0172 
0173     /* Toshiba CB35 Chromebook (Celeron 2955U) */
0174     { 0x0a06, 0x1179, 0x0a88, quirk_backlight_present },
0175 
0176     /* HP Chromebook 14 (Celeron 2955U) */
0177     { 0x0a06, 0x103c, 0x21ed, quirk_backlight_present },
0178 
0179     /* Dell Chromebook 11 */
0180     { 0x0a06, 0x1028, 0x0a35, quirk_backlight_present },
0181 
0182     /* Dell Chromebook 11 (2015 version) */
0183     { 0x0a16, 0x1028, 0x0a35, quirk_backlight_present },
0184 
0185     /* Toshiba Satellite P50-C-18C */
0186     { 0x191B, 0x1179, 0xF840, quirk_increase_t12_delay },
0187 
0188     /* GeminiLake NUC */
0189     { 0x3185, 0x8086, 0x2072, quirk_increase_ddi_disabled_time },
0190     { 0x3184, 0x8086, 0x2072, quirk_increase_ddi_disabled_time },
0191     /* ASRock ITX*/
0192     { 0x3185, 0x1849, 0x2212, quirk_increase_ddi_disabled_time },
0193     { 0x3184, 0x1849, 0x2212, quirk_increase_ddi_disabled_time },
0194     /* ECS Liva Q2 */
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 }