ravb: Use separate clock for gPTP
authorPhil Edworthy <phil.edworthy@renesas.com>
Thu, 12 May 2022 11:47:21 +0000 (12:47 +0100)
committerDavid S. Miller <davem@davemloft.net>
Mon, 16 May 2022 09:14:27 +0000 (10:14 +0100)
RZ/V2M has a separate gPTP reference clock that is used when the
AVB-DMAC Mode Register (CCC) gPTP Clock Select (CSEL) bits are
set to "01: High-speed peripheral bus clock".
Therefore, add a feature that allows this clock to be used for
gPTP.

Signed-off-by: Phil Edworthy <phil.edworthy@renesas.com>
Reviewed-by: Biju Das <biju.das.jz@bp.renesas.com>
Reviewed-by: Sergey Shtylyov <s.shtylyov@omp.ru>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/renesas/ravb.h
drivers/net/ethernet/renesas/ravb_main.c

index e505e80..b980bce 100644 (file)
@@ -1031,6 +1031,7 @@ struct ravb_hw_info {
        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 */
@@ -1042,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];
index 8ccc817..9d281f7 100644 (file)
@@ -2495,11 +2495,15 @@ 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;
 
-       rate = clk_get_rate(priv->clk);
+       if (info->gptp_ref_clk)
+               rate = clk_get_rate(priv->gptp_clk);
+       else
+               rate = clk_get_rate(priv->clk);
        if (!rate)
                return -EINVAL;
 
@@ -2721,6 +2725,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;
 
@@ -2742,7 +2755,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);
@@ -2762,7 +2775,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;
@@ -2825,6 +2838,8 @@ out_dma_free:
        /* 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:
@@ -2846,6 +2861,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,