All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pengyu Luo <mitltlatltl@gmail.com>
To: Bjorn Andersson <andersson@kernel.org>,
	Konrad Dybcio <konradybcio@kernel.org>,
	Rob Herring <robh@kernel.org>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Conor Dooley <conor+dt@kernel.org>, Vinod Koul <vkoul@kernel.org>,
	Kishon Vijay Abraham I <kishon@kernel.org>
Cc: Pengyu Luo <mitltlatltl@gmail.com>,
	linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org
Subject: [PATCH] phy: qualcomm: phy-qcom-eusb2-repeater: rework reg override handler
Date: Sun,  6 Apr 2025 01:43:18 +0800	[thread overview]
Message-ID: <20250405174319.405975-1-mitltlatltl@gmail.com> (raw)

In downstream tree, many registers need to be overrided, it varies
from devices and platforms, not only HS trasmit amplitude(0x51),
HS disconnect threshold(0x53), Tx pre-emphasis tuning(0x57).

The device I plan to upstream also uses it, so I write the patch for
it (Oneplus Pad Pro / Oneplus Pad 2, sm8650-mtp based).

In upstream, only Sony Xperia 1 V is using this, so fixing it for sony,
in downstream, some crd, mtp, htk devices also use it, I have no
such device, don't set it for them.

Signed-off-by: Pengyu Luo <mitltlatltl@gmail.com>
---
 .../qcom/sm8550-sony-xperia-yodo-pdx234.dts   |  5 +-
 .../phy/qualcomm/phy-qcom-eusb2-repeater.c    | 86 +++++++++++++++----
 2 files changed, 72 insertions(+), 19 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/sm8550-sony-xperia-yodo-pdx234.dts b/arch/arm64/boot/dts/qcom/sm8550-sony-xperia-yodo-pdx234.dts
index d90dc7b37..99f5fd32c 100644
--- a/arch/arm64/boot/dts/qcom/sm8550-sony-xperia-yodo-pdx234.dts
+++ b/arch/arm64/boot/dts/qcom/sm8550-sony-xperia-yodo-pdx234.dts
@@ -673,9 +673,8 @@ cam_pwr_a_cs: cam-pwr-a-cs-state {
 };
 
 &pm8550b_eusb2_repeater {
-	qcom,tune-usb2-disc-thres = /bits/ 8 <0x6>;
-	qcom,tune-usb2-amplitude = /bits/ 8 <0xf>;
-	qcom,tune-usb2-preem = /bits/ 8 <0x7>;
+	qcom,param-override-seq = <0x51 0x08 0x53 0x06 0x57 0x07>;
+	qcom,host-param-override-seq = <0x51 0x08 0x53 0x06 0x57 0x07>;
 	vdd18-supply = <&pm8550_l15>;
 	vdd3-supply = <&pm8550_l5>;
 };
