diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2024-09-23 14:05:10 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2024-09-23 14:05:10 -0700 |
| commit | fbb86b0d5f38184873772a84ae50d5edd6a8b046 (patch) | |
| tree | 00f72ab7f03bacef40e725c951795a1565ec2686 /drivers | |
| parent | 7116747a686e3d5decc354e6812f078dd0c44c6e (diff) | |
| parent | 3c2ea12a625dbf5a864f4920235fa1c739d06e7d (diff) | |
| download | linux-fbb86b0d5f38184873772a84ae50d5edd6a8b046.tar.gz linux-fbb86b0d5f38184873772a84ae50d5edd6a8b046.tar.bz2 linux-fbb86b0d5f38184873772a84ae50d5edd6a8b046.zip | |
Merge tag 'phy-for-6.12' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy
Pull phy updates from Vinod Koul:
"New hw support:
- Rcar usb2 support for RZ/G3S SoC
- Nuvoton MA35 SoC USB 2.0 PHY driver
Removed:
- obsolete qcom,usb-8x16-phy bindings
Updates:
- 4 lane PCIe support for Qualcomm X1E80100
- Constify structure in subsystem update
- Subsystem simplification with scoped for each OF child loop update
- Yaml conversion for Qualcomm sata phy, Hiilicon hi3798cv200-combphy
bindings"
* tag 'phy-for-6.12' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy: (40 commits)
phy: renesas: rcar-gen3-usb2: Add support for the RZ/G3S SoC
dt-bindings: phy: renesas,usb2-phy: Document RZ/G3S phy bindings
phy: renesas: rcar-gen3-usb2: Add support to initialize the bus
phy: ti: j721e-wiz: Simplify with scoped for each OF child loop
phy: ti: j721e-wiz: Drop OF node reference earlier for simpler code
phy: ti: gmii-sel: Simplify with dev_err_probe()
phy: ti: am654-serdes: Use scoped device node handling to simplify error paths
phy: qcom: qmp-pcie-msm8996: Simplify with scoped for each OF child loop
phy: mediatek: xsphy: Simplify with scoped for each OF child loop
phy: mediatek: tphy: Simplify with scoped for each OF child loop
phy: hisilicon: usb2: Simplify with scoped for each OF child loop
phy: cadence: sierra: Simplify with scoped for each OF child loop
phy: broadcom: brcm-sata: Simplify with scoped for each OF child loop
phy: broadcom: bcm-cygnus-pcie: Simplify with scoped for each OF child loop
phy: nuvoton: add new driver for the Nuvoton MA35 SoC USB 2.0 PHY
dt-bindings: phy: nuvoton,ma35-usb2-phy: add new bindings
phy: qcom: qmp-pcie: Configure all tables on port B PHY
phy: airoha: adjust initialization delay in airoha_pcie_phy_init()
dt-bindings: phy: socionext,uniphier: add top-level constraints
phy: qcom: qmp-pcie: Add Gen4 4-lanes mode for X1E80100
...
Diffstat (limited to 'drivers')
27 files changed, 1004 insertions, 602 deletions
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index dfab1c66b3e5..f73abff416be 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -95,6 +95,7 @@ source "drivers/phy/mediatek/Kconfig" source "drivers/phy/microchip/Kconfig" source "drivers/phy/motorola/Kconfig" source "drivers/phy/mscc/Kconfig" +source "drivers/phy/nuvoton/Kconfig" source "drivers/phy/qualcomm/Kconfig" source "drivers/phy/ralink/Kconfig" source "drivers/phy/realtek/Kconfig" diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index 5fcbce5f9ab1..ebc399560da4 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -25,6 +25,7 @@ obj-y += allwinner/ \ microchip/ \ motorola/ \ mscc/ \ + nuvoton/ \ qualcomm/ \ ralink/ \ realtek/ \ diff --git a/drivers/phy/broadcom/phy-bcm-cygnus-pcie.c b/drivers/phy/broadcom/phy-bcm-cygnus-pcie.c index cc29b08e49eb..462c61a24ec5 100644 --- a/drivers/phy/broadcom/phy-bcm-cygnus-pcie.c +++ b/drivers/phy/broadcom/phy-bcm-cygnus-pcie.c @@ -113,11 +113,10 @@ static const struct phy_ops cygnus_pcie_phy_ops = { static int cygnus_pcie_phy_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct device_node *node = dev->of_node, *child; + struct device_node *node = dev->of_node; struct cygnus_pcie_phy_core *core; struct phy_provider *provider; unsigned cnt = 0; - int ret; if (of_get_child_count(node) == 0) { dev_err(dev, "PHY no child node\n"); @@ -136,35 +135,31 @@ static int cygnus_pcie_phy_probe(struct platform_device *pdev) mutex_init(&core->lock); - for_each_available_child_of_node(node, child) { + for_each_available_child_of_node_scoped(node, child) { unsigned int id; struct cygnus_pcie_phy *p; if (of_property_read_u32(child, "reg", &id)) { dev_err(dev, "missing reg property for %pOFn\n", child); - ret = -EINVAL; - goto put_child; + return -EINVAL; } if (id >= MAX_NUM_PHYS) { dev_err(dev, "invalid PHY id: %u\n", id); - ret = -EINVAL; - goto put_child; + return -EINVAL; } if (core->phys[id].phy) { dev_err(dev, "duplicated PHY id: %u\n", id); - ret = -EINVAL; - goto put_child; + return -EINVAL; } p = &core->phys[id]; p->phy = devm_phy_create(dev, child, &cygnus_pcie_phy_ops); if (IS_ERR(p->phy)) { dev_err(dev, "failed to create PHY\n"); - ret = PTR_ERR(p->phy); - goto put_child; + return PTR_ERR(p->phy); } p->core = core; @@ -184,9 +179,6 @@ static int cygnus_pcie_phy_probe(struct platform_device *pdev) dev_dbg(dev, "registered %u PCIe PHY(s)\n", cnt); return 0; -put_child: - of_node_put(child); - return ret; } static const struct of_device_id cygnus_pcie_phy_match_table[] = { diff --git a/drivers/phy/broadcom/phy-brcm-sata.c b/drivers/phy/broadcom/phy-brcm-sata.c index ed9e18791ec9..228100357054 100644 --- a/drivers/phy/broadcom/phy-brcm-sata.c +++ b/drivers/phy/broadcom/phy-brcm-sata.c @@ -751,11 +751,11 @@ static int brcm_sata_phy_probe(struct platform_device *pdev) { const char *rxaeq_mode; struct device *dev = &pdev->dev; - struct device_node *dn = dev->of_node, *child; + struct device_node *dn = dev->of_node; const struct of_device_id *of_id; struct brcm_sata_phy *priv; struct phy_provider *provider; - int ret, count = 0; + int count = 0; if (of_get_child_count(dn) == 0) return -ENODEV; @@ -782,26 +782,23 @@ static int brcm_sata_phy_probe(struct platform_device *pdev) return PTR_ERR(priv->ctrl_base); } - for_each_available_child_of_node(dn, child) { + for_each_available_child_of_node_scoped(dn, child) { unsigned int id; struct brcm_sata_port *port; if (of_property_read_u32(child, "reg", &id)) { dev_err(dev, "missing reg property in node %pOFn\n", child); - ret = -EINVAL; - goto put_child; + return -EINVAL; } if (id >= MAX_PORTS) { dev_err(dev, "invalid reg: %u\n", id); - ret = -EINVAL; - goto put_child; + return -EINVAL; } if (priv->phys[id].phy) { dev_err(dev, "already registered port %u\n", id); - ret = -EINVAL; - goto put_child; + return -EINVAL; } port = &priv->phys[id]; @@ -822,8 +819,7 @@ static int brcm_sata_phy_probe(struct platform_device *pdev) port->ssc_en = of_property_read_bool(child, "brcm,enable-ssc"); if (IS_ERR(port->phy)) { dev_err(dev, "failed to create PHY\n"); - ret = PTR_ERR(port->phy); - goto put_child; + return PTR_ERR(port->phy); } phy_set_drvdata(port->phy, port); @@ -839,9 +835,6 @@ static int brcm_sata_phy_probe(struct platform_device *pdev) dev_info(dev, "registered %d port(s)\n", count); return 0; -put_child: - of_node_put(child); - return ret; } static struct platform_driver brcm_sata_phy_driver = { diff --git a/drivers/phy/cadence/phy-cadence-sierra.c b/drivers/phy/cadence/phy-cadence-sierra.c index d4eb93ce8232..aeec6eb6be23 100644 --- a/drivers/phy/cadence/phy-cadence-sierra.c +++ b/drivers/phy/cadence/phy-cadence-sierra.c @@ -310,7 +310,7 @@ static const struct clk_parent_data pll_mux_parent_data[][SIERRA_NUM_CMN_PLLC_PA }, }; -static u32 cdns_sierra_pll_mux_table[][SIERRA_NUM_CMN_PLLC_PARENTS] = { +static const u32 cdns_sierra_pll_mux_table[][SIERRA_NUM_CMN_PLLC_PARENTS] = { [CMN_PLLLC] = { 0, 1 }, [CMN_PLLLC1] = { 1, 0 }, }; @@ -362,14 +362,14 @@ struct cdns_sierra_data { u32 id_value; u8 block_offset_shift; u8 reg_offset_shift; - struct cdns_sierra_vals *pcs_cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE] - [NUM_SSC_MODE]; - struct cdns_sierra_vals *phy_pma_ln_vals[NUM_PHY_TYPE][NUM_PHY_TYPE] - [NUM_SSC_MODE]; - struct cdns_sierra_vals *pma_cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE] - [NUM_SSC_MODE]; - struct cdns_sierra_vals *pma_ln_vals[NUM_PHY_TYPE][NUM_PHY_TYPE] - [NUM_SSC_MODE]; + const struct cdns_sierra_vals *pcs_cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE] + [NUM_SSC_MODE]; + const struct cdns_sierra_vals *phy_pma_ln_vals[NUM_PHY_TYPE][NUM_PHY_TYPE] + [NUM_SSC_MODE]; + const struct cdns_sierra_vals *pma_cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE] + [NUM_SSC_MODE]; + const struct cdns_sierra_vals *pma_ln_vals[NUM_PHY_TYPE][NUM_PHY_TYPE] + [NUM_SSC_MODE]; }; struct cdns_regmap_cdb_context { @@ -539,12 +539,12 @@ static int cdns_sierra_phy_init(struct phy *gphy) struct cdns_sierra_inst *ins = phy_get_drvdata(gphy); struct cdns_sierra_phy *phy = dev_get_drvdata(gphy->dev.parent); const struct cdns_sierra_data *init_data = phy->init_data; - struct cdns_sierra_vals *pma_cmn_vals, *pma_ln_vals; + const struct cdns_sierra_vals *pma_cmn_vals, *pma_ln_vals; enum cdns_sierra_phy_type phy_type = ins->phy_type; + const struct cdns_sierra_vals *phy_pma_ln_vals; enum cdns_sierra_ssc_mode ssc = ins->ssc_mode; - struct cdns_sierra_vals *phy_pma_ln_vals; + const struct cdns_sierra_vals *pcs_cmn_vals; const struct cdns_reg_pairs *reg_pairs; - struct cdns_sierra_vals *pcs_cmn_vals; struct regmap *regmap; u32 num_regs; int i, j; @@ -1244,12 +1244,12 @@ static int cdns_sierra_phy_get_resets(struct cdns_sierra_phy *sp, static int cdns_sierra_phy_configure_multilink(struct cdns_sierra_phy *sp) { + const struct cdns_sierra_vals *pma_cmn_vals, *pma_ln_vals; const struct cdns_sierra_data *init_data = sp->init_data; - struct cdns_sierra_vals *pma_cmn_vals, *pma_ln_vals; + const struct cdns_sierra_vals *phy_pma_ln_vals; + const struct cdns_sierra_vals *pcs_cmn_vals; enum cdns_sierra_phy_type phy_t1, phy_t2; - struct cdns_sierra_vals *phy_pma_ln_vals; const struct cdns_reg_pairs *reg_pairs; - struct cdns_sierra_vals *pcs_cmn_vals; int i, j, node, mlane, num_lanes, ret; enum cdns_sierra_ssc_mode ssc; struct regmap *regmap; @@ -1366,7 +1366,7 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev) unsigned int id_value; int ret, node = 0; void __iomem *base; - struct device_node *dn = dev->of_node, *child; + struct device_node *dn = dev->of_node; if (of_get_child_count(dn) == 0) return -ENODEV; @@ -1438,7 +1438,7 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev) sp->autoconf = of_property_read_bool(dn, "cdns,autoconf"); - for_each_available_child_of_node(dn, child) { + for_each_available_child_of_node_scoped(dn, child) { struct phy *gphy; if (!(of_node_name_eq(child, "phy") || @@ -1452,7 +1452,6 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev) dev_err(dev, "failed to get reset %s\n", child->full_name); ret = PTR_ERR(sp->phys[node].lnk_rst); - of_node_put(child); goto put_control; } @@ -1461,7 +1460,6 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev) if (ret) { dev_err(dev, "missing property in node %s\n", child->name); - of_node_put(child); reset_control_put(sp->phys[node].lnk_rst); goto put_control; } @@ -1475,7 +1473,6 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev) gphy = devm_phy_create(dev, child, &noop_ops); if (IS_ERR(gphy)) { ret = PTR_ERR(gphy); - of_node_put(child); reset_control_put(sp->phys[node].lnk_rst); goto put_control; } @@ -1544,11 +1541,11 @@ static void cdns_sierra_phy_remove(struct platform_device *pdev) } /* SGMII PHY PMA lane configuration */ -static struct cdns_reg_pairs sgmii_phy_pma_ln_regs[] = { +static const struct cdns_reg_pairs sgmii_phy_pma_ln_regs[] = { {0x9010, SIERRA_PHY_PMA_XCVR_CTRL} }; -static struct cdns_sierra_vals sgmii_phy_pma_ln_vals = { +static const struct cdns_sierra_vals sgmii_phy_pma_ln_vals = { .reg_pairs = sgmii_phy_pma_ln_regs, .num_regs = ARRAY_SIZE(sgmii_phy_pma_ln_regs), }; @@ -1598,22 +1595,22 @@ static const struct cdns_reg_pairs sgmii_100_no_ssc_plllc1_opt3_ln_regs[] = { {0x0002, SIERRA_RXBUFFER_RCDFECTRL_PREG} }; -static struct cdns_sierra_vals sgmii_100_no_ssc_plllc1_opt3_cmn_vals = { +static const struct cdns_sierra_vals sgmii_100_no_ssc_plllc1_opt3_cmn_vals = { .reg_pairs = sgmii_100_no_ssc_plllc1_opt3_cmn_regs, .num_regs = ARRAY_SIZE(sgmii_100_no_ssc_plllc1_opt3_cmn_regs), }; -static struct cdns_sierra_vals sgmii_100_no_ssc_plllc1_opt3_ln_vals = { +static const struct cdns_sierra_vals sgmii_100_no_ssc_plllc1_opt3_ln_vals = { .reg_pairs = sgmii_100_no_ssc_plllc1_opt3_ln_regs, .num_regs = ARRAY_SIZE(sgmii_100_no_ssc_plllc1_opt3_ln_regs), }; /* QSGMII PHY PMA lane configuration */ -static struct cdns_reg_pairs qsgmii_phy_pma_ln_regs[] = { +static const struct cdns_reg_pairs qsgmii_phy_pma_ln_regs[] = { {0x9010, SIERRA_PHY_PMA_XCVR_CTRL} }; -static struct cdns_sierra_vals qsgmii_phy_pma_ln_vals = { +static const struct cdns_sierra_vals qsgmii_phy_pma_ln_vals = { .reg_pairs = qsgmii_phy_pma_ln_regs, .num_regs = ARRAY_SIZE(qsgmii_phy_pma_ln_regs), }; @@ -1664,22 +1661,22 @@ static const struct cdns_reg_pairs qsgmii_100_no_ssc_plllc1_ln_regs[] = { {0x0002, SIERRA_RXBUFFER_RCDFECTRL_PREG} }; -static struct cdns_sierra_vals qsgmii_100_no_ssc_plllc1_cmn_vals = { +static const struct cdns_sierra_vals qsgmii_100_no_ssc_plllc1_cmn_vals = { .reg_pairs = qsgmii_100_no_ssc_plllc1_cmn_regs, .num_regs = ARRAY_SIZE(qsgmii_100_no_ssc_plllc1_cmn_regs), }; -static struct cdns_sierra_vals qsgmii_100_no_ssc_plllc1_ln_vals = { +static const struct cdns_sierra_vals qsgmii_100_no_ssc_plllc1_ln_vals = { .reg_pairs = qsgmii_100_no_ssc_plllc1_ln_regs, .num_regs = ARRAY_SIZE(qsgmii_100_no_ssc_plllc1_ln_regs), }; /* PCIE PHY PCS common configuration */ -static struct cdns_reg_pairs pcie_phy_pcs_cmn_regs[] = { +static const struct cdns_reg_pairs pcie_phy_pcs_cmn_regs[] = { {0x0430, SIERRA_PHY_PIPE_CMN_CTRL1} }; -static struct cdns_sierra_vals pcie_phy_pcs_cmn_vals = { +static const struct cdns_sierra_vals pcie_phy_pcs_cmn_vals = { .reg_pairs = pcie_phy_pcs_cmn_regs, .num_regs = ARRAY_SIZE(pcie_phy_pcs_cmn_regs), }; @@ -1745,12 +1742,12 @@ static const struct cdns_reg_pairs ml_pcie_100_no_ssc_ln_regs[] = { {0x4432, SIERRA_RXBUFFER_DFECTRL_PREG} }; -static struct cdns_sierra_vals pcie_100_no_ssc_plllc_cmn_vals = { +static const struct cdns_sierra_vals pcie_100_no_ssc_plllc_cmn_vals = { .reg_pairs = pcie_100_no_ssc_plllc_cmn_regs, .num_regs = ARRAY_SIZE(pcie_100_no_ssc_plllc_cmn_regs), }; -static struct cdns_sierra_vals ml_pcie_100_no_ssc_ln_vals = { +static const struct cdns_sierra_vals ml_pcie_100_no_ssc_ln_vals = { .reg_pairs = ml_pcie_100_no_ssc_ln_regs, .num_regs = ARRAY_SIZE(ml_pcie_100_no_ssc_ln_regs), }; @@ -1810,7 +1807,7 @@ static const struct cdns_reg_pairs ti_ml_pcie_100_no_ssc_ln_regs[] = { {0x0002, SIERRA_TX_RCVDET_OVRD_PREG} }; -static struct cdns_sierra_vals ti_ml_pcie_100_no_ssc_ln_vals = { +static const struct cdns_sierra_vals ti_ml_pcie_100_no_ssc_ln_vals = { .reg_pairs = ti_ml_pcie_100_no_ssc_ln_regs, .num_regs = ARRAY_SIZE(ti_ml_pcie_100_no_ssc_ln_regs), }; @@ -1886,12 +1883,12 @@ static const struct cdns_reg_pairs ml_pcie_100_int_ssc_ln_regs[] = { {0x4432, SIERRA_RXBUFFER_DFECTRL_PREG} }; -static struct cdns_sierra_vals pcie_100_int_ssc_plllc_cmn_vals = { +static const struct cdns_sierra_vals pcie_100_int_ssc_plllc_cmn_vals = { .reg_pairs = pcie_100_int_ssc_plllc_cmn_regs, .num_regs = ARRAY_SIZE(pcie_100_int_ssc_plllc_cmn_regs), }; -static struct cdns_sierra_vals ml_pcie_100_int_ssc_ln_vals = { +static const struct cdns_sierra_vals ml_pcie_100_int_ssc_ln_vals = { .reg_pairs = ml_pcie_100_int_ssc_ln_regs, .num_regs = ARRAY_SIZE(ml_pcie_100_int_ssc_ln_regs), }; @@ -1954,7 +1951,7 @@ static const struct cdns_reg_pairs ti_ml_pcie_100_int_ssc_ln_regs[] = { {0x0002, SIERRA_TX_RCVDET_OVRD_PREG} }; -static struct cdns_sierra_vals ti_ml_pcie_100_int_ssc_ln_vals = { +static const struct cdns_sierra_vals ti_ml_pcie_100_int_ssc_ln_vals = { .reg_pairs = ti_ml_pcie_100_int_ssc_ln_regs, .num_regs = ARRAY_SIZE(ti_ml_pcie_100_int_ssc_ln_regs), }; @@ -2024,12 +2021,12 @@ static const struct cdns_reg_pairs ml_pcie_100_ext_ssc_ln_regs[] = { {0x4432, SIERRA_RXBUFFER_DFECTRL_PREG} }; -static struct cdns_sierra_vals pcie_100_ext_ssc_plllc_cmn_vals = { +static const struct cdns_sierra_vals pcie_100_ext_ssc_plllc_cmn_vals = { .reg_pairs = pcie_100_ext_ssc_plllc_cmn_regs, .num_regs = ARRAY_SIZE(pcie_100_ext_ssc_plllc_cmn_regs), }; -static struct cdns_sierra_vals ml_pcie_100_ext_ssc_ln_vals = { +static const struct cdns_sierra_vals ml_pcie_100_ext_ssc_ln_vals = { .reg_pairs = ml_pcie_100_ext_ssc_ln_regs, .num_regs = ARRAY_SIZE(ml_pcie_100_ext_ssc_ln_regs), }; @@ -2092,7 +2089,7 @@ static const struct cdns_reg_pairs ti_ml_pcie_100_ext_ssc_ln_regs[] = { {0x0002, SIERRA_TX_RCVDET_OVRD_PREG} }; -static struct cdns_sierra_vals ti_ml_pcie_100_ext_ssc_ln_vals = { +static const struct cdns_sierra_vals ti_ml_pcie_100_ext_ssc_ln_vals = { .reg_pairs = ti_ml_pcie_100_ext_ssc_ln_regs, .num_regs = ARRAY_SIZE(ti_ml_pcie_100_ext_ssc_ln_regs), }; @@ -2152,12 +2149,12 @@ static const struct cdns_reg_pairs cdns_pcie_ln_regs_no_ssc[] = { {0x4432, SIERRA_RXBUFFER_DFECTRL_PREG} }; -static struct cdns_sierra_vals pcie_100_no_ssc_cmn_vals = { +static const struct cdns_sierra_vals pcie_100_no_ssc_cmn_vals = { .reg_pairs = cdns_pcie_cmn_regs_no_ssc, .num_regs = ARRAY_SIZE(cdns_pcie_cmn_regs_no_ssc), }; -static struct cdns_sierra_vals pcie_100_no_ssc_ln_vals = { +static const struct cdns_sierra_vals pcie_100_no_ssc_ln_vals = { .reg_pairs = cdns_pcie_ln_regs_no_ssc, .num_regs = ARRAY_SIZE(cdns_pcie_ln_regs_no_ssc), }; @@ -2227,12 +2224,12 @@ static const struct cdns_reg_pairs cdns_pcie_ln_regs_int_ssc[] = { {0x4432, SIERRA_RXBUFFER_DFECTRL_PREG} }; -static struct cdns_sierra_vals pcie_100_int_ssc_cmn_vals = { +static const struct cdns_sierra_vals pcie_100_int_ssc_cmn_vals = { .reg_pairs = cdns_pcie_cmn_regs_int_ssc, .num_regs = ARRAY_SIZE(cdns_pcie_cmn_regs_int_ssc), }; -static struct cdns_sierra_vals pcie_100_int_ssc_ln_vals = { +static const struct cdns_sierra_vals pcie_100_int_ssc_ln_vals = { .reg_pairs = cdns_pcie_ln_regs_int_ssc, .num_regs = ARRAY_SIZE(cdns_pcie_ln_regs_int_ssc), }; @@ -2296,12 +2293,12 @@ static const struct cdns_reg_pairs cdns_pcie_ln_regs_ext_ssc[] = { {0x4432, SIERRA_RXBUFFER_DFECTRL_PREG} }; -static struct cdns_sierra_vals pcie_100_ext_ssc_cmn_vals = { +static const struct cdns_sierra_vals pcie_100_ext_ssc_cmn_vals = { .reg_pairs = cdns_pcie_cmn_regs_ext_ssc, .num_regs = ARRAY_SIZE(cdns_pcie_cmn_regs_ext_ssc), }; -static struct cdns_sierra_vals pcie_100_ext_ssc_ln_vals = { +static const struct cdns_sierra_vals pcie_100_ext_ssc_ln_vals = { .reg_pairs = cdns_pcie_ln_regs_ext_ssc, .num_regs = ARRAY_SIZE(cdns_pcie_ln_regs_ext_ssc), }; @@ -2413,12 +2410,12 @@ static const struct cdns_reg_pairs cdns_usb_ln_regs_ext_ssc[] = { {0x4243, SIERRA_RXBUFFER_DFECTRL_PREG} }; -static struct cdns_sierra_vals usb_100_ext_ssc_cmn_vals = { +static const struct cdns_sierra_vals usb_100_ext_ssc_cmn_vals = { .reg_pairs = cdns_usb_cmn_regs_ext_ssc, .num_regs = ARRAY_SIZE(cdns_usb_cmn_regs_ext_ssc), }; -static struct cdns_sierra_vals usb_100_ext_ssc_ln_vals = { +static const struct cdns_sierra_vals usb_100_ext_ssc_ln_vals = { .reg_pairs = cdns_usb_ln_regs_ext_ssc, .num_regs = ARRAY_SIZE(cdns_usb_ln_regs_ext_ssc), }; @@ -2443,7 +2440,7 @@ static const struct cdns_reg_pairs sgmii_pma_cmn_vals[] = { {0x0013, SIERRA_CMN_PLLLC1_DCOCAL_CTRL_PREG}, }; -static struct cdns_sierra_vals sgmii_cmn_vals = { +static const struct cdns_sierra_vals sgmii_cmn_vals = { .reg_pairs = sgmii_pma_cmn_vals, .num_regs = ARRAY_SIZE(sgmii_pma_cmn_vals), }; @@ -2489,7 +2486,7 @@ static const struct cdns_reg_pairs sgmii_ln_regs[] = { {0x321F, SIERRA_CPICAL_RES_STARTCODE_MODE01_PREG}, }; -static struct cdns_sierra_vals sgmii_pma_ln_vals = { +static const struct cdns_sierra_vals sgmii_pma_ln_vals = { .reg_pairs = sgmii_ln_regs, .num_regs = ARRAY_SIZE(sgmii_ln_regs), }; diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c index 56ce82a47f88..8bbbbb87bb22 100644 --- a/drivers/phy/cadence/phy-cadence-torrent.c +++ b/drivers/phy/cadence/phy-cadence-torrent.c @@ -285,7 +285,7 @@ static const int refclk_driver_parent_index[] = { CDNS_TORRENT_RECEIVED_REFCLK }; -static u32 cdns_torrent_refclk_driver_mux_table[] = { 1, 0 }; +static const u32 cdns_torrent_refclk_driver_mux_table[] = { 1, 0 }; enum cdns_torrent_phy_type { TYPE_NONE, @@ -351,6 +351,7 @@ struct cdns_torrent_phy { void __iomem *sd_base; /* SD0801 registers base */ u32 max_bit_rate; /* Maximum link bit rate to use (in Mbps) */ u32 dp_pll; + u32 protocol_bitmask; struct reset_control *phy_rst; struct reset_control *apb_rst; struct device *dev; @@ -422,17 +423,17 @@ struct cdns_reg_pairs { }; struct cdns_torrent_vals { - struct cdns_reg_pairs *reg_pairs; + const struct cdns_reg_pairs *reg_pairs; u32 num_regs; }; struct cdns_torrent_vals_entry { u32 key; - struct cdns_torrent_vals *vals; + const struct cdns_torrent_vals *vals; }; struct cdns_torrent_vals_table { - struct cdns_torrent_vals_entry *entries; + const struct cdns_torrent_vals_entry *entries; u32 num_entries; }; @@ -454,12 +455,12 @@ struct cdns_regmap_cdb_context { u8 reg_offset_shift; }; -static struct cdns_torrent_vals *cdns_torrent_get_tbl_vals(const struct cdns_torrent_vals_table *tbl, - enum cdns_torrent_ref_clk refclk0, - enum cdns_torrent_ref_clk refclk1, - enum cdns_torrent_phy_type link0, - enum cdns_torrent_phy_type link1, - enum cdns_torrent_ssc_mode ssc) +static const struct cdns_torrent_vals *cdns_torrent_get_tbl_vals(const struct cdns_torrent_vals_table *tbl, + enum cdns_torrent_ref_clk refclk0, + enum cdns_torrent_ref_clk refclk1, + enum cdns_torrent_phy_type link0, + enum cdns_torrent_phy_type link1, + enum cdns_torrent_ssc_mode ssc) { int i; u32 key = CDNS_TORRENT_KEY(refclk0, refclk1, link0, link1, ssc); @@ -2306,16 +2307,16 @@ static int cdns_torrent_regmap_init(struct cdns_torrent_phy *cdns_phy) static int cdns_torrent_phy_init(struct phy *phy) { struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent); + const struct cdns_torrent_vals *cmn_vals, *tx_ln_vals, *rx_ln_vals; const struct cdns_torrent_data *init_data = cdns_phy->init_data; - struct cdns_torrent_vals *cmn_vals, *tx_ln_vals, *rx_ln_vals; + const struct cdns_torrent_vals *link_cmn_vals, *xcvr_diag_vals; enum cdns_torrent_ref_clk ref_clk = cdns_phy->ref_clk_rate; - struct cdns_torrent_vals *link_cmn_vals, *xcvr_diag_vals; struct cdns_torrent_inst *inst = phy_get_drvdata(phy); enum cdns_torrent_phy_type phy_type = inst->phy_type; + const struct cdns_torrent_vals *phy_pma_cmn_vals; enum cdns_torrent_ssc_mode ssc = inst->ssc_mode; - struct cdns_torrent_vals *phy_pma_cmn_vals; - struct cdns_torrent_vals *pcs_cmn_vals; - struct cdns_reg_pairs *reg_pairs; + const struct cdns_torrent_vals *pcs_cmn_vals; + const struct cdns_reg_pairs *reg_pairs; struct regmap *regmap; u32 num_regs; int i, j; @@ -2463,166 +2464,216 @@ static const struct phy_ops cdns_torrent_phy_ops = { static int cdns_torrent_phy_configure_multilink(struct cdns_torrent_phy *cdns_phy) { + const struct cdns_torrent_vals *cmn_vals, *tx_ln_vals, *rx_ln_vals; const struct cdns_torrent_data *init_data = cdns_phy->init_data; - struct cdns_torrent_vals *cmn_vals, *tx_ln_vals, *rx_ln_vals; + const struct cdns_torrent_vals *link_cmn_vals, *xcvr_diag_vals; enum cdns_torrent_ref_clk ref_clk1 = cdns_phy->ref_clk1_rate; enum cdns_torrent_ref_clk ref_clk = cdns_phy->ref_clk_rate; - struct cdns_torrent_vals *link_cmn_vals, *xcvr_diag_vals; + const struct cdns_torrent_vals *phy_pma_cmn_vals; + const struct cdns_torrent_vals *pcs_cmn_vals; enum cdns_torrent_phy_type phy_t1, phy_t2; - struct cdns_torrent_vals *phy_pma_cmn_vals; - struct cdns_torrent_vals *pcs_cmn_vals; + const struct cdns_reg_pairs *reg_pairs; int i, j, node, mlane, num_lanes, ret; - struct cdns_reg_pairs *reg_pairs; + struct device *dev = cdns_phy->dev; enum cdns_torrent_ssc_mode ssc; struct regmap *regmap; - u32 num_regs; + u32 num_regs, num_protocols, protocol; - /* Maximum 2 links (subnodes) are supported */ - if (cdns_phy->nsubnodes != 2) + num_protocols = hweight32(cdns_phy->protocol_bitmask); + /* Maximum 2 protocols are supported */ + if (num_protocols > 2) { + dev_err(dev, "at most 2 protocols are supported\n"); return -EINVAL; + } + + + /** + * Get PHY types directly from subnodes if only 2 subnodes exist. + * It is possible for phy_t1 to be the same as phy_t2 for special + * configurations such as PCIe Multilink. + */ + if (cdns_phy->nsubnodes == 2) { + phy_t1 = cdns_phy->phys[0].phy_type; + phy_t2 = cdns_phy->phys[1].phy_type; + } else { + /** + * Both PHY types / protocols should be unique. + * If they are the same, it should be expressed with either + * a) Single-Link (1 Sub-node) - handled via PHY APIs + * OR + * b) Double-Link (2 Sub-nodes) - handled above + */ + if (num_protocols != 2) { + dev_err(dev, "incorrect representation of link\n"); + return -EINVAL; + } - phy_t1 = cdns_phy->phys[0].phy_type; - phy_t2 = cdns_phy->phys[1].phy_type; + phy_t1 = fns(cdns_phy->protocol_bitmask, 0); + phy_t2 = fns(cdns_phy->protocol_bitmask, 1); + } /** - * First configure the PHY for first link with phy_t1. Get the array - * values as [phy_t1][phy_t2][ssc]. + * Configure all links with the protocol phy_t1 first followed by + * configuring all links with the protocol phy_t2. + * + * When phy_t1 = phy_t2, it is a single protocol and configuration + * is performed with a single iteration of the protocol and multiple + * iterations over the sub-nodes (links). + * + * When phy_t1 != phy_t2, there are two protocols and configuration + * is performed by iterating over all sub-nodes matching the first + * protocol and configuring them first, followed by iterating over + * all sub-nodes matching the second protocol and configuring them + * next. */ - for (node = 0; node < cdns_phy->nsubnodes; node++) { - if (node == 1) { + for (protocol = 0; protocol < num_protocols; protocol++) { + /** + * For the case where num_protocols is 1, + * phy_t1 = phy_t2 and the swap is unnecessary. + * + * Swapping phy_t1 and phy_t2 is only required when the + * number of protocols is 2 and there are 2 or more links. + */ + if (protocol == 1) { /** - * If first link with phy_t1 is configured, then - * configure the PHY for second link with phy_t2. + * If first protocol with phy_t1 is configured, then + * configure the PHY for second protocol with phy_t2. * Get the array values as [phy_t2][phy_t1][ssc]. */ swap(phy_t1, phy_t2); swap(ref_clk, ref_clk1); } - mlane = cdns_phy->phys[node].mlane; - ssc = cdns_phy->phys[node].ssc_mode; - num_lanes = cdns_phy->phys[node].num_lanes; + for (node = 0; node < cdns_phy->nsubnodes; node++) { + if (cdns_phy->phys[node].phy_type != phy_t1) + continue; - /** - * PHY configuration specific registers: - * link_cmn_vals depend on combination of PHY types being - * configured and are common for both PHY types, so array - * values should be same for [phy_t1][phy_t2][ssc] and - * [phy_t2][phy_t1][ssc]. - * xcvr_diag_vals also depend on combination of PHY types - * being configured, but these can be different for particular - * PHY type and are per lane. - */ - link_cmn_vals = cdns_torrent_get_tbl_vals(&init_data->link_cmn_vals_tbl, - CLK_ANY, CLK_ANY, - phy_t1, phy_t2, ANY_SSC); - if (link_cmn_vals) { - reg_pairs = link_cmn_vals->reg_pairs; - num_regs = link_cmn_vals->num_regs; - regmap = cdns_phy->regmap_common_cdb; + mlane = cdns_phy->phys[node].mlane; + ssc = cdns_phy->phys[node].ssc_mode; + num_lanes = cdns_phy->phys[node].num_lanes; |
