summaryrefslogtreecommitdiffstats
path: root/core/modules/kernel-vanilla
diff options
context:
space:
mode:
authorSimon Rettberg2022-09-02 14:51:09 +0200
committerSimon Rettberg2022-09-02 14:51:09 +0200
commit79475cde22c9b2d8ef84f68cbec27cacdf44ce3c (patch)
tree288f5e8f0b0b027c8b09e509fdc4d35978bf5d76 /core/modules/kernel-vanilla
parent[run-virt] Linux script starter: +DISPL +XAUTH f. hidden scripts (diff)
downloadmltk-79475cde22c9b2d8ef84f68cbec27cacdf44ce3c.tar.gz
mltk-79475cde22c9b2d8ef84f68cbec27cacdf44ce3c.tar.xz
mltk-79475cde22c9b2d8ef84f68cbec27cacdf44ce3c.zip
[kernel-vanilla] Add patch for DP++ adapter detection
Diffstat (limited to 'core/modules/kernel-vanilla')
-rw-r--r--core/modules/kernel-vanilla/module.build2
-rw-r--r--core/modules/kernel-vanilla/patches/dp-detect-5.15.patch98
2 files changed, 99 insertions, 1 deletions
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