1b70ed300SStefan Roese /* 2b70ed300SStefan Roese * sunxi_emac.c -- Allwinner A10 ethernet driver 3b70ed300SStefan Roese * 4b70ed300SStefan Roese * (C) Copyright 2012, Stefan Roese <sr@denx.de> 5b70ed300SStefan Roese * 6b70ed300SStefan Roese * SPDX-License-Identifier: GPL-2.0+ 7b70ed300SStefan Roese */ 8b70ed300SStefan Roese 9b70ed300SStefan Roese #include <common.h> 10939ed1cbSHans de Goede #include <dm.h> 11b70ed300SStefan Roese #include <linux/err.h> 12b70ed300SStefan Roese #include <malloc.h> 13b70ed300SStefan Roese #include <miiphy.h> 14b70ed300SStefan Roese #include <net.h> 15b70ed300SStefan Roese #include <asm/io.h> 16b70ed300SStefan Roese #include <asm/arch/clock.h> 17b70ed300SStefan Roese #include <asm/arch/gpio.h> 18b70ed300SStefan Roese 19b70ed300SStefan Roese /* EMAC register */ 20b70ed300SStefan Roese struct emac_regs { 21b70ed300SStefan Roese u32 ctl; /* 0x00 */ 22b70ed300SStefan Roese u32 tx_mode; /* 0x04 */ 23b70ed300SStefan Roese u32 tx_flow; /* 0x08 */ 24b70ed300SStefan Roese u32 tx_ctl0; /* 0x0c */ 25b70ed300SStefan Roese u32 tx_ctl1; /* 0x10 */ 26b70ed300SStefan Roese u32 tx_ins; /* 0x14 */ 27b70ed300SStefan Roese u32 tx_pl0; /* 0x18 */ 28b70ed300SStefan Roese u32 tx_pl1; /* 0x1c */ 29b70ed300SStefan Roese u32 tx_sta; /* 0x20 */ 30b70ed300SStefan Roese u32 tx_io_data; /* 0x24 */ 31b70ed300SStefan Roese u32 tx_io_data1;/* 0x28 */ 32b70ed300SStefan Roese u32 tx_tsvl0; /* 0x2c */ 33b70ed300SStefan Roese u32 tx_tsvh0; /* 0x30 */ 34b70ed300SStefan Roese u32 tx_tsvl1; /* 0x34 */ 35b70ed300SStefan Roese u32 tx_tsvh1; /* 0x38 */ 36b70ed300SStefan Roese u32 rx_ctl; /* 0x3c */ 37b70ed300SStefan Roese u32 rx_hash0; /* 0x40 */ 38b70ed300SStefan Roese u32 rx_hash1; /* 0x44 */ 39b70ed300SStefan Roese u32 rx_sta; /* 0x48 */ 40b70ed300SStefan Roese u32 rx_io_data; /* 0x4c */ 41b70ed300SStefan Roese u32 rx_fbc; /* 0x50 */ 42b70ed300SStefan Roese u32 int_ctl; /* 0x54 */ 43b70ed300SStefan Roese u32 int_sta; /* 0x58 */ 44b70ed300SStefan Roese u32 mac_ctl0; /* 0x5c */ 45b70ed300SStefan Roese u32 mac_ctl1; /* 0x60 */ 46b70ed300SStefan Roese u32 mac_ipgt; /* 0x64 */ 47b70ed300SStefan Roese u32 mac_ipgr; /* 0x68 */ 48b70ed300SStefan Roese u32 mac_clrt; /* 0x6c */ 49b70ed300SStefan Roese u32 mac_maxf; /* 0x70 */ 50b70ed300SStefan Roese u32 mac_supp; /* 0x74 */ 51b70ed300SStefan Roese u32 mac_test; /* 0x78 */ 52b70ed300SStefan Roese u32 mac_mcfg; /* 0x7c */ 53b70ed300SStefan Roese u32 mac_mcmd; /* 0x80 */ 54b70ed300SStefan Roese u32 mac_madr; /* 0x84 */ 55b70ed300SStefan Roese u32 mac_mwtd; /* 0x88 */ 56b70ed300SStefan Roese u32 mac_mrdd; /* 0x8c */ 57b70ed300SStefan Roese u32 mac_mind; /* 0x90 */ 58b70ed300SStefan Roese u32 mac_ssrr; /* 0x94 */ 59b70ed300SStefan Roese u32 mac_a0; /* 0x98 */ 60b70ed300SStefan Roese u32 mac_a1; /* 0x9c */ 61b70ed300SStefan Roese }; 62b70ed300SStefan Roese 63b70ed300SStefan Roese /* SRAMC register */ 64b70ed300SStefan Roese struct sunxi_sramc_regs { 65b70ed300SStefan Roese u32 ctrl0; 66b70ed300SStefan Roese u32 ctrl1; 67b70ed300SStefan Roese }; 68b70ed300SStefan Roese 69b70ed300SStefan Roese /* 0: Disable 1: Aborted frame enable(default) */ 70b70ed300SStefan Roese #define EMAC_TX_AB_M (0x1 << 0) 71b70ed300SStefan Roese /* 0: CPU 1: DMA(default) */ 72b70ed300SStefan Roese #define EMAC_TX_TM (0x1 << 1) 73b70ed300SStefan Roese 74b70ed300SStefan Roese #define EMAC_TX_SETUP (0) 75b70ed300SStefan Roese 76b70ed300SStefan Roese /* 0: DRQ asserted 1: DRQ automatically(default) */ 77b70ed300SStefan Roese #define EMAC_RX_DRQ_MODE (0x1 << 1) 78b70ed300SStefan Roese /* 0: CPU 1: DMA(default) */ 79b70ed300SStefan Roese #define EMAC_RX_TM (0x1 << 2) 80b70ed300SStefan Roese /* 0: Normal(default) 1: Pass all Frames */ 81b70ed300SStefan Roese #define EMAC_RX_PA (0x1 << 4) 82b70ed300SStefan Roese /* 0: Normal(default) 1: Pass Control Frames */ 83b70ed300SStefan Roese #define EMAC_RX_PCF (0x1 << 5) 84b70ed300SStefan Roese /* 0: Normal(default) 1: Pass Frames with CRC Error */ 85b70ed300SStefan Roese #define EMAC_RX_PCRCE (0x1 << 6) 86b70ed300SStefan Roese /* 0: Normal(default) 1: Pass Frames with Length Error */ 87b70ed300SStefan Roese #define EMAC_RX_PLE (0x1 << 7) 88b70ed300SStefan Roese /* 0: Normal 1: Pass Frames length out of range(default) */ 89b70ed300SStefan Roese #define EMAC_RX_POR (0x1 << 8) 90b70ed300SStefan Roese /* 0: Not accept 1: Accept unicast Packets(default) */ 91b70ed300SStefan Roese #define EMAC_RX_UCAD (0x1 << 16) 92b70ed300SStefan Roese /* 0: Normal(default) 1: DA Filtering */ 93b70ed300SStefan Roese #define EMAC_RX_DAF (0x1 << 17) 94b70ed300SStefan Roese /* 0: Not accept 1: Accept multicast Packets(default) */ 95b70ed300SStefan Roese #define EMAC_RX_MCO (0x1 << 20) 96b70ed300SStefan Roese /* 0: Disable(default) 1: Enable Hash filter */ 97b70ed300SStefan Roese #define EMAC_RX_MHF (0x1 << 21) 98b70ed300SStefan Roese /* 0: Not accept 1: Accept Broadcast Packets(default) */ 99b70ed300SStefan Roese #define EMAC_RX_BCO (0x1 << 22) 100b70ed300SStefan Roese /* 0: Disable(default) 1: Enable SA Filtering */ 101b70ed300SStefan Roese #define EMAC_RX_SAF (0x1 << 24) 102b70ed300SStefan Roese /* 0: Normal(default) 1: Inverse Filtering */ 103b70ed300SStefan Roese #define EMAC_RX_SAIF (0x1 << 25) 104b70ed300SStefan Roese 105b70ed300SStefan Roese #define EMAC_RX_SETUP (EMAC_RX_POR | EMAC_RX_UCAD | EMAC_RX_DAF | \ 106b70ed300SStefan Roese EMAC_RX_MCO | EMAC_RX_BCO) 107b70ed300SStefan Roese 108b70ed300SStefan Roese /* 0: Disable 1: Enable Receive Flow Control(default) */ 109b70ed300SStefan Roese #define EMAC_MAC_CTL0_RFC (0x1 << 2) 110b70ed300SStefan Roese /* 0: Disable 1: Enable Transmit Flow Control(default) */ 111b70ed300SStefan Roese #define EMAC_MAC_CTL0_TFC (0x1 << 3) 112b70ed300SStefan Roese 113b70ed300SStefan Roese #define EMAC_MAC_CTL0_SETUP (EMAC_MAC_CTL0_RFC | EMAC_MAC_CTL0_TFC) 114b70ed300SStefan Roese 115b70ed300SStefan Roese /* 0: Disable 1: Enable MAC Frame Length Checking(default) */ 116b70ed300SStefan Roese #define EMAC_MAC_CTL1_FLC (0x1 << 1) 117b70ed300SStefan Roese /* 0: Disable(default) 1: Enable Huge Frame */ 118b70ed300SStefan Roese #define EMAC_MAC_CTL1_HF (0x1 << 2) 119b70ed300SStefan Roese /* 0: Disable(default) 1: Enable MAC Delayed CRC */ 120b70ed300SStefan Roese #define EMAC_MAC_CTL1_DCRC (0x1 << 3) 121b70ed300SStefan Roese /* 0: Disable 1: Enable MAC CRC(default) */ 122b70ed300SStefan Roese #define EMAC_MAC_CTL1_CRC (0x1 << 4) 123b70ed300SStefan Roese /* 0: Disable 1: Enable MAC PAD Short frames(default) */ 124b70ed300SStefan Roese #define EMAC_MAC_CTL1_PC (0x1 << 5) 125b70ed300SStefan Roese /* 0: Disable(default) 1: Enable MAC PAD Short frames and append CRC */ 126b70ed300SStefan Roese #define EMAC_MAC_CTL1_VC (0x1 << 6) 127b70ed300SStefan Roese /* 0: Disable(default) 1: Enable MAC auto detect Short frames */ 128b70ed300SStefan Roese #define EMAC_MAC_CTL1_ADP (0x1 << 7) 129b70ed300SStefan Roese /* 0: Disable(default) 1: Enable */ 130b70ed300SStefan Roese #define EMAC_MAC_CTL1_PRE (0x1 << 8) 131b70ed300SStefan Roese /* 0: Disable(default) 1: Enable */ 132b70ed300SStefan Roese #define EMAC_MAC_CTL1_LPE (0x1 << 9) 133b70ed300SStefan Roese /* 0: Disable(default) 1: Enable no back off */ 134b70ed300SStefan Roese #define EMAC_MAC_CTL1_NB (0x1 << 12) 135b70ed300SStefan Roese /* 0: Disable(default) 1: Enable */ 136b70ed300SStefan Roese #define EMAC_MAC_CTL1_BNB (0x1 << 13) 137b70ed300SStefan Roese /* 0: Disable(default) 1: Enable */ 138b70ed300SStefan Roese #define EMAC_MAC_CTL1_ED (0x1 << 14) 139b70ed300SStefan Roese 140b70ed300SStefan Roese #define EMAC_MAC_CTL1_SETUP (EMAC_MAC_CTL1_FLC | EMAC_MAC_CTL1_CRC | \ 141b70ed300SStefan Roese EMAC_MAC_CTL1_PC) 142b70ed300SStefan Roese 143b70ed300SStefan Roese #define EMAC_MAC_IPGT 0x15 144b70ed300SStefan Roese 145b70ed300SStefan Roese #define EMAC_MAC_NBTB_IPG1 0xc 146b70ed300SStefan Roese #define EMAC_MAC_NBTB_IPG2 0x12 147b70ed300SStefan Roese 148b70ed300SStefan Roese #define EMAC_MAC_CW 0x37 149b70ed300SStefan Roese #define EMAC_MAC_RM 0xf 150b70ed300SStefan Roese 151b70ed300SStefan Roese #define EMAC_MAC_MFL 0x0600 152b70ed300SStefan Roese 153b70ed300SStefan Roese /* Receive status */ 154b70ed300SStefan Roese #define EMAC_CRCERR (0x1 << 4) 155b70ed300SStefan Roese #define EMAC_LENERR (0x3 << 5) 156b70ed300SStefan Roese 157d88c2f11SHans de Goede #define EMAC_RX_BUFSIZE 2000 158b70ed300SStefan Roese 159b70ed300SStefan Roese struct emac_eth_dev { 1608145dea4SHans de Goede struct emac_regs *regs; 1618145dea4SHans de Goede struct mii_dev *bus; 1628145dea4SHans de Goede struct phy_device *phydev; 163b70ed300SStefan Roese int link_printed; 164939ed1cbSHans de Goede #ifdef CONFIG_DM_ETH 165939ed1cbSHans de Goede uchar rx_buf[EMAC_RX_BUFSIZE]; 166939ed1cbSHans de Goede #endif 167b70ed300SStefan Roese }; 168b70ed300SStefan Roese 169b70ed300SStefan Roese struct emac_rxhdr { 170b70ed300SStefan Roese s16 rx_len; 171b70ed300SStefan Roese u16 rx_status; 172b70ed300SStefan Roese }; 173b70ed300SStefan Roese 174b70ed300SStefan Roese static void emac_inblk_32bit(void *reg, void *data, int count) 175b70ed300SStefan Roese { 176b70ed300SStefan Roese int cnt = (count + 3) >> 2; 177b70ed300SStefan Roese 178b70ed300SStefan Roese if (cnt) { 179b70ed300SStefan Roese u32 *buf = data; 180b70ed300SStefan Roese 181b70ed300SStefan Roese do { 182b70ed300SStefan Roese u32 x = readl(reg); 183b70ed300SStefan Roese *buf++ = x; 184b70ed300SStefan Roese } while (--cnt); 185b70ed300SStefan Roese } 186b70ed300SStefan Roese } 187b70ed300SStefan Roese 188b70ed300SStefan Roese static void emac_outblk_32bit(void *reg, void *data, int count) 189b70ed300SStefan Roese { 190b70ed300SStefan Roese int cnt = (count + 3) >> 2; 191b70ed300SStefan Roese 192b70ed300SStefan Roese if (cnt) { 193b70ed300SStefan Roese const u32 *buf = data; 194b70ed300SStefan Roese 195b70ed300SStefan Roese do { 196b70ed300SStefan Roese writel(*buf++, reg); 197b70ed300SStefan Roese } while (--cnt); 198b70ed300SStefan Roese } 199b70ed300SStefan Roese } 200b70ed300SStefan Roese 201b70ed300SStefan Roese /* Read a word from phyxcer */ 2028145dea4SHans de Goede static int emac_mdio_read(struct mii_dev *bus, int addr, int devad, int reg) 203b70ed300SStefan Roese { 2048145dea4SHans de Goede struct emac_eth_dev *priv = bus->priv; 2058145dea4SHans de Goede struct emac_regs *regs = priv->regs; 206b70ed300SStefan Roese 207b70ed300SStefan Roese /* issue the phy address and reg */ 208b70ed300SStefan Roese writel(addr << 8 | reg, ®s->mac_madr); 209b70ed300SStefan Roese 210b70ed300SStefan Roese /* pull up the phy io line */ 211b70ed300SStefan Roese writel(0x1, ®s->mac_mcmd); 212b70ed300SStefan Roese 213b70ed300SStefan Roese /* Wait read complete */ 214b70ed300SStefan Roese mdelay(1); 215b70ed300SStefan Roese 216b70ed300SStefan Roese /* push down the phy io line */ 217b70ed300SStefan Roese writel(0x0, ®s->mac_mcmd); 218b70ed300SStefan Roese 2198145dea4SHans de Goede /* And read data */ 2208145dea4SHans de Goede return readl(®s->mac_mrdd); 221b70ed300SStefan Roese } 222b70ed300SStefan Roese 223b70ed300SStefan Roese /* Write a word to phyxcer */ 2248145dea4SHans de Goede static int emac_mdio_write(struct mii_dev *bus, int addr, int devad, int reg, 2258145dea4SHans de Goede u16 value) 226b70ed300SStefan Roese { 2278145dea4SHans de Goede struct emac_eth_dev *priv = bus->priv; 2288145dea4SHans de Goede struct emac_regs *regs = priv->regs; 229b70ed300SStefan Roese 230b70ed300SStefan Roese /* issue the phy address and reg */ 231b70ed300SStefan Roese writel(addr << 8 | reg, ®s->mac_madr); 232b70ed300SStefan Roese 233b70ed300SStefan Roese /* pull up the phy io line */ 234b70ed300SStefan Roese writel(0x1, ®s->mac_mcmd); 235b70ed300SStefan Roese 236b70ed300SStefan Roese /* Wait write complete */ 237b70ed300SStefan Roese mdelay(1); 238b70ed300SStefan Roese 239b70ed300SStefan Roese /* push down the phy io line */ 240b70ed300SStefan Roese writel(0x0, ®s->mac_mcmd); 241b70ed300SStefan Roese 242b70ed300SStefan Roese /* and write data */ 243b70ed300SStefan Roese writel(value, ®s->mac_mwtd); 244b70ed300SStefan Roese 245b70ed300SStefan Roese return 0; 246b70ed300SStefan Roese } 247b70ed300SStefan Roese 2488145dea4SHans de Goede static int sunxi_emac_init_phy(struct emac_eth_dev *priv, void *dev) 249b70ed300SStefan Roese { 2508145dea4SHans de Goede int ret, mask = 0xffffffff; 2518145dea4SHans de Goede 2528145dea4SHans de Goede #ifdef CONFIG_PHY_ADDR 2538145dea4SHans de Goede mask = 1 << CONFIG_PHY_ADDR; 2548145dea4SHans de Goede #endif 2558145dea4SHans de Goede 2568145dea4SHans de Goede priv->bus = mdio_alloc(); 2578145dea4SHans de Goede if (!priv->bus) { 2588145dea4SHans de Goede printf("Failed to allocate MDIO bus\n"); 2598145dea4SHans de Goede return -ENOMEM; 2608145dea4SHans de Goede } 2618145dea4SHans de Goede 2628145dea4SHans de Goede priv->bus->read = emac_mdio_read; 2638145dea4SHans de Goede priv->bus->write = emac_mdio_write; 2648145dea4SHans de Goede priv->bus->priv = priv; 2658145dea4SHans de Goede strcpy(priv->bus->name, "emac"); 2668145dea4SHans de Goede 2678145dea4SHans de Goede ret = mdio_register(priv->bus); 2688145dea4SHans de Goede if (ret) 2698145dea4SHans de Goede return ret; 2708145dea4SHans de Goede 2718145dea4SHans de Goede priv->phydev = phy_find_by_mask(priv->bus, mask, 2728145dea4SHans de Goede PHY_INTERFACE_MODE_MII); 2738145dea4SHans de Goede if (!priv->phydev) 2748145dea4SHans de Goede return -ENODEV; 2758145dea4SHans de Goede 2768145dea4SHans de Goede phy_connect_dev(priv->phydev, dev); 2778145dea4SHans de Goede phy_config(priv->phydev); 2788145dea4SHans de Goede 2798145dea4SHans de Goede return 0; 2808145dea4SHans de Goede } 2818145dea4SHans de Goede 2828145dea4SHans de Goede static void emac_setup(struct emac_eth_dev *priv) 2838145dea4SHans de Goede { 2848145dea4SHans de Goede struct emac_regs *regs = priv->regs; 285b70ed300SStefan Roese u32 reg_val; 286b70ed300SStefan Roese 287b70ed300SStefan Roese /* Set up TX */ 288b70ed300SStefan Roese writel(EMAC_TX_SETUP, ®s->tx_mode); 289b70ed300SStefan Roese 290b70ed300SStefan Roese /* Set up RX */ 291b70ed300SStefan Roese writel(EMAC_RX_SETUP, ®s->rx_ctl); 292b70ed300SStefan Roese 293b70ed300SStefan Roese /* Set MAC */ 294b70ed300SStefan Roese /* Set MAC CTL0 */ 295b70ed300SStefan Roese writel(EMAC_MAC_CTL0_SETUP, ®s->mac_ctl0); 296b70ed300SStefan Roese 297b70ed300SStefan Roese /* Set MAC CTL1 */ 298b70ed300SStefan Roese reg_val = 0; 2998145dea4SHans de Goede if (priv->phydev->duplex == DUPLEX_FULL) 300b70ed300SStefan Roese reg_val = (0x1 << 0); 301b70ed300SStefan Roese writel(EMAC_MAC_CTL1_SETUP | reg_val, ®s->mac_ctl1); 302b70ed300SStefan Roese 303b70ed300SStefan Roese /* Set up IPGT */ 304b70ed300SStefan Roese writel(EMAC_MAC_IPGT, ®s->mac_ipgt); 305b70ed300SStefan Roese 306b70ed300SStefan Roese /* Set up IPGR */ 307b70ed300SStefan Roese writel(EMAC_MAC_NBTB_IPG2 | (EMAC_MAC_NBTB_IPG1 << 8), ®s->mac_ipgr); 308b70ed300SStefan Roese 309b70ed300SStefan Roese /* Set up Collison window */ 310b70ed300SStefan Roese writel(EMAC_MAC_RM | (EMAC_MAC_CW << 8), ®s->mac_clrt); 311b70ed300SStefan Roese 312b70ed300SStefan Roese /* Set up Max Frame Length */ 313b70ed300SStefan Roese writel(EMAC_MAC_MFL, ®s->mac_maxf); 314b70ed300SStefan Roese } 315b70ed300SStefan Roese 316f9f62d2dSHans de Goede static void emac_reset(struct emac_eth_dev *priv) 317b70ed300SStefan Roese { 318f9f62d2dSHans de Goede struct emac_regs *regs = priv->regs; 319b70ed300SStefan Roese 320b70ed300SStefan Roese debug("resetting device\n"); 321b70ed300SStefan Roese 322b70ed300SStefan Roese /* RESET device */ 323b70ed300SStefan Roese writel(0, ®s->ctl); 324b70ed300SStefan Roese udelay(200); 325b70ed300SStefan Roese 326b70ed300SStefan Roese writel(1, ®s->ctl); 327b70ed300SStefan Roese udelay(200); 328b70ed300SStefan Roese } 329b70ed300SStefan Roese 330f9f62d2dSHans de Goede static int _sunxi_emac_eth_init(struct emac_eth_dev *priv, u8 *enetaddr) 331b70ed300SStefan Roese { 332f9f62d2dSHans de Goede struct emac_regs *regs = priv->regs; 3338145dea4SHans de Goede int ret; 334b70ed300SStefan Roese 335b70ed300SStefan Roese /* Init EMAC */ 336b70ed300SStefan Roese 337b70ed300SStefan Roese /* Flush RX FIFO */ 338b70ed300SStefan Roese setbits_le32(®s->rx_ctl, 0x8); 339b70ed300SStefan Roese udelay(1); 340b70ed300SStefan Roese 341b70ed300SStefan Roese /* Init MAC */ 342b70ed300SStefan Roese 343b70ed300SStefan Roese /* Soft reset MAC */ 344b70ed300SStefan Roese clrbits_le32(®s->mac_ctl0, 0x1 << 15); 345b70ed300SStefan Roese 346b70ed300SStefan Roese /* Clear RX counter */ 347b70ed300SStefan Roese writel(0x0, ®s->rx_fbc); 348b70ed300SStefan Roese udelay(1); 349b70ed300SStefan Roese 350b70ed300SStefan Roese /* Set up EMAC */ 3518145dea4SHans de Goede emac_setup(priv); 352b70ed300SStefan Roese 353f9f62d2dSHans de Goede writel(enetaddr[0] << 16 | enetaddr[1] << 8 | enetaddr[2], 354f9f62d2dSHans de Goede ®s->mac_a1); 355f9f62d2dSHans de Goede writel(enetaddr[3] << 16 | enetaddr[4] << 8 | enetaddr[5], 356f9f62d2dSHans de Goede ®s->mac_a0); 357b70ed300SStefan Roese 358b70ed300SStefan Roese mdelay(1); 359b70ed300SStefan Roese 360f9f62d2dSHans de Goede emac_reset(priv); 361b70ed300SStefan Roese 362b70ed300SStefan Roese /* PHY POWER UP */ 3638145dea4SHans de Goede ret = phy_startup(priv->phydev); 3648145dea4SHans de Goede if (ret) { 3658145dea4SHans de Goede printf("Could not initialize PHY %s\n", 3668145dea4SHans de Goede priv->phydev->dev->name); 3678145dea4SHans de Goede return ret; 3688145dea4SHans de Goede } 369b70ed300SStefan Roese 370b70ed300SStefan Roese /* Print link status only once */ 371b70ed300SStefan Roese if (!priv->link_printed) { 372b70ed300SStefan Roese printf("ENET Speed is %d Mbps - %s duplex connection\n", 3738145dea4SHans de Goede priv->phydev->speed, 3748145dea4SHans de Goede priv->phydev->duplex ? "FULL" : "HALF"); 375b70ed300SStefan Roese priv->link_printed = 1; 376b70ed300SStefan Roese } 377b70ed300SStefan Roese 378b70ed300SStefan Roese /* Set EMAC SPEED depend on PHY */ 3798145dea4SHans de Goede if (priv->phydev->speed == SPEED_100) 3808145dea4SHans de Goede setbits_le32(®s->mac_supp, 1 << 8); 3818145dea4SHans de Goede else 3828145dea4SHans de Goede clrbits_le32(®s->mac_supp, 1 << 8); 383b70ed300SStefan Roese 384b70ed300SStefan Roese /* Set duplex depend on phy */ 3858145dea4SHans de Goede if (priv->phydev->duplex == DUPLEX_FULL) 3868145dea4SHans de Goede setbits_le32(®s->mac_ctl1, 1 << 0); 3878145dea4SHans de Goede else 3888145dea4SHans de Goede clrbits_le32(®s->mac_ctl1, 1 << 0); 389b70ed300SStefan Roese 390b70ed300SStefan Roese /* Enable RX/TX */ 391b70ed300SStefan Roese setbits_le32(®s->ctl, 0x7); 392b70ed300SStefan Roese 393b70ed300SStefan Roese return 0; 394b70ed300SStefan Roese } 395b70ed300SStefan Roese 396f9f62d2dSHans de Goede static int _sunxi_emac_eth_recv(struct emac_eth_dev *priv, void *packet) 397b70ed300SStefan Roese { 398f9f62d2dSHans de Goede struct emac_regs *regs = priv->regs; 399b70ed300SStefan Roese struct emac_rxhdr rxhdr; 400b70ed300SStefan Roese u32 rxcount; 401b70ed300SStefan Roese u32 reg_val; 402b70ed300SStefan Roese int rx_len; 403b70ed300SStefan Roese int rx_status; 404b70ed300SStefan Roese int good_packet; 405b70ed300SStefan Roese 406b70ed300SStefan Roese /* Check packet ready or not */ 407b70ed300SStefan Roese 408b70ed300SStefan Roese /* Race warning: The first packet might arrive with 409b70ed300SStefan Roese * the interrupts disabled, but the second will fix 410b70ed300SStefan Roese */ 411b70ed300SStefan Roese rxcount = readl(®s->rx_fbc); 412b70ed300SStefan Roese if (!rxcount) { 413b70ed300SStefan Roese /* Had one stuck? */ 414b70ed300SStefan Roese rxcount = readl(®s->rx_fbc); 415b70ed300SStefan Roese if (!rxcount) 416f9f62d2dSHans de Goede return -EAGAIN; 417b70ed300SStefan Roese } 418b70ed300SStefan Roese 419b70ed300SStefan Roese reg_val = readl(®s->rx_io_data); 420b70ed300SStefan Roese if (reg_val != 0x0143414d) { 421b70ed300SStefan Roese /* Disable RX */ 422b70ed300SStefan Roese clrbits_le32(®s->ctl, 0x1 << 2); 423b70ed300SStefan Roese 424b70ed300SStefan Roese /* Flush RX FIFO */ 425b70ed300SStefan Roese setbits_le32(®s->rx_ctl, 0x1 << 3); 426b70ed300SStefan Roese while (readl(®s->rx_ctl) & (0x1 << 3)) 427b70ed300SStefan Roese ; 428b70ed300SStefan Roese 429b70ed300SStefan Roese /* Enable RX */ 430b70ed300SStefan Roese setbits_le32(®s->ctl, 0x1 << 2); 431b70ed300SStefan Roese 432f9f62d2dSHans de Goede return -EAGAIN; 433b70ed300SStefan Roese } 434b70ed300SStefan Roese 435b70ed300SStefan Roese /* A packet ready now 436b70ed300SStefan Roese * Get status/length 437b70ed300SStefan Roese */ 438b70ed300SStefan Roese good_packet = 1; 439b70ed300SStefan Roese 440b70ed300SStefan Roese emac_inblk_32bit(®s->rx_io_data, &rxhdr, sizeof(rxhdr)); 441b70ed300SStefan Roese 442b70ed300SStefan Roese rx_len = rxhdr.rx_len; 443b70ed300SStefan Roese rx_status = rxhdr.rx_status; 444b70ed300SStefan Roese 445b70ed300SStefan Roese /* Packet Status check */ 446b70ed300SStefan Roese if (rx_len < 0x40) { 447b70ed300SStefan Roese good_packet = 0; 448b70ed300SStefan Roese debug("RX: Bad Packet (runt)\n"); 449b70ed300SStefan Roese } 450b70ed300SStefan Roese 451b70ed300SStefan Roese /* rx_status is identical to RSR register. */ 452b70ed300SStefan Roese if (0 & rx_status & (EMAC_CRCERR | EMAC_LENERR)) { 453b70ed300SStefan Roese good_packet = 0; 454b70ed300SStefan Roese if (rx_status & EMAC_CRCERR) 455b70ed300SStefan Roese printf("crc error\n"); 456b70ed300SStefan Roese if (rx_status & EMAC_LENERR) 457b70ed300SStefan Roese printf("length error\n"); 458b70ed300SStefan Roese } 459b70ed300SStefan Roese 460b70ed300SStefan Roese /* Move data from EMAC */ 461b70ed300SStefan Roese if (good_packet) { 462d88c2f11SHans de Goede if (rx_len > EMAC_RX_BUFSIZE) { 463b70ed300SStefan Roese printf("Received packet is too big (len=%d)\n", rx_len); 464f9f62d2dSHans de Goede return -EMSGSIZE; 465f9f62d2dSHans de Goede } 466f9f62d2dSHans de Goede emac_inblk_32bit((void *)®s->rx_io_data, packet, rx_len); 467b70ed300SStefan Roese return rx_len; 468b70ed300SStefan Roese } 469f9f62d2dSHans de Goede 470f9f62d2dSHans de Goede return -EIO; /* Bad packet */ 471b70ed300SStefan Roese } 472b70ed300SStefan Roese 473f9f62d2dSHans de Goede static int _sunxi_emac_eth_send(struct emac_eth_dev *priv, void *packet, 474f9f62d2dSHans de Goede int len) 475b70ed300SStefan Roese { 476f9f62d2dSHans de Goede struct emac_regs *regs = priv->regs; 477b70ed300SStefan Roese 478b70ed300SStefan Roese /* Select channel 0 */ 479b70ed300SStefan Roese writel(0, ®s->tx_ins); 480b70ed300SStefan Roese 481b70ed300SStefan Roese /* Write packet */ 482b70ed300SStefan Roese emac_outblk_32bit((void *)®s->tx_io_data, packet, len); 483b70ed300SStefan Roese 484b70ed300SStefan Roese /* Set TX len */ 485b70ed300SStefan Roese writel(len, ®s->tx_pl0); 486b70ed300SStefan Roese 487b70ed300SStefan Roese /* Start translate from fifo to phy */ 488b70ed300SStefan Roese setbits_le32(®s->tx_ctl0, 1); 489b70ed300SStefan Roese 490b70ed300SStefan Roese return 0; 491b70ed300SStefan Roese } 492b70ed300SStefan Roese 493f9f62d2dSHans de Goede static void sunxi_emac_board_setup(struct emac_eth_dev *priv) 494b70ed300SStefan Roese { 495b70ed300SStefan Roese struct sunxi_ccm_reg *const ccm = 496b70ed300SStefan Roese (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; 497b70ed300SStefan Roese struct sunxi_sramc_regs *sram = 498b70ed300SStefan Roese (struct sunxi_sramc_regs *)SUNXI_SRAMC_BASE; 499f9f62d2dSHans de Goede struct emac_regs *regs = priv->regs; 500f9f62d2dSHans de Goede int pin; 501f9f62d2dSHans de Goede 502f9f62d2dSHans de Goede /* Map SRAM to EMAC */ 503f9f62d2dSHans de Goede setbits_le32(&sram->ctrl1, 0x5 << 2); 504f9f62d2dSHans de Goede 505f9f62d2dSHans de Goede /* Configure pin mux settings for MII Ethernet */ 506f9f62d2dSHans de Goede for (pin = SUNXI_GPA(0); pin <= SUNXI_GPA(17); pin++) 507f9f62d2dSHans de Goede sunxi_gpio_set_cfgpin(pin, SUNXI_GPA_EMAC); 508f9f62d2dSHans de Goede 509f9f62d2dSHans de Goede /* Set up clock gating */ 510f9f62d2dSHans de Goede setbits_le32(&ccm->ahb_gate0, 0x1 << AHB_GATE_OFFSET_EMAC); 511f9f62d2dSHans de Goede 512f9f62d2dSHans de Goede /* Set MII clock */ 513f9f62d2dSHans de Goede clrsetbits_le32(®s->mac_mcfg, 0xf << 2, 0xd << 2); 514f9f62d2dSHans de Goede } 515f9f62d2dSHans de Goede 516939ed1cbSHans de Goede static int sunxi_emac_eth_start(struct udevice *dev) 517939ed1cbSHans de Goede { 518939ed1cbSHans de Goede struct eth_pdata *pdata = dev_get_platdata(dev); 519939ed1cbSHans de Goede 520939ed1cbSHans de Goede return _sunxi_emac_eth_init(dev->priv, pdata->enetaddr); 521939ed1cbSHans de Goede } 522939ed1cbSHans de Goede 523939ed1cbSHans de Goede static int sunxi_emac_eth_send(struct udevice *dev, void *packet, int length) 524939ed1cbSHans de Goede { 525939ed1cbSHans de Goede struct emac_eth_dev *priv = dev_get_priv(dev); 526939ed1cbSHans de Goede 527939ed1cbSHans de Goede return _sunxi_emac_eth_send(priv, packet, length); 528939ed1cbSHans de Goede } 529939ed1cbSHans de Goede 530*a1ca92eaSSimon Glass static int sunxi_emac_eth_recv(struct udevice *dev, int flags, uchar **packetp) 531939ed1cbSHans de Goede { 532939ed1cbSHans de Goede struct emac_eth_dev *priv = dev_get_priv(dev); 533939ed1cbSHans de Goede int rx_len; 534939ed1cbSHans de Goede 535939ed1cbSHans de Goede rx_len = _sunxi_emac_eth_recv(priv, priv->rx_buf); 536939ed1cbSHans de Goede *packetp = priv->rx_buf; 537939ed1cbSHans de Goede 538939ed1cbSHans de Goede return rx_len; 539939ed1cbSHans de Goede } 540939ed1cbSHans de Goede 541939ed1cbSHans de Goede static void sunxi_emac_eth_stop(struct udevice *dev) 542939ed1cbSHans de Goede { 543939ed1cbSHans de Goede /* Nothing to do here */ 544939ed1cbSHans de Goede } 545939ed1cbSHans de Goede 546939ed1cbSHans de Goede static int sunxi_emac_eth_probe(struct udevice *dev) 547939ed1cbSHans de Goede { 548939ed1cbSHans de Goede struct eth_pdata *pdata = dev_get_platdata(dev); 549939ed1cbSHans de Goede struct emac_eth_dev *priv = dev_get_priv(dev); 550939ed1cbSHans de Goede 551939ed1cbSHans de Goede priv->regs = (struct emac_regs *)pdata->iobase; 552939ed1cbSHans de Goede sunxi_emac_board_setup(priv); 553939ed1cbSHans de Goede 554939ed1cbSHans de Goede return sunxi_emac_init_phy(priv, dev); 555939ed1cbSHans de Goede } 556939ed1cbSHans de Goede 557939ed1cbSHans de Goede static const struct eth_ops sunxi_emac_eth_ops = { 558939ed1cbSHans de Goede .start = sunxi_emac_eth_start, 559939ed1cbSHans de Goede .send = sunxi_emac_eth_send, 560939ed1cbSHans de Goede .recv = sunxi_emac_eth_recv, 561939ed1cbSHans de Goede .stop = sunxi_emac_eth_stop, 562939ed1cbSHans de Goede }; 563939ed1cbSHans de Goede 564939ed1cbSHans de Goede static int sunxi_emac_eth_ofdata_to_platdata(struct udevice *dev) 565939ed1cbSHans de Goede { 566939ed1cbSHans de Goede struct eth_pdata *pdata = dev_get_platdata(dev); 567939ed1cbSHans de Goede 568939ed1cbSHans de Goede pdata->iobase = dev_get_addr(dev); 569939ed1cbSHans de Goede 570939ed1cbSHans de Goede return 0; 571939ed1cbSHans de Goede } 572939ed1cbSHans de Goede 573939ed1cbSHans de Goede static const struct udevice_id sunxi_emac_eth_ids[] = { 574939ed1cbSHans de Goede { .compatible = "allwinner,sun4i-a10-emac" }, 575939ed1cbSHans de Goede { } 576939ed1cbSHans de Goede }; 577939ed1cbSHans de Goede 578939ed1cbSHans de Goede U_BOOT_DRIVER(eth_sunxi_emac) = { 579939ed1cbSHans de Goede .name = "eth_sunxi_emac", 580939ed1cbSHans de Goede .id = UCLASS_ETH, 581939ed1cbSHans de Goede .of_match = sunxi_emac_eth_ids, 582939ed1cbSHans de Goede .ofdata_to_platdata = sunxi_emac_eth_ofdata_to_platdata, 583939ed1cbSHans de Goede .probe = sunxi_emac_eth_probe, 584939ed1cbSHans de Goede .ops = &sunxi_emac_eth_ops, 585939ed1cbSHans de Goede .priv_auto_alloc_size = sizeof(struct emac_eth_dev), 586939ed1cbSHans de Goede .platdata_auto_alloc_size = sizeof(struct eth_pdata), 587939ed1cbSHans de Goede }; 588