Commit 5cf15ce3 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'Renesas-RSZ-V2M-support'



Phil Edworthy says:

====================
Add Renesas RZ/V2M Ethernet support

The RZ/V2M Ethernet is very similar to R-Car Gen3 Ethernet-AVB, though
some small parts are the same as R-Car Gen2.
Other differences are:
* It has separate data (DI), error (Line 1) and management (Line 2) irqs
  rather than one irq for all three.
* Instead of using the High-speed peripheral bus clock for gPTP, it has
  a separate gPTP reference clock.

v4:
 * Add clk_disable_unprepare() for gptp ref clk

v3:
 * Really renamed irq_en_dis_regs to irq_en_dis this time
 * Modified ravb_ptp_extts() to use irq_en_dis
 * Added Reviewed-by tags

v2:
 * Just net patches in this series
 * Instead of reusing ch22 and ch24 interrupt names, use the proper names
 * Renamed irq_en_dis_regs to irq_en_dis
 * Squashed use of GIC reg versus GIE/GID and got rid of separate gptp_ptm_gic feature.
 * Move err_mgmt_irqs code under multi_irqs
 * Minor editing of the commit msgs
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 1a01a075 e1154be7
Loading
Loading
Loading
Loading
+61 −21
Original line number Diff line number Diff line
@@ -43,6 +43,11 @@ properties:
              - renesas,etheravb-r8a779a0     # R-Car V3U
          - const: renesas,etheravb-rcar-gen3 # R-Car Gen3 and RZ/G2

      - items:
          - enum:
              - renesas,etheravb-r9a09g011 # RZ/V2M
          - const: renesas,etheravb-rzv2m  # RZ/V2M compatible

      - items:
          - enum:
              - renesas,r9a07g043-gbeth # RZ/G2UL
@@ -159,6 +164,23 @@ allOf:
            - const: fil
            - const: arp_ns
        rx-internal-delay-ps: false
    else:
      if:
        properties:
          compatible:
            contains:
              const: renesas,etheravb-rzv2m
      then:
        properties:
          interrupts:
            minItems: 29
            maxItems: 29
          interrupt-names:
            items:
              pattern: '^(ch(1?)[0-9])|ch20|ch21|dia|dib|err_a|err_b|mgmt_a|mgmt_b|line3$'
          rx-internal-delay-ps: false
        required:
          - interrupt-names
      else:
        properties:
          interrupts:
@@ -230,6 +252,24 @@ allOf:
            - const: axi
            - const: chi
            - const: refclk
    else:
      if:
        properties:
          compatible:
            contains:
              const: renesas,etheravb-rzv2m
      then:
        properties:
          clocks:
            items:
              - description: Main clock
              - description: Coherent Hub Interface clock
              - description: gPTP reference clock
          clock-names:
            items:
              - const: axi
              - const: chi
              - const: gptp
      else:
        properties:
          clocks:
