[PATCH 2/6] drm: Factor out drm_dp_dual_mode_read_regs()
Imre Deak
imre.deak at intel.com
Wed Nov 16 20:44:06 UTC 2016
In follow-up patches we'll read out more registers and add a new step to
read them out in one go, so factor out the read-out part to keep things
clean at the end.
Cc: Ville Syrjälä <ville.syrjala at linux.intel.com>
Cc: dri-devel at lists.freedesktop.org
Signed-off-by: Imre Deak <imre.deak at intel.com>
---
drivers/gpu/drm/drm_dp_dual_mode_helper.c | 91 +++++++++++++++++++------------
include/drm/drm_dp_dual_mode_helper.h | 5 ++
2 files changed, 60 insertions(+), 36 deletions(-)
diff --git a/drivers/gpu/drm/drm_dp_dual_mode_helper.c b/drivers/gpu/drm/drm_dp_dual_mode_helper.c
index 1764203..1cb6c15 100644
--- a/drivers/gpu/drm/drm_dp_dual_mode_helper.c
+++ b/drivers/gpu/drm/drm_dp_dual_mode_helper.c
@@ -161,6 +161,39 @@ static bool is_lspcon_adaptor(const char hdmi_id[DP_DUAL_MODE_HDMI_ID_LEN],
DP_DUAL_MODE_TYPE_HAS_DPCD));
}
+static int drm_dp_dual_mode_read_regs(struct drm_dp_dual_mode_adaptor *adaptor)
+{
+ struct drm_dp_dual_mode_regs *regs = &adaptor->regs;
+ ssize_t ret;
+
+ ret = drm_dp_dual_mode_read(adaptor, DP_DUAL_MODE_HDMI_ID,
+ regs->hdmi_id, sizeof(regs->hdmi_id));
+ if (ret) {
+ DRM_DEBUG_KMS("Failed to read HDMI ID (%zd)\n", ret);
+ memset(regs, 0, sizeof(*regs));
+ return ret;
+ }
+
+ /*
+ * Sigh. Some (maybe all?) type 1 adaptors are broken and ack
+ * the offset but ignore it, and instead they just always return
+ * data from the start of the HDMI ID buffer.
+ */
+ ret = drm_dp_dual_mode_read(adaptor, DP_DUAL_MODE_ADAPTOR_ID,
+ ®s->adaptor_id,
+ sizeof(regs->adaptor_id));
+ if (ret) {
+ DRM_DEBUG_KMS("Failed to read adaptor ID (%zd)\n", ret);
+ regs->adaptor_id = 0;
+ }
+
+ DRM_DEBUG_KMS("DP dual-mode: HDMI-ID %*pE adaptor-ID %#02x\n",
+ (int)sizeof(regs->hdmi_id), regs->hdmi_id,
+ regs->adaptor_id);
+
+ return 0;
+}
+
/**
* drm_dp_dual_mode_detect - Identify the DP dual mode adaptor
* @adaptor: DP dual mode adaptor
@@ -180,9 +213,7 @@ static bool is_lspcon_adaptor(const char hdmi_id[DP_DUAL_MODE_HDMI_ID_LEN],
void drm_dp_dual_mode_detect(struct drm_dp_dual_mode_adaptor *adaptor,
struct i2c_adapter *i2c_adapter)
{
- char hdmi_id[DP_DUAL_MODE_HDMI_ID_LEN] = {};
- uint8_t adaptor_id = 0x00;
- ssize_t ret;
+ struct drm_dp_dual_mode_regs *regs;
adaptor->i2c_adapter = i2c_adapter;
adaptor->type = DRM_DP_DUAL_MODE_UNKNOWN;
@@ -201,56 +232,44 @@ void drm_dp_dual_mode_detect(struct drm_dp_dual_mode_adaptor *adaptor,
* port or a native HDMI port. Both of these methods are entirely
* hardware/driver specific so we can't deal with them here.
*/
- ret = drm_dp_dual_mode_read(adaptor, DP_DUAL_MODE_HDMI_ID,
- hdmi_id, sizeof(hdmi_id));
- DRM_DEBUG_KMS("DP dual mode HDMI ID: %*pE (err %zd)\n",
- ret ? 0 : (int)sizeof(hdmi_id), hdmi_id, ret);
- if (ret)
+ if (drm_dp_dual_mode_read_regs(adaptor))
return;
+ regs = &adaptor->regs;
/*
- * Sigh. Some (maybe all?) type 1 adaptors are broken and ack
- * the offset but ignore it, and instead they just always return
- * data from the start of the HDMI ID buffer. So for a broken
- * type 1 HDMI adaptor a single byte read will always give us
- * 0x44, and for a type 1 DVI adaptor it should give 0x00
+ * As noted in drm_dp_dual_mode_read_regs() on a broken type1
+ * HDMI adaptor a single byte read of the
+ * DP_DUAL_MODE_ADAPTOR_ID register will always give us 0x44,
+ * and for a type 1 DVI adaptor it should give 0x00
* (assuming it implements any registers). Fortunately neither
* of those values will match the type 2 signature of the
* DP_DUAL_MODE_ADAPTOR_ID register so we can proceed with
* the type 2 adaptor detection safely even in the presence
* of broken type 1 adaptors.
*/
- ret = drm_dp_dual_mode_read(adaptor, DP_DUAL_MODE_ADAPTOR_ID,
- &adaptor_id, sizeof(adaptor_id));
- DRM_DEBUG_KMS("DP dual mode adaptor ID: %02x (err %zd)\n",
- adaptor_id, ret);
- if (ret == 0) {
- if (is_lspcon_adaptor(hdmi_id, adaptor_id)) {
- adaptor->type = DRM_DP_DUAL_MODE_LSPCON;
- return;
- }
- if (is_type2_adaptor(adaptor_id)) {
- if (is_hdmi_adaptor(hdmi_id))
- adaptor->type = DRM_DP_DUAL_MODE_TYPE2_HDMI;
- else
- adaptor->type = DRM_DP_DUAL_MODE_TYPE2_DVI;
- return;
- }
+ if (is_lspcon_adaptor(regs->hdmi_id, regs->adaptor_id)) {
+ adaptor->type = DRM_DP_DUAL_MODE_LSPCON;
+ } else if (is_type2_adaptor(regs->adaptor_id)) {
+ if (is_hdmi_adaptor(regs->hdmi_id))
+ adaptor->type = DRM_DP_DUAL_MODE_TYPE2_HDMI;
+ else
+ adaptor->type = DRM_DP_DUAL_MODE_TYPE2_DVI;
+ } else {
/*
* If neither a proper type 1 ID nor a broken type 1 adaptor
* as described above, assume type 1, but let the user know
* that we may have misdetected the type.
*/
- if (!is_type1_adaptor(adaptor_id) && adaptor_id != hdmi_id[0])
+ if (!is_type1_adaptor(regs->adaptor_id) &&
+ regs->adaptor_id != regs->hdmi_id[0])
DRM_ERROR("Unexpected DP dual mode adaptor ID %02x\n",
- adaptor_id);
+ regs->adaptor_id);
+ if (is_hdmi_adaptor(regs->hdmi_id))
+ adaptor->type = DRM_DP_DUAL_MODE_TYPE1_HDMI;
+ else
+ adaptor->type = DRM_DP_DUAL_MODE_TYPE1_DVI;
}
-
- if (is_hdmi_adaptor(hdmi_id))
- adaptor->type = DRM_DP_DUAL_MODE_TYPE1_HDMI;
- else
- adaptor->type = DRM_DP_DUAL_MODE_TYPE1_DVI;
}
EXPORT_SYMBOL(drm_dp_dual_mode_detect);
diff --git a/include/drm/drm_dp_dual_mode_helper.h b/include/drm/drm_dp_dual_mode_helper.h
index a804d36..1436067 100644
--- a/include/drm/drm_dp_dual_mode_helper.h
+++ b/include/drm/drm_dp_dual_mode_helper.h
@@ -101,6 +101,11 @@ struct i2c_adapter;
struct drm_dp_dual_mode_adaptor {
enum drm_dp_dual_mode_type type;
struct i2c_adapter *i2c_adapter;
+
+ struct drm_dp_dual_mode_regs {
+ uint8_t hdmi_id[16];
+ uint8_t adaptor_id;
+ } regs;
};
void drm_dp_dual_mode_detect(struct drm_dp_dual_mode_adaptor *adaptor,
--
2.5.0
More information about the Intel-gfx-trybot
mailing list