summaryrefslogtreecommitdiff
path: root/components/drivers/ethernet/cadence/macb.h
blob: 46013d0e42de06d5ab7eb863bf555eda787d8cba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
/*
 * Copyright (c) 2006-2023, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2023-11-25     GuEe-GUI     first version
 */

#ifndef __MACB_H__
#define __MACB_H__

#include <rthw.h>
#include <rtthread.h>
#include <rtdevice.h>

#include "../ethernet_dm.h"

/* Queue 0 (legacy offsets) */
#define GEM_NCR                                 0x0000
#define GEM_NCFGR                               0x0004
#define GEM_NSR                                 0x0008
#define GEM_USRIO                               0x000c
#define GEM_DMACFG                              0x0010
#define GEM_TSR                                 0x0014
#define GEM_TSR_TGO                             RT_BIT(3)
#define GEM_TSR_COMP                            RT_BIT(5)
#define GEM_RSR                                 0x0020
#define GEM_ISR                                 0x0024
#define GEM_IER                                 0x0028
#define GEM_IDR                                 0x002c
#define GEM_IMR                                 0x0030
#define GEM_ISR0                                0x0400  /* GEM queue 0 ISR */
#define GEM_IER0                                0x0600  /* GEM queue 0 IER */
#define GEM_IDR0                                0x0620  /* GEM queue 0 IDR */
#define GEM_IMR0                                0x0640  /* GEM queue 0 IMR */
#define GEM_MAN                                 0x0034  /* PHY maintenance (was wrongly 0x340) */
/*
 * GEM queue 0 uses legacy MACB ring/IRQ registers; GEM_*Q1+ live at 0x440/0x480.
 * Linux: queue0 -> MACB_TBQP/RBQP/ISR/IER; queue1+ -> GEM_TBQP(n)/GEM_RBQP(n).
 */
#define GEM_RBQP                                0x0018
#define GEM_TBQP                                0x001c
#define GEM_RBQP1                               0x0480
#define GEM_TBQP1                               0x0440
#define MACB_MAX_QUEUES                         8
#define GEM_QUEUE_TBQP(q)                       (0x0440 + ((q) << 2))
#define GEM_QUEUE_RBQP(q)                       (0x0480 + ((q) << 2))

#define GEM_JML                                 0x0048
#define GEM_PBUFRXCUT                           0x0044
#define GEM_INTMOD                              0x005c
#define GEM_INTMOD_TX_MOD_SHIFT                 16
#define GEM_INTMOD_RX_MOD_SHIFT                 0

#define GEM_SA1B                                0x0088
#define GEM_SA1T                                0x008c

#define GEM_DCFG1                               0x0280
#define GEM_DCFG1_IRQCOR_SHIFT                  23
#define GEM_DCFG5                               0x0290
#define GEM_DCFG6                               0x0294
#define GEM_DCFG6_DAW64_SHIFT                   23

#define GEM_RBQPH                               0x04d4
#define GEM_TBQPH                               0x04c8

#define GEM_AMP                                 0x0054
#define GEM_AMP_AR2R_MAX_PIPE_SHIFT             0
#define GEM_AMP_AW2W_MAX_PIPE_SHIFT             8
#define GEM_AMP_AW2B_FILL_SHIFT                 16

#define GEM_USRIO_RGMII                         RT_BIT(0)

/* TSU / 1588 */
#define GEM_TISUBN                              0x01bc
#define GEM_TSH                                 0x01c0
#define GEM_TSL                                 0x01d0
#define GEM_TN                                  0x01d4
#define GEM_TA                                  0x01d8
#define GEM_TI                                  0x01dc

/* NCR */
#define GEM_NCR_LLB                             RT_BIT(1)
#define GEM_NCR_RE                              RT_BIT(2)
#define GEM_NCR_TE                              RT_BIT(3)
#define GEM_NCR_MPE                             RT_BIT(4)
#define GEM_NCR_CLRSTAT                         RT_BIT(5)
#define GEM_NCR_TSTART                          RT_BIT(9)

