Skip to content

Commit 368ed20

Browse files
committed
drivers: ethernet: stm32: add support of the stm32mp13
Add the support of the stm32mp13 ethernet: - Adapt to HAL API - Add support of a memory region in DT for descriptor and buffers - Add support of PHY with/without crystal 50MHz Signed-off-by: Arnaud Pouliquen <[email protected]> Signed-off-by: Arif Balik <[email protected]>
1 parent ef45ea2 commit 368ed20

File tree

3 files changed

+80
-3
lines changed

3 files changed

+80
-3
lines changed

drivers/ethernet/Kconfig.stm32_hal

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ choice ETH_STM32_HAL_API_VERSION
2626

2727
config ETH_STM32_HAL_API_V2
2828
bool "Use official STM32Cube HAL driver"
29-
depends on SOC_SERIES_STM32H7X || SOC_SERIES_STM32H5X || SOC_SERIES_STM32F4X || SOC_SERIES_STM32F7X || SOC_SERIES_STM32N6X
30-
select USE_STM32_HAL_ETH_EX if SOC_SERIES_STM32N6X
29+
depends on SOC_SERIES_STM32H7X || SOC_SERIES_STM32H5X || SOC_SERIES_STM32F4X || SOC_SERIES_STM32F7X || SOC_SERIES_STM32N6X || SOC_SERIES_STM32MP13X
30+
select USE_STM32_HAL_ETH_EX if SOC_SERIES_STM32N6X || SOC_SERIES_STM32MP13X
3131
help
3232
Use the official STM32Cube HAL driver instead of the legacy one.
3333

