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