|
@@ -35,10 +35,6 @@
|
|
|
|
|
|
#define PRG_ETH0_TXDLY_SHIFT 5
|
|
#define PRG_ETH0_TXDLY_SHIFT 5
|
|
#define PRG_ETH0_TXDLY_MASK GENMASK(6, 5)
|
|
#define PRG_ETH0_TXDLY_MASK GENMASK(6, 5)
|
|
-#define PRG_ETH0_TXDLY_OFF (0x0 << PRG_ETH0_TXDLY_SHIFT)
|
|
|
|
-#define PRG_ETH0_TXDLY_QUARTER (0x1 << PRG_ETH0_TXDLY_SHIFT)
|
|
|
|
-#define PRG_ETH0_TXDLY_HALF (0x2 << PRG_ETH0_TXDLY_SHIFT)
|
|
|
|
-#define PRG_ETH0_TXDLY_THREE_QUARTERS (0x3 << PRG_ETH0_TXDLY_SHIFT)
|
|
|
|
|
|
|
|
/* divider for the result of m250_sel */
|
|
/* divider for the result of m250_sel */
|
|
#define PRG_ETH0_CLK_M250_DIV_SHIFT 7
|
|
#define PRG_ETH0_CLK_M250_DIV_SHIFT 7
|
|
@@ -69,6 +65,8 @@ struct meson8b_dwmac {
|
|
|
|
|
|
struct clk_divider m25_div;
|
|
struct clk_divider m25_div;
|
|
struct clk *m25_div_clk;
|
|
struct clk *m25_div_clk;
|
|
|
|
+
|
|
|
|
+ u32 tx_delay_ns;
|
|
};
|
|
};
|
|
|
|
|
|
static void meson8b_dwmac_mask_bits(struct meson8b_dwmac *dwmac, u32 reg,
|
|
static void meson8b_dwmac_mask_bits(struct meson8b_dwmac *dwmac, u32 reg,
|
|
@@ -179,6 +177,7 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac *dwmac)
|
|
{
|
|
{
|
|
int ret;
|
|
int ret;
|
|
unsigned long clk_rate;
|
|
unsigned long clk_rate;
|
|
|
|
+ u8 tx_dly_val;
|
|
|
|
|
|
switch (dwmac->phy_mode) {
|
|
switch (dwmac->phy_mode) {
|
|
case PHY_INTERFACE_MODE_RGMII:
|
|
case PHY_INTERFACE_MODE_RGMII:
|
|
@@ -196,9 +195,13 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac *dwmac)
|
|
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0,
|
|
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0,
|
|
PRG_ETH0_INVERTED_RMII_CLK, 0);
|
|
PRG_ETH0_INVERTED_RMII_CLK, 0);
|
|
|
|
|
|
- /* TX clock delay - all known boards use a 1/4 cycle delay */
|
|
|
|
|
|
+ /* TX clock delay in ns = "8ns / 4 * tx_dly_val" (where
|
|
|
|
+ * 8ns are exactly one cycle of the 125MHz RGMII TX clock):
|
|
|
|
+ * 0ns = 0x0, 2ns = 0x1, 4ns = 0x2, 6ns = 0x3
|
|
|
|
+ */
|
|
|
|
+ tx_dly_val = dwmac->tx_delay_ns >> 1;
|
|
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_TXDLY_MASK,
|
|
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_TXDLY_MASK,
|
|
- PRG_ETH0_TXDLY_QUARTER);
|
|
|
|
|
|
+ tx_dly_val << PRG_ETH0_TXDLY_SHIFT);
|
|
break;
|
|
break;
|
|
|
|
|
|
case PHY_INTERFACE_MODE_RMII:
|
|
case PHY_INTERFACE_MODE_RMII:
|
|
@@ -284,6 +287,11 @@ static int meson8b_dwmac_probe(struct platform_device *pdev)
|
|
goto err_remove_config_dt;
|
|
goto err_remove_config_dt;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /* use 2ns as fallback since this value was previously hardcoded */
|
|
|
|
+ if (of_property_read_u32(pdev->dev.of_node, "amlogic,tx-delay-ns",
|
|
|
|
+ &dwmac->tx_delay_ns))
|
|
|
|
+ dwmac->tx_delay_ns = 2;
|
|
|
|
+
|
|
ret = meson8b_init_clk(dwmac);
|
|
ret = meson8b_init_clk(dwmac);
|
|
if (ret)
|
|
if (ret)
|
|
goto err_remove_config_dt;
|
|
goto err_remove_config_dt;
|