All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pengyu Luo <mitltlatltl@gmail.com>
To: Vinod Koul <vkoul@kernel.org>,
	Kishon Vijay Abraham I <kishon@kernel.org>,
	Rob Herring <robh@kernel.org>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Conor Dooley <conor+dt@kernel.org>,
	Pengyu Luo <mitltlatltl@gmail.com>,
	Stephen Rothwell <sfr@canb.auug.org.au>,
	Abel Vesa <abel.vesa@linaro.org>
Cc: linux-arm-msm@vger.kernel.org, linux-phy@lists.infradead.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH v2 2/2] phy: qualcomm: phy-qcom-eusb2-repeater: rework reg override handler
Date: Wed, 16 Apr 2025 20:02:01 +0800	[thread overview]
Message-ID: <20250416120201.244133-3-mitltlatltl@gmail.com> (raw)
In-Reply-To: <20250416120201.244133-1-mitltlatltl@gmail.com>

In downstream tree, many registers need to be overridden, it varies
from devices and platforms, with these registers getting more, adding
a handler for this is helpful.

Signed-off-by: Pengyu Luo <mitltlatltl@gmail.com>
---
 .../phy/qualcomm/phy-qcom-eusb2-repeater.c    | 105 +++++++++++++++---
 1 file changed, 92 insertions(+), 13 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c b/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c
index 6bd1b3c75..a4b75e70e 100644
--- a/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c
+++ b/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c
@@ -68,12 +68,27 @@ struct eusb2_repeater_cfg {
 	int num_vregs;
 };
 
+struct tune {
+	const char * const tune_name;
+	const char * const host_tune_name;
+	enum eusb2_reg_layout init_tbl_idx;
+	u8 tune_reg;
+	u8 tune;
+	u8 host_tune;
+};
+
+struct tune_cfg {
+	struct tune *tune_tbl;
+	int tune_tbl_size;
+};
+
 struct eusb2_repeater {
 	struct device *dev;
 	struct regmap *regmap;
 	struct phy *phy;
 	struct regulator_bulk_data *vregs;
 	const struct eusb2_repeater_cfg *cfg;
+	struct tune_cfg *tune_cfg;
 	u32 base;
 	enum phy_mode mode;
 };
@@ -108,6 +123,79 @@ static const struct eusb2_repeater_cfg smb2360_eusb2_cfg = {
 	.num_vregs	= ARRAY_SIZE(pm8550b_vreg_l),
 };
 
