* [PATCH 0/4] phy: qcom: extract common clock-handling code
@ 2025-09-07 14:52 Dmitry Baryshkov
2025-09-07 14:52 ` [PATCH 1/4] phy: qcom: qmp-usb-legacy: switch to common helpers Dmitry Baryshkov
` (3 more replies)
0 siblings, 4 replies; 9+ messages in thread
From: Dmitry Baryshkov @ 2025-09-07 14:52 UTC (permalink / raw)
To: Vinod Koul, Kishon Vijay Abraham I; +Cc: linux-arm-msm, linux-phy, linux-kernel
QMP PHY drivers share code to register PIPE clock and to handle DP link
and pixel clocks. While the amount of share code is not that big, it's
still better to extract it to common helpers, reducing code duplication.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
Dmitry Baryshkov (4):
phy: qcom: qmp-usb-legacy: switch to common helpers
phy: qcom: qmp: extract common PIPE clock helpers
phy: qcom: qmp-pcie: simplify AUX clock registration
phy: qcom: extract common code for DP clocks
drivers/phy/qualcomm/Kconfig | 8 +
drivers/phy/qualcomm/Makefile | 1 +
drivers/phy/qualcomm/phy-qcom-dp-common.c | 164 +++++++++++++++
drivers/phy/qualcomm/phy-qcom-dp-common.h | 22 ++
drivers/phy/qualcomm/phy-qcom-edp.c | 181 ++---------------
drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 244 +++--------------------
drivers/phy/qualcomm/phy-qcom-qmp-common.h | 67 +++++++
drivers/phy/qualcomm/phy-qcom-qmp-pcie-msm8996.c | 62 +-----
drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 83 ++------
drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c | 124 +-----------
drivers/phy/qualcomm/phy-qcom-qmp-usb.c | 60 +-----
drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 60 +-----
12 files changed, 334 insertions(+), 742 deletions(-)
---
base-commit: be5d4872e528796df9d7425f2bd9b3893eb3a42c
change-id: 20250907-qcom-dp-phy-8e94929431e1
Best regards,
--
With best wishes
Dmitry
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/4] phy: qcom: qmp-usb-legacy: switch to common helpers
2025-09-07 14:52 [PATCH 0/4] phy: qcom: extract common clock-handling code Dmitry Baryshkov
@ 2025-09-07 14:52 ` Dmitry Baryshkov
2025-09-08 8:17 ` Konrad Dybcio
2025-09-07 14:52 ` [PATCH 2/4] phy: qcom: qmp: extract common PIPE clock helpers Dmitry Baryshkov
` (2 subsequent siblings)
3 siblings, 1 reply; 9+ messages in thread
From: Dmitry Baryshkov @ 2025-09-07 14:52 UTC (permalink / raw)
To: Vinod Koul, Kishon Vijay Abraham I; +Cc: linux-arm-msm, linux-phy, linux-kernel
Instead of having a copy of the common definitions and functions inside
the usb-legacy PHY driver, use the phy-qcom-qmp-common.h header.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c | 64 ++++----------------------
1 file changed, 8 insertions(+), 56 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c
index 8bf951b0490cfd811635df8940de1b789e21b46c..ddb52c1812dd02e15a840deee934c849405c2a98 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c
@@ -20,6 +20,8 @@
#include <linux/reset.h>
#include <linux/slab.h>
+#include "phy-qcom-qmp-common.h"
+
#include "phy-qcom-qmp.h"
#include "phy-qcom-qmp-pcs-misc-v3.h"
#include "phy-qcom-qmp-pcs-usb-v4.h"
@@ -43,30 +45,6 @@
#define PHY_INIT_COMPLETE_TIMEOUT 10000
-struct qmp_phy_init_tbl {
- unsigned int offset;
- unsigned int val;
- /*
- * mask of lanes for which this register is written
- * for cases when second lane needs different values
- */
- u8 lane_mask;
-};
-
-#define QMP_PHY_INIT_CFG(o, v) \
- { \
- .offset = o, \
- .val = v, \
- .lane_mask = 0xff, \
- }
-
-#define QMP_PHY_INIT_CFG_LANE(o, v, l) \
- { \
- .offset = o, \
- .val = v, \
- .lane_mask = l, \
- }
-
/* set of registers with offsets different per-PHY */
enum qphy_reg_layout {
/* PCS registers */
@@ -698,32 +676,6 @@ static const struct qmp_phy_cfg sm8350_usb3phy_cfg = {
.pcs_usb_offset = 0x300,
};
-static void qmp_usb_legacy_configure_lane(void __iomem *base,
- const struct qmp_phy_init_tbl tbl[],
- int num,
- u8 lane_mask)
-{
- int i;
- const struct qmp_phy_init_tbl *t = tbl;
-
- if (!t)
- return;
-
- for (i = 0; i < num; i++, t++) {
- if (!(t->lane_mask & lane_mask))
- continue;
-
- writel(t->val, base + t->offset);
- }
-}
-
-static void qmp_usb_legacy_configure(void __iomem *base,
- const struct qmp_phy_init_tbl tbl[],
- int num)
-{
- qmp_usb_legacy_configure_lane(base, tbl, num, 0xff);
-}
-
static int qmp_usb_legacy_serdes_init(struct qmp_usb *qmp)
{
const struct qmp_phy_cfg *cfg = qmp->cfg;
@@ -731,7 +683,7 @@ static int qmp_usb_legacy_serdes_init(struct qmp_usb *qmp)
const struct qmp_phy_init_tbl *serdes_tbl = cfg->serdes_tbl;
int serdes_tbl_num = cfg->serdes_tbl_num;
- qmp_usb_legacy_configure(serdes, serdes_tbl, serdes_tbl_num);
+ qmp_configure(qmp->dev, serdes, serdes_tbl, serdes_tbl_num);
return 0;
}
@@ -840,13 +792,13 @@ static int qmp_usb_legacy_power_on(struct phy *phy)
}
/* Tx, Rx, and PCS configurations */
- qmp_usb_legacy_configure_lane(tx, cfg->tx_tbl, cfg->tx_tbl_num, 1);
- qmp_usb_legacy_configure_lane(rx, cfg->rx_tbl, cfg->rx_tbl_num, 1);
+ qmp_configure_lane(qmp->dev, tx, cfg->tx_tbl, cfg->tx_tbl_num, 1);
+ qmp_configure_lane(qmp->dev, rx, cfg->rx_tbl, cfg->rx_tbl_num, 1);
- qmp_usb_legacy_configure_lane(qmp->tx2, cfg->tx_tbl, cfg->tx_tbl_num, 2);
- qmp_usb_legacy_configure_lane(qmp->rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2);
+ qmp_configure_lane(qmp->dev, qmp->tx2, cfg->tx_tbl, cfg->tx_tbl_num, 2);
+ qmp_configure_lane(qmp->dev, qmp->rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2);
- qmp_usb_legacy_configure(pcs, cfg->pcs_tbl, cfg->pcs_tbl_num);
+ qmp_configure(qmp->dev, pcs, cfg->pcs_tbl, cfg->pcs_tbl_num);
usleep_range(10, 20);
--
2.47.3
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/4] phy: qcom: qmp: extract common PIPE clock helpers
2025-09-07 14:52 [PATCH 0/4] phy: qcom: extract common clock-handling code Dmitry Baryshkov
2025-09-07 14:52 ` [PATCH 1/4] phy: qcom: qmp-usb-legacy: switch to common helpers Dmitry Baryshkov
@ 2025-09-07 14:52 ` Dmitry Baryshkov
2025-09-08 8:30 ` Konrad Dybcio
2025-09-07 14:52 ` [PATCH 3/4] phy: qcom: qmp-pcie: simplify AUX clock registration Dmitry Baryshkov
2025-09-07 14:52 ` [PATCH 4/4] phy: qcom: extract common code for DP clocks Dmitry Baryshkov
3 siblings, 1 reply; 9+ messages in thread
From: Dmitry Baryshkov @ 2025-09-07 14:52 UTC (permalink / raw)
To: Vinod Koul, Kishon Vijay Abraham I; +Cc: linux-arm-msm, linux-phy, linux-kernel
Extract the code common to (almost) all QMP PHY drivers, which handles
the 125 MHz PIPE clock. Drop unused pipe_clk_fixed fields from the QMP
PHY structures, using pipe_clk_hw instead (where required).
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 56 +++-----------------
drivers/phy/qualcomm/phy-qcom-qmp-common.h | 67 ++++++++++++++++++++++++
drivers/phy/qualcomm/phy-qcom-qmp-pcie-msm8996.c | 62 +---------------------
drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 67 +++---------------------
drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c | 60 +--------------------
drivers/phy/qualcomm/phy-qcom-qmp-usb.c | 60 +--------------------
drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 60 +--------------------
7 files changed, 87 insertions(+), 345 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
index 7b5af30f1d028c592500e723ecd27b54ed554709..baf25ae442478ac01a5428fa4268470e6b5211e3 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
@@ -1863,7 +1863,7 @@ struct qmp_combo {
unsigned int dp_init_count;
bool dp_powered_on;
- struct clk_fixed_rate pipe_clk_fixed;
+ struct clk_hw *pipe_clk_hw;
struct clk_hw dp_link_hw;
struct clk_hw dp_pixel_hw;
@@ -3512,46 +3512,6 @@ static int qmp_combo_clk_init(struct qmp_combo *qmp)
return devm_clk_bulk_get_optional(dev, num, qmp->clks);
}
-static void phy_clk_release_provider(void *res)
-{
- of_clk_del_provider(res);
-}
-
-/*
- * Register a fixed rate pipe clock.
- *
- * The <s>_pipe_clksrc generated by PHY goes to the GCC that gate
- * controls it. The <s>_pipe_clk coming out of the GCC is requested
- * by the PHY driver for its operations.
- * We register the <s>_pipe_clksrc here. The gcc driver takes care
- * of assigning this <s>_pipe_clksrc as parent to <s>_pipe_clk.
- * Below picture shows this relationship.
- *
- * +---------------+
- * | PHY block |<<---------------------------------------+
- * | | |
- * | +-------+ | +-----+ |
- * I/P---^-->| PLL |---^--->pipe_clksrc--->| GCC |--->pipe_clk---+
- * clk | +-------+ | +-----+
- * +---------------+
- */
-static int phy_pipe_clk_register(struct qmp_combo *qmp, struct device_node *np)
-{
- struct clk_fixed_rate *fixed = &qmp->pipe_clk_fixed;
- struct clk_init_data init = { };
- char name[64];
-
- snprintf(name, sizeof(name), "%s::pipe_clk", dev_name(qmp->dev));
- init.name = name;
- init.ops = &clk_fixed_rate_ops;
-
- /* controllers using QMP phys use 125MHz pipe clock interface */
- fixed->fixed_rate = 125000000;
- fixed->hw.init = &init;
-
- return devm_clk_hw_register(qmp->dev, &fixed->hw);
-}
-
/*
* Display Port PLL driver block diagram for branch clocks
*
@@ -3724,7 +3684,7 @@ static struct clk_hw *qmp_combo_clk_hw_get(struct of_phandle_args *clkspec, void
switch (clkspec->args[0]) {
case QMP_USB43DP_USB3_PIPE_CLK:
- return &qmp->pipe_clk_fixed.hw;
+ return qmp->pipe_clk_hw;
case QMP_USB43DP_DP_LINK_CLK:
return &qmp->dp_link_hw;
case QMP_USB43DP_DP_VCO_DIV_CLK:
@@ -3739,9 +3699,9 @@ static int qmp_combo_register_clocks(struct qmp_combo *qmp, struct device_node *
{
int ret;
- ret = phy_pipe_clk_register(qmp, usb_np);
- if (ret)
- return ret;
+ qmp->pipe_clk_hw = devm_qmp_register_pipe_clock(qmp->dev, usb_np);
+ if (IS_ERR(qmp->pipe_clk_hw))
+ return PTR_ERR(qmp->pipe_clk_hw);
ret = phy_dp_clks_register(qmp, dp_np);
if (ret)
@@ -3757,7 +3717,7 @@ static int qmp_combo_register_clocks(struct qmp_combo *qmp, struct device_node *
* Register multiple providers for legacy bindings with child nodes.
*/
ret = of_clk_add_hw_provider(usb_np, of_clk_hw_simple_get,
- &qmp->pipe_clk_fixed.hw);
+ qmp->pipe_clk_hw);
if (ret)
return ret;
@@ -3765,7 +3725,7 @@ static int qmp_combo_register_clocks(struct qmp_combo *qmp, struct device_node *
* Roll a devm action because the clock provider is the child node, but
* the child node is not actually a device.
*/
- ret = devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, usb_np);
+ ret = devm_add_action_or_reset(qmp->dev, qmp_clk_release_provider, usb_np);
if (ret)
return ret;
@@ -3773,7 +3733,7 @@ static int qmp_combo_register_clocks(struct qmp_combo *qmp, struct device_node *
if (ret)
return ret;
- return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, dp_np);
+ return devm_add_action_or_reset(qmp->dev, qmp_clk_release_provider, dp_np);
}
#if IS_ENABLED(CONFIG_TYPEC)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-common.h b/drivers/phy/qualcomm/phy-qcom-qmp-common.h
index b945fc14cecec4ef00143e144cea4e10225d5947..00041892d9ec7a45e21b0b15301ab65ed996bd45 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-common.h
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-common.h
@@ -6,6 +6,10 @@
#ifndef QCOM_PHY_QMP_COMMON_H_
#define QCOM_PHY_QMP_COMMON_H_
+#include <linux/clk-provider.h>
+#include <linux/device.h>
+#include <linux/of.h>
+
struct qmp_phy_init_tbl {
unsigned int offset;
unsigned int val;
@@ -59,4 +63,67 @@ static inline void qmp_configure(struct device *dev, void __iomem *base,
qmp_configure_lane(dev, base, tbl, num, 0xff);
}
+/*
+ * Register a fixed rate pipe clock.
+ *
+ * The <s>_pipe_clksrc generated by PHY goes to the GCC that gate
+ * controls it. The <s>_pipe_clk coming out of the GCC is requested
+ * by the PHY driver for its operations.
+ * We register the <s>_pipe_clksrc here. The gcc driver takes care
+ * of assigning this <s>_pipe_clksrc as parent to <s>_pipe_clk.
+ * Below picture shows this relationship.
+ *
+ * +---------------+
+ * | PHY block |<<---------------------------------------+
+ * | | |
+ * | +-------+ | +-----+ |
+ * I/P---^-->| PLL |---^--->pipe_clksrc--->| GCC |--->pipe_clk---+
+ * clk | +-------+ | +-----+
+ * +---------------+
+ */
+static inline struct clk_hw *devm_qmp_register_pipe_clock(struct device *dev,
+ struct device_node *np)
+{
+ const char *pname = NULL;
+ char name[64];
+
+ /* ignore if the property is not present */
+ if (np)
+ of_property_read_string(np, "clock-output-names", &pname);
+
+ if (!pname) {
+ snprintf(name, sizeof(name), "%s::pipe_clk", dev_name(dev));
+ pname = name;
+ }
+
+ /* controllers using QMP phys use 125MHz pipe clock interface */
+ return devm_clk_hw_register_fixed_rate(dev, pname, NULL, 0, 125000000);
+}
+
+static inline void qmp_clk_release_provider(void *res)
+{
+ of_clk_del_provider(res);
+}
+
+static inline int devm_qmp_register_pipe_clock_provider(struct device *dev,
+ struct device_node *np)
+{
+ struct clk_hw *fixed;
+ int ret;
+
+ fixed = devm_qmp_register_pipe_clock(dev, np);
+ if (IS_ERR(fixed))
+ return PTR_ERR(fixed);
+
+ ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, fixed);
+ if (ret)
+ return ret;
+
+ /*
+ * Roll a devm action because the clock provider is the child node, but
+ * the child node is not actually a device.
+ */
+ return devm_add_action_or_reset(dev, qmp_clk_release_provider, np);
+}
+
#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie-msm8996.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie-msm8996.c
index a7c65cfe31dfb80d8b1058d3c519a324a309d1c2..226d893c198bdce0ecd3d7d31ed65199fc360ecf 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie-msm8996.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie-msm8996.c
@@ -579,66 +579,6 @@ static int qmp_pcie_msm8996_clk_init(struct device *dev, const struct qmp_phy_cf
return devm_clk_bulk_get(dev, num, qmp->clks);
}
-static void phy_clk_release_provider(void *res)
-{
- of_clk_del_provider(res);
-}
-
-/*
- * Register a fixed rate pipe clock.
- *
- * The <s>_pipe_clksrc generated by PHY goes to the GCC that gate
- * controls it. The <s>_pipe_clk coming out of the GCC is requested
- * by the PHY driver for its operations.
- * We register the <s>_pipe_clksrc here. The gcc driver takes care
- * of assigning this <s>_pipe_clksrc as parent to <s>_pipe_clk.
- * Below picture shows this relationship.
- *
- * +---------------+
- * | PHY block |<<---------------------------------------+
- * | | |
- * | +-------+ | +-----+ |
- * I/P---^-->| PLL |---^--->pipe_clksrc--->| GCC |--->pipe_clk---+
- * clk | +-------+ | +-----+
- * +---------------+
- */
-static int phy_pipe_clk_register(struct qcom_qmp *qmp, struct device_node *np)
-{
- struct clk_fixed_rate *fixed;
- struct clk_init_data init = { };
- int ret;
-
- ret = of_property_read_string(np, "clock-output-names", &init.name);
- if (ret) {
- dev_err(qmp->dev, "%pOFn: No clock-output-names\n", np);
- return ret;
- }
-
- fixed = devm_kzalloc(qmp->dev, sizeof(*fixed), GFP_KERNEL);
- if (!fixed)
- return -ENOMEM;
-
- init.ops = &clk_fixed_rate_ops;
-
- /* controllers using QMP phys use 125MHz pipe clock interface */
- fixed->fixed_rate = 125000000;
- fixed->hw.init = &init;
-
- ret = devm_clk_hw_register(qmp->dev, &fixed->hw);
- if (ret)
- return ret;
-
- ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &fixed->hw);
- if (ret)
- return ret;
-
- /*
- * Roll a devm action because the clock provider is the child node, but
- * the child node is not actually a device.
- */
- return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, np);
-}
-
static const struct phy_ops qmp_pcie_msm8996_ops = {
.power_on = qmp_pcie_msm8996_enable,
.power_off = qmp_pcie_msm8996_disable,
@@ -785,7 +725,7 @@ static int qmp_pcie_msm8996_probe(struct platform_device *pdev)
* Register the pipe clock provided by phy.
* See function description to see details of this pipe clock.
*/
- ret = phy_pipe_clk_register(qmp, child);
+ ret = devm_qmp_register_pipe_clock_provider(dev, child);
if (ret) {
dev_err(qmp->dev,
"failed to register pipe clock source\n");
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index 62b1c845b6275d924fa501ac64e69db5f58844aa..dad44cc0648355fc1533c9afd176b7d37cfa9018 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -3172,7 +3172,7 @@ struct qmp_pcie {
struct phy *phy;
int mode;
- struct clk_fixed_rate pipe_clk_fixed;
+ struct clk_hw *pipe_clk_hw;
struct clk_fixed_rate aux_clk_fixed;
};
@@ -4789,57 +4789,6 @@ static int qmp_pcie_clk_init(struct qmp_pcie *qmp)
return devm_clk_bulk_get_optional(dev, num, qmp->clks);
}
-static void phy_clk_release_provider(void *res)
-{
- of_clk_del_provider(res);
-}
-
-/*
- * Register a fixed rate pipe clock.
- *
- * The <s>_pipe_clksrc generated by PHY goes to the GCC that gate
- * controls it. The <s>_pipe_clk coming out of the GCC is requested
- * by the PHY driver for its operations.
- * We register the <s>_pipe_clksrc here. The gcc driver takes care
- * of assigning this <s>_pipe_clksrc as parent to <s>_pipe_clk.
- * Below picture shows this relationship.
- *
- * +---------------+
- * | PHY block |<<---------------------------------------+
- * | | |
- * | +-------+ | +-----+ |
- * I/P---^-->| PLL |---^--->pipe_clksrc--->| GCC |--->pipe_clk---+
- * clk | +-------+ | +-----+
- * +---------------+
- */
-static int phy_pipe_clk_register(struct qmp_pcie *qmp, struct device_node *np)
-{
- struct clk_fixed_rate *fixed = &qmp->pipe_clk_fixed;
- struct clk_init_data init = { };
- int ret;
-
- ret = of_property_read_string_index(np, "clock-output-names", 0, &init.name);
- if (ret) {
- dev_err(qmp->dev, "%pOFn: No clock-output-names\n", np);
- return ret;
- }
-
- init.ops = &clk_fixed_rate_ops;
-
- /*
- * Controllers using QMP PHY-s use 125MHz pipe clock interface
- * unless other frequency is specified in the PHY config.
- */
- if (qmp->cfg->pipe_clock_rate)
- fixed->fixed_rate = qmp->cfg->pipe_clock_rate;
- else
- fixed->fixed_rate = 125000000;
-
- fixed->hw.init = &init;
-
- return devm_clk_hw_register(qmp->dev, &fixed->hw);
-}
-
/*
* Register a fixed rate PHY aux clock.
*
@@ -4881,11 +4830,11 @@ static struct clk_hw *qmp_pcie_clk_hw_get(struct of_phandle_args *clkspec, void
/* Support legacy bindings */
if (!clkspec->args_count)
- return &qmp->pipe_clk_fixed.hw;
+ return qmp->pipe_clk_hw;
switch (clkspec->args[0]) {
case QMP_PCIE_PIPE_CLK:
- return &qmp->pipe_clk_fixed.hw;
+ return qmp->pipe_clk_hw;
case QMP_PCIE_PHY_AUX_CLK:
return &qmp->aux_clk_fixed.hw;
}
@@ -4897,9 +4846,9 @@ static int qmp_pcie_register_clocks(struct qmp_pcie *qmp, struct device_node *np
{
int ret;
- ret = phy_pipe_clk_register(qmp, np);
- if (ret)
- return ret;
+ qmp->pipe_clk_hw = devm_qmp_register_pipe_clock(qmp->dev, np);
+ if (IS_ERR(qmp->pipe_clk_hw))
+ return PTR_ERR(qmp->pipe_clk_hw);
if (qmp->cfg->aux_clock_rate) {
ret = phy_aux_clk_register(qmp, np);
@@ -4910,7 +4859,7 @@ static int qmp_pcie_register_clocks(struct qmp_pcie *qmp, struct device_node *np
if (ret)
return ret;
} else {
- ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &qmp->pipe_clk_fixed.hw);
+ ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, qmp->pipe_clk_hw);
if (ret)
return ret;
}
@@ -4919,7 +4868,7 @@ static int qmp_pcie_register_clocks(struct qmp_pcie *qmp, struct device_node *np
* Roll a devm action because the clock provider is the child node, but
* the child node is not actually a device.
*/
- return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, np);
+ return devm_add_action_or_reset(qmp->dev, qmp_clk_release_provider, np);
}
static int qmp_pcie_parse_dt_legacy(struct qmp_pcie *qmp, struct device_node *np)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c
index ddb52c1812dd02e15a840deee934c849405c2a98..0e775671054ed02024d01e3a11c6d3e2f973a097 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb-legacy.c
@@ -521,8 +521,6 @@ struct qmp_usb {
enum phy_mode mode;
struct phy *phy;
-
- struct clk_fixed_rate pipe_clk_fixed;
};
static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
@@ -1043,62 +1041,6 @@ static int qmp_usb_legacy_clk_init(struct qmp_usb *qmp)
return devm_clk_bulk_get(dev, num, qmp->clks);
}
-static void phy_clk_release_provider(void *res)
-{
- of_clk_del_provider(res);
-}
-
-/*
- * Register a fixed rate pipe clock.
- *
- * The <s>_pipe_clksrc generated by PHY goes to the GCC that gate
- * controls it. The <s>_pipe_clk coming out of the GCC is requested
- * by the PHY driver for its operations.
- * We register the <s>_pipe_clksrc here. The gcc driver takes care
- * of assigning this <s>_pipe_clksrc as parent to <s>_pipe_clk.
- * Below picture shows this relationship.
- *
- * +---------------+
- * | PHY block |<<---------------------------------------+
- * | | |
- * | +-------+ | +-----+ |
- * I/P---^-->| PLL |---^--->pipe_clksrc--->| GCC |--->pipe_clk---+
- * clk | +-------+ | +-----+
- * +---------------+
- */
-static int phy_pipe_clk_register(struct qmp_usb *qmp, struct device_node *np)
-{
- struct clk_fixed_rate *fixed = &qmp->pipe_clk_fixed;
- struct clk_init_data init = { };
- int ret;
-
- ret = of_property_read_string(np, "clock-output-names", &init.name);
- if (ret) {
- dev_err(qmp->dev, "%pOFn: No clock-output-names\n", np);
- return ret;
- }
-
- init.ops = &clk_fixed_rate_ops;
-
- /* controllers using QMP phys use 125MHz pipe clock interface */
- fixed->fixed_rate = 125000000;
- fixed->hw.init = &init;
-
- ret = devm_clk_hw_register(qmp->dev, &fixed->hw);
- if (ret)
- return ret;
-
- ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &fixed->hw);
- if (ret)
- return ret;
-
- /*
- * Roll a devm action because the clock provider is the child node, but
- * the child node is not actually a device.
- */
- return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, np);
-}
-
static int qmp_usb_legacy_parse_dt_legacy(struct qmp_usb *qmp, struct device_node *np)
{
struct platform_device *pdev = to_platform_device(qmp->dev);
@@ -1239,7 +1181,7 @@ static int qmp_usb_legacy_probe(struct platform_device *pdev)
*/
pm_runtime_forbid(dev);
- ret = phy_pipe_clk_register(qmp, np);
+ ret = devm_qmp_register_pipe_clock_provider(dev, np);
if (ret)
goto err_node_put;
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
index ed646a7e705ba3259708775ed5fedbbbada13735..7040b53e482d667f90eef09e3c4a93cb6c01f934 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
@@ -1301,8 +1301,6 @@ struct qmp_usb {
enum phy_mode mode;
struct phy *phy;
-
- struct clk_fixed_rate pipe_clk_fixed;
};
static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
@@ -2046,62 +2044,6 @@ static int qmp_usb_clk_init(struct qmp_usb *qmp)
return devm_clk_bulk_get_optional(dev, num, qmp->clks);
}
-static void phy_clk_release_provider(void *res)
-{
- of_clk_del_provider(res);
-}
-
-/*
- * Register a fixed rate pipe clock.
- *
- * The <s>_pipe_clksrc generated by PHY goes to the GCC that gate
- * controls it. The <s>_pipe_clk coming out of the GCC is requested
- * by the PHY driver for its operations.
- * We register the <s>_pipe_clksrc here. The gcc driver takes care
- * of assigning this <s>_pipe_clksrc as parent to <s>_pipe_clk.
- * Below picture shows this relationship.
- *
- * +---------------+
- * | PHY block |<<---------------------------------------+
- * | | |
- * | +-------+ | +-----+ |
- * I/P---^-->| PLL |---^--->pipe_clksrc--->| GCC |--->pipe_clk---+
- * clk | +-------+ | +-----+
- * +---------------+
- */
-static int phy_pipe_clk_register(struct qmp_usb *qmp, struct device_node *np)
-{
- struct clk_fixed_rate *fixed = &qmp->pipe_clk_fixed;
- struct clk_init_data init = { };
- int ret;
-
- ret = of_property_read_string(np, "clock-output-names", &init.name);
- if (ret) {
- dev_err(qmp->dev, "%pOFn: No clock-output-names\n", np);
- return ret;
- }
-
- init.ops = &clk_fixed_rate_ops;
-
- /* controllers using QMP phys use 125MHz pipe clock interface */
- fixed->fixed_rate = 125000000;
- fixed->hw.init = &init;
-
- ret = devm_clk_hw_register(qmp->dev, &fixed->hw);
- if (ret)
- return ret;
-
- ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &fixed->hw);
- if (ret)
- return ret;
-
- /*
- * Roll a devm action because the clock provider is the child node, but
- * the child node is not actually a device.
- */
- return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, np);
-}
-
static void __iomem *qmp_usb_iomap(struct device *dev, struct device_node *np,
int index, bool exclusive)
{
@@ -2276,7 +2218,7 @@ static int qmp_usb_probe(struct platform_device *pdev)
*/
pm_runtime_forbid(dev);
- ret = phy_pipe_clk_register(qmp, np);
+ ret = devm_qmp_register_pipe_clock_provider(dev, np);
if (ret)
goto err_node_put;
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
index 5e7fcb26744a4401c3076960df9c0dcbec7fdef7..83f3011a93c0cd53f59a1a45406bf4d9107e7ea9 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
@@ -347,8 +347,6 @@ struct qmp_usbc {
struct phy *phy;
- struct clk_fixed_rate pipe_clk_fixed;
-
struct typec_switch_dev *sw;
enum typec_orientation orientation;
};
@@ -796,62 +794,6 @@ static int qmp_usbc_clk_init(struct qmp_usbc *qmp)
return devm_clk_bulk_get_optional(dev, num, qmp->clks);
}
-static void phy_clk_release_provider(void *res)
-{
- of_clk_del_provider(res);
-}
-
-/*
- * Register a fixed rate pipe clock.
- *
- * The <s>_pipe_clksrc generated by PHY goes to the GCC that gate
- * controls it. The <s>_pipe_clk coming out of the GCC is requested
- * by the PHY driver for its operations.
- * We register the <s>_pipe_clksrc here. The gcc driver takes care
- * of assigning this <s>_pipe_clksrc as parent to <s>_pipe_clk.
- * Below picture shows this relationship.
- *
- * +---------------+
- * | PHY block |<<---------------------------------------+
- * | | |
- * | +-------+ | +-----+ |
- * I/P---^-->| PLL |---^--->pipe_clksrc--->| GCC |--->pipe_clk---+
- * clk | +-------+ | +-----+
- * +---------------+
- */
-static int phy_pipe_clk_register(struct qmp_usbc *qmp, struct device_node *np)
-{
- struct clk_fixed_rate *fixed = &qmp->pipe_clk_fixed;
- struct clk_init_data init = { };
- int ret;
-
- ret = of_property_read_string(np, "clock-output-names", &init.name);
- if (ret) {
- dev_err(qmp->dev, "%pOFn: No clock-output-names\n", np);
- return ret;
- }
-
- init.ops = &clk_fixed_rate_ops;
-
- /* controllers using QMP phys use 125MHz pipe clock interface */
- fixed->fixed_rate = 125000000;
- fixed->hw.init = &init;
-
- ret = devm_clk_hw_register(qmp->dev, &fixed->hw);
- if (ret)
- return ret;
-
- ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &fixed->hw);
- if (ret)
- return ret;
-
- /*
- * Roll a devm action because the clock provider is the child node, but
- * the child node is not actually a device.
- */
- return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, np);
-}
-
#if IS_ENABLED(CONFIG_TYPEC)
static int qmp_usbc_typec_switch_set(struct typec_switch_dev *sw,
enum typec_orientation orientation)
@@ -1093,7 +1035,7 @@ static int qmp_usbc_probe(struct platform_device *pdev)
*/
pm_runtime_forbid(dev);
- ret = phy_pipe_clk_register(qmp, np);
+ ret = devm_qmp_register_pipe_clock_provider(dev, np);
if (ret)
goto err_node_put;
--
2.47.3
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 3/4] phy: qcom: qmp-pcie: simplify AUX clock registration
2025-09-07 14:52 [PATCH 0/4] phy: qcom: extract common clock-handling code Dmitry Baryshkov
2025-09-07 14:52 ` [PATCH 1/4] phy: qcom: qmp-usb-legacy: switch to common helpers Dmitry Baryshkov
2025-09-07 14:52 ` [PATCH 2/4] phy: qcom: qmp: extract common PIPE clock helpers Dmitry Baryshkov
@ 2025-09-07 14:52 ` Dmitry Baryshkov
2025-09-08 8:31 ` Konrad Dybcio
2025-09-07 14:52 ` [PATCH 4/4] phy: qcom: extract common code for DP clocks Dmitry Baryshkov
3 siblings, 1 reply; 9+ messages in thread
From: Dmitry Baryshkov @ 2025-09-07 14:52 UTC (permalink / raw)
To: Vinod Koul, Kishon Vijay Abraham I; +Cc: linux-arm-msm, linux-phy, linux-kernel
Instead of hand-coding it, use devm_clk_hw_register_fixed_rate() to
register the PHY AUX clock.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 16 +++++-----------
1 file changed, 5 insertions(+), 11 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index dad44cc0648355fc1533c9afd176b7d37cfa9018..a81facec7e45304f26ca3ce165af90aa5ff56f4e 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -3173,7 +3173,7 @@ struct qmp_pcie {
int mode;
struct clk_hw *pipe_clk_hw;
- struct clk_fixed_rate aux_clk_fixed;
+ struct clk_hw *aux_clk_hw;
};
static bool qphy_checkbits(const void __iomem *base, u32 offset, u32 val)
@@ -4809,19 +4809,13 @@ static int qmp_pcie_clk_init(struct qmp_pcie *qmp)
*/
static int phy_aux_clk_register(struct qmp_pcie *qmp, struct device_node *np)
{
- struct clk_fixed_rate *fixed = &qmp->aux_clk_fixed;
- struct clk_init_data init = { };
char name[64];
snprintf(name, sizeof(name), "%s::phy_aux_clk", dev_name(qmp->dev));
- init.name = name;
- init.ops = &clk_fixed_rate_ops;
-
- fixed->fixed_rate = qmp->cfg->aux_clock_rate;
- fixed->hw.init = &init;
-
- return devm_clk_hw_register(qmp->dev, &fixed->hw);
+ qmp->aux_clk_hw = devm_clk_hw_register_fixed_rate(qmp->dev, name, NULL, 0,
+ qmp->cfg->aux_clock_rate);
+ return PTR_ERR_OR_ZERO(qmp->aux_clk_hw);
}
static struct clk_hw *qmp_pcie_clk_hw_get(struct of_phandle_args *clkspec, void *data)
@@ -4836,7 +4830,7 @@ static struct clk_hw *qmp_pcie_clk_hw_get(struct of_phandle_args *clkspec, void
case QMP_PCIE_PIPE_CLK:
return qmp->pipe_clk_hw;
case QMP_PCIE_PHY_AUX_CLK:
- return &qmp->aux_clk_fixed.hw;
+ return qmp->aux_clk_hw;
}
return ERR_PTR(-EINVAL);
--
2.47.3
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 4/4] phy: qcom: extract common code for DP clocks
2025-09-07 14:52 [PATCH 0/4] phy: qcom: extract common clock-handling code Dmitry Baryshkov
` (2 preceding siblings ...)
2025-09-07 14:52 ` [PATCH 3/4] phy: qcom: qmp-pcie: simplify AUX clock registration Dmitry Baryshkov
@ 2025-09-07 14:52 ` Dmitry Baryshkov
2025-09-09 8:47 ` Konrad Dybcio
3 siblings, 1 reply; 9+ messages in thread
From: Dmitry Baryshkov @ 2025-09-07 14:52 UTC (permalink / raw)
To: Vinod Koul, Kishon Vijay Abraham I; +Cc: linux-arm-msm, linux-phy, linux-kernel
The combo QMP PHY and eDP PHY share DP clocks implementation. With the
USBC PHY gaining DP support it is going to get yet another copy of the
same code.
Extract common DP clock implementation to a separate module. In future
we might want to extract more common functions.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/phy/qualcomm/Kconfig | 8 ++
drivers/phy/qualcomm/Makefile | 1 +
drivers/phy/qualcomm/phy-qcom-dp-common.c | 164 ++++++++++++++++++++++++++
drivers/phy/qualcomm/phy-qcom-dp-common.h | 22 ++++
drivers/phy/qualcomm/phy-qcom-edp.c | 181 ++++------------------------
drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 188 +++---------------------------
6 files changed, 234 insertions(+), 330 deletions(-)
diff --git a/drivers/phy/qualcomm/Kconfig b/drivers/phy/qualcomm/Kconfig
index 60a0ead127fa9f08749e1bc686e15cc5eb341c28..a4da90124f57cf6260d24e1dd45033cfdfbeb087 100644
--- a/drivers/phy/qualcomm/Kconfig
+++ b/drivers/phy/qualcomm/Kconfig
@@ -18,12 +18,19 @@ config PHY_QCOM_APQ8064_SATA
depends on OF
select GENERIC_PHY
+config PHY_QCOM_DP_COMMON
+ tristate
+ help
+ A library implementation of DP / eDP functions common to all Qualcomm
+ DisplayPort / eDP PHYs
+
config PHY_QCOM_EDP
tristate "Qualcomm eDP PHY driver"
depends on ARCH_QCOM || COMPILE_TEST
depends on OF
depends on COMMON_CLK
select GENERIC_PHY
+ select PHY_QCOM_DP_COMMON
help
Enable this driver to support the Qualcomm eDP PHY found in various
Qualcomm chipsets.
@@ -64,6 +71,7 @@ config PHY_QCOM_QMP_COMBO
select GENERIC_PHY
select MFD_SYSCON
select DRM_AUX_BRIDGE if DRM_BRIDGE
+ select PHY_QCOM_DP_COMMON
help
Enable this to support the QMP Combo PHY transceiver that is used
with USB3 and DisplayPort controllers on Qualcomm chips.
diff --git a/drivers/phy/qualcomm/Makefile b/drivers/phy/qualcomm/Makefile
index b71a6a0bed3f1489b1d07664ecd728f1db145986..1491348ed2139481634f8a540964194485126eb5 100644
--- a/drivers/phy/qualcomm/Makefile
+++ b/drivers/phy/qualcomm/Makefile
@@ -2,6 +2,7 @@
obj-$(CONFIG_PHY_ATH79_USB) += phy-ath79-usb.o
obj-$(CONFIG_PHY_QCOM_APQ8064_SATA) += phy-qcom-apq8064-sata.o
obj-$(CONFIG_PHY_QCOM_EDP) += phy-qcom-edp.o
+obj-$(CONFIG_PHY_QCOM_DP_COMMON) += phy-qcom-dp-common.o
obj-$(CONFIG_PHY_QCOM_IPQ4019_USB) += phy-qcom-ipq4019-usb.o
obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA) += phy-qcom-ipq806x-sata.o
obj-$(CONFIG_PHY_QCOM_M31_USB) += phy-qcom-m31.o
diff --git a/drivers/phy/qualcomm/phy-qcom-dp-common.c b/drivers/phy/qualcomm/phy-qcom-dp-common.c
new file mode 100644
index 0000000000000000000000000000000000000000..601f7bed956759367d1ebac8b24444f09b9e9e96
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-dp-common.c
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2017, 2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021, Linaro Ltd.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/device.h>
+#include <linux/module.h>
+
+#include "phy-qcom-dp-common.h"
+
+/*
+ * Display Port PLL driver block diagram for branch clocks
+ *
+ * +------------------------------+
+ * | DP_VCO_CLK |
+ * | |
+ * | +-------------------+ |
+ * | | (DP PLL/VCO) | |
+ * | +---------+---------+ |
+ * | v |
+ * | +----------+-----------+ |
+ * | | hsclk_divsel_clk_src | |
+ * | +----------+-----------+ |
+ * +------------------------------+
+ * |
+ * +---------<---------v------------>----------+
+ * | |
+ * +--------v----------------+ |
+ * | dp_phy_pll_link_clk | |
+ * | link_clk | |
+ * +--------+----------------+ |
+ * | |
+ * | |
+ * v v
+ * Input to DISPCC block |
+ * for link clk, crypto clk |
+ * and interface clock |
+ * |
+ * |
+ * +--------<------------+-----------------+---<---+
+ * | | |
+ * +----v---------+ +--------v-----+ +--------v------+
+ * | vco_divided | | vco_divided | | vco_divided |
+ * | _clk_src | | _clk_src | | _clk_src |
+ * | | | | | |
+ * |divsel_six | | divsel_two | | divsel_four |
+ * +-------+------+ +-----+--------+ +--------+------+
+ * | | |
+ * v---->----------v-------------<------v
+ * |
+ * +----------+-----------------+
+ * | dp_phy_pll_vco_div_clk |
+ * +---------+------------------+
+ * |
+ * v
+ * Input to DISPCC block
+ * for DP pixel clock
+ *
+ */
+static int qmp_dp_pixel_clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
+{
+ switch (req->rate) {
+ case 1620000000UL / 2:
+ case 2700000000UL / 2:
+ /* 5.4 and 8.1 GHz are same link rate as 2.7GHz, i.e. div 4 and div 6 */
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
+static unsigned long qmp_dp_pixel_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+ const struct qcom_dp_common *common;
+ const struct phy_configure_opts_dp *dp_opts;
+
+ common = container_of(hw, struct qcom_dp_common, pixel_hw);
+ dp_opts = &common->dp_opts;
+
+ switch (dp_opts->link_rate) {
+ case 1620:
+ return 1620000000UL / 2;
+ case 2700:
+ return 2700000000UL / 2;
+ case 5400:
+ return 5400000000UL / 4;
+ case 8100:
+ return 8100000000UL / 6;
+ default:
+ return 0;
+ }
+}
+
+static const struct clk_ops qmp_dp_pixel_clk_ops = {
+ .determine_rate = qmp_dp_pixel_clk_determine_rate,
+ .recalc_rate = qmp_dp_pixel_clk_recalc_rate,
+};
+
+static int qmp_dp_link_clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
+{
+ switch (req->rate) {
+ case 162000000:
+ case 270000000:
+ case 540000000:
+ case 810000000:
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
+static unsigned long qmp_dp_link_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+ const struct qcom_dp_common *common;
+ const struct phy_configure_opts_dp *dp_opts;
+
+ common = container_of(hw, struct qcom_dp_common, link_hw);
+ dp_opts = &common->dp_opts;
+
+ switch (dp_opts->link_rate) {
+ case 1620:
+ case 2700:
+ case 5400:
+ case 8100:
+ return dp_opts->link_rate * 100000;
+ default:
+ return 0;
+ }
+}
+
+static const struct clk_ops qmp_dp_link_clk_ops = {
+ .determine_rate = qmp_dp_link_clk_determine_rate,
+ .recalc_rate = qmp_dp_link_clk_recalc_rate,
+};
+
+int devm_qcom_dp_clks_register(struct device *dev,
+ struct qcom_dp_common *dp)
+{
+ struct clk_init_data init = { };
+ char name[64];
+ int ret;
+
+ snprintf(name, sizeof(name), "%s::link_clk", dev_name(dev));
+ init.ops = &qmp_dp_link_clk_ops;
+ init.name = name;
+ dp->link_hw.init = &init;
+ ret = devm_clk_hw_register(dev, &dp->link_hw);
+ if (ret)
+ return ret;
+
+ snprintf(name, sizeof(name), "%s::vco_div_clk", dev_name(dev));
+ init.ops = &qmp_dp_pixel_clk_ops;
+ init.name = name;
+ dp->pixel_hw.init = &init;
+ ret = devm_clk_hw_register(dev, &dp->pixel_hw);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(devm_qcom_dp_clks_register);
diff --git a/drivers/phy/qualcomm/phy-qcom-dp-common.h b/drivers/phy/qualcomm/phy-qcom-dp-common.h
new file mode 100644
index 0000000000000000000000000000000000000000..3d176aafa243176b9f6f92c6e18519f53564efb2
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-dp-common.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#ifndef PHY_QCOM_QMP_DP_COMMON_H
+#define PHY_QCOM_QMP_DP_COMMON_H
+
+#include <linux/clk-provider.h>
+#include <linux/phy/phy-dp.h>
+
+struct qcom_dp_common {
+ struct phy_configure_opts_dp dp_opts;
+ struct clk_hw link_hw;
+ struct clk_hw pixel_hw;
+};
+
+int devm_qcom_dp_clks_register(struct device *dev,
+ struct qcom_dp_common *dp);
+
+#endif
diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c
index f1b51018683d51df064f60440864c6031638670c..bf456b45bf8608127c7e702ab70ee8312f296af4 100644
--- a/drivers/phy/qualcomm/phy-qcom-edp.c
+++ b/drivers/phy/qualcomm/phy-qcom-edp.c
@@ -22,6 +22,8 @@
#include <dt-bindings/phy/phy.h>
+#include "phy-qcom-dp-common.h"
+
#include "phy-qcom-qmp-dp-phy.h"
#include "phy-qcom-qmp-qserdes-com-v4.h"
#include "phy-qcom-qmp-qserdes-com-v6.h"
@@ -98,10 +100,7 @@ struct qcom_edp {
void __iomem *tx1;
void __iomem *pll;
- struct clk_hw dp_link_hw;
- struct clk_hw dp_pixel_hw;
-
- struct phy_configure_opts_dp dp_opts;
+ struct qcom_dp_common dp_common;
struct clk_bulk_data clks[2];
struct regulator_bulk_data supplies[2];
@@ -318,7 +317,7 @@ static int qcom_edp_phy_configure(struct phy *phy, union phy_configure_opts *opt
struct qcom_edp *edp = phy_get_drvdata(phy);
int ret = 0;
- memcpy(&edp->dp_opts, dp_opts, sizeof(*dp_opts));
+ memcpy(&edp->dp_common.dp_opts, dp_opts, sizeof(*dp_opts));
if (dp_opts->set_voltages)
ret = qcom_edp_set_voltages(edp, dp_opts);
@@ -338,7 +337,7 @@ static int qcom_edp_configure_pll(const struct qcom_edp *edp)
static int qcom_edp_set_vco_div(const struct qcom_edp *edp, unsigned long *pixel_freq)
{
- const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
+ const struct phy_configure_opts_dp *dp_opts = &edp->dp_common.dp_opts;
u32 vco_div;
switch (dp_opts->link_rate) {
@@ -406,7 +405,7 @@ static int qcom_edp_com_bias_en_clkbuflr_v4(const struct qcom_edp *edp)
static int qcom_edp_com_configure_ssc_v4(const struct qcom_edp *edp)
{
- const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
+ const struct phy_configure_opts_dp *dp_opts = &edp->dp_common.dp_opts;
u32 step1;
u32 step2;
@@ -440,7 +439,7 @@ static int qcom_edp_com_configure_ssc_v4(const struct qcom_edp *edp)
static int qcom_edp_com_configure_pll_v4(const struct qcom_edp *edp)
{
- const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
+ const struct phy_configure_opts_dp *dp_opts = &edp->dp_common.dp_opts;
u32 div_frac_start2_mode0;
u32 div_frac_start3_mode0;
u32 dec_start_mode0;
@@ -591,7 +590,7 @@ static int qcom_edp_com_bias_en_clkbuflr_v6(const struct qcom_edp *edp)
static int qcom_edp_com_configure_ssc_v6(const struct qcom_edp *edp)
{
- const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
+ const struct phy_configure_opts_dp *dp_opts = &edp->dp_common.dp_opts;
u32 step1;
u32 step2;
@@ -625,7 +624,7 @@ static int qcom_edp_com_configure_ssc_v6(const struct qcom_edp *edp)
static int qcom_edp_com_configure_pll_v6(const struct qcom_edp *edp)
{
- const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
+ const struct phy_configure_opts_dp *dp_opts = &edp->dp_common.dp_opts;
u32 div_frac_start2_mode0;
u32 div_frac_start3_mode0;
u32 dec_start_mode0;
@@ -758,7 +757,7 @@ static int qcom_edp_phy_power_on(struct phy *phy)
writel(0x00, edp->tx0 + TXn_LANE_MODE_1);
writel(0x00, edp->tx1 + TXn_LANE_MODE_1);
- if (edp->dp_opts.ssc) {
+ if (edp->dp_common.dp_opts.ssc) {
ret = qcom_edp_configure_ssc(edp);
if (ret)
return ret;
@@ -818,13 +817,13 @@ static int qcom_edp_phy_power_on(struct phy *phy)
writel(0x1f, edp->tx0 + TXn_TX_DRV_LVL);
writel(0x1f, edp->tx1 + TXn_TX_DRV_LVL);
- if (edp->dp_opts.lanes == 1) {
+ if (edp->dp_common.dp_opts.lanes == 1) {
bias0_en = 0x01;
bias1_en = 0x00;
drvr0_en = 0x06;
drvr1_en = 0x07;
cfg1 = 0x1;
- } else if (edp->dp_opts.lanes == 2) {
+ } else if (edp->dp_common.dp_opts.lanes == 2) {
bias0_en = 0x03;
bias1_en = 0x00;
drvr0_en = 0x04;
@@ -854,8 +853,8 @@ static int qcom_edp_phy_power_on(struct phy *phy)
if (ret)
return ret;
- clk_set_rate(edp->dp_link_hw.clk, edp->dp_opts.link_rate * 100000);
- clk_set_rate(edp->dp_pixel_hw.clk, pixel_freq);
+ clk_set_rate(edp->dp_common.link_hw.clk, edp->dp_common.dp_opts.link_rate * 100000);
+ clk_set_rate(edp->dp_common.pixel_hw.clk, pixel_freq);
return 0;
}
@@ -901,162 +900,22 @@ static const struct phy_ops qcom_edp_ops = {
.owner = THIS_MODULE,
};
-/*
- * Embedded Display Port PLL driver block diagram for branch clocks
- *
- * +------------------------------+
- * | EDP_VCO_CLK |
- * | |
- * | +-------------------+ |
- * | | (EDP PLL/VCO) | |
- * | +---------+---------+ |
- * | v |
- * | +----------+-----------+ |
- * | | hsclk_divsel_clk_src | |
- * | +----------+-----------+ |
- * +------------------------------+
- * |
- * +---------<---------v------------>----------+
- * | |
- * +--------v----------------+ |
- * | edp_phy_pll_link_clk | |
- * | link_clk | |
- * +--------+----------------+ |
- * | |
- * | |
- * v v
- * Input to DISPCC block |
- * for link clk, crypto clk |
- * and interface clock |
- * |
- * |
- * +--------<------------+-----------------+---<---+
- * | | |
- * +----v---------+ +--------v-----+ +--------v------+
- * | vco_divided | | vco_divided | | vco_divided |
- * | _clk_src | | _clk_src | | _clk_src |
- * | | | | | |
- * |divsel_six | | divsel_two | | divsel_four |
- * +-------+------+ +-----+--------+ +--------+------+
- * | | |
- * v---->----------v-------------<------v
- * |
- * +----------+-----------------+
- * | edp_phy_pll_vco_div_clk |
- * +---------+------------------+
- * |
- * v
- * Input to DISPCC block
- * for EDP pixel clock
- *
- */
-static int qcom_edp_dp_pixel_clk_determine_rate(struct clk_hw *hw,
- struct clk_rate_request *req)
-{
- switch (req->rate) {
- case 1620000000UL / 2:
- case 2700000000UL / 2:
- /* 5.4 and 8.1 GHz are same link rate as 2.7GHz, i.e. div 4 and div 6 */
- return 0;
-
- default:
- return -EINVAL;
- }
-}
-
-static unsigned long
-qcom_edp_dp_pixel_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
-{
- const struct qcom_edp *edp = container_of(hw, struct qcom_edp, dp_pixel_hw);
- const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
-
- switch (dp_opts->link_rate) {
- case 1620:
- return 1620000000UL / 2;
- case 2700:
- return 2700000000UL / 2;
- case 5400:
- return 5400000000UL / 4;
- case 8100:
- return 8100000000UL / 6;
- default:
- return 0;
- }
-}
-
-static const struct clk_ops qcom_edp_dp_pixel_clk_ops = {
- .determine_rate = qcom_edp_dp_pixel_clk_determine_rate,
- .recalc_rate = qcom_edp_dp_pixel_clk_recalc_rate,
-};
-
-static int qcom_edp_dp_link_clk_determine_rate(struct clk_hw *hw,
- struct clk_rate_request *req)
-{
- switch (req->rate) {
- case 162000000:
- case 270000000:
- case 540000000:
- case 810000000:
- return 0;
-
- default:
- return -EINVAL;
- }
-}
-
-static unsigned long
-qcom_edp_dp_link_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
-{
- const struct qcom_edp *edp = container_of(hw, struct qcom_edp, dp_link_hw);
- const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
-
- switch (dp_opts->link_rate) {
- case 1620:
- case 2700:
- case 5400:
- case 8100:
- return dp_opts->link_rate * 100000;
-
- default:
- return 0;
- }
-}
-
-static const struct clk_ops qcom_edp_dp_link_clk_ops = {
- .determine_rate = qcom_edp_dp_link_clk_determine_rate,
- .recalc_rate = qcom_edp_dp_link_clk_recalc_rate,
-};
-
static int qcom_edp_clks_register(struct qcom_edp *edp, struct device_node *np)
{
struct clk_hw_onecell_data *data;
- struct clk_init_data init = { };
- char name[64];
int ret;
+ ret = devm_qcom_dp_clks_register(edp->dev, &edp->dp_common);
+ if (ret)
+ return ret;
+
data = devm_kzalloc(edp->dev, struct_size(data, hws, 2), GFP_KERNEL);
if (!data)
return -ENOMEM;
data->num = 2;
- snprintf(name, sizeof(name), "%s::link_clk", dev_name(edp->dev));
- init.ops = &qcom_edp_dp_link_clk_ops;
- init.name = name;
- edp->dp_link_hw.init = &init;
- ret = devm_clk_hw_register(edp->dev, &edp->dp_link_hw);
- if (ret)
- return ret;
-
- snprintf(name, sizeof(name), "%s::vco_div_clk", dev_name(edp->dev));
- init.ops = &qcom_edp_dp_pixel_clk_ops;
- init.name = name;
- edp->dp_pixel_hw.init = &init;
- ret = devm_clk_hw_register(edp->dev, &edp->dp_pixel_hw);
- if (ret)
- return ret;
-
- data->hws[0] = &edp->dp_link_hw;
- data->hws[1] = &edp->dp_pixel_hw;
+ data->hws[0] = &edp->dp_common.link_hw;
+ data->hws[1] = &edp->dp_common.pixel_hw;
return devm_of_clk_add_hw_provider(edp->dev, of_clk_hw_onecell_get, data);
}
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
index baf25ae442478ac01a5428fa4268470e6b5211e3..8b6a27464b3303eb0d66b97f7d7cfb10687821e4 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
@@ -26,6 +26,8 @@
#include <dt-bindings/phy/phy-qcom-qmp.h>
+#include "phy-qcom-dp-common.h"
+
#include "phy-qcom-qmp-common.h"
#include "phy-qcom-qmp.h"
@@ -1859,13 +1861,11 @@ struct qmp_combo {
struct phy *dp_phy;
unsigned int dp_aux_cfg;
- struct phy_configure_opts_dp dp_opts;
unsigned int dp_init_count;
bool dp_powered_on;
struct clk_hw *pipe_clk_hw;
- struct clk_hw dp_link_hw;
- struct clk_hw dp_pixel_hw;
+ struct qcom_dp_common dp_common;
struct typec_switch_dev *sw;
enum typec_orientation orientation;
@@ -2515,7 +2515,7 @@ static int qmp_combo_dp_serdes_init(struct qmp_combo *qmp)
{
const struct qmp_phy_cfg *cfg = qmp->cfg;
void __iomem *serdes = qmp->dp_serdes;
- const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts;
+ const struct phy_configure_opts_dp *dp_opts = &qmp->dp_common.dp_opts;
qmp_configure(qmp->dev, serdes, cfg->dp_serdes_tbl,
cfg->dp_serdes_tbl_num);
@@ -2592,7 +2592,7 @@ static void qmp_v3_dp_aux_init(struct qmp_combo *qmp)
static int qmp_combo_configure_dp_swing(struct qmp_combo *qmp)
{
- const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts;
+ const struct phy_configure_opts_dp *dp_opts = &qmp->dp_common.dp_opts;
const struct qmp_phy_cfg *cfg = qmp->cfg;
unsigned int v_level = 0, p_level = 0;
u8 voltage_swing_cfg, pre_emphasis_cfg;
@@ -2629,7 +2629,7 @@ static int qmp_combo_configure_dp_swing(struct qmp_combo *qmp)
static void qmp_v3_configure_dp_tx(struct qmp_combo *qmp)
{
- const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts;
+ const struct phy_configure_opts_dp *dp_opts = &qmp->dp_common.dp_opts;
u32 bias_en, drvr_en;
if (qmp_combo_configure_dp_swing(qmp) < 0)
@@ -2652,7 +2652,7 @@ static void qmp_v3_configure_dp_tx(struct qmp_combo *qmp)
static bool qmp_combo_configure_dp_mode(struct qmp_combo *qmp)
{
bool reverse = (qmp->orientation == TYPEC_ORIENTATION_REVERSE);
- const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts;
+ const struct phy_configure_opts_dp *dp_opts = &qmp->dp_common.dp_opts;
u32 val;
val = DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
@@ -2675,7 +2675,7 @@ static bool qmp_combo_configure_dp_mode(struct qmp_combo *qmp)
static int qmp_combo_configure_dp_clocks(struct qmp_combo *qmp)
{
- const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts;
+ const struct phy_configure_opts_dp *dp_opts = &qmp->dp_common.dp_opts;
u32 phy_vco_div;
unsigned long pixel_freq;
const struct qmp_phy_cfg *cfg = qmp->cfg;
@@ -2703,8 +2703,8 @@ static int qmp_combo_configure_dp_clocks(struct qmp_combo *qmp)
}
writel(phy_vco_div, qmp->dp_dp_phy + cfg->regs[QPHY_DP_PHY_VCO_DIV]);
- clk_set_rate(qmp->dp_link_hw.clk, dp_opts->link_rate * 100000);
- clk_set_rate(qmp->dp_pixel_hw.clk, pixel_freq);
+ clk_set_rate(qmp->dp_common.link_hw.clk, dp_opts->link_rate * 100000);
+ clk_set_rate(qmp->dp_common.pixel_hw.clk, pixel_freq);
return 0;
}
@@ -2891,7 +2891,7 @@ static int qmp_v4_configure_dp_phy(struct qmp_combo *qmp)
{
const struct qmp_phy_cfg *cfg = qmp->cfg;
bool reverse = (qmp->orientation == TYPEC_ORIENTATION_REVERSE);
- const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts;
+ const struct phy_configure_opts_dp *dp_opts = &qmp->dp_common.dp_opts;
u32 bias0_en, drvr0_en, bias1_en, drvr1_en;
u32 status;
int ret;
@@ -2976,10 +2976,10 @@ static int qmp_combo_dp_configure(struct phy *phy, union phy_configure_opts *opt
mutex_lock(&qmp->phy_mutex);
- memcpy(&qmp->dp_opts, dp_opts, sizeof(*dp_opts));
- if (qmp->dp_opts.set_voltages) {
+ memcpy(&qmp->dp_common.dp_opts, dp_opts, sizeof(*dp_opts));
+ if (qmp->dp_common.dp_opts.set_voltages) {
cfg->configure_dp_tx(qmp);
- qmp->dp_opts.set_voltages = 0;
+ qmp->dp_common.dp_opts.set_voltages = 0;
}
mutex_unlock(&qmp->phy_mutex);
@@ -3512,131 +3512,6 @@ static int qmp_combo_clk_init(struct qmp_combo *qmp)
return devm_clk_bulk_get_optional(dev, num, qmp->clks);
}
-/*
- * Display Port PLL driver block diagram for branch clocks
- *
- * +------------------------------+
- * | DP_VCO_CLK |
- * | |
- * | +-------------------+ |
- * | | (DP PLL/VCO) | |
- * | +---------+---------+ |
- * | v |
- * | +----------+-----------+ |
- * | | hsclk_divsel_clk_src | |
- * | +----------+-----------+ |
- * +------------------------------+
- * |
- * +---------<---------v------------>----------+
- * | |
- * +--------v----------------+ |
- * | dp_phy_pll_link_clk | |
- * | link_clk | |
- * +--------+----------------+ |
- * | |
- * | |
- * v v
- * Input to DISPCC block |
- * for link clk, crypto clk |
- * and interface clock |
- * |
- * |
- * +--------<------------+-----------------+---<---+
- * | | |
- * +----v---------+ +--------v-----+ +--------v------+
- * | vco_divided | | vco_divided | | vco_divided |
- * | _clk_src | | _clk_src | | _clk_src |
- * | | | | | |
- * |divsel_six | | divsel_two | | divsel_four |
- * +-------+------+ +-----+--------+ +--------+------+
- * | | |
- * v---->----------v-------------<------v
- * |
- * +----------+-----------------+
- * | dp_phy_pll_vco_div_clk |
- * +---------+------------------+
- * |
- * v
- * Input to DISPCC block
- * for DP pixel clock
- *
- */
-static int qmp_dp_pixel_clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
-{
- switch (req->rate) {
- case 1620000000UL / 2:
- case 2700000000UL / 2:
- /* 5.4 and 8.1 GHz are same link rate as 2.7GHz, i.e. div 4 and div 6 */
- return 0;
- default:
- return -EINVAL;
- }
-}
-
-static unsigned long qmp_dp_pixel_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
-{
- const struct qmp_combo *qmp;
- const struct phy_configure_opts_dp *dp_opts;
-
- qmp = container_of(hw, struct qmp_combo, dp_pixel_hw);
- dp_opts = &qmp->dp_opts;
-
- switch (dp_opts->link_rate) {
- case 1620:
- return 1620000000UL / 2;
- case 2700:
- return 2700000000UL / 2;
- case 5400:
- return 5400000000UL / 4;
- case 8100:
- return 8100000000UL / 6;
- default:
- return 0;
- }
-}
-
-static const struct clk_ops qmp_dp_pixel_clk_ops = {
- .determine_rate = qmp_dp_pixel_clk_determine_rate,
- .recalc_rate = qmp_dp_pixel_clk_recalc_rate,
-};
-
-static int qmp_dp_link_clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
-{
- switch (req->rate) {
- case 162000000:
- case 270000000:
- case 540000000:
- case 810000000:
- return 0;
- default:
- return -EINVAL;
- }
-}
-
-static unsigned long qmp_dp_link_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
-{
- const struct qmp_combo *qmp;
- const struct phy_configure_opts_dp *dp_opts;
-
- qmp = container_of(hw, struct qmp_combo, dp_link_hw);
- dp_opts = &qmp->dp_opts;
-
- switch (dp_opts->link_rate) {
- case 1620:
- case 2700:
- case 5400:
- case 8100:
- return dp_opts->link_rate * 100000;
- default:
- return 0;
- }
-}
-
-static const struct clk_ops qmp_dp_link_clk_ops = {
- .determine_rate = qmp_dp_link_clk_determine_rate,
- .recalc_rate = qmp_dp_link_clk_recalc_rate,
-};
-
static struct clk_hw *qmp_dp_clks_hw_get(struct of_phandle_args *clkspec, void *data)
{
struct qmp_combo *qmp = data;
@@ -3648,34 +3523,9 @@ static struct clk_hw *qmp_dp_clks_hw_get(struct of_phandle_args *clkspec, void *
}
if (idx == 0)
- return &qmp->dp_link_hw;
-
- return &qmp->dp_pixel_hw;
-}
-
-static int phy_dp_clks_register(struct qmp_combo *qmp, struct device_node *np)
-{
- struct clk_init_data init = { };
- char name[64];
- int ret;
+ return &qmp->dp_common.link_hw;
- snprintf(name, sizeof(name), "%s::link_clk", dev_name(qmp->dev));
- init.ops = &qmp_dp_link_clk_ops;
- init.name = name;
- qmp->dp_link_hw.init = &init;
- ret = devm_clk_hw_register(qmp->dev, &qmp->dp_link_hw);
- if (ret)
- return ret;
-
- snprintf(name, sizeof(name), "%s::vco_div_clk", dev_name(qmp->dev));
- init.ops = &qmp_dp_pixel_clk_ops;
- init.name = name;
- qmp->dp_pixel_hw.init = &init;
- ret = devm_clk_hw_register(qmp->dev, &qmp->dp_pixel_hw);
- if (ret)
- return ret;
-
- return 0;
+ return &qmp->dp_common.pixel_hw;
}
static struct clk_hw *qmp_combo_clk_hw_get(struct of_phandle_args *clkspec, void *data)
@@ -3686,9 +3536,9 @@ static struct clk_hw *qmp_combo_clk_hw_get(struct of_phandle_args *clkspec, void
case QMP_USB43DP_USB3_PIPE_CLK:
return qmp->pipe_clk_hw;
case QMP_USB43DP_DP_LINK_CLK:
- return &qmp->dp_link_hw;
+ return &qmp->dp_common.link_hw;
case QMP_USB43DP_DP_VCO_DIV_CLK:
- return &qmp->dp_pixel_hw;
+ return &qmp->dp_common.pixel_hw;
}
return ERR_PTR(-EINVAL);
@@ -3703,7 +3553,7 @@ static int qmp_combo_register_clocks(struct qmp_combo *qmp, struct device_node *
if (IS_ERR(qmp->pipe_clk_hw))
return PTR_ERR(qmp->pipe_clk_hw);
- ret = phy_dp_clks_register(qmp, dp_np);
+ ret = devm_qcom_dp_clks_register(qmp->dev, &qmp->dp_common);
if (ret)
return ret;
--
2.47.3
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 1/4] phy: qcom: qmp-usb-legacy: switch to common helpers
2025-09-07 14:52 ` [PATCH 1/4] phy: qcom: qmp-usb-legacy: switch to common helpers Dmitry Baryshkov
@ 2025-09-08 8:17 ` Konrad Dybcio
0 siblings, 0 replies; 9+ messages in thread
From: Konrad Dybcio @ 2025-09-08 8:17 UTC (permalink / raw)
To: Dmitry Baryshkov, Vinod Koul, Kishon Vijay Abraham I
Cc: linux-arm-msm, linux-phy, linux-kernel
On 9/7/25 4:52 PM, Dmitry Baryshkov wrote:
> Instead of having a copy of the common definitions and functions inside
> the usb-legacy PHY driver, use the phy-qcom-qmp-common.h header.
>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> ---
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Konrad
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/4] phy: qcom: qmp: extract common PIPE clock helpers
2025-09-07 14:52 ` [PATCH 2/4] phy: qcom: qmp: extract common PIPE clock helpers Dmitry Baryshkov
@ 2025-09-08 8:30 ` Konrad Dybcio
0 siblings, 0 replies; 9+ messages in thread
From: Konrad Dybcio @ 2025-09-08 8:30 UTC (permalink / raw)
To: Dmitry Baryshkov, Vinod Koul, Kishon Vijay Abraham I
Cc: linux-arm-msm, linux-phy, linux-kernel
On 9/7/25 4:52 PM, Dmitry Baryshkov wrote:
> Extract the code common to (almost) all QMP PHY drivers, which handles
> the 125 MHz PIPE clock.
The rate is a little more in depth, but:
a) it doesn't matter because Linux currently only prints it in debugfs
b) your new wrappers can be trivially expanded which I suppose I'll do in
some follow-up when that'll be useful
Thanks!
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Konrad
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 3/4] phy: qcom: qmp-pcie: simplify AUX clock registration
2025-09-07 14:52 ` [PATCH 3/4] phy: qcom: qmp-pcie: simplify AUX clock registration Dmitry Baryshkov
@ 2025-09-08 8:31 ` Konrad Dybcio
0 siblings, 0 replies; 9+ messages in thread
From: Konrad Dybcio @ 2025-09-08 8:31 UTC (permalink / raw)
To: Dmitry Baryshkov, Vinod Koul, Kishon Vijay Abraham I
Cc: linux-arm-msm, linux-phy, linux-kernel
On 9/7/25 4:52 PM, Dmitry Baryshkov wrote:
> Instead of hand-coding it, use devm_clk_hw_register_fixed_rate() to
> register the PHY AUX clock.
>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> ---
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Konrad
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 4/4] phy: qcom: extract common code for DP clocks
2025-09-07 14:52 ` [PATCH 4/4] phy: qcom: extract common code for DP clocks Dmitry Baryshkov
@ 2025-09-09 8:47 ` Konrad Dybcio
0 siblings, 0 replies; 9+ messages in thread
From: Konrad Dybcio @ 2025-09-09 8:47 UTC (permalink / raw)
To: Dmitry Baryshkov, Vinod Koul, Kishon Vijay Abraham I
Cc: linux-arm-msm, linux-phy, linux-kernel
On 9/7/25 4:52 PM, Dmitry Baryshkov wrote:
> The combo QMP PHY and eDP PHY share DP clocks implementation. With the
> USBC PHY gaining DP support it is going to get yet another copy of the
> same code.
>
> Extract common DP clock implementation to a separate module. In future
> we might want to extract more common functions.
>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> ---
[...]
> + * | | |
> + * +----v---------+ +--------v-----+ +--------v------+
> + * | vco_divided | | vco_divided | | vco_divided |
> + * | _clk_src | | _clk_src | | _clk_src |
> + * | | | | | |
> + * |divsel_six | | divsel_two | | divsel_four |
> + * +-------+------+ +-----+--------+ +--------+------+
div6 is oddly misaligned
[...]
> +static int qmp_dp_pixel_clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
> +{
> + switch (req->rate) {
> + case 1620000000UL / 2:
> + case 2700000000UL / 2:
> + /* 5.4 and 8.1 GHz are same link rate as 2.7GHz, i.e. div 4 and div 6 */
"(2.7 GHz / 2) == (5.4 GHz / 4) == (8.1 GHz / 6)"?
anyway
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Konrad
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2025-09-09 10:13 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-07 14:52 [PATCH 0/4] phy: qcom: extract common clock-handling code Dmitry Baryshkov
2025-09-07 14:52 ` [PATCH 1/4] phy: qcom: qmp-usb-legacy: switch to common helpers Dmitry Baryshkov
2025-09-08 8:17 ` Konrad Dybcio
2025-09-07 14:52 ` [PATCH 2/4] phy: qcom: qmp: extract common PIPE clock helpers Dmitry Baryshkov
2025-09-08 8:30 ` Konrad Dybcio
2025-09-07 14:52 ` [PATCH 3/4] phy: qcom: qmp-pcie: simplify AUX clock registration Dmitry Baryshkov
2025-09-08 8:31 ` Konrad Dybcio
2025-09-07 14:52 ` [PATCH 4/4] phy: qcom: extract common code for DP clocks Dmitry Baryshkov
2025-09-09 8:47 ` Konrad Dybcio
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).