summaryrefslogtreecommitdiff
path: root/components/drivers/ethernet/synopsys/dwmac.h
blob: b6e73f351e16d3849d16b20fca8fb1fa658196f1 (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
/*
 * Copyright (c) 2006-2022, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2022-11-26     GuEe-GUI     first version
 */

#ifndef __DWMAC_H__
#define __DWMAC_H__

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

#include <drivers/misc.h>
#include "../ethernet_dm.h"

/* GMAC4 MAC registers (offset from mac_base) */
#define GMAC_CONFIG                     0x0000
#define GMAC_PACKET_FILTER              0x0008
#define GMAC_MDIO_ADDR                  0x0200
#define GMAC_MDIO_DATA                  0x0204
#define GMAC_ADDR_HIGH(reg)             (0x0300 + (reg) * 8)
#define GMAC_ADDR_LOW(reg)              (0x0304 + (reg) * 8)
#define GMAC_RXQ_CTRL0                  0x00a0
#define GMAC_RXQ_CTRL1                  0x00a4

#define GMAC_CONFIG_RE                  RT_BIT(0)
#define GMAC_CONFIG_TE                  RT_BIT(1)
#define GMAC_CONFIG_DM                  RT_BIT(13)
#define GMAC_CONFIG_FES                 RT_BIT(14)
#define GMAC_CONFIG_PS                  RT_BIT(15)
#define GMAC_CONFIG_IPC                 RT_BIT(27)

#define GMAC_PF_PM                      RT_BIT(4)

#define GMAC_RX_DCB_QUEUE_ENABLE(q)     RT_BIT(((q) * 2) + 1)
#define GMAC_RXQCTRL_MCBCQEN            RT_BIT(20)
#define GMAC_RXQCTRL_MCBCQ_MASK         RT_GENMASK(18, 16)
#define GMAC_RXQCTRL_MCBCQ_SHIFT        16

/* DMA top-level (offset from mac_base) */
#define DMA_BUS_MODE                    0x1000
#define DMA_SYS_BUS_MODE                0x1004
#define DMA_BUS_MODE_SFT_RESET          RT_BIT(0)
#define DMA_SYS_BUS_FB                  RT_BIT(0)
#define DMA_SYS_BUS_MB                  RT_BIT(14)
#define DMA_SYS_BUS_AAL                 RT_BIT(12)
#define DMA_AXI_BLEN16                  RT_BIT(3)
#define DMA_AXI_BLEN8                   RT_BIT(2)
#define DMA_AXI_BLEN4                   RT_BIT(1)
#define DMA_AXI_BLEN32                  RT_BIT(4)
#define DMA_AXI_BLEN64                  RT_BIT(5)
#define DMA_AXI_BLEN128                 RT_BIT(6)
#define DMA_AXI_BLEN256                 RT_BIT(7)
#define DMA_AXI_WR_OSR_LMT_SHIFT        24
#define DMA_AXI_RD_OSR_LMT_SHIFT        16

#define DMA_CHAN_BASE                   0x1100
#define DMA_CHAN_OFFSET                 0x80
#define DMA_CHAN_CONTROL(c)             (DMA_CHAN_BASE + (c) * DMA_CHAN_OFFSET)
#define DMA_CHAN_TX_CONTROL(c)          (DMA_CHAN_CONTROL(c) + 0x04)
#define DMA_CHAN_RX_CONTROL(c)          (DMA_CHAN_CONTROL(c) + 0x08)
#define DMA_CHAN_TX_BASE_ADDR(c)        (DMA_CHAN_CONTROL(c) + 0x14)
#define DMA_CHAN_RX_BASE_ADDR(c)        (DMA_CHAN_CONTROL(c) + 0x1c)
#define DMA_CHAN_TX_END_ADDR(c)         (DMA_CHAN_CONTROL(c) + 0x20)
#define DMA_CHAN_RX_END_ADDR(c)         (DMA_CHAN_CONTROL(c) + 0x28)
#define DMA_CHAN_TX_RING_LEN(c)         (DMA_CHAN_CONTROL(c) + 0x2c)
#define DMA_CHAN_RX_RING_LEN(c)         (DMA_CHAN_CONTROL(c) + 0x30)
#define DMA_CHAN_INTR_ENA(c)            (DMA_CHAN_CONTROL(c) + 0x34)
#define DMA_CHAN_STATUS(c)              (DMA_CHAN_CONTROL(c) + 0x60)

#define DMA_CONTROL_ST                  RT_BIT(0)
#define DMA_CONTROL_SR                  RT_BIT(0)
#define DMA_CONTROL_OSP                 RT_BIT(4)
#define DMA_CONTROL_TSE                 RT_BIT(12)
#define DMA_BUS_MODE_PBL_SHIFT          16
#define DMA_BUS_MODE_RPBL_SHIFT         16
#define DMA_RBSZ_SHIFT                  1
#define DMA_RBSZ_MASK                   RT_GENMASK(14, 1)

#define DMA_CHAN_STATUS_TI              RT_BIT(0)
#define DMA_CHAN_STATUS_RI              RT_BIT(6)
#define DMA_CHAN_STATUS_NIS             RT_BIT(15)

#define DMA_CHAN_INTR_ENA_RIE           RT_BIT(6)
#define DMA_CHAN_INTR_ENA_TIE           RT_BIT(0)
#define DMA_CHAN_INTR_ENA_NIE           RT_BIT(16)
#define DMA_CHAN_INTR_ENA_AIE           RT_BIT(15)
#define DMA_CHAN_INTR_ENA_NIE_4_10      RT_BIT(15)
#define DMA_CHAN_INTR_ENA_AIE_4_10      RT_BIT(14)
#define DMA_CHAN_INTR_ENA_FBE           RT_BIT(12)
#define DMA_CHAN_INTR_DEFAULT_MASK      (DMA_CHAN_INTR_ENA_NIE | \
                                         DMA_CHAN_INTR_ENA_AIE | \
                                         DMA_CHAN_INTR_ENA_FBE | \
                                         DMA_CHAN_INTR_ENA_RIE | \
                                         DMA_CHAN_INTR_ENA_TIE)
