diff mbox

imx-drm: fix hdmi hotplug detection initial state

Message ID E1Wb5Nd-0002Ef-Es@rmk-PC.arm.linux.org.uk (mailing list archive)
State New, archived
Headers show

Commit Message

Russell King April 18, 2014, 9:46 a.m. UTC
The initial state at boot is assumed to be disconnected, and we hope
to receive an interrupt to update the status.  Let's be more explicit
about the current state - reading the PHY status register tells us
the current level of the hotplug signal, which we can report back in
the _detect() method.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
Having discussed the issue of how to detect HDMI with David Airlie last
night, it is perfectly fine to use the HPD signal.  The reason adapters
like Intel i915 use EDID is because of cross-talk on their HPD signals,
which cause them to falsely indicate transitions when nothing has really
changed state.  So, to say that EDID polling is somehow more in keeping
with DRM than using the HPD signal is rather bogus.

The patch below fixes imx-hdmi for good systems where the HPD signal is
wired up at the board level.

 drivers/staging/imx-drm/imx-hdmi.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

Comments

Tim Harvey April 24, 2014, 9 p.m. UTC | #1
On Fri, Apr 18, 2014 at 2:46 AM, Russell King
<rmk+kernel@arm.linux.org.uk> wrote:
>
> The initial state at boot is assumed to be disconnected, and we hope
> to receive an interrupt to update the status.  Let's be more explicit
> about the current state - reading the PHY status register tells us
> the current level of the hotplug signal, which we can report back in
> the _detect() method.
>
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---
> Having discussed the issue of how to detect HDMI with David Airlie last
> night, it is perfectly fine to use the HPD signal.  The reason adapters
> like Intel i915 use EDID is because of cross-talk on their HPD signals,
> which cause them to falsely indicate transitions when nothing has really
> changed state.  So, to say that EDID polling is somehow more in keeping
> with DRM than using the HPD signal is rather bogus.
>
> The patch below fixes imx-hdmi for good systems where the HPD signal is
> wired up at the board level.
>
>  drivers/staging/imx-drm/imx-hdmi.c | 9 +++------
>  1 file changed, 3 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/staging/imx-drm/imx-hdmi.c
> index d47dedd2cdb4..6f5efcc89880 100644
> --- a/drivers/staging/imx-drm/imx-hdmi.c
> +++ b/drivers/staging/imx-drm/imx-hdmi.c
> @@ -120,8 +120,6 @@ struct imx_hdmi {
>         struct clk *isfr_clk;
>         struct clk *iahb_clk;
>
> -       enum drm_connector_status connector_status;
> -
>         struct hdmi_data_info hdmi_data;
>         int vic;
>
> @@ -1382,7 +1380,9 @@ static enum drm_connector_status imx_hdmi_connector_detect(struct drm_connector
>  {
>         struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi,
>                                              connector);
> -       return hdmi->connector_status;
> +
> +       return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ?
> +               connector_status_connected : connector_status_disconnected;
>  }
>
>  static int imx_hdmi_connector_get_modes(struct drm_connector *connector)
> @@ -1524,7 +1524,6 @@ static irqreturn_t imx_hdmi_irq(int irq, void *dev_id)
>
>                         hdmi_modb(hdmi, 0, HDMI_PHY_HPD, HDMI_PHY_POL0);
>
> -                       hdmi->connector_status = connector_status_connected;
>                         imx_hdmi_poweron(hdmi);
>                 } else {
>                         dev_dbg(hdmi->dev, "EVENT=plugout\n");
> @@ -1532,7 +1531,6 @@ static irqreturn_t imx_hdmi_irq(int irq, void *dev_id)
>                         hdmi_modb(hdmi, HDMI_PHY_HPD, HDMI_PHY_HPD,
>                                 HDMI_PHY_POL0);
>
> -                       hdmi->connector_status = connector_status_disconnected;
>                         imx_hdmi_poweroff(hdmi);
>                 }
>                 drm_helper_hpd_irq_event(hdmi->connector.dev);
> @@ -1606,7 +1604,6 @@ static int imx_hdmi_bind(struct device *dev, struct device *master, void *data)
>                 return -ENOMEM;
>
>         hdmi->dev = dev;
> -       hdmi->connector_status = connector_status_disconnected;
>         hdmi->sample_rate = 48000;
>         hdmi->ratio = 100;
>
> --
> 1.8.3.1
>

