Skip to content

Commit

Permalink
drivers: net: xgene: Add support RGMII TX/RX delay configuration
Browse files Browse the repository at this point in the history
Add RGMII TX/RX delay configuration support. RGMII standard requires 2ns
delay to help the RGMII bridge receiver to sample data correctly. If the
default value does not provide proper centering of the data sample, the
TX/RX delay parameters can be used to adjust accordingly.

Signed-off-by: Iyappan Subramanian <isubramanian@apm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Iyappan Subramanian authored and David S. Miller committed Oct 30, 2015
1 parent b7af147 commit 16615a4
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 1 deletion.
8 changes: 7 additions & 1 deletion drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,7 @@ static void xgene_gmac_reset(struct xgene_enet_pdata *pdata)

static void xgene_gmac_init(struct xgene_enet_pdata *pdata)
{
struct device *dev = &pdata->pdev->dev;
u32 value, mc2;
u32 intf_ctl, rgmii;
u32 icm0, icm2;
Expand Down Expand Up @@ -490,7 +491,12 @@ static void xgene_gmac_init(struct xgene_enet_pdata *pdata)
default:
ENET_INTERFACE_MODE2_SET(&mc2, 2);
intf_ctl |= ENET_GHD_MODE;
CFG_TXCLK_MUXSEL0_SET(&rgmii, 4);

if (dev->of_node) {
CFG_TXCLK_MUXSEL0_SET(&rgmii, pdata->tx_delay);
CFG_RXCLK_MUXSEL0_SET(&rgmii, pdata->rx_delay);
}

xgene_enet_rd_csr(pdata, DEBUG_REG_ADDR, &value);
value |= CFG_BYPASS_UNISEC_TX | CFG_BYPASS_UNISEC_RX;
xgene_enet_wr_csr(pdata, DEBUG_REG_ADDR, value);
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/apm/xgene/xgene_enet_hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ enum xgene_enet_rm {
#define CFG_BYPASS_UNISEC_RX BIT(1)
#define CFG_CLE_BYPASS_EN0 BIT(31)
#define CFG_TXCLK_MUXSEL0_SET(dst, val) xgene_set_bits(dst, val, 29, 3)
#define CFG_RXCLK_MUXSEL0_SET(dst, val) xgene_set_bits(dst, val, 26, 3)

#define CFG_CLE_IP_PROTOCOL0_SET(dst, val) xgene_set_bits(dst, val, 16, 2)
#define CFG_CLE_DSTQID0_SET(dst, val) xgene_set_bits(dst, val, 0, 12)
Expand Down
49 changes: 49 additions & 0 deletions drivers/net/ethernet/apm/xgene/xgene_enet_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1118,6 +1118,47 @@ static int xgene_get_port_id_dt(struct device *dev, struct xgene_enet_pdata *pda
return ret;
}

static int xgene_get_tx_delay(struct xgene_enet_pdata *pdata)
{
struct device *dev = &pdata->pdev->dev;
int delay, ret;

ret = of_property_read_u32(dev->of_node, "tx-delay", &delay);
if (ret) {
pdata->tx_delay = 4;
return 0;
}

if (delay < 0 || delay > 7) {
dev_err(dev, "Invalid tx-delay specified\n");
return -EINVAL;
}

pdata->tx_delay = delay;

return 0;
}

static int xgene_get_rx_delay(struct xgene_enet_pdata *pdata)
{
struct device *dev = &pdata->pdev->dev;
int delay, ret;

ret = of_property_read_u32(dev->of_node, "rx-delay", &delay);
if (ret) {
pdata->rx_delay = 2;
return 0;
}

if (delay < 0 || delay > 7) {
dev_err(dev, "Invalid rx-delay specified\n");
return -EINVAL;
}

pdata->rx_delay = delay;

return 0;
}

static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
{
Expand Down Expand Up @@ -1194,6 +1235,14 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
return -ENODEV;
}

ret = xgene_get_tx_delay(pdata);
if (ret)
return ret;

ret = xgene_get_rx_delay(pdata);
if (ret)
return ret;

ret = platform_get_irq(pdev, 0);
if (ret <= 0) {
dev_err(dev, "Unable to get ENET Rx IRQ\n");
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/apm/xgene/xgene_enet_main.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,8 @@ struct xgene_enet_pdata {
u8 bp_bufnum;
u16 ring_num;
u32 mss;
u8 tx_delay;
u8 rx_delay;
};

struct xgene_indirect_ctl {
Expand Down

0 comments on commit 16615a4

Please sign in to comment.