File Index
Files and directories
Sign in
FILE

mtk-ge.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/phy/mediatek/mtk-ge.c C
  1// SPDX-License-Identifier: GPL-2.0+
  2#include <linux/bitfield.h>
  3#include <linux/module.h>
  4#include <linux/phy.h>
  5
  6#include "mtk.h"
  7
  8#define MTK_GPHY_ID_MT7530		0x03a29412
  9#define MTK_GPHY_ID_MT7531		0x03a29441
 10
 11#define MTK_PHY_PAGE_EXTENDED_2			0x0002
 12#define MTK_PHY_PAGE_EXTENDED_3			0x0003
 13#define MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG11	0x11
 14
 15#define MTK_PHY_PAGE_EXTENDED_2A30		0x2a30
 16
 17/* Registers on Token Ring debug nodes */
 18/* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x17 */
 19#define SLAVE_DSP_READY_TIME_MASK		GENMASK(22, 15)
 20
 21/* Registers on MDIO_MMD_VEND1 */
 22#define MTK_PHY_GBE_MODE_TX_DELAY_SEL		0x13
 23#define MTK_PHY_TEST_MODE_TX_DELAY_SEL		0x14
 24#define   MTK_TX_DELAY_PAIR_B_MASK		GENMASK(10, 8)
 25#define   MTK_TX_DELAY_PAIR_D_MASK		GENMASK(2, 0)
 26
 27#define MTK_PHY_MCC_CTRL_AND_TX_POWER_CTRL	0xa6
 28#define   MTK_MCC_NEARECHO_OFFSET_MASK		GENMASK(15, 8)
 29
 30#define MTK_PHY_RXADC_CTRL_RG7			0xc6
 31#define   MTK_PHY_DA_AD_BUF_BIAS_LP_MASK	GENMASK(9, 8)
 32
 33#define MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG123	0x123
 34#define   MTK_PHY_LPI_NORM_MSE_LO_THRESH100_MASK	GENMASK(15, 8)
 35#define   MTK_PHY_LPI_NORM_MSE_HI_THRESH100_MASK	GENMASK(7, 0)
 36
 37static void mtk_gephy_config_init(struct phy_device *phydev)
 38{
 39	/* Enable HW auto downshift */
 40	phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED_1,
 41			 MTK_PHY_AUX_CTRL_AND_STATUS,
 42			 0, MTK_PHY_ENABLE_DOWNSHIFT);
 43
 44	/* Increase SlvDPSready time */
 45	mtk_tr_modify(phydev, 0x1, 0xf, 0x17, SLAVE_DSP_READY_TIME_MASK,
 46		      FIELD_PREP(SLAVE_DSP_READY_TIME_MASK, 0x5e));
 47
 48	/* Adjust 100_mse_threshold */
 49	phy_modify_mmd(phydev, MDIO_MMD_VEND1,
 50		       MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG123,
 51		       MTK_PHY_LPI_NORM_MSE_LO_THRESH100_MASK |
 52		       MTK_PHY_LPI_NORM_MSE_HI_THRESH100_MASK,
 53		       FIELD_PREP(MTK_PHY_LPI_NORM_MSE_LO_THRESH100_MASK,
 54				  0xff) |
 55		       FIELD_PREP(MTK_PHY_LPI_NORM_MSE_HI_THRESH100_MASK,
 56				  0xff));
 57
 58	/* If echo time is narrower than 0x3, it will be regarded as noise */
 59	phy_modify_mmd(phydev, MDIO_MMD_VEND1,
 60		       MTK_PHY_MCC_CTRL_AND_TX_POWER_CTRL,
 61		       MTK_MCC_NEARECHO_OFFSET_MASK,
 62		       FIELD_PREP(MTK_MCC_NEARECHO_OFFSET_MASK, 0x3));
 63}
 64
 65static int mt7530_phy_config_init(struct phy_device *phydev)
 66{
 67	mtk_gephy_config_init(phydev);
 68
 69	/* Increase post_update_timer */
 70	phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3,
 71			MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG11, 0x4b);
 72
 73	return 0;
 74}
 75
 76static int mt7531_phy_config_init(struct phy_device *phydev)
 77{
 78	mtk_gephy_config_init(phydev);
 79
 80	/* PHY link down power saving enable */
 81	phy_set_bits(phydev, 0x17, BIT(4));
 82	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7,
 83		       MTK_PHY_DA_AD_BUF_BIAS_LP_MASK,
 84		       FIELD_PREP(MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3));
 85
 86	/* Set TX Pair delay selection */
 87	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_GBE_MODE_TX_DELAY_SEL,
 88		       MTK_TX_DELAY_PAIR_B_MASK | MTK_TX_DELAY_PAIR_D_MASK,
 89		       FIELD_PREP(MTK_TX_DELAY_PAIR_B_MASK, 0x4) |
 90		       FIELD_PREP(MTK_TX_DELAY_PAIR_D_MASK, 0x4));
 91	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TEST_MODE_TX_DELAY_SEL,
 92		       MTK_TX_DELAY_PAIR_B_MASK | MTK_TX_DELAY_PAIR_D_MASK,
 93		       FIELD_PREP(MTK_TX_DELAY_PAIR_B_MASK, 0x4) |
 94		       FIELD_PREP(MTK_TX_DELAY_PAIR_D_MASK, 0x4));
 95
 96	return 0;
 97}
 98
 99static struct phy_driver mtk_gephy_driver[] = {
100	{
101		PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7530),
102		.name		= "MediaTek MT7530 PHY",
103		.config_init	= mt7530_phy_config_init,
104		/* Interrupts are handled by the switch, not the PHY
105		 * itself.
106		 */
107		.config_intr	= genphy_no_config_intr,
108		.handle_interrupt = genphy_handle_interrupt_no_ack,
109		.suspend	= genphy_suspend,
110		.resume		= genphy_resume,
111		.read_page	= mtk_phy_read_page,
112		.write_page	= mtk_phy_write_page,
113	},
114	{
115		PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7531),
116		.name		= "MediaTek MT7531 PHY",
117		.config_init	= mt7531_phy_config_init,
118		/* Interrupts are handled by the switch, not the PHY
119		 * itself.
120		 */
121		.config_intr	= genphy_no_config_intr,
122		.handle_interrupt = genphy_handle_interrupt_no_ack,
123		.suspend	= genphy_suspend,
124		.resume		= genphy_resume,
125		.read_page	= mtk_phy_read_page,
126		.write_page	= mtk_phy_write_page,
127	},
128};
129
130module_phy_driver(mtk_gephy_driver);
131
132static const struct mdio_device_id __maybe_unused mtk_gephy_tbl[] = {
133	{ PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7530) },
134	{ PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7531) },
135	{ }
136};
137
138MODULE_DESCRIPTION("MediaTek Gigabit Ethernet PHY driver");
139MODULE_AUTHOR("DENG, Qingfang <dqfext@gmail.com>");
140MODULE_LICENSE("GPL");
141
142MODULE_DEVICE_TABLE(mdio, mtk_gephy_tbl);
~/ Read-only file preview.