forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-31 f70575805708cabdedea7498aaa3f710fde4d920
kernel/drivers/gpu/drm/drm_dp_dual_mode_helper.c
....@@ -20,13 +20,15 @@
2020 * OTHER DEALINGS IN THE SOFTWARE.
2121 */
2222
23
+#include <linux/delay.h>
2324 #include <linux/errno.h>
2425 #include <linux/export.h>
2526 #include <linux/i2c.h>
2627 #include <linux/slab.h>
2728 #include <linux/string.h>
29
+
2830 #include <drm/drm_dp_dual_mode_helper.h>
29
-#include <drm/drmP.h>
31
+#include <drm/drm_print.h>
3032
3133 /**
3234 * DOC: dp dual mode helpers
....@@ -60,23 +62,45 @@
6062 ssize_t drm_dp_dual_mode_read(struct i2c_adapter *adapter,
6163 u8 offset, void *buffer, size_t size)
6264 {
65
+ u8 zero = 0;
66
+ char *tmpbuf = NULL;
67
+ /*
68
+ * As sub-addressing is not supported by all adaptors,
69
+ * always explicitly read from the start and discard
70
+ * any bytes that come before the requested offset.
71
+ * This way, no matter whether the adaptor supports it
72
+ * or not, we'll end up reading the proper data.
73
+ */
6374 struct i2c_msg msgs[] = {
6475 {
6576 .addr = DP_DUAL_MODE_SLAVE_ADDRESS,
6677 .flags = 0,
6778 .len = 1,
68
- .buf = &offset,
79
+ .buf = &zero,
6980 },
7081 {
7182 .addr = DP_DUAL_MODE_SLAVE_ADDRESS,
7283 .flags = I2C_M_RD,
73
- .len = size,
84
+ .len = size + offset,
7485 .buf = buffer,
7586 },
7687 };
7788 int ret;
7889
90
+ if (offset) {
91
+ tmpbuf = kmalloc(size + offset, GFP_KERNEL);
92
+ if (!tmpbuf)
93
+ return -ENOMEM;
94
+
95
+ msgs[1].buf = tmpbuf;
96
+ }
97
+
7998 ret = i2c_transfer(adapter, msgs, ARRAY_SIZE(msgs));
99
+ if (tmpbuf)
100
+ memcpy(buffer, tmpbuf + offset, size);
101
+
102
+ kfree(tmpbuf);
103
+
80104 if (ret < 0)
81105 return ret;
82106 if (ret != ARRAY_SIZE(msgs))
....@@ -203,18 +227,6 @@
203227 if (ret)
204228 return DRM_DP_DUAL_MODE_UNKNOWN;
205229
206
- /*
207
- * Sigh. Some (maybe all?) type 1 adaptors are broken and ack
208
- * the offset but ignore it, and instead they just always return
209
- * data from the start of the HDMI ID buffer. So for a broken
210
- * type 1 HDMI adaptor a single byte read will always give us
211
- * 0x44, and for a type 1 DVI adaptor it should give 0x00
212
- * (assuming it implements any registers). Fortunately neither
213
- * of those values will match the type 2 signature of the
214
- * DP_DUAL_MODE_ADAPTOR_ID register so we can proceed with
215
- * the type 2 adaptor detection safely even in the presence
216
- * of broken type 1 adaptors.
217
- */
218230 ret = drm_dp_dual_mode_read(adapter, DP_DUAL_MODE_ADAPTOR_ID,
219231 &adaptor_id, sizeof(adaptor_id));
220232 DRM_DEBUG_KMS("DP dual mode adaptor ID: %02x (err %zd)\n",
....@@ -229,11 +241,10 @@
229241 return DRM_DP_DUAL_MODE_TYPE2_DVI;
230242 }
231243 /*
232
- * If neither a proper type 1 ID nor a broken type 1 adaptor
233
- * as described above, assume type 1, but let the user know
234
- * that we may have misdetected the type.
244
+ * If not a proper type 1 ID, still assume type 1, but let
245
+ * the user know that we may have misdetected the type.
235246 */
236
- if (!is_type1_adaptor(adaptor_id) && adaptor_id != hdmi_id[0])
247
+ if (!is_type1_adaptor(adaptor_id))
237248 DRM_ERROR("Unexpected DP dual mode adaptor ID %02x\n",
238249 adaptor_id);
239250
....@@ -337,10 +348,8 @@
337348 * @enable: enable (as opposed to disable) the TMDS output buffers
338349 *
339350 * Set the state of the TMDS output buffers in the adaptor. For
340
- * type2 this is set via the DP_DUAL_MODE_TMDS_OEN register. As
341
- * some type 1 adaptors have problems with registers (see comments
342
- * in drm_dp_dual_mode_detect()) we avoid touching the register,
343
- * making this function a no-op on type 1 adaptors.
351
+ * type2 this is set via the DP_DUAL_MODE_TMDS_OEN register.
352
+ * Type1 adaptors do not support any register writes.
344353 *
345354 * Returns:
346355 * 0 on success, negative error code on failure