Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /* PTP 1588 clock using the Renesas Ethernet AVB
0003  *
0004  * Copyright (C) 2013-2015 Renesas Electronics Corporation
0005  * Copyright (C) 2015 Renesas Solutions Corp.
0006  * Copyright (C) 2015-2016 Cogent Embedded, Inc. <source@cogentembedded.com>
0007  */
0008 
0009 #include "ravb.h"
0010 
0011 static int ravb_ptp_tcr_request(struct ravb_private *priv, u32 request)
0012 {
0013     struct net_device *ndev = priv->ndev;
0014     int error;
0015 
0016     error = ravb_wait(ndev, GCCR, GCCR_TCR, GCCR_TCR_NOREQ);
0017     if (error)
0018         return error;
0019 
0020     ravb_modify(ndev, GCCR, request, request);
0021     return ravb_wait(ndev, GCCR, GCCR_TCR, GCCR_TCR_NOREQ);
0022 }
0023 
0024 /* Caller must hold the lock */
0025 static int ravb_ptp_time_read(struct ravb_private *priv, struct timespec64 *ts)
0026 {
0027     struct net_device *ndev = priv->ndev;
0028     int error;
0029 
0030     error = ravb_ptp_tcr_request(priv, GCCR_TCR_CAPTURE);
0031     if (error)
0032         return error;
0033 
0034     ts->tv_nsec = ravb_read(ndev, GCT0);
0035     ts->tv_sec  = ravb_read(ndev, GCT1) |
0036         ((s64)ravb_read(ndev, GCT2) << 32);
0037 
0038     return 0;
0039 }
0040 
0041 /* Caller must hold the lock */
0042 static int ravb_ptp_time_write(struct ravb_private *priv,
0043                 const struct timespec64 *ts)
0044 {
0045     struct net_device *ndev = priv->ndev;
0046     int error;
0047     u32 gccr;
0048 
0049     error = ravb_ptp_tcr_request(priv, GCCR_TCR_RESET);
0050     if (error)
0051         return error;
0052 
0053     gccr = ravb_read(ndev, GCCR);
0054     if (gccr & GCCR_LTO)
0055         return -EBUSY;
0056     ravb_write(ndev, ts->tv_nsec, GTO0);
0057     ravb_write(ndev, ts->tv_sec,  GTO1);
0058     ravb_write(ndev, (ts->tv_sec >> 32) & 0xffff, GTO2);
0059     ravb_write(ndev, gccr | GCCR_LTO, GCCR);
0060 
0061     return 0;
0062 }
0063 
0064 /* Caller must hold the lock */
0065 static int ravb_ptp_update_compare(struct ravb_private *priv, u32 ns)
0066 {
0067     struct net_device *ndev = priv->ndev;
0068     /* When the comparison value (GPTC.PTCV) is in range of
0069      * [x-1 to x+1] (x is the configured increment value in
0070      * GTI.TIV), it may happen that a comparison match is
0071      * not detected when the timer wraps around.
0072      */
0073     u32 gti_ns_plus_1 = (priv->ptp.current_addend >> 20) + 1;
0074     u32 gccr;
0075 
0076     if (ns < gti_ns_plus_1)
0077         ns = gti_ns_plus_1;
0078     else if (ns > 0 - gti_ns_plus_1)
0079         ns = 0 - gti_ns_plus_1;
0080 
0081     gccr = ravb_read(ndev, GCCR);
0082     if (gccr & GCCR_LPTC)
0083         return -EBUSY;
0084     ravb_write(ndev, ns, GPTC);
0085     ravb_write(ndev, gccr | GCCR_LPTC, GCCR);
0086 
0087     return 0;
0088 }
0089 
0090 /* PTP clock operations */
0091 static int ravb_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
0092 {
0093     struct ravb_private *priv = container_of(ptp, struct ravb_private,
0094                          ptp.info);
0095     struct net_device *ndev = priv->ndev;
0096     unsigned long flags;
0097     u32 diff, addend;
0098     bool neg_adj = false;
0099     u32 gccr;
0100 
0101     if (ppb < 0) {
0102         neg_adj = true;
0103         ppb = -ppb;
0104     }
0105     addend = priv->ptp.default_addend;
0106     diff = div_u64((u64)addend * ppb, NSEC_PER_SEC);
0107 
0108     addend = neg_adj ? addend - diff : addend + diff;
0109 
0110     spin_lock_irqsave(&priv->lock, flags);
0111 
0112     priv->ptp.current_addend = addend;
0113 
0114     gccr = ravb_read(ndev, GCCR);
0115     if (gccr & GCCR_LTI) {
0116         spin_unlock_irqrestore(&priv->lock, flags);
0117         return -EBUSY;
0118     }
0119     ravb_write(ndev, addend & GTI_TIV, GTI);
0120     ravb_write(ndev, gccr | GCCR_LTI, GCCR);
0121 
0122     spin_unlock_irqrestore(&priv->lock, flags);
0123 
0124     return 0;
0125 }
0126 
0127 static int ravb_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
0128 {
0129     struct ravb_private *priv = container_of(ptp, struct ravb_private,
0130                          ptp.info);
0131     struct timespec64 ts;
0132     unsigned long flags;
0133     int error;
0134 
0135     spin_lock_irqsave(&priv->lock, flags);
0136     error = ravb_ptp_time_read(priv, &ts);
0137     if (!error) {
0138         u64 now = ktime_to_ns(timespec64_to_ktime(ts));
0139 
0140         ts = ns_to_timespec64(now + delta);
0141         error = ravb_ptp_time_write(priv, &ts);
0142     }
0143     spin_unlock_irqrestore(&priv->lock, flags);
0144 
0145     return error;
0146 }
0147 
0148 static int ravb_ptp_gettime64(struct ptp_clock_info *ptp, struct timespec64 *ts)
0149 {
0150     struct ravb_private *priv = container_of(ptp, struct ravb_private,
0151                          ptp.info);
0152     unsigned long flags;
0153     int error;
0154 
0155     spin_lock_irqsave(&priv->lock, flags);
0156     error = ravb_ptp_time_read(priv, ts);
0157     spin_unlock_irqrestore(&priv->lock, flags);
0158 
0159     return error;
0160 }
0161 
0162 static int ravb_ptp_settime64(struct ptp_clock_info *ptp,
0163                   const struct timespec64 *ts)
0164 {
0165     struct ravb_private *priv = container_of(ptp, struct ravb_private,
0166                          ptp.info);
0167     unsigned long flags;
0168     int error;
0169 
0170     spin_lock_irqsave(&priv->lock, flags);
0171     error = ravb_ptp_time_write(priv, ts);
0172     spin_unlock_irqrestore(&priv->lock, flags);
0173 
0174     return error;
0175 }
0176 
0177 static int ravb_ptp_extts(struct ptp_clock_info *ptp,
0178               struct ptp_extts_request *req, int on)
0179 {
0180     struct ravb_private *priv = container_of(ptp, struct ravb_private,
0181                          ptp.info);
0182     const struct ravb_hw_info *info = priv->info;
0183     struct net_device *ndev = priv->ndev;
0184     unsigned long flags;
0185 
0186     /* Reject requests with unsupported flags */
0187     if (req->flags & ~(PTP_ENABLE_FEATURE |
0188                PTP_RISING_EDGE |
0189                PTP_FALLING_EDGE |
0190                PTP_STRICT_FLAGS))
0191         return -EOPNOTSUPP;
0192 
0193     if (req->index)
0194         return -EINVAL;
0195 
0196     if (priv->ptp.extts[req->index] == on)
0197         return 0;
0198     priv->ptp.extts[req->index] = on;
0199 
0200     spin_lock_irqsave(&priv->lock, flags);
0201     if (!info->irq_en_dis)
0202         ravb_modify(ndev, GIC, GIC_PTCE, on ? GIC_PTCE : 0);
0203     else if (on)
0204         ravb_write(ndev, GIE_PTCS, GIE);
0205     else
0206         ravb_write(ndev, GID_PTCD, GID);
0207     spin_unlock_irqrestore(&priv->lock, flags);
0208 
0209     return 0;
0210 }
0211 
0212 static int ravb_ptp_perout(struct ptp_clock_info *ptp,
0213                struct ptp_perout_request *req, int on)
0214 {
0215     struct ravb_private *priv = container_of(ptp, struct ravb_private,
0216                          ptp.info);
0217     const struct ravb_hw_info *info = priv->info;
0218     struct net_device *ndev = priv->ndev;
0219     struct ravb_ptp_perout *perout;
0220     unsigned long flags;
0221     int error = 0;
0222 
0223     /* Reject requests with unsupported flags */
0224     if (req->flags)
0225         return -EOPNOTSUPP;
0226 
0227     if (req->index)
0228         return -EINVAL;
0229 
0230     if (on) {
0231         u64 start_ns;
0232         u64 period_ns;
0233 
0234         start_ns = req->start.sec * NSEC_PER_SEC + req->start.nsec;
0235         period_ns = req->period.sec * NSEC_PER_SEC + req->period.nsec;
0236 
0237         if (start_ns > U32_MAX) {
0238             netdev_warn(ndev,
0239                     "ptp: start value (nsec) is over limit. Maximum size of start is only 32 bits\n");
0240             return -ERANGE;
0241         }
0242 
0243         if (period_ns > U32_MAX) {
0244             netdev_warn(ndev,
0245                     "ptp: period value (nsec) is over limit. Maximum size of period is only 32 bits\n");
0246             return -ERANGE;
0247         }
0248 
0249         spin_lock_irqsave(&priv->lock, flags);
0250 
0251         perout = &priv->ptp.perout[req->index];
0252         perout->target = (u32)start_ns;
0253         perout->period = (u32)period_ns;
0254         error = ravb_ptp_update_compare(priv, (u32)start_ns);
0255         if (!error) {
0256             /* Unmask interrupt */
0257             if (!info->irq_en_dis)
0258                 ravb_modify(ndev, GIC, GIC_PTME, GIC_PTME);
0259             else
0260                 ravb_write(ndev, GIE_PTMS0, GIE);
0261         }
0262     } else  {
0263         spin_lock_irqsave(&priv->lock, flags);
0264 
0265         perout = &priv->ptp.perout[req->index];
0266         perout->period = 0;
0267 
0268         /* Mask interrupt */
0269         if (!info->irq_en_dis)
0270             ravb_modify(ndev, GIC, GIC_PTME, 0);
0271         else
0272             ravb_write(ndev, GID_PTMD0, GID);
0273     }
0274     spin_unlock_irqrestore(&priv->lock, flags);
0275 
0276     return error;
0277 }
0278 
0279 static int ravb_ptp_enable(struct ptp_clock_info *ptp,
0280                struct ptp_clock_request *req, int on)
0281 {
0282     switch (req->type) {
0283     case PTP_CLK_REQ_EXTTS:
0284         return ravb_ptp_extts(ptp, &req->extts, on);
0285     case PTP_CLK_REQ_PEROUT:
0286         return ravb_ptp_perout(ptp, &req->perout, on);
0287     default:
0288         return -EOPNOTSUPP;
0289     }
0290 }
0291 
0292 static const struct ptp_clock_info ravb_ptp_info = {
0293     .owner      = THIS_MODULE,
0294     .name       = "ravb clock",
0295     .max_adj    = 50000000,
0296     .n_ext_ts   = N_EXT_TS,
0297     .n_per_out  = N_PER_OUT,
0298     .adjfreq    = ravb_ptp_adjfreq,
0299     .adjtime    = ravb_ptp_adjtime,
0300     .gettime64  = ravb_ptp_gettime64,
0301     .settime64  = ravb_ptp_settime64,
0302     .enable     = ravb_ptp_enable,
0303 };
0304 
0305 /* Caller must hold the lock */
0306 void ravb_ptp_interrupt(struct net_device *ndev)
0307 {
0308     struct ravb_private *priv = netdev_priv(ndev);
0309     u32 gis = ravb_read(ndev, GIS);
0310 
0311     gis &= ravb_read(ndev, GIC);
0312     if (gis & GIS_PTCF) {
0313         struct ptp_clock_event event;
0314 
0315         event.type = PTP_CLOCK_EXTTS;
0316         event.index = 0;
0317         event.timestamp = ravb_read(ndev, GCPT);
0318         ptp_clock_event(priv->ptp.clock, &event);
0319     }
0320     if (gis & GIS_PTMF) {
0321         struct ravb_ptp_perout *perout = priv->ptp.perout;
0322 
0323         if (perout->period) {
0324             perout->target += perout->period;
0325             ravb_ptp_update_compare(priv, perout->target);
0326         }
0327     }
0328 
0329     ravb_write(ndev, ~(gis | GIS_RESERVED), GIS);
0330 }
0331 
0332 void ravb_ptp_init(struct net_device *ndev, struct platform_device *pdev)
0333 {
0334     struct ravb_private *priv = netdev_priv(ndev);
0335     unsigned long flags;
0336 
0337     priv->ptp.info = ravb_ptp_info;
0338 
0339     priv->ptp.default_addend = ravb_read(ndev, GTI);
0340     priv->ptp.current_addend = priv->ptp.default_addend;
0341 
0342     spin_lock_irqsave(&priv->lock, flags);
0343     ravb_wait(ndev, GCCR, GCCR_TCR, GCCR_TCR_NOREQ);
0344     ravb_modify(ndev, GCCR, GCCR_TCSS, GCCR_TCSS_ADJGPTP);
0345     spin_unlock_irqrestore(&priv->lock, flags);
0346 
0347     priv->ptp.clock = ptp_clock_register(&priv->ptp.info, &pdev->dev);
0348 }
0349 
0350 void ravb_ptp_stop(struct net_device *ndev)
0351 {
0352     struct ravb_private *priv = netdev_priv(ndev);
0353 
0354     ravb_write(ndev, 0, GIC);
0355     ravb_write(ndev, 0, GIS);
0356 
0357     ptp_clock_unregister(priv->ptp.clock);
0358 }