diff --git a/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c b/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c
index 6bd1b3c75..151e93cd0 100644
--- a/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c
+++ b/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c
@@ -76,6 +76,11 @@ struct eusb2_repeater {
 	const struct eusb2_repeater_cfg *cfg;
 	u32 base;
 	enum phy_mode mode;
+
+	u32 *param_override_seq;
+	u32 *host_param_override_seq;
+	u8 param_override_seq_cnt;
+	u8 host_param_override_seq_cnt;
 };
 
 static const char * const pm8550b_vreg_l[] = {
@@ -108,6 +113,63 @@ static const struct eusb2_repeater_cfg smb2360_eusb2_cfg = {
 	.num_vregs	= ARRAY_SIZE(pm8550b_vreg_l),
 };
 
+static void eusb2_repeater_write_overrides(struct eusb2_repeater *rptr,
+					   u32 *seq, u8 cnt)
+{
+	int i;
+
+	for (i = 0; i < cnt; i += 2)
+		regmap_write(rptr->regmap, rptr->base + seq[i], seq[i + 1]);
+}
+
+static int eusb2_repeater_read_overrides(struct device *dev, const char *prop,
+					 u32 **seq, u8 *seq_cnt)
+{
+	int num_elem, ret;
+
+	num_elem = of_property_count_elems_of_size(dev->of_node, prop, sizeof(**seq));
+	if (num_elem > 0) {
+		if (num_elem % 2) {
+			dev_err(dev, "invalid len for %s\n", prop);
+			return -EINVAL;
+		}
+
+		*seq_cnt = num_elem;
+		*seq = devm_kcalloc(dev, num_elem, sizeof(**seq), GFP_KERNEL);
+		if (!*seq)
+			return -ENOMEM;
+
+		ret = of_property_read_u32_array(dev->of_node, prop, *seq, num_elem);
+		if (ret) {
+			dev_err(dev, "%s read failed %d\n", prop, ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int eusb2_repeater_parse_dt(struct eusb2_repeater *rptr)
+{
+	int ret;
+
+	ret = of_property_read_u32(rptr->dev->of_node, "reg", &rptr->base);
+	if (ret < 0)
+		return ret;
+
+	ret = eusb2_repeater_read_overrides(rptr->dev, "qcom,param-override-seq",
+					    &rptr->param_override_seq,
+					    &rptr->param_override_seq_cnt);
+	if (ret < 0)
+		return ret;
+
+	ret = eusb2_repeater_read_overrides(rptr->dev, "qcom,host-param-override-seq",
+					    &rptr->host_param_override_seq,
+					    &rptr->host_param_override_seq_cnt);
+
+	return ret;
+}
+
 static int eusb2_repeater_init_vregs(struct eusb2_repeater *rptr)
 {
 	int num = rptr->cfg->num_vregs;
@@ -127,20 +189,12 @@ static int eusb2_repeater_init_vregs(struct eusb2_repeater *rptr)
 static int eusb2_repeater_init(struct phy *phy)
 {
 	struct eusb2_repeater *rptr = phy_get_drvdata(phy);
-	struct device_node *np = rptr->dev->of_node;
 	struct regmap *regmap = rptr->regmap;
 	const u32 *init_tbl = rptr->cfg->init_tbl;
-	u8 tune_usb2_preem = init_tbl[TUNE_USB2_PREEM];
-	u8 tune_hsdisc = init_tbl[TUNE_HSDISC];
-	u8 tune_iusb2 = init_tbl[TUNE_IUSB2];
 	u32 base = rptr->base;
 	u32 val;
 	int ret;
 
-	of_property_read_u8(np, "qcom,tune-usb2-amplitude", &tune_iusb2);
-	of_property_read_u8(np, "qcom,tune-usb2-disc-thres", &tune_hsdisc);
-	of_property_read_u8(np, "qcom,tune-usb2-preem", &tune_usb2_preem);
-
 	ret = regulator_bulk_enable(rptr->cfg->num_vregs, rptr->vregs);
 	if (ret)
 		return ret;
@@ -156,10 +210,9 @@ static int eusb2_repeater_init(struct phy *phy)
 	regmap_write(regmap, base + EUSB2_TUNE_SQUELCH_U, init_tbl[TUNE_SQUELCH_U]);
 	regmap_write(regmap, base + EUSB2_TUNE_RES_FSDIF, init_tbl[TUNE_RES_FSDIF]);
 	regmap_write(regmap, base + EUSB2_TUNE_USB2_CROSSOVER, init_tbl[TUNE_USB2_CROSSOVER]);
-
-	regmap_write(regmap, base + EUSB2_TUNE_USB2_PREEM, tune_usb2_preem);
-	regmap_write(regmap, base + EUSB2_TUNE_HSDISC, tune_hsdisc);
-	regmap_write(regmap, base + EUSB2_TUNE_IUSB2, tune_iusb2);
+	regmap_write(regmap, base + EUSB2_TUNE_USB2_PREEM, init_tbl[TUNE_USB2_PREEM]);
+	regmap_write(regmap, base + EUSB2_TUNE_HSDISC, init_tbl[TUNE_HSDISC]);
+	regmap_write(regmap, base + EUSB2_TUNE_IUSB2, init_tbl[TUNE_IUSB2]);
 
 	ret = regmap_read_poll_timeout(regmap, base + EUSB2_RPTR_STATUS, val, val & RPTR_OK, 10, 5);
 	if (ret)
@@ -177,6 +230,8 @@ static int eusb2_repeater_set_mode(struct phy *phy,
 
 	switch (mode) {
 	case PHY_MODE_USB_HOST:
+		eusb2_repeater_write_overrides(rptr, rptr->host_param_override_seq,
+					       rptr->host_param_override_seq_cnt);
 		/*
 		 * CM.Lx is prohibited when repeater is already into Lx state as
 		 * per eUSB 1.2 Spec. Below implement software workaround until
@@ -186,6 +241,8 @@ static int eusb2_repeater_set_mode(struct phy *phy,
 		regmap_write(regmap, base + EUSB2_FORCE_VAL_5, V_CLK_19P2M_EN);
 		break;
 	case PHY_MODE_USB_DEVICE:
+		eusb2_repeater_write_overrides(rptr, rptr->param_override_seq,
+					       rptr->param_override_seq_cnt);
 		/*
 		 * In device mode clear host mode related workaround as there
 		 * is no repeater reset available, and enable/disable of
@@ -222,7 +279,6 @@ static int eusb2_repeater_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct phy_provider *phy_provider;
 	struct device_node *np = dev->of_node;
-	u32 res;
 	int ret;
 
 	rptr = devm_kzalloc(dev, sizeof(*rptr), GFP_KERNEL);
@@ -240,12 +296,10 @@ static int eusb2_repeater_probe(struct platform_device *pdev)
 	if (!rptr->regmap)
 		return -ENODEV;
 
-	ret = of_property_read_u32(np, "reg", &res);
+	ret = eusb2_repeater_parse_dt(rptr);
 	if (ret < 0)
 		return ret;
 
-	rptr->base = res;
-
 	ret = eusb2_repeater_init_vregs(rptr);
 	if (ret < 0) {
 		dev_err(dev, "unable to get supplies\n");
-- 
2.49.0


WARNING: multiple messages have this Message-ID (diff)
From: Pengyu Luo <mitltlatltl@gmail.com>
To: Bjorn Andersson <andersson@kernel.org>,
	Konrad Dybcio <konradybcio@kernel.org>,
	Rob Herring <robh@kernel.org>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Conor Dooley <conor+dt@kernel.org>, Vinod Koul <vkoul@kernel.org>,
	Kishon Vijay Abraham I <kishon@kernel.org>
Cc: Pengyu Luo <mitltlatltl@gmail.com>,
	linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org
Subject: [PATCH] phy: qualcomm: phy-qcom-eusb2-repeater: rework reg override handler
Date: Sun,  6 Apr 2025 01:43:18 +0800	[thread overview]
Message-ID: <20250405174319.405975-1-mitltlatltl@gmail.com> (raw)

In downstream tree, many registers need to be overrided, it varies
from devices and platforms, not only HS trasmit amplitude(0x51),
HS disconnect threshold(0x53), Tx pre-emphasis tuning(0x57).

The device I plan to upstream also uses it, so I write the patch for
it (Oneplus Pad Pro / Oneplus Pad 2, sm8650-mtp based).

In upstream, only Sony Xperia 1 V is using this, so fixing it for sony,
in downstream, some crd, mtp, htk devices also use it, I have no
such device, don't set it for them.

Signed-off-by: Pengyu Luo <mitltlatltl@gmail.com>
---
 .../qcom/sm8550-sony-xperia-yodo-pdx234.dts   |  5 +-
 .../phy/qualcomm/phy-qcom-eusb2-repeater.c    | 86 +++++++++++++++----
 2 files changed, 72 insertions(+), 19 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/sm8550-sony-xperia-yodo-pdx234.dts b/arch/arm64/boot/dts/qcom/sm8550-sony-xperia-yodo-pdx234.dts
index d90dc7b37..99f5fd32c 100644
--- a/arch/arm64/boot/dts/qcom/sm8550-sony-xperia-yodo-pdx234.dts
+++ b/arch/arm64/boot/dts/qcom/sm8550-sony-xperia-yodo-pdx234.dts
@@ -673,9 +673,8 @@ cam_pwr_a_cs: cam-pwr-a-cs-state {
 };
 
 &pm8550b_eusb2_repeater {
-	qcom,tune-usb2-disc-thres = /bits/ 8 <0x6>;
-	qcom,tune-usb2-amplitude = /bits/ 8 <0xf>;
-	qcom,tune-usb2-preem = /bits/ 8 <0x7>;
+	qcom,param-override-seq = <0x51 0x08 0x53 0x06 0x57 0x07>;
+	qcom,host-param-override-seq = <0x51 0x08 0x53 0x06 0x57 0x07>;
 	vdd18-supply = <&pm8550_l15>;
 	vdd3-supply = <&pm8550_l5>;
 };
diff --git a/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c b/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c
index 6bd1b3c75..151e93cd0 100644
--- a/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c
+++ b/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c
@@ -76,6 +76,11 @@ struct eusb2_repeater {
 	const struct eusb2_repeater_cfg *cfg;
 	u32 base;
 	enum phy_mode mode;
+
+	u32 *param_override_seq;
+	u32 *host_param_override_seq;
+	u8 param_override_seq_cnt;
+	u8 host_param_override_seq_cnt;
 };
 
 static const char * const pm8550b_vreg_l[] = {
@@ -108,6 +113,63 @@ static const struct eusb2_repeater_cfg smb2360_eusb2_cfg = {
 	.num_vregs	= ARRAY_SIZE(pm8550b_vreg_l),
 };
 
+static void eusb2_repeater_write_overrides(struct eusb2_repeater *rptr,
+					   u32 *seq, u8 cnt)
+{
+	int i;
+
+	for (i = 0; i < cnt; i += 2)
+		regmap_write(rptr->regmap, rptr->base + seq[i], seq[i + 1]);
+}
+
+static int eusb2_repeater_read_overrides(struct device *dev, const char *prop,
+					 u32 **seq, u8 *seq_cnt)
+{
+	int num_elem, ret;
+
+	num_elem = of_property_count_elems_of_size(dev->of_node, prop, sizeof(**seq));
+	if (num_elem > 0) {
+		if (num_elem % 2) {
+			dev_err(dev, "invalid len for %s\n", prop);
+			return -EINVAL;
+		}
+
+		*seq_cnt = num_elem;
+		*seq = devm_kcalloc(dev, num_elem, sizeof(**seq), GFP_KERNEL);
+		if (!*seq)
+			return -ENOMEM;
+
+		ret = of_property_read_u32_array(dev->of_node, prop, *seq, num_elem);
+		if (ret) {
+			dev_err(dev, "%s read failed %d\n", prop, ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int eusb2_repeater_parse_dt(struct eusb2_repeater *rptr)
+{
+	int ret;
+
+	ret = of_property_read_u32(rptr->dev->of_node, "reg", &rptr->base);
+	if (ret < 0)
+		return ret;
+
+	ret = eusb2_repeater_read_overrides(rptr->dev, "qcom,param-override-seq",
+					    &rptr->param_override_seq,
+					    &rptr->param_override_seq_cnt);
+	if (ret < 0)
+		return ret;
+
+	ret = eusb2_repeater_read_overrides(rptr->dev, "qcom,host-param-override-seq",
+					    &rptr->host_param_override_seq,
+					    &rptr->host_param_override_seq_cnt);
+
+	return ret;
+}
+
 static int eusb2_repeater_init_vregs(struct eusb2_repeater *rptr)
 {
 	int num = rptr->cfg->num_vregs;
@@ -127,20 +189,12 @@ static int eusb2_repeater_init_vregs(struct eusb2_repeater *rptr)
 static int eusb2_repeater_init(struct phy *phy)
 {
 	struct eusb2_repeater *rptr = phy_get_drvdata(phy);
-	struct device_node *np = rptr->dev->of_node;
 	struct regmap *regmap = rptr->regmap;
 	const u32 *init_tbl = rptr->cfg->init_tbl;
-	u8 tune_usb2_preem = init_tbl[TUNE_USB2_PREEM];
-	u8 tune_hsdisc = init_tbl[TUNE_HSDISC];
-	u8 tune_iusb2 = init_tbl[TUNE_IUSB2];
 	u32 base = rptr->base;
 	u32 val;
 	int ret;
 
-	of_property_read_u8(np, "qcom,tune-usb2-amplitude", &tune_iusb2);
-	of_property_read_u8(np, "qcom,tune-usb2-disc-thres", &tune_hsdisc);
-	of_property_read_u8(np, "qcom,tune-usb2-preem", &tune_usb2_preem);
-
 	ret = regulator_bulk_enable(rptr->cfg->num_vregs, rptr->vregs);
 	if (ret)
 		return ret;
@@ -156,10 +210,9 @@ static int eusb2_repeater_init(struct phy *phy)
 	regmap_write(regmap, base + EUSB2_TUNE_SQUELCH_U, init_tbl[TUNE_SQUELCH_U]);
 	regmap_write(regmap, base + EUSB2_TUNE_RES_FSDIF, init_tbl[TUNE_RES_FSDIF]);
 	regmap_write(regmap, base + EUSB2_TUNE_USB2_CROSSOVER, init_tbl[TUNE_USB2_CROSSOVER]);
-
-	regmap_write(regmap, base + EUSB2_TUNE_USB2_PREEM, tune_usb2_preem);
-	regmap_write(regmap, base + EUSB2_TUNE_HSDISC, tune_hsdisc);
-	regmap_write(regmap, base + EUSB2_TUNE_IUSB2, tune_iusb2);
+	regmap_write(regmap, base + EUSB2_TUNE_USB2_PREEM, init_tbl[TUNE_USB2_PREEM]);
+	regmap_write(regmap, base + EUSB2_TUNE_HSDISC, init_tbl[TUNE_HSDISC]);
+	regmap_write(regmap, base + EUSB2_TUNE_IUSB2, init_tbl[TUNE_IUSB2]);
 
 	ret = regmap_read_poll_timeout(regmap, base + EUSB2_RPTR_STATUS, val, val & RPTR_OK, 10, 5);
 	if (ret)
@@ -177,6 +230,8 @@ static int eusb2_repeater_set_mode(struct phy *phy,
 
 	switch (mode) {
 	case PHY_MODE_USB_HOST:
+		eusb2_repeater_write_overrides(rptr, rptr->host_param_override_seq,
+					       rptr->host_param_override_seq_cnt);
 		/*
 		 * CM.Lx is prohibited when repeater is already into Lx state as
 		 * per eUSB 1.2 Spec. Below implement software workaround until
@@ -186,6 +241,8 @@ static int eusb2_repeater_set_mode(struct phy *phy,
 		regmap_write(regmap, base + EUSB2_FORCE_VAL_5, V_CLK_19P2M_EN);
 		break;
 	case PHY_MODE_USB_DEVICE:
+		eusb2_repeater_write_overrides(rptr, rptr->param_override_seq,
+					       rptr->param_override_seq_cnt);
 		/*
 		 * In device mode clear host mode related workaround as there
 		 * is no repeater reset available, and enable/disable of
@@ -222,7 +279,6 @@ static int eusb2_repeater_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct phy_provider *phy_provider;
 	struct device_node *np = dev->of_node;
-	u32 res;
 	int ret;
 
 	rptr = devm_kzalloc(dev, sizeof(*rptr), GFP_KERNEL);
@@ -240,12 +296,10 @@ static int eusb2_repeater_probe(struct platform_device *pdev)
 	if (!rptr->regmap)
 		return -ENODEV;
 
-	ret = of_property_read_u32(np, "reg", &res);
+	ret = eusb2_repeater_parse_dt(rptr);
 	if (ret < 0)
 		return ret;
 
-	rptr->base = res;
-
 	ret = eusb2_repeater_init_vregs(rptr);
 	if (ret < 0) {
 		dev_err(dev, "unable to get supplies\n");
-- 
2.49.0


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

             reply	other threads:[~2025-04-05 17:45 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-04-05 17:43 Pengyu Luo [this message]
2025-04-05 17:43 ` [PATCH] phy: qualcomm: phy-qcom-eusb2-repeater: rework reg override handler Pengyu Luo
2025-04-06 12:21 ` Krzysztof Kozlowski
2025-04-06 12:21   ` Krzysztof Kozlowski
2025-04-06 20:30 ` Dmitry Baryshkov
2025-04-06 20:30   ` Dmitry Baryshkov
2025-04-07 12:47 ` Rob Herring (Arm)
2025-04-07 12:47   ` Rob Herring (Arm)
  -- strict thread matches above, loose matches on Subject: below --
2025-04-06 20:01 kernel test robot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250405174319.405975-1-mitltlatltl@gmail.com \
    --to=mitltlatltl@gmail.com \
    --cc=andersson@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=kishon@kernel.org \
    --cc=konradybcio@kernel.org \
    --cc=krzk+dt@kernel.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-phy@lists.infradead.org \
    --cc=robh@kernel.org \
    --cc=vkoul@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.