summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Kicinski <kuba@kernel.org>2026-03-30 00:35:29 +0300
committerJakub Kicinski <kuba@kernel.org>2026-03-30 00:35:30 +0300
commit686aad8353a5a4d3358deaba08b748a6b6e6d6c2 (patch)
tree37cccea77b9c35536c10e42cbc8fd8caf9982d44
parent57ec1622b62ae8dcd88a0084c49c5b72b1850e68 (diff)
parentcd1082a96f9a1ffe053e48ac0a1b4fffb189c30e (diff)
downloadlinux-686aad8353a5a4d3358deaba08b748a6b6e6d6c2.tar.xz
Merge branch 'macb-usrio-tsu-patches'
Conor Dooley says: ==================== macb usrio/tsu patches At the very least, it'd be good of the soc vendor folks could check their platforms and see if their usrio stuff actually lines up with what the driver currently calls "macb_default_usrio". Ours didn't and it was a nasty surprise. Ryan and I figured out that the sama7g5 stuff is not actually using the same usrio bits as earlier devices, so there's now more patches in this series to split them apart. I've not tested the split or the new property due to lack of hardware, but Ryan has. Marking this stuff net-next, because although they're fixes I don't see any particular urgency, and it avoids creating some dependencies between cleanup items and the fixes. ==================== Link: https://patch.msgid.link/20260325-unsterile-flail-4c7729750dc4@spud Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rw-r--r--Documentation/devicetree/bindings/net/cdns,macb.yaml71
-rw-r--r--drivers/net/ethernet/cadence/macb.h8
-rw-r--r--drivers/net/ethernet/cadence/macb_main.c187
3 files changed, 212 insertions, 54 deletions
diff --git a/Documentation/devicetree/bindings/net/cdns,macb.yaml b/Documentation/devicetree/bindings/net/cdns,macb.yaml
index feb168385837..2c8c080a3d88 100644
--- a/Documentation/devicetree/bindings/net/cdns,macb.yaml
+++ b/Documentation/devicetree/bindings/net/cdns,macb.yaml
@@ -130,10 +130,23 @@ properties:
cdns,refclk-ext:
type: boolean
+ deprecated: true
+ description: |
+ This selects if the REFCLK for RMII is provided by an external source.
+ For RGMII mode this selects if the 125MHz REF clock is provided by an external
+ source.
+
+ This property has been replaced by cdns,refclk-source, as it only works
+ for devices that use an internal reference clock by default.
+
+ cdns,refclk-source:
+ $ref: /schemas/types.yaml#/definitions/string
+ enum:
+ - internal
+ - external
description:
- This selects if the REFCLK for RMII is provided by an external source.
- For RGMII mode this selects if the 125MHz REF clock is provided by an external
- source.
+ Select whether or not the refclk for RGMII or RMII is provided by an
+ internal or external source. The default is device specific.
cdns,rx-watermark:
$ref: /schemas/types.yaml#/definitions/uint32
@@ -145,6 +158,12 @@ properties:
that need to be filled, before the forwarding process is activated.
Width of the SRAM is platform dependent, and can be 4, 8 or 16 bytes.
+ cdns,timer-adjust:
+ type: boolean
+ description:
+ Set when the hardware is operating in timer-adjust mode, where the timer
+ is controlled by the gem_tsu_inc_ctrl and gem_tsu_ms inputs.
+
'#address-cells':
const: 1
@@ -194,6 +213,15 @@ allOf:
properties:
reg:
maxItems: 1
+ - if:
+ not:
+ properties:
+ compatible:
+ contains:
+ const: microchip,mpfs-macb
+ then:
+ properties:
+ cdns,timer-adjust: false
- if:
properties:
@@ -215,6 +243,43 @@ allOf:
properties:
mdio: false
+ - if:
+ not:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - microchip,sama7g5-gem
+ - microchip,sama7g5-emac
+ then:
+ properties:
+ cdns,refclk-source: false
+
+ - if:
+ not:
+ properties:
+ compatible:
+ contains:
+ const: microchip,sama7g5-gem
+ then:
+ properties:
+ cdns,refclk-ext: false
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - microchip,sama7g5-emac
+ then:
+ properties:
+ cdns,refclk-source:
+ default: external
+ else:
+ properties:
+ cdns,refclk-source:
+ default: internal
+
unevaluatedProperties: false
examples:
diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
index c69828b27dae..16527dbab875 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -524,6 +524,8 @@
#define GEM_IRQCOR_SIZE 1
#define GEM_DBWDEF_OFFSET 25
#define GEM_DBWDEF_SIZE 3
+#define GEM_USERIO_OFFSET 9
+#define GEM_USERIO_SIZE 1
#define GEM_NO_PCS_OFFSET 0
#define GEM_NO_PCS_SIZE 1
@@ -786,6 +788,9 @@
#define MACB_CAPS_RSC BIT(23)
#define MACB_CAPS_NO_LSO BIT(24)
#define MACB_CAPS_EEE BIT(25)
+#define MACB_CAPS_USRIO_HAS_MII BIT(26)
+#define MACB_CAPS_USRIO_HAS_REFCLK_SOURCE BIT(27)
+#define MACB_CAPS_USRIO_HAS_TSUCLK_SOURCE BIT(28)
/* LSO settings */
#define MACB_LSO_UFO_ENABLE 0x01
@@ -1225,7 +1230,10 @@ struct macb_usrio_config {
u32 rmii;
u32 rgmii;
u32 refclk;
+ u32 clken;
u32 hdfctlen;
+ u32 tsu_source;
+ bool refclk_default_external;
};
struct macb_config {
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index c8182559edf6..7a48ebe0741f 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -3765,15 +3765,14 @@ static unsigned int gem_get_tsu_rate(struct macb *bp)
struct clk *tsu_clk;
unsigned int tsu_rate;
- tsu_clk = devm_clk_get(&bp->pdev->dev, "tsu_clk");
- if (!IS_ERR(tsu_clk))
- tsu_rate = clk_get_rate(tsu_clk);
- /* try pclk instead */
- else if (!IS_ERR(bp->pclk)) {
+ if (!IS_ERR_OR_NULL(bp->tsu_clk)) {
+ tsu_rate = clk_get_rate(bp->tsu_clk);
+ } else {
tsu_clk = bp->pclk;
tsu_rate = clk_get_rate(tsu_clk);
- } else
- return -ENOTSUPP;
+ dev_warn(&bp->pdev->dev, "devicetree missing tsu_clk, using pclk as fallback\n");
+ }
+
return tsu_rate;
}
@@ -4576,14 +4575,12 @@ static const struct net_device_ops macb_netdev_ops = {
static void macb_configure_caps(struct macb *bp,
const struct macb_config *dt_conf)
{
- struct device_node *np = bp->pdev->dev.of_node;
- bool refclk_ext;
u32 dcfg;
- refclk_ext = of_property_read_bool(np, "cdns,refclk-ext");
+ bp->caps = dt_conf->caps;
- if (dt_conf)
- bp->caps = dt_conf->caps;
+ if (!dt_conf->usrio)
+ bp->caps |= MACB_CAPS_USRIO_DISABLED;
if (hw_is_gem(bp->regs, bp->native_io)) {
bp->caps |= MACB_CAPS_MACB_IS_GEM;
@@ -4593,6 +4590,8 @@ static void macb_configure_caps(struct macb *bp,
bp->caps |= MACB_CAPS_ISR_CLEAR_ON_WRITE;
if (GEM_BFEXT(NO_PCS, dcfg) == 0)
bp->caps |= MACB_CAPS_PCS;
+ if (!(dcfg & GEM_BIT(USERIO)))
+ bp->caps |= MACB_CAPS_USRIO_DISABLED;
dcfg = gem_readl(bp, DCFG12);
if (GEM_BFEXT(HIGH_SPEED, dcfg) == 1)
bp->caps |= MACB_CAPS_HIGH_SPEED;
@@ -4614,9 +4613,6 @@ static void macb_configure_caps(struct macb *bp,
}
}
- if (refclk_ext)
- bp->caps |= MACB_CAPS_USRIO_HAS_CLKEN;
-
dev_dbg(&bp->pdev->dev, "Cadence caps 0x%08x\n", bp->caps);
}
@@ -4884,16 +4880,52 @@ static int macb_init_dflt(struct platform_device *pdev)
if (!(bp->caps & MACB_CAPS_USRIO_DISABLED)) {
val = 0;
- if (phy_interface_mode_is_rgmii(bp->phy_interface))
- val = bp->usrio->rgmii;
- else if (bp->phy_interface == PHY_INTERFACE_MODE_RMII &&
- (bp->caps & MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII))
- val = bp->usrio->rmii;
- else if (!(bp->caps & MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII))
- val = bp->usrio->mii;
+ if (bp->caps & MACB_CAPS_USRIO_HAS_MII) {
+ if (phy_interface_mode_is_rgmii(bp->phy_interface))
+ val = bp->usrio->rgmii;
+ else if (bp->phy_interface == PHY_INTERFACE_MODE_RMII &&
+ (bp->caps & MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII))
+ val = bp->usrio->rmii;
+ else if (!(bp->caps & MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII))
+ val = bp->usrio->mii;
+ }
if (bp->caps & MACB_CAPS_USRIO_HAS_CLKEN)
- val |= bp->usrio->refclk;
+ val |= bp->usrio->clken;
+
+ if (bp->caps & MACB_CAPS_USRIO_HAS_REFCLK_SOURCE) {
+ const char *prop;
+ bool refclk_ext;
+ int ret;
+
+ /* Default to whatever was set in the match data for
+ * this device. There's two properties for refclk
+ * control, but the boolean one is deprecated so is
+ * a lower priority to check, no device should have
+ * both.
+ */
+ refclk_ext = bp->usrio->refclk_default_external;
+
+ ret = of_property_read_string(pdev->dev.of_node,
+ "cdns,refclk-source", &prop);
+ if (!ret) {
+ if (!strcmp(prop, "external"))
+ refclk_ext = true;
+ else
+ refclk_ext = false;
+ } else {
+ ret = of_property_read_bool(pdev->dev.of_node,
+ "cdns,refclk-ext");
+ if (ret)
+ refclk_ext = true;
+ }
+
+ if (refclk_ext)
+ val |= bp->usrio->refclk;
+ }
+
+ if (bp->caps & MACB_CAPS_USRIO_HAS_TSUCLK_SOURCE)
+ val |= bp->usrio->tsu_source;
macb_or_gem_writel(bp, USRIO, val);
}
@@ -4917,13 +4949,6 @@ static int macb_init(struct platform_device *pdev,
return macb_init_dflt(pdev);
}
-static const struct macb_usrio_config macb_default_usrio = {
- .mii = MACB_BIT(MII),
- .rmii = MACB_BIT(RMII),
- .rgmii = GEM_BIT(RGMII),
- .refclk = MACB_BIT(CLKEN),
-};
-
#if defined(CONFIG_OF)
/* 1518 rounded up */
#define AT91ETHER_MAX_RBUFF_SZ 0x600
@@ -5498,64 +5523,102 @@ static int eyeq5_init(struct platform_device *pdev)
return ret;
}
-static const struct macb_usrio_config sama7g5_usrio = {
+static const struct macb_usrio_config at91_default_usrio = {
+ .mii = MACB_BIT(MII),
+ .rmii = MACB_BIT(RMII),
+ .rgmii = GEM_BIT(RGMII),
+ .clken = MACB_BIT(CLKEN),
+};
+
+static const struct macb_usrio_config mpfs_usrio = {
+ .tsu_source = 0,
+};
+
+static const struct macb_usrio_config sama7g5_gem_usrio = {
.mii = 0,
.rmii = 1,
.rgmii = 2,
.refclk = BIT(2),
+ .refclk_default_external = false,
+ .hdfctlen = BIT(6),
+};
+
+static const struct macb_usrio_config sama7g5_emac_usrio = {
+ .mii = 0,
+ .rmii = 1,
+ .rgmii = 2,
+ .refclk = BIT(2),
+ .refclk_default_external = true,
.hdfctlen = BIT(6),
};
static const struct macb_config fu540_c000_config = {
.caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE | MACB_CAPS_JUMBO |
- MACB_CAPS_GEM_HAS_PTP,
+ MACB_CAPS_GEM_HAS_PTP | MACB_CAPS_USRIO_HAS_MII,
.dma_burst_length = 16,
.clk_init = fu540_c000_clk_init,
.init = fu540_c000_init,
.jumbo_max_len = 10240,
+ .usrio = &at91_default_usrio,
};
static const struct macb_config at91sam9260_config = {
- .caps = MACB_CAPS_USRIO_HAS_CLKEN | MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII,
+ .caps = MACB_CAPS_USRIO_HAS_CLKEN | MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII |
+ MACB_CAPS_USRIO_HAS_MII,
+ .usrio = &at91_default_usrio,
};
static const struct macb_config sama5d3macb_config = {
.caps = MACB_CAPS_SG_DISABLED |
- MACB_CAPS_USRIO_HAS_CLKEN | MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII,
+ MACB_CAPS_USRIO_HAS_CLKEN | MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII |
+ MACB_CAPS_USRIO_HAS_MII,
+ .usrio = &at91_default_usrio,
};
static const struct macb_config pc302gem_config = {
- .caps = MACB_CAPS_SG_DISABLED | MACB_CAPS_GIGABIT_MODE_AVAILABLE,
+ .caps = MACB_CAPS_SG_DISABLED | MACB_CAPS_GIGABIT_MODE_AVAILABLE |
+ MACB_CAPS_USRIO_HAS_MII,
.dma_burst_length = 16,
+ .usrio = &at91_default_usrio,
};
static const struct macb_config sama5d2_config = {
- .caps = MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII | MACB_CAPS_JUMBO,
+ .caps = MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII | MACB_CAPS_JUMBO |
+ MACB_CAPS_USRIO_HAS_MII,
.dma_burst_length = 16,
.jumbo_max_len = 10240,
+ .usrio = &at91_default_usrio,
};
static const struct macb_config sama5d29_config = {
- .caps = MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII | MACB_CAPS_GEM_HAS_PTP,
+ .caps = MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII | MACB_CAPS_GEM_HAS_PTP |
+ MACB_CAPS_USRIO_HAS_MII,
.dma_burst_length = 16,
+ .usrio = &at91_default_usrio,
};
static const struct macb_config sama5d3_config = {
.caps = MACB_CAPS_SG_DISABLED | MACB_CAPS_GIGABIT_MODE_AVAILABLE |
- MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII | MACB_CAPS_JUMBO,
+ MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII | MACB_CAPS_JUMBO |
+ MACB_CAPS_USRIO_HAS_MII,
.dma_burst_length = 16,
.jumbo_max_len = 10240,
+ .usrio = &at91_default_usrio,
};
static const struct macb_config sama5d4_config = {
- .caps = MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII,
+ .caps = MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII |
+ MACB_CAPS_USRIO_HAS_MII,
.dma_burst_length = 4,
+ .usrio = &at91_default_usrio,
};
static const struct macb_config emac_config = {
- .caps = MACB_CAPS_NEEDS_RSTONUBR | MACB_CAPS_MACB_IS_EMAC,
+ .caps = MACB_CAPS_NEEDS_RSTONUBR | MACB_CAPS_MACB_IS_EMAC |
+ MACB_CAPS_USRIO_HAS_MII,
.clk_init = at91ether_clk_init,
.init = at91ether_init,
+ .usrio = &at91_default_usrio,
};
static const struct macb_config np4_config = {
@@ -5565,24 +5628,30 @@ static const struct macb_config np4_config = {
static const struct macb_config zynqmp_config = {
.caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE |
MACB_CAPS_JUMBO |
- MACB_CAPS_GEM_HAS_PTP | MACB_CAPS_BD_RD_PREFETCH,
+ MACB_CAPS_GEM_HAS_PTP | MACB_CAPS_BD_RD_PREFETCH |
+ MACB_CAPS_USRIO_HAS_MII,
.dma_burst_length = 16,
.init = init_reset_optional,
.jumbo_max_len = 10240,
+ .usrio = &at91_default_usrio,
};
static const struct macb_config zynq_config = {
.caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE | MACB_CAPS_NO_GIGABIT_HALF |
- MACB_CAPS_NEEDS_RSTONUBR,
+ MACB_CAPS_NEEDS_RSTONUBR |
+ MACB_CAPS_USRIO_HAS_MII,
.dma_burst_length = 16,
+ .usrio = &at91_default_usrio,
};
static const struct macb_config mpfs_config = {
.caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE |
MACB_CAPS_JUMBO |
- MACB_CAPS_GEM_HAS_PTP,
+ MACB_CAPS_GEM_HAS_PTP |
+ MACB_CAPS_USRIO_HAS_TSUCLK_SOURCE,
.dma_burst_length = 16,
.init = init_reset_optional,
+ .usrio = &mpfs_usrio,
.max_tx_length = 4040, /* Cadence Erratum 1686 */
.jumbo_max_len = 4040,
};
@@ -5590,27 +5659,33 @@ static const struct macb_config mpfs_config = {
static const struct macb_config sama7g5_gem_config = {
.caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE | MACB_CAPS_CLK_HW_CHG |
MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII |
- MACB_CAPS_MIIONRGMII | MACB_CAPS_GEM_HAS_PTP,
+ MACB_CAPS_USRIO_HAS_REFCLK_SOURCE |
+ MACB_CAPS_MIIONRGMII | MACB_CAPS_GEM_HAS_PTP |
+ MACB_CAPS_USRIO_HAS_MII,
.dma_burst_length = 16,
- .usrio = &sama7g5_usrio,
+ .usrio = &sama7g5_gem_usrio,
};
static const struct macb_config sama7g5_emac_config = {
.caps = MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII |
- MACB_CAPS_USRIO_HAS_CLKEN | MACB_CAPS_MIIONRGMII |
- MACB_CAPS_GEM_HAS_PTP,
+ MACB_CAPS_MIIONRGMII |
+ MACB_CAPS_USRIO_HAS_REFCLK_SOURCE |
+ MACB_CAPS_GEM_HAS_PTP |
+ MACB_CAPS_USRIO_HAS_MII,
.dma_burst_length = 16,
- .usrio = &sama7g5_usrio,
+ .usrio = &sama7g5_emac_usrio,
};
static const struct macb_config versal_config = {
.caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE | MACB_CAPS_JUMBO |
MACB_CAPS_GEM_HAS_PTP | MACB_CAPS_BD_RD_PREFETCH |
MACB_CAPS_NEED_TSUCLK | MACB_CAPS_QUEUE_DISABLE |
- MACB_CAPS_QBV,
+ MACB_CAPS_QBV |
+ MACB_CAPS_USRIO_HAS_MII,
.dma_burst_length = 16,
.init = init_reset_optional,
.jumbo_max_len = 10240,
+ .usrio = &at91_default_usrio,
};
static const struct macb_config eyeq5_config = {
@@ -5626,8 +5701,10 @@ static const struct macb_config raspberrypi_rp1_config = {
.caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE | MACB_CAPS_CLK_HW_CHG |
MACB_CAPS_JUMBO |
MACB_CAPS_GEM_HAS_PTP |
- MACB_CAPS_EEE,
+ MACB_CAPS_EEE |
+ MACB_CAPS_USRIO_HAS_MII,
.dma_burst_length = 16,
+ .usrio = &at91_default_usrio,
.jumbo_max_len = 10240,
};
@@ -5675,6 +5752,7 @@ static const struct macb_config default_gem_config = {
MACB_CAPS_JUMBO |
MACB_CAPS_GEM_HAS_PTP,
.dma_burst_length = 16,
+ .usrio = &at91_default_usrio,
.jumbo_max_len = 10240,
};
@@ -5761,7 +5839,14 @@ static int macb_probe(struct platform_device *pdev)
bp->wol = 0;
device_set_wakeup_capable(&pdev->dev, 1);
- bp->usrio = macb_config->usrio ? : &macb_default_usrio;
+ bp->usrio = macb_config->usrio;
+
+ if (of_property_read_bool(bp->pdev->dev.of_node, "cdns,timer-adjust") &&
+ IS_ENABLED(CONFIG_MACB_USE_HWSTAMP)) {
+ dev_err(&pdev->dev, "Timer adjust mode is not supported\n");
+ err = -EINVAL;
+ goto err_out_free_netdev;
+ }
/* By default we set to partial store and forward mode for zynqmp.
* Disable if not set in devicetree.