Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'phy-fixes-6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy

Pull phy fixes from Vinod Koul:

- static checker (array size, bounds) fix for marvel driver

- Rockchip rk3588 pcie fixes for bifurcation and mux

- Qualcomm qmp-compbo fix for VCO, register base and regulator name for
m31 driver

- charger det crash fix for ti driver

* tag 'phy-fixes-6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy:
phy: ti: tusb1210: Resolve charger-det crash if charger psy is unregistered
phy: qcom: qmp-combo: fix VCO div offset on v5_5nm and v6
phy: phy-rockchip-samsung-hdptx: Select CONFIG_RATIONAL
phy: qcom: m31: match requested regulator name with dt schema
phy: qcom: qmp-combo: Fix register base for QSERDES_DP_PHY_MODE
phy: qcom: qmp-combo: Fix VCO div offset on v3
phy: rockchip: naneng-combphy: Fix mux on rk3588
phy: rockchip-snps-pcie3: fix clearing PHP_GRF_PCIESEL_CON bits
phy: rockchip-snps-pcie3: fix bifurcation on rk3588
phy: freescale: imx8m-pcie: fix pcie link-up instability
phy: marvell: a3700-comphy: Fix hardcoded array size
phy: marvell: a3700-comphy: Fix out of bounds read

+80 -42
+4 -2
drivers/phy/freescale/phy-fsl-imx8m-pcie.c
··· 110 110 /* Source clock from SoC internal PLL */ 111 111 writel(ANA_PLL_CLK_OUT_TO_EXT_IO_SEL, 112 112 imx8_phy->base + IMX8MM_PCIE_PHY_CMN_REG062); 113 - writel(AUX_PLL_REFCLK_SEL_SYS_PLL, 114 - imx8_phy->base + IMX8MM_PCIE_PHY_CMN_REG063); 113 + if (imx8_phy->drvdata->variant != IMX8MM) { 114 + writel(AUX_PLL_REFCLK_SEL_SYS_PLL, 115 + imx8_phy->base + IMX8MM_PCIE_PHY_CMN_REG063); 116 + } 115 117 val = ANA_AUX_RX_TX_SEL_TX | ANA_AUX_TX_TERM; 116 118 writel(val | ANA_AUX_RX_TERM_GND_EN, 117 119 imx8_phy->base + IMX8MM_PCIE_PHY_CMN_REG064);
+5 -4
drivers/phy/marvell/phy-mvebu-a3700-comphy.c
··· 603 603 u16 val; 604 604 605 605 fix_idx = 0; 606 - for (addr = 0; addr < 512; addr++) { 606 + for (addr = 0; addr < ARRAY_SIZE(gbe_phy_init); addr++) { 607 607 /* 608 608 * All PHY register values are defined in full for 3.125Gbps 609 609 * SERDES speed. The values required for 1.25 Gbps are almost ··· 611 611 * comparison to 3.125 Gbps values. These register values are 612 612 * stored in "gbe_phy_init_fix" array. 613 613 */ 614 - if (!is_1gbps && gbe_phy_init_fix[fix_idx].addr == addr) { 614 + if (!is_1gbps && 615 + fix_idx < ARRAY_SIZE(gbe_phy_init_fix) && 616 + gbe_phy_init_fix[fix_idx].addr == addr) { 615 617 /* Use new value */ 616 618 val = gbe_phy_init_fix[fix_idx].value; 617 - if (fix_idx < ARRAY_SIZE(gbe_phy_init_fix)) 618 - fix_idx++; 619 + fix_idx++; 619 620 } else { 620 621 val = gbe_phy_init[addr]; 621 622 }
+1 -1
drivers/phy/qualcomm/phy-qcom-m31.c
··· 297 297 return dev_err_probe(dev, PTR_ERR(qphy->phy), 298 298 "failed to create phy\n"); 299 299 300 - qphy->vreg = devm_regulator_get(dev, "vdda-phy"); 300 + qphy->vreg = devm_regulator_get(dev, "vdd"); 301 301 if (IS_ERR(qphy->vreg)) 302 302 return dev_err_probe(dev, PTR_ERR(qphy->vreg), 303 303 "failed to get vreg\n");
+9 -3
drivers/phy/qualcomm/phy-qcom-qmp-combo.c
··· 77 77 QPHY_COM_BIAS_EN_CLKBUFLR_EN, 78 78 79 79 QPHY_DP_PHY_STATUS, 80 + QPHY_DP_PHY_VCO_DIV, 80 81 81 82 QPHY_TX_TX_POL_INV, 82 83 QPHY_TX_TX_DRV_LVL, ··· 103 102 [QPHY_COM_BIAS_EN_CLKBUFLR_EN] = QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 104 103 105 104 [QPHY_DP_PHY_STATUS] = QSERDES_V3_DP_PHY_STATUS, 105 + [QPHY_DP_PHY_VCO_DIV] = QSERDES_V3_DP_PHY_VCO_DIV, 106 106 107 107 [QPHY_TX_TX_POL_INV] = QSERDES_V3_TX_TX_POL_INV, 108 108 [QPHY_TX_TX_DRV_LVL] = QSERDES_V3_TX_TX_DRV_LVL, ··· 128 126 [QPHY_COM_BIAS_EN_CLKBUFLR_EN] = QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN, 129 127 130 128 [QPHY_DP_PHY_STATUS] = QSERDES_V4_DP_PHY_STATUS, 129 + [QPHY_DP_PHY_VCO_DIV] = QSERDES_V4_DP_PHY_VCO_DIV, 131 130 132 131 [QPHY_TX_TX_POL_INV] = QSERDES_V4_TX_TX_POL_INV, 133 132 [QPHY_TX_TX_DRV_LVL] = QSERDES_V4_TX_TX_DRV_LVL, ··· 153 150 [QPHY_COM_BIAS_EN_CLKBUFLR_EN] = QSERDES_V5_COM_BIAS_EN_CLKBUFLR_EN, 154 151 155 152 [QPHY_DP_PHY_STATUS] = QSERDES_V5_DP_PHY_STATUS, 153 + [QPHY_DP_PHY_VCO_DIV] = QSERDES_V5_DP_PHY_VCO_DIV, 156 154 157 155 [QPHY_TX_TX_POL_INV] = QSERDES_V5_5NM_TX_TX_POL_INV, 158 156 [QPHY_TX_TX_DRV_LVL] = QSERDES_V5_5NM_TX_TX_DRV_LVL, ··· 178 174 [QPHY_COM_BIAS_EN_CLKBUFLR_EN] = QSERDES_V6_COM_PLL_BIAS_EN_CLK_BUFLR_EN, 179 175 180 176 [QPHY_DP_PHY_STATUS] = QSERDES_V6_DP_PHY_STATUS, 177 + [QPHY_DP_PHY_VCO_DIV] = QSERDES_V6_DP_PHY_VCO_DIV, 181 178 182 179 [QPHY_TX_TX_POL_INV] = QSERDES_V6_TX_TX_POL_INV, 183 180 [QPHY_TX_TX_DRV_LVL] = QSERDES_V6_TX_TX_DRV_LVL, ··· 2155 2150 writel(val, qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL); 2156 2151 2157 2152 if (reverse) 2158 - writel(0x4c, qmp->pcs + QSERDES_DP_PHY_MODE); 2153 + writel(0x4c, qmp->dp_dp_phy + QSERDES_DP_PHY_MODE); 2159 2154 else 2160 - writel(0x5c, qmp->pcs + QSERDES_DP_PHY_MODE); 2155 + writel(0x5c, qmp->dp_dp_phy + QSERDES_DP_PHY_MODE); 2161 2156 2162 2157 return reverse; 2163 2158 } ··· 2167 2162 const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts; 2168 2163 u32 phy_vco_div; 2169 2164 unsigned long pixel_freq; 2165 + const struct qmp_phy_cfg *cfg = qmp->cfg; 2170 2166 2171 2167 switch (dp_opts->link_rate) { 2172 2168 case 1620: ··· 2190 2184 /* Other link rates aren't supported */ 2191 2185 return -EINVAL; 2192 2186 } 2193 - writel(phy_vco_div, qmp->dp_dp_phy + QSERDES_V4_DP_PHY_VCO_DIV); 2187 + writel(phy_vco_div, qmp->dp_dp_phy + cfg->regs[QPHY_DP_PHY_VCO_DIV]); 2194 2188 2195 2189 clk_set_rate(qmp->dp_link_hw.clk, dp_opts->link_rate * 100000); 2196 2190 clk_set_rate(qmp->dp_pixel_hw.clk, pixel_freq);
+1
drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v5.h
··· 7 7 #define QCOM_PHY_QMP_DP_PHY_V5_H_ 8 8 9 9 /* Only for QMP V5 PHY - DP PHY registers */ 10 + #define QSERDES_V5_DP_PHY_VCO_DIV 0x070 10 11 #define QSERDES_V5_DP_PHY_AUX_INTERRUPT_STATUS 0x0d8 11 12 #define QSERDES_V5_DP_PHY_STATUS 0x0dc 12 13
+1
drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v6.h
··· 7 7 #define QCOM_PHY_QMP_DP_PHY_V6_H_ 8 8 9 9 /* Only for QMP V6 PHY - DP PHY registers */ 10 + #define QSERDES_V6_DP_PHY_VCO_DIV 0x070 10 11 #define QSERDES_V6_DP_PHY_AUX_INTERRUPT_STATUS 0x0e0 11 12 #define QSERDES_V6_DP_PHY_STATUS 0x0e4 12 13
+1
drivers/phy/rockchip/Kconfig
··· 87 87 tristate "Rockchip Samsung HDMI/eDP Combo PHY driver" 88 88 depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF 89 89 select GENERIC_PHY 90 + select RATIONAL 90 91 help 91 92 Enable this to support the Rockchip HDMI/eDP Combo PHY 92 93 with Samsung IP block.
+33 -3
drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
··· 125 125 }; 126 126 127 127 struct rockchip_combphy_cfg { 128 + unsigned int num_phys; 129 + unsigned int phy_ids[3]; 128 130 const struct rockchip_combphy_grfcfg *grfcfg; 129 131 int (*combphy_cfg)(struct rockchip_combphy_priv *priv); 130 132 }; 131 133 132 134 struct rockchip_combphy_priv { 133 135 u8 type; 136 + int id; 134 137 void __iomem *mmio; 135 138 int num_clks; 136 139 struct clk_bulk_data *clks; ··· 323 320 struct rockchip_combphy_priv *priv; 324 321 const struct rockchip_combphy_cfg *phy_cfg; 325 322 struct resource *res; 326 - int ret; 323 + int ret, id; 327 324 328 325 phy_cfg = of_device_get_match_data(dev); 329 326 if (!phy_cfg) { ··· 339 336 if (IS_ERR(priv->mmio)) { 340 337 ret = PTR_ERR(priv->mmio); 341 338 return ret; 339 + } 340 + 341 + /* find the phy-id from the io address */ 342 + priv->id = -ENODEV; 343 + for (id = 0; id < phy_cfg->num_phys; id++) { 344 + if (res->start == phy_cfg->phy_ids[id]) { 345 + priv->id = id; 346 + break; 347 + } 342 348 } 343 349 344 350 priv->dev = dev; ··· 574 562 }; 575 563 576 564 static const struct rockchip_combphy_cfg rk3568_combphy_cfgs = { 565 + .num_phys = 3, 566 + .phy_ids = { 567 + 0xfe820000, 568 + 0xfe830000, 569 + 0xfe840000, 570 + }, 577 571 .grfcfg = &rk3568_combphy_grfcfgs, 578 572 .combphy_cfg = rk3568_combphy_cfg, 579 573 }; ··· 596 578 rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true); 597 579 rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_pcie, true); 598 580 rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_pcie, true); 599 - rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_pcie1l0_sel, true); 600 - rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_pcie1l1_sel, true); 581 + switch (priv->id) { 582 + case 1: 583 + rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_pcie1l0_sel, true); 584 + break; 585 + case 2: 586 + rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_pcie1l1_sel, true); 587 + break; 588 + } 601 589 break; 602 590 case PHY_TYPE_USB3: 603 591 /* Set SSC downward spread spectrum */ ··· 760 736 }; 761 737 762 738 static const struct rockchip_combphy_cfg rk3588_combphy_cfgs = { 739 + .num_phys = 3, 740 + .phy_ids = { 741 + 0xfee00000, 742 + 0xfee10000, 743 + 0xfee20000, 744 + }, 763 745 .grfcfg = &rk3588_combphy_grfcfgs, 764 746 .combphy_cfg = rk3588_combphy_cfg, 765 747 };
+13 -18
drivers/phy/rockchip/phy-rockchip-snps-pcie3.c
··· 40 40 #define RK3588_BIFURCATION_LANE_0_1 BIT(0) 41 41 #define RK3588_BIFURCATION_LANE_2_3 BIT(1) 42 42 #define RK3588_LANE_AGGREGATION BIT(2) 43 + #define RK3588_PCIE1LN_SEL_EN (GENMASK(1, 0) << 16) 44 + #define RK3588_PCIE30_PHY_MODE_EN (GENMASK(2, 0) << 16) 43 45 44 46 struct rockchip_p3phy_ops; 45 47 ··· 134 132 static int rockchip_p3phy_rk3588_init(struct rockchip_p3phy_priv *priv) 135 133 { 136 134 u32 reg = 0; 137 - u8 mode = 0; 135 + u8 mode = RK3588_LANE_AGGREGATION; /* default */ 138 136 int ret; 139 137 140 138 /* Deassert PCIe PMA output clamp mode */ ··· 142 140 143 141 /* Set bifurcation if needed */ 144 142 for (int i = 0; i < priv->num_lanes; i++) { 145 - if (!priv->lanes[i]) 146 - mode |= (BIT(i) << 3); 147 - 148 143 if (priv->lanes[i] > 1) 149 - mode |= (BIT(i) >> 1); 144 + mode &= ~RK3588_LANE_AGGREGATION; 145 + if (priv->lanes[i] == 3) 146 + mode |= RK3588_BIFURCATION_LANE_0_1; 147 + if (priv->lanes[i] == 4) 148 + mode |= RK3588_BIFURCATION_LANE_2_3; 150 149 } 151 150 152 - if (!mode) 153 - reg = RK3588_LANE_AGGREGATION; 154 - else { 155 - if (mode & (BIT(0) | BIT(1))) 156 - reg |= RK3588_BIFURCATION_LANE_0_1; 157 - 158 - if (mode & (BIT(2) | BIT(3))) 159 - reg |= RK3588_BIFURCATION_LANE_2_3; 160 - } 161 - 162 - regmap_write(priv->phy_grf, RK3588_PCIE3PHY_GRF_CMN_CON0, (0x7<<16) | reg); 151 + reg = mode; 152 + regmap_write(priv->phy_grf, RK3588_PCIE3PHY_GRF_CMN_CON0, 153 + RK3588_PCIE30_PHY_MODE_EN | reg); 163 154 164 155 /* Set pcie1ln_sel in PHP_GRF_PCIESEL_CON */ 165 156 if (!IS_ERR(priv->pipe_grf)) { 166 - reg = (mode & (BIT(6) | BIT(7))) >> 6; 157 + reg = mode & (RK3588_BIFURCATION_LANE_0_1 | RK3588_BIFURCATION_LANE_2_3); 167 158 if (reg) 168 159 regmap_write(priv->pipe_grf, PHP_GRF_PCIESEL_CON, 169 - (reg << 16) | reg); 160 + RK3588_PCIE1LN_SEL_EN | reg); 170 161 } 171 162 172 163 reset_control_deassert(priv->p30phy);
+12 -11
drivers/phy/ti/phy-tusb1210.c
··· 69 69 struct delayed_work chg_det_work; 70 70 struct notifier_block psy_nb; 71 71 struct power_supply *psy; 72 - struct power_supply *charger; 73 72 #endif 74 73 }; 75 74 ··· 235 236 236 237 static bool tusb1210_get_online(struct tusb1210 *tusb) 237 238 { 239 + struct power_supply *charger = NULL; 238 240 union power_supply_propval val; 239 - int i; 241 + bool online = false; 242 + int i, ret; 240 243 241 - for (i = 0; i < ARRAY_SIZE(tusb1210_chargers) && !tusb->charger; i++) 242 - tusb->charger = power_supply_get_by_name(tusb1210_chargers[i]); 244 + for (i = 0; i < ARRAY_SIZE(tusb1210_chargers) && !charger; i++) 245 + charger = power_supply_get_by_name(tusb1210_chargers[i]); 243 246 244 - if (!tusb->charger) 247 + if (!charger) 245 248 return false; 246 249 247 - if (power_supply_get_property(tusb->charger, POWER_SUPPLY_PROP_ONLINE, &val)) 248 - return false; 250 + ret = power_supply_get_property(charger, POWER_SUPPLY_PROP_ONLINE, &val); 251 + if (ret == 0) 252 + online = val.intval; 249 253 250 - return val.intval; 254 + power_supply_put(charger); 255 + 256 + return online; 251 257 } 252 258 253 259 static void tusb1210_chg_det_work(struct work_struct *work) ··· 477 473 cancel_delayed_work_sync(&tusb->chg_det_work); 478 474 power_supply_unregister(tusb->psy); 479 475 } 480 - 481 - if (tusb->charger) 482 - power_supply_put(tusb->charger); 483 476 } 484 477 #else 485 478 static void tusb1210_probe_charger_detect(struct tusb1210 *tusb) { }