usb: pd: Make SVDM Version configurable in VDM header
authorKyle Tso <kyletso@google.com>
Fri, 5 Feb 2021 03:34:10 +0000 (11:34 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 9 Feb 2021 10:48:54 +0000 (11:48 +0100)
PD Rev 3.0 introduces SVDM Version 2.0. This patch makes the field
configuable in the header in order to be able to be compatible with
older SVDM version.

Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Kyle Tso <kyletso@google.com>
Link: https://lore.kernel.org/r/20210205033415.3320439-3-kyletso@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/typec/altmodes/displayport.c
drivers/usb/typec/tcpm/tcpm.c
drivers/usb/typec/ucsi/displayport.c
include/linux/usb/pd_vdo.h

index e62e5e3..0abc312 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/usb/typec_dp.h>
 #include "displayport.h"
 
-#define DP_HEADER(_dp, cmd)            (VDO((_dp)->alt->svid, 1, cmd) | \
+#define DP_HEADER(_dp, cmd)            (VDO((_dp)->alt->svid, 1, SVDM_VER_1_0, cmd) | \
                                         VDO_OPOS(USB_TYPEC_DP_MODE))
 
 enum {
index 8558ab0..9aadb1e 100644 (file)
@@ -1544,17 +1544,17 @@ static int tcpm_pd_svdm(struct tcpm_port *port, struct typec_altmode *adev,
                case CMD_DISCOVER_IDENT:
                        /* 6.4.4.3.1 */
                        svdm_consume_identity(port, p, cnt);
-                       response[0] = VDO(USB_SID_PD, 1, CMD_DISCOVER_SVID);
+                       response[0] = VDO(USB_SID_PD, 1, SVDM_VER_1_0, CMD_DISCOVER_SVID);
                        rlen = 1;
                        break;
                case CMD_DISCOVER_SVID:
                        /* 6.4.4.3.2 */
                        if (svdm_consume_svids(port, p, cnt)) {
-                               response[0] = VDO(USB_SID_PD, 1,
+                               response[0] = VDO(USB_SID_PD, 1, SVDM_VER_1_0,
                                                  CMD_DISCOVER_SVID);
                                rlen = 1;
                        } else if (modep->nsvids && supports_modal(port)) {
-                               response[0] = VDO(modep->svids[0], 1,
+                               response[0] = VDO(modep->svids[0], 1, SVDM_VER_1_0,
                                                  CMD_DISCOVER_MODES);
                                rlen = 1;
                        }
@@ -1565,7 +1565,7 @@ static int tcpm_pd_svdm(struct tcpm_port *port, struct typec_altmode *adev,
                        modep->svid_index++;
                        if (modep->svid_index < modep->nsvids) {
                                u16 svid = modep->svids[modep->svid_index];
-                               response[0] = VDO(svid, 1, CMD_DISCOVER_MODES);
+                               response[0] = VDO(svid, 1, SVDM_VER_1_0, CMD_DISCOVER_MODES);
                                rlen = 1;
                        } else {
                                tcpm_register_partner_altmodes(port);
@@ -1695,7 +1695,7 @@ static void tcpm_handle_vdm_request(struct tcpm_port *port,
                        break;
                case ADEV_QUEUE_VDM_SEND_EXIT_MODE_ON_FAIL:
                        if (typec_altmode_vdm(adev, p[0], &p[1], cnt)) {
-                               response[0] = VDO(adev->svid, 1, CMD_EXIT_MODE);
+                               response[0] = VDO(adev->svid, 1, SVDM_VER_1_0, CMD_EXIT_MODE);
                                response[0] |= VDO_OPOS(adev->mode);
                                rlen = 1;
                        }
@@ -1729,7 +1729,7 @@ static void tcpm_send_vdm(struct tcpm_port *port, u32 vid, int cmd,
 
        /* set VDM header with VID & CMD */
        header = VDO(vid, ((vid & USB_SID_PD) == USB_SID_PD) ?
-                       1 : (PD_VDO_CMD(cmd) <= CMD_ATTENTION), cmd);
+                       1 : (PD_VDO_CMD(cmd) <= CMD_ATTENTION), SVDM_VER_1_0, cmd);
        tcpm_queue_vdm(port, header, data, count);
 }
 
@@ -2024,7 +2024,7 @@ static int tcpm_altmode_enter(struct typec_altmode *altmode, u32 *vdo)
        struct tcpm_port *port = typec_altmode_get_drvdata(altmode);
        u32 header;
 
-       header = VDO(altmode->svid, vdo ? 2 : 1, CMD_ENTER_MODE);
+       header = VDO(altmode->svid, vdo ? 2 : 1, SVDM_VER_1_0, CMD_ENTER_MODE);
        header |= VDO_OPOS(altmode->mode);
 
        tcpm_queue_vdm_unlocked(port, header, vdo, vdo ? 1 : 0);
@@ -2036,7 +2036,7 @@ static int tcpm_altmode_exit(struct typec_altmode *altmode)
        struct tcpm_port *port = typec_altmode_get_drvdata(altmode);
        u32 header;
 
-       header = VDO(altmode->svid, 1, CMD_EXIT_MODE);
+       header = VDO(altmode->svid, 1, SVDM_VER_1_0, CMD_EXIT_MODE);
        header |= VDO_OPOS(altmode->mode);
 
        tcpm_queue_vdm_unlocked(port, header, NULL, 0);
index 261131c..1d387bd 100644 (file)
@@ -83,7 +83,7 @@ static int ucsi_displayport_enter(struct typec_altmode *alt, u32 *vdo)
         * mode, and letting the alt mode driver continue.
         */
 
-       dp->header = VDO(USB_TYPEC_DP_SID, 1, CMD_ENTER_MODE);
+       dp->header = VDO(USB_TYPEC_DP_SID, 1, SVDM_VER_1_0, CMD_ENTER_MODE);
        dp->header |= VDO_OPOS(USB_TYPEC_DP_MODE);
        dp->header |= VDO_CMDT(CMDT_RSP_ACK);
 
@@ -120,7 +120,7 @@ static int ucsi_displayport_exit(struct typec_altmode *alt)
        if (ret < 0)
                goto out_unlock;
 
-       dp->header = VDO(USB_TYPEC_DP_SID, 1, CMD_EXIT_MODE);
+       dp->header = VDO(USB_TYPEC_DP_SID, 1, SVDM_VER_1_0, CMD_EXIT_MODE);
        dp->header |= VDO_OPOS(USB_TYPEC_DP_MODE);
        dp->header |= VDO_CMDT(CMDT_RSP_ACK);
 
@@ -200,7 +200,7 @@ static int ucsi_displayport_vdm(struct typec_altmode *alt,
 
        switch (cmd_type) {
        case CMDT_INIT:
-               dp->header = VDO(USB_TYPEC_DP_SID, 1, cmd);
+               dp->header = VDO(USB_TYPEC_DP_SID, 1, SVDM_VER_1_0, cmd);
                dp->header |= VDO_OPOS(USB_TYPEC_DP_MODE);
 
                switch (cmd) {
index 5de7f55..b057250 100644 (file)
  * ----------
  * <31:16>  :: SVID
  * <15>     :: VDM type ( 1b == structured, 0b == unstructured )
- * <14:13>  :: Structured VDM version (can only be 00 == 1.0 currently)
+ * <14:13>  :: Structured VDM version
  * <12:11>  :: reserved
  * <10:8>   :: object position (1-7 valid ... used for enter/exit mode only)
  * <7:6>    :: command type (SVDM only?)
  * <5>      :: reserved (SVDM), command type (UVDM)
  * <4:0>    :: command
  */
-#define VDO(vid, type, custom)                         \
+#define VDO(vid, type, ver, custom)                    \
        (((vid) << 16) |                                \
         ((type) << 15) |                               \
+        ((ver) << 13) |                                \
         ((custom) & 0x7FFF))
 
 #define VDO_SVDM_TYPE          (1 << 15)
 #define VDO_SVDM_VERS(x)       ((x) << 13)
 #define VDO_OPOS(x)            ((x) << 8)
 #define VDO_CMDT(x)            ((x) << 6)
+#define VDO_SVDM_VERS_MASK     VDO_SVDM_VERS(0x3)
 #define VDO_OPOS_MASK          VDO_OPOS(0x7)
 #define VDO_CMDT_MASK          VDO_CMDT(0x3)
 
@@ -74,6 +76,7 @@
 
 #define PD_VDO_VID(vdo)                ((vdo) >> 16)
 #define PD_VDO_SVDM(vdo)       (((vdo) >> 15) & 1)
+#define PD_VDO_SVDM_VER(vdo)   (((vdo) >> 13) & 0x3)
 #define PD_VDO_OPOS(vdo)       (((vdo) >> 8) & 0x7)
 #define PD_VDO_CMD(vdo)                ((vdo) & 0x1f)
 #define PD_VDO_CMDT(vdo)       (((vdo) >> 6) & 0x3)