Merge branch 'macb-sama7g5'
Claudiu Beznea says: ==================== net: macb: add support for sama7g5 This series adds support for SAMA7G5 Ethernet interfaces: one 10/100Mbps and one 1Gbps interfaces. Along with it I also included a fix to disable clocks for SiFive FU540-C000 on failure path of fu540_c000_clk_init(). Thank you, Claudiu Beznea Changed in v3: - use clk_bulk_disable_unprepare in patch 3/8 - corrected clang compilation warning in patch 3/8 - revert changes in macb_clk_init() in patch 3/8 Changes in v2: - introduced patch "net: macb: add function to disable all macb clocks" and update patch "net: macb: unprepare clocks in case of failure" accordingly - collected tags ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
102779c6f8
@ -16,6 +16,8 @@ Required properties:
|
||||
Use "cdns,zynq-gem" Xilinx Zynq-7xxx SoC.
|
||||
Use "cdns,zynqmp-gem" for Zynq Ultrascale+ MPSoC.
|
||||
Use "sifive,fu540-c000-gem" for SiFive FU540-C000 SoC.
|
||||
Use "microchip,sama7g5-emac" for Microchip SAMA7G5 ethernet interface.
|
||||
Use "microchip,sama7g5-gem" for Microchip SAMA7G5 gigabit ethernet interface.
|
||||
Or the generic form: "cdns,emac".
|
||||
- reg: Address and length of the register set for the device
|
||||
For "sifive,fu540-c000-gem", second range is required to specify the
|
||||
|
@ -699,6 +699,7 @@
|
||||
#define MACB_CAPS_GEM_HAS_PTP 0x00000040
|
||||
#define MACB_CAPS_BD_RD_PREFETCH 0x00000080
|
||||
#define MACB_CAPS_NEEDS_RSTONUBR 0x00000100
|
||||
#define MACB_CAPS_CLK_HW_CHG 0x04000000
|
||||
#define MACB_CAPS_MACB_IS_EMAC 0x08000000
|
||||
#define MACB_CAPS_FIFO_MODE 0x10000000
|
||||
#define MACB_CAPS_GIGABIT_MODE_AVAILABLE 0x20000000
|
||||
@ -1147,6 +1148,14 @@ struct macb_pm_data {
|
||||
u32 usrio;
|
||||
};
|
||||
|
||||
struct macb_usrio_config {
|
||||
u32 mii;
|
||||
u32 rmii;
|
||||
u32 rgmii;
|
||||
u32 refclk;
|
||||
u32 hdfctlen;
|
||||
};
|
||||
|
||||
struct macb_config {
|
||||
u32 caps;
|
||||
unsigned int dma_burst_length;
|
||||
@ -1155,6 +1164,7 @@ struct macb_config {
|
||||
struct clk **rx_clk, struct clk **tsu_clk);
|
||||
int (*init)(struct platform_device *pdev);
|
||||
int jumbo_max_len;
|
||||
const struct macb_usrio_config *usrio;
|
||||
};
|
||||
|
||||
struct tsu_incr {
|
||||
@ -1288,6 +1298,7 @@ struct macb {
|
||||
u32 rx_intr_mask;
|
||||
|
||||
struct macb_pm_data pm_data;
|
||||
const struct macb_usrio_config *usrio;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_MACB_USE_HWSTAMP
|
||||
|
@ -460,15 +460,14 @@ static void macb_init_buffers(struct macb *bp)
|
||||
|
||||
/**
|
||||
* macb_set_tx_clk() - Set a clock to a new frequency
|
||||
* @clk: Pointer to the clock to change
|
||||
* @bp: pointer to struct macb
|
||||
* @speed: New frequency in Hz
|
||||
* @dev: Pointer to the struct net_device
|
||||
*/
|
||||
static void macb_set_tx_clk(struct clk *clk, int speed, struct net_device *dev)
|
||||
static void macb_set_tx_clk(struct macb *bp, int speed)
|
||||
{
|
||||
long ferr, rate, rate_rounded;
|
||||
|
||||
if (!clk)
|
||||
if (!bp->tx_clk || !(bp->caps & MACB_CAPS_CLK_HW_CHG))
|
||||
return;
|
||||
|
||||
switch (speed) {
|
||||
@ -485,7 +484,7 @@ static void macb_set_tx_clk(struct clk *clk, int speed, struct net_device *dev)
|
||||
return;
|
||||
}
|
||||
|
||||
rate_rounded = clk_round_rate(clk, rate);
|
||||
rate_rounded = clk_round_rate(bp->tx_clk, rate);
|
||||
if (rate_rounded < 0)
|
||||
return;
|
||||
|
||||
@ -495,11 +494,12 @@ static void macb_set_tx_clk(struct clk *clk, int speed, struct net_device *dev)
|
||||
ferr = abs(rate_rounded - rate);
|
||||
ferr = DIV_ROUND_UP(ferr, rate / 100000);
|
||||
if (ferr > 5)
|
||||
netdev_warn(dev, "unable to generate target frequency: %ld Hz\n",
|
||||
netdev_warn(bp->dev,
|
||||
"unable to generate target frequency: %ld Hz\n",
|
||||
rate);
|
||||
|
||||
if (clk_set_rate(clk, rate_rounded))
|
||||
netdev_err(dev, "adjusting tx_clk failed.\n");
|
||||
if (clk_set_rate(bp->tx_clk, rate_rounded))
|
||||
netdev_err(bp->dev, "adjusting tx_clk failed.\n");
|
||||
}
|
||||
|
||||
static void macb_validate(struct phylink_config *config,
|
||||
@ -751,7 +751,7 @@ static void macb_mac_link_up(struct phylink_config *config,
|
||||
if (rx_pause)
|
||||
ctrl |= MACB_BIT(PAE);
|
||||
|
||||
macb_set_tx_clk(bp->tx_clk, speed, ndev);
|
||||
macb_set_tx_clk(bp, speed);
|
||||
|
||||
/* Initialize rings & buffers as clearing MACB_BIT(TE) in link down
|
||||
* cleared the pipeline and control registers.
|
||||
@ -3694,6 +3694,20 @@ static void macb_probe_queues(void __iomem *mem,
|
||||
*num_queues = hweight32(*queue_mask);
|
||||
}
|
||||
|
||||
static void macb_clks_disable(struct clk *pclk, struct clk *hclk, struct clk *tx_clk,
|
||||
struct clk *rx_clk, struct clk *tsu_clk)
|
||||
{
|
||||
struct clk_bulk_data clks[] = {
|
||||
{ .clk = tsu_clk, },
|
||||
{ .clk = rx_clk, },
|
||||
{ .clk = pclk, },
|
||||
{ .clk = hclk, },
|
||||
{ .clk = tx_clk },
|
||||
};
|
||||
|
||||
clk_bulk_disable_unprepare(ARRAY_SIZE(clks), clks);
|
||||
}
|
||||
|
||||
static int macb_clk_init(struct platform_device *pdev, struct clk **pclk,
|
||||
struct clk **hclk, struct clk **tx_clk,
|
||||
struct clk **rx_clk, struct clk **tsu_clk)
|
||||
@ -3913,15 +3927,15 @@ static int macb_init(struct platform_device *pdev)
|
||||
if (!(bp->caps & MACB_CAPS_USRIO_DISABLED)) {
|
||||
val = 0;
|
||||
if (phy_interface_mode_is_rgmii(bp->phy_interface))
|
||||
val = GEM_BIT(RGMII);
|
||||
val = bp->usrio->rgmii;
|
||||
else if (bp->phy_interface == PHY_INTERFACE_MODE_RMII &&
|
||||
(bp->caps & MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII))
|
||||
val = MACB_BIT(RMII);
|
||||
val = bp->usrio->rmii;
|
||||
else if (!(bp->caps & MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII))
|
||||
val = MACB_BIT(MII);
|
||||
val = bp->usrio->mii;
|
||||
|
||||
if (bp->caps & MACB_CAPS_USRIO_HAS_CLKEN)
|
||||
val |= MACB_BIT(CLKEN);
|
||||
val |= bp->usrio->refclk;
|
||||
|
||||
macb_or_gem_writel(bp, USRIO, val);
|
||||
}
|
||||
@ -4406,8 +4420,10 @@ static int fu540_c000_clk_init(struct platform_device *pdev, struct clk **pclk,
|
||||
return err;
|
||||
|
||||
mgmt = devm_kzalloc(&pdev->dev, sizeof(*mgmt), GFP_KERNEL);
|
||||
if (!mgmt)
|
||||
return -ENOMEM;
|
||||
if (!mgmt) {
|
||||
err = -ENOMEM;
|
||||
goto err_disable_clks;
|
||||
}
|
||||
|
||||
init.name = "sifive-gemgxl-mgmt";
|
||||
init.ops = &fu540_c000_ops;
|
||||
@ -4418,16 +4434,26 @@ static int fu540_c000_clk_init(struct platform_device *pdev, struct clk **pclk,
|
||||
mgmt->hw.init = &init;
|
||||
|
||||
*tx_clk = devm_clk_register(&pdev->dev, &mgmt->hw);
|
||||
if (IS_ERR(*tx_clk))
|
||||
return PTR_ERR(*tx_clk);
|
||||
if (IS_ERR(*tx_clk)) {
|
||||
err = PTR_ERR(*tx_clk);
|
||||
goto err_disable_clks;
|
||||
}
|
||||
|
||||
err = clk_prepare_enable(*tx_clk);
|
||||
if (err)
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "failed to enable tx_clk (%u)\n", err);
|
||||
else
|
||||
*tx_clk = NULL;
|
||||
goto err_disable_clks;
|
||||
} else {
|
||||
dev_info(&pdev->dev, "Registered clk switch '%s'\n", init.name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_disable_clks:
|
||||
macb_clks_disable(*pclk, *hclk, *tx_clk, *rx_clk, *tsu_clk);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int fu540_c000_init(struct platform_device *pdev)
|
||||
@ -4439,6 +4465,21 @@ static int fu540_c000_init(struct platform_device *pdev)
|
||||
return macb_init(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),
|
||||
};
|
||||
|
||||
static const struct macb_usrio_config sama7g5_usrio = {
|
||||
.mii = 0,
|
||||
.rmii = 1,
|
||||
.rgmii = 2,
|
||||
.refclk = BIT(2),
|
||||
.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,
|
||||
@ -4446,12 +4487,14 @@ static const struct macb_config fu540_c000_config = {
|
||||
.clk_init = fu540_c000_clk_init,
|
||||
.init = fu540_c000_init,
|
||||
.jumbo_max_len = 10240,
|
||||
.usrio = &macb_default_usrio,
|
||||
};
|
||||
|
||||
static const struct macb_config at91sam9260_config = {
|
||||
.caps = MACB_CAPS_USRIO_HAS_CLKEN | MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII,
|
||||
.clk_init = macb_clk_init,
|
||||
.init = macb_init,
|
||||
.usrio = &macb_default_usrio,
|
||||
};
|
||||
|
||||
static const struct macb_config sama5d3macb_config = {
|
||||
@ -4459,6 +4502,7 @@ static const struct macb_config sama5d3macb_config = {
|
||||
| MACB_CAPS_USRIO_HAS_CLKEN | MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII,
|
||||
.clk_init = macb_clk_init,
|
||||
.init = macb_init,
|
||||
.usrio = &macb_default_usrio,
|
||||
};
|
||||
|
||||
static const struct macb_config pc302gem_config = {
|
||||
@ -4466,6 +4510,7 @@ static const struct macb_config pc302gem_config = {
|
||||
.dma_burst_length = 16,
|
||||
.clk_init = macb_clk_init,
|
||||
.init = macb_init,
|
||||
.usrio = &macb_default_usrio,
|
||||
};
|
||||
|
||||
static const struct macb_config sama5d2_config = {
|
||||
@ -4473,6 +4518,7 @@ static const struct macb_config sama5d2_config = {
|
||||
.dma_burst_length = 16,
|
||||
.clk_init = macb_clk_init,
|
||||
.init = macb_init,
|
||||
.usrio = &macb_default_usrio,
|
||||
};
|
||||
|
||||
static const struct macb_config sama5d3_config = {
|
||||
@ -4482,6 +4528,7 @@ static const struct macb_config sama5d3_config = {
|
||||
.clk_init = macb_clk_init,
|
||||
.init = macb_init,
|
||||
.jumbo_max_len = 10240,
|
||||
.usrio = &macb_default_usrio,
|
||||
};
|
||||
|
||||
static const struct macb_config sama5d4_config = {
|
||||
@ -4489,18 +4536,21 @@ static const struct macb_config sama5d4_config = {
|
||||
.dma_burst_length = 4,
|
||||
.clk_init = macb_clk_init,
|
||||
.init = macb_init,
|
||||
.usrio = &macb_default_usrio,
|
||||
};
|
||||
|
||||
static const struct macb_config emac_config = {
|
||||
.caps = MACB_CAPS_NEEDS_RSTONUBR | MACB_CAPS_MACB_IS_EMAC,
|
||||
.clk_init = at91ether_clk_init,
|
||||
.init = at91ether_init,
|
||||
.usrio = &macb_default_usrio,
|
||||
};
|
||||
|
||||
static const struct macb_config np4_config = {
|
||||
.caps = MACB_CAPS_USRIO_DISABLED,
|
||||
.clk_init = macb_clk_init,
|
||||
.init = macb_init,
|
||||
.usrio = &macb_default_usrio,
|
||||
};
|
||||
|
||||
static const struct macb_config zynqmp_config = {
|
||||
@ -4511,6 +4561,7 @@ static const struct macb_config zynqmp_config = {
|
||||
.clk_init = macb_clk_init,
|
||||
.init = macb_init,
|
||||
.jumbo_max_len = 10240,
|
||||
.usrio = &macb_default_usrio,
|
||||
};
|
||||
|
||||
static const struct macb_config zynq_config = {
|
||||
@ -4519,6 +4570,23 @@ static const struct macb_config zynq_config = {
|
||||
.dma_burst_length = 16,
|
||||
.clk_init = macb_clk_init,
|
||||
.init = macb_init,
|
||||
.usrio = &macb_default_usrio,
|
||||
};
|
||||
|
||||
static const struct macb_config sama7g5_gem_config = {
|
||||
.caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE | MACB_CAPS_CLK_HW_CHG,
|
||||
.dma_burst_length = 16,
|
||||
.clk_init = macb_clk_init,
|
||||
.init = macb_init,
|
||||
.usrio = &sama7g5_usrio,
|
||||
};
|
||||
|
||||
static const struct macb_config sama7g5_emac_config = {
|
||||
.caps = MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII | MACB_CAPS_USRIO_HAS_CLKEN,
|
||||
.dma_burst_length = 16,
|
||||
.clk_init = macb_clk_init,
|
||||
.init = macb_init,
|
||||
.usrio = &sama7g5_usrio,
|
||||
};
|
||||
|
||||
static const struct of_device_id macb_dt_ids[] = {
|
||||
@ -4538,6 +4606,8 @@ static const struct of_device_id macb_dt_ids[] = {
|
||||
{ .compatible = "cdns,zynqmp-gem", .data = &zynqmp_config},
|
||||
{ .compatible = "cdns,zynq-gem", .data = &zynq_config },
|
||||
{ .compatible = "sifive,fu540-c000-gem", .data = &fu540_c000_config },
|
||||
{ .compatible = "microchip,sama7g5-gem", .data = &sama7g5_gem_config },
|
||||
{ .compatible = "microchip,sama7g5-emac", .data = &sama7g5_emac_config },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, macb_dt_ids);
|
||||
@ -4640,6 +4710,8 @@ static int macb_probe(struct platform_device *pdev)
|
||||
bp->wol |= MACB_WOL_HAS_MAGIC_PACKET;
|
||||
device_set_wakeup_capable(&pdev->dev, bp->wol & MACB_WOL_HAS_MAGIC_PACKET);
|
||||
|
||||
bp->usrio = macb_config->usrio;
|
||||
|
||||
spin_lock_init(&bp->lock);
|
||||
|
||||
/* setup capabilities */
|
||||
@ -4735,11 +4807,7 @@ err_out_free_netdev:
|
||||
free_netdev(dev);
|
||||
|
||||
err_disable_clocks:
|
||||
clk_disable_unprepare(tx_clk);
|
||||
clk_disable_unprepare(hclk);
|
||||
clk_disable_unprepare(pclk);
|
||||
clk_disable_unprepare(rx_clk);
|
||||
clk_disable_unprepare(tsu_clk);
|
||||
macb_clks_disable(pclk, hclk, tx_clk, rx_clk, tsu_clk);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
pm_runtime_set_suspended(&pdev->dev);
|
||||
pm_runtime_dont_use_autosuspend(&pdev->dev);
|
||||
@ -4764,11 +4832,8 @@ static int macb_remove(struct platform_device *pdev)
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
pm_runtime_dont_use_autosuspend(&pdev->dev);
|
||||
if (!pm_runtime_suspended(&pdev->dev)) {
|
||||
clk_disable_unprepare(bp->tx_clk);
|
||||
clk_disable_unprepare(bp->hclk);
|
||||
clk_disable_unprepare(bp->pclk);
|
||||
clk_disable_unprepare(bp->rx_clk);
|
||||
clk_disable_unprepare(bp->tsu_clk);
|
||||
macb_clks_disable(bp->pclk, bp->hclk, bp->tx_clk,
|
||||
bp->rx_clk, bp->tsu_clk);
|
||||
pm_runtime_set_suspended(&pdev->dev);
|
||||
}
|
||||
phylink_destroy(bp->phylink);
|
||||
@ -4947,13 +5012,10 @@ static int __maybe_unused macb_runtime_suspend(struct device *dev)
|
||||
struct net_device *netdev = dev_get_drvdata(dev);
|
||||
struct macb *bp = netdev_priv(netdev);
|
||||
|
||||
if (!(device_may_wakeup(dev))) {
|
||||
clk_disable_unprepare(bp->tx_clk);
|
||||
clk_disable_unprepare(bp->hclk);
|
||||
clk_disable_unprepare(bp->pclk);
|
||||
clk_disable_unprepare(bp->rx_clk);
|
||||
}
|
||||
clk_disable_unprepare(bp->tsu_clk);
|
||||
if (!(device_may_wakeup(dev)))
|
||||
macb_clks_disable(bp->pclk, bp->hclk, bp->tx_clk, bp->rx_clk, bp->tsu_clk);
|
||||
else
|
||||
macb_clks_disable(NULL, NULL, NULL, NULL, bp->tsu_clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user