Re: [PATCH] usb: typec: tipd: Fix Thunderbolt altmode VDOs for cd321x

Heikki Krogerus <[email protected]>
Newsgroups org.kernel.vger.linux-usb,dev.linux.lists.asahi,org.kernel.vger.linux-kernel,org.kernel.vger.stable
Message-ID <[email protected]>
On Thu, Aug 13, 2026 at 08:16:15PM +0200, Sven Peter wrote:
> The Intel VID status register is actually 9 bytes long and doesn't
> contain the raw VDOs but only the upper 16bits for device mode and enter
> mode. Shift those two fields into place and reconstruct the cable
> discover mode VDO from the data status register instead since it's not
> directly accessible. With this fixed now the correct VDOs are forwarded
> to the PHY and the to-be-submitted Thunderbolt/USB4 native host interface
> so that the right mode can be negotiated and the link actually comes up.
> 
> Link: https://www.ti.com/lit/ug/slvubh2b/slvubh2b.pdf
> Fixes: 0b31c978935f ("usb: typec: tipd: Read USB4, Thunderbolt and DisplayPort status for cd321x")
> Fixes: 82432bbfb9e8 ("usb: typec: tipd: Handle mode transitions for CD321x")
> Cc: [email protected]
> Signed-off-by: Sven Peter <[email protected]>

Acked-by: Heikki Krogerus <[email protected]>

> ---
>  drivers/usb/typec/tipd/core.c     | 17 +++++++++++++----
>  drivers/usb/typec/tipd/tps6598x.h |  4 ++--
>  2 files changed, 15 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c
> index d5ee0af9058b..159d1a2f9a1f 100644
> --- a/drivers/usb/typec/tipd/core.c
> +++ b/drivers/usb/typec/tipd/core.c
> @@ -114,7 +114,6 @@ struct tps6598x_intel_vid_status_reg {
>  	__le32 attention_vdo;
>  	__le16 enter_vdo;
>  	__le16 device_mode;
> -	__le16 cable_mode;
>  } __packed;
>  
>  /* Standard Task return codes */
> @@ -700,9 +699,19 @@ static void cd321x_typec_update_mode(struct tps6598x *tps, struct cd321x_status
>  		   cd321x->state.mode == TYPEC_TBT_MODE)
>  			return;
>  
> -		tbt_data.cable_mode = le16_to_cpu(st->intel_vid_status.cable_mode);
> -		tbt_data.device_mode = le16_to_cpu(st->intel_vid_status.device_mode);
> -		tbt_data.enter_vdo = le16_to_cpu(st->intel_vid_status.enter_vdo);
> +		tbt_data.cable_mode = TBT_MODE |
> +			TBT_SET_CABLE_SPEED(TPS_DATA_STATUS_TBT_CABLE_SPEED(st->data_status)) |
> +			TBT_SET_CABLE_ROUNDED(TPS_DATA_STATUS_TBT_CABLE_GEN(st->data_status));
> +		if (st->data_status & TPS_DATA_STATUS_OPTICAL_CABLE)
> +			tbt_data.cable_mode |= TBT_CABLE_OPTICAL;
> +		if (st->data_status & TPS_DATA_STATUS_ACTIVE_LINK_TRAIN)
> +			tbt_data.cable_mode |= TBT_CABLE_LINK_TRAINING;
> +		if (st->data_status & TPS_DATA_STATUS_ACTIVE_CABLE)
> +			tbt_data.cable_mode |= TBT_CABLE_ACTIVE_PASSIVE;
> +		tbt_data.device_mode = TBT_MODE |
> +			(u32)le16_to_cpu(st->intel_vid_status.device_mode) << 16;
> +		tbt_data.enter_vdo =
> +			(u32)le16_to_cpu(st->intel_vid_status.enter_vdo) << 16;
>  		cd321x->state.alt = cd321x->port_altmode_tbt;
>  		cd321x->state.mode = TYPEC_TBT_MODE;
>  		cd321x->state.data = &tbt_data;
> diff --git a/drivers/usb/typec/tipd/tps6598x.h b/drivers/usb/typec/tipd/tps6598x.h
> index 03edbb77bbd6..d172c84ada74 100644
> --- a/drivers/usb/typec/tipd/tps6598x.h
> +++ b/drivers/usb/typec/tipd/tps6598x.h
> @@ -206,10 +206,10 @@
>  #define TPS_DATA_STATUS_DP_PIN_ASSIGNMENT(x) \
>  	TPS_FIELD_GET(TPS_DATA_STATUS_DP_PIN_ASSIGNMENT_MASK, (x))
>  #define TPS_DATA_STATUS_TBT_CABLE_SPEED_MASK   GENMASK(27, 25)
> -#define TPS_DATA_STATUS_TBT_CABLE_SPEED \
> +#define TPS_DATA_STATUS_TBT_CABLE_SPEED(x) \
>  	TPS_FIELD_GET(TPS_DATA_STATUS_TBT_CABLE_SPEED_MASK, (x))
>  #define TPS_DATA_STATUS_TBT_CABLE_GEN_MASK     GENMASK(29, 28)
> -#define TPS_DATA_STATUS_TBT_CABLE_GEN \
> +#define TPS_DATA_STATUS_TBT_CABLE_GEN(x) \
>  	TPS_FIELD_GET(TPS_DATA_STATUS_TBT_CABLE_GEN_MASK, (x))
>  
>  /* Map data status to DP spec assignments */
> 
> ---
> base-commit: dc59e4fea9d83f03bad6bddf3fa2e52491777482
> change-id: 20260813-b4-tipd-vdo-fix-44e65b48aea3
> 
> Best regards,
> --  
> Sven Peter <[email protected]>
> 

-- 
heikki
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.