summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/drm_dp_helper.c
diff options
context:
space:
mode:
authorLyude Paul <lyude@redhat.com>2020-02-11 13:33:46 -0500
committerLyude Paul <lyude@redhat.com>2020-03-03 20:34:31 -0500
commit0883ce8146ed6074c76399f4e70dbed788582e12 (patch)
tree83eb95c367030a38440bef88bc2644bdbe9d4ef5 /drivers/gpu/drm/drm_dp_helper.c
parent391615d998367b6495ccf9e685120986e8d02fa6 (diff)
drm/dp: Introduce EDID-based quirks
The whole point of using OUIs is so that we can recognize certain devices and potentially apply quirks for them. Normally this should work quite well, but there appears to be quite a number of laptop panels out there that will fill the OUI but not the device ID. As such, for devices like this I can't imagine it's a very good idea to try relying on OUIs for applying quirks. As well, some laptop vendors have confirmed to us that their panels have this exact issue. So, let's introduce the ability to apply DP quirks based on EDID identification. We reuse the same quirk bits for OUI-based quirks, so that callers can simply check all possible quirks using drm_dp_has_quirk(). Signed-off-by: Lyude Paul <lyude@redhat.com> Cc: Jani Nikula <jani.nikula@intel.com> Reviewed-by: Adam Jackson <ajax@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20200211183358.157448-2-lyude@redhat.com
Diffstat (limited to 'drivers/gpu/drm/drm_dp_helper.c')
-rw-r--r--drivers/gpu/drm/drm_dp_helper.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 5a103e9b3c86..db23308f4d8b 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -1221,6 +1221,67 @@ drm_dp_get_quirks(const struct drm_dp_dpcd_ident *ident, bool is_branch)
#undef DEVICE_ID_ANY
#undef DEVICE_ID
+struct edid_quirk {
+ u8 mfg_id[2];
+ u8 prod_id[2];
+ u32 quirks;
+};
+
+#define MFG(first, second) { (first), (second) }
+#define PROD_ID(first, second) { (first), (second) }
+
+/*
+ * Some devices have unreliable OUIDs where they don't set the device ID
+ * correctly, and as a result we need to use the EDID for finding additional
+ * DP quirks in such cases.
+ */
+static const struct edid_quirk edid_quirk_list[] = {
+};
+
+#undef MFG
+#undef PROD_ID
+
+/**
+ * drm_dp_get_edid_quirks() - Check the EDID of a DP device to find additional
+ * DP-specific quirks
+ * @edid: The EDID to check
+ *
+ * While OUIDs are meant to be used to recognize a DisplayPort device, a lot
+ * of manufacturers don't seem to like following standards and neglect to fill
+ * the dev-ID in, making it impossible to only use OUIDs for determining
+ * quirks in some cases. This function can be used to check the EDID and look
+ * up any additional DP quirks. The bits returned by this function correspond
+ * to the quirk bits in &drm_dp_quirk.
+ *
+ * Returns: a bitmask of quirks, if any. The driver can check this using
+ * drm_dp_has_quirk().
+ */
+u32 drm_dp_get_edid_quirks(const struct edid *edid)
+{
+ const struct edid_quirk *quirk;
+ u32 quirks = 0;
+ int i;
+
+ if (!edid)
+ return 0;
+
+ for (i = 0; i < ARRAY_SIZE(edid_quirk_list); i++) {
+ quirk = &edid_quirk_list[i];
+ if (memcmp(quirk->mfg_id, edid->mfg_id,
+ sizeof(edid->mfg_id)) == 0 &&
+ memcmp(quirk->prod_id, edid->prod_code,
+ sizeof(edid->prod_code)) == 0)
+ quirks |= quirk->quirks;
+ }
+
+ DRM_DEBUG_KMS("DP sink: EDID mfg %*phD prod-ID %*phD quirks: 0x%04x\n",
+ (int)sizeof(edid->mfg_id), edid->mfg_id,
+ (int)sizeof(edid->prod_code), edid->prod_code, quirks);
+
+ return quirks;
+}
+EXPORT_SYMBOL(drm_dp_get_edid_quirks);
+
/**
* drm_dp_read_desc - read sink/branch descriptor from DPCD
* @aux: DisplayPort AUX channel