1/*
2 * Copyright 2017, NXP
3 * Copyright 2017, Data61
4 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
5 * ABN 41 687 119 230.
6 *
7 * This software may be distributed and modified according to the terms of
8 * the GNU General Public License version 2. Note that NO WARRANTY is provided.
9 * See "LICENSE_GPLv2.txt" for details.
10 *
11 * @TAG(DATA61_GPL)
12 */
13
14#include "enet.h"
15#include <stdint.h>
16#include <assert.h>
17#include "io.h"
18#include <platsupport/clock.h>
19#include "unimplemented.h"
20#include "../../debug.h"
21#include <stdlib.h>
22
23#ifdef CONFIG_PLAT_IMX6
24#define IMX6_ENET_PADDR 0x02188000
25#define IMX6_ENET_SIZE  0x00004000
26#endif
27#ifdef CONFIG_PLAT_IMX8MQ_EVK
28#define IMX6_ENET_PADDR 0x30be0000
29#define IMX6_ENET_SIZE  0x10000
30
31#define CCM_PADDR 0x30380000
32#define CCM_SIZE 0x10000
33#endif
34
35#define ENET_FREQ  125000000UL
36#define MDC_FREQ    20000000UL /* must be less than 2.5MHz */
37
38struct mib_regs {
39    /* NOTE: Counter not implemented because it is not applicable (read 0 always).*/
40    uint32_t rmon_t_drop;        /* 00 Register Count of frames not counted correctly */
41    uint32_t rmon_t_packets;     /* 04 RMON Tx packet count */
42    uint32_t rmon_t_bc_pkt;      /* 08 RMON Tx Broadcast Packets */
43    uint32_t rmon_t_mc_pkt;      /* 0C RMON Tx Multicast Packets */
44    uint32_t rmon_t_crc_align;   /* 10 RMON Tx Packets w CRC/Align error */
45    uint32_t rmon_t_undersize;   /* 14 RMON Tx Packets < 64 bytes, good CRC */
46    uint32_t rmon_t_oversize;    /* 18 RMON Tx Packets > MAX_FL bytes, good CRC */
47    uint32_t rmon_t_frag;        /* 1C RMON Tx Packets < 64 bytes, bad CRC */
48    uint32_t rmon_t_jab;         /* 20 RMON Tx Packets > MAX_FL bytes, bad CRC*/
49    uint32_t rmon_t_col;         /* 24 RMON Tx collision count */
50    uint32_t rmon_t_p64;         /* 28 RMON Tx 64 byte packets */
51    uint32_t rmon_t_p65to127n;   /* 2C RMON Tx 65 to 127 byte packets */
52    uint32_t rmon_t_p128to255n;  /* 30 RMON Tx 128 to 255 byte packets */
53    uint32_t rmon_t_p256to511;   /* 34 RMON Tx 256 to 511 byte packets */
54    uint32_t rmon_t_p512to1023;  /* 38 RMON Tx 512 to 1023 byte packets */
55    uint32_t rmon_t_p1024to2047; /* 3C RMON Tx 1024 to 2047 byte packets */
56    uint32_t rmon_t_p_gte2048;   /* 40 RMON Tx packets w > 2048 bytes */
57    uint32_t rmon_t_octets;      /* 44 RMON Tx Octets */
58    /* NOTE: Counter not implemented because it is not applicable (read 0 always). */
59    uint32_t ieee_t_drop;        /* 48 Count of frames not counted correctly */
60    uint32_t ieee_t_frame_ok;    /* 4C Frames Transmitted OK */
61    uint32_t ieee_t_1col;        /* 50 Frames Transmitted with Single Collision */
62    uint32_t ieee_t_mcol;        /* 54 Frames Transmitted with Multiple Collisions */
63    uint32_t ieee_t_def;         /* 58 Frames Transmitted after Deferral Delay */
64    uint32_t ieee_t_lcol;        /* 5C Frames Transmitted with Late Collision */
65    uint32_t ieee_t_excol;       /* 60 Frames Transmitted with Excessive Collisions */
66    uint32_t ieee_t_macerr;      /* 64 Frames Transmitted with Tx FIFO Underrun */
67    uint32_t ieee_t_cserr;       /* 68 Frames Transmitted with Carrier Sense Error */
68    /* NOTE: Counter not implemented because there is no SQE information available (read 0 always). */
69    uint32_t ieee_t_sqe;         /* 6C Frames Transmitted with SQE Error */
70    uint32_t ieee_t_fdxfc;       /* 70 Flow Control Pause frames transmitted */
71    /* NOTE: Counts total octets (includes header and FCS fields). */
72    uint32_t ieee_t_octets_ok;   /* 74 Octet count for Frames Transmitted w/o Error */
73    uint32_t res0[3];
74    uint32_t rmon_r_packets;     /* 84 RMON Rx packet count */
75    uint32_t rmon_r_bc_pkt;      /* 88 RMON Rx Broadcast Packets */
76    uint32_t rmon_r_mc_pkt;      /* 8C RMON Rx Multicast Packets */
77    uint32_t rmon_r_crc_align;   /* 90 RMON Rx Packets w CRC/Align error */
78    uint32_t rmon_r_undersize;   /* 94 RMON Rx Packets < 64 bytes, good CRC */
79    uint32_t rmon_r_oversize;    /* 98 RMON Rx Packets > MAX_FL, good CRC */
80    uint32_t rmon_r_frag;        /* 9C RMON Rx Packets < 64 bytes, bad CRC */
81    uint32_t rmon_r_jab;         /* A0 RMON Rx Packets > MAX_FL bytes, bad CRC  */
82    uint32_t rmon_r_resvd_0;     /* A4 Reserved */
83    uint32_t rmon_r_p64;         /* A8 RMON Rx 64 byte packets */
84    uint32_t rmon_r_p65to127;    /* AC RMON Rx 65 to 127 byte packets */
85    uint32_t rmon_r_p128to255;   /* B0 RMON Rx 128 to 255 byte packets */
86    uint32_t rmon_r_p256to511;   /* B4 RMON Rx 256 to 511 byte packets */
87    uint32_t rmon_r_p512to1023;  /* B8 RMON Rx 512 to 1023 byte packets */
88    uint32_t rmon_r_p1024to2047; /* BC RMON Rx 1024 to 2047 byte packets */
89    uint32_t rmon_r_p_gte2048;   /* C0 RMON Rx packets w > 2048 bytes */
90    uint32_t rmon_r_octets;      /* C4 RMON Rx Octets */
91    /* NOTE: Counter increments if a frame with invalid/missing SFD character is
92     * detected and has been dropped. None of the other counters increments if
93     * this counter increments. */
94    uint32_t ieee_r_drop;        /* C8 Count of frames not counted correctly */
95    uint32_t ieee_r_frame_ok;    /* CC Frames Received OK */
96    uint32_t ieee_r_crc;         /* D0 Frames Received with CRC Error */
97    uint32_t ieee_r_align;       /* D4 Frames Received with Alignment Error */
98    /* Assume they mean D8... */
99    uint32_t ieee_r_macerr;      /* D7 Receive FIFO Overflow count */
100    uint32_t ieee_r_fdxfc;       /* DC Flow Control Pause frames received */
101    /* NOTE: Counts total octets (includes header and FCS fields ) */
102    uint32_t ieee_r_octets_ok;   /* E0 Octet count for Frames Rcvd w/o Error */
103    uint32_t res1[7];
104};
105
106struct enet_regs {
107    /* Configuration */
108    uint32_t res0[1];
109    uint32_t eir;    /* 004 Interrupt Event Register */
110    uint32_t eimr;   /* 008 Interrupt Mask Register */
111    uint32_t res1[1];
112    uint32_t rdar;   /* 010 Receive Descriptor Active Register */
113    uint32_t tdar;   /* 014 Transmit Descriptor Active Register */
114    uint32_t res2[3];
115    uint32_t ecr;    /* 024 Ethernet Control Register */
116    uint32_t res3[6];
117    uint32_t mmfr;   /* 040 MII Management Frame Register */
118    uint32_t mscr;   /* 044 MII Speed Control Register */
119    uint32_t res4[7];
120    uint32_t mibc;   /* 064 MIB Control Register */
121    uint32_t res5[7];
122    uint32_t rcr;    /* 084 Receive Control Register */
123    uint32_t res6[15];
124    uint32_t tcr;    /* 0C4 Transmit Control Register */
125    uint32_t res7[7];
126    uint32_t palr;   /* 0E4 Physical Address Lower Register */
127    uint32_t paur;   /* 0E8 Physical Address Upper Register */
128    uint32_t opd;    /* 0EC Opcode/Pause Duration Register */
129    uint32_t res8[10];
130    uint32_t iaur;   /* 118 Descriptor Individual Upper Address Register */
131    uint32_t ialr;   /* 11C Descriptor Individual Lower Address Register */
132    uint32_t gaur;   /* 120 Descriptor Group Upper Address Register */
133    uint32_t galr;   /* 124 Descriptor Group Lower Address Register */
134    uint32_t res9[7];
135    uint32_t tfwr;   /* 144 Transmit FIFO Watermark Register */
136    uint32_t res10[14];
137    uint32_t rdsr;   /* 180 Receive Descriptor Ring Start Register */
138    uint32_t tdsr;   /* 184 Transmit Buffer Descriptor Ring Start Register */
139    uint32_t mrbr;   /* 188 Maximum Receive Buffer Size Register */
140    uint32_t res12[1];
141    uint32_t rsfl;   /* 190 Receive FIFO Section Full Threshold */
142    uint32_t rsem;   /* 194 Receive FIFO Section Empty Threshold */
143    uint32_t raem;   /* 198 Receive FIFO Almost Empty Threshold */
144    uint32_t rafl;   /* 19C Receive FIFO Almost Full Threshold */
145    uint32_t tsem;   /* 1A0 Transmit FIFO Section Empty Threshold */
146    uint32_t taem;   /* 1A4 Transmit FIFO Almost Empty Threshold */
147    uint32_t tafl;   /* 1A8 Transmit FIFO Almost Full Threshold */
148    uint32_t tipg;   /* 1AC Transmit Inter-Packet Gap */
149    uint32_t ftrl;   /* 1B0 Frame Truncation Length */
150    uint32_t res13[3];
151    uint32_t tacc;   /* 1C0 Transmit Accelerator Function Configuration */
152    uint32_t racc;   /* 1C4 Receive Accelerator Function Configuration */
153    uint32_t res14[14];
154    /* 0x200: Statistics counters MIB block RFC 2819 */
155    struct mib_regs mib;
156    uint32_t res15[64];
157    /* 0x400: 1588 adjustable timer (TSM) and 1588 frame control */
158    uint32_t atcr;   /* 400 Timer Control Register */
159    uint32_t atvr;   /* 404 Timer Value Register */
160    uint32_t atoff;  /* 408 Timer Offset Register */
161    uint32_t atper;  /* 40C Timer Period Register */
162    uint32_t atcor;  /* 410 Timer Correction Register */
163    uint32_t atinc;  /* 414 Time-Stamping Clock Period Register */
164    uint32_t atstmp; /* 418 Timestamp of Last Transmitted Frame */
165    uint32_t res16[121];
166
167    /* 0x600: Capture/compare block */
168    uint32_t res17[1];
169    uint32_t tgsr;   /* 604 Timer Global Status Register */
170    uint32_t tcsr0;  /* 608 Timer Control Status Register */
171    uint32_t tccr0;  /* 60C Timer Compare Capture Register */
172    uint32_t tcsr1;  /* 610 Timer Control Status Register */
173    uint32_t tccr1;  /* 614 Timer Compare Capture Register */
174    uint32_t tcsr2;  /* 618 Timer Control Status Register */
175    uint32_t tccr2;  /* 61C Timer Compare Capture Register */
176    uint32_t tcsr3;  /* 620 Timer Control Status Register */
177    uint32_t tccr3;  /* 624 Timer Compare Capture Register */
178};
179
180struct enet {
181    void *dummy;
182};
183
184typedef volatile struct enet_regs enet_regs_t;
185
186static inline enet_regs_t *enet_get_regs(struct enet *enet)
187{
188    return (enet_regs_t *)enet;
189}
190
191/* Ethernet control register */
192#define ECR_DBSWP   BIT(8) /* descriptor byte swapping enable */
193#define ECR_STOPEN  BIT(7) /* Disable ENET clock in doze mode */
194#define ECR_DBGEN   BIT(6) /* Harware freeze when in debug mode */
195#define ECR_SPEED   BIT(5) /* Enable 1000Mbps */
196#define ECR_EN1588  BIT(4) /* Enhanced descriptors */
197#define ECR_SLEEP   BIT(3) /* Enter sleep mode */
198#define ECR_MAGICEN BIT(2) /* Magic packet detection enable */
199#define ECR_ETHEREN BIT(1) /* Enable */
200#define ECR_RESET   BIT(0) /* Reset */
201
202/* Receive control register */
203#define RCR_GRS       BIT(31) /* Graceful Receive Stopped */
204#define RCR_NLC       BIT(30) /* No payload Length Check */
205#define RCR_MAX_FL(x) (((x) & 0x3fff) << 16) /* Maximum Frame Length */
206#define RCR_CFEN      BIT(15) /* MAC Control Frame Enable */
207#define RCR_CRCSTRIP  BIT(14) /* Do not Forward Received CRC */
208#define RCR_PAUFWD    BIT(13) /* Forward Pause Frames */
209#define RCR_PADEN     BIT(12) /* Frame padding enable */
210#define RCR_RMII_10T  BIT( 9) /* 10 Mbps */
211#define RCR_RMII_MODE BIT( 8) /* RMII Mode Enable */
212#define RCR_RGMII_EN  BIT( 6) /* RGMII  Mode Enable. RMII must not be set */
213#define RCR_FCE       BIT( 5) /* Flow control enable */
214#define RCR_BC_REJ    BIT( 4) /* Broadcast frame reject */
215#define RCR_PROM      BIT( 3) /* Promiscuous mode */
216#define RCR_MII_MODE  BIT( 2) /* This field must always be set */
217#define RCR_DRT       BIT( 1) /* Don't receive while transmitting (half duplex) */
218#define RCR_LOOP      BIT( 0) /* internal loop back */
219
220/* Transmit control register */
221#define TCR_CRCINS    BIT( 9) /* Insert CRC on transit */
222#define TCR_ADDINS    BIT( 8) /* Insert MAC address on transit */
223#define TCR_ADDSEL(x) (((x) & 0x7) << 5) /* MAC select (supports only 0) */
224#define TCR_RFCPAUSE  BIT(4) /* Received a pause frame */
225#define TCR_TFCPAUSE  BIT(3) /* Transmit pause frame after the current frame completes */
226#define TCR_FDEN      BIT(2) /* Full duplex enable */
227#define TCR_GTS       BIT(0) /* Graceful TX stop */
228
229/* Receive Accelerator Function Configuration */
230#define RACC_LINEDIS  BIT(6) /* Discard frames with MAC layer errors */
231
232/* Transmit FIFO watermark */
233#define TFWR_STRFWD   BIT( 8) /* Enables store and forward */
234
235/* MIB control */
236#define MIBC_DIS      BIT(31) /* Disable MIB counters */
237#define MIBC_IDLE     BIT(30) /* MIB currently updating a counter */
238#define MIBC_CLEAR    BIT(29) /* Clear all counters */
239
240/* RX descriptor active */
241#define RDAR_RDAR     BIT(24) /* RX descriptor active */
242
243/* TX descriptor active */
244#define TDAR_TDAR     BIT(24) /* TX descriptor active */
245
246/* TODO this should be defined elsewhere */
247#define FRAME_LEN 1518
248
249#define PAUSE_FRAME_TYPE_FIELD 0x8808 /* fixed magic */
250#define PAUSE_OPCODE_FIELD     0x0001 /* Fixed magic opcode used when sending pause frames */
251/* configurable */
252#define PAUSE_DURATION             32 /* Pause duration field when sending pause frames */
253#define STRFWD_BYTES              128 /* Number of bytes in buffer before transmission begins */
254
255#define TIPG                       8 /* TX inter-packet gap between 8 and 27 bytes */
256
257#define PHYOP_VALID      (BIT(30) | BIT(17))
258#define PHYOP_READ        BIT(29)
259#define PHYOP_WRITE       BIT(28)
260#define PHYOP_PHY_SHIFT       23
261#define PHYOP_REG_SHIFT       18
262#define PHYOP_DATA_SHIFT       0
263
264/******************
265 *** MDIO clock ***
266 ******************/
267
268static freq_t _mdc_clk_get_freq(clk_t *clk)
269{
270    enet_regs_t *regs = (enet_regs_t *)clk->priv;
271    uint32_t fin = clk_get_freq(clk->parent);
272    uint32_t v = (regs->mscr >> 1) & 0x3f;
273    uint32_t fout = fin / ((v + 1) * 2);
274    return fout;
275}
276
277static freq_t _mdc_clk_set_freq(clk_t *clk, freq_t hz)
278{
279    enet_regs_t *regs = (enet_regs_t *)clk->priv;
280    uint32_t fin = clk_get_freq(clk->parent);
281    uint32_t v;
282
283    if (hz > 2500000UL) {
284        hz = 2500000UL;
285    } else if (hz == 0) {
286        hz = 1;
287    }
288
289    v = fin / (2 * hz) - 1;
290
291    if (v == -1) {
292        v = 0;
293    } else if (v > 0x3f) {
294        v = 0x3f;
295    }
296
297    regs->mscr = v << 1;
298    CLK_DEBUG(printf("Set MDC frequency to %.1f Mhz (<= 2.5 Mhz)\n",
299                     (float)clk_get_freq(clk) / MHZ));
300    return clk_get_freq(clk);
301}
302
303static void _mdc_clk_recal(struct clock *clk)
304{
305    assert(0);
306}
307
308static clk_t *_mdc_clk_init(clk_t *clk)
309{
310    return clk;
311}
312
313static struct clock mdc_clk = {
314    .id = CLK_CUSTOM,
315    .name = "mdc_clk",
316    .priv = NULL,
317    .req_freq = 2500000UL,
318    .set_freq = &_mdc_clk_set_freq,
319    .get_freq = &_mdc_clk_get_freq,
320    .recal = &_mdc_clk_recal,
321    .init = &_mdc_clk_init,
322    .parent = NULL,
323    .sibling = NULL,
324    .child = NULL,
325};
326
327#ifdef CONFIG_PLAT_IMX8MQ_EVK
328static freq_t _enet_clk_get_freq(clk_t *clk)
329{
330    return clk->req_freq;
331}
332
333static struct clock enet_clk = {
334    .id = CLK_CUSTOM,
335    .name = "enet_clk",
336    .priv = NULL,
337    .req_freq = 125000000UL,
338    .set_freq = NULL,
339    .get_freq = &_enet_clk_get_freq,
340    .recal = NULL,
341    .init = NULL,
342    .parent = NULL,
343    .sibling = NULL,
344    .child = NULL,
345};
346#endif
347
348void enet_set_speed(struct enet *enet, int speed, int full_duplex)
349{
350    enet_regs_t *regs = enet_get_regs(enet);
351    uint32_t ecr = regs->ecr;
352    uint32_t rcr = regs->rcr;
353    /* RGMII mode */
354    rcr &= ~RCR_RMII_MODE;
355    rcr |= RCR_RGMII_EN | RCR_MII_MODE;
356    /* Now select speed */
357    switch (speed) {
358    case 1000:
359        ecr |= ECR_SPEED;
360        rcr &= ~RCR_RMII_10T;
361        break;
362    case 100:
363        ecr &= ~ECR_SPEED;
364        rcr &= ~RCR_RMII_10T;
365        break;
366    case 10:
367        ecr &= ~ECR_SPEED;
368        rcr |= RCR_RMII_10T;
369        break;
370    default:
371        printf("Invalid speed\n");
372        assert(0);
373        return;
374    }
375    /* Now select duplex */
376    if (full_duplex) {
377        rcr &= ~RCR_DRT;
378    } else {
379        rcr |= RCR_DRT;
380    }
381    /* Write the registers */
382    regs->ecr = ecr;
383    regs->rcr = rcr;
384}
385
386/****************
387 *** MDIO bus ***
388 ****************/
389
390int enet_mdio_read(struct enet *enet, uint16_t phy, uint16_t reg)
391{
392    enet_regs_t *regs = enet_get_regs(enet);
393    uint32_t v;
394    assert(!(phy & ~0x1f));
395    assert(!(reg & ~0x1f));
396    assert(regs->mscr);
397    assert(!enet_clr_events(enet, NETIRQ_MII));
398    v  = phy << PHYOP_PHY_SHIFT | reg << PHYOP_REG_SHIFT;
399    v |= PHYOP_READ | PHYOP_VALID;
400    writel(v, &regs->mmfr);
401    while (!enet_clr_events(enet, NETIRQ_MII)) {
402        dsb();
403    }
404    return readl(&regs->mmfr) & 0xffff;
405}
406
407int enet_mdio_write(struct enet *enet, uint16_t phy, uint16_t reg, uint16_t data)
408{
409    enet_regs_t *regs = enet_get_regs(enet);
410    uint32_t v;
411    assert(!(phy & ~0x1f));
412    assert(!(reg & ~0x1f));
413    assert(regs->mscr);
414    assert(!enet_clr_events(enet, NETIRQ_MII));
415    v  = phy << PHYOP_PHY_SHIFT | reg << PHYOP_REG_SHIFT | data;
416    v |= PHYOP_WRITE | PHYOP_VALID;
417    regs->mmfr = v;
418    while (!enet_clr_events(enet, NETIRQ_MII));
419    return 0;
420}
421
422/*******************
423 *** ENET driver ***
424 *******************/
425void enet_rx_enable(struct enet *enet)
426{
427    enet_get_regs(enet)->rdar = RDAR_RDAR;
428}
429
430int enet_rx_enabled(struct enet *enet)
431{
432    return enet_get_regs(enet)->rdar == RDAR_RDAR;
433}
434
435int enet_tx_enabled(struct enet *enet)
436{
437    return enet_get_regs(enet)->tdar == TDAR_TDAR;
438}
439
440void enet_tx_enable(struct enet *enet)
441{
442    enet_get_regs(enet)->tdar = TDAR_TDAR;
443}
444
445void enet_enable(struct enet *enet)
446{
447    enet_regs_t *regs = enet_get_regs(enet);
448    regs->ecr |= ECR_ETHEREN;
449}
450
451int enet_enabled(struct enet *enet)
452{
453    enet_regs_t *regs = enet_get_regs(enet);
454    return (regs->ecr & ECR_ETHEREN) != 0;
455}
456
457void enet_disable(struct enet *enet)
458{
459    enet_regs_t *regs = enet_get_regs(enet);
460    assert(!"WARNING Descriptors will be reset");
461    regs->ecr &= ~ECR_ETHEREN;
462}
463
464void enet_set_mac(struct enet *enet, unsigned char *mac)
465{
466    enet_regs_t *regs = enet_get_regs(enet);
467    regs->palr = mac[0] << 24 | mac[1] << 16 | mac[2] << 8 | mac[3] << 0;
468    regs->paur = mac[4] << 24 | mac[5] << 16 | PAUSE_FRAME_TYPE_FIELD;
469}
470
471void enet_get_mac(struct enet *enet, unsigned char *mac)
472{
473    enet_regs_t *regs = enet_get_regs(enet);
474    uint32_t macl = regs->palr;
475    uint32_t macu = regs->paur;
476
477    /* set MAC hardware address */
478    mac[0] = macl >> 24;
479    mac[1] = macl >> 16;
480    mac[2] = macl >>  8;
481    mac[3] = macl >>  0;
482    mac[4] = macu >> 24;
483    mac[5] = macu >> 16;
484}
485
486void enet_enable_events(struct enet *enet, uint32_t mask)
487{
488    assert(enet);
489    enet_get_regs(enet)->eimr = mask;
490}
491
492uint32_t enet_get_events(struct enet *enet)
493{
494    return enet_get_regs(enet)->eir;
495}
496
497uint32_t enet_clr_events(struct enet *enet, uint32_t bits)
498{
499    enet_regs_t *regs = enet_get_regs(enet);
500    uint32_t e = regs->eir & bits;
501    /* write 1 to clear */
502    regs->eir = e;
503    return e;
504}
505
506void enet_prom_enable(struct enet *enet)
507{
508    enet_regs_t *regs = enet_get_regs(enet);
509    regs->rcr |= RCR_PROM;
510}
511
512void enet_prom_disable(struct enet *enet)
513{
514    enet_regs_t *regs = enet_get_regs(enet);
515    regs->rcr &= ~RCR_PROM;
516}
517
518struct enet *
519enet_init(struct desc_data desc_data, ps_io_ops_t *io_ops)
520{
521    enet_regs_t *regs;
522    struct enet *ret;
523    struct clock *enet_clk_ptr = NULL;
524
525    /* Map in the device */
526    regs = RESOURCE(&io_ops->io_mapper, IMX6_ENET);
527    if (regs == NULL) {
528        return NULL;
529    }
530    ret = (struct enet *)regs;
531    /* Perform reset */
532    regs->ecr = ECR_RESET;
533    while (regs->ecr & ECR_RESET);
534    regs->ecr |= ECR_DBSWP;
535
536    /* Clear and mask interrupts */
537    regs->eimr = 0x00000000;
538    regs->eir  = 0xffffffff;
539
540#ifdef CONFIG_PLAT_IMX6
541    /* Set the ethernet clock frequency */
542    clock_sys_t *clk_sys = malloc(sizeof(clock_sys_t));
543    clock_sys_init(io_ops, clk_sys);
544    enet_clk_ptr = clk_get_clock(clk_sys, CLK_ENET);
545    clk_set_freq(enet_clk_ptr, ENET_FREQ);
546#endif
547#ifdef CONFIG_PLAT_IMX8MQ_EVK
548    enet_clk_ptr = &enet_clk;
549    // TODO Implement an actual clock driver for the imx8mq
550    void *clock_base = RESOURCE(&io_ops->io_mapper, CCM);
551    if (!clock_base) {
552        return NULL;
553    }
554
555    uint32_t *ccgr_enet_set = clock_base + 0x40a0;
556    uint32_t *ccgr_enet_clr = clock_base + 0x40a4;
557    uint32_t *ccgr_sim_enet_set = clock_base + 0x4400;
558    uint32_t *ccgr_sim_enet_clr = clock_base + 0x4404;
559
560    /* Gate the clocks first */
561    *ccgr_enet_clr = 0x3;
562    *ccgr_sim_enet_clr = 0x3;
563
564    /* Setup the clocks to have the proper sources/configs */
565    uint32_t *enet_axi_target = clock_base + 0x8880;
566    uint32_t *enet_ref_target = clock_base + 0xa980;
567    uint32_t *enet_timer_target = clock_base + 0xaa00;
568
569    *enet_axi_target = BIT(28) | 0x01000000; // ENABLE | MUX SYS1_PLL | POST AND PRE DIVIDE BY 1
570    *enet_ref_target = BIT(28) | 0x01000000; // ENABLE | MUX PLL2_DIV8 | POST AND PRE DIVIDE BY 1
571    *enet_timer_target = BIT(28) | 0x01000000 | ((4) & 0x3f); // ENABLE | MUX PLL2_DIV10 | POST DIVIDE BY 4, PRE DIVIDE BY 1
572
573    /* Ungate the clocks now */
574    *ccgr_enet_set = 0x3;
575    *ccgr_sim_enet_set = 0x3;
576#endif
577
578    /* Set the MDIO clock frequency */
579    mdc_clk.priv = (void *)enet_get_regs(ret);
580    clk_register_child(enet_clk_ptr, &mdc_clk);
581    clk_set_freq(&mdc_clk, MDC_FREQ);
582
583    /* Clear out MIB */
584    enet_clear_mib(ret);
585
586    /* Descriptor group and individual hash tables - Not changed on reset */
587    regs->iaur = 0;
588    regs->ialr = 0;
589    regs->gaur = 0;
590    regs->galr = 0;
591
592    /* Set MAC and pause frame type field */
593    enet_set_mac(ret, (unsigned char *)"\0\0\0\0\0\0");
594
595    /* Configure pause frames (continues into MAC registers...) */
596    regs->opd = PAUSE_OPCODE_FIELD << 16;
597#ifdef PAUSE_DURATION
598    if (PAUSE_DURATION >= 0) {
599        regs->opd |= PAUSE_DURATION << 0;
600    }
601#endif
602
603    /* TX inter-packet gap */
604    regs->tipg = TIPG;
605    /* Tranmsmit FIFO Watermark register - store and forward */
606    regs->tfwr = 0;
607#ifdef STRFWD_BYTES
608    if (STRFWD_BYTES > 0) {
609        regs->tfwr = STRFWD_BYTES / 64;
610        regs->tfwr |= TFWR_STRFWD;
611    }
612#endif
613
614    /* Do not forward frames with errors */
615    regs->racc = RACC_LINEDIS;
616
617    /* DMA descriptors */
618    regs->tdsr = desc_data.tx_phys;
619    regs->rdsr = desc_data.rx_phys;
620    regs->mrbr = desc_data.rx_bufsize;
621
622    /* Receive control - Set frame length and RGMII mode */
623    regs->rcr = RCR_MAX_FL(FRAME_LEN) | RCR_RGMII_EN | RCR_MII_MODE;
624    /* Transmit control - Full duplex mode */
625    regs->tcr = TCR_FDEN;
626
627    /* Setup the control path to the phy */
628    return ret;
629}
630
631/****************************
632 *** Debug and statistics ***
633 ****************************/
634
635static void dump_regs(uint32_t *start, int size)
636{
637    int i, j;
638    uint32_t *base = start;
639    for (i = 0; i < size / sizeof(*start);) {
640        printf("+0x%03x: ", ((uint32_t)(start - base)) * 4);
641        for (j = 0; j < 4; j++, i++, start++) {
642            printf("0x%08x ", *start);
643        }
644        printf("\n");
645    }
646}
647
648void enet_dump_regs(struct enet *enet)
649{
650    enet_regs_t *regs = enet_get_regs(enet);
651    printf("\nEthernet regs\n");
652    dump_regs((uint32_t *)regs, sizeof(*regs));
653    printf("\n");
654}
655
656void enet_clear_mib(struct enet *enet)
657{
658    enet_regs_t *regs = enet_get_regs(enet);
659    /* Disable */
660    regs->mibc |= MIBC_DIS;
661    while (!(regs->mibc & MIBC_IDLE));
662    /* Clear */
663    regs->mibc |= MIBC_CLEAR;
664    while (!(regs->mibc & MIBC_IDLE));
665    /* Restart */
666    regs->mibc &= ~MIBC_CLEAR;
667    regs->mibc &= ~MIBC_DIS;
668}
669
670void enet_print_mib(struct enet *enet)
671{
672    enet_regs_t *regs = enet_get_regs(enet);
673    volatile struct mib_regs *mib = &regs->mib;
674    regs->mibc |= MIBC_DIS;
675
676    printf("Ethernet Counter regs\n");
677    dump_regs((uint32_t *)mib, sizeof(*mib));
678    printf("\n");
679
680    printf("-----------------------------\n");
681    printf("RX  Frames RX OK: %d/%d\n", mib->ieee_r_frame_ok,
682           mib->rmon_r_packets);
683    printf("RX FIFO overflow: %d\n", mib->ieee_r_macerr);
684    printf("RX  pause frames: %d\n", mib->ieee_r_fdxfc);
685    printf("-----------------------------\n");
686    printf("TX  Frames TX OK: %d/%d\n", mib->ieee_t_frame_ok,
687           mib->rmon_t_packets);
688    printf("TX FIFO underrun: %d\n", mib->ieee_t_macerr);
689    printf("TX  pause frames: %d\n", mib->ieee_t_fdxfc);
690    printf("-----------------------------\n");
691    printf("\n");
692    regs->mibc &= ~MIBC_DIS;
693}
694
695void enet_print_state(struct enet *enet)
696{
697    enet_regs_t *regs = enet_get_regs(enet);
698    printf("Ethernet state: %s\n", (enet_enabled(enet)) ? "Active" : "Inactive");
699    printf("      TX state: %s\n", (enet_tx_enabled(enet)) ? "Active" : "Inactive");
700    printf("      RX state: %s\n", (enet_rx_enabled(enet)) ? "Active" : "Inactive");
701    printf("    TX control: 0x%08x\n", regs->tcr);
702    printf("    RX control: 0x%08x\n", regs->rcr);
703    printf("  RX desc base: 0x%08x (size: 0x%x)\n", regs->rdsr, regs->mrbr);
704    printf("  TX desc base: 0x%08x\n", regs->tdsr);
705    printf("Enabled events: 0x%08x\n", regs->eimr);
706    printf("Pending events: 0x%08x\n", regs->eir);
707    printf("         Speed: ????\n");
708    printf("\n");
709}
710