#define DMA_CHAN_INTR_DEFAULT_MASK_4_10 (DMA_CHAN_INTR_ENA_NIE_4_10 | \
                                         DMA_CHAN_INTR_ENA_AIE_4_10 | \
                                         DMA_CHAN_INTR_ENA_FBE | \
                                         DMA_CHAN_INTR_ENA_RIE | \
                                         DMA_CHAN_INTR_ENA_TIE)

#define MTL_OPERATION_MODE              0x0c00
#define MTL_RXQ_DMA_MAP0                0x0c30
#define MTL_RXQ_DMA_QXMDMACH_MASK(q)    (0xf << (8 * (q)))
#define MTL_RXQ_DMA_QXMDMACH(chan, q)   ((chan) << (8 * (q)))
#define MTL_CHAN_BASE                   0x0d00
#define MTL_CHAN_OFFSET                 0x40
#define MTL_CHAN_TX_OP_MODE(c)          (MTL_CHAN_BASE + (c) * MTL_CHAN_OFFSET)
#define MTL_CHAN_RX_OP_MODE(c)          (MTL_CHAN_BASE + (c) * MTL_CHAN_OFFSET + 0x30)
#define MTL_OP_MODE_RSF                 RT_BIT(5)
#define MTL_OP_MODE_TSF                 RT_BIT(1)
#define MTL_OP_MODE_TXQEN               RT_BIT(3)

/* Enhanced descriptors (DWMAC4) */
#define TDES2_BUFFER1_SIZE_MASK         RT_GENMASK(13, 0)
#define TDES3_PACKET_SIZE_MASK          RT_GENMASK(14, 0)
#define TDES3_CHECKSUM_INSERTION_SHIFT  16
#define TDES3_CHECKSUM_INSERTION_FULL   (3 << TDES3_CHECKSUM_INSERTION_SHIFT)
#define TDES3_FIRST_DESCRIPTOR          RT_BIT(29)
#define TDES3_LAST_DESCRIPTOR           RT_BIT(28)
#define TDES3_OWN                       RT_BIT(31)
#define RDES3_OWN                       RT_BIT(31)
#define RDES3_INT_ON_COMPLETION_EN      RT_BIT(30)
#define RDES3_BUFFER1_VALID_ADDR        RT_BIT(24)
#define RDES3_PACKET_SIZE_MASK          RT_GENMASK(14, 0)

#define MII_ADDR_GBUSY                  RT_BIT(0)
#define MII_DATA_GD_MASK                RT_GENMASK(15, 0)
#define MII_GMAC4_GOC_SHIFT             2
#define MII_GMAC4_WRITE                 (1 << MII_GMAC4_GOC_SHIFT)
#define MII_GMAC4_READ                  (3 << MII_GMAC4_GOC_SHIFT)
#define MII_GMAC4_ADDR_SHIFT            21
#define MII_GMAC4_ADDR_MASK             RT_GENMASK(25, 21)
#define MII_GMAC4_REG_SHIFT             16
#define MII_GMAC4_REG_MASK              RT_GENMASK(20, 16)
#define MII_GMAC4_CSR_SHIFT             8
#define MII_GMAC4_CSR_100_150M          (0x4 << MII_GMAC4_CSR_SHIFT)

#define DWMAC_RX_RING_SIZE              32
#define DWMAC_TX_RING_SIZE              16
#define DWMAC_RX_BUFFER_SIZE            1536
#define DWMAC_CHAN                      0
#define DWMAC_DMA_PBL                   8
#define DWMAC_MDIO_TIMEOUT_US           10000

