@@ -306,6 +306,23 @@ static int mlx5_mtctr_syncdevicetime(ktime_t *device_time,
306
306
return 0 ;
307
307
}
308
308
309
+ static int
310
+ mlx5_mtctr_syncdevicecyclestime (ktime_t * device_time ,
311
+ struct system_counterval_t * sys_counterval ,
312
+ void * ctx )
313
+ {
314
+ struct mlx5_core_dev * mdev = ctx ;
315
+ u64 device ;
316
+ int err ;
317
+
318
+ err = mlx5_mtctr_read (mdev , false, sys_counterval , & device );
319
+ if (err )
320
+ return err ;
321
+ * device_time = ns_to_ktime (device );
322
+
323
+ return 0 ;
324
+ }
325
+
309
326
static int mlx5_ptp_getcrosststamp (struct ptp_clock_info * ptp ,
310
327
struct system_device_crosststamp * cts )
311
328
{
@@ -330,6 +347,32 @@ static int mlx5_ptp_getcrosststamp(struct ptp_clock_info *ptp,
330
347
mlx5_clock_unlock (clock );
331
348
return err ;
332
349
}
350
+
351
+ static int mlx5_ptp_getcrosscycles (struct ptp_clock_info * ptp ,
352
+ struct system_device_crosststamp * cts )
353
+ {
354
+ struct mlx5_clock * clock =
355
+ container_of (ptp , struct mlx5_clock , ptp_info );
356
+ struct system_time_snapshot history_begin = {0 };
357
+ struct mlx5_core_dev * mdev ;
358
+ int err ;
359
+
360
+ mlx5_clock_lock (clock );
361
+ mdev = mlx5_clock_mdev_get (clock );
362
+
363
+ if (!mlx5_is_ptm_source_time_available (mdev )) {
364
+ err = - EBUSY ;
365
+ goto unlock ;
366
+ }
367
+
368
+ ktime_get_snapshot (& history_begin );
369
+
370
+ err = get_device_system_crosststamp (mlx5_mtctr_syncdevicecyclestime ,
371
+ mdev , & history_begin , cts );
372
+ unlock :
373
+ mlx5_clock_unlock (clock );
374
+ return err ;
375
+ }
333
376
#endif /* CONFIG_X86 */
334
377
335
378
static u64 mlx5_read_time (struct mlx5_core_dev * dev ,
@@ -528,6 +571,24 @@ static int mlx5_ptp_gettimex(struct ptp_clock_info *ptp, struct timespec64 *ts,
528
571
return 0 ;
529
572
}
530
573
574
+ static int mlx5_ptp_getcyclesx (struct ptp_clock_info * ptp ,
575
+ struct timespec64 * ts ,
576
+ struct ptp_system_timestamp * sts )
577
+ {
578
+ struct mlx5_clock * clock = container_of (ptp , struct mlx5_clock ,
579
+ ptp_info );
580
+ struct mlx5_core_dev * mdev ;
581
+ u64 cycles ;
582
+
583
+ mlx5_clock_lock (clock );
584
+ mdev = mlx5_clock_mdev_get (clock );
585
+
586
+ cycles = mlx5_read_time (mdev , sts , false);
587
+ * ts = ns_to_timespec64 (cycles );
588
+ mlx5_clock_unlock (clock );
589
+ return 0 ;
590
+ }
591
+
531
592
static int mlx5_ptp_adjtime_real_time (struct mlx5_core_dev * mdev , s64 delta )
532
593
{
533
594
u32 in [MLX5_ST_SZ_DW (mtutc_reg )] = {};
@@ -1244,19 +1305,30 @@ static void mlx5_init_timer_max_freq_adjustment(struct mlx5_core_dev *mdev)
1244
1305
static void mlx5_init_timer_clock (struct mlx5_core_dev * mdev )
1245
1306
{
1246
1307
struct mlx5_clock * clock = mdev -> clock ;
1308
+ bool expose_cycles ;
1247
1309
1248
1310
/* Configure the PHC */
1249
1311
clock -> ptp_info = mlx5_ptp_clock_info ;
1250
1312
1251
1313
if (MLX5_CAP_MCAM_REG (mdev , mtutc ))
1252
1314
mlx5_init_timer_max_freq_adjustment (mdev );
1253
1315
1316
+ expose_cycles = !MLX5_CAP_GEN (mdev , disciplined_fr_counter ) ||
1317
+ !mlx5_real_time_mode (mdev );
1318
+
1254
1319
#ifdef CONFIG_X86
1255
1320
if (MLX5_CAP_MCAM_REG3 (mdev , mtptm ) &&
1256
- MLX5_CAP_MCAM_REG3 (mdev , mtctr ) && boot_cpu_has (X86_FEATURE_ART ))
1321
+ MLX5_CAP_MCAM_REG3 (mdev , mtctr ) && boot_cpu_has (X86_FEATURE_ART )) {
1257
1322
clock -> ptp_info .getcrosststamp = mlx5_ptp_getcrosststamp ;
1323
+ if (expose_cycles )
1324
+ clock -> ptp_info .getcrosscycles =
1325
+ mlx5_ptp_getcrosscycles ;
1326
+ }
1258
1327
#endif /* CONFIG_X86 */
1259
1328
1329
+ if (expose_cycles )
1330
+ clock -> ptp_info .getcyclesx64 = mlx5_ptp_getcyclesx ;
1331
+
1260
1332
mlx5_timecounter_init (mdev );
1261
1333
mlx5_init_clock_info (mdev );
1262
1334
mlx5_init_overflow_period (mdev );
0 commit comments