RE: [RFC PATCH] usb: typec: tcpm: match source fixed pdo with sink variable pdo

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi
> -----Original Message-----
> From: Hans de Goede [mailto:hdegoede@xxxxxxxxxx]
> Sent: 2018年3月13日 19:36
> To: Jun Li <jun.li@xxxxxxx>; gregkh@xxxxxxxxxxxxxxxxxxx; linux@xxxxxxxxxxxx;
> heikki.krogerus@xxxxxxxxxxxxxxx; Adam.Thomson.Opensource@xxxxxxxxxxx;
> Badhri@xxxxxxxxxx
> Cc: linux-usb@xxxxxxxxxxxxxxx; dl-linux-imx <linux-imx@xxxxxxx>
> Subject: Re: [RFC PATCH] usb: typec: tcpm: match source fixed pdo with sink
> variable pdo
> 
> Hi,
> 
> On 13-03-18 01:02, Li Jun wrote:
> > This patch tries to fix the problem describled on revert patch
> > commit[1], suppose any supported voltage ranges of sink should be
> > describled by variable pdo, so instead of revert the patch of only
> > comparing source and sink pdo to select one source pdo, this patch
> > adds the match between source fixed pdo and sink variable pdo.
> >
> > [1]
> >
> https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww
> > .spinics.net%2Flists%2Flinux-usb%2Fmsg166366.html&data=02%7C01%7Cju
> n.l
> >
> i%40nxp.com%7C569be5e2496442f514bd08d588d69fc6%7C686ea1d3bc2b4
> c6fa92cd
> >
> 99c5c301635%7C0%7C0%7C636565377744465803&sdata=hUPib1nNtXArpZ
> Pn0TfMdui
> > ARnVPvc6CezTr0UxJFCI%3D&reserved=0
> >
> > CC: Hans de Goede <hdegoede@xxxxxxxxxx>
> > CC: Guenter Roeck <linux@xxxxxxxxxxxx>
> > CC: Heikki Krogerus <heikki.krogerus@xxxxxxxxxxxxxxx>
> > CC: Adam Thomson <Adam.Thomson.Opensource@xxxxxxxxxxx>
> > CC: Badhri Jagan Sridharan <Badhri@xxxxxxxxxx>
> > Signed-off-by: Li Jun <jun.li@xxxxxxx>
> > ---
> >   drivers/usb/typec/tcpm.c | 31 +++++++++++++++++++++++++++++++
> >   1 file changed, 31 insertions(+)
> >
> > diff --git a/drivers/usb/typec/tcpm.c b/drivers/usb/typec/tcpm.c index
> > ef3a60d..8a74a43 100644
> > --- a/drivers/usb/typec/tcpm.c
> > +++ b/drivers/usb/typec/tcpm.c
> > @@ -1815,6 +1815,37 @@ static int tcpm_pd_select_pdo(struct tcpm_port
> *port, int *sink_pdo,
> >   					break;
> >   				}
> >   			}
> > +
> > +			/*
> > +			 * If the source pdo has the same voltage with one
> > +			 * fixed pdo, no need check variable pdo for it.
> > +			 */
> > +			if (j < port->nr_fixed)
> > +				continue;
> > +
> > +			for (j = port->nr_fixed +
> > +				 port->nr_batt;
> > +			     j < port->nr_fixed +
> > +				 port->nr_batt +
> > +				 port->nr_var;
> > +			     j++) {
> > +				if (pdo_fixed_voltage(pdo) >=
> > +				     pdo_min_voltage(port->snk_pdo[j]) &&
> > +				     pdo_fixed_voltage(pdo) <=
> > +				     pdo_max_voltage(port->snk_pdo[j])) {
> > +					ma = min_current(pdo, port->snk_pdo[j]);
> > +					mv = pdo_fixed_voltage(pdo);
> > +					mw = ma * mv / 1000;
> > +					if (mw > max_mw ||
> > +					    (mw == max_mw && mv > max_mv)) {
> > +						ret = 0;
> > +						*src_pdo = i;
> > +						*sink_pdo = j;
> > +						max_mw = mw;
> > +						max_mv = mv;
> > +					}
> > +				}
> > +			}
> >   		} else if (type == PDO_TYPE_BATT) {
> >   			for (j = port->nr_fixed;
> >   			     j < port->nr_fixed +
> >
> 
> First of all, this seems to be a fix on top of your previous, reverted patch.
>

It's on top of the patch to be reverted by you.
 
> Since your patch has been reverted, please send a new fixed patch replacing it.
> 

It's Badhri's patch, not mine.

Author: Badhri Jagan Sridharan <badhri@xxxxxxxxxx>
Date:   Wed Nov 15 17:01:56 2017 -0800

    typec: tcpm: Only request matching pdos

> As for the proposed fix, you are just fixing the fixed source, variable snk cap
> case here. What if things are the other way around, so fixed snk, variable
> source?

I think that may not work, as the sink defines itself only can work at one
fixed voltage, a variable PDO can make sure the output voltage fixed?

Below is the description of variable supply PDO from PD spec:
"The Variable Supply (non-Battery) PDO exposes very poorly regulated Sources.
The output voltage of a Variable Supply (non-Battery) shall remain within the
absolute maximum output voltage and the absolute minimum output voltage
exposed in the Variable Supply PDO"

So I think a basic rule is the voltage range of selected source PDO should be
within the voltage range of sink PDO, no matter what type they are:
(max_src_mv <= max_snk_mv && min_src_mv >= min_snk_mv)

With this condition meet, then we can select one source PDO with bigger mw or,
the same mw but higher voltage.

> 
> You really need to stop comparing fixed to fixed and variable to variable, etc.

Agree.

> 
> Instead do something like this
> 
>          for (i = 0; i < port->nr_source_caps; i++) {
>                  u32 pdo = port->source_caps[i];
>                  enum pd_pdo_type type = pdo_type(pdo);
>                  unsigned int mv, ma, mw;
> 
>                  if (type == PDO_TYPE_FIXED)
>                          mv = pdo_fixed_voltage(pdo);
>                  else
>                          mv = pdo_min_voltage(pdo);
> 
>                  if (type == PDO_TYPE_BATT) {
>                          mw = pdo_max_power(pdo);
>                  } else {
> 			/* FIXME should not use max_snk_ma here */
>                          ma = min(pdo_max_current(pdo),
>                                   port->max_snk_ma);
>                          mw = ma * mv / 1000;
>                  }
> 
> 		for (j = 0; j < port->nr_snk_pdo; j++) {
> 			if (pdo_type(port->snk_pdo[j]) == PDO_TYPE_FIXED)
> 				max_snk_mv = pdo_fixed_voltage(port->snk_pdo[j]);
> 				/* FIXME also get ma / mw settings */
> 			} else {
> 				max_snk_mv = pdo_max_voltage(port->snk_pdo[j]);
> 				/* FIXME also get ma / mw settings */
> 			}
> 
> 			/* Prefer higher voltages if available */
> 	                if ((mw > max_mw || (mw == max_mw && mv >
> max_mv)) &&
> 	                    mv <= max_snk_mv) {
> 	                        ret = i;
>          	                max_mw = mw;
>                  	        max_mv = mv;
> 	                }
> 		}
> 	}
> 
> Note the above example code only has been adjusted to compare the voltages
> from the snk pdo-s it needs to be fixed to also deal with ma/mw

We are dealing sink ma/mw after target source PDO is decided, in
tcpm_pd_build_request(), it's used to set cap mismatch etc.

the code looks like below:
for (i = 0; i < port->nr_source_caps; i++) {
        u32 pdo = port->source_caps[i];
        enum pd_pdo_type type = pdo_type(pdo);
        unsigned int max_src_mv, min_src_mv, min_snk_mv, max_snk_mv,
                src_mw, src_ma;

        if (type == PDO_TYPE_FIXED) {
                max_src_mv = pdo_fixed_voltage(pdo);
                min_src_mv = max_src_mv;
        } else {
                max_src_mv = pdo_max_voltage(pdo);
                min_src_mv = pdo_min_voltage(pdo);
        }

        if (type == PDO_TYPE_BATT) {
                src_mw = pdo_max_power(pdo);
        } else {
                src_ma = pdo_max_current(pdo);
                src_mw = src_ma * min_src_mv / 1000;
        }

        for (j = 0; j < port->nr_snk_pdo; j++) {
                if (pdo_type(port->snk_pdo[j]) == PDO_TYPE_FIXED) {
                        min_snk_mv = pdo_fixed_voltage(port->snk_pdo[j]);
                        max_snk_mv = pdo_fixed_voltage(port->snk_pdo[j]);

                } else {
                        min_snk_mv = pdo_min_voltage(port->snk_pdo[j]);
                        max_snk_mv = pdo_max_voltage(port->snk_pdo[j]);
                }

                if (max_src_mv <= max_snk_mv && min_src_mv >= min_snk_mv) {
                        /* Prefer higher voltages if available */
                        if (src_mw > max_mw || (src_mw == max_mw &&
                                                min_src_mv > max_mv)) {
                                target_src_pdo = i;
								target_snk_pdo = j;
                                max_mw = src_mw;
                                max_mv = min_src_mv;
                        }
                }
        }
}

Thanks
Jun
> 
> Regards,
> 
> Hans
��.n��������+%������w��{.n�����{���)��jg��������ݢj����G�������j:+v���w�m������w�������h�����٥




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux