Author: avg
Date: Mon Sep 21 10:02:11 2020
New Revision: 365943
URL: https://svnweb.freebsd.org/changeset/base/365943

Log:
  aw_usbphy: add support for device mode operation
  
  OTG mode is not supported still.  It's easy to do it as a one-off
  detection, but the proper support requires continuous monitoring and
  communicating the current state to the USB layer.
  
  Also, fix phy0_route setting for H3.  Remove duplicate register
  definitions.
  
  Tested on Orange Pi PC Plus with dr_mode="peripheral" using
    hw.usb.template=3
    umodem_load="YES"
  
  Reviewed by:  manu
  MFC after:    5 weeks
  Differential Revision: https://reviews.freebsd.org/D26348

Modified:
  head/sys/arm/allwinner/aw_usbphy.c

Modified: head/sys/arm/allwinner/aw_usbphy.c
==============================================================================
--- head/sys/arm/allwinner/aw_usbphy.c  Mon Sep 21 09:50:57 2020        
(r365942)
+++ head/sys/arm/allwinner/aw_usbphy.c  Mon Sep 21 10:02:11 2020        
(r365943)
@@ -102,7 +102,7 @@ static const struct aw_usbphy_conf h3_usbphy_conf = {
        .num_phys = 4,
        .phy_type = AWUSBPHY_TYPE_H3,
        .pmu_unk1 = true,
-       .phy0_route = false,
+       .phy0_route = true,
 };
 
 static const struct aw_usbphy_conf a64_usbphy_conf = {
@@ -175,8 +175,10 @@ DEFINE_CLASS_1(awusbphy_phynode, awusbphy_phynode_clas
 #define         FORCE_ID               (0x3 << 14)
 #define         FORCE_ID_SHIFT         14
 #define         FORCE_ID_LOW           2
+#define         FORCE_ID_HIGH          3
 #define         FORCE_VBUS_VALID       (0x3 << 12)
 #define         FORCE_VBUS_VALID_SHIFT 12
+#define         FORCE_VBUS_VALID_LOW   2
 #define         FORCE_VBUS_VALID_HIGH  3
 #define         VBUS_CHANGE_DET        (1 << 6)
 #define         ID_CHANGE_DET          (1 << 5)
@@ -190,18 +192,6 @@ DEFINE_CLASS_1(awusbphy_phynode, awusbphy_phynode_clas
 #define         PMU_ULPI_BYPASS        (1 << 0)
 #define        PMU_UNK_H3      0x10
 #define         PMU_UNK_H3_CLR         0x2
-#define        PHY_CSR         0x00
-#define         ID_PULLUP_EN           (1 << 17)
-#define         DPDM_PULLUP_EN         (1 << 16)
-#define         FORCE_ID               (0x3 << 14)
-#define         FORCE_ID_SHIFT         14
-#define         FORCE_ID_LOW           2
-#define         FORCE_VBUS_VALID       (0x3 << 12)
-#define         FORCE_VBUS_VALID_SHIFT 12
-#define         FORCE_VBUS_VALID_HIGH  3
-#define         VBUS_CHANGE_DET        (1 << 6)
-#define         ID_CHANGE_DET          (1 << 5)
-#define         DPDM_CHANGE_DET        (1 << 4)
 
 static void
 awusbphy_configure(device_t dev, int phyno)
@@ -335,7 +325,12 @@ awusbphy_vbus_detect(device_t dev, int *val)
                return (0);
        }
 
-       *val = 0;
+       /* TODO check vbus_power-supply. */
+
+       /*
+        * If there is no way to detect, assume present.
+        */
+       *val = 1;
        return (0);
 }
 
@@ -369,10 +364,11 @@ awusbphy_phy_enable(struct phynode *phynode, bool enab
                if (error)
                        goto out;
 
-               if (vbus_det == 1) {
+               /* TODO check vbus_power-supply as well. */
+               if (sc->vbus_det_valid && vbus_det == 1) {
                        if (bootverbose)
-                               device_printf(dev, "External VBUS detected, not 
enabling the regulator\n");
-
+                               device_printf(dev, "External VBUS detected, "
+                                   "not enabling the regulator\n");
                        return (0);
                }
        }
@@ -426,36 +422,40 @@ awusbphy_set_mode(struct phynode *phynode, int mode)
                return (0);
        }
 
+       if (sc->mode == mode)
+               return (0);
+       if (mode == PHY_USB_MODE_OTG)   /* TODO */
+               return (EOPNOTSUPP);
+
+       error = awusbphy_vbus_detect(dev, &vbus_det);
+       if (error != 0)
+               return (error);
+
+       val = bus_read_4(sc->phy_ctrl, PHY_CSR);
+       val &= ~(VBUS_CHANGE_DET | ID_CHANGE_DET | DPDM_CHANGE_DET);
+       val |= (ID_PULLUP_EN | DPDM_PULLUP_EN);
+       val &= ~FORCE_VBUS_VALID;
+       val |= (vbus_det ? FORCE_VBUS_VALID_HIGH : FORCE_VBUS_VALID_LOW) <<
+           FORCE_VBUS_VALID_SHIFT;
+       val &= ~FORCE_ID;
+
        switch (mode) {
        case PHY_USB_MODE_HOST:
-               val = bus_read_4(sc->phy_ctrl, PHY_CSR);
-               val &= ~(VBUS_CHANGE_DET | ID_CHANGE_DET | DPDM_CHANGE_DET);
-               val |= (ID_PULLUP_EN | DPDM_PULLUP_EN);
-               val &= ~FORCE_ID;
                val |= (FORCE_ID_LOW << FORCE_ID_SHIFT);
-               val &= ~FORCE_VBUS_VALID;
-               val |= (FORCE_VBUS_VALID_HIGH << FORCE_VBUS_VALID_SHIFT);
-               bus_write_4(sc->phy_ctrl, PHY_CSR, val);
-               if (sc->phy_conf->phy0_route == true) {
-                       error = awusbphy_vbus_detect(dev, &vbus_det);
-                       if (error)
-                               goto out;
-                       if (vbus_det == 0)
-                               CLR4(sc->phy_ctrl, OTG_PHY_CFG,
-                                 OTG_PHY_ROUTE_OTG);
-                       else
-                               SET4(sc->phy_ctrl, OTG_PHY_CFG,
-                                 OTG_PHY_ROUTE_OTG);
-               }
+               if (sc->phy_conf->phy0_route)
+                       CLR4(sc->phy_ctrl, OTG_PHY_CFG, OTG_PHY_ROUTE_OTG);
                break;
-       case PHY_USB_MODE_OTG:
-               /* TODO */
+       case PHY_USB_MODE_DEVICE:
+               val |= (FORCE_ID_HIGH << FORCE_ID_SHIFT);
+               if (sc->phy_conf->phy0_route)
+                       SET4(sc->phy_ctrl, OTG_PHY_CFG, OTG_PHY_ROUTE_OTG);
                break;
+       default:
+               return (EINVAL);
        }
 
+       bus_write_4(sc->phy_ctrl, PHY_CSR, val);
        sc->mode = mode;
-
-out:
        return (0);
 }
 
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to