+static struct tune tune_tbl[] = {
+	{
+		.tune_name = "qcom,tune-usb2-amplitude",
+		.host_tune_name = "qcom,tune-usb2-amplitude-host",
+		.init_tbl_idx = TUNE_IUSB2,
+		.tune_reg = EUSB2_TUNE_IUSB2,
+	},
+	{
+		.tune_name = "qcom,tune-usb2-disc-thres",
+		.host_tune_name = "qcom,tune-usb2-disc-thres-host",
+		.init_tbl_idx = TUNE_HSDISC,
+		.tune_reg = EUSB2_TUNE_HSDISC,
+
+	},
+	{
+		.tune_name = "qcom,tune-usb2-squelch",
+		.host_tune_name = "qcom,tune-usb2-squelch-host",
+		.init_tbl_idx = TUNE_SQUELCH_U,
+		.tune_reg = EUSB2_TUNE_SQUELCH_U,
+	},
+	{
+		.tune_name = "qcom,tune-usb2-preem",
+		.host_tune_name = "qcom,tune-usb2-preem-host",
+		.init_tbl_idx = TUNE_USB2_PREEM,
+		.tune_reg = EUSB2_TUNE_USB2_PREEM,
+	},
+};
+
+static struct tune_cfg tune_cfg = {
+	.tune_tbl	= tune_tbl,
+	.tune_tbl_size	= ARRAY_SIZE(tune_tbl),
+};
+
+static void eusb2_repeater_write_overrides(struct eusb2_repeater *rptr,
+					   bool is_host_mode)
+{
+	struct tune *tune_tbl;
+	int size, i;
+
+	tune_tbl = rptr->tune_cfg->tune_tbl;
+	size = rptr->tune_cfg->tune_tbl_size;
+
+	for (i = 0; i < size; ++i)
+		regmap_write(rptr->regmap, rptr->base + tune_tbl[i].tune_reg,
+			     is_host_mode ? tune_tbl[i].host_tune : tune_tbl[i].tune);
+}
+
+static void eusb2_repeater_parse_dt(struct eusb2_repeater *rptr)
+{
+	struct device_node *np = rptr->dev->of_node;
+	const u32 *init_tbl = rptr->cfg->init_tbl;
+	struct tune *tune_tbl;
+	int size, i, idx;
+
+	tune_tbl = tune_cfg.tune_tbl;
+	size = tune_cfg.tune_tbl_size;
+
+	for (i = 0; i < size; ++i) {
+		/* set default values from init_tbl */
+		idx = tune_tbl[i].init_tbl_idx;
+		tune_tbl[i].tune = init_tbl[idx];
+		tune_tbl[i].host_tune = init_tbl[idx];
+
+		/* update values from dt */
+		of_property_read_u8(np, tune_tbl[i].tune_name,
+				    &tune_tbl[i].tune);
+		of_property_read_u8(np, tune_tbl[i].host_tune_name,
+				    &tune_tbl[i].host_tune);
+	}
+
+	rptr->tune_cfg = &tune_cfg;
+}
+
 static int eusb2_repeater_init_vregs(struct eusb2_repeater *rptr)
 {
 	int num = rptr->cfg->num_vregs;
@@ -127,20 +215,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;
@@ -153,14 +233,9 @@ static int eusb2_repeater_init(struct phy *phy)
 	regmap_write(regmap, base + EUSB2_TUNE_USB2_HS_COMP_CUR, init_tbl[TUNE_USB2_HS_COMP_CUR]);
 	regmap_write(regmap, base + EUSB2_TUNE_USB2_EQU, init_tbl[TUNE_USB2_EQU]);
 	regmap_write(regmap, base + EUSB2_TUNE_USB2_SLEW, init_tbl[TUNE_USB2_SLEW]);
-	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);
-
 	ret = regmap_read_poll_timeout(regmap, base + EUSB2_RPTR_STATUS, val, val & RPTR_OK, 10, 5);
 	if (ret)
 		dev_err(rptr->dev, "initialization timed-out\n");
