Skip to content

Commit efacb56

Browse files
Yixun Landavem330
authored andcommitted
net: stmmac: dwmac-meson: extend phy mode setting
In the Meson-AXG SoC, the phy mode setting of PRG_ETH0 in the glue layer is extended from bit[0] to bit[2:0]. There is no problem if we configure it to the RGMII 1000M PHY mode, since the register setting is coincidentally compatible with previous one, but for the RMII 100M PHY mode, the configuration need to be changed to value - b100. This patch was verified with a RTL8201F 100M ethernet PHY. Signed-off-by: Yixun Lan <[email protected]> Acked-by: Martin Blumenstingl <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 7e5d05e commit efacb56

File tree

1 file changed

+104
-16
lines changed

1 file changed

+104
-16
lines changed

drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c

Lines changed: 104 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <linux/io.h>
1919
#include <linux/ioport.h>
2020
#include <linux/module.h>
21+
#include <linux/of_device.h>
2122
#include <linux/of_net.h>
2223
#include <linux/mfd/syscon.h>
2324
#include <linux/platform_device.h>
@@ -29,6 +30,10 @@
2930

3031
#define PRG_ETH0_RGMII_MODE BIT(0)
3132

33+
#define PRG_ETH0_EXT_PHY_MODE_MASK GENMASK(2, 0)
34+
#define PRG_ETH0_EXT_RGMII_MODE 1
35+
#define PRG_ETH0_EXT_RMII_MODE 4
36+
3237
/* mux to choose between fclk_div2 (bit unset) and mpll2 (bit set) */
3338
#define PRG_ETH0_CLK_M250_SEL_SHIFT 4
3439
#define PRG_ETH0_CLK_M250_SEL_MASK GENMASK(4, 4)
@@ -47,12 +52,20 @@
4752

4853
#define MUX_CLK_NUM_PARENTS 2
4954

55+
struct meson8b_dwmac;
56+
57+
struct meson8b_dwmac_data {
58+
int (*set_phy_mode)(struct meson8b_dwmac *dwmac);
59+
};
60+
5061
struct meson8b_dwmac {
51-
struct device *dev;
52-
void __iomem *regs;
53-
phy_interface_t phy_mode;
54-
struct clk *rgmii_tx_clk;
55-
u32 tx_delay_ns;
62+
struct device *dev;
63+
void __iomem *regs;
64+
65+
const struct meson8b_dwmac_data *data;
66+
phy_interface_t phy_mode;
67+
struct clk *rgmii_tx_clk;
68+
u32 tx_delay_ns;
5669
};
5770

5871
struct meson8b_dwmac_clk_configs {
@@ -171,6 +184,59 @@ static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac *dwmac)
171184
return 0;
172185
}
173186

187+
static int meson8b_set_phy_mode(struct meson8b_dwmac *dwmac)
188+
{
189+
switch (dwmac->phy_mode) {
190+
case PHY_INTERFACE_MODE_RGMII:
191+
case PHY_INTERFACE_MODE_RGMII_RXID:
192+
case PHY_INTERFACE_MODE_RGMII_ID:
193+
case PHY_INTERFACE_MODE_RGMII_TXID:
194+
/* enable RGMII mode */
195+
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0,
196+
PRG_ETH0_RGMII_MODE,
197+
PRG_ETH0_RGMII_MODE);
198+
break;
199+
case PHY_INTERFACE_MODE_RMII:
200+
/* disable RGMII mode -> enables RMII mode */
201+
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0,
202+
PRG_ETH0_RGMII_MODE, 0);
203+
break;
204+
default:
205+
dev_err(dwmac->dev, "fail to set phy-mode %s\n",
206+
phy_modes(dwmac->phy_mode));
207+
return -EINVAL;
208+
}
209+
210+
return 0;
211+
}
212+
213+
static int meson_axg_set_phy_mode(struct meson8b_dwmac *dwmac)
214+
{
215+
switch (dwmac->phy_mode) {
216+
case PHY_INTERFACE_MODE_RGMII:
217+
case PHY_INTERFACE_MODE_RGMII_RXID:
218+
case PHY_INTERFACE_MODE_RGMII_ID:
219+
case PHY_INTERFACE_MODE_RGMII_TXID:
220+
/* enable RGMII mode */
221+
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0,
222+
PRG_ETH0_EXT_PHY_MODE_MASK,
223+
PRG_ETH0_EXT_RGMII_MODE);
224+
break;
225+
case PHY_INTERFACE_MODE_RMII:
226+
/* disable RGMII mode -> enables RMII mode */
227+
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0,
228+
PRG_ETH0_EXT_PHY_MODE_MASK,
229+
PRG_ETH0_EXT_RMII_MODE);
230+
break;
231+
default:
232+
dev_err(dwmac->dev, "fail to set phy-mode %s\n",
233+
phy_modes(dwmac->phy_mode));
234+
return -EINVAL;
235+
}
236+
237+
return 0;
238+
}
239+
174240
static int meson8b_init_prg_eth(struct meson8b_dwmac *dwmac)
175241
{
176242
int ret;
@@ -188,10 +254,6 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac *dwmac)
188254

