Rockchip: linux: add patch to work arround CEC issues in dw-hdmi

This patch is no longer required for any of my devices (what it was
in previous kernel versions): as it seems to provide no harm and might
still be neccessary for other HDMI sinks I'm re-adding it here.
This commit is contained in:
Alex Bee 2021-03-07 19:30:59 +01:00
parent 845e6c61d7
commit 6c47c60b8a

View File

@ -741,3 +741,62 @@ index 1bb3f4a6e496..99f28dac0791 100644
&gpu {
mali-supply = <&vdd_logic>;
};
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jonas Karlman <jonas@kwiboo.se>
Date: Tue, 26 Feb 2019 20:45:14 +0000
Subject: [PATCH] WIP: dw-hdmi-cec: sleep 100ms on error
---
drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
index 70ab4fbdc23e..4dbc370e538f 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
@@ -4,6 +4,7 @@
*
* Copyright (C) 2015-2017 Russell King.
*/
+#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/module.h>
@@ -129,8 +130,15 @@ static irqreturn_t dw_hdmi_cec_hardirq(int irq, void *data)
dw_hdmi_write(cec, stat, HDMI_IH_CEC_STAT0);
- if (stat & CEC_STAT_ERROR_INIT) {
- cec->tx_status = CEC_TX_STATUS_ERROR;
+ /* Status with both done and error_initiator bits have been seen
+ * on Rockchip RK3328 devices, transmit attempt seems to have failed
+ * when this happens, report as low drive and block cec-framework
+ * 100ms before core retransmits the failed message, this seems to
+ * mitigate the issue with failed transmit attempts.
+ */
+ if ((stat & (CEC_STAT_DONE|CEC_STAT_ERROR_INIT)) == (CEC_STAT_DONE|CEC_STAT_ERROR_INIT)) {
+ pr_info("dw_hdmi_cec_hardirq: stat=%02x LOW_DRIVE\n", stat);
+ cec->tx_status = CEC_TX_STATUS_LOW_DRIVE;
cec->tx_done = true;
ret = IRQ_WAKE_THREAD;
} else if (stat & CEC_STAT_DONE) {
@@ -141,6 +149,10 @@ static irqreturn_t dw_hdmi_cec_hardirq(int irq, void *data)
cec->tx_status = CEC_TX_STATUS_NACK;
cec->tx_done = true;
ret = IRQ_WAKE_THREAD;
+ } else if (stat & CEC_STAT_ERROR_INIT) {
+ cec->tx_status = CEC_TX_STATUS_ERROR;
+ cec->tx_done = true;
+ ret = IRQ_WAKE_THREAD;
}
if (stat & CEC_STAT_EOM) {
@@ -173,6 +185,8 @@ static irqreturn_t dw_hdmi_cec_thread(int irq, void *data)
if (cec->tx_done) {
cec->tx_done = false;
+ if (cec->tx_status == CEC_TX_STATUS_LOW_DRIVE)
+ msleep(100);
cec_transmit_attempt_done(adap, cec->tx_status);
}
if (cec->rx_done) {