/*
 * NCFGR: GEM uses same SPD/FD as MACB (bit0/1); gigabit is GEM_GBE @ bit10,
 * not bit31.
 */
#define GEM_NCFGR_SPD                           RT_BIT(0)   /* 100 Mbps */
#define GEM_NCFGR_FD                            RT_BIT(1)   /* Full duplex */
#define GEM_NCFGR_GBE                           RT_BIT(10)  /* 1000 Mbps (GEM) */
#define GEM_NCFGR_BIG                           RT_BIT(8)   /* Receive 1536-byte frames */
#define GEM_NCFGR_DRFCS                         RT_BIT(17)  /* Discard RX FCS */

/* DBW in NCFGR bits [22:21] */
#define GEM_NCFGR_DBW_SHIFT                     21

/* MDC clock divider in NCFGR bits [20:18] */
#define GEM_NCFGR_CLK_SHIFT                     18

/* NSR */
#define GEM_NSR_IDLE                            RT_BIT(2)

/* RSR */
#define GEM_RSR_BNA                             RT_BIT(0)
#define GEM_RSR_REC                             RT_BIT(1)
#define GEM_RSR_OVR                             RT_BIT(2)

/* ISR / IER / IDR / IMR: queue 0 @ 0x24..0x30; extra GEM queues @ 0x400/0x600 */
#define GEM_INT_MFD                             RT_BIT(0)
#define GEM_INT_HRESP                           RT_BIT(11)
#define GEM_INT_RCOMP                           RT_BIT(1)
#define GEM_INT_RXUBR                           RT_BIT(2)
#define GEM_INT_TXUBR                           RT_BIT(3)
#define GEM_INT_TUND                            RT_BIT(4)
#define GEM_INT_RLE                             RT_BIT(5)
#define GEM_INT_TXERR                           RT_BIT(6)
#define GEM_INT_TCOMP                           RT_BIT(7)
#define GEM_INT_LINK                            RT_BIT(9)
#define GEM_INT_ROVR                            RT_BIT(10)

#define GEM_INT_RX_BITS                         (GEM_INT_RCOMP | GEM_INT_RXUBR | GEM_INT_ROVR)
#define GEM_INT_TX_BITS                         (GEM_INT_TCOMP | GEM_INT_TUND | GEM_INT_RLE | GEM_INT_TXERR)

/* MAN (MDIO clause 22) */
#define GEM_MAN_SOF                             1
#define GEM_MAN_WRITE                           1
#define GEM_MAN_READ                            2
#define GEM_MAN_CODE                            2

#define GEM_MAN_DATA_OFF                        0
#define GEM_MAN_DATA_SZ                         16
#define GEM_MAN_CODE_OFF                        16
#define GEM_MAN_CODE_SZ                         2
#define GEM_MAN_REGA_OFF                        18
#define GEM_MAN_REGA_SZ                         5
#define GEM_MAN_PHYA_OFF                        23
#define GEM_MAN_PHYA_SZ                         5
#define GEM_MAN_RW_OFF                          28
#define GEM_MAN_RW_SZ                           2
#define GEM_MAN_SOF_OFF                         30
#define GEM_MAN_SOF_SZ                          2
#define GEM_MAN_BF(name, val)                   (((val) & ((1 << GEM_MAN_##name##_SZ) - 1)) << GEM_MAN_##name##_OFF)

/*
 * RX descriptor word @addr: OWNERSHIP uses bit0 (RX_USED); WRAP is bit1.
 * Word @ctrl: frame length in bits [11:0], SOF/EOF for single-buffer frames.
 */
#define GEM_RX_USED                             RT_BIT(0)   /* In addr */
#define GEM_RX_WRAP                             RT_BIT(1)   /* In addr */
#define GEM_RX_LEN_MASK                         0x0fff      /* FRMLEN in ctrl */
#define GEM_RX_SOF                              RT_BIT(14)
#define GEM_RX_EOF                              RT_BIT(15)