189255
case PHY_INTERFACE_MODE_RGMII_ID:
190256
case PHY_INTERFACE_MODE_RGMII_TXID:
191-
/* enable RGMII mode */
192-
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_RGMII_MODE,
193-
PRG_ETH0_RGMII_MODE);
194-
195257
/* only relevant for RMII mode -> disable in RGMII mode */
196258
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0,
197259
PRG_ETH0_INVERTED_RMII_CLK, 0);
@@ -224,10 +286,6 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac *dwmac)
224286
break;
225287

226288
case PHY_INTERFACE_MODE_RMII:
227-
/* disable RGMII mode -> enables RMII mode */
228-
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_RGMII_MODE,
229-
0);
230-
231289
/* invert internal clk_rmii_i to generate 25/2.5 tx_rx_clk */
232290
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0,
233291
PRG_ETH0_INVERTED_RMII_CLK,
@@ -274,6 +332,11 @@ static int meson8b_dwmac_probe(struct platform_device *pdev)
274332
goto err_remove_config_dt;
275333
}
276334

335+
dwmac->data = (const struct meson8b_dwmac_data *)
336+
of_device_get_match_data(&pdev->dev);
337+
if (!dwmac->data)
338+
return -EINVAL;
339+
277340
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
278341
dwmac->regs = devm_ioremap_resource(&pdev->dev, res);
279342
if (IS_ERR(dwmac->regs)) {
@@ -298,6 +361,10 @@ static int meson8b_dwmac_probe(struct platform_device *pdev)
298361
if (ret)
299362
goto err_remove_config_dt;
300363

364+
ret = dwmac->data->set_phy_mode(dwmac);
365+
if (ret)
366+
goto err_remove_config_dt;
367+
301368
ret = meson8b_init_prg_eth(dwmac);
302369
if (ret)
303370
goto err_remove_config_dt;
@@ -316,10 +383,31 @@ static int meson8b_dwmac_probe(struct platform_device *pdev)
316383
return ret;
317384
}
318385

386+
static const struct meson8b_dwmac_data meson8b_dwmac_data = {
387+
.set_phy_mode = meson8b_set_phy_mode,
388+
};
389+
390+
static const struct meson8b_dwmac_data meson_axg_dwmac_data = {
391+
.set_phy_mode = meson_axg_set_phy_mode,
392+
};
393+
319394
static const struct of_device_id meson8b_dwmac_match[] = {
320-
{ .compatible = "amlogic,meson8b-dwmac" },
321-
{ .compatible = "amlogic,meson8m2-dwmac" },
322-
{ .compatible = "amlogic,meson-gxbb-dwmac" },
395+
{
396+
.compatible = "amlogic,meson8b-dwmac",
397+
.data = &meson8b_dwmac_data,
398+
},
399+
{
400+
.compatible = "amlogic,meson8m2-dwmac",
401+
.data = &meson8b_dwmac_data,
402+
},
403+
{
404+
.compatible = "amlogic,meson-gxbb-dwmac",
405+
.data = &meson8b_dwmac_data,
406+
},
407+
{
408+
.compatible = "amlogic,meson-axg-dwmac",
409+
.data = &meson_axg_dwmac_data,
410+
},
323411
{ }
324412
};
325413
MODULE_DEVICE_TABLE(of, meson8b_dwmac_match);

0 commit comments

Comments
 (0)