summaryrefslogtreecommitdiff
path: root/drivers/phy/qualcomm
diff options
context:
space:
mode:
authorJohan Hovold <johan+linaro@kernel.org>2022-11-14 14:06:11 +0300
committerVinod Koul <vkoul@kernel.org>2022-11-24 20:16:52 +0300
commitc7fbe5bd14145425d38a3b1e4d59f1b3acff3eba (patch)
treebce2834c52ba20ce04e52c9c2bd472d8f01f94a7 /drivers/phy/qualcomm
parentdae95d7f667d20ab81976f846ed0bf2c71dbfe18 (diff)
downloadlinux-c7fbe5bd14145425d38a3b1e4d59f1b3acff3eba.tar.xz
phy: qcom-qmp-combo: separate USB and DP devicetree parsing
Separate the devicetree parsing of the USB and DP child nodes in two dedicated helpers in preparation for merging the driver data. Note that only the USB part of the PHY has a pipe clock and that the DP implementation only uses the tx/tx2 and pcs register regions. Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Signed-off-by: Johan Hovold <johan+linaro@kernel.org> Link: https://lore.kernel.org/r/20221114110621.4639-13-johan+linaro@kernel.org Signed-off-by: Vinod Koul <vkoul@kernel.org>
Diffstat (limited to 'drivers/phy/qualcomm')
-rw-r--r--drivers/phy/qualcomm/phy-qcom-qmp-combo.c82
1 files changed, 58 insertions, 24 deletions
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
index c059e4aeecdb..9c4528dff316 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
@@ -2576,13 +2576,12 @@ static int phy_dp_clks_register(struct qcom_qmp *qmp, struct qmp_phy *qphy,
return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, np);
}
-static int qmp_combo_create(struct device *dev, struct device_node *np, int id,
+static int qmp_combo_create_dp(struct device *dev, struct device_node *np, int id,
void __iomem *serdes, const struct qmp_phy_cfg *cfg)
{
struct qcom_qmp *qmp = dev_get_drvdata(dev);
struct phy *generic_phy;
struct qmp_phy *qphy;
- const struct phy_ops *ops;
int ret;
qphy = devm_kzalloc(dev, sizeof(*qphy), GFP_KERNEL);
@@ -2592,7 +2591,57 @@ static int qmp_combo_create(struct device *dev, struct device_node *np, int id,
qphy->cfg = cfg;
qphy->serdes = serdes;
/*
- * Get memory resources for each PHY:
+ * Get memory resources from the DP child node:
+ * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2.
+ * For dual lane PHYs: tx2 -> 3, rx2 -> 4
+ *
+ * Note that only tx/tx2 and pcs are used by the DP implementation.
+ */
+ qphy->tx = devm_of_iomap(dev, np, 0, NULL);
+ if (IS_ERR(qphy->tx))
+ return PTR_ERR(qphy->tx);
+
+ qphy->pcs = devm_of_iomap(dev, np, 2, NULL);
+ if (IS_ERR(qphy->pcs))
+ return PTR_ERR(qphy->pcs);
+
+ if (cfg->lanes >= 2) {
+ qphy->tx2 = devm_of_iomap(dev, np, 3, NULL);
+ if (IS_ERR(qphy->tx2))
+ return PTR_ERR(qphy->tx2);
+ }
+
+ generic_phy = devm_phy_create(dev, np, &qmp_combo_dp_phy_ops);
+ if (IS_ERR(generic_phy)) {
+ ret = PTR_ERR(generic_phy);
+ dev_err(dev, "failed to create DP PHY: %d\n", ret);
+ return ret;
+ }
+
+ qphy->phy = generic_phy;
+ qphy->qmp = qmp;
+ qmp->phys[id] = qphy;
+ phy_set_drvdata(generic_phy, qphy);
+
+ return 0;
+}
+
+static int qmp_combo_create_usb(struct device *dev, struct device_node *np, int id,
+ void __iomem *serdes, const struct qmp_phy_cfg *cfg)
+{
+ struct qcom_qmp *qmp = dev_get_drvdata(dev);
+ struct phy *generic_phy;
+ struct qmp_phy *qphy;
+ int ret;
+
+ qphy = devm_kzalloc(dev, sizeof(*qphy), GFP_KERNEL);
+ if (!qphy)
+ return -ENOMEM;
+
+ qphy->cfg = cfg;
+ qphy->serdes = serdes;
+ /*
+ * Get memory resources from the USB child node:
* Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2.
* For dual lane PHYs: tx2 -> 3, rx2 -> 4, pcs_misc (optional) -> 5
* For single lane PHYs: pcs_misc (optional) -> 3.
@@ -2631,31 +2680,16 @@ static int qmp_combo_create(struct device *dev, struct device_node *np, int id,
qphy->pcs_misc = NULL;
}
- /*
- * Get PHY's Pipe clock, if any. USB3 and PCIe are PIPE3
- * based phys, so they essentially have pipe clock. So,
- * we return error in case phy is USB3 or PIPE type.
- * Otherwise, we initialize pipe clock to NULL for
- * all phys that don't need this.
- */
qphy->pipe_clk = devm_get_clk_from_child(dev, np, NULL);
if (IS_ERR(qphy->pipe_clk)) {
- if (cfg->type == PHY_TYPE_USB3)
- return dev_err_probe(dev, PTR_ERR(qphy->pipe_clk),
- "failed to get lane%d pipe_clk\n",
- id);
- qphy->pipe_clk = NULL;
+ return dev_err_probe(dev, PTR_ERR(qphy->pipe_clk),
+ "failed to get lane%d pipe_clk\n", id);
}
- if (cfg->type == PHY_TYPE_DP)
- ops = &qmp_combo_dp_phy_ops;
- else
- ops = &qmp_combo_usb_phy_ops;
-
- generic_phy = devm_phy_create(dev, np, ops);
+ generic_phy = devm_phy_create(dev, np, &qmp_combo_usb_phy_ops);
if (IS_ERR(generic_phy)) {
ret = PTR_ERR(generic_phy);
- dev_err(dev, "failed to create qphy %d\n", ret);
+ dev_err(dev, "failed to create USB PHY: %d\n", ret);
return ret;
}
@@ -2752,7 +2786,7 @@ static int qmp_combo_probe(struct platform_device *pdev)
serdes = dp_serdes;
/* Create per-lane phy */
- ret = qmp_combo_create(dev, child, id, serdes, cfg);
+ ret = qmp_combo_create_dp(dev, child, id, serdes, cfg);
if (ret) {
dev_err(dev, "failed to create lane%d phy, %d\n",
id, ret);
@@ -2770,7 +2804,7 @@ static int qmp_combo_probe(struct platform_device *pdev)
serdes = usb_serdes;
/* Create per-lane phy */
- ret = qmp_combo_create(dev, child, id, serdes, cfg);
+ ret = qmp_combo_create_usb(dev, child, id, serdes, cfg);
if (ret) {
dev_err(dev, "failed to create lane%d phy, %d\n",
id, ret);