usb: phy-msm-qusb-v2: Override TUNE1 while honoring efuse value

We need to set BIT:7 of TUNE1 register and DEBUG_CTRL1 to 0x09
for host mode chirp fix while honoring the efuse value. Now we
are checking if efuse value is present or not, based on that we
are programming TUNE1 value. This change also adds a property
on which we can decide to override BIAS_CTRL2 from driver.
This change also adds support to override tuneX paramerters
through debugfs in HOST mode.

Change-Id: I2f562391464b8a035b6dec23d1b909765cb4613a
Signed-off-by: Pratham Pratap <prathampratap@codeaurora.org>
diff --git a/Documentation/devicetree/bindings/usb/msm-phy.txt b/Documentation/devicetree/bindings/usb/msm-phy.txt
index b880890..c28b05b 100644
--- a/Documentation/devicetree/bindings/usb/msm-phy.txt
+++ b/Documentation/devicetree/bindings/usb/msm-phy.txt
@@ -191,6 +191,8 @@
  - qcom,tune2-efuse-correction: The value to be adjusted from fused value for
    improved rise/fall times.
  - qcom,host-chirp-erratum: Indicates host chirp fix is required.
+ - qcom,override-bias-ctrl2: Indicates override is done from driver for
+   BIAS_CTRL2 register.
  - nvmem-cells: specifies the handle to represent the SoC revision.
    usually it is defined by qfprom device node.
  - nvmem-cell-names: specifies the given nvmem cell name as defined in
diff --git a/drivers/usb/phy/phy-msm-qusb-v2.c b/drivers/usb/phy/phy-msm-qusb-v2.c
index 33a7f6a..6dfca9c 100644
--- a/drivers/usb/phy/phy-msm-qusb-v2.c
+++ b/drivers/usb/phy/phy-msm-qusb-v2.c
@@ -71,7 +71,6 @@
 #define SQ_CTRL1_CHIRP_DISABLE		0x20
 #define SQ_CTRL2_CHIRP_DISABLE		0x80
 
-#define PORT_TUNE1_OVERRIDE_VAL		0xc5
 #define DEBUG_CTRL1_OVERRIDE_VAL	0x09
 
 /* PERIPH_SS_PHY_REFGEN_NORTH_BG_CTRL register bits */
@@ -154,6 +153,7 @@
 	struct hrtimer		timer;
 	int			soc_min_rev;
 	bool			host_chirp_erratum;
+	bool			override_bias_ctrl2;
 };
 
 #ifdef CONFIG_NVMEM
@@ -473,6 +473,7 @@
 static void qusb_phy_host_init(struct usb_phy *phy)
 {
 	u8 reg;
+	int p_index;
 	struct qusb_phy *qphy = container_of(phy, struct qusb_phy, phy);
 
 	dev_dbg(phy->dev, "%s\n", __func__);
@@ -480,17 +481,43 @@
 	qusb_phy_write_seq(qphy->base, qphy->qusb_phy_host_init_seq,
 			qphy->host_init_seq_len, 0);
 
-	/* If soc revision is mentioned and host_chirp_erratum flag is set
-	 * then override TUNE1 and DEBUG_CTRL1
-	 */
-	if (qphy->soc_min_rev && qphy->host_chirp_erratum) {
-		writel_relaxed(PORT_TUNE1_OVERRIDE_VAL,
-				qphy->base + qphy->phy_reg[PORT_TUNE1]);
-		writel_relaxed(DEBUG_CTRL1_OVERRIDE_VAL,
-				qphy->base + qphy->phy_reg[DEBUG_CTRL1]);
+	if (qphy->efuse_reg) {
+		if (!qphy->tune_val)
+			qusb_phy_get_tune1_param(qphy);
+	} else {
+		/* For non fused chips we need to write the TUNE1 param as
+		 * specified in DT otherwise we will end up writing 0 to
+		 * to TUNE1
+		 */
+		qphy->tune_val = readb_relaxed(qphy->base +
+					qphy->phy_reg[PORT_TUNE1]);
 	}
 
-	if (qphy->refgen_north_bg_reg)
+	/* If soc revision is mentioned and host_chirp_erratum flag is set
+	 * then override TUNE1 and DEBUG_CTRL1 while honouring efuse values
+	 */
+	if (qphy->soc_min_rev && qphy->host_chirp_erratum) {
+		writel_relaxed(qphy->tune_val | BIT(7),
+			qphy->base + qphy->phy_reg[PORT_TUNE1]);
+		pr_debug("%s(): Programming TUNE1 parameter as:%x\n",
+			__func__, readb_relaxed(qphy->base +
+					qphy->phy_reg[PORT_TUNE1]));
+		writel_relaxed(DEBUG_CTRL1_OVERRIDE_VAL,
+			qphy->base + qphy->phy_reg[DEBUG_CTRL1]);
+	} else {
+		writel_relaxed(qphy->tune_val,
+			qphy->base + qphy->phy_reg[PORT_TUNE1]);
+	}
+
+	/* if debugfs based tunex params are set, use that value. */
+	for (p_index = 0; p_index < 5; p_index++) {
+		if (qphy->tune[p_index])
+			writel_relaxed(qphy->tune[p_index],
+				qphy->base + qphy->phy_reg[PORT_TUNE1] +
+							(4 * p_index));
+	}
+
+	if (qphy->refgen_north_bg_reg && qphy->override_bias_ctrl2)
 		if (readl_relaxed(qphy->refgen_north_bg_reg) & BANDGAP_BYPASS)
 			writel_relaxed(BIAS_CTRL_2_OVERRIDE_VAL,
 				qphy->base + qphy->phy_reg[BIAS_CTRL_2]);
@@ -585,7 +612,7 @@
 							(4 * p_index));
 	}
 
-	if (qphy->refgen_north_bg_reg)
+	if (qphy->refgen_north_bg_reg && qphy->override_bias_ctrl2)
 		if (readl_relaxed(qphy->refgen_north_bg_reg) & BANDGAP_BYPASS)
 			writel_relaxed(BIAS_CTRL_2_OVERRIDE_VAL,
 				qphy->base + qphy->phy_reg[BIAS_CTRL_2]);
@@ -1209,6 +1236,9 @@
 	qphy->host_chirp_erratum = of_property_read_bool(dev->of_node,
 					"qcom,host-chirp-erratum");
 
+	qphy->override_bias_ctrl2 = of_property_read_bool(dev->of_node,
+					"qcom,override-bias-ctrl2");
+
 	ret = of_property_read_u32_array(dev->of_node, "qcom,vdd-voltage-level",
 					 (u32 *) qphy->vdd_levels,
 					 ARRAY_SIZE(qphy->vdd_levels));