Skip to content

Commit fb6bef2

Browse files
masayuki2009xiaoxiang781216
authored andcommitted
arch: imx6: Add support for AR8031 gigabit ethernet phy
Summary: - This commit adds AR8031 gigabit ethernet phy for the sabre-6quad board. Impact: - None Testing: - Tested with sabre-6quad:netnsh_ar8031 (will be added later) Signed-off-by: Masayuki Ishikawa <[email protected]>
1 parent 8c89052 commit fb6bef2

File tree

3 files changed

+63
-21
lines changed

3 files changed

+63
-21
lines changed

arch/arm/src/imx6/Kconfig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,10 @@ config IMX_ENET_PHYINIT
165165
imx_phy_boardinitialize(); The i.MX6 ENET driver will call this
166166
function one time before it first uses the PHY.
167167

168+
config IMX_ENET_WITH_QEMU
169+
bool "With QEMU"
170+
default y
171+
168172
endmenu # IMX_ENET
169173

170174
config IMX_DDR_SIZE

arch/arm/src/imx6/hardware/imx_enet.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@
191191
#define ENET_ECR_MAGICEN (1 << 2) /* Bit 2: Magic packet detection enable */
192192
#define ENET_ECR_SLEEP (1 << 3) /* Bit 3: Sleep mode enable */
193193
#define ENET_ECR_EN1588 (1 << 4) /* Bit 4: EN1588 enable */
194-
/* Bit 5: Reserved */
194+
#define ENET_ECR_SPEED (1 << 5) /* Bit 5: 1000-Mbit/s mode */
195195
#define ENET_ECR_DBGEN (1 << 6) /* Bit 6: Debug enable */
196196
#define ENET_ECR_STOPEN (1 << 7) /* Bit 7: STOPEN Signal Control */
197197
#ifdef IMX_ENET_HAS_DBSWAP
@@ -248,7 +248,8 @@
248248
#define ENET_RCR_PROM (1 << 3) /* Bit 3: Promiscuous mode */
249249
#define ENET_RCR_BC_REJ (1 << 4) /* Bit 4: Broadcast frame reject */
250250
#define ENET_RCR_FCE (1 << 5) /* Bit 5: Flow control enable */
251-
/* Bits 6-7: Reserved */
251+
#define ENET_RCR_RGMII_EN (1 << 6) /* Bit 6: RGMII mode enable */
252+
/* Bit 7: Reserved */
252253
#define ENET_RCR_RMII_MODE (1 << 8) /* Bit 8: RMII mode enable */
253254
#define ENET_RCR_RMII_10T (1 << 9) /* Bit 9: Enables 10-Mbps mode of the RMII */
254255
/* Bits 10-11: Reserved */

arch/arm/src/imx6/imx_enet.c

Lines changed: 56 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,16 @@
201201
# define BOARD_PHY_10BASET(s) (((s) & MII_DP83825I_PHYSTS_SPEED) != 0)
202202
# define BOARD_PHY_100BASET(s) (((s) & MII_DP83825I_PHYSTS_SPEED) == 0)
203203
# define BOARD_PHY_ISDUPLEX(s) (((s) & MII_DP83825I_PHYSTS_DUPLEX) != 0)
204+
#elif defined(CONFIG_ETH0_PHY_AR8031)
205+
# define BOARD_PHY_NAME "AR8031"
206+
# define BOARD_PHYID1 MII_PHYID1_AR8031
207+
# define BOARD_PHYID2 MII_PHYID2_AR8031
208+
# define BOARD_PHY_STATUS MII_AR8031_PSSR
209+
# define BOARD_PHY_ADDR (1)
210+
# define BOARD_PHY_10BASET(s) (((s) & MII_AR8031_PSSR_10MBPS) == ((s) & MII_AR8031_PSSR_SPEEDMASK))
211+
# define BOARD_PHY_100BASET(s) (((s) & MII_AR8031_PSSR_100MBPS) == ((s) & MII_AR8031_PSSR_SPEEDMASK))
212+
# define BOARD_PHY_1000BASET(s) (((s) & MII_AR8031_PSSR_1000MBPS) == ((s) & MII_AR8031_PSSR_SPEEDMASK))
213+
# define BOARD_PHY_ISDUPLEX(s) (((s) & MII_AR8031_PSSR_DUPLEX) != 0)
204214
#else
205215
# error "Unrecognized or missing PHY selection"
206216
#endif
@@ -216,7 +226,7 @@
216226
* = 23
217227
*/
218228

