xref: /openbmc/u-boot/drivers/net/mt7628-eth.c (revision 6f443330)
1*c895ef46SStefan Roese // SPDX-License-Identifier: GPL-2.0+
2*c895ef46SStefan Roese /*
3*c895ef46SStefan Roese  * MediaTek ethernet IP driver for U-Boot
4*c895ef46SStefan Roese  *
5*c895ef46SStefan Roese  * Copyright (C) 2018 Stefan Roese <sr@denx.de>
6*c895ef46SStefan Roese  *
7*c895ef46SStefan Roese  * This code is mostly based on the code extracted from this MediaTek
8*c895ef46SStefan Roese  * github repository:
9*c895ef46SStefan Roese  *
10*c895ef46SStefan Roese  * https://github.com/MediaTek-Labs/linkit-smart-uboot.git
11*c895ef46SStefan Roese  *
12*c895ef46SStefan Roese  * I was not able to find a specific license or other developers
13*c895ef46SStefan Roese  * copyrights here, so I can't add them here.
14*c895ef46SStefan Roese  */
15*c895ef46SStefan Roese 
16*c895ef46SStefan Roese #include <common.h>
17*c895ef46SStefan Roese #include <dm.h>
18*c895ef46SStefan Roese #include <malloc.h>
19*c895ef46SStefan Roese #include <miiphy.h>
20*c895ef46SStefan Roese #include <net.h>
21*c895ef46SStefan Roese #include <regmap.h>
22*c895ef46SStefan Roese #include <syscon.h>
23*c895ef46SStefan Roese #include <wait_bit.h>
24*c895ef46SStefan Roese #include <asm/io.h>
25*c895ef46SStefan Roese #include <linux/bitfield.h>
26*c895ef46SStefan Roese #include <linux/err.h>
27*c895ef46SStefan Roese 
28*c895ef46SStefan Roese /* System controller register */
29*c895ef46SStefan Roese #define MT7628_RSTCTRL_REG	0x34
30*c895ef46SStefan Roese #define RSTCTRL_EPHY_RST	BIT(24)
31*c895ef46SStefan Roese 
32*c895ef46SStefan Roese #define MT7628_AGPIO_CFG_REG	0x3c
33*c895ef46SStefan Roese #define MT7628_EPHY_GPIO_AIO_EN	GENMASK(20, 17)
34*c895ef46SStefan Roese #define MT7628_EPHY_P0_DIS	BIT(16)
35*c895ef46SStefan Roese 
36*c895ef46SStefan Roese #define MT7628_GPIO2_MODE_REG	0x64
37*c895ef46SStefan Roese 
38*c895ef46SStefan Roese /* Ethernet frame engine register */
39*c895ef46SStefan Roese #define PDMA_RELATED		0x0800
40*c895ef46SStefan Roese 
41*c895ef46SStefan Roese #define TX_BASE_PTR0		(PDMA_RELATED + 0x000)
42*c895ef46SStefan Roese #define TX_MAX_CNT0		(PDMA_RELATED + 0x004)
43*c895ef46SStefan Roese #define TX_CTX_IDX0		(PDMA_RELATED + 0x008)
44*c895ef46SStefan Roese #define TX_DTX_IDX0		(PDMA_RELATED + 0x00c)
45*c895ef46SStefan Roese 
46*c895ef46SStefan Roese #define RX_BASE_PTR0		(PDMA_RELATED + 0x100)
47*c895ef46SStefan Roese #define RX_MAX_CNT0		(PDMA_RELATED + 0x104)
48*c895ef46SStefan Roese #define RX_CALC_IDX0		(PDMA_RELATED + 0x108)
49*c895ef46SStefan Roese 
50*c895ef46SStefan Roese #define PDMA_GLO_CFG		(PDMA_RELATED + 0x204)
51*c895ef46SStefan Roese #define PDMA_RST_IDX		(PDMA_RELATED + 0x208)
52*c895ef46SStefan Roese #define DLY_INT_CFG		(PDMA_RELATED + 0x20c)
53*c895ef46SStefan Roese 
54*c895ef46SStefan Roese #define SDM_RELATED		0x0c00
55*c895ef46SStefan Roese 
56*c895ef46SStefan Roese #define SDM_MAC_ADRL		(SDM_RELATED + 0x0c)	/* MAC address LSB */
57*c895ef46SStefan Roese #define SDM_MAC_ADRH		(SDM_RELATED + 0x10)	/* MAC Address MSB */
58*c895ef46SStefan Roese 
59*c895ef46SStefan Roese #define RST_DTX_IDX0		BIT(0)
60*c895ef46SStefan Roese #define RST_DRX_IDX0		BIT(16)
61*c895ef46SStefan Roese 
62*c895ef46SStefan Roese #define TX_DMA_EN		BIT(0)
63*c895ef46SStefan Roese #define TX_DMA_BUSY		BIT(1)
64*c895ef46SStefan Roese #define RX_DMA_EN		BIT(2)
65*c895ef46SStefan Roese #define RX_DMA_BUSY		BIT(3)
66*c895ef46SStefan Roese #define TX_WB_DDONE		BIT(6)
67*c895ef46SStefan Roese 
68*c895ef46SStefan Roese /* Ethernet switch register */
69*c895ef46SStefan Roese #define MT7628_SWITCH_FCT0	0x0008
70*c895ef46SStefan Roese #define MT7628_SWITCH_PFC1	0x0014
71*c895ef46SStefan Roese #define MT7628_SWITCH_FPA	0x0084
72*c895ef46SStefan Roese #define MT7628_SWITCH_SOCPC	0x008c
73*c895ef46SStefan Roese #define MT7628_SWITCH_POC0	0x0090
74*c895ef46SStefan Roese #define MT7628_SWITCH_POC2	0x0098
75*c895ef46SStefan Roese #define MT7628_SWITCH_SGC	0x009c
76*c895ef46SStefan Roese #define MT7628_SWITCH_PCR0	0x00c0
77*c895ef46SStefan Roese #define PCR0_PHY_ADDR		GENMASK(4, 0)
78*c895ef46SStefan Roese #define PCR0_PHY_REG		GENMASK(12, 8)
79*c895ef46SStefan Roese #define PCR0_WT_PHY_CMD		BIT(13)
80*c895ef46SStefan Roese #define PCR0_RD_PHY_CMD		BIT(14)
81*c895ef46SStefan Roese #define PCR0_WT_DATA		GENMASK(31, 16)
82*c895ef46SStefan Roese 
83*c895ef46SStefan Roese #define MT7628_SWITCH_PCR1	0x00c4
84*c895ef46SStefan Roese #define PCR1_WT_DONE		BIT(0)
85*c895ef46SStefan Roese #define PCR1_RD_RDY		BIT(1)
86*c895ef46SStefan Roese #define PCR1_RD_DATA		GENMASK(31, 16)
87*c895ef46SStefan Roese 
88*c895ef46SStefan Roese #define MT7628_SWITCH_FPA1	0x00c8
89*c895ef46SStefan Roese #define MT7628_SWITCH_FCT2	0x00cc
90*c895ef46SStefan Roese #define MT7628_SWITCH_SGC2	0x00e4
91*c895ef46SStefan Roese #define MT7628_SWITCH_BMU_CTRL	0x0110
92*c895ef46SStefan Roese 
93*c895ef46SStefan Roese /* rxd2 */
94*c895ef46SStefan Roese #define RX_DMA_DONE		BIT(31)
95*c895ef46SStefan Roese #define RX_DMA_LSO		BIT(30)
96*c895ef46SStefan Roese #define RX_DMA_PLEN0		GENMASK(29, 16)
97*c895ef46SStefan Roese #define RX_DMA_TAG		BIT(15)
98*c895ef46SStefan Roese 
99*c895ef46SStefan Roese struct fe_rx_dma {
100*c895ef46SStefan Roese 	unsigned int rxd1;
101*c895ef46SStefan Roese 	unsigned int rxd2;
102*c895ef46SStefan Roese 	unsigned int rxd3;
103*c895ef46SStefan Roese 	unsigned int rxd4;
104*c895ef46SStefan Roese } __packed __aligned(4);
105*c895ef46SStefan Roese 
106*c895ef46SStefan Roese #define TX_DMA_PLEN0		GENMASK(29, 16)
107*c895ef46SStefan Roese #define TX_DMA_LS1		BIT(14)
108*c895ef46SStefan Roese #define TX_DMA_LS0		BIT(30)
109*c895ef46SStefan Roese #define TX_DMA_DONE		BIT(31)
110*c895ef46SStefan Roese 
111*c895ef46SStefan Roese #define TX_DMA_INS_VLAN_MT7621	BIT(16)
112*c895ef46SStefan Roese #define TX_DMA_INS_VLAN		BIT(7)
113*c895ef46SStefan Roese #define TX_DMA_INS_PPPOE	BIT(12)
114*c895ef46SStefan Roese #define TX_DMA_PN		GENMASK(26, 24)
115*c895ef46SStefan Roese 
116*c895ef46SStefan Roese struct fe_tx_dma {
117*c895ef46SStefan Roese 	unsigned int txd1;
118*c895ef46SStefan Roese 	unsigned int txd2;
119*c895ef46SStefan Roese 	unsigned int txd3;
120*c895ef46SStefan Roese 	unsigned int txd4;
121*c895ef46SStefan Roese } __packed __aligned(4);
122*c895ef46SStefan Roese 
123*c895ef46SStefan Roese #define NUM_RX_DESC		256
124*c895ef46SStefan Roese #define NUM_TX_DESC		4
125*c895ef46SStefan Roese 
126*c895ef46SStefan Roese #define PADDING_LENGTH		60
127*c895ef46SStefan Roese 
128*c895ef46SStefan Roese #define MTK_QDMA_PAGE_SIZE	2048
129*c895ef46SStefan Roese 
130*c895ef46SStefan Roese #define CONFIG_MDIO_TIMEOUT	100
131*c895ef46SStefan Roese #define CONFIG_DMA_STOP_TIMEOUT	100
132*c895ef46SStefan Roese #define CONFIG_TX_DMA_TIMEOUT	100
133*c895ef46SStefan Roese 
134*c895ef46SStefan Roese #define LINK_DELAY_TIME		500		/* 500 ms */
135*c895ef46SStefan Roese #define LINK_TIMEOUT		10000		/* 10 seconds */
136*c895ef46SStefan Roese 
137*c895ef46SStefan Roese struct mt7628_eth_dev {
138*c895ef46SStefan Roese 	void __iomem *base;		/* frame engine base address */
139*c895ef46SStefan Roese 	void __iomem *eth_sw_base;	/* switch base address */
140*c895ef46SStefan Roese 	struct regmap *sysctrl_regmap;	/* system-controller reg-map */
141*c895ef46SStefan Roese 
142*c895ef46SStefan Roese 	struct mii_dev *bus;
143*c895ef46SStefan Roese 
144*c895ef46SStefan Roese 	struct fe_tx_dma *tx_ring;
145*c895ef46SStefan Roese 	struct fe_rx_dma *rx_ring;
146*c895ef46SStefan Roese 
147*c895ef46SStefan Roese 	u8 *rx_buf[NUM_RX_DESC];
148*c895ef46SStefan Roese 
149*c895ef46SStefan Roese 	/* Point to the next RXD DMA wants to use in RXD Ring0 */
150*c895ef46SStefan Roese 	int rx_dma_idx;
151*c895ef46SStefan Roese 	/* Point to the next TXD in TXD Ring0 CPU wants to use */
152*c895ef46SStefan Roese 	int tx_dma_idx;
153*c895ef46SStefan Roese };
154*c895ef46SStefan Roese 
mdio_wait_read(struct mt7628_eth_dev * priv,u32 mask,bool mask_set)155*c895ef46SStefan Roese static int mdio_wait_read(struct mt7628_eth_dev *priv, u32 mask, bool mask_set)
156*c895ef46SStefan Roese {
157*c895ef46SStefan Roese 	void __iomem *base = priv->eth_sw_base;
158*c895ef46SStefan Roese 	int ret;
159*c895ef46SStefan Roese 
160*c895ef46SStefan Roese 	ret = wait_for_bit_le32(base + MT7628_SWITCH_PCR1, mask, mask_set,
161*c895ef46SStefan Roese 				CONFIG_MDIO_TIMEOUT, false);
162*c895ef46SStefan Roese 	if (ret) {
163*c895ef46SStefan Roese 		printf("MDIO operation timeout!\n");
164*c895ef46SStefan Roese 		return -ETIMEDOUT;
165*c895ef46SStefan Roese 	}
166*c895ef46SStefan Roese 
167*c895ef46SStefan Roese 	return 0;
168*c895ef46SStefan Roese }
169*c895ef46SStefan Roese 
mii_mgr_read(struct mt7628_eth_dev * priv,u32 phy_addr,u32 phy_register,u32 * read_data)170*c895ef46SStefan Roese static int mii_mgr_read(struct mt7628_eth_dev *priv,
171*c895ef46SStefan Roese 			u32 phy_addr, u32 phy_register, u32 *read_data)
172*c895ef46SStefan Roese {
173*c895ef46SStefan Roese 	void __iomem *base = priv->eth_sw_base;
174*c895ef46SStefan Roese 	u32 status = 0;
175*c895ef46SStefan Roese 	u32 ret;
176*c895ef46SStefan Roese 
177*c895ef46SStefan Roese 	*read_data = 0xffff;
178*c895ef46SStefan Roese 	/* Make sure previous read operation is complete */
179*c895ef46SStefan Roese 	ret = mdio_wait_read(priv, PCR1_RD_RDY, false);
180*c895ef46SStefan Roese 	if (ret)
181*c895ef46SStefan Roese 		return ret;
182*c895ef46SStefan Roese 
183*c895ef46SStefan Roese 	writel(PCR0_RD_PHY_CMD |
184*c895ef46SStefan Roese 	       FIELD_PREP(PCR0_PHY_REG, phy_register) |
185*c895ef46SStefan Roese 	       FIELD_PREP(PCR0_PHY_ADDR, phy_addr),
186*c895ef46SStefan Roese 	       base + MT7628_SWITCH_PCR0);
187*c895ef46SStefan Roese 
188*c895ef46SStefan Roese 	/* Make sure previous read operation is complete */
189*c895ef46SStefan Roese 	ret = mdio_wait_read(priv, PCR1_RD_RDY, true);
190*c895ef46SStefan Roese 	if (ret)
191*c895ef46SStefan Roese 		return ret;
192*c895ef46SStefan Roese 
193*c895ef46SStefan Roese 	status = readl(base + MT7628_SWITCH_PCR1);
194*c895ef46SStefan Roese 	*read_data = FIELD_GET(PCR1_RD_DATA, status);
195*c895ef46SStefan Roese 
196*c895ef46SStefan Roese 	return 0;
197*c895ef46SStefan Roese }
198*c895ef46SStefan Roese 
mii_mgr_write(struct mt7628_eth_dev * priv,u32 phy_addr,u32 phy_register,u32 write_data)199*c895ef46SStefan Roese static int mii_mgr_write(struct mt7628_eth_dev *priv,
200*c895ef46SStefan Roese 			 u32 phy_addr, u32 phy_register, u32 write_data)
201*c895ef46SStefan Roese {
202*c895ef46SStefan Roese 	void __iomem *base = priv->eth_sw_base;
203*c895ef46SStefan Roese 	u32 data;
204*c895ef46SStefan Roese 	int ret;
205*c895ef46SStefan Roese 
206*c895ef46SStefan Roese 	/* Make sure previous write operation is complete */
207*c895ef46SStefan Roese 	ret = mdio_wait_read(priv, PCR1_WT_DONE, false);
208*c895ef46SStefan Roese 	if (ret)
209*c895ef46SStefan Roese 		return ret;
210*c895ef46SStefan Roese 
211*c895ef46SStefan Roese 	data = FIELD_PREP(PCR0_WT_DATA, write_data) |
212*c895ef46SStefan Roese 		FIELD_PREP(PCR0_PHY_REG, phy_register) |
213*c895ef46SStefan Roese 		FIELD_PREP(PCR0_PHY_ADDR, phy_addr) |
214*c895ef46SStefan Roese 		PCR0_WT_PHY_CMD;
215*c895ef46SStefan Roese 	writel(data, base + MT7628_SWITCH_PCR0);
216*c895ef46SStefan Roese 
217*c895ef46SStefan Roese 	return mdio_wait_read(priv, PCR1_WT_DONE, true);
218*c895ef46SStefan Roese }
219*c895ef46SStefan Roese 
mt7628_mdio_read(struct mii_dev * bus,int addr,int devad,int reg)220*c895ef46SStefan Roese static int mt7628_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
221*c895ef46SStefan Roese {
222*c895ef46SStefan Roese 	u32 val;
223*c895ef46SStefan Roese 	int ret;
224*c895ef46SStefan Roese 
225*c895ef46SStefan Roese 	ret = mii_mgr_read(bus->priv, addr, reg, &val);
226*c895ef46SStefan Roese 	if (ret)
227*c895ef46SStefan Roese 		return ret;
228*c895ef46SStefan Roese 
229*c895ef46SStefan Roese 	return val;
230*c895ef46SStefan Roese }
231*c895ef46SStefan Roese 
mt7628_mdio_write(struct mii_dev * bus,int addr,int devad,int reg,u16 value)232*c895ef46SStefan Roese static int mt7628_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
233*c895ef46SStefan Roese 			     u16 value)
234*c895ef46SStefan Roese {
235*c895ef46SStefan Roese 	return mii_mgr_write(bus->priv, addr, reg, value);
236*c895ef46SStefan Roese }
237*c895ef46SStefan Roese 
mt7628_ephy_init(struct mt7628_eth_dev * priv)238*c895ef46SStefan Roese static void mt7628_ephy_init(struct mt7628_eth_dev *priv)
239*c895ef46SStefan Roese {
240*c895ef46SStefan Roese 	int i;
241*c895ef46SStefan Roese 
242*c895ef46SStefan Roese 	mii_mgr_write(priv, 0, 31, 0x2000);	/* change G2 page */
243*c895ef46SStefan Roese 	mii_mgr_write(priv, 0, 26, 0x0000);
244*c895ef46SStefan Roese 
245*c895ef46SStefan Roese 	for (i = 0; i < 5; i++) {
246*c895ef46SStefan Roese 		mii_mgr_write(priv, i, 31, 0x8000);	/* change L0 page */
247*c895ef46SStefan Roese 		mii_mgr_write(priv, i,  0, 0x3100);
248*c895ef46SStefan Roese 
249*c895ef46SStefan Roese 		/* EEE disable */
250*c895ef46SStefan Roese 		mii_mgr_write(priv, i, 30, 0xa000);
251*c895ef46SStefan Roese 		mii_mgr_write(priv, i, 31, 0xa000);	/* change L2 page */
252*c895ef46SStefan Roese 		mii_mgr_write(priv, i, 16, 0x0606);
253*c895ef46SStefan Roese 		mii_mgr_write(priv, i, 23, 0x0f0e);
254*c895ef46SStefan Roese 		mii_mgr_write(priv, i, 24, 0x1610);
255*c895ef46SStefan Roese 		mii_mgr_write(priv, i, 30, 0x1f15);
256*c895ef46SStefan Roese 		mii_mgr_write(priv, i, 28, 0x6111);
257*c895ef46SStefan Roese 	}
258*c895ef46SStefan Roese 
259*c895ef46SStefan Roese 	/* 100Base AOI setting */
260*c895ef46SStefan Roese 	mii_mgr_write(priv, 0, 31, 0x5000);	/* change G5 page */
261*c895ef46SStefan Roese 	mii_mgr_write(priv, 0, 19, 0x004a);
262*c895ef46SStefan Roese 	mii_mgr_write(priv, 0, 20, 0x015a);
263*c895ef46SStefan Roese 	mii_mgr_write(priv, 0, 21, 0x00ee);
264*c895ef46SStefan Roese 	mii_mgr_write(priv, 0, 22, 0x0033);
265*c895ef46SStefan Roese 	mii_mgr_write(priv, 0, 23, 0x020a);
266*c895ef46SStefan Roese 	mii_mgr_write(priv, 0, 24, 0x0000);
267*c895ef46SStefan Roese 	mii_mgr_write(priv, 0, 25, 0x024a);
268*c895ef46SStefan Roese 	mii_mgr_write(priv, 0, 26, 0x035a);
269*c895ef46SStefan Roese 	mii_mgr_write(priv, 0, 27, 0x02ee);
270*c895ef46SStefan Roese 	mii_mgr_write(priv, 0, 28, 0x0233);
271*c895ef46SStefan Roese 	mii_mgr_write(priv, 0, 29, 0x000a);
272*c895ef46SStefan Roese 	mii_mgr_write(priv, 0, 30, 0x0000);
273*c895ef46SStefan Roese 
274*c895ef46SStefan Roese 	/* Fix EPHY idle state abnormal behavior */
275*c895ef46SStefan Roese 	mii_mgr_write(priv, 0, 31, 0x4000);	/* change G4 page */
276*c895ef46SStefan Roese 	mii_mgr_write(priv, 0, 29, 0x000d);
277*c895ef46SStefan Roese 	mii_mgr_write(priv, 0, 30, 0x0500);
278*c895ef46SStefan Roese }
279*c895ef46SStefan Roese 
rt305x_esw_init(struct mt7628_eth_dev * priv)280*c895ef46SStefan Roese static void rt305x_esw_init(struct mt7628_eth_dev *priv)
281*c895ef46SStefan Roese {
282*c895ef46SStefan Roese 	void __iomem *base = priv->eth_sw_base;
283*c895ef46SStefan Roese 
284*c895ef46SStefan Roese 	/*
285*c895ef46SStefan Roese 	 * FC_RLS_TH=200, FC_SET_TH=160
286*c895ef46SStefan Roese 	 * DROP_RLS=120, DROP_SET_TH=80
287*c895ef46SStefan Roese 	 */
288*c895ef46SStefan Roese 	writel(0xc8a07850, base + MT7628_SWITCH_FCT0);
289*c895ef46SStefan Roese 	writel(0x00000000, base + MT7628_SWITCH_SGC2);
290*c895ef46SStefan Roese 	writel(0x00405555, base + MT7628_SWITCH_PFC1);
291*c895ef46SStefan Roese 	writel(0x00007f7f, base + MT7628_SWITCH_POC0);
292*c895ef46SStefan Roese 	writel(0x00007f7f, base + MT7628_SWITCH_POC2);	/* disable VLAN */
293*c895ef46SStefan Roese 	writel(0x0002500c, base + MT7628_SWITCH_FCT2);
294*c895ef46SStefan Roese 	/* hashing algorithm=XOR48, aging interval=300sec */
295*c895ef46SStefan Roese 	writel(0x0008a301, base + MT7628_SWITCH_SGC);
296*c895ef46SStefan Roese 	writel(0x02404040, base + MT7628_SWITCH_SOCPC);
297*c895ef46SStefan Roese 
298*c895ef46SStefan Roese 	/* Ext PHY Addr=0x1f */
299*c895ef46SStefan Roese 	writel(0x3f502b28, base + MT7628_SWITCH_FPA1);
300*c895ef46SStefan Roese 	writel(0x00000000, base + MT7628_SWITCH_FPA);
301*c895ef46SStefan Roese 	/* 1us cycle number=125 (FE's clock=125Mhz) */
302*c895ef46SStefan Roese 	writel(0x7d000000, base + MT7628_SWITCH_BMU_CTRL);
303*c895ef46SStefan Roese 
304*c895ef46SStefan Roese 	/* Configure analog GPIO setup */
305*c895ef46SStefan Roese 	regmap_update_bits(priv->sysctrl_regmap, MT7628_AGPIO_CFG_REG,
306*c895ef46SStefan Roese 			   MT7628_EPHY_P0_DIS, MT7628_EPHY_GPIO_AIO_EN);
307*c895ef46SStefan Roese 
308*c895ef46SStefan Roese 	/* Reset PHY */
309*c895ef46SStefan Roese 	regmap_update_bits(priv->sysctrl_regmap, MT7628_RSTCTRL_REG,
310*c895ef46SStefan Roese 			   0, RSTCTRL_EPHY_RST);
311*c895ef46SStefan Roese 	regmap_update_bits(priv->sysctrl_regmap, MT7628_RSTCTRL_REG,
312*c895ef46SStefan Roese 			   RSTCTRL_EPHY_RST, 0);
313*c895ef46SStefan Roese 	mdelay(10);
314*c895ef46SStefan Roese 
315*c895ef46SStefan Roese 	/* Set P0 EPHY LED mode */
316*c895ef46SStefan Roese 	regmap_update_bits(priv->sysctrl_regmap, MT7628_GPIO2_MODE_REG,
317*c895ef46SStefan Roese 			   0x0ffc0ffc, 0x05540554);
318*c895ef46SStefan Roese 	mdelay(10);
319*c895ef46SStefan Roese 
320*c895ef46SStefan Roese 	mt7628_ephy_init(priv);
321*c895ef46SStefan Roese }
322*c895ef46SStefan Roese 
eth_dma_start(struct mt7628_eth_dev * priv)323*c895ef46SStefan Roese static void eth_dma_start(struct mt7628_eth_dev *priv)
324*c895ef46SStefan Roese {
325*c895ef46SStefan Roese 	void __iomem *base = priv->base;
326*c895ef46SStefan Roese 
327*c895ef46SStefan Roese 	setbits_le32(base + PDMA_GLO_CFG, TX_WB_DDONE | RX_DMA_EN | TX_DMA_EN);
328*c895ef46SStefan Roese }
329*c895ef46SStefan Roese 
eth_dma_stop(struct mt7628_eth_dev * priv)330*c895ef46SStefan Roese static void eth_dma_stop(struct mt7628_eth_dev *priv)
331*c895ef46SStefan Roese {
332*c895ef46SStefan Roese 	void __iomem *base = priv->base;
333*c895ef46SStefan Roese 	int ret;
334*c895ef46SStefan Roese 
335*c895ef46SStefan Roese 	clrbits_le32(base + PDMA_GLO_CFG, TX_WB_DDONE | RX_DMA_EN | TX_DMA_EN);
336*c895ef46SStefan Roese 
337*c895ef46SStefan Roese 	/* Wait for DMA to stop */
338*c895ef46SStefan Roese 	ret = wait_for_bit_le32(base + PDMA_GLO_CFG,
339*c895ef46SStefan Roese 				RX_DMA_BUSY | TX_DMA_BUSY, false,
340*c895ef46SStefan Roese 				CONFIG_DMA_STOP_TIMEOUT, false);
341*c895ef46SStefan Roese 	if (ret)
342*c895ef46SStefan Roese 		printf("DMA stop timeout error!\n");
343*c895ef46SStefan Roese }
344*c895ef46SStefan Roese 
mt7628_eth_write_hwaddr(struct udevice * dev)345*c895ef46SStefan Roese static int mt7628_eth_write_hwaddr(struct udevice *dev)
346*c895ef46SStefan Roese {
347*c895ef46SStefan Roese 	struct mt7628_eth_dev *priv = dev_get_priv(dev);
348*c895ef46SStefan Roese 	void __iomem *base = priv->base;
349*c895ef46SStefan Roese 	u8 *addr = ((struct eth_pdata *)dev_get_platdata(dev))->enetaddr;
350*c895ef46SStefan Roese 	u32 val;
351*c895ef46SStefan Roese 
352*c895ef46SStefan Roese 	/* Set MAC address. */
353*c895ef46SStefan Roese 	val = addr[0];
354*c895ef46SStefan Roese 	val = (val << 8) | addr[1];
355*c895ef46SStefan Roese 	writel(val, base + SDM_MAC_ADRH);
356*c895ef46SStefan Roese 
357*c895ef46SStefan Roese 	val = addr[2];
358*c895ef46SStefan Roese 	val = (val << 8) | addr[3];
359*c895ef46SStefan Roese 	val = (val << 8) | addr[4];
360*c895ef46SStefan Roese 	val = (val << 8) | addr[5];
361*c895ef46SStefan Roese 	writel(val, base + SDM_MAC_ADRL);
362*c895ef46SStefan Roese 
363*c895ef46SStefan Roese 	return 0;
364*c895ef46SStefan Roese }
365*c895ef46SStefan Roese 
mt7628_eth_send(struct udevice * dev,void * packet,int length)366*c895ef46SStefan Roese static int mt7628_eth_send(struct udevice *dev, void *packet, int length)
367*c895ef46SStefan Roese {
368*c895ef46SStefan Roese 	struct mt7628_eth_dev *priv = dev_get_priv(dev);
369*c895ef46SStefan Roese 	void __iomem *base = priv->base;
370*c895ef46SStefan Roese 	int ret;
371*c895ef46SStefan Roese 	int idx;
372*c895ef46SStefan Roese 	int i;
373*c895ef46SStefan Roese 
374*c895ef46SStefan Roese 	idx = priv->tx_dma_idx;
375*c895ef46SStefan Roese 
376*c895ef46SStefan Roese 	/* Pad message to a minimum length */
377*c895ef46SStefan Roese 	if (length < PADDING_LENGTH) {
378*c895ef46SStefan Roese 		char *p = (char *)packet;
379*c895ef46SStefan Roese 
380*c895ef46SStefan Roese 		for (i = 0; i < PADDING_LENGTH - length; i++)
381*c895ef46SStefan Roese 			p[length + i] = 0;
382*c895ef46SStefan Roese 		length = PADDING_LENGTH;
383*c895ef46SStefan Roese 	}
384*c895ef46SStefan Roese 
385*c895ef46SStefan Roese 	/* Check if buffer is ready for next TX DMA */
386*c895ef46SStefan Roese 	ret = wait_for_bit_le32(&priv->tx_ring[idx].txd2, TX_DMA_DONE, true,
387*c895ef46SStefan Roese 				CONFIG_TX_DMA_TIMEOUT, false);
388*c895ef46SStefan Roese 	if (ret) {
389*c895ef46SStefan Roese 		printf("TX: DMA still busy on buffer %d\n", idx);
390*c895ef46SStefan Roese 		return ret;
391*c895ef46SStefan Roese 	}
392*c895ef46SStefan Roese 
393*c895ef46SStefan Roese 	flush_dcache_range((u32)packet, (u32)packet + length);
394*c895ef46SStefan Roese 
395*c895ef46SStefan Roese 	priv->tx_ring[idx].txd1 = CPHYSADDR(packet);
396*c895ef46SStefan Roese 	priv->tx_ring[idx].txd2 &= ~TX_DMA_PLEN0;
397*c895ef46SStefan Roese 	priv->tx_ring[idx].txd2 |= FIELD_PREP(TX_DMA_PLEN0, length);
398*c895ef46SStefan Roese 	priv->tx_ring[idx].txd2 &= ~TX_DMA_DONE;
399*c895ef46SStefan Roese 
400*c895ef46SStefan Roese 	idx = (idx + 1) % NUM_TX_DESC;
401*c895ef46SStefan Roese 
402*c895ef46SStefan Roese 	/* Make sure the writes executed at this place */
403*c895ef46SStefan Roese 	wmb();
404*c895ef46SStefan Roese 	writel(idx, base + TX_CTX_IDX0);
405*c895ef46SStefan Roese 
406*c895ef46SStefan Roese 	priv->tx_dma_idx = idx;
407*c895ef46SStefan Roese 
408*c895ef46SStefan Roese 	return 0;
409*c895ef46SStefan Roese }
410*c895ef46SStefan Roese 
mt7628_eth_recv(struct udevice * dev,int flags,uchar ** packetp)411*c895ef46SStefan Roese static int mt7628_eth_recv(struct udevice *dev, int flags, uchar **packetp)
412*c895ef46SStefan Roese {
413*c895ef46SStefan Roese 	struct mt7628_eth_dev *priv = dev_get_priv(dev);
414*c895ef46SStefan Roese 	u32 rxd_info;
415*c895ef46SStefan Roese 	int length;
416*c895ef46SStefan Roese 	int idx;
417*c895ef46SStefan Roese 
418*c895ef46SStefan Roese 	idx = priv->rx_dma_idx;
419*c895ef46SStefan Roese 
420*c895ef46SStefan Roese 	rxd_info = priv->rx_ring[idx].rxd2;
421*c895ef46SStefan Roese 	if ((rxd_info & RX_DMA_DONE) == 0)
422*c895ef46SStefan Roese 		return -EAGAIN;
423*c895ef46SStefan Roese 
424*c895ef46SStefan Roese 	length = FIELD_GET(RX_DMA_PLEN0, priv->rx_ring[idx].rxd2);
425*c895ef46SStefan Roese 	if (length == 0 || length > MTK_QDMA_PAGE_SIZE) {
426*c895ef46SStefan Roese 		printf("%s: invalid length (%d bytes)\n", __func__, length);
427*c895ef46SStefan Roese 		return -EIO;
428*c895ef46SStefan Roese 	}
429*c895ef46SStefan Roese 
430*c895ef46SStefan Roese 	*packetp = priv->rx_buf[idx];
431*c895ef46SStefan Roese 	invalidate_dcache_range((u32)*packetp, (u32)*packetp + length);
432*c895ef46SStefan Roese 
433*c895ef46SStefan Roese 	priv->rx_ring[idx].rxd4 = 0;
434*c895ef46SStefan Roese 	priv->rx_ring[idx].rxd2 = RX_DMA_LSO;
435*c895ef46SStefan Roese 
436*c895ef46SStefan Roese 	/* Make sure the writes executed at this place */
437*c895ef46SStefan Roese 	wmb();
438*c895ef46SStefan Roese 
439*c895ef46SStefan Roese 	return length;
440*c895ef46SStefan Roese }
441*c895ef46SStefan Roese 
mt7628_eth_free_pkt(struct udevice * dev,uchar * packet,int length)442*c895ef46SStefan Roese static int mt7628_eth_free_pkt(struct udevice *dev, uchar *packet, int length)
443*c895ef46SStefan Roese {
444*c895ef46SStefan Roese 	struct mt7628_eth_dev *priv = dev_get_priv(dev);
445*c895ef46SStefan Roese 	void __iomem *base = priv->base;
446*c895ef46SStefan Roese 	int idx;
447*c895ef46SStefan Roese 
448*c895ef46SStefan Roese 	idx = priv->rx_dma_idx;
449*c895ef46SStefan Roese 
450*c895ef46SStefan Roese 	/* Move point to next RXD which wants to alloc */
451*c895ef46SStefan Roese 	writel(idx, base + RX_CALC_IDX0);
452*c895ef46SStefan Roese 
453*c895ef46SStefan Roese 	/* Update to Next packet point that was received */
454*c895ef46SStefan Roese 	idx = (idx + 1) % NUM_RX_DESC;
455*c895ef46SStefan Roese 
456*c895ef46SStefan Roese 	priv->rx_dma_idx = idx;
457*c895ef46SStefan Roese 
458*c895ef46SStefan Roese 	return 0;
459*c895ef46SStefan Roese }
460*c895ef46SStefan Roese 
phy_link_up(struct mt7628_eth_dev * priv)461*c895ef46SStefan Roese static int phy_link_up(struct mt7628_eth_dev *priv)
462*c895ef46SStefan Roese {
463*c895ef46SStefan Roese 	u32 val;
464*c895ef46SStefan Roese 
465*c895ef46SStefan Roese 	mii_mgr_read(priv, 0x00, MII_BMSR, &val);
466*c895ef46SStefan Roese 	return !!(val & BMSR_LSTATUS);
467*c895ef46SStefan Roese }
468*c895ef46SStefan Roese 
mt7628_eth_start(struct udevice * dev)469*c895ef46SStefan Roese static int mt7628_eth_start(struct udevice *dev)
470*c895ef46SStefan Roese {
471*c895ef46SStefan Roese 	struct mt7628_eth_dev *priv = dev_get_priv(dev);
472*c895ef46SStefan Roese 	void __iomem *base = priv->base;
473*c895ef46SStefan Roese 	uchar packet[MTK_QDMA_PAGE_SIZE];
474*c895ef46SStefan Roese 	uchar *packetp;
475*c895ef46SStefan Roese 	int i;
476*c895ef46SStefan Roese 
477*c895ef46SStefan Roese 	for (i = 0; i < NUM_RX_DESC; i++) {
478*c895ef46SStefan Roese 		memset((void *)&priv->rx_ring[i], 0, sizeof(priv->rx_ring[0]));
479*c895ef46SStefan Roese 		priv->rx_ring[i].rxd2 |= RX_DMA_LSO;
480*c895ef46SStefan Roese 		priv->rx_ring[i].rxd1 = CPHYSADDR(priv->rx_buf[i]);
481*c895ef46SStefan Roese 	}
482*c895ef46SStefan Roese 
483*c895ef46SStefan Roese 	for (i = 0; i < NUM_TX_DESC; i++) {
484*c895ef46SStefan Roese 		memset((void *)&priv->tx_ring[i], 0, sizeof(priv->tx_ring[0]));
485*c895ef46SStefan Roese 		priv->tx_ring[i].txd2 = TX_DMA_LS0 | TX_DMA_DONE;
486*c895ef46SStefan Roese 		priv->tx_ring[i].txd4 = FIELD_PREP(TX_DMA_PN, 1);
487*c895ef46SStefan Roese 	}
488*c895ef46SStefan Roese 
489*c895ef46SStefan Roese 	priv->rx_dma_idx = 0;
490*c895ef46SStefan Roese 	priv->tx_dma_idx = 0;
491*c895ef46SStefan Roese 
492*c895ef46SStefan Roese 	/* Make sure the writes executed at this place */
493*c895ef46SStefan Roese 	wmb();
494*c895ef46SStefan Roese 
495*c895ef46SStefan Roese 	/* disable delay interrupt */
496*c895ef46SStefan Roese 	writel(0, base + DLY_INT_CFG);
497*c895ef46SStefan Roese 
498*c895ef46SStefan Roese 	clrbits_le32(base + PDMA_GLO_CFG, 0xffff0000);
499*c895ef46SStefan Roese 
500*c895ef46SStefan Roese 	/* Tell the adapter where the TX/RX rings are located. */
501*c895ef46SStefan Roese 	writel(CPHYSADDR(&priv->rx_ring[0]), base + RX_BASE_PTR0);
502*c895ef46SStefan Roese 	writel(CPHYSADDR((u32)&priv->tx_ring[0]), base + TX_BASE_PTR0);
503*c895ef46SStefan Roese 
504*c895ef46SStefan Roese 	writel(NUM_RX_DESC, base + RX_MAX_CNT0);
505*c895ef46SStefan Roese 	writel(NUM_TX_DESC, base + TX_MAX_CNT0);
506*c895ef46SStefan Roese 
507*c895ef46SStefan Roese 	writel(priv->tx_dma_idx, base + TX_CTX_IDX0);
508*c895ef46SStefan Roese 	writel(RST_DTX_IDX0, base + PDMA_RST_IDX);
509*c895ef46SStefan Roese 
510*c895ef46SStefan Roese 	writel(NUM_RX_DESC - 1, base + RX_CALC_IDX0);
511*c895ef46SStefan Roese 	writel(RST_DRX_IDX0, base + PDMA_RST_IDX);
512*c895ef46SStefan Roese 
513*c895ef46SStefan Roese 	/* Make sure the writes executed at this place */
514*c895ef46SStefan Roese 	wmb();
515*c895ef46SStefan Roese 	eth_dma_start(priv);
516*c895ef46SStefan Roese 
517*c895ef46SStefan Roese 	/* Check if link is not up yet */
518*c895ef46SStefan Roese 	if (!phy_link_up(priv)) {
519*c895ef46SStefan Roese 		/* Wait for link to come up */
520*c895ef46SStefan Roese 
521*c895ef46SStefan Roese 		printf("Waiting for link to come up .");
522*c895ef46SStefan Roese 		for (i = 0; i < (LINK_TIMEOUT / LINK_DELAY_TIME); i++) {
523*c895ef46SStefan Roese 			mdelay(LINK_DELAY_TIME);
524*c895ef46SStefan Roese 			if (phy_link_up(priv)) {
525*c895ef46SStefan Roese 				mdelay(100);	/* Ensure all is ready */
526*c895ef46SStefan Roese 				break;
527*c895ef46SStefan Roese 			}
528*c895ef46SStefan Roese 
529*c895ef46SStefan Roese 			printf(".");
530*c895ef46SStefan Roese 		}
531*c895ef46SStefan Roese 
532*c895ef46SStefan Roese 		if (phy_link_up(priv))
533*c895ef46SStefan Roese 			printf(" done\n");
534*c895ef46SStefan Roese 		else
535*c895ef46SStefan Roese 			printf(" timeout! Trying anyways\n");
536*c895ef46SStefan Roese 	}
537*c895ef46SStefan Roese 
538*c895ef46SStefan Roese 	/*
539*c895ef46SStefan Roese 	 * The integrated switch seems to queue some received ethernet
540*c895ef46SStefan Roese 	 * packets in some FIFO. Lets read the already queued packets
541*c895ef46SStefan Roese 	 * out by using the receive routine, so that these old messages
542*c895ef46SStefan Roese 	 * are dropped before the new xfer starts.
543*c895ef46SStefan Roese 	 */
544*c895ef46SStefan Roese 	packetp = &packet[0];
545*c895ef46SStefan Roese 	while (mt7628_eth_recv(dev, 0, &packetp) != -EAGAIN)
546*c895ef46SStefan Roese 		mt7628_eth_free_pkt(dev, packetp, 0);
547*c895ef46SStefan Roese 
548*c895ef46SStefan Roese 	return 0;
549*c895ef46SStefan Roese }
550*c895ef46SStefan Roese 
mt7628_eth_stop(struct udevice * dev)551*c895ef46SStefan Roese static void mt7628_eth_stop(struct udevice *dev)
552*c895ef46SStefan Roese {
553*c895ef46SStefan Roese 	struct mt7628_eth_dev *priv = dev_get_priv(dev);
554*c895ef46SStefan Roese 
555*c895ef46SStefan Roese 	eth_dma_stop(priv);
556*c895ef46SStefan Roese }
557*c895ef46SStefan Roese 
mt7628_eth_probe(struct udevice * dev)558*c895ef46SStefan Roese static int mt7628_eth_probe(struct udevice *dev)
559*c895ef46SStefan Roese {
560*c895ef46SStefan Roese 	struct mt7628_eth_dev *priv = dev_get_priv(dev);
561*c895ef46SStefan Roese 	struct udevice *syscon;
562*c895ef46SStefan Roese 	struct mii_dev *bus;
563*c895ef46SStefan Roese 	int ret;
564*c895ef46SStefan Roese 	int i;
565*c895ef46SStefan Roese 
566*c895ef46SStefan Roese 	/* Save frame-engine base address for later use */
567*c895ef46SStefan Roese 	priv->base = dev_remap_addr_index(dev, 0);
568*c895ef46SStefan Roese 	if (IS_ERR(priv->base))
569*c895ef46SStefan Roese 		return PTR_ERR(priv->base);
570*c895ef46SStefan Roese 
571*c895ef46SStefan Roese 	/* Save switch base address for later use */
572*c895ef46SStefan Roese 	priv->eth_sw_base = dev_remap_addr_index(dev, 1);
573*c895ef46SStefan Roese 	if (IS_ERR(priv->eth_sw_base))
574*c895ef46SStefan Roese 		return PTR_ERR(priv->eth_sw_base);
575*c895ef46SStefan Roese 
576*c895ef46SStefan Roese 	/* Get system controller regmap */
577*c895ef46SStefan Roese 	ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev,
578*c895ef46SStefan Roese 					   "syscon", &syscon);
579*c895ef46SStefan Roese 	if (ret) {
580*c895ef46SStefan Roese 		pr_err("unable to find syscon device\n");
581*c895ef46SStefan Roese 		return ret;
582*c895ef46SStefan Roese 	}
583*c895ef46SStefan Roese 
584*c895ef46SStefan Roese 	priv->sysctrl_regmap = syscon_get_regmap(syscon);
585*c895ef46SStefan Roese 	if (!priv->sysctrl_regmap) {
586*c895ef46SStefan Roese 		pr_err("unable to find regmap\n");
587*c895ef46SStefan Roese 		return -ENODEV;
588*c895ef46SStefan Roese 	}
589*c895ef46SStefan Roese 
590*c895ef46SStefan Roese 	/* Put rx and tx rings into KSEG1 area (uncached) */
591*c895ef46SStefan Roese 	priv->tx_ring = (struct fe_tx_dma *)
592*c895ef46SStefan Roese 		KSEG1ADDR(memalign(ARCH_DMA_MINALIGN,
593*c895ef46SStefan Roese 				   sizeof(*priv->tx_ring) * NUM_TX_DESC));
594*c895ef46SStefan Roese 	priv->rx_ring = (struct fe_rx_dma *)
595*c895ef46SStefan Roese 		KSEG1ADDR(memalign(ARCH_DMA_MINALIGN,
596*c895ef46SStefan Roese 				   sizeof(*priv->rx_ring) * NUM_RX_DESC));
597*c895ef46SStefan Roese 
598*c895ef46SStefan Roese 	for (i = 0; i < NUM_RX_DESC; i++)
599*c895ef46SStefan Roese 		priv->rx_buf[i] = memalign(PKTALIGN, MTK_QDMA_PAGE_SIZE);
600*c895ef46SStefan Roese 
601*c895ef46SStefan Roese 	bus = mdio_alloc();
602*c895ef46SStefan Roese 	if (!bus) {
603*c895ef46SStefan Roese 		printf("Failed to allocate MDIO bus\n");
604*c895ef46SStefan Roese 		return -ENOMEM;
605*c895ef46SStefan Roese 	}
606*c895ef46SStefan Roese 
607*c895ef46SStefan Roese 	bus->read = mt7628_mdio_read;
608*c895ef46SStefan Roese 	bus->write = mt7628_mdio_write;
609*c895ef46SStefan Roese 	snprintf(bus->name, sizeof(bus->name), dev->name);
610*c895ef46SStefan Roese 	bus->priv = (void *)priv;
611*c895ef46SStefan Roese 
612*c895ef46SStefan Roese 	ret = mdio_register(bus);
613*c895ef46SStefan Roese 	if (ret)
614*c895ef46SStefan Roese 		return ret;
615*c895ef46SStefan Roese 
616*c895ef46SStefan Roese 	/* Switch configuration */
617*c895ef46SStefan Roese 	rt305x_esw_init(priv);
618*c895ef46SStefan Roese 
619*c895ef46SStefan Roese 	return 0;
620*c895ef46SStefan Roese }
621*c895ef46SStefan Roese 
622*c895ef46SStefan Roese static const struct eth_ops mt7628_eth_ops = {
623*c895ef46SStefan Roese 	.start		= mt7628_eth_start,
624*c895ef46SStefan Roese 	.send		= mt7628_eth_send,
625*c895ef46SStefan Roese 	.recv		= mt7628_eth_recv,
626*c895ef46SStefan Roese 	.free_pkt	= mt7628_eth_free_pkt,
627*c895ef46SStefan Roese 	.stop		= mt7628_eth_stop,
628*c895ef46SStefan Roese 	.write_hwaddr	= mt7628_eth_write_hwaddr,
629*c895ef46SStefan Roese };
630*c895ef46SStefan Roese 
631*c895ef46SStefan Roese static const struct udevice_id mt7628_eth_ids[] = {
632*c895ef46SStefan Roese 	{ .compatible = "mediatek,mt7628-eth" },
633*c895ef46SStefan Roese 	{ }
634*c895ef46SStefan Roese };
635*c895ef46SStefan Roese 
636*c895ef46SStefan Roese U_BOOT_DRIVER(mt7628_eth) = {
637*c895ef46SStefan Roese 	.name	= "mt7628_eth",
638*c895ef46SStefan Roese 	.id	= UCLASS_ETH,
639*c895ef46SStefan Roese 	.of_match = mt7628_eth_ids,
640*c895ef46SStefan Roese 	.probe	= mt7628_eth_probe,
641*c895ef46SStefan Roese 	.ops	= &mt7628_eth_ops,
642*c895ef46SStefan Roese 	.priv_auto_alloc_size = sizeof(struct mt7628_eth_dev),
643*c895ef46SStefan Roese 	.platdata_auto_alloc_size = sizeof(struct eth_pdata),
644*c895ef46SStefan Roese };
645