DRM Master ignoring hotplug event during display switching (QT)
Daniel Vetter
daniel at ffwll.ch
Wed Jun 8 15:42:42 UTC 2022
On Wed, Jun 08, 2022 at 05:41:29PM +0200, Daniel Vetter wrote:
> On Tue, Jun 07, 2022 at 11:03:09PM +0530, Jagan Teki wrote:
> > On Tue, Jun 7, 2022 at 8:04 PM Daniel Vetter <daniel at ffwll.ch> wrote:
> > >
> > > On Thu, 2 Jun 2022 at 17:43, Jagan Teki <jagan at amarulasolutions.com> wrote:
> > > >
> > > > Hi Daniel,
> > > >
> > > > On Wed, Mar 30, 2022 at 3:27 PM Daniel Vetter <daniel at ffwll.ch> wrote:
> > > > >
> > > > > On Wed, Mar 30, 2022 at 10:52:54AM +0200, Maxime Ripard wrote:
> > > > > > On Tue, Mar 29, 2022 at 11:38:32PM +0530, Jagan Teki wrote:
> > > > > > > Hi all,
> > > > > > >
> > > > > > > I have implemented runtime display switching in the MIPI switch design
> > > > > > > where LVDS and HDMI bridges are selected with the help of runtime
> > > > > > > GPIO.
> > > > > > >
> > > > > > > Initial discussion on the same can be found here,
> > > > > > > https://www.spinics.net/lists/dri-devel/msg318524.html
> > > > > > >
> > > > > > > The implementation has been done by creating each connector at
> > > > > > > runtime. The default boot will create the LVDS connector and based on
> > > > > > > the HDMI plug-in the ISR.
> > > > > > >
> > > > > > > 1. forcing the LVDS to disconnect
> > > > > > > 2. call drm_kms_helper_hotplug_event
> > > > > > > 3. detach the bridge chain
> > > > > > > 4. attach the new bridge chain (HDMI)
> > > > > > > 5. call drm_kms_helper_hotplug_event
> > > > > > >
> > > > > > > do the reverse when we unplug the HDMI cable.
> > > > > > >
> > > > > > > So, the bridge chains are attached and detached based on GPIO
> > > > > > > Interrupt which is indeed identified based on the physical HDMIA
> > > > > > > connector.
> > > > > > >
> > > > > > > Pipeline for LVDS,
> > > > > > > mxfsb => nwl-dsi => display-switch => sn65dsi83=> panel-bridge
> > > > > > >
> > > > > > > Pipeline for HDMI,
> > > > > > > mxfsb => nwl-dsi => display-switch => adv7511 => display-connector
> > > > > > >
> > > > > > > With this, implementation and I can able switch the displays with
> > > > > > > default DRM (without specific DRM applications) where the LVDS is ON
> > > > > > > by default and when HDMI plug-in the LVDS OFF/HDMI ON, and when HDMI
> > > > > > > unplug the HDMI OFF/LVDS ON.
> > > > > > >
> > > > > > > However, with QT5 I can see the DRM Master ignoring hotplug event by
> > > > > > > returning 0 on drm_master_internal_acquire in
> > > > > > > drm_fb_helper_hotplug_event. With this the hotplug returned early so
> > > > > > > it cannot able to disconnect and connect the new switching connector.
> > > > > > >
> > > > > > > Any help?
> > > > > >
> > > > > > I'm not sure why you started another discussion with pretty much the
> > > > > > same content, but you can't rely on userspace handling the hotplug
> > > > > > event. You'll have to deal with the case where it just doesn't.
> > > > >
> > > > > Well I missed the old thread, so I'm replying here.
> > > > >
> > > > > You should not handle this at all from a hotplug.
> > > > >
> > > > > The way kms works is roughly as follows:
> > > > >
> > > > > 1. hw output state changes
> > > > > 2. driver detects this (either through hpd interrupt or polling)
> > > > > 3. driver sends out hotplug uevent
> > > > >
> > > > > That's it. Nothing else, no bridge rebinding, no link retaining is
> > > > > required.
> > > > >
> > > > > Then either userspace or fbcon emulation reacts to this hotplug event by
> > > > > doing an atomic modeset, where it hopefully disables the old output and
> > > > > re-enables the new output. Your atomic_check needs to validate that
> > > > > everything is all right (i.e. not enabling both at the same time).
> > > > >
> > > > > Note that if you change stuff underneath, then that tends to seriously
> > > > > upset atomic users. Also you should try to continue supporting at least
> > > > > page flips with the wrong config, compositors otherwise tend to crash.
> > > > >
> > > > > This also means that if userspace doesn't handle hotplug events, then you
> > > > > might end up with a black screen. That's ok. We try to avoid that when
> > > > > it's practical (e.g. dp sst link retraining), but not when it's too hard
> > > > > (dp mst hot-replug relies on userspace restoring everything).
> > > > >
> > > > > Finally exchanging the bridge chain isn't supported, there's no locking
> > > > > for that since it's assumed to be invariant over the lifetim of the
> > > > > drm_device instance. The simplest way to make that happen right now is to
> > > > > have 2 drm_encoder instances, one with the lvds bridge chain, the other
> > > > > with the hdmi bridge chain, and select the right encoder/bridge chain
> > > > > depending upon which output userspace picks.
> > > >
> > > > I've created 2 instances of encoders. endpoint 0 for HDMI bridge chain
> > > > and endpoint 1 for LVDS bridge chain. Each bridge chain uses a
> > > > respective encoder instance in order to start attaching the bridge
> > > > like below.
> > > >
> > > > 1. find the bridge at endpoint 0
> > > > 2. drm_bridge_attach(&mxsfb->encoder[0], mxsfb->bridge[0], NULL, 0)
> > > >
> > > > and repeat for endpoint 1
> > > >
> > > > The bridge chain established fine for endpoint 0 but returned -EBUSY
> > > > while the bridge chain attached for endpoint 1. looks like bridge->dev
> > > > is still being used in endpoint 0 even though we have a separate
> > > > bridge point from mxsfb.
> > > >
> > > > Any thought on how to establish the dual bridge chain here?
> > >
> > > Are you using 2 different struct drm_bridge for this? Reusing the same
> > > drm_bridge for the 2nd encoder and endpoint is the only thing I can
> > > come up with that would result in this.
> >
> > Yes, I did try to re-use the same bridge pointer. drm_bridge_attach
> > giving an -EBUSY while attaching the 2nd bridge chain.
>
> Yeah that doesn't work. You can embed 2 drm_bridge within the same struct,
> that should work. So essentially 1 platform_driver which registers 2
> bridges. But binding the same bridge twice is an error, because a bridge
> is strictly a 1:1 connection. Not a 2:2 connection.
Two clarify: That struct with the 2 drm_bridge would be the platform
driver private you register, not part of your platform_driver structure
ofc. It needs to be attached to the struct platform_dev, not the driver.
Just in case I confused you here even more :-)
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
More information about the dri-devel
mailing list