drivers/ethernet/eth_stm32_hal_priv.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,15 @@
3333
struct eth_stm32_hal_dev_cfg {
3434
void (*config_func)(void);
3535
struct stm32_pclken pclken;
36+
#if DT_INST_CLOCKS_HAS_NAME(0, mac_clk)
37+
struct stm32_pclken pclken_mac;
38+
#endif
39+
#if DT_INST_CLOCKS_HAS_NAME(0, eth_ker)
40+
struct stm32_pclken pclken_ker;
41+
#endif
42+
#if defined(CONFIG_SOC_SERIES_STM32MP13X)
43+
ETH_ClkSrcTypeDef clockselection;
44+
#endif /* CONFIG_SOC_SERIES_STM32MP13X */
3645
struct stm32_pclken pclken_rx;
3746
struct stm32_pclken pclken_tx;
3847
#if DT_INST_CLOCKS_HAS_NAME(0, mac_clk_ptp)

drivers/ethernet/eth_stm32_hal_v2.c

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
3333
#include <zephyr/irq.h>
3434
#include <zephyr/net/lldp.h>
3535
#include <zephyr/drivers/hwinfo.h>
36+
#include <zephyr/linker/devicetree_regions.h>
3637

3738
#if defined(CONFIG_NET_DSA_DEPRECATED)
3839
#include <zephyr/net/dsa.h>
@@ -100,6 +101,12 @@ static const struct device *eth_stm32_phy_dev = DEVICE_DT_GET(DT_INST_PHANDLE(0,
100101
#elif defined(CONFIG_SOC_SERIES_STM32H7X)
101102
#define __eth_stm32_desc __attribute__((section(".eth_stm32_desc")))
102103
#define __eth_stm32_buf __attribute__((section(".eth_stm32_buf")))
104+
#elif defined(CONFIG_SOC_SERIES_STM32MP13X)
105+
#define ETH_DMA_REGION DT_PHANDLE(DT_NODELABEL(mac), memory_regions)
106+
#define ETH_DMA_LINKER_REGION_NAME LINKER_DT_NODE_REGION_NAME(ETH_DMA_REGION)
107+
108+
#define __eth_stm32_desc ALIGN_32BYTES(__attribute__((__section__(ETH_DMA_LINKER_REGION_NAME))))
109+
#define __eth_stm32_buf ALIGN_32BYTES(__attribute__((__section__(ETH_DMA_LINKER_REGION_NAME))))
103110
#elif defined(CONFIG_NOCACHE_MEMORY)
104111
#define __eth_stm32_desc __nocache __aligned(4)
105112
#define __eth_stm32_buf __nocache __aligned(4)
@@ -144,7 +151,11 @@ static struct eth_stm32_rx_buffer_header dma_rx_buffer_header[ETH_RXBUFNB];
144151
static struct eth_stm32_tx_buffer_header dma_tx_buffer_header[ETH_TXBUFNB];
145152
static struct eth_stm32_tx_context dma_tx_context[ETH_TX_DESC_CNT];
146153

154+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32mp13_ethernet)
155+
void HAL_ETH_RxAllocateCallback(ETH_HandleTypeDef *heth, uint8_t **buf)
156+
#else
147157
void HAL_ETH_RxAllocateCallback(uint8_t **buf)
158+
#endif
148159
{
149160
for (size_t i = 0; i < ETH_RXBUFNB; ++i) {
150161
if (!dma_rx_buffer_header[i].used) {
@@ -162,7 +173,12 @@ void HAL_ETH_RxAllocateCallback(uint8_t **buf)
162173
typedef uint8_t (*RxBufferPtr)[ETH_STM32_RX_BUF_SIZE];
163174

164175
/* called by HAL_ETH_ReadData() */
176+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32mp13_ethernet)
177+
void HAL_ETH_RxLinkCallback(ETH_HandleTypeDef *heth, void **pStart, void **pEnd,
178+
uint8_t *buff, uint16_t Length)
179+
#else
165180
void HAL_ETH_RxLinkCallback(void **pStart, void **pEnd, uint8_t *buff, uint16_t Length)
181+
#endif
166182
{
167183
/* buff points to the begin on one of the rx buffers,
168184
* so we can compute the index of the given buffer
@@ -187,7 +203,11 @@ void HAL_ETH_RxLinkCallback(void **pStart, void **pEnd, uint8_t *buff, uint16_t
187203
}
188204

189205
/* Called by HAL_ETH_ReleaseTxPacket */
206+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32mp13_ethernet)
207+
void HAL_ETH_TxFreeCallback(ETH_HandleTypeDef *heth, uint32_t *buff)
208+
#else
190209
void HAL_ETH_TxFreeCallback(uint32_t *buff)
210+
#endif
191211
{
192212
__ASSERT_NO_MSG(buff != NULL);
193213

@@ -410,7 +430,11 @@ static int eth_tx(const struct device *dev, struct net_pkt *pkt)
410430
HAL_ETH_ReleaseTxPacket(heth);
411431
} else {
412432
/* We need to release the tx context and its buffers */
433+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32mp13_ethernet)
434+
HAL_ETH_TxFreeCallback(heth, (uint32_t *)ctx);
435+
#else
413436
HAL_ETH_TxFreeCallback((uint32_t *)ctx);
437+
#endif
414438
}
415439

416440
k_mutex_unlock(&dev_data->tx_mutex);
@@ -628,7 +652,10 @@ void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth)
628652
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */
629653
}
630654

631-
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet)
655+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32mp13_ethernet)
656+
dev_data->stats.error_details.rx_crc_errors = heth->Instance->MMCRXCRCEPR;
657+
dev_data->stats.error_details.rx_align_errors = heth->Instance->MMCRXAEPR;
658+
#elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet)
632659
dev_data->stats.error_details.rx_crc_errors = heth->Instance->MMCRCRCEPR;
633660
dev_data->stats.error_details.rx_align_errors = heth->Instance->MMCRAEPR;
634661
#else
@@ -714,25 +741,49 @@ static int eth_initialize(const struct device *dev)
714741
struct eth_stm32_hal_dev_data *dev_data = dev->data;
715742
const struct eth_stm32_hal_dev_cfg *cfg = dev->config;
716743
ETH_HandleTypeDef *heth = &dev_data->heth;
744+
__maybe_unused uint8_t *desc_uncached_addr;
717745
int ret = 0;
718746

719747
if (!device_is_ready(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE))) {
720748
LOG_ERR("clock control device not ready");
721749
return -ENODEV;
722750
}
723751

752+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32mp13_ethernet)
753+
/* Map memory region for DMA descriptor and buffer as non cacheable */
754+
k_mem_map_phys_bare(&desc_uncached_addr,
755+
DT_REG_ADDR(ETH_DMA_REGION),
756+
DT_REG_SIZE(ETH_DMA_REGION),
757+
K_MEM_PERM_RW | K_MEM_DIRECT_MAP | K_MEM_CACHE_NONE);
758+
#endif
759+
724760
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_ethernet)
725761
/* RISAF Configuration */
726762
RISAF_Config();
727763
#endif
728764

765+
#if DT_INST_CLOCKS_HAS_NAME(0, eth_ker)
766+
/* Turn on DCMIPP peripheral clock */
767+
ret = clock_control_configure(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE),
768+
(clock_control_subsys_t)&cfg->pclken_ker,
769+
NULL);
770+
if (ret < 0) {
771+
LOG_ERR("Failed to configure ETH kernel clock. Error %d", ret);
772+
return ret;
773+
}
774+
#endif
729775
/* enable clock */
730776
ret = clock_control_on(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE),
731777
(clock_control_subsys_t)&cfg->pclken);
732778
ret |= clock_control_on(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE),
733779
(clock_control_subsys_t)&cfg->pclken_tx);
734780
ret |= clock_control_on(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE),
735781
(clock_control_subsys_t)&cfg->pclken_rx);
782+
#if DT_INST_CLOCKS_HAS_NAME(0, mac_clk)
783+
ret |= clock_control_on(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE),
784+
(clock_control_subsys_t)&cfg->pclken_mac);
785+
#endif
786+
736787
#if DT_INST_CLOCKS_HAS_NAME(0, mac_clk_ptp)
737788
ret |= clock_control_on(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE),
738789
(clock_control_subsys_t)&cfg->pclken_ptp);
@@ -812,6 +863,7 @@ static void eth_stm32_mcast_filter(const struct device *dev, const struct ethern
812863
static int eth_init_api_v2(const struct device *dev)
813864
{
814865
HAL_StatusTypeDef hal_ret = HAL_OK;
866+
__maybe_unused const struct eth_stm32_hal_dev_cfg *cfg = dev->config;
815867
struct eth_stm32_hal_dev_data *dev_data = dev->data;
816868
ETH_HandleTypeDef *heth = &dev_data->heth;
817869

@@ -826,6 +878,10 @@ static int eth_init_api_v2(const struct device *dev)
826878
#endif
827879
heth->Init.RxBuffLen = ETH_STM32_RX_BUF_SIZE;
828880

881+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32mp13_ethernet)
882+
/* APO test : TBD */
883+
heth->Init.ClockSelection = cfg->clockselection;
884+
#endif
829885
hal_ret = HAL_ETH_Init(heth);
830886
if (hal_ret == HAL_TIMEOUT) {
831887
/* HAL Init time out. This could be linked to */
@@ -1134,6 +1190,18 @@ static const struct eth_stm32_hal_dev_cfg eth0_config = {
11341190
.config_func = eth0_irq_config,
11351191
.pclken = {.bus = DT_CLOCKS_CELL_BY_NAME(DT_INST_PARENT(0), stm_eth, bus),
11361192
.enr = DT_CLOCKS_CELL_BY_NAME(DT_INST_PARENT(0), stm_eth, bits)},
1193+
#if DT_INST_CLOCKS_HAS_NAME(0, mac_clk)
1194+
.pclken_mac = {.bus = DT_INST_CLOCKS_CELL_BY_NAME(0, mac_clk, bus),
1195+
.enr = DT_INST_CLOCKS_CELL_BY_NAME(0, mac_clk, bits)},
1196+
#endif
1197+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32mp13_ethernet)
1198+
.clockselection = DT_NODE_HAS_PROP(0, st_ext_phyclk) ? HAL_ETH1_REF_CLK_RCC
1199+
: HAL_ETH1_REF_CLK_RX_CLK_PIN,
1200+
#endif
1201+
#if DT_INST_CLOCKS_HAS_NAME(0, eth_ker)
1202+
.pclken_ker = {.bus = DT_INST_CLOCKS_CELL_BY_NAME(0, eth_ker, bus),
1203+
.enr = DT_INST_CLOCKS_CELL_BY_NAME(0, eth_ker, bits)},
1204+
#endif
11371205
.pclken_tx = {.bus = DT_INST_CLOCKS_CELL_BY_NAME(0, mac_clk_tx, bus),
11381206
.enr = DT_INST_CLOCKS_CELL_BY_NAME(0, mac_clk_tx, bits)},
11391207
.pclken_rx = {.bus = DT_INST_CLOCKS_CELL_BY_NAME(0, mac_clk_rx, bus),

0 commit comments

Comments
 (0)