+6 −0
Original line number Diff line number Diff line
@@ -1027,8 +1027,11 @@ struct ravb_hw_info {
	unsigned tx_counters:1;		/* E-MAC has TX counters */
	unsigned carrier_counters:1;	/* E-MAC has carrier counters */
	unsigned multi_irqs:1;		/* AVB-DMAC and E-MAC has multiple irqs */
	unsigned irq_en_dis:1;		/* Has separate irq enable and disable regs */
	unsigned err_mgmt_irqs:1;	/* Line1 (Err) and Line2 (Mgmt) irqs are separate */
	unsigned gptp:1;		/* AVB-DMAC has gPTP support */
	unsigned ccc_gac:1;		/* AVB-DMAC has gPTP support active in config mode */
	unsigned gptp_ref_clk:1;	/* gPTP has separate reference clock */
	unsigned nc_queues:1;		/* AVB-DMAC has RX and TX NC queues */
	unsigned magic_pkt:1;		/* E-MAC supports magic packet detection */
	unsigned half_duplex:1;		/* E-MAC supports half duplex mode */
@@ -1040,6 +1043,7 @@ struct ravb_private {
	void __iomem *addr;
	struct clk *clk;
	struct clk *refclk;
	struct clk *gptp_clk;
	struct mdiobb_ctrl mdiobb;
	u32 num_rx_ring[NUM_RX_QUEUE];
	u32 num_tx_ring[NUM_TX_QUEUE];
@@ -1077,6 +1081,8 @@ struct ravb_private {
	int msg_enable;
	int speed;
	int emac_irq;
	int erra_irq;
	int mgmta_irq;
	int rx_irqs[NUM_RX_QUEUE];
	int tx_irqs[NUM_TX_QUEUE];

+98 −11
Original line number Diff line number Diff line
@@ -1124,7 +1124,7 @@ static bool ravb_queue_interrupt(struct net_device *ndev, int q)
	if (((ris0 & ric0) & BIT(q)) || ((tis  & tic)  & BIT(q))) {
		if (napi_schedule_prep(&priv->napi[q])) {
			/* Mask RX and TX interrupts */
			if (!info->multi_irqs) {
			if (!info->irq_en_dis) {
				ravb_write(ndev, ric0 & ~BIT(q), RIC0);
				ravb_write(ndev, tic & ~BIT(q), TIC);
			} else {
@@ -1306,7 +1306,7 @@ static int ravb_poll(struct napi_struct *napi, int budget)

	/* Re-enable RX/TX interrupts */
	spin_lock_irqsave(&priv->lock, flags);
	if (!info->multi_irqs) {
	if (!info->irq_en_dis) {
		ravb_modify(ndev, RIC0, mask, mask);
		ravb_modify(ndev, TIC,  mask, mask);
	} else {
@@ -1798,12 +1798,23 @@ static int ravb_open(struct net_device *ndev)
				      ndev, dev, "ch19:tx_nc");
		if (error)
			goto out_free_irq_nc_rx;

		if (info->err_mgmt_irqs) {
			error = ravb_hook_irq(priv->erra_irq, ravb_multi_interrupt,
					      ndev, dev, "err_a");
			if (error)
				goto out_free_irq_nc_tx;
			error = ravb_hook_irq(priv->mgmta_irq, ravb_multi_interrupt,
					      ndev, dev, "mgmt_a");
			if (error)
				goto out_free_irq_erra;
		}
	}

	/* Device init */
	error = ravb_dmac_init(ndev);
	if (error)
		goto out_free_irq_nc_tx;
		goto out_free_irq_mgmta;
	ravb_emac_init(ndev);

	/* Initialise PTP Clock driver */
@@ -1823,9 +1834,15 @@ static int ravb_open(struct net_device *ndev)
	/* Stop PTP Clock driver */
	if (info->gptp)
		ravb_ptp_stop(ndev);
out_free_irq_nc_tx:
out_free_irq_mgmta:
	if (!info->multi_irqs)
		goto out_free_irq;
	if (info->err_mgmt_irqs)
		free_irq(priv->mgmta_irq, ndev);
out_free_irq_erra:
	if (info->err_mgmt_irqs)
		free_irq(priv->erra_irq, ndev);
out_free_irq_nc_tx:
	free_irq(priv->tx_irqs[RAVB_NC], ndev);
out_free_irq_nc_rx:
	free_irq(priv->rx_irqs[RAVB_NC], ndev);
@@ -2166,6 +2183,10 @@ static int ravb_close(struct net_device *ndev)
		free_irq(priv->tx_irqs[RAVB_BE], ndev);
		free_irq(priv->rx_irqs[RAVB_BE], ndev);
		free_irq(priv->emac_irq, ndev);
		if (info->err_mgmt_irqs) {
			free_irq(priv->erra_irq, ndev);
			free_irq(priv->mgmta_irq, ndev);
		}
	}
	free_irq(ndev->irq, ndev);

@@ -2410,6 +2431,7 @@ static const struct ravb_hw_info ravb_gen3_hw_info = {
	.internal_delay = 1,
	.tx_counters = 1,
	.multi_irqs = 1,
	.irq_en_dis = 1,
	.ccc_gac = 1,
	.nc_queues = 1,
	.magic_pkt = 1,
@@ -2438,6 +2460,31 @@ static const struct ravb_hw_info ravb_gen2_hw_info = {
	.magic_pkt = 1,
};

static const struct ravb_hw_info ravb_rzv2m_hw_info = {
	.rx_ring_free = ravb_rx_ring_free_rcar,
	.rx_ring_format = ravb_rx_ring_format_rcar,
	.alloc_rx_desc = ravb_alloc_rx_desc_rcar,
	.receive = ravb_rx_rcar,
	.set_rate = ravb_set_rate_rcar,
	.set_feature = ravb_set_features_rcar,
	.dmac_init = ravb_dmac_init_rcar,
	.emac_init = ravb_emac_init_rcar,
	.gstrings_stats = ravb_gstrings_stats,
	.gstrings_size = sizeof(ravb_gstrings_stats),
	.net_hw_features = NETIF_F_RXCSUM,
	.net_features = NETIF_F_RXCSUM,
	.stats_len = ARRAY_SIZE(ravb_gstrings_stats),
	.max_rx_len = RX_BUF_SZ + RAVB_ALIGN - 1,
	.tccr_mask = TCCR_TSRQ0 | TCCR_TSRQ1 | TCCR_TSRQ2 | TCCR_TSRQ3,
	.rx_max_buf_size = SZ_2K,
	.multi_irqs = 1,
	.err_mgmt_irqs = 1,
	.gptp = 1,
	.gptp_ref_clk = 1,
	.nc_queues = 1,
	.magic_pkt = 1,
};

static const struct ravb_hw_info gbeth_hw_info = {
	.rx_ring_free = ravb_rx_ring_free_gbeth,
	.rx_ring_format = ravb_rx_ring_format_gbeth,
@@ -2465,6 +2512,7 @@ static const struct of_device_id ravb_match_table[] = {
	{ .compatible = "renesas,etheravb-rcar-gen2", .data = &ravb_gen2_hw_info },
	{ .compatible = "renesas,etheravb-r8a7795", .data = &ravb_gen3_hw_info },
	{ .compatible = "renesas,etheravb-rcar-gen3", .data = &ravb_gen3_hw_info },
	{ .compatible = "renesas,etheravb-rzv2m", .data = &ravb_rzv2m_hw_info },
	{ .compatible = "renesas,rzg2l-gbeth", .data = &gbeth_hw_info },
	{ }
};
@@ -2473,10 +2521,14 @@ MODULE_DEVICE_TABLE(of, ravb_match_table);
static int ravb_set_gti(struct net_device *ndev)
{
	struct ravb_private *priv = netdev_priv(ndev);
	const struct ravb_hw_info *info = priv->info;
	struct device *dev = ndev->dev.parent;
	unsigned long rate;
	uint64_t inc;

	if (info->gptp_ref_clk)
		rate = clk_get_rate(priv->gptp_clk);
	else
		rate = clk_get_rate(priv->clk);
	if (!rate)
		return -EINVAL;
@@ -2594,10 +2646,14 @@ static int ravb_probe(struct platform_device *pdev)
	pm_runtime_enable(&pdev->dev);
	pm_runtime_get_sync(&pdev->dev);

	if (info->multi_irqs)
		irq = platform_get_irq_byname(pdev, "ch22");
	if (info->multi_irqs) {
		if (info->err_mgmt_irqs)
			irq = platform_get_irq_byname(pdev, "dia");
		else
			irq = platform_get_irq_byname(pdev, "ch22");
	} else {
		irq = platform_get_irq(pdev, 0);
	}
	if (irq < 0) {
		error = irq;
		goto out_release;
@@ -2639,6 +2695,9 @@ static int ravb_probe(struct platform_device *pdev)
		of_property_read_bool(np, "renesas,ether-link-active-low");

	if (info->multi_irqs) {
		if (info->err_mgmt_irqs)
			irq = platform_get_irq_byname(pdev, "line3");
		else
			irq = platform_get_irq_byname(pdev, "ch24");
		if (irq < 0) {
			error = irq;
@@ -2661,6 +2720,22 @@ static int ravb_probe(struct platform_device *pdev)
			}
			priv->tx_irqs[i] = irq;
		}

		if (info->err_mgmt_irqs) {
			irq = platform_get_irq_byname(pdev, "err_a");
			if (irq < 0) {
				error = irq;
				goto out_release;
			}
			priv->erra_irq = irq;

			irq = platform_get_irq_byname(pdev, "mgmt_a");
			if (irq < 0) {
				error = irq;
				goto out_release;
			}
			priv->mgmta_irq = irq;
		}
	}

	priv->clk = devm_clk_get(&pdev->dev, NULL);
@@ -2676,6 +2751,15 @@ static int ravb_probe(struct platform_device *pdev)
	}
	clk_prepare_enable(priv->refclk);

	if (info->gptp_ref_clk) {
		priv->gptp_clk = devm_clk_get(&pdev->dev, "gptp");
		if (IS_ERR(priv->gptp_clk)) {
			error = PTR_ERR(priv->gptp_clk);
			goto out_disable_refclk;
		}
		clk_prepare_enable(priv->gptp_clk);
	}

	ndev->max_mtu = info->rx_max_buf_size - (ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN);
	ndev->min_mtu = ETH_MIN_MTU;

@@ -2697,7 +2781,7 @@ static int ravb_probe(struct platform_device *pdev)
		/* Set GTI value */
		error = ravb_set_gti(ndev);
		if (error)
			goto out_disable_refclk;
			goto out_disable_gptp_clk;

		/* Request GTI loading */
		ravb_modify(ndev, GCCR, GCCR_LTI, GCCR_LTI);
@@ -2717,7 +2801,7 @@ static int ravb_probe(struct platform_device *pdev)
			"Cannot allocate desc base address table (size %d bytes)\n",
			priv->desc_bat_size);
		error = -ENOMEM;
		goto out_disable_refclk;
		goto out_disable_gptp_clk;
	}
	for (q = RAVB_BE; q < DBAT_ENTRY_NUM; q++)
		priv->desc_bat[q].die_dt = DT_EOS;
@@ -2780,6 +2864,8 @@ static int ravb_probe(struct platform_device *pdev)
	/* Stop PTP Clock driver */
	if (info->ccc_gac)
		ravb_ptp_stop(ndev);
out_disable_gptp_clk:
	clk_disable_unprepare(priv->gptp_clk);
out_disable_refclk:
	clk_disable_unprepare(priv->refclk);
out_release:
@@ -2801,6 +2887,7 @@ static int ravb_remove(struct platform_device *pdev)
	if (info->ccc_gac)
		ravb_ptp_stop(ndev);

	clk_disable_unprepare(priv->gptp_clk);
	clk_disable_unprepare(priv->refclk);

	dma_free_coherent(ndev->dev.parent, priv->desc_bat_size, priv->desc_bat,
+3 −3
Original line number Diff line number Diff line
@@ -198,7 +198,7 @@ static int ravb_ptp_extts(struct ptp_clock_info *ptp,
	priv->ptp.extts[req->index] = on;

	spin_lock_irqsave(&priv->lock, flags);
	if (!info->multi_irqs)
	if (!info->irq_en_dis)
		ravb_modify(ndev, GIC, GIC_PTCE, on ? GIC_PTCE : 0);
	else if (on)
		ravb_write(ndev, GIE_PTCS, GIE);
@@ -254,7 +254,7 @@ static int ravb_ptp_perout(struct ptp_clock_info *ptp,
		error = ravb_ptp_update_compare(priv, (u32)start_ns);
		if (!error) {
			/* Unmask interrupt */
			if (!info->multi_irqs)
			if (!info->irq_en_dis)
				ravb_modify(ndev, GIC, GIC_PTME, GIC_PTME);
			else
				ravb_write(ndev, GIE_PTMS0, GIE);
@@ -266,7 +266,7 @@ static int ravb_ptp_perout(struct ptp_clock_info *ptp,
		perout->period = 0;

		/* Mask interrupt */
		if (!info->multi_irqs)
		if (!info->irq_en_dis)
			ravb_modify(ndev, GIC, GIC_PTME, 0);
		else
			ravb_write(ndev, GID_PTMD0, GID);