blob: 944412958d69961baf4bcd31504aab8b8f6ea7c1 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0
Stephen Warren50709602016-10-21 14:46:47 -06002/*
3 * Copyright (c) 2016, NVIDIA CORPORATION.
4 *
Stephen Warren50709602016-10-21 14:46:47 -06005 * Portions based on U-Boot's rtl8169.c.
6 */
7
8/*
9 * This driver supports the Synopsys Designware Ethernet QOS (Quality Of
10 * Service) IP block. The IP supports multiple options for bus type, clocking/
11 * reset structure, and feature list.
12 *
13 * The driver is written such that generic core logic is kept separate from
14 * configuration-specific logic. Code that interacts with configuration-
15 * specific resources is split out into separate functions to avoid polluting
16 * common code. If/when this driver is enhanced to support multiple
17 * configurations, the core code should be adapted to call all configuration-
18 * specific functions through function pointers, with the definition of those
19 * function pointers being supplied by struct udevice_id eqos_ids[]'s .data
20 * field.
21 *
22 * The following configurations are currently supported:
23 * tegra186:
24 * NVIDIA's Tegra186 chip. This configuration uses an AXI master/DMA bus, an
25 * AHB slave/register bus, contains the DMA, MTL, and MAC sub-blocks, and
26 * supports a single RGMII PHY. This configuration also has SW control over
27 * all clock and reset signals to the HW block.
28 */
Patrick Delaunay9e6ed382020-09-09 18:30:06 +020029
Stephen Warren50709602016-10-21 14:46:47 -060030#include <common.h>
31#include <clk.h>
Simon Glass63334482019-11-14 12:57:39 -070032#include <cpu_func.h>
Stephen Warren50709602016-10-21 14:46:47 -060033#include <dm.h>
34#include <errno.h>
Simon Glass0f2af882020-05-10 11:40:05 -060035#include <log.h>
Simon Glass9bc15642020-02-03 07:36:16 -070036#include <malloc.h>
Stephen Warren50709602016-10-21 14:46:47 -060037#include <memalign.h>
38#include <miiphy.h>
39#include <net.h>
40#include <netdev.h>
41#include <phy.h>
42#include <reset.h>
43#include <wait_bit.h>
Simon Glass274e0b02020-05-10 11:39:56 -060044#include <asm/cache.h>
Stephen Warren50709602016-10-21 14:46:47 -060045#include <asm/gpio.h>
46#include <asm/io.h>
Ye Liad122b72020-05-03 22:41:15 +080047#include <eth_phy.h>
Fugang Duandd455e62020-05-03 22:41:18 +080048#ifdef CONFIG_ARCH_IMX8M
49#include <asm/arch/clock.h>
50#include <asm/mach-imx/sys_proto.h>
51#endif
Simon Glass4dcacfc2020-05-10 11:40:13 -060052#include <linux/bitops.h>
Simon Glassdbd79542020-05-10 11:40:11 -060053#include <linux/delay.h>
Stephen Warren50709602016-10-21 14:46:47 -060054
55/* Core registers */
56
57#define EQOS_MAC_REGS_BASE 0x000
58struct eqos_mac_regs {
59 uint32_t configuration; /* 0x000 */
60 uint32_t unused_004[(0x070 - 0x004) / 4]; /* 0x004 */
61 uint32_t q0_tx_flow_ctrl; /* 0x070 */
62 uint32_t unused_070[(0x090 - 0x074) / 4]; /* 0x074 */
63 uint32_t rx_flow_ctrl; /* 0x090 */
64 uint32_t unused_094; /* 0x094 */
65 uint32_t txq_prty_map0; /* 0x098 */
66 uint32_t unused_09c; /* 0x09c */
67 uint32_t rxq_ctrl0; /* 0x0a0 */
68 uint32_t unused_0a4; /* 0x0a4 */
69 uint32_t rxq_ctrl2; /* 0x0a8 */
70 uint32_t unused_0ac[(0x0dc - 0x0ac) / 4]; /* 0x0ac */
71 uint32_t us_tic_counter; /* 0x0dc */
72 uint32_t unused_0e0[(0x11c - 0x0e0) / 4]; /* 0x0e0 */
73 uint32_t hw_feature0; /* 0x11c */
74 uint32_t hw_feature1; /* 0x120 */
75 uint32_t hw_feature2; /* 0x124 */
76 uint32_t unused_128[(0x200 - 0x128) / 4]; /* 0x128 */
77 uint32_t mdio_address; /* 0x200 */
78 uint32_t mdio_data; /* 0x204 */
79 uint32_t unused_208[(0x300 - 0x208) / 4]; /* 0x208 */
80 uint32_t address0_high; /* 0x300 */
81 uint32_t address0_low; /* 0x304 */
82};
83
84#define EQOS_MAC_CONFIGURATION_GPSLCE BIT(23)
85#define EQOS_MAC_CONFIGURATION_CST BIT(21)
86#define EQOS_MAC_CONFIGURATION_ACS BIT(20)
87#define EQOS_MAC_CONFIGURATION_WD BIT(19)
88#define EQOS_MAC_CONFIGURATION_JD BIT(17)
89#define EQOS_MAC_CONFIGURATION_JE BIT(16)
90#define EQOS_MAC_CONFIGURATION_PS BIT(15)
91#define EQOS_MAC_CONFIGURATION_FES BIT(14)
92#define EQOS_MAC_CONFIGURATION_DM BIT(13)
Fugang Duan37aae5f2020-05-03 22:41:17 +080093#define EQOS_MAC_CONFIGURATION_LM BIT(12)
Stephen Warren50709602016-10-21 14:46:47 -060094#define EQOS_MAC_CONFIGURATION_TE BIT(1)
95#define EQOS_MAC_CONFIGURATION_RE BIT(0)
96
97#define EQOS_MAC_Q0_TX_FLOW_CTRL_PT_SHIFT 16
98#define EQOS_MAC_Q0_TX_FLOW_CTRL_PT_MASK 0xffff
99#define EQOS_MAC_Q0_TX_FLOW_CTRL_TFE BIT(1)
100
101#define EQOS_MAC_RX_FLOW_CTRL_RFE BIT(0)
102
103#define EQOS_MAC_TXQ_PRTY_MAP0_PSTQ0_SHIFT 0
104#define EQOS_MAC_TXQ_PRTY_MAP0_PSTQ0_MASK 0xff
105
106#define EQOS_MAC_RXQ_CTRL0_RXQ0EN_SHIFT 0
107#define EQOS_MAC_RXQ_CTRL0_RXQ0EN_MASK 3
108#define EQOS_MAC_RXQ_CTRL0_RXQ0EN_NOT_ENABLED 0
109#define EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB 2
Christophe Roullier6beb7802019-05-17 15:08:44 +0200110#define EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_AV 1
Stephen Warren50709602016-10-21 14:46:47 -0600111
112#define EQOS_MAC_RXQ_CTRL2_PSRQ0_SHIFT 0
113#define EQOS_MAC_RXQ_CTRL2_PSRQ0_MASK 0xff
114
Fugang Duan37aae5f2020-05-03 22:41:17 +0800115#define EQOS_MAC_HW_FEATURE0_MMCSEL_SHIFT 8
116#define EQOS_MAC_HW_FEATURE0_HDSEL_SHIFT 2
117#define EQOS_MAC_HW_FEATURE0_GMIISEL_SHIFT 1
118#define EQOS_MAC_HW_FEATURE0_MIISEL_SHIFT 0
119
Stephen Warren50709602016-10-21 14:46:47 -0600120#define EQOS_MAC_HW_FEATURE1_TXFIFOSIZE_SHIFT 6
121#define EQOS_MAC_HW_FEATURE1_TXFIFOSIZE_MASK 0x1f
122#define EQOS_MAC_HW_FEATURE1_RXFIFOSIZE_SHIFT 0
123#define EQOS_MAC_HW_FEATURE1_RXFIFOSIZE_MASK 0x1f
124
Fugang Duan37aae5f2020-05-03 22:41:17 +0800125#define EQOS_MAC_HW_FEATURE3_ASP_SHIFT 28
126#define EQOS_MAC_HW_FEATURE3_ASP_MASK 0x3
127
Stephen Warren50709602016-10-21 14:46:47 -0600128#define EQOS_MAC_MDIO_ADDRESS_PA_SHIFT 21
129#define EQOS_MAC_MDIO_ADDRESS_RDA_SHIFT 16
130#define EQOS_MAC_MDIO_ADDRESS_CR_SHIFT 8
131#define EQOS_MAC_MDIO_ADDRESS_CR_20_35 2
Christophe Roullier6beb7802019-05-17 15:08:44 +0200132#define EQOS_MAC_MDIO_ADDRESS_CR_250_300 5
Stephen Warren50709602016-10-21 14:46:47 -0600133#define EQOS_MAC_MDIO_ADDRESS_SKAP BIT(4)
134#define EQOS_MAC_MDIO_ADDRESS_GOC_SHIFT 2
135#define EQOS_MAC_MDIO_ADDRESS_GOC_READ 3
136#define EQOS_MAC_MDIO_ADDRESS_GOC_WRITE 1
137#define EQOS_MAC_MDIO_ADDRESS_C45E BIT(1)
138#define EQOS_MAC_MDIO_ADDRESS_GB BIT(0)
139
140#define EQOS_MAC_MDIO_DATA_GD_MASK 0xffff
141
142#define EQOS_MTL_REGS_BASE 0xd00
143struct eqos_mtl_regs {
144 uint32_t txq0_operation_mode; /* 0xd00 */
145 uint32_t unused_d04; /* 0xd04 */
146 uint32_t txq0_debug; /* 0xd08 */
147 uint32_t unused_d0c[(0xd18 - 0xd0c) / 4]; /* 0xd0c */
148 uint32_t txq0_quantum_weight; /* 0xd18 */
149 uint32_t unused_d1c[(0xd30 - 0xd1c) / 4]; /* 0xd1c */
150 uint32_t rxq0_operation_mode; /* 0xd30 */
151 uint32_t unused_d34; /* 0xd34 */
152 uint32_t rxq0_debug; /* 0xd38 */
153};
154
155#define EQOS_MTL_TXQ0_OPERATION_MODE_TQS_SHIFT 16
156#define EQOS_MTL_TXQ0_OPERATION_MODE_TQS_MASK 0x1ff
157#define EQOS_MTL_TXQ0_OPERATION_MODE_TXQEN_SHIFT 2
158#define EQOS_MTL_TXQ0_OPERATION_MODE_TXQEN_MASK 3
159#define EQOS_MTL_TXQ0_OPERATION_MODE_TXQEN_ENABLED 2
160#define EQOS_MTL_TXQ0_OPERATION_MODE_TSF BIT(1)
161#define EQOS_MTL_TXQ0_OPERATION_MODE_FTQ BIT(0)
162
163#define EQOS_MTL_TXQ0_DEBUG_TXQSTS BIT(4)
164#define EQOS_MTL_TXQ0_DEBUG_TRCSTS_SHIFT 1
165#define EQOS_MTL_TXQ0_DEBUG_TRCSTS_MASK 3
166
167#define EQOS_MTL_RXQ0_OPERATION_MODE_RQS_SHIFT 20
168#define EQOS_MTL_RXQ0_OPERATION_MODE_RQS_MASK 0x3ff
169#define EQOS_MTL_RXQ0_OPERATION_MODE_RFD_SHIFT 14
170#define EQOS_MTL_RXQ0_OPERATION_MODE_RFD_MASK 0x3f
171#define EQOS_MTL_RXQ0_OPERATION_MODE_RFA_SHIFT 8
172#define EQOS_MTL_RXQ0_OPERATION_MODE_RFA_MASK 0x3f
173#define EQOS_MTL_RXQ0_OPERATION_MODE_EHFC BIT(7)
174#define EQOS_MTL_RXQ0_OPERATION_MODE_RSF BIT(5)
Fugang Duan37aae5f2020-05-03 22:41:17 +0800175#define EQOS_MTL_RXQ0_OPERATION_MODE_FEP BIT(4)
176#define EQOS_MTL_RXQ0_OPERATION_MODE_FUP BIT(3)
Stephen Warren50709602016-10-21 14:46:47 -0600177
178#define EQOS_MTL_RXQ0_DEBUG_PRXQ_SHIFT 16
179#define EQOS_MTL_RXQ0_DEBUG_PRXQ_MASK 0x7fff
180#define EQOS_MTL_RXQ0_DEBUG_RXQSTS_SHIFT 4
181#define EQOS_MTL_RXQ0_DEBUG_RXQSTS_MASK 3
182
183#define EQOS_DMA_REGS_BASE 0x1000
184struct eqos_dma_regs {
185 uint32_t mode; /* 0x1000 */
186 uint32_t sysbus_mode; /* 0x1004 */
187 uint32_t unused_1008[(0x1100 - 0x1008) / 4]; /* 0x1008 */
188 uint32_t ch0_control; /* 0x1100 */
189 uint32_t ch0_tx_control; /* 0x1104 */
190 uint32_t ch0_rx_control; /* 0x1108 */
191 uint32_t unused_110c; /* 0x110c */
192 uint32_t ch0_txdesc_list_haddress; /* 0x1110 */
193 uint32_t ch0_txdesc_list_address; /* 0x1114 */
194 uint32_t ch0_rxdesc_list_haddress; /* 0x1118 */
195 uint32_t ch0_rxdesc_list_address; /* 0x111c */
196 uint32_t ch0_txdesc_tail_pointer; /* 0x1120 */
197 uint32_t unused_1124; /* 0x1124 */
198 uint32_t ch0_rxdesc_tail_pointer; /* 0x1128 */
199 uint32_t ch0_txdesc_ring_length; /* 0x112c */
200 uint32_t ch0_rxdesc_ring_length; /* 0x1130 */
201};
202
203#define EQOS_DMA_MODE_SWR BIT(0)
204
205#define EQOS_DMA_SYSBUS_MODE_RD_OSR_LMT_SHIFT 16
206#define EQOS_DMA_SYSBUS_MODE_RD_OSR_LMT_MASK 0xf
207#define EQOS_DMA_SYSBUS_MODE_EAME BIT(11)
208#define EQOS_DMA_SYSBUS_MODE_BLEN16 BIT(3)
209#define EQOS_DMA_SYSBUS_MODE_BLEN8 BIT(2)
210#define EQOS_DMA_SYSBUS_MODE_BLEN4 BIT(1)
211
Marek Vasut89077732021-01-07 11:12:16 +0100212#define EQOS_DMA_CH0_CONTROL_DSL_SHIFT 18
Stephen Warren50709602016-10-21 14:46:47 -0600213#define EQOS_DMA_CH0_CONTROL_PBLX8 BIT(16)
214
215#define EQOS_DMA_CH0_TX_CONTROL_TXPBL_SHIFT 16
216#define EQOS_DMA_CH0_TX_CONTROL_TXPBL_MASK 0x3f
217#define EQOS_DMA_CH0_TX_CONTROL_OSP BIT(4)
218#define EQOS_DMA_CH0_TX_CONTROL_ST BIT(0)
219
220#define EQOS_DMA_CH0_RX_CONTROL_RXPBL_SHIFT 16
221#define EQOS_DMA_CH0_RX_CONTROL_RXPBL_MASK 0x3f
222#define EQOS_DMA_CH0_RX_CONTROL_RBSZ_SHIFT 1
223#define EQOS_DMA_CH0_RX_CONTROL_RBSZ_MASK 0x3fff
224#define EQOS_DMA_CH0_RX_CONTROL_SR BIT(0)
225
226/* These registers are Tegra186-specific */
227#define EQOS_TEGRA186_REGS_BASE 0x8800
228struct eqos_tegra186_regs {
229 uint32_t sdmemcomppadctrl; /* 0x8800 */
230 uint32_t auto_cal_config; /* 0x8804 */
231 uint32_t unused_8808; /* 0x8808 */
232 uint32_t auto_cal_status; /* 0x880c */
233};
234
235#define EQOS_SDMEMCOMPPADCTRL_PAD_E_INPUT_OR_E_PWRD BIT(31)
236
237#define EQOS_AUTO_CAL_CONFIG_START BIT(31)
238#define EQOS_AUTO_CAL_CONFIG_ENABLE BIT(29)
239
240#define EQOS_AUTO_CAL_STATUS_ACTIVE BIT(31)
241
242/* Descriptors */
Stephen Warren50709602016-10-21 14:46:47 -0600243/* We assume ARCH_DMA_MINALIGN >= 16; 16 is the EQOS HW minimum */
244#define EQOS_DESCRIPTOR_ALIGN ARCH_DMA_MINALIGN
245#define EQOS_DESCRIPTORS_TX 4
246#define EQOS_DESCRIPTORS_RX 4
247#define EQOS_DESCRIPTORS_NUM (EQOS_DESCRIPTORS_TX + EQOS_DESCRIPTORS_RX)
Stephen Warren50709602016-10-21 14:46:47 -0600248#define EQOS_BUFFER_ALIGN ARCH_DMA_MINALIGN
249#define EQOS_MAX_PACKET_SIZE ALIGN(1568, ARCH_DMA_MINALIGN)
250#define EQOS_RX_BUFFER_SIZE (EQOS_DESCRIPTORS_RX * EQOS_MAX_PACKET_SIZE)
251
Stephen Warren50709602016-10-21 14:46:47 -0600252struct eqos_desc {
253 u32 des0;
254 u32 des1;
255 u32 des2;
256 u32 des3;
257};
258
259#define EQOS_DESC3_OWN BIT(31)
260#define EQOS_DESC3_FD BIT(29)
261#define EQOS_DESC3_LD BIT(28)
262#define EQOS_DESC3_BUF1V BIT(24)
263
Marek Vasut89077732021-01-07 11:12:16 +0100264#define EQOS_AXI_WIDTH_32 4
265#define EQOS_AXI_WIDTH_64 8
266#define EQOS_AXI_WIDTH_128 16
267
Stephen Warren50709602016-10-21 14:46:47 -0600268struct eqos_config {
269 bool reg_access_always_ok;
Christophe Roullier6beb7802019-05-17 15:08:44 +0200270 int mdio_wait;
271 int swr_wait;
272 int config_mac;
273 int config_mac_mdio;
Marek Vasut89077732021-01-07 11:12:16 +0100274 unsigned int axi_bus_width;
Christophe Roullier6beb7802019-05-17 15:08:44 +0200275 phy_interface_t (*interface)(struct udevice *dev);
276 struct eqos_ops *ops;
277};
278
279struct eqos_ops {
280 void (*eqos_inval_desc)(void *desc);
281 void (*eqos_flush_desc)(void *desc);
282 void (*eqos_inval_buffer)(void *buf, size_t size);
283 void (*eqos_flush_buffer)(void *buf, size_t size);
284 int (*eqos_probe_resources)(struct udevice *dev);
285 int (*eqos_remove_resources)(struct udevice *dev);
286 int (*eqos_stop_resets)(struct udevice *dev);
287 int (*eqos_start_resets)(struct udevice *dev);
288 void (*eqos_stop_clks)(struct udevice *dev);
289 int (*eqos_start_clks)(struct udevice *dev);
290 int (*eqos_calibrate_pads)(struct udevice *dev);
291 int (*eqos_disable_calibration)(struct udevice *dev);
292 int (*eqos_set_tx_clk_speed)(struct udevice *dev);
293 ulong (*eqos_get_tick_clk_rate)(struct udevice *dev);
Stephen Warren50709602016-10-21 14:46:47 -0600294};
295
296struct eqos_priv {
297 struct udevice *dev;
298 const struct eqos_config *config;
299 fdt_addr_t regs;
300 struct eqos_mac_regs *mac_regs;
301 struct eqos_mtl_regs *mtl_regs;
302 struct eqos_dma_regs *dma_regs;
303 struct eqos_tegra186_regs *tegra186_regs;
304 struct reset_ctl reset_ctl;
305 struct gpio_desc phy_reset_gpio;
306 struct clk clk_master_bus;
307 struct clk clk_rx;
308 struct clk clk_ptp_ref;
309 struct clk clk_tx;
Christophe Roullier6beb7802019-05-17 15:08:44 +0200310 struct clk clk_ck;
Stephen Warren50709602016-10-21 14:46:47 -0600311 struct clk clk_slave_bus;
312 struct mii_dev *mii;
313 struct phy_device *phy;
Patrick Delaunay5c8db372020-03-18 10:50:16 +0100314 int phyaddr;
315 u32 max_speed;
Stephen Warren50709602016-10-21 14:46:47 -0600316 void *descs;
Stephen Warren50709602016-10-21 14:46:47 -0600317 int tx_desc_idx, rx_desc_idx;
Marek Vasut89077732021-01-07 11:12:16 +0100318 unsigned int desc_size;
Stephen Warren50709602016-10-21 14:46:47 -0600319 void *tx_dma_buf;
320 void *rx_dma_buf;
321 void *rx_pkt;
322 bool started;
323 bool reg_access_ok;
324};
325
326/*
327 * TX and RX descriptors are 16 bytes. This causes problems with the cache
328 * maintenance on CPUs where the cache-line size exceeds the size of these
329 * descriptors. What will happen is that when the driver receives a packet
330 * it will be immediately requeued for the hardware to reuse. The CPU will
331 * therefore need to flush the cache-line containing the descriptor, which
332 * will cause all other descriptors in the same cache-line to be flushed
333 * along with it. If one of those descriptors had been written to by the
334 * device those changes (and the associated packet) will be lost.
335 *
336 * To work around this, we make use of non-cached memory if available. If
337 * descriptors are mapped uncached there's no need to manually flush them
338 * or invalidate them.
339 *
340 * Note that this only applies to descriptors. The packet data buffers do
341 * not have the same constraints since they are 1536 bytes large, so they
342 * are unlikely to share cache-lines.
343 */
Marek Vasut89077732021-01-07 11:12:16 +0100344static void *eqos_alloc_descs(struct eqos_priv *eqos, unsigned int num)
Stephen Warren50709602016-10-21 14:46:47 -0600345{
Marek Vasut89077732021-01-07 11:12:16 +0100346 eqos->desc_size = ALIGN(sizeof(struct eqos_desc),
347 (unsigned int)ARCH_DMA_MINALIGN);
348
349 return memalign(eqos->desc_size, num * eqos->desc_size);
Stephen Warren50709602016-10-21 14:46:47 -0600350}
351
352static void eqos_free_descs(void *descs)
353{
Stephen Warren50709602016-10-21 14:46:47 -0600354 free(descs);
Stephen Warren50709602016-10-21 14:46:47 -0600355}
356
Marek Vasut89077732021-01-07 11:12:16 +0100357static struct eqos_desc *eqos_get_desc(struct eqos_priv *eqos,
358 unsigned int num, bool rx)
Stephen Warren50709602016-10-21 14:46:47 -0600359{
Marek Vasut89077732021-01-07 11:12:16 +0100360 return eqos->descs +
361 ((rx ? EQOS_DESCRIPTORS_TX : 0) + num) * eqos->desc_size;
Stephen Warren50709602016-10-21 14:46:47 -0600362}
363
Fugang Duan37aae5f2020-05-03 22:41:17 +0800364static void eqos_inval_desc_generic(void *desc)
Stephen Warren50709602016-10-21 14:46:47 -0600365{
Marek Vasut89077732021-01-07 11:12:16 +0100366 unsigned long start = (unsigned long)desc;
367 unsigned long end = ALIGN(start + sizeof(struct eqos_desc),
368 ARCH_DMA_MINALIGN);
Christophe Roullier6beb7802019-05-17 15:08:44 +0200369
370 invalidate_dcache_range(start, end);
Stephen Warren50709602016-10-21 14:46:47 -0600371}
372
Fugang Duan37aae5f2020-05-03 22:41:17 +0800373static void eqos_flush_desc_generic(void *desc)
Christophe Roullier6beb7802019-05-17 15:08:44 +0200374{
Marek Vasut89077732021-01-07 11:12:16 +0100375 unsigned long start = (unsigned long)desc;
376 unsigned long end = ALIGN(start + sizeof(struct eqos_desc),
377 ARCH_DMA_MINALIGN);
Christophe Roullier6beb7802019-05-17 15:08:44 +0200378
379 flush_dcache_range(start, end);
Christophe Roullier6beb7802019-05-17 15:08:44 +0200380}
381
382static void eqos_inval_buffer_tegra186(void *buf, size_t size)
Stephen Warren50709602016-10-21 14:46:47 -0600383{
384 unsigned long start = (unsigned long)buf & ~(ARCH_DMA_MINALIGN - 1);
385 unsigned long end = ALIGN(start + size, ARCH_DMA_MINALIGN);
386
387 invalidate_dcache_range(start, end);
388}
389
Fugang Duan37aae5f2020-05-03 22:41:17 +0800390static void eqos_inval_buffer_generic(void *buf, size_t size)
Christophe Roullier6beb7802019-05-17 15:08:44 +0200391{
392 unsigned long start = rounddown((unsigned long)buf, ARCH_DMA_MINALIGN);
393 unsigned long end = roundup((unsigned long)buf + size,
394 ARCH_DMA_MINALIGN);
395
396 invalidate_dcache_range(start, end);
397}
398
399static void eqos_flush_buffer_tegra186(void *buf, size_t size)
Stephen Warren50709602016-10-21 14:46:47 -0600400{
401 flush_cache((unsigned long)buf, size);
402}
403
Fugang Duan37aae5f2020-05-03 22:41:17 +0800404static void eqos_flush_buffer_generic(void *buf, size_t size)
Christophe Roullier6beb7802019-05-17 15:08:44 +0200405{
406 unsigned long start = rounddown((unsigned long)buf, ARCH_DMA_MINALIGN);
407 unsigned long end = roundup((unsigned long)buf + size,
408 ARCH_DMA_MINALIGN);
409
410 flush_dcache_range(start, end);
411}
412
Stephen Warren50709602016-10-21 14:46:47 -0600413static int eqos_mdio_wait_idle(struct eqos_priv *eqos)
414{
Álvaro Fernández Rojas918de032018-01-23 17:14:55 +0100415 return wait_for_bit_le32(&eqos->mac_regs->mdio_address,
416 EQOS_MAC_MDIO_ADDRESS_GB, false,
417 1000000, true);
Stephen Warren50709602016-10-21 14:46:47 -0600418}
419
420static int eqos_mdio_read(struct mii_dev *bus, int mdio_addr, int mdio_devad,
421 int mdio_reg)
422{
423 struct eqos_priv *eqos = bus->priv;
424 u32 val;
425 int ret;
426
427 debug("%s(dev=%p, addr=%x, reg=%d):\n", __func__, eqos->dev, mdio_addr,
428 mdio_reg);
429
430 ret = eqos_mdio_wait_idle(eqos);
431 if (ret) {
Masahiro Yamada81e10422017-09-16 14:10:41 +0900432 pr_err("MDIO not idle at entry");
Stephen Warren50709602016-10-21 14:46:47 -0600433 return ret;
434 }
435
436 val = readl(&eqos->mac_regs->mdio_address);
437 val &= EQOS_MAC_MDIO_ADDRESS_SKAP |
438 EQOS_MAC_MDIO_ADDRESS_C45E;
439 val |= (mdio_addr << EQOS_MAC_MDIO_ADDRESS_PA_SHIFT) |
440 (mdio_reg << EQOS_MAC_MDIO_ADDRESS_RDA_SHIFT) |
Christophe Roullier6beb7802019-05-17 15:08:44 +0200441 (eqos->config->config_mac_mdio <<
Stephen Warren50709602016-10-21 14:46:47 -0600442 EQOS_MAC_MDIO_ADDRESS_CR_SHIFT) |
443 (EQOS_MAC_MDIO_ADDRESS_GOC_READ <<
444 EQOS_MAC_MDIO_ADDRESS_GOC_SHIFT) |
445 EQOS_MAC_MDIO_ADDRESS_GB;
446 writel(val, &eqos->mac_regs->mdio_address);
447
Christophe Roullier6beb7802019-05-17 15:08:44 +0200448 udelay(eqos->config->mdio_wait);
Stephen Warren50709602016-10-21 14:46:47 -0600449
450 ret = eqos_mdio_wait_idle(eqos);
451 if (ret) {
Masahiro Yamada81e10422017-09-16 14:10:41 +0900452 pr_err("MDIO read didn't complete");
Stephen Warren50709602016-10-21 14:46:47 -0600453 return ret;
454 }
455
456 val = readl(&eqos->mac_regs->mdio_data);
457 val &= EQOS_MAC_MDIO_DATA_GD_MASK;
458
459 debug("%s: val=%x\n", __func__, val);
460
461 return val;
462}
463
464static int eqos_mdio_write(struct mii_dev *bus, int mdio_addr, int mdio_devad,
465 int mdio_reg, u16 mdio_val)
466{
467 struct eqos_priv *eqos = bus->priv;
468 u32 val;
469 int ret;
470
471 debug("%s(dev=%p, addr=%x, reg=%d, val=%x):\n", __func__, eqos->dev,
472 mdio_addr, mdio_reg, mdio_val);
473
474 ret = eqos_mdio_wait_idle(eqos);
475 if (ret) {
Masahiro Yamada81e10422017-09-16 14:10:41 +0900476 pr_err("MDIO not idle at entry");
Stephen Warren50709602016-10-21 14:46:47 -0600477 return ret;
478 }
479
480 writel(mdio_val, &eqos->mac_regs->mdio_data);
481
482 val = readl(&eqos->mac_regs->mdio_address);
483 val &= EQOS_MAC_MDIO_ADDRESS_SKAP |
484 EQOS_MAC_MDIO_ADDRESS_C45E;
485 val |= (mdio_addr << EQOS_MAC_MDIO_ADDRESS_PA_SHIFT) |
486 (mdio_reg << EQOS_MAC_MDIO_ADDRESS_RDA_SHIFT) |
Christophe Roullier6beb7802019-05-17 15:08:44 +0200487 (eqos->config->config_mac_mdio <<
Stephen Warren50709602016-10-21 14:46:47 -0600488 EQOS_MAC_MDIO_ADDRESS_CR_SHIFT) |
489 (EQOS_MAC_MDIO_ADDRESS_GOC_WRITE <<
490 EQOS_MAC_MDIO_ADDRESS_GOC_SHIFT) |
491 EQOS_MAC_MDIO_ADDRESS_GB;
492 writel(val, &eqos->mac_regs->mdio_address);
493
Christophe Roullier6beb7802019-05-17 15:08:44 +0200494 udelay(eqos->config->mdio_wait);
Stephen Warren50709602016-10-21 14:46:47 -0600495
496 ret = eqos_mdio_wait_idle(eqos);
497 if (ret) {
Masahiro Yamada81e10422017-09-16 14:10:41 +0900498 pr_err("MDIO read didn't complete");
Stephen Warren50709602016-10-21 14:46:47 -0600499 return ret;
500 }
501
502 return 0;
503}
504
505static int eqos_start_clks_tegra186(struct udevice *dev)
506{
Fugang Duan37aae5f2020-05-03 22:41:17 +0800507#ifdef CONFIG_CLK
Stephen Warren50709602016-10-21 14:46:47 -0600508 struct eqos_priv *eqos = dev_get_priv(dev);
509 int ret;
510
511 debug("%s(dev=%p):\n", __func__, dev);
512
513 ret = clk_enable(&eqos->clk_slave_bus);
514 if (ret < 0) {
Masahiro Yamada81e10422017-09-16 14:10:41 +0900515 pr_err("clk_enable(clk_slave_bus) failed: %d", ret);
Stephen Warren50709602016-10-21 14:46:47 -0600516 goto err;
517 }
518
519 ret = clk_enable(&eqos->clk_master_bus);
520 if (ret < 0) {
Masahiro Yamada81e10422017-09-16 14:10:41 +0900521 pr_err("clk_enable(clk_master_bus) failed: %d", ret);
Stephen Warren50709602016-10-21 14:46:47 -0600522 goto err_disable_clk_slave_bus;
523 }
524
525 ret = clk_enable(&eqos->clk_rx);
526 if (ret < 0) {
Masahiro Yamada81e10422017-09-16 14:10:41 +0900527 pr_err("clk_enable(clk_rx) failed: %d", ret);
Stephen Warren50709602016-10-21 14:46:47 -0600528 goto err_disable_clk_master_bus;
529 }
530
531 ret = clk_enable(&eqos->clk_ptp_ref);
532 if (ret < 0) {
Masahiro Yamada81e10422017-09-16 14:10:41 +0900533 pr_err("clk_enable(clk_ptp_ref) failed: %d", ret);
Stephen Warren50709602016-10-21 14:46:47 -0600534 goto err_disable_clk_rx;
535 }
536
537 ret = clk_set_rate(&eqos->clk_ptp_ref, 125 * 1000 * 1000);
538 if (ret < 0) {
Masahiro Yamada81e10422017-09-16 14:10:41 +0900539 pr_err("clk_set_rate(clk_ptp_ref) failed: %d", ret);
Stephen Warren50709602016-10-21 14:46:47 -0600540 goto err_disable_clk_ptp_ref;
541 }
542
543 ret = clk_enable(&eqos->clk_tx);
544 if (ret < 0) {
Masahiro Yamada81e10422017-09-16 14:10:41 +0900545 pr_err("clk_enable(clk_tx) failed: %d", ret);
Stephen Warren50709602016-10-21 14:46:47 -0600546 goto err_disable_clk_ptp_ref;
547 }
Fugang Duan37aae5f2020-05-03 22:41:17 +0800548#endif
Stephen Warren50709602016-10-21 14:46:47 -0600549
550 debug("%s: OK\n", __func__);
551 return 0;
552
Fugang Duan37aae5f2020-05-03 22:41:17 +0800553#ifdef CONFIG_CLK
Stephen Warren50709602016-10-21 14:46:47 -0600554err_disable_clk_ptp_ref:
555 clk_disable(&eqos->clk_ptp_ref);
556err_disable_clk_rx:
557 clk_disable(&eqos->clk_rx);
558err_disable_clk_master_bus:
559 clk_disable(&eqos->clk_master_bus);
560err_disable_clk_slave_bus:
561 clk_disable(&eqos->clk_slave_bus);
562err:
563 debug("%s: FAILED: %d\n", __func__, ret);
564 return ret;
Fugang Duan37aae5f2020-05-03 22:41:17 +0800565#endif
Stephen Warren50709602016-10-21 14:46:47 -0600566}
567
Christophe Roullier6beb7802019-05-17 15:08:44 +0200568static int eqos_start_clks_stm32(struct udevice *dev)
569{
Fugang Duan37aae5f2020-05-03 22:41:17 +0800570#ifdef CONFIG_CLK
Christophe Roullier6beb7802019-05-17 15:08:44 +0200571 struct eqos_priv *eqos = dev_get_priv(dev);
572 int ret;
573
574 debug("%s(dev=%p):\n", __func__, dev);
575
576 ret = clk_enable(&eqos->clk_master_bus);
577 if (ret < 0) {
578 pr_err("clk_enable(clk_master_bus) failed: %d", ret);
579 goto err;
580 }
581
582 ret = clk_enable(&eqos->clk_rx);
583 if (ret < 0) {
584 pr_err("clk_enable(clk_rx) failed: %d", ret);
585 goto err_disable_clk_master_bus;
586 }
587
588 ret = clk_enable(&eqos->clk_tx);
589 if (ret < 0) {
590 pr_err("clk_enable(clk_tx) failed: %d", ret);
591 goto err_disable_clk_rx;
592 }
593
594 if (clk_valid(&eqos->clk_ck)) {
595 ret = clk_enable(&eqos->clk_ck);
596 if (ret < 0) {
597 pr_err("clk_enable(clk_ck) failed: %d", ret);
598 goto err_disable_clk_tx;
599 }
600 }
Fugang Duan37aae5f2020-05-03 22:41:17 +0800601#endif
Christophe Roullier6beb7802019-05-17 15:08:44 +0200602
603 debug("%s: OK\n", __func__);
604 return 0;
605
Fugang Duan37aae5f2020-05-03 22:41:17 +0800606#ifdef CONFIG_CLK
Christophe Roullier6beb7802019-05-17 15:08:44 +0200607err_disable_clk_tx:
608 clk_disable(&eqos->clk_tx);
609err_disable_clk_rx:
610 clk_disable(&eqos->clk_rx);
611err_disable_clk_master_bus:
612 clk_disable(&eqos->clk_master_bus);
613err:
614 debug("%s: FAILED: %d\n", __func__, ret);
615 return ret;
Fugang Duan37aae5f2020-05-03 22:41:17 +0800616#endif
Christophe Roullier6beb7802019-05-17 15:08:44 +0200617}
618
Fugang Duan37aae5f2020-05-03 22:41:17 +0800619static int eqos_start_clks_imx(struct udevice *dev)
620{
621 return 0;
622}
623
Patrick Delaunay6864a5992019-08-01 11:29:02 +0200624static void eqos_stop_clks_tegra186(struct udevice *dev)
Stephen Warren50709602016-10-21 14:46:47 -0600625{
Fugang Duan37aae5f2020-05-03 22:41:17 +0800626#ifdef CONFIG_CLK
Stephen Warren50709602016-10-21 14:46:47 -0600627 struct eqos_priv *eqos = dev_get_priv(dev);
628
629 debug("%s(dev=%p):\n", __func__, dev);
630
631 clk_disable(&eqos->clk_tx);
632 clk_disable(&eqos->clk_ptp_ref);
633 clk_disable(&eqos->clk_rx);
634 clk_disable(&eqos->clk_master_bus);
635 clk_disable(&eqos->clk_slave_bus);
Fugang Duan37aae5f2020-05-03 22:41:17 +0800636#endif
Stephen Warren50709602016-10-21 14:46:47 -0600637
638 debug("%s: OK\n", __func__);
639}
640
Patrick Delaunay6864a5992019-08-01 11:29:02 +0200641static void eqos_stop_clks_stm32(struct udevice *dev)
Christophe Roullier6beb7802019-05-17 15:08:44 +0200642{
Fugang Duan37aae5f2020-05-03 22:41:17 +0800643#ifdef CONFIG_CLK
Christophe Roullier6beb7802019-05-17 15:08:44 +0200644 struct eqos_priv *eqos = dev_get_priv(dev);
645
646 debug("%s(dev=%p):\n", __func__, dev);
647
648 clk_disable(&eqos->clk_tx);
649 clk_disable(&eqos->clk_rx);
650 clk_disable(&eqos->clk_master_bus);
651 if (clk_valid(&eqos->clk_ck))
652 clk_disable(&eqos->clk_ck);
Fugang Duan37aae5f2020-05-03 22:41:17 +0800653#endif
Christophe Roullier6beb7802019-05-17 15:08:44 +0200654
655 debug("%s: OK\n", __func__);
656}
657
Fugang Duan37aae5f2020-05-03 22:41:17 +0800658static void eqos_stop_clks_imx(struct udevice *dev)
659{
660 /* empty */
661}
662
Stephen Warren50709602016-10-21 14:46:47 -0600663static int eqos_start_resets_tegra186(struct udevice *dev)
664{
665 struct eqos_priv *eqos = dev_get_priv(dev);
666 int ret;
667
668 debug("%s(dev=%p):\n", __func__, dev);
669
670 ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 1);
671 if (ret < 0) {
Masahiro Yamada81e10422017-09-16 14:10:41 +0900672 pr_err("dm_gpio_set_value(phy_reset, assert) failed: %d", ret);
Stephen Warren50709602016-10-21 14:46:47 -0600673 return ret;
674 }
675
676 udelay(2);
677
678 ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 0);
679 if (ret < 0) {
Masahiro Yamada81e10422017-09-16 14:10:41 +0900680 pr_err("dm_gpio_set_value(phy_reset, deassert) failed: %d", ret);
Stephen Warren50709602016-10-21 14:46:47 -0600681 return ret;
682 }
683
684 ret = reset_assert(&eqos->reset_ctl);
685 if (ret < 0) {
Masahiro Yamada81e10422017-09-16 14:10:41 +0900686 pr_err("reset_assert() failed: %d", ret);
Stephen Warren50709602016-10-21 14:46:47 -0600687 return ret;
688 }
689
690 udelay(2);
691
692 ret = reset_deassert(&eqos->reset_ctl);
693 if (ret < 0) {
Masahiro Yamada81e10422017-09-16 14:10:41 +0900694 pr_err("reset_deassert() failed: %d", ret);
Stephen Warren50709602016-10-21 14:46:47 -0600695 return ret;
696 }
697
698 debug("%s: OK\n", __func__);
699 return 0;
700}
701
Christophe Roullier6beb7802019-05-17 15:08:44 +0200702static int eqos_start_resets_stm32(struct udevice *dev)
703{
Christophe Roullier104dab52020-03-18 10:50:15 +0100704 struct eqos_priv *eqos = dev_get_priv(dev);
705 int ret;
706
707 debug("%s(dev=%p):\n", __func__, dev);
708 if (dm_gpio_is_valid(&eqos->phy_reset_gpio)) {
709 ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 1);
710 if (ret < 0) {
711 pr_err("dm_gpio_set_value(phy_reset, assert) failed: %d",
712 ret);
713 return ret;
714 }
715
716 udelay(2);
717
718 ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 0);
719 if (ret < 0) {
720 pr_err("dm_gpio_set_value(phy_reset, deassert) failed: %d",
721 ret);
722 return ret;
723 }
724 }
725 debug("%s: OK\n", __func__);
726
Fugang Duan37aae5f2020-05-03 22:41:17 +0800727 return 0;
728}
729
730static int eqos_start_resets_imx(struct udevice *dev)
731{
Christophe Roullier6beb7802019-05-17 15:08:44 +0200732 return 0;
733}
734
Stephen Warren50709602016-10-21 14:46:47 -0600735static int eqos_stop_resets_tegra186(struct udevice *dev)
736{
737 struct eqos_priv *eqos = dev_get_priv(dev);
738
739 reset_assert(&eqos->reset_ctl);
740 dm_gpio_set_value(&eqos->phy_reset_gpio, 1);
741
Christophe Roullier6beb7802019-05-17 15:08:44 +0200742 return 0;
743}
744
745static int eqos_stop_resets_stm32(struct udevice *dev)
746{
Christophe Roullier104dab52020-03-18 10:50:15 +0100747 struct eqos_priv *eqos = dev_get_priv(dev);
748 int ret;
749
750 if (dm_gpio_is_valid(&eqos->phy_reset_gpio)) {
751 ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 1);
752 if (ret < 0) {
753 pr_err("dm_gpio_set_value(phy_reset, assert) failed: %d",
754 ret);
755 return ret;
756 }
757 }
758
Fugang Duan37aae5f2020-05-03 22:41:17 +0800759 return 0;
760}
761
762static int eqos_stop_resets_imx(struct udevice *dev)
763{
Stephen Warren50709602016-10-21 14:46:47 -0600764 return 0;
765}
766
767static int eqos_calibrate_pads_tegra186(struct udevice *dev)
768{
769 struct eqos_priv *eqos = dev_get_priv(dev);
770 int ret;
771
772 debug("%s(dev=%p):\n", __func__, dev);
773
774 setbits_le32(&eqos->tegra186_regs->sdmemcomppadctrl,
775 EQOS_SDMEMCOMPPADCTRL_PAD_E_INPUT_OR_E_PWRD);
776
777 udelay(1);
778
779 setbits_le32(&eqos->tegra186_regs->auto_cal_config,
780 EQOS_AUTO_CAL_CONFIG_START | EQOS_AUTO_CAL_CONFIG_ENABLE);
781
Álvaro Fernández Rojas918de032018-01-23 17:14:55 +0100782 ret = wait_for_bit_le32(&eqos->tegra186_regs->auto_cal_status,
783 EQOS_AUTO_CAL_STATUS_ACTIVE, true, 10, false);
Stephen Warren50709602016-10-21 14:46:47 -0600784 if (ret) {
Masahiro Yamada81e10422017-09-16 14:10:41 +0900785 pr_err("calibrate didn't start");
Stephen Warren50709602016-10-21 14:46:47 -0600786 goto failed;
787 }
788
Álvaro Fernández Rojas918de032018-01-23 17:14:55 +0100789 ret = wait_for_bit_le32(&eqos->tegra186_regs->auto_cal_status,
790 EQOS_AUTO_CAL_STATUS_ACTIVE, false, 10, false);
Stephen Warren50709602016-10-21 14:46:47 -0600791 if (ret) {
Masahiro Yamada81e10422017-09-16 14:10:41 +0900792 pr_err("calibrate didn't finish");
Stephen Warren50709602016-10-21 14:46:47 -0600793 goto failed;
794 }
795
796 ret = 0;
797
798failed:
799 clrbits_le32(&eqos->tegra186_regs->sdmemcomppadctrl,
800 EQOS_SDMEMCOMPPADCTRL_PAD_E_INPUT_OR_E_PWRD);
801
802 debug("%s: returns %d\n", __func__, ret);
803
804 return ret;
805}
806
807static int eqos_disable_calibration_tegra186(struct udevice *dev)
808{
809 struct eqos_priv *eqos = dev_get_priv(dev);
810
811 debug("%s(dev=%p):\n", __func__, dev);
812
813 clrbits_le32(&eqos->tegra186_regs->auto_cal_config,
814 EQOS_AUTO_CAL_CONFIG_ENABLE);
815
816 return 0;
817}
818
819static ulong eqos_get_tick_clk_rate_tegra186(struct udevice *dev)
820{
Fugang Duan37aae5f2020-05-03 22:41:17 +0800821#ifdef CONFIG_CLK
Stephen Warren50709602016-10-21 14:46:47 -0600822 struct eqos_priv *eqos = dev_get_priv(dev);
823
824 return clk_get_rate(&eqos->clk_slave_bus);
Fugang Duan37aae5f2020-05-03 22:41:17 +0800825#else
826 return 0;
827#endif
Stephen Warren50709602016-10-21 14:46:47 -0600828}
829
Christophe Roullier6beb7802019-05-17 15:08:44 +0200830static ulong eqos_get_tick_clk_rate_stm32(struct udevice *dev)
831{
Fugang Duan37aae5f2020-05-03 22:41:17 +0800832#ifdef CONFIG_CLK
Christophe Roullier6beb7802019-05-17 15:08:44 +0200833 struct eqos_priv *eqos = dev_get_priv(dev);
834
835 return clk_get_rate(&eqos->clk_master_bus);
Fugang Duan37aae5f2020-05-03 22:41:17 +0800836#else
837 return 0;
838#endif
839}
840
Fugang Duandd455e62020-05-03 22:41:18 +0800841__weak u32 imx_get_eqos_csr_clk(void)
Fugang Duan37aae5f2020-05-03 22:41:17 +0800842{
Fugang Duan37aae5f2020-05-03 22:41:17 +0800843 return 100 * 1000000;
Christophe Roullier6beb7802019-05-17 15:08:44 +0200844}
Fugang Duandd455e62020-05-03 22:41:18 +0800845__weak int imx_eqos_txclk_set_rate(unsigned long rate)
846{
847 return 0;
848}
849
850static ulong eqos_get_tick_clk_rate_imx(struct udevice *dev)
851{
852 return imx_get_eqos_csr_clk();
853}
Christophe Roullier6beb7802019-05-17 15:08:44 +0200854
855static int eqos_calibrate_pads_stm32(struct udevice *dev)
856{
857 return 0;
858}
859
Fugang Duan37aae5f2020-05-03 22:41:17 +0800860static int eqos_calibrate_pads_imx(struct udevice *dev)
861{
862 return 0;
863}
864
Christophe Roullier6beb7802019-05-17 15:08:44 +0200865static int eqos_disable_calibration_stm32(struct udevice *dev)
866{
867 return 0;
868}
869
Fugang Duan37aae5f2020-05-03 22:41:17 +0800870static int eqos_disable_calibration_imx(struct udevice *dev)
871{
872 return 0;
873}
874
Stephen Warren50709602016-10-21 14:46:47 -0600875static int eqos_set_full_duplex(struct udevice *dev)
876{
877 struct eqos_priv *eqos = dev_get_priv(dev);
878
879 debug("%s(dev=%p):\n", __func__, dev);
880
881 setbits_le32(&eqos->mac_regs->configuration, EQOS_MAC_CONFIGURATION_DM);
882
883 return 0;
884}
885
886static int eqos_set_half_duplex(struct udevice *dev)
887{
888 struct eqos_priv *eqos = dev_get_priv(dev);
889
890 debug("%s(dev=%p):\n", __func__, dev);
891
892 clrbits_le32(&eqos->mac_regs->configuration, EQOS_MAC_CONFIGURATION_DM);
893
894 /* WAR: Flush TX queue when switching to half-duplex */
895 setbits_le32(&eqos->mtl_regs->txq0_operation_mode,
896 EQOS_MTL_TXQ0_OPERATION_MODE_FTQ);
897
898 return 0;
899}
900
901static int eqos_set_gmii_speed(struct udevice *dev)
902{
903 struct eqos_priv *eqos = dev_get_priv(dev);
904
905 debug("%s(dev=%p):\n", __func__, dev);
906
907 clrbits_le32(&eqos->mac_regs->configuration,
908 EQOS_MAC_CONFIGURATION_PS | EQOS_MAC_CONFIGURATION_FES);
909
910 return 0;
911}
912
913static int eqos_set_mii_speed_100(struct udevice *dev)
914{
915 struct eqos_priv *eqos = dev_get_priv(dev);
916
917 debug("%s(dev=%p):\n", __func__, dev);
918
919 setbits_le32(&eqos->mac_regs->configuration,
920 EQOS_MAC_CONFIGURATION_PS | EQOS_MAC_CONFIGURATION_FES);
921
922 return 0;
923}
924
925static int eqos_set_mii_speed_10(struct udevice *dev)
926{
927 struct eqos_priv *eqos = dev_get_priv(dev);
928
929 debug("%s(dev=%p):\n", __func__, dev);
930
931 clrsetbits_le32(&eqos->mac_regs->configuration,
932 EQOS_MAC_CONFIGURATION_FES, EQOS_MAC_CONFIGURATION_PS);
933
934 return 0;
935}
936
937static int eqos_set_tx_clk_speed_tegra186(struct udevice *dev)
938{
Fugang Duan37aae5f2020-05-03 22:41:17 +0800939#ifdef CONFIG_CLK
Stephen Warren50709602016-10-21 14:46:47 -0600940 struct eqos_priv *eqos = dev_get_priv(dev);
941 ulong rate;
942 int ret;
943
944 debug("%s(dev=%p):\n", __func__, dev);
945
946 switch (eqos->phy->speed) {
947 case SPEED_1000:
948 rate = 125 * 1000 * 1000;
949 break;
950 case SPEED_100:
951 rate = 25 * 1000 * 1000;
952 break;
953 case SPEED_10:
954 rate = 2.5 * 1000 * 1000;
955 break;
956 default:
Masahiro Yamada81e10422017-09-16 14:10:41 +0900957 pr_err("invalid speed %d", eqos->phy->speed);
Stephen Warren50709602016-10-21 14:46:47 -0600958 return -EINVAL;
959 }
960
961 ret = clk_set_rate(&eqos->clk_tx, rate);
962 if (ret < 0) {
Masahiro Yamada81e10422017-09-16 14:10:41 +0900963 pr_err("clk_set_rate(tx_clk, %lu) failed: %d", rate, ret);
Stephen Warren50709602016-10-21 14:46:47 -0600964 return ret;
965 }
Fugang Duan37aae5f2020-05-03 22:41:17 +0800966#endif
Stephen Warren50709602016-10-21 14:46:47 -0600967
968 return 0;
969}
970
Christophe Roullier6beb7802019-05-17 15:08:44 +0200971static int eqos_set_tx_clk_speed_stm32(struct udevice *dev)
972{
973 return 0;
974}
975
Fugang Duan37aae5f2020-05-03 22:41:17 +0800976static int eqos_set_tx_clk_speed_imx(struct udevice *dev)
977{
Fugang Duandd455e62020-05-03 22:41:18 +0800978 struct eqos_priv *eqos = dev_get_priv(dev);
979 ulong rate;
980 int ret;
981
982 debug("%s(dev=%p):\n", __func__, dev);
983
984 switch (eqos->phy->speed) {
985 case SPEED_1000:
986 rate = 125 * 1000 * 1000;
987 break;
988 case SPEED_100:
989 rate = 25 * 1000 * 1000;
990 break;
991 case SPEED_10:
992 rate = 2.5 * 1000 * 1000;
993 break;
994 default:
995 pr_err("invalid speed %d", eqos->phy->speed);
996 return -EINVAL;
997 }
998
999 ret = imx_eqos_txclk_set_rate(rate);
1000 if (ret < 0) {
1001 pr_err("imx (tx_clk, %lu) failed: %d", rate, ret);
1002 return ret;
1003 }
1004
Fugang Duan37aae5f2020-05-03 22:41:17 +08001005 return 0;
1006}
1007
Stephen Warren50709602016-10-21 14:46:47 -06001008static int eqos_adjust_link(struct udevice *dev)
1009{
1010 struct eqos_priv *eqos = dev_get_priv(dev);
1011 int ret;
1012 bool en_calibration;
1013
1014 debug("%s(dev=%p):\n", __func__, dev);
1015
1016 if (eqos->phy->duplex)
1017 ret = eqos_set_full_duplex(dev);
1018 else
1019 ret = eqos_set_half_duplex(dev);
1020 if (ret < 0) {
Masahiro Yamada81e10422017-09-16 14:10:41 +09001021 pr_err("eqos_set_*_duplex() failed: %d", ret);
Stephen Warren50709602016-10-21 14:46:47 -06001022 return ret;
1023 }
1024
1025 switch (eqos->phy->speed) {
1026 case SPEED_1000:
1027 en_calibration = true;
1028 ret = eqos_set_gmii_speed(dev);
1029 break;
1030 case SPEED_100:
1031 en_calibration = true;
1032 ret = eqos_set_mii_speed_100(dev);
1033 break;
1034 case SPEED_10:
1035 en_calibration = false;
1036 ret = eqos_set_mii_speed_10(dev);
1037 break;
1038 default:
Masahiro Yamada81e10422017-09-16 14:10:41 +09001039 pr_err("invalid speed %d", eqos->phy->speed);
Stephen Warren50709602016-10-21 14:46:47 -06001040 return -EINVAL;
1041 }
1042 if (ret < 0) {
Masahiro Yamada81e10422017-09-16 14:10:41 +09001043 pr_err("eqos_set_*mii_speed*() failed: %d", ret);
Stephen Warren50709602016-10-21 14:46:47 -06001044 return ret;
1045 }
1046
1047 if (en_calibration) {
Christophe Roullier6beb7802019-05-17 15:08:44 +02001048 ret = eqos->config->ops->eqos_calibrate_pads(dev);
Stephen Warren50709602016-10-21 14:46:47 -06001049 if (ret < 0) {
Christophe Roullier6beb7802019-05-17 15:08:44 +02001050 pr_err("eqos_calibrate_pads() failed: %d",
1051 ret);
Stephen Warren50709602016-10-21 14:46:47 -06001052 return ret;
1053 }
1054 } else {
Christophe Roullier6beb7802019-05-17 15:08:44 +02001055 ret = eqos->config->ops->eqos_disable_calibration(dev);
Stephen Warren50709602016-10-21 14:46:47 -06001056 if (ret < 0) {
Christophe Roullier6beb7802019-05-17 15:08:44 +02001057 pr_err("eqos_disable_calibration() failed: %d",
1058 ret);
Stephen Warren50709602016-10-21 14:46:47 -06001059 return ret;
1060 }
1061 }
Christophe Roullier6beb7802019-05-17 15:08:44 +02001062 ret = eqos->config->ops->eqos_set_tx_clk_speed(dev);
Stephen Warren50709602016-10-21 14:46:47 -06001063 if (ret < 0) {
Christophe Roullier6beb7802019-05-17 15:08:44 +02001064 pr_err("eqos_set_tx_clk_speed() failed: %d", ret);
Stephen Warren50709602016-10-21 14:46:47 -06001065 return ret;
1066 }
1067
1068 return 0;
1069}
1070
1071static int eqos_write_hwaddr(struct udevice *dev)
1072{
Simon Glassfa20e932020-12-03 16:55:20 -07001073 struct eth_pdata *plat = dev_get_plat(dev);
Stephen Warren50709602016-10-21 14:46:47 -06001074 struct eqos_priv *eqos = dev_get_priv(dev);
1075 uint32_t val;
1076
1077 /*
1078 * This function may be called before start() or after stop(). At that
1079 * time, on at least some configurations of the EQoS HW, all clocks to
1080 * the EQoS HW block will be stopped, and a reset signal applied. If
1081 * any register access is attempted in this state, bus timeouts or CPU
1082 * hangs may occur. This check prevents that.
1083 *
1084 * A simple solution to this problem would be to not implement
1085 * write_hwaddr(), since start() always writes the MAC address into HW
1086 * anyway. However, it is desirable to implement write_hwaddr() to
1087 * support the case of SW that runs subsequent to U-Boot which expects
1088 * the MAC address to already be programmed into the EQoS registers,
1089 * which must happen irrespective of whether the U-Boot user (or
1090 * scripts) actually made use of the EQoS device, and hence
1091 * irrespective of whether start() was ever called.
1092 *
1093 * Note that this requirement by subsequent SW is not valid for
1094 * Tegra186, and is likely not valid for any non-PCI instantiation of
1095 * the EQoS HW block. This function is implemented solely as
1096 * future-proofing with the expectation the driver will eventually be
1097 * ported to some system where the expectation above is true.
1098 */
1099 if (!eqos->config->reg_access_always_ok && !eqos->reg_access_ok)
1100 return 0;
1101
1102 /* Update the MAC address */
1103 val = (plat->enetaddr[5] << 8) |
1104 (plat->enetaddr[4]);
1105 writel(val, &eqos->mac_regs->address0_high);
1106 val = (plat->enetaddr[3] << 24) |
1107 (plat->enetaddr[2] << 16) |
1108 (plat->enetaddr[1] << 8) |
1109 (plat->enetaddr[0]);
1110 writel(val, &eqos->mac_regs->address0_low);
1111
1112 return 0;
1113}
1114
Ye Li3fb1a0e2020-05-03 22:41:20 +08001115static int eqos_read_rom_hwaddr(struct udevice *dev)
1116{
Simon Glassfa20e932020-12-03 16:55:20 -07001117 struct eth_pdata *pdata = dev_get_plat(dev);
Ye Li3fb1a0e2020-05-03 22:41:20 +08001118
1119#ifdef CONFIG_ARCH_IMX8M
Simon Glass3e14a222020-12-16 21:20:16 -07001120 imx_get_mac_from_fuse(dev_seq(dev), pdata->enetaddr);
Ye Li3fb1a0e2020-05-03 22:41:20 +08001121#endif
1122 return !is_valid_ethaddr(pdata->enetaddr);
1123}
1124
Stephen Warren50709602016-10-21 14:46:47 -06001125static int eqos_start(struct udevice *dev)
1126{
1127 struct eqos_priv *eqos = dev_get_priv(dev);
1128 int ret, i;
1129 ulong rate;
1130 u32 val, tx_fifo_sz, rx_fifo_sz, tqs, rqs, pbl;
1131 ulong last_rx_desc;
Marek Vasut89077732021-01-07 11:12:16 +01001132 ulong desc_pad;
Stephen Warren50709602016-10-21 14:46:47 -06001133
1134 debug("%s(dev=%p):\n", __func__, dev);
1135
1136 eqos->tx_desc_idx = 0;
1137 eqos->rx_desc_idx = 0;
1138
Christophe Roullier6beb7802019-05-17 15:08:44 +02001139 ret = eqos->config->ops->eqos_start_clks(dev);
Stephen Warren50709602016-10-21 14:46:47 -06001140 if (ret < 0) {
Christophe Roullier6beb7802019-05-17 15:08:44 +02001141 pr_err("eqos_start_clks() failed: %d", ret);
Stephen Warren50709602016-10-21 14:46:47 -06001142 goto err;
1143 }
1144
Christophe Roullier6beb7802019-05-17 15:08:44 +02001145 ret = eqos->config->ops->eqos_start_resets(dev);
Stephen Warren50709602016-10-21 14:46:47 -06001146 if (ret < 0) {
Christophe Roullier6beb7802019-05-17 15:08:44 +02001147 pr_err("eqos_start_resets() failed: %d", ret);
Stephen Warren50709602016-10-21 14:46:47 -06001148 goto err_stop_clks;
1149 }
1150
1151 udelay(10);
1152
1153 eqos->reg_access_ok = true;
1154
Álvaro Fernández Rojas918de032018-01-23 17:14:55 +01001155 ret = wait_for_bit_le32(&eqos->dma_regs->mode,
Christophe Roullier6beb7802019-05-17 15:08:44 +02001156 EQOS_DMA_MODE_SWR, false,
1157 eqos->config->swr_wait, false);
Stephen Warren50709602016-10-21 14:46:47 -06001158 if (ret) {
Masahiro Yamada81e10422017-09-16 14:10:41 +09001159 pr_err("EQOS_DMA_MODE_SWR stuck");
Stephen Warren50709602016-10-21 14:46:47 -06001160 goto err_stop_resets;
1161 }
1162
Christophe Roullier6beb7802019-05-17 15:08:44 +02001163 ret = eqos->config->ops->eqos_calibrate_pads(dev);
Stephen Warren50709602016-10-21 14:46:47 -06001164 if (ret < 0) {
Christophe Roullier6beb7802019-05-17 15:08:44 +02001165 pr_err("eqos_calibrate_pads() failed: %d", ret);
Stephen Warren50709602016-10-21 14:46:47 -06001166 goto err_stop_resets;
1167 }
Christophe Roullier6beb7802019-05-17 15:08:44 +02001168 rate = eqos->config->ops->eqos_get_tick_clk_rate(dev);
Stephen Warren50709602016-10-21 14:46:47 -06001169
Stephen Warren50709602016-10-21 14:46:47 -06001170 val = (rate / 1000000) - 1;
1171 writel(val, &eqos->mac_regs->us_tic_counter);
1172
Christophe Roullier6beb7802019-05-17 15:08:44 +02001173 /*
1174 * if PHY was already connected and configured,
1175 * don't need to reconnect/reconfigure again
1176 */
Stephen Warren50709602016-10-21 14:46:47 -06001177 if (!eqos->phy) {
Ye Liad122b72020-05-03 22:41:15 +08001178 int addr = -1;
1179#ifdef CONFIG_DM_ETH_PHY
1180 addr = eth_phy_get_addr(dev);
1181#endif
1182#ifdef DWC_NET_PHYADDR
1183 addr = DWC_NET_PHYADDR;
1184#endif
1185 eqos->phy = phy_connect(eqos->mii, addr, dev,
Christophe Roullier6beb7802019-05-17 15:08:44 +02001186 eqos->config->interface(dev));
1187 if (!eqos->phy) {
1188 pr_err("phy_connect() failed");
1189 goto err_stop_resets;
1190 }
Patrick Delaunay5c8db372020-03-18 10:50:16 +01001191
1192 if (eqos->max_speed) {
1193 ret = phy_set_supported(eqos->phy, eqos->max_speed);
1194 if (ret) {
1195 pr_err("phy_set_supported() failed: %d", ret);
1196 goto err_shutdown_phy;
1197 }
1198 }
1199
Christophe Roullier6beb7802019-05-17 15:08:44 +02001200 ret = phy_config(eqos->phy);
1201 if (ret < 0) {
1202 pr_err("phy_config() failed: %d", ret);
1203 goto err_shutdown_phy;
1204 }
Stephen Warren50709602016-10-21 14:46:47 -06001205 }
Christophe Roullier6beb7802019-05-17 15:08:44 +02001206
Stephen Warren50709602016-10-21 14:46:47 -06001207 ret = phy_startup(eqos->phy);
1208 if (ret < 0) {
Masahiro Yamada81e10422017-09-16 14:10:41 +09001209 pr_err("phy_startup() failed: %d", ret);
Stephen Warren50709602016-10-21 14:46:47 -06001210 goto err_shutdown_phy;
1211 }
1212
1213 if (!eqos->phy->link) {
Masahiro Yamada81e10422017-09-16 14:10:41 +09001214 pr_err("No link");
Stephen Warren50709602016-10-21 14:46:47 -06001215 goto err_shutdown_phy;
1216 }
1217
1218 ret = eqos_adjust_link(dev);
1219 if (ret < 0) {
Masahiro Yamada81e10422017-09-16 14:10:41 +09001220 pr_err("eqos_adjust_link() failed: %d", ret);
Stephen Warren50709602016-10-21 14:46:47 -06001221 goto err_shutdown_phy;
1222 }
1223
1224 /* Configure MTL */
Fugang Duan37aae5f2020-05-03 22:41:17 +08001225 writel(0x60, &eqos->mtl_regs->txq0_quantum_weight - 0x100);
Stephen Warren50709602016-10-21 14:46:47 -06001226
1227 /* Enable Store and Forward mode for TX */
1228 /* Program Tx operating mode */
1229 setbits_le32(&eqos->mtl_regs->txq0_operation_mode,
1230 EQOS_MTL_TXQ0_OPERATION_MODE_TSF |
1231 (EQOS_MTL_TXQ0_OPERATION_MODE_TXQEN_ENABLED <<
1232 EQOS_MTL_TXQ0_OPERATION_MODE_TXQEN_SHIFT));
1233
1234 /* Transmit Queue weight */
1235 writel(0x10, &eqos->mtl_regs->txq0_quantum_weight);
1236
1237 /* Enable Store and Forward mode for RX, since no jumbo frame */
1238 setbits_le32(&eqos->mtl_regs->rxq0_operation_mode,
Fugang Duan37aae5f2020-05-03 22:41:17 +08001239 EQOS_MTL_RXQ0_OPERATION_MODE_RSF |
1240 EQOS_MTL_RXQ0_OPERATION_MODE_FEP |
1241 EQOS_MTL_RXQ0_OPERATION_MODE_FUP);
Stephen Warren50709602016-10-21 14:46:47 -06001242
1243 /* Transmit/Receive queue fifo size; use all RAM for 1 queue */
1244 val = readl(&eqos->mac_regs->hw_feature1);
1245 tx_fifo_sz = (val >> EQOS_MAC_HW_FEATURE1_TXFIFOSIZE_SHIFT) &
1246 EQOS_MAC_HW_FEATURE1_TXFIFOSIZE_MASK;
1247 rx_fifo_sz = (val >> EQOS_MAC_HW_FEATURE1_RXFIFOSIZE_SHIFT) &
1248 EQOS_MAC_HW_FEATURE1_RXFIFOSIZE_MASK;
1249
1250 /*
1251 * r/tx_fifo_sz is encoded as log2(n / 128). Undo that by shifting.
1252 * r/tqs is encoded as (n / 256) - 1.
1253 */
1254 tqs = (128 << tx_fifo_sz) / 256 - 1;
1255 rqs = (128 << rx_fifo_sz) / 256 - 1;
1256
1257 clrsetbits_le32(&eqos->mtl_regs->txq0_operation_mode,
1258 EQOS_MTL_TXQ0_OPERATION_MODE_TQS_MASK <<
1259 EQOS_MTL_TXQ0_OPERATION_MODE_TQS_SHIFT,
1260 tqs << EQOS_MTL_TXQ0_OPERATION_MODE_TQS_SHIFT);
1261 clrsetbits_le32(&eqos->mtl_regs->rxq0_operation_mode,
1262 EQOS_MTL_RXQ0_OPERATION_MODE_RQS_MASK <<
1263 EQOS_MTL_RXQ0_OPERATION_MODE_RQS_SHIFT,
1264 rqs << EQOS_MTL_RXQ0_OPERATION_MODE_RQS_SHIFT);
1265
1266 /* Flow control used only if each channel gets 4KB or more FIFO */
1267 if (rqs >= ((4096 / 256) - 1)) {
1268 u32 rfd, rfa;
1269
1270 setbits_le32(&eqos->mtl_regs->rxq0_operation_mode,
1271 EQOS_MTL_RXQ0_OPERATION_MODE_EHFC);
1272
1273 /*
1274 * Set Threshold for Activating Flow Contol space for min 2
1275 * frames ie, (1500 * 1) = 1500 bytes.
1276 *
1277 * Set Threshold for Deactivating Flow Contol for space of
1278 * min 1 frame (frame size 1500bytes) in receive fifo
1279 */
1280 if (rqs == ((4096 / 256) - 1)) {
1281 /*
1282 * This violates the above formula because of FIFO size
1283 * limit therefore overflow may occur inspite of this.
1284 */
1285 rfd = 0x3; /* Full-3K */
1286 rfa = 0x1; /* Full-1.5K */
1287 } else if (rqs == ((8192 / 256) - 1)) {
1288 rfd = 0x6; /* Full-4K */
1289 rfa = 0xa; /* Full-6K */
1290 } else if (rqs == ((16384 / 256) - 1)) {
1291 rfd = 0x6; /* Full-4K */
1292 rfa = 0x12; /* Full-10K */
1293 } else {
1294 rfd = 0x6; /* Full-4K */
1295 rfa = 0x1E; /* Full-16K */
1296 }
1297
1298 clrsetbits_le32(&eqos->mtl_regs->rxq0_operation_mode,
1299 (EQOS_MTL_RXQ0_OPERATION_MODE_RFD_MASK <<
1300 EQOS_MTL_RXQ0_OPERATION_MODE_RFD_SHIFT) |
1301 (EQOS_MTL_RXQ0_OPERATION_MODE_RFA_MASK <<
1302 EQOS_MTL_RXQ0_OPERATION_MODE_RFA_SHIFT),
1303 (rfd <<
1304 EQOS_MTL_RXQ0_OPERATION_MODE_RFD_SHIFT) |
1305 (rfa <<
1306 EQOS_MTL_RXQ0_OPERATION_MODE_RFA_SHIFT));
1307 }
1308
1309 /* Configure MAC */
1310
1311 clrsetbits_le32(&eqos->mac_regs->rxq_ctrl0,
1312 EQOS_MAC_RXQ_CTRL0_RXQ0EN_MASK <<
1313 EQOS_MAC_RXQ_CTRL0_RXQ0EN_SHIFT,
Christophe Roullier6beb7802019-05-17 15:08:44 +02001314 eqos->config->config_mac <<
Stephen Warren50709602016-10-21 14:46:47 -06001315 EQOS_MAC_RXQ_CTRL0_RXQ0EN_SHIFT);
1316
Fugang Duan37aae5f2020-05-03 22:41:17 +08001317 clrsetbits_le32(&eqos->mac_regs->rxq_ctrl0,
1318 EQOS_MAC_RXQ_CTRL0_RXQ0EN_MASK <<
1319 EQOS_MAC_RXQ_CTRL0_RXQ0EN_SHIFT,
1320 0x2 <<
1321 EQOS_MAC_RXQ_CTRL0_RXQ0EN_SHIFT);
1322
1323 /* Multicast and Broadcast Queue Enable */
1324 setbits_le32(&eqos->mac_regs->unused_0a4,
1325 0x00100000);
1326 /* enable promise mode */
1327 setbits_le32(&eqos->mac_regs->unused_004[1],
1328 0x1);
1329
Stephen Warren50709602016-10-21 14:46:47 -06001330 /* Set TX flow control parameters */
1331 /* Set Pause Time */
1332 setbits_le32(&eqos->mac_regs->q0_tx_flow_ctrl,
1333 0xffff << EQOS_MAC_Q0_TX_FLOW_CTRL_PT_SHIFT);
1334 /* Assign priority for TX flow control */
1335 clrbits_le32(&eqos->mac_regs->txq_prty_map0,
1336 EQOS_MAC_TXQ_PRTY_MAP0_PSTQ0_MASK <<
1337 EQOS_MAC_TXQ_PRTY_MAP0_PSTQ0_SHIFT);
1338 /* Assign priority for RX flow control */
1339 clrbits_le32(&eqos->mac_regs->rxq_ctrl2,
1340 EQOS_MAC_RXQ_CTRL2_PSRQ0_MASK <<
1341 EQOS_MAC_RXQ_CTRL2_PSRQ0_SHIFT);
1342 /* Enable flow control */
1343 setbits_le32(&eqos->mac_regs->q0_tx_flow_ctrl,
1344 EQOS_MAC_Q0_TX_FLOW_CTRL_TFE);
1345 setbits_le32(&eqos->mac_regs->rx_flow_ctrl,
1346 EQOS_MAC_RX_FLOW_CTRL_RFE);
1347
1348 clrsetbits_le32(&eqos->mac_regs->configuration,
1349 EQOS_MAC_CONFIGURATION_GPSLCE |
1350 EQOS_MAC_CONFIGURATION_WD |
1351 EQOS_MAC_CONFIGURATION_JD |
1352 EQOS_MAC_CONFIGURATION_JE,
1353 EQOS_MAC_CONFIGURATION_CST |
1354 EQOS_MAC_CONFIGURATION_ACS);
1355
1356 eqos_write_hwaddr(dev);
1357
1358 /* Configure DMA */
1359
1360 /* Enable OSP mode */
1361 setbits_le32(&eqos->dma_regs->ch0_tx_control,
1362 EQOS_DMA_CH0_TX_CONTROL_OSP);
1363
1364 /* RX buffer size. Must be a multiple of bus width */
1365 clrsetbits_le32(&eqos->dma_regs->ch0_rx_control,
1366 EQOS_DMA_CH0_RX_CONTROL_RBSZ_MASK <<
1367 EQOS_DMA_CH0_RX_CONTROL_RBSZ_SHIFT,
1368 EQOS_MAX_PACKET_SIZE <<
1369 EQOS_DMA_CH0_RX_CONTROL_RBSZ_SHIFT);
1370
Marek Vasut89077732021-01-07 11:12:16 +01001371 desc_pad = (eqos->desc_size - sizeof(struct eqos_desc)) /
1372 eqos->config->axi_bus_width;
1373
Stephen Warren50709602016-10-21 14:46:47 -06001374 setbits_le32(&eqos->dma_regs->ch0_control,
Marek Vasut89077732021-01-07 11:12:16 +01001375 EQOS_DMA_CH0_CONTROL_PBLX8 |
1376 (desc_pad << EQOS_DMA_CH0_CONTROL_DSL_SHIFT));
Stephen Warren50709602016-10-21 14:46:47 -06001377
1378 /*
1379 * Burst length must be < 1/2 FIFO size.
1380 * FIFO size in tqs is encoded as (n / 256) - 1.
1381 * Each burst is n * 8 (PBLX8) * 16 (AXI width) == 128 bytes.
1382 * Half of n * 256 is n * 128, so pbl == tqs, modulo the -1.
1383 */
1384 pbl = tqs + 1;
1385 if (pbl > 32)
1386 pbl = 32;
1387 clrsetbits_le32(&eqos->dma_regs->ch0_tx_control,
1388 EQOS_DMA_CH0_TX_CONTROL_TXPBL_MASK <<
1389 EQOS_DMA_CH0_TX_CONTROL_TXPBL_SHIFT,
1390 pbl << EQOS_DMA_CH0_TX_CONTROL_TXPBL_SHIFT);
1391
1392 clrsetbits_le32(&eqos->dma_regs->ch0_rx_control,
1393 EQOS_DMA_CH0_RX_CONTROL_RXPBL_MASK <<
1394 EQOS_DMA_CH0_RX_CONTROL_RXPBL_SHIFT,
1395 8 << EQOS_DMA_CH0_RX_CONTROL_RXPBL_SHIFT);
1396
1397 /* DMA performance configuration */
1398 val = (2 << EQOS_DMA_SYSBUS_MODE_RD_OSR_LMT_SHIFT) |
1399 EQOS_DMA_SYSBUS_MODE_EAME | EQOS_DMA_SYSBUS_MODE_BLEN16 |
1400 EQOS_DMA_SYSBUS_MODE_BLEN8 | EQOS_DMA_SYSBUS_MODE_BLEN4;
1401 writel(val, &eqos->dma_regs->sysbus_mode);
1402
1403 /* Set up descriptors */
1404
Marek Vasut89077732021-01-07 11:12:16 +01001405 memset(eqos->descs, 0, eqos->desc_size * EQOS_DESCRIPTORS_NUM);
1406
1407 for (i = 0; i < EQOS_DESCRIPTORS_TX; i++) {
1408 struct eqos_desc *tx_desc = eqos_get_desc(eqos, i, false);
1409 eqos->config->ops->eqos_flush_desc(tx_desc);
1410 }
1411
Stephen Warren50709602016-10-21 14:46:47 -06001412 for (i = 0; i < EQOS_DESCRIPTORS_RX; i++) {
Marek Vasut89077732021-01-07 11:12:16 +01001413 struct eqos_desc *rx_desc = eqos_get_desc(eqos, i, true);
Stephen Warren50709602016-10-21 14:46:47 -06001414 rx_desc->des0 = (u32)(ulong)(eqos->rx_dma_buf +
1415 (i * EQOS_MAX_PACKET_SIZE));
Marek Vasutd54c98e2020-03-23 02:02:57 +01001416 rx_desc->des3 = EQOS_DESC3_OWN | EQOS_DESC3_BUF1V;
Fugang Duan37aae5f2020-05-03 22:41:17 +08001417 mb();
Marek Vasut873f8e42020-03-23 02:09:01 +01001418 eqos->config->ops->eqos_flush_desc(rx_desc);
Fugang Duan37aae5f2020-05-03 22:41:17 +08001419 eqos->config->ops->eqos_inval_buffer(eqos->rx_dma_buf +
1420 (i * EQOS_MAX_PACKET_SIZE),
1421 EQOS_MAX_PACKET_SIZE);
Stephen Warren50709602016-10-21 14:46:47 -06001422 }
Stephen Warren50709602016-10-21 14:46:47 -06001423
1424 writel(0, &eqos->dma_regs->ch0_txdesc_list_haddress);
Marek Vasut89077732021-01-07 11:12:16 +01001425 writel((ulong)eqos_get_desc(eqos, 0, false),
1426 &eqos->dma_regs->ch0_txdesc_list_address);
Stephen Warren50709602016-10-21 14:46:47 -06001427 writel(EQOS_DESCRIPTORS_TX - 1,
1428 &eqos->dma_regs->ch0_txdesc_ring_length);
1429
1430 writel(0, &eqos->dma_regs->ch0_rxdesc_list_haddress);
Marek Vasut89077732021-01-07 11:12:16 +01001431 writel((ulong)eqos_get_desc(eqos, 0, true),
1432 &eqos->dma_regs->ch0_rxdesc_list_address);
Stephen Warren50709602016-10-21 14:46:47 -06001433 writel(EQOS_DESCRIPTORS_RX - 1,
1434 &eqos->dma_regs->ch0_rxdesc_ring_length);
1435
1436 /* Enable everything */
Stephen Warren50709602016-10-21 14:46:47 -06001437 setbits_le32(&eqos->dma_regs->ch0_tx_control,
1438 EQOS_DMA_CH0_TX_CONTROL_ST);
1439 setbits_le32(&eqos->dma_regs->ch0_rx_control,
1440 EQOS_DMA_CH0_RX_CONTROL_SR);
Fugang Duan37aae5f2020-05-03 22:41:17 +08001441 setbits_le32(&eqos->mac_regs->configuration,
1442 EQOS_MAC_CONFIGURATION_TE | EQOS_MAC_CONFIGURATION_RE);
Stephen Warren50709602016-10-21 14:46:47 -06001443
1444 /* TX tail pointer not written until we need to TX a packet */
1445 /*
1446 * Point RX tail pointer at last descriptor. Ideally, we'd point at the
1447 * first descriptor, implying all descriptors were available. However,
1448 * that's not distinguishable from none of the descriptors being
1449 * available.
1450 */
Marek Vasut89077732021-01-07 11:12:16 +01001451 last_rx_desc = (ulong)eqos_get_desc(eqos, EQOS_DESCRIPTORS_RX - 1, true);
Stephen Warren50709602016-10-21 14:46:47 -06001452 writel(last_rx_desc, &eqos->dma_regs->ch0_rxdesc_tail_pointer);
1453
1454 eqos->started = true;
1455
1456 debug("%s: OK\n", __func__);
1457 return 0;
1458
1459err_shutdown_phy:
1460 phy_shutdown(eqos->phy);
Stephen Warren50709602016-10-21 14:46:47 -06001461err_stop_resets:
Christophe Roullier6beb7802019-05-17 15:08:44 +02001462 eqos->config->ops->eqos_stop_resets(dev);
Stephen Warren50709602016-10-21 14:46:47 -06001463err_stop_clks:
Christophe Roullier6beb7802019-05-17 15:08:44 +02001464 eqos->config->ops->eqos_stop_clks(dev);
Stephen Warren50709602016-10-21 14:46:47 -06001465err:
Masahiro Yamada81e10422017-09-16 14:10:41 +09001466 pr_err("FAILED: %d", ret);
Stephen Warren50709602016-10-21 14:46:47 -06001467 return ret;
1468}
1469
Patrick Delaunay6864a5992019-08-01 11:29:02 +02001470static void eqos_stop(struct udevice *dev)
Stephen Warren50709602016-10-21 14:46:47 -06001471{
1472 struct eqos_priv *eqos = dev_get_priv(dev);
1473 int i;
1474
1475 debug("%s(dev=%p):\n", __func__, dev);
1476
1477 if (!eqos->started)
1478 return;
1479 eqos->started = false;
1480 eqos->reg_access_ok = false;
1481
1482 /* Disable TX DMA */
1483 clrbits_le32(&eqos->dma_regs->ch0_tx_control,
1484 EQOS_DMA_CH0_TX_CONTROL_ST);
1485
1486 /* Wait for TX all packets to drain out of MTL */
1487 for (i = 0; i < 1000000; i++) {
1488 u32 val = readl(&eqos->mtl_regs->txq0_debug);
1489 u32 trcsts = (val >> EQOS_MTL_TXQ0_DEBUG_TRCSTS_SHIFT) &
1490 EQOS_MTL_TXQ0_DEBUG_TRCSTS_MASK;
1491 u32 txqsts = val & EQOS_MTL_TXQ0_DEBUG_TXQSTS;
1492 if ((trcsts != 1) && (!txqsts))
1493 break;
1494 }
1495
1496 /* Turn off MAC TX and RX */
1497 clrbits_le32(&eqos->mac_regs->configuration,
1498 EQOS_MAC_CONFIGURATION_TE | EQOS_MAC_CONFIGURATION_RE);
1499
1500 /* Wait for all RX packets to drain out of MTL */
1501 for (i = 0; i < 1000000; i++) {
1502 u32 val = readl(&eqos->mtl_regs->rxq0_debug);
1503 u32 prxq = (val >> EQOS_MTL_RXQ0_DEBUG_PRXQ_SHIFT) &
1504 EQOS_MTL_RXQ0_DEBUG_PRXQ_MASK;
1505 u32 rxqsts = (val >> EQOS_MTL_RXQ0_DEBUG_RXQSTS_SHIFT) &
1506 EQOS_MTL_RXQ0_DEBUG_RXQSTS_MASK;
1507 if ((!prxq) && (!rxqsts))
1508 break;
1509 }
1510
1511 /* Turn off RX DMA */
1512 clrbits_le32(&eqos->dma_regs->ch0_rx_control,
1513 EQOS_DMA_CH0_RX_CONTROL_SR);
1514
1515 if (eqos->phy) {
1516 phy_shutdown(eqos->phy);
Stephen Warren50709602016-10-21 14:46:47 -06001517 }
Christophe Roullier6beb7802019-05-17 15:08:44 +02001518 eqos->config->ops->eqos_stop_resets(dev);
1519 eqos->config->ops->eqos_stop_clks(dev);
Stephen Warren50709602016-10-21 14:46:47 -06001520
1521 debug("%s: OK\n", __func__);
1522}
1523
Patrick Delaunay6864a5992019-08-01 11:29:02 +02001524static int eqos_send(struct udevice *dev, void *packet, int length)
Stephen Warren50709602016-10-21 14:46:47 -06001525{
1526 struct eqos_priv *eqos = dev_get_priv(dev);
1527 struct eqos_desc *tx_desc;
1528 int i;
1529
1530 debug("%s(dev=%p, packet=%p, length=%d):\n", __func__, dev, packet,
1531 length);
1532
1533 memcpy(eqos->tx_dma_buf, packet, length);
Christophe Roullier6beb7802019-05-17 15:08:44 +02001534 eqos->config->ops->eqos_flush_buffer(eqos->tx_dma_buf, length);
Stephen Warren50709602016-10-21 14:46:47 -06001535
Marek Vasut89077732021-01-07 11:12:16 +01001536 tx_desc = eqos_get_desc(eqos, eqos->tx_desc_idx, false);
Stephen Warren50709602016-10-21 14:46:47 -06001537 eqos->tx_desc_idx++;
1538 eqos->tx_desc_idx %= EQOS_DESCRIPTORS_TX;
1539
1540 tx_desc->des0 = (ulong)eqos->tx_dma_buf;
1541 tx_desc->des1 = 0;
1542 tx_desc->des2 = length;
1543 /*
1544 * Make sure that if HW sees the _OWN write below, it will see all the
1545 * writes to the rest of the descriptor too.
1546 */
1547 mb();
1548 tx_desc->des3 = EQOS_DESC3_OWN | EQOS_DESC3_FD | EQOS_DESC3_LD | length;
Christophe Roullier6beb7802019-05-17 15:08:44 +02001549 eqos->config->ops->eqos_flush_desc(tx_desc);
Stephen Warren50709602016-10-21 14:46:47 -06001550
Marek Vasut89077732021-01-07 11:12:16 +01001551 writel((ulong)eqos_get_desc(eqos, eqos->tx_desc_idx, false),
Marek Vasutf4f1f4d2020-03-23 02:03:50 +01001552 &eqos->dma_regs->ch0_txdesc_tail_pointer);
Stephen Warren50709602016-10-21 14:46:47 -06001553
1554 for (i = 0; i < 1000000; i++) {
Christophe Roullier6beb7802019-05-17 15:08:44 +02001555 eqos->config->ops->eqos_inval_desc(tx_desc);
Stephen Warren50709602016-10-21 14:46:47 -06001556 if (!(readl(&tx_desc->des3) & EQOS_DESC3_OWN))
1557 return 0;
1558 udelay(1);
1559 }
1560
1561 debug("%s: TX timeout\n", __func__);
1562
1563 return -ETIMEDOUT;
1564}
1565
Patrick Delaunay6864a5992019-08-01 11:29:02 +02001566static int eqos_recv(struct udevice *dev, int flags, uchar **packetp)
Stephen Warren50709602016-10-21 14:46:47 -06001567{
1568 struct eqos_priv *eqos = dev_get_priv(dev);
1569 struct eqos_desc *rx_desc;
1570 int length;
1571
1572 debug("%s(dev=%p, flags=%x):\n", __func__, dev, flags);
1573
Marek Vasut89077732021-01-07 11:12:16 +01001574 rx_desc = eqos_get_desc(eqos, eqos->rx_desc_idx, true);
Marek Vasutc4db8442020-03-23 02:09:21 +01001575 eqos->config->ops->eqos_inval_desc(rx_desc);
Stephen Warren50709602016-10-21 14:46:47 -06001576 if (rx_desc->des3 & EQOS_DESC3_OWN) {
1577 debug("%s: RX packet not available\n", __func__);
1578 return -EAGAIN;
1579 }
1580
1581 *packetp = eqos->rx_dma_buf +
1582 (eqos->rx_desc_idx * EQOS_MAX_PACKET_SIZE);
1583 length = rx_desc->des3 & 0x7fff;
1584 debug("%s: *packetp=%p, length=%d\n", __func__, *packetp, length);
1585
Christophe Roullier6beb7802019-05-17 15:08:44 +02001586 eqos->config->ops->eqos_inval_buffer(*packetp, length);
Stephen Warren50709602016-10-21 14:46:47 -06001587
1588 return length;
1589}
1590
Patrick Delaunay6864a5992019-08-01 11:29:02 +02001591static int eqos_free_pkt(struct udevice *dev, uchar *packet, int length)
Stephen Warren50709602016-10-21 14:46:47 -06001592{
1593 struct eqos_priv *eqos = dev_get_priv(dev);
1594 uchar *packet_expected;
1595 struct eqos_desc *rx_desc;
1596
1597 debug("%s(packet=%p, length=%d)\n", __func__, packet, length);
1598
1599 packet_expected = eqos->rx_dma_buf +
1600 (eqos->rx_desc_idx * EQOS_MAX_PACKET_SIZE);
1601 if (packet != packet_expected) {
1602 debug("%s: Unexpected packet (expected %p)\n", __func__,
1603 packet_expected);
1604 return -EINVAL;
1605 }
1606
Fugang Duan37aae5f2020-05-03 22:41:17 +08001607 eqos->config->ops->eqos_inval_buffer(packet, length);
1608
Marek Vasut89077732021-01-07 11:12:16 +01001609 rx_desc = eqos_get_desc(eqos, eqos->rx_desc_idx, true);
Marek Vasute8e5c2b2020-03-23 02:09:55 +01001610
Marek Vasut091b6db2020-03-23 02:11:46 +01001611 rx_desc->des0 = 0;
1612 mb();
1613 eqos->config->ops->eqos_flush_desc(rx_desc);
Marek Vasute8e5c2b2020-03-23 02:09:55 +01001614 eqos->config->ops->eqos_inval_buffer(packet, length);
Stephen Warren50709602016-10-21 14:46:47 -06001615 rx_desc->des0 = (u32)(ulong)packet;
1616 rx_desc->des1 = 0;
1617 rx_desc->des2 = 0;
1618 /*
1619 * Make sure that if HW sees the _OWN write below, it will see all the
1620 * writes to the rest of the descriptor too.
1621 */
1622 mb();
Marek Vasutd54c98e2020-03-23 02:02:57 +01001623 rx_desc->des3 = EQOS_DESC3_OWN | EQOS_DESC3_BUF1V;
Christophe Roullier6beb7802019-05-17 15:08:44 +02001624 eqos->config->ops->eqos_flush_desc(rx_desc);
Stephen Warren50709602016-10-21 14:46:47 -06001625
1626 writel((ulong)rx_desc, &eqos->dma_regs->ch0_rxdesc_tail_pointer);
1627
1628 eqos->rx_desc_idx++;
1629 eqos->rx_desc_idx %= EQOS_DESCRIPTORS_RX;
1630
1631 return 0;
1632}
1633
1634static int eqos_probe_resources_core(struct udevice *dev)
1635{
1636 struct eqos_priv *eqos = dev_get_priv(dev);
1637 int ret;
1638
1639 debug("%s(dev=%p):\n", __func__, dev);
1640
Marek Vasut89077732021-01-07 11:12:16 +01001641 eqos->descs = eqos_alloc_descs(eqos, EQOS_DESCRIPTORS_NUM);
Stephen Warren50709602016-10-21 14:46:47 -06001642 if (!eqos->descs) {
1643 debug("%s: eqos_alloc_descs() failed\n", __func__);
1644 ret = -ENOMEM;
1645 goto err;
1646 }
Stephen Warren50709602016-10-21 14:46:47 -06001647
1648 eqos->tx_dma_buf = memalign(EQOS_BUFFER_ALIGN, EQOS_MAX_PACKET_SIZE);
1649 if (!eqos->tx_dma_buf) {
1650 debug("%s: memalign(tx_dma_buf) failed\n", __func__);
1651 ret = -ENOMEM;
1652 goto err_free_descs;
1653 }
Christophe Roullier6beb7802019-05-17 15:08:44 +02001654 debug("%s: tx_dma_buf=%p\n", __func__, eqos->tx_dma_buf);
Stephen Warren50709602016-10-21 14:46:47 -06001655
1656 eqos->rx_dma_buf = memalign(EQOS_BUFFER_ALIGN, EQOS_RX_BUFFER_SIZE);
1657 if (!eqos->rx_dma_buf) {
1658 debug("%s: memalign(rx_dma_buf) failed\n", __func__);
1659 ret = -ENOMEM;
1660 goto err_free_tx_dma_buf;
1661 }
Christophe Roullier6beb7802019-05-17 15:08:44 +02001662 debug("%s: rx_dma_buf=%p\n", __func__, eqos->rx_dma_buf);
Stephen Warren50709602016-10-21 14:46:47 -06001663
1664 eqos->rx_pkt = malloc(EQOS_MAX_PACKET_SIZE);
1665 if (!eqos->rx_pkt) {
1666 debug("%s: malloc(rx_pkt) failed\n", __func__);
1667 ret = -ENOMEM;
1668 goto err_free_rx_dma_buf;
1669 }
1670 debug("%s: rx_pkt=%p\n", __func__, eqos->rx_pkt);
1671
Marek Vasute8e5c2b2020-03-23 02:09:55 +01001672 eqos->config->ops->eqos_inval_buffer(eqos->rx_dma_buf,
1673 EQOS_MAX_PACKET_SIZE * EQOS_DESCRIPTORS_RX);
1674
Stephen Warren50709602016-10-21 14:46:47 -06001675 debug("%s: OK\n", __func__);
1676 return 0;
1677
1678err_free_rx_dma_buf:
1679 free(eqos->rx_dma_buf);
1680err_free_tx_dma_buf:
1681 free(eqos->tx_dma_buf);
1682err_free_descs:
1683 eqos_free_descs(eqos->descs);
1684err:
1685
1686 debug("%s: returns %d\n", __func__, ret);
1687 return ret;
1688}
1689
1690static int eqos_remove_resources_core(struct udevice *dev)
1691{
1692 struct eqos_priv *eqos = dev_get_priv(dev);
1693
1694 debug("%s(dev=%p):\n", __func__, dev);
1695
1696 free(eqos->rx_pkt);
1697 free(eqos->rx_dma_buf);
1698 free(eqos->tx_dma_buf);
1699 eqos_free_descs(eqos->descs);
1700
1701 debug("%s: OK\n", __func__);
1702 return 0;
1703}
1704
1705static int eqos_probe_resources_tegra186(struct udevice *dev)
1706{
1707 struct eqos_priv *eqos = dev_get_priv(dev);
1708 int ret;
1709
1710 debug("%s(dev=%p):\n", __func__, dev);
1711
1712 ret = reset_get_by_name(dev, "eqos", &eqos->reset_ctl);
1713 if (ret) {
Masahiro Yamada81e10422017-09-16 14:10:41 +09001714 pr_err("reset_get_by_name(rst) failed: %d", ret);
Stephen Warren50709602016-10-21 14:46:47 -06001715 return ret;
1716 }
1717
1718 ret = gpio_request_by_name(dev, "phy-reset-gpios", 0,
1719 &eqos->phy_reset_gpio,
1720 GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
1721 if (ret) {
Masahiro Yamada81e10422017-09-16 14:10:41 +09001722 pr_err("gpio_request_by_name(phy reset) failed: %d", ret);
Stephen Warren50709602016-10-21 14:46:47 -06001723 goto err_free_reset_eqos;
1724 }
1725
1726 ret = clk_get_by_name(dev, "slave_bus", &eqos->clk_slave_bus);
1727 if (ret) {
Masahiro Yamada81e10422017-09-16 14:10:41 +09001728 pr_err("clk_get_by_name(slave_bus) failed: %d", ret);
Stephen Warren50709602016-10-21 14:46:47 -06001729 goto err_free_gpio_phy_reset;
1730 }
1731
1732 ret = clk_get_by_name(dev, "master_bus", &eqos->clk_master_bus);
1733 if (ret) {
Masahiro Yamada81e10422017-09-16 14:10:41 +09001734 pr_err("clk_get_by_name(master_bus) failed: %d", ret);
Stephen Warren50709602016-10-21 14:46:47 -06001735 goto err_free_clk_slave_bus;
1736 }
1737
1738 ret = clk_get_by_name(dev, "rx", &eqos->clk_rx);
1739 if (ret) {
Masahiro Yamada81e10422017-09-16 14:10:41 +09001740 pr_err("clk_get_by_name(rx) failed: %d", ret);
Stephen Warren50709602016-10-21 14:46:47 -06001741 goto err_free_clk_master_bus;
1742 }
1743
1744 ret = clk_get_by_name(dev, "ptp_ref", &eqos->clk_ptp_ref);
1745 if (ret) {
Masahiro Yamada81e10422017-09-16 14:10:41 +09001746 pr_err("clk_get_by_name(ptp_ref) failed: %d", ret);
Stephen Warren50709602016-10-21 14:46:47 -06001747 goto err_free_clk_rx;
1748 return ret;
1749 }
1750
1751 ret = clk_get_by_name(dev, "tx", &eqos->clk_tx);
1752 if (ret) {
Masahiro Yamada81e10422017-09-16 14:10:41 +09001753 pr_err("clk_get_by_name(tx) failed: %d", ret);
Stephen Warren50709602016-10-21 14:46:47 -06001754 goto err_free_clk_ptp_ref;
1755 }
1756
1757 debug("%s: OK\n", __func__);
1758 return 0;
1759
1760err_free_clk_ptp_ref:
1761 clk_free(&eqos->clk_ptp_ref);
1762err_free_clk_rx:
1763 clk_free(&eqos->clk_rx);
1764err_free_clk_master_bus:
1765 clk_free(&eqos->clk_master_bus);
1766err_free_clk_slave_bus:
1767 clk_free(&eqos->clk_slave_bus);
1768err_free_gpio_phy_reset:
1769 dm_gpio_free(dev, &eqos->phy_reset_gpio);
1770err_free_reset_eqos:
1771 reset_free(&eqos->reset_ctl);
1772
1773 debug("%s: returns %d\n", __func__, ret);
1774 return ret;
1775}
1776
Christophe Roullier6beb7802019-05-17 15:08:44 +02001777/* board-specific Ethernet Interface initializations. */
Patrick Delaunaybff66f92019-08-01 11:29:03 +02001778__weak int board_interface_eth_init(struct udevice *dev,
1779 phy_interface_t interface_type)
Christophe Roullier6beb7802019-05-17 15:08:44 +02001780{
1781 return 0;
1782}
1783
1784static int eqos_probe_resources_stm32(struct udevice *dev)
1785{
1786 struct eqos_priv *eqos = dev_get_priv(dev);
1787 int ret;
1788 phy_interface_t interface;
Christophe Roullier104dab52020-03-18 10:50:15 +01001789 struct ofnode_phandle_args phandle_args;
Christophe Roullier6beb7802019-05-17 15:08:44 +02001790
1791 debug("%s(dev=%p):\n", __func__, dev);
1792
1793 interface = eqos->config->interface(dev);
1794
1795 if (interface == PHY_INTERFACE_MODE_NONE) {
1796 pr_err("Invalid PHY interface\n");
1797 return -EINVAL;
1798 }
1799
Patrick Delaunaybff66f92019-08-01 11:29:03 +02001800 ret = board_interface_eth_init(dev, interface);
Christophe Roullier6beb7802019-05-17 15:08:44 +02001801 if (ret)
1802 return -EINVAL;
1803
Patrick Delaunay5c8db372020-03-18 10:50:16 +01001804 eqos->max_speed = dev_read_u32_default(dev, "max-speed", 0);
1805
Christophe Roullier6beb7802019-05-17 15:08:44 +02001806 ret = clk_get_by_name(dev, "stmmaceth", &eqos->clk_master_bus);
1807 if (ret) {
1808 pr_err("clk_get_by_name(master_bus) failed: %d", ret);
1809 goto err_probe;
1810 }
1811
1812 ret = clk_get_by_name(dev, "mac-clk-rx", &eqos->clk_rx);
1813 if (ret) {
1814 pr_err("clk_get_by_name(rx) failed: %d", ret);
1815 goto err_free_clk_master_bus;
1816 }
1817
1818 ret = clk_get_by_name(dev, "mac-clk-tx", &eqos->clk_tx);
1819 if (ret) {
1820 pr_err("clk_get_by_name(tx) failed: %d", ret);
1821 goto err_free_clk_rx;
1822 }
1823
1824 /* Get ETH_CLK clocks (optional) */
1825 ret = clk_get_by_name(dev, "eth-ck", &eqos->clk_ck);
1826 if (ret)
1827 pr_warn("No phy clock provided %d", ret);
1828
Patrick Delaunay5c8db372020-03-18 10:50:16 +01001829 eqos->phyaddr = -1;
Christophe Roullier104dab52020-03-18 10:50:15 +01001830 ret = dev_read_phandle_with_args(dev, "phy-handle", NULL, 0, 0,
1831 &phandle_args);
1832 if (!ret) {
1833 /* search "reset-gpios" in phy node */
1834 ret = gpio_request_by_name_nodev(phandle_args.node,
1835 "reset-gpios", 0,
1836 &eqos->phy_reset_gpio,
1837 GPIOD_IS_OUT |
1838 GPIOD_IS_OUT_ACTIVE);
1839 if (ret)
1840 pr_warn("gpio_request_by_name(phy reset) not provided %d",
1841 ret);
Patrick Delaunay5c8db372020-03-18 10:50:16 +01001842
1843 eqos->phyaddr = ofnode_read_u32_default(phandle_args.node,
1844 "reg", -1);
Christophe Roullier104dab52020-03-18 10:50:15 +01001845 }
1846
Christophe Roullier6beb7802019-05-17 15:08:44 +02001847 debug("%s: OK\n", __func__);
1848 return 0;
1849
1850err_free_clk_rx:
1851 clk_free(&eqos->clk_rx);
1852err_free_clk_master_bus:
1853 clk_free(&eqos->clk_master_bus);
1854err_probe:
1855
1856 debug("%s: returns %d\n", __func__, ret);
1857 return ret;
1858}
1859
1860static phy_interface_t eqos_get_interface_stm32(struct udevice *dev)
1861{
1862 const char *phy_mode;
1863 phy_interface_t interface = PHY_INTERFACE_MODE_NONE;
1864
1865 debug("%s(dev=%p):\n", __func__, dev);
1866
Patrick Delaunay9e6ed382020-09-09 18:30:06 +02001867 phy_mode = dev_read_prop(dev, "phy-mode", NULL);
Christophe Roullier6beb7802019-05-17 15:08:44 +02001868 if (phy_mode)
1869 interface = phy_get_interface_by_name(phy_mode);
1870
1871 return interface;
1872}
1873
1874static phy_interface_t eqos_get_interface_tegra186(struct udevice *dev)
1875{
1876 return PHY_INTERFACE_MODE_MII;
1877}
1878
Fugang Duan37aae5f2020-05-03 22:41:17 +08001879static int eqos_probe_resources_imx(struct udevice *dev)
1880{
1881 struct eqos_priv *eqos = dev_get_priv(dev);
1882 phy_interface_t interface;
1883
1884 debug("%s(dev=%p):\n", __func__, dev);
1885
1886 interface = eqos->config->interface(dev);
1887
1888 if (interface == PHY_INTERFACE_MODE_NONE) {
1889 pr_err("Invalid PHY interface\n");
1890 return -EINVAL;
1891 }
1892
1893 debug("%s: OK\n", __func__);
1894 return 0;
1895}
1896
1897static phy_interface_t eqos_get_interface_imx(struct udevice *dev)
1898{
Fugang Duandd455e62020-05-03 22:41:18 +08001899 const char *phy_mode;
1900 phy_interface_t interface = PHY_INTERFACE_MODE_NONE;
1901
1902 debug("%s(dev=%p):\n", __func__, dev);
1903
Patrick Delaunay9e6ed382020-09-09 18:30:06 +02001904 phy_mode = dev_read_prop(dev, "phy-mode", NULL);
Fugang Duandd455e62020-05-03 22:41:18 +08001905 if (phy_mode)
1906 interface = phy_get_interface_by_name(phy_mode);
1907
1908 return interface;
Fugang Duan37aae5f2020-05-03 22:41:17 +08001909}
1910
Stephen Warren50709602016-10-21 14:46:47 -06001911static int eqos_remove_resources_tegra186(struct udevice *dev)
1912{
1913 struct eqos_priv *eqos = dev_get_priv(dev);
1914
1915 debug("%s(dev=%p):\n", __func__, dev);
1916
Fugang Duan37aae5f2020-05-03 22:41:17 +08001917#ifdef CONFIG_CLK
Stephen Warren50709602016-10-21 14:46:47 -06001918 clk_free(&eqos->clk_tx);
1919 clk_free(&eqos->clk_ptp_ref);
1920 clk_free(&eqos->clk_rx);
1921 clk_free(&eqos->clk_slave_bus);
1922 clk_free(&eqos->clk_master_bus);
Fugang Duan37aae5f2020-05-03 22:41:17 +08001923#endif
Stephen Warren50709602016-10-21 14:46:47 -06001924 dm_gpio_free(dev, &eqos->phy_reset_gpio);
1925 reset_free(&eqos->reset_ctl);
1926
1927 debug("%s: OK\n", __func__);
1928 return 0;
1929}
1930
Christophe Roullier6beb7802019-05-17 15:08:44 +02001931static int eqos_remove_resources_stm32(struct udevice *dev)
1932{
Fugang Duan37aae5f2020-05-03 22:41:17 +08001933#ifdef CONFIG_CLK
Christophe Roullier6beb7802019-05-17 15:08:44 +02001934 struct eqos_priv *eqos = dev_get_priv(dev);
1935
1936 debug("%s(dev=%p):\n", __func__, dev);
1937
1938 clk_free(&eqos->clk_tx);
1939 clk_free(&eqos->clk_rx);
1940 clk_free(&eqos->clk_master_bus);
1941 if (clk_valid(&eqos->clk_ck))
1942 clk_free(&eqos->clk_ck);
Fugang Duan37aae5f2020-05-03 22:41:17 +08001943#endif
Christophe Roullier6beb7802019-05-17 15:08:44 +02001944
Christophe Roullier104dab52020-03-18 10:50:15 +01001945 if (dm_gpio_is_valid(&eqos->phy_reset_gpio))
1946 dm_gpio_free(dev, &eqos->phy_reset_gpio);
1947
Christophe Roullier6beb7802019-05-17 15:08:44 +02001948 debug("%s: OK\n", __func__);
1949 return 0;
1950}
1951
Fugang Duan37aae5f2020-05-03 22:41:17 +08001952static int eqos_remove_resources_imx(struct udevice *dev)
1953{
1954 return 0;
1955}
1956
Stephen Warren50709602016-10-21 14:46:47 -06001957static int eqos_probe(struct udevice *dev)
1958{
1959 struct eqos_priv *eqos = dev_get_priv(dev);
1960 int ret;
1961
1962 debug("%s(dev=%p):\n", __func__, dev);
1963
1964 eqos->dev = dev;
1965 eqos->config = (void *)dev_get_driver_data(dev);
1966
Masahiro Yamadaa89b4de2020-07-17 14:36:48 +09001967 eqos->regs = dev_read_addr(dev);
Stephen Warren50709602016-10-21 14:46:47 -06001968 if (eqos->regs == FDT_ADDR_T_NONE) {
Masahiro Yamadaa89b4de2020-07-17 14:36:48 +09001969 pr_err("dev_read_addr() failed");
Stephen Warren50709602016-10-21 14:46:47 -06001970 return -ENODEV;
1971 }
1972 eqos->mac_regs = (void *)(eqos->regs + EQOS_MAC_REGS_BASE);
1973 eqos->mtl_regs = (void *)(eqos->regs + EQOS_MTL_REGS_BASE);
1974 eqos->dma_regs = (void *)(eqos->regs + EQOS_DMA_REGS_BASE);
1975 eqos->tegra186_regs = (void *)(eqos->regs + EQOS_TEGRA186_REGS_BASE);
1976
1977 ret = eqos_probe_resources_core(dev);
1978 if (ret < 0) {
Masahiro Yamada81e10422017-09-16 14:10:41 +09001979 pr_err("eqos_probe_resources_core() failed: %d", ret);
Stephen Warren50709602016-10-21 14:46:47 -06001980 return ret;
1981 }
1982
Christophe Roullier6beb7802019-05-17 15:08:44 +02001983 ret = eqos->config->ops->eqos_probe_resources(dev);
Stephen Warren50709602016-10-21 14:46:47 -06001984 if (ret < 0) {
Christophe Roullier6beb7802019-05-17 15:08:44 +02001985 pr_err("eqos_probe_resources() failed: %d", ret);
Stephen Warren50709602016-10-21 14:46:47 -06001986 goto err_remove_resources_core;
1987 }
1988
Ye Liad122b72020-05-03 22:41:15 +08001989#ifdef CONFIG_DM_ETH_PHY
1990 eqos->mii = eth_phy_get_mdio_bus(dev);
1991#endif
Stephen Warren50709602016-10-21 14:46:47 -06001992 if (!eqos->mii) {
Ye Liad122b72020-05-03 22:41:15 +08001993 eqos->mii = mdio_alloc();
1994 if (!eqos->mii) {
1995 pr_err("mdio_alloc() failed");
1996 ret = -ENOMEM;
1997 goto err_remove_resources_tegra;
1998 }
1999 eqos->mii->read = eqos_mdio_read;
2000 eqos->mii->write = eqos_mdio_write;
2001 eqos->mii->priv = eqos;
2002 strcpy(eqos->mii->name, dev->name);
Stephen Warren50709602016-10-21 14:46:47 -06002003
Ye Liad122b72020-05-03 22:41:15 +08002004 ret = mdio_register(eqos->mii);
2005 if (ret < 0) {
2006 pr_err("mdio_register() failed: %d", ret);
2007 goto err_free_mdio;
2008 }
Stephen Warren50709602016-10-21 14:46:47 -06002009 }
2010
Ye Liad122b72020-05-03 22:41:15 +08002011#ifdef CONFIG_DM_ETH_PHY
2012 eth_phy_set_mdio_bus(dev, eqos->mii);
2013#endif
2014
Stephen Warren50709602016-10-21 14:46:47 -06002015 debug("%s: OK\n", __func__);
2016 return 0;
2017
2018err_free_mdio:
2019 mdio_free(eqos->mii);
2020err_remove_resources_tegra:
Christophe Roullier6beb7802019-05-17 15:08:44 +02002021 eqos->config->ops->eqos_remove_resources(dev);
Stephen Warren50709602016-10-21 14:46:47 -06002022err_remove_resources_core:
2023 eqos_remove_resources_core(dev);
2024
2025 debug("%s: returns %d\n", __func__, ret);
2026 return ret;
2027}
2028
2029static int eqos_remove(struct udevice *dev)
2030{
2031 struct eqos_priv *eqos = dev_get_priv(dev);
2032
2033 debug("%s(dev=%p):\n", __func__, dev);
2034
2035 mdio_unregister(eqos->mii);
2036 mdio_free(eqos->mii);
Christophe Roullier6beb7802019-05-17 15:08:44 +02002037 eqos->config->ops->eqos_remove_resources(dev);
2038
Stephen Warren50709602016-10-21 14:46:47 -06002039 eqos_probe_resources_core(dev);
2040
2041 debug("%s: OK\n", __func__);
2042 return 0;
2043}
2044
2045static const struct eth_ops eqos_ops = {
2046 .start = eqos_start,
2047 .stop = eqos_stop,
2048 .send = eqos_send,
2049 .recv = eqos_recv,
2050 .free_pkt = eqos_free_pkt,
2051 .write_hwaddr = eqos_write_hwaddr,
Ye Li3fb1a0e2020-05-03 22:41:20 +08002052 .read_rom_hwaddr = eqos_read_rom_hwaddr,
Stephen Warren50709602016-10-21 14:46:47 -06002053};
2054
Christophe Roullier6beb7802019-05-17 15:08:44 +02002055static struct eqos_ops eqos_tegra186_ops = {
Marek Vasut89077732021-01-07 11:12:16 +01002056 .eqos_inval_desc = eqos_inval_desc_generic,
2057 .eqos_flush_desc = eqos_flush_desc_generic,
Christophe Roullier6beb7802019-05-17 15:08:44 +02002058 .eqos_inval_buffer = eqos_inval_buffer_tegra186,
2059 .eqos_flush_buffer = eqos_flush_buffer_tegra186,
2060 .eqos_probe_resources = eqos_probe_resources_tegra186,
2061 .eqos_remove_resources = eqos_remove_resources_tegra186,
2062 .eqos_stop_resets = eqos_stop_resets_tegra186,
2063 .eqos_start_resets = eqos_start_resets_tegra186,
2064 .eqos_stop_clks = eqos_stop_clks_tegra186,
2065 .eqos_start_clks = eqos_start_clks_tegra186,
2066 .eqos_calibrate_pads = eqos_calibrate_pads_tegra186,
2067 .eqos_disable_calibration = eqos_disable_calibration_tegra186,
2068 .eqos_set_tx_clk_speed = eqos_set_tx_clk_speed_tegra186,
2069 .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_tegra186
2070};
2071
Patrick Delaunay68083902020-06-08 11:27:19 +02002072static const struct eqos_config __maybe_unused eqos_tegra186_config = {
Stephen Warren50709602016-10-21 14:46:47 -06002073 .reg_access_always_ok = false,
Christophe Roullier6beb7802019-05-17 15:08:44 +02002074 .mdio_wait = 10,
2075 .swr_wait = 10,
2076 .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB,
2077 .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_20_35,
Marek Vasut89077732021-01-07 11:12:16 +01002078 .axi_bus_width = EQOS_AXI_WIDTH_128,
Christophe Roullier6beb7802019-05-17 15:08:44 +02002079 .interface = eqos_get_interface_tegra186,
2080 .ops = &eqos_tegra186_ops
2081};
2082
2083static struct eqos_ops eqos_stm32_ops = {
Fugang Duan37aae5f2020-05-03 22:41:17 +08002084 .eqos_inval_desc = eqos_inval_desc_generic,
2085 .eqos_flush_desc = eqos_flush_desc_generic,
2086 .eqos_inval_buffer = eqos_inval_buffer_generic,
2087 .eqos_flush_buffer = eqos_flush_buffer_generic,
Christophe Roullier6beb7802019-05-17 15:08:44 +02002088 .eqos_probe_resources = eqos_probe_resources_stm32,
2089 .eqos_remove_resources = eqos_remove_resources_stm32,
2090 .eqos_stop_resets = eqos_stop_resets_stm32,
2091 .eqos_start_resets = eqos_start_resets_stm32,
2092 .eqos_stop_clks = eqos_stop_clks_stm32,
2093 .eqos_start_clks = eqos_start_clks_stm32,
2094 .eqos_calibrate_pads = eqos_calibrate_pads_stm32,
2095 .eqos_disable_calibration = eqos_disable_calibration_stm32,
2096 .eqos_set_tx_clk_speed = eqos_set_tx_clk_speed_stm32,
2097 .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_stm32
2098};
2099
Patrick Delaunay68083902020-06-08 11:27:19 +02002100static const struct eqos_config __maybe_unused eqos_stm32_config = {
Christophe Roullier6beb7802019-05-17 15:08:44 +02002101 .reg_access_always_ok = false,
2102 .mdio_wait = 10000,
2103 .swr_wait = 50,
2104 .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_AV,
2105 .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_250_300,
Marek Vasut89077732021-01-07 11:12:16 +01002106 .axi_bus_width = EQOS_AXI_WIDTH_64,
Christophe Roullier6beb7802019-05-17 15:08:44 +02002107 .interface = eqos_get_interface_stm32,
2108 .ops = &eqos_stm32_ops
Stephen Warren50709602016-10-21 14:46:47 -06002109};
2110
Fugang Duan37aae5f2020-05-03 22:41:17 +08002111static struct eqos_ops eqos_imx_ops = {
2112 .eqos_inval_desc = eqos_inval_desc_generic,
2113 .eqos_flush_desc = eqos_flush_desc_generic,
2114 .eqos_inval_buffer = eqos_inval_buffer_generic,
2115 .eqos_flush_buffer = eqos_flush_buffer_generic,
2116 .eqos_probe_resources = eqos_probe_resources_imx,
2117 .eqos_remove_resources = eqos_remove_resources_imx,
2118 .eqos_stop_resets = eqos_stop_resets_imx,
2119 .eqos_start_resets = eqos_start_resets_imx,
2120 .eqos_stop_clks = eqos_stop_clks_imx,
2121 .eqos_start_clks = eqos_start_clks_imx,
2122 .eqos_calibrate_pads = eqos_calibrate_pads_imx,
2123 .eqos_disable_calibration = eqos_disable_calibration_imx,
2124 .eqos_set_tx_clk_speed = eqos_set_tx_clk_speed_imx,
2125 .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_imx
2126};
2127
Patrick Delaunay68083902020-06-08 11:27:19 +02002128struct eqos_config __maybe_unused eqos_imx_config = {
Fugang Duan37aae5f2020-05-03 22:41:17 +08002129 .reg_access_always_ok = false,
2130 .mdio_wait = 10000,
2131 .swr_wait = 50,
2132 .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB,
2133 .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_250_300,
Marek Vasut89077732021-01-07 11:12:16 +01002134 .axi_bus_width = EQOS_AXI_WIDTH_64,
Fugang Duan37aae5f2020-05-03 22:41:17 +08002135 .interface = eqos_get_interface_imx,
2136 .ops = &eqos_imx_ops
2137};
2138
Stephen Warren50709602016-10-21 14:46:47 -06002139static const struct udevice_id eqos_ids[] = {
Patrick Delaunay68083902020-06-08 11:27:19 +02002140#if IS_ENABLED(CONFIG_DWC_ETH_QOS_TEGRA186)
Stephen Warren50709602016-10-21 14:46:47 -06002141 {
2142 .compatible = "nvidia,tegra186-eqos",
2143 .data = (ulong)&eqos_tegra186_config
2144 },
Patrick Delaunay68083902020-06-08 11:27:19 +02002145#endif
2146#if IS_ENABLED(CONFIG_DWC_ETH_QOS_STM32)
Christophe Roullier6beb7802019-05-17 15:08:44 +02002147 {
Patrick Delaunaya0466f62020-05-14 15:00:23 +02002148 .compatible = "st,stm32mp1-dwmac",
Christophe Roullier6beb7802019-05-17 15:08:44 +02002149 .data = (ulong)&eqos_stm32_config
2150 },
Patrick Delaunay68083902020-06-08 11:27:19 +02002151#endif
2152#if IS_ENABLED(CONFIG_DWC_ETH_QOS_IMX)
Fugang Duan37aae5f2020-05-03 22:41:17 +08002153 {
2154 .compatible = "fsl,imx-eqos",
2155 .data = (ulong)&eqos_imx_config
2156 },
Patrick Delaunay68083902020-06-08 11:27:19 +02002157#endif
Christophe Roullier6beb7802019-05-17 15:08:44 +02002158
Stephen Warren50709602016-10-21 14:46:47 -06002159 { }
2160};
2161
2162U_BOOT_DRIVER(eth_eqos) = {
2163 .name = "eth_eqos",
2164 .id = UCLASS_ETH,
Fugang Duan37aae5f2020-05-03 22:41:17 +08002165 .of_match = of_match_ptr(eqos_ids),
Stephen Warren50709602016-10-21 14:46:47 -06002166 .probe = eqos_probe,
2167 .remove = eqos_remove,
2168 .ops = &eqos_ops,
Simon Glass8a2b47f2020-12-03 16:55:17 -07002169 .priv_auto = sizeof(struct eqos_priv),
Simon Glass71fa5b42020-12-03 16:55:18 -07002170 .plat_auto = sizeof(struct eth_pdata),
Stephen Warren50709602016-10-21 14:46:47 -06002171};