phy: rockchip-inno-usb3: add phy_cp_test function for u3phy
authorWilliam Wu <wulf@rock-chips.com>
Tue, 21 Feb 2017 12:00:51 +0000 (20:00 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Wed, 22 Feb 2017 06:18:58 +0000 (14:18 +0800)
The Inno USB3 PHY disable the ability to toggle the CP test
pattern by default. But when do do USB3 compliance test, it
need to change the CP test pattern according to the requirement
of oscilloscope.

This patch add phy_cp_test function to enable the USB3 PHY
to detect the negative pulse which from the Aux Out of the
oscilloscope in SSRX+, and then the USB3 PHY can toggle the
CP test pattern while do USB3 compliance test.

Change-Id: Idbdf937a7a032dcedfd5f207b2d6d5961ed27b15
Signed-off-by: William Wu <wulf@rock-chips.com>
drivers/phy/phy-rockchip-inno-usb3.c

index 62e71a2bf9c5655b0127b1b7d23ef34d24291894..ab80ce059233d983ff982ab4d156fbf46f6f77ad 100644 (file)
@@ -118,6 +118,8 @@ struct rockchip_u3phy_cfg {
        int (*phy_tuning)(struct rockchip_u3phy *,
                          struct rockchip_u3phy_port *,
                          struct device_node *);
+       int (*phy_cp_test)(struct rockchip_u3phy *,
+                          struct rockchip_u3phy_port *);
 };
 
 struct rockchip_u3phy_port {
@@ -360,6 +362,33 @@ done:
        return 0;
 }
 
+static int rockchip_u3phy_cp_test(struct phy *phy)
+{
+       struct rockchip_u3phy_port *u3phy_port = phy_get_drvdata(phy);
+       struct rockchip_u3phy *u3phy = dev_get_drvdata(phy->dev.parent);
+       int ret;
+
+       if (u3phy->cfgs->phy_cp_test) {
+               /*
+                * When do USB3 compliance test, we may connect the oscilloscope
+                * front panel Aux Out to the DUT SSRX+, the Aux Out of the
+                * oscilloscope outputs a negative pulse whose width is between
+                * 300- 400 ns which may trigger some DUTs to change the CP test
+                * pattern.
+                *
+                * The Inno USB3 PHY disable the function to detect the negative
+                * pulse in SSRX+ by default, so we need to enable the function
+                * to toggle the CP test pattern before do USB3 compliance test.
+                */
+               dev_dbg(u3phy->dev, "prepare for u3phy compliance test\n");
+               ret = u3phy->cfgs->phy_cp_test(u3phy, u3phy_port);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
 static __maybe_unused
 struct phy *rockchip_u3phy_xlate(struct device *dev,
                                 struct of_phandle_args *args)
@@ -394,6 +423,7 @@ static struct phy_ops rockchip_u3phy_ops = {
        .exit           = rockchip_u3phy_exit,
        .power_on       = rockchip_u3phy_power_on,
        .power_off      = rockchip_u3phy_power_off,
+       .cp_test        = rockchip_u3phy_cp_test,
        .owner          = THIS_MODULE,
 };
 
@@ -928,6 +958,19 @@ static int rk3328_u3phy_tuning(struct rockchip_u3phy *u3phy,
        return 0;
 }
 
+static int rk322xh_u3phy_cp_test_enable(struct rockchip_u3phy *u3phy,
+                                       struct rockchip_u3phy_port *u3phy_port)
+{
+       if (u3phy_port->type == U3PHY_TYPE_PIPE) {
+               writel(0x0c, u3phy_port->base + 0x408);
+       } else {
+               dev_err(u3phy->dev, "The u3phy type is not pipe\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 static const struct rockchip_u3phy_cfg rk3328_u3phy_cfgs[] = {
        {
                .reg            = 0xff470000,
@@ -945,6 +988,7 @@ static const struct rockchip_u3phy_cfg rk3328_u3phy_cfgs[] = {
                },
                .phy_pipe_power = rk3328_u3phy_pipe_power,
                .phy_tuning     = rk3328_u3phy_tuning,
+               .phy_cp_test    = rk322xh_u3phy_cp_test_enable,
        },
        { /* sentinel */ }
 };