Hi Russell,

I'm still seeing issues with HDMI detect on powerup, at least on my
Gateworks Ventana boards (which have no voltage devider or anything
else on the HPD line to the IMX6 other than a TVS). I'm currently
using your latest imx-drm-staging branch and have applied this patch
on top of it. When I enable debug in imx-hdmi.c I see the following:

on powerup with HDMI attached:
[    6.291082] imx-ipuv3 2400000.ipu: IPUv3H probed
[    6.298370] imx-ipuv3 2800000.ipu: IPUv3H probed
[    6.310356] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
[    6.317087] [drm] No driver support for vblank timestamp query.
[    6.324249] imx-drm display-subsystem.11: bound imx-ipuv3-crtc.0
(ops ipu_crtc_ops)
[    6.332475] imx-drm display-subsystem.11: bound imx-ipuv3-crtc.1
(ops ipu_crtc_ops)
[    6.340616] imx-drm display-subsystem.11: bound imx-ipuv3-crtc.2
(ops ipu_crtc_ops)
[    6.349221] imx-drm display-subsystem.11: bound imx-ipuv3-crtc.3
(ops ipu_crtc_ops)
[    6.358098] imx-hdmi 120000.hdmi: Detected HDMI controller 0x13:0xa:0xa0:0xc1
[    6.365366] hdmi_compute_cts: freq: 48000 pixel_clk: 74250000 ratio: 100
[    6.372169] imx-hdmi 120000.hdmi: hdmi_set_clk_regenerator:
samplerate=48000  ratio=100  pixelclk=74250000  N=6144 cts=74250
[    6.383971] imx-drm display-subsystem.11: bound 120000.hdmi (ops hdmi_ops)
[    6.383998] imx-hdmi 120000.hdmi: EVENT=plugin
[    6.384011] imx-hdmi 120000.hdmi: imx_hdmi_poweron
[    6.384022] imx-hdmi 120000.hdmi: imx_hdmi_setup vic=0
[    6.384031] imx-hdmi 120000.hdmi: Non-CEA mode used in HDMI
[    6.384038] imx-hdmi 120000.hdmi: final pixclk = 0
[    6.402148] imx-hdmi 120000.hdmi: imx_hdmi_setup DVI mode
[    6.428804] imx-drm display-subsystem.11: bound ldb.10 (ops imx_ldb_ops)
[    6.490101] imx-hdmi 120000.hdmi: got edid: width[70] x height[39]
[    6.506191] imx-drm display-subsystem.11: fb0:  frame buffer device
[    6.512596] imx-drm display-subsystem.11: registered panic notifier
[    6.518947] [drm] Initialized imx-drm 1.0.0 20120507 on minor 0

I think the issue may be that the plugin event was encountered and
EDID read before the frame buffer device exists?

on hotplug:
[  153.216538] imx-hdmi 120000.hdmi: EVENT=plugout
[  155.596765] imx-hdmi 120000.hdmi: EVENT=plugin
[  155.601273] imx-hdmi 120000.hdmi: Non-CEA mode used in HDMI
[  155.606985] imx-hdmi 120000.hdmi: final pixclk = 0
[  155.629933] imx-hdmi 120000.hdmi: imx_hdmi_setup DVI mode
[  155.684976] imx-hdmi 120000.hdmi: got edid: width[70] x height[39]
[  155.695157] imx-hdmi 120000.hdmi: CEA mode used vic=4
[  155.700234] imx-hdmi 120000.hdmi: final pixclk = 74250000
[  155.723830] imx-hdmi 120000.hdmi: imx_hdmi_setup CEA mode
[  155.729251] hdmi_compute_cts: freq: 48000 pixel_clk: 74250000 ratio: 100
[  155.736044] imx-hdmi 120000.hdmi: hdmi_set_clk_regenerator:
samplerate=48000  ratio=100  pixelclk=74250000  N=6144 cts=74250
[  155.748264] imx-hdmi 120000.hdmi: CEA mode used vic=4
[  155.754049] imx-hdmi 120000.hdmi: final pixclk = 74250000
[  155.777569] imx-hdmi 120000.hdmi: imx_hdmi_setup CEA mode
[  155.783089] hdmi_compute_cts: freq: 48000 pixel_clk: 74250000 ratio: 100
[  155.789859] imx-hdmi 120000.hdmi: hdmi_set_clk_regenerator:
samplerate=48000  ratio=100  pixelclk=74250000  N=6144 cts=74250
[  156.277154] imx-hdmi 120000.hdmi: EVENT=plugout
[  156.281774] imx-hdmi 120000.hdmi: EVENT=plugin
[  156.286398] imx-hdmi 120000.hdmi: CEA mode used vic=4
[  156.291470] imx-hdmi 120000.hdmi: final pixclk = 74250000
[  156.315042] imx-hdmi 120000.hdmi: imx_hdmi_setup CEA mode
[  156.320512] hdmi_compute_cts: freq: 48000 pixel_clk: 74250000 ratio: 100
[  156.327302] imx-hdmi 120000.hdmi: hdmi_set_clk_regenerator:
samplerate=48000  ratio=100  pixelclk=74250000  N=6144 cts=74250
display is now sync'd and good