219-
#define IMX_MII_SPEED 0x38 /* 100Mbs. Revisit and remove hardcoded value */
229+
#define IMX_MII_SPEED 0xd /* 1000Mbs. Revisit and remove hardcoded value */
220230
#if IMX_MII_SPEED > 63
221231
# error "IMX_MII_SPEED is out-of-range"
222232
#endif
@@ -377,7 +387,7 @@ static int imx_phyintenable(struct imx_driver_s *priv);
377387
#endif
378388
static inline void imx_initmii(struct imx_driver_s *priv);
379389

380-
#if 0 /* TODO */
390+
#ifndef CONFIG_IMX_ENET_WITH_QEMU
381391
static int imx_writemii(struct imx_driver_s *priv, uint8_t phyaddr,
382392
uint8_t regaddr, uint16_t data);
383393
static int imx_readmii(struct imx_driver_s *priv, uint8_t phyaddr,
@@ -1327,13 +1337,18 @@ static int imx_ifup_action(struct net_driver_s *dev, bool resetphy)
13271337
/* And enable the MAC itself */
13281338

13291339
regval = imx_enet_getreg32(priv, IMX_ENET_ECR_OFFSET);
1330-
regval |= ENET_ECR_ETHEREN
1340+
regval |= ENET_ECR_ETHEREN | ENET_ECR_SPEED
13311341
#ifdef IMX_USE_DBSWAP
13321342
| ENET_ECR_DBSWP
13331343
#endif
13341344
;
1345+
13351346
imx_enet_putreg32(priv, regval, IMX_ENET_ECR_OFFSET);
13361347

1348+
/* Set TX FIFO write to avoid TX FIFO underrun */
1349+
1350+
imx_enet_putreg32(priv, 0x3f, IMX_ENET_TFWR_OFFSET);
1351+
13371352
/* Indicate that there have been empty receive buffers produced */
13381353

13391354
imx_enet_putreg32(priv, ENET_RDAR, IMX_ENET_RDAR_OFFSET);
@@ -1873,7 +1888,7 @@ static void imx_initmii(struct imx_driver_s *priv)
18731888
*
18741889
****************************************************************************/
18751890

1876-
#if 0 /* TODO */
1891+
#ifndef CONFIG_IMX_ENET_WITH_QEMU
18771892
static int imx_writemii(struct imx_driver_s *priv, uint8_t phyaddr,
18781893
uint8_t regaddr, uint16_t data)
18791894
{
@@ -1935,7 +1950,7 @@ static int imx_writemii(struct imx_driver_s *priv, uint8_t phyaddr,
19351950
*
19361951
****************************************************************************/
19371952

1938-
#if 0 /* TODO */
1953+
#ifndef CONFIG_IMX_ENET_WITH_QEMU
19391954
static int imx_readmii(struct imx_driver_s *priv, uint8_t phyaddr,
19401955
uint8_t regaddr, uint16_t *data)
19411956
{
@@ -2005,7 +2020,7 @@ static int imx_readmii(struct imx_driver_s *priv, uint8_t phyaddr,
20052020

20062021
static inline int imx_initphy(struct imx_driver_s *priv, bool renogphy)
20072022
{
2008-
#if 0 /* TODO */
2023+
#ifndef CONFIG_IMX_ENET_WITH_QEMU
20092024
uint32_t rcr;
20102025
uint32_t tcr;
20112026
uint32_t racc;
@@ -2160,6 +2175,23 @@ static inline int imx_initphy(struct imx_driver_s *priv, bool renogphy)
21602175
MII_ADVERTISE_10BASETXHALF |
21612176
MII_ADVERTISE_CSMA);
21622177

2178+
#elif defined (CONFIG_ETH0_PHY_AR8031)
2179+
2180+
/* Advertise Gigabit support */
2181+
2182+
imx_writemii(priv, phyaddr, MII_ADVERTISE,
2183+
MII_ADVERTISE_1000XFULL |
2184+
MII_ADVERTISE_1000XHALF |
2185+
MII_ADVERTISE_100BASETXFULL |
2186+
MII_ADVERTISE_100BASETXHALF |
2187+
MII_ADVERTISE_10BASETXFULL |
2188+
MII_ADVERTISE_10BASETXHALF |
2189+
MII_ADVERTISE_CSMA);
2190+
2191+
/* Then reset PHY */
2192+
2193+
ninfo("AR8031: *** reset phy (phyaddr=0x%x) \n", phyaddr);
2194+
imx_writemii(priv, phyaddr, MII_MCR, MII_MCR_RESET);
21632195
#endif
21642196

21652197
/* Start auto negotiation */
@@ -2253,16 +2285,13 @@ static inline int imx_initphy(struct imx_driver_s *priv, bool renogphy)
22532285
* configuration and the auto negotiation results.
22542286
*/
22552287

2256-
#ifdef CONFIG_IMX_ENETUSEMII
22572288
rcr = ENET_RCR_CRCFWD |
22582289
(CONFIG_NET_ETH_PKTSIZE + CONFIG_NET_GUARDSIZE)
22592290
<< ENET_RCR_MAX_FL_SHIFT |
2291+
#ifdef CONFIG_IMX_ENETUSEMII
22602292
ENET_RCR_MII_MODE;
22612293
#else
2262-
rcr = ENET_RCR_RMII_MODE | ENET_RCR_CRCFWD |
2263-
(CONFIG_NET_ETH_PKTSIZE + CONFIG_NET_GUARDSIZE)
2264-
<< ENET_RCR_MAX_FL_SHIFT |
2265-
ENET_RCR_MII_MODE;
2294+
ENET_RCR_RGMII_EN;
22662295
#endif
22672296
tcr = 0;
22682297

@@ -2307,6 +2336,14 @@ static inline int imx_initphy(struct imx_driver_s *priv, bool renogphy)
23072336

23082337
ninfo("%s: 100 Base-T\n", BOARD_PHY_NAME);
23092338
}
2339+
#ifdef CONFIG_ETH0_PHY_AR8031
2340+
else if (BOARD_PHY_1000BASET(phydata))
2341+
{
2342+
/* 1000 Mbps */
2343+
2344+
ninfo("%s: 1000 Base-T\n", BOARD_PHY_NAME);
2345+
}
2346+
#endif
23102347
else
23112348
{
23122349
/* This might happen if Autonegotiation did not complete(?) */
@@ -2488,7 +2525,7 @@ int imx_netinitialize(int intf)
24882525
#endif
24892526
priv->dev.d_private = g_enet; /* Used to recover private state from dev */
24902527

2491-
#if 0 /* TODO */
2528+
#if 0 /* NOTE: clock & iomux are set in u-boot */
24922529
uint32_t regval;
24932530

24942531
/* Configure ENET1_TX_CLK */
@@ -2519,7 +2556,7 @@ int imx_netinitialize(int intf)
25192556
imx_config_gpio(GPIO_ENET_RX_ER);
25202557
#endif
25212558

2522-
#endif /* TODO */
2559+
#endif /* if 0 */
25232560

25242561
/* Attach the Ethernet MAC IEEE 1588 timer interrupt handler */
25252562

@@ -2556,16 +2593,16 @@ int imx_netinitialize(int intf)
25562593

25572594
/* hardcoded offset: todo: need proper header file */
25582595

2559-
#if 0 /* TODO */
2560-
uidl = getreg32(IMX_OCOTP_BASE + 0x410);
2561-
uidml = getreg32(IMX_OCOTP_BASE + 0x420);
2596+
#ifndef CONFIG_IMX_ENET_WITH_QEMU
2597+
uidl = getreg32(IMX_OCOTPCTRL_VBASE + 0x620);
2598+
uidml = getreg32(IMX_OCOTPCTRL_VBASE + 0x630);
2599+
#else
2600+
uidml |= 0x00000200;
2601+
uidml &= 0x0000feff;
25622602
#endif
25632603

25642604
mac = priv->dev.d_mac.ether.ether_addr_octet;
25652605

2566-
uidml |= 0x00000200;
2567-
uidml &= 0x0000feff;
2568-
25692606
mac[0] = (uidml & 0x0000ff00) >> 8;
25702607
mac[1] = (uidml & 0x000000ff);
25712608
mac[2] = (uidl & 0xff000000) >> 24;

0 commit comments

Comments
 (0)