Re: [PATCH v4 18/18] platform/chrome: cros_ec_typec: Handle lack of HPD information
From: Stephen Boyd
Date: Fri Sep 06 2024 - 19:23:04 EST
Quoting Tzung-Bi Shih (2024-09-06 01:18:21)
> On Wed, Sep 04, 2024 at 02:45:36PM -0700, Stephen Boyd wrote:
> > Quoting Tzung-Bi Shih (2024-09-04 02:36:45)
> > > On Sat, Aug 31, 2024 at 09:06:56PM -0700, Stephen Boyd wrote:
> > > > + /* Inject HPD from the GPIO state if EC firmware is broken. */
> > > > + if (typec->hpd_asserted)
> > > > + resp->flags |= USB_PD_MUX_HPD_LVL;
> > >
> > > `typec->hpd_asserted` is shared between all typec->ports[...]. Would it be
> > > possible that a HPD is asserted for another port but not current `port`?
> > > E.g.: cros_typec_inject_hpd() for port 2 and cros_typec_dp_bridge_hpd_notify()
> > > gets called due to port 1 at the same time?
> >
> > I'd like to avoid synchronizing the hpd notify and this injection code,
> > if that's what you're asking. Thinking about this though, I've realized
> > that it's broken even when HPD is working on the EC. Consider this
> > scenario with two type-c ports C0 and C1:
> >
> > [...]
>
> I understood it more: originally, I was wondering if it needs an array
> `typec->hpd_asserted[...]` for storing HPD for each port. But, no.
>
> What cros_typec_dp_bridge_hpd_notify() get is just a connected/disconnected
> signal. It kicks off cros_typec_port_work() for finding which port is
> supposed to trigger the event (with some logic with `active_dp_port`,
> `mux_gpio`, and `hpd_asserted`).
Ok, cool. I intend to split this device into multiple devices, one per
DP bridge. I haven't done that though because I don't have any device
that has two independent DP controllers.
>
>
> Curious about one more scenario, is it possible:
>
> Initially, no DP port and no mux is using:
> active_dp_port = NULL
> hpd_asserted = false
> mux_gpio = NULL
>
> CPU A CPU B
> ------------------------------------------------------------------------------
> cros_typec_port_work()
> cros_typec_port_update(port_num=0)
> [C0 connected]
> cros_typec_dp_bridge_hpd_notify()
> hpd_asserted = true
The work is queued again here because it's already running.
> cros_typec_port_update(port_num=1)
> cros_typec_configure_mux(port_num=1)
> cros_typec_inject_hpd()
> active_dp_port = C1
Yeah it's a problem because we need to read the mux_gpio to figure out
which way it's steering. We can't recreate the "first to assert HPD"
logic that the EC has because we can't control when the worker runs. At
least we can skip reading the mux if only one port has entered DP mode.
I'm hoping that the scenario where both ports are in DP mode almost
never happens, but if it does then we'll have to read the mux when hpd
is asserted to figure out which port DP is muxed to.