Regards,

Tim
Russell King - ARM Linux April 24, 2014, 10:07 p.m. UTC | #2
On Thu, Apr 24, 2014 at 02:00:49PM -0700, Tim Harvey wrote:
> I'm still seeing issues with HDMI detect on powerup, at least on my
> Gateworks Ventana boards (which have no voltage devider or anything
> else on the HPD line to the IMX6 other than a TVS). I'm currently
> using your latest imx-drm-staging branch and have applied this patch
> on top of it. When I enable debug in imx-hdmi.c I see the following:

So it's a similar setup to the Cubox-i.

> on powerup with HDMI attached:
> [    6.291082] imx-ipuv3 2400000.ipu: IPUv3H probed
> [    6.298370] imx-ipuv3 2800000.ipu: IPUv3H probed
> [    6.310356] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
> [    6.317087] [drm] No driver support for vblank timestamp query.
> [    6.324249] imx-drm display-subsystem.11: bound imx-ipuv3-crtc.0
> (ops ipu_crtc_ops)
> [    6.332475] imx-drm display-subsystem.11: bound imx-ipuv3-crtc.1
> (ops ipu_crtc_ops)
> [    6.340616] imx-drm display-subsystem.11: bound imx-ipuv3-crtc.2
> (ops ipu_crtc_ops)
> [    6.349221] imx-drm display-subsystem.11: bound imx-ipuv3-crtc.3
> (ops ipu_crtc_ops)
> [    6.358098] imx-hdmi 120000.hdmi: Detected HDMI controller 0x13:0xa:0xa0:0xc1
> [    6.365366] hdmi_compute_cts: freq: 48000 pixel_clk: 74250000 ratio: 100
> [    6.372169] imx-hdmi 120000.hdmi: hdmi_set_clk_regenerator:
> samplerate=48000  ratio=100  pixelclk=74250000  N=6144 cts=74250
> [    6.383971] imx-drm display-subsystem.11: bound 120000.hdmi (ops hdmi_ops)
> [    6.383998] imx-hdmi 120000.hdmi: EVENT=plugin
> [    6.384011] imx-hdmi 120000.hdmi: imx_hdmi_poweron
> [    6.384022] imx-hdmi 120000.hdmi: imx_hdmi_setup vic=0
> [    6.384031] imx-hdmi 120000.hdmi: Non-CEA mode used in HDMI
> [    6.384038] imx-hdmi 120000.hdmi: final pixclk = 0
> [    6.402148] imx-hdmi 120000.hdmi: imx_hdmi_setup DVI mode
> [    6.428804] imx-drm display-subsystem.11: bound ldb.10 (ops imx_ldb_ops)
> [    6.490101] imx-hdmi 120000.hdmi: got edid: width[70] x height[39]
> [    6.506191] imx-drm display-subsystem.11: fb0:  frame buffer device
> [    6.512596] imx-drm display-subsystem.11: registered panic notifier
> [    6.518947] [drm] Initialized imx-drm 1.0.0 20120507 on minor 0

So at boot, I see this:

[    1.282549] imx-ipuv3 2400000.ipu: IPUv3H probed
[    1.295494] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
[    1.302197] [drm] No driver support for vblank timestamp query.
[    1.308315] imx-drm display-subsystem.10: bound imx-ipuv3-crtc.0 (ops ipu_crtc_ops)
[    1.326728] imx-drm display-subsystem.10: bound imx-ipuv3-crtc.1 (ops ipu_crtc_ops)
[    1.336741] imx-hdmi 120000.hdmi: Detected HDMI controller 0x13:0x1a:0xa0:0xc1
[    1.346109] hdmi_compute_cts: freq: 48000 pixel_clk: 74250000 ratio: 100
[    1.346128] imx-hdmi 120000.hdmi: hdmi_set_clk_regenerator: samplerate=48000  ratio=100  pixelclk=74250000  N=6144 cts=74250
[    1.346276] imx-hdmi 120000.hdmi: EVENT=plugin
[    1.346291] imx-hdmi 120000.hdmi: Non-CEA mode used in HDMI
[    1.346301] imx-hdmi 120000.hdmi: final pixclk = 0
[    1.364422] imx-hdmi 120000.hdmi: imx_hdmi_setup DVI mode
[    1.365896] imx-drm display-subsystem.10: bound 120000.hdmi (ops hdmi_ops)
[    1.428629] imx-hdmi 120000.hdmi: got edid: width[128] x height[72]
[    1.435752] imx-hdmi 120000.hdmi: CEA mode used vic=31
[    1.435761] imx-hdmi 120000.hdmi: final pixclk = 148500000
[    1.453879] imx-hdmi 120000.hdmi: imx_hdmi_setup CEA mode
[    1.453886] hdmi_compute_cts: freq: 48000 pixel_clk: 148500000 ratio: 100
[    1.453896] imx-hdmi 120000.hdmi: hdmi_set_clk_regenerator: samplerate=48000  ratio=100  pixelclk=148500000  N=6144 cts=148500
[    1.454549] imx-hdmi 120000.hdmi: CEA mode used vic=31
[    1.454555] imx-hdmi 120000.hdmi: final pixclk = 148500000
[    1.472685] imx-hdmi 120000.hdmi: imx_hdmi_setup CEA mode
[    1.472691] hdmi_compute_cts: freq: 48000 pixel_clk: 148500000 ratio: 100
[    1.472702] imx-hdmi 120000.hdmi: hdmi_set_clk_regenerator: samplerate=48000  ratio=100  pixelclk=148500000  N=6144 cts=148500
[    1.489418] Console: switching to colour frame buffer device 240x67
[    1.511370] imx-drm display-subsystem.10: fb0:  frame buffer device
[    1.517770] imx-drm display-subsystem.10: registered panic notifier
[    1.524160] [drm] Initialized imx-drm 1.0.0 20120507 on minor 0

which is only with imx-hdmi bound, no ldb.  The difference you will
notice is that there's the "Console: switching ..." line, which is
there because I have fbcon enabled.

Therefore, I suspect that it is working as it should - if you enable
fbcon, it should automatically initialise.  If you don't have fbcon
enabled, then it'll probably wait for a userspace DRM driver to bring
it up.
Tim Harvey April 24, 2014, 10:57 p.m. UTC | #3
On Thu, Apr 24, 2014 at 3:07 PM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Thu, Apr 24, 2014 at 02:00:49PM -0700, Tim Harvey wrote:
>> I'm still seeing issues with HDMI detect on powerup, at least on my
>> Gateworks Ventana boards (which have no voltage devider or anything
>> else on the HPD line to the IMX6 other than a TVS). I'm currently
>> using your latest imx-drm-staging branch and have applied this patch
>> on top of it. When I enable debug in imx-hdmi.c I see the following:
>
> So it's a similar setup to the Cubox-i.
>
<snip>
>
> which is only with imx-hdmi bound, no ldb.  The difference you will
> notice is that there's the "Console: switching ..." line, which is
> there because I have fbcon enabled.
>
> Therefore, I suspect that it is working as it should - if you enable
> fbcon, it should automatically initialise.  If you don't have fbcon
> enabled, then it'll probably wait for a userspace DRM driver to bring
> it up.
>

Russell,

Yes, your correct. If I enable fbcon it comes up at boot. But what if
I don't want fbcon? I have CONFIG_LOGO=y and I would expect that to
come up without needing to hotswap. Something must still be missing
that is getting taken care of by fbcon.

Thanks,

