Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions drivers/ethernet/dwc_ether_qos/eth_qos.c
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ static void eth_qos_dma_rx_process(const struct device *dev, uint8_t dma_ch)

/* Packet reception error */
if (eth_qos_rdes_pkt_error(desc)) {
eth_stats_update_errors_rx(p->iface);
eth_stats_update_errors_rx(data->iface);
net_pkt_unref(pkt);
pkt = NULL;
goto next;
Expand Down Expand Up @@ -850,7 +850,7 @@ void eth_qos_common_isr(const struct device *dev)
eth_qos_dma_rx_fill_desc(dev, dma_ch);
}
#endif
dma_ch_status &= ~(1 << dma_ch);
dma_status &= ~BIT(dma_ch);
}
}
if (mtl_status) {
Expand Down Expand Up @@ -966,11 +966,18 @@ int eth_qos_init(const struct device *dev)
const struct eth_qos_config *cfg = dev->config;
struct eth_qos_data *data = dev->data;
uint32_t dma_ch;
int ret;

if (cfg->skip_init) {
return 0;
}

ret = pinctrl_apply_state(cfg->pincfg, PINCTRL_STATE_DEFAULT);
if (ret < 0) {
LOG_ERR("%s: failed to apply pinctrl: %d", dev->name, ret);
return ret;
}

if (!cfg->dma_only && cfg->phy != NULL && !device_is_ready(cfg->phy)) {
LOG_ERR("%s: PHY device is not ready", dev->name);
return -EFAULT;
Expand Down Expand Up @@ -1037,6 +1044,7 @@ struct ethernet_api eth_qos_api = {
};

#define ETH_QOS_INIT(n) \
PINCTRL_DT_INST_DEFINE(n); \
ETH_QOS_INIT_FUNC(n) \
ETH_QOS_DMA_INIT(n); \
ETH_QOS_MTL_INIT(n); \
Expand Down
4 changes: 4 additions & 0 deletions drivers/ethernet/dwc_ether_qos/eth_qos_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <zephyr/cache.h>
#include <zephyr/device.h>
#include <zephyr/kernel.h>
#include <zephyr/drivers/pinctrl.h>
#include <zephyr/net_buf.h>
#include <zephyr/net/net_if.h>
#include <zephyr/net/net_pkt.h>
Expand Down Expand Up @@ -112,6 +113,8 @@ struct eth_qos_config {
/* Device nodes */
/** Phy deivce */
const struct device *phy;
/** Pin control configuration */
const struct pinctrl_dev_config *pincfg;
#if CONFIG_PTP_CLOCK
/** PTP Clock Device */
const struct device *ptp_clock;
Expand Down Expand Up @@ -1037,6 +1040,7 @@ static inline void eth_qos_set_mac_addr(const struct device *dev, uint8_t nr, ui
{.init = eth_qos##n##_init, \
.base = DT_INST_REG_ADDR(n), \
.phy = DEVICE_DT_GET_OR_NULL(DT_INST_PHANDLE(n, phy_handle)), \
.pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
.dma_rx_channel = ETH_QOS_RX_CHANNELS_TO_USE(n), \
.dma_tx_channel = ETH_QOS_TX_CHANNELS_TO_USE(n), \
.dma_rx = eth_qos##n##_dma_rx_config, \
Expand Down
118 changes: 114 additions & 4 deletions drivers/ethernet/mdio/mdio_qos.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,75 @@ LOG_MODULE_REGISTER(mdio_qos, CONFIG_MDIO_LOG_LEVEL);
#include <zephyr/drivers/pinctrl.h>
#include <zephyr/sys/util.h>

#if defined(CONFIG_SOC_FAMILY_AURIX)
#include "soc.h"
/* GETH CLC register on TC3xx — separate from MAC reg region (0xF001D000).
* Confirmed against iLLD TC37A IfxGeth_reg.h.
*/
#define GETH_CLC_ADDR 0xf001f000
/* GETH wrapper GPCTL: bits [24:22] EPR = PHY interface mode.
* 0=MII, 1=RGMII, 4=RMII (iLLD IfxGeth_PhyInterfaceMode).
* Upstream dwc_ether_qos does not touch this; without EPR=RMII the GETH
* does not output the 50 MHz REF_CLK to the PHY, so the PHY can't link.
*/
#define GETH_GPCTL_ADDR 0xf001f008
#define GETH_GPCTL_EPR_RMII (4u << 22)
#define GETH_GPCTL_EPR_MASK (7u << 22)
#define GETH_SKEWCTL_ADDR 0xf001f040
#define SCU_CCUCON5_ADDR 0xf003604c
#define SCU_CCUCON5_GETHDIV_MASK 0xfu
#define SCU_CCUCON5_GETHDIV_150MHZ 2u
#define SCU_CCUCON5_UP BIT(30)
#define SCU_CCUCON5_LCK BIT(31)
/* GETH kernel reset registers — required by iLLD before DMA SWR.
* Keep this sequence local to GETH: iLLD writes KRST0/KRST1 first,
* waits for KRST0.RSTSTAT, then clears KRSTCLR.
*/
#define GETH_KRST0_ADDR 0xf001f014

static int aurix_geth_enable_clock_source(uint32_t timeout)
{
uint32_t before = sys_read32(SCU_CCUCON5_ADDR);
uint32_t target = (before & ~(SCU_CCUCON5_GETHDIV_MASK | SCU_CCUCON5_LCK)) |
SCU_CCUCON5_GETHDIV_150MHZ | SCU_CCUCON5_UP;

if ((before & SCU_CCUCON5_GETHDIV_MASK) != SCU_CCUCON5_GETHDIV_150MHZ) {
if (!WAIT_FOR((sys_read32(SCU_CCUCON5_ADDR) & SCU_CCUCON5_LCK) == 0,
timeout, k_busy_wait(1))) {
LOG_ERR("GETH CCUCON5 lock did not clear before update");
return 0;
}
aurix_safety_endinit_enable(false);
sys_write32(target, SCU_CCUCON5_ADDR);
aurix_safety_endinit_enable(true);
}
if (!WAIT_FOR(((sys_read32(SCU_CCUCON5_ADDR) & SCU_CCUCON5_LCK) == 0) &&
((sys_read32(SCU_CCUCON5_ADDR) & SCU_CCUCON5_GETHDIV_MASK) ==
SCU_CCUCON5_GETHDIV_150MHZ), timeout, k_busy_wait(1))) {
LOG_ERR("GETH CCUCON5.GETHDIV update timed out");
return 0;
}
return 1;
}

static int aurix_geth_kernel_reset(uint32_t timeout)
{
aurix_cpu_endinit_enable(false);
sys_write32(1, GETH_KRST0_ADDR);
sys_write32(1, GETH_KRST0_ADDR + 4);
aurix_cpu_endinit_enable(true);
int ok = WAIT_FOR((sys_read32(GETH_KRST0_ADDR) & 0x2) == 0x2,
timeout, k_busy_wait(1));
if (ok) {
aurix_cpu_endinit_enable(false);
sys_write32(1, GETH_KRST0_ADDR + 8);
aurix_cpu_endinit_enable(true);
}

return ok;
}
#endif

#define PHY_OPERATION_TIMEOUT_US 250000

#define MAC_MDIO_ADDRESS 0x0
Expand Down Expand Up @@ -113,7 +182,7 @@ static int mdio_qos_read(const struct device *dev, uint8_t prtad, uint8_t regad,

qos_mdio_transfer(dev, prtad, regad, false, false);

if (!WAIT_FOR(!qos_mdio_busy(dev), PHY_OPERATION_TIMEOUT_US, k_sleep(K_USEC(1000)))) {
if (!WAIT_FOR(!qos_mdio_busy(dev), PHY_OPERATION_TIMEOUT_US, k_busy_wait(1000))) {
LOG_ERR("phy timeout");
k_sem_give(&dev_data->sem);
return -ETIMEDOUT;
Expand Down Expand Up @@ -160,7 +229,7 @@ static int mdio_qos_write(const struct device *dev, uint8_t prtad, uint8_t regad
sys_write32(data, cfg->base_addr + MAC_MDIO_DATA);
qos_mdio_transfer(dev, prtad, regad, true, false);

if (!WAIT_FOR(!qos_mdio_busy(dev), PHY_OPERATION_TIMEOUT_US, k_sleep(K_USEC(1000)))) {
if (!WAIT_FOR(!qos_mdio_busy(dev), PHY_OPERATION_TIMEOUT_US, k_busy_wait(1000))) {
LOG_ERR("phy timeout");
err = -ETIMEDOUT;
}
Expand Down Expand Up @@ -205,7 +274,7 @@ static int mdio_qos_read_c45(const struct device *dev, uint8_t prtad, uint8_t de
sys_write32((regad << 16), cfg->base_addr + MAC_MDIO_DATA);
qos_mdio_transfer(dev, prtad, devad, false, true);

if (!WAIT_FOR(!qos_mdio_busy(dev), PHY_OPERATION_TIMEOUT_US, k_sleep(K_USEC(1000)))) {
if (!WAIT_FOR(!qos_mdio_busy(dev), PHY_OPERATION_TIMEOUT_US, k_busy_wait(1000))) {
LOG_ERR("phy timeout");
k_sem_give(&dev_data->sem);
err = -ETIMEDOUT;
Expand Down Expand Up @@ -252,7 +321,7 @@ static int mdio_qos_write_c45(const struct device *dev, uint8_t prtad, uint8_t d
sys_write32((regad << 16) | data, cfg->base_addr + MAC_MDIO_DATA);
qos_mdio_transfer(dev, prtad, devad, true, true);

if (!WAIT_FOR(!qos_mdio_busy(dev), PHY_OPERATION_TIMEOUT_US, k_sleep(K_USEC(1000)))) {
if (!WAIT_FOR(!qos_mdio_busy(dev), PHY_OPERATION_TIMEOUT_US, k_busy_wait(1000))) {
LOG_ERR("phy timeout");
k_sem_give(&dev_data->sem);
err = -ETIMEDOUT;
Expand Down Expand Up @@ -308,6 +377,47 @@ static int mdio_qos_initialize(const struct device *dev)
int ret;
uint32_t rate;

#if defined(CONFIG_SOC_FAMILY_AURIX)
if (!aurix_geth_enable_clock_source(1000)) {
LOG_ERR("GETH fGETH clock divider update timed out");
return -EIO;
}

LOG_INF("Enabling GETH module clock (CLC=0x%x)", GETH_CLC_ADDR);
if (!aurix_enable_clock(GETH_CLC_ADDR, 1000)) {
LOG_ERR("GETH CLC unlock timed out");
return -EIO;
}
LOG_INF("GETH clock enabled");

/* Follow iLLD IfxGeth_Eth_initModule sequence:
* GPCTL.EPR = 0 → SKEWCTL = 0 → resetModule (KRST0/1/CLR) → wait
* → GPCTL.EPR = RMII → (eth_qos will then do DMA SWR)
* Skipping the kernel reset leaves the DMA in a state where SWR
* never self-clears, producing "Failed to reset mac".
*/
sys_write32(sys_read32(GETH_GPCTL_ADDR) & ~GETH_GPCTL_EPR_MASK,
GETH_GPCTL_ADDR);
sys_write32(0, GETH_SKEWCTL_ADDR);
if (!aurix_geth_kernel_reset(1000)) {
LOG_ERR("GETH kernel reset timed out");
return -EIO;
}
k_busy_wait(10); /* ≥35 fSPB cycles per iLLD GETH_TC.002 */

/* KRST also re-asserts CLC.DISR, so any GETH MMR access after
* the kernel reset (e.g. PHY driver MDIO probe at next init
* priority) would trap (Class 4 TIN 2) just like at cold boot.
* Re-unlock CLC before continuing.
*/
if (!aurix_enable_clock(GETH_CLC_ADDR, 1000)) {
LOG_ERR("GETH CLC re-unlock after KRST timed out");
return -EIO;
}

sys_write32(GETH_GPCTL_EPR_RMII | 0x3u, GETH_GPCTL_ADDR);
#endif

k_sem_init(&dev_data->sem, 1, 1);

ret = pinctrl_apply_state(cfg->pinctrl, PINCTRL_STATE_DEFAULT);
Expand Down
4 changes: 2 additions & 2 deletions drivers/ethernet/phy/phy_ti_dp83825.c
Original file line number Diff line number Diff line change
Expand Up @@ -261,9 +261,9 @@ static int phy_ti_dp83825_static_cfg(const struct device *dev)
}

if (config->phy_iface == DP83825_RMII) {
reg_val |= PHY_TI_DP83825_RCSR_REF_CLK_SEL;
} else {
reg_val &= ~PHY_TI_DP83825_RCSR_REF_CLK_SEL;
} else {
reg_val |= PHY_TI_DP83825_RCSR_REF_CLK_SEL;
}

ret = phy_ti_dp83825_write(dev, PHY_TI_DP83825_RCSR_REG, (uint32_t)reg_val);
Expand Down
7 changes: 7 additions & 0 deletions drivers/timer/tc3x_stm.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <zephyr/sys/util.h>

#include "IfxStm_reg.h"
#include <soc.h>

#define TIMER_BASE_ADDR DT_REG_ADDR_BY_IDX(DT_CHOSEN(infineon_system_timer), 0)

Expand Down Expand Up @@ -171,6 +172,10 @@ void sys_clock_disable()

static int sys_clock_driver_init(void)
{
if (!aurix_enable_clock(TIMER_BASE_ADDR + offsetof(Ifx_STM, CLC), 1000)) {
return -EIO;
}

IRQ_CONNECT(DT_IRQ_BY_IDX(DT_CHOSEN(infineon_system_timer), 0, irq),
DT_IRQ_BY_IDX(DT_CHOSEN(infineon_system_timer), 0, priority), sys_clock_isr,
NULL, 0);
Expand All @@ -181,7 +186,9 @@ static int sys_clock_driver_init(void)

/* Set debug freeze if selected */
#if DT_PROP(DT_CHOSEN(infineon_system_timer), freeze)
aurix_cpu_endinit_enable(false);
sys_write32(0x12000000, TIMER_BASE_ADDR + offsetof(Ifx_STM, OCS));
aurix_cpu_endinit_enable(true);
#endif
/* Set compare window */
Ifx_STM_CMCON cmcon = {.B.MSIZE0 = 31, .B.MSTART0 = 0};
Expand Down