* [PATCH v5 00/16] phy: qcom-qmp-pcie: add support for sc8280xp
@ 2022-11-05 14:59 Johan Hovold
2022-11-05 14:59 ` [PATCH v5 01/16] phy: qcom-qmp-pcie: sort device-id table Johan Hovold
` (16 more replies)
0 siblings, 17 replies; 19+ messages in thread
From: Johan Hovold @ 2022-11-05 14:59 UTC (permalink / raw)
To: Vinod Koul
Cc: Andy Gross, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, linux-arm-msm, linux-phy, devicetree,
linux-kernel, Johan Hovold
This series adds support for the PCIe PHYs on SC8280XP including its
four-lane PHYs.
The first half of the series clean up the driver in preparation for
supporting SC8280XP and its new devicetree bindings that drops the
legacy child node and the (incomplete) description of register
subregions.
The other QMP bindings suffer from similar problems and follow-on series
will do corresponding changes to the UFS, USB and combo QMP bindings and
drivers.
Johan
Changes in v5
- use the shorter tables identifier throughout the driver (Vinod)
Changes in v4
- break out switch to shorter tables identifier in a preparatory patch
(Vinod)
Changes in v3
- use bulk clk API for pipe clocks (Dmitry)
Changes in v2
- rename current DT schema after first SoC added to the original
bindings (IPQ8074) and add a reference to the new SC8280XP bindings
instead of marking the current bindings as "legacy" (Krzysztof)
- add "sc8280xp" infix to the new DT schema filename (Krzysztof)
- tighten description of the 'qcom,4ln-config-sel' phandle array
(Krzysztof)
Johan Hovold (16):
phy: qcom-qmp-pcie: sort device-id table
phy: qcom-qmp-pcie: move device-id table
phy: qcom-qmp-pcie: merge driver data
phy: qcom-qmp-pcie: clean up device-tree parsing
phy: qcom-qmp-pcie: clean up probe initialisation
phy: qcom-qmp-pcie: rename PHY ops structure
phy: qcom-qmp-pcie: clean up PHY lane init
phy: qcom-qmp-pcie: use shorter tables identifiers
phy: qcom-qmp-pcie: add register init helper
dt-bindings: phy: qcom,qmp-pcie: rename current bindings
dt-bindings: phy: qcom,qmp-pcie: add sc8280xp bindings
phy: qcom-qmp-pcie: restructure PHY creation
phy: qcom-qmp-pcie: fix initialisation reset
phy: qcom-qmp-pcie: add support for pipediv2 clock
phy: qcom-qmp-pcie: add support for sc8280xp
phy: qcom-qmp-pcie: add support for sc8280xp 4-lane PHYs
...hy.yaml => qcom,ipq8074-qmp-pcie-phy.yaml} | 7 +-
.../phy/qcom,sc8280xp-qmp-pcie-phy.yaml | 165 ++++
drivers/phy/qualcomm/Kconfig | 1 +
drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 874 ++++++++++++------
.../phy/qualcomm/phy-qcom-qmp-pcs-pcie-v5.h | 2 +
5 files changed, 770 insertions(+), 279 deletions(-)
rename Documentation/devicetree/bindings/phy/{qcom,qmp-pcie-phy.yaml => qcom,ipq8074-qmp-pcie-phy.yaml} (96%)
create mode 100644 Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
--
2.37.4
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v5 01/16] phy: qcom-qmp-pcie: sort device-id table
2022-11-05 14:59 [PATCH v5 00/16] phy: qcom-qmp-pcie: add support for sc8280xp Johan Hovold
@ 2022-11-05 14:59 ` Johan Hovold
2022-11-05 14:59 ` [PATCH v5 02/16] phy: qcom-qmp-pcie: move " Johan Hovold
` (15 subsequent siblings)
16 siblings, 0 replies; 19+ messages in thread
From: Johan Hovold @ 2022-11-05 14:59 UTC (permalink / raw)
To: Vinod Koul
Cc: Andy Gross, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, linux-arm-msm, linux-phy, devicetree,
linux-kernel, Johan Hovold, Dmitry Baryshkov
Sort the device-id table by compatible string to make it easier to find
and add new entries.
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
---
drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index 7c81667dd968..4e5111d19692 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -2282,17 +2282,17 @@ static int qmp_pcie_create(struct device *dev, struct device_node *np, int id,
static const struct of_device_id qmp_pcie_of_match_table[] = {
{
- .compatible = "qcom,msm8998-qmp-pcie-phy",
- .data = &msm8998_pciephy_cfg,
- }, {
- .compatible = "qcom,ipq8074-qmp-pcie-phy",
- .data = &ipq8074_pciephy_cfg,
+ .compatible = "qcom,ipq6018-qmp-pcie-phy",
+ .data = &ipq6018_pciephy_cfg,
}, {
.compatible = "qcom,ipq8074-qmp-gen3-pcie-phy",
.data = &ipq8074_pciephy_gen3_cfg,
}, {
- .compatible = "qcom,ipq6018-qmp-pcie-phy",
- .data = &ipq6018_pciephy_cfg,
+ .compatible = "qcom,ipq8074-qmp-pcie-phy",
+ .data = &ipq8074_pciephy_cfg,
+ }, {
+ .compatible = "qcom,msm8998-qmp-pcie-phy",
+ .data = &msm8998_pciephy_cfg,
}, {
.compatible = "qcom,sc8180x-qmp-pcie-phy",
.data = &sc8180x_pciephy_cfg,
@@ -2302,6 +2302,9 @@ static const struct of_device_id qmp_pcie_of_match_table[] = {
}, {
.compatible = "qcom,sdm845-qmp-pcie-phy",
.data = &sdm845_qmp_pciephy_cfg,
+ }, {
+ .compatible = "qcom,sdx55-qmp-pcie-phy",
+ .data = &sdx55_qmp_pciephy_cfg,
}, {
.compatible = "qcom,sm8250-qmp-gen3x1-pcie-phy",
.data = &sm8250_qmp_gen3x1_pciephy_cfg,
@@ -2311,9 +2314,6 @@ static const struct of_device_id qmp_pcie_of_match_table[] = {
}, {
.compatible = "qcom,sm8250-qmp-modem-pcie-phy",
.data = &sm8250_qmp_gen3x2_pciephy_cfg,
- }, {
- .compatible = "qcom,sdx55-qmp-pcie-phy",
- .data = &sdx55_qmp_pciephy_cfg,
}, {
.compatible = "qcom,sm8450-qmp-gen3x1-pcie-phy",
.data = &sm8450_qmp_gen3x1_pciephy_cfg,
--
2.37.4
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v5 02/16] phy: qcom-qmp-pcie: move device-id table
2022-11-05 14:59 [PATCH v5 00/16] phy: qcom-qmp-pcie: add support for sc8280xp Johan Hovold
2022-11-05 14:59 ` [PATCH v5 01/16] phy: qcom-qmp-pcie: sort device-id table Johan Hovold
@ 2022-11-05 14:59 ` Johan Hovold
2022-11-05 14:59 ` [PATCH v5 03/16] phy: qcom-qmp-pcie: merge driver data Johan Hovold
` (14 subsequent siblings)
16 siblings, 0 replies; 19+ messages in thread
From: Johan Hovold @ 2022-11-05 14:59 UTC (permalink / raw)
To: Vinod Koul
Cc: Andy Gross, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, linux-arm-msm, linux-phy, devicetree,
linux-kernel, Johan Hovold, Dmitry Baryshkov
Move the device-id table below probe() and next to the driver structure
to keep the driver callback functions grouped together.
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
---
drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 90 ++++++++++++------------
1 file changed, 45 insertions(+), 45 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index 4e5111d19692..e66f6adc404b 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -2280,51 +2280,6 @@ static int qmp_pcie_create(struct device *dev, struct device_node *np, int id,
return 0;
}
-static const struct of_device_id qmp_pcie_of_match_table[] = {
- {
- .compatible = "qcom,ipq6018-qmp-pcie-phy",
- .data = &ipq6018_pciephy_cfg,
- }, {
- .compatible = "qcom,ipq8074-qmp-gen3-pcie-phy",
- .data = &ipq8074_pciephy_gen3_cfg,
- }, {
- .compatible = "qcom,ipq8074-qmp-pcie-phy",
- .data = &ipq8074_pciephy_cfg,
- }, {
- .compatible = "qcom,msm8998-qmp-pcie-phy",
- .data = &msm8998_pciephy_cfg,
- }, {
- .compatible = "qcom,sc8180x-qmp-pcie-phy",
- .data = &sc8180x_pciephy_cfg,
- }, {
- .compatible = "qcom,sdm845-qhp-pcie-phy",
- .data = &sdm845_qhp_pciephy_cfg,
- }, {
- .compatible = "qcom,sdm845-qmp-pcie-phy",
- .data = &sdm845_qmp_pciephy_cfg,
- }, {
- .compatible = "qcom,sdx55-qmp-pcie-phy",
- .data = &sdx55_qmp_pciephy_cfg,
- }, {
- .compatible = "qcom,sm8250-qmp-gen3x1-pcie-phy",
- .data = &sm8250_qmp_gen3x1_pciephy_cfg,
- }, {
- .compatible = "qcom,sm8250-qmp-gen3x2-pcie-phy",
- .data = &sm8250_qmp_gen3x2_pciephy_cfg,
- }, {
- .compatible = "qcom,sm8250-qmp-modem-pcie-phy",
- .data = &sm8250_qmp_gen3x2_pciephy_cfg,
- }, {
- .compatible = "qcom,sm8450-qmp-gen3x1-pcie-phy",
- .data = &sm8450_qmp_gen3x1_pciephy_cfg,
- }, {
- .compatible = "qcom,sm8450-qmp-gen4x2-pcie-phy",
- .data = &sm8450_qmp_gen4x2_pciephy_cfg,
- },
- { },
-};
-MODULE_DEVICE_TABLE(of, qmp_pcie_of_match_table);
-
static int qmp_pcie_probe(struct platform_device *pdev)
{
struct qcom_qmp *qmp;
@@ -2408,6 +2363,51 @@ static int qmp_pcie_probe(struct platform_device *pdev)
return ret;
}
+static const struct of_device_id qmp_pcie_of_match_table[] = {
+ {
+ .compatible = "qcom,ipq6018-qmp-pcie-phy",
+ .data = &ipq6018_pciephy_cfg,
+ }, {
+ .compatible = "qcom,ipq8074-qmp-gen3-pcie-phy",
+ .data = &ipq8074_pciephy_gen3_cfg,
+ }, {
+ .compatible = "qcom,ipq8074-qmp-pcie-phy",
+ .data = &ipq8074_pciephy_cfg,
+ }, {
+ .compatible = "qcom,msm8998-qmp-pcie-phy",
+ .data = &msm8998_pciephy_cfg,
+ }, {
+ .compatible = "qcom,sc8180x-qmp-pcie-phy",
+ .data = &sc8180x_pciephy_cfg,
+ }, {
+ .compatible = "qcom,sdm845-qhp-pcie-phy",
+ .data = &sdm845_qhp_pciephy_cfg,
+ }, {
+ .compatible = "qcom,sdm845-qmp-pcie-phy",
+ .data = &sdm845_qmp_pciephy_cfg,
+ }, {
+ .compatible = "qcom,sdx55-qmp-pcie-phy",
+ .data = &sdx55_qmp_pciephy_cfg,
+ }, {
+ .compatible = "qcom,sm8250-qmp-gen3x1-pcie-phy",
+ .data = &sm8250_qmp_gen3x1_pciephy_cfg,
+ }, {
+ .compatible = "qcom,sm8250-qmp-gen3x2-pcie-phy",
+ .data = &sm8250_qmp_gen3x2_pciephy_cfg,
+ }, {
+ .compatible = "qcom,sm8250-qmp-modem-pcie-phy",
+ .data = &sm8250_qmp_gen3x2_pciephy_cfg,
+ }, {
+ .compatible = "qcom,sm8450-qmp-gen3x1-pcie-phy",
+ .data = &sm8450_qmp_gen3x1_pciephy_cfg,
+ }, {
+ .compatible = "qcom,sm8450-qmp-gen4x2-pcie-phy",
+ .data = &sm8450_qmp_gen4x2_pciephy_cfg,
+ },
+ { },
+};
+MODULE_DEVICE_TABLE(of, qmp_pcie_of_match_table);
+
static struct platform_driver qmp_pcie_driver = {
.probe = qmp_pcie_probe,
.driver = {
--
2.37.4
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v5 03/16] phy: qcom-qmp-pcie: merge driver data
2022-11-05 14:59 [PATCH v5 00/16] phy: qcom-qmp-pcie: add support for sc8280xp Johan Hovold
2022-11-05 14:59 ` [PATCH v5 01/16] phy: qcom-qmp-pcie: sort device-id table Johan Hovold
2022-11-05 14:59 ` [PATCH v5 02/16] phy: qcom-qmp-pcie: move " Johan Hovold
@ 2022-11-05 14:59 ` Johan Hovold
2022-11-05 14:59 ` [PATCH v5 04/16] phy: qcom-qmp-pcie: clean up device-tree parsing Johan Hovold
` (13 subsequent siblings)
16 siblings, 0 replies; 19+ messages in thread
From: Johan Hovold @ 2022-11-05 14:59 UTC (permalink / raw)
To: Vinod Koul
Cc: Andy Gross, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, linux-arm-msm, linux-phy, devicetree,
linux-kernel, Johan Hovold, Dmitry Baryshkov
The PCIe QMP PHY driver only manages a single PHY so merge the old
qcom_qmp and qmp_phy structures and drop the PHY array.
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
---
drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 218 +++++++++--------------
1 file changed, 88 insertions(+), 130 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index e66f6adc404b..667a87e7c917 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -1365,56 +1365,26 @@ struct qmp_phy_cfg {
unsigned long pipe_clock_rate;
};
-/**
- * struct qmp_phy - per-lane phy descriptor
- *
- * @phy: generic phy
- * @cfg: phy specific configuration
- * @serdes: iomapped memory space for phy's serdes (i.e. PLL)
- * @tx: iomapped memory space for lane's tx
- * @rx: iomapped memory space for lane's rx
- * @pcs: iomapped memory space for lane's pcs
- * @tx2: iomapped memory space for second lane's tx (in dual lane PHYs)
- * @rx2: iomapped memory space for second lane's rx (in dual lane PHYs)
- * @pcs_misc: iomapped memory space for lane's pcs_misc
- * @pipe_clk: pipe clock
- * @qmp: QMP phy to which this lane belongs
- * @mode: currently selected PHY mode
- */
-struct qmp_phy {
- struct phy *phy;
+struct qmp_pcie {
+ struct device *dev;
+
const struct qmp_phy_cfg *cfg;
+
void __iomem *serdes;
+ void __iomem *pcs;
+ void __iomem *pcs_misc;
void __iomem *tx;
void __iomem *rx;
- void __iomem *pcs;
void __iomem *tx2;
void __iomem *rx2;
- void __iomem *pcs_misc;
- struct clk *pipe_clk;
- struct qcom_qmp *qmp;
- int mode;
-};
-
-/**
- * struct qcom_qmp - structure holding QMP phy block attributes
- *
- * @dev: device
- *
- * @clks: array of clocks required by phy
- * @resets: array of resets required by phy
- * @vregs: regulator supplies bulk data
- *
- * @phys: array of per-lane phy descriptors
- */
-struct qcom_qmp {
- struct device *dev;
+ struct clk *pipe_clk;
struct clk_bulk_data *clks;
struct reset_control_bulk_data *resets;
struct regulator_bulk_data *vregs;
- struct qmp_phy **phys;
+ struct phy *phy;
+ int mode;
};
static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
@@ -1850,9 +1820,9 @@ static void qmp_pcie_configure(void __iomem *base,
qmp_pcie_configure_lane(base, tbl, num, 0xff);
}
-static void qmp_pcie_serdes_init(struct qmp_phy *qphy, const struct qmp_phy_cfg_tables *tables)
+static void qmp_pcie_serdes_init(struct qmp_pcie *qmp, const struct qmp_phy_cfg_tables *tables)
{
- void __iomem *serdes = qphy->serdes;
+ void __iomem *serdes = qmp->serdes;
if (!tables)
return;
@@ -1860,11 +1830,11 @@ static void qmp_pcie_serdes_init(struct qmp_phy *qphy, const struct qmp_phy_cfg_
qmp_pcie_configure(serdes, tables->serdes, tables->serdes_num);
}
-static void qmp_pcie_lanes_init(struct qmp_phy *qphy, const struct qmp_phy_cfg_tables *tables)
+static void qmp_pcie_lanes_init(struct qmp_pcie *qmp, const struct qmp_phy_cfg_tables *tables)
{
- const struct qmp_phy_cfg *cfg = qphy->cfg;
- void __iomem *tx = qphy->tx;
- void __iomem *rx = qphy->rx;
+ const struct qmp_phy_cfg *cfg = qmp->cfg;
+ void __iomem *tx = qmp->tx;
+ void __iomem *rx = qmp->rx;
if (!tables)
return;
@@ -1872,17 +1842,17 @@ static void qmp_pcie_lanes_init(struct qmp_phy *qphy, const struct qmp_phy_cfg_t
qmp_pcie_configure_lane(tx, tables->tx, tables->tx_num, 1);
if (cfg->lanes >= 2)
- qmp_pcie_configure_lane(qphy->tx2, tables->tx, tables->tx_num, 2);
+ qmp_pcie_configure_lane(qmp->tx2, tables->tx, tables->tx_num, 2);
qmp_pcie_configure_lane(rx, tables->rx, tables->rx_num, 1);
if (cfg->lanes >= 2)
- qmp_pcie_configure_lane(qphy->rx2, tables->rx, tables->rx_num, 2);
+ qmp_pcie_configure_lane(qmp->rx2, tables->rx, tables->rx_num, 2);
}
-static void qmp_pcie_pcs_init(struct qmp_phy *qphy, const struct qmp_phy_cfg_tables *tables)
+static void qmp_pcie_pcs_init(struct qmp_pcie *qmp, const struct qmp_phy_cfg_tables *tables)
{
- void __iomem *pcs = qphy->pcs;
- void __iomem *pcs_misc = qphy->pcs_misc;
+ void __iomem *pcs = qmp->pcs;
+ void __iomem *pcs_misc = qmp->pcs_misc;
if (!tables)
return;
@@ -1893,9 +1863,8 @@ static void qmp_pcie_pcs_init(struct qmp_phy *qphy, const struct qmp_phy_cfg_tab
static int qmp_pcie_init(struct phy *phy)
{
- struct qmp_phy *qphy = phy_get_drvdata(phy);
- struct qcom_qmp *qmp = qphy->qmp;
- const struct qmp_phy_cfg *cfg = qphy->cfg;
+ struct qmp_pcie *qmp = phy_get_drvdata(phy);
+ const struct qmp_phy_cfg *cfg = qmp->cfg;
int ret;
ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs);
@@ -1932,9 +1901,8 @@ static int qmp_pcie_init(struct phy *phy)
static int qmp_pcie_exit(struct phy *phy)
{
- struct qmp_phy *qphy = phy_get_drvdata(phy);
- struct qcom_qmp *qmp = qphy->qmp;
- const struct qmp_phy_cfg *cfg = qphy->cfg;
+ struct qmp_pcie *qmp = phy_get_drvdata(phy);
+ const struct qmp_phy_cfg *cfg = qmp->cfg;
reset_control_bulk_assert(cfg->num_resets, qmp->resets);
@@ -1947,11 +1915,10 @@ static int qmp_pcie_exit(struct phy *phy)
static int qmp_pcie_power_on(struct phy *phy)
{
- struct qmp_phy *qphy = phy_get_drvdata(phy);
- struct qcom_qmp *qmp = qphy->qmp;
- const struct qmp_phy_cfg *cfg = qphy->cfg;
+ struct qmp_pcie *qmp = phy_get_drvdata(phy);
+ const struct qmp_phy_cfg *cfg = qmp->cfg;
const struct qmp_phy_cfg_tables *mode_tables;
- void __iomem *pcs = qphy->pcs;
+ void __iomem *pcs = qmp->pcs;
void __iomem *status;
unsigned int mask, val;
int ret;
@@ -1959,26 +1926,26 @@ static int qmp_pcie_power_on(struct phy *phy)
qphy_setbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
cfg->pwrdn_ctrl);
- if (qphy->mode == PHY_MODE_PCIE_RC)
+ if (qmp->mode == PHY_MODE_PCIE_RC)
mode_tables = cfg->tables_rc;
else
mode_tables = cfg->tables_ep;
- qmp_pcie_serdes_init(qphy, &cfg->tables);
- qmp_pcie_serdes_init(qphy, mode_tables);
+ qmp_pcie_serdes_init(qmp, &cfg->tables);
+ qmp_pcie_serdes_init(qmp, mode_tables);
- ret = clk_prepare_enable(qphy->pipe_clk);
+ ret = clk_prepare_enable(qmp->pipe_clk);
if (ret) {
dev_err(qmp->dev, "pipe_clk enable failed err=%d\n", ret);
return ret;
}
/* Tx, Rx, and PCS configurations */
- qmp_pcie_lanes_init(qphy, &cfg->tables);
- qmp_pcie_lanes_init(qphy, mode_tables);
+ qmp_pcie_lanes_init(qmp, &cfg->tables);
+ qmp_pcie_lanes_init(qmp, mode_tables);
- qmp_pcie_pcs_init(qphy, &cfg->tables);
- qmp_pcie_pcs_init(qphy, mode_tables);
+ qmp_pcie_pcs_init(qmp, &cfg->tables);
+ qmp_pcie_pcs_init(qmp, mode_tables);
/* Pull PHY out of reset state */
qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
@@ -2001,27 +1968,27 @@ static int qmp_pcie_power_on(struct phy *phy)
return 0;
err_disable_pipe_clk:
- clk_disable_unprepare(qphy->pipe_clk);
+ clk_disable_unprepare(qmp->pipe_clk);
return ret;
}
static int qmp_pcie_power_off(struct phy *phy)
{
- struct qmp_phy *qphy = phy_get_drvdata(phy);
- const struct qmp_phy_cfg *cfg = qphy->cfg;
+ struct qmp_pcie *qmp = phy_get_drvdata(phy);
+ const struct qmp_phy_cfg *cfg = qmp->cfg;
- clk_disable_unprepare(qphy->pipe_clk);
+ clk_disable_unprepare(qmp->pipe_clk);
/* PHY reset */
- qphy_setbits(qphy->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
+ qphy_setbits(qmp->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
/* stop SerDes and Phy-Coding-Sublayer */
- qphy_clrbits(qphy->pcs, cfg->regs[QPHY_START_CTRL],
+ qphy_clrbits(qmp->pcs, cfg->regs[QPHY_START_CTRL],
SERDES_START | PCS_START);
/* Put PHY into POWER DOWN state: active low */
- qphy_clrbits(qphy->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
+ qphy_clrbits(qmp->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
cfg->pwrdn_ctrl);
return 0;
@@ -2055,12 +2022,12 @@ static int qmp_pcie_disable(struct phy *phy)
static int qmp_pcie_set_mode(struct phy *phy, enum phy_mode mode, int submode)
{
- struct qmp_phy *qphy = phy_get_drvdata(phy);
+ struct qmp_pcie *qmp = phy_get_drvdata(phy);
switch (submode) {
case PHY_MODE_PCIE_RC:
case PHY_MODE_PCIE_EP:
- qphy->mode = submode;
+ qmp->mode = submode;
break;
default:
dev_err(&phy->dev, "Unsupported submode %d\n", submode);
@@ -2072,7 +2039,7 @@ static int qmp_pcie_set_mode(struct phy *phy, enum phy_mode mode, int submode)
static int qmp_pcie_vreg_init(struct device *dev, const struct qmp_phy_cfg *cfg)
{
- struct qcom_qmp *qmp = dev_get_drvdata(dev);
+ struct qmp_pcie *qmp = dev_get_drvdata(dev);
int num = cfg->num_vregs;
int i;
@@ -2088,7 +2055,7 @@ static int qmp_pcie_vreg_init(struct device *dev, const struct qmp_phy_cfg *cfg)
static int qmp_pcie_reset_init(struct device *dev, const struct qmp_phy_cfg *cfg)
{
- struct qcom_qmp *qmp = dev_get_drvdata(dev);
+ struct qmp_pcie *qmp = dev_get_drvdata(dev);
int i;
int ret;
@@ -2109,7 +2076,7 @@ static int qmp_pcie_reset_init(struct device *dev, const struct qmp_phy_cfg *cfg
static int qmp_pcie_clk_init(struct device *dev, const struct qmp_phy_cfg *cfg)
{
- struct qcom_qmp *qmp = dev_get_drvdata(dev);
+ struct qmp_pcie *qmp = dev_get_drvdata(dev);
int num = cfg->num_clks;
int i;
@@ -2146,7 +2113,7 @@ static void phy_clk_release_provider(void *res)
* clk | +-------+ | +-----+
* +---------------+
*/
-static int phy_pipe_clk_register(struct qcom_qmp *qmp, struct device_node *np)
+static int phy_pipe_clk_register(struct qmp_pcie *qmp, struct device_node *np)
{
struct clk_fixed_rate *fixed;
struct clk_init_data init = { };
@@ -2168,8 +2135,8 @@ static int phy_pipe_clk_register(struct qcom_qmp *qmp, struct device_node *np)
* Controllers using QMP PHY-s use 125MHz pipe clock interface
* unless other frequency is specified in the PHY config.
*/
- if (qmp->phys[0]->cfg->pipe_clock_rate)
- fixed->fixed_rate = qmp->phys[0]->cfg->pipe_clock_rate;
+ if (qmp->cfg->pipe_clock_rate)
+ fixed->fixed_rate = qmp->cfg->pipe_clock_rate;
else
fixed->fixed_rate = 125000000;
@@ -2197,97 +2164,92 @@ static const struct phy_ops qmp_pcie_ops = {
.owner = THIS_MODULE,
};
-static int qmp_pcie_create(struct device *dev, struct device_node *np, int id,
+static int qmp_pcie_create(struct device *dev, struct device_node *np,
void __iomem *serdes, const struct qmp_phy_cfg *cfg)
{
- struct qcom_qmp *qmp = dev_get_drvdata(dev);
+ struct qmp_pcie *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;
+ qmp->mode = PHY_MODE_PCIE_RC;
- qphy->mode = PHY_MODE_PCIE_RC;
+ qmp->cfg = cfg;
+ qmp->serdes = serdes;
- qphy->cfg = cfg;
- qphy->serdes = serdes;
/*
* Get memory resources for the PHY:
* 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.
*/
- qphy->tx = devm_of_iomap(dev, np, 0, NULL);
- if (IS_ERR(qphy->tx))
- return PTR_ERR(qphy->tx);
+ qmp->tx = devm_of_iomap(dev, np, 0, NULL);
+ if (IS_ERR(qmp->tx))
+ return PTR_ERR(qmp->tx);
if (of_device_is_compatible(dev->of_node, "qcom,sdm845-qhp-pcie-phy"))
- qphy->rx = qphy->tx;
+ qmp->rx = qmp->tx;
else
- qphy->rx = devm_of_iomap(dev, np, 1, NULL);
- if (IS_ERR(qphy->rx))
- return PTR_ERR(qphy->rx);
+ qmp->rx = devm_of_iomap(dev, np, 1, NULL);
+ if (IS_ERR(qmp->rx))
+ return PTR_ERR(qmp->rx);
- qphy->pcs = devm_of_iomap(dev, np, 2, NULL);
- if (IS_ERR(qphy->pcs))
- return PTR_ERR(qphy->pcs);
+ qmp->pcs = devm_of_iomap(dev, np, 2, NULL);
+ if (IS_ERR(qmp->pcs))
+ return PTR_ERR(qmp->pcs);
if (cfg->lanes >= 2) {
- qphy->tx2 = devm_of_iomap(dev, np, 3, NULL);
- if (IS_ERR(qphy->tx2))
- return PTR_ERR(qphy->tx2);
+ qmp->tx2 = devm_of_iomap(dev, np, 3, NULL);
+ if (IS_ERR(qmp->tx2))
+ return PTR_ERR(qmp->tx2);
- qphy->rx2 = devm_of_iomap(dev, np, 4, NULL);
- if (IS_ERR(qphy->rx2))
- return PTR_ERR(qphy->rx2);
+ qmp->rx2 = devm_of_iomap(dev, np, 4, NULL);
+ if (IS_ERR(qmp->rx2))
+ return PTR_ERR(qmp->rx2);
- qphy->pcs_misc = devm_of_iomap(dev, np, 5, NULL);
+ qmp->pcs_misc = devm_of_iomap(dev, np, 5, NULL);
} else {
- qphy->pcs_misc = devm_of_iomap(dev, np, 3, NULL);
+ qmp->pcs_misc = devm_of_iomap(dev, np, 3, NULL);
}
- if (IS_ERR(qphy->pcs_misc) &&
+ if (IS_ERR(qmp->pcs_misc) &&
of_device_is_compatible(dev->of_node, "qcom,ipq6018-qmp-pcie-phy"))
- qphy->pcs_misc = qphy->pcs + 0x400;
+ qmp->pcs_misc = qmp->pcs + 0x400;
- if (IS_ERR(qphy->pcs_misc)) {
+ if (IS_ERR(qmp->pcs_misc)) {
if (cfg->tables.pcs_misc ||
(cfg->tables_rc && cfg->tables_rc->pcs_misc) ||
- (cfg->tables_ep && cfg->tables_ep->pcs_misc))
- return PTR_ERR(qphy->pcs_misc);
+ (cfg->tables_ep && cfg->tables_ep->pcs_misc)) {
+ return PTR_ERR(qmp->pcs_misc);
+ }
}
- qphy->pipe_clk = devm_get_clk_from_child(dev, np, NULL);
- if (IS_ERR(qphy->pipe_clk)) {
- return dev_err_probe(dev, PTR_ERR(qphy->pipe_clk),
- "failed to get lane%d pipe clock\n", id);
+ qmp->pipe_clk = devm_get_clk_from_child(dev, np, NULL);
+ if (IS_ERR(qmp->pipe_clk)) {
+ return dev_err_probe(dev, PTR_ERR(qmp->pipe_clk),
+ "failed to get pipe clock\n");
}
generic_phy = devm_phy_create(dev, np, &qmp_pcie_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 PHY: %d\n", ret);
return ret;
}
- qphy->phy = generic_phy;
- qphy->qmp = qmp;
- qmp->phys[id] = qphy;
- phy_set_drvdata(generic_phy, qphy);
+ qmp->phy = generic_phy;
+ phy_set_drvdata(generic_phy, qmp);
return 0;
}
static int qmp_pcie_probe(struct platform_device *pdev)
{
- struct qcom_qmp *qmp;
struct device *dev = &pdev->dev;
struct device_node *child;
struct phy_provider *phy_provider;
void __iomem *serdes;
const struct qmp_phy_cfg *cfg = NULL;
+ struct qmp_pcie *qmp;
int num, id;
int ret;
@@ -2326,14 +2288,10 @@ static int qmp_pcie_probe(struct platform_device *pdev)
if (num > 1)
return -EINVAL;
- qmp->phys = devm_kcalloc(dev, num, sizeof(*qmp->phys), GFP_KERNEL);
- if (!qmp->phys)
- return -ENOMEM;
-
id = 0;
for_each_available_child_of_node(dev->of_node, child) {
/* Create per-lane phy */
- ret = qmp_pcie_create(dev, child, id, serdes, cfg);
+ ret = qmp_pcie_create(dev, child, serdes, cfg);
if (ret) {
dev_err(dev, "failed to create lane%d phy, %d\n",
id, ret);
--
2.37.4
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v5 04/16] phy: qcom-qmp-pcie: clean up device-tree parsing
2022-11-05 14:59 [PATCH v5 00/16] phy: qcom-qmp-pcie: add support for sc8280xp Johan Hovold
` (2 preceding siblings ...)
2022-11-05 14:59 ` [PATCH v5 03/16] phy: qcom-qmp-pcie: merge driver data Johan Hovold
@ 2022-11-05 14:59 ` Johan Hovold
2022-11-05 14:59 ` [PATCH v5 05/16] phy: qcom-qmp-pcie: clean up probe initialisation Johan Hovold
` (12 subsequent siblings)
16 siblings, 0 replies; 19+ messages in thread
From: Johan Hovold @ 2022-11-05 14:59 UTC (permalink / raw)
To: Vinod Koul
Cc: Andy Gross, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, linux-arm-msm, linux-phy, devicetree,
linux-kernel, Johan Hovold, Dmitry Baryshkov
Since the QMP driver split there will be at most a single child node so
drop the obsolete iteration construct.
While at it, drop the verbose error logging that would have been
printed also on probe deferrals.
Note that there's no need to check if there are additional child nodes
(the kernel is not a devicetree validator), but let's return an error if
there are no child nodes at all for now.
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
---
drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 34 +++++++-----------------
1 file changed, 9 insertions(+), 25 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index 667a87e7c917..bc96518ad6b0 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -2250,7 +2250,6 @@ static int qmp_pcie_probe(struct platform_device *pdev)
void __iomem *serdes;
const struct qmp_phy_cfg *cfg = NULL;
struct qmp_pcie *qmp;
- int num, id;
int ret;
qmp = devm_kzalloc(dev, sizeof(*qmp), GFP_KERNEL);
@@ -2283,34 +2282,19 @@ static int qmp_pcie_probe(struct platform_device *pdev)
if (ret)
return ret;
- num = of_get_available_child_count(dev->of_node);
- /* do we have a rogue child node ? */
- if (num > 1)
+ child = of_get_next_available_child(dev->of_node, NULL);
+ if (!child)
return -EINVAL;
- id = 0;
- for_each_available_child_of_node(dev->of_node, child) {
- /* Create per-lane phy */
- ret = qmp_pcie_create(dev, child, serdes, cfg);
- if (ret) {
- dev_err(dev, "failed to create lane%d phy, %d\n",
- id, ret);
- goto err_node_put;
- }
+ ret = qmp_pcie_create(dev, child, serdes, cfg);
+ if (ret)
+ goto err_node_put;
- /*
- * Register the pipe clock provided by phy.
- * See function description to see details of this pipe clock.
- */
- ret = phy_pipe_clk_register(qmp, child);
- if (ret) {
- dev_err(qmp->dev,
- "failed to register pipe clock source\n");
- goto err_node_put;
- }
+ ret = phy_pipe_clk_register(qmp, child);
+ if (ret)
+ goto err_node_put;
- id++;
- }
+ of_node_put(child);
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
--
2.37.4
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v5 05/16] phy: qcom-qmp-pcie: clean up probe initialisation
2022-11-05 14:59 [PATCH v5 00/16] phy: qcom-qmp-pcie: add support for sc8280xp Johan Hovold
` (3 preceding siblings ...)
2022-11-05 14:59 ` [PATCH v5 04/16] phy: qcom-qmp-pcie: clean up device-tree parsing Johan Hovold
@ 2022-11-05 14:59 ` Johan Hovold
2022-11-05 14:59 ` [PATCH v5 06/16] phy: qcom-qmp-pcie: rename PHY ops structure Johan Hovold
` (11 subsequent siblings)
16 siblings, 0 replies; 19+ messages in thread
From: Johan Hovold @ 2022-11-05 14:59 UTC (permalink / raw)
To: Vinod Koul
Cc: Andy Gross, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, linux-arm-msm, linux-phy, devicetree,
linux-kernel, Johan Hovold, Dmitry Baryshkov
Stop abusing the driver data pointer and instead pass the driver state
structure directly to the initialisation helpers during probe.
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
---
drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 49 +++++++++++-------------
1 file changed, 23 insertions(+), 26 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index bc96518ad6b0..e30cbc94cbf6 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -2037,9 +2037,10 @@ static int qmp_pcie_set_mode(struct phy *phy, enum phy_mode mode, int submode)
return 0;
}
-static int qmp_pcie_vreg_init(struct device *dev, const struct qmp_phy_cfg *cfg)
+static int qmp_pcie_vreg_init(struct qmp_pcie *qmp)
{
- struct qmp_pcie *qmp = dev_get_drvdata(dev);
+ const struct qmp_phy_cfg *cfg = qmp->cfg;
+ struct device *dev = qmp->dev;
int num = cfg->num_vregs;
int i;
@@ -2053,9 +2054,10 @@ static int qmp_pcie_vreg_init(struct device *dev, const struct qmp_phy_cfg *cfg)
return devm_regulator_bulk_get(dev, num, qmp->vregs);
}
-static int qmp_pcie_reset_init(struct device *dev, const struct qmp_phy_cfg *cfg)
+static int qmp_pcie_reset_init(struct qmp_pcie *qmp)
{
- struct qmp_pcie *qmp = dev_get_drvdata(dev);
+ const struct qmp_phy_cfg *cfg = qmp->cfg;
+ struct device *dev = qmp->dev;
int i;
int ret;
@@ -2074,9 +2076,10 @@ static int qmp_pcie_reset_init(struct device *dev, const struct qmp_phy_cfg *cfg
return 0;
}
-static int qmp_pcie_clk_init(struct device *dev, const struct qmp_phy_cfg *cfg)
+static int qmp_pcie_clk_init(struct qmp_pcie *qmp)
{
- struct qmp_pcie *qmp = dev_get_drvdata(dev);
+ const struct qmp_phy_cfg *cfg = qmp->cfg;
+ struct device *dev = qmp->dev;
int num = cfg->num_clks;
int i;
@@ -2164,18 +2167,15 @@ static const struct phy_ops qmp_pcie_ops = {
.owner = THIS_MODULE,
};
-static int qmp_pcie_create(struct device *dev, struct device_node *np,
- void __iomem *serdes, const struct qmp_phy_cfg *cfg)
+static int qmp_pcie_create(struct qmp_pcie *qmp, struct device_node *np)
{
- struct qmp_pcie *qmp = dev_get_drvdata(dev);
+ const struct qmp_phy_cfg *cfg = qmp->cfg;
+ struct device *dev = qmp->dev;
struct phy *generic_phy;
int ret;
qmp->mode = PHY_MODE_PCIE_RC;
- qmp->cfg = cfg;
- qmp->serdes = serdes;
-
/*
* Get memory resources for the PHY:
* Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2.
@@ -2247,8 +2247,6 @@ static int qmp_pcie_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct device_node *child;
struct phy_provider *phy_provider;
- void __iomem *serdes;
- const struct qmp_phy_cfg *cfg = NULL;
struct qmp_pcie *qmp;
int ret;
@@ -2257,28 +2255,27 @@ static int qmp_pcie_probe(struct platform_device *pdev)
return -ENOMEM;
qmp->dev = dev;
- dev_set_drvdata(dev, qmp);
- cfg = of_device_get_match_data(dev);
- if (!cfg)
+ qmp->cfg = of_device_get_match_data(dev);
+ if (!qmp->cfg)
return -EINVAL;
- WARN_ON_ONCE(!cfg->pwrdn_ctrl);
- WARN_ON_ONCE(!cfg->phy_status);
+ WARN_ON_ONCE(!qmp->cfg->pwrdn_ctrl);
+ WARN_ON_ONCE(!qmp->cfg->phy_status);
- serdes = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(serdes))
- return PTR_ERR(serdes);
+ qmp->serdes = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(qmp->serdes))
+ return PTR_ERR(qmp->serdes);
- ret = qmp_pcie_clk_init(dev, cfg);
+ ret = qmp_pcie_clk_init(qmp);
if (ret)
return ret;
- ret = qmp_pcie_reset_init(dev, cfg);
+ ret = qmp_pcie_reset_init(qmp);
if (ret)
return ret;
- ret = qmp_pcie_vreg_init(dev, cfg);
+ ret = qmp_pcie_vreg_init(qmp);
if (ret)
return ret;
@@ -2286,7 +2283,7 @@ static int qmp_pcie_probe(struct platform_device *pdev)
if (!child)
return -EINVAL;
- ret = qmp_pcie_create(dev, child, serdes, cfg);
+ ret = qmp_pcie_create(qmp, child);
if (ret)
goto err_node_put;
--
2.37.4
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v5 06/16] phy: qcom-qmp-pcie: rename PHY ops structure
2022-11-05 14:59 [PATCH v5 00/16] phy: qcom-qmp-pcie: add support for sc8280xp Johan Hovold
` (4 preceding siblings ...)
2022-11-05 14:59 ` [PATCH v5 05/16] phy: qcom-qmp-pcie: clean up probe initialisation Johan Hovold
@ 2022-11-05 14:59 ` Johan Hovold
2022-11-05 14:59 ` [PATCH v5 07/16] phy: qcom-qmp-pcie: clean up PHY lane init Johan Hovold
` (10 subsequent siblings)
16 siblings, 0 replies; 19+ messages in thread
From: Johan Hovold @ 2022-11-05 14:59 UTC (permalink / raw)
To: Vinod Koul
Cc: Andy Gross, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, linux-arm-msm, linux-phy, devicetree,
linux-kernel, Johan Hovold, Dmitry Baryshkov
Rename the PHY operation structure so that it has a "phy_ops" suffix and
move it next to the implementation.
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
---
drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index e30cbc94cbf6..bd946438e3c3 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -2037,6 +2037,13 @@ static int qmp_pcie_set_mode(struct phy *phy, enum phy_mode mode, int submode)
return 0;
}
+static const struct phy_ops qmp_pcie_phy_ops = {
+ .power_on = qmp_pcie_enable,
+ .power_off = qmp_pcie_disable,
+ .set_mode = qmp_pcie_set_mode,
+ .owner = THIS_MODULE,
+};
+
static int qmp_pcie_vreg_init(struct qmp_pcie *qmp)
{
const struct qmp_phy_cfg *cfg = qmp->cfg;
@@ -2160,13 +2167,6 @@ static int phy_pipe_clk_register(struct qmp_pcie *qmp, struct device_node *np)
return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, np);
}
-static const struct phy_ops qmp_pcie_ops = {
- .power_on = qmp_pcie_enable,
- .power_off = qmp_pcie_disable,
- .set_mode = qmp_pcie_set_mode,
- .owner = THIS_MODULE,
-};
-
static int qmp_pcie_create(struct qmp_pcie *qmp, struct device_node *np)
{
const struct qmp_phy_cfg *cfg = qmp->cfg;
@@ -2229,7 +2229,7 @@ static int qmp_pcie_create(struct qmp_pcie *qmp, struct device_node *np)
"failed to get pipe clock\n");
}
- generic_phy = devm_phy_create(dev, np, &qmp_pcie_ops);
+ generic_phy = devm_phy_create(dev, np, &qmp_pcie_phy_ops);
if (IS_ERR(generic_phy)) {
ret = PTR_ERR(generic_phy);
dev_err(dev, "failed to create PHY: %d\n", ret);
--
2.37.4
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v5 07/16] phy: qcom-qmp-pcie: clean up PHY lane init
2022-11-05 14:59 [PATCH v5 00/16] phy: qcom-qmp-pcie: add support for sc8280xp Johan Hovold
` (5 preceding siblings ...)
2022-11-05 14:59 ` [PATCH v5 06/16] phy: qcom-qmp-pcie: rename PHY ops structure Johan Hovold
@ 2022-11-05 14:59 ` Johan Hovold
2022-11-05 14:59 ` [PATCH v5 08/16] phy: qcom-qmp-pcie: use shorter tables identifiers Johan Hovold
` (9 subsequent siblings)
16 siblings, 0 replies; 19+ messages in thread
From: Johan Hovold @ 2022-11-05 14:59 UTC (permalink / raw)
To: Vinod Koul
Cc: Andy Gross, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, linux-arm-msm, linux-phy, devicetree,
linux-kernel, Johan Hovold, Dmitry Baryshkov
Clean up the PHY lane initialisation somewhat by adding further
temporary variables and programming both tx and rx for the second lane
after the first lane.
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
---
drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index bd946438e3c3..dd7e72424fc0 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -1835,18 +1835,19 @@ static void qmp_pcie_lanes_init(struct qmp_pcie *qmp, const struct qmp_phy_cfg_t
const struct qmp_phy_cfg *cfg = qmp->cfg;
void __iomem *tx = qmp->tx;
void __iomem *rx = qmp->rx;
+ void __iomem *tx2 = qmp->tx2;
+ void __iomem *rx2 = qmp->rx2;
if (!tables)
return;
qmp_pcie_configure_lane(tx, tables->tx, tables->tx_num, 1);
-
- if (cfg->lanes >= 2)
- qmp_pcie_configure_lane(qmp->tx2, tables->tx, tables->tx_num, 2);
-
qmp_pcie_configure_lane(rx, tables->rx, tables->rx_num, 1);
- if (cfg->lanes >= 2)
- qmp_pcie_configure_lane(qmp->rx2, tables->rx, tables->rx_num, 2);
+
+ if (cfg->lanes >= 2) {
+ qmp_pcie_configure_lane(tx2, tables->tx, tables->tx_num, 2);
+ qmp_pcie_configure_lane(rx2, tables->rx, tables->rx_num, 2);
+ }
}
static void qmp_pcie_pcs_init(struct qmp_pcie *qmp, const struct qmp_phy_cfg_tables *tables)
--
2.37.4
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v5 08/16] phy: qcom-qmp-pcie: use shorter tables identifiers
2022-11-05 14:59 [PATCH v5 00/16] phy: qcom-qmp-pcie: add support for sc8280xp Johan Hovold
` (6 preceding siblings ...)
2022-11-05 14:59 ` [PATCH v5 07/16] phy: qcom-qmp-pcie: clean up PHY lane init Johan Hovold
@ 2022-11-05 14:59 ` Johan Hovold
2022-11-05 21:39 ` Dmitry Baryshkov
2022-11-05 14:59 ` [PATCH v5 09/16] phy: qcom-qmp-pcie: add register init helper Johan Hovold
` (8 subsequent siblings)
16 siblings, 1 reply; 19+ messages in thread
From: Johan Hovold @ 2022-11-05 14:59 UTC (permalink / raw)
To: Vinod Koul
Cc: Andy Gross, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, linux-arm-msm, linux-phy, devicetree,
linux-kernel, Johan Hovold
The QMP drivers all use 'tbl' to refer to their register initialisation
tables.
For consistency use 'tbls' rather than 'tables' to refer to the new
aggregate table structures.
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
---
drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 90 ++++++++++++------------
1 file changed, 45 insertions(+), 45 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index dd7e72424fc0..a977f2bbd831 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -1313,7 +1313,7 @@ static const struct qmp_phy_init_tbl sm8450_qmp_gen4x2_pcie_ep_pcs_misc_tbl[] =
QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_OSC_DTCT_MODE2_CONFIG5, 0x08),
};
-struct qmp_phy_cfg_tables {
+struct qmp_phy_cfg_tbls {
const struct qmp_phy_init_tbl *serdes;
int serdes_num;
const struct qmp_phy_init_tbl *tx;
@@ -1331,7 +1331,7 @@ struct qmp_phy_cfg {
int lanes;
/* Main init sequence for PHY blocks - serdes, tx, rx, pcs */
- const struct qmp_phy_cfg_tables tables;
+ const struct qmp_phy_cfg_tbls tbls;
/*
* Additional init sequences for PHY blocks, providing additional
* register programming. They are used for providing separate sequences
@@ -1339,8 +1339,8 @@ struct qmp_phy_cfg {
*
* If EP mode is not supported, both tables can be left unset.
*/
- const struct qmp_phy_cfg_tables *tables_rc;
- const struct qmp_phy_cfg_tables *tables_ep;
+ const struct qmp_phy_cfg_tbls *tbls_rc;
+ const struct qmp_phy_cfg_tbls *tbls_ep;
/* clock ids to be requested */
const char * const *clk_list;
@@ -1442,7 +1442,7 @@ static const char * const sdm845_pciephy_reset_l[] = {
static const struct qmp_phy_cfg ipq8074_pciephy_cfg = {
.lanes = 1,
- .tables = {
+ .tbls = {
.serdes = ipq8074_pcie_serdes_tbl,
.serdes_num = ARRAY_SIZE(ipq8074_pcie_serdes_tbl),
.tx = ipq8074_pcie_tx_tbl,
@@ -1467,7 +1467,7 @@ static const struct qmp_phy_cfg ipq8074_pciephy_cfg = {
static const struct qmp_phy_cfg ipq8074_pciephy_gen3_cfg = {
.lanes = 1,
- .tables = {
+ .tbls = {
.serdes = ipq8074_pcie_gen3_serdes_tbl,
.serdes_num = ARRAY_SIZE(ipq8074_pcie_gen3_serdes_tbl),
.tx = ipq8074_pcie_gen3_tx_tbl,
@@ -1494,7 +1494,7 @@ static const struct qmp_phy_cfg ipq8074_pciephy_gen3_cfg = {
static const struct qmp_phy_cfg ipq6018_pciephy_cfg = {
.lanes = 1,
- .tables = {
+ .tbls = {
.serdes = ipq6018_pcie_serdes_tbl,
.serdes_num = ARRAY_SIZE(ipq6018_pcie_serdes_tbl),
.tx = ipq6018_pcie_tx_tbl,
@@ -1521,7 +1521,7 @@ static const struct qmp_phy_cfg ipq6018_pciephy_cfg = {
static const struct qmp_phy_cfg sdm845_qmp_pciephy_cfg = {
.lanes = 1,
- .tables = {
+ .tbls = {
.serdes = sdm845_qmp_pcie_serdes_tbl,
.serdes_num = ARRAY_SIZE(sdm845_qmp_pcie_serdes_tbl),
.tx = sdm845_qmp_pcie_tx_tbl,
@@ -1548,7 +1548,7 @@ static const struct qmp_phy_cfg sdm845_qmp_pciephy_cfg = {
static const struct qmp_phy_cfg sdm845_qhp_pciephy_cfg = {
.lanes = 1,
- .tables = {
+ .tbls = {
.serdes = sdm845_qhp_pcie_serdes_tbl,
.serdes_num = ARRAY_SIZE(sdm845_qhp_pcie_serdes_tbl),
.tx = sdm845_qhp_pcie_tx_tbl,
@@ -1573,7 +1573,7 @@ static const struct qmp_phy_cfg sdm845_qhp_pciephy_cfg = {
static const struct qmp_phy_cfg sm8250_qmp_gen3x1_pciephy_cfg = {
.lanes = 1,
- .tables = {
+ .tbls = {
.serdes = sm8250_qmp_pcie_serdes_tbl,
.serdes_num = ARRAY_SIZE(sm8250_qmp_pcie_serdes_tbl),
.tx = sm8250_qmp_pcie_tx_tbl,
@@ -1585,7 +1585,7 @@ static const struct qmp_phy_cfg sm8250_qmp_gen3x1_pciephy_cfg = {
.pcs_misc = sm8250_qmp_pcie_pcs_misc_tbl,
.pcs_misc_num = ARRAY_SIZE(sm8250_qmp_pcie_pcs_misc_tbl),
},
- .tables_rc = &(const struct qmp_phy_cfg_tables) {
+ .tbls_rc = &(const struct qmp_phy_cfg_tbls) {
.serdes = sm8250_qmp_gen3x1_pcie_serdes_tbl,
.serdes_num = ARRAY_SIZE(sm8250_qmp_gen3x1_pcie_serdes_tbl),
.rx = sm8250_qmp_gen3x1_pcie_rx_tbl,
@@ -1610,7 +1610,7 @@ static const struct qmp_phy_cfg sm8250_qmp_gen3x1_pciephy_cfg = {
static const struct qmp_phy_cfg sm8250_qmp_gen3x2_pciephy_cfg = {
.lanes = 2,
- .tables = {
+ .tbls = {
.serdes = sm8250_qmp_pcie_serdes_tbl,
.serdes_num = ARRAY_SIZE(sm8250_qmp_pcie_serdes_tbl),
.tx = sm8250_qmp_pcie_tx_tbl,
@@ -1622,7 +1622,7 @@ static const struct qmp_phy_cfg sm8250_qmp_gen3x2_pciephy_cfg = {
.pcs_misc = sm8250_qmp_pcie_pcs_misc_tbl,
.pcs_misc_num = ARRAY_SIZE(sm8250_qmp_pcie_pcs_misc_tbl),
},
- .tables_rc = &(const struct qmp_phy_cfg_tables) {
+ .tbls_rc = &(const struct qmp_phy_cfg_tbls) {
.tx = sm8250_qmp_gen3x2_pcie_tx_tbl,
.tx_num = ARRAY_SIZE(sm8250_qmp_gen3x2_pcie_tx_tbl),
.rx = sm8250_qmp_gen3x2_pcie_rx_tbl,
@@ -1647,7 +1647,7 @@ static const struct qmp_phy_cfg sm8250_qmp_gen3x2_pciephy_cfg = {
static const struct qmp_phy_cfg msm8998_pciephy_cfg = {
.lanes = 1,
- .tables = {
+ .tbls = {
.serdes = msm8998_pcie_serdes_tbl,
.serdes_num = ARRAY_SIZE(msm8998_pcie_serdes_tbl),
.tx = msm8998_pcie_tx_tbl,
@@ -1674,7 +1674,7 @@ static const struct qmp_phy_cfg msm8998_pciephy_cfg = {
static const struct qmp_phy_cfg sc8180x_pciephy_cfg = {
.lanes = 1,
- .tables = {
+ .tbls = {
.serdes = sc8180x_qmp_pcie_serdes_tbl,
.serdes_num = ARRAY_SIZE(sc8180x_qmp_pcie_serdes_tbl),
.tx = sc8180x_qmp_pcie_tx_tbl,
@@ -1701,7 +1701,7 @@ static const struct qmp_phy_cfg sc8180x_pciephy_cfg = {
static const struct qmp_phy_cfg sdx55_qmp_pciephy_cfg = {
.lanes = 2,
- .tables = {
+ .tbls = {
.serdes = sdx55_qmp_pcie_serdes_tbl,
.serdes_num = ARRAY_SIZE(sdx55_qmp_pcie_serdes_tbl),
.tx = sdx55_qmp_pcie_tx_tbl,
@@ -1728,7 +1728,7 @@ static const struct qmp_phy_cfg sdx55_qmp_pciephy_cfg = {
static const struct qmp_phy_cfg sm8450_qmp_gen3x1_pciephy_cfg = {
.lanes = 1,
- .tables = {
+ .tbls = {
.serdes = sm8450_qmp_gen3x1_pcie_serdes_tbl,
.serdes_num = ARRAY_SIZE(sm8450_qmp_gen3x1_pcie_serdes_tbl),
.tx = sm8450_qmp_gen3x1_pcie_tx_tbl,
@@ -1755,7 +1755,7 @@ static const struct qmp_phy_cfg sm8450_qmp_gen3x1_pciephy_cfg = {
static const struct qmp_phy_cfg sm8450_qmp_gen4x2_pciephy_cfg = {
.lanes = 2,
- .tables = {
+ .tbls = {
.serdes = sm8450_qmp_gen4x2_pcie_serdes_tbl,
.serdes_num = ARRAY_SIZE(sm8450_qmp_gen4x2_pcie_serdes_tbl),
.tx = sm8450_qmp_gen4x2_pcie_tx_tbl,
@@ -1768,14 +1768,14 @@ static const struct qmp_phy_cfg sm8450_qmp_gen4x2_pciephy_cfg = {
.pcs_misc_num = ARRAY_SIZE(sm8450_qmp_gen4x2_pcie_pcs_misc_tbl),
},
- .tables_rc = &(const struct qmp_phy_cfg_tables) {
+ .tbls_rc = &(const struct qmp_phy_cfg_tbls) {
.serdes = sm8450_qmp_gen4x2_pcie_rc_serdes_tbl,
.serdes_num = ARRAY_SIZE(sm8450_qmp_gen4x2_pcie_rc_serdes_tbl),
.pcs_misc = sm8450_qmp_gen4x2_pcie_rc_pcs_misc_tbl,
.pcs_misc_num = ARRAY_SIZE(sm8450_qmp_gen4x2_pcie_rc_pcs_misc_tbl),
},
- .tables_ep = &(const struct qmp_phy_cfg_tables) {
+ .tbls_ep = &(const struct qmp_phy_cfg_tbls) {
.serdes = sm8450_qmp_gen4x2_pcie_ep_serdes_tbl,
.serdes_num = ARRAY_SIZE(sm8450_qmp_gen4x2_pcie_ep_serdes_tbl),
.pcs_misc = sm8450_qmp_gen4x2_pcie_ep_pcs_misc_tbl,
@@ -1820,17 +1820,17 @@ static void qmp_pcie_configure(void __iomem *base,
qmp_pcie_configure_lane(base, tbl, num, 0xff);
}
-static void qmp_pcie_serdes_init(struct qmp_pcie *qmp, const struct qmp_phy_cfg_tables *tables)
+static void qmp_pcie_serdes_init(struct qmp_pcie *qmp, const struct qmp_phy_cfg_tbls *tbls)
{
void __iomem *serdes = qmp->serdes;
- if (!tables)
+ if (!tbls)
return;
- qmp_pcie_configure(serdes, tables->serdes, tables->serdes_num);
+ qmp_pcie_configure(serdes, tbls->serdes, tbls->serdes_num);
}
-static void qmp_pcie_lanes_init(struct qmp_pcie *qmp, const struct qmp_phy_cfg_tables *tables)
+static void qmp_pcie_lanes_init(struct qmp_pcie *qmp, const struct qmp_phy_cfg_tbls *tbls)
{
const struct qmp_phy_cfg *cfg = qmp->cfg;
void __iomem *tx = qmp->tx;
@@ -1838,28 +1838,28 @@ static void qmp_pcie_lanes_init(struct qmp_pcie *qmp, const struct qmp_phy_cfg_t
void __iomem *tx2 = qmp->tx2;
void __iomem *rx2 = qmp->rx2;
- if (!tables)
+ if (!tbls)
return;
- qmp_pcie_configure_lane(tx, tables->tx, tables->tx_num, 1);
- qmp_pcie_configure_lane(rx, tables->rx, tables->rx_num, 1);
+ qmp_pcie_configure_lane(tx, tbls->tx, tbls->tx_num, 1);
+ qmp_pcie_configure_lane(rx, tbls->rx, tbls->rx_num, 1);
if (cfg->lanes >= 2) {
- qmp_pcie_configure_lane(tx2, tables->tx, tables->tx_num, 2);
- qmp_pcie_configure_lane(rx2, tables->rx, tables->rx_num, 2);
+ qmp_pcie_configure_lane(tx2, tbls->tx, tbls->tx_num, 2);
+ qmp_pcie_configure_lane(rx2, tbls->rx, tbls->rx_num, 2);
}
}
-static void qmp_pcie_pcs_init(struct qmp_pcie *qmp, const struct qmp_phy_cfg_tables *tables)
+static void qmp_pcie_pcs_init(struct qmp_pcie *qmp, const struct qmp_phy_cfg_tbls *tbls)
{
void __iomem *pcs = qmp->pcs;
void __iomem *pcs_misc = qmp->pcs_misc;
- if (!tables)
+ if (!tbls)
return;
- qmp_pcie_configure(pcs, tables->pcs, tables->pcs_num);
- qmp_pcie_configure(pcs_misc, tables->pcs_misc, tables->pcs_misc_num);
+ qmp_pcie_configure(pcs, tbls->pcs, tbls->pcs_num);
+ qmp_pcie_configure(pcs_misc, tbls->pcs_misc, tbls->pcs_misc_num);
}
static int qmp_pcie_init(struct phy *phy)
@@ -1918,7 +1918,7 @@ static int qmp_pcie_power_on(struct phy *phy)
{
struct qmp_pcie *qmp = phy_get_drvdata(phy);
const struct qmp_phy_cfg *cfg = qmp->cfg;
- const struct qmp_phy_cfg_tables *mode_tables;
+ const struct qmp_phy_cfg_tbls *mode_tbls;
void __iomem *pcs = qmp->pcs;
void __iomem *status;
unsigned int mask, val;
@@ -1928,12 +1928,12 @@ static int qmp_pcie_power_on(struct phy *phy)
cfg->pwrdn_ctrl);
if (qmp->mode == PHY_MODE_PCIE_RC)
- mode_tables = cfg->tables_rc;
+ mode_tbls = cfg->tbls_rc;
else
- mode_tables = cfg->tables_ep;
+ mode_tbls = cfg->tbls_ep;
- qmp_pcie_serdes_init(qmp, &cfg->tables);
- qmp_pcie_serdes_init(qmp, mode_tables);
+ qmp_pcie_serdes_init(qmp, &cfg->tbls);
+ qmp_pcie_serdes_init(qmp, mode_tbls);
ret = clk_prepare_enable(qmp->pipe_clk);
if (ret) {
@@ -1942,11 +1942,11 @@ static int qmp_pcie_power_on(struct phy *phy)
}
/* Tx, Rx, and PCS configurations */
- qmp_pcie_lanes_init(qmp, &cfg->tables);
- qmp_pcie_lanes_init(qmp, mode_tables);
+ qmp_pcie_lanes_init(qmp, &cfg->tbls);
+ qmp_pcie_lanes_init(qmp, mode_tbls);
- qmp_pcie_pcs_init(qmp, &cfg->tables);
- qmp_pcie_pcs_init(qmp, mode_tables);
+ qmp_pcie_pcs_init(qmp, &cfg->tbls);
+ qmp_pcie_pcs_init(qmp, mode_tbls);
/* Pull PHY out of reset state */
qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
@@ -2217,9 +2217,9 @@ static int qmp_pcie_create(struct qmp_pcie *qmp, struct device_node *np)
qmp->pcs_misc = qmp->pcs + 0x400;
if (IS_ERR(qmp->pcs_misc)) {
- if (cfg->tables.pcs_misc ||
- (cfg->tables_rc && cfg->tables_rc->pcs_misc) ||
- (cfg->tables_ep && cfg->tables_ep->pcs_misc)) {
+ if (cfg->tbls.pcs_misc ||
+ (cfg->tbls_rc && cfg->tbls_rc->pcs_misc) ||
+ (cfg->tbls_ep && cfg->tbls_ep->pcs_misc)) {
return PTR_ERR(qmp->pcs_misc);
}
}
--
2.37.4
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v5 09/16] phy: qcom-qmp-pcie: add register init helper
2022-11-05 14:59 [PATCH v5 00/16] phy: qcom-qmp-pcie: add support for sc8280xp Johan Hovold
` (7 preceding siblings ...)
2022-11-05 14:59 ` [PATCH v5 08/16] phy: qcom-qmp-pcie: use shorter tables identifiers Johan Hovold
@ 2022-11-05 14:59 ` Johan Hovold
2022-11-05 14:59 ` [PATCH v5 10/16] dt-bindings: phy: qcom,qmp-pcie: rename current bindings Johan Hovold
` (7 subsequent siblings)
16 siblings, 0 replies; 19+ messages in thread
From: Johan Hovold @ 2022-11-05 14:59 UTC (permalink / raw)
To: Vinod Koul
Cc: Andy Gross, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, linux-arm-msm, linux-phy, devicetree,
linux-kernel, Johan Hovold, Dmitry Baryshkov
Generalise the serdes initialisation helper so that it can be used to
initialise all the PHY registers (e.g. serdes, tx, rx, pcs).
Note that this defers the ungating of the PIPE clock somewhat, which is
fine as it isn't needed until starting the PHY.
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
---
drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 37 +++++-------------------
1 file changed, 8 insertions(+), 29 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index a977f2bbd831..09999d5b5268 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -1820,27 +1820,22 @@ static void qmp_pcie_configure(void __iomem *base,
qmp_pcie_configure_lane(base, tbl, num, 0xff);
}
-static void qmp_pcie_serdes_init(struct qmp_pcie *qmp, const struct qmp_phy_cfg_tbls *tbls)
-{
- void __iomem *serdes = qmp->serdes;
-
- if (!tbls)
- return;
-
- qmp_pcie_configure(serdes, tbls->serdes, tbls->serdes_num);
-}
-
-static void qmp_pcie_lanes_init(struct qmp_pcie *qmp, const struct qmp_phy_cfg_tbls *tbls)
+static void qmp_pcie_init_registers(struct qmp_pcie *qmp, const struct qmp_phy_cfg_tbls *tbls)
{
const struct qmp_phy_cfg *cfg = qmp->cfg;
+ void __iomem *serdes = qmp->serdes;
void __iomem *tx = qmp->tx;
void __iomem *rx = qmp->rx;
void __iomem *tx2 = qmp->tx2;
void __iomem *rx2 = qmp->rx2;
+ void __iomem *pcs = qmp->pcs;
+ void __iomem *pcs_misc = qmp->pcs_misc;
if (!tbls)
return;
+ qmp_pcie_configure(serdes, tbls->serdes, tbls->serdes_num);
+
qmp_pcie_configure_lane(tx, tbls->tx, tbls->tx_num, 1);
qmp_pcie_configure_lane(rx, tbls->rx, tbls->rx_num, 1);
@@ -1848,15 +1843,6 @@ static void qmp_pcie_lanes_init(struct qmp_pcie *qmp, const struct qmp_phy_cfg_t
qmp_pcie_configure_lane(tx2, tbls->tx, tbls->tx_num, 2);
qmp_pcie_configure_lane(rx2, tbls->rx, tbls->rx_num, 2);
}
-}
-
-static void qmp_pcie_pcs_init(struct qmp_pcie *qmp, const struct qmp_phy_cfg_tbls *tbls)
-{
- void __iomem *pcs = qmp->pcs;
- void __iomem *pcs_misc = qmp->pcs_misc;
-
- if (!tbls)
- return;
qmp_pcie_configure(pcs, tbls->pcs, tbls->pcs_num);
qmp_pcie_configure(pcs_misc, tbls->pcs_misc, tbls->pcs_misc_num);
@@ -1932,8 +1918,8 @@ static int qmp_pcie_power_on(struct phy *phy)
else
mode_tbls = cfg->tbls_ep;
- qmp_pcie_serdes_init(qmp, &cfg->tbls);
- qmp_pcie_serdes_init(qmp, mode_tbls);
+ qmp_pcie_init_registers(qmp, &cfg->tbls);
+ qmp_pcie_init_registers(qmp, mode_tbls);
ret = clk_prepare_enable(qmp->pipe_clk);
if (ret) {
@@ -1941,13 +1927,6 @@ static int qmp_pcie_power_on(struct phy *phy)
return ret;
}
- /* Tx, Rx, and PCS configurations */
- qmp_pcie_lanes_init(qmp, &cfg->tbls);
- qmp_pcie_lanes_init(qmp, mode_tbls);
-
- qmp_pcie_pcs_init(qmp, &cfg->tbls);
- qmp_pcie_pcs_init(qmp, mode_tbls);
-
/* Pull PHY out of reset state */
qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
--
2.37.4
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v5 10/16] dt-bindings: phy: qcom,qmp-pcie: rename current bindings
2022-11-05 14:59 [PATCH v5 00/16] phy: qcom-qmp-pcie: add support for sc8280xp Johan Hovold
` (8 preceding siblings ...)
2022-11-05 14:59 ` [PATCH v5 09/16] phy: qcom-qmp-pcie: add register init helper Johan Hovold
@ 2022-11-05 14:59 ` Johan Hovold
2022-11-05 14:59 ` [PATCH v5 11/16] dt-bindings: phy: qcom,qmp-pcie: add sc8280xp bindings Johan Hovold
` (6 subsequent siblings)
16 siblings, 0 replies; 19+ messages in thread
From: Johan Hovold @ 2022-11-05 14:59 UTC (permalink / raw)
To: Vinod Koul
Cc: Andy Gross, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, linux-arm-msm, linux-phy, devicetree,
linux-kernel, Johan Hovold, Krzysztof Kozlowski
The current QMP PCIe PHY bindings are based on the original MSM8996
binding which provided multiple PHYs per IP block and these in turn were
described by child nodes.
Later QMP PCIe PHY blocks only provide a single PHY and the remnant
child node does not really reflect the hardware.
The original MSM8996 binding also ended up describing the individual
register blocks as belonging to either the wrapper node or the PHY child
nodes.
This is an unnecessary level of detail which has lead to problems when
later IP blocks using different register layouts have been forced to fit
the original mould rather than updating the binding. The bindings are
arguable also incomplete as they only the describe register blocks used
by the current Linux drivers (e.g. does not include the per lane PCS
registers).
In preparation for adding new bindings for SC8280XP which further
bindings can be based on, rename the current schema file after IPQ8074,
which was the first SoC added to the bindings after MSM8996 (which has
already been split out), and add a reference to the SC8280XP bindings.
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
---
...om,qmp-pcie-phy.yaml => qcom,ipq8074-qmp-pcie-phy.yaml} | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
rename Documentation/devicetree/bindings/phy/{qcom,qmp-pcie-phy.yaml => qcom,ipq8074-qmp-pcie-phy.yaml} (96%)
diff --git a/Documentation/devicetree/bindings/phy/qcom,qmp-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,ipq8074-qmp-pcie-phy.yaml
similarity index 96%
rename from Documentation/devicetree/bindings/phy/qcom,qmp-pcie-phy.yaml
rename to Documentation/devicetree/bindings/phy/qcom,ipq8074-qmp-pcie-phy.yaml
index 324ad7d03a38..62045dcfb20c 100644
--- a/Documentation/devicetree/bindings/phy/qcom,qmp-pcie-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,ipq8074-qmp-pcie-phy.yaml
@@ -1,10 +1,10 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
-$id: http://devicetree.org/schemas/phy/qcom,qmp-pcie-phy.yaml#
+$id: http://devicetree.org/schemas/phy/qcom,ipq8074-qmp-pcie-phy.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
-title: Qualcomm QMP PHY controller (PCIe)
+title: Qualcomm QMP PHY controller (PCIe, IPQ8074)
maintainers:
- Vinod Koul <vkoul@kernel.org>
@@ -13,6 +13,9 @@ description:
QMP PHY controller supports physical layer functionality for a number of
controllers on Qualcomm chipsets, such as, PCIe, UFS, and USB.
+ Note that these bindings are for SoCs up to SC8180X. For newer SoCs, see
+ qcom,sc8280xp-qmp-pcie-phy.yaml.
+
properties:
compatible:
enum:
--
2.37.4
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v5 11/16] dt-bindings: phy: qcom,qmp-pcie: add sc8280xp bindings
2022-11-05 14:59 [PATCH v5 00/16] phy: qcom-qmp-pcie: add support for sc8280xp Johan Hovold
` (9 preceding siblings ...)
2022-11-05 14:59 ` [PATCH v5 10/16] dt-bindings: phy: qcom,qmp-pcie: rename current bindings Johan Hovold
@ 2022-11-05 14:59 ` Johan Hovold
2022-11-05 14:59 ` [PATCH v5 12/16] phy: qcom-qmp-pcie: restructure PHY creation Johan Hovold
` (5 subsequent siblings)
16 siblings, 0 replies; 19+ messages in thread
From: Johan Hovold @ 2022-11-05 14:59 UTC (permalink / raw)
To: Vinod Koul
Cc: Andy Gross, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, linux-arm-msm, linux-phy, devicetree,
linux-kernel, Johan Hovold, Krzysztof Kozlowski
Add bindings for the PCIe QMP PHYs found on SC8280XP.
The PCIe2 and PCIe3 controllers and PHYs on SC8280XP can be used in
4-lane mode or as separate controllers and PHYs in 2-lane mode (e.g. as
PCIe2A and PCIe2B).
The configuration for a specific system can be read from a TCSR register.
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
---
.../phy/qcom,sc8280xp-qmp-pcie-phy.yaml | 165 ++++++++++++++++++
1 file changed, 165 insertions(+)
create mode 100644 Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
new file mode 100644
index 000000000000..80aa8d2507fb
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
@@ -0,0 +1,165 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-pcie-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm QMP PHY controller (PCIe, SC8280XP)
+
+maintainers:
+ - Vinod Koul <vkoul@kernel.org>
+
+description:
+ The QMP PHY controller supports physical layer functionality for a number of
+ controllers on Qualcomm chipsets, such as, PCIe, UFS, and USB.
+
+properties:
+ compatible:
+ enum:
+ - qcom,sc8280xp-qmp-gen3x1-pcie-phy
+ - qcom,sc8280xp-qmp-gen3x2-pcie-phy
+ - qcom,sc8280xp-qmp-gen3x4-pcie-phy
+
+ reg:
+ minItems: 1
+ maxItems: 2
+
+ clocks:
+ maxItems: 6
+
+ clock-names:
+ items:
+ - const: aux
+ - const: cfg_ahb
+ - const: ref
+ - const: rchng
+ - const: pipe
+ - const: pipediv2
+
+ power-domains:
+ maxItems: 1
+
+ resets:
+ maxItems: 1
+
+ reset-names:
+ items:
+ - const: phy
+
+ vdda-phy-supply: true
+
+ vdda-pll-supply: true
+
+ qcom,4ln-config-sel:
+ description: PCIe 4-lane configuration
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+ items:
+ - items:
+ - description: phandle of TCSR syscon
+ - description: offset of PCIe 4-lane configuration register
+ - description: offset of configuration bit for this PHY
+
+ "#clock-cells":
+ const: 0
+
+ clock-output-names:
+ maxItems: 1
+
+ "#phy-cells":
+ const: 0
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - clock-names
+ - power-domains
+ - resets
+ - reset-names
+ - vdda-phy-supply
+ - vdda-pll-supply
+ - "#clock-cells"
+ - clock-output-names
+ - "#phy-cells"
+
+additionalProperties: false
+
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - qcom,sc8280xp-qmp-gen3x4-pcie-phy
+ then:
+ properties:
+ reg:
+ items:
+ - description: port a
+ - description: port b
+ required:
+ - qcom,4ln-config-sel
+ else:
+ properties:
+ reg:
+ maxItems: 1
+
+examples:
+ - |
+ #include <dt-bindings/clock/qcom,gcc-sc8280xp.h>
+
+ pcie2b_phy: phy@1c18000 {
+ compatible = "qcom,sc8280xp-qmp-gen3x2-pcie-phy";
+ reg = <0x01c18000 0x2000>;
+
+ clocks = <&gcc GCC_PCIE_2B_AUX_CLK>,
+ <&gcc GCC_PCIE_2B_CFG_AHB_CLK>,
+ <&gcc GCC_PCIE_2A2B_CLKREF_CLK>,
+ <&gcc GCC_PCIE2B_PHY_RCHNG_CLK>,
+ <&gcc GCC_PCIE_2B_PIPE_CLK>,
+ <&gcc GCC_PCIE_2B_PIPEDIV2_CLK>;
+ clock-names = "aux", "cfg_ahb", "ref", "rchng",
+ "pipe", "pipediv2";
+
+ power-domains = <&gcc PCIE_2B_GDSC>;
+
+ resets = <&gcc GCC_PCIE_2B_PHY_BCR>;
+ reset-names = "phy";
+
+ vdda-phy-supply = <&vreg_l6d>;
+ vdda-pll-supply = <&vreg_l4d>;
+
+ #clock-cells = <0>;
+ clock-output-names = "pcie_2b_pipe_clk";
+
+ #phy-cells = <0>;
+ };
+
+ pcie2a_phy: phy@1c24000 {
+ compatible = "qcom,sc8280xp-qmp-gen3x4-pcie-phy";
+ reg = <0x01c24000 0x2000>, <0x01c26000 0x2000>;
+
+ clocks = <&gcc GCC_PCIE_2A_AUX_CLK>,
+ <&gcc GCC_PCIE_2A_CFG_AHB_CLK>,
+ <&gcc GCC_PCIE_2A2B_CLKREF_CLK>,
+ <&gcc GCC_PCIE2A_PHY_RCHNG_CLK>,
+ <&gcc GCC_PCIE_2A_PIPE_CLK>,
+ <&gcc GCC_PCIE_2A_PIPEDIV2_CLK>;
+ clock-names = "aux", "cfg_ahb", "ref", "rchng",
+ "pipe", "pipediv2";
+
+ power-domains = <&gcc PCIE_2A_GDSC>;
+
+ resets = <&gcc GCC_PCIE_2A_PHY_BCR>;
+ reset-names = "phy";
+
+ vdda-phy-supply = <&vreg_l6d>;
+ vdda-pll-supply = <&vreg_l4d>;
+
+ qcom,4ln-config-sel = <&tcsr 0xa044 0>;
+
+ #clock-cells = <0>;
+ clock-output-names = "pcie_2a_pipe_clk";
+
+ #phy-cells = <0>;
+ };
--
2.37.4
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v5 12/16] phy: qcom-qmp-pcie: restructure PHY creation
2022-11-05 14:59 [PATCH v5 00/16] phy: qcom-qmp-pcie: add support for sc8280xp Johan Hovold
` (10 preceding siblings ...)
2022-11-05 14:59 ` [PATCH v5 11/16] dt-bindings: phy: qcom,qmp-pcie: add sc8280xp bindings Johan Hovold
@ 2022-11-05 14:59 ` Johan Hovold
2022-11-05 14:59 ` [PATCH v5 13/16] phy: qcom-qmp-pcie: fix initialisation reset Johan Hovold
` (4 subsequent siblings)
16 siblings, 0 replies; 19+ messages in thread
From: Johan Hovold @ 2022-11-05 14:59 UTC (permalink / raw)
To: Vinod Koul
Cc: Andy Gross, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, linux-arm-msm, linux-phy, devicetree,
linux-kernel, Johan Hovold, Dmitry Baryshkov
In preparation for supporting devicetree bindings which do not use a
child node, move the PHY creation to probe() proper and parse the serdes
resource in what is now the legacy devicetree helper.
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
---
drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 36 +++++++++++-------------
1 file changed, 17 insertions(+), 19 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index 09999d5b5268..8af84ff755ab 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -2147,14 +2147,15 @@ static int phy_pipe_clk_register(struct qmp_pcie *qmp, struct device_node *np)
return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, np);
}
-static int qmp_pcie_create(struct qmp_pcie *qmp, struct device_node *np)
+static int qmp_pcie_parse_dt_legacy(struct qmp_pcie *qmp, struct device_node *np)
{
+ struct platform_device *pdev = to_platform_device(qmp->dev);
const struct qmp_phy_cfg *cfg = qmp->cfg;
struct device *dev = qmp->dev;
- struct phy *generic_phy;
- int ret;
- qmp->mode = PHY_MODE_PCIE_RC;
+ qmp->serdes = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(qmp->serdes))
+ return PTR_ERR(qmp->serdes);
/*
* Get memory resources for the PHY:
@@ -2209,16 +2210,6 @@ static int qmp_pcie_create(struct qmp_pcie *qmp, struct device_node *np)
"failed to get pipe clock\n");
}
- generic_phy = devm_phy_create(dev, np, &qmp_pcie_phy_ops);
- if (IS_ERR(generic_phy)) {
- ret = PTR_ERR(generic_phy);
- dev_err(dev, "failed to create PHY: %d\n", ret);
- return ret;
- }
-
- qmp->phy = generic_phy;
- phy_set_drvdata(generic_phy, qmp);
-
return 0;
}
@@ -2243,10 +2234,6 @@ static int qmp_pcie_probe(struct platform_device *pdev)
WARN_ON_ONCE(!qmp->cfg->pwrdn_ctrl);
WARN_ON_ONCE(!qmp->cfg->phy_status);
- qmp->serdes = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(qmp->serdes))
- return PTR_ERR(qmp->serdes);
-
ret = qmp_pcie_clk_init(qmp);
if (ret)
return ret;
@@ -2263,7 +2250,7 @@ static int qmp_pcie_probe(struct platform_device *pdev)
if (!child)
return -EINVAL;
- ret = qmp_pcie_create(qmp, child);
+ ret = qmp_pcie_parse_dt_legacy(qmp, child);
if (ret)
goto err_node_put;
@@ -2271,6 +2258,17 @@ static int qmp_pcie_probe(struct platform_device *pdev)
if (ret)
goto err_node_put;
+ qmp->mode = PHY_MODE_PCIE_RC;
+
+ qmp->phy = devm_phy_create(dev, child, &qmp_pcie_phy_ops);
+ if (IS_ERR(qmp->phy)) {
+ ret = PTR_ERR(qmp->phy);
+ dev_err(dev, "failed to create PHY: %d\n", ret);
+ goto err_node_put;
+ }
+
+ phy_set_drvdata(qmp->phy, qmp);
+
of_node_put(child);
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
--
2.37.4
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v5 13/16] phy: qcom-qmp-pcie: fix initialisation reset
2022-11-05 14:59 [PATCH v5 00/16] phy: qcom-qmp-pcie: add support for sc8280xp Johan Hovold
` (11 preceding siblings ...)
2022-11-05 14:59 ` [PATCH v5 12/16] phy: qcom-qmp-pcie: restructure PHY creation Johan Hovold
@ 2022-11-05 14:59 ` Johan Hovold
2022-11-05 14:59 ` [PATCH v5 14/16] phy: qcom-qmp-pcie: add support for pipediv2 clock Johan Hovold
` (3 subsequent siblings)
16 siblings, 0 replies; 19+ messages in thread
From: Johan Hovold @ 2022-11-05 14:59 UTC (permalink / raw)
To: Vinod Koul
Cc: Andy Gross, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, linux-arm-msm, linux-phy, devicetree,
linux-kernel, Johan Hovold, Dmitry Baryshkov
Add the missing delay after asserting reset. This is specifically needed
for the reset to have any effect on SC8280XP.
The vendor driver uses a 1 ms delay, but that seems a bit excessive.
Instead use a 200 us delay which appears to be more than enough and also
matches the UFS reset delay added by commit 870b1279c7a0 ("scsi:
ufs-qcom: Add reset control support for host controller").
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
---
drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index 8af84ff755ab..06844552922e 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -1866,6 +1866,8 @@ static int qmp_pcie_init(struct phy *phy)
goto err_disable_regulators;
}
+ usleep_range(200, 300);
+
ret = reset_control_bulk_deassert(cfg->num_resets, qmp->resets);
if (ret) {
dev_err(qmp->dev, "reset deassert failed\n");
--
2.37.4
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v5 14/16] phy: qcom-qmp-pcie: add support for pipediv2 clock
2022-11-05 14:59 [PATCH v5 00/16] phy: qcom-qmp-pcie: add support for sc8280xp Johan Hovold
` (12 preceding siblings ...)
2022-11-05 14:59 ` [PATCH v5 13/16] phy: qcom-qmp-pcie: fix initialisation reset Johan Hovold
@ 2022-11-05 14:59 ` Johan Hovold
2022-11-05 14:59 ` [PATCH v5 15/16] phy: qcom-qmp-pcie: add support for sc8280xp Johan Hovold
` (2 subsequent siblings)
16 siblings, 0 replies; 19+ messages in thread
From: Johan Hovold @ 2022-11-05 14:59 UTC (permalink / raw)
To: Vinod Koul
Cc: Andy Gross, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, linux-arm-msm, linux-phy, devicetree,
linux-kernel, Johan Hovold, Dmitry Baryshkov
Some QMP PHYs have a second fixed-divider pipe clock that needs to be
enabled along with the pipe clock.
Add support for an optional "pipediv2" clock.
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
---
drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 25 ++++++++++++++----------
1 file changed, 15 insertions(+), 10 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index 06844552922e..d671b05c73dd 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -1378,8 +1378,10 @@ struct qmp_pcie {
void __iomem *tx2;
void __iomem *rx2;
- struct clk *pipe_clk;
struct clk_bulk_data *clks;
+ struct clk_bulk_data pipe_clks[2];
+ int num_pipe_clks;
+
struct reset_control_bulk_data *resets;
struct regulator_bulk_data *vregs;
@@ -1923,11 +1925,9 @@ static int qmp_pcie_power_on(struct phy *phy)
qmp_pcie_init_registers(qmp, &cfg->tbls);
qmp_pcie_init_registers(qmp, mode_tbls);
- ret = clk_prepare_enable(qmp->pipe_clk);
- if (ret) {
- dev_err(qmp->dev, "pipe_clk enable failed err=%d\n", ret);
+ ret = clk_bulk_prepare_enable(qmp->num_pipe_clks, qmp->pipe_clks);
+ if (ret)
return ret;
- }
/* Pull PHY out of reset state */
qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
@@ -1950,7 +1950,7 @@ static int qmp_pcie_power_on(struct phy *phy)
return 0;
err_disable_pipe_clk:
- clk_disable_unprepare(qmp->pipe_clk);
+ clk_bulk_disable_unprepare(qmp->num_pipe_clks, qmp->pipe_clks);
return ret;
}
@@ -1960,7 +1960,7 @@ static int qmp_pcie_power_off(struct phy *phy)
struct qmp_pcie *qmp = phy_get_drvdata(phy);
const struct qmp_phy_cfg *cfg = qmp->cfg;
- clk_disable_unprepare(qmp->pipe_clk);
+ clk_bulk_disable_unprepare(qmp->num_pipe_clks, qmp->pipe_clks);
/* PHY reset */
qphy_setbits(qmp->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
@@ -2154,6 +2154,7 @@ static int qmp_pcie_parse_dt_legacy(struct qmp_pcie *qmp, struct device_node *np
struct platform_device *pdev = to_platform_device(qmp->dev);
const struct qmp_phy_cfg *cfg = qmp->cfg;
struct device *dev = qmp->dev;
+ struct clk *clk;
qmp->serdes = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(qmp->serdes))
@@ -2206,12 +2207,16 @@ static int qmp_pcie_parse_dt_legacy(struct qmp_pcie *qmp, struct device_node *np
}
}
- qmp->pipe_clk = devm_get_clk_from_child(dev, np, NULL);
- if (IS_ERR(qmp->pipe_clk)) {
- return dev_err_probe(dev, PTR_ERR(qmp->pipe_clk),
+ clk = devm_get_clk_from_child(dev, np, NULL);
+ if (IS_ERR(clk)) {
+ return dev_err_probe(dev, PTR_ERR(clk),
"failed to get pipe clock\n");
}
+ qmp->num_pipe_clks = 1;
+ qmp->pipe_clks[0].id = "pipe";
+ qmp->pipe_clks[0].clk = clk;
+
return 0;
}
--
2.37.4
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v5 15/16] phy: qcom-qmp-pcie: add support for sc8280xp
2022-11-05 14:59 [PATCH v5 00/16] phy: qcom-qmp-pcie: add support for sc8280xp Johan Hovold
` (13 preceding siblings ...)
2022-11-05 14:59 ` [PATCH v5 14/16] phy: qcom-qmp-pcie: add support for pipediv2 clock Johan Hovold
@ 2022-11-05 14:59 ` Johan Hovold
2022-11-05 14:59 ` [PATCH v5 16/16] phy: qcom-qmp-pcie: add support for sc8280xp 4-lane PHYs Johan Hovold
2022-11-10 7:05 ` [PATCH v5 00/16] phy: qcom-qmp-pcie: add support for sc8280xp Vinod Koul
16 siblings, 0 replies; 19+ messages in thread
From: Johan Hovold @ 2022-11-05 14:59 UTC (permalink / raw)
To: Vinod Koul
Cc: Andy Gross, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, linux-arm-msm, linux-phy, devicetree,
linux-kernel, Johan Hovold, Dmitry Baryshkov
Add support for the single and dual-lane PHYs found on SC8280XP.
Note that the SC8280XP binding does not try to describe every register
subregion and instead the driver holds the corresponding offsets.
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
---
drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 299 +++++++++++++++++-
.../phy/qualcomm/phy-qcom-qmp-pcs-pcie-v5.h | 2 +
2 files changed, 291 insertions(+), 10 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index d671b05c73dd..f507a67a8361 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -834,6 +834,143 @@ static const struct qmp_phy_init_tbl sc8180x_qmp_pcie_pcs_misc_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
};
+static const struct qmp_phy_init_tbl sc8280xp_qmp_pcie_serdes_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_EN_CENTER, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_PER1, 0x31),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_PER2, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE1_MODE0, 0xde),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE2_MODE0, 0x07),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE1_MODE1, 0x4c),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_STEP_SIZE2_MODE1, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_CLK_ENABLE1, 0x90),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_IVCO, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE0, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE1, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE0, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE1, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE0, 0x36),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE1, 0x36),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_EN_SEL, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP_EN, 0x42),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE0, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE0, 0x1a),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE1, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE1, 0x34),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE0, 0x82),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE1, 0x68),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START1_MODE0, 0x55),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START2_MODE0, 0x55),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START3_MODE0, 0x03),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START1_MODE1, 0xab),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START2_MODE1, 0xaa),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_DIV_FRAC_START3_MODE1, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE1_MODE0, 0x24),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE1_MODE1, 0xb4),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE2_MODE1, 0x03),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_CLK_SELECT, 0x34),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_SEL, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_CORECLK_DIV_MODE1, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xb9),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0x94),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x18),
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
+};
+
+static const struct qmp_phy_init_tbl sc8280xp_qmp_gen3x1_pcie_rc_serdes_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_BUF_ENABLE, 0x07),
+};
+
+static const struct qmp_phy_init_tbl sc8280xp_qmp_gen3x2_pcie_rc_serdes_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
+};
+
+static const struct qmp_phy_init_tbl sc8280xp_qmp_gen3x1_pcie_tx_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_PI_QEC_CTRL, 0x20),
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0x75),
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_4, 0x3f),
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x1d),
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x0c),
+};
+
+static const struct qmp_phy_init_tbl sc8280xp_qmp_gen3x1_pcie_rx_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0x7f),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0xff),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xbf),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x3f),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0xd8),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0xdc),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0xdc),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0x5c),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x34),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xa6),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_TX_ADAPT_POST_THRESH, 0xf0),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH3, 0x34),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL2, 0x07),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_GM_CAL, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH1, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH2, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0xf0),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
+};
+
+static const struct qmp_phy_init_tbl sc8280xp_qmp_gen3x1_pcie_pcs_tbl[] = {
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_REFGEN_REQ_CONFIG1, 0x05),
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_RX_SIGDET_LVL, 0x77),
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_RATE_SLEW_CNTRL1, 0x0b),
+};
+
+static const struct qmp_phy_init_tbl sc8280xp_qmp_gen3x1_pcie_pcs_misc_tbl[] = {
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_INT_AUX_CLK_CONFIG1, 0x00),
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_EQ_CONFIG2, 0x0f),
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
+};
+
+static const struct qmp_phy_init_tbl sc8280xp_qmp_gen3x2_pcie_tx_tbl[] = {
+ QMP_PHY_INIT_CFG_LANE(QSERDES_V5_TX_PI_QEC_CTRL, 0x02, 1),
+ QMP_PHY_INIT_CFG_LANE(QSERDES_V5_TX_PI_QEC_CTRL, 0x04, 2),
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0xd5),
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_4, 0x3f),
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x11),
+ QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x0c),
+};
+
+static const struct qmp_phy_init_tbl sc8280xp_qmp_gen3x2_pcie_rx_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0x7f),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0xff),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0x7f),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x34),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0xd8),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0xdc),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0xdc),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0x5c),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x34),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xa6),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH3, 0x34),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL2, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_GM_CAL, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH1, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH2, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0xf0),
+ QMP_PHY_INIT_CFG(QSERDES_V5_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38),
+};
+
+static const struct qmp_phy_init_tbl sc8280xp_qmp_gen3x2_pcie_pcs_tbl[] = {
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_REFGEN_REQ_CONFIG1, 0x05),
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_RX_SIGDET_LVL, 0x88),
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_RATE_SLEW_CNTRL1, 0x0b),
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_EQ_CONFIG3, 0x0f),
+};
+
+static const struct qmp_phy_init_tbl sc8280xp_qmp_gen3x2_pcie_pcs_misc_tbl[] = {
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_POWER_STATE_CONFIG2, 0x1d),
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_POWER_STATE_CONFIG4, 0x07),
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
+};
+
static const struct qmp_phy_init_tbl sm8250_qmp_pcie_serdes_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x08),
QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_SELECT, 0x34),
@@ -1313,6 +1450,16 @@ static const struct qmp_phy_init_tbl sm8450_qmp_gen4x2_pcie_ep_pcs_misc_tbl[] =
QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_OSC_DTCT_MODE2_CONFIG5, 0x08),
};
+struct qmp_pcie_offsets {
+ u16 serdes;
+ u16 pcs;
+ u16 pcs_misc;
+ u16 tx;
+ u16 rx;
+ u16 tx2;
+ u16 rx2;
+};
+
struct qmp_phy_cfg_tbls {
const struct qmp_phy_init_tbl *serdes;
int serdes_num;
@@ -1330,6 +1477,8 @@ struct qmp_phy_cfg_tbls {
struct qmp_phy_cfg {
int lanes;
+ const struct qmp_pcie_offsets *offsets;
+
/* Main init sequence for PHY blocks - serdes, tx, rx, pcs */
const struct qmp_phy_cfg_tbls tbls;
/*
@@ -1422,6 +1571,9 @@ static const char * const msm8996_phy_clk_l[] = {
"aux", "cfg_ahb", "ref",
};
+static const char * const sc8280xp_pciephy_clk_l[] = {
+ "aux", "cfg_ahb", "ref", "rchng",
+};
static const char * const sdm845_pciephy_clk_l[] = {
"aux", "cfg_ahb", "ref", "refgen",
@@ -1441,6 +1593,16 @@ static const char * const sdm845_pciephy_reset_l[] = {
"phy",
};
+static const struct qmp_pcie_offsets qmp_pcie_offsets_v5 = {
+ .serdes = 0,
+ .pcs = 0x0200,
+ .pcs_misc = 0x0600,
+ .tx = 0x0e00,
+ .rx = 0x1000,
+ .tx2 = 0x1600,
+ .rx2 = 0x1800,
+};
+
static const struct qmp_phy_cfg ipq8074_pciephy_cfg = {
.lanes = 1,
@@ -1700,6 +1862,76 @@ static const struct qmp_phy_cfg sc8180x_pciephy_cfg = {
.phy_status = PHYSTATUS,
};
+static const struct qmp_phy_cfg sc8280xp_qmp_gen3x1_pciephy_cfg = {
+ .lanes = 1,
+
+ .offsets = &qmp_pcie_offsets_v5,
+
+ .tbls = {
+ .serdes = sc8280xp_qmp_pcie_serdes_tbl,
+ .serdes_num = ARRAY_SIZE(sc8280xp_qmp_pcie_serdes_tbl),
+ .tx = sc8280xp_qmp_gen3x1_pcie_tx_tbl,
+ .tx_num = ARRAY_SIZE(sc8280xp_qmp_gen3x1_pcie_tx_tbl),
+ .rx = sc8280xp_qmp_gen3x1_pcie_rx_tbl,
+ .rx_num = ARRAY_SIZE(sc8280xp_qmp_gen3x1_pcie_rx_tbl),
+ .pcs = sc8280xp_qmp_gen3x1_pcie_pcs_tbl,
+ .pcs_num = ARRAY_SIZE(sc8280xp_qmp_gen3x1_pcie_pcs_tbl),
+ .pcs_misc = sc8280xp_qmp_gen3x1_pcie_pcs_misc_tbl,
+ .pcs_misc_num = ARRAY_SIZE(sc8280xp_qmp_gen3x1_pcie_pcs_misc_tbl),
+ },
+
+ .tbls_rc = &(const struct qmp_phy_cfg_tbls) {
+ .serdes = sc8280xp_qmp_gen3x1_pcie_rc_serdes_tbl,
+ .serdes_num = ARRAY_SIZE(sc8280xp_qmp_gen3x1_pcie_rc_serdes_tbl),
+ },
+
+ .clk_list = sc8280xp_pciephy_clk_l,
+ .num_clks = ARRAY_SIZE(sc8280xp_pciephy_clk_l),
+ .reset_list = sdm845_pciephy_reset_l,
+ .num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l),
+ .vreg_list = qmp_phy_vreg_l,
+ .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
+ .regs = sm8250_pcie_regs_layout,
+
+ .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
+ .phy_status = PHYSTATUS,
+};
+
+static const struct qmp_phy_cfg sc8280xp_qmp_gen3x2_pciephy_cfg = {
+ .lanes = 2,
+
+ .offsets = &qmp_pcie_offsets_v5,
+
+ .tbls = {
+ .serdes = sc8280xp_qmp_pcie_serdes_tbl,
+ .serdes_num = ARRAY_SIZE(sc8280xp_qmp_pcie_serdes_tbl),
+ .tx = sc8280xp_qmp_gen3x2_pcie_tx_tbl,
+ .tx_num = ARRAY_SIZE(sc8280xp_qmp_gen3x2_pcie_tx_tbl),
+ .rx = sc8280xp_qmp_gen3x2_pcie_rx_tbl,
+ .rx_num = ARRAY_SIZE(sc8280xp_qmp_gen3x2_pcie_rx_tbl),
+ .pcs = sc8280xp_qmp_gen3x2_pcie_pcs_tbl,
+ .pcs_num = ARRAY_SIZE(sc8280xp_qmp_gen3x2_pcie_pcs_tbl),
+ .pcs_misc = sc8280xp_qmp_gen3x2_pcie_pcs_misc_tbl,
+ .pcs_misc_num = ARRAY_SIZE(sc8280xp_qmp_gen3x2_pcie_pcs_misc_tbl),
+ },
+
+ .tbls_rc = &(const struct qmp_phy_cfg_tbls) {
+ .serdes = sc8280xp_qmp_gen3x2_pcie_rc_serdes_tbl,
+ .serdes_num = ARRAY_SIZE(sc8280xp_qmp_gen3x2_pcie_rc_serdes_tbl),
+ },
+
+ .clk_list = sc8280xp_pciephy_clk_l,
+ .num_clks = ARRAY_SIZE(sc8280xp_pciephy_clk_l),
+ .reset_list = sdm845_pciephy_reset_l,
+ .num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l),
+ .vreg_list = qmp_phy_vreg_l,
+ .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
+ .regs = sm8250_pcie_regs_layout,
+
+ .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
+ .phy_status = PHYSTATUS,
+};
+
static const struct qmp_phy_cfg sdx55_qmp_pciephy_cfg = {
.lanes = 2,
@@ -2220,11 +2452,49 @@ static int qmp_pcie_parse_dt_legacy(struct qmp_pcie *qmp, struct device_node *np
return 0;
}
+static int qmp_pcie_parse_dt(struct qmp_pcie *qmp)
+{
+ struct platform_device *pdev = to_platform_device(qmp->dev);
+ const struct qmp_phy_cfg *cfg = qmp->cfg;
+ const struct qmp_pcie_offsets *offs = cfg->offsets;
+ struct device *dev = qmp->dev;
+ void __iomem *base;
+ int ret;
+
+ if (!offs)
+ return -EINVAL;
+
+ base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ qmp->serdes = base + offs->serdes;
+ qmp->pcs = base + offs->pcs;
+ qmp->pcs_misc = base + offs->pcs_misc;
+ qmp->tx = base + offs->tx;
+ qmp->rx = base + offs->rx;
+
+ if (cfg->lanes >= 2) {
+ qmp->tx2 = base + offs->tx2;
+ qmp->rx2 = base + offs->rx2;
+ }
+
+ qmp->num_pipe_clks = 2;
+ qmp->pipe_clks[0].id = "pipe";
+ qmp->pipe_clks[1].id = "pipediv2";
+
+ ret = devm_clk_bulk_get(dev, qmp->num_pipe_clks, qmp->pipe_clks);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
static int qmp_pcie_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
- struct device_node *child;
struct phy_provider *phy_provider;
+ struct device_node *np;
struct qmp_pcie *qmp;
int ret;
@@ -2253,21 +2523,24 @@ static int qmp_pcie_probe(struct platform_device *pdev)
if (ret)
return ret;
- child = of_get_next_available_child(dev->of_node, NULL);
- if (!child)
- return -EINVAL;
-
- ret = qmp_pcie_parse_dt_legacy(qmp, child);
+ /* Check for legacy binding with child node. */
+ np = of_get_next_available_child(dev->of_node, NULL);
+ if (np) {
+ ret = qmp_pcie_parse_dt_legacy(qmp, np);
+ } else {
+ np = of_node_get(dev->of_node);
+ ret = qmp_pcie_parse_dt(qmp);
+ }
if (ret)
goto err_node_put;
- ret = phy_pipe_clk_register(qmp, child);
+ ret = phy_pipe_clk_register(qmp, np);
if (ret)
goto err_node_put;
qmp->mode = PHY_MODE_PCIE_RC;
- qmp->phy = devm_phy_create(dev, child, &qmp_pcie_phy_ops);
+ qmp->phy = devm_phy_create(dev, np, &qmp_pcie_phy_ops);
if (IS_ERR(qmp->phy)) {
ret = PTR_ERR(qmp->phy);
dev_err(dev, "failed to create PHY: %d\n", ret);
@@ -2276,14 +2549,14 @@ static int qmp_pcie_probe(struct platform_device *pdev)
phy_set_drvdata(qmp->phy, qmp);
- of_node_put(child);
+ of_node_put(np);
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
return PTR_ERR_OR_ZERO(phy_provider);
err_node_put:
- of_node_put(child);
+ of_node_put(np);
return ret;
}
@@ -2303,6 +2576,12 @@ static const struct of_device_id qmp_pcie_of_match_table[] = {
}, {
.compatible = "qcom,sc8180x-qmp-pcie-phy",
.data = &sc8180x_pciephy_cfg,
+ }, {
+ .compatible = "qcom,sc8280xp-qmp-gen3x1-pcie-phy",
+ .data = &sc8280xp_qmp_gen3x1_pciephy_cfg,
+ }, {
+ .compatible = "qcom,sc8280xp-qmp-gen3x2-pcie-phy",
+ .data = &sc8280xp_qmp_gen3x2_pciephy_cfg,
}, {
.compatible = "qcom,sdm845-qhp-pcie-phy",
.data = &sdm845_qhp_pciephy_cfg,
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v5.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v5.h
index 2e19fb3f051e..a469ae2a10a1 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v5.h
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v5.h
@@ -8,6 +8,8 @@
#define QCOM_PHY_QMP_PCS_PCIE_V5_H_
/* Only for QMP V5 PHY - PCS_PCIE registers */
+#define QPHY_V5_PCS_PCIE_POWER_STATE_CONFIG2 0x0c
+#define QPHY_V5_PCS_PCIE_POWER_STATE_CONFIG4 0x14
#define QPHY_V5_PCS_PCIE_ENDPOINT_REFCLK_DRIVE 0x20
#define QPHY_V5_PCS_PCIE_INT_AUX_CLK_CONFIG1 0x54
#define QPHY_V5_PCS_PCIE_OSC_DTCT_ACTIONS 0x94
--
2.37.4
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v5 16/16] phy: qcom-qmp-pcie: add support for sc8280xp 4-lane PHYs
2022-11-05 14:59 [PATCH v5 00/16] phy: qcom-qmp-pcie: add support for sc8280xp Johan Hovold
` (14 preceding siblings ...)
2022-11-05 14:59 ` [PATCH v5 15/16] phy: qcom-qmp-pcie: add support for sc8280xp Johan Hovold
@ 2022-11-05 14:59 ` Johan Hovold
2022-11-10 7:05 ` [PATCH v5 00/16] phy: qcom-qmp-pcie: add support for sc8280xp Vinod Koul
16 siblings, 0 replies; 19+ messages in thread
From: Johan Hovold @ 2022-11-05 14:59 UTC (permalink / raw)
To: Vinod Koul
Cc: Andy Gross, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, linux-arm-msm, linux-phy, devicetree,
linux-kernel, Johan Hovold, Dmitry Baryshkov
The PCIe2 and PCIe3 controllers and PHYs on SC8280XP can be used in
4-lane mode or as separate controllers and PHYs in 2-lane mode (e.g. as
PCIe2A and PCIe2B).
Add support for fetching the 4-lane configuration from the TCSR and
programming the lane registers of the second port when in 4-lane mode.
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
---
drivers/phy/qualcomm/Kconfig | 1 +
drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 117 +++++++++++++++++++++++
2 files changed, 118 insertions(+)
diff --git a/drivers/phy/qualcomm/Kconfig b/drivers/phy/qualcomm/Kconfig
index 5c98850f5a36..eb9ddc685b38 100644
--- a/drivers/phy/qualcomm/Kconfig
+++ b/drivers/phy/qualcomm/Kconfig
@@ -54,6 +54,7 @@ config PHY_QCOM_QMP
tristate "Qualcomm QMP PHY Driver"
depends on OF && COMMON_CLK && (ARCH_QCOM || COMPILE_TEST)
select GENERIC_PHY
+ select MFD_SYSCON
help
Enable this to support the QMP PHY transceiver that is used
with controllers such as PCIe, UFS, and USB on Qualcomm chips.
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index f507a67a8361..111716e25b17 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -10,6 +10,7 @@
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
@@ -17,6 +18,7 @@
#include <linux/phy/pcie.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
+#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/reset.h>
#include <linux/slab.h>
@@ -886,6 +888,10 @@ static const struct qmp_phy_init_tbl sc8280xp_qmp_gen3x2_pcie_rc_serdes_tbl[] =
QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
};
+static const struct qmp_phy_init_tbl sc8280xp_qmp_gen3x4_pcie_serdes_4ln_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIAS_EN_CLKBUFLR_EN, 0x1c),
+};
+
static const struct qmp_phy_init_tbl sc8280xp_qmp_gen3x1_pcie_tx_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V5_TX_PI_QEC_CTRL, 0x20),
QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0x75),
@@ -1491,6 +1497,9 @@ struct qmp_phy_cfg {
const struct qmp_phy_cfg_tbls *tbls_rc;
const struct qmp_phy_cfg_tbls *tbls_ep;
+ const struct qmp_phy_init_tbl *serdes_4ln_tbl;
+ int serdes_4ln_num;
+
/* clock ids to be requested */
const char * const *clk_list;
int num_clks;
@@ -1518,6 +1527,7 @@ struct qmp_pcie {
struct device *dev;
const struct qmp_phy_cfg *cfg;
+ bool tcsr_4ln_config;
void __iomem *serdes;
void __iomem *pcs;
@@ -1527,6 +1537,8 @@ struct qmp_pcie {
void __iomem *tx2;
void __iomem *rx2;
+ void __iomem *port_b;
+
struct clk_bulk_data *clks;
struct clk_bulk_data pipe_clks[2];
int num_pipe_clks;
@@ -1932,6 +1944,44 @@ static const struct qmp_phy_cfg sc8280xp_qmp_gen3x2_pciephy_cfg = {
.phy_status = PHYSTATUS,
};
+static const struct qmp_phy_cfg sc8280xp_qmp_gen3x4_pciephy_cfg = {
+ .lanes = 4,
+
+ .offsets = &qmp_pcie_offsets_v5,
+
+ .tbls = {
+ .serdes = sc8280xp_qmp_pcie_serdes_tbl,
+ .serdes_num = ARRAY_SIZE(sc8280xp_qmp_pcie_serdes_tbl),
+ .tx = sc8280xp_qmp_gen3x2_pcie_tx_tbl,
+ .tx_num = ARRAY_SIZE(sc8280xp_qmp_gen3x2_pcie_tx_tbl),
+ .rx = sc8280xp_qmp_gen3x2_pcie_rx_tbl,
+ .rx_num = ARRAY_SIZE(sc8280xp_qmp_gen3x2_pcie_rx_tbl),
+ .pcs = sc8280xp_qmp_gen3x2_pcie_pcs_tbl,
+ .pcs_num = ARRAY_SIZE(sc8280xp_qmp_gen3x2_pcie_pcs_tbl),
+ .pcs_misc = sc8280xp_qmp_gen3x2_pcie_pcs_misc_tbl,
+ .pcs_misc_num = ARRAY_SIZE(sc8280xp_qmp_gen3x2_pcie_pcs_misc_tbl),
+ },
+
+ .tbls_rc = &(const struct qmp_phy_cfg_tbls) {
+ .serdes = sc8280xp_qmp_gen3x2_pcie_rc_serdes_tbl,
+ .serdes_num = ARRAY_SIZE(sc8280xp_qmp_gen3x2_pcie_rc_serdes_tbl),
+ },
+
+ .serdes_4ln_tbl = sc8280xp_qmp_gen3x4_pcie_serdes_4ln_tbl,
+ .serdes_4ln_num = ARRAY_SIZE(sc8280xp_qmp_gen3x4_pcie_serdes_4ln_tbl),
+
+ .clk_list = sc8280xp_pciephy_clk_l,
+ .num_clks = ARRAY_SIZE(sc8280xp_pciephy_clk_l),
+ .reset_list = sdm845_pciephy_reset_l,
+ .num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l),
+ .vreg_list = qmp_phy_vreg_l,
+ .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
+ .regs = sm8250_pcie_regs_layout,
+
+ .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
+ .phy_status = PHYSTATUS,
+};
+
static const struct qmp_phy_cfg sdx55_qmp_pciephy_cfg = {
.lanes = 2,
@@ -2054,6 +2104,24 @@ static void qmp_pcie_configure(void __iomem *base,
qmp_pcie_configure_lane(base, tbl, num, 0xff);
}
+static void qmp_pcie_init_port_b(struct qmp_pcie *qmp, const struct qmp_phy_cfg_tbls *tbls)
+{
+ const struct qmp_phy_cfg *cfg = qmp->cfg;
+ const struct qmp_pcie_offsets *offs = cfg->offsets;
+ void __iomem *tx3, *rx3, *tx4, *rx4;
+
+ tx3 = qmp->port_b + offs->tx;
+ rx3 = qmp->port_b + offs->rx;
+ tx4 = qmp->port_b + offs->tx2;
+ rx4 = qmp->port_b + offs->rx2;
+
+ qmp_pcie_configure_lane(tx3, tbls->tx, tbls->tx_num, 1);
+ qmp_pcie_configure_lane(rx3, tbls->rx, tbls->rx_num, 1);
+
+ qmp_pcie_configure_lane(tx4, tbls->tx, tbls->tx_num, 2);
+ qmp_pcie_configure_lane(rx4, tbls->rx, tbls->rx_num, 2);
+}
+
static void qmp_pcie_init_registers(struct qmp_pcie *qmp, const struct qmp_phy_cfg_tbls *tbls)
{
const struct qmp_phy_cfg *cfg = qmp->cfg;
@@ -2080,6 +2148,11 @@ static void qmp_pcie_init_registers(struct qmp_pcie *qmp, const struct qmp_phy_c
qmp_pcie_configure(pcs, tbls->pcs, tbls->pcs_num);
qmp_pcie_configure(pcs_misc, tbls->pcs_misc, tbls->pcs_misc_num);
+
+ if (cfg->lanes >= 4 && qmp->tcsr_4ln_config) {
+ qmp_pcie_configure(serdes, cfg->serdes_4ln_tbl, cfg->serdes_4ln_num);
+ qmp_pcie_init_port_b(qmp, tbls);
+ }
}
static int qmp_pcie_init(struct phy *phy)
@@ -2452,6 +2525,37 @@ static int qmp_pcie_parse_dt_legacy(struct qmp_pcie *qmp, struct device_node *np
return 0;
}
+static int qmp_pcie_get_4ln_config(struct qmp_pcie *qmp)
+{
+ struct regmap *tcsr;
+ unsigned int args[2];
+ int ret;
+
+ tcsr = syscon_regmap_lookup_by_phandle_args(qmp->dev->of_node,
+ "qcom,4ln-config-sel",
+ ARRAY_SIZE(args), args);
+ if (IS_ERR(tcsr)) {
+ ret = PTR_ERR(tcsr);
+ if (ret == -ENOENT)
+ return 0;
+
+ dev_err(qmp->dev, "failed to lookup syscon: %d\n", ret);
+ return ret;
+ }
+
+ ret = regmap_test_bits(tcsr, args[0], BIT(args[1]));
+ if (ret < 0) {
+ dev_err(qmp->dev, "failed to read tcsr: %d\n", ret);
+ return ret;
+ }
+
+ qmp->tcsr_4ln_config = ret;
+
+ dev_dbg(qmp->dev, "4ln_config_sel = %d\n", qmp->tcsr_4ln_config);
+
+ return 0;
+}
+
static int qmp_pcie_parse_dt(struct qmp_pcie *qmp)
{
struct platform_device *pdev = to_platform_device(qmp->dev);
@@ -2464,6 +2568,10 @@ static int qmp_pcie_parse_dt(struct qmp_pcie *qmp)
if (!offs)
return -EINVAL;
+ ret = qmp_pcie_get_4ln_config(qmp);
+ if (ret)
+ return ret;
+
base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base))
return PTR_ERR(base);
@@ -2479,6 +2587,12 @@ static int qmp_pcie_parse_dt(struct qmp_pcie *qmp)
qmp->rx2 = base + offs->rx2;
}
+ if (qmp->cfg->lanes >= 4 && qmp->tcsr_4ln_config) {
+ qmp->port_b = devm_platform_ioremap_resource(pdev, 1);
+ if (IS_ERR(qmp->port_b))
+ return PTR_ERR(qmp->port_b);
+ }
+
qmp->num_pipe_clks = 2;
qmp->pipe_clks[0].id = "pipe";
qmp->pipe_clks[1].id = "pipediv2";
@@ -2582,6 +2696,9 @@ static const struct of_device_id qmp_pcie_of_match_table[] = {
}, {
.compatible = "qcom,sc8280xp-qmp-gen3x2-pcie-phy",
.data = &sc8280xp_qmp_gen3x2_pciephy_cfg,
+ }, {
+ .compatible = "qcom,sc8280xp-qmp-gen3x4-pcie-phy",
+ .data = &sc8280xp_qmp_gen3x4_pciephy_cfg,
}, {
.compatible = "qcom,sdm845-qhp-pcie-phy",
.data = &sdm845_qhp_pciephy_cfg,
--
2.37.4
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH v5 08/16] phy: qcom-qmp-pcie: use shorter tables identifiers
2022-11-05 14:59 ` [PATCH v5 08/16] phy: qcom-qmp-pcie: use shorter tables identifiers Johan Hovold
@ 2022-11-05 21:39 ` Dmitry Baryshkov
0 siblings, 0 replies; 19+ messages in thread
From: Dmitry Baryshkov @ 2022-11-05 21:39 UTC (permalink / raw)
To: Johan Hovold, Vinod Koul
Cc: Andy Gross, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, linux-arm-msm, linux-phy, devicetree,
linux-kernel
On 05/11/2022 17:59, Johan Hovold wrote:
> The QMP drivers all use 'tbl' to refer to their register initialisation
> tables.
>
> For consistency use 'tbls' rather than 'tables' to refer to the new
> aggregate table structures.
>
> Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
> ---
> drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 90 ++++++++++++------------
> 1 file changed, 45 insertions(+), 45 deletions(-)
>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v5 00/16] phy: qcom-qmp-pcie: add support for sc8280xp
2022-11-05 14:59 [PATCH v5 00/16] phy: qcom-qmp-pcie: add support for sc8280xp Johan Hovold
` (15 preceding siblings ...)
2022-11-05 14:59 ` [PATCH v5 16/16] phy: qcom-qmp-pcie: add support for sc8280xp 4-lane PHYs Johan Hovold
@ 2022-11-10 7:05 ` Vinod Koul
16 siblings, 0 replies; 19+ messages in thread
From: Vinod Koul @ 2022-11-10 7:05 UTC (permalink / raw)
To: Johan Hovold
Cc: Andy Gross, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, linux-arm-msm, linux-phy, devicetree,
linux-kernel
On 05-11-22, 15:59, Johan Hovold wrote:
> This series adds support for the PCIe PHYs on SC8280XP including its
> four-lane PHYs.
>
> The first half of the series clean up the driver in preparation for
> supporting SC8280XP and its new devicetree bindings that drops the
> legacy child node and the (incomplete) description of register
> subregions.
Applied, thanks
--
~Vinod
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2022-11-10 7:05 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-11-05 14:59 [PATCH v5 00/16] phy: qcom-qmp-pcie: add support for sc8280xp Johan Hovold
2022-11-05 14:59 ` [PATCH v5 01/16] phy: qcom-qmp-pcie: sort device-id table Johan Hovold
2022-11-05 14:59 ` [PATCH v5 02/16] phy: qcom-qmp-pcie: move " Johan Hovold
2022-11-05 14:59 ` [PATCH v5 03/16] phy: qcom-qmp-pcie: merge driver data Johan Hovold
2022-11-05 14:59 ` [PATCH v5 04/16] phy: qcom-qmp-pcie: clean up device-tree parsing Johan Hovold
2022-11-05 14:59 ` [PATCH v5 05/16] phy: qcom-qmp-pcie: clean up probe initialisation Johan Hovold
2022-11-05 14:59 ` [PATCH v5 06/16] phy: qcom-qmp-pcie: rename PHY ops structure Johan Hovold
2022-11-05 14:59 ` [PATCH v5 07/16] phy: qcom-qmp-pcie: clean up PHY lane init Johan Hovold
2022-11-05 14:59 ` [PATCH v5 08/16] phy: qcom-qmp-pcie: use shorter tables identifiers Johan Hovold
2022-11-05 21:39 ` Dmitry Baryshkov
2022-11-05 14:59 ` [PATCH v5 09/16] phy: qcom-qmp-pcie: add register init helper Johan Hovold
2022-11-05 14:59 ` [PATCH v5 10/16] dt-bindings: phy: qcom,qmp-pcie: rename current bindings Johan Hovold
2022-11-05 14:59 ` [PATCH v5 11/16] dt-bindings: phy: qcom,qmp-pcie: add sc8280xp bindings Johan Hovold
2022-11-05 14:59 ` [PATCH v5 12/16] phy: qcom-qmp-pcie: restructure PHY creation Johan Hovold
2022-11-05 14:59 ` [PATCH v5 13/16] phy: qcom-qmp-pcie: fix initialisation reset Johan Hovold
2022-11-05 14:59 ` [PATCH v5 14/16] phy: qcom-qmp-pcie: add support for pipediv2 clock Johan Hovold
2022-11-05 14:59 ` [PATCH v5 15/16] phy: qcom-qmp-pcie: add support for sc8280xp Johan Hovold
2022-11-05 14:59 ` [PATCH v5 16/16] phy: qcom-qmp-pcie: add support for sc8280xp 4-lane PHYs Johan Hovold
2022-11-10 7:05 ` [PATCH v5 00/16] phy: qcom-qmp-pcie: add support for sc8280xp Vinod Koul
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).