/* TX descriptor @ctrl (GEM length bits [13:0]) */
#define GEM_TX_LAST                             RT_BIT(15)
#define GEM_TX_NOCRC                            RT_BIT(16)
#define GEM_TX_WRAP                             RT_BIT(30)
#define GEM_TX_USED                             RT_BIT(31)
#define GEM_TX_LEN_MASK                         0x3fff

/* DMACFG */
#define GEM_DMACFG_FBLDO_SHIFT                  0
#define GEM_DMACFG_ENDIA_DESC_SHIFT             6
#define GEM_DMACFG_ENDIA_PKT_SHIFT              7
#define GEM_DMACFG_RXBMS_SHIFT                  8
#define GEM_DMACFG_TXPBMS_SHIFT                 10
#define GEM_DMACFG_RXBS_SHIFT                   16
#define GEM_DMACFG_DDRP_SHIFT                   24
#define GEM_DMACFG_RXEXT_SHIFT                  28
#define GEM_DMACFG_TXEXT_SHIFT                  29
#define GEM_DMACFG_ADDR64_SHIFT                 30

#define GEM_DMACFG_RXBS_MASK                    0xff

#define GEM_CLK_DIV8                            0
#define GEM_CLK_DIV16                           1
#define GEM_CLK_DIV32                           2
#define GEM_CLK_DIV48                           3
#define GEM_CLK_DIV64                           4
#define GEM_CLK_DIV96                           5
#define GEM_CLK_DIV128                          6
#define GEM_CLK_DIV224                          7

/* DCFG5: TSU present */
#define GEM_DCFG5_TSU_SHIFT                     8

#define GEM_DBW32                               0
#define GEM_DBW64                               1
#define GEM_DBW128                              2

#define MACB_CAP_USRIO_HAS_CLKEN                RT_BIT(1)
#define MACB_CAP_USRIO_DEFAULT_MII_GMII         RT_BIT(2)
#define MACB_CAP_NO_GIGABIT_HALF                RT_BIT(3)
#define MACB_CAP_USRIO_DISABLED                 RT_BIT(4)
#define MACB_CAP_JUMBO                          RT_BIT(5)
#define MACB_CAP_GEM_HAS_PTP                    RT_BIT(6)
#define MACB_CAP_BD_RD_PREFETCH                 RT_BIT(7)
#define MACB_CAP_NEEDS_RSTONUBR                 RT_BIT(8)
#define MACB_CAP_MIIONRGMII                     RT_BIT(9)
#define MACB_CAP_NEED_TSUCLK                    RT_BIT(10)
#define MACB_CAP_QUEUE_DISABLE                  RT_BIT(11)
#define MACB_CAP_QBV                            RT_BIT(12)
#define MACB_CAP_CLK_HW_CHG                     RT_BIT(15)
#define MACB_CAP_MACB_IS_EMAC                   RT_BIT(16)
#define MACB_CAP_GIGABIT_MODE_AVAILABLE         RT_BIT(18)
#define MACB_CAP_SG_DISABLED                    RT_BIT(19)
#define MACB_CAP_NO_LSO                         RT_BIT(24)

struct macb_eth;

struct macb_config
{
    rt_uint32_t caps;
    rt_uint8_t dma_burst_length;
    rt_uint16_t jumbo_max_len;
    rt_uint16_t max_tx_len;
};

struct macb_dma_desc
{
    rt_uint32_t addr;
    rt_uint32_t ctrl;
};

struct macb_dma_desc_64
{
    rt_uint32_t addrh;
    rt_uint32_t resvd;
};

#define MACB_RX_RING_SIZE                       32
#define MACB_TX_RING_SIZE                       16
#define MACB_RX_BUFFER_SIZE                     1536

