Reviewed-by: Daniel Vetter <daniel.vet...@ffwll.ch>
Signed-off-by: Jani Nikula <jani.nik...@intel.com>
---
 drivers/gpu/drm/drm_dp_helper.c | 35 +++++++++++++++++++++++++++++++++++
 include/drm/drm_dp_helper.h     | 19 +++++++++++++++++++
 2 files changed, 54 insertions(+)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 3e5f52110ea1..52e0ca9a5bb1 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -1208,3 +1208,38 @@ int drm_dp_stop_crc(struct drm_dp_aux *aux)
        return 0;
 }
 EXPORT_SYMBOL(drm_dp_stop_crc);
+
+/**
+ * drm_dp_read_desc - read sink/branch descriptor from DPCD
+ * @aux: DisplayPort AUX channel
+ * @desc: Device decriptor to fill from DPCD
+ * @is_branch: true for branch devices, false for sink devices
+ *
+ * Read DPCD 0x400 (sink) or 0x500 (branch) into @desc. Also debug log the
+ * identification.
+ *
+ * Returns 0 on success or a negative error code on failure.
+ */
+int drm_dp_read_desc(struct drm_dp_aux *aux, struct drm_dp_desc *desc,
+                    bool is_branch)
+{
+       struct drm_dp_dpcd_ident *ident = &desc->ident;
+       unsigned int offset = is_branch ? DP_BRANCH_OUI : DP_SINK_OUI;
+       int ret, dev_id_len;
+
+       ret = drm_dp_dpcd_read(aux, offset, ident, sizeof(*ident));
+       if (ret < 0)
+               return ret;
+
+       dev_id_len = strnlen(ident->device_id, sizeof(ident->device_id));
+
+       DRM_DEBUG_KMS("DP %s: OUI %*phD dev-ID %*pE HW-rev %d.%d SW-rev 
%d.%d\n",
+                     is_branch ? "branch" : "sink",
+                     (int)sizeof(ident->oui), ident->oui,
+                     dev_id_len, ident->device_id,
+                     ident->hw_rev >> 4, ident->hw_rev & 0xf,
+                     ident->sw_major_rev, ident->sw_minor_rev);
+
+       return 0;
+}
+EXPORT_SYMBOL(drm_dp_read_desc);
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index f7007e544f29..aee5b96b51d7 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -1079,4 +1079,23 @@ void drm_dp_aux_unregister(struct drm_dp_aux *aux);
 int drm_dp_start_crc(struct drm_dp_aux *aux, struct drm_crtc *crtc);
 int drm_dp_stop_crc(struct drm_dp_aux *aux);
 
+struct drm_dp_dpcd_ident {
+       u8 oui[3];
+       u8 device_id[6];
+       u8 hw_rev;
+       u8 sw_major_rev;
+       u8 sw_minor_rev;
+} __packed;
+
+/**
+ * struct drm_dp_desc - DP branch/sink device descriptor
+ * @ident: DP device identification from DPCD 0x400 (sink) or 0x500 (branch).
+ */
+struct drm_dp_desc {
+       struct drm_dp_dpcd_ident ident;
+};
+
+int drm_dp_read_desc(struct drm_dp_aux *aux, struct drm_dp_desc *desc,
+                    bool is_branch);
+
 #endif /* _DRM_DP_HELPER_H_ */
-- 
2.11.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to