Skip to content

Commit 6d31f2d

Browse files
committed
net: phy: mediatek: i2p5g: add support for mt7987
1 parent 7cd33ba commit 6d31f2d

1 file changed

Lines changed: 342 additions & 3 deletions

File tree

drivers/net/phy/mediatek/mtk-2p5ge.c

Lines changed: 342 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,77 @@
99

1010
#include "mtk.h"
1111

12+
#define MTK_2P5GPHY_ID_MT7987 0x00339c91
1213
#define MTK_2P5GPHY_ID_MT7988 0x00339c11
1314

15+
#define MT7987_2P5GE_PMB_FW "mediatek/mt7987/i2p5ge-phy-pmb.bin"
16+
#define MT7987_2P5GE_PMB_FW_SIZE 0x18000
17+
#define MT7987_2P5GE_DSPBITTB \
18+
"mediatek/mt7987/i2p5ge-phy-DSPBitTb.bin"
19+
#define MT7987_2P5GE_DSPBITTB_SIZE 0x7000
20+
1421
#define MT7988_2P5GE_PMB_FW "mediatek/mt7988/i2p5ge-phy-pmb.bin"
1522
#define MT7988_2P5GE_PMB_FW_SIZE 0x20000
1623
#define MT7988_2P5GE_PMB_FW_BASE 0x0f100000
1724
#define MT7988_2P5GE_PMB_FW_LEN 0x20000
25+
26+
#define MTK_2P5GPHY_PMD_REG_BASE 0x0f010000
27+
#define MTK_2P5GPHY_PMD_REG_LEN 0x210
28+
#define DO_NOT_RESET 0x28
29+
#define DO_NOT_RESET_XBZ BIT(0)
30+
#define DO_NOT_RESET_PMA BIT(3)
31+
#define DO_NOT_RESET_RX BIT(5)
32+
#define FNPLL_PWR_CTRL1 0x208
33+
#define RG_SPEED_MASK GENMASK(3, 0)
34+
#define RG_SPEED_2500 BIT(3)
35+
#define RG_SPEED_100 BIT(0)
36+
#define FNPLL_PWR_CTRL_STATUS 0x20c
37+
#define RG_STABLE_MASK GENMASK(3, 0)
38+
#define RG_SPEED_2500_STABLE BIT(3)
39+
#define RG_SPEED_100_STABLE BIT(0)
40+
41+
#define MTK_2P5GPHY_XBZ_PCS_REG_BASE 0x0f030000
42+
#define MTK_2P5GPHY_XBZ_PCS_REG_LEN 0x844
43+
#define PHY_CTRL_CONFIG 0x200
44+
#define PMU_WP 0x800
45+
#define WRITE_PROTECT_KEY 0xCAFEF00D
46+
#define PMU_PMA_AUTO_CFG 0x820
47+
#define POWER_ON_AUTO_MODE BIT(16)
48+
#define PMU_AUTO_MODE_EN BIT(0)
49+
#define PMU_PMA_STATUS 0x840
50+
#define CLK_IS_DISABLED BIT(3)
51+
52+
#define MTK_2P5GPHY_XBZ_PMA_RX_BASE 0x0f080000
53+
#define MTK_2P5GPHY_XBZ_PMA_RX_LEN 0x5228
54+
#define SMEM_WDAT0 0x5000
55+
#define SMEM_WDAT1 0x5004
56+
#define SMEM_WDAT2 0x5008
57+
#define SMEM_WDAT3 0x500c
58+
#define SMEM_CTRL 0x5024
59+
#define SMEM_HW_RDATA_ZERO BIT(24)
60+
#define SMEM_ADDR_REF_ADDR 0x502c
61+
#define CM_CTRL_P01 0x5100
62+
#define CM_CTRL_P23 0x5124
63+
#define DM_CTRL_P01 0x5200
64+
#define DM_CTRL_P23 0x5224
65+
66+
#define MTK_2P5GPHY_CHIP_SCU_BASE 0x0f0cf800
67+
#define MTK_2P5GPHY_CHIP_SCU_LEN 0x12c
68+
#define SYS_SW_RESET 0x128
69+
#define RESET_RST_CNT BIT(0)
70+
1871
#define MTK_2P5GPHY_MCU_CSR_BASE 0x0f0f0000
1972
#define MTK_2P5GPHY_MCU_CSR_LEN 0x20
73+
2074
#define MD32_EN_CFG 0x18
21-
#define MD32_EN BIT(0)
75+
#define MD32_EN BIT(0)
76+
77+
#define MTK_2P5GPHY_PMB_FW_BASE 0x0f100000
78+
79+
#define MTK_2P5GPHY_APB_BASE 0x11c30000
80+
#define MTK_2P5GPHY_APB_LEN 0x9c
81+
#define SW_RESET 0x94
82+
#define MD32_RESTART_EN_CLEAR BIT(9)
2283

