Skip to content
Open
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
121 changes: 117 additions & 4 deletions drivers/ethernet/phy/phy_ti_dp83867.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,23 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, LOG_LEVEL);
#define PHY_TI_DP83867_CFG3 0x001e
#define PHY_TI_DP83867_INT_EN BIT(7)

#define PHY_TI_DP83867_PHYCR 0x0010
#define PHY_TI_DP83867_FIFO_DEPTH_MASK (BIT(14) | BIT(15))
#define PHY_TI_DP83867_FIFO_DEPTH_SHIFT 14
#define PHY_TI_DP83867_FIFO_DEPTH_3B 0x0
#define PHY_TI_DP83867_FIFO_DEPTH_4B 0x1
#define PHY_TI_DP83867_FIFO_DEPTH_6B 0x2
#define PHY_TI_DP83867_FIFO_DEPTH_8B 0x3
#define DP83867_CTRL 0x1f
#define DP83867_SWRESET BIT(15)
#define DP83867_SWRESTART BIT(14)
#define DP83867_CFG4_REG 0x0031
#define DP83867_CFG4_RX_STRAP_BIT BIT(7)
#define MMD_CTRL_ADDR 0x0D
#define MMD_CTRL_DATA 0x0E
#define DP83867_REGCR_FUNC_ADDR (0x0 << 14)
#define DP83867_REGCR_FUNC_DATA_NO_POSTINC (0x1 << 14)

#define DP83867_RGMIICTL1 0x32
#define DP83867_RGMIIDCTL 0x86

Expand Down Expand Up @@ -120,6 +137,60 @@ static int phy_ti_dp83867_write(const struct device *dev, uint16_t reg_addr, uin
return 0;
}

static int phy_ti_dp83867_indirect_read(const struct device *dev, uint16_t reg_addr,
uint32_t *data)
{
const struct ti_dp83867_config *config = dev->config;
int ret;

ret = mdio_write(config->mdio_dev, config->addr, MMD_CTRL_ADDR,
DP83867_REGCR_FUNC_ADDR | DP83867_CTRL);
if (ret) {
return ret;
}

ret = mdio_write(config->mdio_dev, config->addr, MMD_CTRL_DATA, reg_addr);
if (ret) {
return ret;
}

ret = mdio_write(config->mdio_dev, config->addr, MMD_CTRL_ADDR,
DP83867_REGCR_FUNC_DATA_NO_POSTINC | DP83867_CTRL);
if (ret) {
return ret;
}

ret = mdio_read(config->mdio_dev, config->addr, MMD_CTRL_DATA, (uint16_t *)data);
return ret;
}

static int phy_ti_dp83867_indirect_write(const struct device *dev, uint16_t reg_addr,
uint32_t data)
{
const struct ti_dp83867_config *config = dev->config;
int ret;

ret = mdio_write(config->mdio_dev, config->addr, MMD_CTRL_ADDR,
DP83867_REGCR_FUNC_ADDR | DP83867_CTRL);
if (ret) {
return ret;
}

ret = mdio_write(config->mdio_dev, config->addr, MMD_CTRL_DATA, reg_addr);
if (ret) {
return ret;
}

ret = mdio_write(config->mdio_dev, config->addr, MMD_CTRL_ADDR,
DP83867_REGCR_FUNC_DATA_NO_POSTINC | DP83867_CTRL);
if (ret) {
return ret;
}

ret = mdio_write(config->mdio_dev, config->addr, MMD_CTRL_DATA, (uint16_t)data);
return ret;
}

#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios)
static int phy_ti_dp83867_clear_interrupt(struct ti_dp83867_data *data)
{
Expand Down Expand Up @@ -275,6 +346,12 @@ static int phy_ti_dp83867_reset(const struct device *dev)
return ret;
}

ret = phy_ti_dp83867_write(dev, DP83867_CTRL, DP83867_SWRESET);
if (ret < 0) {
LOG_ERR("Error writing phy (%d) control register", config->addr);
return ret;
}

#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios)
if (config->reset_gpio.port) {
ret = gpio_pin_set_dt(&config->reset_gpio, 1);
Expand All @@ -296,6 +373,12 @@ static int phy_ti_dp83867_reset(const struct device *dev)
LOG_ERR("Error writing phy (%d) basic control register", config->addr);
}