@@ -177,6 +252,7 @@ static int eusb2_repeater_set_mode(struct phy *phy,
 
 	switch (mode) {
 	case PHY_MODE_USB_HOST:
+		eusb2_repeater_write_overrides(rptr, true);
 		/*
 		 * CM.Lx is prohibited when repeater is already into Lx state as
 		 * per eUSB 1.2 Spec. Below implement software workaround until
@@ -186,6 +262,7 @@ 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, false);
 		/*
 		 * In device mode clear host mode related workaround as there
 		 * is no repeater reset available, and enable/disable of
@@ -252,6 +329,8 @@ static int eusb2_repeater_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	eusb2_repeater_parse_dt(rptr);
+
 	rptr->phy = devm_phy_create(dev, np, &eusb2_repeater_ops);
 	if (IS_ERR(rptr->phy)) {
 		dev_err(dev, "failed to create PHY: %d\n", ret);
-- 
2.49.0


WARNING: multiple messages have this Message-ID (diff)
From: Pengyu Luo <mitltlatltl@gmail.com>
To: Vinod Koul <vkoul@kernel.org>,
	Kishon Vijay Abraham I <kishon@kernel.org>,
	Rob Herring <robh@kernel.org>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Conor Dooley <conor+dt@kernel.org>,
	Pengyu Luo <mitltlatltl@gmail.com>,
	Stephen Rothwell <sfr@canb.auug.org.au>,
	Abel Vesa <abel.vesa@linaro.org>
Cc: linux-arm-msm@vger.kernel.org, linux-phy@lists.infradead.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH v2 2/2] phy: qualcomm: phy-qcom-eusb2-repeater: rework reg override handler
Date: Wed, 16 Apr 2025 20:02:01 +0800	[thread overview]
Message-ID: <20250416120201.244133-3-mitltlatltl@gmail.com> (raw)
In-Reply-To: <20250416120201.244133-1-mitltlatltl@gmail.com>

In downstream tree, many registers need to be overridden, it varies
from devices and platforms, with these registers getting more, adding
a handler for this is helpful.

Signed-off-by: Pengyu Luo <mitltlatltl@gmail.com>
---
 .../phy/qualcomm/phy-qcom-eusb2-repeater.c    | 105 +++++++++++++++---
 1 file changed, 92 insertions(+), 13 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c b/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c
index 6bd1b3c75..a4b75e70e 100644
--- a/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c
+++ b/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c
@@ -68,12 +68,27 @@ struct eusb2_repeater_cfg {
 	int num_vregs;
 };
 
+struct tune {
+	const char * const tune_name;
+	const char * const host_tune_name;
+	enum eusb2_reg_layout init_tbl_idx;
+	u8 tune_reg;
+	u8 tune;
+	u8 host_tune;
+};
+
+struct tune_cfg {
+	struct tune *tune_tbl;
+	int tune_tbl_size;
+};
+
 struct eusb2_repeater {
 	struct device *dev;
 	struct regmap *regmap;
 	struct phy *phy;
 	struct regulator_bulk_data *vregs;
 	const struct eusb2_repeater_cfg *cfg;
+	struct tune_cfg *tune_cfg;
 	u32 base;
 	enum phy_mode mode;
 };
@@ -108,6 +123,79 @@ static const struct eusb2_repeater_cfg smb2360_eusb2_cfg = {
 	.num_vregs	= ARRAY_SIZE(pm8550b_vreg_l),
 };
 
+static struct tune tune_tbl[] = {
+	{
+		.tune_name = "qcom,tune-usb2-amplitude",
+		.host_tune_name = "qcom,tune-usb2-amplitude-host",
+		.init_tbl_idx = TUNE_IUSB2,
+		.tune_reg = EUSB2_TUNE_IUSB2,
+	},
+	{
+		.tune_name = "qcom,tune-usb2-disc-thres",
+		.host_tune_name = "qcom,tune-usb2-disc-thres-host",
+		.init_tbl_idx = TUNE_HSDISC,
+		.tune_reg = EUSB2_TUNE_HSDISC,
+
+	},
+	{
+		.tune_name = "qcom,tune-usb2-squelch",
+		.host_tune_name = "qcom,tune-usb2-squelch-host",
+		.init_tbl_idx = TUNE_SQUELCH_U,
+		.tune_reg = EUSB2_TUNE_SQUELCH_U,
+	},
+	{
+		.tune_name = "qcom,tune-usb2-preem",
+		.host_tune_name = "qcom,tune-usb2-preem-host",
+		.init_tbl_idx = TUNE_USB2_PREEM,
+		.tune_reg = EUSB2_TUNE_USB2_PREEM,
+	},
+};
+
+static struct tune_cfg tune_cfg = {
+	.tune_tbl	= tune_tbl,
+	.tune_tbl_size	= ARRAY_SIZE(tune_tbl),
+};
+
+static void eusb2_repeater_write_overrides(struct eusb2_repeater *rptr,
+					   bool is_host_mode)
+{
+	struct tune *tune_tbl;
+	int size, i;
+
+	tune_tbl = rptr->tune_cfg->tune_tbl;
+	size = rptr->tune_cfg->tune_tbl_size;
+
+	for (i = 0; i < size; ++i)
+		regmap_write(rptr->regmap, rptr->base + tune_tbl[i].tune_reg,
+			     is_host_mode ? tune_tbl[i].host_tune : tune_tbl[i].tune);
+}
+
+static void eusb2_repeater_parse_dt(struct eusb2_repeater *rptr)
+{
+	struct device_node *np = rptr->dev->of_node;
+	const u32 *init_tbl = rptr->cfg->init_tbl;
+	struct tune *tune_tbl;
+	int size, i, idx;
+
+	tune_tbl = tune_cfg.tune_tbl;
+	size = tune_cfg.tune_tbl_size;
+
+	for (i = 0; i < size; ++i) {
+		/* set default values from init_tbl */
+		idx = tune_tbl[i].init_tbl_idx;
+		tune_tbl[i].tune = init_tbl[idx];
+		tune_tbl[i].host_tune = init_tbl[idx];
+
+		/* update values from dt */
+		of_property_read_u8(np, tune_tbl[i].tune_name,
+				    &tune_tbl[i].tune);
+		of_property_read_u8(np, tune_tbl[i].host_tune_name,
+				    &tune_tbl[i].host_tune);
+	}
+
+	rptr->tune_cfg = &tune_cfg;
+}
+
 static int eusb2_repeater_init_vregs(struct eusb2_repeater *rptr)
 {
 	int num = rptr->cfg->num_vregs;
@@ -127,20 +215,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;
@@ -153,14 +233,9 @@ static int eusb2_repeater_init(struct phy *phy)
 	regmap_write(regmap, base + EUSB2_TUNE_USB2_HS_COMP_CUR, init_tbl[TUNE_USB2_HS_COMP_CUR]);
 	regmap_write(regmap, base + EUSB2_TUNE_USB2_EQU, init_tbl[TUNE_USB2_EQU]);
 	regmap_write(regmap, base + EUSB2_TUNE_USB2_SLEW, init_tbl[TUNE_USB2_SLEW]);
-	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);
-
 	ret = regmap_read_poll_timeout(regmap, base + EUSB2_RPTR_STATUS, val, val & RPTR_OK, 10, 5);
 	if (ret)
 		dev_err(rptr->dev, "initialization timed-out\n");
