From 79475cde22c9b2d8ef84f68cbec27cacdf44ce3c Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Fri, 2 Sep 2022 14:51:09 +0200 Subject: [kernel-vanilla] Add patch for DP++ adapter detection --- core/modules/kernel-vanilla/module.build | 2 +- .../kernel-vanilla/patches/dp-detect-5.15.patch | 98 ++++++++++++++++++++++ 2 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 core/modules/kernel-vanilla/patches/dp-detect-5.15.patch (limited to 'core/modules/kernel-vanilla') diff --git a/core/modules/kernel-vanilla/module.build b/core/modules/kernel-vanilla/module.build index eb43e586..ec40e649 100644 --- a/core/modules/kernel-vanilla/module.build +++ b/core/modules/kernel-vanilla/module.build @@ -79,7 +79,7 @@ fetch_kernel_source() { # Other patches local patch cde "$MODULE_WORK_DIR/ksrc" - for patch in "${MODULE_DIR}/patches/"*; do + for patch in "${MODULE_DIR}/patches/"*${TARGET_KERNEL_SHORT%.*}*; do [ -f "$patch" ] || continue grep -q -F "$patch" "patches-done" && continue pinfo "Applying $(basename "$patch")" diff --git a/core/modules/kernel-vanilla/patches/dp-detect-5.15.patch b/core/modules/kernel-vanilla/patches/dp-detect-5.15.patch new file mode 100644 index 00000000..eaf0c9a0 --- /dev/null +++ b/core/modules/kernel-vanilla/patches/dp-detect-5.15.patch @@ -0,0 +1,98 @@ +diff --git a/drivers/gpu/drm/drm_dp_dual_mode_helper.c b/drivers/gpu/drm/drm_dp_dual_mode_helper.c +index 3ea53bb67..6147da983 100644 +--- a/drivers/gpu/drm/drm_dp_dual_mode_helper.c ++++ b/drivers/gpu/drm/drm_dp_dual_mode_helper.c +@@ -63,23 +63,42 @@ + ssize_t drm_dp_dual_mode_read(struct i2c_adapter *adapter, + u8 offset, void *buffer, size_t size) + { ++ int ret; ++ u8 zero = 0; ++ char *tmpbuf; ++ /* ++ * As sub-addressing is not supported by all adaptors, ++ * always explicitly read from the start and discard ++ * any bytes that come before the requested offset. ++ * This way, no matter whether the adaptor supports it ++ * or not, we'll end up reading the proper data. ++ */ + struct i2c_msg msgs[] = { + { + .addr = DP_DUAL_MODE_SLAVE_ADDRESS, + .flags = 0, + .len = 1, +- .buf = &offset, ++ .buf = &zero, + }, + { + .addr = DP_DUAL_MODE_SLAVE_ADDRESS, + .flags = I2C_M_RD, +- .len = size, +- .buf = buffer, ++ .len = size + offset, ++ .buf = NULL, + }, + }; +- int ret; + ++ tmpbuf = kmalloc(size + offset, GFP_KERNEL); ++ if (!tmpbuf) ++ return -ENOMEM; ++ ++ msgs[1].buf = tmpbuf; + ret = i2c_transfer(adapter, msgs, ARRAY_SIZE(msgs)); ++ if (ret == ARRAY_SIZE(msgs)) ++ memcpy(buffer, tmpbuf + offset, size); ++ ++ kfree(tmpbuf); ++ + if (ret < 0) + return ret; + if (ret != ARRAY_SIZE(msgs)) +@@ -208,18 +227,6 @@ enum drm_dp_dual_mode_type drm_dp_dual_mode_detect(const struct drm_device *dev, + if (ret) + return DRM_DP_DUAL_MODE_UNKNOWN; + +- /* +- * 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 +- * (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(adapter, DP_DUAL_MODE_ADAPTOR_ID, + &adaptor_id, sizeof(adaptor_id)); + drm_dbg_kms(dev, "DP dual mode adaptor ID: %02x (err %zd)\n", adaptor_id, ret); +@@ -233,11 +240,10 @@ enum drm_dp_dual_mode_type drm_dp_dual_mode_detect(const struct drm_device *dev, + return DRM_DP_DUAL_MODE_TYPE2_DVI; + } + /* +- * 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 not a proper type 1 ID, still 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(adaptor_id)) + drm_err(dev, "Unexpected DP dual mode adaptor ID %02x\n", adaptor_id); + + } +@@ -343,10 +349,8 @@ EXPORT_SYMBOL(drm_dp_dual_mode_get_tmds_output); + * @enable: enable (as opposed to disable) the TMDS output buffers + * + * Set the state of the TMDS output buffers in the adaptor. For +- * type2 this is set via the DP_DUAL_MODE_TMDS_OEN register. As +- * some type 1 adaptors have problems with registers (see comments +- * in drm_dp_dual_mode_detect()) we avoid touching the register, +- * making this function a no-op on type 1 adaptors. ++ * type2 this is set via the DP_DUAL_MODE_TMDS_OEN register. ++ * Type1 adaptors do not support any register writes. + * + * Returns: + * 0 on success, negative error code on failure -- cgit v1.2.3-55-g7522