enum dwmac_core_type
{
    DWMAC_CORE_GMAC4,
};

struct dwmac_desc
{
    rt_uint32_t des0;
    rt_uint32_t des1;
    rt_uint32_t des2;
    rt_uint32_t des3;
};

#define DWMAC_CAP_TSO                   RT_BIT(0)
#define DWMAC_CAP_PTP                   RT_BIT(1)

struct dwmac_axi_cfg
{
    rt_uint32_t wr_osr_lmt;
    rt_uint32_t rd_osr_lmt;
    rt_bool_t fixed_burst;
    rt_bool_t mixed_burst;
    rt_bool_t aal;
    rt_uint32_t blen_mask;
};

struct dwmac_mtl_cfg
{
    rt_uint32_t rx_queues;
    rt_uint32_t tx_queues;
};

struct dwmac_eth;

struct dwmac_plat_ops
{
    rt_uint32_t flags;

    rt_err_t (*parse_ofw)(struct dwmac_eth *eth);
    rt_err_t (*init)(struct dwmac_eth *eth);
    void     (*exit)(struct dwmac_eth *eth);
    rt_err_t (*fix_link_speed)(struct dwmac_eth *eth, int speed);
};

struct dwmac_config
{
    enum dwmac_core_type core_type;
    rt_uint32_t caps;
    rt_uint8_t dma_pbl;
    const struct dwmac_plat_ops *plat;
};

struct dwmac_eth
{
    struct eth_device parent;
    struct rt_device *dev;

    void *mac_base;
    int irq;

    struct rt_phy_device *phy;
    struct mii_bus *mii;

    rt_uint8_t mac[6];
    int phy_interface;

    struct rt_clk *stmmac_clk;
    struct rt_clk *mac_clk_speed;
    struct rt_clk *mac_clk_rx;
    struct rt_clk *mac_clk_tx;
    struct rt_clk *clk_mac_refout;
    struct rt_clk *ptp_clk;
    struct rt_clk *aclk;
    struct rt_clk *pclk;
    struct rt_reset_control *rst;
#ifdef RT_USING_REGULATOR
    struct rt_regulator *phy_supply;
#endif

    rt_ssize_t phy_reset_pin;
    rt_uint8_t phy_reset_active;
    rt_uint32_t phy_reset_delays[3];

    struct dwmac_desc *rx_ring;
    struct dwmac_desc *tx_ring;
    rt_ubase_t rx_ring_dma;
    rt_ubase_t tx_ring_dma;
    rt_uint8_t *rx_buffers;
    rt_ubase_t rx_buffers_dma;
    rt_uint8_t *tx_buffers;
    rt_ubase_t tx_buffers_dma;
    rt_size_t dma_blob_size;
    rt_ubase_t dma_blob_handle;

    rt_uint32_t tx_idx;
    rt_uint32_t rx_idx;

    rt_uint8_t dma_pbl;
    rt_uint8_t dma_txpbl;
    rt_uint8_t dma_rxpbl;
    rt_bool_t tso_en;
    struct dwmac_axi_cfg axi;
    struct dwmac_mtl_cfg mtl;

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

#ifdef RT_USING_SYSTEM_WORKQUEUE
    struct rt_work phy_retry_work;
    rt_bool_t phy_work_inited;
#endif

    const struct dwmac_config *config;
    void *plat_priv;

#ifdef RT_ETHERNET_DWMAC_PTP
    struct rt_ptp_clock ptp_parent;
    rt_uint32_t ptp_clk_rate;
    rt_uint32_t default_addend;
    rt_uint32_t sub_second_inc;
    rt_uint32_t systime_flags;
    rt_uint8_t pps_out_num;
    rt_uint8_t aux_snapshot_num;
#endif /* RT_ETHERNET_DWMAC_PTP */
};

#define dwmac_readl(eth, reg)           HWREG32((rt_uint8_t *)(eth)->mac_base + (reg))
#define dwmac_writel(eth, reg, val)     HWREG32((rt_uint8_t *)(eth)->mac_base + (reg)) = (val)

rt_inline const struct dwmac_plat_ops *dwmac_plat(const struct dwmac_eth *eth)
{
    if (eth && eth->config && eth->config->plat)
    {
        return eth->config->plat;
    }

    return RT_NULL;
}

rt_err_t dwmac_probe(struct dwmac_eth *eth);
rt_err_t dwmac_remove(struct dwmac_eth *eth);
rt_err_t dwmac_eth_common_probe(struct dwmac_eth *eth);
rt_err_t dwmac_eth_common_remove(struct dwmac_eth *eth);

#ifdef RT_ETHERNET_DWMAC_PTP
rt_err_t dwmac_ptp_register(struct dwmac_eth *eth);
void dwmac_ptp_unregister(struct dwmac_eth *eth);
#endif /* RT_ETHERNET_DWMAC_PTP */

#endif /* __DWMAC_H__ */