1 /*
2  * Driver for Synopsys DesignWare MAC
3  *
4  * Copyright (c) 2021 BayLibre SAS
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 
10 #define LOG_MODULE_NAME dwmac_plat
11 #define LOG_LEVEL CONFIG_ETHERNET_LOG_LEVEL
12 #include <zephyr/logging/log.h>
13 LOG_MODULE_REGISTER(LOG_MODULE_NAME);
14 
15 #define DT_DRV_COMPAT snps_designware_ethernet
16 
17 #include <sys/types.h>
18 #include <zephyr/kernel/mm.h>
19 #include <zephyr/kernel.h>
20 #include <zephyr/cache.h>
21 #include <zephyr/net/ethernet.h>
22 #include <zephyr/irq.h>
23 
24 #include "eth_dwmac_priv.h"
25 
dwmac_bus_init(struct dwmac_priv * p)26 int dwmac_bus_init(struct dwmac_priv *p)
27 {
28 	p->base_addr = DT_INST_REG_ADDR(0);
29 	return 0;
30 }
31 
32 #if (CONFIG_DCACHE_LINE_SIZE+0 == 0)
33 #error "CONFIG_DCACHE_LINE_SIZE must be configured to a non-zero value"
34 #endif
35 
36 static struct dwmac_dma_desc __aligned(CONFIG_DCACHE_LINE_SIZE)
37 			dwmac_tx_rx_descriptors[NB_TX_DESCS + NB_RX_DESCS];
38 
39 static const uint8_t dwmac_mac_addr[6] = DT_INST_PROP(0, local_mac_address);
40 
dwmac_platform_init(struct dwmac_priv * p)41 void dwmac_platform_init(struct dwmac_priv *p)
42 {
43 	uint8_t *desc_uncached_addr;
44 	uintptr_t desc_phys_addr;
45 
46 	/* make sure no valid cache lines map to the descriptor area */
47 	sys_cache_data_invd_range(dwmac_tx_rx_descriptors,
48 				  sizeof(dwmac_tx_rx_descriptors));
49 
50 	desc_phys_addr = k_mem_phys_addr(dwmac_tx_rx_descriptors);
51 
52 	/* remap descriptor rings uncached */
53 	k_mem_map_phys_bare(&desc_uncached_addr, desc_phys_addr,
54 			    sizeof(dwmac_tx_rx_descriptors),
55 			    K_MEM_PERM_RW | K_MEM_CACHE_NONE);
56 
57 	LOG_DBG("desc virt %p uncached %p phys 0x%lx",
58 		dwmac_tx_rx_descriptors, desc_uncached_addr, desc_phys_addr);
59 
60 	p->tx_descs = (void *)desc_uncached_addr;
61 	desc_uncached_addr += NB_TX_DESCS * sizeof(struct dwmac_dma_desc);
62 	p->rx_descs = (void *)desc_uncached_addr;
63 
64 	p->tx_descs_phys = desc_phys_addr;
65 	desc_phys_addr += NB_TX_DESCS * sizeof(struct dwmac_dma_desc);
66 	p->rx_descs_phys = desc_phys_addr;
67 
68 	/* basic configuration for this platform */
69 	REG_WRITE(MAC_CONF,
70 		  MAC_CONF_PS |
71 		  MAC_CONF_FES |
72 		  MAC_CONF_DM);
73 	REG_WRITE(DMA_SYSBUS_MODE,
74 		  DMA_SYSBUS_MODE_AAL |
75 #ifdef CONFIG_64BIT
76 		  DMA_SYSBUS_MODE_EAME |
77 #endif
78 		  DMA_SYSBUS_MODE_FB);
79 
80 	/* set up IRQs (still masked for now) */
81 	IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), dwmac_isr,
82 		    DEVICE_DT_INST_GET(0), 0);
83 	irq_enable(DT_INST_IRQN(0));
84 
85 	/* retrieve MAC address */
86 	memcpy(p->mac_addr, dwmac_mac_addr, sizeof(p->mac_addr));
87 }
88 
89 /* Our private device instance */
90 static struct dwmac_priv dwmac_instance;
91 
92 ETH_NET_DEVICE_DT_INST_DEFINE(0,
93 			      dwmac_probe,
94 			      NULL,
95 			      &dwmac_instance,
96 			      NULL,
97 			      CONFIG_ETH_INIT_PRIORITY,
98 			      &dwmac_api,
99 			      NET_ETH_MTU);
100