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 {
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)
.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,
};
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,
},
.phy_pipe_power = rk3328_u3phy_pipe_power,
.phy_tuning = rk3328_u3phy_tuning,
+ .phy_cp_test = rk322xh_u3phy_cp_test_enable,
},
{ /* sentinel */ }
};