summaryrefslogtreecommitdiff
path: root/drivers/net/dsa/microchip/lan937x_main.c
diff options
context:
space:
mode:
authorArun Ramadoss <arun.ramadoss@microchip.com>2022-07-24 14:58:20 +0530
committerDavid S. Miller <davem@davemloft.net>2022-07-27 09:39:17 +0100
commitb19ac41faa3f9602f245d1ab679f7fa96d388320 (patch)
tree8bc5e40bbaa39f091452ff52ee2faeadb9a6f3bf /drivers/net/dsa/microchip/lan937x_main.c
parentdc1c596edba5e656256c2d6e6922246c7803f2de (diff)
net: dsa: microchip: apply rgmii tx and rx delay in phylink mac config
This patch read the rgmii tx and rx delay from device tree and stored it in the ksz_port. It applies the rgmii delay to the xmii tune adjust register based on the interface selected in phylink mac config. There are two rgmii port in LAN937x and value to be loaded in the register vary depends on the port selected. Signed-off-by: Arun Ramadoss <arun.ramadoss@microchip.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/dsa/microchip/lan937x_main.c')
-rw-r--r--drivers/net/dsa/microchip/lan937x_main.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/drivers/net/dsa/microchip/lan937x_main.c b/drivers/net/dsa/microchip/lan937x_main.c
index d86ffdf976b0..797fe7f62394 100644
--- a/drivers/net/dsa/microchip/lan937x_main.c
+++ b/drivers/net/dsa/microchip/lan937x_main.c
@@ -315,6 +315,45 @@ int lan937x_change_mtu(struct ksz_device *dev, int port, int new_mtu)
return 0;
}
+static void lan937x_set_tune_adj(struct ksz_device *dev, int port,
+ u16 reg, u8 val)
+{
+ u16 data16;
+
+ ksz_pread16(dev, port, reg, &data16);
+
+ /* Update tune Adjust */
+ data16 |= FIELD_PREP(PORT_TUNE_ADJ, val);
+ ksz_pwrite16(dev, port, reg, data16);
+
+ /* write DLL reset to take effect */
+ data16 |= PORT_DLL_RESET;
+ ksz_pwrite16(dev, port, reg, data16);
+}
+
+static void lan937x_set_rgmii_tx_delay(struct ksz_device *dev, int port)
+{
+ u8 val;
+
+ /* Apply different codes based on the ports as per characterization
+ * results
+ */
+ val = (port == LAN937X_RGMII_1_PORT) ? RGMII_1_TX_DELAY_2NS :
+ RGMII_2_TX_DELAY_2NS;
+
+ lan937x_set_tune_adj(dev, port, REG_PORT_XMII_CTRL_5, val);
+}
+
+static void lan937x_set_rgmii_rx_delay(struct ksz_device *dev, int port)
+{
+ u8 val;
+
+ val = (port == LAN937X_RGMII_1_PORT) ? RGMII_1_RX_DELAY_2NS :
+ RGMII_2_RX_DELAY_2NS;
+
+ lan937x_set_tune_adj(dev, port, REG_PORT_XMII_CTRL_4, val);
+}
+
void lan937x_phylink_get_caps(struct ksz_device *dev, int port,
struct phylink_config *config)
{
@@ -327,6 +366,23 @@ void lan937x_phylink_get_caps(struct ksz_device *dev, int port,
}
}
+void lan937x_setup_rgmii_delay(struct ksz_device *dev, int port)
+{
+ struct ksz_port *p = &dev->ports[port];
+
+ if (p->rgmii_tx_val) {
+ lan937x_set_rgmii_tx_delay(dev, port);
+ dev_info(dev->dev, "Applied rgmii tx delay for the port %d\n",
+ port);
+ }
+
+ if (p->rgmii_rx_val) {
+ lan937x_set_rgmii_rx_delay(dev, port);
+ dev_info(dev->dev, "Applied rgmii rx delay for the port %d\n",
+ port);
+ }
+}
+
void lan937x_phylink_mac_config(struct ksz_device *dev, int port,
unsigned int mode,
const struct phylink_link_state *state)