/* RXBS encoding: buffer_bytes / 64 */
#define MACB_RX_BUFFER_SIZE_DIV64               (MACB_RX_BUFFER_SIZE / 64)

struct macb_eth
{
    struct eth_device parent;
#ifdef RT_ETHERNET_CADENCE_PTP
    struct rt_ptp_clock ptp_parent;
#endif
    struct rt_device *dev;

    struct rt_phy_device *phy;
    struct mii_bus *mii;

    int irq;
    void *regs;

    struct rt_clk *pclk;
    struct rt_clk *hclk;
    struct rt_clk *tsu_clk;
    struct rt_clk *tx_clk;

    rt_uint8_t mac[6];
    rt_bool_t is_gem;
    rt_bool_t dma_64bit;
    rt_bool_t native_io;
    rt_bool_t isr_clear_on_write;
    rt_uint32_t ncr_shadow;
    rt_uint32_t ncfgr_shadow;

    const struct macb_config *config;
    rt_uint16_t max_tx_len;

    int phy_interface;
    rt_ssize_t phy_reset_pin;
    rt_uint8_t phy_reset_active;
    rt_uint16_t phy_reset_ms;
    rt_uint8_t aw2w_max_pipe;
    rt_uint8_t ar2r_max_pipe;
    rt_bool_t use_aw2b_fill;

    struct macb_dma_desc *rx_ring;
    struct macb_dma_desc *tx_ring;
    rt_uint8_t *rx_buffer;
    rt_uint8_t *tx_buffer;
    rt_size_t dma_blob_size;
    rt_ubase_t dma_blob_handle;
    rt_ubase_t rx_ring_dma;
    rt_ubase_t tx_ring_dma;
    rt_ubase_t rx_buffer_dma;
    rt_ubase_t tx_buffer_dma;

    struct macb_dma_desc *dummy_desc;
    rt_ubase_t dummy_desc_dma;
    rt_size_t dummy_desc_size;

    rt_uint32_t rx_tail;
    rt_uint32_t tx_head;
    rt_uint32_t tx_tail;

    rt_bool_t net_registered;
    rt_bool_t irq_installed;
    rt_bool_t hw_ready;
    rt_bool_t mac_started;
    rt_bool_t phy_configured;

#ifdef RT_USING_SYSTEM_WORKQUEUE
    struct rt_work phy_retry_work;
    int phy_retry_count;
#endif

    struct rt_mutex mdio_lock;
    struct rt_semaphore tx_sem;
};

#define raw_to_macb_eth(raw) \
    rt_container_of(rt_container_of(raw, struct eth_device, parent), struct macb_eth, parent)
#define raw_to_macb_ptp(raw) \
    rt_container_of(raw, struct macb_eth, ptp_parent)

rt_inline rt_uint32_t macb_readl(struct macb_eth *eth, rt_uint32_t off)
{
    if (eth->native_io)
    {
        return *(volatile rt_uint32_t *)((rt_uint8_t *)eth->regs + off);
    }

    return HWREG32(eth->regs + off);
}

rt_inline void macb_writel(struct macb_eth *eth, rt_uint32_t off, rt_uint32_t val)
{
    if (eth->native_io)
    {
        *(volatile rt_uint32_t *)((rt_uint8_t *)eth->regs + off) = val;
    }
    else
    {
        HWREG32(eth->regs + off) = val;
    }
}

rt_err_t macb_eth_hw_init(struct macb_eth *eth);
void macb_eth_hw_stop(struct macb_eth *eth);

rt_err_t macb_eth_common_probe(struct macb_eth *eth);
rt_err_t macb_eth_common_remove(struct macb_eth *eth);

#ifdef RT_ETHERNET_CADENCE_PTP
rt_err_t macb_ptp_register(struct macb_eth *eth);
void macb_ptp_unregister(struct macb_eth *eth);
#endif

#endif /* __MACB_H__ */