1*8ae51b6fSMarek Vasut /* 2*8ae51b6fSMarek Vasut * drivers/net/ravb.c 3*8ae51b6fSMarek Vasut * This file is driver for Renesas Ethernet AVB. 4*8ae51b6fSMarek Vasut * 5*8ae51b6fSMarek Vasut * Copyright (C) 2015-2017 Renesas Electronics Corporation 6*8ae51b6fSMarek Vasut * 7*8ae51b6fSMarek Vasut * Based on the SuperH Ethernet driver. 8*8ae51b6fSMarek Vasut * 9*8ae51b6fSMarek Vasut * SPDX-License-Identifier: GPL-2.0+ 10*8ae51b6fSMarek Vasut */ 11*8ae51b6fSMarek Vasut 12*8ae51b6fSMarek Vasut #include <common.h> 13*8ae51b6fSMarek Vasut #include <dm.h> 14*8ae51b6fSMarek Vasut #include <errno.h> 15*8ae51b6fSMarek Vasut #include <miiphy.h> 16*8ae51b6fSMarek Vasut #include <malloc.h> 17*8ae51b6fSMarek Vasut #include <linux/mii.h> 18*8ae51b6fSMarek Vasut #include <wait_bit.h> 19*8ae51b6fSMarek Vasut #include <asm/io.h> 20*8ae51b6fSMarek Vasut 21*8ae51b6fSMarek Vasut /* Registers */ 22*8ae51b6fSMarek Vasut #define RAVB_REG_CCC 0x000 23*8ae51b6fSMarek Vasut #define RAVB_REG_DBAT 0x004 24*8ae51b6fSMarek Vasut #define RAVB_REG_CSR 0x00C 25*8ae51b6fSMarek Vasut #define RAVB_REG_APSR 0x08C 26*8ae51b6fSMarek Vasut #define RAVB_REG_RCR 0x090 27*8ae51b6fSMarek Vasut #define RAVB_REG_TGC 0x300 28*8ae51b6fSMarek Vasut #define RAVB_REG_TCCR 0x304 29*8ae51b6fSMarek Vasut #define RAVB_REG_RIC0 0x360 30*8ae51b6fSMarek Vasut #define RAVB_REG_RIC1 0x368 31*8ae51b6fSMarek Vasut #define RAVB_REG_RIC2 0x370 32*8ae51b6fSMarek Vasut #define RAVB_REG_TIC 0x378 33*8ae51b6fSMarek Vasut #define RAVB_REG_ECMR 0x500 34*8ae51b6fSMarek Vasut #define RAVB_REG_RFLR 0x508 35*8ae51b6fSMarek Vasut #define RAVB_REG_ECSIPR 0x518 36*8ae51b6fSMarek Vasut #define RAVB_REG_PIR 0x520 37*8ae51b6fSMarek Vasut #define RAVB_REG_GECMR 0x5b0 38*8ae51b6fSMarek Vasut #define RAVB_REG_MAHR 0x5c0 39*8ae51b6fSMarek Vasut #define RAVB_REG_MALR 0x5c8 40*8ae51b6fSMarek Vasut 41*8ae51b6fSMarek Vasut #define CCC_OPC_CONFIG BIT(0) 42*8ae51b6fSMarek Vasut #define CCC_OPC_OPERATION BIT(1) 43*8ae51b6fSMarek Vasut #define CCC_BOC BIT(20) 44*8ae51b6fSMarek Vasut 45*8ae51b6fSMarek Vasut #define CSR_OPS 0x0000000F 46*8ae51b6fSMarek Vasut #define CSR_OPS_CONFIG BIT(1) 47*8ae51b6fSMarek Vasut 48*8ae51b6fSMarek Vasut #define TCCR_TSRQ0 BIT(0) 49*8ae51b6fSMarek Vasut 50*8ae51b6fSMarek Vasut #define RFLR_RFL_MIN 0x05EE 51*8ae51b6fSMarek Vasut 52*8ae51b6fSMarek Vasut #define PIR_MDI BIT(3) 53*8ae51b6fSMarek Vasut #define PIR_MDO BIT(2) 54*8ae51b6fSMarek Vasut #define PIR_MMD BIT(1) 55*8ae51b6fSMarek Vasut #define PIR_MDC BIT(0) 56*8ae51b6fSMarek Vasut 57*8ae51b6fSMarek Vasut #define ECMR_TRCCM BIT(26) 58*8ae51b6fSMarek Vasut #define ECMR_RZPF BIT(20) 59*8ae51b6fSMarek Vasut #define ECMR_PFR BIT(18) 60*8ae51b6fSMarek Vasut #define ECMR_RXF BIT(17) 61*8ae51b6fSMarek Vasut #define ECMR_RE BIT(6) 62*8ae51b6fSMarek Vasut #define ECMR_TE BIT(5) 63*8ae51b6fSMarek Vasut #define ECMR_DM BIT(1) 64*8ae51b6fSMarek Vasut #define ECMR_CHG_DM (ECMR_TRCCM | ECMR_RZPF | ECMR_PFR | ECMR_RXF) 65*8ae51b6fSMarek Vasut 66*8ae51b6fSMarek Vasut /* DMA Descriptors */ 67*8ae51b6fSMarek Vasut #define RAVB_NUM_BASE_DESC 16 68*8ae51b6fSMarek Vasut #define RAVB_NUM_TX_DESC 8 69*8ae51b6fSMarek Vasut #define RAVB_NUM_RX_DESC 8 70*8ae51b6fSMarek Vasut 71*8ae51b6fSMarek Vasut #define RAVB_TX_QUEUE_OFFSET 0 72*8ae51b6fSMarek Vasut #define RAVB_RX_QUEUE_OFFSET 4 73*8ae51b6fSMarek Vasut 74*8ae51b6fSMarek Vasut #define RAVB_DESC_DT(n) ((n) << 28) 75*8ae51b6fSMarek Vasut #define RAVB_DESC_DT_FSINGLE RAVB_DESC_DT(0x7) 76*8ae51b6fSMarek Vasut #define RAVB_DESC_DT_LINKFIX RAVB_DESC_DT(0x9) 77*8ae51b6fSMarek Vasut #define RAVB_DESC_DT_EOS RAVB_DESC_DT(0xa) 78*8ae51b6fSMarek Vasut #define RAVB_DESC_DT_FEMPTY RAVB_DESC_DT(0xc) 79*8ae51b6fSMarek Vasut #define RAVB_DESC_DT_EEMPTY RAVB_DESC_DT(0x3) 80*8ae51b6fSMarek Vasut #define RAVB_DESC_DT_MASK RAVB_DESC_DT(0xf) 81*8ae51b6fSMarek Vasut 82*8ae51b6fSMarek Vasut #define RAVB_DESC_DS(n) (((n) & 0xfff) << 0) 83*8ae51b6fSMarek Vasut #define RAVB_DESC_DS_MASK 0xfff 84*8ae51b6fSMarek Vasut 85*8ae51b6fSMarek Vasut #define RAVB_RX_DESC_MSC_MC BIT(23) 86*8ae51b6fSMarek Vasut #define RAVB_RX_DESC_MSC_CEEF BIT(22) 87*8ae51b6fSMarek Vasut #define RAVB_RX_DESC_MSC_CRL BIT(21) 88*8ae51b6fSMarek Vasut #define RAVB_RX_DESC_MSC_FRE BIT(20) 89*8ae51b6fSMarek Vasut #define RAVB_RX_DESC_MSC_RTLF BIT(19) 90*8ae51b6fSMarek Vasut #define RAVB_RX_DESC_MSC_RTSF BIT(18) 91*8ae51b6fSMarek Vasut #define RAVB_RX_DESC_MSC_RFE BIT(17) 92*8ae51b6fSMarek Vasut #define RAVB_RX_DESC_MSC_CRC BIT(16) 93*8ae51b6fSMarek Vasut #define RAVB_RX_DESC_MSC_MASK (0xff << 16) 94*8ae51b6fSMarek Vasut 95*8ae51b6fSMarek Vasut #define RAVB_RX_DESC_MSC_RX_ERR_MASK \ 96*8ae51b6fSMarek Vasut (RAVB_RX_DESC_MSC_CRC | RAVB_RX_DESC_MSC_RFE | RAVB_RX_DESC_MSC_RTLF | \ 97*8ae51b6fSMarek Vasut RAVB_RX_DESC_MSC_RTSF | RAVB_RX_DESC_MSC_CEEF) 98*8ae51b6fSMarek Vasut 99*8ae51b6fSMarek Vasut #define RAVB_TX_TIMEOUT_MS 1000 100*8ae51b6fSMarek Vasut 101*8ae51b6fSMarek Vasut struct ravb_desc { 102*8ae51b6fSMarek Vasut u32 ctrl; 103*8ae51b6fSMarek Vasut u32 dptr; 104*8ae51b6fSMarek Vasut }; 105*8ae51b6fSMarek Vasut 106*8ae51b6fSMarek Vasut struct ravb_rxdesc { 107*8ae51b6fSMarek Vasut struct ravb_desc data; 108*8ae51b6fSMarek Vasut struct ravb_desc link; 109*8ae51b6fSMarek Vasut u8 __pad[48]; 110*8ae51b6fSMarek Vasut u8 packet[PKTSIZE_ALIGN]; 111*8ae51b6fSMarek Vasut }; 112*8ae51b6fSMarek Vasut 113*8ae51b6fSMarek Vasut struct ravb_priv { 114*8ae51b6fSMarek Vasut struct ravb_desc base_desc[RAVB_NUM_BASE_DESC]; 115*8ae51b6fSMarek Vasut struct ravb_desc tx_desc[RAVB_NUM_TX_DESC]; 116*8ae51b6fSMarek Vasut struct ravb_rxdesc rx_desc[RAVB_NUM_RX_DESC]; 117*8ae51b6fSMarek Vasut u32 rx_desc_idx; 118*8ae51b6fSMarek Vasut u32 tx_desc_idx; 119*8ae51b6fSMarek Vasut 120*8ae51b6fSMarek Vasut struct phy_device *phydev; 121*8ae51b6fSMarek Vasut struct mii_dev *bus; 122*8ae51b6fSMarek Vasut void __iomem *iobase; 123*8ae51b6fSMarek Vasut }; 124*8ae51b6fSMarek Vasut 125*8ae51b6fSMarek Vasut static inline void ravb_flush_dcache(u32 addr, u32 len) 126*8ae51b6fSMarek Vasut { 127*8ae51b6fSMarek Vasut flush_dcache_range(addr, addr + len); 128*8ae51b6fSMarek Vasut } 129*8ae51b6fSMarek Vasut 130*8ae51b6fSMarek Vasut static inline void ravb_invalidate_dcache(u32 addr, u32 len) 131*8ae51b6fSMarek Vasut { 132*8ae51b6fSMarek Vasut u32 start = addr & ~((uintptr_t)ARCH_DMA_MINALIGN - 1); 133*8ae51b6fSMarek Vasut u32 end = roundup(addr + len, ARCH_DMA_MINALIGN); 134*8ae51b6fSMarek Vasut invalidate_dcache_range(start, end); 135*8ae51b6fSMarek Vasut } 136*8ae51b6fSMarek Vasut 137*8ae51b6fSMarek Vasut static int ravb_send(struct udevice *dev, void *packet, int len) 138*8ae51b6fSMarek Vasut { 139*8ae51b6fSMarek Vasut struct ravb_priv *eth = dev_get_priv(dev); 140*8ae51b6fSMarek Vasut struct ravb_desc *desc = ð->tx_desc[eth->tx_desc_idx]; 141*8ae51b6fSMarek Vasut unsigned int start; 142*8ae51b6fSMarek Vasut 143*8ae51b6fSMarek Vasut /* Update TX descriptor */ 144*8ae51b6fSMarek Vasut ravb_flush_dcache((uintptr_t)packet, len); 145*8ae51b6fSMarek Vasut memset(desc, 0x0, sizeof(*desc)); 146*8ae51b6fSMarek Vasut desc->ctrl = RAVB_DESC_DT_FSINGLE | RAVB_DESC_DS(len); 147*8ae51b6fSMarek Vasut desc->dptr = (uintptr_t)packet; 148*8ae51b6fSMarek Vasut ravb_flush_dcache((uintptr_t)desc, sizeof(*desc)); 149*8ae51b6fSMarek Vasut 150*8ae51b6fSMarek Vasut /* Restart the transmitter if disabled */ 151*8ae51b6fSMarek Vasut if (!(readl(eth->iobase + RAVB_REG_TCCR) & TCCR_TSRQ0)) 152*8ae51b6fSMarek Vasut setbits_le32(eth->iobase + RAVB_REG_TCCR, TCCR_TSRQ0); 153*8ae51b6fSMarek Vasut 154*8ae51b6fSMarek Vasut /* Wait until packet is transmitted */ 155*8ae51b6fSMarek Vasut start = get_timer(0); 156*8ae51b6fSMarek Vasut while (get_timer(start) < RAVB_TX_TIMEOUT_MS) { 157*8ae51b6fSMarek Vasut ravb_invalidate_dcache((uintptr_t)desc, sizeof(*desc)); 158*8ae51b6fSMarek Vasut if ((desc->ctrl & RAVB_DESC_DT_MASK) != RAVB_DESC_DT_FSINGLE) 159*8ae51b6fSMarek Vasut break; 160*8ae51b6fSMarek Vasut udelay(10); 161*8ae51b6fSMarek Vasut }; 162*8ae51b6fSMarek Vasut 163*8ae51b6fSMarek Vasut if (get_timer(start) >= RAVB_TX_TIMEOUT_MS) 164*8ae51b6fSMarek Vasut return -ETIMEDOUT; 165*8ae51b6fSMarek Vasut 166*8ae51b6fSMarek Vasut eth->tx_desc_idx = (eth->tx_desc_idx + 1) % (RAVB_NUM_TX_DESC - 1); 167*8ae51b6fSMarek Vasut return 0; 168*8ae51b6fSMarek Vasut } 169*8ae51b6fSMarek Vasut 170*8ae51b6fSMarek Vasut static int ravb_recv(struct udevice *dev, int flags, uchar **packetp) 171*8ae51b6fSMarek Vasut { 172*8ae51b6fSMarek Vasut struct ravb_priv *eth = dev_get_priv(dev); 173*8ae51b6fSMarek Vasut struct ravb_rxdesc *desc = ð->rx_desc[eth->rx_desc_idx]; 174*8ae51b6fSMarek Vasut int len; 175*8ae51b6fSMarek Vasut u8 *packet; 176*8ae51b6fSMarek Vasut 177*8ae51b6fSMarek Vasut /* Check if the rx descriptor is ready */ 178*8ae51b6fSMarek Vasut ravb_invalidate_dcache((uintptr_t)desc, sizeof(*desc)); 179*8ae51b6fSMarek Vasut if ((desc->data.ctrl & RAVB_DESC_DT_MASK) == RAVB_DESC_DT_FEMPTY) 180*8ae51b6fSMarek Vasut return -EAGAIN; 181*8ae51b6fSMarek Vasut 182*8ae51b6fSMarek Vasut /* Check for errors */ 183*8ae51b6fSMarek Vasut if (desc->data.ctrl & RAVB_RX_DESC_MSC_RX_ERR_MASK) { 184*8ae51b6fSMarek Vasut desc->data.ctrl &= ~RAVB_RX_DESC_MSC_MASK; 185*8ae51b6fSMarek Vasut return -EAGAIN; 186*8ae51b6fSMarek Vasut } 187*8ae51b6fSMarek Vasut 188*8ae51b6fSMarek Vasut len = desc->data.ctrl & RAVB_DESC_DS_MASK; 189*8ae51b6fSMarek Vasut packet = (u8 *)(uintptr_t)desc->data.dptr; 190*8ae51b6fSMarek Vasut ravb_invalidate_dcache((uintptr_t)packet, len); 191*8ae51b6fSMarek Vasut 192*8ae51b6fSMarek Vasut *packetp = packet; 193*8ae51b6fSMarek Vasut return len; 194*8ae51b6fSMarek Vasut } 195*8ae51b6fSMarek Vasut 196*8ae51b6fSMarek Vasut static int ravb_free_pkt(struct udevice *dev, uchar *packet, int length) 197*8ae51b6fSMarek Vasut { 198*8ae51b6fSMarek Vasut struct ravb_priv *eth = dev_get_priv(dev); 199*8ae51b6fSMarek Vasut struct ravb_rxdesc *desc = ð->rx_desc[eth->rx_desc_idx]; 200*8ae51b6fSMarek Vasut 201*8ae51b6fSMarek Vasut /* Make current descriptor available again */ 202*8ae51b6fSMarek Vasut desc->data.ctrl = RAVB_DESC_DT_FEMPTY | RAVB_DESC_DS(PKTSIZE_ALIGN); 203*8ae51b6fSMarek Vasut ravb_flush_dcache((uintptr_t)desc, sizeof(*desc)); 204*8ae51b6fSMarek Vasut 205*8ae51b6fSMarek Vasut /* Point to the next descriptor */ 206*8ae51b6fSMarek Vasut eth->rx_desc_idx = (eth->rx_desc_idx + 1) % RAVB_NUM_RX_DESC; 207*8ae51b6fSMarek Vasut desc = ð->rx_desc[eth->rx_desc_idx]; 208*8ae51b6fSMarek Vasut ravb_invalidate_dcache((uintptr_t)desc, sizeof(*desc)); 209*8ae51b6fSMarek Vasut 210*8ae51b6fSMarek Vasut return 0; 211*8ae51b6fSMarek Vasut } 212*8ae51b6fSMarek Vasut 213*8ae51b6fSMarek Vasut static int ravb_reset(struct udevice *dev) 214*8ae51b6fSMarek Vasut { 215*8ae51b6fSMarek Vasut struct ravb_priv *eth = dev_get_priv(dev); 216*8ae51b6fSMarek Vasut 217*8ae51b6fSMarek Vasut /* Set config mode */ 218*8ae51b6fSMarek Vasut writel(CCC_OPC_CONFIG, eth->iobase + RAVB_REG_CCC); 219*8ae51b6fSMarek Vasut 220*8ae51b6fSMarek Vasut /* Check the operating mode is changed to the config mode. */ 221*8ae51b6fSMarek Vasut return wait_for_bit(dev->name, (void *)eth->iobase + RAVB_REG_CSR, 222*8ae51b6fSMarek Vasut CSR_OPS_CONFIG, true, 100, true); 223*8ae51b6fSMarek Vasut } 224*8ae51b6fSMarek Vasut 225*8ae51b6fSMarek Vasut static void ravb_base_desc_init(struct ravb_priv *eth) 226*8ae51b6fSMarek Vasut { 227*8ae51b6fSMarek Vasut const u32 desc_size = RAVB_NUM_BASE_DESC * sizeof(struct ravb_desc); 228*8ae51b6fSMarek Vasut int i; 229*8ae51b6fSMarek Vasut 230*8ae51b6fSMarek Vasut /* Initialize all descriptors */ 231*8ae51b6fSMarek Vasut memset(eth->base_desc, 0x0, desc_size); 232*8ae51b6fSMarek Vasut 233*8ae51b6fSMarek Vasut for (i = 0; i < RAVB_NUM_BASE_DESC; i++) 234*8ae51b6fSMarek Vasut eth->base_desc[i].ctrl = RAVB_DESC_DT_EOS; 235*8ae51b6fSMarek Vasut 236*8ae51b6fSMarek Vasut ravb_flush_dcache((uintptr_t)eth->base_desc, desc_size); 237*8ae51b6fSMarek Vasut 238*8ae51b6fSMarek Vasut /* Register the descriptor base address table */ 239*8ae51b6fSMarek Vasut writel((uintptr_t)eth->base_desc, eth->iobase + RAVB_REG_DBAT); 240*8ae51b6fSMarek Vasut } 241*8ae51b6fSMarek Vasut 242*8ae51b6fSMarek Vasut static void ravb_tx_desc_init(struct ravb_priv *eth) 243*8ae51b6fSMarek Vasut { 244*8ae51b6fSMarek Vasut const u32 desc_size = RAVB_NUM_TX_DESC * sizeof(struct ravb_desc); 245*8ae51b6fSMarek Vasut int i; 246*8ae51b6fSMarek Vasut 247*8ae51b6fSMarek Vasut /* Initialize all descriptors */ 248*8ae51b6fSMarek Vasut memset(eth->tx_desc, 0x0, desc_size); 249*8ae51b6fSMarek Vasut eth->tx_desc_idx = 0; 250*8ae51b6fSMarek Vasut 251*8ae51b6fSMarek Vasut for (i = 0; i < RAVB_NUM_TX_DESC; i++) 252*8ae51b6fSMarek Vasut eth->tx_desc[i].ctrl = RAVB_DESC_DT_EEMPTY; 253*8ae51b6fSMarek Vasut 254*8ae51b6fSMarek Vasut /* Mark the end of the descriptors */ 255*8ae51b6fSMarek Vasut eth->tx_desc[RAVB_NUM_TX_DESC - 1].ctrl = RAVB_DESC_DT_LINKFIX; 256*8ae51b6fSMarek Vasut eth->tx_desc[RAVB_NUM_TX_DESC - 1].dptr = (uintptr_t)eth->tx_desc; 257*8ae51b6fSMarek Vasut ravb_flush_dcache((uintptr_t)eth->tx_desc, desc_size); 258*8ae51b6fSMarek Vasut 259*8ae51b6fSMarek Vasut /* Point the controller to the TX descriptor list. */ 260*8ae51b6fSMarek Vasut eth->base_desc[RAVB_TX_QUEUE_OFFSET].ctrl = RAVB_DESC_DT_LINKFIX; 261*8ae51b6fSMarek Vasut eth->base_desc[RAVB_TX_QUEUE_OFFSET].dptr = (uintptr_t)eth->tx_desc; 262*8ae51b6fSMarek Vasut ravb_flush_dcache((uintptr_t)ð->base_desc[RAVB_TX_QUEUE_OFFSET], 263*8ae51b6fSMarek Vasut sizeof(struct ravb_desc)); 264*8ae51b6fSMarek Vasut } 265*8ae51b6fSMarek Vasut 266*8ae51b6fSMarek Vasut static void ravb_rx_desc_init(struct ravb_priv *eth) 267*8ae51b6fSMarek Vasut { 268*8ae51b6fSMarek Vasut const u32 desc_size = RAVB_NUM_RX_DESC * sizeof(struct ravb_rxdesc); 269*8ae51b6fSMarek Vasut int i; 270*8ae51b6fSMarek Vasut 271*8ae51b6fSMarek Vasut /* Initialize all descriptors */ 272*8ae51b6fSMarek Vasut memset(eth->rx_desc, 0x0, desc_size); 273*8ae51b6fSMarek Vasut eth->rx_desc_idx = 0; 274*8ae51b6fSMarek Vasut 275*8ae51b6fSMarek Vasut for (i = 0; i < RAVB_NUM_RX_DESC; i++) { 276*8ae51b6fSMarek Vasut eth->rx_desc[i].data.ctrl = RAVB_DESC_DT_EEMPTY | 277*8ae51b6fSMarek Vasut RAVB_DESC_DS(PKTSIZE_ALIGN); 278*8ae51b6fSMarek Vasut eth->rx_desc[i].data.dptr = (uintptr_t)eth->rx_desc[i].packet; 279*8ae51b6fSMarek Vasut 280*8ae51b6fSMarek Vasut eth->rx_desc[i].link.ctrl = RAVB_DESC_DT_LINKFIX; 281*8ae51b6fSMarek Vasut eth->rx_desc[i].link.dptr = (uintptr_t)ð->rx_desc[i + 1]; 282*8ae51b6fSMarek Vasut } 283*8ae51b6fSMarek Vasut 284*8ae51b6fSMarek Vasut /* Mark the end of the descriptors */ 285*8ae51b6fSMarek Vasut eth->rx_desc[RAVB_NUM_RX_DESC - 1].link.ctrl = RAVB_DESC_DT_LINKFIX; 286*8ae51b6fSMarek Vasut eth->rx_desc[RAVB_NUM_RX_DESC - 1].link.dptr = (uintptr_t)eth->rx_desc; 287*8ae51b6fSMarek Vasut ravb_flush_dcache((uintptr_t)eth->rx_desc, desc_size); 288*8ae51b6fSMarek Vasut 289*8ae51b6fSMarek Vasut /* Point the controller to the rx descriptor list */ 290*8ae51b6fSMarek Vasut eth->base_desc[RAVB_RX_QUEUE_OFFSET].ctrl = RAVB_DESC_DT_LINKFIX; 291*8ae51b6fSMarek Vasut eth->base_desc[RAVB_RX_QUEUE_OFFSET].dptr = (uintptr_t)eth->rx_desc; 292*8ae51b6fSMarek Vasut ravb_flush_dcache((uintptr_t)ð->base_desc[RAVB_RX_QUEUE_OFFSET], 293*8ae51b6fSMarek Vasut sizeof(struct ravb_desc)); 294*8ae51b6fSMarek Vasut } 295*8ae51b6fSMarek Vasut 296*8ae51b6fSMarek Vasut static int ravb_phy_config(struct udevice *dev) 297*8ae51b6fSMarek Vasut { 298*8ae51b6fSMarek Vasut struct ravb_priv *eth = dev_get_priv(dev); 299*8ae51b6fSMarek Vasut struct eth_pdata *pdata = dev_get_platdata(dev); 300*8ae51b6fSMarek Vasut struct phy_device *phydev; 301*8ae51b6fSMarek Vasut int reg; 302*8ae51b6fSMarek Vasut 303*8ae51b6fSMarek Vasut phydev = phy_connect(eth->bus, pdata->phy_interface, 304*8ae51b6fSMarek Vasut dev, PHY_INTERFACE_MODE_RGMII_ID); 305*8ae51b6fSMarek Vasut if (!phydev) 306*8ae51b6fSMarek Vasut return -ENODEV; 307*8ae51b6fSMarek Vasut 308*8ae51b6fSMarek Vasut eth->phydev = phydev; 309*8ae51b6fSMarek Vasut 310*8ae51b6fSMarek Vasut /* 10BASE is not supported for Ethernet AVB MAC */ 311*8ae51b6fSMarek Vasut phydev->supported &= ~(SUPPORTED_10baseT_Full 312*8ae51b6fSMarek Vasut | SUPPORTED_10baseT_Half); 313*8ae51b6fSMarek Vasut if (pdata->max_speed != 1000) { 314*8ae51b6fSMarek Vasut phydev->supported &= ~(SUPPORTED_1000baseT_Half 315*8ae51b6fSMarek Vasut | SUPPORTED_1000baseT_Full); 316*8ae51b6fSMarek Vasut reg = phy_read(phydev, -1, MII_CTRL1000); 317*8ae51b6fSMarek Vasut reg &= ~(BIT(9) | BIT(8)); 318*8ae51b6fSMarek Vasut phy_write(phydev, -1, MII_CTRL1000, reg); 319*8ae51b6fSMarek Vasut } 320*8ae51b6fSMarek Vasut 321*8ae51b6fSMarek Vasut phy_config(phydev); 322*8ae51b6fSMarek Vasut 323*8ae51b6fSMarek Vasut return 0; 324*8ae51b6fSMarek Vasut } 325*8ae51b6fSMarek Vasut 326*8ae51b6fSMarek Vasut /* Set Mac address */ 327*8ae51b6fSMarek Vasut static int ravb_write_hwaddr(struct udevice *dev) 328*8ae51b6fSMarek Vasut { 329*8ae51b6fSMarek Vasut struct ravb_priv *eth = dev_get_priv(dev); 330*8ae51b6fSMarek Vasut struct eth_pdata *pdata = dev_get_platdata(dev); 331*8ae51b6fSMarek Vasut unsigned char *mac = pdata->enetaddr; 332*8ae51b6fSMarek Vasut 333*8ae51b6fSMarek Vasut writel((mac[0] << 24) | (mac[1] << 16) | (mac[2] << 8) | mac[3], 334*8ae51b6fSMarek Vasut eth->iobase + RAVB_REG_MAHR); 335*8ae51b6fSMarek Vasut 336*8ae51b6fSMarek Vasut writel((mac[4] << 8) | mac[5], eth->iobase + RAVB_REG_MALR); 337*8ae51b6fSMarek Vasut 338*8ae51b6fSMarek Vasut return 0; 339*8ae51b6fSMarek Vasut } 340*8ae51b6fSMarek Vasut 341*8ae51b6fSMarek Vasut /* E-MAC init function */ 342*8ae51b6fSMarek Vasut static int ravb_mac_init(struct ravb_priv *eth) 343*8ae51b6fSMarek Vasut { 344*8ae51b6fSMarek Vasut /* Disable MAC Interrupt */ 345*8ae51b6fSMarek Vasut writel(0, eth->iobase + RAVB_REG_ECSIPR); 346*8ae51b6fSMarek Vasut 347*8ae51b6fSMarek Vasut /* Recv frame limit set register */ 348*8ae51b6fSMarek Vasut writel(RFLR_RFL_MIN, eth->iobase + RAVB_REG_RFLR); 349*8ae51b6fSMarek Vasut 350*8ae51b6fSMarek Vasut return 0; 351*8ae51b6fSMarek Vasut } 352*8ae51b6fSMarek Vasut 353*8ae51b6fSMarek Vasut /* AVB-DMAC init function */ 354*8ae51b6fSMarek Vasut static int ravb_dmac_init(struct udevice *dev) 355*8ae51b6fSMarek Vasut { 356*8ae51b6fSMarek Vasut struct ravb_priv *eth = dev_get_priv(dev); 357*8ae51b6fSMarek Vasut struct eth_pdata *pdata = dev_get_platdata(dev); 358*8ae51b6fSMarek Vasut int ret = 0; 359*8ae51b6fSMarek Vasut 360*8ae51b6fSMarek Vasut /* Set CONFIG mode */ 361*8ae51b6fSMarek Vasut ret = ravb_reset(dev); 362*8ae51b6fSMarek Vasut if (ret) 363*8ae51b6fSMarek Vasut return ret; 364*8ae51b6fSMarek Vasut 365*8ae51b6fSMarek Vasut /* Disable all interrupts */ 366*8ae51b6fSMarek Vasut writel(0, eth->iobase + RAVB_REG_RIC0); 367*8ae51b6fSMarek Vasut writel(0, eth->iobase + RAVB_REG_RIC1); 368*8ae51b6fSMarek Vasut writel(0, eth->iobase + RAVB_REG_RIC2); 369*8ae51b6fSMarek Vasut writel(0, eth->iobase + RAVB_REG_TIC); 370*8ae51b6fSMarek Vasut 371*8ae51b6fSMarek Vasut /* Set little endian */ 372*8ae51b6fSMarek Vasut clrbits_le32(eth->iobase + RAVB_REG_CCC, CCC_BOC); 373*8ae51b6fSMarek Vasut 374*8ae51b6fSMarek Vasut /* AVB rx set */ 375*8ae51b6fSMarek Vasut writel(0x18000001, eth->iobase + RAVB_REG_RCR); 376*8ae51b6fSMarek Vasut 377*8ae51b6fSMarek Vasut /* FIFO size set */ 378*8ae51b6fSMarek Vasut writel(0x00222210, eth->iobase + RAVB_REG_TGC); 379*8ae51b6fSMarek Vasut 380*8ae51b6fSMarek Vasut /* Delay CLK: 2ns */ 381*8ae51b6fSMarek Vasut if (pdata->max_speed == 1000) 382*8ae51b6fSMarek Vasut writel(BIT(14), eth->iobase + RAVB_REG_APSR); 383*8ae51b6fSMarek Vasut 384*8ae51b6fSMarek Vasut return 0; 385*8ae51b6fSMarek Vasut } 386*8ae51b6fSMarek Vasut 387*8ae51b6fSMarek Vasut static int ravb_config(struct udevice *dev) 388*8ae51b6fSMarek Vasut { 389*8ae51b6fSMarek Vasut struct ravb_priv *eth = dev_get_priv(dev); 390*8ae51b6fSMarek Vasut struct phy_device *phy; 391*8ae51b6fSMarek Vasut u32 mask = ECMR_CHG_DM | ECMR_RE | ECMR_TE; 392*8ae51b6fSMarek Vasut int ret; 393*8ae51b6fSMarek Vasut 394*8ae51b6fSMarek Vasut /* Configure AVB-DMAC register */ 395*8ae51b6fSMarek Vasut ravb_dmac_init(dev); 396*8ae51b6fSMarek Vasut 397*8ae51b6fSMarek Vasut /* Configure E-MAC registers */ 398*8ae51b6fSMarek Vasut ravb_mac_init(eth); 399*8ae51b6fSMarek Vasut ravb_write_hwaddr(dev); 400*8ae51b6fSMarek Vasut 401*8ae51b6fSMarek Vasut /* Configure phy */ 402*8ae51b6fSMarek Vasut ret = ravb_phy_config(dev); 403*8ae51b6fSMarek Vasut if (ret) 404*8ae51b6fSMarek Vasut return ret; 405*8ae51b6fSMarek Vasut 406*8ae51b6fSMarek Vasut phy = eth->phydev; 407*8ae51b6fSMarek Vasut 408*8ae51b6fSMarek Vasut ret = phy_startup(phy); 409*8ae51b6fSMarek Vasut if (ret) 410*8ae51b6fSMarek Vasut return ret; 411*8ae51b6fSMarek Vasut 412*8ae51b6fSMarek Vasut /* Set the transfer speed */ 413*8ae51b6fSMarek Vasut if (phy->speed == 100) 414*8ae51b6fSMarek Vasut writel(0, eth->iobase + RAVB_REG_GECMR); 415*8ae51b6fSMarek Vasut else if (phy->speed == 1000) 416*8ae51b6fSMarek Vasut writel(1, eth->iobase + RAVB_REG_GECMR); 417*8ae51b6fSMarek Vasut 418*8ae51b6fSMarek Vasut /* Check if full duplex mode is supported by the phy */ 419*8ae51b6fSMarek Vasut if (phy->duplex) 420*8ae51b6fSMarek Vasut mask |= ECMR_DM; 421*8ae51b6fSMarek Vasut 422*8ae51b6fSMarek Vasut writel(mask, eth->iobase + RAVB_REG_ECMR); 423*8ae51b6fSMarek Vasut 424*8ae51b6fSMarek Vasut phy->drv->writeext(phy, -1, 0x02, 0x08, (0x0f << 5) | 0x19); 425*8ae51b6fSMarek Vasut 426*8ae51b6fSMarek Vasut return 0; 427*8ae51b6fSMarek Vasut } 428*8ae51b6fSMarek Vasut 429*8ae51b6fSMarek Vasut int ravb_start(struct udevice *dev) 430*8ae51b6fSMarek Vasut { 431*8ae51b6fSMarek Vasut struct ravb_priv *eth = dev_get_priv(dev); 432*8ae51b6fSMarek Vasut int ret; 433*8ae51b6fSMarek Vasut 434*8ae51b6fSMarek Vasut ret = ravb_reset(dev); 435*8ae51b6fSMarek Vasut if (ret) 436*8ae51b6fSMarek Vasut return ret; 437*8ae51b6fSMarek Vasut 438*8ae51b6fSMarek Vasut ravb_base_desc_init(eth); 439*8ae51b6fSMarek Vasut ravb_tx_desc_init(eth); 440*8ae51b6fSMarek Vasut ravb_rx_desc_init(eth); 441*8ae51b6fSMarek Vasut 442*8ae51b6fSMarek Vasut ret = ravb_config(dev); 443*8ae51b6fSMarek Vasut if (ret) 444*8ae51b6fSMarek Vasut return ret; 445*8ae51b6fSMarek Vasut 446*8ae51b6fSMarek Vasut /* Setting the control will start the AVB-DMAC process. */ 447*8ae51b6fSMarek Vasut writel(CCC_OPC_OPERATION, eth->iobase + RAVB_REG_CCC); 448*8ae51b6fSMarek Vasut 449*8ae51b6fSMarek Vasut return 0; 450*8ae51b6fSMarek Vasut } 451*8ae51b6fSMarek Vasut 452*8ae51b6fSMarek Vasut static void ravb_stop(struct udevice *dev) 453*8ae51b6fSMarek Vasut { 454*8ae51b6fSMarek Vasut ravb_reset(dev); 455*8ae51b6fSMarek Vasut } 456*8ae51b6fSMarek Vasut 457*8ae51b6fSMarek Vasut static int ravb_probe(struct udevice *dev) 458*8ae51b6fSMarek Vasut { 459*8ae51b6fSMarek Vasut struct eth_pdata *pdata = dev_get_platdata(dev); 460*8ae51b6fSMarek Vasut struct ravb_priv *eth = dev_get_priv(dev); 461*8ae51b6fSMarek Vasut struct mii_dev *mdiodev; 462*8ae51b6fSMarek Vasut void __iomem *iobase; 463*8ae51b6fSMarek Vasut int ret; 464*8ae51b6fSMarek Vasut 465*8ae51b6fSMarek Vasut iobase = map_physmem(pdata->iobase, 0x1000, MAP_NOCACHE); 466*8ae51b6fSMarek Vasut eth->iobase = iobase; 467*8ae51b6fSMarek Vasut 468*8ae51b6fSMarek Vasut mdiodev = mdio_alloc(); 469*8ae51b6fSMarek Vasut if (!mdiodev) { 470*8ae51b6fSMarek Vasut ret = -ENOMEM; 471*8ae51b6fSMarek Vasut goto err_mdio_alloc; 472*8ae51b6fSMarek Vasut } 473*8ae51b6fSMarek Vasut 474*8ae51b6fSMarek Vasut mdiodev->read = bb_miiphy_read; 475*8ae51b6fSMarek Vasut mdiodev->write = bb_miiphy_write; 476*8ae51b6fSMarek Vasut bb_miiphy_buses[0].priv = eth; 477*8ae51b6fSMarek Vasut snprintf(mdiodev->name, sizeof(mdiodev->name), dev->name); 478*8ae51b6fSMarek Vasut 479*8ae51b6fSMarek Vasut ret = mdio_register(mdiodev); 480*8ae51b6fSMarek Vasut if (ret < 0) 481*8ae51b6fSMarek Vasut goto err_mdio_register; 482*8ae51b6fSMarek Vasut 483*8ae51b6fSMarek Vasut eth->bus = miiphy_get_dev_by_name(dev->name); 484*8ae51b6fSMarek Vasut 485*8ae51b6fSMarek Vasut return 0; 486*8ae51b6fSMarek Vasut 487*8ae51b6fSMarek Vasut err_mdio_register: 488*8ae51b6fSMarek Vasut mdio_free(mdiodev); 489*8ae51b6fSMarek Vasut err_mdio_alloc: 490*8ae51b6fSMarek Vasut unmap_physmem(eth->iobase, MAP_NOCACHE); 491*8ae51b6fSMarek Vasut return ret; 492*8ae51b6fSMarek Vasut } 493*8ae51b6fSMarek Vasut 494*8ae51b6fSMarek Vasut static int ravb_remove(struct udevice *dev) 495*8ae51b6fSMarek Vasut { 496*8ae51b6fSMarek Vasut struct ravb_priv *eth = dev_get_priv(dev); 497*8ae51b6fSMarek Vasut 498*8ae51b6fSMarek Vasut free(eth->phydev); 499*8ae51b6fSMarek Vasut mdio_unregister(eth->bus); 500*8ae51b6fSMarek Vasut mdio_free(eth->bus); 501*8ae51b6fSMarek Vasut unmap_physmem(eth->iobase, MAP_NOCACHE); 502*8ae51b6fSMarek Vasut 503*8ae51b6fSMarek Vasut return 0; 504*8ae51b6fSMarek Vasut } 505*8ae51b6fSMarek Vasut 506*8ae51b6fSMarek Vasut int ravb_bb_init(struct bb_miiphy_bus *bus) 507*8ae51b6fSMarek Vasut { 508*8ae51b6fSMarek Vasut return 0; 509*8ae51b6fSMarek Vasut } 510*8ae51b6fSMarek Vasut 511*8ae51b6fSMarek Vasut int ravb_bb_mdio_active(struct bb_miiphy_bus *bus) 512*8ae51b6fSMarek Vasut { 513*8ae51b6fSMarek Vasut struct ravb_priv *eth = bus->priv; 514*8ae51b6fSMarek Vasut 515*8ae51b6fSMarek Vasut setbits_le32(eth->iobase + RAVB_REG_PIR, PIR_MMD); 516*8ae51b6fSMarek Vasut 517*8ae51b6fSMarek Vasut return 0; 518*8ae51b6fSMarek Vasut } 519*8ae51b6fSMarek Vasut 520*8ae51b6fSMarek Vasut int ravb_bb_mdio_tristate(struct bb_miiphy_bus *bus) 521*8ae51b6fSMarek Vasut { 522*8ae51b6fSMarek Vasut struct ravb_priv *eth = bus->priv; 523*8ae51b6fSMarek Vasut 524*8ae51b6fSMarek Vasut clrbits_le32(eth->iobase + RAVB_REG_PIR, PIR_MMD); 525*8ae51b6fSMarek Vasut 526*8ae51b6fSMarek Vasut return 0; 527*8ae51b6fSMarek Vasut } 528*8ae51b6fSMarek Vasut 529*8ae51b6fSMarek Vasut int ravb_bb_set_mdio(struct bb_miiphy_bus *bus, int v) 530*8ae51b6fSMarek Vasut { 531*8ae51b6fSMarek Vasut struct ravb_priv *eth = bus->priv; 532*8ae51b6fSMarek Vasut 533*8ae51b6fSMarek Vasut if (v) 534*8ae51b6fSMarek Vasut setbits_le32(eth->iobase + RAVB_REG_PIR, PIR_MDO); 535*8ae51b6fSMarek Vasut else 536*8ae51b6fSMarek Vasut clrbits_le32(eth->iobase + RAVB_REG_PIR, PIR_MDO); 537*8ae51b6fSMarek Vasut 538*8ae51b6fSMarek Vasut return 0; 539*8ae51b6fSMarek Vasut } 540*8ae51b6fSMarek Vasut 541*8ae51b6fSMarek Vasut int ravb_bb_get_mdio(struct bb_miiphy_bus *bus, int *v) 542*8ae51b6fSMarek Vasut { 543*8ae51b6fSMarek Vasut struct ravb_priv *eth = bus->priv; 544*8ae51b6fSMarek Vasut 545*8ae51b6fSMarek Vasut *v = (readl(eth->iobase + RAVB_REG_PIR) & PIR_MDI) >> 3; 546*8ae51b6fSMarek Vasut 547*8ae51b6fSMarek Vasut return 0; 548*8ae51b6fSMarek Vasut } 549*8ae51b6fSMarek Vasut 550*8ae51b6fSMarek Vasut int ravb_bb_set_mdc(struct bb_miiphy_bus *bus, int v) 551*8ae51b6fSMarek Vasut { 552*8ae51b6fSMarek Vasut struct ravb_priv *eth = bus->priv; 553*8ae51b6fSMarek Vasut 554*8ae51b6fSMarek Vasut if (v) 555*8ae51b6fSMarek Vasut setbits_le32(eth->iobase + RAVB_REG_PIR, PIR_MDC); 556*8ae51b6fSMarek Vasut else 557*8ae51b6fSMarek Vasut clrbits_le32(eth->iobase + RAVB_REG_PIR, PIR_MDC); 558*8ae51b6fSMarek Vasut 559*8ae51b6fSMarek Vasut return 0; 560*8ae51b6fSMarek Vasut } 561*8ae51b6fSMarek Vasut 562*8ae51b6fSMarek Vasut int ravb_bb_delay(struct bb_miiphy_bus *bus) 563*8ae51b6fSMarek Vasut { 564*8ae51b6fSMarek Vasut udelay(10); 565*8ae51b6fSMarek Vasut 566*8ae51b6fSMarek Vasut return 0; 567*8ae51b6fSMarek Vasut } 568*8ae51b6fSMarek Vasut 569*8ae51b6fSMarek Vasut struct bb_miiphy_bus bb_miiphy_buses[] = { 570*8ae51b6fSMarek Vasut { 571*8ae51b6fSMarek Vasut .name = "ravb", 572*8ae51b6fSMarek Vasut .init = ravb_bb_init, 573*8ae51b6fSMarek Vasut .mdio_active = ravb_bb_mdio_active, 574*8ae51b6fSMarek Vasut .mdio_tristate = ravb_bb_mdio_tristate, 575*8ae51b6fSMarek Vasut .set_mdio = ravb_bb_set_mdio, 576*8ae51b6fSMarek Vasut .get_mdio = ravb_bb_get_mdio, 577*8ae51b6fSMarek Vasut .set_mdc = ravb_bb_set_mdc, 578*8ae51b6fSMarek Vasut .delay = ravb_bb_delay, 579*8ae51b6fSMarek Vasut }, 580*8ae51b6fSMarek Vasut }; 581*8ae51b6fSMarek Vasut int bb_miiphy_buses_num = ARRAY_SIZE(bb_miiphy_buses); 582*8ae51b6fSMarek Vasut 583*8ae51b6fSMarek Vasut static const struct eth_ops ravb_ops = { 584*8ae51b6fSMarek Vasut .start = ravb_start, 585*8ae51b6fSMarek Vasut .send = ravb_send, 586*8ae51b6fSMarek Vasut .recv = ravb_recv, 587*8ae51b6fSMarek Vasut .free_pkt = ravb_free_pkt, 588*8ae51b6fSMarek Vasut .stop = ravb_stop, 589*8ae51b6fSMarek Vasut .write_hwaddr = ravb_write_hwaddr, 590*8ae51b6fSMarek Vasut }; 591*8ae51b6fSMarek Vasut 592*8ae51b6fSMarek Vasut U_BOOT_DRIVER(eth_ravb) = { 593*8ae51b6fSMarek Vasut .name = "ravb", 594*8ae51b6fSMarek Vasut .id = UCLASS_ETH, 595*8ae51b6fSMarek Vasut .probe = ravb_probe, 596*8ae51b6fSMarek Vasut .remove = ravb_remove, 597*8ae51b6fSMarek Vasut .ops = &ravb_ops, 598*8ae51b6fSMarek Vasut .priv_auto_alloc_size = sizeof(struct ravb_priv), 599*8ae51b6fSMarek Vasut .platdata_auto_alloc_size = sizeof(struct eth_pdata), 600*8ae51b6fSMarek Vasut .flags = DM_FLAG_ALLOC_PRIV_DMA, 601*8ae51b6fSMarek Vasut }; 602