ret = phy_ti_dp83867_write(dev, DP83867_CTRL, DP83867_SWRESTART);
if (ret) {
LOG_ERR("Error writing phy (%d) control register", config->addr);
return ret;
}

done:
/* POR release time (minimum specified is T4=195us) */
k_busy_wait(PHY_TI_DP83867_POR_DELAY);
Expand Down Expand Up @@ -457,6 +540,7 @@ static int phy_ti_dp83867_init(const struct device *dev)
struct ti_dp83867_data *data = dev->data;
int ret;
uint32_t rgmii_ctl_val = 0, rgmii_dctl_val = 0;
uint32_t cfg4_val = 0, phycr_val = 0;

data->dev = dev;

Expand All @@ -483,8 +567,22 @@ static int phy_ti_dp83867_init(const struct device *dev)
return ret;
}

/* Read the Strap quirk bit to configure it to 0 */
ret = phy_ti_dp83867_indirect_read(dev, DP83867_CFG4_REG, &cfg4_val);
if (ret) {
LOG_ERR("Error reading DP83867_CFG4");
return ret;
}

cfg4_val &= ~DP83867_CFG4_RX_STRAP_BIT;
ret = phy_ti_dp83867_indirect_write(dev, DP83867_CFG4_REG, cfg4_val);
if (ret) {
LOG_ERR("Error writing DP83867_CFG4");
return ret;
}

/* Read the RGMIICTL1 register to configure internal delay enable bits*/
ret = phy_ti_dp83867_read(dev, DP83867_RGMIICTL1, &rgmii_ctl_val);
ret = phy_ti_dp83867_indirect_read(dev, DP83867_RGMIICTL1, &rgmii_ctl_val);
if (ret) {
LOG_ERR("Error reading DP83867_RGMIICTL1");
return ret;
Expand Down Expand Up @@ -513,14 +611,14 @@ static int phy_ti_dp83867_init(const struct device *dev)
}

/* write updated delay enable configuration to PHY(DP83867_RGMIICTL1)*/
ret = phy_ti_dp83867_write(dev, DP83867_RGMIICTL1, rgmii_ctl_val);
ret = phy_ti_dp83867_indirect_write(dev, DP83867_RGMIICTL1, rgmii_ctl_val);
if (ret) {
LOG_ERR("Failed to write DP83867_RGMIICTL1");
return ret;
}

/* Read RGMIIDCTL the delay value control register*/
ret = phy_ti_dp83867_read(dev, DP83867_RGMIIDCTL, &rgmii_dctl_val);
ret = phy_ti_dp83867_indirect_read(dev, DP83867_RGMIIDCTL, &rgmii_dctl_val);
if (ret) {
LOG_ERR("Error reading DP83867_RGMIIDCTL");
return ret;
Expand All @@ -542,12 +640,27 @@ static int phy_ti_dp83867_init(const struct device *dev)
}

/* Write final delay values to PHY(DP83867_RGMIIDCTL) */
ret = phy_ti_dp83867_write(dev, DP83867_RGMIIDCTL, rgmii_dctl_val);
ret = phy_ti_dp83867_indirect_write(dev, DP83867_RGMIIDCTL, rgmii_dctl_val);
if (ret) {
LOG_ERR("Error writing DP83867_RGMIIDCTL");
return ret;
}

/* Verify fifo depth value */
ret = phy_ti_dp83867_read(dev, PHY_TI_DP83867_PHYCR, &phycr_val);
if (ret) {
LOG_ERR("Error reading DP83867_PHYCR");
return ret;
}

uint8_t fifo_depth = (phycr_val & PHY_TI_DP83867_FIFO_DEPTH_MASK) >>
PHY_TI_DP83867_FIFO_DEPTH_SHIFT;
if (fifo_depth == PHY_TI_DP83867_FIFO_DEPTH_4B) {
LOG_INF("TX FIFO depth is set to 4 bytes/nibbles");
} else {
LOG_WRN("TX FIFO depth is not set to 4 bytes/nibbles (actual: %u)", fifo_depth);
}

k_work_init_delayable(&data->phy_monitor_work, phy_ti_dp83867_monitor_work_handler);

#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios)
Expand Down