lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:   Tue, 30 Aug 2022 11:25:38 -0500
From:   Frank Li <Frank.Li@....com>
To:     kishon@...com, vkoul@...nel.org, robh+dt@...nel.org,
        krzysztof.kozlowski+dt@...aro.org, shawnguo@...nel.org,
        s.hauer@...gutronix.de, kernel@...gutronix.de, festevam@...il.com,
        linux-imx@....com, balbi@...nel.org, gregkh@...uxfoundation.org,
        linux-phy@...ts.infradead.org, devicetree@...r.kernel.org,
        linux-arm-kernel@...ts.infradead.org, linux-kernel@...r.kernel.org,
        linux-usb@...r.kernel.org, imx@...ts.linux.dev
Subject: [PATCH v1 1/1] usb: phy: mxs: apply board calibration value base on chip trim value

USBPHY_TRIM_OVERRIDE provide chip trim value. DTS provide board level
calibration data. Board level calibration data should be base on chip
trim value.

For example, TXCAL45DP board level hope add +2.85% register base on
standard 45ohm. But chip trim value is -5.25% to get 45ohm output.
Actually finial TXCAL45DP should be -5.25% + 2.85% = -2.4%.

If chip have not trim value at USBPHY_TRIM_OVERRIDE, No behavior change.
board level calibration will be applied.

If chip have trim value at USBPHY_TRIM_OVERRIDE and no DTS board level
data, chip trim value will be applied.

Signed-off-by: Frank Li <Frank.Li@....com>
---
 drivers/usb/phy/phy-mxs-usb.c | 40 ++++++++++++++++++++++++++++++++---
 1 file changed, 37 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c
index f909741641ec3..e11b2b9c18a1e 100644
--- a/drivers/usb/phy/phy-mxs-usb.c
+++ b/drivers/usb/phy/phy-mxs-usb.c
@@ -38,6 +38,12 @@
 #define HW_USBPHY_IP_SET			0x94
 #define HW_USBPHY_IP_CLR			0x98
 
+#define HW_USBPHY_TRIM_OVERRIDE			0x130
+#define GM_USBPHY_TRIM_TXCAL45DP(x)		(((x) >> 28) & 0xF)
+#define GM_USBPHY_TRIM_TXCAL45DN(x)		(((x) >> 24) & 0xF)
+#define GM_USBPHY_TRIM_TX_D_CAL(x)		(((x) >> 20) & 0xF)
+#define GM_USBPHY_TRIM_DEFAULT			0x7
+
 #define GM_USBPHY_TX_TXCAL45DP(x)            (((x) & 0xf) << 16)
 #define GM_USBPHY_TX_TXCAL45DN(x)            (((x) & 0xf) << 8)
 #define GM_USBPHY_TX_D_CAL(x)                (((x) & 0xf) << 0)
@@ -993,6 +999,19 @@ static enum usb_charger_type mxs_phy_dcd_flow(struct usb_phy *phy)
 	return chgr_type;
 }
 
+static int mxs_phy_trim_offset(int val, int trim)
+{
+	if (trim == 0)
+		return val;
+
+	val = val + trim - GM_USBPHY_TRIM_DEFAULT;
+
+	val = max(val, 0);
+	val = min(val, 0xf);
+
+	return val;
+}
+
 static int mxs_phy_probe(struct platform_device *pdev)
 {
 	void __iomem *base;
@@ -1001,6 +1020,7 @@ static int mxs_phy_probe(struct platform_device *pdev)
 	int ret;
 	struct device_node *np = pdev->dev.of_node;
 	u32 val;
+	u32 trim;
 
 	base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(base))
@@ -1038,26 +1058,38 @@ static int mxs_phy_probe(struct platform_device *pdev)
 		}
 	}
 
+	trim = readl(base + HW_USBPHY_TRIM_OVERRIDE);
+	trim &= GENMASK(31, 20);
+	val = 45;
+	ret = of_property_read_u32(np, "fsl,tx-cal-45-dn-ohms", &val);
 	/* Precompute which bits of the TX register are to be updated, if any */
-	if (!of_property_read_u32(np, "fsl,tx-cal-45-dn-ohms", &val) &&
+	if ((!ret || trim) &&
 	    val >= MXS_PHY_TX_CAL45_MIN && val <= MXS_PHY_TX_CAL45_MAX) {
 		/* Scale to a 4-bit value */
 		val = (MXS_PHY_TX_CAL45_MAX - val) * 0xF
 			/ (MXS_PHY_TX_CAL45_MAX - MXS_PHY_TX_CAL45_MIN);
+
+		val = mxs_phy_trim_offset(val, GM_USBPHY_TRIM_TXCAL45DN(trim));
 		mxs_phy->tx_reg_mask |= GM_USBPHY_TX_TXCAL45DN(~0);
 		mxs_phy->tx_reg_set  |= GM_USBPHY_TX_TXCAL45DN(val);
 	}
 
-	if (!of_property_read_u32(np, "fsl,tx-cal-45-dp-ohms", &val) &&
+	val = 45;
+	ret = of_property_read_u32(np, "fsl,tx-cal-45-dp-ohms", &val);
+	if ((!ret || trim) &&
 	    val >= MXS_PHY_TX_CAL45_MIN && val <= MXS_PHY_TX_CAL45_MAX) {
 		/* Scale to a 4-bit value. */
 		val = (MXS_PHY_TX_CAL45_MAX - val) * 0xF
 			/ (MXS_PHY_TX_CAL45_MAX - MXS_PHY_TX_CAL45_MIN);
+
+		val = mxs_phy_trim_offset(val, GM_USBPHY_TRIM_TXCAL45DP(trim));
 		mxs_phy->tx_reg_mask |= GM_USBPHY_TX_TXCAL45DP(~0);
 		mxs_phy->tx_reg_set  |= GM_USBPHY_TX_TXCAL45DP(val);
 	}
 
-	if (!of_property_read_u32(np, "fsl,tx-d-cal", &val) &&
+	val = 100;
+	ret = of_property_read_u32(np, "fsl,tx-d-cal", &val);
+	if ((!ret || trim) &&
 	    val >= MXS_PHY_TX_D_CAL_MIN && val <= MXS_PHY_TX_D_CAL_MAX) {
 		/* Scale to a 4-bit value.  Round up the values and heavily
 		 * weight the rounding by adding 2/3 of the denominator.
@@ -1065,6 +1097,8 @@ static int mxs_phy_probe(struct platform_device *pdev)
 		val = ((MXS_PHY_TX_D_CAL_MAX - val) * 0xF
 			+ (MXS_PHY_TX_D_CAL_MAX - MXS_PHY_TX_D_CAL_MIN) * 2/3)
 			/ (MXS_PHY_TX_D_CAL_MAX - MXS_PHY_TX_D_CAL_MIN);
+
+		val = mxs_phy_trim_offset(val, GM_USBPHY_TRIM_TX_D_CAL(trim));
 		mxs_phy->tx_reg_mask |= GM_USBPHY_TX_D_CAL(~0);
 		mxs_phy->tx_reg_set  |= GM_USBPHY_TX_D_CAL(val);
 	}
-- 
2.35.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