2384
#define BASE100T_STATUS_EXTEND 0x10
2485
#define BASE1000T_STATUS_EXTEND 0x11
@@ -32,6 +93,14 @@
3293
#define MTK_PHY_LPI_PCS_DSP_CTRL 0x121
3394
#define MTK_PHY_LPI_SIG_EN_LO_THRESH100_MASK GENMASK(12, 8)
3495

96+
#define MTK_PHY_LINK_STATUS_RELATED (0x147)
97+
#define MTK_PHY_BYPASS_LINK_STATUS_OK BIT(4)
98+
#define MTK_PHY_FORCE_LINK_STATUS_HCD BIT(3)
99+
100+
#define MTK_PHY_AN_FORCE_SPEED_REG (0x313)
101+
#define MTK_PHY_MASTER_FORCE_SPEED_SEL_EN BIT(7)
102+
#define MTK_PHY_MASTER_FORCE_SPEED_SEL_MASK GENMASK(6, 0)
103+
35104
#define MTK_PHY_HOST_CMD1 0x800e
36105
#define MTK_PHY_HOST_CMD2 0x800f
37106
/* Registers on Token Ring debug nodes */
@@ -45,7 +114,249 @@ enum {
45114
PHY_AUX_SPD_2500,
46115
};
47116

48-
static int mt798x_2p5ge_phy_load_fw(struct phy_device *phydev)
117+
static int mt7987_2p5ge_phy_load_fw(struct phy_device *phydev)
118+
{
119+
struct mtk_i2p5ge_phy_priv *priv = phydev->priv;
120+
struct device *dev = &phydev->mdio.dev;
121+
void __iomem *xbz_pcs_reg_base;
122+
void __iomem *xbz_pma_rx_base;
123+
void __iomem *chip_scu_base;
124+
void __iomem *pmd_reg_base;
125+
void __iomem *mcu_csr_base;
126+
const struct firmware *fw;
127+
void __iomem *apb_base;
128+
void __iomem *pmb_addr;
129+
int ret, i;
130+
u32 reg;
131+
132+
if (priv->fw_loaded)
133+
return 0;
134+
135+
apb_base = ioremap(MTK_2P5GPHY_APB_BASE,
136+
MTK_2P5GPHY_APB_LEN);
137+
if (!apb_base)
138+
return -ENOMEM;
139+
140+
pmd_reg_base = ioremap(MTK_2P5GPHY_PMD_REG_BASE,
141+
MTK_2P5GPHY_PMD_REG_LEN);
142+
if (!pmd_reg_base) {
143+
ret = -ENOMEM;
144+
goto free_apb;
145+
}
146+
147+
xbz_pcs_reg_base = ioremap(MTK_2P5GPHY_XBZ_PCS_REG_BASE,
148+
MTK_2P5GPHY_XBZ_PCS_REG_LEN);
149+
if (!xbz_pcs_reg_base) {
150+
ret = -ENOMEM;
151+
goto free_pmd;
152+
}
153+
154+
xbz_pma_rx_base = ioremap(MTK_2P5GPHY_XBZ_PMA_RX_BASE,
155+
MTK_2P5GPHY_XBZ_PMA_RX_LEN);
156+
if (!xbz_pma_rx_base) {
157+
ret = -ENOMEM;
158+
goto free_pcs;
159+
}
160+
161+
chip_scu_base = ioremap(MTK_2P5GPHY_CHIP_SCU_BASE,
162+
MTK_2P5GPHY_CHIP_SCU_LEN);
163+
if (!chip_scu_base) {
164+
ret = -ENOMEM;
165+
goto free_pma;
166+
}
167+
168+
mcu_csr_base = ioremap(MTK_2P5GPHY_MCU_CSR_BASE,
169+
MTK_2P5GPHY_MCU_CSR_LEN);
170+
if (!mcu_csr_base) {
171+
ret = -ENOMEM;
172+
goto free_chip_scu;
173+
}
174+
175+
pmb_addr = ioremap(MTK_2P5GPHY_PMB_FW_BASE, MT7987_2P5GE_PMB_FW_SIZE);
176+
if (!pmb_addr) {
177+
return -ENOMEM;
178+
goto free_mcu_csr;
179+
}
180+
181+
ret = request_firmware(&fw, MT7987_2P5GE_PMB_FW, dev);
182+
if (ret) {
183+
dev_err(dev, "failed to load firmware: %s, ret: %d\n",
184+
MT7987_2P5GE_PMB_FW, ret);
185+
goto free_pmb_addr;
186+
}
187+
188+
if (fw->size != MT7987_2P5GE_PMB_FW_SIZE) {
189+
dev_err(dev, "PMb firmware size 0x%zx != 0x%x\n",
190+
fw->size, MT7987_2P5GE_PMB_FW_SIZE);
191+
ret = -EINVAL;
192+
goto release_fw;
193+
}
194+
195+
/* Force 2.5Gphy back to AN state */
196+
phy_set_bits(phydev, MII_BMCR, BMCR_RESET);
197+
usleep_range(5000, 6000);
198+
phy_set_bits(phydev, MII_BMCR, BMCR_PDOWN);
199+
200+
reg = readw(apb_base + SW_RESET);
201+
writew(reg & ~MD32_RESTART_EN_CLEAR, apb_base + SW_RESET);
202+
writew(reg | MD32_RESTART_EN_CLEAR, apb_base + SW_RESET);
203+
writew(reg & ~MD32_RESTART_EN_CLEAR, apb_base + SW_RESET);
204+
205+
reg = readw(mcu_csr_base + MD32_EN_CFG);
206+
writew(reg & ~MD32_EN, mcu_csr_base + MD32_EN_CFG);
207+
208+
for (i = 0; i < MT7987_2P5GE_PMB_FW_SIZE - 1; i += 4)
209+
writel(*((uint32_t *)(fw->data + i)), pmb_addr + i);
210+
dev_info(dev, "Firmware date code: %x/%x/%x, version: %x.%x\n",
211+
be16_to_cpu(*((__be16 *)(fw->data +
212+
MT7987_2P5GE_PMB_FW_SIZE - 8))),
213+
*(fw->data + MT7987_2P5GE_PMB_FW_SIZE - 6),
214+
*(fw->data + MT7987_2P5GE_PMB_FW_SIZE - 5),
215+
*(fw->data + MT7987_2P5GE_PMB_FW_SIZE - 2),
216+
*(fw->data + MT7987_2P5GE_PMB_FW_SIZE - 1));
217+
release_firmware(fw);
218+
219+
/* Enable 100Mbps module clock. */
220+
writel(FIELD_PREP(RG_SPEED_MASK, RG_SPEED_100),
221+
pmd_reg_base + FNPLL_PWR_CTRL1);
222+
223+
/* Check if 100Mbps module clock is ready. */
224+
ret = readl_poll_timeout(pmd_reg_base + FNPLL_PWR_CTRL_STATUS, reg,
225+
reg & RG_SPEED_100_STABLE, 1, 10000);
226+
if (ret)
227+
dev_err(dev, "Fail to enable 100Mbps module clock: %d\n", ret);
228+
229+
/* Enable 2.5Gbps module clock. */
230+
writel(FIELD_PREP(RG_SPEED_MASK, RG_SPEED_2500),
231+
pmd_reg_base + FNPLL_PWR_CTRL1);
232+
233+
/* Check if 2.5Gbps module clock is ready. */
234+
ret = readl_poll_timeout(pmd_reg_base + FNPLL_PWR_CTRL_STATUS, reg,
235+
reg & RG_SPEED_2500_STABLE, 1, 10000);
236+
237+
if (ret)
238+
dev_err(dev, "Fail to enable 2.5Gbps module clock: %d\n", ret);
239+
240+
/* Disable AN */
241+
phy_clear_bits(phydev, MII_BMCR, BMCR_ANENABLE);
242+
243+
/* Force to run at 2.5G speed */
244+
phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_AN_FORCE_SPEED_REG,
245+
MTK_PHY_MASTER_FORCE_SPEED_SEL_MASK,
246+
MTK_PHY_MASTER_FORCE_SPEED_SEL_EN |
247+
FIELD_PREP(MTK_PHY_MASTER_FORCE_SPEED_SEL_MASK, 0x1b));
248+
249+
phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LINK_STATUS_RELATED,
250+
MTK_PHY_BYPASS_LINK_STATUS_OK |
251+
MTK_PHY_FORCE_LINK_STATUS_HCD);
252+
253+
/* Set xbz, pma and rx as "do not reset" in order to input DSP code. */
254+
reg = readl(pmd_reg_base + DO_NOT_RESET);
255+
reg |= DO_NOT_RESET_XBZ | DO_NOT_RESET_PMA | DO_NOT_RESET_RX;
256+
writel(reg, pmd_reg_base + DO_NOT_RESET);
257+
258+
reg = readl(chip_scu_base + SYS_SW_RESET);
259+
writel(reg & ~RESET_RST_CNT, chip_scu_base + SYS_SW_RESET);
260+
261+
writel(WRITE_PROTECT_KEY, xbz_pcs_reg_base + PMU_WP);
262+
263+
reg = readl(xbz_pcs_reg_base + PMU_PMA_AUTO_CFG);
264+
reg |= PMU_AUTO_MODE_EN | POWER_ON_AUTO_MODE;
265+
writel(reg, xbz_pcs_reg_base + PMU_PMA_AUTO_CFG);
266+
267+
/* Check if clock in auto mode is disabled. */
268+
ret = readl_poll_timeout(xbz_pcs_reg_base + PMU_PMA_STATUS, reg,
269+
(reg & CLK_IS_DISABLED) == 0x0, 1, 100000);
270+
if (ret)
271+
dev_err(dev, "Clock isn't disabled in auto mode: %d\n", ret);
272+
273+
reg = readl(xbz_pma_rx_base + SMEM_CTRL);
274+
writel(reg | SMEM_HW_RDATA_ZERO, xbz_pma_rx_base + SMEM_CTRL);
275+
276+
reg = readl(xbz_pcs_reg_base + PHY_CTRL_CONFIG);
277+
writel(reg | BIT(16), xbz_pcs_reg_base + PHY_CTRL_CONFIG);
278+
279+
/* Initialize data memory */
280+
reg = readl(xbz_pma_rx_base + DM_CTRL_P01);
281+
writel(reg | BIT(28), xbz_pma_rx_base + DM_CTRL_P01);
282+
reg = readl(xbz_pma_rx_base + DM_CTRL_P23);
283+
writel(reg | BIT(28), xbz_pma_rx_base + DM_CTRL_P23);
284+
285+
/* Initialize coefficient memory */
286+
reg = readl(xbz_pma_rx_base + CM_CTRL_P01);
287+
writel(reg | BIT(28), xbz_pma_rx_base + CM_CTRL_P01);
288+
reg = readl(xbz_pma_rx_base + CM_CTRL_P23);
289+
writel(reg | BIT(28), xbz_pma_rx_base + CM_CTRL_P23);
290+
291+
/* Initilize PM offset */
292+
writel(0, xbz_pma_rx_base + SMEM_ADDR_REF_ADDR);
293+
294+
ret = request_firmware(&fw, MT7987_2P5GE_DSPBITTB, dev);
295+
if (ret) {
296+
dev_err(dev, "failed to load firmware: %s, ret: %d\n",
297+
MT7987_2P5GE_DSPBITTB, ret);
298+
goto free_pmb_addr;
299+
}
300+
if (fw->size != MT7987_2P5GE_DSPBITTB_SIZE) {
301+
dev_err(dev, "DSPBITTB size 0x%zx != 0x%x\n",
302+
fw->size, MT7987_2P5GE_DSPBITTB_SIZE);
303+
ret = -EINVAL;
304+
goto release_fw;
305+
}
306+
307+
for (i = 0; i < fw->size - 1; i += 16) {
308+
writel(*((uint32_t *)(fw->data + i)),
309+
xbz_pma_rx_base + SMEM_WDAT0);
310+
writel(*((uint32_t *)(fw->data + i + 0x4)),
311+
xbz_pma_rx_base + SMEM_WDAT1);
312+
writel(*((uint32_t *)(fw->data + i + 0x8)),
313+
xbz_pma_rx_base + SMEM_WDAT2);
314+
writel(*((uint32_t *)(fw->data + i + 0xc)),
315+
xbz_pma_rx_base + SMEM_WDAT3);
316+
}
317+
318+
reg = readl(xbz_pma_rx_base + DM_CTRL_P01);
319+
writel(reg & ~BIT(28), xbz_pma_rx_base + DM_CTRL_P01);
320+
321+
reg = readl(xbz_pma_rx_base + DM_CTRL_P23);
322+
writel(reg & ~BIT(28), xbz_pma_rx_base + DM_CTRL_P23);
323+
324+
reg = readl(xbz_pma_rx_base + CM_CTRL_P01);
325+
writel(reg & ~BIT(28), xbz_pma_rx_base + CM_CTRL_P01);
326+
327+
reg = readl(xbz_pma_rx_base + CM_CTRL_P23);
328+
writel(reg & ~BIT(28), xbz_pma_rx_base + CM_CTRL_P23);
329+
330+
reg = readw(mcu_csr_base + MD32_EN_CFG);
331+
writew(reg | MD32_EN, mcu_csr_base + MD32_EN_CFG);
332+
phy_set_bits(phydev, MII_BMCR, BMCR_RESET);
333+
/* We need a delay here to stabilize initialization of MCU */
334+
usleep_range(7000, 8000);
335+
dev_info(dev, "Firmware loading/trigger ok.\n");
336+
337+
priv->fw_loaded = true;
338+
339+
release_fw:
340+
release_firmware(fw);
341+
free_pmb_addr:
342+
iounmap(pmb_addr);
343+
free_mcu_csr:
344+
iounmap(mcu_csr_base);
345+
free_chip_scu:
346+
iounmap(chip_scu_base);
347+
free_pma:
348+
iounmap(xbz_pma_rx_base);
349+
free_pcs:
350+
iounmap(xbz_pcs_reg_base);
351+
free_pmd:
352+
iounmap(pmd_reg_base);
353+
free_apb:
354+
iounmap(apb_base);
355+
356+
return ret;
357+
}
358+
359+
static int mt7988_2p5ge_phy_load_fw(struct phy_device *phydev)
49360
{
50361
struct device *dev = &phydev->mdio.dev;
51362
void __iomem *mcu_csr_base, *pmb_addr;
@@ -255,6 +566,7 @@ static int mt798x_2p5ge_phy_probe(struct phy_device *phydev)
255566
int ret;
256567

257568
switch (phydev->drv->phy_id) {
569+
case MTK_2P5GPHY_ID_MT7987:
258570
case MTK_2P5GPHY_ID_MT7988:
259571
/* This built-in 2.5GbE hardware only sets MDIO_DEVS_PMAPMD.
260572
* Set the rest by this driver since PCS/AN/VEND1/VEND2 MDIO
@@ -269,7 +581,20 @@ static int mt798x_2p5ge_phy_probe(struct phy_device *phydev)
269581
return -EINVAL;
270582
}
271583

272-
ret = mt798x_2p5ge_phy_load_fw(phydev);
584+
switch (phydev->drv->phy_id) {
585+
case MTK_2P5GPHY_ID_MT7987:
586+
ret = mt7987_2p5ge_phy_load_fw(phydev);
587+
phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
588+
MTK_PHY_LED_ON_POLARITY);
589+
break;
590+
case MTK_2P5GPHY_ID_MT7988:
591+
ret = mt7988_2p5ge_phy_load_fw(phydev);
592+
phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
593+
MTK_PHY_LED_ON_POLARITY);
594+
break;
595+
default:
596+
return -EINVAL;
597+
}
273598
if (ret < 0)
274599
return ret;
275600

@@ -290,6 +615,20 @@ static int mt798x_2p5ge_phy_probe(struct phy_device *phydev)
290615
}
291616

292617
static struct phy_driver mtk_2p5gephy_driver[] = {
618+
{
619+
PHY_ID_MATCH_MODEL(MTK_2P5GPHY_ID_MT7987),
620+
.name = "MediaTek MT7987 2.5GbE PHY",
621+
.probe = mt798x_2p5ge_phy_probe,
622+
.config_init = mt798x_2p5ge_phy_config_init,
623+
.config_aneg = mt798x_2p5ge_phy_config_aneg,
624+
.get_features = mt798x_2p5ge_phy_get_features,
625+
.read_status = mt798x_2p5ge_phy_read_status,
626+
.get_rate_matching = mt798x_2p5ge_phy_get_rate_matching,
627+
.suspend = genphy_suspend,
628+
.resume = genphy_resume,
629+
.read_page = mtk_phy_read_page,
630+
.write_page = mtk_phy_write_page,
631+
},
293632
{
294633
PHY_ID_MATCH_MODEL(MTK_2P5GPHY_ID_MT7988),
295634
.name = "MediaTek MT7988 2.5GbE PHY",

0 commit comments

Comments
 (0)