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

phy: uniphier-pcie: Add dual-phy support for NX1 SoC

NX1 SoC supports 2 lanes and has dual-phy. Should set appropriate
configuration values to both PHY registers.

Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
Link: https://lore.kernel.org/r/1635503947-18250-7-git-send-email-hayashi.kunihiko@socionext.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Kunihiko Hayashi and committed by
Vinod Koul
7f1abed4 25bba42f

+34 -14
+34 -14
drivers/phy/socionext/phy-uniphier-pcie.c
··· 27 27 #define TESTI_DAT_MASK GENMASK(13, 6) 28 28 #define TESTI_ADR_MASK GENMASK(5, 1) 29 29 #define TESTI_WR_EN BIT(0) 30 + #define TESTIO_PHY_SHIFT 16 30 31 31 32 #define PCL_PHY_TEST_O 0x2004 32 33 #define TESTO_DAT_MASK GENMASK(7, 0) ··· 66 65 67 66 struct uniphier_pciephy_soc_data { 68 67 bool is_legacy; 68 + bool is_dual_phy; 69 69 void (*set_phymode)(struct regmap *regmap); 70 70 }; 71 71 72 72 static void uniphier_pciephy_testio_write(struct uniphier_pciephy_priv *priv, 73 - u32 data) 73 + int id, u32 data) 74 74 { 75 + if (id) 76 + data <<= TESTIO_PHY_SHIFT; 77 + 75 78 /* need to read TESTO twice after accessing TESTI */ 76 79 writel(data, priv->base + PCL_PHY_TEST_I); 77 80 readl(priv->base + PCL_PHY_TEST_O); 78 81 readl(priv->base + PCL_PHY_TEST_O); 79 82 } 80 83 84 + static u32 uniphier_pciephy_testio_read(struct uniphier_pciephy_priv *priv, int id) 85 + { 86 + u32 val = readl(priv->base + PCL_PHY_TEST_O); 87 + 88 + if (id) 89 + val >>= TESTIO_PHY_SHIFT; 90 + 91 + return val & TESTO_DAT_MASK; 92 + } 93 + 81 94 static void uniphier_pciephy_set_param(struct uniphier_pciephy_priv *priv, 82 - u32 reg, u32 mask, u32 param) 95 + int id, u32 reg, u32 mask, u32 param) 83 96 { 84 97 u32 val; 85 98 86 99 /* read previous data */ 87 100 val = FIELD_PREP(TESTI_DAT_MASK, 1); 88 101 val |= FIELD_PREP(TESTI_ADR_MASK, reg); 89 - uniphier_pciephy_testio_write(priv, val); 90 - val = readl(priv->base + PCL_PHY_TEST_O) & TESTO_DAT_MASK; 102 + uniphier_pciephy_testio_write(priv, id, val); 103 + val = uniphier_pciephy_testio_read(priv, id); 91 104 92 105 /* update value */ 93 106 val &= ~mask; 94 107 val |= mask & param; 95 108 val = FIELD_PREP(TESTI_DAT_MASK, val); 96 109 val |= FIELD_PREP(TESTI_ADR_MASK, reg); 97 - uniphier_pciephy_testio_write(priv, val); 98 - uniphier_pciephy_testio_write(priv, val | TESTI_WR_EN); 99 - uniphier_pciephy_testio_write(priv, val); 110 + uniphier_pciephy_testio_write(priv, id, val); 111 + uniphier_pciephy_testio_write(priv, id, val | TESTI_WR_EN); 112 + uniphier_pciephy_testio_write(priv, id, val); 100 113 101 114 /* read current data as dummy */ 102 115 val = FIELD_PREP(TESTI_DAT_MASK, 1); 103 116 val |= FIELD_PREP(TESTI_ADR_MASK, reg); 104 - uniphier_pciephy_testio_write(priv, val); 105 - readl(priv->base + PCL_PHY_TEST_O); 117 + uniphier_pciephy_testio_write(priv, id, val); 118 + uniphier_pciephy_testio_read(priv, id); 106 119 } 107 120 108 121 static void uniphier_pciephy_assert(struct uniphier_pciephy_priv *priv) ··· 142 127 { 143 128 struct uniphier_pciephy_priv *priv = phy_get_drvdata(phy); 144 129 u32 val; 145 - int ret; 130 + int ret, id; 146 131 147 132 ret = clk_prepare_enable(priv->clk); 148 133 if (ret) ··· 170 155 if (priv->data->is_legacy) 171 156 return 0; 172 157 173 - uniphier_pciephy_set_param(priv, PCL_PHY_R00, 158 + for (id = 0; id < (priv->data->is_dual_phy ? 2 : 1); id++) { 159 + uniphier_pciephy_set_param(priv, id, PCL_PHY_R00, 174 160 RX_EQ_ADJ_EN, RX_EQ_ADJ_EN); 175 - uniphier_pciephy_set_param(priv, PCL_PHY_R06, RX_EQ_ADJ, 161 + uniphier_pciephy_set_param(priv, id, PCL_PHY_R06, RX_EQ_ADJ, 176 162 FIELD_PREP(RX_EQ_ADJ, RX_EQ_ADJ_VAL)); 177 - uniphier_pciephy_set_param(priv, PCL_PHY_R26, VCO_CTRL, 163 + uniphier_pciephy_set_param(priv, id, PCL_PHY_R26, VCO_CTRL, 178 164 FIELD_PREP(VCO_CTRL, VCO_CTRL_INIT_VAL)); 179 - uniphier_pciephy_set_param(priv, PCL_PHY_R28, VCOPLL_CLMP, 165 + uniphier_pciephy_set_param(priv, id, PCL_PHY_R28, VCOPLL_CLMP, 180 166 FIELD_PREP(VCOPLL_CLMP, VCOPLL_CLMP_VAL)); 167 + } 181 168 usleep_range(1, 10); 182 169 183 170 uniphier_pciephy_deassert(priv); ··· 299 282 300 283 static const struct uniphier_pciephy_soc_data uniphier_ld20_data = { 301 284 .is_legacy = false, 285 + .is_dual_phy = false, 302 286 .set_phymode = uniphier_pciephy_ld20_setmode, 303 287 }; 304 288 305 289 static const struct uniphier_pciephy_soc_data uniphier_pxs3_data = { 306 290 .is_legacy = false, 291 + .is_dual_phy = false, 307 292 }; 308 293 309 294 static const struct uniphier_pciephy_soc_data uniphier_nx1_data = { 310 295 .is_legacy = false, 296 + .is_dual_phy = true, 311 297 .set_phymode = uniphier_pciephy_nx1_setmode, 312 298 }; 313 299