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 --- This fix should go in for -rc - though it's probably too late to get it in for 3.15, it may be considered as a potential stable candidate. If not, can we get this in for 3.16-rc1 please?
Thanks.
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;
On Fri, Jun 06, 2014 at 02:56:43PM +0100, Russell King 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
This fix should go in for -rc - though it's probably too late to get it in for 3.15, it may be considered as a potential stable candidate. If not, can we get this in for 3.16-rc1 please?
Yes, it's too late for 3.15, but I can mark it for -stable and get it in for 3.16-rc1.
thanks,
greg k-h
Russell,
On Fri, Jun 6, 2014 at 10:56 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
I have applied this patch against 3.15 and I still have the following issue on a mx6qsabresd:
If I boot the kernel with the HDMI cable connected, no HDMI image comes up. In order to get HDMI working I need to remove and then reconnect the cable.
Still haven't had a chance to debug this though.
On Mon, Jun 09, 2014 at 10:44:14AM -0300, Fabio Estevam wrote:
Russell,
On Fri, Jun 6, 2014 at 10:56 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
I have applied this patch against 3.15 and I still have the following issue on a mx6qsabresd:
If I boot the kernel with the HDMI cable connected, no HDMI image comes up. In order to get HDMI working I need to remove and then reconnect the cable.
Still haven't had a chance to debug this though.
Please check the status in /sys/class/drm/card0-HDMI-A-1/status. This should report the current state of the hotplug detection.
Remember that this code detects off the HPD signal - if the HPD signal has not been correctly wired up, this patch is not going to help (really it comes down to a hardware fault, which I'm not trying to solve with this patch.)
What I'm trying to resolve with this patch is that the state detected on properly wired up systems corresponds with the real initial state of the interface at initialisation time.
The problem with the current code is that we start off assuming that the interface is disconnected, and we rely on an interrupt arriving to change that state. If for whatever reason that interrupt does not arrive, then, even if the HPD signal is active, we continue believing that the interface is not connected.
I seem to remember discussion in the past that the HPD signal is not wired up on SabreSD. Really, this needs to be a DT flag to indicate that the connectivity on the platform is not correct, and we should fallback to using RXSENSE detection and/or DDC polling (both of which are sub-standard and incorrect to the HDMI spec.)
I'd suggest a standard HDMI interface property like:
hotplug-detect = "hpd" | "rxsense" | "ddc"
defaulting to the standard hpd method.
As I've said in the past, my problem with just going with DDC polling for everything is that the connected HDMI sink is permitted to update the EDID EEPROM (when it does, it is required to lower and re-raise the HPD signal.) If we are polling DDC, we may hit the situation where the EDID EEPROM is mid-update and possibly end up with corrupted data (though there's a checksum to save us from this.)
While I2C is multi-master, we're talking about consumer stuff here, and I bet I2C arbitration on the DDC bus is not something that is tested. I would not be surprised if the assumption is made that when HPD is lowered, the HDMI sink has exclusive access to the EEPROM and doesn't need to be concerned with arbitration.
RXSENSE has the problem that it doesn't detect EDID updates (there's no requirement for a HDMI sink to make RXSENSE on a source go inactive across an EDID update.)
So, I would much rather go by the spec, using the HPD signal on devices where that signal is correctly wired, and only fall back to other methods (which cause us to go against the standard) where the hardware is buggy.
On Mon, Jun 9, 2014 at 11:06 AM, Russell King - ARM Linux linux@arm.linux.org.uk wrote:
Please check the status in /sys/class/drm/card0-HDMI-A-1/status. This should report the current state of the hotplug detection.
/sys/class/drm/card0-HDMI-A-1/status returns the correct state for HDMI cable connection.
Remember that this code detects off the HPD signal - if the HPD signal has not been correctly wired up, this patch is not going to help (really it comes down to a hardware fault, which I'm not trying to solve with this patch.)
What I'm trying to resolve with this patch is that the state detected on properly wired up systems corresponds with the real initial state of the interface at initialisation time.
The problem with the current code is that we start off assuming that the interface is disconnected, and we rely on an interrupt arriving to change that state. If for whatever reason that interrupt does not arrive, then, even if the HPD signal is active, we continue believing that the interface is not connected.
I seem to remember discussion in the past that the HPD signal is not wired up on SabreSD. Really, this needs to be a DT flag to indicate
It is sabrelite board that does not have HPD signal not wired up.
sabresd does have HPD signal connected.
The HDMI undetected issue I am seeing on sabresd seems to be related to the simultaneous usage of HDMI and LVDS.
If I remove the ldb node from the imx6qdl-sabresd.dtsi, then the HDMI cable is correctly detected and HDMI is shown right after boot.
On Mon, Jun 09, 2014 at 11:29:28AM -0300, Fabio Estevam wrote:
On Mon, Jun 9, 2014 at 11:06 AM, Russell King - ARM Linux linux@arm.linux.org.uk wrote:
Please check the status in /sys/class/drm/card0-HDMI-A-1/status. This should report the current state of the hotplug detection.
/sys/class/drm/card0-HDMI-A-1/status returns the correct state for HDMI cable connection.
Remember that this code detects off the HPD signal - if the HPD signal has not been correctly wired up, this patch is not going to help (really it comes down to a hardware fault, which I'm not trying to solve with this patch.)
What I'm trying to resolve with this patch is that the state detected on properly wired up systems corresponds with the real initial state of the interface at initialisation time.
The problem with the current code is that we start off assuming that the interface is disconnected, and we rely on an interrupt arriving to change that state. If for whatever reason that interrupt does not arrive, then, even if the HPD signal is active, we continue believing that the interface is not connected.
I seem to remember discussion in the past that the HPD signal is not wired up on SabreSD. Really, this needs to be a DT flag to indicate
It is sabrelite board that does not have HPD signal not wired up.
sabresd does have HPD signal connected.
The HDMI undetected issue I am seeing on sabresd seems to be related to the simultaneous usage of HDMI and LVDS.
If I remove the ldb node from the imx6qdl-sabresd.dtsi, then the HDMI cable is correctly detected and HDMI is shown right after boot.
This is a known limitation.
http://thread.gmane.org/gmane.linux.ports.arm.kernel/315968/focus=318559
Shawn
On Mon, Jun 9, 2014 at 11:33 AM, Shawn Guo shawn.guo@freescale.com wrote:
On Mon, Jun 09, 2014 at 11:29:28AM -0300, Fabio Estevam wrote:
On Mon, Jun 9, 2014 at 11:06 AM, Russell King - ARM Linux linux@arm.linux.org.uk wrote:
Please check the status in /sys/class/drm/card0-HDMI-A-1/status. This should report the current state of the hotplug detection.
/sys/class/drm/card0-HDMI-A-1/status returns the correct state for HDMI cable connection.
Remember that this code detects off the HPD signal - if the HPD signal has not been correctly wired up, this patch is not going to help (really it comes down to a hardware fault, which I'm not trying to solve with this patch.)
What I'm trying to resolve with this patch is that the state detected on properly wired up systems corresponds with the real initial state of the interface at initialisation time.
The problem with the current code is that we start off assuming that the interface is disconnected, and we rely on an interrupt arriving to change that state. If for whatever reason that interrupt does not arrive, then, even if the HPD signal is active, we continue believing that the interface is not connected.
I seem to remember discussion in the past that the HPD signal is not wired up on SabreSD. Really, this needs to be a DT flag to indicate
It is sabrelite board that does not have HPD signal not wired up.
sabresd does have HPD signal connected.
The HDMI undetected issue I am seeing on sabresd seems to be related to the simultaneous usage of HDMI and LVDS.
If I remove the ldb node from the imx6qdl-sabresd.dtsi, then the HDMI cable is correctly detected and HDMI is shown right after boot.
This is a known limitation.
http://thread.gmane.org/gmane.linux.ports.arm.kernel/315968/focus=318559
There were versions of linux-next that hdmi and lvds works at the same time without problems.
On Mon, Jun 09, 2014 at 11:29:28AM -0300, Fabio Estevam wrote:
On Mon, Jun 9, 2014 at 11:06 AM, Russell King - ARM Linux linux@arm.linux.org.uk wrote:
Please check the status in /sys/class/drm/card0-HDMI-A-1/status. This should report the current state of the hotplug detection.
/sys/class/drm/card0-HDMI-A-1/status returns the correct state for HDMI cable connection.
Good, so that means we're reporting the correct status to the DRM layer. Please post the kernel boot messages, one with the HDMI cable disconnected, and one with a HDMI sink connected.
The HDMI undetected issue I am seeing on sabresd seems to be related to the simultaneous usage of HDMI and LVDS.
If I remove the ldb node from the imx6qdl-sabresd.dtsi, then the HDMI cable is correctly detected and HDMI is shown right after boot.
I wonder if the problem is that HDMI and LVDS are interfering with each other wrt the required pixel clock, and LVDS is winning. If we have HDMI enabled, many HDMI sinks will only work if we set one of their supported modes (with the dot clock within 1% - though some sinks are more lenient).
I think the Novena people have run into this issue, but I've not seen much in the way of contributions back, despite them making use of my patches...
On Mon, Jun 9, 2014 at 2:49 PM, Russell King - ARM Linux linux@arm.linux.org.uk wrote:
On Mon, Jun 09, 2014 at 11:29:28AM -0300, Fabio Estevam wrote:
On Mon, Jun 9, 2014 at 11:06 AM, Russell King - ARM Linux linux@arm.linux.org.uk wrote:
Please check the status in /sys/class/drm/card0-HDMI-A-1/status. This should report the current state of the hotplug detection.
/sys/class/drm/card0-HDMI-A-1/status returns the correct state for HDMI cable connection.
Good, so that means we're reporting the correct status to the DRM layer. Please post the kernel boot messages, one with the HDMI cable disconnected, and one with a HDMI sink connected.
With HDMI cable connected (no image is seen on HDMI, only on lvds cable):
imx-ipuv3 2400000.ipu: IPUv3H probed imx-ipuv3 2800000.ipu: IPUv3H probed [drm] Supports vblank timestamp caching Rev 2 (21.10.2013). mmcblk0: mmc1:0007 SD4GB 3.70 GiB [drm] No driver support for vblank timestamp query. mmcblk0: unknown partition table imx-drm display-subsystem.11: bound imx-ipuv3-crtc.0 (ops ipu_crtc_ops) imx-drm display-subsystem.11: bound imx-ipuv3-crtc.1 (ops ipu_crtc_ops) imx-drm display-subsystem.11: bound imx-ipuv3-crtc.2 (ops ipu_crtc_ops) imx-drm display-subsystem.11: bound imx-ipuv3-crtc.3 (ops ipu_crtc_ops) imx-hdmi 120000.hdmi: Detected HDMI controller 0x13:0xa:0xa0:0xc1 imx-hdmi 120000.hdmi: hdmi_set_clk_regenerator: samplerate=48000 ratio=100 pixelclk=74250000 N=6144 cts=74250 imx-drm display-subsystem.11: bound 120000.hdmi (ops hdmi_ops) imx-hdmi 120000.hdmi: EVENT=plugin imx-hdmi 120000.hdmi: Non-CEA mode used in HDMI imx-hdmi 120000.hdmi: final pixclk = 0 imx-drm display-subsystem.11: bound ldb.10 (ops imx_ldb_ops) imx-hdmi 120000.hdmi: imx_hdmi_setup DVI mode imx-hdmi 120000.hdmi: got edid: width[51] x height[28] imx-hdmi 120000.hdmi: Non-CEA mode used in HDMI imx-hdmi 120000.hdmi: final pixclk = 138500000 imx-hdmi 120000.hdmi: imx_hdmi_setup DVI mode imx-hdmi 120000.hdmi: Non-CEA mode used in HDMI imx-hdmi 120000.hdmi: final pixclk = 138500000 imx-hdmi 120000.hdmi: imx_hdmi_setup DVI mode
If I disconnect/reconnect the HDMI cable (then image is seen on both HDMI and LVDS):
root@freescale /$ imx-hdmi 120000.hdmi: EVENT=plugout imx-hdmi 120000.hdmi: EVENT=plugin imx-hdmi 120000.hdmi: Non-CEA mode used in HDMI imx-hdmi 120000.hdmi: final pixclk = 138500000 imx-hdmi 120000.hdmi: imx_hdmi_setup DVI mode imx-hdmi 120000.hdmi: got edid: width[51] x height[28] imx-hdmi 120000.hdmi: Non-CEA mode used in HDMI imx-hdmi 120000.hdmi: final pixclk = 138500000 imx-hdmi 120000.hdmi: imx_hdmi_setup DVI mode imx-hdmi 120000.hdmi: Non-CEA mode used in HDMI imx-hdmi 120000.hdmi: final pixclk = 138500000 imx-hdmi 120000.hdmi: imx_hdmi_setup DVI mode
Now booting the kernel with HDMI disconnected:
[drm] Supports vblank timestamp caching Rev 2 (21.10.2013). mmcblk0: mmc1:0007 SD4GB 3.70 GiB [drm] No driver support for vblank timestamp query. mmcblk0: unknown partition table imx-drm display-subsystem.11: bound imx-ipuv3-crtc.0 (ops ipu_crtc_ops) imx-drm display-subsystem.11: bound imx-ipuv3-crtc.1 (ops ipu_crtc_ops) imx-drm display-subsystem.11: bound imx-ipuv3-crtc.2 (ops ipu_crtc_ops) imx-drm display-subsystem.11: bound imx-ipuv3-crtc.3 (ops ipu_crtc_ops) imx-hdmi 120000.hdmi: Detected HDMI controller 0x13:0xa:0xa0:0xc1 imx-hdmi 120000.hdmi: hdmi_set_clk_regenerator: samplerate=48000 ratio=100 pixelclk=74250000 N=6144 cts=74250 imx-drm display-subsystem.11: bound 120000.hdmi (ops hdmi_ops) imx-drm display-subsystem.11: bound ldb.10 (ops imx_ldb_ops) Console: switching to colour frame buffer device 128x48 imx-drm display-subsystem.11: fb0: frame buffer device imx-drm display-subsystem.11: registered panic notifier [drm] Initialized imx-drm 1.0.0 20120507 on minor 0
And after connecting the HDMI cable:
imx-hdmi 120000.hdmi: EVENT=plugin imx-hdmi 120000.hdmi: Non-CEA mode used in HDMI imx-hdmi 120000.hdmi: final pixclk = 0 imx-hdmi 120000.hdmi: imx_hdmi_setup DVI mode imx-hdmi 120000.hdmi: got edid: width[51] x height[28] imx-hdmi 120000.hdmi: Non-CEA mode used in HDMI imx-hdmi 120000.hdmi: final pixclk = 78800000 imx-hdmi 120000.hdmi: imx_hdmi_setup DVI mode imx-hdmi 120000.hdmi: Non-CEA mode used in HDMI imx-hdmi 120000.hdmi: final pixclk = 78800000 imx-hdmi 120000.hdmi: imx_hdmi_setup DVI mode
Image is seen on both LVDS and HDMI monitor, but HDMI resolution is not correct (this is a different bug though).
The HDMI undetected issue I am seeing on sabresd seems to be related to the simultaneous usage of HDMI and LVDS.
If I remove the ldb node from the imx6qdl-sabresd.dtsi, then the HDMI cable is correctly detected and HDMI is shown right after boot.
I wonder if the problem is that HDMI and LVDS are interfering with each other wrt the required pixel clock, and LVDS is winning. If we have HDMI enabled, many HDMI sinks will only work if we set one of their supported modes (with the dot clock within 1% - though some sinks are more lenient).
Yes, it seems this is the case.
Thanks
On Mon, Jun 9, 2014 at 3:15 PM, Fabio Estevam festevam@gmail.com wrote:
I wonder if the problem is that HDMI and LVDS are interfering with each other wrt the required pixel clock, and LVDS is winning. If we have HDMI enabled, many HDMI sinks will only work if we set one of their supported modes (with the dot clock within 1% - though some sinks are more lenient).
Yes, it seems this is the case.
I tested not using pll5 as the parent of LVDS:
--- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -439,12 +439,6 @@ static void __init imx6q_clocks_init(struct device_node *cc clk_register_clkdev(clk[gpt_ipg_per], "per", "imx-gpt.0"); clk_register_clkdev(clk[enet_ref], "enet_ref", NULL);
- if ((imx_get_soc_revision() != IMX_CHIP_REVISION_1_0) || - cpu_is_imx6dl()) { - clk_set_parent(clk[ldb_di0_sel], clk[pll5_video_div]); - clk_set_parent(clk[ldb_di1_sel], clk[pll5_video_div]); - } - clk_set_parent(clk[ipu1_di0_pre_sel], clk[pll5_video_div]); clk_set_parent(clk[ipu1_di1_pre_sel], clk[pll5_video_div]); clk_set_parent(clk[ipu2_di0_pre_sel], clk[pll5_video_div]);
Then the HDMI detection works fine and I get images on both HDMI and LVDS.
I understand that many LVDS panels need a frequency range that can only be obtained via PLL5 though.
On Mon, Jun 9, 2014 at 3:38 PM, Fabio Estevam festevam@gmail.com wrote:
On Mon, Jun 9, 2014 at 3:15 PM, Fabio Estevam festevam@gmail.com wrote:
I wonder if the problem is that HDMI and LVDS are interfering with each other wrt the required pixel clock, and LVDS is winning. If we have HDMI enabled, many HDMI sinks will only work if we set one of their supported modes (with the dot clock within 1% - though some sinks are more lenient).
Yes, it seems this is the case.
I tested not using pll5 as the parent of LVDS:
--- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -439,12 +439,6 @@ static void __init imx6q_clocks_init(struct device_node *cc clk_register_clkdev(clk[gpt_ipg_per], "per", "imx-gpt.0"); clk_register_clkdev(clk[enet_ref], "enet_ref", NULL);
if ((imx_get_soc_revision() != IMX_CHIP_REVISION_1_0) ||
cpu_is_imx6dl()) {
clk_set_parent(clk[ldb_di0_sel], clk[pll5_video_div]);
clk_set_parent(clk[ldb_di1_sel], clk[pll5_video_div]);
}
clk_set_parent(clk[ipu1_di0_pre_sel], clk[pll5_video_div]); clk_set_parent(clk[ipu1_di1_pre_sel], clk[pll5_video_div]); clk_set_parent(clk[ipu2_di0_pre_sel], clk[pll5_video_div]);
Then the HDMI detection works fine and I get images on both HDMI and LVDS.
I understand that many LVDS panels need a frequency range that can only be obtained via PLL5 though.
Also tested keeping LVDS parent as PLL5 and reverted this commit:
commit 17b9b3b9e88ac6564689283a08034faf2c048fdb Author: Sascha Hauer s.hauer@pengutronix.de Date: Mon Apr 14 16:20:39 2014 +0200
ARM: imx6q: clk: Parent DI clocks to video PLL via di_pre_sel
Route the video PLL to the display interface clocks via the di_pre_sel and di_sel muxes by default.
Signed-off-by: Sascha Hauer s.hauer@pengutronix.de Signed-off-by: Philipp Zabel p.zabel@pengutronix.de Tested-by: Russell King rmk+kernel@arm.linux.org.uk Signed-off-by: Shawn Guo shawn.guo@freescale.com
,then HDMI and LVDS work at the same time.
On Mon, Jun 09, 2014 at 03:47:46PM -0300, Fabio Estevam wrote:
Also tested keeping LVDS parent as PLL5 and reverted this commit:
commit 17b9b3b9e88ac6564689283a08034faf2c048fdb Author: Sascha Hauer s.hauer@pengutronix.de Date: Mon Apr 14 16:20:39 2014 +0200
ARM: imx6q: clk: Parent DI clocks to video PLL via di_pre_sel Route the video PLL to the display interface clocks via the di_pre_sel and di_sel muxes by default. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de> Tested-by: Russell King <rmk+kernel@arm.linux.org.uk> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
,then HDMI and LVDS work at the same time.
Right, so the problem isn't at the HDMI level, but at the DI level... so that's where we need to debug what's being setup. I left some debugging in ipu-di.c - could you try enabling that please?
On Mon, Jun 9, 2014 at 5:09 PM, Russell King - ARM Linux linux@arm.linux.org.uk wrote:
Right, so the problem isn't at the HDMI level, but at the DI level... so that's where we need to debug what's being setup. I left some debugging in ipu-di.c - could you try enabling that please?
Sure, will capture the logs tomorrow morning because I don't have access to the HDMI monitor at the moment.
Thanks
On Mon, Jun 9, 2014 at 5:09 PM, Russell King - ARM Linux linux@arm.linux.org.uk wrote:
Right, so the problem isn't at the HDMI level, but at the DI level... so that's where we need to debug what's being setup. I left some debugging in ipu-di.c - could you try enabling that please?
Booting the kernel with the HDMI cable connected (no image is seen on HDMI, only on LVDS):
imx-ipuv3 2400000.ipu: DI0 base: 0x02640000 remapped to c08f6000 imx-ipuv3 2400000.ipu: DI1 base: 0x02648000 remapped to c08fe000 imx-ipuv3 2400000.ipu: IPUv3H probed imx-ipuv3 2800000.ipu: DI0 base: 0x02a40000 remapped to c09b6000 imx-ipuv3 2800000.ipu: DI1 base: 0x02a48000 remapped to c09be000 imx-ipuv3 2800000.ipu: IPUv3H probed mmcblk0: mmc1:0007 SD4GB 3.70 GiB [drm] Supports vblank timestamp caching Rev 2 (21.10.2013). [drm] No driver support for vblank timestamp query. imx-drm display-subsystem.11: bound imx-ipuv3-crtc.0 (ops ipu_crtc_ops) imx-drm display-subsystem.11: bound imx-ipuv3-crtc.1 (ops ipu_crtc_ops) imx-drm display-subsystem.11: bound imx-ipuv3-crtc.2 (ops ipu_crtc_ops) imx-drm display-subsystem.11: bound imx-ipuv3-crtc.3 (ops ipu_crtc_ops) imx-hdmi 120000.hdmi: Detected HDMI controller 0x13:0xa:0xa0:0xc1 imx-drm display-subsystem.11: bound 120000.hdmi (ops hdmi_ops) imx-drm display-subsystem.11: bound ldb.10 (ops imx_ldb_ops) mmcblk0: unknown partition table imx-ipuv3 2400000.ipu: disp 0: panel size = 1920 x 1080 imx-ipuv3 2400000.ipu: Clocks: IPU 264000000Hz DI 24000000Hz Needed 138500000Hz imx-ipuv3 2400000.ipu: IPU clock can give 132000000 with divider 2, error -4.3% imx-ipuv3 2400000.ipu: Want 138500000Hz IPU 264000000Hz DI 138500000Hz using DI, 138500000Hz imx-ipuv3 2400000.ipu: disp 1: panel size = 1024 x 768 imx-ipuv3 2400000.ipu: Clocks: IPU 264000000Hz DI 64999999Hz Needed 65000000Hz imx-ipuv3 2400000.ipu: Want 65000000Hz IPU 264000000Hz DI 64999999Hz using DI, 64999999Hz
After cable removal: root@freescale /$ imx-ipuv3 2400000.ipu: disp 0: panel size = 1024 x 768 imx-ipuv3 2400000.ipu: Clocks: IPU 264000000Hz DI 64999999Hz Needed 65000000Hz imx-ipuv3 2400000.ipu: Want 65000000Hz IPU 264000000Hz DI 64999999Hz using DI, 64999999Hz
After cable re-insertion (image is seen on both HDMI and LVDS):
imx-ipuv3 2400000.ipu: disp 0: panel size = 1920 x 1080 imx-ipuv3 2400000.ipu: Clocks: IPU 264000000Hz DI 64999999Hz Needed 138500000Hz imx-ipuv3 2400000.ipu: IPU clock can give 132000000 with divider 2, error -4.3% imx-ipuv3 2400000.ipu: Want 138500000Hz IPU 264000000Hz DI 129999997Hz using DI, 129999997Hz imx-ipuv3 2400000.ipu: disp 1: panel size = 1024 x 768 imx-ipuv3 2400000.ipu: Clocks: IPU 264000000Hz DI 64999999Hz Needed 65000000Hz imx-ipuv3 2400000.ipu: Want 65000000Hz IPU 264000000Hz DI 64999999Hz using DI, 64999999Hz
On Tue, Jun 10, 2014 at 9:58 AM, Fabio Estevam festevam@gmail.com wrote:
On Mon, Jun 9, 2014 at 5:09 PM, Russell King - ARM Linux linux@arm.linux.org.uk wrote:
Right, so the problem isn't at the HDMI level, but at the DI level... so that's where we need to debug what's being setup. I left some debugging in ipu-di.c - could you try enabling that please?
Booting the kernel with the HDMI cable connected (no image is seen on HDMI, only on LVDS):
In case it helps, I am also able to reproduce the problem on a imx6dl-hummingboard using the attached debug patch.
On Tue, Jun 10, 2014 at 10:32:25AM -0300, Fabio Estevam wrote:
On Tue, Jun 10, 2014 at 9:58 AM, Fabio Estevam festevam@gmail.com wrote:
On Mon, Jun 9, 2014 at 5:09 PM, Russell King - ARM Linux linux@arm.linux.org.uk wrote:
Right, so the problem isn't at the HDMI level, but at the DI level... so that's where we need to debug what's being setup. I left some debugging in ipu-di.c - could you try enabling that please?
Booting the kernel with the HDMI cable connected (no image is seen on HDMI, only on LVDS):
In case it helps, I am also able to reproduce the problem on a imx6dl-hummingboard using the attached debug patch.
Thanks, that's most useful for my testing. I have a version of the HB here which has an LVDS connector on... but I have no LVDS panel to connect to it.
Anyway, this is the pertinent information which confirms what's going on... from /sys/kernel/debug/clk/clk_summary - reformatting a little:
pll5_video 1 1 909999984 0 pll5_post_div 1 1 454999992 0 pll5_video_div 2 2 454999992 0 ... ipu1_di0_pre_sel 1 1 454999992 0 ipu1_di0_pre 1 1 454999992 0 ipu1_di0_sel 1 1 454999992 0 ipu1_di0 1 1 454999992 0 ldb_di1_sel 1 1 454999992 0 ldb_di1_div_3_5 1 1 129999997 0 ldb_di1_podf 1 1 64999999 0 ldb_di1 1 1 64999999 0 ipu1_di1_sel 1 1 64999999 0 ipu1_di1 1 1 64999999 0
This shows that ipu1_di1 is correctly connected to the ldb_di1 clock, and we can see what happened to the HDMI clock - and it's /not/ good because we end up feeding a clock in excess of the stated maximum to the IPU... 455MHz vs 270MHz max.
When Xorg is running, and Xorg has disabled the LVDS:
pll5_video 1 1 1188000000 0 pll5_post_div 1 1 297000000 0 pll5_video_div 1 1 148500000 0 ... ipu1_di0_pre_sel 1 1 148500000 0 ipu1_di0_pre 1 1 148500000 0 ipu1_di0_sel 1 1 148500000 0 ipu1_di0 1 1 148500000 0 ldb_di1_sel 0 0 148500000 0 ldb_di1_div_3_5 0 0 42428571 0 ldb_di1_podf 0 0 21214286 0 ldb_di1 0 0 21214286 0 ipu1_di1_sel 0 0 21214286 0 ipu1_di1 0 0 21214286 0
Now, can we satisfy the combination of required clocks...
LDB - 65MHz pixel clock, * 7 => 455MHz shift clock (note that had PLL3 PFD3 been routed to the LDB clocks, then we'd almost have this - 454.7MHz.)
HDMI - 148.5MHz pixel clock * 2 => 297MHz * 3 => 445.5MHz * 4 => 594MHz (note that had PLL2 PFD1 been routed to the IPU DI clocks, this would get 1080, 720, 576 and 480 p/i modes.)
Well, that question becomes whether 446MHz (3sf) and 455MHz are close enough. Given that the HDMI clock is related to the audio clock, we should try to maintain its accuracy. So, subsituting 446MHz as the LDB shift clock would give us a clock of 63.6MHz, which is a little over a 2% error.
The problem here is that we need more inteligence from CCF in order to do that - we need it to be able to reprogram the dividers so that the IPU DI0 clock remains at 148.5MHz while increasing the output of pll5_video_div three-fold.
Another solution would be to source the LDB clock from PLL3 at 480MHz, this gives a pixel clock of 68.6MHz (3sf). The other options are 396MHz, 352MHz which would produce a considerably slower clock.
I've just been digging in a few LVDS panel data sheets, and it seems many have quite a tolerance on the clock. A 640x480 panel (Optrex) says anything between 20 and 30MHz is acceptable. An 800x600 Toshiba works out at anything between 29MHz and 40MHz. AUO 1024x768 gives a range of 50 to 81MHz. However, there are some other AUO panels which we have in drm_panel which specify an exact frequency. We don't have the ability in drm_panel to specify a range of frequencies - it may be useful if we did, since we could use that to work out whether we can drive both simultaneously off one PLL or one of the fixed clocks.
Hi Russell,
Am Mittwoch, den 11.06.2014, 09:17 +0100 schrieb Russell King - ARM Linux:
On Tue, Jun 10, 2014 at 10:32:25AM -0300, Fabio Estevam wrote:
On Tue, Jun 10, 2014 at 9:58 AM, Fabio Estevam festevam@gmail.com wrote:
On Mon, Jun 9, 2014 at 5:09 PM, Russell King - ARM Linux linux@arm.linux.org.uk wrote:
Right, so the problem isn't at the HDMI level, but at the DI level... so that's where we need to debug what's being setup. I left some debugging in ipu-di.c - could you try enabling that please?
Booting the kernel with the HDMI cable connected (no image is seen on HDMI, only on LVDS):
In case it helps, I am also able to reproduce the problem on a imx6dl-hummingboard using the attached debug patch.
Thanks, that's most useful for my testing. I have a version of the HB here which has an LVDS connector on... but I have no LVDS panel to connect to it.
Anyway, this is the pertinent information which confirms what's going on... from /sys/kernel/debug/clk/clk_summary - reformatting a little:
[...]
Now, can we satisfy the combination of required clocks...
LDB - 65MHz pixel clock, * 7 => 455MHz shift clock (note that had PLL3 PFD3 been routed to the LDB clocks, then we'd almost have this - 454.7MHz.)
HDMI - 148.5MHz pixel clock * 2 => 297MHz * 3 => 445.5MHz * 4 => 594MHz (note that had PLL2 PFD1 been routed to the IPU DI clocks, this would get 1080, 720, 576 and 480 p/i modes.)
That would have been nice. Also there's the Audio PLL which is similar to the Video PLL, only with a different post divider.
Well, that question becomes whether 446MHz (3sf) and 455MHz are close enough. Given that the HDMI clock is related to the audio clock, we should try to maintain its accuracy. So, subsituting 446MHz as the LDB shift clock would give us a clock of 63.6MHz, which is a little over a 2% error.
The problem here is that we need more inteligence from CCF in order to do that - we need it to be able to reprogram the dividers so that the IPU DI0 clock remains at 148.5MHz while increasing the output of pll5_video_div three-fold.
Part of this could be achieved if clock notifiers would have a way to give feedback to the core code when they NAK a clock change.
[...]
I've just been digging in a few LVDS panel data sheets, and it seems many have quite a tolerance on the clock. A 640x480 panel (Optrex) says anything between 20 and 30MHz is acceptable. An 800x600 Toshiba works out at anything between 29MHz and 40MHz. AUO 1024x768 gives a range of 50 to 81MHz. However, there are some other AUO panels which we have in drm_panel which specify an exact frequency. We don't have the ability in drm_panel to specify a range of frequencies - it may be useful if we did, since we could use that to work out whether we can drive both simultaneously off one PLL or one of the fixed clocks.
For this reason struct display_timing includes minimum, maximum and typical values for all timing parameters. This is also supported by the display timing device tree bindings: Documentation/devicetree/bindings/video/display-timing.txt Unfortunately there is no code yet that can make use of this information.
regards Philipp
On Wed, Jun 11, 2014 at 5:17 AM, Russell King - ARM Linux linux@arm.linux.org.uk wrote:
The problem here is that we need more inteligence from CCF in order to do that - we need it to be able to reprogram the dividers so that the IPU DI0 clock remains at 148.5MHz while increasing the output of pll5_video_div three-fold.
Another solution would be to source the LDB clock from PLL3 at 480MHz, this gives a pixel clock of 68.6MHz (3sf). The other options are
Ok, I have tried this approach:
--- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -441,8 +441,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm
if ((imx_get_soc_revision() != IMX_CHIP_REVISION_1_0) || cpu_is_imx6dl()) { - clk_set_parent(clk[ldb_di0_sel], clk[pll5_video_div]); - clk_set_parent(clk[ldb_di1_sel], clk[pll5_video_div]); + clk_set_parent(clk[ldb_di0_sel], clk[pll3_usb_otg]); + clk_set_parent(clk[ldb_di1_sel], clk[pll3_usb_otg]); }
and it allows HDMI and LVDS to be displayed if I boot with the HDMI kernel connected. Would this be an acceptable solution in the meantime?
On Mon, Jun 16, 2014 at 11:13:02AM -0300, Fabio Estevam wrote:
On Wed, Jun 11, 2014 at 5:17 AM, Russell King - ARM Linux linux@arm.linux.org.uk wrote:
The problem here is that we need more inteligence from CCF in order to do that - we need it to be able to reprogram the dividers so that the IPU DI0 clock remains at 148.5MHz while increasing the output of pll5_video_div three-fold.
Another solution would be to source the LDB clock from PLL3 at 480MHz, this gives a pixel clock of 68.6MHz (3sf). The other options are
Ok, I have tried this approach:
--- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -441,8 +441,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm
if ((imx_get_soc_revision() != IMX_CHIP_REVISION_1_0) || cpu_is_imx6dl()) {
clk_set_parent(clk[ldb_di0_sel], clk[pll5_video_div]);
clk_set_parent(clk[ldb_di1_sel], clk[pll5_video_div]);
clk_set_parent(clk[ldb_di0_sel], clk[pll3_usb_otg]);
clk_set_parent(clk[ldb_di1_sel], clk[pll3_usb_otg]); }
and it allows HDMI and LVDS to be displayed if I boot with the HDMI kernel connected. Would this be an acceptable solution in the meantime?
I have no objection to that as an interim solution, but it does leave me wondering whether this causes LDB to change the USB OTG clocks. Might it be worth printing something, just in case someone finds USB OTG breaks and wonders why?
On Tue, Jun 10, 2014 at 09:58:54AM -0300, Fabio Estevam wrote:
Booting the kernel with the HDMI cable connected (no image is seen on HDMI, only on LVDS):
Reformatting a bit:
disp 0: panel size = 1920 x 1080 Clocks: IPU 264000000Hz DI 24000000Hz Needed 138500000Hz IPU clock can give 132000000 with divider 2, error -4.3% Want 138500000Hz IPU 264000000Hz DI 138500000Hz using DI, 138500000Hz disp 1: panel size = 1024 x 768 Clocks: IPU 264000000Hz DI 64999999Hz Needed 65000000Hz Want 65000000Hz IPU 264000000Hz DI 64999999Hz using DI, 64999999Hz
After cable removal: disp 0: panel size = 1024 x 768 Clocks: IPU 264000000Hz DI 64999999Hz Needed 65000000Hz Want 65000000Hz IPU 264000000Hz DI 64999999Hz using DI, 64999999Hz
So here we can see that the clock for DI0 got changed beneath it from 138.5MHz to 65MHz, probably when the DI1 clock was changed.
After cable re-insertion (image is seen on both HDMI and LVDS): disp 0: panel size = 1920 x 1080 Clocks: IPU 264000000Hz DI 64999999Hz Needed 138500000Hz IPU clock can give 132000000 with divider 2, error -4.3% Want 138500000Hz IPU 264000000Hz DI 129999997Hz using DI, 129999997Hz disp 1: panel size = 1024 x 768 Clocks: IPU 264000000Hz DI 64999999Hz Needed 65000000Hz Want 65000000Hz IPU 264000000Hz DI 64999999Hz using DI, 64999999Hz
The strange thing here is that DI0, when asking for 138.5MHz, only gets 130MHz (a multiple of DI1's frequency) yet when DI1 reduced it to 65MHz, the CCF just obliged.
Let's go back to the basic requirements for LDB, because I think there's a bug here.
1. the LDB serial clock must be 7x the LDB DI clock. 2. for single/split/separate mode, the IPU DI clock must be the same and synchronous with the LDB DI clock. 3. for dual mode, the IPU DI clock must be twice the LDB DI clock, and must be synchronised with the LDB DI clock.
(1) is provided for us via the CCM clock tree - there is already a /7 divider between the LDB serial clock and the LDB DI clock:
LM --+-------- LDB serial `- /7 -- LDB DI clock
where LM is the LDB clock muxer.
I'm going to leave case (3) for the time being, because at the moment, I can't see how to achieve it given the clock tree structure that the iMX6 CPUs offer - I'm going to make the assumption at the present time that this mode is not supported.
The easiest way to achieve (2) is to set the IPU DI clock mux to select the LDB DI clock directly:
LM --+---------------- LDB serial `- /7 -+-------- LDB DI clock `- IM -- IPU DI clock
where 'M' is the IPU DI clock muxer. However, we're currently setting this up as:
LM --+---------------- LDB serial `- /7 -+-------- LDB DI clock IPM --- /N ---- IM --- IPU DI clock
and hoping that the LDB and IPU DI clocks are appropriately synchronised. This is the bug I refer to above.
Finally, for HDMI, we need:
PLL5 -- IPM -- IM -- IPU DI clock
What this implies is that we need control of the IPU DI clock muxer (IM) and each DI needs to know what kind of display bridge(s) are connected to it, so that the appropriate parent(s) can be selected.
We can get a little closer to that (and clean up the code) with the patch below. It gives us some of the information we have really been wanting to know all along in ipu_crtc_mode_set(), that is which kinds of bridges are connected to the DI.
What we /really/ need to solve the above problem is exactly which bridges are connected as well - whether it's LDB0 or LDB1, and also how to get at the clocks to be able to control that mux. I'm at a loss how best to do that given the complexity of iMX6 DT, and I don't think we want to add these to the IPU/DI node as the IPU/DI isn't really connected to these clocks - it's connected to the IM mux which is internal to the CCM.
I think this patch also should help Denis Carikli, as the polarity of the clock signal (etc) also depends on the type(s) of encoders attached to the DI. We really should fail if we end up with encoders with incompatible requirements trying to be bound to a single DI.
(side note: I'd really like to get rid of imx_drm_panel_format*()...)
In any case, to fix this I think we're looking at changing the DT stuff again, and as the IPU code is moving out of drivers/staging, this is going to become increasing difficult...
drivers/staging/imx-drm/imx-drm-core.c | 3 +-- drivers/staging/imx-drm/imx-drm.h | 2 +- drivers/staging/imx-drm/ipuv3-crtc.c | 40 +++++++++++++++++++--------------- 3 files changed, 25 insertions(+), 20 deletions(-)
diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index 7da0cad27b49..c538c82f8a32 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -115,8 +115,7 @@ int imx_drm_panel_format_pins(struct drm_encoder *encoder, helper = &imx_crtc->imx_drm_helper_funcs; if (helper->set_interface_pix_fmt) return helper->set_interface_pix_fmt(encoder->crtc, - encoder->encoder_type, interface_pix_fmt, - hsync_pin, vsync_pin); + interface_pix_fmt, hsync_pin, vsync_pin); return 0; } EXPORT_SYMBOL_GPL(imx_drm_panel_format_pins); diff --git a/drivers/staging/imx-drm/imx-drm.h b/drivers/staging/imx-drm/imx-drm.h index a322bac55414..0bf8e5eb76e3 100644 --- a/drivers/staging/imx-drm/imx-drm.h +++ b/drivers/staging/imx-drm/imx-drm.h @@ -17,7 +17,7 @@ int imx_drm_crtc_id(struct imx_drm_crtc *crtc); struct imx_drm_crtc_helper_funcs { int (*enable_vblank)(struct drm_crtc *crtc); void (*disable_vblank)(struct drm_crtc *crtc); - int (*set_interface_pix_fmt)(struct drm_crtc *crtc, u32 encoder_type, + int (*set_interface_pix_fmt)(struct drm_crtc *crtc, u32 pix_fmt, int hsync_pin, int vsync_pin); const struct drm_crtc_helper_funcs *crtc_helper_funcs; const struct drm_crtc_funcs *crtc_funcs; diff --git a/drivers/staging/imx-drm/ipuv3-crtc.c b/drivers/staging/imx-drm/ipuv3-crtc.c index 47bec5e17358..796e9bef15f0 100644 --- a/drivers/staging/imx-drm/ipuv3-crtc.c +++ b/drivers/staging/imx-drm/ipuv3-crtc.c @@ -51,7 +51,6 @@ struct ipu_crtc { struct drm_framebuffer *newfb; int irq; u32 interface_pix_fmt; - unsigned long di_clkflags; int di_hsync_pin; int di_vsync_pin; }; @@ -146,10 +145,13 @@ static int ipu_crtc_mode_set(struct drm_crtc *crtc, int x, int y, struct drm_framebuffer *old_fb) { + struct drm_device *dev = crtc->dev; + struct drm_encoder *encoder; struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); - int ret; struct ipu_di_signal_cfg sig_cfg = {}; + unsigned long encoder_types = 0; u32 out_pixel_fmt; + int ret;
dev_dbg(ipu_crtc->dev, "%s: mode->hdisplay: %d\n", __func__, mode->hdisplay); @@ -165,6 +167,24 @@ static int ipu_crtc_mode_set(struct drm_crtc *crtc, if (mode->flags & DRM_MODE_FLAG_PVSYNC) sig_cfg.Vsync_pol = 1;
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) + if (encoder->crtc == crtc) + encoder_types |= BIT(encoder->encoder_type); + + dev_dbg(ipu_crtc->dev, "%s: attached to encoder types 0x%x\n", + __func__, encoder_types); + + /* + * If we have DAC, TVDAC or LDB, then we need the IPU DI clock + * to be the same as the LDB DI clock. + */ + if (encoder_types & (BIT(DRM_MODE_ENCODER_DAC) | + BIT(DRM_MODE_ENCODER_TVDAC) | + BIT(DRM_MODE_ENCODER_LVDS))) + sig_cfg.clkflags = IPU_DI_CLKMODE_SYNC | IPU_DI_CLKMODE_EXT; + else + sig_cfg.clkflags = 0; + sig_cfg.enable_pol = 1; sig_cfg.clk_pol = 0; sig_cfg.width = mode->hdisplay; @@ -178,7 +198,6 @@ static int ipu_crtc_mode_set(struct drm_crtc *crtc, sig_cfg.v_sync_width = mode->vsync_end - mode->vsync_start; sig_cfg.v_end_width = mode->vsync_start - mode->vdisplay; sig_cfg.pixelclock = mode->clock * 1000; - sig_cfg.clkflags = ipu_crtc->di_clkflags;
sig_cfg.v_to_h_sync = 0;
@@ -277,7 +296,7 @@ static void ipu_disable_vblank(struct drm_crtc *crtc) ipu_crtc->newfb = NULL; }
-static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc, u32 encoder_type, +static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc, u32 pixfmt, int hsync_pin, int vsync_pin) { struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); @@ -286,19 +305,6 @@ static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc, u32 encoder_type, ipu_crtc->di_hsync_pin = hsync_pin; ipu_crtc->di_vsync_pin = vsync_pin;
- switch (encoder_type) { - case DRM_MODE_ENCODER_DAC: - case DRM_MODE_ENCODER_TVDAC: - case DRM_MODE_ENCODER_LVDS: - ipu_crtc->di_clkflags = IPU_DI_CLKMODE_SYNC | - IPU_DI_CLKMODE_EXT; - break; - case DRM_MODE_ENCODER_TMDS: - case DRM_MODE_ENCODER_NONE: - ipu_crtc->di_clkflags = 0; - break; - } - return 0; }
On Tue, Jun 10, 2014 at 04:13:06PM +0100, Russell King - ARM Linux wrote:
where 'M' is the IPU DI clock muxer. However, we're currently setting this up as:
LM --+---------------- LDB serial `- /7 -+-------- LDB DI clock IPM --- /N ---- IM --- IPU DI clock
and hoping that the LDB and IPU DI clocks are appropriately synchronised.
I've just found that we do indeed do this - but there's nothing to switch the configuration back when the LDB is no longer using a particular DI.
Also, I'm having a hard time working out why we have the LDB being given all sorts of clocks...
LM --+----------------- LDB serial (clks 33, aka di0_pll) `- /7 -+--------- LDB DI clock (clks 135, aka di0) `- IM --- IPU DI clock (clks 39, aka di0_sel)
The LDB is given all of these to play with, including reprogramming the IM, and there's nothing which ever programs IM to anything but the LDB DI clock once it's set there.
Not only does this feel horribly unclean from the DT perspective, but it's also a horrid violation of reasonable layering. What if we wanted to fix this by adding control of di0_sel to the HDMI interface too? We then need to list yet again the IPU DI clock and the desired input clock there, and make the imx-hdmi code aware of that.
Wouldn't it be better to have the ipuv3-crtc, or even the IPU DI code be in control of its external clock mux, and request the IPU DI code to select a particular input clock? In other words, have one central place where the IPU DI clock is controlled, rather than ending up with it spread through lots of different sub-drivers?
On Tue, Jun 10, 2014 at 05:14:21PM +0100, Russell King - ARM Linux wrote:
On Tue, Jun 10, 2014 at 04:13:06PM +0100, Russell King - ARM Linux wrote:
where 'M' is the IPU DI clock muxer. However, we're currently setting this up as:
LM --+---------------- LDB serial `- /7 -+-------- LDB DI clock IPM --- /N ---- IM --- IPU DI clock
and hoping that the LDB and IPU DI clocks are appropriately synchronised.
I've just found that we do indeed do this - but there's nothing to switch the configuration back when the LDB is no longer using a particular DI.
Also, I'm having a hard time working out why we have the LDB being given all sorts of clocks...
LM --+----------------- LDB serial (clks 33, aka di0_pll) `- /7 -+--------- LDB DI clock (clks 135, aka di0) `- IM --- IPU DI clock (clks 39, aka di0_sel)
The LDB is given all of these to play with, including reprogramming the IM, and there's nothing which ever programs IM to anything but the LDB DI clock once it's set there.
*Sigh*... is the clock tree represented in Linux even correct?
--|\ --| | --| |------------------+----------------------------------------- --| | ^ ldb_di0_sel | --|/ (clks 33) | `-- /3.5 ---- /2 ------------------ G -+-- ^ ^ ldb_di0_podf | ^ ldb_di0 ldb_di0_div_3_5 | .----------------------' | '------|\ (ldb_di1)------------| | (ipp_di0)------------| |--------- G ---- (ipp_di1)------------| | ^ ^ ipu1_di0 (ipu1_di0_pre)------------|/ ipu1_di0_sel
This diagram is drawn from the code in clk-imx6.c, and it does not agree with what is in the SoC manuals - this is the representation redrawn from the manuals:
--|\ --| | --| |------------------+---------------------------------- G ---- --| | ^ ldb_di0_sel | ^ ldb serial --|/ (clks 33) | `-- /3.5 ---- /2 -----------------+------- ^ ^ ldb_di0_podf | ^ ldb di ldb_di0_div_3_5 | .-----------------' | '------|\ (ldb_di1)------------| | (ipp_di0)------------| |--------- G ---- (ipp_di1)------------| | ^ ^ ipu1_di0 (ipu1_di0_pre)------------|/ ipu1_di0_sel
The difference is, there is no clock gate between the LDB DI clock and the /7 divider, but there is a clock gate on the LDB serial clock.
In another location, the iMX6QDL manual suggests that it may be more like this:
--|\ --| | --| |----------- cg ---+----------------------------------------- --| | ^ ldb_di0_sel | ^ ldb serial --|/ (clks 33) | `-- /3.5 ---- /2 -----------------+------- ^ ^ ldb_di0_podf | ^ ldb di ldb_di0_div_3_5 | .-----------------' | '------|\ (ldb_di1)------------| | (ipp_di0)------------| |---------------- (ipp_di1)------------| | ^ ^ ipu1_di0 (ipu1_di0_pre)-- cg ------|/ ipu1_di0_sel
although "cg" is not defined what it is. Another place seems to confirm the above diagram, saying that the "ldb_di0_clk_enable" gating bits controls both "ch_0_serial_clk" (presumably the ldb serial clock) and "di_0_clk_nc" (presumably the ldb di clock. If that's correct "cg" refers to the clock gating via the CCM_CCGR registers, which appear in the CCM clock tree diagram under LPCG.
So... I wonder which one of these three is actually the right one...
On Tue, Jun 10, 2014 at 2:04 PM, Russell King - ARM Linux linux@arm.linux.org.uk wrote:
This diagram is drawn from the code in clk-imx6.c, and it does not agree with what is in the SoC manuals - this is the representation redrawn from the manuals:
....
The difference is, there is no clock gate between the LDB DI clock and the /7 divider, but there is a clock gate on the LDB serial clock.
This is the correct version. "i.MX 6Dual/6Quad Applications Processor Reference Manual - Rev. 1, 04/2013" shows it incorrectly though.
On Mon, Jun 09, 2014 at 03:38:55PM -0300, Fabio Estevam wrote:
On Mon, Jun 9, 2014 at 3:15 PM, Fabio Estevam festevam@gmail.com wrote:
I wonder if the problem is that HDMI and LVDS are interfering with each other wrt the required pixel clock, and LVDS is winning. If we have HDMI enabled, many HDMI sinks will only work if we set one of their supported modes (with the dot clock within 1% - though some sinks are more lenient).
Yes, it seems this is the case.
I tested not using pll5 as the parent of LVDS:
--- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -439,12 +439,6 @@ static void __init imx6q_clocks_init(struct device_node *cc clk_register_clkdev(clk[gpt_ipg_per], "per", "imx-gpt.0"); clk_register_clkdev(clk[enet_ref], "enet_ref", NULL);
if ((imx_get_soc_revision() != IMX_CHIP_REVISION_1_0) ||
cpu_is_imx6dl()) {
clk_set_parent(clk[ldb_di0_sel], clk[pll5_video_div]);
clk_set_parent(clk[ldb_di1_sel], clk[pll5_video_div]);
}
clk_set_parent(clk[ipu1_di0_pre_sel], clk[pll5_video_div]); clk_set_parent(clk[ipu1_di1_pre_sel], clk[pll5_video_div]); clk_set_parent(clk[ipu2_di0_pre_sel], clk[pll5_video_div]);
Then the HDMI detection works fine and I get images on both HDMI and LVDS.
I understand that many LVDS panels need a frequency range that can only be obtained via PLL5 though.
HDMI pretty much fundamentally requires PLL5.
On Mon, Jun 09, 2014 at 03:15:16PM -0300, Fabio Estevam wrote:
With HDMI cable connected (no image is seen on HDMI, only on lvds cable):
imx-drm display-subsystem.11: bound 120000.hdmi (ops hdmi_ops) imx-hdmi 120000.hdmi: EVENT=plugin imx-hdmi 120000.hdmi: Non-CEA mode used in HDMI imx-hdmi 120000.hdmi: final pixclk = 0
Right, so it does know that the HDMI sink is connected...
imx-drm display-subsystem.11: bound ldb.10 (ops imx_ldb_ops) imx-hdmi 120000.hdmi: imx_hdmi_setup DVI mode imx-hdmi 120000.hdmi: got edid: width[51] x height[28] imx-hdmi 120000.hdmi: Non-CEA mode used in HDMI imx-hdmi 120000.hdmi: final pixclk = 138500000 imx-hdmi 120000.hdmi: imx_hdmi_setup DVI mode imx-hdmi 120000.hdmi: Non-CEA mode used in HDMI imx-hdmi 120000.hdmi: final pixclk = 138500000 imx-hdmi 120000.hdmi: imx_hdmi_setup DVI mode
And the mode it's setting has a pixel clock frequency of 138.5MHz here.
If I disconnect/reconnect the HDMI cable (then image is seen on both HDMI and LVDS):
root@freescale /$ imx-hdmi 120000.hdmi: EVENT=plugout imx-hdmi 120000.hdmi: EVENT=plugin imx-hdmi 120000.hdmi: Non-CEA mode used in HDMI imx-hdmi 120000.hdmi: final pixclk = 138500000 imx-hdmi 120000.hdmi: imx_hdmi_setup DVI mode imx-hdmi 120000.hdmi: got edid: width[51] x height[28] imx-hdmi 120000.hdmi: Non-CEA mode used in HDMI imx-hdmi 120000.hdmi: final pixclk = 138500000 imx-hdmi 120000.hdmi: imx_hdmi_setup DVI mode imx-hdmi 120000.hdmi: Non-CEA mode used in HDMI imx-hdmi 120000.hdmi: final pixclk = 138500000 imx-hdmi 120000.hdmi: imx_hdmi_setup DVI mode
And here it again configures 138.5MHz pixel clock - same as above. So, from this we can't see any difference in the setup, and we can say that it's not mode->clock which is the problem.
Now booting the kernel with HDMI disconnected:
imx-hdmi 120000.hdmi: Detected HDMI controller 0x13:0xa:0xa0:0xc1 imx-hdmi 120000.hdmi: hdmi_set_clk_regenerator: samplerate=48000 ratio=100 pixelclk=74250000 N=6144 cts=74250 imx-drm display-subsystem.11: bound 120000.hdmi (ops hdmi_ops)
Right, so here it knows that there's nothing connected.
imx-drm display-subsystem.11: bound ldb.10 (ops imx_ldb_ops) Console: switching to colour frame buffer device 128x48
So it selects an initial mode based upon the LVDS device configuration.
And after connecting the HDMI cable:
imx-hdmi 120000.hdmi: EVENT=plugin imx-hdmi 120000.hdmi: Non-CEA mode used in HDMI imx-hdmi 120000.hdmi: final pixclk = 0 imx-hdmi 120000.hdmi: imx_hdmi_setup DVI mode imx-hdmi 120000.hdmi: got edid: width[51] x height[28] imx-hdmi 120000.hdmi: Non-CEA mode used in HDMI imx-hdmi 120000.hdmi: final pixclk = 78800000 imx-hdmi 120000.hdmi: imx_hdmi_setup DVI mode imx-hdmi 120000.hdmi: Non-CEA mode used in HDMI imx-hdmi 120000.hdmi: final pixclk = 78800000 imx-hdmi 120000.hdmi: imx_hdmi_setup DVI mode
Image is seen on both LVDS and HDMI monitor, but HDMI resolution is not correct (this is a different bug though).
I'm guessing that here, DRM kept the original configuration rather than selecting one appropriate to the newly connected device.
On Mon, Jun 9, 2014 at 7:29 AM, Fabio Estevam festevam@gmail.com wrote:
On Mon, Jun 9, 2014 at 11:06 AM, Russell King - ARM Linux linux@arm.linux.org.uk wrote:
Please check the status in /sys/class/drm/card0-HDMI-A-1/status. This should report the current state of the hotplug detection.
/sys/class/drm/card0-HDMI-A-1/status returns the correct state for HDMI cable connection.
Remember that this code detects off the HPD signal - if the HPD signal has not been correctly wired up, this patch is not going to help (really it comes down to a hardware fault, which I'm not trying to solve with this patch.)
What I'm trying to resolve with this patch is that the state detected on properly wired up systems corresponds with the real initial state of the interface at initialisation time.
The problem with the current code is that we start off assuming that the interface is disconnected, and we rely on an interrupt arriving to change that state. If for whatever reason that interrupt does not arrive, then, even if the HPD signal is active, we continue believing that the interface is not connected.
I seem to remember discussion in the past that the HPD signal is not wired up on SabreSD. Really, this needs to be a DT flag to indicate
It is sabrelite board that does not have HPD signal not wired up.
sabresd does have HPD signal connected.
The HDMI undetected issue I am seeing on sabresd seems to be related to the simultaneous usage of HDMI and LVDS.
If I remove the ldb node from the imx6qdl-sabresd.dtsi, then the HDMI cable is correctly detected and HDMI is shown right after boot.
Fabio,
I'm following along with this thread as I see the same thing you do on our Ventana boards that support both LVDS and HDMI: without hot-plugging the HDMI connector I get not HDMI out simply by having the LVDS node populated.
I am curious however how you are getting simultaneous display on both LVDS and HDMI on a SabreSD board as the standard resistor loading would make the EDID's of both conflict (which causes EDID read failures) - perhaps you are using an LVDS display with no EDID or perhaps you have modified the resistor loading on a SabreSD to move them to different i2cs? Or is there some kernel param/config I don't see to tell the imx_hdmi driver to ignore EDID and force in a mode?
Regards,
Tim
Hi Tim,
On Tue, Jun 10, 2014 at 3:54 PM, Tim Harvey tharvey@gateworks.com wrote:
Fabio,
I'm following along with this thread as I see the same thing you do on our Ventana boards that support both LVDS and HDMI: without hot-plugging the HDMI connector I get not HDMI out simply by having the LVDS node populated.
I am curious however how you are getting simultaneous display on both LVDS and HDMI on a SabreSD board as the standard resistor loading would make the EDID's of both conflict (which causes EDID read failures) - perhaps you are using an LVDS display with no EDID or
Yes, there is no EDID in the LVDS I am using.
imxqdl-sabresd.dtsi declares the LVDS resolution to be 1024x768 and it never changes.
dri-devel@lists.freedesktop.org