Commit 7b270b72 authored by Chen-Yu Tsai's avatar Chen-Yu Tsai Committed by David S. Miller

net: stmmac: dwmac-sun8i: Support different ranges for TX/RX delay chains

On the R40 SoC, the RX delay chain only has a range of 0~7 (hundred
picoseconds), instead of 0~31. Also the TX delay chain is completely
absent.

This patch adds support for different ranges by adding per-compatible
maximum values in the variant data. A maximum of 0 indicates that the
delay chain is not supported or absent.
Signed-off-by: default avatarChen-Yu Tsai <wens@csie.org>
Acked-by: default avatarMaxime Ripard <maxime.ripard@bootlin.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 49a06cae
...@@ -47,6 +47,12 @@ ...@@ -47,6 +47,12 @@
* @support_mii: Does the MAC handle MII * @support_mii: Does the MAC handle MII
* @support_rmii: Does the MAC handle RMII * @support_rmii: Does the MAC handle RMII
* @support_rgmii: Does the MAC handle RGMII * @support_rgmii: Does the MAC handle RGMII
*
* @rx_delay_max: Maximum raw value for RX delay chain
* @tx_delay_max: Maximum raw value for TX delay chain
* These two also indicate the bitmask for
* the RX and TX delay chain registers. A
* value of zero indicates this is not supported.
*/ */
struct emac_variant { struct emac_variant {
u32 default_syscon_value; u32 default_syscon_value;
...@@ -55,6 +61,8 @@ struct emac_variant { ...@@ -55,6 +61,8 @@ struct emac_variant {
bool support_mii; bool support_mii;
bool support_rmii; bool support_rmii;
bool support_rgmii; bool support_rgmii;
u8 rx_delay_max;
u8 tx_delay_max;
}; };
/* struct sunxi_priv_data - hold all sunxi private data /* struct sunxi_priv_data - hold all sunxi private data
...@@ -91,7 +99,9 @@ static const struct emac_variant emac_variant_h3 = { ...@@ -91,7 +99,9 @@ static const struct emac_variant emac_variant_h3 = {
.soc_has_internal_phy = true, .soc_has_internal_phy = true,
.support_mii = true, .support_mii = true,
.support_rmii = true, .support_rmii = true,
.support_rgmii = true .support_rgmii = true,
.rx_delay_max = 31,
.tx_delay_max = 7,
}; };
static const struct emac_variant emac_variant_v3s = { static const struct emac_variant emac_variant_v3s = {
...@@ -106,7 +116,9 @@ static const struct emac_variant emac_variant_a83t = { ...@@ -106,7 +116,9 @@ static const struct emac_variant emac_variant_a83t = {
.syscon_field = &sun8i_syscon_reg_field, .syscon_field = &sun8i_syscon_reg_field,
.soc_has_internal_phy = false, .soc_has_internal_phy = false,
.support_mii = true, .support_mii = true,
.support_rgmii = true .support_rgmii = true,
.rx_delay_max = 31,
.tx_delay_max = 7,
}; };
static const struct emac_variant emac_variant_a64 = { static const struct emac_variant emac_variant_a64 = {
...@@ -115,7 +127,9 @@ static const struct emac_variant emac_variant_a64 = { ...@@ -115,7 +127,9 @@ static const struct emac_variant emac_variant_a64 = {
.soc_has_internal_phy = false, .soc_has_internal_phy = false,
.support_mii = true, .support_mii = true,
.support_rmii = true, .support_rmii = true,
.support_rgmii = true .support_rgmii = true,
.rx_delay_max = 31,
.tx_delay_max = 7,
}; };
#define EMAC_BASIC_CTL0 0x00 #define EMAC_BASIC_CTL0 0x00
...@@ -219,9 +233,7 @@ static const struct emac_variant emac_variant_a64 = { ...@@ -219,9 +233,7 @@ static const struct emac_variant emac_variant_a64 = {
#define SYSCON_RMII_EN BIT(13) /* 1: enable RMII (overrides EPIT) */ #define SYSCON_RMII_EN BIT(13) /* 1: enable RMII (overrides EPIT) */
/* Generic system control EMAC_CLK bits */ /* Generic system control EMAC_CLK bits */
#define SYSCON_ETXDC_MASK GENMASK(2, 0)
#define SYSCON_ETXDC_SHIFT 10 #define SYSCON_ETXDC_SHIFT 10
#define SYSCON_ERXDC_MASK GENMASK(4, 0)
#define SYSCON_ERXDC_SHIFT 5 #define SYSCON_ERXDC_SHIFT 5
/* EMAC PHY Interface Type */ /* EMAC PHY Interface Type */
#define SYSCON_EPIT BIT(2) /* 1: RGMII, 0: MII */ #define SYSCON_EPIT BIT(2) /* 1: RGMII, 0: MII */
...@@ -847,8 +859,9 @@ static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv) ...@@ -847,8 +859,9 @@ static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv)
} }
val /= 100; val /= 100;
dev_dbg(priv->device, "set tx-delay to %x\n", val); dev_dbg(priv->device, "set tx-delay to %x\n", val);
if (val <= SYSCON_ETXDC_MASK) { if (val <= gmac->variant->tx_delay_max) {
reg &= ~(SYSCON_ETXDC_MASK << SYSCON_ETXDC_SHIFT); reg &= ~(gmac->variant->tx_delay_max <<
SYSCON_ETXDC_SHIFT);
reg |= (val << SYSCON_ETXDC_SHIFT); reg |= (val << SYSCON_ETXDC_SHIFT);
} else { } else {
dev_err(priv->device, "Invalid TX clock delay: %d\n", dev_err(priv->device, "Invalid TX clock delay: %d\n",
...@@ -864,8 +877,9 @@ static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv) ...@@ -864,8 +877,9 @@ static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv)
} }
val /= 100; val /= 100;
dev_dbg(priv->device, "set rx-delay to %x\n", val); dev_dbg(priv->device, "set rx-delay to %x\n", val);
if (val <= SYSCON_ERXDC_MASK) { if (val <= gmac->variant->rx_delay_max) {
reg &= ~(SYSCON_ERXDC_MASK << SYSCON_ERXDC_SHIFT); reg &= ~(gmac->variant->rx_delay_max <<
SYSCON_ERXDC_SHIFT);
reg |= (val << SYSCON_ERXDC_SHIFT); reg |= (val << SYSCON_ERXDC_SHIFT);
} else { } else {
dev_err(priv->device, "Invalid RX clock delay: %d\n", dev_err(priv->device, "Invalid RX clock delay: %d\n",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment