All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] dw-hdmi CEC support
@ 2017-05-30 14:22 ` Russell King - ARM Linux
  0 siblings, 0 replies; 84+ messages in thread
From: Russell King - ARM Linux @ 2017-05-30 14:22 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

This series adds dw-hdmi CEC support.  This is done in four stages:

1. Remove definitions that are not required from dw-hdmi.h
2. Add cec-notifier support
3. Fix up the clkdis register support, as this register contains a
   clock disable bit for the CEC module.
4. Add the driver.

The CEC driver has been updated to use the register accessors in the
main driver - it would be nice if it was possible to use the regmap
support directly, but there's some knowledge private to the main
driver that's required to correctly access the registers.  (I don't
understand why the register stride isn't part of regmap.)

 drivers/gpu/drm/bridge/synopsys/Kconfig       |   8 +
 drivers/gpu/drm/bridge/synopsys/Makefile      |   1 +
 drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 320 ++++++++++++++++++++++++++
 drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h |  19 ++
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c     |  87 ++++++-
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.h     |  45 ----
 6 files changed, 423 insertions(+), 57 deletions(-)

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 0/4] dw-hdmi CEC support
@ 2017-05-30 14:22 ` Russell King - ARM Linux
  0 siblings, 0 replies; 84+ messages in thread
From: Russell King - ARM Linux @ 2017-05-30 14:22 UTC (permalink / raw)
  To: Hans Verkuil; +Cc: David Airlie, Archit Taneja, linux-arm-kernel, dri-devel

Hi,

This series adds dw-hdmi CEC support.  This is done in four stages:

1. Remove definitions that are not required from dw-hdmi.h
2. Add cec-notifier support
3. Fix up the clkdis register support, as this register contains a
   clock disable bit for the CEC module.
4. Add the driver.

The CEC driver has been updated to use the register accessors in the
main driver - it would be nice if it was possible to use the regmap
support directly, but there's some knowledge private to the main
driver that's required to correctly access the registers.  (I don't
understand why the register stride isn't part of regmap.)

 drivers/gpu/drm/bridge/synopsys/Kconfig       |   8 +
 drivers/gpu/drm/bridge/synopsys/Makefile      |   1 +
 drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 320 ++++++++++++++++++++++++++
 drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h |  19 ++
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c     |  87 ++++++-
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.h     |  45 ----
 6 files changed, 423 insertions(+), 57 deletions(-)

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 1/4] drm/bridge: dw-hdmi: remove CEC engine register definitions
  2017-05-30 14:22 ` Russell King - ARM Linux
@ 2017-05-30 14:23   ` Russell King
  -1 siblings, 0 replies; 84+ messages in thread
From: Russell King @ 2017-05-30 14:23 UTC (permalink / raw)
  To: linux-arm-kernel

We don't need the CEC engine register definitions, so let's remove them.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.h | 45 -------------------------------
 1 file changed, 45 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
index c59f87e1483e..091831e4f9d5 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
@@ -478,51 +478,6 @@
 #define HDMI_A_PRESETUP                         0x501A
 #define HDMI_A_SRM_BASE                         0x5020
 
-/* CEC Engine Registers */
-#define HDMI_CEC_CTRL                           0x7D00
-#define HDMI_CEC_STAT                           0x7D01
-#define HDMI_CEC_MASK                           0x7D02
-#define HDMI_CEC_POLARITY                       0x7D03
-#define HDMI_CEC_INT                            0x7D04
-#define HDMI_CEC_ADDR_L                         0x7D05
-#define HDMI_CEC_ADDR_H                         0x7D06
-#define HDMI_CEC_TX_CNT                         0x7D07
-#define HDMI_CEC_RX_CNT                         0x7D08
-#define HDMI_CEC_TX_DATA0                       0x7D10
-#define HDMI_CEC_TX_DATA1                       0x7D11
-#define HDMI_CEC_TX_DATA2                       0x7D12
-#define HDMI_CEC_TX_DATA3                       0x7D13
-#define HDMI_CEC_TX_DATA4                       0x7D14
-#define HDMI_CEC_TX_DATA5                       0x7D15
-#define HDMI_CEC_TX_DATA6                       0x7D16
-#define HDMI_CEC_TX_DATA7                       0x7D17
-#define HDMI_CEC_TX_DATA8                       0x7D18
-#define HDMI_CEC_TX_DATA9                       0x7D19
-#define HDMI_CEC_TX_DATA10                      0x7D1a
-#define HDMI_CEC_TX_DATA11                      0x7D1b
-#define HDMI_CEC_TX_DATA12                      0x7D1c
-#define HDMI_CEC_TX_DATA13                      0x7D1d
-#define HDMI_CEC_TX_DATA14                      0x7D1e
-#define HDMI_CEC_TX_DATA15                      0x7D1f
-#define HDMI_CEC_RX_DATA0                       0x7D20
-#define HDMI_CEC_RX_DATA1                       0x7D21
-#define HDMI_CEC_RX_DATA2                       0x7D22
-#define HDMI_CEC_RX_DATA3                       0x7D23
-#define HDMI_CEC_RX_DATA4                       0x7D24
-#define HDMI_CEC_RX_DATA5                       0x7D25
-#define HDMI_CEC_RX_DATA6                       0x7D26
-#define HDMI_CEC_RX_DATA7                       0x7D27
-#define HDMI_CEC_RX_DATA8                       0x7D28
-#define HDMI_CEC_RX_DATA9                       0x7D29
-#define HDMI_CEC_RX_DATA10                      0x7D2a
-#define HDMI_CEC_RX_DATA11                      0x7D2b
-#define HDMI_CEC_RX_DATA12                      0x7D2c
-#define HDMI_CEC_RX_DATA13                      0x7D2d
-#define HDMI_CEC_RX_DATA14                      0x7D2e
-#define HDMI_CEC_RX_DATA15                      0x7D2f
-#define HDMI_CEC_LOCK                           0x7D30
-#define HDMI_CEC_WKUPCTRL                       0x7D31
-
 /* I2C Master Registers (E-DDC) */
 #define HDMI_I2CM_SLAVE                         0x7E00
 #define HDMI_I2CM_ADDRESS                       0x7E01
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH 1/4] drm/bridge: dw-hdmi: remove CEC engine register definitions
@ 2017-05-30 14:23   ` Russell King
  0 siblings, 0 replies; 84+ messages in thread
From: Russell King @ 2017-05-30 14:23 UTC (permalink / raw)
  To: Hans Verkuil; +Cc: David Airlie, Archit Taneja, dri-devel, linux-arm-kernel

We don't need the CEC engine register definitions, so let's remove them.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.h | 45 -------------------------------
 1 file changed, 45 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
index c59f87e1483e..091831e4f9d5 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
@@ -478,51 +478,6 @@
 #define HDMI_A_PRESETUP                         0x501A
 #define HDMI_A_SRM_BASE                         0x5020
 
-/* CEC Engine Registers */
-#define HDMI_CEC_CTRL                           0x7D00
-#define HDMI_CEC_STAT                           0x7D01
-#define HDMI_CEC_MASK                           0x7D02
-#define HDMI_CEC_POLARITY                       0x7D03
-#define HDMI_CEC_INT                            0x7D04
-#define HDMI_CEC_ADDR_L                         0x7D05
-#define HDMI_CEC_ADDR_H                         0x7D06
-#define HDMI_CEC_TX_CNT                         0x7D07
-#define HDMI_CEC_RX_CNT                         0x7D08
-#define HDMI_CEC_TX_DATA0                       0x7D10
-#define HDMI_CEC_TX_DATA1                       0x7D11
-#define HDMI_CEC_TX_DATA2                       0x7D12
-#define HDMI_CEC_TX_DATA3                       0x7D13
-#define HDMI_CEC_TX_DATA4                       0x7D14
-#define HDMI_CEC_TX_DATA5                       0x7D15
-#define HDMI_CEC_TX_DATA6                       0x7D16
-#define HDMI_CEC_TX_DATA7                       0x7D17
-#define HDMI_CEC_TX_DATA8                       0x7D18
-#define HDMI_CEC_TX_DATA9                       0x7D19
-#define HDMI_CEC_TX_DATA10                      0x7D1a
-#define HDMI_CEC_TX_DATA11                      0x7D1b
-#define HDMI_CEC_TX_DATA12                      0x7D1c
-#define HDMI_CEC_TX_DATA13                      0x7D1d
-#define HDMI_CEC_TX_DATA14                      0x7D1e
-#define HDMI_CEC_TX_DATA15                      0x7D1f
-#define HDMI_CEC_RX_DATA0                       0x7D20
-#define HDMI_CEC_RX_DATA1                       0x7D21
-#define HDMI_CEC_RX_DATA2                       0x7D22
-#define HDMI_CEC_RX_DATA3                       0x7D23
-#define HDMI_CEC_RX_DATA4                       0x7D24
-#define HDMI_CEC_RX_DATA5                       0x7D25
-#define HDMI_CEC_RX_DATA6                       0x7D26
-#define HDMI_CEC_RX_DATA7                       0x7D27
-#define HDMI_CEC_RX_DATA8                       0x7D28
-#define HDMI_CEC_RX_DATA9                       0x7D29
-#define HDMI_CEC_RX_DATA10                      0x7D2a
-#define HDMI_CEC_RX_DATA11                      0x7D2b
-#define HDMI_CEC_RX_DATA12                      0x7D2c
-#define HDMI_CEC_RX_DATA13                      0x7D2d
-#define HDMI_CEC_RX_DATA14                      0x7D2e
-#define HDMI_CEC_RX_DATA15                      0x7D2f
-#define HDMI_CEC_LOCK                           0x7D30
-#define HDMI_CEC_WKUPCTRL                       0x7D31
-
 /* I2C Master Registers (E-DDC) */
 #define HDMI_I2CM_SLAVE                         0x7E00
 #define HDMI_I2CM_ADDRESS                       0x7E01
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH 2/4] drm/bridge: dw-hdmi: add cec notifier support
  2017-05-30 14:22 ` Russell King - ARM Linux
@ 2017-05-30 14:23   ` Russell King
  -1 siblings, 0 replies; 84+ messages in thread
From: Russell King @ 2017-05-30 14:23 UTC (permalink / raw)
  To: linux-arm-kernel

Add CEC notifier support to the HDMI bridge driver, so that the CEC
part of the IP can receive its physical address.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 4e1f54a675d8..966422576c44 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -36,7 +36,10 @@
 #include "dw-hdmi.h"
 #include "dw-hdmi-audio.h"
 
+#include <media/cec-notifier.h>
+
 #define DDC_SEGMENT_ADDR	0x30
+
 #define HDMI_EDID_LEN		512
 
 enum hdmi_datamap {
@@ -173,6 +176,8 @@ struct dw_hdmi {
 
 	unsigned int reg_shift;
 	struct regmap *regm;
+
+	struct cec_notifier *cec_notifier;
 };
 
 #define HDMI_IH_PHY_STAT0_RX_SENSE \
@@ -1870,6 +1875,7 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
 		hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
 		hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
 		drm_mode_connector_update_edid_property(connector, edid);
+		cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
 		ret = drm_add_edid_modes(connector, edid);
 		/* Store the ELD */
 		drm_edid_to_eld(connector, edid);
@@ -2108,11 +2114,16 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
 	 * ask the source to re-read the EDID.
 	 */
 	if (intr_stat &
-	    (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD))
+	    (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) {
 		__dw_hdmi_setup_rx_sense(hdmi,
 					 phy_stat & HDMI_PHY_HPD,
 					 phy_stat & HDMI_PHY_RX_SENSE);
 
+		if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0)
+			cec_notifier_set_phys_addr(hdmi->cec_notifier,
+						   CEC_PHYS_ADDR_INVALID);
+	}
+
 	if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
 		dev_dbg(hdmi->dev, "EVENT=%s\n",
 			phy_int_pol & HDMI_PHY_HPD ? "plugin" : "plugout");
@@ -2365,6 +2376,12 @@ __dw_hdmi_probe(struct platform_device *pdev,
 	if (ret)
 		goto err_iahb;
 
+	hdmi->cec_notifier = cec_notifier_get(dev);
+	if (!hdmi->cec_notifier) {
+		ret = -ENOMEM;
+		goto err_iahb;
+	}
+
 	/*
 	 * To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator
 	 * N and cts values before enabling phy
@@ -2437,6 +2454,9 @@ __dw_hdmi_probe(struct platform_device *pdev,
 		hdmi->ddc = NULL;
 	}
 
+	if (hdmi->cec_notifier)
+		cec_notifier_put(hdmi->cec_notifier);
+
 	clk_disable_unprepare(hdmi->iahb_clk);
 err_isfr:
 	clk_disable_unprepare(hdmi->isfr_clk);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH 2/4] drm/bridge: dw-hdmi: add cec notifier support
@ 2017-05-30 14:23   ` Russell King
  0 siblings, 0 replies; 84+ messages in thread
From: Russell King @ 2017-05-30 14:23 UTC (permalink / raw)
  To: Hans Verkuil; +Cc: David Airlie, Archit Taneja, dri-devel, linux-arm-kernel

Add CEC notifier support to the HDMI bridge driver, so that the CEC
part of the IP can receive its physical address.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 4e1f54a675d8..966422576c44 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -36,7 +36,10 @@
 #include "dw-hdmi.h"
 #include "dw-hdmi-audio.h"
 
+#include <media/cec-notifier.h>
+
 #define DDC_SEGMENT_ADDR	0x30
+
 #define HDMI_EDID_LEN		512
 
 enum hdmi_datamap {
@@ -173,6 +176,8 @@ struct dw_hdmi {
 
 	unsigned int reg_shift;
 	struct regmap *regm;
+
+	struct cec_notifier *cec_notifier;
 };
 
 #define HDMI_IH_PHY_STAT0_RX_SENSE \
@@ -1870,6 +1875,7 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
 		hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
 		hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
 		drm_mode_connector_update_edid_property(connector, edid);
+		cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
 		ret = drm_add_edid_modes(connector, edid);
 		/* Store the ELD */
 		drm_edid_to_eld(connector, edid);
@@ -2108,11 +2114,16 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
 	 * ask the source to re-read the EDID.
 	 */
 	if (intr_stat &
-	    (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD))
+	    (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) {
 		__dw_hdmi_setup_rx_sense(hdmi,
 					 phy_stat & HDMI_PHY_HPD,
 					 phy_stat & HDMI_PHY_RX_SENSE);
 
+		if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0)
+			cec_notifier_set_phys_addr(hdmi->cec_notifier,
+						   CEC_PHYS_ADDR_INVALID);
+	}
+
 	if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
 		dev_dbg(hdmi->dev, "EVENT=%s\n",
 			phy_int_pol & HDMI_PHY_HPD ? "plugin" : "plugout");
@@ -2365,6 +2376,12 @@ __dw_hdmi_probe(struct platform_device *pdev,
 	if (ret)
 		goto err_iahb;
 
+	hdmi->cec_notifier = cec_notifier_get(dev);
+	if (!hdmi->cec_notifier) {
+		ret = -ENOMEM;
+		goto err_iahb;
+	}
+
 	/*
 	 * To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator
 	 * N and cts values before enabling phy
@@ -2437,6 +2454,9 @@ __dw_hdmi_probe(struct platform_device *pdev,
 		hdmi->ddc = NULL;
 	}
 
+	if (hdmi->cec_notifier)
+		cec_notifier_put(hdmi->cec_notifier);
+
 	clk_disable_unprepare(hdmi->iahb_clk);
 err_isfr:
 	clk_disable_unprepare(hdmi->isfr_clk);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH 3/4] drm/bridge: dw-hdmi: add better clock disable control
  2017-05-30 14:22 ` Russell King - ARM Linux
@ 2017-05-30 14:23   ` Russell King
  -1 siblings, 0 replies; 84+ messages in thread
From: Russell King @ 2017-05-30 14:23 UTC (permalink / raw)
  To: linux-arm-kernel

The video setup path aways sets the clock disable register to a specific
value, which has the effect of disabling the CEC engine.  When we add the
CEC driver, this becomes a problem.

Fix this by only setting/clearing the bits that the video path needs to.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 966422576c44..58781d4c1034 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -166,6 +166,7 @@ struct dw_hdmi {
 	bool bridge_is_on;		/* indicates the bridge is on */
 	bool rxsense;			/* rxsense state */
 	u8 phy_mask;			/* desired phy int mask settings */
+	u8 mc_clkdis;			/* clock disable register */
 
 	spinlock_t audio_lock;
 	struct mutex audio_mutex;
@@ -1543,8 +1544,6 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
 /* HDMI Initialization Step B.4 */
 static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
 {
-	u8 clkdis;
-
 	/* control period minimum duration */
 	hdmi_writeb(hdmi, 12, HDMI_FC_CTRLDUR);
 	hdmi_writeb(hdmi, 32, HDMI_FC_EXCTRLDUR);
@@ -1556,17 +1555,21 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
 	hdmi_writeb(hdmi, 0x21, HDMI_FC_CH2PREAM);
 
 	/* Enable pixel clock and tmds data path */
-	clkdis = 0x7F;
-	clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
-	hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
+	hdmi->mc_clkdis |= HDMI_MC_CLKDIS_HDCPCLK_DISABLE |
+			   HDMI_MC_CLKDIS_CSCCLK_DISABLE |
+			   HDMI_MC_CLKDIS_AUDCLK_DISABLE |
+			   HDMI_MC_CLKDIS_PREPCLK_DISABLE |
+			   HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
+	hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
+	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
 
-	clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
-	hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
+	hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
+	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
 
 	/* Enable csc path */
 	if (is_color_space_conversion(hdmi)) {
-		clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
-		hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
+		hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
+		hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
 	}
 
 	/* Enable color space conversion if needed */
@@ -1580,7 +1583,8 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
 
 static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi)
 {
-	hdmi_modb(hdmi, 0, HDMI_MC_CLKDIS_AUDCLK_DISABLE, HDMI_MC_CLKDIS);
+	hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_AUDCLK_DISABLE;
+	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
 }
 
 /* Workaround to clear the overflow condition */
@@ -2261,6 +2265,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
 	hdmi->disabled = true;
 	hdmi->rxsense = true;
 	hdmi->phy_mask = (u8)~(HDMI_PHY_HPD | HDMI_PHY_RX_SENSE);
+	hdmi->mc_clkdis = 0x7f;
 
 	mutex_init(&hdmi->mutex);
 	mutex_init(&hdmi->audio_mutex);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH 3/4] drm/bridge: dw-hdmi: add better clock disable control
@ 2017-05-30 14:23   ` Russell King
  0 siblings, 0 replies; 84+ messages in thread
From: Russell King @ 2017-05-30 14:23 UTC (permalink / raw)
  To: Hans Verkuil; +Cc: David Airlie, Archit Taneja, dri-devel, linux-arm-kernel

The video setup path aways sets the clock disable register to a specific
value, which has the effect of disabling the CEC engine.  When we add the
CEC driver, this becomes a problem.

Fix this by only setting/clearing the bits that the video path needs to.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 966422576c44..58781d4c1034 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -166,6 +166,7 @@ struct dw_hdmi {
 	bool bridge_is_on;		/* indicates the bridge is on */
 	bool rxsense;			/* rxsense state */
 	u8 phy_mask;			/* desired phy int mask settings */
+	u8 mc_clkdis;			/* clock disable register */
 
 	spinlock_t audio_lock;
 	struct mutex audio_mutex;
@@ -1543,8 +1544,6 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
 /* HDMI Initialization Step B.4 */
 static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
 {
-	u8 clkdis;
-
 	/* control period minimum duration */
 	hdmi_writeb(hdmi, 12, HDMI_FC_CTRLDUR);
 	hdmi_writeb(hdmi, 32, HDMI_FC_EXCTRLDUR);
@@ -1556,17 +1555,21 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
 	hdmi_writeb(hdmi, 0x21, HDMI_FC_CH2PREAM);
 
 	/* Enable pixel clock and tmds data path */
-	clkdis = 0x7F;
-	clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
-	hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
+	hdmi->mc_clkdis |= HDMI_MC_CLKDIS_HDCPCLK_DISABLE |
+			   HDMI_MC_CLKDIS_CSCCLK_DISABLE |
+			   HDMI_MC_CLKDIS_AUDCLK_DISABLE |
+			   HDMI_MC_CLKDIS_PREPCLK_DISABLE |
+			   HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
+	hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
+	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
 
-	clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
-	hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
+	hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
+	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
 
 	/* Enable csc path */
 	if (is_color_space_conversion(hdmi)) {
-		clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
-		hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
+		hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
+		hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
 	}
 
 	/* Enable color space conversion if needed */
@@ -1580,7 +1583,8 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
 
 static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi)
 {
-	hdmi_modb(hdmi, 0, HDMI_MC_CLKDIS_AUDCLK_DISABLE, HDMI_MC_CLKDIS);
+	hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_AUDCLK_DISABLE;
+	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
 }
 
 /* Workaround to clear the overflow condition */
@@ -2261,6 +2265,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
 	hdmi->disabled = true;
 	hdmi->rxsense = true;
 	hdmi->phy_mask = (u8)~(HDMI_PHY_HPD | HDMI_PHY_RX_SENSE);
+	hdmi->mc_clkdis = 0x7f;
 
 	mutex_init(&hdmi->mutex);
 	mutex_init(&hdmi->audio_mutex);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver
  2017-05-30 14:22 ` Russell King - ARM Linux
@ 2017-05-30 14:23   ` Russell King
  -1 siblings, 0 replies; 84+ messages in thread
From: Russell King @ 2017-05-30 14:23 UTC (permalink / raw)
  To: linux-arm-kernel

Add a CEC driver for the dw-hdmi hardware.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/gpu/drm/bridge/synopsys/Kconfig       |   8 +
 drivers/gpu/drm/bridge/synopsys/Makefile      |   1 +
 drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 320 ++++++++++++++++++++++++++
 drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h |  19 ++
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c     |  40 +++-
 5 files changed, 387 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
 create mode 100644 drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h

diff --git a/drivers/gpu/drm/bridge/synopsys/Kconfig b/drivers/gpu/drm/bridge/synopsys/Kconfig
index 40d2827a6d19..bd30a0a07272 100644
--- a/drivers/gpu/drm/bridge/synopsys/Kconfig
+++ b/drivers/gpu/drm/bridge/synopsys/Kconfig
@@ -21,3 +21,11 @@ config DRM_DW_HDMI_I2S_AUDIO
 	help
 	  Support the I2S Audio interface which is part of the Synopsys
 	  Designware HDMI block.
+
+config DRM_DW_HDMI_CEC
+	tristate "Synopsis Designware CEC interface"
+	depends on DRM_DW_HDMI && MEDIA_CEC_SUPPORT
+	select MEDIA_CEC_NOTIFIER
+	help
+	  Support the CE interface which is part of the Synopsis
+	  Designware HDMI block.
diff --git a/drivers/gpu/drm/bridge/synopsys/Makefile b/drivers/gpu/drm/bridge/synopsys/Makefile
index 17aa7a65b57e..6fe415903668 100644
--- a/drivers/gpu/drm/bridge/synopsys/Makefile
+++ b/drivers/gpu/drm/bridge/synopsys/Makefile
@@ -3,3 +3,4 @@
 obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
 obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
 obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o
+obj-$(CONFIG_DRM_DW_HDMI_CEC) += dw-hdmi-cec.o
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
new file mode 100644
index 000000000000..761ef5ae687d
--- /dev/null
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
@@ -0,0 +1,320 @@
+/*
+ * Designware HDMI CEC driver
+ *
+ * Copyright (C) 2015-2017 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+
+#include <drm/drm_edid.h>
+
+#include <media/cec.h>
+#include <media/cec-notifier.h>
+
+#include "dw-hdmi-cec.h"
+
+enum {
+	HDMI_IH_CEC_STAT0	= 0x0106,
+	HDMI_IH_MUTE_CEC_STAT0	= 0x0186,
+
+	HDMI_CEC_CTRL		= 0x7d00,
+	CEC_CTRL_START		= BIT(0),
+	CEC_CTRL_NORMAL		= 1 << 1,
+
+	HDMI_CEC_STAT		= 0x7d01,
+	CEC_STAT_DONE		= BIT(0),
+	CEC_STAT_EOM		= BIT(1),
+	CEC_STAT_NACK		= BIT(2),
+	CEC_STAT_ARBLOST	= BIT(3),
+	CEC_STAT_ERROR_INIT	= BIT(4),
+	CEC_STAT_ERROR_FOLL	= BIT(5),
+	CEC_STAT_WAKEUP		= BIT(6),
+
+	HDMI_CEC_MASK		= 0x7d02,
+	HDMI_CEC_POLARITY	= 0x7d03,
+	HDMI_CEC_INT		= 0x7d04,
+	HDMI_CEC_ADDR_L		= 0x7d05,
+	HDMI_CEC_ADDR_H		= 0x7d06,
+	HDMI_CEC_TX_CNT		= 0x7d07,
+	HDMI_CEC_RX_CNT		= 0x7d08,
+	HDMI_CEC_TX_DATA0	= 0x7d10,
+	HDMI_CEC_RX_DATA0	= 0x7d20,
+	HDMI_CEC_LOCK		= 0x7d30,
+	HDMI_CEC_WKUPCTRL	= 0x7d31,
+};
+
+struct dw_hdmi_cec {
+	struct dw_hdmi *hdmi;
+	const struct dw_hdmi_cec_ops *ops;
+	u32 addresses;
+	struct cec_adapter *adap;
+	struct cec_msg rx_msg;
+	unsigned int tx_status;
+	bool tx_done;
+	bool rx_done;
+	struct cec_notifier *notify;
+	int retries;
+	int irq;
+};
+
+static void dw_hdmi_write(struct dw_hdmi_cec *cec, u8 val, int offset)
+{
+	cec->ops->write(cec->hdmi, val, offset);
+}
+
+static u8 dw_hdmi_read(struct dw_hdmi_cec *cec, int offset)
+{
+	return cec->ops->read(cec->hdmi, offset);
+}
+
+static int dw_hdmi_cec_log_addr(struct cec_adapter *adap, u8 logical_addr)
+{
+	struct dw_hdmi_cec *cec = adap->priv;
+	u32 addresses;
+
+	if (logical_addr == CEC_LOG_ADDR_INVALID)
+		addresses = cec->addresses = 0;
+	else
+		addresses = cec->addresses |= BIT(logical_addr) | BIT(15);
+
+	dw_hdmi_write(cec, addresses & 255, HDMI_CEC_ADDR_L);
+	dw_hdmi_write(cec, addresses >> 8, HDMI_CEC_ADDR_H);
+
+	return 0;
+}
+
+static int dw_hdmi_cec_transmit(struct cec_adapter *adap, u8 attempts,
+				u32 signal_free_time, struct cec_msg *msg)
+{
+	struct dw_hdmi_cec *cec = adap->priv;
+	unsigned i;
+
+	cec->retries = attempts;
+
+	for (i = 0; i < msg->len; i++)
+		dw_hdmi_write(cec, msg->msg[i], HDMI_CEC_TX_DATA0 + i);
+
+	dw_hdmi_write(cec, msg->len, HDMI_CEC_TX_CNT);
+	dw_hdmi_write(cec, CEC_CTRL_NORMAL | CEC_CTRL_START, HDMI_CEC_CTRL);
+
+	return 0;
+}
+
+static irqreturn_t dw_hdmi_cec_hardirq(int irq, void *data)
+{
+	struct cec_adapter *adap = data;
+	struct dw_hdmi_cec *cec = adap->priv;
+	unsigned stat = dw_hdmi_read(cec, HDMI_IH_CEC_STAT0);
+	irqreturn_t ret = IRQ_HANDLED;
+
+	if (stat == 0)
+		return IRQ_NONE;
+
+	dw_hdmi_write(cec, stat, HDMI_IH_CEC_STAT0);
+
+	if (stat & CEC_STAT_ERROR_INIT) {
+		if (cec->retries) {
+			unsigned v = dw_hdmi_read(cec, HDMI_CEC_CTRL);
+			dw_hdmi_write(cec, v | CEC_CTRL_START, HDMI_CEC_CTRL);
+			cec->retries -= 1;
+		} else {
+			cec->tx_status = CEC_TX_STATUS_MAX_RETRIES;
+			cec->tx_done = true;
+			ret = IRQ_WAKE_THREAD;
+		}
+	} else if (stat & CEC_STAT_DONE) {
+		cec->tx_status = CEC_TX_STATUS_OK;
+		cec->tx_done = true;
+		ret = IRQ_WAKE_THREAD;
+	} else if (stat & CEC_STAT_NACK) {
+		cec->tx_status = CEC_TX_STATUS_NACK;
+		cec->tx_done = true;
+		ret = IRQ_WAKE_THREAD;
+	}
+
+	if (stat & CEC_STAT_EOM) {
+		unsigned len, i;
+
+		len = dw_hdmi_read(cec, HDMI_CEC_RX_CNT);
+		if (len > sizeof(cec->rx_msg.msg))
+			len = sizeof(cec->rx_msg.msg);
+
+		for (i = 0; i < len; i++)
+			cec->rx_msg.msg[i] =
+				dw_hdmi_read(cec, HDMI_CEC_RX_DATA0 + i);
+
+		dw_hdmi_write(cec, 0, HDMI_CEC_LOCK);
+
+		cec->rx_msg.len = len;
+		smp_wmb();
+		cec->rx_done = true;
+
+		ret = IRQ_WAKE_THREAD;
+	}
+
+	return ret;
+}
+
+static irqreturn_t dw_hdmi_cec_thread(int irq, void *data)
+{
+	struct cec_adapter *adap = data;
+	struct dw_hdmi_cec *cec = adap->priv;
+
+	if (cec->tx_done) {
+		cec->tx_done = false;
+		cec_transmit_done(adap, cec->tx_status, 0, 0, 0, 0);
+	}
+	if (cec->rx_done) {
+		cec->rx_done = false;
+		smp_rmb();
+		cec_received_msg(adap, &cec->rx_msg);
+	}
+	return IRQ_HANDLED;
+}
+
+static int dw_hdmi_cec_enable(struct cec_adapter *adap, bool enable)
+{
+	struct dw_hdmi_cec *cec = adap->priv;
+
+	if (!enable) {
+		dw_hdmi_write(cec, ~0, HDMI_CEC_MASK);
+		dw_hdmi_write(cec, ~0, HDMI_IH_MUTE_CEC_STAT0);
+		dw_hdmi_write(cec, 0, HDMI_CEC_POLARITY);
+
+		cec->ops->disable(cec->hdmi);
+	} else {
+		unsigned irqs;
+
+		dw_hdmi_write(cec, 0, HDMI_CEC_CTRL);
+		dw_hdmi_write(cec, ~0, HDMI_IH_CEC_STAT0);
+		dw_hdmi_write(cec, 0, HDMI_CEC_LOCK);
+
+		dw_hdmi_cec_log_addr(cec->adap, CEC_LOG_ADDR_INVALID);
+
+		cec->ops->enable(cec->hdmi);
+
+		irqs = CEC_STAT_ERROR_INIT | CEC_STAT_NACK | CEC_STAT_EOM |
+		       CEC_STAT_DONE;
+		dw_hdmi_write(cec, irqs, HDMI_CEC_POLARITY);
+		dw_hdmi_write(cec, ~irqs, HDMI_CEC_MASK);
+		dw_hdmi_write(cec, ~irqs, HDMI_IH_MUTE_CEC_STAT0);
+	}
+	return 0;
+}
+
+static const struct cec_adap_ops dw_hdmi_cec_ops = {
+	.adap_enable = dw_hdmi_cec_enable,
+	.adap_log_addr = dw_hdmi_cec_log_addr,
+	.adap_transmit = dw_hdmi_cec_transmit,
+};
+
+static void dw_hdmi_cec_del(void *data)
+{
+	struct dw_hdmi_cec *cec = data;
+
+	cec_delete_adapter(cec->adap);
+}
+
+static int dw_hdmi_cec_probe(struct platform_device *pdev)
+{
+	struct dw_hdmi_cec_data *data = dev_get_platdata(&pdev->dev);
+	struct dw_hdmi_cec *cec;
+	int ret;
+
+	if (!data)
+		return -ENXIO;
+
+	/*
+	 * Our device is just a convenience - we want to link to the real
+	 * hardware device here, so that userspace can see the association
+	 * between the HDMI hardware and its associated CEC chardev.
+	 */
+	cec = devm_kzalloc(&pdev->dev, sizeof(*cec), GFP_KERNEL);
+	if (!cec)
+		return -ENOMEM;
+
+	cec->irq = data->irq;
+	cec->ops = data->ops;
+	cec->hdmi = data->hdmi;
+
+	platform_set_drvdata(pdev, cec);
+
+	dw_hdmi_write(cec, 0, HDMI_CEC_TX_CNT);
+	dw_hdmi_write(cec, ~0, HDMI_CEC_MASK);
+	dw_hdmi_write(cec, ~0, HDMI_IH_MUTE_CEC_STAT0);
+	dw_hdmi_write(cec, 0, HDMI_CEC_POLARITY);
+
+	cec->adap = cec_allocate_adapter(&dw_hdmi_cec_ops, cec, "dw_hdmi",
+					 CEC_CAP_LOG_ADDRS | CEC_CAP_TRANSMIT |
+					 CEC_CAP_RC, CEC_MAX_LOG_ADDRS);
+	if (IS_ERR(cec->adap))
+		return PTR_ERR(cec->adap);
+
+	/* override the module pointer */
+	cec->adap->owner = THIS_MODULE;
+
+	ret = devm_add_action(&pdev->dev, dw_hdmi_cec_del, cec);
+	if (ret) {
+		cec_delete_adapter(cec->adap);
+		return ret;
+	}
+
+	ret = devm_request_threaded_irq(&pdev->dev, cec->irq,
+					dw_hdmi_cec_hardirq,
+					dw_hdmi_cec_thread, IRQF_SHARED,
+					"dw-hdmi-cec", cec->adap);
+	if (ret < 0)
+		return ret;
+
+	cec->notify = cec_notifier_get(pdev->dev.parent);
+	if (!cec->notify)
+		return -ENOMEM;
+
+	ret = cec_register_adapter(cec->adap, pdev->dev.parent);
+	if (ret < 0) {
+		cec_notifier_put(cec->notify);
+		return ret;
+	}
+
+	/*
+	 * CEC documentation says we must not call cec_delete_adapter
+	 * after a successful call to cec_register_adapter().
+	 */
+	devm_remove_action(&pdev->dev, dw_hdmi_cec_del, cec);
+
+	cec_register_cec_notifier(cec->adap, cec->notify);
+
+	return 0;
+}
+
+static int dw_hdmi_cec_remove(struct platform_device *pdev)
+{
+	struct dw_hdmi_cec *cec = platform_get_drvdata(pdev);
+
+	cec_unregister_adapter(cec->adap);
+	cec_notifier_put(cec->notify);
+
+	return 0;
+}
+
+static struct platform_driver dw_hdmi_cec_driver = {
+	.probe	= dw_hdmi_cec_probe,
+	.remove	= dw_hdmi_cec_remove,
+	.driver = {
+		.name = "dw-hdmi-cec",
+	},
+};
+module_platform_driver(dw_hdmi_cec_driver);
+
+MODULE_AUTHOR("Russell King <rmk+kernel@armlinux.org.uk>");
+MODULE_DESCRIPTION("Synopsis Designware HDMI CEC driver for i.MX");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS(PLATFORM_MODULE_PREFIX "dw-hdmi-cec");
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
new file mode 100644
index 000000000000..cf4dc121a2c4
--- /dev/null
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
@@ -0,0 +1,19 @@
+#ifndef DW_HDMI_CEC_H
+#define DW_HDMI_CEC_H
+
+struct dw_hdmi;
+
+struct dw_hdmi_cec_ops {
+	void (*write)(struct dw_hdmi *hdmi, u8 val, int offset);
+	u8 (*read)(struct dw_hdmi *hdmi, int offset);
+	void (*enable)(struct dw_hdmi *hdmi);
+	void (*disable)(struct dw_hdmi *hdmi);
+};
+
+struct dw_hdmi_cec_data {
+	struct dw_hdmi *hdmi;
+	const struct dw_hdmi_cec_ops *ops;
+	int irq;
+};
+
+#endif
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 58781d4c1034..5a389f1f58d9 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -35,6 +35,7 @@
 
 #include "dw-hdmi.h"
 #include "dw-hdmi-audio.h"
+#include "dw-hdmi-cec.h"
 
 #include <media/cec-notifier.h>
 
@@ -133,6 +134,7 @@ struct dw_hdmi {
 	unsigned int version;
 
 	struct platform_device *audio;
+	struct platform_device *cec;
 	struct device *dev;
 	struct clk *isfr_clk;
 	struct clk *iahb_clk;
@@ -1766,7 +1768,6 @@ static void initialize_hdmi_ih_mutes(struct dw_hdmi *hdmi)
 	hdmi_writeb(hdmi, 0xff, HDMI_AUD_HBR_MASK);
 	hdmi_writeb(hdmi, 0xff, HDMI_GP_MASK);
 	hdmi_writeb(hdmi, 0xff, HDMI_A_APIINTMSK);
-	hdmi_writeb(hdmi, 0xff, HDMI_CEC_MASK);
 	hdmi_writeb(hdmi, 0xff, HDMI_I2CM_INT);
 	hdmi_writeb(hdmi, 0xff, HDMI_I2CM_CTLINT);
 
@@ -2223,6 +2224,29 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi)
 	return -ENODEV;
 }
 
+static void dw_hdmi_cec_enable(struct dw_hdmi *hdmi)
+{
+	mutex_lock(&hdmi->mutex);
+	hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CECCLK_DISABLE;
+	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
+	mutex_unlock(&hdmi->mutex);
+}
+
+static void dw_hdmi_cec_disable(struct dw_hdmi *hdmi)
+{
+	mutex_lock(&hdmi->mutex);
+	hdmi->mc_clkdis |= HDMI_MC_CLKDIS_CECCLK_DISABLE;
+	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
+	mutex_unlock(&hdmi->mutex);
+}
+
+static const struct dw_hdmi_cec_ops dw_hdmi_cec_ops = {
+	.write = hdmi_writeb,
+	.read = hdmi_readb,
+	.enable = dw_hdmi_cec_enable,
+	.disable = dw_hdmi_cec_disable,
+};
+
 static const struct regmap_config hdmi_regmap_8bit_config = {
 	.reg_bits	= 32,
 	.val_bits	= 8,
@@ -2245,6 +2269,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
 	struct device_node *np = dev->of_node;
 	struct platform_device_info pdevinfo;
 	struct device_node *ddc_node;
+	struct dw_hdmi_cec_data cec;
 	struct dw_hdmi *hdmi;
 	struct resource *iores = NULL;
 	int irq;
@@ -2445,6 +2470,17 @@ __dw_hdmi_probe(struct platform_device *pdev,
 		hdmi->audio = platform_device_register_full(&pdevinfo);
 	}
 
+	cec.hdmi = hdmi;
+	cec.ops = &dw_hdmi_cec_ops;
+	cec.irq = irq;
+
+	pdevinfo.name = "dw-hdmi-cec";
+	pdevinfo.data = &cec;
+	pdevinfo.size_data = sizeof(cec);
+	pdevinfo.dma_mask = 0;
+
+	hdmi->cec = platform_device_register_full(&pdevinfo);
+
 	/* Reset HDMI DDC I2C master controller and mute I2CM interrupts */
 	if (hdmi->i2c)
 		dw_hdmi_i2c_init(hdmi);
@@ -2475,6 +2511,8 @@ static void __dw_hdmi_remove(struct dw_hdmi *hdmi)
 {
 	if (hdmi->audio && !IS_ERR(hdmi->audio))
 		platform_device_unregister(hdmi->audio);
+	if (!IS_ERR(hdmi->cec))
+		platform_device_unregister(hdmi->cec);
 
 	/* Disable all interrupts */
 	hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver
@ 2017-05-30 14:23   ` Russell King
  0 siblings, 0 replies; 84+ messages in thread
From: Russell King @ 2017-05-30 14:23 UTC (permalink / raw)
  To: Hans Verkuil; +Cc: David Airlie, Archit Taneja, dri-devel, linux-arm-kernel

Add a CEC driver for the dw-hdmi hardware.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/gpu/drm/bridge/synopsys/Kconfig       |   8 +
 drivers/gpu/drm/bridge/synopsys/Makefile      |   1 +
 drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 320 ++++++++++++++++++++++++++
 drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h |  19 ++
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c     |  40 +++-
 5 files changed, 387 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
 create mode 100644 drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h

diff --git a/drivers/gpu/drm/bridge/synopsys/Kconfig b/drivers/gpu/drm/bridge/synopsys/Kconfig
index 40d2827a6d19..bd30a0a07272 100644
--- a/drivers/gpu/drm/bridge/synopsys/Kconfig
+++ b/drivers/gpu/drm/bridge/synopsys/Kconfig
@@ -21,3 +21,11 @@ config DRM_DW_HDMI_I2S_AUDIO
 	help
 	  Support the I2S Audio interface which is part of the Synopsys
 	  Designware HDMI block.
+
+config DRM_DW_HDMI_CEC
+	tristate "Synopsis Designware CEC interface"
+	depends on DRM_DW_HDMI && MEDIA_CEC_SUPPORT
+	select MEDIA_CEC_NOTIFIER
+	help
+	  Support the CE interface which is part of the Synopsis
+	  Designware HDMI block.
diff --git a/drivers/gpu/drm/bridge/synopsys/Makefile b/drivers/gpu/drm/bridge/synopsys/Makefile
index 17aa7a65b57e..6fe415903668 100644
--- a/drivers/gpu/drm/bridge/synopsys/Makefile
+++ b/drivers/gpu/drm/bridge/synopsys/Makefile
@@ -3,3 +3,4 @@
 obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
 obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
 obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o
+obj-$(CONFIG_DRM_DW_HDMI_CEC) += dw-hdmi-cec.o
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
new file mode 100644
index 000000000000..761ef5ae687d
--- /dev/null
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
@@ -0,0 +1,320 @@
+/*
+ * Designware HDMI CEC driver
+ *
+ * Copyright (C) 2015-2017 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+
+#include <drm/drm_edid.h>
+
+#include <media/cec.h>
+#include <media/cec-notifier.h>
+
+#include "dw-hdmi-cec.h"
+
+enum {
+	HDMI_IH_CEC_STAT0	= 0x0106,
+	HDMI_IH_MUTE_CEC_STAT0	= 0x0186,
+
+	HDMI_CEC_CTRL		= 0x7d00,
+	CEC_CTRL_START		= BIT(0),
+	CEC_CTRL_NORMAL		= 1 << 1,
+
+	HDMI_CEC_STAT		= 0x7d01,
+	CEC_STAT_DONE		= BIT(0),
+	CEC_STAT_EOM		= BIT(1),
+	CEC_STAT_NACK		= BIT(2),
+	CEC_STAT_ARBLOST	= BIT(3),
+	CEC_STAT_ERROR_INIT	= BIT(4),
+	CEC_STAT_ERROR_FOLL	= BIT(5),
+	CEC_STAT_WAKEUP		= BIT(6),
+
+	HDMI_CEC_MASK		= 0x7d02,
+	HDMI_CEC_POLARITY	= 0x7d03,
+	HDMI_CEC_INT		= 0x7d04,
+	HDMI_CEC_ADDR_L		= 0x7d05,
+	HDMI_CEC_ADDR_H		= 0x7d06,
+	HDMI_CEC_TX_CNT		= 0x7d07,
+	HDMI_CEC_RX_CNT		= 0x7d08,
+	HDMI_CEC_TX_DATA0	= 0x7d10,
+	HDMI_CEC_RX_DATA0	= 0x7d20,
+	HDMI_CEC_LOCK		= 0x7d30,
+	HDMI_CEC_WKUPCTRL	= 0x7d31,
+};
+
+struct dw_hdmi_cec {
+	struct dw_hdmi *hdmi;
+	const struct dw_hdmi_cec_ops *ops;
+	u32 addresses;
+	struct cec_adapter *adap;
+	struct cec_msg rx_msg;
+	unsigned int tx_status;
+	bool tx_done;
+	bool rx_done;
+	struct cec_notifier *notify;
+	int retries;
+	int irq;
+};
+
+static void dw_hdmi_write(struct dw_hdmi_cec *cec, u8 val, int offset)
+{
+	cec->ops->write(cec->hdmi, val, offset);
+}
+
+static u8 dw_hdmi_read(struct dw_hdmi_cec *cec, int offset)
+{
+	return cec->ops->read(cec->hdmi, offset);
+}
+
+static int dw_hdmi_cec_log_addr(struct cec_adapter *adap, u8 logical_addr)
+{
+	struct dw_hdmi_cec *cec = adap->priv;
+	u32 addresses;
+
+	if (logical_addr == CEC_LOG_ADDR_INVALID)
+		addresses = cec->addresses = 0;
+	else
+		addresses = cec->addresses |= BIT(logical_addr) | BIT(15);
+
+	dw_hdmi_write(cec, addresses & 255, HDMI_CEC_ADDR_L);
+	dw_hdmi_write(cec, addresses >> 8, HDMI_CEC_ADDR_H);
+
+	return 0;
+}
+
+static int dw_hdmi_cec_transmit(struct cec_adapter *adap, u8 attempts,
+				u32 signal_free_time, struct cec_msg *msg)
+{
+	struct dw_hdmi_cec *cec = adap->priv;
+	unsigned i;
+
+	cec->retries = attempts;
+
+	for (i = 0; i < msg->len; i++)
+		dw_hdmi_write(cec, msg->msg[i], HDMI_CEC_TX_DATA0 + i);
+
+	dw_hdmi_write(cec, msg->len, HDMI_CEC_TX_CNT);
+	dw_hdmi_write(cec, CEC_CTRL_NORMAL | CEC_CTRL_START, HDMI_CEC_CTRL);
+
+	return 0;
+}
+
+static irqreturn_t dw_hdmi_cec_hardirq(int irq, void *data)
+{
+	struct cec_adapter *adap = data;
+	struct dw_hdmi_cec *cec = adap->priv;
+	unsigned stat = dw_hdmi_read(cec, HDMI_IH_CEC_STAT0);
+	irqreturn_t ret = IRQ_HANDLED;
+
+	if (stat == 0)
+		return IRQ_NONE;
+
+	dw_hdmi_write(cec, stat, HDMI_IH_CEC_STAT0);
+
+	if (stat & CEC_STAT_ERROR_INIT) {
+		if (cec->retries) {
+			unsigned v = dw_hdmi_read(cec, HDMI_CEC_CTRL);
+			dw_hdmi_write(cec, v | CEC_CTRL_START, HDMI_CEC_CTRL);
+			cec->retries -= 1;
+		} else {
+			cec->tx_status = CEC_TX_STATUS_MAX_RETRIES;
+			cec->tx_done = true;
+			ret = IRQ_WAKE_THREAD;
+		}
+	} else if (stat & CEC_STAT_DONE) {
+		cec->tx_status = CEC_TX_STATUS_OK;
+		cec->tx_done = true;
+		ret = IRQ_WAKE_THREAD;
+	} else if (stat & CEC_STAT_NACK) {
+		cec->tx_status = CEC_TX_STATUS_NACK;
+		cec->tx_done = true;
+		ret = IRQ_WAKE_THREAD;
+	}
+
+	if (stat & CEC_STAT_EOM) {
+		unsigned len, i;
+
+		len = dw_hdmi_read(cec, HDMI_CEC_RX_CNT);
+		if (len > sizeof(cec->rx_msg.msg))
+			len = sizeof(cec->rx_msg.msg);
+
+		for (i = 0; i < len; i++)
+			cec->rx_msg.msg[i] =
+				dw_hdmi_read(cec, HDMI_CEC_RX_DATA0 + i);
+
+		dw_hdmi_write(cec, 0, HDMI_CEC_LOCK);
+
+		cec->rx_msg.len = len;
+		smp_wmb();
+		cec->rx_done = true;
+
+		ret = IRQ_WAKE_THREAD;
+	}
+
+	return ret;
+}
+
+static irqreturn_t dw_hdmi_cec_thread(int irq, void *data)
+{
+	struct cec_adapter *adap = data;
+	struct dw_hdmi_cec *cec = adap->priv;
+
+	if (cec->tx_done) {
+		cec->tx_done = false;
+		cec_transmit_done(adap, cec->tx_status, 0, 0, 0, 0);
+	}
+	if (cec->rx_done) {
+		cec->rx_done = false;
+		smp_rmb();
+		cec_received_msg(adap, &cec->rx_msg);
+	}
+	return IRQ_HANDLED;
+}
+
+static int dw_hdmi_cec_enable(struct cec_adapter *adap, bool enable)
+{
+	struct dw_hdmi_cec *cec = adap->priv;
+
+	if (!enable) {
+		dw_hdmi_write(cec, ~0, HDMI_CEC_MASK);
+		dw_hdmi_write(cec, ~0, HDMI_IH_MUTE_CEC_STAT0);
+		dw_hdmi_write(cec, 0, HDMI_CEC_POLARITY);
+
+		cec->ops->disable(cec->hdmi);
+	} else {
+		unsigned irqs;
+
+		dw_hdmi_write(cec, 0, HDMI_CEC_CTRL);
+		dw_hdmi_write(cec, ~0, HDMI_IH_CEC_STAT0);
+		dw_hdmi_write(cec, 0, HDMI_CEC_LOCK);
+
+		dw_hdmi_cec_log_addr(cec->adap, CEC_LOG_ADDR_INVALID);
+
+		cec->ops->enable(cec->hdmi);
+
+		irqs = CEC_STAT_ERROR_INIT | CEC_STAT_NACK | CEC_STAT_EOM |
+		       CEC_STAT_DONE;
+		dw_hdmi_write(cec, irqs, HDMI_CEC_POLARITY);
+		dw_hdmi_write(cec, ~irqs, HDMI_CEC_MASK);
+		dw_hdmi_write(cec, ~irqs, HDMI_IH_MUTE_CEC_STAT0);
+	}
+	return 0;
+}
+
+static const struct cec_adap_ops dw_hdmi_cec_ops = {
+	.adap_enable = dw_hdmi_cec_enable,
+	.adap_log_addr = dw_hdmi_cec_log_addr,
+	.adap_transmit = dw_hdmi_cec_transmit,
+};
+
+static void dw_hdmi_cec_del(void *data)
+{
+	struct dw_hdmi_cec *cec = data;
+
+	cec_delete_adapter(cec->adap);
+}
+
+static int dw_hdmi_cec_probe(struct platform_device *pdev)
+{
+	struct dw_hdmi_cec_data *data = dev_get_platdata(&pdev->dev);
+	struct dw_hdmi_cec *cec;
+	int ret;
+
+	if (!data)
+		return -ENXIO;
+
+	/*
+	 * Our device is just a convenience - we want to link to the real
+	 * hardware device here, so that userspace can see the association
+	 * between the HDMI hardware and its associated CEC chardev.
+	 */
+	cec = devm_kzalloc(&pdev->dev, sizeof(*cec), GFP_KERNEL);
+	if (!cec)
+		return -ENOMEM;
+
+	cec->irq = data->irq;
+	cec->ops = data->ops;
+	cec->hdmi = data->hdmi;
+
+	platform_set_drvdata(pdev, cec);
+
+	dw_hdmi_write(cec, 0, HDMI_CEC_TX_CNT);
+	dw_hdmi_write(cec, ~0, HDMI_CEC_MASK);
+	dw_hdmi_write(cec, ~0, HDMI_IH_MUTE_CEC_STAT0);
+	dw_hdmi_write(cec, 0, HDMI_CEC_POLARITY);
+
+	cec->adap = cec_allocate_adapter(&dw_hdmi_cec_ops, cec, "dw_hdmi",
+					 CEC_CAP_LOG_ADDRS | CEC_CAP_TRANSMIT |
+					 CEC_CAP_RC, CEC_MAX_LOG_ADDRS);
+	if (IS_ERR(cec->adap))
+		return PTR_ERR(cec->adap);
+
+	/* override the module pointer */
+	cec->adap->owner = THIS_MODULE;
+
+	ret = devm_add_action(&pdev->dev, dw_hdmi_cec_del, cec);
+	if (ret) {
+		cec_delete_adapter(cec->adap);
+		return ret;
+	}
+
+	ret = devm_request_threaded_irq(&pdev->dev, cec->irq,
+					dw_hdmi_cec_hardirq,
+					dw_hdmi_cec_thread, IRQF_SHARED,
+					"dw-hdmi-cec", cec->adap);
+	if (ret < 0)
+		return ret;
+
+	cec->notify = cec_notifier_get(pdev->dev.parent);
+	if (!cec->notify)
+		return -ENOMEM;
+
+	ret = cec_register_adapter(cec->adap, pdev->dev.parent);
+	if (ret < 0) {
+		cec_notifier_put(cec->notify);
+		return ret;
+	}
+
+	/*
+	 * CEC documentation says we must not call cec_delete_adapter
+	 * after a successful call to cec_register_adapter().
+	 */
+	devm_remove_action(&pdev->dev, dw_hdmi_cec_del, cec);
+
+	cec_register_cec_notifier(cec->adap, cec->notify);
+
+	return 0;
+}
+
+static int dw_hdmi_cec_remove(struct platform_device *pdev)
+{
+	struct dw_hdmi_cec *cec = platform_get_drvdata(pdev);
+
+	cec_unregister_adapter(cec->adap);
+	cec_notifier_put(cec->notify);
+
+	return 0;
+}
+
+static struct platform_driver dw_hdmi_cec_driver = {
+	.probe	= dw_hdmi_cec_probe,
+	.remove	= dw_hdmi_cec_remove,
+	.driver = {
+		.name = "dw-hdmi-cec",
+	},
+};
+module_platform_driver(dw_hdmi_cec_driver);
+
+MODULE_AUTHOR("Russell King <rmk+kernel@armlinux.org.uk>");
+MODULE_DESCRIPTION("Synopsis Designware HDMI CEC driver for i.MX");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS(PLATFORM_MODULE_PREFIX "dw-hdmi-cec");
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
new file mode 100644
index 000000000000..cf4dc121a2c4
--- /dev/null
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
@@ -0,0 +1,19 @@
+#ifndef DW_HDMI_CEC_H
+#define DW_HDMI_CEC_H
+
+struct dw_hdmi;
+
+struct dw_hdmi_cec_ops {
+	void (*write)(struct dw_hdmi *hdmi, u8 val, int offset);
+	u8 (*read)(struct dw_hdmi *hdmi, int offset);
+	void (*enable)(struct dw_hdmi *hdmi);
+	void (*disable)(struct dw_hdmi *hdmi);
+};
+
+struct dw_hdmi_cec_data {
+	struct dw_hdmi *hdmi;
+	const struct dw_hdmi_cec_ops *ops;
+	int irq;
+};
+
+#endif
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 58781d4c1034..5a389f1f58d9 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -35,6 +35,7 @@
 
 #include "dw-hdmi.h"
 #include "dw-hdmi-audio.h"
+#include "dw-hdmi-cec.h"
 
 #include <media/cec-notifier.h>
 
@@ -133,6 +134,7 @@ struct dw_hdmi {
 	unsigned int version;
 
 	struct platform_device *audio;
+	struct platform_device *cec;
 	struct device *dev;
 	struct clk *isfr_clk;
 	struct clk *iahb_clk;
@@ -1766,7 +1768,6 @@ static void initialize_hdmi_ih_mutes(struct dw_hdmi *hdmi)
 	hdmi_writeb(hdmi, 0xff, HDMI_AUD_HBR_MASK);
 	hdmi_writeb(hdmi, 0xff, HDMI_GP_MASK);
 	hdmi_writeb(hdmi, 0xff, HDMI_A_APIINTMSK);
-	hdmi_writeb(hdmi, 0xff, HDMI_CEC_MASK);
 	hdmi_writeb(hdmi, 0xff, HDMI_I2CM_INT);
 	hdmi_writeb(hdmi, 0xff, HDMI_I2CM_CTLINT);
 
@@ -2223,6 +2224,29 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi)
 	return -ENODEV;
 }
 
+static void dw_hdmi_cec_enable(struct dw_hdmi *hdmi)
+{
+	mutex_lock(&hdmi->mutex);
+	hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CECCLK_DISABLE;
+	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
+	mutex_unlock(&hdmi->mutex);
+}
+
+static void dw_hdmi_cec_disable(struct dw_hdmi *hdmi)
+{
+	mutex_lock(&hdmi->mutex);
+	hdmi->mc_clkdis |= HDMI_MC_CLKDIS_CECCLK_DISABLE;
+	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
+	mutex_unlock(&hdmi->mutex);
+}
+
+static const struct dw_hdmi_cec_ops dw_hdmi_cec_ops = {
+	.write = hdmi_writeb,
+	.read = hdmi_readb,
+	.enable = dw_hdmi_cec_enable,
+	.disable = dw_hdmi_cec_disable,
+};
+
 static const struct regmap_config hdmi_regmap_8bit_config = {
 	.reg_bits	= 32,
 	.val_bits	= 8,
@@ -2245,6 +2269,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
 	struct device_node *np = dev->of_node;
 	struct platform_device_info pdevinfo;
 	struct device_node *ddc_node;
+	struct dw_hdmi_cec_data cec;
 	struct dw_hdmi *hdmi;
 	struct resource *iores = NULL;
 	int irq;
@@ -2445,6 +2470,17 @@ __dw_hdmi_probe(struct platform_device *pdev,
 		hdmi->audio = platform_device_register_full(&pdevinfo);
 	}
 
+	cec.hdmi = hdmi;
+	cec.ops = &dw_hdmi_cec_ops;
+	cec.irq = irq;
+
+	pdevinfo.name = "dw-hdmi-cec";
+	pdevinfo.data = &cec;
+	pdevinfo.size_data = sizeof(cec);
+	pdevinfo.dma_mask = 0;
+
+	hdmi->cec = platform_device_register_full(&pdevinfo);
+
 	/* Reset HDMI DDC I2C master controller and mute I2CM interrupts */
 	if (hdmi->i2c)
 		dw_hdmi_i2c_init(hdmi);
@@ -2475,6 +2511,8 @@ static void __dw_hdmi_remove(struct dw_hdmi *hdmi)
 {
 	if (hdmi->audio && !IS_ERR(hdmi->audio))
 		platform_device_unregister(hdmi->audio);
+	if (!IS_ERR(hdmi->cec))
+		platform_device_unregister(hdmi->cec);
 
 	/* Disable all interrupts */
 	hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 84+ messages in thread

* [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver
  2017-05-30 14:23   ` Russell King
@ 2017-06-01  0:53     ` Jose Abreu
  -1 siblings, 0 replies; 84+ messages in thread
From: Jose Abreu @ 2017-06-01  0:53 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Russell,


On 30-05-2017 15:23, Russell King wrote:
> Add a CEC driver for the dw-hdmi hardware.
>
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> ---
>  drivers/gpu/drm/bridge/synopsys/Kconfig       |   8 +
>  drivers/gpu/drm/bridge/synopsys/Makefile      |   1 +
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 320 ++++++++++++++++++++++++++
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h |  19 ++
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c     |  40 +++-
>  5 files changed, 387 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
>  create mode 100644 drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
>
> diff --git a/drivers/gpu/drm/bridge/synopsys/Kconfig b/drivers/gpu/drm/bridge/synopsys/Kconfig
> index 40d2827a6d19..bd30a0a07272 100644
> --- a/drivers/gpu/drm/bridge/synopsys/Kconfig
> +++ b/drivers/gpu/drm/bridge/synopsys/Kconfig
> @@ -21,3 +21,11 @@ config DRM_DW_HDMI_I2S_AUDIO
>  	help
>  	  Support the I2S Audio interface which is part of the Synopsys
>  	  Designware HDMI block.
> +
> +config DRM_DW_HDMI_CEC
> +	tristate "Synopsis Designware CEC interface"
> +	depends on DRM_DW_HDMI && MEDIA_CEC_SUPPORT
> +	select MEDIA_CEC_NOTIFIER
> +	help
> +	  Support the CE interface which is part of the Synopsis

Synopsis -> Synopsys

> +	  Designware HDMI block.
> diff --git a/drivers/gpu/drm/bridge/synopsys/Makefile b/drivers/gpu/drm/bridge/synopsys/Makefile
> index 17aa7a65b57e..6fe415903668 100644
> --- a/drivers/gpu/drm/bridge/synopsys/Makefile
> +++ b/drivers/gpu/drm/bridge/synopsys/Makefile
> @@ -3,3 +3,4 @@
>  obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
>  obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
>  obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o
> +obj-$(CONFIG_DRM_DW_HDMI_CEC) += dw-hdmi-cec.o
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
> new file mode 100644
> index 000000000000..761ef5ae687d
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
> @@ -0,0 +1,320 @@
> +/*
> + * Designware HDMI CEC driver
> + *
> + * Copyright (C) 2015-2017 Russell King.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/sched.h>
> +#include <linux/slab.h>
> +
> +#include <drm/drm_edid.h>
> +
> +#include <media/cec.h>
> +#include <media/cec-notifier.h>
> +
> +#include "dw-hdmi-cec.h"
> +
> +enum {
> +	HDMI_IH_CEC_STAT0	= 0x0106,
> +	HDMI_IH_MUTE_CEC_STAT0	= 0x0186,
> +
> +	HDMI_CEC_CTRL		= 0x7d00,
> +	CEC_CTRL_START		= BIT(0),
> +	CEC_CTRL_NORMAL		= 1 << 1,
> +
> +	HDMI_CEC_STAT		= 0x7d01,
> +	CEC_STAT_DONE		= BIT(0),
> +	CEC_STAT_EOM		= BIT(1),
> +	CEC_STAT_NACK		= BIT(2),
> +	CEC_STAT_ARBLOST	= BIT(3),
> +	CEC_STAT_ERROR_INIT	= BIT(4),
> +	CEC_STAT_ERROR_FOLL	= BIT(5),
> +	CEC_STAT_WAKEUP		= BIT(6),

I rather like the format HDMI_{REGISTER_NAME}_{FIELD_NAME} so
that it clearly identifies this is a internal driver register and
not a CEC core register, but I guess its up to you :)

> +
> +	HDMI_CEC_MASK		= 0x7d02,
> +	HDMI_CEC_POLARITY	= 0x7d03,
> +	HDMI_CEC_INT		= 0x7d04,
> +	HDMI_CEC_ADDR_L		= 0x7d05,
> +	HDMI_CEC_ADDR_H		= 0x7d06,
> +	HDMI_CEC_TX_CNT		= 0x7d07,
> +	HDMI_CEC_RX_CNT		= 0x7d08,
> +	HDMI_CEC_TX_DATA0	= 0x7d10,
> +	HDMI_CEC_RX_DATA0	= 0x7d20,
> +	HDMI_CEC_LOCK		= 0x7d30,
> +	HDMI_CEC_WKUPCTRL	= 0x7d31,
> +};
> +
> +struct dw_hdmi_cec {
> +	struct dw_hdmi *hdmi;
> +	const struct dw_hdmi_cec_ops *ops;
> +	u32 addresses;
> +	struct cec_adapter *adap;
> +	struct cec_msg rx_msg;
> +	unsigned int tx_status;
> +	bool tx_done;
> +	bool rx_done;
> +	struct cec_notifier *notify;
> +	int retries;
> +	int irq;
> +};
> +
> +static void dw_hdmi_write(struct dw_hdmi_cec *cec, u8 val, int offset)
> +{
> +	cec->ops->write(cec->hdmi, val, offset);
> +}
> +
> +static u8 dw_hdmi_read(struct dw_hdmi_cec *cec, int offset)
> +{
> +	return cec->ops->read(cec->hdmi, offset);
> +}
> +
> +static int dw_hdmi_cec_log_addr(struct cec_adapter *adap, u8 logical_addr)
> +{
> +	struct dw_hdmi_cec *cec = adap->priv;

You can use "cec = cec_get_drvdata(adap)" here, as in the rest of
the code.

> +	u32 addresses;
> +
> +	if (logical_addr == CEC_LOG_ADDR_INVALID)
> +		addresses = cec->addresses = 0;
> +	else
> +		addresses = cec->addresses |= BIT(logical_addr) | BIT(15);
> +
> +	dw_hdmi_write(cec, addresses & 255, HDMI_CEC_ADDR_L);
> +	dw_hdmi_write(cec, addresses >> 8, HDMI_CEC_ADDR_H);
> +
> +	return 0;
> +}
> +
> +static int dw_hdmi_cec_transmit(struct cec_adapter *adap, u8 attempts,
> +				u32 signal_free_time, struct cec_msg *msg)
> +{
> +	struct dw_hdmi_cec *cec = adap->priv;
> +	unsigned i;
> +
> +	cec->retries = attempts;

I think you should check first if CEC engine is in normal
operation mode, as a safety measure.

> +
> +	for (i = 0; i < msg->len; i++)
> +		dw_hdmi_write(cec, msg->msg[i], HDMI_CEC_TX_DATA0 + i);
> +
> +	dw_hdmi_write(cec, msg->len, HDMI_CEC_TX_CNT);
> +	dw_hdmi_write(cec, CEC_CTRL_NORMAL | CEC_CTRL_START, HDMI_CEC_CTRL);
> +
> +	return 0;
> +}
> +
> +static irqreturn_t dw_hdmi_cec_hardirq(int irq, void *data)
> +{
> +	struct cec_adapter *adap = data;
> +	struct dw_hdmi_cec *cec = adap->priv;
> +	unsigned stat = dw_hdmi_read(cec, HDMI_IH_CEC_STAT0);
> +	irqreturn_t ret = IRQ_HANDLED;
> +
> +	if (stat == 0)
> +		return IRQ_NONE;
> +
> +	dw_hdmi_write(cec, stat, HDMI_IH_CEC_STAT0);
> +
> +	if (stat & CEC_STAT_ERROR_INIT) {
> +		if (cec->retries) {
> +			unsigned v = dw_hdmi_read(cec, HDMI_CEC_CTRL);
> +			dw_hdmi_write(cec, v | CEC_CTRL_START, HDMI_CEC_CTRL);
> +			cec->retries -= 1;
> +		} else {
> +			cec->tx_status = CEC_TX_STATUS_MAX_RETRIES;
> +			cec->tx_done = true;
> +			ret = IRQ_WAKE_THREAD;
> +		}
> +	} else if (stat & CEC_STAT_DONE) {
> +		cec->tx_status = CEC_TX_STATUS_OK;
> +		cec->tx_done = true;
> +		ret = IRQ_WAKE_THREAD;
> +	} else if (stat & CEC_STAT_NACK) {
> +		cec->tx_status = CEC_TX_STATUS_NACK;
> +		cec->tx_done = true;
> +		ret = IRQ_WAKE_THREAD;
> +	}
> +
> +	if (stat & CEC_STAT_EOM) {
> +		unsigned len, i;
> +
> +		len = dw_hdmi_read(cec, HDMI_CEC_RX_CNT);
> +		if (len > sizeof(cec->rx_msg.msg))
> +			len = sizeof(cec->rx_msg.msg);
> +
> +		for (i = 0; i < len; i++)
> +			cec->rx_msg.msg[i] =
> +				dw_hdmi_read(cec, HDMI_CEC_RX_DATA0 + i);
> +
> +		dw_hdmi_write(cec, 0, HDMI_CEC_LOCK);
> +
> +		cec->rx_msg.len = len;
> +		smp_wmb();
> +		cec->rx_done = true;
> +
> +		ret = IRQ_WAKE_THREAD;
> +	}
> +
> +	return ret;
> +}
> +
> +static irqreturn_t dw_hdmi_cec_thread(int irq, void *data)
> +{
> +	struct cec_adapter *adap = data;
> +	struct dw_hdmi_cec *cec = adap->priv;
> +
> +	if (cec->tx_done) {
> +		cec->tx_done = false;
> +		cec_transmit_done(adap, cec->tx_status, 0, 0, 0, 0);
> +	}
> +	if (cec->rx_done) {
> +		cec->rx_done = false;
> +		smp_rmb();
> +		cec_received_msg(adap, &cec->rx_msg);
> +	}
> +	return IRQ_HANDLED;
> +}
> +
> +static int dw_hdmi_cec_enable(struct cec_adapter *adap, bool enable)
> +{
> +	struct dw_hdmi_cec *cec = adap->priv;
> +
> +	if (!enable) {
> +		dw_hdmi_write(cec, ~0, HDMI_CEC_MASK);
> +		dw_hdmi_write(cec, ~0, HDMI_IH_MUTE_CEC_STAT0);
> +		dw_hdmi_write(cec, 0, HDMI_CEC_POLARITY);
> +
> +		cec->ops->disable(cec->hdmi);
> +	} else {
> +		unsigned irqs;
> +
> +		dw_hdmi_write(cec, 0, HDMI_CEC_CTRL);
> +		dw_hdmi_write(cec, ~0, HDMI_IH_CEC_STAT0);
> +		dw_hdmi_write(cec, 0, HDMI_CEC_LOCK);
> +
> +		dw_hdmi_cec_log_addr(cec->adap, CEC_LOG_ADDR_INVALID);
> +
> +		cec->ops->enable(cec->hdmi);
> +
> +		irqs = CEC_STAT_ERROR_INIT | CEC_STAT_NACK | CEC_STAT_EOM |
> +		       CEC_STAT_DONE;
> +		dw_hdmi_write(cec, irqs, HDMI_CEC_POLARITY);
> +		dw_hdmi_write(cec, ~irqs, HDMI_CEC_MASK);
> +		dw_hdmi_write(cec, ~irqs, HDMI_IH_MUTE_CEC_STAT0);
> +	}
> +	return 0;
> +}
> +
> +static const struct cec_adap_ops dw_hdmi_cec_ops = {
> +	.adap_enable = dw_hdmi_cec_enable,
> +	.adap_log_addr = dw_hdmi_cec_log_addr,
> +	.adap_transmit = dw_hdmi_cec_transmit,
> +};
> +
> +static void dw_hdmi_cec_del(void *data)
> +{
> +	struct dw_hdmi_cec *cec = data;
> +
> +	cec_delete_adapter(cec->adap);
> +}
> +
> +static int dw_hdmi_cec_probe(struct platform_device *pdev)
> +{
> +	struct dw_hdmi_cec_data *data = dev_get_platdata(&pdev->dev);
> +	struct dw_hdmi_cec *cec;
> +	int ret;
> +
> +	if (!data)
> +		return -ENXIO;
> +
> +	/*
> +	 * Our device is just a convenience - we want to link to the real
> +	 * hardware device here, so that userspace can see the association
> +	 * between the HDMI hardware and its associated CEC chardev.
> +	 */
> +	cec = devm_kzalloc(&pdev->dev, sizeof(*cec), GFP_KERNEL);
> +	if (!cec)
> +		return -ENOMEM;
> +
> +	cec->irq = data->irq;
> +	cec->ops = data->ops;
> +	cec->hdmi = data->hdmi;
> +
> +	platform_set_drvdata(pdev, cec);
> +
> +	dw_hdmi_write(cec, 0, HDMI_CEC_TX_CNT);
> +	dw_hdmi_write(cec, ~0, HDMI_CEC_MASK);
> +	dw_hdmi_write(cec, ~0, HDMI_IH_MUTE_CEC_STAT0);
> +	dw_hdmi_write(cec, 0, HDMI_CEC_POLARITY);
> +
> +	cec->adap = cec_allocate_adapter(&dw_hdmi_cec_ops, cec, "dw_hdmi",
> +					 CEC_CAP_LOG_ADDRS | CEC_CAP_TRANSMIT |
> +					 CEC_CAP_RC, CEC_MAX_LOG_ADDRS);
> +	if (IS_ERR(cec->adap))
> +		return PTR_ERR(cec->adap);
> +
> +	/* override the module pointer */
> +	cec->adap->owner = THIS_MODULE;
> +
> +	ret = devm_add_action(&pdev->dev, dw_hdmi_cec_del, cec);
> +	if (ret) {
> +		cec_delete_adapter(cec->adap);
> +		return ret;
> +	}
> +
> +	ret = devm_request_threaded_irq(&pdev->dev, cec->irq,
> +					dw_hdmi_cec_hardirq,
> +					dw_hdmi_cec_thread, IRQF_SHARED,
> +					"dw-hdmi-cec", cec->adap);
> +	if (ret < 0)
> +		return ret;
> +
> +	cec->notify = cec_notifier_get(pdev->dev.parent);
> +	if (!cec->notify)
> +		return -ENOMEM;
> +
> +	ret = cec_register_adapter(cec->adap, pdev->dev.parent);
> +	if (ret < 0) {
> +		cec_notifier_put(cec->notify);
> +		return ret;
> +	}
> +
> +	/*
> +	 * CEC documentation says we must not call cec_delete_adapter
> +	 * after a successful call to cec_register_adapter().
> +	 */
> +	devm_remove_action(&pdev->dev, dw_hdmi_cec_del, cec);
> +
> +	cec_register_cec_notifier(cec->adap, cec->notify);
> +
> +	return 0;
> +}
> +
> +static int dw_hdmi_cec_remove(struct platform_device *pdev)
> +{
> +	struct dw_hdmi_cec *cec = platform_get_drvdata(pdev);
> +
> +	cec_unregister_adapter(cec->adap);
> +	cec_notifier_put(cec->notify);
> +
> +	return 0;
> +}
> +
> +static struct platform_driver dw_hdmi_cec_driver = {
> +	.probe	= dw_hdmi_cec_probe,
> +	.remove	= dw_hdmi_cec_remove,
> +	.driver = {
> +		.name = "dw-hdmi-cec",
> +	},
> +};
> +module_platform_driver(dw_hdmi_cec_driver);
> +
> +MODULE_AUTHOR("Russell King <rmk+kernel@armlinux.org.uk>");
> +MODULE_DESCRIPTION("Synopsis Designware HDMI CEC driver for i.MX");

Synopsis -> Synopsys

> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS(PLATFORM_MODULE_PREFIX "dw-hdmi-cec");
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
> new file mode 100644
> index 000000000000..cf4dc121a2c4
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
> @@ -0,0 +1,19 @@
> +#ifndef DW_HDMI_CEC_H
> +#define DW_HDMI_CEC_H
> +
> +struct dw_hdmi;
> +
> +struct dw_hdmi_cec_ops {
> +	void (*write)(struct dw_hdmi *hdmi, u8 val, int offset);
> +	u8 (*read)(struct dw_hdmi *hdmi, int offset);
> +	void (*enable)(struct dw_hdmi *hdmi);
> +	void (*disable)(struct dw_hdmi *hdmi);
> +};
> +
> +struct dw_hdmi_cec_data {
> +	struct dw_hdmi *hdmi;
> +	const struct dw_hdmi_cec_ops *ops;
> +	int irq;
> +};
> +
> +#endif
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 58781d4c1034..5a389f1f58d9 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -35,6 +35,7 @@
>  
>  #include "dw-hdmi.h"
>  #include "dw-hdmi-audio.h"
> +#include "dw-hdmi-cec.h"
>  
>  #include <media/cec-notifier.h>
>  
> @@ -133,6 +134,7 @@ struct dw_hdmi {
>  	unsigned int version;
>  
>  	struct platform_device *audio;
> +	struct platform_device *cec;
>  	struct device *dev;
>  	struct clk *isfr_clk;
>  	struct clk *iahb_clk;
> @@ -1766,7 +1768,6 @@ static void initialize_hdmi_ih_mutes(struct dw_hdmi *hdmi)
>  	hdmi_writeb(hdmi, 0xff, HDMI_AUD_HBR_MASK);
>  	hdmi_writeb(hdmi, 0xff, HDMI_GP_MASK);
>  	hdmi_writeb(hdmi, 0xff, HDMI_A_APIINTMSK);
> -	hdmi_writeb(hdmi, 0xff, HDMI_CEC_MASK);
>  	hdmi_writeb(hdmi, 0xff, HDMI_I2CM_INT);
>  	hdmi_writeb(hdmi, 0xff, HDMI_I2CM_CTLINT);
>  
> @@ -2223,6 +2224,29 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi)
>  	return -ENODEV;
>  }
>  
> +static void dw_hdmi_cec_enable(struct dw_hdmi *hdmi)
> +{
> +	mutex_lock(&hdmi->mutex);
> +	hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CECCLK_DISABLE;
> +	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
> +	mutex_unlock(&hdmi->mutex);
> +}
> +
> +static void dw_hdmi_cec_disable(struct dw_hdmi *hdmi)
> +{
> +	mutex_lock(&hdmi->mutex);
> +	hdmi->mc_clkdis |= HDMI_MC_CLKDIS_CECCLK_DISABLE;
> +	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
> +	mutex_unlock(&hdmi->mutex);
> +}
> +
> +static const struct dw_hdmi_cec_ops dw_hdmi_cec_ops = {
> +	.write = hdmi_writeb,
> +	.read = hdmi_readb,
> +	.enable = dw_hdmi_cec_enable,
> +	.disable = dw_hdmi_cec_disable,
> +};
> +
>  static const struct regmap_config hdmi_regmap_8bit_config = {
>  	.reg_bits	= 32,
>  	.val_bits	= 8,
> @@ -2245,6 +2269,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  	struct device_node *np = dev->of_node;
>  	struct platform_device_info pdevinfo;
>  	struct device_node *ddc_node;
> +	struct dw_hdmi_cec_data cec;
>  	struct dw_hdmi *hdmi;
>  	struct resource *iores = NULL;
>  	int irq;
> @@ -2445,6 +2470,17 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  		hdmi->audio = platform_device_register_full(&pdevinfo);
>  	}
>  
> +	cec.hdmi = hdmi;
> +	cec.ops = &dw_hdmi_cec_ops;
> +	cec.irq = irq;
> +
> +	pdevinfo.name = "dw-hdmi-cec";
> +	pdevinfo.data = &cec;
> +	pdevinfo.size_data = sizeof(cec);
> +	pdevinfo.dma_mask = 0;
> +
> +	hdmi->cec = platform_device_register_full(&pdevinfo);
> +
>  	/* Reset HDMI DDC I2C master controller and mute I2CM interrupts */
>  	if (hdmi->i2c)
>  		dw_hdmi_i2c_init(hdmi);
> @@ -2475,6 +2511,8 @@ static void __dw_hdmi_remove(struct dw_hdmi *hdmi)
>  {
>  	if (hdmi->audio && !IS_ERR(hdmi->audio))
>  		platform_device_unregister(hdmi->audio);
> +	if (!IS_ERR(hdmi->cec))
> +		platform_device_unregister(hdmi->cec);
>  
>  	/* Disable all interrupts */
>  	hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);

Best regards,
Jose Miguel Abreu

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver
@ 2017-06-01  0:53     ` Jose Abreu
  0 siblings, 0 replies; 84+ messages in thread
From: Jose Abreu @ 2017-06-01  0:53 UTC (permalink / raw)
  To: Russell King; +Cc: Hans Verkuil, linux-arm-kernel, dri-devel

Hi Russell,


On 30-05-2017 15:23, Russell King wrote:
> Add a CEC driver for the dw-hdmi hardware.
>
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> ---
>  drivers/gpu/drm/bridge/synopsys/Kconfig       |   8 +
>  drivers/gpu/drm/bridge/synopsys/Makefile      |   1 +
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 320 ++++++++++++++++++++++++++
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h |  19 ++
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c     |  40 +++-
>  5 files changed, 387 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
>  create mode 100644 drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
>
> diff --git a/drivers/gpu/drm/bridge/synopsys/Kconfig b/drivers/gpu/drm/bridge/synopsys/Kconfig
> index 40d2827a6d19..bd30a0a07272 100644
> --- a/drivers/gpu/drm/bridge/synopsys/Kconfig
> +++ b/drivers/gpu/drm/bridge/synopsys/Kconfig
> @@ -21,3 +21,11 @@ config DRM_DW_HDMI_I2S_AUDIO
>  	help
>  	  Support the I2S Audio interface which is part of the Synopsys
>  	  Designware HDMI block.
> +
> +config DRM_DW_HDMI_CEC
> +	tristate "Synopsis Designware CEC interface"
> +	depends on DRM_DW_HDMI && MEDIA_CEC_SUPPORT
> +	select MEDIA_CEC_NOTIFIER
> +	help
> +	  Support the CE interface which is part of the Synopsis

Synopsis -> Synopsys

> +	  Designware HDMI block.
> diff --git a/drivers/gpu/drm/bridge/synopsys/Makefile b/drivers/gpu/drm/bridge/synopsys/Makefile
> index 17aa7a65b57e..6fe415903668 100644
> --- a/drivers/gpu/drm/bridge/synopsys/Makefile
> +++ b/drivers/gpu/drm/bridge/synopsys/Makefile
> @@ -3,3 +3,4 @@
>  obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
>  obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
>  obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o
> +obj-$(CONFIG_DRM_DW_HDMI_CEC) += dw-hdmi-cec.o
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
> new file mode 100644
> index 000000000000..761ef5ae687d
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
> @@ -0,0 +1,320 @@
> +/*
> + * Designware HDMI CEC driver
> + *
> + * Copyright (C) 2015-2017 Russell King.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/sched.h>
> +#include <linux/slab.h>
> +
> +#include <drm/drm_edid.h>
> +
> +#include <media/cec.h>
> +#include <media/cec-notifier.h>
> +
> +#include "dw-hdmi-cec.h"
> +
> +enum {
> +	HDMI_IH_CEC_STAT0	= 0x0106,
> +	HDMI_IH_MUTE_CEC_STAT0	= 0x0186,
> +
> +	HDMI_CEC_CTRL		= 0x7d00,
> +	CEC_CTRL_START		= BIT(0),
> +	CEC_CTRL_NORMAL		= 1 << 1,
> +
> +	HDMI_CEC_STAT		= 0x7d01,
> +	CEC_STAT_DONE		= BIT(0),
> +	CEC_STAT_EOM		= BIT(1),
> +	CEC_STAT_NACK		= BIT(2),
> +	CEC_STAT_ARBLOST	= BIT(3),
> +	CEC_STAT_ERROR_INIT	= BIT(4),
> +	CEC_STAT_ERROR_FOLL	= BIT(5),
> +	CEC_STAT_WAKEUP		= BIT(6),

I rather like the format HDMI_{REGISTER_NAME}_{FIELD_NAME} so
that it clearly identifies this is a internal driver register and
not a CEC core register, but I guess its up to you :)

> +
> +	HDMI_CEC_MASK		= 0x7d02,
> +	HDMI_CEC_POLARITY	= 0x7d03,
> +	HDMI_CEC_INT		= 0x7d04,
> +	HDMI_CEC_ADDR_L		= 0x7d05,
> +	HDMI_CEC_ADDR_H		= 0x7d06,
> +	HDMI_CEC_TX_CNT		= 0x7d07,
> +	HDMI_CEC_RX_CNT		= 0x7d08,
> +	HDMI_CEC_TX_DATA0	= 0x7d10,
> +	HDMI_CEC_RX_DATA0	= 0x7d20,
> +	HDMI_CEC_LOCK		= 0x7d30,
> +	HDMI_CEC_WKUPCTRL	= 0x7d31,
> +};
> +
> +struct dw_hdmi_cec {
> +	struct dw_hdmi *hdmi;
> +	const struct dw_hdmi_cec_ops *ops;
> +	u32 addresses;
> +	struct cec_adapter *adap;
> +	struct cec_msg rx_msg;
> +	unsigned int tx_status;
> +	bool tx_done;
> +	bool rx_done;
> +	struct cec_notifier *notify;
> +	int retries;
> +	int irq;
> +};
> +
> +static void dw_hdmi_write(struct dw_hdmi_cec *cec, u8 val, int offset)
> +{
> +	cec->ops->write(cec->hdmi, val, offset);
> +}
> +
> +static u8 dw_hdmi_read(struct dw_hdmi_cec *cec, int offset)
> +{
> +	return cec->ops->read(cec->hdmi, offset);
> +}
> +
> +static int dw_hdmi_cec_log_addr(struct cec_adapter *adap, u8 logical_addr)
> +{
> +	struct dw_hdmi_cec *cec = adap->priv;

You can use "cec = cec_get_drvdata(adap)" here, as in the rest of
the code.

> +	u32 addresses;
> +
> +	if (logical_addr == CEC_LOG_ADDR_INVALID)
> +		addresses = cec->addresses = 0;
> +	else
> +		addresses = cec->addresses |= BIT(logical_addr) | BIT(15);
> +
> +	dw_hdmi_write(cec, addresses & 255, HDMI_CEC_ADDR_L);
> +	dw_hdmi_write(cec, addresses >> 8, HDMI_CEC_ADDR_H);
> +
> +	return 0;
> +}
> +
> +static int dw_hdmi_cec_transmit(struct cec_adapter *adap, u8 attempts,
> +				u32 signal_free_time, struct cec_msg *msg)
> +{
> +	struct dw_hdmi_cec *cec = adap->priv;
> +	unsigned i;
> +
> +	cec->retries = attempts;

I think you should check first if CEC engine is in normal
operation mode, as a safety measure.

> +
> +	for (i = 0; i < msg->len; i++)
> +		dw_hdmi_write(cec, msg->msg[i], HDMI_CEC_TX_DATA0 + i);
> +
> +	dw_hdmi_write(cec, msg->len, HDMI_CEC_TX_CNT);
> +	dw_hdmi_write(cec, CEC_CTRL_NORMAL | CEC_CTRL_START, HDMI_CEC_CTRL);
> +
> +	return 0;
> +}
> +
> +static irqreturn_t dw_hdmi_cec_hardirq(int irq, void *data)
> +{
> +	struct cec_adapter *adap = data;
> +	struct dw_hdmi_cec *cec = adap->priv;
> +	unsigned stat = dw_hdmi_read(cec, HDMI_IH_CEC_STAT0);
> +	irqreturn_t ret = IRQ_HANDLED;
> +
> +	if (stat == 0)
> +		return IRQ_NONE;
> +
> +	dw_hdmi_write(cec, stat, HDMI_IH_CEC_STAT0);
> +
> +	if (stat & CEC_STAT_ERROR_INIT) {
> +		if (cec->retries) {
> +			unsigned v = dw_hdmi_read(cec, HDMI_CEC_CTRL);
> +			dw_hdmi_write(cec, v | CEC_CTRL_START, HDMI_CEC_CTRL);
> +			cec->retries -= 1;
> +		} else {
> +			cec->tx_status = CEC_TX_STATUS_MAX_RETRIES;
> +			cec->tx_done = true;
> +			ret = IRQ_WAKE_THREAD;
> +		}
> +	} else if (stat & CEC_STAT_DONE) {
> +		cec->tx_status = CEC_TX_STATUS_OK;
> +		cec->tx_done = true;
> +		ret = IRQ_WAKE_THREAD;
> +	} else if (stat & CEC_STAT_NACK) {
> +		cec->tx_status = CEC_TX_STATUS_NACK;
> +		cec->tx_done = true;
> +		ret = IRQ_WAKE_THREAD;
> +	}
> +
> +	if (stat & CEC_STAT_EOM) {
> +		unsigned len, i;
> +
> +		len = dw_hdmi_read(cec, HDMI_CEC_RX_CNT);
> +		if (len > sizeof(cec->rx_msg.msg))
> +			len = sizeof(cec->rx_msg.msg);
> +
> +		for (i = 0; i < len; i++)
> +			cec->rx_msg.msg[i] =
> +				dw_hdmi_read(cec, HDMI_CEC_RX_DATA0 + i);
> +
> +		dw_hdmi_write(cec, 0, HDMI_CEC_LOCK);
> +
> +		cec->rx_msg.len = len;
> +		smp_wmb();
> +		cec->rx_done = true;
> +
> +		ret = IRQ_WAKE_THREAD;
> +	}
> +
> +	return ret;
> +}
> +
> +static irqreturn_t dw_hdmi_cec_thread(int irq, void *data)
> +{
> +	struct cec_adapter *adap = data;
> +	struct dw_hdmi_cec *cec = adap->priv;
> +
> +	if (cec->tx_done) {
> +		cec->tx_done = false;
> +		cec_transmit_done(adap, cec->tx_status, 0, 0, 0, 0);
> +	}
> +	if (cec->rx_done) {
> +		cec->rx_done = false;
> +		smp_rmb();
> +		cec_received_msg(adap, &cec->rx_msg);
> +	}
> +	return IRQ_HANDLED;
> +}
> +
> +static int dw_hdmi_cec_enable(struct cec_adapter *adap, bool enable)
> +{
> +	struct dw_hdmi_cec *cec = adap->priv;
> +
> +	if (!enable) {
> +		dw_hdmi_write(cec, ~0, HDMI_CEC_MASK);
> +		dw_hdmi_write(cec, ~0, HDMI_IH_MUTE_CEC_STAT0);
> +		dw_hdmi_write(cec, 0, HDMI_CEC_POLARITY);
> +
> +		cec->ops->disable(cec->hdmi);
> +	} else {
> +		unsigned irqs;
> +
> +		dw_hdmi_write(cec, 0, HDMI_CEC_CTRL);
> +		dw_hdmi_write(cec, ~0, HDMI_IH_CEC_STAT0);
> +		dw_hdmi_write(cec, 0, HDMI_CEC_LOCK);
> +
> +		dw_hdmi_cec_log_addr(cec->adap, CEC_LOG_ADDR_INVALID);
> +
> +		cec->ops->enable(cec->hdmi);
> +
> +		irqs = CEC_STAT_ERROR_INIT | CEC_STAT_NACK | CEC_STAT_EOM |
> +		       CEC_STAT_DONE;
> +		dw_hdmi_write(cec, irqs, HDMI_CEC_POLARITY);
> +		dw_hdmi_write(cec, ~irqs, HDMI_CEC_MASK);
> +		dw_hdmi_write(cec, ~irqs, HDMI_IH_MUTE_CEC_STAT0);
> +	}
> +	return 0;
> +}
> +
> +static const struct cec_adap_ops dw_hdmi_cec_ops = {
> +	.adap_enable = dw_hdmi_cec_enable,
> +	.adap_log_addr = dw_hdmi_cec_log_addr,
> +	.adap_transmit = dw_hdmi_cec_transmit,
> +};
> +
> +static void dw_hdmi_cec_del(void *data)
> +{
> +	struct dw_hdmi_cec *cec = data;
> +
> +	cec_delete_adapter(cec->adap);
> +}
> +
> +static int dw_hdmi_cec_probe(struct platform_device *pdev)
> +{
> +	struct dw_hdmi_cec_data *data = dev_get_platdata(&pdev->dev);
> +	struct dw_hdmi_cec *cec;
> +	int ret;
> +
> +	if (!data)
> +		return -ENXIO;
> +
> +	/*
> +	 * Our device is just a convenience - we want to link to the real
> +	 * hardware device here, so that userspace can see the association
> +	 * between the HDMI hardware and its associated CEC chardev.
> +	 */
> +	cec = devm_kzalloc(&pdev->dev, sizeof(*cec), GFP_KERNEL);
> +	if (!cec)
> +		return -ENOMEM;
> +
> +	cec->irq = data->irq;
> +	cec->ops = data->ops;
> +	cec->hdmi = data->hdmi;
> +
> +	platform_set_drvdata(pdev, cec);
> +
> +	dw_hdmi_write(cec, 0, HDMI_CEC_TX_CNT);
> +	dw_hdmi_write(cec, ~0, HDMI_CEC_MASK);
> +	dw_hdmi_write(cec, ~0, HDMI_IH_MUTE_CEC_STAT0);
> +	dw_hdmi_write(cec, 0, HDMI_CEC_POLARITY);
> +
> +	cec->adap = cec_allocate_adapter(&dw_hdmi_cec_ops, cec, "dw_hdmi",
> +					 CEC_CAP_LOG_ADDRS | CEC_CAP_TRANSMIT |
> +					 CEC_CAP_RC, CEC_MAX_LOG_ADDRS);
> +	if (IS_ERR(cec->adap))
> +		return PTR_ERR(cec->adap);
> +
> +	/* override the module pointer */
> +	cec->adap->owner = THIS_MODULE;
> +
> +	ret = devm_add_action(&pdev->dev, dw_hdmi_cec_del, cec);
> +	if (ret) {
> +		cec_delete_adapter(cec->adap);
> +		return ret;
> +	}
> +
> +	ret = devm_request_threaded_irq(&pdev->dev, cec->irq,
> +					dw_hdmi_cec_hardirq,
> +					dw_hdmi_cec_thread, IRQF_SHARED,
> +					"dw-hdmi-cec", cec->adap);
> +	if (ret < 0)
> +		return ret;
> +
> +	cec->notify = cec_notifier_get(pdev->dev.parent);
> +	if (!cec->notify)
> +		return -ENOMEM;
> +
> +	ret = cec_register_adapter(cec->adap, pdev->dev.parent);
> +	if (ret < 0) {
> +		cec_notifier_put(cec->notify);
> +		return ret;
> +	}
> +
> +	/*
> +	 * CEC documentation says we must not call cec_delete_adapter
> +	 * after a successful call to cec_register_adapter().
> +	 */
> +	devm_remove_action(&pdev->dev, dw_hdmi_cec_del, cec);
> +
> +	cec_register_cec_notifier(cec->adap, cec->notify);
> +
> +	return 0;
> +}
> +
> +static int dw_hdmi_cec_remove(struct platform_device *pdev)
> +{
> +	struct dw_hdmi_cec *cec = platform_get_drvdata(pdev);
> +
> +	cec_unregister_adapter(cec->adap);
> +	cec_notifier_put(cec->notify);
> +
> +	return 0;
> +}
> +
> +static struct platform_driver dw_hdmi_cec_driver = {
> +	.probe	= dw_hdmi_cec_probe,
> +	.remove	= dw_hdmi_cec_remove,
> +	.driver = {
> +		.name = "dw-hdmi-cec",
> +	},
> +};
> +module_platform_driver(dw_hdmi_cec_driver);
> +
> +MODULE_AUTHOR("Russell King <rmk+kernel@armlinux.org.uk>");
> +MODULE_DESCRIPTION("Synopsis Designware HDMI CEC driver for i.MX");

Synopsis -> Synopsys

> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS(PLATFORM_MODULE_PREFIX "dw-hdmi-cec");
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
> new file mode 100644
> index 000000000000..cf4dc121a2c4
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
> @@ -0,0 +1,19 @@
> +#ifndef DW_HDMI_CEC_H
> +#define DW_HDMI_CEC_H
> +
> +struct dw_hdmi;
> +
> +struct dw_hdmi_cec_ops {
> +	void (*write)(struct dw_hdmi *hdmi, u8 val, int offset);
> +	u8 (*read)(struct dw_hdmi *hdmi, int offset);
> +	void (*enable)(struct dw_hdmi *hdmi);
> +	void (*disable)(struct dw_hdmi *hdmi);
> +};
> +
> +struct dw_hdmi_cec_data {
> +	struct dw_hdmi *hdmi;
> +	const struct dw_hdmi_cec_ops *ops;
> +	int irq;
> +};
> +
> +#endif
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 58781d4c1034..5a389f1f58d9 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -35,6 +35,7 @@
>  
>  #include "dw-hdmi.h"
>  #include "dw-hdmi-audio.h"
> +#include "dw-hdmi-cec.h"
>  
>  #include <media/cec-notifier.h>
>  
> @@ -133,6 +134,7 @@ struct dw_hdmi {
>  	unsigned int version;
>  
>  	struct platform_device *audio;
> +	struct platform_device *cec;
>  	struct device *dev;
>  	struct clk *isfr_clk;
>  	struct clk *iahb_clk;
> @@ -1766,7 +1768,6 @@ static void initialize_hdmi_ih_mutes(struct dw_hdmi *hdmi)
>  	hdmi_writeb(hdmi, 0xff, HDMI_AUD_HBR_MASK);
>  	hdmi_writeb(hdmi, 0xff, HDMI_GP_MASK);
>  	hdmi_writeb(hdmi, 0xff, HDMI_A_APIINTMSK);
> -	hdmi_writeb(hdmi, 0xff, HDMI_CEC_MASK);
>  	hdmi_writeb(hdmi, 0xff, HDMI_I2CM_INT);
>  	hdmi_writeb(hdmi, 0xff, HDMI_I2CM_CTLINT);
>  
> @@ -2223,6 +2224,29 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi)
>  	return -ENODEV;
>  }
>  
> +static void dw_hdmi_cec_enable(struct dw_hdmi *hdmi)
> +{
> +	mutex_lock(&hdmi->mutex);
> +	hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CECCLK_DISABLE;
> +	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
> +	mutex_unlock(&hdmi->mutex);
> +}
> +
> +static void dw_hdmi_cec_disable(struct dw_hdmi *hdmi)
> +{
> +	mutex_lock(&hdmi->mutex);
> +	hdmi->mc_clkdis |= HDMI_MC_CLKDIS_CECCLK_DISABLE;
> +	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
> +	mutex_unlock(&hdmi->mutex);
> +}
> +
> +static const struct dw_hdmi_cec_ops dw_hdmi_cec_ops = {
> +	.write = hdmi_writeb,
> +	.read = hdmi_readb,
> +	.enable = dw_hdmi_cec_enable,
> +	.disable = dw_hdmi_cec_disable,
> +};
> +
>  static const struct regmap_config hdmi_regmap_8bit_config = {
>  	.reg_bits	= 32,
>  	.val_bits	= 8,
> @@ -2245,6 +2269,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  	struct device_node *np = dev->of_node;
>  	struct platform_device_info pdevinfo;
>  	struct device_node *ddc_node;
> +	struct dw_hdmi_cec_data cec;
>  	struct dw_hdmi *hdmi;
>  	struct resource *iores = NULL;
>  	int irq;
> @@ -2445,6 +2470,17 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  		hdmi->audio = platform_device_register_full(&pdevinfo);
>  	}
>  
> +	cec.hdmi = hdmi;
> +	cec.ops = &dw_hdmi_cec_ops;
> +	cec.irq = irq;
> +
> +	pdevinfo.name = "dw-hdmi-cec";
> +	pdevinfo.data = &cec;
> +	pdevinfo.size_data = sizeof(cec);
> +	pdevinfo.dma_mask = 0;
> +
> +	hdmi->cec = platform_device_register_full(&pdevinfo);
> +
>  	/* Reset HDMI DDC I2C master controller and mute I2CM interrupts */
>  	if (hdmi->i2c)
>  		dw_hdmi_i2c_init(hdmi);
> @@ -2475,6 +2511,8 @@ static void __dw_hdmi_remove(struct dw_hdmi *hdmi)
>  {
>  	if (hdmi->audio && !IS_ERR(hdmi->audio))
>  		platform_device_unregister(hdmi->audio);
> +	if (!IS_ERR(hdmi->cec))
> +		platform_device_unregister(hdmi->cec);
>  
>  	/* Disable all interrupts */
>  	hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);

Best regards,
Jose Miguel Abreu

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 3/4] drm/bridge: dw-hdmi: add better clock disable control
  2017-05-30 14:23   ` Russell King
@ 2017-06-01  0:55     ` Jose Abreu
  -1 siblings, 0 replies; 84+ messages in thread
From: Jose Abreu @ 2017-06-01  0:55 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Russell,


On 30-05-2017 15:23, Russell King wrote:
> The video setup path aways sets the clock disable register to a specific
> value, which has the effect of disabling the CEC engine.  When we add the
> CEC driver, this becomes a problem.
>
> Fix this by only setting/clearing the bits that the video path needs to.
>
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>

Reviewed-by: Jose Abreu <joabreu@synopsys.com>

Best regards,
Jose Miguel Abreu

> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 25 +++++++++++++++----------
>  1 file changed, 15 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 966422576c44..58781d4c1034 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -166,6 +166,7 @@ struct dw_hdmi {
>  	bool bridge_is_on;		/* indicates the bridge is on */
>  	bool rxsense;			/* rxsense state */
>  	u8 phy_mask;			/* desired phy int mask settings */
> +	u8 mc_clkdis;			/* clock disable register */
>  
>  	spinlock_t audio_lock;
>  	struct mutex audio_mutex;
> @@ -1543,8 +1544,6 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
>  /* HDMI Initialization Step B.4 */
>  static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
>  {
> -	u8 clkdis;
> -
>  	/* control period minimum duration */
>  	hdmi_writeb(hdmi, 12, HDMI_FC_CTRLDUR);
>  	hdmi_writeb(hdmi, 32, HDMI_FC_EXCTRLDUR);
> @@ -1556,17 +1555,21 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
>  	hdmi_writeb(hdmi, 0x21, HDMI_FC_CH2PREAM);
>  
>  	/* Enable pixel clock and tmds data path */
> -	clkdis = 0x7F;
> -	clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
> -	hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
> +	hdmi->mc_clkdis |= HDMI_MC_CLKDIS_HDCPCLK_DISABLE |
> +			   HDMI_MC_CLKDIS_CSCCLK_DISABLE |
> +			   HDMI_MC_CLKDIS_AUDCLK_DISABLE |
> +			   HDMI_MC_CLKDIS_PREPCLK_DISABLE |
> +			   HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
> +	hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
> +	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
>  
> -	clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
> -	hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
> +	hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
> +	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
>  
>  	/* Enable csc path */
>  	if (is_color_space_conversion(hdmi)) {
> -		clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
> -		hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
> +		hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
> +		hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
>  	}
>  
>  	/* Enable color space conversion if needed */
> @@ -1580,7 +1583,8 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
>  
>  static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi)
>  {
> -	hdmi_modb(hdmi, 0, HDMI_MC_CLKDIS_AUDCLK_DISABLE, HDMI_MC_CLKDIS);
> +	hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_AUDCLK_DISABLE;
> +	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
>  }
>  
>  /* Workaround to clear the overflow condition */
> @@ -2261,6 +2265,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  	hdmi->disabled = true;
>  	hdmi->rxsense = true;
>  	hdmi->phy_mask = (u8)~(HDMI_PHY_HPD | HDMI_PHY_RX_SENSE);
> +	hdmi->mc_clkdis = 0x7f;
>  
>  	mutex_init(&hdmi->mutex);
>  	mutex_init(&hdmi->audio_mutex);

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH 3/4] drm/bridge: dw-hdmi: add better clock disable control
@ 2017-06-01  0:55     ` Jose Abreu
  0 siblings, 0 replies; 84+ messages in thread
From: Jose Abreu @ 2017-06-01  0:55 UTC (permalink / raw)
  To: Russell King, Hans Verkuil; +Cc: linux-arm-kernel, dri-devel

Hi Russell,


On 30-05-2017 15:23, Russell King wrote:
> The video setup path aways sets the clock disable register to a specific
> value, which has the effect of disabling the CEC engine.  When we add the
> CEC driver, this becomes a problem.
>
> Fix this by only setting/clearing the bits that the video path needs to.
>
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>

Reviewed-by: Jose Abreu <joabreu@synopsys.com>

Best regards,
Jose Miguel Abreu

> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 25 +++++++++++++++----------
>  1 file changed, 15 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 966422576c44..58781d4c1034 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -166,6 +166,7 @@ struct dw_hdmi {
>  	bool bridge_is_on;		/* indicates the bridge is on */
>  	bool rxsense;			/* rxsense state */
>  	u8 phy_mask;			/* desired phy int mask settings */
> +	u8 mc_clkdis;			/* clock disable register */
>  
>  	spinlock_t audio_lock;
>  	struct mutex audio_mutex;
> @@ -1543,8 +1544,6 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
>  /* HDMI Initialization Step B.4 */
>  static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
>  {
> -	u8 clkdis;
> -
>  	/* control period minimum duration */
>  	hdmi_writeb(hdmi, 12, HDMI_FC_CTRLDUR);
>  	hdmi_writeb(hdmi, 32, HDMI_FC_EXCTRLDUR);
> @@ -1556,17 +1555,21 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
>  	hdmi_writeb(hdmi, 0x21, HDMI_FC_CH2PREAM);
>  
>  	/* Enable pixel clock and tmds data path */
> -	clkdis = 0x7F;
> -	clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
> -	hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
> +	hdmi->mc_clkdis |= HDMI_MC_CLKDIS_HDCPCLK_DISABLE |
> +			   HDMI_MC_CLKDIS_CSCCLK_DISABLE |
> +			   HDMI_MC_CLKDIS_AUDCLK_DISABLE |
> +			   HDMI_MC_CLKDIS_PREPCLK_DISABLE |
> +			   HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
> +	hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
> +	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
>  
> -	clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
> -	hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
> +	hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
> +	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
>  
>  	/* Enable csc path */
>  	if (is_color_space_conversion(hdmi)) {
> -		clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
> -		hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
> +		hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
> +		hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
>  	}
>  
>  	/* Enable color space conversion if needed */
> @@ -1580,7 +1583,8 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
>  
>  static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi)
>  {
> -	hdmi_modb(hdmi, 0, HDMI_MC_CLKDIS_AUDCLK_DISABLE, HDMI_MC_CLKDIS);
> +	hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_AUDCLK_DISABLE;
> +	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
>  }
>  
>  /* Workaround to clear the overflow condition */
> @@ -2261,6 +2265,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  	hdmi->disabled = true;
>  	hdmi->rxsense = true;
>  	hdmi->phy_mask = (u8)~(HDMI_PHY_HPD | HDMI_PHY_RX_SENSE);
> +	hdmi->mc_clkdis = 0x7f;
>  
>  	mutex_init(&hdmi->mutex);
>  	mutex_init(&hdmi->audio_mutex);

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver
  2017-05-30 14:23   ` Russell King
@ 2017-06-01  8:31     ` Hans Verkuil
  -1 siblings, 0 replies; 84+ messages in thread
From: Hans Verkuil @ 2017-06-01  8:31 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Russell,

First a few top-level questions:

1) What was the reason for using the cec-notifier here? Isn't this
   tightly integrated into the main dw-hdmi block? For the tda driver
   it is clearly required, but for tightly coupled HDMI & CEC HW I
   just create the adapter from the HDMI driver. As a small bonus it
   avoids adding the cec-notifier code and the control flow is a bit
   easier to trace.

2) I may have asked this before, apologies if I repeat myself: does
   this CEC implementation support CEC monitoring (aka snooping)? If
   it does, then I recommend that it is implemented since it is very
   useful.

3) Is the CEC still active if there is no hotplug signal? Or is it
   powered off in that case? Ideally it should still be possible to
   send CEC messages even if there is no hotplug. This is explicitly
   allowed by the CEC 2.0 spec to wake up displays that turn off the
   HPD, but that still have a working CEC controller.

   If this is not possible, then you need to use the CEC_CAP_NEEDS_HPD
   capability. See: https://patchwork.linuxtv.org/patch/41478/

   This will almost certainly be merged for 4.13 since other CEC drivers
   need this as well.

On 05/30/17 16:23, Russell King wrote:
> Add a CEC driver for the dw-hdmi hardware.
> 
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> ---
>  drivers/gpu/drm/bridge/synopsys/Kconfig       |   8 +
>  drivers/gpu/drm/bridge/synopsys/Makefile      |   1 +
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 320 ++++++++++++++++++++++++++
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h |  19 ++
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c     |  40 +++-
>  5 files changed, 387 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
>  create mode 100644 drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/Kconfig b/drivers/gpu/drm/bridge/synopsys/Kconfig
> index 40d2827a6d19..bd30a0a07272 100644
> --- a/drivers/gpu/drm/bridge/synopsys/Kconfig
> +++ b/drivers/gpu/drm/bridge/synopsys/Kconfig
> @@ -21,3 +21,11 @@ config DRM_DW_HDMI_I2S_AUDIO
>  	help
>  	  Support the I2S Audio interface which is part of the Synopsys
>  	  Designware HDMI block.
> +
> +config DRM_DW_HDMI_CEC
> +	tristate "Synopsis Designware CEC interface"
> +	depends on DRM_DW_HDMI && MEDIA_CEC_SUPPORT
> +	select MEDIA_CEC_NOTIFIER
> +	help
> +	  Support the CE interface which is part of the Synopsis
> +	  Designware HDMI block.

This will change. Patches to fix the config handling are pending for 4.12.

Here you can see the pending patches:
https://git.linuxtv.org/hverkuil/media_tree.git/log/?h=drm-cec

The patches from 'cec-notifier.h: handle unreachable CONFIG_CEC_CORE' to
'cec: drop MEDIA_CEC_DEBUG' should all be merged in 4.12.

That means that this config becomes:

+
+config DRM_DW_HDMI_CEC
+	tristate "Synopsis Designware CEC interface"
+	depends on DRM_DW_HDMI
+	select CEC_CORE
+	select CEC_NOTIFIER
+	help
+	  Support the CE interface which is part of the Synopsis
+	  Designware HDMI block.

> diff --git a/drivers/gpu/drm/bridge/synopsys/Makefile b/drivers/gpu/drm/bridge/synopsys/Makefile
> index 17aa7a65b57e..6fe415903668 100644
> --- a/drivers/gpu/drm/bridge/synopsys/Makefile
> +++ b/drivers/gpu/drm/bridge/synopsys/Makefile
> @@ -3,3 +3,4 @@
>  obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
>  obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
>  obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o
> +obj-$(CONFIG_DRM_DW_HDMI_CEC) += dw-hdmi-cec.o
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
> new file mode 100644
> index 000000000000..761ef5ae687d
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
> @@ -0,0 +1,320 @@
> +/*
> + * Designware HDMI CEC driver
> + *
> + * Copyright (C) 2015-2017 Russell King.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/sched.h>
> +#include <linux/slab.h>
> +
> +#include <drm/drm_edid.h>
> +
> +#include <media/cec.h>
> +#include <media/cec-notifier.h>
> +
> +#include "dw-hdmi-cec.h"
> +
> +enum {
> +	HDMI_IH_CEC_STAT0	= 0x0106,
> +	HDMI_IH_MUTE_CEC_STAT0	= 0x0186,
> +
> +	HDMI_CEC_CTRL		= 0x7d00,
> +	CEC_CTRL_START		= BIT(0),
> +	CEC_CTRL_NORMAL		= 1 << 1,
> +
> +	HDMI_CEC_STAT		= 0x7d01,
> +	CEC_STAT_DONE		= BIT(0),
> +	CEC_STAT_EOM		= BIT(1),
> +	CEC_STAT_NACK		= BIT(2),
> +	CEC_STAT_ARBLOST	= BIT(3),
> +	CEC_STAT_ERROR_INIT	= BIT(4),
> +	CEC_STAT_ERROR_FOLL	= BIT(5),
> +	CEC_STAT_WAKEUP		= BIT(6),
> +
> +	HDMI_CEC_MASK		= 0x7d02,
> +	HDMI_CEC_POLARITY	= 0x7d03,
> +	HDMI_CEC_INT		= 0x7d04,
> +	HDMI_CEC_ADDR_L		= 0x7d05,
> +	HDMI_CEC_ADDR_H		= 0x7d06,
> +	HDMI_CEC_TX_CNT		= 0x7d07,
> +	HDMI_CEC_RX_CNT		= 0x7d08,
> +	HDMI_CEC_TX_DATA0	= 0x7d10,
> +	HDMI_CEC_RX_DATA0	= 0x7d20,
> +	HDMI_CEC_LOCK		= 0x7d30,
> +	HDMI_CEC_WKUPCTRL	= 0x7d31,
> +};
> +
> +struct dw_hdmi_cec {
> +	struct dw_hdmi *hdmi;
> +	const struct dw_hdmi_cec_ops *ops;
> +	u32 addresses;
> +	struct cec_adapter *adap;
> +	struct cec_msg rx_msg;
> +	unsigned int tx_status;
> +	bool tx_done;
> +	bool rx_done;
> +	struct cec_notifier *notify;
> +	int retries;
> +	int irq;
> +};
> +
> +static void dw_hdmi_write(struct dw_hdmi_cec *cec, u8 val, int offset)
> +{
> +	cec->ops->write(cec->hdmi, val, offset);
> +}
> +
> +static u8 dw_hdmi_read(struct dw_hdmi_cec *cec, int offset)
> +{
> +	return cec->ops->read(cec->hdmi, offset);
> +}
> +
> +static int dw_hdmi_cec_log_addr(struct cec_adapter *adap, u8 logical_addr)
> +{
> +	struct dw_hdmi_cec *cec = adap->priv;
> +	u32 addresses;
> +
> +	if (logical_addr == CEC_LOG_ADDR_INVALID)
> +		addresses = cec->addresses = 0;
> +	else
> +		addresses = cec->addresses |= BIT(logical_addr) | BIT(15);
> +
> +	dw_hdmi_write(cec, addresses & 255, HDMI_CEC_ADDR_L);
> +	dw_hdmi_write(cec, addresses >> 8, HDMI_CEC_ADDR_H);

The addresses local variable doesn't really seem needed.

> +
> +	return 0;
> +}
> +
> +static int dw_hdmi_cec_transmit(struct cec_adapter *adap, u8 attempts,
> +				u32 signal_free_time, struct cec_msg *msg)
> +{
> +	struct dw_hdmi_cec *cec = adap->priv;
> +	unsigned i;
> +
> +	cec->retries = attempts;

Should probably be 'cec->retries = attempts - 1;'
Since 2 attempts == 1 retry.

> +
> +	for (i = 0; i < msg->len; i++)
> +		dw_hdmi_write(cec, msg->msg[i], HDMI_CEC_TX_DATA0 + i);
> +
> +	dw_hdmi_write(cec, msg->len, HDMI_CEC_TX_CNT);
> +	dw_hdmi_write(cec, CEC_CTRL_NORMAL | CEC_CTRL_START, HDMI_CEC_CTRL);
> +
> +	return 0;
> +}
> +
> +static irqreturn_t dw_hdmi_cec_hardirq(int irq, void *data)
> +{
> +	struct cec_adapter *adap = data;
> +	struct dw_hdmi_cec *cec = adap->priv;
> +	unsigned stat = dw_hdmi_read(cec, HDMI_IH_CEC_STAT0);
> +	irqreturn_t ret = IRQ_HANDLED;
> +
> +	if (stat == 0)
> +		return IRQ_NONE;
> +
> +	dw_hdmi_write(cec, stat, HDMI_IH_CEC_STAT0);
> +
> +	if (stat & CEC_STAT_ERROR_INIT) {
> +		if (cec->retries) {
> +			unsigned v = dw_hdmi_read(cec, HDMI_CEC_CTRL);
> +			dw_hdmi_write(cec, v | CEC_CTRL_START, HDMI_CEC_CTRL);
> +			cec->retries -= 1;

Why handle retries here at all? Just mark this as CEC_TX_STATUS_ERROR and set
tx_done to true. The CEC core will just call dw_hdmi_cec_transmit again if
it needs to make another attempt. I suggest that the whole retry code is
dropped.

> +		} else {
> +			cec->tx_status = CEC_TX_STATUS_MAX_RETRIES;
> +			cec->tx_done = true;
> +			ret = IRQ_WAKE_THREAD;
> +		}
> +	} else if (stat & CEC_STAT_DONE) {
> +		cec->tx_status = CEC_TX_STATUS_OK;
> +		cec->tx_done = true;
> +		ret = IRQ_WAKE_THREAD;
> +	} else if (stat & CEC_STAT_NACK) {
> +		cec->tx_status = CEC_TX_STATUS_NACK;
> +		cec->tx_done = true;
> +		ret = IRQ_WAKE_THREAD;
> +	}
> +
> +	if (stat & CEC_STAT_EOM) {
> +		unsigned len, i;
> +
> +		len = dw_hdmi_read(cec, HDMI_CEC_RX_CNT);
> +		if (len > sizeof(cec->rx_msg.msg))
> +			len = sizeof(cec->rx_msg.msg);
> +
> +		for (i = 0; i < len; i++)
> +			cec->rx_msg.msg[i] =
> +				dw_hdmi_read(cec, HDMI_CEC_RX_DATA0 + i);
> +
> +		dw_hdmi_write(cec, 0, HDMI_CEC_LOCK);
> +
> +		cec->rx_msg.len = len;
> +		smp_wmb();
> +		cec->rx_done = true;
> +
> +		ret = IRQ_WAKE_THREAD;
> +	}
> +
> +	return ret;
> +}
> +
> +static irqreturn_t dw_hdmi_cec_thread(int irq, void *data)
> +{
> +	struct cec_adapter *adap = data;
> +	struct dw_hdmi_cec *cec = adap->priv;
> +
> +	if (cec->tx_done) {
> +		cec->tx_done = false;
> +		cec_transmit_done(adap, cec->tx_status, 0, 0, 0, 0);

I think I will make a patch for a new helper function where you can just call:

cec_transmit_attempt_done(adap, cec->tx_status);

and that will call cec_transmit_done filling in the other arguments
based on the status.

Most CEC HW doesn't do retries so only make one attempt. In that case
only one of the remaining count arguments is 1 and that's based on the
status.

Having correct error counts is useful for debugging problems.

> +	}
> +	if (cec->rx_done) {
> +		cec->rx_done = false;
> +		smp_rmb();
> +		cec_received_msg(adap, &cec->rx_msg);
> +	}
> +	return IRQ_HANDLED;
> +}
> +
> +static int dw_hdmi_cec_enable(struct cec_adapter *adap, bool enable)
> +{
> +	struct dw_hdmi_cec *cec = adap->priv;
> +
> +	if (!enable) {
> +		dw_hdmi_write(cec, ~0, HDMI_CEC_MASK);
> +		dw_hdmi_write(cec, ~0, HDMI_IH_MUTE_CEC_STAT0);
> +		dw_hdmi_write(cec, 0, HDMI_CEC_POLARITY);
> +
> +		cec->ops->disable(cec->hdmi);
> +	} else {
> +		unsigned irqs;
> +
> +		dw_hdmi_write(cec, 0, HDMI_CEC_CTRL);
> +		dw_hdmi_write(cec, ~0, HDMI_IH_CEC_STAT0);
> +		dw_hdmi_write(cec, 0, HDMI_CEC_LOCK);
> +
> +		dw_hdmi_cec_log_addr(cec->adap, CEC_LOG_ADDR_INVALID);
> +
> +		cec->ops->enable(cec->hdmi);
> +
> +		irqs = CEC_STAT_ERROR_INIT | CEC_STAT_NACK | CEC_STAT_EOM |
> +		       CEC_STAT_DONE;
> +		dw_hdmi_write(cec, irqs, HDMI_CEC_POLARITY);
> +		dw_hdmi_write(cec, ~irqs, HDMI_CEC_MASK);
> +		dw_hdmi_write(cec, ~irqs, HDMI_IH_MUTE_CEC_STAT0);
> +	}
> +	return 0;
> +}
> +
> +static const struct cec_adap_ops dw_hdmi_cec_ops = {
> +	.adap_enable = dw_hdmi_cec_enable,
> +	.adap_log_addr = dw_hdmi_cec_log_addr,
> +	.adap_transmit = dw_hdmi_cec_transmit,
> +};
> +
> +static void dw_hdmi_cec_del(void *data)
> +{
> +	struct dw_hdmi_cec *cec = data;
> +
> +	cec_delete_adapter(cec->adap);
> +}
> +
> +static int dw_hdmi_cec_probe(struct platform_device *pdev)
> +{
> +	struct dw_hdmi_cec_data *data = dev_get_platdata(&pdev->dev);
> +	struct dw_hdmi_cec *cec;
> +	int ret;
> +
> +	if (!data)
> +		return -ENXIO;
> +
> +	/*
> +	 * Our device is just a convenience - we want to link to the real
> +	 * hardware device here, so that userspace can see the association
> +	 * between the HDMI hardware and its associated CEC chardev.
> +	 */
> +	cec = devm_kzalloc(&pdev->dev, sizeof(*cec), GFP_KERNEL);
> +	if (!cec)
> +		return -ENOMEM;
> +
> +	cec->irq = data->irq;
> +	cec->ops = data->ops;
> +	cec->hdmi = data->hdmi;
> +
> +	platform_set_drvdata(pdev, cec);
> +
> +	dw_hdmi_write(cec, 0, HDMI_CEC_TX_CNT);
> +	dw_hdmi_write(cec, ~0, HDMI_CEC_MASK);
> +	dw_hdmi_write(cec, ~0, HDMI_IH_MUTE_CEC_STAT0);
> +	dw_hdmi_write(cec, 0, HDMI_CEC_POLARITY);
> +
> +	cec->adap = cec_allocate_adapter(&dw_hdmi_cec_ops, cec, "dw_hdmi",
> +					 CEC_CAP_LOG_ADDRS | CEC_CAP_TRANSMIT |
> +					 CEC_CAP_RC, CEC_MAX_LOG_ADDRS);
> +	if (IS_ERR(cec->adap))
> +		return PTR_ERR(cec->adap);
> +
> +	/* override the module pointer */
> +	cec->adap->owner = THIS_MODULE;
> +
> +	ret = devm_add_action(&pdev->dev, dw_hdmi_cec_del, cec);
> +	if (ret) {
> +		cec_delete_adapter(cec->adap);
> +		return ret;
> +	}
> +
> +	ret = devm_request_threaded_irq(&pdev->dev, cec->irq,
> +					dw_hdmi_cec_hardirq,
> +					dw_hdmi_cec_thread, IRQF_SHARED,
> +					"dw-hdmi-cec", cec->adap);
> +	if (ret < 0)
> +		return ret;
> +
> +	cec->notify = cec_notifier_get(pdev->dev.parent);
> +	if (!cec->notify)
> +		return -ENOMEM;
> +
> +	ret = cec_register_adapter(cec->adap, pdev->dev.parent);
> +	if (ret < 0) {
> +		cec_notifier_put(cec->notify);
> +		return ret;
> +	}
> +
> +	/*
> +	 * CEC documentation says we must not call cec_delete_adapter
> +	 * after a successful call to cec_register_adapter().
> +	 */
> +	devm_remove_action(&pdev->dev, dw_hdmi_cec_del, cec);
> +
> +	cec_register_cec_notifier(cec->adap, cec->notify);
> +
> +	return 0;
> +}
> +
> +static int dw_hdmi_cec_remove(struct platform_device *pdev)
> +{
> +	struct dw_hdmi_cec *cec = platform_get_drvdata(pdev);
> +
> +	cec_unregister_adapter(cec->adap);
> +	cec_notifier_put(cec->notify);
> +
> +	return 0;
> +}
> +
> +static struct platform_driver dw_hdmi_cec_driver = {
> +	.probe	= dw_hdmi_cec_probe,
> +	.remove	= dw_hdmi_cec_remove,
> +	.driver = {
> +		.name = "dw-hdmi-cec",
> +	},
> +};
> +module_platform_driver(dw_hdmi_cec_driver);
> +
> +MODULE_AUTHOR("Russell King <rmk+kernel@armlinux.org.uk>");
> +MODULE_DESCRIPTION("Synopsis Designware HDMI CEC driver for i.MX");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS(PLATFORM_MODULE_PREFIX "dw-hdmi-cec");
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
> new file mode 100644
> index 000000000000..cf4dc121a2c4
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
> @@ -0,0 +1,19 @@
> +#ifndef DW_HDMI_CEC_H
> +#define DW_HDMI_CEC_H
> +
> +struct dw_hdmi;
> +
> +struct dw_hdmi_cec_ops {
> +	void (*write)(struct dw_hdmi *hdmi, u8 val, int offset);
> +	u8 (*read)(struct dw_hdmi *hdmi, int offset);
> +	void (*enable)(struct dw_hdmi *hdmi);
> +	void (*disable)(struct dw_hdmi *hdmi);
> +};
> +
> +struct dw_hdmi_cec_data {
> +	struct dw_hdmi *hdmi;
> +	const struct dw_hdmi_cec_ops *ops;
> +	int irq;
> +};
> +
> +#endif
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 58781d4c1034..5a389f1f58d9 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -35,6 +35,7 @@
>  
>  #include "dw-hdmi.h"
>  #include "dw-hdmi-audio.h"
> +#include "dw-hdmi-cec.h"
>  
>  #include <media/cec-notifier.h>
>  
> @@ -133,6 +134,7 @@ struct dw_hdmi {
>  	unsigned int version;
>  
>  	struct platform_device *audio;
> +	struct platform_device *cec;
>  	struct device *dev;
>  	struct clk *isfr_clk;
>  	struct clk *iahb_clk;
> @@ -1766,7 +1768,6 @@ static void initialize_hdmi_ih_mutes(struct dw_hdmi *hdmi)
>  	hdmi_writeb(hdmi, 0xff, HDMI_AUD_HBR_MASK);
>  	hdmi_writeb(hdmi, 0xff, HDMI_GP_MASK);
>  	hdmi_writeb(hdmi, 0xff, HDMI_A_APIINTMSK);
> -	hdmi_writeb(hdmi, 0xff, HDMI_CEC_MASK);
>  	hdmi_writeb(hdmi, 0xff, HDMI_I2CM_INT);
>  	hdmi_writeb(hdmi, 0xff, HDMI_I2CM_CTLINT);
>  
> @@ -2223,6 +2224,29 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi)
>  	return -ENODEV;
>  }
>  
> +static void dw_hdmi_cec_enable(struct dw_hdmi *hdmi)
> +{
> +	mutex_lock(&hdmi->mutex);
> +	hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CECCLK_DISABLE;
> +	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
> +	mutex_unlock(&hdmi->mutex);
> +}
> +
> +static void dw_hdmi_cec_disable(struct dw_hdmi *hdmi)
> +{
> +	mutex_lock(&hdmi->mutex);
> +	hdmi->mc_clkdis |= HDMI_MC_CLKDIS_CECCLK_DISABLE;
> +	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
> +	mutex_unlock(&hdmi->mutex);
> +}
> +
> +static const struct dw_hdmi_cec_ops dw_hdmi_cec_ops = {
> +	.write = hdmi_writeb,
> +	.read = hdmi_readb,
> +	.enable = dw_hdmi_cec_enable,
> +	.disable = dw_hdmi_cec_disable,
> +};
> +

This feels over-engineered and I suspect it is simplified if you just
add a cec_adapter pointer to struct dw_hdmi and link dw-hdmi-cec.c
together with dw-hdmi.c.

In other implementations I have done (see e.g. the recent drm displayport
CEC patch series) this works quite well.

>  static const struct regmap_config hdmi_regmap_8bit_config = {
>  	.reg_bits	= 32,
>  	.val_bits	= 8,
> @@ -2245,6 +2269,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  	struct device_node *np = dev->of_node;
>  	struct platform_device_info pdevinfo;
>  	struct device_node *ddc_node;
> +	struct dw_hdmi_cec_data cec;
>  	struct dw_hdmi *hdmi;
>  	struct resource *iores = NULL;
>  	int irq;
> @@ -2445,6 +2470,17 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  		hdmi->audio = platform_device_register_full(&pdevinfo);
>  	}
>  
> +	cec.hdmi = hdmi;
> +	cec.ops = &dw_hdmi_cec_ops;
> +	cec.irq = irq;
> +
> +	pdevinfo.name = "dw-hdmi-cec";
> +	pdevinfo.data = &cec;
> +	pdevinfo.size_data = sizeof(cec);
> +	pdevinfo.dma_mask = 0;
> +
> +	hdmi->cec = platform_device_register_full(&pdevinfo);
> +
>  	/* Reset HDMI DDC I2C master controller and mute I2CM interrupts */
>  	if (hdmi->i2c)
>  		dw_hdmi_i2c_init(hdmi);
> @@ -2475,6 +2511,8 @@ static void __dw_hdmi_remove(struct dw_hdmi *hdmi)
>  {
>  	if (hdmi->audio && !IS_ERR(hdmi->audio))
>  		platform_device_unregister(hdmi->audio);
> +	if (!IS_ERR(hdmi->cec))
> +		platform_device_unregister(hdmi->cec);
>  
>  	/* Disable all interrupts */
>  	hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
> 

Regards,

	Hans

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver
@ 2017-06-01  8:31     ` Hans Verkuil
  0 siblings, 0 replies; 84+ messages in thread
From: Hans Verkuil @ 2017-06-01  8:31 UTC (permalink / raw)
  To: Russell King; +Cc: linux-arm-kernel, dri-devel

Hi Russell,

First a few top-level questions:

1) What was the reason for using the cec-notifier here? Isn't this
   tightly integrated into the main dw-hdmi block? For the tda driver
   it is clearly required, but for tightly coupled HDMI & CEC HW I
   just create the adapter from the HDMI driver. As a small bonus it
   avoids adding the cec-notifier code and the control flow is a bit
   easier to trace.

2) I may have asked this before, apologies if I repeat myself: does
   this CEC implementation support CEC monitoring (aka snooping)? If
   it does, then I recommend that it is implemented since it is very
   useful.

3) Is the CEC still active if there is no hotplug signal? Or is it
   powered off in that case? Ideally it should still be possible to
   send CEC messages even if there is no hotplug. This is explicitly
   allowed by the CEC 2.0 spec to wake up displays that turn off the
   HPD, but that still have a working CEC controller.

   If this is not possible, then you need to use the CEC_CAP_NEEDS_HPD
   capability. See: https://patchwork.linuxtv.org/patch/41478/

   This will almost certainly be merged for 4.13 since other CEC drivers
   need this as well.

On 05/30/17 16:23, Russell King wrote:
> Add a CEC driver for the dw-hdmi hardware.
> 
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> ---
>  drivers/gpu/drm/bridge/synopsys/Kconfig       |   8 +
>  drivers/gpu/drm/bridge/synopsys/Makefile      |   1 +
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 320 ++++++++++++++++++++++++++
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h |  19 ++
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c     |  40 +++-
>  5 files changed, 387 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
>  create mode 100644 drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/Kconfig b/drivers/gpu/drm/bridge/synopsys/Kconfig
> index 40d2827a6d19..bd30a0a07272 100644
> --- a/drivers/gpu/drm/bridge/synopsys/Kconfig
> +++ b/drivers/gpu/drm/bridge/synopsys/Kconfig
> @@ -21,3 +21,11 @@ config DRM_DW_HDMI_I2S_AUDIO
>  	help
>  	  Support the I2S Audio interface which is part of the Synopsys
>  	  Designware HDMI block.
> +
> +config DRM_DW_HDMI_CEC
> +	tristate "Synopsis Designware CEC interface"
> +	depends on DRM_DW_HDMI && MEDIA_CEC_SUPPORT
> +	select MEDIA_CEC_NOTIFIER
> +	help
> +	  Support the CE interface which is part of the Synopsis
> +	  Designware HDMI block.

This will change. Patches to fix the config handling are pending for 4.12.

Here you can see the pending patches:
https://git.linuxtv.org/hverkuil/media_tree.git/log/?h=drm-cec

The patches from 'cec-notifier.h: handle unreachable CONFIG_CEC_CORE' to
'cec: drop MEDIA_CEC_DEBUG' should all be merged in 4.12.

That means that this config becomes:

+
+config DRM_DW_HDMI_CEC
+	tristate "Synopsis Designware CEC interface"
+	depends on DRM_DW_HDMI
+	select CEC_CORE
+	select CEC_NOTIFIER
+	help
+	  Support the CE interface which is part of the Synopsis
+	  Designware HDMI block.

> diff --git a/drivers/gpu/drm/bridge/synopsys/Makefile b/drivers/gpu/drm/bridge/synopsys/Makefile
> index 17aa7a65b57e..6fe415903668 100644
> --- a/drivers/gpu/drm/bridge/synopsys/Makefile
> +++ b/drivers/gpu/drm/bridge/synopsys/Makefile
> @@ -3,3 +3,4 @@
>  obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
>  obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
>  obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o
> +obj-$(CONFIG_DRM_DW_HDMI_CEC) += dw-hdmi-cec.o
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
> new file mode 100644
> index 000000000000..761ef5ae687d
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
> @@ -0,0 +1,320 @@
> +/*
> + * Designware HDMI CEC driver
> + *
> + * Copyright (C) 2015-2017 Russell King.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/sched.h>
> +#include <linux/slab.h>
> +
> +#include <drm/drm_edid.h>
> +
> +#include <media/cec.h>
> +#include <media/cec-notifier.h>
> +
> +#include "dw-hdmi-cec.h"
> +
> +enum {
> +	HDMI_IH_CEC_STAT0	= 0x0106,
> +	HDMI_IH_MUTE_CEC_STAT0	= 0x0186,
> +
> +	HDMI_CEC_CTRL		= 0x7d00,
> +	CEC_CTRL_START		= BIT(0),
> +	CEC_CTRL_NORMAL		= 1 << 1,
> +
> +	HDMI_CEC_STAT		= 0x7d01,
> +	CEC_STAT_DONE		= BIT(0),
> +	CEC_STAT_EOM		= BIT(1),
> +	CEC_STAT_NACK		= BIT(2),
> +	CEC_STAT_ARBLOST	= BIT(3),
> +	CEC_STAT_ERROR_INIT	= BIT(4),
> +	CEC_STAT_ERROR_FOLL	= BIT(5),
> +	CEC_STAT_WAKEUP		= BIT(6),
> +
> +	HDMI_CEC_MASK		= 0x7d02,
> +	HDMI_CEC_POLARITY	= 0x7d03,
> +	HDMI_CEC_INT		= 0x7d04,
> +	HDMI_CEC_ADDR_L		= 0x7d05,
> +	HDMI_CEC_ADDR_H		= 0x7d06,
> +	HDMI_CEC_TX_CNT		= 0x7d07,
> +	HDMI_CEC_RX_CNT		= 0x7d08,
> +	HDMI_CEC_TX_DATA0	= 0x7d10,
> +	HDMI_CEC_RX_DATA0	= 0x7d20,
> +	HDMI_CEC_LOCK		= 0x7d30,
> +	HDMI_CEC_WKUPCTRL	= 0x7d31,
> +};
> +
> +struct dw_hdmi_cec {
> +	struct dw_hdmi *hdmi;
> +	const struct dw_hdmi_cec_ops *ops;
> +	u32 addresses;
> +	struct cec_adapter *adap;
> +	struct cec_msg rx_msg;
> +	unsigned int tx_status;
> +	bool tx_done;
> +	bool rx_done;
> +	struct cec_notifier *notify;
> +	int retries;
> +	int irq;
> +};
> +
> +static void dw_hdmi_write(struct dw_hdmi_cec *cec, u8 val, int offset)
> +{
> +	cec->ops->write(cec->hdmi, val, offset);
> +}
> +
> +static u8 dw_hdmi_read(struct dw_hdmi_cec *cec, int offset)
> +{
> +	return cec->ops->read(cec->hdmi, offset);
> +}
> +
> +static int dw_hdmi_cec_log_addr(struct cec_adapter *adap, u8 logical_addr)
> +{
> +	struct dw_hdmi_cec *cec = adap->priv;
> +	u32 addresses;
> +
> +	if (logical_addr == CEC_LOG_ADDR_INVALID)
> +		addresses = cec->addresses = 0;
> +	else
> +		addresses = cec->addresses |= BIT(logical_addr) | BIT(15);
> +
> +	dw_hdmi_write(cec, addresses & 255, HDMI_CEC_ADDR_L);
> +	dw_hdmi_write(cec, addresses >> 8, HDMI_CEC_ADDR_H);

The addresses local variable doesn't really seem needed.

> +
> +	return 0;
> +}
> +
> +static int dw_hdmi_cec_transmit(struct cec_adapter *adap, u8 attempts,
> +				u32 signal_free_time, struct cec_msg *msg)
> +{
> +	struct dw_hdmi_cec *cec = adap->priv;
> +	unsigned i;
> +
> +	cec->retries = attempts;

Should probably be 'cec->retries = attempts - 1;'
Since 2 attempts == 1 retry.

> +
> +	for (i = 0; i < msg->len; i++)
> +		dw_hdmi_write(cec, msg->msg[i], HDMI_CEC_TX_DATA0 + i);
> +
> +	dw_hdmi_write(cec, msg->len, HDMI_CEC_TX_CNT);
> +	dw_hdmi_write(cec, CEC_CTRL_NORMAL | CEC_CTRL_START, HDMI_CEC_CTRL);
> +
> +	return 0;
> +}
> +
> +static irqreturn_t dw_hdmi_cec_hardirq(int irq, void *data)
> +{
> +	struct cec_adapter *adap = data;
> +	struct dw_hdmi_cec *cec = adap->priv;
> +	unsigned stat = dw_hdmi_read(cec, HDMI_IH_CEC_STAT0);
> +	irqreturn_t ret = IRQ_HANDLED;
> +
> +	if (stat == 0)
> +		return IRQ_NONE;
> +
> +	dw_hdmi_write(cec, stat, HDMI_IH_CEC_STAT0);
> +
> +	if (stat & CEC_STAT_ERROR_INIT) {
> +		if (cec->retries) {
> +			unsigned v = dw_hdmi_read(cec, HDMI_CEC_CTRL);
> +			dw_hdmi_write(cec, v | CEC_CTRL_START, HDMI_CEC_CTRL);
> +			cec->retries -= 1;

Why handle retries here at all? Just mark this as CEC_TX_STATUS_ERROR and set
tx_done to true. The CEC core will just call dw_hdmi_cec_transmit again if
it needs to make another attempt. I suggest that the whole retry code is
dropped.

> +		} else {
> +			cec->tx_status = CEC_TX_STATUS_MAX_RETRIES;
> +			cec->tx_done = true;
> +			ret = IRQ_WAKE_THREAD;
> +		}
> +	} else if (stat & CEC_STAT_DONE) {
> +		cec->tx_status = CEC_TX_STATUS_OK;
> +		cec->tx_done = true;
> +		ret = IRQ_WAKE_THREAD;
> +	} else if (stat & CEC_STAT_NACK) {
> +		cec->tx_status = CEC_TX_STATUS_NACK;
> +		cec->tx_done = true;
> +		ret = IRQ_WAKE_THREAD;
> +	}
> +
> +	if (stat & CEC_STAT_EOM) {
> +		unsigned len, i;
> +
> +		len = dw_hdmi_read(cec, HDMI_CEC_RX_CNT);
> +		if (len > sizeof(cec->rx_msg.msg))
> +			len = sizeof(cec->rx_msg.msg);
> +
> +		for (i = 0; i < len; i++)
> +			cec->rx_msg.msg[i] =
> +				dw_hdmi_read(cec, HDMI_CEC_RX_DATA0 + i);
> +
> +		dw_hdmi_write(cec, 0, HDMI_CEC_LOCK);
> +
> +		cec->rx_msg.len = len;
> +		smp_wmb();
> +		cec->rx_done = true;
> +
> +		ret = IRQ_WAKE_THREAD;
> +	}
> +
> +	return ret;
> +}
> +
> +static irqreturn_t dw_hdmi_cec_thread(int irq, void *data)
> +{
> +	struct cec_adapter *adap = data;
> +	struct dw_hdmi_cec *cec = adap->priv;
> +
> +	if (cec->tx_done) {
> +		cec->tx_done = false;
> +		cec_transmit_done(adap, cec->tx_status, 0, 0, 0, 0);

I think I will make a patch for a new helper function where you can just call:

cec_transmit_attempt_done(adap, cec->tx_status);

and that will call cec_transmit_done filling in the other arguments
based on the status.

Most CEC HW doesn't do retries so only make one attempt. In that case
only one of the remaining count arguments is 1 and that's based on the
status.

Having correct error counts is useful for debugging problems.

> +	}
> +	if (cec->rx_done) {
> +		cec->rx_done = false;
> +		smp_rmb();
> +		cec_received_msg(adap, &cec->rx_msg);
> +	}
> +	return IRQ_HANDLED;
> +}
> +
> +static int dw_hdmi_cec_enable(struct cec_adapter *adap, bool enable)
> +{
> +	struct dw_hdmi_cec *cec = adap->priv;
> +
> +	if (!enable) {
> +		dw_hdmi_write(cec, ~0, HDMI_CEC_MASK);
> +		dw_hdmi_write(cec, ~0, HDMI_IH_MUTE_CEC_STAT0);
> +		dw_hdmi_write(cec, 0, HDMI_CEC_POLARITY);
> +
> +		cec->ops->disable(cec->hdmi);
> +	} else {
> +		unsigned irqs;
> +
> +		dw_hdmi_write(cec, 0, HDMI_CEC_CTRL);
> +		dw_hdmi_write(cec, ~0, HDMI_IH_CEC_STAT0);
> +		dw_hdmi_write(cec, 0, HDMI_CEC_LOCK);
> +
> +		dw_hdmi_cec_log_addr(cec->adap, CEC_LOG_ADDR_INVALID);
> +
> +		cec->ops->enable(cec->hdmi);
> +
> +		irqs = CEC_STAT_ERROR_INIT | CEC_STAT_NACK | CEC_STAT_EOM |
> +		       CEC_STAT_DONE;
> +		dw_hdmi_write(cec, irqs, HDMI_CEC_POLARITY);
> +		dw_hdmi_write(cec, ~irqs, HDMI_CEC_MASK);
> +		dw_hdmi_write(cec, ~irqs, HDMI_IH_MUTE_CEC_STAT0);
> +	}
> +	return 0;
> +}
> +
> +static const struct cec_adap_ops dw_hdmi_cec_ops = {
> +	.adap_enable = dw_hdmi_cec_enable,
> +	.adap_log_addr = dw_hdmi_cec_log_addr,
> +	.adap_transmit = dw_hdmi_cec_transmit,
> +};
> +
> +static void dw_hdmi_cec_del(void *data)
> +{
> +	struct dw_hdmi_cec *cec = data;
> +
> +	cec_delete_adapter(cec->adap);
> +}
> +
> +static int dw_hdmi_cec_probe(struct platform_device *pdev)
> +{
> +	struct dw_hdmi_cec_data *data = dev_get_platdata(&pdev->dev);
> +	struct dw_hdmi_cec *cec;
> +	int ret;
> +
> +	if (!data)
> +		return -ENXIO;
> +
> +	/*
> +	 * Our device is just a convenience - we want to link to the real
> +	 * hardware device here, so that userspace can see the association
> +	 * between the HDMI hardware and its associated CEC chardev.
> +	 */
> +	cec = devm_kzalloc(&pdev->dev, sizeof(*cec), GFP_KERNEL);
> +	if (!cec)
> +		return -ENOMEM;
> +
> +	cec->irq = data->irq;
> +	cec->ops = data->ops;
> +	cec->hdmi = data->hdmi;
> +
> +	platform_set_drvdata(pdev, cec);
> +
> +	dw_hdmi_write(cec, 0, HDMI_CEC_TX_CNT);
> +	dw_hdmi_write(cec, ~0, HDMI_CEC_MASK);
> +	dw_hdmi_write(cec, ~0, HDMI_IH_MUTE_CEC_STAT0);
> +	dw_hdmi_write(cec, 0, HDMI_CEC_POLARITY);
> +
> +	cec->adap = cec_allocate_adapter(&dw_hdmi_cec_ops, cec, "dw_hdmi",
> +					 CEC_CAP_LOG_ADDRS | CEC_CAP_TRANSMIT |
> +					 CEC_CAP_RC, CEC_MAX_LOG_ADDRS);
> +	if (IS_ERR(cec->adap))
> +		return PTR_ERR(cec->adap);
> +
> +	/* override the module pointer */
> +	cec->adap->owner = THIS_MODULE;
> +
> +	ret = devm_add_action(&pdev->dev, dw_hdmi_cec_del, cec);
> +	if (ret) {
> +		cec_delete_adapter(cec->adap);
> +		return ret;
> +	}
> +
> +	ret = devm_request_threaded_irq(&pdev->dev, cec->irq,
> +					dw_hdmi_cec_hardirq,
> +					dw_hdmi_cec_thread, IRQF_SHARED,
> +					"dw-hdmi-cec", cec->adap);
> +	if (ret < 0)
> +		return ret;
> +
> +	cec->notify = cec_notifier_get(pdev->dev.parent);
> +	if (!cec->notify)
> +		return -ENOMEM;
> +
> +	ret = cec_register_adapter(cec->adap, pdev->dev.parent);
> +	if (ret < 0) {
> +		cec_notifier_put(cec->notify);
> +		return ret;
> +	}
> +
> +	/*
> +	 * CEC documentation says we must not call cec_delete_adapter
> +	 * after a successful call to cec_register_adapter().
> +	 */
> +	devm_remove_action(&pdev->dev, dw_hdmi_cec_del, cec);
> +
> +	cec_register_cec_notifier(cec->adap, cec->notify);
> +
> +	return 0;
> +}
> +
> +static int dw_hdmi_cec_remove(struct platform_device *pdev)
> +{
> +	struct dw_hdmi_cec *cec = platform_get_drvdata(pdev);
> +
> +	cec_unregister_adapter(cec->adap);
> +	cec_notifier_put(cec->notify);
> +
> +	return 0;
> +}
> +
> +static struct platform_driver dw_hdmi_cec_driver = {
> +	.probe	= dw_hdmi_cec_probe,
> +	.remove	= dw_hdmi_cec_remove,
> +	.driver = {
> +		.name = "dw-hdmi-cec",
> +	},
> +};
> +module_platform_driver(dw_hdmi_cec_driver);
> +
> +MODULE_AUTHOR("Russell King <rmk+kernel@armlinux.org.uk>");
> +MODULE_DESCRIPTION("Synopsis Designware HDMI CEC driver for i.MX");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS(PLATFORM_MODULE_PREFIX "dw-hdmi-cec");
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
> new file mode 100644
> index 000000000000..cf4dc121a2c4
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
> @@ -0,0 +1,19 @@
> +#ifndef DW_HDMI_CEC_H
> +#define DW_HDMI_CEC_H
> +
> +struct dw_hdmi;
> +
> +struct dw_hdmi_cec_ops {
> +	void (*write)(struct dw_hdmi *hdmi, u8 val, int offset);
> +	u8 (*read)(struct dw_hdmi *hdmi, int offset);
> +	void (*enable)(struct dw_hdmi *hdmi);
> +	void (*disable)(struct dw_hdmi *hdmi);
> +};
> +
> +struct dw_hdmi_cec_data {
> +	struct dw_hdmi *hdmi;
> +	const struct dw_hdmi_cec_ops *ops;
> +	int irq;
> +};
> +
> +#endif
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 58781d4c1034..5a389f1f58d9 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -35,6 +35,7 @@
>  
>  #include "dw-hdmi.h"
>  #include "dw-hdmi-audio.h"
> +#include "dw-hdmi-cec.h"
>  
>  #include <media/cec-notifier.h>
>  
> @@ -133,6 +134,7 @@ struct dw_hdmi {
>  	unsigned int version;
>  
>  	struct platform_device *audio;
> +	struct platform_device *cec;
>  	struct device *dev;
>  	struct clk *isfr_clk;
>  	struct clk *iahb_clk;
> @@ -1766,7 +1768,6 @@ static void initialize_hdmi_ih_mutes(struct dw_hdmi *hdmi)
>  	hdmi_writeb(hdmi, 0xff, HDMI_AUD_HBR_MASK);
>  	hdmi_writeb(hdmi, 0xff, HDMI_GP_MASK);
>  	hdmi_writeb(hdmi, 0xff, HDMI_A_APIINTMSK);
> -	hdmi_writeb(hdmi, 0xff, HDMI_CEC_MASK);
>  	hdmi_writeb(hdmi, 0xff, HDMI_I2CM_INT);
>  	hdmi_writeb(hdmi, 0xff, HDMI_I2CM_CTLINT);
>  
> @@ -2223,6 +2224,29 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi)
>  	return -ENODEV;
>  }
>  
> +static void dw_hdmi_cec_enable(struct dw_hdmi *hdmi)
> +{
> +	mutex_lock(&hdmi->mutex);
> +	hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CECCLK_DISABLE;
> +	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
> +	mutex_unlock(&hdmi->mutex);
> +}
> +
> +static void dw_hdmi_cec_disable(struct dw_hdmi *hdmi)
> +{
> +	mutex_lock(&hdmi->mutex);
> +	hdmi->mc_clkdis |= HDMI_MC_CLKDIS_CECCLK_DISABLE;
> +	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
> +	mutex_unlock(&hdmi->mutex);
> +}
> +
> +static const struct dw_hdmi_cec_ops dw_hdmi_cec_ops = {
> +	.write = hdmi_writeb,
> +	.read = hdmi_readb,
> +	.enable = dw_hdmi_cec_enable,
> +	.disable = dw_hdmi_cec_disable,
> +};
> +

This feels over-engineered and I suspect it is simplified if you just
add a cec_adapter pointer to struct dw_hdmi and link dw-hdmi-cec.c
together with dw-hdmi.c.

In other implementations I have done (see e.g. the recent drm displayport
CEC patch series) this works quite well.

>  static const struct regmap_config hdmi_regmap_8bit_config = {
>  	.reg_bits	= 32,
>  	.val_bits	= 8,
> @@ -2245,6 +2269,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  	struct device_node *np = dev->of_node;
>  	struct platform_device_info pdevinfo;
>  	struct device_node *ddc_node;
> +	struct dw_hdmi_cec_data cec;
>  	struct dw_hdmi *hdmi;
>  	struct resource *iores = NULL;
>  	int irq;
> @@ -2445,6 +2470,17 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  		hdmi->audio = platform_device_register_full(&pdevinfo);
>  	}
>  
> +	cec.hdmi = hdmi;
> +	cec.ops = &dw_hdmi_cec_ops;
> +	cec.irq = irq;
> +
> +	pdevinfo.name = "dw-hdmi-cec";
> +	pdevinfo.data = &cec;
> +	pdevinfo.size_data = sizeof(cec);
> +	pdevinfo.dma_mask = 0;
> +
> +	hdmi->cec = platform_device_register_full(&pdevinfo);
> +
>  	/* Reset HDMI DDC I2C master controller and mute I2CM interrupts */
>  	if (hdmi->i2c)
>  		dw_hdmi_i2c_init(hdmi);
> @@ -2475,6 +2511,8 @@ static void __dw_hdmi_remove(struct dw_hdmi *hdmi)
>  {
>  	if (hdmi->audio && !IS_ERR(hdmi->audio))
>  		platform_device_unregister(hdmi->audio);
> +	if (!IS_ERR(hdmi->cec))
> +		platform_device_unregister(hdmi->cec);
>  
>  	/* Disable all interrupts */
>  	hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
> 

Regards,

	Hans
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver
  2017-06-01  8:31     ` Hans Verkuil
@ 2017-06-01  9:46       ` Russell King - ARM Linux
  -1 siblings, 0 replies; 84+ messages in thread
From: Russell King - ARM Linux @ 2017-06-01  9:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jun 01, 2017 at 10:31:10AM +0200, Hans Verkuil wrote:
> Hi Russell,
> 
> First a few top-level questions:

Hi Hans,

> 1) What was the reason for using the cec-notifier here? Isn't this
>    tightly integrated into the main dw-hdmi block? For the tda driver
>    it is clearly required, but for tightly coupled HDMI & CEC HW I
>    just create the adapter from the HDMI driver. As a small bonus it
>    avoids adding the cec-notifier code and the control flow is a bit
>    easier to trace.

It's to avoid complex dependencies.  If it's all built in to the HDMI
driver, then the HDMI driver needs to depend on all the media stuff
being non-modular.  For a video output device, this is sub-optimal,
because you want the video output device to work during boot.

I feel strongly about this point, especially as we have had many years
of users being able to use dw-hdmi without needing CEC enabled.

> 2) I may have asked this before, apologies if I repeat myself: does
>    this CEC implementation support CEC monitoring (aka snooping)? If
>    it does, then I recommend that it is implemented since it is very
>    useful.

It does not.

> 3) Is the CEC still active if there is no hotplug signal? Or is it
>    powered off in that case? Ideally it should still be possible to
>    send CEC messages even if there is no hotplug. This is explicitly
>    allowed by the CEC 2.0 spec to wake up displays that turn off the
>    HPD, but that still have a working CEC controller.

This is not specified in the documentation, so I don't think we know
without experimentation.  This would be a future enhancement to the
patch set.

> > diff --git a/drivers/gpu/drm/bridge/synopsys/Kconfig b/drivers/gpu/drm/bridge/synopsys/Kconfig
> > index 40d2827a6d19..bd30a0a07272 100644
> > --- a/drivers/gpu/drm/bridge/synopsys/Kconfig
> > +++ b/drivers/gpu/drm/bridge/synopsys/Kconfig
> > @@ -21,3 +21,11 @@ config DRM_DW_HDMI_I2S_AUDIO
> >  	help
> >  	  Support the I2S Audio interface which is part of the Synopsys
> >  	  Designware HDMI block.
> > +
> > +config DRM_DW_HDMI_CEC
> > +	tristate "Synopsis Designware CEC interface"
> > +	depends on DRM_DW_HDMI && MEDIA_CEC_SUPPORT
> > +	select MEDIA_CEC_NOTIFIER
> > +	help
> > +	  Support the CE interface which is part of the Synopsis
> > +	  Designware HDMI block.
> 
> This will change. Patches to fix the config handling are pending for 4.12.
> 
> Here you can see the pending patches:
> https://git.linuxtv.org/hverkuil/media_tree.git/log/?h=drm-cec
> 
> The patches from 'cec-notifier.h: handle unreachable CONFIG_CEC_CORE' to
> 'cec: drop MEDIA_CEC_DEBUG' should all be merged in 4.12.
> 
> That means that this config becomes:
> 
> +
> +config DRM_DW_HDMI_CEC
> +	tristate "Synopsis Designware CEC interface"
> +	depends on DRM_DW_HDMI
> +	select CEC_CORE
> +	select CEC_NOTIFIER
> +	help
> +	  Support the CE interface which is part of the Synopsis
> +	  Designware HDMI block.

You will also need to select MEDIA_SUPPORT to avoid dependency issues.
CEC_CORE and CEC_NOTIFIER are both lumped under an "if MEDIA_SUPPORT"
block in drivers/media/Kconfig, so they depend on this symbol.  Asking
Kconfig to select these two symbols without MEDIA_SUPPORT creates an
invalid configuration - unless CEC has been moved out from being under
MEDIA_SUPPORT.  (I haven't looked at your tree yet.)

> > +static int dw_hdmi_cec_log_addr(struct cec_adapter *adap, u8 logical_addr)
> > +{
> > +	struct dw_hdmi_cec *cec = adap->priv;
> > +	u32 addresses;
> > +
> > +	if (logical_addr == CEC_LOG_ADDR_INVALID)
> > +		addresses = cec->addresses = 0;
> > +	else
> > +		addresses = cec->addresses |= BIT(logical_addr) | BIT(15);
> > +
> > +	dw_hdmi_write(cec, addresses & 255, HDMI_CEC_ADDR_L);
> > +	dw_hdmi_write(cec, addresses >> 8, HDMI_CEC_ADDR_H);
> 
> The addresses local variable doesn't really seem needed.

Ok.

> > +static int dw_hdmi_cec_transmit(struct cec_adapter *adap, u8 attempts,
> > +				u32 signal_free_time, struct cec_msg *msg)
> > +{
> > +	struct dw_hdmi_cec *cec = adap->priv;
> > +	unsigned i;
> > +
> > +	cec->retries = attempts;
> 
> Should probably be 'cec->retries = attempts - 1;'
> Since 2 attempts == 1 retry.

Probably correct, but rather moot given your comment below.

> > +static irqreturn_t dw_hdmi_cec_hardirq(int irq, void *data)
> > +{
> > +	struct cec_adapter *adap = data;
> > +	struct dw_hdmi_cec *cec = adap->priv;
> > +	unsigned stat = dw_hdmi_read(cec, HDMI_IH_CEC_STAT0);
> > +	irqreturn_t ret = IRQ_HANDLED;
> > +
> > +	if (stat == 0)
> > +		return IRQ_NONE;
> > +
> > +	dw_hdmi_write(cec, stat, HDMI_IH_CEC_STAT0);
> > +
> > +	if (stat & CEC_STAT_ERROR_INIT) {
> > +		if (cec->retries) {
> > +			unsigned v = dw_hdmi_read(cec, HDMI_CEC_CTRL);
> > +			dw_hdmi_write(cec, v | CEC_CTRL_START, HDMI_CEC_CTRL);
> > +			cec->retries -= 1;
> 
> Why handle retries here at all? Just mark this as CEC_TX_STATUS_ERROR and set
> tx_done to true. The CEC core will just call dw_hdmi_cec_transmit again if
> it needs to make another attempt. I suggest that the whole retry code is
> dropped.

Probably comes from a previous iteration of your CEC core which required
the driver to do retries, so it can probably be fixed up in the way you
describe.

However, presumably this needs a different status other than
"CEC_TX_STATUS_MAX_RETRIES"?  I don't see a way to report this error to
the CEC core in a way that it will retry.

> > +static irqreturn_t dw_hdmi_cec_thread(int irq, void *data)
> > +{
> > +	struct cec_adapter *adap = data;
> > +	struct dw_hdmi_cec *cec = adap->priv;
> > +
> > +	if (cec->tx_done) {
> > +		cec->tx_done = false;
> > +		cec_transmit_done(adap, cec->tx_status, 0, 0, 0, 0);
> 
> I think I will make a patch for a new helper function where you can just call:
> 
> cec_transmit_attempt_done(adap, cec->tx_status);
> 
> and that will call cec_transmit_done filling in the other arguments
> based on the status.
> 
> Most CEC HW doesn't do retries so only make one attempt. In that case
> only one of the remaining count arguments is 1 and that's based on the
> status.
> 
> Having correct error counts is useful for debugging problems.

It hasn't been clear to me which counts should be non-zero, and it seems
like entirely redundant information given that the status argument
indicates what happened to the message.

> > +static void dw_hdmi_cec_disable(struct dw_hdmi *hdmi)
> > +{
> > +	mutex_lock(&hdmi->mutex);
> > +	hdmi->mc_clkdis |= HDMI_MC_CLKDIS_CECCLK_DISABLE;
> > +	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
> > +	mutex_unlock(&hdmi->mutex);
> > +}
> > +
> > +static const struct dw_hdmi_cec_ops dw_hdmi_cec_ops = {
> > +	.write = hdmi_writeb,
> > +	.read = hdmi_readb,
> > +	.enable = dw_hdmi_cec_enable,
> > +	.disable = dw_hdmi_cec_disable,
> > +};
> > +
> 
> This feels over-engineered and I suspect it is simplified if you just
> add a cec_adapter pointer to struct dw_hdmi and link dw-hdmi-cec.c
> together with dw-hdmi.c.

As I mention above, to do so would mean that dw-hdmi has to be modular
if you want CEC to be modular, and I don't think that is reasonable
for a video output device, which may be the source of kernel boot
messages.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver
@ 2017-06-01  9:46       ` Russell King - ARM Linux
  0 siblings, 0 replies; 84+ messages in thread
From: Russell King - ARM Linux @ 2017-06-01  9:46 UTC (permalink / raw)
  To: Hans Verkuil; +Cc: linux-arm-kernel, dri-devel

On Thu, Jun 01, 2017 at 10:31:10AM +0200, Hans Verkuil wrote:
> Hi Russell,
> 
> First a few top-level questions:

Hi Hans,

> 1) What was the reason for using the cec-notifier here? Isn't this
>    tightly integrated into the main dw-hdmi block? For the tda driver
>    it is clearly required, but for tightly coupled HDMI & CEC HW I
>    just create the adapter from the HDMI driver. As a small bonus it
>    avoids adding the cec-notifier code and the control flow is a bit
>    easier to trace.

It's to avoid complex dependencies.  If it's all built in to the HDMI
driver, then the HDMI driver needs to depend on all the media stuff
being non-modular.  For a video output device, this is sub-optimal,
because you want the video output device to work during boot.

I feel strongly about this point, especially as we have had many years
of users being able to use dw-hdmi without needing CEC enabled.

> 2) I may have asked this before, apologies if I repeat myself: does
>    this CEC implementation support CEC monitoring (aka snooping)? If
>    it does, then I recommend that it is implemented since it is very
>    useful.

It does not.

> 3) Is the CEC still active if there is no hotplug signal? Or is it
>    powered off in that case? Ideally it should still be possible to
>    send CEC messages even if there is no hotplug. This is explicitly
>    allowed by the CEC 2.0 spec to wake up displays that turn off the
>    HPD, but that still have a working CEC controller.

This is not specified in the documentation, so I don't think we know
without experimentation.  This would be a future enhancement to the
patch set.

> > diff --git a/drivers/gpu/drm/bridge/synopsys/Kconfig b/drivers/gpu/drm/bridge/synopsys/Kconfig
> > index 40d2827a6d19..bd30a0a07272 100644
> > --- a/drivers/gpu/drm/bridge/synopsys/Kconfig
> > +++ b/drivers/gpu/drm/bridge/synopsys/Kconfig
> > @@ -21,3 +21,11 @@ config DRM_DW_HDMI_I2S_AUDIO
> >  	help
> >  	  Support the I2S Audio interface which is part of the Synopsys
> >  	  Designware HDMI block.
> > +
> > +config DRM_DW_HDMI_CEC
> > +	tristate "Synopsis Designware CEC interface"
> > +	depends on DRM_DW_HDMI && MEDIA_CEC_SUPPORT
> > +	select MEDIA_CEC_NOTIFIER
> > +	help
> > +	  Support the CE interface which is part of the Synopsis
> > +	  Designware HDMI block.
> 
> This will change. Patches to fix the config handling are pending for 4.12.
> 
> Here you can see the pending patches:
> https://git.linuxtv.org/hverkuil/media_tree.git/log/?h=drm-cec
> 
> The patches from 'cec-notifier.h: handle unreachable CONFIG_CEC_CORE' to
> 'cec: drop MEDIA_CEC_DEBUG' should all be merged in 4.12.
> 
> That means that this config becomes:
> 
> +
> +config DRM_DW_HDMI_CEC
> +	tristate "Synopsis Designware CEC interface"
> +	depends on DRM_DW_HDMI
> +	select CEC_CORE
> +	select CEC_NOTIFIER
> +	help
> +	  Support the CE interface which is part of the Synopsis
> +	  Designware HDMI block.

You will also need to select MEDIA_SUPPORT to avoid dependency issues.
CEC_CORE and CEC_NOTIFIER are both lumped under an "if MEDIA_SUPPORT"
block in drivers/media/Kconfig, so they depend on this symbol.  Asking
Kconfig to select these two symbols without MEDIA_SUPPORT creates an
invalid configuration - unless CEC has been moved out from being under
MEDIA_SUPPORT.  (I haven't looked at your tree yet.)

> > +static int dw_hdmi_cec_log_addr(struct cec_adapter *adap, u8 logical_addr)
> > +{
> > +	struct dw_hdmi_cec *cec = adap->priv;
> > +	u32 addresses;
> > +
> > +	if (logical_addr == CEC_LOG_ADDR_INVALID)
> > +		addresses = cec->addresses = 0;
> > +	else
> > +		addresses = cec->addresses |= BIT(logical_addr) | BIT(15);
> > +
> > +	dw_hdmi_write(cec, addresses & 255, HDMI_CEC_ADDR_L);
> > +	dw_hdmi_write(cec, addresses >> 8, HDMI_CEC_ADDR_H);
> 
> The addresses local variable doesn't really seem needed.

Ok.

> > +static int dw_hdmi_cec_transmit(struct cec_adapter *adap, u8 attempts,
> > +				u32 signal_free_time, struct cec_msg *msg)
> > +{
> > +	struct dw_hdmi_cec *cec = adap->priv;
> > +	unsigned i;
> > +
> > +	cec->retries = attempts;
> 
> Should probably be 'cec->retries = attempts - 1;'
> Since 2 attempts == 1 retry.

Probably correct, but rather moot given your comment below.

> > +static irqreturn_t dw_hdmi_cec_hardirq(int irq, void *data)
> > +{
> > +	struct cec_adapter *adap = data;
> > +	struct dw_hdmi_cec *cec = adap->priv;
> > +	unsigned stat = dw_hdmi_read(cec, HDMI_IH_CEC_STAT0);
> > +	irqreturn_t ret = IRQ_HANDLED;
> > +
> > +	if (stat == 0)
> > +		return IRQ_NONE;
> > +
> > +	dw_hdmi_write(cec, stat, HDMI_IH_CEC_STAT0);
> > +
> > +	if (stat & CEC_STAT_ERROR_INIT) {
> > +		if (cec->retries) {
> > +			unsigned v = dw_hdmi_read(cec, HDMI_CEC_CTRL);
> > +			dw_hdmi_write(cec, v | CEC_CTRL_START, HDMI_CEC_CTRL);
> > +			cec->retries -= 1;
> 
> Why handle retries here at all? Just mark this as CEC_TX_STATUS_ERROR and set
> tx_done to true. The CEC core will just call dw_hdmi_cec_transmit again if
> it needs to make another attempt. I suggest that the whole retry code is
> dropped.

Probably comes from a previous iteration of your CEC core which required
the driver to do retries, so it can probably be fixed up in the way you
describe.

However, presumably this needs a different status other than
"CEC_TX_STATUS_MAX_RETRIES"?  I don't see a way to report this error to
the CEC core in a way that it will retry.

> > +static irqreturn_t dw_hdmi_cec_thread(int irq, void *data)
> > +{
> > +	struct cec_adapter *adap = data;
> > +	struct dw_hdmi_cec *cec = adap->priv;
> > +
> > +	if (cec->tx_done) {
> > +		cec->tx_done = false;
> > +		cec_transmit_done(adap, cec->tx_status, 0, 0, 0, 0);
> 
> I think I will make a patch for a new helper function where you can just call:
> 
> cec_transmit_attempt_done(adap, cec->tx_status);
> 
> and that will call cec_transmit_done filling in the other arguments
> based on the status.
> 
> Most CEC HW doesn't do retries so only make one attempt. In that case
> only one of the remaining count arguments is 1 and that's based on the
> status.
> 
> Having correct error counts is useful for debugging problems.

It hasn't been clear to me which counts should be non-zero, and it seems
like entirely redundant information given that the status argument
indicates what happened to the message.

> > +static void dw_hdmi_cec_disable(struct dw_hdmi *hdmi)
> > +{
> > +	mutex_lock(&hdmi->mutex);
> > +	hdmi->mc_clkdis |= HDMI_MC_CLKDIS_CECCLK_DISABLE;
> > +	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
> > +	mutex_unlock(&hdmi->mutex);
> > +}
> > +
> > +static const struct dw_hdmi_cec_ops dw_hdmi_cec_ops = {
> > +	.write = hdmi_writeb,
> > +	.read = hdmi_readb,
> > +	.enable = dw_hdmi_cec_enable,
> > +	.disable = dw_hdmi_cec_disable,
> > +};
> > +
> 
> This feels over-engineered and I suspect it is simplified if you just
> add a cec_adapter pointer to struct dw_hdmi and link dw-hdmi-cec.c
> together with dw-hdmi.c.

As I mention above, to do so would mean that dw-hdmi has to be modular
if you want CEC to be modular, and I don't think that is reasonable
for a video output device, which may be the source of kernel boot
messages.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver
  2017-06-01  9:46       ` Russell King - ARM Linux
@ 2017-06-01 10:44         ` Hans Verkuil
  -1 siblings, 0 replies; 84+ messages in thread
From: Hans Verkuil @ 2017-06-01 10:44 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/01/17 11:46, Russell King - ARM Linux wrote:
> On Thu, Jun 01, 2017 at 10:31:10AM +0200, Hans Verkuil wrote:
>> Hi Russell,
>>
>> First a few top-level questions:
> 
> Hi Hans,
> 
>> 1) What was the reason for using the cec-notifier here? Isn't this
>>    tightly integrated into the main dw-hdmi block? For the tda driver
>>    it is clearly required, but for tightly coupled HDMI & CEC HW I
>>    just create the adapter from the HDMI driver. As a small bonus it
>>    avoids adding the cec-notifier code and the control flow is a bit
>>    easier to trace.
> 
> It's to avoid complex dependencies.  If it's all built in to the HDMI
> driver, then the HDMI driver needs to depend on all the media stuff
> being non-modular.  For a video output device, this is sub-optimal,
> because you want the video output device to work during boot.

This is no longer true after my rework of the CEC kernel config.

After doing a 'select CEC_CORE' the cec framework will be compiled
correctly.

It no longer depends on the media subsystem (except if you want to use
the remote control passthrough since the RC framework is part of media).

Selecting CEC_CORE will only select the cec core code.

> 
> I feel strongly about this point, especially as we have had many years
> of users being able to use dw-hdmi without needing CEC enabled.
> 
>> 2) I may have asked this before, apologies if I repeat myself: does
>>    this CEC implementation support CEC monitoring (aka snooping)? If
>>    it does, then I recommend that it is implemented since it is very
>>    useful.
> 
> It does not.
> 
>> 3) Is the CEC still active if there is no hotplug signal? Or is it
>>    powered off in that case? Ideally it should still be possible to
>>    send CEC messages even if there is no hotplug. This is explicitly
>>    allowed by the CEC 2.0 spec to wake up displays that turn off the
>>    HPD, but that still have a working CEC controller.
> 
> This is not specified in the documentation, so I don't think we know
> without experimentation.  This would be a future enhancement to the
> patch set.
> 
>>> diff --git a/drivers/gpu/drm/bridge/synopsys/Kconfig b/drivers/gpu/drm/bridge/synopsys/Kconfig
>>> index 40d2827a6d19..bd30a0a07272 100644
>>> --- a/drivers/gpu/drm/bridge/synopsys/Kconfig
>>> +++ b/drivers/gpu/drm/bridge/synopsys/Kconfig
>>> @@ -21,3 +21,11 @@ config DRM_DW_HDMI_I2S_AUDIO
>>>  	help
>>>  	  Support the I2S Audio interface which is part of the Synopsys
>>>  	  Designware HDMI block.
>>> +
>>> +config DRM_DW_HDMI_CEC
>>> +	tristate "Synopsis Designware CEC interface"
>>> +	depends on DRM_DW_HDMI && MEDIA_CEC_SUPPORT
>>> +	select MEDIA_CEC_NOTIFIER
>>> +	help
>>> +	  Support the CE interface which is part of the Synopsis
>>> +	  Designware HDMI block.
>>
>> This will change. Patches to fix the config handling are pending for 4.12.
>>
>> Here you can see the pending patches:
>> https://git.linuxtv.org/hverkuil/media_tree.git/log/?h=drm-cec
>>
>> The patches from 'cec-notifier.h: handle unreachable CONFIG_CEC_CORE' to
>> 'cec: drop MEDIA_CEC_DEBUG' should all be merged in 4.12.
>>
>> That means that this config becomes:
>>
>> +
>> +config DRM_DW_HDMI_CEC
>> +	tristate "Synopsis Designware CEC interface"
>> +	depends on DRM_DW_HDMI
>> +	select CEC_CORE
>> +	select CEC_NOTIFIER
>> +	help
>> +	  Support the CE interface which is part of the Synopsis
>> +	  Designware HDMI block.
> 
> You will also need to select MEDIA_SUPPORT to avoid dependency issues.
> CEC_CORE and CEC_NOTIFIER are both lumped under an "if MEDIA_SUPPORT"
> block in drivers/media/Kconfig, so they depend on this symbol.

No, they've been moved up. They no longer depend on the MEDIA_SUPPORT.
So that's been fixed.

> Asking
> Kconfig to select these two symbols without MEDIA_SUPPORT creates an
> invalid configuration - unless CEC has been moved out from being under
> MEDIA_SUPPORT.  (I haven't looked at your tree yet.)
> 
>>> +static int dw_hdmi_cec_log_addr(struct cec_adapter *adap, u8 logical_addr)
>>> +{
>>> +	struct dw_hdmi_cec *cec = adap->priv;
>>> +	u32 addresses;
>>> +
>>> +	if (logical_addr == CEC_LOG_ADDR_INVALID)
>>> +		addresses = cec->addresses = 0;
>>> +	else
>>> +		addresses = cec->addresses |= BIT(logical_addr) | BIT(15);
>>> +
>>> +	dw_hdmi_write(cec, addresses & 255, HDMI_CEC_ADDR_L);
>>> +	dw_hdmi_write(cec, addresses >> 8, HDMI_CEC_ADDR_H);
>>
>> The addresses local variable doesn't really seem needed.
> 
> Ok.
> 
>>> +static int dw_hdmi_cec_transmit(struct cec_adapter *adap, u8 attempts,
>>> +				u32 signal_free_time, struct cec_msg *msg)
>>> +{
>>> +	struct dw_hdmi_cec *cec = adap->priv;
>>> +	unsigned i;
>>> +
>>> +	cec->retries = attempts;
>>
>> Should probably be 'cec->retries = attempts - 1;'
>> Since 2 attempts == 1 retry.
> 
> Probably correct, but rather moot given your comment below.
> 
>>> +static irqreturn_t dw_hdmi_cec_hardirq(int irq, void *data)
>>> +{
>>> +	struct cec_adapter *adap = data;
>>> +	struct dw_hdmi_cec *cec = adap->priv;
>>> +	unsigned stat = dw_hdmi_read(cec, HDMI_IH_CEC_STAT0);
>>> +	irqreturn_t ret = IRQ_HANDLED;
>>> +
>>> +	if (stat == 0)
>>> +		return IRQ_NONE;
>>> +
>>> +	dw_hdmi_write(cec, stat, HDMI_IH_CEC_STAT0);
>>> +
>>> +	if (stat & CEC_STAT_ERROR_INIT) {
>>> +		if (cec->retries) {
>>> +			unsigned v = dw_hdmi_read(cec, HDMI_CEC_CTRL);
>>> +			dw_hdmi_write(cec, v | CEC_CTRL_START, HDMI_CEC_CTRL);
>>> +			cec->retries -= 1;
>>
>> Why handle retries here at all? Just mark this as CEC_TX_STATUS_ERROR and set
>> tx_done to true. The CEC core will just call dw_hdmi_cec_transmit again if
>> it needs to make another attempt. I suggest that the whole retry code is
>> dropped.
> 
> Probably comes from a previous iteration of your CEC core which required
> the driver to do retries, so it can probably be fixed up in the way you
> describe.
> 
> However, presumably this needs a different status other than
> "CEC_TX_STATUS_MAX_RETRIES"?  I don't see a way to report this error to
> the CEC core in a way that it will retry.

If the framework does the retries, then the cec driver will never return the
MAX_RETRIES status. Just whether the transmit was OK/NACKed/LOW_DRIVE/ERROR.

> 
>>> +static irqreturn_t dw_hdmi_cec_thread(int irq, void *data)
>>> +{
>>> +	struct cec_adapter *adap = data;
>>> +	struct dw_hdmi_cec *cec = adap->priv;
>>> +
>>> +	if (cec->tx_done) {
>>> +		cec->tx_done = false;
>>> +		cec_transmit_done(adap, cec->tx_status, 0, 0, 0, 0);
>>
>> I think I will make a patch for a new helper function where you can just call:
>>
>> cec_transmit_attempt_done(adap, cec->tx_status);
>>
>> and that will call cec_transmit_done filling in the other arguments
>> based on the status.
>>
>> Most CEC HW doesn't do retries so only make one attempt. In that case
>> only one of the remaining count arguments is 1 and that's based on the
>> status.
>>
>> Having correct error counts is useful for debugging problems.
> 
> It hasn't been clear to me which counts should be non-zero, and it seems
> like entirely redundant information given that the status argument
> indicates what happened to the message.

True for HW that doesn't retry. Expect a patch today/tomorrow.

>>> +static void dw_hdmi_cec_disable(struct dw_hdmi *hdmi)
>>> +{
>>> +	mutex_lock(&hdmi->mutex);
>>> +	hdmi->mc_clkdis |= HDMI_MC_CLKDIS_CECCLK_DISABLE;
>>> +	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
>>> +	mutex_unlock(&hdmi->mutex);
>>> +}
>>> +
>>> +static const struct dw_hdmi_cec_ops dw_hdmi_cec_ops = {
>>> +	.write = hdmi_writeb,
>>> +	.read = hdmi_readb,
>>> +	.enable = dw_hdmi_cec_enable,
>>> +	.disable = dw_hdmi_cec_disable,
>>> +};
>>> +
>>
>> This feels over-engineered and I suspect it is simplified if you just
>> add a cec_adapter pointer to struct dw_hdmi and link dw-hdmi-cec.c
>> together with dw-hdmi.c.
> 
> As I mention above, to do so would mean that dw-hdmi has to be modular
> if you want CEC to be modular, and I don't think that is reasonable
> for a video output device, which may be the source of kernel boot
> messages.
> 

Indeed, but this dependency mess has been fixed, so this is no longer an
issue.

Regards,

	Hans

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver
@ 2017-06-01 10:44         ` Hans Verkuil
  0 siblings, 0 replies; 84+ messages in thread
From: Hans Verkuil @ 2017-06-01 10:44 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: linux-arm-kernel, dri-devel

On 06/01/17 11:46, Russell King - ARM Linux wrote:
> On Thu, Jun 01, 2017 at 10:31:10AM +0200, Hans Verkuil wrote:
>> Hi Russell,
>>
>> First a few top-level questions:
> 
> Hi Hans,
> 
>> 1) What was the reason for using the cec-notifier here? Isn't this
>>    tightly integrated into the main dw-hdmi block? For the tda driver
>>    it is clearly required, but for tightly coupled HDMI & CEC HW I
>>    just create the adapter from the HDMI driver. As a small bonus it
>>    avoids adding the cec-notifier code and the control flow is a bit
>>    easier to trace.
> 
> It's to avoid complex dependencies.  If it's all built in to the HDMI
> driver, then the HDMI driver needs to depend on all the media stuff
> being non-modular.  For a video output device, this is sub-optimal,
> because you want the video output device to work during boot.

This is no longer true after my rework of the CEC kernel config.

After doing a 'select CEC_CORE' the cec framework will be compiled
correctly.

It no longer depends on the media subsystem (except if you want to use
the remote control passthrough since the RC framework is part of media).

Selecting CEC_CORE will only select the cec core code.

> 
> I feel strongly about this point, especially as we have had many years
> of users being able to use dw-hdmi without needing CEC enabled.
> 
>> 2) I may have asked this before, apologies if I repeat myself: does
>>    this CEC implementation support CEC monitoring (aka snooping)? If
>>    it does, then I recommend that it is implemented since it is very
>>    useful.
> 
> It does not.
> 
>> 3) Is the CEC still active if there is no hotplug signal? Or is it
>>    powered off in that case? Ideally it should still be possible to
>>    send CEC messages even if there is no hotplug. This is explicitly
>>    allowed by the CEC 2.0 spec to wake up displays that turn off the
>>    HPD, but that still have a working CEC controller.
> 
> This is not specified in the documentation, so I don't think we know
> without experimentation.  This would be a future enhancement to the
> patch set.
> 
>>> diff --git a/drivers/gpu/drm/bridge/synopsys/Kconfig b/drivers/gpu/drm/bridge/synopsys/Kconfig
>>> index 40d2827a6d19..bd30a0a07272 100644
>>> --- a/drivers/gpu/drm/bridge/synopsys/Kconfig
>>> +++ b/drivers/gpu/drm/bridge/synopsys/Kconfig
>>> @@ -21,3 +21,11 @@ config DRM_DW_HDMI_I2S_AUDIO
>>>  	help
>>>  	  Support the I2S Audio interface which is part of the Synopsys
>>>  	  Designware HDMI block.
>>> +
>>> +config DRM_DW_HDMI_CEC
>>> +	tristate "Synopsis Designware CEC interface"
>>> +	depends on DRM_DW_HDMI && MEDIA_CEC_SUPPORT
>>> +	select MEDIA_CEC_NOTIFIER
>>> +	help
>>> +	  Support the CE interface which is part of the Synopsis
>>> +	  Designware HDMI block.
>>
>> This will change. Patches to fix the config handling are pending for 4.12.
>>
>> Here you can see the pending patches:
>> https://git.linuxtv.org/hverkuil/media_tree.git/log/?h=drm-cec
>>
>> The patches from 'cec-notifier.h: handle unreachable CONFIG_CEC_CORE' to
>> 'cec: drop MEDIA_CEC_DEBUG' should all be merged in 4.12.
>>
>> That means that this config becomes:
>>
>> +
>> +config DRM_DW_HDMI_CEC
>> +	tristate "Synopsis Designware CEC interface"
>> +	depends on DRM_DW_HDMI
>> +	select CEC_CORE
>> +	select CEC_NOTIFIER
>> +	help
>> +	  Support the CE interface which is part of the Synopsis
>> +	  Designware HDMI block.
> 
> You will also need to select MEDIA_SUPPORT to avoid dependency issues.
> CEC_CORE and CEC_NOTIFIER are both lumped under an "if MEDIA_SUPPORT"
> block in drivers/media/Kconfig, so they depend on this symbol.

No, they've been moved up. They no longer depend on the MEDIA_SUPPORT.
So that's been fixed.

> Asking
> Kconfig to select these two symbols without MEDIA_SUPPORT creates an
> invalid configuration - unless CEC has been moved out from being under
> MEDIA_SUPPORT.  (I haven't looked at your tree yet.)
> 
>>> +static int dw_hdmi_cec_log_addr(struct cec_adapter *adap, u8 logical_addr)
>>> +{
>>> +	struct dw_hdmi_cec *cec = adap->priv;
>>> +	u32 addresses;
>>> +
>>> +	if (logical_addr == CEC_LOG_ADDR_INVALID)
>>> +		addresses = cec->addresses = 0;
>>> +	else
>>> +		addresses = cec->addresses |= BIT(logical_addr) | BIT(15);
>>> +
>>> +	dw_hdmi_write(cec, addresses & 255, HDMI_CEC_ADDR_L);
>>> +	dw_hdmi_write(cec, addresses >> 8, HDMI_CEC_ADDR_H);
>>
>> The addresses local variable doesn't really seem needed.
> 
> Ok.
> 
>>> +static int dw_hdmi_cec_transmit(struct cec_adapter *adap, u8 attempts,
>>> +				u32 signal_free_time, struct cec_msg *msg)
>>> +{
>>> +	struct dw_hdmi_cec *cec = adap->priv;
>>> +	unsigned i;
>>> +
>>> +	cec->retries = attempts;
>>
>> Should probably be 'cec->retries = attempts - 1;'
>> Since 2 attempts == 1 retry.
> 
> Probably correct, but rather moot given your comment below.
> 
>>> +static irqreturn_t dw_hdmi_cec_hardirq(int irq, void *data)
>>> +{
>>> +	struct cec_adapter *adap = data;
>>> +	struct dw_hdmi_cec *cec = adap->priv;
>>> +	unsigned stat = dw_hdmi_read(cec, HDMI_IH_CEC_STAT0);
>>> +	irqreturn_t ret = IRQ_HANDLED;
>>> +
>>> +	if (stat == 0)
>>> +		return IRQ_NONE;
>>> +
>>> +	dw_hdmi_write(cec, stat, HDMI_IH_CEC_STAT0);
>>> +
>>> +	if (stat & CEC_STAT_ERROR_INIT) {
>>> +		if (cec->retries) {
>>> +			unsigned v = dw_hdmi_read(cec, HDMI_CEC_CTRL);
>>> +			dw_hdmi_write(cec, v | CEC_CTRL_START, HDMI_CEC_CTRL);
>>> +			cec->retries -= 1;
>>
>> Why handle retries here at all? Just mark this as CEC_TX_STATUS_ERROR and set
>> tx_done to true. The CEC core will just call dw_hdmi_cec_transmit again if
>> it needs to make another attempt. I suggest that the whole retry code is
>> dropped.
> 
> Probably comes from a previous iteration of your CEC core which required
> the driver to do retries, so it can probably be fixed up in the way you
> describe.
> 
> However, presumably this needs a different status other than
> "CEC_TX_STATUS_MAX_RETRIES"?  I don't see a way to report this error to
> the CEC core in a way that it will retry.

If the framework does the retries, then the cec driver will never return the
MAX_RETRIES status. Just whether the transmit was OK/NACKed/LOW_DRIVE/ERROR.

> 
>>> +static irqreturn_t dw_hdmi_cec_thread(int irq, void *data)
>>> +{
>>> +	struct cec_adapter *adap = data;
>>> +	struct dw_hdmi_cec *cec = adap->priv;
>>> +
>>> +	if (cec->tx_done) {
>>> +		cec->tx_done = false;
>>> +		cec_transmit_done(adap, cec->tx_status, 0, 0, 0, 0);
>>
>> I think I will make a patch for a new helper function where you can just call:
>>
>> cec_transmit_attempt_done(adap, cec->tx_status);
>>
>> and that will call cec_transmit_done filling in the other arguments
>> based on the status.
>>
>> Most CEC HW doesn't do retries so only make one attempt. In that case
>> only one of the remaining count arguments is 1 and that's based on the
>> status.
>>
>> Having correct error counts is useful for debugging problems.
> 
> It hasn't been clear to me which counts should be non-zero, and it seems
> like entirely redundant information given that the status argument
> indicates what happened to the message.

True for HW that doesn't retry. Expect a patch today/tomorrow.

>>> +static void dw_hdmi_cec_disable(struct dw_hdmi *hdmi)
>>> +{
>>> +	mutex_lock(&hdmi->mutex);
>>> +	hdmi->mc_clkdis |= HDMI_MC_CLKDIS_CECCLK_DISABLE;
>>> +	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
>>> +	mutex_unlock(&hdmi->mutex);
>>> +}
>>> +
>>> +static const struct dw_hdmi_cec_ops dw_hdmi_cec_ops = {
>>> +	.write = hdmi_writeb,
>>> +	.read = hdmi_readb,
>>> +	.enable = dw_hdmi_cec_enable,
>>> +	.disable = dw_hdmi_cec_disable,
>>> +};
>>> +
>>
>> This feels over-engineered and I suspect it is simplified if you just
>> add a cec_adapter pointer to struct dw_hdmi and link dw-hdmi-cec.c
>> together with dw-hdmi.c.
> 
> As I mention above, to do so would mean that dw-hdmi has to be modular
> if you want CEC to be modular, and I don't think that is reasonable
> for a video output device, which may be the source of kernel boot
> messages.
> 

Indeed, but this dependency mess has been fixed, so this is no longer an
issue.

Regards,

	Hans
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver
  2017-05-30 14:23   ` Russell King
@ 2017-06-01 13:47     ` Neil Armstrong
  -1 siblings, 0 replies; 84+ messages in thread
From: Neil Armstrong @ 2017-06-01 13:47 UTC (permalink / raw)
  To: linux-arm-kernel

On 05/30/2017 04:23 PM, Russell King wrote:
> Add a CEC driver for the dw-hdmi hardware.
> 
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> ---
>  drivers/gpu/drm/bridge/synopsys/Kconfig       |   8 +
>  drivers/gpu/drm/bridge/synopsys/Makefile      |   1 +
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 320 ++++++++++++++++++++++++++
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h |  19 ++
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c     |  40 +++-
>  5 files changed, 387 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
>  create mode 100644 drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/Kconfig b/drivers/gpu/drm/bridge/synopsys/Kconfig
> index 40d2827a6d19..bd30a0a07272 100644
> --- a/drivers/gpu/drm/bridge/synopsys/Kconfig
> +++ b/drivers/gpu/drm/bridge/synopsys/Kconfig
> @@ -21,3 +21,11 @@ config DRM_DW_HDMI_I2S_AUDIO
>  	help
>  	  Support the I2S Audio interface which is part of the Synopsys
>  	  Designware HDMI block.
> +
> +config DRM_DW_HDMI_CEC
> +	tristate "Synopsis Designware CEC interface"
> +	depends on DRM_DW_HDMI && MEDIA_CEC_SUPPORT
> +	select MEDIA_CEC_NOTIFIER
> +	help
> +	  Support the CE interface which is part of the Synopsis
> +	  Designware HDMI block.
> diff --git a/drivers/gpu/drm/bridge/synopsys/Makefile b/drivers/gpu/drm/bridge/synopsys/Makefile
> index 17aa7a65b57e..6fe415903668 100644
> --- a/drivers/gpu/drm/bridge/synopsys/Makefile
> +++ b/drivers/gpu/drm/bridge/synopsys/Makefile
> @@ -3,3 +3,4 @@
>  obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
>  obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
>  obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o
> +obj-$(CONFIG_DRM_DW_HDMI_CEC) += dw-hdmi-cec.o
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
> new file mode 100644
> index 000000000000..761ef5ae687d
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
> @@ -0,0 +1,320 @@
> +/*
> + * Designware HDMI CEC driver
> + *
> + * Copyright (C) 2015-2017 Russell King.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/sched.h>
> +#include <linux/slab.h>
> +
> +#include <drm/drm_edid.h>
> +
> +#include <media/cec.h>
> +#include <media/cec-notifier.h>
> +
> +#include "dw-hdmi-cec.h"
> +
> +enum {
> +	HDMI_IH_CEC_STAT0	= 0x0106,
> +	HDMI_IH_MUTE_CEC_STAT0	= 0x0186,
> +
> +	HDMI_CEC_CTRL		= 0x7d00,
> +	CEC_CTRL_START		= BIT(0),
> +	CEC_CTRL_NORMAL		= 1 << 1,
> +
> +	HDMI_CEC_STAT		= 0x7d01,
> +	CEC_STAT_DONE		= BIT(0),
> +	CEC_STAT_EOM		= BIT(1),
> +	CEC_STAT_NACK		= BIT(2),
> +	CEC_STAT_ARBLOST	= BIT(3),
> +	CEC_STAT_ERROR_INIT	= BIT(4),
> +	CEC_STAT_ERROR_FOLL	= BIT(5),
> +	CEC_STAT_WAKEUP		= BIT(6),
> +
> +	HDMI_CEC_MASK		= 0x7d02,
> +	HDMI_CEC_POLARITY	= 0x7d03,
> +	HDMI_CEC_INT		= 0x7d04,
> +	HDMI_CEC_ADDR_L		= 0x7d05,
> +	HDMI_CEC_ADDR_H		= 0x7d06,
> +	HDMI_CEC_TX_CNT		= 0x7d07,
> +	HDMI_CEC_RX_CNT		= 0x7d08,
> +	HDMI_CEC_TX_DATA0	= 0x7d10,
> +	HDMI_CEC_RX_DATA0	= 0x7d20,
> +	HDMI_CEC_LOCK		= 0x7d30,
> +	HDMI_CEC_WKUPCTRL	= 0x7d31,
> +};
> +
> +struct dw_hdmi_cec {
> +	struct dw_hdmi *hdmi;
> +	const struct dw_hdmi_cec_ops *ops;
> +	u32 addresses;
> +	struct cec_adapter *adap;
> +	struct cec_msg rx_msg;
> +	unsigned int tx_status;
> +	bool tx_done;
> +	bool rx_done;
> +	struct cec_notifier *notify;
> +	int retries;
> +	int irq;
> +};
> +
> +static void dw_hdmi_write(struct dw_hdmi_cec *cec, u8 val, int offset)
> +{
> +	cec->ops->write(cec->hdmi, val, offset);
> +}
> +
> +static u8 dw_hdmi_read(struct dw_hdmi_cec *cec, int offset)
> +{
> +	return cec->ops->read(cec->hdmi, offset);
> +}
> +
> +static int dw_hdmi_cec_log_addr(struct cec_adapter *adap, u8 logical_addr)
> +{
> +	struct dw_hdmi_cec *cec = adap->priv;
> +	u32 addresses;
> +
> +	if (logical_addr == CEC_LOG_ADDR_INVALID)
> +		addresses = cec->addresses = 0;
> +	else
> +		addresses = cec->addresses |= BIT(logical_addr) | BIT(15);
> +
> +	dw_hdmi_write(cec, addresses & 255, HDMI_CEC_ADDR_L);
> +	dw_hdmi_write(cec, addresses >> 8, HDMI_CEC_ADDR_H);
> +
> +	return 0;
> +}
> +
> +static int dw_hdmi_cec_transmit(struct cec_adapter *adap, u8 attempts,
> +				u32 signal_free_time, struct cec_msg *msg)
> +{
> +	struct dw_hdmi_cec *cec = adap->priv;
> +	unsigned i;
> +
> +	cec->retries = attempts;
> +
> +	for (i = 0; i < msg->len; i++)
> +		dw_hdmi_write(cec, msg->msg[i], HDMI_CEC_TX_DATA0 + i);
> +
> +	dw_hdmi_write(cec, msg->len, HDMI_CEC_TX_CNT);
> +	dw_hdmi_write(cec, CEC_CTRL_NORMAL | CEC_CTRL_START, HDMI_CEC_CTRL);
> +
> +	return 0;
> +}
> +
> +static irqreturn_t dw_hdmi_cec_hardirq(int irq, void *data)
> +{
> +	struct cec_adapter *adap = data;
> +	struct dw_hdmi_cec *cec = adap->priv;
> +	unsigned stat = dw_hdmi_read(cec, HDMI_IH_CEC_STAT0);
> +	irqreturn_t ret = IRQ_HANDLED;
> +
> +	if (stat == 0)
> +		return IRQ_NONE;
> +
> +	dw_hdmi_write(cec, stat, HDMI_IH_CEC_STAT0);
> +
> +	if (stat & CEC_STAT_ERROR_INIT) {
> +		if (cec->retries) {
> +			unsigned v = dw_hdmi_read(cec, HDMI_CEC_CTRL);
> +			dw_hdmi_write(cec, v | CEC_CTRL_START, HDMI_CEC_CTRL);
> +			cec->retries -= 1;
> +		} else {
> +			cec->tx_status = CEC_TX_STATUS_MAX_RETRIES;
> +			cec->tx_done = true;
> +			ret = IRQ_WAKE_THREAD;
> +		}
> +	} else if (stat & CEC_STAT_DONE) {
> +		cec->tx_status = CEC_TX_STATUS_OK;
> +		cec->tx_done = true;
> +		ret = IRQ_WAKE_THREAD;
> +	} else if (stat & CEC_STAT_NACK) {
> +		cec->tx_status = CEC_TX_STATUS_NACK;
> +		cec->tx_done = true;
> +		ret = IRQ_WAKE_THREAD;
> +	}
> +
> +	if (stat & CEC_STAT_EOM) {
> +		unsigned len, i;
> +
> +		len = dw_hdmi_read(cec, HDMI_CEC_RX_CNT);
> +		if (len > sizeof(cec->rx_msg.msg))
> +			len = sizeof(cec->rx_msg.msg);
> +
> +		for (i = 0; i < len; i++)
> +			cec->rx_msg.msg[i] =
> +				dw_hdmi_read(cec, HDMI_CEC_RX_DATA0 + i);
> +
> +		dw_hdmi_write(cec, 0, HDMI_CEC_LOCK);
> +
> +		cec->rx_msg.len = len;
> +		smp_wmb();
> +		cec->rx_done = true;
> +
> +		ret = IRQ_WAKE_THREAD;
> +	}
> +
> +	return ret;
> +}
> +
> +static irqreturn_t dw_hdmi_cec_thread(int irq, void *data)
> +{
> +	struct cec_adapter *adap = data;
> +	struct dw_hdmi_cec *cec = adap->priv;
> +
> +	if (cec->tx_done) {
> +		cec->tx_done = false;
> +		cec_transmit_done(adap, cec->tx_status, 0, 0, 0, 0);
> +	}
> +	if (cec->rx_done) {
> +		cec->rx_done = false;
> +		smp_rmb();
> +		cec_received_msg(adap, &cec->rx_msg);
> +	}
> +	return IRQ_HANDLED;
> +}
> +
> +static int dw_hdmi_cec_enable(struct cec_adapter *adap, bool enable)
> +{
> +	struct dw_hdmi_cec *cec = adap->priv;
> +
> +	if (!enable) {
> +		dw_hdmi_write(cec, ~0, HDMI_CEC_MASK);
> +		dw_hdmi_write(cec, ~0, HDMI_IH_MUTE_CEC_STAT0);
> +		dw_hdmi_write(cec, 0, HDMI_CEC_POLARITY);
> +
> +		cec->ops->disable(cec->hdmi);
> +	} else {
> +		unsigned irqs;
> +
> +		dw_hdmi_write(cec, 0, HDMI_CEC_CTRL);
> +		dw_hdmi_write(cec, ~0, HDMI_IH_CEC_STAT0);
> +		dw_hdmi_write(cec, 0, HDMI_CEC_LOCK);
> +
> +		dw_hdmi_cec_log_addr(cec->adap, CEC_LOG_ADDR_INVALID);
> +
> +		cec->ops->enable(cec->hdmi);
> +
> +		irqs = CEC_STAT_ERROR_INIT | CEC_STAT_NACK | CEC_STAT_EOM |
> +		       CEC_STAT_DONE;
> +		dw_hdmi_write(cec, irqs, HDMI_CEC_POLARITY);
> +		dw_hdmi_write(cec, ~irqs, HDMI_CEC_MASK);
> +		dw_hdmi_write(cec, ~irqs, HDMI_IH_MUTE_CEC_STAT0);
> +	}
> +	return 0;
> +}
> +
> +static const struct cec_adap_ops dw_hdmi_cec_ops = {
> +	.adap_enable = dw_hdmi_cec_enable,
> +	.adap_log_addr = dw_hdmi_cec_log_addr,
> +	.adap_transmit = dw_hdmi_cec_transmit,
> +};
> +
> +static void dw_hdmi_cec_del(void *data)
> +{
> +	struct dw_hdmi_cec *cec = data;
> +
> +	cec_delete_adapter(cec->adap);
> +}
> +
> +static int dw_hdmi_cec_probe(struct platform_device *pdev)
> +{
> +	struct dw_hdmi_cec_data *data = dev_get_platdata(&pdev->dev);
> +	struct dw_hdmi_cec *cec;
> +	int ret;
> +
> +	if (!data)
> +		return -ENXIO;
> +
> +	/*
> +	 * Our device is just a convenience - we want to link to the real
> +	 * hardware device here, so that userspace can see the association
> +	 * between the HDMI hardware and its associated CEC chardev.
> +	 */
> +	cec = devm_kzalloc(&pdev->dev, sizeof(*cec), GFP_KERNEL);
> +	if (!cec)
> +		return -ENOMEM;
> +
> +	cec->irq = data->irq;
> +	cec->ops = data->ops;
> +	cec->hdmi = data->hdmi;
> +
> +	platform_set_drvdata(pdev, cec);
> +
> +	dw_hdmi_write(cec, 0, HDMI_CEC_TX_CNT);
> +	dw_hdmi_write(cec, ~0, HDMI_CEC_MASK);
> +	dw_hdmi_write(cec, ~0, HDMI_IH_MUTE_CEC_STAT0);
> +	dw_hdmi_write(cec, 0, HDMI_CEC_POLARITY);
> +
> +	cec->adap = cec_allocate_adapter(&dw_hdmi_cec_ops, cec, "dw_hdmi",
> +					 CEC_CAP_LOG_ADDRS | CEC_CAP_TRANSMIT |
> +					 CEC_CAP_RC, CEC_MAX_LOG_ADDRS);
> +	if (IS_ERR(cec->adap))
> +		return PTR_ERR(cec->adap);
> +
> +	/* override the module pointer */
> +	cec->adap->owner = THIS_MODULE;
> +
> +	ret = devm_add_action(&pdev->dev, dw_hdmi_cec_del, cec);
> +	if (ret) {
> +		cec_delete_adapter(cec->adap);
> +		return ret;
> +	}
> +
> +	ret = devm_request_threaded_irq(&pdev->dev, cec->irq,
> +					dw_hdmi_cec_hardirq,
> +					dw_hdmi_cec_thread, IRQF_SHARED,
> +					"dw-hdmi-cec", cec->adap);
> +	if (ret < 0)
> +		return ret;
> +
> +	cec->notify = cec_notifier_get(pdev->dev.parent);
> +	if (!cec->notify)
> +		return -ENOMEM;
> +
> +	ret = cec_register_adapter(cec->adap, pdev->dev.parent);
> +	if (ret < 0) {
> +		cec_notifier_put(cec->notify);
> +		return ret;
> +	}
> +
> +	/*
> +	 * CEC documentation says we must not call cec_delete_adapter
> +	 * after a successful call to cec_register_adapter().
> +	 */
> +	devm_remove_action(&pdev->dev, dw_hdmi_cec_del, cec);
> +
> +	cec_register_cec_notifier(cec->adap, cec->notify);
> +
> +	return 0;
> +}
> +
> +static int dw_hdmi_cec_remove(struct platform_device *pdev)
> +{
> +	struct dw_hdmi_cec *cec = platform_get_drvdata(pdev);
> +
> +	cec_unregister_adapter(cec->adap);
> +	cec_notifier_put(cec->notify);
> +
> +	return 0;
> +}
> +
> +static struct platform_driver dw_hdmi_cec_driver = {
> +	.probe	= dw_hdmi_cec_probe,
> +	.remove	= dw_hdmi_cec_remove,
> +	.driver = {
> +		.name = "dw-hdmi-cec",
> +	},
> +};
> +module_platform_driver(dw_hdmi_cec_driver);
> +
> +MODULE_AUTHOR("Russell King <rmk+kernel@armlinux.org.uk>");
> +MODULE_DESCRIPTION("Synopsis Designware HDMI CEC driver for i.MX");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS(PLATFORM_MODULE_PREFIX "dw-hdmi-cec");
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
> new file mode 100644
> index 000000000000..cf4dc121a2c4
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
> @@ -0,0 +1,19 @@
> +#ifndef DW_HDMI_CEC_H
> +#define DW_HDMI_CEC_H
> +
> +struct dw_hdmi;
> +
> +struct dw_hdmi_cec_ops {
> +	void (*write)(struct dw_hdmi *hdmi, u8 val, int offset);
> +	u8 (*read)(struct dw_hdmi *hdmi, int offset);
> +	void (*enable)(struct dw_hdmi *hdmi);
> +	void (*disable)(struct dw_hdmi *hdmi);
> +};
> +
> +struct dw_hdmi_cec_data {
> +	struct dw_hdmi *hdmi;
> +	const struct dw_hdmi_cec_ops *ops;
> +	int irq;
> +};
> +
> +#endif
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 58781d4c1034..5a389f1f58d9 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -35,6 +35,7 @@
>  
>  #include "dw-hdmi.h"
>  #include "dw-hdmi-audio.h"
> +#include "dw-hdmi-cec.h"
>  
>  #include <media/cec-notifier.h>
>  
> @@ -133,6 +134,7 @@ struct dw_hdmi {
>  	unsigned int version;
>  
>  	struct platform_device *audio;
> +	struct platform_device *cec;
>  	struct device *dev;
>  	struct clk *isfr_clk;
>  	struct clk *iahb_clk;
> @@ -1766,7 +1768,6 @@ static void initialize_hdmi_ih_mutes(struct dw_hdmi *hdmi)
>  	hdmi_writeb(hdmi, 0xff, HDMI_AUD_HBR_MASK);
>  	hdmi_writeb(hdmi, 0xff, HDMI_GP_MASK);
>  	hdmi_writeb(hdmi, 0xff, HDMI_A_APIINTMSK);
> -	hdmi_writeb(hdmi, 0xff, HDMI_CEC_MASK);
>  	hdmi_writeb(hdmi, 0xff, HDMI_I2CM_INT);
>  	hdmi_writeb(hdmi, 0xff, HDMI_I2CM_CTLINT);
>  
> @@ -2223,6 +2224,29 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi)
>  	return -ENODEV;
>  }
>  
> +static void dw_hdmi_cec_enable(struct dw_hdmi *hdmi)
> +{
> +	mutex_lock(&hdmi->mutex);
> +	hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CECCLK_DISABLE;
> +	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
> +	mutex_unlock(&hdmi->mutex);
> +}
> +
> +static void dw_hdmi_cec_disable(struct dw_hdmi *hdmi)
> +{
> +	mutex_lock(&hdmi->mutex);
> +	hdmi->mc_clkdis |= HDMI_MC_CLKDIS_CECCLK_DISABLE;
> +	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
> +	mutex_unlock(&hdmi->mutex);
> +}
> +
> +static const struct dw_hdmi_cec_ops dw_hdmi_cec_ops = {
> +	.write = hdmi_writeb,
> +	.read = hdmi_readb,
> +	.enable = dw_hdmi_cec_enable,
> +	.disable = dw_hdmi_cec_disable,
> +};
> +
>  static const struct regmap_config hdmi_regmap_8bit_config = {
>  	.reg_bits	= 32,
>  	.val_bits	= 8,
> @@ -2245,6 +2269,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  	struct device_node *np = dev->of_node;
>  	struct platform_device_info pdevinfo;
>  	struct device_node *ddc_node;
> +	struct dw_hdmi_cec_data cec;
>  	struct dw_hdmi *hdmi;
>  	struct resource *iores = NULL;
>  	int irq;
> @@ -2445,6 +2470,17 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  		hdmi->audio = platform_device_register_full(&pdevinfo);
>  	}
>  
> +	cec.hdmi = hdmi;
> +	cec.ops = &dw_hdmi_cec_ops;
> +	cec.irq = irq;
> +
> +	pdevinfo.name = "dw-hdmi-cec";
> +	pdevinfo.data = &cec;
> +	pdevinfo.size_data = sizeof(cec);
> +	pdevinfo.dma_mask = 0;
> +
> +	hdmi->cec = platform_device_register_full(&pdevinfo);

Maybe you should check the config bit before enabling CEC :

 /* CONFIG0_ID field values */
 +	HDMI_CONFIG0_CEC = 0x2,

if (config0 & HDMI_CONFIG0_CEC) {
}

> +
>  	/* Reset HDMI DDC I2C master controller and mute I2CM interrupts */
>  	if (hdmi->i2c)
>  		dw_hdmi_i2c_init(hdmi);
> @@ -2475,6 +2511,8 @@ static void __dw_hdmi_remove(struct dw_hdmi *hdmi)
>  {
>  	if (hdmi->audio && !IS_ERR(hdmi->audio))
>  		platform_device_unregister(hdmi->audio);
> +	if (!IS_ERR(hdmi->cec))
> +		platform_device_unregister(hdmi->cec);
>  
>  	/* Disable all interrupts */
>  	hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
> 

Apart from that and the s/Synopsis/Synopsys/ typos:

Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>

Neil

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver
@ 2017-06-01 13:47     ` Neil Armstrong
  0 siblings, 0 replies; 84+ messages in thread
From: Neil Armstrong @ 2017-06-01 13:47 UTC (permalink / raw)
  To: Russell King, Hans Verkuil; +Cc: linux-arm-kernel, dri-devel

On 05/30/2017 04:23 PM, Russell King wrote:
> Add a CEC driver for the dw-hdmi hardware.
> 
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> ---
>  drivers/gpu/drm/bridge/synopsys/Kconfig       |   8 +
>  drivers/gpu/drm/bridge/synopsys/Makefile      |   1 +
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 320 ++++++++++++++++++++++++++
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h |  19 ++
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c     |  40 +++-
>  5 files changed, 387 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
>  create mode 100644 drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/Kconfig b/drivers/gpu/drm/bridge/synopsys/Kconfig
> index 40d2827a6d19..bd30a0a07272 100644
> --- a/drivers/gpu/drm/bridge/synopsys/Kconfig
> +++ b/drivers/gpu/drm/bridge/synopsys/Kconfig
> @@ -21,3 +21,11 @@ config DRM_DW_HDMI_I2S_AUDIO
>  	help
>  	  Support the I2S Audio interface which is part of the Synopsys
>  	  Designware HDMI block.
> +
> +config DRM_DW_HDMI_CEC
> +	tristate "Synopsis Designware CEC interface"
> +	depends on DRM_DW_HDMI && MEDIA_CEC_SUPPORT
> +	select MEDIA_CEC_NOTIFIER
> +	help
> +	  Support the CE interface which is part of the Synopsis
> +	  Designware HDMI block.
> diff --git a/drivers/gpu/drm/bridge/synopsys/Makefile b/drivers/gpu/drm/bridge/synopsys/Makefile
> index 17aa7a65b57e..6fe415903668 100644
> --- a/drivers/gpu/drm/bridge/synopsys/Makefile
> +++ b/drivers/gpu/drm/bridge/synopsys/Makefile
> @@ -3,3 +3,4 @@
>  obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
>  obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
>  obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o
> +obj-$(CONFIG_DRM_DW_HDMI_CEC) += dw-hdmi-cec.o
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
> new file mode 100644
> index 000000000000..761ef5ae687d
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
> @@ -0,0 +1,320 @@
> +/*
> + * Designware HDMI CEC driver
> + *
> + * Copyright (C) 2015-2017 Russell King.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/sched.h>
> +#include <linux/slab.h>
> +
> +#include <drm/drm_edid.h>
> +
> +#include <media/cec.h>
> +#include <media/cec-notifier.h>
> +
> +#include "dw-hdmi-cec.h"
> +
> +enum {
> +	HDMI_IH_CEC_STAT0	= 0x0106,
> +	HDMI_IH_MUTE_CEC_STAT0	= 0x0186,
> +
> +	HDMI_CEC_CTRL		= 0x7d00,
> +	CEC_CTRL_START		= BIT(0),
> +	CEC_CTRL_NORMAL		= 1 << 1,
> +
> +	HDMI_CEC_STAT		= 0x7d01,
> +	CEC_STAT_DONE		= BIT(0),
> +	CEC_STAT_EOM		= BIT(1),
> +	CEC_STAT_NACK		= BIT(2),
> +	CEC_STAT_ARBLOST	= BIT(3),
> +	CEC_STAT_ERROR_INIT	= BIT(4),
> +	CEC_STAT_ERROR_FOLL	= BIT(5),
> +	CEC_STAT_WAKEUP		= BIT(6),
> +
> +	HDMI_CEC_MASK		= 0x7d02,
> +	HDMI_CEC_POLARITY	= 0x7d03,
> +	HDMI_CEC_INT		= 0x7d04,
> +	HDMI_CEC_ADDR_L		= 0x7d05,
> +	HDMI_CEC_ADDR_H		= 0x7d06,
> +	HDMI_CEC_TX_CNT		= 0x7d07,
> +	HDMI_CEC_RX_CNT		= 0x7d08,
> +	HDMI_CEC_TX_DATA0	= 0x7d10,
> +	HDMI_CEC_RX_DATA0	= 0x7d20,
> +	HDMI_CEC_LOCK		= 0x7d30,
> +	HDMI_CEC_WKUPCTRL	= 0x7d31,
> +};
> +
> +struct dw_hdmi_cec {
> +	struct dw_hdmi *hdmi;
> +	const struct dw_hdmi_cec_ops *ops;
> +	u32 addresses;
> +	struct cec_adapter *adap;
> +	struct cec_msg rx_msg;
> +	unsigned int tx_status;
> +	bool tx_done;
> +	bool rx_done;
> +	struct cec_notifier *notify;
> +	int retries;
> +	int irq;
> +};
> +
> +static void dw_hdmi_write(struct dw_hdmi_cec *cec, u8 val, int offset)
> +{
> +	cec->ops->write(cec->hdmi, val, offset);
> +}
> +
> +static u8 dw_hdmi_read(struct dw_hdmi_cec *cec, int offset)
> +{
> +	return cec->ops->read(cec->hdmi, offset);
> +}
> +
> +static int dw_hdmi_cec_log_addr(struct cec_adapter *adap, u8 logical_addr)
> +{
> +	struct dw_hdmi_cec *cec = adap->priv;
> +	u32 addresses;
> +
> +	if (logical_addr == CEC_LOG_ADDR_INVALID)
> +		addresses = cec->addresses = 0;
> +	else
> +		addresses = cec->addresses |= BIT(logical_addr) | BIT(15);
> +
> +	dw_hdmi_write(cec, addresses & 255, HDMI_CEC_ADDR_L);
> +	dw_hdmi_write(cec, addresses >> 8, HDMI_CEC_ADDR_H);
> +
> +	return 0;
> +}
> +
> +static int dw_hdmi_cec_transmit(struct cec_adapter *adap, u8 attempts,
> +				u32 signal_free_time, struct cec_msg *msg)
> +{
> +	struct dw_hdmi_cec *cec = adap->priv;
> +	unsigned i;
> +
> +	cec->retries = attempts;
> +
> +	for (i = 0; i < msg->len; i++)
> +		dw_hdmi_write(cec, msg->msg[i], HDMI_CEC_TX_DATA0 + i);
> +
> +	dw_hdmi_write(cec, msg->len, HDMI_CEC_TX_CNT);
> +	dw_hdmi_write(cec, CEC_CTRL_NORMAL | CEC_CTRL_START, HDMI_CEC_CTRL);
> +
> +	return 0;
> +}
> +
> +static irqreturn_t dw_hdmi_cec_hardirq(int irq, void *data)
> +{
> +	struct cec_adapter *adap = data;
> +	struct dw_hdmi_cec *cec = adap->priv;
> +	unsigned stat = dw_hdmi_read(cec, HDMI_IH_CEC_STAT0);
> +	irqreturn_t ret = IRQ_HANDLED;
> +
> +	if (stat == 0)
> +		return IRQ_NONE;
> +
> +	dw_hdmi_write(cec, stat, HDMI_IH_CEC_STAT0);
> +
> +	if (stat & CEC_STAT_ERROR_INIT) {
> +		if (cec->retries) {
> +			unsigned v = dw_hdmi_read(cec, HDMI_CEC_CTRL);
> +			dw_hdmi_write(cec, v | CEC_CTRL_START, HDMI_CEC_CTRL);
> +			cec->retries -= 1;
> +		} else {
> +			cec->tx_status = CEC_TX_STATUS_MAX_RETRIES;
> +			cec->tx_done = true;
> +			ret = IRQ_WAKE_THREAD;
> +		}
> +	} else if (stat & CEC_STAT_DONE) {
> +		cec->tx_status = CEC_TX_STATUS_OK;
> +		cec->tx_done = true;
> +		ret = IRQ_WAKE_THREAD;
> +	} else if (stat & CEC_STAT_NACK) {
> +		cec->tx_status = CEC_TX_STATUS_NACK;
> +		cec->tx_done = true;
> +		ret = IRQ_WAKE_THREAD;
> +	}
> +
> +	if (stat & CEC_STAT_EOM) {
> +		unsigned len, i;
> +
> +		len = dw_hdmi_read(cec, HDMI_CEC_RX_CNT);
> +		if (len > sizeof(cec->rx_msg.msg))
> +			len = sizeof(cec->rx_msg.msg);
> +
> +		for (i = 0; i < len; i++)
> +			cec->rx_msg.msg[i] =
> +				dw_hdmi_read(cec, HDMI_CEC_RX_DATA0 + i);
> +
> +		dw_hdmi_write(cec, 0, HDMI_CEC_LOCK);
> +
> +		cec->rx_msg.len = len;
> +		smp_wmb();
> +		cec->rx_done = true;
> +
> +		ret = IRQ_WAKE_THREAD;
> +	}
> +
> +	return ret;
> +}
> +
> +static irqreturn_t dw_hdmi_cec_thread(int irq, void *data)
> +{
> +	struct cec_adapter *adap = data;
> +	struct dw_hdmi_cec *cec = adap->priv;
> +
> +	if (cec->tx_done) {
> +		cec->tx_done = false;
> +		cec_transmit_done(adap, cec->tx_status, 0, 0, 0, 0);
> +	}
> +	if (cec->rx_done) {
> +		cec->rx_done = false;
> +		smp_rmb();
> +		cec_received_msg(adap, &cec->rx_msg);
> +	}
> +	return IRQ_HANDLED;
> +}
> +
> +static int dw_hdmi_cec_enable(struct cec_adapter *adap, bool enable)
> +{
> +	struct dw_hdmi_cec *cec = adap->priv;
> +
> +	if (!enable) {
> +		dw_hdmi_write(cec, ~0, HDMI_CEC_MASK);
> +		dw_hdmi_write(cec, ~0, HDMI_IH_MUTE_CEC_STAT0);
> +		dw_hdmi_write(cec, 0, HDMI_CEC_POLARITY);
> +
> +		cec->ops->disable(cec->hdmi);
> +	} else {
> +		unsigned irqs;
> +
> +		dw_hdmi_write(cec, 0, HDMI_CEC_CTRL);
> +		dw_hdmi_write(cec, ~0, HDMI_IH_CEC_STAT0);
> +		dw_hdmi_write(cec, 0, HDMI_CEC_LOCK);
> +
> +		dw_hdmi_cec_log_addr(cec->adap, CEC_LOG_ADDR_INVALID);
> +
> +		cec->ops->enable(cec->hdmi);
> +
> +		irqs = CEC_STAT_ERROR_INIT | CEC_STAT_NACK | CEC_STAT_EOM |
> +		       CEC_STAT_DONE;
> +		dw_hdmi_write(cec, irqs, HDMI_CEC_POLARITY);
> +		dw_hdmi_write(cec, ~irqs, HDMI_CEC_MASK);
> +		dw_hdmi_write(cec, ~irqs, HDMI_IH_MUTE_CEC_STAT0);
> +	}
> +	return 0;
> +}
> +
> +static const struct cec_adap_ops dw_hdmi_cec_ops = {
> +	.adap_enable = dw_hdmi_cec_enable,
> +	.adap_log_addr = dw_hdmi_cec_log_addr,
> +	.adap_transmit = dw_hdmi_cec_transmit,
> +};
> +
> +static void dw_hdmi_cec_del(void *data)
> +{
> +	struct dw_hdmi_cec *cec = data;
> +
> +	cec_delete_adapter(cec->adap);
> +}
> +
> +static int dw_hdmi_cec_probe(struct platform_device *pdev)
> +{
> +	struct dw_hdmi_cec_data *data = dev_get_platdata(&pdev->dev);
> +	struct dw_hdmi_cec *cec;
> +	int ret;
> +
> +	if (!data)
> +		return -ENXIO;
> +
> +	/*
> +	 * Our device is just a convenience - we want to link to the real
> +	 * hardware device here, so that userspace can see the association
> +	 * between the HDMI hardware and its associated CEC chardev.
> +	 */
> +	cec = devm_kzalloc(&pdev->dev, sizeof(*cec), GFP_KERNEL);
> +	if (!cec)
> +		return -ENOMEM;
> +
> +	cec->irq = data->irq;
> +	cec->ops = data->ops;
> +	cec->hdmi = data->hdmi;
> +
> +	platform_set_drvdata(pdev, cec);
> +
> +	dw_hdmi_write(cec, 0, HDMI_CEC_TX_CNT);
> +	dw_hdmi_write(cec, ~0, HDMI_CEC_MASK);
> +	dw_hdmi_write(cec, ~0, HDMI_IH_MUTE_CEC_STAT0);
> +	dw_hdmi_write(cec, 0, HDMI_CEC_POLARITY);
> +
> +	cec->adap = cec_allocate_adapter(&dw_hdmi_cec_ops, cec, "dw_hdmi",
> +					 CEC_CAP_LOG_ADDRS | CEC_CAP_TRANSMIT |
> +					 CEC_CAP_RC, CEC_MAX_LOG_ADDRS);
> +	if (IS_ERR(cec->adap))
> +		return PTR_ERR(cec->adap);
> +
> +	/* override the module pointer */
> +	cec->adap->owner = THIS_MODULE;
> +
> +	ret = devm_add_action(&pdev->dev, dw_hdmi_cec_del, cec);
> +	if (ret) {
> +		cec_delete_adapter(cec->adap);
> +		return ret;
> +	}
> +
> +	ret = devm_request_threaded_irq(&pdev->dev, cec->irq,
> +					dw_hdmi_cec_hardirq,
> +					dw_hdmi_cec_thread, IRQF_SHARED,
> +					"dw-hdmi-cec", cec->adap);
> +	if (ret < 0)
> +		return ret;
> +
> +	cec->notify = cec_notifier_get(pdev->dev.parent);
> +	if (!cec->notify)
> +		return -ENOMEM;
> +
> +	ret = cec_register_adapter(cec->adap, pdev->dev.parent);
> +	if (ret < 0) {
> +		cec_notifier_put(cec->notify);
> +		return ret;
> +	}
> +
> +	/*
> +	 * CEC documentation says we must not call cec_delete_adapter
> +	 * after a successful call to cec_register_adapter().
> +	 */
> +	devm_remove_action(&pdev->dev, dw_hdmi_cec_del, cec);
> +
> +	cec_register_cec_notifier(cec->adap, cec->notify);
> +
> +	return 0;
> +}
> +
> +static int dw_hdmi_cec_remove(struct platform_device *pdev)
> +{
> +	struct dw_hdmi_cec *cec = platform_get_drvdata(pdev);
> +
> +	cec_unregister_adapter(cec->adap);
> +	cec_notifier_put(cec->notify);
> +
> +	return 0;
> +}
> +
> +static struct platform_driver dw_hdmi_cec_driver = {
> +	.probe	= dw_hdmi_cec_probe,
> +	.remove	= dw_hdmi_cec_remove,
> +	.driver = {
> +		.name = "dw-hdmi-cec",
> +	},
> +};
> +module_platform_driver(dw_hdmi_cec_driver);
> +
> +MODULE_AUTHOR("Russell King <rmk+kernel@armlinux.org.uk>");
> +MODULE_DESCRIPTION("Synopsis Designware HDMI CEC driver for i.MX");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS(PLATFORM_MODULE_PREFIX "dw-hdmi-cec");
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
> new file mode 100644
> index 000000000000..cf4dc121a2c4
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
> @@ -0,0 +1,19 @@
> +#ifndef DW_HDMI_CEC_H
> +#define DW_HDMI_CEC_H
> +
> +struct dw_hdmi;
> +
> +struct dw_hdmi_cec_ops {
> +	void (*write)(struct dw_hdmi *hdmi, u8 val, int offset);
> +	u8 (*read)(struct dw_hdmi *hdmi, int offset);
> +	void (*enable)(struct dw_hdmi *hdmi);
> +	void (*disable)(struct dw_hdmi *hdmi);
> +};
> +
> +struct dw_hdmi_cec_data {
> +	struct dw_hdmi *hdmi;
> +	const struct dw_hdmi_cec_ops *ops;
> +	int irq;
> +};
> +
> +#endif
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 58781d4c1034..5a389f1f58d9 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -35,6 +35,7 @@
>  
>  #include "dw-hdmi.h"
>  #include "dw-hdmi-audio.h"
> +#include "dw-hdmi-cec.h"
>  
>  #include <media/cec-notifier.h>
>  
> @@ -133,6 +134,7 @@ struct dw_hdmi {
>  	unsigned int version;
>  
>  	struct platform_device *audio;
> +	struct platform_device *cec;
>  	struct device *dev;
>  	struct clk *isfr_clk;
>  	struct clk *iahb_clk;
> @@ -1766,7 +1768,6 @@ static void initialize_hdmi_ih_mutes(struct dw_hdmi *hdmi)
>  	hdmi_writeb(hdmi, 0xff, HDMI_AUD_HBR_MASK);
>  	hdmi_writeb(hdmi, 0xff, HDMI_GP_MASK);
>  	hdmi_writeb(hdmi, 0xff, HDMI_A_APIINTMSK);
> -	hdmi_writeb(hdmi, 0xff, HDMI_CEC_MASK);
>  	hdmi_writeb(hdmi, 0xff, HDMI_I2CM_INT);
>  	hdmi_writeb(hdmi, 0xff, HDMI_I2CM_CTLINT);
>  
> @@ -2223,6 +2224,29 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi)
>  	return -ENODEV;
>  }
>  
> +static void dw_hdmi_cec_enable(struct dw_hdmi *hdmi)
> +{
> +	mutex_lock(&hdmi->mutex);
> +	hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CECCLK_DISABLE;
> +	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
> +	mutex_unlock(&hdmi->mutex);
> +}
> +
> +static void dw_hdmi_cec_disable(struct dw_hdmi *hdmi)
> +{
> +	mutex_lock(&hdmi->mutex);
> +	hdmi->mc_clkdis |= HDMI_MC_CLKDIS_CECCLK_DISABLE;
> +	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
> +	mutex_unlock(&hdmi->mutex);
> +}
> +
> +static const struct dw_hdmi_cec_ops dw_hdmi_cec_ops = {
> +	.write = hdmi_writeb,
> +	.read = hdmi_readb,
> +	.enable = dw_hdmi_cec_enable,
> +	.disable = dw_hdmi_cec_disable,
> +};
> +
>  static const struct regmap_config hdmi_regmap_8bit_config = {
>  	.reg_bits	= 32,
>  	.val_bits	= 8,
> @@ -2245,6 +2269,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  	struct device_node *np = dev->of_node;
>  	struct platform_device_info pdevinfo;
>  	struct device_node *ddc_node;
> +	struct dw_hdmi_cec_data cec;
>  	struct dw_hdmi *hdmi;
>  	struct resource *iores = NULL;
>  	int irq;
> @@ -2445,6 +2470,17 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  		hdmi->audio = platform_device_register_full(&pdevinfo);
>  	}
>  
> +	cec.hdmi = hdmi;
> +	cec.ops = &dw_hdmi_cec_ops;
> +	cec.irq = irq;
> +
> +	pdevinfo.name = "dw-hdmi-cec";
> +	pdevinfo.data = &cec;
> +	pdevinfo.size_data = sizeof(cec);
> +	pdevinfo.dma_mask = 0;
> +
> +	hdmi->cec = platform_device_register_full(&pdevinfo);

Maybe you should check the config bit before enabling CEC :

 /* CONFIG0_ID field values */
 +	HDMI_CONFIG0_CEC = 0x2,

if (config0 & HDMI_CONFIG0_CEC) {
}

> +
>  	/* Reset HDMI DDC I2C master controller and mute I2CM interrupts */
>  	if (hdmi->i2c)
>  		dw_hdmi_i2c_init(hdmi);
> @@ -2475,6 +2511,8 @@ static void __dw_hdmi_remove(struct dw_hdmi *hdmi)
>  {
>  	if (hdmi->audio && !IS_ERR(hdmi->audio))
>  		platform_device_unregister(hdmi->audio);
> +	if (!IS_ERR(hdmi->cec))
> +		platform_device_unregister(hdmi->cec);
>  
>  	/* Disable all interrupts */
>  	hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
> 

Apart from that and the s/Synopsis/Synopsys/ typos:

Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>

Neil
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver
  2017-06-01  0:53     ` Jose Abreu
@ 2017-06-01 22:30       ` Russell King - ARM Linux
  -1 siblings, 0 replies; 84+ messages in thread
From: Russell King - ARM Linux @ 2017-06-01 22:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jun 01, 2017 at 01:53:21AM +0100, Jose Abreu wrote:
> Hi Russell,
> 
> 
> On 30-05-2017 15:23, Russell King wrote:
> > +static int dw_hdmi_cec_transmit(struct cec_adapter *adap, u8 attempts,
> > +				u32 signal_free_time, struct cec_msg *msg)
> > +{
> > +	struct dw_hdmi_cec *cec = adap->priv;
> > +	unsigned i;
> > +
> > +	cec->retries = attempts;
> 
> I think you should check first if CEC engine is in normal
> operation mode, as a safety measure.

I'm not sure what you mean there, because the iMX6 manuals don't mention
anything about that.  The only "modes" it talks about is initiator mode
and follower mode.  Moreover, there's nothing in what was FSL's driver
that hints at that either.

Maybe you could provide some further technical information on this
point?

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver
@ 2017-06-01 22:30       ` Russell King - ARM Linux
  0 siblings, 0 replies; 84+ messages in thread
From: Russell King - ARM Linux @ 2017-06-01 22:30 UTC (permalink / raw)
  To: Jose Abreu; +Cc: Hans Verkuil, linux-arm-kernel, dri-devel

On Thu, Jun 01, 2017 at 01:53:21AM +0100, Jose Abreu wrote:
> Hi Russell,
> 
> 
> On 30-05-2017 15:23, Russell King wrote:
> > +static int dw_hdmi_cec_transmit(struct cec_adapter *adap, u8 attempts,
> > +				u32 signal_free_time, struct cec_msg *msg)
> > +{
> > +	struct dw_hdmi_cec *cec = adap->priv;
> > +	unsigned i;
> > +
> > +	cec->retries = attempts;
> 
> I think you should check first if CEC engine is in normal
> operation mode, as a safety measure.

I'm not sure what you mean there, because the iMX6 manuals don't mention
anything about that.  The only "modes" it talks about is initiator mode
and follower mode.  Moreover, there's nothing in what was FSL's driver
that hints at that either.

Maybe you could provide some further technical information on this
point?

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver
  2017-06-01 22:30       ` Russell King - ARM Linux
@ 2017-06-02  5:02         ` Jose Abreu
  -1 siblings, 0 replies; 84+ messages in thread
From: Jose Abreu @ 2017-06-02  5:02 UTC (permalink / raw)
  To: linux-arm-kernel



On 01-06-2017 23:30, Russell King - ARM Linux wrote:
> On Thu, Jun 01, 2017 at 01:53:21AM +0100, Jose Abreu wrote:
>> Hi Russell,
>>
>>
>> On 30-05-2017 15:23, Russell King wrote:
>>> +static int dw_hdmi_cec_transmit(struct cec_adapter *adap, u8 attempts,
>>> +				u32 signal_free_time, struct cec_msg *msg)
>>> +{
>>> +	struct dw_hdmi_cec *cec = adap->priv;
>>> +	unsigned i;
>>> +
>>> +	cec->retries = attempts;
>> I think you should check first if CEC engine is in normal
>> operation mode, as a safety measure.
> I'm not sure what you mean there, because the iMX6 manuals don't mention
> anything about that.  The only "modes" it talks about is initiator mode
> and follower mode.  Moreover, there's nothing in what was FSL's driver
> that hints at that either.
>
> Maybe you could provide some further technical information on this
> point?
>

You should check that CEC is: not in standy, acknowledges
broadcast messages, signal free time is 5bit period, and not lost
arbitration, which basically means CEC_CTRL must be 0x2 and
IH_CEC_STAT0 must not have ARB_LOST set. I do know you set 0x3 at
the end of this function but according to all the docs I have you
must first set 0x2 before writing message.

Best regards,
Jose Miguel Abreu

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver
@ 2017-06-02  5:02         ` Jose Abreu
  0 siblings, 0 replies; 84+ messages in thread
From: Jose Abreu @ 2017-06-02  5:02 UTC (permalink / raw)
  To: Russell King - ARM Linux, Jose Abreu
  Cc: Hans Verkuil, linux-arm-kernel, dri-devel



On 01-06-2017 23:30, Russell King - ARM Linux wrote:
> On Thu, Jun 01, 2017 at 01:53:21AM +0100, Jose Abreu wrote:
>> Hi Russell,
>>
>>
>> On 30-05-2017 15:23, Russell King wrote:
>>> +static int dw_hdmi_cec_transmit(struct cec_adapter *adap, u8 attempts,
>>> +				u32 signal_free_time, struct cec_msg *msg)
>>> +{
>>> +	struct dw_hdmi_cec *cec = adap->priv;
>>> +	unsigned i;
>>> +
>>> +	cec->retries = attempts;
>> I think you should check first if CEC engine is in normal
>> operation mode, as a safety measure.
> I'm not sure what you mean there, because the iMX6 manuals don't mention
> anything about that.  The only "modes" it talks about is initiator mode
> and follower mode.  Moreover, there's nothing in what was FSL's driver
> that hints at that either.
>
> Maybe you could provide some further technical information on this
> point?
>

You should check that CEC is: not in standy, acknowledges
broadcast messages, signal free time is 5bit period, and not lost
arbitration, which basically means CEC_CTRL must be 0x2 and
IH_CEC_STAT0 must not have ARB_LOST set. I do know you set 0x3 at
the end of this function but according to all the docs I have you
must first set 0x2 before writing message.

Best regards,
Jose Miguel Abreu

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver
  2017-06-01 13:47     ` Neil Armstrong
@ 2017-06-02  6:31       ` Hans Verkuil
  -1 siblings, 0 replies; 84+ messages in thread
From: Hans Verkuil @ 2017-06-02  6:31 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/01/2017 03:47 PM, Neil Armstrong wrote:
> On 05/30/2017 04:23 PM, Russell King wrote:
>> Add a CEC driver for the dw-hdmi hardware.
>>
>> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
>> ---
>>   drivers/gpu/drm/bridge/synopsys/Kconfig       |   8 +
>>   drivers/gpu/drm/bridge/synopsys/Makefile      |   1 +
>>   drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 320 ++++++++++++++++++++++++++
>>   drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h |  19 ++
>>   drivers/gpu/drm/bridge/synopsys/dw-hdmi.c     |  40 +++-
>>   5 files changed, 387 insertions(+), 1 deletion(-)
>>   create mode 100644 drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
>>   create mode 100644 drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
>>
>> diff --git a/drivers/gpu/drm/bridge/synopsys/Kconfig b/drivers/gpu/drm/bridge/synopsys/Kconfig
>> index 40d2827a6d19..bd30a0a07272 100644
>> --- a/drivers/gpu/drm/bridge/synopsys/Kconfig
>> +++ b/drivers/gpu/drm/bridge/synopsys/Kconfig
>> @@ -21,3 +21,11 @@ config DRM_DW_HDMI_I2S_AUDIO
>>   	help
>>   	  Support the I2S Audio interface which is part of the Synopsys
>>   	  Designware HDMI block.
>> +
>> +config DRM_DW_HDMI_CEC
>> +	tristate "Synopsis Designware CEC interface"
>> +	depends on DRM_DW_HDMI && MEDIA_CEC_SUPPORT
>> +	select MEDIA_CEC_NOTIFIER
>> +	help
>> +	  Support the CE interface which is part of the Synopsis
>> +	  Designware HDMI block.
>> diff --git a/drivers/gpu/drm/bridge/synopsys/Makefile b/drivers/gpu/drm/bridge/synopsys/Makefile
>> index 17aa7a65b57e..6fe415903668 100644
>> --- a/drivers/gpu/drm/bridge/synopsys/Makefile
>> +++ b/drivers/gpu/drm/bridge/synopsys/Makefile
>> @@ -3,3 +3,4 @@
>>   obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
>>   obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
>>   obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o
>> +obj-$(CONFIG_DRM_DW_HDMI_CEC) += dw-hdmi-cec.o
>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
>> new file mode 100644
>> index 000000000000..761ef5ae687d
>> --- /dev/null
>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
>> @@ -0,0 +1,320 @@
>> +/*
>> + * Designware HDMI CEC driver
>> + *
>> + * Copyright (C) 2015-2017 Russell King.
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +#include <linux/interrupt.h>
>> +#include <linux/io.h>
>> +#include <linux/module.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/sched.h>
>> +#include <linux/slab.h>
>> +
>> +#include <drm/drm_edid.h>
>> +
>> +#include <media/cec.h>
>> +#include <media/cec-notifier.h>
>> +
>> +#include "dw-hdmi-cec.h"
>> +
>> +enum {
>> +	HDMI_IH_CEC_STAT0	= 0x0106,
>> +	HDMI_IH_MUTE_CEC_STAT0	= 0x0186,
>> +
>> +	HDMI_CEC_CTRL		= 0x7d00,
>> +	CEC_CTRL_START		= BIT(0),
>> +	CEC_CTRL_NORMAL		= 1 << 1,
>> +
>> +	HDMI_CEC_STAT		= 0x7d01,
>> +	CEC_STAT_DONE		= BIT(0),
>> +	CEC_STAT_EOM		= BIT(1),
>> +	CEC_STAT_NACK		= BIT(2),
>> +	CEC_STAT_ARBLOST	= BIT(3),
>> +	CEC_STAT_ERROR_INIT	= BIT(4),
>> +	CEC_STAT_ERROR_FOLL	= BIT(5),
>> +	CEC_STAT_WAKEUP		= BIT(6),

I hadn't realized until Jose Abreu's latest reply, but you need to check the
ARBLOST status and set the TX state to CEC_TX_STATUS_ARB_LOST.

I think CEC_STAT_ERROR_FOLL might equal CEC_TX_STATUS_LOW_DRIVE, but without
documentation I can't be sure.

My experience is that this low drive condition tends to be poorly reported by
hardware. Either that or poorly documented. This is why I added a
CEC_TX_STATUS_ERROR status as a catch-all error status when it is unclear from
the hardware/documentation what error occurred.

Jose, do you know which status bit is used to report a follower pulling the
CEC line low for a long time (approx. 3.6 ms) to signal a CEC error?

Regards,

	Hans

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver
@ 2017-06-02  6:31       ` Hans Verkuil
  0 siblings, 0 replies; 84+ messages in thread
From: Hans Verkuil @ 2017-06-02  6:31 UTC (permalink / raw)
  To: Neil Armstrong, Russell King; +Cc: Jose Abreu, dri-devel, linux-arm-kernel

On 06/01/2017 03:47 PM, Neil Armstrong wrote:
> On 05/30/2017 04:23 PM, Russell King wrote:
>> Add a CEC driver for the dw-hdmi hardware.
>>
>> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
>> ---
>>   drivers/gpu/drm/bridge/synopsys/Kconfig       |   8 +
>>   drivers/gpu/drm/bridge/synopsys/Makefile      |   1 +
>>   drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 320 ++++++++++++++++++++++++++
>>   drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h |  19 ++
>>   drivers/gpu/drm/bridge/synopsys/dw-hdmi.c     |  40 +++-
>>   5 files changed, 387 insertions(+), 1 deletion(-)
>>   create mode 100644 drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
>>   create mode 100644 drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
>>
>> diff --git a/drivers/gpu/drm/bridge/synopsys/Kconfig b/drivers/gpu/drm/bridge/synopsys/Kconfig
>> index 40d2827a6d19..bd30a0a07272 100644
>> --- a/drivers/gpu/drm/bridge/synopsys/Kconfig
>> +++ b/drivers/gpu/drm/bridge/synopsys/Kconfig
>> @@ -21,3 +21,11 @@ config DRM_DW_HDMI_I2S_AUDIO
>>   	help
>>   	  Support the I2S Audio interface which is part of the Synopsys
>>   	  Designware HDMI block.
>> +
>> +config DRM_DW_HDMI_CEC
>> +	tristate "Synopsis Designware CEC interface"
>> +	depends on DRM_DW_HDMI && MEDIA_CEC_SUPPORT
>> +	select MEDIA_CEC_NOTIFIER
>> +	help
>> +	  Support the CE interface which is part of the Synopsis
>> +	  Designware HDMI block.
>> diff --git a/drivers/gpu/drm/bridge/synopsys/Makefile b/drivers/gpu/drm/bridge/synopsys/Makefile
>> index 17aa7a65b57e..6fe415903668 100644
>> --- a/drivers/gpu/drm/bridge/synopsys/Makefile
>> +++ b/drivers/gpu/drm/bridge/synopsys/Makefile
>> @@ -3,3 +3,4 @@
>>   obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
>>   obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
>>   obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o
>> +obj-$(CONFIG_DRM_DW_HDMI_CEC) += dw-hdmi-cec.o
>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
>> new file mode 100644
>> index 000000000000..761ef5ae687d
>> --- /dev/null
>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
>> @@ -0,0 +1,320 @@
>> +/*
>> + * Designware HDMI CEC driver
>> + *
>> + * Copyright (C) 2015-2017 Russell King.
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +#include <linux/interrupt.h>
>> +#include <linux/io.h>
>> +#include <linux/module.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/sched.h>
>> +#include <linux/slab.h>
>> +
>> +#include <drm/drm_edid.h>
>> +
>> +#include <media/cec.h>
>> +#include <media/cec-notifier.h>
>> +
>> +#include "dw-hdmi-cec.h"
>> +
>> +enum {
>> +	HDMI_IH_CEC_STAT0	= 0x0106,
>> +	HDMI_IH_MUTE_CEC_STAT0	= 0x0186,
>> +
>> +	HDMI_CEC_CTRL		= 0x7d00,
>> +	CEC_CTRL_START		= BIT(0),
>> +	CEC_CTRL_NORMAL		= 1 << 1,
>> +
>> +	HDMI_CEC_STAT		= 0x7d01,
>> +	CEC_STAT_DONE		= BIT(0),
>> +	CEC_STAT_EOM		= BIT(1),
>> +	CEC_STAT_NACK		= BIT(2),
>> +	CEC_STAT_ARBLOST	= BIT(3),
>> +	CEC_STAT_ERROR_INIT	= BIT(4),
>> +	CEC_STAT_ERROR_FOLL	= BIT(5),
>> +	CEC_STAT_WAKEUP		= BIT(6),

I hadn't realized until Jose Abreu's latest reply, but you need to check the
ARBLOST status and set the TX state to CEC_TX_STATUS_ARB_LOST.

I think CEC_STAT_ERROR_FOLL might equal CEC_TX_STATUS_LOW_DRIVE, but without
documentation I can't be sure.

My experience is that this low drive condition tends to be poorly reported by
hardware. Either that or poorly documented. This is why I added a
CEC_TX_STATUS_ERROR status as a catch-all error status when it is unclear from
the hardware/documentation what error occurred.

Jose, do you know which status bit is used to report a follower pulling the
CEC line low for a long time (approx. 3.6 ms) to signal a CEC error?

Regards,

	Hans

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver
  2017-06-02  6:31       ` Hans Verkuil
@ 2017-06-02  6:43         ` Jose Abreu
  -1 siblings, 0 replies; 84+ messages in thread
From: Jose Abreu @ 2017-06-02  6:43 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Hans,


On 02-06-2017 07:31, Hans Verkuil wrote:
> On 06/01/2017 03:47 PM, Neil Armstrong wrote:
>> On 05/30/2017 04:23 PM, Russell King wrote:
>>> Add a CEC driver for the dw-hdmi hardware.
>>>
>>> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
>>> ---
>>>   drivers/gpu/drm/bridge/synopsys/Kconfig       |   8 +
>>>   drivers/gpu/drm/bridge/synopsys/Makefile      |   1 +
>>>   drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 320
>>> ++++++++++++++++++++++++++
>>>   drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h |  19 ++
>>>   drivers/gpu/drm/bridge/synopsys/dw-hdmi.c     |  40 +++-
>>>   5 files changed, 387 insertions(+), 1 deletion(-)
>>>   create mode 100644
>>> drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
>>>   create mode 100644
>>> drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
>>>
>>> diff --git a/drivers/gpu/drm/bridge/synopsys/Kconfig
>>> b/drivers/gpu/drm/bridge/synopsys/Kconfig
>>> index 40d2827a6d19..bd30a0a07272 100644
>>> --- a/drivers/gpu/drm/bridge/synopsys/Kconfig
>>> +++ b/drivers/gpu/drm/bridge/synopsys/Kconfig
>>> @@ -21,3 +21,11 @@ config DRM_DW_HDMI_I2S_AUDIO
>>>       help
>>>         Support the I2S Audio interface which is part of the
>>> Synopsys
>>>         Designware HDMI block.
>>> +
>>> +config DRM_DW_HDMI_CEC
>>> +    tristate "Synopsis Designware CEC interface"
>>> +    depends on DRM_DW_HDMI && MEDIA_CEC_SUPPORT
>>> +    select MEDIA_CEC_NOTIFIER
>>> +    help
>>> +      Support the CE interface which is part of the Synopsis
>>> +      Designware HDMI block.
>>> diff --git a/drivers/gpu/drm/bridge/synopsys/Makefile
>>> b/drivers/gpu/drm/bridge/synopsys/Makefile
>>> index 17aa7a65b57e..6fe415903668 100644
>>> --- a/drivers/gpu/drm/bridge/synopsys/Makefile
>>> +++ b/drivers/gpu/drm/bridge/synopsys/Makefile
>>> @@ -3,3 +3,4 @@
>>>   obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
>>>   obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
>>>   obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o
>>> +obj-$(CONFIG_DRM_DW_HDMI_CEC) += dw-hdmi-cec.o
>>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
>>> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
>>> new file mode 100644
>>> index 000000000000..761ef5ae687d
>>> --- /dev/null
>>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
>>> @@ -0,0 +1,320 @@
>>> +/*
>>> + * Designware HDMI CEC driver
>>> + *
>>> + * Copyright (C) 2015-2017 Russell King.
>>> + *
>>> + * This program is free software; you can redistribute it
>>> and/or modify
>>> + * it under the terms of the GNU General Public License
>>> version 2 as
>>> + * published by the Free Software Foundation.
>>> + */
>>> +#include <linux/interrupt.h>
>>> +#include <linux/io.h>
>>> +#include <linux/module.h>
>>> +#include <linux/platform_device.h>
>>> +#include <linux/sched.h>
>>> +#include <linux/slab.h>
>>> +
>>> +#include <drm/drm_edid.h>
>>> +
>>> +#include <media/cec.h>
>>> +#include <media/cec-notifier.h>
>>> +
>>> +#include "dw-hdmi-cec.h"
>>> +
>>> +enum {
>>> +    HDMI_IH_CEC_STAT0    = 0x0106,
>>> +    HDMI_IH_MUTE_CEC_STAT0    = 0x0186,
>>> +
>>> +    HDMI_CEC_CTRL        = 0x7d00,
>>> +    CEC_CTRL_START        = BIT(0),
>>> +    CEC_CTRL_NORMAL        = 1 << 1,
>>> +
>>> +    HDMI_CEC_STAT        = 0x7d01,
>>> +    CEC_STAT_DONE        = BIT(0),
>>> +    CEC_STAT_EOM        = BIT(1),
>>> +    CEC_STAT_NACK        = BIT(2),
>>> +    CEC_STAT_ARBLOST    = BIT(3),
>>> +    CEC_STAT_ERROR_INIT    = BIT(4),
>>> +    CEC_STAT_ERROR_FOLL    = BIT(5),
>>> +    CEC_STAT_WAKEUP        = BIT(6),
>
> I hadn't realized until Jose Abreu's latest reply, but you need
> to check the
> ARBLOST status and set the TX state to CEC_TX_STATUS_ARB_LOST.
>
> I think CEC_STAT_ERROR_FOLL might equal
> CEC_TX_STATUS_LOW_DRIVE, but without
> documentation I can't be sure.
>
> My experience is that this low drive condition tends to be
> poorly reported by
> hardware. Either that or poorly documented. This is why I added a
> CEC_TX_STATUS_ERROR status as a catch-all error status when it
> is unclear from
> the hardware/documentation what error occurred.
>
> Jose, do you know which status bit is used to report a follower
> pulling the
> CEC line low for a long time (approx. 3.6 ms) to signal a CEC
> error?

Bit 5 for follower error, bit 4 for initiator error.

Best regards,
Jose Miguel Abreu

>
> Regards,
>
>     Hans

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver
@ 2017-06-02  6:43         ` Jose Abreu
  0 siblings, 0 replies; 84+ messages in thread
From: Jose Abreu @ 2017-06-02  6:43 UTC (permalink / raw)
  To: Hans Verkuil, Neil Armstrong, Russell King
  Cc: Jose Abreu, dri-devel, linux-arm-kernel

Hi Hans,


On 02-06-2017 07:31, Hans Verkuil wrote:
> On 06/01/2017 03:47 PM, Neil Armstrong wrote:
>> On 05/30/2017 04:23 PM, Russell King wrote:
>>> Add a CEC driver for the dw-hdmi hardware.
>>>
>>> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
>>> ---
>>>   drivers/gpu/drm/bridge/synopsys/Kconfig       |   8 +
>>>   drivers/gpu/drm/bridge/synopsys/Makefile      |   1 +
>>>   drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 320
>>> ++++++++++++++++++++++++++
>>>   drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h |  19 ++
>>>   drivers/gpu/drm/bridge/synopsys/dw-hdmi.c     |  40 +++-
>>>   5 files changed, 387 insertions(+), 1 deletion(-)
>>>   create mode 100644
>>> drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
>>>   create mode 100644
>>> drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
>>>
>>> diff --git a/drivers/gpu/drm/bridge/synopsys/Kconfig
>>> b/drivers/gpu/drm/bridge/synopsys/Kconfig
>>> index 40d2827a6d19..bd30a0a07272 100644
>>> --- a/drivers/gpu/drm/bridge/synopsys/Kconfig
>>> +++ b/drivers/gpu/drm/bridge/synopsys/Kconfig
>>> @@ -21,3 +21,11 @@ config DRM_DW_HDMI_I2S_AUDIO
>>>       help
>>>         Support the I2S Audio interface which is part of the
>>> Synopsys
>>>         Designware HDMI block.
>>> +
>>> +config DRM_DW_HDMI_CEC
>>> +    tristate "Synopsis Designware CEC interface"
>>> +    depends on DRM_DW_HDMI && MEDIA_CEC_SUPPORT
>>> +    select MEDIA_CEC_NOTIFIER
>>> +    help
>>> +      Support the CE interface which is part of the Synopsis
>>> +      Designware HDMI block.
>>> diff --git a/drivers/gpu/drm/bridge/synopsys/Makefile
>>> b/drivers/gpu/drm/bridge/synopsys/Makefile
>>> index 17aa7a65b57e..6fe415903668 100644
>>> --- a/drivers/gpu/drm/bridge/synopsys/Makefile
>>> +++ b/drivers/gpu/drm/bridge/synopsys/Makefile
>>> @@ -3,3 +3,4 @@
>>>   obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
>>>   obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
>>>   obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o
>>> +obj-$(CONFIG_DRM_DW_HDMI_CEC) += dw-hdmi-cec.o
>>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
>>> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
>>> new file mode 100644
>>> index 000000000000..761ef5ae687d
>>> --- /dev/null
>>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
>>> @@ -0,0 +1,320 @@
>>> +/*
>>> + * Designware HDMI CEC driver
>>> + *
>>> + * Copyright (C) 2015-2017 Russell King.
>>> + *
>>> + * This program is free software; you can redistribute it
>>> and/or modify
>>> + * it under the terms of the GNU General Public License
>>> version 2 as
>>> + * published by the Free Software Foundation.
>>> + */
>>> +#include <linux/interrupt.h>
>>> +#include <linux/io.h>
>>> +#include <linux/module.h>
>>> +#include <linux/platform_device.h>
>>> +#include <linux/sched.h>
>>> +#include <linux/slab.h>
>>> +
>>> +#include <drm/drm_edid.h>
>>> +
>>> +#include <media/cec.h>
>>> +#include <media/cec-notifier.h>
>>> +
>>> +#include "dw-hdmi-cec.h"
>>> +
>>> +enum {
>>> +    HDMI_IH_CEC_STAT0    = 0x0106,
>>> +    HDMI_IH_MUTE_CEC_STAT0    = 0x0186,
>>> +
>>> +    HDMI_CEC_CTRL        = 0x7d00,
>>> +    CEC_CTRL_START        = BIT(0),
>>> +    CEC_CTRL_NORMAL        = 1 << 1,
>>> +
>>> +    HDMI_CEC_STAT        = 0x7d01,
>>> +    CEC_STAT_DONE        = BIT(0),
>>> +    CEC_STAT_EOM        = BIT(1),
>>> +    CEC_STAT_NACK        = BIT(2),
>>> +    CEC_STAT_ARBLOST    = BIT(3),
>>> +    CEC_STAT_ERROR_INIT    = BIT(4),
>>> +    CEC_STAT_ERROR_FOLL    = BIT(5),
>>> +    CEC_STAT_WAKEUP        = BIT(6),
>
> I hadn't realized until Jose Abreu's latest reply, but you need
> to check the
> ARBLOST status and set the TX state to CEC_TX_STATUS_ARB_LOST.
>
> I think CEC_STAT_ERROR_FOLL might equal
> CEC_TX_STATUS_LOW_DRIVE, but without
> documentation I can't be sure.
>
> My experience is that this low drive condition tends to be
> poorly reported by
> hardware. Either that or poorly documented. This is why I added a
> CEC_TX_STATUS_ERROR status as a catch-all error status when it
> is unclear from
> the hardware/documentation what error occurred.
>
> Jose, do you know which status bit is used to report a follower
> pulling the
> CEC line low for a long time (approx. 3.6 ms) to signal a CEC
> error?

Bit 5 for follower error, bit 4 for initiator error.

Best regards,
Jose Miguel Abreu

>
> Regards,
>
>     Hans

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver
  2017-06-02  6:43         ` Jose Abreu
@ 2017-06-02  9:06           ` Hans Verkuil
  -1 siblings, 0 replies; 84+ messages in thread
From: Hans Verkuil @ 2017-06-02  9:06 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/02/17 08:43, Jose Abreu wrote:
> Hi Hans,
> 
> 
> On 02-06-2017 07:31, Hans Verkuil wrote:
>> On 06/01/2017 03:47 PM, Neil Armstrong wrote:
>>> On 05/30/2017 04:23 PM, Russell King wrote:
>>>> Add a CEC driver for the dw-hdmi hardware.
>>>>
>>>> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
>>>> ---
>>>>   drivers/gpu/drm/bridge/synopsys/Kconfig       |   8 +
>>>>   drivers/gpu/drm/bridge/synopsys/Makefile      |   1 +
>>>>   drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 320
>>>> ++++++++++++++++++++++++++
>>>>   drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h |  19 ++
>>>>   drivers/gpu/drm/bridge/synopsys/dw-hdmi.c     |  40 +++-
>>>>   5 files changed, 387 insertions(+), 1 deletion(-)
>>>>   create mode 100644
>>>> drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
>>>>   create mode 100644
>>>> drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
>>>>
>>>> diff --git a/drivers/gpu/drm/bridge/synopsys/Kconfig
>>>> b/drivers/gpu/drm/bridge/synopsys/Kconfig
>>>> index 40d2827a6d19..bd30a0a07272 100644
>>>> --- a/drivers/gpu/drm/bridge/synopsys/Kconfig
>>>> +++ b/drivers/gpu/drm/bridge/synopsys/Kconfig
>>>> @@ -21,3 +21,11 @@ config DRM_DW_HDMI_I2S_AUDIO
>>>>       help
>>>>         Support the I2S Audio interface which is part of the
>>>> Synopsys
>>>>         Designware HDMI block.
>>>> +
>>>> +config DRM_DW_HDMI_CEC
>>>> +    tristate "Synopsis Designware CEC interface"
>>>> +    depends on DRM_DW_HDMI && MEDIA_CEC_SUPPORT
>>>> +    select MEDIA_CEC_NOTIFIER
>>>> +    help
>>>> +      Support the CE interface which is part of the Synopsis
>>>> +      Designware HDMI block.
>>>> diff --git a/drivers/gpu/drm/bridge/synopsys/Makefile
>>>> b/drivers/gpu/drm/bridge/synopsys/Makefile
>>>> index 17aa7a65b57e..6fe415903668 100644
>>>> --- a/drivers/gpu/drm/bridge/synopsys/Makefile
>>>> +++ b/drivers/gpu/drm/bridge/synopsys/Makefile
>>>> @@ -3,3 +3,4 @@
>>>>   obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
>>>>   obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
>>>>   obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o
>>>> +obj-$(CONFIG_DRM_DW_HDMI_CEC) += dw-hdmi-cec.o
>>>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
>>>> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
>>>> new file mode 100644
>>>> index 000000000000..761ef5ae687d
>>>> --- /dev/null
>>>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
>>>> @@ -0,0 +1,320 @@
>>>> +/*
>>>> + * Designware HDMI CEC driver
>>>> + *
>>>> + * Copyright (C) 2015-2017 Russell King.
>>>> + *
>>>> + * This program is free software; you can redistribute it
>>>> and/or modify
>>>> + * it under the terms of the GNU General Public License
>>>> version 2 as
>>>> + * published by the Free Software Foundation.
>>>> + */
>>>> +#include <linux/interrupt.h>
>>>> +#include <linux/io.h>
>>>> +#include <linux/module.h>
>>>> +#include <linux/platform_device.h>
>>>> +#include <linux/sched.h>
>>>> +#include <linux/slab.h>
>>>> +
>>>> +#include <drm/drm_edid.h>
>>>> +
>>>> +#include <media/cec.h>
>>>> +#include <media/cec-notifier.h>
>>>> +
>>>> +#include "dw-hdmi-cec.h"
>>>> +
>>>> +enum {
>>>> +    HDMI_IH_CEC_STAT0    = 0x0106,
>>>> +    HDMI_IH_MUTE_CEC_STAT0    = 0x0186,
>>>> +
>>>> +    HDMI_CEC_CTRL        = 0x7d00,
>>>> +    CEC_CTRL_START        = BIT(0),
>>>> +    CEC_CTRL_NORMAL        = 1 << 1,
>>>> +
>>>> +    HDMI_CEC_STAT        = 0x7d01,
>>>> +    CEC_STAT_DONE        = BIT(0),
>>>> +    CEC_STAT_EOM        = BIT(1),
>>>> +    CEC_STAT_NACK        = BIT(2),
>>>> +    CEC_STAT_ARBLOST    = BIT(3),
>>>> +    CEC_STAT_ERROR_INIT    = BIT(4),
>>>> +    CEC_STAT_ERROR_FOLL    = BIT(5),
>>>> +    CEC_STAT_WAKEUP        = BIT(6),
>>
>> I hadn't realized until Jose Abreu's latest reply, but you need
>> to check the
>> ARBLOST status and set the TX state to CEC_TX_STATUS_ARB_LOST.
>>
>> I think CEC_STAT_ERROR_FOLL might equal
>> CEC_TX_STATUS_LOW_DRIVE, but without
>> documentation I can't be sure.
>>
>> My experience is that this low drive condition tends to be
>> poorly reported by
>> hardware. Either that or poorly documented. This is why I added a
>> CEC_TX_STATUS_ERROR status as a catch-all error status when it
>> is unclear from
>> the hardware/documentation what error occurred.
>>
>> Jose, do you know which status bit is used to report a follower
>> pulling the
>> CEC line low for a long time (approx. 3.6 ms) to signal a CEC
>> error?
> 
> Bit 5 for follower error, bit 4 for initiator error.

I gathered that from the define names :-)

But what does it mean? What sort of error is reported here?

I'm guessing here that "follower error" means that one of the remote
CEC devices forced a Low Drive condition, where "initiator error"
means that our adapter forced a Low Drive condition on the bus.

Would that be correct?

If so, then the CEC_STAT_ERROR_INIT can be ignored and ERROR_FOLL
maps to the LOW_DRIVE status.

(Low Drive condition is what is described in section CEC 7.4 "CEC Line
Error Handling" of the HDMI 1.4 Specification).

Regards,

	Hans

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver
@ 2017-06-02  9:06           ` Hans Verkuil
  0 siblings, 0 replies; 84+ messages in thread
From: Hans Verkuil @ 2017-06-02  9:06 UTC (permalink / raw)
  To: Jose Abreu, Neil Armstrong, Russell King; +Cc: linux-arm-kernel, dri-devel

On 06/02/17 08:43, Jose Abreu wrote:
> Hi Hans,
> 
> 
> On 02-06-2017 07:31, Hans Verkuil wrote:
>> On 06/01/2017 03:47 PM, Neil Armstrong wrote:
>>> On 05/30/2017 04:23 PM, Russell King wrote:
>>>> Add a CEC driver for the dw-hdmi hardware.
>>>>
>>>> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
>>>> ---
>>>>   drivers/gpu/drm/bridge/synopsys/Kconfig       |   8 +
>>>>   drivers/gpu/drm/bridge/synopsys/Makefile      |   1 +
>>>>   drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 320
>>>> ++++++++++++++++++++++++++
>>>>   drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h |  19 ++
>>>>   drivers/gpu/drm/bridge/synopsys/dw-hdmi.c     |  40 +++-
>>>>   5 files changed, 387 insertions(+), 1 deletion(-)
>>>>   create mode 100644
>>>> drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
>>>>   create mode 100644
>>>> drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
>>>>
>>>> diff --git a/drivers/gpu/drm/bridge/synopsys/Kconfig
>>>> b/drivers/gpu/drm/bridge/synopsys/Kconfig
>>>> index 40d2827a6d19..bd30a0a07272 100644
>>>> --- a/drivers/gpu/drm/bridge/synopsys/Kconfig
>>>> +++ b/drivers/gpu/drm/bridge/synopsys/Kconfig
>>>> @@ -21,3 +21,11 @@ config DRM_DW_HDMI_I2S_AUDIO
>>>>       help
>>>>         Support the I2S Audio interface which is part of the
>>>> Synopsys
>>>>         Designware HDMI block.
>>>> +
>>>> +config DRM_DW_HDMI_CEC
>>>> +    tristate "Synopsis Designware CEC interface"
>>>> +    depends on DRM_DW_HDMI && MEDIA_CEC_SUPPORT
>>>> +    select MEDIA_CEC_NOTIFIER
>>>> +    help
>>>> +      Support the CE interface which is part of the Synopsis
>>>> +      Designware HDMI block.
>>>> diff --git a/drivers/gpu/drm/bridge/synopsys/Makefile
>>>> b/drivers/gpu/drm/bridge/synopsys/Makefile
>>>> index 17aa7a65b57e..6fe415903668 100644
>>>> --- a/drivers/gpu/drm/bridge/synopsys/Makefile
>>>> +++ b/drivers/gpu/drm/bridge/synopsys/Makefile
>>>> @@ -3,3 +3,4 @@
>>>>   obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
>>>>   obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
>>>>   obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o
>>>> +obj-$(CONFIG_DRM_DW_HDMI_CEC) += dw-hdmi-cec.o
>>>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
>>>> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
>>>> new file mode 100644
>>>> index 000000000000..761ef5ae687d
>>>> --- /dev/null
>>>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
>>>> @@ -0,0 +1,320 @@
>>>> +/*
>>>> + * Designware HDMI CEC driver
>>>> + *
>>>> + * Copyright (C) 2015-2017 Russell King.
>>>> + *
>>>> + * This program is free software; you can redistribute it
>>>> and/or modify
>>>> + * it under the terms of the GNU General Public License
>>>> version 2 as
>>>> + * published by the Free Software Foundation.
>>>> + */
>>>> +#include <linux/interrupt.h>
>>>> +#include <linux/io.h>
>>>> +#include <linux/module.h>
>>>> +#include <linux/platform_device.h>
>>>> +#include <linux/sched.h>
>>>> +#include <linux/slab.h>
>>>> +
>>>> +#include <drm/drm_edid.h>
>>>> +
>>>> +#include <media/cec.h>
>>>> +#include <media/cec-notifier.h>
>>>> +
>>>> +#include "dw-hdmi-cec.h"
>>>> +
>>>> +enum {
>>>> +    HDMI_IH_CEC_STAT0    = 0x0106,
>>>> +    HDMI_IH_MUTE_CEC_STAT0    = 0x0186,
>>>> +
>>>> +    HDMI_CEC_CTRL        = 0x7d00,
>>>> +    CEC_CTRL_START        = BIT(0),
>>>> +    CEC_CTRL_NORMAL        = 1 << 1,
>>>> +
>>>> +    HDMI_CEC_STAT        = 0x7d01,
>>>> +    CEC_STAT_DONE        = BIT(0),
>>>> +    CEC_STAT_EOM        = BIT(1),
>>>> +    CEC_STAT_NACK        = BIT(2),
>>>> +    CEC_STAT_ARBLOST    = BIT(3),
>>>> +    CEC_STAT_ERROR_INIT    = BIT(4),
>>>> +    CEC_STAT_ERROR_FOLL    = BIT(5),
>>>> +    CEC_STAT_WAKEUP        = BIT(6),
>>
>> I hadn't realized until Jose Abreu's latest reply, but you need
>> to check the
>> ARBLOST status and set the TX state to CEC_TX_STATUS_ARB_LOST.
>>
>> I think CEC_STAT_ERROR_FOLL might equal
>> CEC_TX_STATUS_LOW_DRIVE, but without
>> documentation I can't be sure.
>>
>> My experience is that this low drive condition tends to be
>> poorly reported by
>> hardware. Either that or poorly documented. This is why I added a
>> CEC_TX_STATUS_ERROR status as a catch-all error status when it
>> is unclear from
>> the hardware/documentation what error occurred.
>>
>> Jose, do you know which status bit is used to report a follower
>> pulling the
>> CEC line low for a long time (approx. 3.6 ms) to signal a CEC
>> error?
> 
> Bit 5 for follower error, bit 4 for initiator error.

I gathered that from the define names :-)

But what does it mean? What sort of error is reported here?

I'm guessing here that "follower error" means that one of the remote
CEC devices forced a Low Drive condition, where "initiator error"
means that our adapter forced a Low Drive condition on the bus.

Would that be correct?

If so, then the CEC_STAT_ERROR_INIT can be ignored and ERROR_FOLL
maps to the LOW_DRIVE status.

(Low Drive condition is what is described in section CEC 7.4 "CEC Line
Error Handling" of the HDMI 1.4 Specification).

Regards,

	Hans
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver
  2017-06-02  5:02         ` Jose Abreu
@ 2017-06-02  9:15           ` Russell King - ARM Linux
  -1 siblings, 0 replies; 84+ messages in thread
From: Russell King - ARM Linux @ 2017-06-02  9:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jun 02, 2017 at 06:02:28AM +0100, Jose Abreu wrote:
> You should check that CEC is: not in standy, acknowledges
> broadcast messages, signal free time is 5bit period, and not lost
> arbitration, which basically means CEC_CTRL must be 0x2 and
> IH_CEC_STAT0 must not have ARB_LOST set.

If ARB_LOST is set, that will trigger an interrupt, and the interrupt
handler will clear the bit.  So all the time that the interrupt handler
is present, ARB_LOST should be clear whenever we try to send a message.

When we enable the CEC interface, we zero the CEC_CTRL register, which
takes the controller out of standby, and initialises the command
register.

Bits 2:1 select the signal free time, and there's no requirement
specified to require them to be set to '01' before writing the
message - in fact, it's legal for them to be set to other values,
particularly when retrying, which is something I've missed.

     2-1             Frame Type bit
  FRAME_TYP
                     00    Signal Free Time = 3-bit periods. Previous
			   attempt to send frame is unsuccessful.
                     01    Signal Free Time = 5-bit periods. New initiator
			   wants to send a frame.
                     10    Signal Free Time = 7-bit periods. Present
			   initiator wants to send another frame
			   immediately after its previous frame. (spec
			   CEC 9.1)
                     11    Illegal value. If software write this value,
			   hardware will set the value to the default 2'b01.

Clearly from that, there are times when we want to transmit a message
without a 5-bit signal free time period, particularly when we're
retrying or wanting to send another frame, so I don't believe that
there's a requirement for the control register to always be set to
0x02.  I suspect that where that value is coming from is an application
note describing how to send a brand new message each time, and not
covering the other cases.

It could be that we need to set the frame type before loading the
message - that I'll buy, but not that it must always be set to 0x02.

Provided that the standby and BC_NACK bits are both cleared should
be sufficient.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver
@ 2017-06-02  9:15           ` Russell King - ARM Linux
  0 siblings, 0 replies; 84+ messages in thread
From: Russell King - ARM Linux @ 2017-06-02  9:15 UTC (permalink / raw)
  To: Jose Abreu; +Cc: Hans Verkuil, linux-arm-kernel, dri-devel

On Fri, Jun 02, 2017 at 06:02:28AM +0100, Jose Abreu wrote:
> You should check that CEC is: not in standy, acknowledges
> broadcast messages, signal free time is 5bit period, and not lost
> arbitration, which basically means CEC_CTRL must be 0x2 and
> IH_CEC_STAT0 must not have ARB_LOST set.

If ARB_LOST is set, that will trigger an interrupt, and the interrupt
handler will clear the bit.  So all the time that the interrupt handler
is present, ARB_LOST should be clear whenever we try to send a message.

When we enable the CEC interface, we zero the CEC_CTRL register, which
takes the controller out of standby, and initialises the command
register.

Bits 2:1 select the signal free time, and there's no requirement
specified to require them to be set to '01' before writing the
message - in fact, it's legal for them to be set to other values,
particularly when retrying, which is something I've missed.

     2-1             Frame Type bit
  FRAME_TYP
                     00    Signal Free Time = 3-bit periods. Previous
			   attempt to send frame is unsuccessful.
                     01    Signal Free Time = 5-bit periods. New initiator
			   wants to send a frame.
                     10    Signal Free Time = 7-bit periods. Present
			   initiator wants to send another frame
			   immediately after its previous frame. (spec
			   CEC 9.1)
                     11    Illegal value. If software write this value,
			   hardware will set the value to the default 2'b01.

Clearly from that, there are times when we want to transmit a message
without a 5-bit signal free time period, particularly when we're
retrying or wanting to send another frame, so I don't believe that
there's a requirement for the control register to always be set to
0x02.  I suspect that where that value is coming from is an application
note describing how to send a brand new message each time, and not
covering the other cases.

It could be that we need to set the frame type before loading the
message - that I'll buy, but not that it must always be set to 0x02.

Provided that the standby and BC_NACK bits are both cleared should
be sufficient.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver
  2017-06-02  9:06           ` Hans Verkuil
@ 2017-06-02  9:18             ` Russell King - ARM Linux
  -1 siblings, 0 replies; 84+ messages in thread
From: Russell King - ARM Linux @ 2017-06-02  9:18 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jun 02, 2017 at 11:06:24AM +0200, Hans Verkuil wrote:
> On 06/02/17 08:43, Jose Abreu wrote:
> > Hi Hans,
> > 
> > 
> > On 02-06-2017 07:31, Hans Verkuil wrote:
> >> On 06/01/2017 03:47 PM, Neil Armstrong wrote:
> >>> On 05/30/2017 04:23 PM, Russell King wrote:
> >>>> Add a CEC driver for the dw-hdmi hardware.
> >>>>
> >>>> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> >>>> ---
> >>>>   drivers/gpu/drm/bridge/synopsys/Kconfig       |   8 +
> >>>>   drivers/gpu/drm/bridge/synopsys/Makefile      |   1 +
> >>>>   drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 320
> >>>> ++++++++++++++++++++++++++
> >>>>   drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h |  19 ++
> >>>>   drivers/gpu/drm/bridge/synopsys/dw-hdmi.c     |  40 +++-
> >>>>   5 files changed, 387 insertions(+), 1 deletion(-)
> >>>>   create mode 100644
> >>>> drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
> >>>>   create mode 100644
> >>>> drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
> >>>>
> >>>> diff --git a/drivers/gpu/drm/bridge/synopsys/Kconfig
> >>>> b/drivers/gpu/drm/bridge/synopsys/Kconfig
> >>>> index 40d2827a6d19..bd30a0a07272 100644
> >>>> --- a/drivers/gpu/drm/bridge/synopsys/Kconfig
> >>>> +++ b/drivers/gpu/drm/bridge/synopsys/Kconfig
> >>>> @@ -21,3 +21,11 @@ config DRM_DW_HDMI_I2S_AUDIO
> >>>>       help
> >>>>         Support the I2S Audio interface which is part of the
> >>>> Synopsys
> >>>>         Designware HDMI block.
> >>>> +
> >>>> +config DRM_DW_HDMI_CEC
> >>>> +    tristate "Synopsis Designware CEC interface"
> >>>> +    depends on DRM_DW_HDMI && MEDIA_CEC_SUPPORT
> >>>> +    select MEDIA_CEC_NOTIFIER
> >>>> +    help
> >>>> +      Support the CE interface which is part of the Synopsis
> >>>> +      Designware HDMI block.
> >>>> diff --git a/drivers/gpu/drm/bridge/synopsys/Makefile
> >>>> b/drivers/gpu/drm/bridge/synopsys/Makefile
> >>>> index 17aa7a65b57e..6fe415903668 100644
> >>>> --- a/drivers/gpu/drm/bridge/synopsys/Makefile
> >>>> +++ b/drivers/gpu/drm/bridge/synopsys/Makefile
> >>>> @@ -3,3 +3,4 @@
> >>>>   obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
> >>>>   obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
> >>>>   obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o
> >>>> +obj-$(CONFIG_DRM_DW_HDMI_CEC) += dw-hdmi-cec.o
> >>>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
> >>>> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
> >>>> new file mode 100644
> >>>> index 000000000000..761ef5ae687d
> >>>> --- /dev/null
> >>>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
> >>>> @@ -0,0 +1,320 @@
> >>>> +/*
> >>>> + * Designware HDMI CEC driver
> >>>> + *
> >>>> + * Copyright (C) 2015-2017 Russell King.
> >>>> + *
> >>>> + * This program is free software; you can redistribute it
> >>>> and/or modify
> >>>> + * it under the terms of the GNU General Public License
> >>>> version 2 as
> >>>> + * published by the Free Software Foundation.
> >>>> + */
> >>>> +#include <linux/interrupt.h>
> >>>> +#include <linux/io.h>
> >>>> +#include <linux/module.h>
> >>>> +#include <linux/platform_device.h>
> >>>> +#include <linux/sched.h>
> >>>> +#include <linux/slab.h>
> >>>> +
> >>>> +#include <drm/drm_edid.h>
> >>>> +
> >>>> +#include <media/cec.h>
> >>>> +#include <media/cec-notifier.h>
> >>>> +
> >>>> +#include "dw-hdmi-cec.h"
> >>>> +
> >>>> +enum {
> >>>> +    HDMI_IH_CEC_STAT0    = 0x0106,
> >>>> +    HDMI_IH_MUTE_CEC_STAT0    = 0x0186,
> >>>> +
> >>>> +    HDMI_CEC_CTRL        = 0x7d00,
> >>>> +    CEC_CTRL_START        = BIT(0),
> >>>> +    CEC_CTRL_NORMAL        = 1 << 1,
> >>>> +
> >>>> +    HDMI_CEC_STAT        = 0x7d01,
> >>>> +    CEC_STAT_DONE        = BIT(0),
> >>>> +    CEC_STAT_EOM        = BIT(1),
> >>>> +    CEC_STAT_NACK        = BIT(2),
> >>>> +    CEC_STAT_ARBLOST    = BIT(3),
> >>>> +    CEC_STAT_ERROR_INIT    = BIT(4),
> >>>> +    CEC_STAT_ERROR_FOLL    = BIT(5),
> >>>> +    CEC_STAT_WAKEUP        = BIT(6),
> >>
> >> I hadn't realized until Jose Abreu's latest reply, but you need
> >> to check the
> >> ARBLOST status and set the TX state to CEC_TX_STATUS_ARB_LOST.
> >>
> >> I think CEC_STAT_ERROR_FOLL might equal
> >> CEC_TX_STATUS_LOW_DRIVE, but without
> >> documentation I can't be sure.
> >>
> >> My experience is that this low drive condition tends to be
> >> poorly reported by
> >> hardware. Either that or poorly documented. This is why I added a
> >> CEC_TX_STATUS_ERROR status as a catch-all error status when it
> >> is unclear from
> >> the hardware/documentation what error occurred.
> >>
> >> Jose, do you know which status bit is used to report a follower
> >> pulling the
> >> CEC line low for a long time (approx. 3.6 ms) to signal a CEC
> >> error?
> > 
> > Bit 5 for follower error, bit 4 for initiator error.
> 
> I gathered that from the define names :-)
> 
> But what does it mean? What sort of error is reported here?

I think the problem is that no one really knows, the documentation is
quite poor:

     5       An error is notified by a follower. Abnormal logic data
 ERROR_FOLL  bit error (for follower).
     4       An error is detected on cec line (for initiator only).
 ERROR_INIT

It is so vague that you can read anything into that description.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver
@ 2017-06-02  9:18             ` Russell King - ARM Linux
  0 siblings, 0 replies; 84+ messages in thread
From: Russell King - ARM Linux @ 2017-06-02  9:18 UTC (permalink / raw)
  To: Hans Verkuil; +Cc: Jose Abreu, linux-arm-kernel, dri-devel, Neil Armstrong

On Fri, Jun 02, 2017 at 11:06:24AM +0200, Hans Verkuil wrote:
> On 06/02/17 08:43, Jose Abreu wrote:
> > Hi Hans,
> > 
> > 
> > On 02-06-2017 07:31, Hans Verkuil wrote:
> >> On 06/01/2017 03:47 PM, Neil Armstrong wrote:
> >>> On 05/30/2017 04:23 PM, Russell King wrote:
> >>>> Add a CEC driver for the dw-hdmi hardware.
> >>>>
> >>>> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> >>>> ---
> >>>>   drivers/gpu/drm/bridge/synopsys/Kconfig       |   8 +
> >>>>   drivers/gpu/drm/bridge/synopsys/Makefile      |   1 +
> >>>>   drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 320
> >>>> ++++++++++++++++++++++++++
> >>>>   drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h |  19 ++
> >>>>   drivers/gpu/drm/bridge/synopsys/dw-hdmi.c     |  40 +++-
> >>>>   5 files changed, 387 insertions(+), 1 deletion(-)
> >>>>   create mode 100644
> >>>> drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
> >>>>   create mode 100644
> >>>> drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
> >>>>
> >>>> diff --git a/drivers/gpu/drm/bridge/synopsys/Kconfig
> >>>> b/drivers/gpu/drm/bridge/synopsys/Kconfig
> >>>> index 40d2827a6d19..bd30a0a07272 100644
> >>>> --- a/drivers/gpu/drm/bridge/synopsys/Kconfig
> >>>> +++ b/drivers/gpu/drm/bridge/synopsys/Kconfig
> >>>> @@ -21,3 +21,11 @@ config DRM_DW_HDMI_I2S_AUDIO
> >>>>       help
> >>>>         Support the I2S Audio interface which is part of the
> >>>> Synopsys
> >>>>         Designware HDMI block.
> >>>> +
> >>>> +config DRM_DW_HDMI_CEC
> >>>> +    tristate "Synopsis Designware CEC interface"
> >>>> +    depends on DRM_DW_HDMI && MEDIA_CEC_SUPPORT
> >>>> +    select MEDIA_CEC_NOTIFIER
> >>>> +    help
> >>>> +      Support the CE interface which is part of the Synopsis
> >>>> +      Designware HDMI block.
> >>>> diff --git a/drivers/gpu/drm/bridge/synopsys/Makefile
> >>>> b/drivers/gpu/drm/bridge/synopsys/Makefile
> >>>> index 17aa7a65b57e..6fe415903668 100644
> >>>> --- a/drivers/gpu/drm/bridge/synopsys/Makefile
> >>>> +++ b/drivers/gpu/drm/bridge/synopsys/Makefile
> >>>> @@ -3,3 +3,4 @@
> >>>>   obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
> >>>>   obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
> >>>>   obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o
> >>>> +obj-$(CONFIG_DRM_DW_HDMI_CEC) += dw-hdmi-cec.o
> >>>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
> >>>> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
> >>>> new file mode 100644
> >>>> index 000000000000..761ef5ae687d
> >>>> --- /dev/null
> >>>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
> >>>> @@ -0,0 +1,320 @@
> >>>> +/*
> >>>> + * Designware HDMI CEC driver
> >>>> + *
> >>>> + * Copyright (C) 2015-2017 Russell King.
> >>>> + *
> >>>> + * This program is free software; you can redistribute it
> >>>> and/or modify
> >>>> + * it under the terms of the GNU General Public License
> >>>> version 2 as
> >>>> + * published by the Free Software Foundation.
> >>>> + */
> >>>> +#include <linux/interrupt.h>
> >>>> +#include <linux/io.h>
> >>>> +#include <linux/module.h>
> >>>> +#include <linux/platform_device.h>
> >>>> +#include <linux/sched.h>
> >>>> +#include <linux/slab.h>
> >>>> +
> >>>> +#include <drm/drm_edid.h>
> >>>> +
> >>>> +#include <media/cec.h>
> >>>> +#include <media/cec-notifier.h>
> >>>> +
> >>>> +#include "dw-hdmi-cec.h"
> >>>> +
> >>>> +enum {
> >>>> +    HDMI_IH_CEC_STAT0    = 0x0106,
> >>>> +    HDMI_IH_MUTE_CEC_STAT0    = 0x0186,
> >>>> +
> >>>> +    HDMI_CEC_CTRL        = 0x7d00,
> >>>> +    CEC_CTRL_START        = BIT(0),
> >>>> +    CEC_CTRL_NORMAL        = 1 << 1,
> >>>> +
> >>>> +    HDMI_CEC_STAT        = 0x7d01,
> >>>> +    CEC_STAT_DONE        = BIT(0),
> >>>> +    CEC_STAT_EOM        = BIT(1),
> >>>> +    CEC_STAT_NACK        = BIT(2),
> >>>> +    CEC_STAT_ARBLOST    = BIT(3),
> >>>> +    CEC_STAT_ERROR_INIT    = BIT(4),
> >>>> +    CEC_STAT_ERROR_FOLL    = BIT(5),
> >>>> +    CEC_STAT_WAKEUP        = BIT(6),
> >>
> >> I hadn't realized until Jose Abreu's latest reply, but you need
> >> to check the
> >> ARBLOST status and set the TX state to CEC_TX_STATUS_ARB_LOST.
> >>
> >> I think CEC_STAT_ERROR_FOLL might equal
> >> CEC_TX_STATUS_LOW_DRIVE, but without
> >> documentation I can't be sure.
> >>
> >> My experience is that this low drive condition tends to be
> >> poorly reported by
> >> hardware. Either that or poorly documented. This is why I added a
> >> CEC_TX_STATUS_ERROR status as a catch-all error status when it
> >> is unclear from
> >> the hardware/documentation what error occurred.
> >>
> >> Jose, do you know which status bit is used to report a follower
> >> pulling the
> >> CEC line low for a long time (approx. 3.6 ms) to signal a CEC
> >> error?
> > 
> > Bit 5 for follower error, bit 4 for initiator error.
> 
> I gathered that from the define names :-)
> 
> But what does it mean? What sort of error is reported here?

I think the problem is that no one really knows, the documentation is
quite poor:

     5       An error is notified by a follower. Abnormal logic data
 ERROR_FOLL  bit error (for follower).
     4       An error is detected on cec line (for initiator only).
 ERROR_INIT

It is so vague that you can read anything into that description.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver
  2017-06-02  9:15           ` Russell King - ARM Linux
@ 2017-06-02  9:28             ` Hans Verkuil
  -1 siblings, 0 replies; 84+ messages in thread
From: Hans Verkuil @ 2017-06-02  9:28 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/02/17 11:15, Russell King - ARM Linux wrote:
> On Fri, Jun 02, 2017 at 06:02:28AM +0100, Jose Abreu wrote:
>> You should check that CEC is: not in standy, acknowledges
>> broadcast messages, signal free time is 5bit period, and not lost
>> arbitration, which basically means CEC_CTRL must be 0x2 and
>> IH_CEC_STAT0 must not have ARB_LOST set.
> 
> If ARB_LOST is set, that will trigger an interrupt, and the interrupt
> handler will clear the bit.  So all the time that the interrupt handler
> is present, ARB_LOST should be clear whenever we try to send a message.
> 
> When we enable the CEC interface, we zero the CEC_CTRL register, which
> takes the controller out of standby, and initialises the command
> register.
> 
> Bits 2:1 select the signal free time, and there's no requirement
> specified to require them to be set to '01' before writing the
> message - in fact, it's legal for them to be set to other values,
> particularly when retrying, which is something I've missed.
> 
>      2-1             Frame Type bit
>   FRAME_TYP
>                      00    Signal Free Time = 3-bit periods. Previous
> 			   attempt to send frame is unsuccessful.
>                      01    Signal Free Time = 5-bit periods. New initiator
> 			   wants to send a frame.
>                      10    Signal Free Time = 7-bit periods. Present
> 			   initiator wants to send another frame
> 			   immediately after its previous frame. (spec
> 			   CEC 9.1)
>                      11    Illegal value. If software write this value,
> 			   hardware will set the value to the default 2'b01.

The 'signal_free_time' argument of adap_transmit will have the recommended
signal free time. You can test against the CEC_SIGNAL_FREE_TIME_* defines
from media/cec.h. You probably saw this already, but just in case you missed
this...

Regards,

	Hans

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver
@ 2017-06-02  9:28             ` Hans Verkuil
  0 siblings, 0 replies; 84+ messages in thread
From: Hans Verkuil @ 2017-06-02  9:28 UTC (permalink / raw)
  To: Russell King - ARM Linux, Jose Abreu; +Cc: linux-arm-kernel, dri-devel

On 06/02/17 11:15, Russell King - ARM Linux wrote:
> On Fri, Jun 02, 2017 at 06:02:28AM +0100, Jose Abreu wrote:
>> You should check that CEC is: not in standy, acknowledges
>> broadcast messages, signal free time is 5bit period, and not lost
>> arbitration, which basically means CEC_CTRL must be 0x2 and
>> IH_CEC_STAT0 must not have ARB_LOST set.
> 
> If ARB_LOST is set, that will trigger an interrupt, and the interrupt
> handler will clear the bit.  So all the time that the interrupt handler
> is present, ARB_LOST should be clear whenever we try to send a message.
> 
> When we enable the CEC interface, we zero the CEC_CTRL register, which
> takes the controller out of standby, and initialises the command
> register.
> 
> Bits 2:1 select the signal free time, and there's no requirement
> specified to require them to be set to '01' before writing the
> message - in fact, it's legal for them to be set to other values,
> particularly when retrying, which is something I've missed.
> 
>      2-1             Frame Type bit
>   FRAME_TYP
>                      00    Signal Free Time = 3-bit periods. Previous
> 			   attempt to send frame is unsuccessful.
>                      01    Signal Free Time = 5-bit periods. New initiator
> 			   wants to send a frame.
>                      10    Signal Free Time = 7-bit periods. Present
> 			   initiator wants to send another frame
> 			   immediately after its previous frame. (spec
> 			   CEC 9.1)
>                      11    Illegal value. If software write this value,
> 			   hardware will set the value to the default 2'b01.

The 'signal_free_time' argument of adap_transmit will have the recommended
signal free time. You can test against the CEC_SIGNAL_FREE_TIME_* defines
from media/cec.h. You probably saw this already, but just in case you missed
this...

Regards,

	Hans
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver
  2017-06-02  9:28             ` Hans Verkuil
@ 2017-06-02  9:36               ` Russell King - ARM Linux
  -1 siblings, 0 replies; 84+ messages in thread
From: Russell King - ARM Linux @ 2017-06-02  9:36 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jun 02, 2017 at 11:28:08AM +0200, Hans Verkuil wrote:
> The 'signal_free_time' argument of adap_transmit will have the recommended
> signal free time. You can test against the CEC_SIGNAL_FREE_TIME_* defines
> from media/cec.h. You probably saw this already, but just in case you missed
> this...

Yes, it's a recent addition to the CEC core, which I've added support
for, but it doesn't make too much sense until the retrying stuff is
sorted out.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver
@ 2017-06-02  9:36               ` Russell King - ARM Linux
  0 siblings, 0 replies; 84+ messages in thread
From: Russell King - ARM Linux @ 2017-06-02  9:36 UTC (permalink / raw)
  To: Hans Verkuil; +Cc: Jose Abreu, linux-arm-kernel, dri-devel

On Fri, Jun 02, 2017 at 11:28:08AM +0200, Hans Verkuil wrote:
> The 'signal_free_time' argument of adap_transmit will have the recommended
> signal free time. You can test against the CEC_SIGNAL_FREE_TIME_* defines
> from media/cec.h. You probably saw this already, but just in case you missed
> this...

Yes, it's a recent addition to the CEC core, which I've added support
for, but it doesn't make too much sense until the retrying stuff is
sorted out.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver
  2017-06-01  8:31     ` Hans Verkuil
@ 2017-06-02 12:07       ` Russell King - ARM Linux
  -1 siblings, 0 replies; 84+ messages in thread
From: Russell King - ARM Linux @ 2017-06-02 12:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jun 01, 2017 at 10:31:10AM +0200, Hans Verkuil wrote:
> This will change. Patches to fix the config handling are pending for 4.12.
> 
> Here you can see the pending patches:
> https://git.linuxtv.org/hverkuil/media_tree.git/log/?h=drm-cec
> 
> The patches from 'cec-notifier.h: handle unreachable CONFIG_CEC_CORE' to
> 'cec: drop MEDIA_CEC_DEBUG' should all be merged in 4.12.

Hi Hans,

I'll wait until these have hit mainline before generating another
patch series.  Do you have any idea when that might happen?

Thanks.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver
@ 2017-06-02 12:07       ` Russell King - ARM Linux
  0 siblings, 0 replies; 84+ messages in thread
From: Russell King - ARM Linux @ 2017-06-02 12:07 UTC (permalink / raw)
  To: Hans Verkuil; +Cc: linux-arm-kernel, dri-devel

On Thu, Jun 01, 2017 at 10:31:10AM +0200, Hans Verkuil wrote:
> This will change. Patches to fix the config handling are pending for 4.12.
> 
> Here you can see the pending patches:
> https://git.linuxtv.org/hverkuil/media_tree.git/log/?h=drm-cec
> 
> The patches from 'cec-notifier.h: handle unreachable CONFIG_CEC_CORE' to
> 'cec: drop MEDIA_CEC_DEBUG' should all be merged in 4.12.

Hi Hans,

I'll wait until these have hit mainline before generating another
patch series.  Do you have any idea when that might happen?

Thanks.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver
  2017-06-02 12:07       ` Russell King - ARM Linux
@ 2017-06-02 12:29         ` Hans Verkuil
  -1 siblings, 0 replies; 84+ messages in thread
From: Hans Verkuil @ 2017-06-02 12:29 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/02/17 14:07, Russell King - ARM Linux wrote:
> On Thu, Jun 01, 2017 at 10:31:10AM +0200, Hans Verkuil wrote:
>> This will change. Patches to fix the config handling are pending for 4.12.
>>
>> Here you can see the pending patches:
>> https://git.linuxtv.org/hverkuil/media_tree.git/log/?h=drm-cec
>>
>> The patches from 'cec-notifier.h: handle unreachable CONFIG_CEC_CORE' to
>> 'cec: drop MEDIA_CEC_DEBUG' should all be merged in 4.12.
> 
> Hi Hans,
> 
> I'll wait until these have hit mainline before generating another
> patch series.  Do you have any idea when that might happen?

rc6? Hard to tell, I know Mauro is very busy so it can be difficult to
predict.

Regards,

	Hans

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver
@ 2017-06-02 12:29         ` Hans Verkuil
  0 siblings, 0 replies; 84+ messages in thread
From: Hans Verkuil @ 2017-06-02 12:29 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: linux-arm-kernel, dri-devel

On 06/02/17 14:07, Russell King - ARM Linux wrote:
> On Thu, Jun 01, 2017 at 10:31:10AM +0200, Hans Verkuil wrote:
>> This will change. Patches to fix the config handling are pending for 4.12.
>>
>> Here you can see the pending patches:
>> https://git.linuxtv.org/hverkuil/media_tree.git/log/?h=drm-cec
>>
>> The patches from 'cec-notifier.h: handle unreachable CONFIG_CEC_CORE' to
>> 'cec: drop MEDIA_CEC_DEBUG' should all be merged in 4.12.
> 
> Hi Hans,
> 
> I'll wait until these have hit mainline before generating another
> patch series.  Do you have any idea when that might happen?

rc6? Hard to tell, I know Mauro is very busy so it can be difficult to
predict.

Regards,

	Hans
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 2/4] drm/bridge: dw-hdmi: add cec notifier support
  2017-05-30 14:23   ` Russell King
@ 2017-06-09 12:59     ` Neil Armstrong
  -1 siblings, 0 replies; 84+ messages in thread
From: Neil Armstrong @ 2017-06-09 12:59 UTC (permalink / raw)
  To: linux-arm-kernel

On 05/30/2017 04:23 PM, Russell King wrote:
> Add CEC notifier support to the HDMI bridge driver, so that the CEC
> part of the IP can receive its physical address.
> 
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 22 +++++++++++++++++++++-
>  1 file changed, 21 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 4e1f54a675d8..966422576c44 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -36,7 +36,10 @@
>  #include "dw-hdmi.h"
>  #include "dw-hdmi-audio.h"
>  
> +#include <media/cec-notifier.h>
> +
>  #define DDC_SEGMENT_ADDR	0x30
> +
>  #define HDMI_EDID_LEN		512
>  
>  enum hdmi_datamap {
> @@ -173,6 +176,8 @@ struct dw_hdmi {
>  
>  	unsigned int reg_shift;
>  	struct regmap *regm;
> +
> +	struct cec_notifier *cec_notifier;
>  };
>  
>  #define HDMI_IH_PHY_STAT0_RX_SENSE \
> @@ -1870,6 +1875,7 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
>  		hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
>  		hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
>  		drm_mode_connector_update_edid_property(connector, edid);
> +		cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
>  		ret = drm_add_edid_modes(connector, edid);
>  		/* Store the ELD */
>  		drm_edid_to_eld(connector, edid);
> @@ -2108,11 +2114,16 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
>  	 * ask the source to re-read the EDID.
>  	 */
>  	if (intr_stat &
> -	    (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD))
> +	    (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) {
>  		__dw_hdmi_setup_rx_sense(hdmi,
>  					 phy_stat & HDMI_PHY_HPD,
>  					 phy_stat & HDMI_PHY_RX_SENSE);
>  
> +		if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0)
> +			cec_notifier_set_phys_addr(hdmi->cec_notifier,
> +						   CEC_PHYS_ADDR_INVALID);
> +	}
> +
>  	if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
>  		dev_dbg(hdmi->dev, "EVENT=%s\n",
>  			phy_int_pol & HDMI_PHY_HPD ? "plugin" : "plugout");
> @@ -2365,6 +2376,12 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  	if (ret)
>  		goto err_iahb;
>  
> +	hdmi->cec_notifier = cec_notifier_get(dev);
> +	if (!hdmi->cec_notifier) {
> +		ret = -ENOMEM;
> +		goto err_iahb;
> +	}
> +
>  	/*
>  	 * To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator
>  	 * N and cts values before enabling phy
> @@ -2437,6 +2454,9 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  		hdmi->ddc = NULL;
>  	}
>  
> +	if (hdmi->cec_notifier)
> +		cec_notifier_put(hdmi->cec_notifier);
> +
>  	clk_disable_unprepare(hdmi->iahb_clk);
>  err_isfr:
>  	clk_disable_unprepare(hdmi->isfr_clk);
> 

Hi Archit,

I think this one could go through drm-next since it's quite
standalone and will reduce the DW-HDMI CEC patchset and dependencies.

Tested on Amlogic SoCs using my in-development CEC driver.

Tested-by: Neil Armstrong <narmstrong@baylibre.com>
Acked-by: Neil Armstrong <narmstrong@baylibre.com>

Thanks Russell for the patch,
Neil

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH 2/4] drm/bridge: dw-hdmi: add cec notifier support
@ 2017-06-09 12:59     ` Neil Armstrong
  0 siblings, 0 replies; 84+ messages in thread
From: Neil Armstrong @ 2017-06-09 12:59 UTC (permalink / raw)
  To: Russell King, Hans Verkuil; +Cc: linux-arm-kernel, dri-devel

On 05/30/2017 04:23 PM, Russell King wrote:
> Add CEC notifier support to the HDMI bridge driver, so that the CEC
> part of the IP can receive its physical address.
> 
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 22 +++++++++++++++++++++-
>  1 file changed, 21 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 4e1f54a675d8..966422576c44 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -36,7 +36,10 @@
>  #include "dw-hdmi.h"
>  #include "dw-hdmi-audio.h"
>  
> +#include <media/cec-notifier.h>
> +
>  #define DDC_SEGMENT_ADDR	0x30
> +
>  #define HDMI_EDID_LEN		512
>  
>  enum hdmi_datamap {
> @@ -173,6 +176,8 @@ struct dw_hdmi {
>  
>  	unsigned int reg_shift;
>  	struct regmap *regm;
> +
> +	struct cec_notifier *cec_notifier;
>  };
>  
>  #define HDMI_IH_PHY_STAT0_RX_SENSE \
> @@ -1870,6 +1875,7 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
>  		hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
>  		hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
>  		drm_mode_connector_update_edid_property(connector, edid);
> +		cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
>  		ret = drm_add_edid_modes(connector, edid);
>  		/* Store the ELD */
>  		drm_edid_to_eld(connector, edid);
> @@ -2108,11 +2114,16 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
>  	 * ask the source to re-read the EDID.
>  	 */
>  	if (intr_stat &
> -	    (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD))
> +	    (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) {
>  		__dw_hdmi_setup_rx_sense(hdmi,
>  					 phy_stat & HDMI_PHY_HPD,
>  					 phy_stat & HDMI_PHY_RX_SENSE);
>  
> +		if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0)
> +			cec_notifier_set_phys_addr(hdmi->cec_notifier,
> +						   CEC_PHYS_ADDR_INVALID);
> +	}
> +
>  	if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
>  		dev_dbg(hdmi->dev, "EVENT=%s\n",
>  			phy_int_pol & HDMI_PHY_HPD ? "plugin" : "plugout");
> @@ -2365,6 +2376,12 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  	if (ret)
>  		goto err_iahb;
>  
> +	hdmi->cec_notifier = cec_notifier_get(dev);
> +	if (!hdmi->cec_notifier) {
> +		ret = -ENOMEM;
> +		goto err_iahb;
> +	}
> +
>  	/*
>  	 * To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator
>  	 * N and cts values before enabling phy
> @@ -2437,6 +2454,9 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  		hdmi->ddc = NULL;
>  	}
>  
> +	if (hdmi->cec_notifier)
> +		cec_notifier_put(hdmi->cec_notifier);
> +
>  	clk_disable_unprepare(hdmi->iahb_clk);
>  err_isfr:
>  	clk_disable_unprepare(hdmi->isfr_clk);
> 

Hi Archit,

I think this one could go through drm-next since it's quite
standalone and will reduce the DW-HDMI CEC patchset and dependencies.

Tested on Amlogic SoCs using my in-development CEC driver.

Tested-by: Neil Armstrong <narmstrong@baylibre.com>
Acked-by: Neil Armstrong <narmstrong@baylibre.com>

Thanks Russell for the patch,
Neil
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 2/4] drm/bridge: dw-hdmi: add cec notifier support
  2017-06-09 12:59     ` Neil Armstrong
@ 2017-06-09 13:38       ` Russell King - ARM Linux
  -1 siblings, 0 replies; 84+ messages in thread
From: Russell King - ARM Linux @ 2017-06-09 13:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jun 09, 2017 at 02:59:20PM +0200, Neil Armstrong wrote:
> On 05/30/2017 04:23 PM, Russell King wrote:
> > Add CEC notifier support to the HDMI bridge driver, so that the CEC
> > part of the IP can receive its physical address.
> > 
> > Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> > ---
> >  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 22 +++++++++++++++++++++-
> >  1 file changed, 21 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> > index 4e1f54a675d8..966422576c44 100644
> > --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> > +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> > @@ -36,7 +36,10 @@
> >  #include "dw-hdmi.h"
> >  #include "dw-hdmi-audio.h"
> >  
> > +#include <media/cec-notifier.h>
> > +
> >  #define DDC_SEGMENT_ADDR	0x30
> > +
> >  #define HDMI_EDID_LEN		512
> >  
> >  enum hdmi_datamap {
> > @@ -173,6 +176,8 @@ struct dw_hdmi {
> >  
> >  	unsigned int reg_shift;
> >  	struct regmap *regm;
> > +
> > +	struct cec_notifier *cec_notifier;
> >  };
> >  
> >  #define HDMI_IH_PHY_STAT0_RX_SENSE \
> > @@ -1870,6 +1875,7 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
> >  		hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
> >  		hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
> >  		drm_mode_connector_update_edid_property(connector, edid);
> > +		cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
> >  		ret = drm_add_edid_modes(connector, edid);
> >  		/* Store the ELD */
> >  		drm_edid_to_eld(connector, edid);
> > @@ -2108,11 +2114,16 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
> >  	 * ask the source to re-read the EDID.
> >  	 */
> >  	if (intr_stat &
> > -	    (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD))
> > +	    (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) {
> >  		__dw_hdmi_setup_rx_sense(hdmi,
> >  					 phy_stat & HDMI_PHY_HPD,
> >  					 phy_stat & HDMI_PHY_RX_SENSE);
> >  
> > +		if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0)
> > +			cec_notifier_set_phys_addr(hdmi->cec_notifier,
> > +						   CEC_PHYS_ADDR_INVALID);
> > +	}
> > +
> >  	if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
> >  		dev_dbg(hdmi->dev, "EVENT=%s\n",
> >  			phy_int_pol & HDMI_PHY_HPD ? "plugin" : "plugout");
> > @@ -2365,6 +2376,12 @@ __dw_hdmi_probe(struct platform_device *pdev,
> >  	if (ret)
> >  		goto err_iahb;
> >  
> > +	hdmi->cec_notifier = cec_notifier_get(dev);
> > +	if (!hdmi->cec_notifier) {
> > +		ret = -ENOMEM;
> > +		goto err_iahb;
> > +	}
> > +
> >  	/*
> >  	 * To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator
> >  	 * N and cts values before enabling phy
> > @@ -2437,6 +2454,9 @@ __dw_hdmi_probe(struct platform_device *pdev,
> >  		hdmi->ddc = NULL;
> >  	}
> >  
> > +	if (hdmi->cec_notifier)
> > +		cec_notifier_put(hdmi->cec_notifier);
> > +
> >  	clk_disable_unprepare(hdmi->iahb_clk);
> >  err_isfr:
> >  	clk_disable_unprepare(hdmi->isfr_clk);
> > 
> 
> Hi Archit,
> 
> I think this one could go through drm-next since it's quite
> standalone and will reduce the DW-HDMI CEC patchset and dependencies.

Not a good idea.  If you read all the comments, Hans is suggesting that
CEC should be part of dw-hdmi itself, not stand-alone.  That would mean
this patch probably changes - basically, with CEC support built-in to
dw-hdmi, we don't need the notifier stuff.

So, I'd suggest _not_ merging it at the moment, because the patch could
well become obsolete.

Wait until the CEC changes that Hans has talked about have hit mainline
and I've had a chance to rework this for those.  We're waiting on Mauro
for that at the moment.

(I do find it rather frustrating that CEC seems to evolve very rapidly,
it makes it quite difficult to publish a patch set, and get it merged.)

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH 2/4] drm/bridge: dw-hdmi: add cec notifier support
@ 2017-06-09 13:38       ` Russell King - ARM Linux
  0 siblings, 0 replies; 84+ messages in thread
From: Russell King - ARM Linux @ 2017-06-09 13:38 UTC (permalink / raw)
  To: Neil Armstrong
  Cc: Hans Verkuil, David Airlie, Archit Taneja, dri-devel, linux-arm-kernel

On Fri, Jun 09, 2017 at 02:59:20PM +0200, Neil Armstrong wrote:
> On 05/30/2017 04:23 PM, Russell King wrote:
> > Add CEC notifier support to the HDMI bridge driver, so that the CEC
> > part of the IP can receive its physical address.
> > 
> > Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> > ---
> >  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 22 +++++++++++++++++++++-
> >  1 file changed, 21 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> > index 4e1f54a675d8..966422576c44 100644
> > --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> > +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> > @@ -36,7 +36,10 @@
> >  #include "dw-hdmi.h"
> >  #include "dw-hdmi-audio.h"
> >  
> > +#include <media/cec-notifier.h>
> > +
> >  #define DDC_SEGMENT_ADDR	0x30
> > +
> >  #define HDMI_EDID_LEN		512
> >  
> >  enum hdmi_datamap {
> > @@ -173,6 +176,8 @@ struct dw_hdmi {
> >  
> >  	unsigned int reg_shift;
> >  	struct regmap *regm;
> > +
> > +	struct cec_notifier *cec_notifier;
> >  };
> >  
> >  #define HDMI_IH_PHY_STAT0_RX_SENSE \
> > @@ -1870,6 +1875,7 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
> >  		hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
> >  		hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
> >  		drm_mode_connector_update_edid_property(connector, edid);
> > +		cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
> >  		ret = drm_add_edid_modes(connector, edid);
> >  		/* Store the ELD */
> >  		drm_edid_to_eld(connector, edid);
> > @@ -2108,11 +2114,16 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
> >  	 * ask the source to re-read the EDID.
> >  	 */
> >  	if (intr_stat &
> > -	    (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD))
> > +	    (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) {
> >  		__dw_hdmi_setup_rx_sense(hdmi,
> >  					 phy_stat & HDMI_PHY_HPD,
> >  					 phy_stat & HDMI_PHY_RX_SENSE);
> >  
> > +		if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0)
> > +			cec_notifier_set_phys_addr(hdmi->cec_notifier,
> > +						   CEC_PHYS_ADDR_INVALID);
> > +	}
> > +
> >  	if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
> >  		dev_dbg(hdmi->dev, "EVENT=%s\n",
> >  			phy_int_pol & HDMI_PHY_HPD ? "plugin" : "plugout");
> > @@ -2365,6 +2376,12 @@ __dw_hdmi_probe(struct platform_device *pdev,
> >  	if (ret)
> >  		goto err_iahb;
> >  
> > +	hdmi->cec_notifier = cec_notifier_get(dev);
> > +	if (!hdmi->cec_notifier) {
> > +		ret = -ENOMEM;
> > +		goto err_iahb;
> > +	}
> > +
> >  	/*
> >  	 * To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator
> >  	 * N and cts values before enabling phy
> > @@ -2437,6 +2454,9 @@ __dw_hdmi_probe(struct platform_device *pdev,
> >  		hdmi->ddc = NULL;
> >  	}
> >  
> > +	if (hdmi->cec_notifier)
> > +		cec_notifier_put(hdmi->cec_notifier);
> > +
> >  	clk_disable_unprepare(hdmi->iahb_clk);
> >  err_isfr:
> >  	clk_disable_unprepare(hdmi->isfr_clk);
> > 
> 
> Hi Archit,
> 
> I think this one could go through drm-next since it's quite
> standalone and will reduce the DW-HDMI CEC patchset and dependencies.

Not a good idea.  If you read all the comments, Hans is suggesting that
CEC should be part of dw-hdmi itself, not stand-alone.  That would mean
this patch probably changes - basically, with CEC support built-in to
dw-hdmi, we don't need the notifier stuff.

So, I'd suggest _not_ merging it at the moment, because the patch could
well become obsolete.

Wait until the CEC changes that Hans has talked about have hit mainline
and I've had a chance to rework this for those.  We're waiting on Mauro
for that at the moment.

(I do find it rather frustrating that CEC seems to evolve very rapidly,
it makes it quite difficult to publish a patch set, and get it merged.)

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 2/4] drm/bridge: dw-hdmi: add cec notifier support
  2017-06-09 13:38       ` Russell King - ARM Linux
@ 2017-06-09 13:51         ` Hans Verkuil
  -1 siblings, 0 replies; 84+ messages in thread
From: Hans Verkuil @ 2017-06-09 13:51 UTC (permalink / raw)
  To: linux-arm-kernel

On 09/06/17 15:38, Russell King - ARM Linux wrote:
> On Fri, Jun 09, 2017 at 02:59:20PM +0200, Neil Armstrong wrote:
>> On 05/30/2017 04:23 PM, Russell King wrote:
>>> Add CEC notifier support to the HDMI bridge driver, so that the CEC
>>> part of the IP can receive its physical address.
>>>
>>> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
>>> ---
>>>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 22 +++++++++++++++++++++-
>>>  1 file changed, 21 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>> index 4e1f54a675d8..966422576c44 100644
>>> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>> @@ -36,7 +36,10 @@
>>>  #include "dw-hdmi.h"
>>>  #include "dw-hdmi-audio.h"
>>>  
>>> +#include <media/cec-notifier.h>
>>> +
>>>  #define DDC_SEGMENT_ADDR	0x30
>>> +
>>>  #define HDMI_EDID_LEN		512
>>>  
>>>  enum hdmi_datamap {
>>> @@ -173,6 +176,8 @@ struct dw_hdmi {
>>>  
>>>  	unsigned int reg_shift;
>>>  	struct regmap *regm;
>>> +
>>> +	struct cec_notifier *cec_notifier;
>>>  };
>>>  
>>>  #define HDMI_IH_PHY_STAT0_RX_SENSE \
>>> @@ -1870,6 +1875,7 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
>>>  		hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
>>>  		hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
>>>  		drm_mode_connector_update_edid_property(connector, edid);
>>> +		cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
>>>  		ret = drm_add_edid_modes(connector, edid);
>>>  		/* Store the ELD */
>>>  		drm_edid_to_eld(connector, edid);
>>> @@ -2108,11 +2114,16 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
>>>  	 * ask the source to re-read the EDID.
>>>  	 */
>>>  	if (intr_stat &
>>> -	    (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD))
>>> +	    (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) {
>>>  		__dw_hdmi_setup_rx_sense(hdmi,
>>>  					 phy_stat & HDMI_PHY_HPD,
>>>  					 phy_stat & HDMI_PHY_RX_SENSE);
>>>  
>>> +		if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0)
>>> +			cec_notifier_set_phys_addr(hdmi->cec_notifier,
>>> +						   CEC_PHYS_ADDR_INVALID);
>>> +	}
>>> +
>>>  	if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
>>>  		dev_dbg(hdmi->dev, "EVENT=%s\n",
>>>  			phy_int_pol & HDMI_PHY_HPD ? "plugin" : "plugout");
>>> @@ -2365,6 +2376,12 @@ __dw_hdmi_probe(struct platform_device *pdev,
>>>  	if (ret)
>>>  		goto err_iahb;
>>>  
>>> +	hdmi->cec_notifier = cec_notifier_get(dev);
>>> +	if (!hdmi->cec_notifier) {
>>> +		ret = -ENOMEM;
>>> +		goto err_iahb;
>>> +	}
>>> +
>>>  	/*
>>>  	 * To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator
>>>  	 * N and cts values before enabling phy
>>> @@ -2437,6 +2454,9 @@ __dw_hdmi_probe(struct platform_device *pdev,
>>>  		hdmi->ddc = NULL;
>>>  	}
>>>  
>>> +	if (hdmi->cec_notifier)
>>> +		cec_notifier_put(hdmi->cec_notifier);
>>> +
>>>  	clk_disable_unprepare(hdmi->iahb_clk);
>>>  err_isfr:
>>>  	clk_disable_unprepare(hdmi->isfr_clk);
>>>
>>
>> Hi Archit,
>>
>> I think this one could go through drm-next since it's quite
>> standalone and will reduce the DW-HDMI CEC patchset and dependencies.
> 
> Not a good idea.  If you read all the comments, Hans is suggesting that
> CEC should be part of dw-hdmi itself, not stand-alone.  That would mean
> this patch probably changes - basically, with CEC support built-in to
> dw-hdmi, we don't need the notifier stuff.
> 
> So, I'd suggest _not_ merging it at the moment, because the patch could
> well become obsolete.
> 
> Wait until the CEC changes that Hans has talked about have hit mainline
> and I've had a chance to rework this for those.  We're waiting on Mauro
> for that at the moment.

The patches are in mainline now. Note: you may get the occasional kbuild
robot emails since there are a few more CEC patches pending for 4.12 but
that's just slight CEC header changes to fix obscure .config combinations.
It should not affect your patches. I expect those pending fixes to hit
mainline some time next week.

> (I do find it rather frustrating that CEC seems to evolve very rapidly,
> it makes it quite difficult to publish a patch set, and get it merged.)

It's a pretty new framework and yours and my own work on drm drivers showed
a few shortcomings, primarily in the way the kernel config options were set
up for CEC.

I believe this is now sorted with 4.12.

What makes CEC a bit tricky is that it straddles two subsystems: drm and media.
Always harder to synchronize things.

Regards,

	Hans

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH 2/4] drm/bridge: dw-hdmi: add cec notifier support
@ 2017-06-09 13:51         ` Hans Verkuil
  0 siblings, 0 replies; 84+ messages in thread
From: Hans Verkuil @ 2017-06-09 13:51 UTC (permalink / raw)
  To: Russell King - ARM Linux, Neil Armstrong; +Cc: dri-devel, linux-arm-kernel

On 09/06/17 15:38, Russell King - ARM Linux wrote:
> On Fri, Jun 09, 2017 at 02:59:20PM +0200, Neil Armstrong wrote:
>> On 05/30/2017 04:23 PM, Russell King wrote:
>>> Add CEC notifier support to the HDMI bridge driver, so that the CEC
>>> part of the IP can receive its physical address.
>>>
>>> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
>>> ---
>>>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 22 +++++++++++++++++++++-
>>>  1 file changed, 21 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>> index 4e1f54a675d8..966422576c44 100644
>>> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>> @@ -36,7 +36,10 @@
>>>  #include "dw-hdmi.h"
>>>  #include "dw-hdmi-audio.h"
>>>  
>>> +#include <media/cec-notifier.h>
>>> +
>>>  #define DDC_SEGMENT_ADDR	0x30
>>> +
>>>  #define HDMI_EDID_LEN		512
>>>  
>>>  enum hdmi_datamap {
>>> @@ -173,6 +176,8 @@ struct dw_hdmi {
>>>  
>>>  	unsigned int reg_shift;
>>>  	struct regmap *regm;
>>> +
>>> +	struct cec_notifier *cec_notifier;
>>>  };
>>>  
>>>  #define HDMI_IH_PHY_STAT0_RX_SENSE \
>>> @@ -1870,6 +1875,7 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
>>>  		hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
>>>  		hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
>>>  		drm_mode_connector_update_edid_property(connector, edid);
>>> +		cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
>>>  		ret = drm_add_edid_modes(connector, edid);
>>>  		/* Store the ELD */
>>>  		drm_edid_to_eld(connector, edid);
>>> @@ -2108,11 +2114,16 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
>>>  	 * ask the source to re-read the EDID.
>>>  	 */
>>>  	if (intr_stat &
>>> -	    (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD))
>>> +	    (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) {
>>>  		__dw_hdmi_setup_rx_sense(hdmi,
>>>  					 phy_stat & HDMI_PHY_HPD,
>>>  					 phy_stat & HDMI_PHY_RX_SENSE);
>>>  
>>> +		if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0)
>>> +			cec_notifier_set_phys_addr(hdmi->cec_notifier,
>>> +						   CEC_PHYS_ADDR_INVALID);
>>> +	}
>>> +
>>>  	if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
>>>  		dev_dbg(hdmi->dev, "EVENT=%s\n",
>>>  			phy_int_pol & HDMI_PHY_HPD ? "plugin" : "plugout");
>>> @@ -2365,6 +2376,12 @@ __dw_hdmi_probe(struct platform_device *pdev,
>>>  	if (ret)
>>>  		goto err_iahb;
>>>  
>>> +	hdmi->cec_notifier = cec_notifier_get(dev);
>>> +	if (!hdmi->cec_notifier) {
>>> +		ret = -ENOMEM;
>>> +		goto err_iahb;
>>> +	}
>>> +
>>>  	/*
>>>  	 * To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator
>>>  	 * N and cts values before enabling phy
>>> @@ -2437,6 +2454,9 @@ __dw_hdmi_probe(struct platform_device *pdev,
>>>  		hdmi->ddc = NULL;
>>>  	}
>>>  
>>> +	if (hdmi->cec_notifier)
>>> +		cec_notifier_put(hdmi->cec_notifier);
>>> +
>>>  	clk_disable_unprepare(hdmi->iahb_clk);
>>>  err_isfr:
>>>  	clk_disable_unprepare(hdmi->isfr_clk);
>>>
>>
>> Hi Archit,
>>
>> I think this one could go through drm-next since it's quite
>> standalone and will reduce the DW-HDMI CEC patchset and dependencies.
> 
> Not a good idea.  If you read all the comments, Hans is suggesting that
> CEC should be part of dw-hdmi itself, not stand-alone.  That would mean
> this patch probably changes - basically, with CEC support built-in to
> dw-hdmi, we don't need the notifier stuff.
> 
> So, I'd suggest _not_ merging it at the moment, because the patch could
> well become obsolete.
> 
> Wait until the CEC changes that Hans has talked about have hit mainline
> and I've had a chance to rework this for those.  We're waiting on Mauro
> for that at the moment.

The patches are in mainline now. Note: you may get the occasional kbuild
robot emails since there are a few more CEC patches pending for 4.12 but
that's just slight CEC header changes to fix obscure .config combinations.
It should not affect your patches. I expect those pending fixes to hit
mainline some time next week.

> (I do find it rather frustrating that CEC seems to evolve very rapidly,
> it makes it quite difficult to publish a patch set, and get it merged.)

It's a pretty new framework and yours and my own work on drm drivers showed
a few shortcomings, primarily in the way the kernel config options were set
up for CEC.

I believe this is now sorted with 4.12.

What makes CEC a bit tricky is that it straddles two subsystems: drm and media.
Always harder to synchronize things.

Regards,

	Hans
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 2/4] drm/bridge: dw-hdmi: add cec notifier support
  2017-06-09 13:38       ` Russell King - ARM Linux
@ 2017-06-09 13:56         ` Neil Armstrong
  -1 siblings, 0 replies; 84+ messages in thread
From: Neil Armstrong @ 2017-06-09 13:56 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/09/2017 03:38 PM, Russell King - ARM Linux wrote:
> On Fri, Jun 09, 2017 at 02:59:20PM +0200, Neil Armstrong wrote:
>> On 05/30/2017 04:23 PM, Russell King wrote:
>>> Add CEC notifier support to the HDMI bridge driver, so that the CEC
>>> part of the IP can receive its physical address.
>>>
>>> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
>>> ---
>>>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 22 +++++++++++++++++++++-
>>>  1 file changed, 21 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>> index 4e1f54a675d8..966422576c44 100644
>>> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>> @@ -36,7 +36,10 @@
>>>  #include "dw-hdmi.h"
>>>  #include "dw-hdmi-audio.h"
>>>  
>>> +#include <media/cec-notifier.h>
>>> +
>>>  #define DDC_SEGMENT_ADDR	0x30
>>> +
>>>  #define HDMI_EDID_LEN		512
>>>  
>>>  enum hdmi_datamap {
>>> @@ -173,6 +176,8 @@ struct dw_hdmi {
>>>  
>>>  	unsigned int reg_shift;
>>>  	struct regmap *regm;
>>> +
>>> +	struct cec_notifier *cec_notifier;
>>>  };
>>>  
>>>  #define HDMI_IH_PHY_STAT0_RX_SENSE \
>>> @@ -1870,6 +1875,7 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
>>>  		hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
>>>  		hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
>>>  		drm_mode_connector_update_edid_property(connector, edid);
>>> +		cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
>>>  		ret = drm_add_edid_modes(connector, edid);
>>>  		/* Store the ELD */
>>>  		drm_edid_to_eld(connector, edid);
>>> @@ -2108,11 +2114,16 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
>>>  	 * ask the source to re-read the EDID.
>>>  	 */
>>>  	if (intr_stat &
>>> -	    (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD))
>>> +	    (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) {
>>>  		__dw_hdmi_setup_rx_sense(hdmi,
>>>  					 phy_stat & HDMI_PHY_HPD,
>>>  					 phy_stat & HDMI_PHY_RX_SENSE);
>>>  
>>> +		if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0)
>>> +			cec_notifier_set_phys_addr(hdmi->cec_notifier,
>>> +						   CEC_PHYS_ADDR_INVALID);
>>> +	}
>>> +
>>>  	if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
>>>  		dev_dbg(hdmi->dev, "EVENT=%s\n",
>>>  			phy_int_pol & HDMI_PHY_HPD ? "plugin" : "plugout");
>>> @@ -2365,6 +2376,12 @@ __dw_hdmi_probe(struct platform_device *pdev,
>>>  	if (ret)
>>>  		goto err_iahb;
>>>  
>>> +	hdmi->cec_notifier = cec_notifier_get(dev);
>>> +	if (!hdmi->cec_notifier) {
>>> +		ret = -ENOMEM;
>>> +		goto err_iahb;
>>> +	}
>>> +
>>>  	/*
>>>  	 * To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator
>>>  	 * N and cts values before enabling phy
>>> @@ -2437,6 +2454,9 @@ __dw_hdmi_probe(struct platform_device *pdev,
>>>  		hdmi->ddc = NULL;
>>>  	}
>>>  
>>> +	if (hdmi->cec_notifier)
>>> +		cec_notifier_put(hdmi->cec_notifier);
>>> +
>>>  	clk_disable_unprepare(hdmi->iahb_clk);
>>>  err_isfr:
>>>  	clk_disable_unprepare(hdmi->isfr_clk);
>>>
>>
>> Hi Archit,
>>
>> I think this one could go through drm-next since it's quite
>> standalone and will reduce the DW-HDMI CEC patchset and dependencies.
> 
> Not a good idea.  If you read all the comments, Hans is suggesting that
> CEC should be part of dw-hdmi itself, not stand-alone.  That would mean
> this patch probably changes - basically, with CEC support built-in to
> dw-hdmi, we don't need the notifier stuff.

Hi Russell,

Yes, but on the Amlogic Meson plarform, the DW-HDMI CEC controller is not used,
but a custom one, so this notifier is actually useful for this platform and
maybe others.

> 
> So, I'd suggest _not_ merging it at the moment, because the patch could
> well become obsolete.

It won't since the Meson platform needs it...

> 
> Wait until the CEC changes that Hans has talked about have hit mainline
> and I've had a chance to rework this for those.  We're waiting on Mauro
> for that at the moment.
> 
> (I do find it rather frustrating that CEC seems to evolve very rapidly,
> it makes it quite difficult to publish a patch set, and get it merged.)
> 

Should we really wait until I push the Amlogic AO CEC driver ? Having a
notifier in the DW-HDMI driver won't harm anybody since it *will be used*.

Neil

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH 2/4] drm/bridge: dw-hdmi: add cec notifier support
@ 2017-06-09 13:56         ` Neil Armstrong
  0 siblings, 0 replies; 84+ messages in thread
From: Neil Armstrong @ 2017-06-09 13:56 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: Hans Verkuil, dri-devel, linux-arm-kernel

On 06/09/2017 03:38 PM, Russell King - ARM Linux wrote:
> On Fri, Jun 09, 2017 at 02:59:20PM +0200, Neil Armstrong wrote:
>> On 05/30/2017 04:23 PM, Russell King wrote:
>>> Add CEC notifier support to the HDMI bridge driver, so that the CEC
>>> part of the IP can receive its physical address.
>>>
>>> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
>>> ---
>>>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 22 +++++++++++++++++++++-
>>>  1 file changed, 21 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>> index 4e1f54a675d8..966422576c44 100644
>>> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>> @@ -36,7 +36,10 @@
>>>  #include "dw-hdmi.h"
>>>  #include "dw-hdmi-audio.h"
>>>  
>>> +#include <media/cec-notifier.h>
>>> +
>>>  #define DDC_SEGMENT_ADDR	0x30
>>> +
>>>  #define HDMI_EDID_LEN		512
>>>  
>>>  enum hdmi_datamap {
>>> @@ -173,6 +176,8 @@ struct dw_hdmi {
>>>  
>>>  	unsigned int reg_shift;
>>>  	struct regmap *regm;
>>> +
>>> +	struct cec_notifier *cec_notifier;
>>>  };
>>>  
>>>  #define HDMI_IH_PHY_STAT0_RX_SENSE \
>>> @@ -1870,6 +1875,7 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
>>>  		hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
>>>  		hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
>>>  		drm_mode_connector_update_edid_property(connector, edid);
>>> +		cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
>>>  		ret = drm_add_edid_modes(connector, edid);
>>>  		/* Store the ELD */
>>>  		drm_edid_to_eld(connector, edid);
>>> @@ -2108,11 +2114,16 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
>>>  	 * ask the source to re-read the EDID.
>>>  	 */
>>>  	if (intr_stat &
>>> -	    (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD))
>>> +	    (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) {
>>>  		__dw_hdmi_setup_rx_sense(hdmi,
>>>  					 phy_stat & HDMI_PHY_HPD,
>>>  					 phy_stat & HDMI_PHY_RX_SENSE);
>>>  
>>> +		if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0)
>>> +			cec_notifier_set_phys_addr(hdmi->cec_notifier,
>>> +						   CEC_PHYS_ADDR_INVALID);
>>> +	}
>>> +
>>>  	if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
>>>  		dev_dbg(hdmi->dev, "EVENT=%s\n",
>>>  			phy_int_pol & HDMI_PHY_HPD ? "plugin" : "plugout");
>>> @@ -2365,6 +2376,12 @@ __dw_hdmi_probe(struct platform_device *pdev,
>>>  	if (ret)
>>>  		goto err_iahb;
>>>  
>>> +	hdmi->cec_notifier = cec_notifier_get(dev);
>>> +	if (!hdmi->cec_notifier) {
>>> +		ret = -ENOMEM;
>>> +		goto err_iahb;
>>> +	}
>>> +
>>>  	/*
>>>  	 * To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator
>>>  	 * N and cts values before enabling phy
>>> @@ -2437,6 +2454,9 @@ __dw_hdmi_probe(struct platform_device *pdev,
>>>  		hdmi->ddc = NULL;
>>>  	}
>>>  
>>> +	if (hdmi->cec_notifier)
>>> +		cec_notifier_put(hdmi->cec_notifier);
>>> +
>>>  	clk_disable_unprepare(hdmi->iahb_clk);
>>>  err_isfr:
>>>  	clk_disable_unprepare(hdmi->isfr_clk);
>>>
>>
>> Hi Archit,
>>
>> I think this one could go through drm-next since it's quite
>> standalone and will reduce the DW-HDMI CEC patchset and dependencies.
> 
> Not a good idea.  If you read all the comments, Hans is suggesting that
> CEC should be part of dw-hdmi itself, not stand-alone.  That would mean
> this patch probably changes - basically, with CEC support built-in to
> dw-hdmi, we don't need the notifier stuff.

Hi Russell,

Yes, but on the Amlogic Meson plarform, the DW-HDMI CEC controller is not used,
but a custom one, so this notifier is actually useful for this platform and
maybe others.

> 
> So, I'd suggest _not_ merging it at the moment, because the patch could
> well become obsolete.

It won't since the Meson platform needs it...

> 
> Wait until the CEC changes that Hans has talked about have hit mainline
> and I've had a chance to rework this for those.  We're waiting on Mauro
> for that at the moment.
> 
> (I do find it rather frustrating that CEC seems to evolve very rapidly,
> it makes it quite difficult to publish a patch set, and get it merged.)
> 

Should we really wait until I push the Amlogic AO CEC driver ? Having a
notifier in the DW-HDMI driver won't harm anybody since it *will be used*.

Neil
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 2/4] drm/bridge: dw-hdmi: add cec notifier support
  2017-06-09 13:56         ` Neil Armstrong
@ 2017-06-09 14:04           ` Hans Verkuil
  -1 siblings, 0 replies; 84+ messages in thread
From: Hans Verkuil @ 2017-06-09 14:04 UTC (permalink / raw)
  To: linux-arm-kernel

On 09/06/17 15:56, Neil Armstrong wrote:
> On 06/09/2017 03:38 PM, Russell King - ARM Linux wrote:
>> On Fri, Jun 09, 2017 at 02:59:20PM +0200, Neil Armstrong wrote:
>>> On 05/30/2017 04:23 PM, Russell King wrote:
>>>> Add CEC notifier support to the HDMI bridge driver, so that the CEC
>>>> part of the IP can receive its physical address.
>>>>
>>>> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
>>>> ---
>>>>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 22 +++++++++++++++++++++-
>>>>  1 file changed, 21 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>>> index 4e1f54a675d8..966422576c44 100644
>>>> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>>> @@ -36,7 +36,10 @@
>>>>  #include "dw-hdmi.h"
>>>>  #include "dw-hdmi-audio.h"
>>>>  
>>>> +#include <media/cec-notifier.h>
>>>> +
>>>>  #define DDC_SEGMENT_ADDR	0x30
>>>> +
>>>>  #define HDMI_EDID_LEN		512
>>>>  
>>>>  enum hdmi_datamap {
>>>> @@ -173,6 +176,8 @@ struct dw_hdmi {
>>>>  
>>>>  	unsigned int reg_shift;
>>>>  	struct regmap *regm;
>>>> +
>>>> +	struct cec_notifier *cec_notifier;
>>>>  };
>>>>  
>>>>  #define HDMI_IH_PHY_STAT0_RX_SENSE \
>>>> @@ -1870,6 +1875,7 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
>>>>  		hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
>>>>  		hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
>>>>  		drm_mode_connector_update_edid_property(connector, edid);
>>>> +		cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
>>>>  		ret = drm_add_edid_modes(connector, edid);
>>>>  		/* Store the ELD */
>>>>  		drm_edid_to_eld(connector, edid);
>>>> @@ -2108,11 +2114,16 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
>>>>  	 * ask the source to re-read the EDID.
>>>>  	 */
>>>>  	if (intr_stat &
>>>> -	    (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD))
>>>> +	    (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) {
>>>>  		__dw_hdmi_setup_rx_sense(hdmi,
>>>>  					 phy_stat & HDMI_PHY_HPD,
>>>>  					 phy_stat & HDMI_PHY_RX_SENSE);
>>>>  
>>>> +		if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0)
>>>> +			cec_notifier_set_phys_addr(hdmi->cec_notifier,
>>>> +						   CEC_PHYS_ADDR_INVALID);
>>>> +	}
>>>> +
>>>>  	if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
>>>>  		dev_dbg(hdmi->dev, "EVENT=%s\n",
>>>>  			phy_int_pol & HDMI_PHY_HPD ? "plugin" : "plugout");
>>>> @@ -2365,6 +2376,12 @@ __dw_hdmi_probe(struct platform_device *pdev,
>>>>  	if (ret)
>>>>  		goto err_iahb;
>>>>  
>>>> +	hdmi->cec_notifier = cec_notifier_get(dev);
>>>> +	if (!hdmi->cec_notifier) {
>>>> +		ret = -ENOMEM;
>>>> +		goto err_iahb;
>>>> +	}
>>>> +
>>>>  	/*
>>>>  	 * To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator
>>>>  	 * N and cts values before enabling phy
>>>> @@ -2437,6 +2454,9 @@ __dw_hdmi_probe(struct platform_device *pdev,
>>>>  		hdmi->ddc = NULL;
>>>>  	}
>>>>  
>>>> +	if (hdmi->cec_notifier)
>>>> +		cec_notifier_put(hdmi->cec_notifier);
>>>> +
>>>>  	clk_disable_unprepare(hdmi->iahb_clk);
>>>>  err_isfr:
>>>>  	clk_disable_unprepare(hdmi->isfr_clk);
>>>>
>>>
>>> Hi Archit,
>>>
>>> I think this one could go through drm-next since it's quite
>>> standalone and will reduce the DW-HDMI CEC patchset and dependencies.
>>
>> Not a good idea.  If you read all the comments, Hans is suggesting that
>> CEC should be part of dw-hdmi itself, not stand-alone.  That would mean
>> this patch probably changes - basically, with CEC support built-in to
>> dw-hdmi, we don't need the notifier stuff.
> 
> Hi Russell,
> 
> Yes, but on the Amlogic Meson plarform, the DW-HDMI CEC controller is not used,
> but a custom one, so this notifier is actually useful for this platform and
> maybe others.
> 
>>
>> So, I'd suggest _not_ merging it at the moment, because the patch could
>> well become obsolete.
> 
> It won't since the Meson platform needs it...

Ah, I wasn't aware of that when I wrote my original comments. In that case
we do need the notifier. Which is fine, as long as the reason for that is
documented.

> 
>>
>> Wait until the CEC changes that Hans has talked about have hit mainline
>> and I've had a chance to rework this for those.  We're waiting on Mauro
>> for that at the moment.
>>
>> (I do find it rather frustrating that CEC seems to evolve very rapidly,
>> it makes it quite difficult to publish a patch set, and get it merged.)
>>
> 
> Should we really wait until I push the Amlogic AO CEC driver ? Having a
> notifier in the DW-HDMI driver won't harm anybody since it *will be used*.

I'm OK with the notifier in this case.

Regards,

	Hans

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH 2/4] drm/bridge: dw-hdmi: add cec notifier support
@ 2017-06-09 14:04           ` Hans Verkuil
  0 siblings, 0 replies; 84+ messages in thread
From: Hans Verkuil @ 2017-06-09 14:04 UTC (permalink / raw)
  To: Neil Armstrong, Russell King - ARM Linux; +Cc: linux-arm-kernel, dri-devel

On 09/06/17 15:56, Neil Armstrong wrote:
> On 06/09/2017 03:38 PM, Russell King - ARM Linux wrote:
>> On Fri, Jun 09, 2017 at 02:59:20PM +0200, Neil Armstrong wrote:
>>> On 05/30/2017 04:23 PM, Russell King wrote:
>>>> Add CEC notifier support to the HDMI bridge driver, so that the CEC
>>>> part of the IP can receive its physical address.
>>>>
>>>> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
>>>> ---
>>>>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 22 +++++++++++++++++++++-
>>>>  1 file changed, 21 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>>> index 4e1f54a675d8..966422576c44 100644
>>>> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>>> @@ -36,7 +36,10 @@
>>>>  #include "dw-hdmi.h"
>>>>  #include "dw-hdmi-audio.h"
>>>>  
>>>> +#include <media/cec-notifier.h>
>>>> +
>>>>  #define DDC_SEGMENT_ADDR	0x30
>>>> +
>>>>  #define HDMI_EDID_LEN		512
>>>>  
>>>>  enum hdmi_datamap {
>>>> @@ -173,6 +176,8 @@ struct dw_hdmi {
>>>>  
>>>>  	unsigned int reg_shift;
>>>>  	struct regmap *regm;
>>>> +
>>>> +	struct cec_notifier *cec_notifier;
>>>>  };
>>>>  
>>>>  #define HDMI_IH_PHY_STAT0_RX_SENSE \
>>>> @@ -1870,6 +1875,7 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
>>>>  		hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
>>>>  		hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
>>>>  		drm_mode_connector_update_edid_property(connector, edid);
>>>> +		cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
>>>>  		ret = drm_add_edid_modes(connector, edid);
>>>>  		/* Store the ELD */
>>>>  		drm_edid_to_eld(connector, edid);
>>>> @@ -2108,11 +2114,16 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
>>>>  	 * ask the source to re-read the EDID.
>>>>  	 */
>>>>  	if (intr_stat &
>>>> -	    (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD))
>>>> +	    (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) {
>>>>  		__dw_hdmi_setup_rx_sense(hdmi,
>>>>  					 phy_stat & HDMI_PHY_HPD,
>>>>  					 phy_stat & HDMI_PHY_RX_SENSE);
>>>>  
>>>> +		if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0)
>>>> +			cec_notifier_set_phys_addr(hdmi->cec_notifier,
>>>> +						   CEC_PHYS_ADDR_INVALID);
>>>> +	}
>>>> +
>>>>  	if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
>>>>  		dev_dbg(hdmi->dev, "EVENT=%s\n",
>>>>  			phy_int_pol & HDMI_PHY_HPD ? "plugin" : "plugout");
>>>> @@ -2365,6 +2376,12 @@ __dw_hdmi_probe(struct platform_device *pdev,
>>>>  	if (ret)
>>>>  		goto err_iahb;
>>>>  
>>>> +	hdmi->cec_notifier = cec_notifier_get(dev);
>>>> +	if (!hdmi->cec_notifier) {
>>>> +		ret = -ENOMEM;
>>>> +		goto err_iahb;
>>>> +	}
>>>> +
>>>>  	/*
>>>>  	 * To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator
>>>>  	 * N and cts values before enabling phy
>>>> @@ -2437,6 +2454,9 @@ __dw_hdmi_probe(struct platform_device *pdev,
>>>>  		hdmi->ddc = NULL;
>>>>  	}
>>>>  
>>>> +	if (hdmi->cec_notifier)
>>>> +		cec_notifier_put(hdmi->cec_notifier);
>>>> +
>>>>  	clk_disable_unprepare(hdmi->iahb_clk);
>>>>  err_isfr:
>>>>  	clk_disable_unprepare(hdmi->isfr_clk);
>>>>
>>>
>>> Hi Archit,
>>>
>>> I think this one could go through drm-next since it's quite
>>> standalone and will reduce the DW-HDMI CEC patchset and dependencies.
>>
>> Not a good idea.  If you read all the comments, Hans is suggesting that
>> CEC should be part of dw-hdmi itself, not stand-alone.  That would mean
>> this patch probably changes - basically, with CEC support built-in to
>> dw-hdmi, we don't need the notifier stuff.
> 
> Hi Russell,
> 
> Yes, but on the Amlogic Meson plarform, the DW-HDMI CEC controller is not used,
> but a custom one, so this notifier is actually useful for this platform and
> maybe others.
> 
>>
>> So, I'd suggest _not_ merging it at the moment, because the patch could
>> well become obsolete.
> 
> It won't since the Meson platform needs it...

Ah, I wasn't aware of that when I wrote my original comments. In that case
we do need the notifier. Which is fine, as long as the reason for that is
documented.

> 
>>
>> Wait until the CEC changes that Hans has talked about have hit mainline
>> and I've had a chance to rework this for those.  We're waiting on Mauro
>> for that at the moment.
>>
>> (I do find it rather frustrating that CEC seems to evolve very rapidly,
>> it makes it quite difficult to publish a patch set, and get it merged.)
>>
> 
> Should we really wait until I push the Amlogic AO CEC driver ? Having a
> notifier in the DW-HDMI driver won't harm anybody since it *will be used*.

I'm OK with the notifier in this case.

Regards,

	Hans

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 2/4] drm/bridge: dw-hdmi: add cec notifier support
  2017-06-09 13:56         ` Neil Armstrong
@ 2017-06-09 14:10           ` Russell King - ARM Linux
  -1 siblings, 0 replies; 84+ messages in thread
From: Russell King - ARM Linux @ 2017-06-09 14:10 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jun 09, 2017 at 03:56:39PM +0200, Neil Armstrong wrote:
> Yes, but on the Amlogic Meson plarform, the DW-HDMI CEC controller is
> not used, but a custom one, so this notifier is actually useful for
> this platform and maybe others.

Is the CEC controller configured into dw-hdmi (is the config bit set?)
I'm just wondering if we're going to end up with two CEC drivers trying
to bind to the same notifier.

> Should we really wait until I push the Amlogic AO CEC driver ? Having a
> notifier in the DW-HDMI driver won't harm anybody since it *will be used*.

It sounds like this adds additional information that has been missing
from the review of my patches - and I suspect changes Hans' comments.
So, I'll wait, it seems pointless to try and update the patches when
it's not clear how to proceed due to other dependencies, especially
when it means that their existing state is what's required (I'm pleased
that I've held off modifying the patches so far.)

If that means having to wait another kernel revision, then I guess that's
what will have to happen.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH 2/4] drm/bridge: dw-hdmi: add cec notifier support
@ 2017-06-09 14:10           ` Russell King - ARM Linux
  0 siblings, 0 replies; 84+ messages in thread
From: Russell King - ARM Linux @ 2017-06-09 14:10 UTC (permalink / raw)
  To: Neil Armstrong
  Cc: Hans Verkuil, David Airlie, Archit Taneja, dri-devel, linux-arm-kernel

On Fri, Jun 09, 2017 at 03:56:39PM +0200, Neil Armstrong wrote:
> Yes, but on the Amlogic Meson plarform, the DW-HDMI CEC controller is
> not used, but a custom one, so this notifier is actually useful for
> this platform and maybe others.

Is the CEC controller configured into dw-hdmi (is the config bit set?)
I'm just wondering if we're going to end up with two CEC drivers trying
to bind to the same notifier.

> Should we really wait until I push the Amlogic AO CEC driver ? Having a
> notifier in the DW-HDMI driver won't harm anybody since it *will be used*.

It sounds like this adds additional information that has been missing
from the review of my patches - and I suspect changes Hans' comments.
So, I'll wait, it seems pointless to try and update the patches when
it's not clear how to proceed due to other dependencies, especially
when it means that their existing state is what's required (I'm pleased
that I've held off modifying the patches so far.)

If that means having to wait another kernel revision, then I guess that's
what will have to happen.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 1/4] drm/bridge: dw-hdmi: remove CEC engine register definitions
  2017-05-30 14:23   ` Russell King
@ 2017-06-09 14:24     ` Hans Verkuil
  -1 siblings, 0 replies; 84+ messages in thread
From: Hans Verkuil @ 2017-06-09 14:24 UTC (permalink / raw)
  To: linux-arm-kernel

On 30/05/17 16:23, Russell King wrote:
> We don't need the CEC engine register definitions, so let's remove them.
> 
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>

Acked-by: Hans Verkuil <hans.verkuil@cisco.com>

Regards,

	Hans

> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.h | 45 -------------------------------
>  1 file changed, 45 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
> index c59f87e1483e..091831e4f9d5 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
> @@ -478,51 +478,6 @@
>  #define HDMI_A_PRESETUP                         0x501A
>  #define HDMI_A_SRM_BASE                         0x5020
>  
> -/* CEC Engine Registers */
> -#define HDMI_CEC_CTRL                           0x7D00
> -#define HDMI_CEC_STAT                           0x7D01
> -#define HDMI_CEC_MASK                           0x7D02
> -#define HDMI_CEC_POLARITY                       0x7D03
> -#define HDMI_CEC_INT                            0x7D04
> -#define HDMI_CEC_ADDR_L                         0x7D05
> -#define HDMI_CEC_ADDR_H                         0x7D06
> -#define HDMI_CEC_TX_CNT                         0x7D07
> -#define HDMI_CEC_RX_CNT                         0x7D08
> -#define HDMI_CEC_TX_DATA0                       0x7D10
> -#define HDMI_CEC_TX_DATA1                       0x7D11
> -#define HDMI_CEC_TX_DATA2                       0x7D12
> -#define HDMI_CEC_TX_DATA3                       0x7D13
> -#define HDMI_CEC_TX_DATA4                       0x7D14
> -#define HDMI_CEC_TX_DATA5                       0x7D15
> -#define HDMI_CEC_TX_DATA6                       0x7D16
> -#define HDMI_CEC_TX_DATA7                       0x7D17
> -#define HDMI_CEC_TX_DATA8                       0x7D18
> -#define HDMI_CEC_TX_DATA9                       0x7D19
> -#define HDMI_CEC_TX_DATA10                      0x7D1a
> -#define HDMI_CEC_TX_DATA11                      0x7D1b
> -#define HDMI_CEC_TX_DATA12                      0x7D1c
> -#define HDMI_CEC_TX_DATA13                      0x7D1d
> -#define HDMI_CEC_TX_DATA14                      0x7D1e
> -#define HDMI_CEC_TX_DATA15                      0x7D1f
> -#define HDMI_CEC_RX_DATA0                       0x7D20
> -#define HDMI_CEC_RX_DATA1                       0x7D21
> -#define HDMI_CEC_RX_DATA2                       0x7D22
> -#define HDMI_CEC_RX_DATA3                       0x7D23
> -#define HDMI_CEC_RX_DATA4                       0x7D24
> -#define HDMI_CEC_RX_DATA5                       0x7D25
> -#define HDMI_CEC_RX_DATA6                       0x7D26
> -#define HDMI_CEC_RX_DATA7                       0x7D27
> -#define HDMI_CEC_RX_DATA8                       0x7D28
> -#define HDMI_CEC_RX_DATA9                       0x7D29
> -#define HDMI_CEC_RX_DATA10                      0x7D2a
> -#define HDMI_CEC_RX_DATA11                      0x7D2b
> -#define HDMI_CEC_RX_DATA12                      0x7D2c
> -#define HDMI_CEC_RX_DATA13                      0x7D2d
> -#define HDMI_CEC_RX_DATA14                      0x7D2e
> -#define HDMI_CEC_RX_DATA15                      0x7D2f
> -#define HDMI_CEC_LOCK                           0x7D30
> -#define HDMI_CEC_WKUPCTRL                       0x7D31
> -
>  /* I2C Master Registers (E-DDC) */
>  #define HDMI_I2CM_SLAVE                         0x7E00
>  #define HDMI_I2CM_ADDRESS                       0x7E01
> 

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH 1/4] drm/bridge: dw-hdmi: remove CEC engine register definitions
@ 2017-06-09 14:24     ` Hans Verkuil
  0 siblings, 0 replies; 84+ messages in thread
From: Hans Verkuil @ 2017-06-09 14:24 UTC (permalink / raw)
  To: Russell King; +Cc: linux-arm-kernel, dri-devel

On 30/05/17 16:23, Russell King wrote:
> We don't need the CEC engine register definitions, so let's remove them.
> 
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>

Acked-by: Hans Verkuil <hans.verkuil@cisco.com>

Regards,

	Hans

> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.h | 45 -------------------------------
>  1 file changed, 45 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
> index c59f87e1483e..091831e4f9d5 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
> @@ -478,51 +478,6 @@
>  #define HDMI_A_PRESETUP                         0x501A
>  #define HDMI_A_SRM_BASE                         0x5020
>  
> -/* CEC Engine Registers */
> -#define HDMI_CEC_CTRL                           0x7D00
> -#define HDMI_CEC_STAT                           0x7D01
> -#define HDMI_CEC_MASK                           0x7D02
> -#define HDMI_CEC_POLARITY                       0x7D03
> -#define HDMI_CEC_INT                            0x7D04
> -#define HDMI_CEC_ADDR_L                         0x7D05
> -#define HDMI_CEC_ADDR_H                         0x7D06
> -#define HDMI_CEC_TX_CNT                         0x7D07
> -#define HDMI_CEC_RX_CNT                         0x7D08
> -#define HDMI_CEC_TX_DATA0                       0x7D10
> -#define HDMI_CEC_TX_DATA1                       0x7D11
> -#define HDMI_CEC_TX_DATA2                       0x7D12
> -#define HDMI_CEC_TX_DATA3                       0x7D13
> -#define HDMI_CEC_TX_DATA4                       0x7D14
> -#define HDMI_CEC_TX_DATA5                       0x7D15
> -#define HDMI_CEC_TX_DATA6                       0x7D16
> -#define HDMI_CEC_TX_DATA7                       0x7D17
> -#define HDMI_CEC_TX_DATA8                       0x7D18
> -#define HDMI_CEC_TX_DATA9                       0x7D19
> -#define HDMI_CEC_TX_DATA10                      0x7D1a
> -#define HDMI_CEC_TX_DATA11                      0x7D1b
> -#define HDMI_CEC_TX_DATA12                      0x7D1c
> -#define HDMI_CEC_TX_DATA13                      0x7D1d
> -#define HDMI_CEC_TX_DATA14                      0x7D1e
> -#define HDMI_CEC_TX_DATA15                      0x7D1f
> -#define HDMI_CEC_RX_DATA0                       0x7D20
> -#define HDMI_CEC_RX_DATA1                       0x7D21
> -#define HDMI_CEC_RX_DATA2                       0x7D22
> -#define HDMI_CEC_RX_DATA3                       0x7D23
> -#define HDMI_CEC_RX_DATA4                       0x7D24
> -#define HDMI_CEC_RX_DATA5                       0x7D25
> -#define HDMI_CEC_RX_DATA6                       0x7D26
> -#define HDMI_CEC_RX_DATA7                       0x7D27
> -#define HDMI_CEC_RX_DATA8                       0x7D28
> -#define HDMI_CEC_RX_DATA9                       0x7D29
> -#define HDMI_CEC_RX_DATA10                      0x7D2a
> -#define HDMI_CEC_RX_DATA11                      0x7D2b
> -#define HDMI_CEC_RX_DATA12                      0x7D2c
> -#define HDMI_CEC_RX_DATA13                      0x7D2d
> -#define HDMI_CEC_RX_DATA14                      0x7D2e
> -#define HDMI_CEC_RX_DATA15                      0x7D2f
> -#define HDMI_CEC_LOCK                           0x7D30
> -#define HDMI_CEC_WKUPCTRL                       0x7D31
> -
>  /* I2C Master Registers (E-DDC) */
>  #define HDMI_I2CM_SLAVE                         0x7E00
>  #define HDMI_I2CM_ADDRESS                       0x7E01
> 

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 2/4] drm/bridge: dw-hdmi: add cec notifier support
  2017-05-30 14:23   ` Russell King
@ 2017-06-09 14:27     ` Hans Verkuil
  -1 siblings, 0 replies; 84+ messages in thread
From: Hans Verkuil @ 2017-06-09 14:27 UTC (permalink / raw)
  To: linux-arm-kernel

On 30/05/17 16:23, Russell King wrote:
> Add CEC notifier support to the HDMI bridge driver, so that the CEC
> part of the IP can receive its physical address.
> 
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>

Given the fact that there are devices that do not use the built-in dw-hdmi
CEC IP but something else, using a notifier here makes a lot of sense.

So:

Acked-by: Hans Verkuil <hans.verkuil@cisco.com>

Regards,

	Hans

> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 22 +++++++++++++++++++++-
>  1 file changed, 21 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 4e1f54a675d8..966422576c44 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -36,7 +36,10 @@
>  #include "dw-hdmi.h"
>  #include "dw-hdmi-audio.h"
>  
> +#include <media/cec-notifier.h>
> +
>  #define DDC_SEGMENT_ADDR	0x30
> +
>  #define HDMI_EDID_LEN		512
>  
>  enum hdmi_datamap {
> @@ -173,6 +176,8 @@ struct dw_hdmi {
>  
>  	unsigned int reg_shift;
>  	struct regmap *regm;
> +
> +	struct cec_notifier *cec_notifier;
>  };
>  
>  #define HDMI_IH_PHY_STAT0_RX_SENSE \
> @@ -1870,6 +1875,7 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
>  		hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
>  		hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
>  		drm_mode_connector_update_edid_property(connector, edid);
> +		cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
>  		ret = drm_add_edid_modes(connector, edid);
>  		/* Store the ELD */
>  		drm_edid_to_eld(connector, edid);
> @@ -2108,11 +2114,16 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
>  	 * ask the source to re-read the EDID.
>  	 */
>  	if (intr_stat &
> -	    (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD))
> +	    (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) {
>  		__dw_hdmi_setup_rx_sense(hdmi,
>  					 phy_stat & HDMI_PHY_HPD,
>  					 phy_stat & HDMI_PHY_RX_SENSE);
>  
> +		if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0)
> +			cec_notifier_set_phys_addr(hdmi->cec_notifier,
> +						   CEC_PHYS_ADDR_INVALID);
> +	}
> +
>  	if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
>  		dev_dbg(hdmi->dev, "EVENT=%s\n",
>  			phy_int_pol & HDMI_PHY_HPD ? "plugin" : "plugout");
> @@ -2365,6 +2376,12 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  	if (ret)
>  		goto err_iahb;
>  
> +	hdmi->cec_notifier = cec_notifier_get(dev);
> +	if (!hdmi->cec_notifier) {
> +		ret = -ENOMEM;
> +		goto err_iahb;
> +	}
> +
>  	/*
>  	 * To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator
>  	 * N and cts values before enabling phy
> @@ -2437,6 +2454,9 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  		hdmi->ddc = NULL;
>  	}
>  
> +	if (hdmi->cec_notifier)
> +		cec_notifier_put(hdmi->cec_notifier);
> +
>  	clk_disable_unprepare(hdmi->iahb_clk);
>  err_isfr:
>  	clk_disable_unprepare(hdmi->isfr_clk);
> 

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH 2/4] drm/bridge: dw-hdmi: add cec notifier support
@ 2017-06-09 14:27     ` Hans Verkuil
  0 siblings, 0 replies; 84+ messages in thread
From: Hans Verkuil @ 2017-06-09 14:27 UTC (permalink / raw)
  To: Russell King; +Cc: linux-arm-kernel, dri-devel, Neil Armstrong

On 30/05/17 16:23, Russell King wrote:
> Add CEC notifier support to the HDMI bridge driver, so that the CEC
> part of the IP can receive its physical address.
> 
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>

Given the fact that there are devices that do not use the built-in dw-hdmi
CEC IP but something else, using a notifier here makes a lot of sense.

So:

Acked-by: Hans Verkuil <hans.verkuil@cisco.com>

Regards,

	Hans

> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 22 +++++++++++++++++++++-
>  1 file changed, 21 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 4e1f54a675d8..966422576c44 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -36,7 +36,10 @@
>  #include "dw-hdmi.h"
>  #include "dw-hdmi-audio.h"
>  
> +#include <media/cec-notifier.h>
> +
>  #define DDC_SEGMENT_ADDR	0x30
> +
>  #define HDMI_EDID_LEN		512
>  
>  enum hdmi_datamap {
> @@ -173,6 +176,8 @@ struct dw_hdmi {
>  
>  	unsigned int reg_shift;
>  	struct regmap *regm;
> +
> +	struct cec_notifier *cec_notifier;
>  };
>  
>  #define HDMI_IH_PHY_STAT0_RX_SENSE \
> @@ -1870,6 +1875,7 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
>  		hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
>  		hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
>  		drm_mode_connector_update_edid_property(connector, edid);
> +		cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
>  		ret = drm_add_edid_modes(connector, edid);
>  		/* Store the ELD */
>  		drm_edid_to_eld(connector, edid);
> @@ -2108,11 +2114,16 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
>  	 * ask the source to re-read the EDID.
>  	 */
>  	if (intr_stat &
> -	    (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD))
> +	    (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) {
>  		__dw_hdmi_setup_rx_sense(hdmi,
>  					 phy_stat & HDMI_PHY_HPD,
>  					 phy_stat & HDMI_PHY_RX_SENSE);
>  
> +		if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0)
> +			cec_notifier_set_phys_addr(hdmi->cec_notifier,
> +						   CEC_PHYS_ADDR_INVALID);
> +	}
> +
>  	if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
>  		dev_dbg(hdmi->dev, "EVENT=%s\n",
>  			phy_int_pol & HDMI_PHY_HPD ? "plugin" : "plugout");
> @@ -2365,6 +2376,12 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  	if (ret)
>  		goto err_iahb;
>  
> +	hdmi->cec_notifier = cec_notifier_get(dev);
> +	if (!hdmi->cec_notifier) {
> +		ret = -ENOMEM;
> +		goto err_iahb;
> +	}
> +
>  	/*
>  	 * To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator
>  	 * N and cts values before enabling phy
> @@ -2437,6 +2454,9 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  		hdmi->ddc = NULL;
>  	}
>  
> +	if (hdmi->cec_notifier)
> +		cec_notifier_put(hdmi->cec_notifier);
> +
>  	clk_disable_unprepare(hdmi->iahb_clk);
>  err_isfr:
>  	clk_disable_unprepare(hdmi->isfr_clk);
> 

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 3/4] drm/bridge: dw-hdmi: add better clock disable control
  2017-05-30 14:23   ` Russell King
@ 2017-06-09 14:28     ` Hans Verkuil
  -1 siblings, 0 replies; 84+ messages in thread
From: Hans Verkuil @ 2017-06-09 14:28 UTC (permalink / raw)
  To: linux-arm-kernel

On 30/05/17 16:23, Russell King wrote:
> The video setup path aways sets the clock disable register to a specific
> value, which has the effect of disabling the CEC engine.  When we add the
> CEC driver, this becomes a problem.
> 
> Fix this by only setting/clearing the bits that the video path needs to.
> 
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>

For what it is worth:

Acked-by: Hans Verkuil <hans.verkuil@cisco.com>

Regards,

	Hans

> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 25 +++++++++++++++----------
>  1 file changed, 15 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 966422576c44..58781d4c1034 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -166,6 +166,7 @@ struct dw_hdmi {
>  	bool bridge_is_on;		/* indicates the bridge is on */
>  	bool rxsense;			/* rxsense state */
>  	u8 phy_mask;			/* desired phy int mask settings */
> +	u8 mc_clkdis;			/* clock disable register */
>  
>  	spinlock_t audio_lock;
>  	struct mutex audio_mutex;
> @@ -1543,8 +1544,6 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
>  /* HDMI Initialization Step B.4 */
>  static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
>  {
> -	u8 clkdis;
> -
>  	/* control period minimum duration */
>  	hdmi_writeb(hdmi, 12, HDMI_FC_CTRLDUR);
>  	hdmi_writeb(hdmi, 32, HDMI_FC_EXCTRLDUR);
> @@ -1556,17 +1555,21 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
>  	hdmi_writeb(hdmi, 0x21, HDMI_FC_CH2PREAM);
>  
>  	/* Enable pixel clock and tmds data path */
> -	clkdis = 0x7F;
> -	clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
> -	hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
> +	hdmi->mc_clkdis |= HDMI_MC_CLKDIS_HDCPCLK_DISABLE |
> +			   HDMI_MC_CLKDIS_CSCCLK_DISABLE |
> +			   HDMI_MC_CLKDIS_AUDCLK_DISABLE |
> +			   HDMI_MC_CLKDIS_PREPCLK_DISABLE |
> +			   HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
> +	hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
> +	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
>  
> -	clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
> -	hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
> +	hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
> +	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
>  
>  	/* Enable csc path */
>  	if (is_color_space_conversion(hdmi)) {
> -		clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
> -		hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
> +		hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
> +		hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
>  	}
>  
>  	/* Enable color space conversion if needed */
> @@ -1580,7 +1583,8 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
>  
>  static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi)
>  {
> -	hdmi_modb(hdmi, 0, HDMI_MC_CLKDIS_AUDCLK_DISABLE, HDMI_MC_CLKDIS);
> +	hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_AUDCLK_DISABLE;
> +	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
>  }
>  
>  /* Workaround to clear the overflow condition */
> @@ -2261,6 +2265,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  	hdmi->disabled = true;
>  	hdmi->rxsense = true;
>  	hdmi->phy_mask = (u8)~(HDMI_PHY_HPD | HDMI_PHY_RX_SENSE);
> +	hdmi->mc_clkdis = 0x7f;
>  
>  	mutex_init(&hdmi->mutex);
>  	mutex_init(&hdmi->audio_mutex);
> 

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH 3/4] drm/bridge: dw-hdmi: add better clock disable control
@ 2017-06-09 14:28     ` Hans Verkuil
  0 siblings, 0 replies; 84+ messages in thread
From: Hans Verkuil @ 2017-06-09 14:28 UTC (permalink / raw)
  To: Russell King; +Cc: linux-arm-kernel, dri-devel, Neil Armstrong

On 30/05/17 16:23, Russell King wrote:
> The video setup path aways sets the clock disable register to a specific
> value, which has the effect of disabling the CEC engine.  When we add the
> CEC driver, this becomes a problem.
> 
> Fix this by only setting/clearing the bits that the video path needs to.
> 
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>

For what it is worth:

Acked-by: Hans Verkuil <hans.verkuil@cisco.com>

Regards,

	Hans

> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 25 +++++++++++++++----------
>  1 file changed, 15 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 966422576c44..58781d4c1034 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -166,6 +166,7 @@ struct dw_hdmi {
>  	bool bridge_is_on;		/* indicates the bridge is on */
>  	bool rxsense;			/* rxsense state */
>  	u8 phy_mask;			/* desired phy int mask settings */
> +	u8 mc_clkdis;			/* clock disable register */
>  
>  	spinlock_t audio_lock;
>  	struct mutex audio_mutex;
> @@ -1543,8 +1544,6 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
>  /* HDMI Initialization Step B.4 */
>  static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
>  {
> -	u8 clkdis;
> -
>  	/* control period minimum duration */
>  	hdmi_writeb(hdmi, 12, HDMI_FC_CTRLDUR);
>  	hdmi_writeb(hdmi, 32, HDMI_FC_EXCTRLDUR);
> @@ -1556,17 +1555,21 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
>  	hdmi_writeb(hdmi, 0x21, HDMI_FC_CH2PREAM);
>  
>  	/* Enable pixel clock and tmds data path */
> -	clkdis = 0x7F;
> -	clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
> -	hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
> +	hdmi->mc_clkdis |= HDMI_MC_CLKDIS_HDCPCLK_DISABLE |
> +			   HDMI_MC_CLKDIS_CSCCLK_DISABLE |
> +			   HDMI_MC_CLKDIS_AUDCLK_DISABLE |
> +			   HDMI_MC_CLKDIS_PREPCLK_DISABLE |
> +			   HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
> +	hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
> +	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
>  
> -	clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
> -	hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
> +	hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
> +	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
>  
>  	/* Enable csc path */
>  	if (is_color_space_conversion(hdmi)) {
> -		clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
> -		hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
> +		hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
> +		hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
>  	}
>  
>  	/* Enable color space conversion if needed */
> @@ -1580,7 +1583,8 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
>  
>  static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi)
>  {
> -	hdmi_modb(hdmi, 0, HDMI_MC_CLKDIS_AUDCLK_DISABLE, HDMI_MC_CLKDIS);
> +	hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_AUDCLK_DISABLE;
> +	hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
>  }
>  
>  /* Workaround to clear the overflow condition */
> @@ -2261,6 +2265,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
>  	hdmi->disabled = true;
>  	hdmi->rxsense = true;
>  	hdmi->phy_mask = (u8)~(HDMI_PHY_HPD | HDMI_PHY_RX_SENSE);
> +	hdmi->mc_clkdis = 0x7f;
>  
>  	mutex_init(&hdmi->mutex);
>  	mutex_init(&hdmi->audio_mutex);
> 

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 2/4] drm/bridge: dw-hdmi: add cec notifier support
  2017-06-09 14:10           ` Russell King - ARM Linux
@ 2017-06-09 14:38             ` Hans Verkuil
  -1 siblings, 0 replies; 84+ messages in thread
From: Hans Verkuil @ 2017-06-09 14:38 UTC (permalink / raw)
  To: linux-arm-kernel

On 09/06/17 16:10, Russell King - ARM Linux wrote:
> On Fri, Jun 09, 2017 at 03:56:39PM +0200, Neil Armstrong wrote:
>> Yes, but on the Amlogic Meson plarform, the DW-HDMI CEC controller is
>> not used, but a custom one, so this notifier is actually useful for
>> this platform and maybe others.
> 
> Is the CEC controller configured into dw-hdmi (is the config bit set?)
> I'm just wondering if we're going to end up with two CEC drivers trying
> to bind to the same notifier.
> 
>> Should we really wait until I push the Amlogic AO CEC driver ? Having a
>> notifier in the DW-HDMI driver won't harm anybody since it *will be used*.
> 
> It sounds like this adds additional information that has been missing
> from the review of my patches - and I suspect changes Hans' comments.
> So, I'll wait, it seems pointless to try and update the patches when
> it's not clear how to proceed due to other dependencies, especially
> when it means that their existing state is what's required (I'm pleased
> that I've held off modifying the patches so far.)
> 
> If that means having to wait another kernel revision, then I guess that's
> what will have to happen.
> 

I've Acked patches 1-3. Patch 4 can be rebased on top of the latest mainline
and just ignore any notifier-related comments I made in my review of this
patch.

I have no problem with patches 1-3 being merged now.

Regards,

	Hans

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH 2/4] drm/bridge: dw-hdmi: add cec notifier support
@ 2017-06-09 14:38             ` Hans Verkuil
  0 siblings, 0 replies; 84+ messages in thread
From: Hans Verkuil @ 2017-06-09 14:38 UTC (permalink / raw)
  To: Russell King - ARM Linux, Neil Armstrong; +Cc: dri-devel, linux-arm-kernel

On 09/06/17 16:10, Russell King - ARM Linux wrote:
> On Fri, Jun 09, 2017 at 03:56:39PM +0200, Neil Armstrong wrote:
>> Yes, but on the Amlogic Meson plarform, the DW-HDMI CEC controller is
>> not used, but a custom one, so this notifier is actually useful for
>> this platform and maybe others.
> 
> Is the CEC controller configured into dw-hdmi (is the config bit set?)
> I'm just wondering if we're going to end up with two CEC drivers trying
> to bind to the same notifier.
> 
>> Should we really wait until I push the Amlogic AO CEC driver ? Having a
>> notifier in the DW-HDMI driver won't harm anybody since it *will be used*.
> 
> It sounds like this adds additional information that has been missing
> from the review of my patches - and I suspect changes Hans' comments.
> So, I'll wait, it seems pointless to try and update the patches when
> it's not clear how to proceed due to other dependencies, especially
> when it means that their existing state is what's required (I'm pleased
> that I've held off modifying the patches so far.)
> 
> If that means having to wait another kernel revision, then I guess that's
> what will have to happen.
> 

I've Acked patches 1-3. Patch 4 can be rebased on top of the latest mainline
and just ignore any notifier-related comments I made in my review of this
patch.

I have no problem with patches 1-3 being merged now.

Regards,

	Hans
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver
  2017-06-01  8:31     ` Hans Verkuil
@ 2017-06-12  8:42       ` Hans Verkuil
  -1 siblings, 0 replies; 84+ messages in thread
From: Hans Verkuil @ 2017-06-12  8:42 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/01/2017 10:31 AM, Hans Verkuil wrote:
> Hi Russell,
> 
> First a few top-level questions:
> 
> 1) What was the reason for using the cec-notifier here? Isn't this
>     tightly integrated into the main dw-hdmi block? For the tda driver
>     it is clearly required, but for tightly coupled HDMI & CEC HW I
>     just create the adapter from the HDMI driver. As a small bonus it
>     avoids adding the cec-notifier code and the control flow is a bit
>     easier to trace.
> 
> 2) I may have asked this before, apologies if I repeat myself: does
>     this CEC implementation support CEC monitoring (aka snooping)? If
>     it does, then I recommend that it is implemented since it is very
>     useful.
> 
> 3) Is the CEC still active if there is no hotplug signal? Or is it
>     powered off in that case? Ideally it should still be possible to
>     send CEC messages even if there is no hotplug. This is explicitly
>     allowed by the CEC 2.0 spec to wake up displays that turn off the
>     HPD, but that still have a working CEC controller.
> 
>     If this is not possible, then you need to use the CEC_CAP_NEEDS_HPD
>     capability. See: https://patchwork.linuxtv.org/patch/41478/
> 
>     This will almost certainly be merged for 4.13 since other CEC drivers
>     need this as well.

FYI: I tested your patch series with my cubox-i and CEC doesn't work if there
is no HPD. I fiddles around a bit in dw_hdmi.c to prevent it from powering off
the HDMI and PHY, but without any luck. It could be a hardware issue on the
cubox-i (e.g. a level-shifter that powers off when the HPD goes low, although
I don't see anything like that in the schematics), or it can be a driver issue
or a Synopsys IP issue. I really can't tell.

I added text in my status document (https://hverkuil.home.xs4all.nl/cec-status.txt)
at the end on how to test this.

Otherwise the CEC support on the cubox-i was working very well.

Regards,

	Hans

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver
@ 2017-06-12  8:42       ` Hans Verkuil
  0 siblings, 0 replies; 84+ messages in thread
From: Hans Verkuil @ 2017-06-12  8:42 UTC (permalink / raw)
  To: Russell King; +Cc: dri-devel, linux-arm-kernel

On 06/01/2017 10:31 AM, Hans Verkuil wrote:
> Hi Russell,
> 
> First a few top-level questions:
> 
> 1) What was the reason for using the cec-notifier here? Isn't this
>     tightly integrated into the main dw-hdmi block? For the tda driver
>     it is clearly required, but for tightly coupled HDMI & CEC HW I
>     just create the adapter from the HDMI driver. As a small bonus it
>     avoids adding the cec-notifier code and the control flow is a bit
>     easier to trace.
> 
> 2) I may have asked this before, apologies if I repeat myself: does
>     this CEC implementation support CEC monitoring (aka snooping)? If
>     it does, then I recommend that it is implemented since it is very
>     useful.
> 
> 3) Is the CEC still active if there is no hotplug signal? Or is it
>     powered off in that case? Ideally it should still be possible to
>     send CEC messages even if there is no hotplug. This is explicitly
>     allowed by the CEC 2.0 spec to wake up displays that turn off the
>     HPD, but that still have a working CEC controller.
> 
>     If this is not possible, then you need to use the CEC_CAP_NEEDS_HPD
>     capability. See: https://patchwork.linuxtv.org/patch/41478/
> 
>     This will almost certainly be merged for 4.13 since other CEC drivers
>     need this as well.

FYI: I tested your patch series with my cubox-i and CEC doesn't work if there
is no HPD. I fiddles around a bit in dw_hdmi.c to prevent it from powering off
the HDMI and PHY, but without any luck. It could be a hardware issue on the
cubox-i (e.g. a level-shifter that powers off when the HPD goes low, although
I don't see anything like that in the schematics), or it can be a driver issue
or a Synopsys IP issue. I really can't tell.

I added text in my status document (https://hverkuil.home.xs4all.nl/cec-status.txt)
at the end on how to test this.

Otherwise the CEC support on the cubox-i was working very well.

Regards,

	Hans
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 2/4] drm/bridge: dw-hdmi: add cec notifier support
  2017-06-09 14:10           ` Russell King - ARM Linux
@ 2017-07-17  8:56             ` Hans Verkuil
  -1 siblings, 0 replies; 84+ messages in thread
From: Hans Verkuil @ 2017-07-17  8:56 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Russell,

On 09/06/17 16:10, Russell King - ARM Linux wrote:
> On Fri, Jun 09, 2017 at 03:56:39PM +0200, Neil Armstrong wrote:
>> Yes, but on the Amlogic Meson plarform, the DW-HDMI CEC controller is
>> not used, but a custom one, so this notifier is actually useful for
>> this platform and maybe others.
> 
> Is the CEC controller configured into dw-hdmi (is the config bit set?)
> I'm just wondering if we're going to end up with two CEC drivers trying
> to bind to the same notifier.
> 
>> Should we really wait until I push the Amlogic AO CEC driver ? Having a
>> notifier in the DW-HDMI driver won't harm anybody since it *will be used*.
> 
> It sounds like this adds additional information that has been missing
> from the review of my patches - and I suspect changes Hans' comments.
> So, I'll wait, it seems pointless to try and update the patches when
> it's not clear how to proceed due to other dependencies, especially
> when it means that their existing state is what's required (I'm pleased
> that I've held off modifying the patches so far.)
> 
> If that means having to wait another kernel revision, then I guess that's
> what will have to happen.

Can you respin your patch series, keeping the notifier support? The CEC
kernel config handling has been cleaned up (just select CEC_CORE and
CEC_NOTIFIER) so you should be good to go.

I've already Acked patches 1-3. I had some comments for patch 4, so that
needs a bit more work.

Note that there is now a cec_transmit_attempt_done() helper function that
will simplify your code.

Regards,

	Hans

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH 2/4] drm/bridge: dw-hdmi: add cec notifier support
@ 2017-07-17  8:56             ` Hans Verkuil
  0 siblings, 0 replies; 84+ messages in thread
From: Hans Verkuil @ 2017-07-17  8:56 UTC (permalink / raw)
  To: Russell King - ARM Linux, Neil Armstrong; +Cc: linux-arm-kernel, dri-devel

Hi Russell,

On 09/06/17 16:10, Russell King - ARM Linux wrote:
> On Fri, Jun 09, 2017 at 03:56:39PM +0200, Neil Armstrong wrote:
>> Yes, but on the Amlogic Meson plarform, the DW-HDMI CEC controller is
>> not used, but a custom one, so this notifier is actually useful for
>> this platform and maybe others.
> 
> Is the CEC controller configured into dw-hdmi (is the config bit set?)
> I'm just wondering if we're going to end up with two CEC drivers trying
> to bind to the same notifier.
> 
>> Should we really wait until I push the Amlogic AO CEC driver ? Having a
>> notifier in the DW-HDMI driver won't harm anybody since it *will be used*.
> 
> It sounds like this adds additional information that has been missing
> from the review of my patches - and I suspect changes Hans' comments.
> So, I'll wait, it seems pointless to try and update the patches when
> it's not clear how to proceed due to other dependencies, especially
> when it means that their existing state is what's required (I'm pleased
> that I've held off modifying the patches so far.)
> 
> If that means having to wait another kernel revision, then I guess that's
> what will have to happen.

Can you respin your patch series, keeping the notifier support? The CEC
kernel config handling has been cleaned up (just select CEC_CORE and
CEC_NOTIFIER) so you should be good to go.

I've already Acked patches 1-3. I had some comments for patch 4, so that
needs a bit more work.

Note that there is now a cec_transmit_attempt_done() helper function that
will simplify your code.

Regards,

	Hans
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 2/4] drm/bridge: dw-hdmi: add cec notifier support
  2017-07-17  8:56             ` Hans Verkuil
@ 2017-07-17  9:05               ` Russell King - ARM Linux
  -1 siblings, 0 replies; 84+ messages in thread
From: Russell King - ARM Linux @ 2017-07-17  9:05 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jul 17, 2017 at 10:56:47AM +0200, Hans Verkuil wrote:
> Hi Russell,
> 
> On 09/06/17 16:10, Russell King - ARM Linux wrote:
> > On Fri, Jun 09, 2017 at 03:56:39PM +0200, Neil Armstrong wrote:
> >> Yes, but on the Amlogic Meson plarform, the DW-HDMI CEC controller is
> >> not used, but a custom one, so this notifier is actually useful for
> >> this platform and maybe others.
> > 
> > Is the CEC controller configured into dw-hdmi (is the config bit set?)
> > I'm just wondering if we're going to end up with two CEC drivers trying
> > to bind to the same notifier.
> > 
> >> Should we really wait until I push the Amlogic AO CEC driver ? Having a
> >> notifier in the DW-HDMI driver won't harm anybody since it *will be used*.
> > 
> > It sounds like this adds additional information that has been missing
> > from the review of my patches - and I suspect changes Hans' comments.
> > So, I'll wait, it seems pointless to try and update the patches when
> > it's not clear how to proceed due to other dependencies, especially
> > when it means that their existing state is what's required (I'm pleased
> > that I've held off modifying the patches so far.)
> > 
> > If that means having to wait another kernel revision, then I guess that's
> > what will have to happen.
> 
> Can you respin your patch series, keeping the notifier support? The CEC
> kernel config handling has been cleaned up (just select CEC_CORE and
> CEC_NOTIFIER) so you should be good to go.

Not yet - the change to the way you're dealing with Kconfig in CEC is
fundamentally broken, and needs fixing before we can merge dw-hdmi-cec
support.

As a result of these Kconfig changes, dw-hdmi-cec now fails if:

1. You build the CEC part as a module
2. You build the HDMI part into the kernel

This results in CEC_NOTIFIER=y and CEC_CORE=m, which, when the HDMI part
gets built, results in the stubs in the notifier code being used, rather
than the real functions.  This in turn causes the CEC part to never
receive a physical address, which is therefore non-functional.

I did have a patch to fix this, but it was never committed, and I got
busy with other stuff (so it ended up being git reset --hard away.)

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH 2/4] drm/bridge: dw-hdmi: add cec notifier support
@ 2017-07-17  9:05               ` Russell King - ARM Linux
  0 siblings, 0 replies; 84+ messages in thread
From: Russell King - ARM Linux @ 2017-07-17  9:05 UTC (permalink / raw)
  To: Hans Verkuil; +Cc: linux-arm-kernel, dri-devel, Neil Armstrong

On Mon, Jul 17, 2017 at 10:56:47AM +0200, Hans Verkuil wrote:
> Hi Russell,
> 
> On 09/06/17 16:10, Russell King - ARM Linux wrote:
> > On Fri, Jun 09, 2017 at 03:56:39PM +0200, Neil Armstrong wrote:
> >> Yes, but on the Amlogic Meson plarform, the DW-HDMI CEC controller is
> >> not used, but a custom one, so this notifier is actually useful for
> >> this platform and maybe others.
> > 
> > Is the CEC controller configured into dw-hdmi (is the config bit set?)
> > I'm just wondering if we're going to end up with two CEC drivers trying
> > to bind to the same notifier.
> > 
> >> Should we really wait until I push the Amlogic AO CEC driver ? Having a
> >> notifier in the DW-HDMI driver won't harm anybody since it *will be used*.
> > 
> > It sounds like this adds additional information that has been missing
> > from the review of my patches - and I suspect changes Hans' comments.
> > So, I'll wait, it seems pointless to try and update the patches when
> > it's not clear how to proceed due to other dependencies, especially
> > when it means that their existing state is what's required (I'm pleased
> > that I've held off modifying the patches so far.)
> > 
> > If that means having to wait another kernel revision, then I guess that's
> > what will have to happen.
> 
> Can you respin your patch series, keeping the notifier support? The CEC
> kernel config handling has been cleaned up (just select CEC_CORE and
> CEC_NOTIFIER) so you should be good to go.

Not yet - the change to the way you're dealing with Kconfig in CEC is
fundamentally broken, and needs fixing before we can merge dw-hdmi-cec
support.

As a result of these Kconfig changes, dw-hdmi-cec now fails if:

1. You build the CEC part as a module
2. You build the HDMI part into the kernel

This results in CEC_NOTIFIER=y and CEC_CORE=m, which, when the HDMI part
gets built, results in the stubs in the notifier code being used, rather
than the real functions.  This in turn causes the CEC part to never
receive a physical address, which is therefore non-functional.

I did have a patch to fix this, but it was never committed, and I got
busy with other stuff (so it ended up being git reset --hard away.)

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 2/4] drm/bridge: dw-hdmi: add cec notifier support
  2017-07-17  9:05               ` Russell King - ARM Linux
@ 2017-07-17 11:19                 ` Hans Verkuil
  -1 siblings, 0 replies; 84+ messages in thread
From: Hans Verkuil @ 2017-07-17 11:19 UTC (permalink / raw)
  To: linux-arm-kernel

On 17/07/17 11:05, Russell King - ARM Linux wrote:
> On Mon, Jul 17, 2017 at 10:56:47AM +0200, Hans Verkuil wrote:
>> Hi Russell,
>>
>> On 09/06/17 16:10, Russell King - ARM Linux wrote:
>>> On Fri, Jun 09, 2017 at 03:56:39PM +0200, Neil Armstrong wrote:
>>>> Yes, but on the Amlogic Meson plarform, the DW-HDMI CEC controller is
>>>> not used, but a custom one, so this notifier is actually useful for
>>>> this platform and maybe others.
>>>
>>> Is the CEC controller configured into dw-hdmi (is the config bit set?)
>>> I'm just wondering if we're going to end up with two CEC drivers trying
>>> to bind to the same notifier.
>>>
>>>> Should we really wait until I push the Amlogic AO CEC driver ? Having a
>>>> notifier in the DW-HDMI driver won't harm anybody since it *will be used*.
>>>
>>> It sounds like this adds additional information that has been missing
>>> from the review of my patches - and I suspect changes Hans' comments.
>>> So, I'll wait, it seems pointless to try and update the patches when
>>> it's not clear how to proceed due to other dependencies, especially
>>> when it means that their existing state is what's required (I'm pleased
>>> that I've held off modifying the patches so far.)
>>>
>>> If that means having to wait another kernel revision, then I guess that's
>>> what will have to happen.
>>
>> Can you respin your patch series, keeping the notifier support? The CEC
>> kernel config handling has been cleaned up (just select CEC_CORE and
>> CEC_NOTIFIER) so you should be good to go.
> 
> Not yet - the change to the way you're dealing with Kconfig in CEC is
> fundamentally broken, and needs fixing before we can merge dw-hdmi-cec
> support.
> 
> As a result of these Kconfig changes, dw-hdmi-cec now fails if:
> 
> 1. You build the CEC part as a module
> 2. You build the HDMI part into the kernel
> 
> This results in CEC_NOTIFIER=y and CEC_CORE=m, which, when the HDMI part
> gets built, results in the stubs in the notifier code being used, rather
> than the real functions.  This in turn causes the CEC part to never
> receive a physical address, which is therefore non-functional.
> 
> I did have a patch to fix this, but it was never committed, and I got
> busy with other stuff (so it ended up being git reset --hard away.)
> 

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH 2/4] drm/bridge: dw-hdmi: add cec notifier support
@ 2017-07-17 11:19                 ` Hans Verkuil
  0 siblings, 0 replies; 84+ messages in thread
From: Hans Verkuil @ 2017-07-17 11:19 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: linux-arm-kernel, dri-devel, Neil Armstrong

On 17/07/17 11:05, Russell King - ARM Linux wrote:
> On Mon, Jul 17, 2017 at 10:56:47AM +0200, Hans Verkuil wrote:
>> Hi Russell,
>>
>> On 09/06/17 16:10, Russell King - ARM Linux wrote:
>>> On Fri, Jun 09, 2017 at 03:56:39PM +0200, Neil Armstrong wrote:
>>>> Yes, but on the Amlogic Meson plarform, the DW-HDMI CEC controller is
>>>> not used, but a custom one, so this notifier is actually useful for
>>>> this platform and maybe others.
>>>
>>> Is the CEC controller configured into dw-hdmi (is the config bit set?)
>>> I'm just wondering if we're going to end up with two CEC drivers trying
>>> to bind to the same notifier.
>>>
>>>> Should we really wait until I push the Amlogic AO CEC driver ? Having a
>>>> notifier in the DW-HDMI driver won't harm anybody since it *will be used*.
>>>
>>> It sounds like this adds additional information that has been missing
>>> from the review of my patches - and I suspect changes Hans' comments.
>>> So, I'll wait, it seems pointless to try and update the patches when
>>> it's not clear how to proceed due to other dependencies, especially
>>> when it means that their existing state is what's required (I'm pleased
>>> that I've held off modifying the patches so far.)
>>>
>>> If that means having to wait another kernel revision, then I guess that's
>>> what will have to happen.
>>
>> Can you respin your patch series, keeping the notifier support? The CEC
>> kernel config handling has been cleaned up (just select CEC_CORE and
>> CEC_NOTIFIER) so you should be good to go.
> 
> Not yet - the change to the way you're dealing with Kconfig in CEC is
> fundamentally broken, and needs fixing before we can merge dw-hdmi-cec
> support.
> 
> As a result of these Kconfig changes, dw-hdmi-cec now fails if:
> 
> 1. You build the CEC part as a module
> 2. You build the HDMI part into the kernel
> 
> This results in CEC_NOTIFIER=y and CEC_CORE=m, which, when the HDMI part
> gets built, results in the stubs in the notifier code being used, rather
> than the real functions.  This in turn causes the CEC part to never
> receive a physical address, which is therefore non-functional.
> 
> I did have a patch to fix this, but it was never committed, and I got
> busy with other stuff (so it ended up being git reset --hard away.)
> 

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 2/4] drm/bridge: dw-hdmi: add cec notifier support
  2017-07-17  9:05               ` Russell King - ARM Linux
@ 2017-07-17 11:39                 ` Hans Verkuil
  -1 siblings, 0 replies; 84+ messages in thread
From: Hans Verkuil @ 2017-07-17 11:39 UTC (permalink / raw)
  To: linux-arm-kernel

On 17/07/17 11:05, Russell King - ARM Linux wrote:
> On Mon, Jul 17, 2017 at 10:56:47AM +0200, Hans Verkuil wrote:
>> Hi Russell,
>>
>> On 09/06/17 16:10, Russell King - ARM Linux wrote:
>>> On Fri, Jun 09, 2017 at 03:56:39PM +0200, Neil Armstrong wrote:
>>>> Yes, but on the Amlogic Meson plarform, the DW-HDMI CEC controller is
>>>> not used, but a custom one, so this notifier is actually useful for
>>>> this platform and maybe others.
>>>
>>> Is the CEC controller configured into dw-hdmi (is the config bit set?)
>>> I'm just wondering if we're going to end up with two CEC drivers trying
>>> to bind to the same notifier.
>>>
>>>> Should we really wait until I push the Amlogic AO CEC driver ? Having a
>>>> notifier in the DW-HDMI driver won't harm anybody since it *will be used*.
>>>
>>> It sounds like this adds additional information that has been missing
>>> from the review of my patches - and I suspect changes Hans' comments.
>>> So, I'll wait, it seems pointless to try and update the patches when
>>> it's not clear how to proceed due to other dependencies, especially
>>> when it means that their existing state is what's required (I'm pleased
>>> that I've held off modifying the patches so far.)
>>>
>>> If that means having to wait another kernel revision, then I guess that's
>>> what will have to happen.
>>
>> Can you respin your patch series, keeping the notifier support? The CEC
>> kernel config handling has been cleaned up (just select CEC_CORE and
>> CEC_NOTIFIER) so you should be good to go.
> 
> Not yet - the change to the way you're dealing with Kconfig in CEC is
> fundamentally broken, and needs fixing before we can merge dw-hdmi-cec
> support.
> 
> As a result of these Kconfig changes, dw-hdmi-cec now fails if:
> 
> 1. You build the CEC part as a module
> 2. You build the HDMI part into the kernel
> 
> This results in CEC_NOTIFIER=y and CEC_CORE=m, which, when the HDMI part
> gets built, results in the stubs in the notifier code being used, rather
> than the real functions.  This in turn causes the CEC part to never
> receive a physical address, which is therefore non-functional.
> 
> I did have a patch to fix this, but it was never committed, and I got
> busy with other stuff (so it ended up being git reset --hard away.)
> 

This is more a DRM_DW_HDMI issue than a CEC issue IMHO.

This will fix this:

config DRM_DW_HDMI
        tristate
        select DRM_KMS_HELPER
        select REGMAP_MMIO
        select CEC_CORE if CEC_NOTIFIER			<<<<<<

config DRM_DW_HDMI_CEC
        tristate "Synopsis Designware CEC interface"
        depends on DRM_DW_HDMI
        select CEC_CORE
        select CEC_NOTIFIER
        help
          Support the CE interface which is part of the Synopsis
          Designware HDMI block.

This makes sense: if DRM_DW_HDMI_CEC is disabled but another CEC module is
used instead (as is apparently the case for amlogic), then the

	select CEC_CORE if CEC_NOTIFIER

line ensures that CONFIG_CEC_CORE has the right m/y value.

Regards,

	Hans

PS: Sorry for the empty reply earlier: I accidentally pressed 'Send' too soon :-)

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH 2/4] drm/bridge: dw-hdmi: add cec notifier support
@ 2017-07-17 11:39                 ` Hans Verkuil
  0 siblings, 0 replies; 84+ messages in thread
From: Hans Verkuil @ 2017-07-17 11:39 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: linux-arm-kernel, dri-devel, Neil Armstrong

On 17/07/17 11:05, Russell King - ARM Linux wrote:
> On Mon, Jul 17, 2017 at 10:56:47AM +0200, Hans Verkuil wrote:
>> Hi Russell,
>>
>> On 09/06/17 16:10, Russell King - ARM Linux wrote:
>>> On Fri, Jun 09, 2017 at 03:56:39PM +0200, Neil Armstrong wrote:
>>>> Yes, but on the Amlogic Meson plarform, the DW-HDMI CEC controller is
>>>> not used, but a custom one, so this notifier is actually useful for
>>>> this platform and maybe others.
>>>
>>> Is the CEC controller configured into dw-hdmi (is the config bit set?)
>>> I'm just wondering if we're going to end up with two CEC drivers trying
>>> to bind to the same notifier.
>>>
>>>> Should we really wait until I push the Amlogic AO CEC driver ? Having a
>>>> notifier in the DW-HDMI driver won't harm anybody since it *will be used*.
>>>
>>> It sounds like this adds additional information that has been missing
>>> from the review of my patches - and I suspect changes Hans' comments.
>>> So, I'll wait, it seems pointless to try and update the patches when
>>> it's not clear how to proceed due to other dependencies, especially
>>> when it means that their existing state is what's required (I'm pleased
>>> that I've held off modifying the patches so far.)
>>>
>>> If that means having to wait another kernel revision, then I guess that's
>>> what will have to happen.
>>
>> Can you respin your patch series, keeping the notifier support? The CEC
>> kernel config handling has been cleaned up (just select CEC_CORE and
>> CEC_NOTIFIER) so you should be good to go.
> 
> Not yet - the change to the way you're dealing with Kconfig in CEC is
> fundamentally broken, and needs fixing before we can merge dw-hdmi-cec
> support.
> 
> As a result of these Kconfig changes, dw-hdmi-cec now fails if:
> 
> 1. You build the CEC part as a module
> 2. You build the HDMI part into the kernel
> 
> This results in CEC_NOTIFIER=y and CEC_CORE=m, which, when the HDMI part
> gets built, results in the stubs in the notifier code being used, rather
> than the real functions.  This in turn causes the CEC part to never
> receive a physical address, which is therefore non-functional.
> 
> I did have a patch to fix this, but it was never committed, and I got
> busy with other stuff (so it ended up being git reset --hard away.)
> 

This is more a DRM_DW_HDMI issue than a CEC issue IMHO.

This will fix this:

config DRM_DW_HDMI
        tristate
        select DRM_KMS_HELPER
        select REGMAP_MMIO
        select CEC_CORE if CEC_NOTIFIER			<<<<<<

config DRM_DW_HDMI_CEC
        tristate "Synopsis Designware CEC interface"
        depends on DRM_DW_HDMI
        select CEC_CORE
        select CEC_NOTIFIER
        help
          Support the CE interface which is part of the Synopsis
          Designware HDMI block.

This makes sense: if DRM_DW_HDMI_CEC is disabled but another CEC module is
used instead (as is apparently the case for amlogic), then the

	select CEC_CORE if CEC_NOTIFIER

line ensures that CONFIG_CEC_CORE has the right m/y value.

Regards,

	Hans

PS: Sorry for the empty reply earlier: I accidentally pressed 'Send' too soon :-)
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 2/4] drm/bridge: dw-hdmi: add cec notifier support
  2017-07-17 11:39                 ` Hans Verkuil
@ 2017-07-17 12:05                   ` Russell King - ARM Linux
  -1 siblings, 0 replies; 84+ messages in thread
From: Russell King - ARM Linux @ 2017-07-17 12:05 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jul 17, 2017 at 01:39:48PM +0200, Hans Verkuil wrote:
> On 17/07/17 11:05, Russell King - ARM Linux wrote:
> > On Mon, Jul 17, 2017 at 10:56:47AM +0200, Hans Verkuil wrote:
> >> Hi Russell,
> >>
> >> On 09/06/17 16:10, Russell King - ARM Linux wrote:
> >>> On Fri, Jun 09, 2017 at 03:56:39PM +0200, Neil Armstrong wrote:
> >>>> Yes, but on the Amlogic Meson plarform, the DW-HDMI CEC controller is
> >>>> not used, but a custom one, so this notifier is actually useful for
> >>>> this platform and maybe others.
> >>>
> >>> Is the CEC controller configured into dw-hdmi (is the config bit set?)
> >>> I'm just wondering if we're going to end up with two CEC drivers trying
> >>> to bind to the same notifier.
> >>>
> >>>> Should we really wait until I push the Amlogic AO CEC driver ? Having a
> >>>> notifier in the DW-HDMI driver won't harm anybody since it *will be used*.
> >>>
> >>> It sounds like this adds additional information that has been missing
> >>> from the review of my patches - and I suspect changes Hans' comments.
> >>> So, I'll wait, it seems pointless to try and update the patches when
> >>> it's not clear how to proceed due to other dependencies, especially
> >>> when it means that their existing state is what's required (I'm pleased
> >>> that I've held off modifying the patches so far.)
> >>>
> >>> If that means having to wait another kernel revision, then I guess that's
> >>> what will have to happen.
> >>
> >> Can you respin your patch series, keeping the notifier support? The CEC
> >> kernel config handling has been cleaned up (just select CEC_CORE and
> >> CEC_NOTIFIER) so you should be good to go.
> > 
> > Not yet - the change to the way you're dealing with Kconfig in CEC is
> > fundamentally broken, and needs fixing before we can merge dw-hdmi-cec
> > support.
> > 
> > As a result of these Kconfig changes, dw-hdmi-cec now fails if:
> > 
> > 1. You build the CEC part as a module
> > 2. You build the HDMI part into the kernel
> > 
> > This results in CEC_NOTIFIER=y and CEC_CORE=m, which, when the HDMI part
> > gets built, results in the stubs in the notifier code being used, rather
> > than the real functions.  This in turn causes the CEC part to never
> > receive a physical address, which is therefore non-functional.
> > 
> > I did have a patch to fix this, but it was never committed, and I got
> > busy with other stuff (so it ended up being git reset --hard away.)
> > 
> 
> This is more a DRM_DW_HDMI issue than a CEC issue IMHO.
> 
> This will fix this:
> 
> config DRM_DW_HDMI
>         tristate
>         select DRM_KMS_HELPER
>         select REGMAP_MMIO
>         select CEC_CORE if CEC_NOTIFIER			<<<<<<
> 
> config DRM_DW_HDMI_CEC
>         tristate "Synopsis Designware CEC interface"
>         depends on DRM_DW_HDMI
>         select CEC_CORE
>         select CEC_NOTIFIER
>         help
>           Support the CE interface which is part of the Synopsis
>           Designware HDMI block.
> 
> This makes sense: if DRM_DW_HDMI_CEC is disabled but another CEC module is
> used instead (as is apparently the case for amlogic), then the
> 
> 	select CEC_CORE if CEC_NOTIFIER
> 
> line ensures that CONFIG_CEC_CORE has the right m/y value.

I disagree with this approach.

If DRM_DW_HDMI=y and DRM_DW_HDMI_CEC=n, but some other driver is enabled
that selects CEC_NOTIFIER, then we end up with CEC_CORE forced enabled
through dw-hdmi, even though we haven't asked for the CEC part to be
enabled.

You might as well have CEC_NOTIFIER itself select CEC_CORE, and be done
with it, because that's basically what this boils down to.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH 2/4] drm/bridge: dw-hdmi: add cec notifier support
@ 2017-07-17 12:05                   ` Russell King - ARM Linux
  0 siblings, 0 replies; 84+ messages in thread
From: Russell King - ARM Linux @ 2017-07-17 12:05 UTC (permalink / raw)
  To: Hans Verkuil; +Cc: linux-arm-kernel, dri-devel, Neil Armstrong

On Mon, Jul 17, 2017 at 01:39:48PM +0200, Hans Verkuil wrote:
> On 17/07/17 11:05, Russell King - ARM Linux wrote:
> > On Mon, Jul 17, 2017 at 10:56:47AM +0200, Hans Verkuil wrote:
> >> Hi Russell,
> >>
> >> On 09/06/17 16:10, Russell King - ARM Linux wrote:
> >>> On Fri, Jun 09, 2017 at 03:56:39PM +0200, Neil Armstrong wrote:
> >>>> Yes, but on the Amlogic Meson plarform, the DW-HDMI CEC controller is
> >>>> not used, but a custom one, so this notifier is actually useful for
> >>>> this platform and maybe others.
> >>>
> >>> Is the CEC controller configured into dw-hdmi (is the config bit set?)
> >>> I'm just wondering if we're going to end up with two CEC drivers trying
> >>> to bind to the same notifier.
> >>>
> >>>> Should we really wait until I push the Amlogic AO CEC driver ? Having a
> >>>> notifier in the DW-HDMI driver won't harm anybody since it *will be used*.
> >>>
> >>> It sounds like this adds additional information that has been missing
> >>> from the review of my patches - and I suspect changes Hans' comments.
> >>> So, I'll wait, it seems pointless to try and update the patches when
> >>> it's not clear how to proceed due to other dependencies, especially
> >>> when it means that their existing state is what's required (I'm pleased
> >>> that I've held off modifying the patches so far.)
> >>>
> >>> If that means having to wait another kernel revision, then I guess that's
> >>> what will have to happen.
> >>
> >> Can you respin your patch series, keeping the notifier support? The CEC
> >> kernel config handling has been cleaned up (just select CEC_CORE and
> >> CEC_NOTIFIER) so you should be good to go.
> > 
> > Not yet - the change to the way you're dealing with Kconfig in CEC is
> > fundamentally broken, and needs fixing before we can merge dw-hdmi-cec
> > support.
> > 
> > As a result of these Kconfig changes, dw-hdmi-cec now fails if:
> > 
> > 1. You build the CEC part as a module
> > 2. You build the HDMI part into the kernel
> > 
> > This results in CEC_NOTIFIER=y and CEC_CORE=m, which, when the HDMI part
> > gets built, results in the stubs in the notifier code being used, rather
> > than the real functions.  This in turn causes the CEC part to never
> > receive a physical address, which is therefore non-functional.
> > 
> > I did have a patch to fix this, but it was never committed, and I got
> > busy with other stuff (so it ended up being git reset --hard away.)
> > 
> 
> This is more a DRM_DW_HDMI issue than a CEC issue IMHO.
> 
> This will fix this:
> 
> config DRM_DW_HDMI
>         tristate
>         select DRM_KMS_HELPER
>         select REGMAP_MMIO
>         select CEC_CORE if CEC_NOTIFIER			<<<<<<
> 
> config DRM_DW_HDMI_CEC
>         tristate "Synopsis Designware CEC interface"
>         depends on DRM_DW_HDMI
>         select CEC_CORE
>         select CEC_NOTIFIER
>         help
>           Support the CE interface which is part of the Synopsis
>           Designware HDMI block.
> 
> This makes sense: if DRM_DW_HDMI_CEC is disabled but another CEC module is
> used instead (as is apparently the case for amlogic), then the
> 
> 	select CEC_CORE if CEC_NOTIFIER
> 
> line ensures that CONFIG_CEC_CORE has the right m/y value.

I disagree with this approach.

If DRM_DW_HDMI=y and DRM_DW_HDMI_CEC=n, but some other driver is enabled
that selects CEC_NOTIFIER, then we end up with CEC_CORE forced enabled
through dw-hdmi, even though we haven't asked for the CEC part to be
enabled.

You might as well have CEC_NOTIFIER itself select CEC_CORE, and be done
with it, because that's basically what this boils down to.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 2/4] drm/bridge: dw-hdmi: add cec notifier support
  2017-07-17 12:05                   ` Russell King - ARM Linux
@ 2017-07-17 12:23                     ` Hans Verkuil
  -1 siblings, 0 replies; 84+ messages in thread
From: Hans Verkuil @ 2017-07-17 12:23 UTC (permalink / raw)
  To: linux-arm-kernel

On 17/07/17 14:05, Russell King - ARM Linux wrote:
> On Mon, Jul 17, 2017 at 01:39:48PM +0200, Hans Verkuil wrote:
>> On 17/07/17 11:05, Russell King - ARM Linux wrote:
>>> On Mon, Jul 17, 2017 at 10:56:47AM +0200, Hans Verkuil wrote:
>>>> Hi Russell,
>>>>
>>>> On 09/06/17 16:10, Russell King - ARM Linux wrote:
>>>>> On Fri, Jun 09, 2017 at 03:56:39PM +0200, Neil Armstrong wrote:
>>>>>> Yes, but on the Amlogic Meson plarform, the DW-HDMI CEC controller is
>>>>>> not used, but a custom one, so this notifier is actually useful for
>>>>>> this platform and maybe others.
>>>>>
>>>>> Is the CEC controller configured into dw-hdmi (is the config bit set?)
>>>>> I'm just wondering if we're going to end up with two CEC drivers trying
>>>>> to bind to the same notifier.
>>>>>
>>>>>> Should we really wait until I push the Amlogic AO CEC driver ? Having a
>>>>>> notifier in the DW-HDMI driver won't harm anybody since it *will be used*.
>>>>>
>>>>> It sounds like this adds additional information that has been missing
>>>>> from the review of my patches - and I suspect changes Hans' comments.
>>>>> So, I'll wait, it seems pointless to try and update the patches when
>>>>> it's not clear how to proceed due to other dependencies, especially
>>>>> when it means that their existing state is what's required (I'm pleased
>>>>> that I've held off modifying the patches so far.)
>>>>>
>>>>> If that means having to wait another kernel revision, then I guess that's
>>>>> what will have to happen.
>>>>
>>>> Can you respin your patch series, keeping the notifier support? The CEC
>>>> kernel config handling has been cleaned up (just select CEC_CORE and
>>>> CEC_NOTIFIER) so you should be good to go.
>>>
>>> Not yet - the change to the way you're dealing with Kconfig in CEC is
>>> fundamentally broken, and needs fixing before we can merge dw-hdmi-cec
>>> support.
>>>
>>> As a result of these Kconfig changes, dw-hdmi-cec now fails if:
>>>
>>> 1. You build the CEC part as a module
>>> 2. You build the HDMI part into the kernel
>>>
>>> This results in CEC_NOTIFIER=y and CEC_CORE=m, which, when the HDMI part
>>> gets built, results in the stubs in the notifier code being used, rather
>>> than the real functions.  This in turn causes the CEC part to never
>>> receive a physical address, which is therefore non-functional.
>>>
>>> I did have a patch to fix this, but it was never committed, and I got
>>> busy with other stuff (so it ended up being git reset --hard away.)
>>>
>>
>> This is more a DRM_DW_HDMI issue than a CEC issue IMHO.
>>
>> This will fix this:
>>
>> config DRM_DW_HDMI
>>         tristate
>>         select DRM_KMS_HELPER
>>         select REGMAP_MMIO
>>         select CEC_CORE if CEC_NOTIFIER			<<<<<<
>>
>> config DRM_DW_HDMI_CEC
>>         tristate "Synopsis Designware CEC interface"
>>         depends on DRM_DW_HDMI
>>         select CEC_CORE
>>         select CEC_NOTIFIER
>>         help
>>           Support the CE interface which is part of the Synopsis
>>           Designware HDMI block.
>>
>> This makes sense: if DRM_DW_HDMI_CEC is disabled but another CEC module is
>> used instead (as is apparently the case for amlogic), then the
>>
>> 	select CEC_CORE if CEC_NOTIFIER
>>
>> line ensures that CONFIG_CEC_CORE has the right m/y value.
> 
> I disagree with this approach.
> 
> If DRM_DW_HDMI=y and DRM_DW_HDMI_CEC=n, but some other driver is enabled
> that selects CEC_NOTIFIER, then we end up with CEC_CORE forced enabled
> through dw-hdmi, even though we haven't asked for the CEC part to be
> enabled.

If CEC_NOTIFIER is enabled by a CEC driver, then CEC_CORE will also be
enabled (without CEC_CORE that driver wouldn't compile, obviously).

So I don't see the problem. All the select...if does is make sure that
the CEC_CORE can be reached from the HDMI driver if someone enabled the
CEC notifier (and thus CEC_CORE).

> You might as well have CEC_NOTIFIER itself select CEC_CORE, and be done
> with it, because that's basically what this boils down to.

That makes no sense.

If CEC_NOTIFIER is set, then both the CEC driver and the HDMI driver have to
select CEC_CORE to ensure the right dependency. If CEC_NOTIFIER is not set,
then only the CEC driver has to select CEC_CORE. In that case the CEC code
is typically either integrated into the HDMI driver or it is a standalone
device like the USB pulse8-cec driver.

Regards,

	Hans

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH 2/4] drm/bridge: dw-hdmi: add cec notifier support
@ 2017-07-17 12:23                     ` Hans Verkuil
  0 siblings, 0 replies; 84+ messages in thread
From: Hans Verkuil @ 2017-07-17 12:23 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: linux-arm-kernel, dri-devel, Neil Armstrong

On 17/07/17 14:05, Russell King - ARM Linux wrote:
> On Mon, Jul 17, 2017 at 01:39:48PM +0200, Hans Verkuil wrote:
>> On 17/07/17 11:05, Russell King - ARM Linux wrote:
>>> On Mon, Jul 17, 2017 at 10:56:47AM +0200, Hans Verkuil wrote:
>>>> Hi Russell,
>>>>
>>>> On 09/06/17 16:10, Russell King - ARM Linux wrote:
>>>>> On Fri, Jun 09, 2017 at 03:56:39PM +0200, Neil Armstrong wrote:
>>>>>> Yes, but on the Amlogic Meson plarform, the DW-HDMI CEC controller is
>>>>>> not used, but a custom one, so this notifier is actually useful for
>>>>>> this platform and maybe others.
>>>>>
>>>>> Is the CEC controller configured into dw-hdmi (is the config bit set?)
>>>>> I'm just wondering if we're going to end up with two CEC drivers trying
>>>>> to bind to the same notifier.
>>>>>
>>>>>> Should we really wait until I push the Amlogic AO CEC driver ? Having a
>>>>>> notifier in the DW-HDMI driver won't harm anybody since it *will be used*.
>>>>>
>>>>> It sounds like this adds additional information that has been missing
>>>>> from the review of my patches - and I suspect changes Hans' comments.
>>>>> So, I'll wait, it seems pointless to try and update the patches when
>>>>> it's not clear how to proceed due to other dependencies, especially
>>>>> when it means that their existing state is what's required (I'm pleased
>>>>> that I've held off modifying the patches so far.)
>>>>>
>>>>> If that means having to wait another kernel revision, then I guess that's
>>>>> what will have to happen.
>>>>
>>>> Can you respin your patch series, keeping the notifier support? The CEC
>>>> kernel config handling has been cleaned up (just select CEC_CORE and
>>>> CEC_NOTIFIER) so you should be good to go.
>>>
>>> Not yet - the change to the way you're dealing with Kconfig in CEC is
>>> fundamentally broken, and needs fixing before we can merge dw-hdmi-cec
>>> support.
>>>
>>> As a result of these Kconfig changes, dw-hdmi-cec now fails if:
>>>
>>> 1. You build the CEC part as a module
>>> 2. You build the HDMI part into the kernel
>>>
>>> This results in CEC_NOTIFIER=y and CEC_CORE=m, which, when the HDMI part
>>> gets built, results in the stubs in the notifier code being used, rather
>>> than the real functions.  This in turn causes the CEC part to never
>>> receive a physical address, which is therefore non-functional.
>>>
>>> I did have a patch to fix this, but it was never committed, and I got
>>> busy with other stuff (so it ended up being git reset --hard away.)
>>>
>>
>> This is more a DRM_DW_HDMI issue than a CEC issue IMHO.
>>
>> This will fix this:
>>
>> config DRM_DW_HDMI
>>         tristate
>>         select DRM_KMS_HELPER
>>         select REGMAP_MMIO
>>         select CEC_CORE if CEC_NOTIFIER			<<<<<<
>>
>> config DRM_DW_HDMI_CEC
>>         tristate "Synopsis Designware CEC interface"
>>         depends on DRM_DW_HDMI
>>         select CEC_CORE
>>         select CEC_NOTIFIER
>>         help
>>           Support the CE interface which is part of the Synopsis
>>           Designware HDMI block.
>>
>> This makes sense: if DRM_DW_HDMI_CEC is disabled but another CEC module is
>> used instead (as is apparently the case for amlogic), then the
>>
>> 	select CEC_CORE if CEC_NOTIFIER
>>
>> line ensures that CONFIG_CEC_CORE has the right m/y value.
> 
> I disagree with this approach.
> 
> If DRM_DW_HDMI=y and DRM_DW_HDMI_CEC=n, but some other driver is enabled
> that selects CEC_NOTIFIER, then we end up with CEC_CORE forced enabled
> through dw-hdmi, even though we haven't asked for the CEC part to be
> enabled.

If CEC_NOTIFIER is enabled by a CEC driver, then CEC_CORE will also be
enabled (without CEC_CORE that driver wouldn't compile, obviously).

So I don't see the problem. All the select...if does is make sure that
the CEC_CORE can be reached from the HDMI driver if someone enabled the
CEC notifier (and thus CEC_CORE).

> You might as well have CEC_NOTIFIER itself select CEC_CORE, and be done
> with it, because that's basically what this boils down to.

That makes no sense.

If CEC_NOTIFIER is set, then both the CEC driver and the HDMI driver have to
select CEC_CORE to ensure the right dependency. If CEC_NOTIFIER is not set,
then only the CEC driver has to select CEC_CORE. In that case the CEC code
is typically either integrated into the HDMI driver or it is a standalone
device like the USB pulse8-cec driver.

Regards,

	Hans
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 2/4] drm/bridge: dw-hdmi: add cec notifier support
  2017-07-17 12:23                     ` Hans Verkuil
@ 2017-07-24 12:16                       ` Hans Verkuil
  -1 siblings, 0 replies; 84+ messages in thread
From: Hans Verkuil @ 2017-07-24 12:16 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Russell,

On 07/17/2017 02:23 PM, Hans Verkuil wrote:
> On 17/07/17 14:05, Russell King - ARM Linux wrote:
>> On Mon, Jul 17, 2017 at 01:39:48PM +0200, Hans Verkuil wrote:
>>> On 17/07/17 11:05, Russell King - ARM Linux wrote:
>>>> On Mon, Jul 17, 2017 at 10:56:47AM +0200, Hans Verkuil wrote:
>>>>> Hi Russell,
>>>>>
>>>>> On 09/06/17 16:10, Russell King - ARM Linux wrote:
>>>>>> On Fri, Jun 09, 2017 at 03:56:39PM +0200, Neil Armstrong wrote:
>>>>>>> Yes, but on the Amlogic Meson plarform, the DW-HDMI CEC controller is
>>>>>>> not used, but a custom one, so this notifier is actually useful for
>>>>>>> this platform and maybe others.
>>>>>>
>>>>>> Is the CEC controller configured into dw-hdmi (is the config bit set?)
>>>>>> I'm just wondering if we're going to end up with two CEC drivers trying
>>>>>> to bind to the same notifier.
>>>>>>
>>>>>>> Should we really wait until I push the Amlogic AO CEC driver ? Having a
>>>>>>> notifier in the DW-HDMI driver won't harm anybody since it *will be used*.
>>>>>>
>>>>>> It sounds like this adds additional information that has been missing
>>>>>> from the review of my patches - and I suspect changes Hans' comments.
>>>>>> So, I'll wait, it seems pointless to try and update the patches when
>>>>>> it's not clear how to proceed due to other dependencies, especially
>>>>>> when it means that their existing state is what's required (I'm pleased
>>>>>> that I've held off modifying the patches so far.)
>>>>>>
>>>>>> If that means having to wait another kernel revision, then I guess that's
>>>>>> what will have to happen.
>>>>>
>>>>> Can you respin your patch series, keeping the notifier support? The CEC
>>>>> kernel config handling has been cleaned up (just select CEC_CORE and
>>>>> CEC_NOTIFIER) so you should be good to go.
>>>>
>>>> Not yet - the change to the way you're dealing with Kconfig in CEC is
>>>> fundamentally broken, and needs fixing before we can merge dw-hdmi-cec
>>>> support.
>>>>
>>>> As a result of these Kconfig changes, dw-hdmi-cec now fails if:
>>>>
>>>> 1. You build the CEC part as a module
>>>> 2. You build the HDMI part into the kernel
>>>>
>>>> This results in CEC_NOTIFIER=y and CEC_CORE=m, which, when the HDMI part
>>>> gets built, results in the stubs in the notifier code being used, rather
>>>> than the real functions.  This in turn causes the CEC part to never
>>>> receive a physical address, which is therefore non-functional.
>>>>
>>>> I did have a patch to fix this, but it was never committed, and I got
>>>> busy with other stuff (so it ended up being git reset --hard away.)
>>>>
>>>
>>> This is more a DRM_DW_HDMI issue than a CEC issue IMHO.
>>>
>>> This will fix this:
>>>
>>> config DRM_DW_HDMI
>>>          tristate
>>>          select DRM_KMS_HELPER
>>>          select REGMAP_MMIO
>>>          select CEC_CORE if CEC_NOTIFIER			<<<<<<
>>>
>>> config DRM_DW_HDMI_CEC
>>>          tristate "Synopsis Designware CEC interface"
>>>          depends on DRM_DW_HDMI
>>>          select CEC_CORE
>>>          select CEC_NOTIFIER
>>>          help
>>>            Support the CE interface which is part of the Synopsis
>>>            Designware HDMI block.
>>>
>>> This makes sense: if DRM_DW_HDMI_CEC is disabled but another CEC module is
>>> used instead (as is apparently the case for amlogic), then the
>>>
>>> 	select CEC_CORE if CEC_NOTIFIER
>>>
>>> line ensures that CONFIG_CEC_CORE has the right m/y value.
>>
>> I disagree with this approach.
>>
>> If DRM_DW_HDMI=y and DRM_DW_HDMI_CEC=n, but some other driver is enabled
>> that selects CEC_NOTIFIER, then we end up with CEC_CORE forced enabled
>> through dw-hdmi, even though we haven't asked for the CEC part to be
>> enabled.
> 
> If CEC_NOTIFIER is enabled by a CEC driver, then CEC_CORE will also be
> enabled (without CEC_CORE that driver wouldn't compile, obviously).
> 
> So I don't see the problem. All the select...if does is make sure that
> the CEC_CORE can be reached from the HDMI driver if someone enabled the
> CEC notifier (and thus CEC_CORE).
> 
>> You might as well have CEC_NOTIFIER itself select CEC_CORE, and be done
>> with it, because that's basically what this boils down to.
> 
> That makes no sense.
> 
> If CEC_NOTIFIER is set, then both the CEC driver and the HDMI driver have to
> select CEC_CORE to ensure the right dependency. If CEC_NOTIFIER is not set,
> then only the CEC driver has to select CEC_CORE. In that case the CEC code
> is typically either integrated into the HDMI driver or it is a standalone
> device like the USB pulse8-cec driver.

Just to make sure you aren't waiting for me to do anything: as far as I can tell
the Kconfig above will ensure the right dependencies. If you have an example
where this fails, then let me know. I am not planning on making any changes.
Frankly, I wouldn't know what to change since AFAICT it is all working with
the above Kconfig.

Regards,

	Hans

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH 2/4] drm/bridge: dw-hdmi: add cec notifier support
@ 2017-07-24 12:16                       ` Hans Verkuil
  0 siblings, 0 replies; 84+ messages in thread
From: Hans Verkuil @ 2017-07-24 12:16 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: dri-devel, linux-arm-kernel, Neil Armstrong

Hi Russell,

On 07/17/2017 02:23 PM, Hans Verkuil wrote:
> On 17/07/17 14:05, Russell King - ARM Linux wrote:
>> On Mon, Jul 17, 2017 at 01:39:48PM +0200, Hans Verkuil wrote:
>>> On 17/07/17 11:05, Russell King - ARM Linux wrote:
>>>> On Mon, Jul 17, 2017 at 10:56:47AM +0200, Hans Verkuil wrote:
>>>>> Hi Russell,
>>>>>
>>>>> On 09/06/17 16:10, Russell King - ARM Linux wrote:
>>>>>> On Fri, Jun 09, 2017 at 03:56:39PM +0200, Neil Armstrong wrote:
>>>>>>> Yes, but on the Amlogic Meson plarform, the DW-HDMI CEC controller is
>>>>>>> not used, but a custom one, so this notifier is actually useful for
>>>>>>> this platform and maybe others.
>>>>>>
>>>>>> Is the CEC controller configured into dw-hdmi (is the config bit set?)
>>>>>> I'm just wondering if we're going to end up with two CEC drivers trying
>>>>>> to bind to the same notifier.
>>>>>>
>>>>>>> Should we really wait until I push the Amlogic AO CEC driver ? Having a
>>>>>>> notifier in the DW-HDMI driver won't harm anybody since it *will be used*.
>>>>>>
>>>>>> It sounds like this adds additional information that has been missing
>>>>>> from the review of my patches - and I suspect changes Hans' comments.
>>>>>> So, I'll wait, it seems pointless to try and update the patches when
>>>>>> it's not clear how to proceed due to other dependencies, especially
>>>>>> when it means that their existing state is what's required (I'm pleased
>>>>>> that I've held off modifying the patches so far.)
>>>>>>
>>>>>> If that means having to wait another kernel revision, then I guess that's
>>>>>> what will have to happen.
>>>>>
>>>>> Can you respin your patch series, keeping the notifier support? The CEC
>>>>> kernel config handling has been cleaned up (just select CEC_CORE and
>>>>> CEC_NOTIFIER) so you should be good to go.
>>>>
>>>> Not yet - the change to the way you're dealing with Kconfig in CEC is
>>>> fundamentally broken, and needs fixing before we can merge dw-hdmi-cec
>>>> support.
>>>>
>>>> As a result of these Kconfig changes, dw-hdmi-cec now fails if:
>>>>
>>>> 1. You build the CEC part as a module
>>>> 2. You build the HDMI part into the kernel
>>>>
>>>> This results in CEC_NOTIFIER=y and CEC_CORE=m, which, when the HDMI part
>>>> gets built, results in the stubs in the notifier code being used, rather
>>>> than the real functions.  This in turn causes the CEC part to never
>>>> receive a physical address, which is therefore non-functional.
>>>>
>>>> I did have a patch to fix this, but it was never committed, and I got
>>>> busy with other stuff (so it ended up being git reset --hard away.)
>>>>
>>>
>>> This is more a DRM_DW_HDMI issue than a CEC issue IMHO.
>>>
>>> This will fix this:
>>>
>>> config DRM_DW_HDMI
>>>          tristate
>>>          select DRM_KMS_HELPER
>>>          select REGMAP_MMIO
>>>          select CEC_CORE if CEC_NOTIFIER			<<<<<<
>>>
>>> config DRM_DW_HDMI_CEC
>>>          tristate "Synopsis Designware CEC interface"
>>>          depends on DRM_DW_HDMI
>>>          select CEC_CORE
>>>          select CEC_NOTIFIER
>>>          help
>>>            Support the CE interface which is part of the Synopsis
>>>            Designware HDMI block.
>>>
>>> This makes sense: if DRM_DW_HDMI_CEC is disabled but another CEC module is
>>> used instead (as is apparently the case for amlogic), then the
>>>
>>> 	select CEC_CORE if CEC_NOTIFIER
>>>
>>> line ensures that CONFIG_CEC_CORE has the right m/y value.
>>
>> I disagree with this approach.
>>
>> If DRM_DW_HDMI=y and DRM_DW_HDMI_CEC=n, but some other driver is enabled
>> that selects CEC_NOTIFIER, then we end up with CEC_CORE forced enabled
>> through dw-hdmi, even though we haven't asked for the CEC part to be
>> enabled.
> 
> If CEC_NOTIFIER is enabled by a CEC driver, then CEC_CORE will also be
> enabled (without CEC_CORE that driver wouldn't compile, obviously).
> 
> So I don't see the problem. All the select...if does is make sure that
> the CEC_CORE can be reached from the HDMI driver if someone enabled the
> CEC notifier (and thus CEC_CORE).
> 
>> You might as well have CEC_NOTIFIER itself select CEC_CORE, and be done
>> with it, because that's basically what this boils down to.
> 
> That makes no sense.
> 
> If CEC_NOTIFIER is set, then both the CEC driver and the HDMI driver have to
> select CEC_CORE to ensure the right dependency. If CEC_NOTIFIER is not set,
> then only the CEC driver has to select CEC_CORE. In that case the CEC code
> is typically either integrated into the HDMI driver or it is a standalone
> device like the USB pulse8-cec driver.

Just to make sure you aren't waiting for me to do anything: as far as I can tell
the Kconfig above will ensure the right dependencies. If you have an example
where this fails, then let me know. I am not planning on making any changes.
Frankly, I wouldn't know what to change since AFAICT it is all working with
the above Kconfig.

Regards,

	Hans

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 2/4] drm/bridge: dw-hdmi: add cec notifier support
  2017-07-24 12:16                       ` Hans Verkuil
@ 2017-07-24 13:07                         ` Russell King - ARM Linux
  -1 siblings, 0 replies; 84+ messages in thread
From: Russell King - ARM Linux @ 2017-07-24 13:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jul 24, 2017 at 02:16:40PM +0200, Hans Verkuil wrote:
> Hi Russell,
> 
> On 07/17/2017 02:23 PM, Hans Verkuil wrote:
> >On 17/07/17 14:05, Russell King - ARM Linux wrote:
> >>On Mon, Jul 17, 2017 at 01:39:48PM +0200, Hans Verkuil wrote:
> >>>On 17/07/17 11:05, Russell King - ARM Linux wrote:
> >>>>On Mon, Jul 17, 2017 at 10:56:47AM +0200, Hans Verkuil wrote:
> >>>>>Hi Russell,
> >>>>>
> >>>>>On 09/06/17 16:10, Russell King - ARM Linux wrote:
> >>>>>>On Fri, Jun 09, 2017 at 03:56:39PM +0200, Neil Armstrong wrote:
> >>>>>>>Yes, but on the Amlogic Meson plarform, the DW-HDMI CEC controller is
> >>>>>>>not used, but a custom one, so this notifier is actually useful for
> >>>>>>>this platform and maybe others.
> >>>>>>
> >>>>>>Is the CEC controller configured into dw-hdmi (is the config bit set?)
> >>>>>>I'm just wondering if we're going to end up with two CEC drivers trying
> >>>>>>to bind to the same notifier.
> >>>>>>
> >>>>>>>Should we really wait until I push the Amlogic AO CEC driver ? Having a
> >>>>>>>notifier in the DW-HDMI driver won't harm anybody since it *will be used*.
> >>>>>>
> >>>>>>It sounds like this adds additional information that has been missing
> >>>>>>from the review of my patches - and I suspect changes Hans' comments.
> >>>>>>So, I'll wait, it seems pointless to try and update the patches when
> >>>>>>it's not clear how to proceed due to other dependencies, especially
> >>>>>>when it means that their existing state is what's required (I'm pleased
> >>>>>>that I've held off modifying the patches so far.)
> >>>>>>
> >>>>>>If that means having to wait another kernel revision, then I guess that's
> >>>>>>what will have to happen.
> >>>>>
> >>>>>Can you respin your patch series, keeping the notifier support? The CEC
> >>>>>kernel config handling has been cleaned up (just select CEC_CORE and
> >>>>>CEC_NOTIFIER) so you should be good to go.
> >>>>
> >>>>Not yet - the change to the way you're dealing with Kconfig in CEC is
> >>>>fundamentally broken, and needs fixing before we can merge dw-hdmi-cec
> >>>>support.
> >>>>
> >>>>As a result of these Kconfig changes, dw-hdmi-cec now fails if:
> >>>>
> >>>>1. You build the CEC part as a module
> >>>>2. You build the HDMI part into the kernel
> >>>>
> >>>>This results in CEC_NOTIFIER=y and CEC_CORE=m, which, when the HDMI part
> >>>>gets built, results in the stubs in the notifier code being used, rather
> >>>>than the real functions.  This in turn causes the CEC part to never
> >>>>receive a physical address, which is therefore non-functional.
> >>>>
> >>>>I did have a patch to fix this, but it was never committed, and I got
> >>>>busy with other stuff (so it ended up being git reset --hard away.)
> >>>>
> >>>
> >>>This is more a DRM_DW_HDMI issue than a CEC issue IMHO.
> >>>
> >>>This will fix this:
> >>>
> >>>config DRM_DW_HDMI
> >>>         tristate
> >>>         select DRM_KMS_HELPER
> >>>         select REGMAP_MMIO
> >>>         select CEC_CORE if CEC_NOTIFIER			<<<<<<
> >>>
> >>>config DRM_DW_HDMI_CEC
> >>>         tristate "Synopsis Designware CEC interface"
> >>>         depends on DRM_DW_HDMI
> >>>         select CEC_CORE
> >>>         select CEC_NOTIFIER
> >>>         help
> >>>           Support the CE interface which is part of the Synopsis
> >>>           Designware HDMI block.
> >>>
> >>>This makes sense: if DRM_DW_HDMI_CEC is disabled but another CEC module is
> >>>used instead (as is apparently the case for amlogic), then the
> >>>
> >>>	select CEC_CORE if CEC_NOTIFIER
> >>>
> >>>line ensures that CONFIG_CEC_CORE has the right m/y value.
> >>
> >>I disagree with this approach.
> >>
> >>If DRM_DW_HDMI=y and DRM_DW_HDMI_CEC=n, but some other driver is enabled
> >>that selects CEC_NOTIFIER, then we end up with CEC_CORE forced enabled
> >>through dw-hdmi, even though we haven't asked for the CEC part to be
> >>enabled.
> >
> >If CEC_NOTIFIER is enabled by a CEC driver, then CEC_CORE will also be
> >enabled (without CEC_CORE that driver wouldn't compile, obviously).
> >
> >So I don't see the problem. All the select...if does is make sure that
> >the CEC_CORE can be reached from the HDMI driver if someone enabled the
> >CEC notifier (and thus CEC_CORE).
> >
> >>You might as well have CEC_NOTIFIER itself select CEC_CORE, and be done
> >>with it, because that's basically what this boils down to.
> >
> >That makes no sense.
> >
> >If CEC_NOTIFIER is set, then both the CEC driver and the HDMI driver have to
> >select CEC_CORE to ensure the right dependency. If CEC_NOTIFIER is not set,
> >then only the CEC driver has to select CEC_CORE. In that case the CEC code
> >is typically either integrated into the HDMI driver or it is a standalone
> >device like the USB pulse8-cec driver.
> 
> Just to make sure you aren't waiting for me to do anything: as far as I can tell
> the Kconfig above will ensure the right dependencies. If you have an example
> where this fails, then let me know. I am not planning on making any changes.
> Frankly, I wouldn't know what to change since AFAICT it is all working with
> the above Kconfig.

No, I just haven't got around to it yet - I've been busy all last week
trying to work out what's been causing a USB host driver to fail for a 
client, and as such haven't had any chance to look at much else post
merge window yet.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH 2/4] drm/bridge: dw-hdmi: add cec notifier support
@ 2017-07-24 13:07                         ` Russell King - ARM Linux
  0 siblings, 0 replies; 84+ messages in thread
From: Russell King - ARM Linux @ 2017-07-24 13:07 UTC (permalink / raw)
  To: Hans Verkuil; +Cc: dri-devel, linux-arm-kernel, Neil Armstrong

On Mon, Jul 24, 2017 at 02:16:40PM +0200, Hans Verkuil wrote:
> Hi Russell,
> 
> On 07/17/2017 02:23 PM, Hans Verkuil wrote:
> >On 17/07/17 14:05, Russell King - ARM Linux wrote:
> >>On Mon, Jul 17, 2017 at 01:39:48PM +0200, Hans Verkuil wrote:
> >>>On 17/07/17 11:05, Russell King - ARM Linux wrote:
> >>>>On Mon, Jul 17, 2017 at 10:56:47AM +0200, Hans Verkuil wrote:
> >>>>>Hi Russell,
> >>>>>
> >>>>>On 09/06/17 16:10, Russell King - ARM Linux wrote:
> >>>>>>On Fri, Jun 09, 2017 at 03:56:39PM +0200, Neil Armstrong wrote:
> >>>>>>>Yes, but on the Amlogic Meson plarform, the DW-HDMI CEC controller is
> >>>>>>>not used, but a custom one, so this notifier is actually useful for
> >>>>>>>this platform and maybe others.
> >>>>>>
> >>>>>>Is the CEC controller configured into dw-hdmi (is the config bit set?)
> >>>>>>I'm just wondering if we're going to end up with two CEC drivers trying
> >>>>>>to bind to the same notifier.
> >>>>>>
> >>>>>>>Should we really wait until I push the Amlogic AO CEC driver ? Having a
> >>>>>>>notifier in the DW-HDMI driver won't harm anybody since it *will be used*.
> >>>>>>
> >>>>>>It sounds like this adds additional information that has been missing
> >>>>>>from the review of my patches - and I suspect changes Hans' comments.
> >>>>>>So, I'll wait, it seems pointless to try and update the patches when
> >>>>>>it's not clear how to proceed due to other dependencies, especially
> >>>>>>when it means that their existing state is what's required (I'm pleased
> >>>>>>that I've held off modifying the patches so far.)
> >>>>>>
> >>>>>>If that means having to wait another kernel revision, then I guess that's
> >>>>>>what will have to happen.
> >>>>>
> >>>>>Can you respin your patch series, keeping the notifier support? The CEC
> >>>>>kernel config handling has been cleaned up (just select CEC_CORE and
> >>>>>CEC_NOTIFIER) so you should be good to go.
> >>>>
> >>>>Not yet - the change to the way you're dealing with Kconfig in CEC is
> >>>>fundamentally broken, and needs fixing before we can merge dw-hdmi-cec
> >>>>support.
> >>>>
> >>>>As a result of these Kconfig changes, dw-hdmi-cec now fails if:
> >>>>
> >>>>1. You build the CEC part as a module
> >>>>2. You build the HDMI part into the kernel
> >>>>
> >>>>This results in CEC_NOTIFIER=y and CEC_CORE=m, which, when the HDMI part
> >>>>gets built, results in the stubs in the notifier code being used, rather
> >>>>than the real functions.  This in turn causes the CEC part to never
> >>>>receive a physical address, which is therefore non-functional.
> >>>>
> >>>>I did have a patch to fix this, but it was never committed, and I got
> >>>>busy with other stuff (so it ended up being git reset --hard away.)
> >>>>
> >>>
> >>>This is more a DRM_DW_HDMI issue than a CEC issue IMHO.
> >>>
> >>>This will fix this:
> >>>
> >>>config DRM_DW_HDMI
> >>>         tristate
> >>>         select DRM_KMS_HELPER
> >>>         select REGMAP_MMIO
> >>>         select CEC_CORE if CEC_NOTIFIER			<<<<<<
> >>>
> >>>config DRM_DW_HDMI_CEC
> >>>         tristate "Synopsis Designware CEC interface"
> >>>         depends on DRM_DW_HDMI
> >>>         select CEC_CORE
> >>>         select CEC_NOTIFIER
> >>>         help
> >>>           Support the CE interface which is part of the Synopsis
> >>>           Designware HDMI block.
> >>>
> >>>This makes sense: if DRM_DW_HDMI_CEC is disabled but another CEC module is
> >>>used instead (as is apparently the case for amlogic), then the
> >>>
> >>>	select CEC_CORE if CEC_NOTIFIER
> >>>
> >>>line ensures that CONFIG_CEC_CORE has the right m/y value.
> >>
> >>I disagree with this approach.
> >>
> >>If DRM_DW_HDMI=y and DRM_DW_HDMI_CEC=n, but some other driver is enabled
> >>that selects CEC_NOTIFIER, then we end up with CEC_CORE forced enabled
> >>through dw-hdmi, even though we haven't asked for the CEC part to be
> >>enabled.
> >
> >If CEC_NOTIFIER is enabled by a CEC driver, then CEC_CORE will also be
> >enabled (without CEC_CORE that driver wouldn't compile, obviously).
> >
> >So I don't see the problem. All the select...if does is make sure that
> >the CEC_CORE can be reached from the HDMI driver if someone enabled the
> >CEC notifier (and thus CEC_CORE).
> >
> >>You might as well have CEC_NOTIFIER itself select CEC_CORE, and be done
> >>with it, because that's basically what this boils down to.
> >
> >That makes no sense.
> >
> >If CEC_NOTIFIER is set, then both the CEC driver and the HDMI driver have to
> >select CEC_CORE to ensure the right dependency. If CEC_NOTIFIER is not set,
> >then only the CEC driver has to select CEC_CORE. In that case the CEC code
> >is typically either integrated into the HDMI driver or it is a standalone
> >device like the USB pulse8-cec driver.
> 
> Just to make sure you aren't waiting for me to do anything: as far as I can tell
> the Kconfig above will ensure the right dependencies. If you have an example
> where this fails, then let me know. I am not planning on making any changes.
> Frankly, I wouldn't know what to change since AFAICT it is all working with
> the above Kconfig.

No, I just haven't got around to it yet - I've been busy all last week
trying to work out what's been causing a USB host driver to fail for a 
client, and as such haven't had any chance to look at much else post
merge window yet.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* [PATCH 2/4] drm/bridge: dw-hdmi: add cec notifier support
  2017-07-24 13:07                         ` Russell King - ARM Linux
@ 2017-07-24 16:34                           ` Russell King - ARM Linux
  -1 siblings, 0 replies; 84+ messages in thread
From: Russell King - ARM Linux @ 2017-07-24 16:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jul 24, 2017 at 02:07:17PM +0100, Russell King - ARM Linux wrote:
> On Mon, Jul 24, 2017 at 02:16:40PM +0200, Hans Verkuil wrote:
> > Just to make sure you aren't waiting for me to do anything: as far as I can tell
> > the Kconfig above will ensure the right dependencies. If you have an example
> > where this fails, then let me know. I am not planning on making any changes.
> > Frankly, I wouldn't know what to change since AFAICT it is all working with
> > the above Kconfig.
> 
> No, I just haven't got around to it yet - I've been busy all last week
> trying to work out what's been causing a USB host driver to fail for a 
> client, and as such haven't had any chance to look at much else post
> merge window yet.

It's going to be a while yet - today I've attempted to bring my tree
forward to v4.13-rc2, but it's proven a long and difficult task to get
anywhere close to finishing that... and I've just ended up rewinding
back to this morning's state (because I ended up having to drop some
branches that other stuff depended upon.)

I'll have another go later in the week.

Until I can do this, I can't do anything else with mainline work.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 84+ messages in thread

* Re: [PATCH 2/4] drm/bridge: dw-hdmi: add cec notifier support
@ 2017-07-24 16:34                           ` Russell King - ARM Linux
  0 siblings, 0 replies; 84+ messages in thread
From: Russell King - ARM Linux @ 2017-07-24 16:34 UTC (permalink / raw)
  To: Hans Verkuil; +Cc: linux-arm-kernel, dri-devel, Neil Armstrong

On Mon, Jul 24, 2017 at 02:07:17PM +0100, Russell King - ARM Linux wrote:
> On Mon, Jul 24, 2017 at 02:16:40PM +0200, Hans Verkuil wrote:
> > Just to make sure you aren't waiting for me to do anything: as far as I can tell
> > the Kconfig above will ensure the right dependencies. If you have an example
> > where this fails, then let me know. I am not planning on making any changes.
> > Frankly, I wouldn't know what to change since AFAICT it is all working with
> > the above Kconfig.
> 
> No, I just haven't got around to it yet - I've been busy all last week
> trying to work out what's been causing a USB host driver to fail for a 
> client, and as such haven't had any chance to look at much else post
> merge window yet.

It's going to be a while yet - today I've attempted to bring my tree
forward to v4.13-rc2, but it's proven a long and difficult task to get
anywhere close to finishing that... and I've just ended up rewinding
back to this morning's state (because I ended up having to drop some
branches that other stuff depended upon.)

I'll have another go later in the week.

Until I can do this, I can't do anything else with mainline work.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 84+ messages in thread

end of thread, other threads:[~2017-07-24 16:34 UTC | newest]

Thread overview: 84+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-30 14:22 [PATCH 0/4] dw-hdmi CEC support Russell King - ARM Linux
2017-05-30 14:22 ` Russell King - ARM Linux
2017-05-30 14:23 ` [PATCH 1/4] drm/bridge: dw-hdmi: remove CEC engine register definitions Russell King
2017-05-30 14:23   ` Russell King
2017-06-09 14:24   ` Hans Verkuil
2017-06-09 14:24     ` Hans Verkuil
2017-05-30 14:23 ` [PATCH 2/4] drm/bridge: dw-hdmi: add cec notifier support Russell King
2017-05-30 14:23   ` Russell King
2017-06-09 12:59   ` Neil Armstrong
2017-06-09 12:59     ` Neil Armstrong
2017-06-09 13:38     ` Russell King - ARM Linux
2017-06-09 13:38       ` Russell King - ARM Linux
2017-06-09 13:51       ` Hans Verkuil
2017-06-09 13:51         ` Hans Verkuil
2017-06-09 13:56       ` Neil Armstrong
2017-06-09 13:56         ` Neil Armstrong
2017-06-09 14:04         ` Hans Verkuil
2017-06-09 14:04           ` Hans Verkuil
2017-06-09 14:10         ` Russell King - ARM Linux
2017-06-09 14:10           ` Russell King - ARM Linux
2017-06-09 14:38           ` Hans Verkuil
2017-06-09 14:38             ` Hans Verkuil
2017-07-17  8:56           ` Hans Verkuil
2017-07-17  8:56             ` Hans Verkuil
2017-07-17  9:05             ` Russell King - ARM Linux
2017-07-17  9:05               ` Russell King - ARM Linux
2017-07-17 11:19               ` Hans Verkuil
2017-07-17 11:19                 ` Hans Verkuil
2017-07-17 11:39               ` Hans Verkuil
2017-07-17 11:39                 ` Hans Verkuil
2017-07-17 12:05                 ` Russell King - ARM Linux
2017-07-17 12:05                   ` Russell King - ARM Linux
2017-07-17 12:23                   ` Hans Verkuil
2017-07-17 12:23                     ` Hans Verkuil
2017-07-24 12:16                     ` Hans Verkuil
2017-07-24 12:16                       ` Hans Verkuil
2017-07-24 13:07                       ` Russell King - ARM Linux
2017-07-24 13:07                         ` Russell King - ARM Linux
2017-07-24 16:34                         ` Russell King - ARM Linux
2017-07-24 16:34                           ` Russell King - ARM Linux
2017-06-09 14:27   ` Hans Verkuil
2017-06-09 14:27     ` Hans Verkuil
2017-05-30 14:23 ` [PATCH 3/4] drm/bridge: dw-hdmi: add better clock disable control Russell King
2017-05-30 14:23   ` Russell King
2017-06-01  0:55   ` Jose Abreu
2017-06-01  0:55     ` Jose Abreu
2017-06-09 14:28   ` Hans Verkuil
2017-06-09 14:28     ` Hans Verkuil
2017-05-30 14:23 ` [PATCH 4/4] drm/bridge: dw-hdmi: add cec driver Russell King
2017-05-30 14:23   ` Russell King
2017-06-01  0:53   ` Jose Abreu
2017-06-01  0:53     ` Jose Abreu
2017-06-01 22:30     ` Russell King - ARM Linux
2017-06-01 22:30       ` Russell King - ARM Linux
2017-06-02  5:02       ` Jose Abreu
2017-06-02  5:02         ` Jose Abreu
2017-06-02  9:15         ` Russell King - ARM Linux
2017-06-02  9:15           ` Russell King - ARM Linux
2017-06-02  9:28           ` Hans Verkuil
2017-06-02  9:28             ` Hans Verkuil
2017-06-02  9:36             ` Russell King - ARM Linux
2017-06-02  9:36               ` Russell King - ARM Linux
2017-06-01  8:31   ` Hans Verkuil
2017-06-01  8:31     ` Hans Verkuil
2017-06-01  9:46     ` Russell King - ARM Linux
2017-06-01  9:46       ` Russell King - ARM Linux
2017-06-01 10:44       ` Hans Verkuil
2017-06-01 10:44         ` Hans Verkuil
2017-06-02 12:07     ` Russell King - ARM Linux
2017-06-02 12:07       ` Russell King - ARM Linux
2017-06-02 12:29       ` Hans Verkuil
2017-06-02 12:29         ` Hans Verkuil
2017-06-12  8:42     ` Hans Verkuil
2017-06-12  8:42       ` Hans Verkuil
2017-06-01 13:47   ` Neil Armstrong
2017-06-01 13:47     ` Neil Armstrong
2017-06-02  6:31     ` Hans Verkuil
2017-06-02  6:31       ` Hans Verkuil
2017-06-02  6:43       ` Jose Abreu
2017-06-02  6:43         ` Jose Abreu
2017-06-02  9:06         ` Hans Verkuil
2017-06-02  9:06           ` Hans Verkuil
2017-06-02  9:18           ` Russell King - ARM Linux
2017-06-02  9:18             ` Russell King - ARM Linux

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.