@@ -177,6 +252,7 @@ static int eusb2_repeater_set_mode(struct phy *phy,
 
 	switch (mode) {
 	case PHY_MODE_USB_HOST:
+		eusb2_repeater_write_overrides(rptr, true);
 		/*
 		 * CM.Lx is prohibited when repeater is already into Lx state as
 		 * per eUSB 1.2 Spec. Below implement software workaround until
@@ -186,6 +262,7 @@ 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, false);
 		/*
 		 * In device mode clear host mode related workaround as there
 		 * is no repeater reset available, and enable/disable of
@@ -252,6 +329,8 @@ static int eusb2_repeater_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	eusb2_repeater_parse_dt(rptr);
+
 	rptr->phy = devm_phy_create(dev, np, &eusb2_repeater_ops);
 	if (IS_ERR(rptr->phy)) {
 		dev_err(dev, "failed to create PHY: %d\n", ret);
-- 
2.49.0


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

  parent reply	other threads:[~2025-04-16 12:04 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-04-16 12:01 [PATCH v2 0/2] phy: qualcomm: phy-qcom-eusb2-repeater: rework reg override handler Pengyu Luo
2025-04-16 12:01 ` Pengyu Luo
2025-04-16 12:02 ` [PATCH v2 1/2] dt-bindings: phy: qcom,snps-eusb2-repeater: Add more tuning overrides Pengyu Luo
2025-04-16 12:02   ` Pengyu Luo
2025-04-21 21:32   ` Rob Herring
2025-04-21 21:32     ` Rob Herring
2025-04-16 12:02 ` Pengyu Luo [this message]
2025-04-16 12:02   ` [PATCH v2 2/2] phy: qualcomm: phy-qcom-eusb2-repeater: rework reg override handler Pengyu Luo
2025-04-25 19:41   ` Dmitry Baryshkov
2025-04-25 19:41     ` Dmitry Baryshkov
2025-04-26  8:14     ` Pengyu Luo
2025-04-26  8:14       ` Pengyu Luo
2025-04-28 16:58       ` Dmitry Baryshkov
2025-04-28 16:58         ` Dmitry Baryshkov
2025-04-29  9:23         ` Pengyu Luo
2025-04-29  9:23           ` Pengyu Luo

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=20250416120201.244133-3-mitltlatltl@gmail.com \
    --to=mitltlatltl@gmail.com \
    --cc=abel.vesa@linaro.org \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=kishon@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=sfr@canb.auug.org.au \
    --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.