Tim
Russell King - ARM Linux April 24, 2014, 11:23 p.m. UTC | #4
On Thu, Apr 24, 2014 at 03:57:27PM -0700, Tim Harvey wrote:
> On Thu, Apr 24, 2014 at 3:07 PM, Russell King - ARM Linux
> <linux@arm.linux.org.uk> wrote:
> > On Thu, Apr 24, 2014 at 02:00:49PM -0700, Tim Harvey wrote:
> >> I'm still seeing issues with HDMI detect on powerup, at least on my
> >> Gateworks Ventana boards (which have no voltage devider or anything
> >> else on the HPD line to the IMX6 other than a TVS). I'm currently
> >> using your latest imx-drm-staging branch and have applied this patch
> >> on top of it. When I enable debug in imx-hdmi.c I see the following:
> >
> > So it's a similar setup to the Cubox-i.
> >
> <snip>
> >
> > which is only with imx-hdmi bound, no ldb.  The difference you will
> > notice is that there's the "Console: switching ..." line, which is
> > there because I have fbcon enabled.
> >
> > Therefore, I suspect that it is working as it should - if you enable
> > fbcon, it should automatically initialise.  If you don't have fbcon
> > enabled, then it'll probably wait for a userspace DRM driver to bring
> > it up.
> >
> 
> Russell,
> 
> Yes, your correct. If I enable fbcon it comes up at boot. But what if
> I don't want fbcon? I have CONFIG_LOGO=y and I would expect that to
> come up without needing to hotswap. Something must still be missing
> that is getting taken care of by fbcon.

Hmm.  I don't know - tracing the code paths, towards the end of the
imx-drm initialisation, we call drm_fbdev_cma_init(), which should
configure the initial modes - this will only happen if
CONFIG_DRM_IMX_FB_HELPER is enabled, which you seem to have set
already in your boot logs.

drm_fbdev_cma_init() will call drm_fb_helper_initial_config() to set
an initial configuration.  It would seem to think there are available
modes, otherwise you'd get a "No connectors reported connected with modes"
message.

That creates a fb device of the desired size for the mode by calling
back into drm_fbdev_cma_create().  That creates the fbdev device, and
back in drm_fb_helper_single_fb_probe(), the fbdev device is
registered.

And at that point, we're into the depths of the fb device layers to
decide what to do... and it's up to them to set an initial mode.

So, the question I'd put to you is: do you get an initial mode when
trying the same configuration but with a pure fb driver?  I suspect
you'll be in the same situation: without fbcon, fbdev doesn't
initialise registered framebuffers with an initial mode.
diff mbox

Patch

diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/staging/imx-drm/imx-hdmi.c
index d47dedd2cdb4..6f5efcc89880 100644
--- a/drivers/staging/imx-drm/imx-hdmi.c
+++ b/drivers/staging/imx-drm/imx-hdmi.c
@@ -120,8 +120,6 @@  struct imx_hdmi {
 	struct clk *isfr_clk;
 	struct clk *iahb_clk;
 
-	enum drm_connector_status connector_status;
-
 	struct hdmi_data_info hdmi_data;
 	int vic;
 
@@ -1382,7 +1380,9 @@  static enum drm_connector_status imx_hdmi_connector_detect(struct drm_connector
 {
 	struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi,
 					     connector);
-	return hdmi->connector_status;
+
+	return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ?
+		connector_status_connected : connector_status_disconnected;
 }
 
 static int imx_hdmi_connector_get_modes(struct drm_connector *connector)
@@ -1524,7 +1524,6 @@  static irqreturn_t imx_hdmi_irq(int irq, void *dev_id)
 
 			hdmi_modb(hdmi, 0, HDMI_PHY_HPD, HDMI_PHY_POL0);
 
-			hdmi->connector_status = connector_status_connected;
 			imx_hdmi_poweron(hdmi);
 		} else {
 			dev_dbg(hdmi->dev, "EVENT=plugout\n");
@@ -1532,7 +1531,6 @@  static irqreturn_t imx_hdmi_irq(int irq, void *dev_id)
 			hdmi_modb(hdmi, HDMI_PHY_HPD, HDMI_PHY_HPD,
 				HDMI_PHY_POL0);
 
-			hdmi->connector_status = connector_status_disconnected;
 			imx_hdmi_poweroff(hdmi);
 		}
 		drm_helper_hpd_irq_event(hdmi->connector.dev);
@@ -1606,7 +1604,6 @@  static int imx_hdmi_bind(struct device *dev, struct device *master, void *data)
 		return -ENOMEM;
 
 	hdmi->dev = dev;
-	hdmi->connector_status = connector_status_disconnected;
 	hdmi->sample_rate = 48000;
 	hdmi->ratio = 100;