27
27
#include <linux/module.h>
28
28
#include <linux/pm_runtime.h>
29
29
#include <linux/slab.h>
30
+
31
+ #ifdef CONFIG_X86
32
+ /* for art-tsc conversion */
33
+ #include <asm/tsc.h>
34
+ #endif
35
+
30
36
#include <sound/core.h>
31
37
#include <sound/initval.h>
32
38
#include "hda_controller.h"
@@ -337,12 +343,173 @@ static snd_pcm_uframes_t azx_pcm_pointer(struct snd_pcm_substream *substream)
337
343
azx_get_position (chip , azx_dev ));
338
344
}
339
345
346
+ /*
347
+ * azx_scale64: Scale base by mult/div while not overflowing sanely
348
+ *
349
+ * Derived from scale64_check_overflow in kernel/time/timekeeping.c
350
+ *
351
+ * The tmestamps for a 48Khz stream can overflow after (2^64/10^9)/48K which
352
+ * is about 384307 ie ~4.5 days.
353
+ *
354
+ * This scales the calculation so that overflow will happen but after 2^64 /
355
+ * 48000 secs, which is pretty large!
356
+ *
357
+ * In caln below:
358
+ * base may overflow, but since there isn’t any additional division
359
+ * performed on base it’s OK
360
+ * rem can’t overflow because both are 32-bit values
361
+ */
362
+
363
+ #ifdef CONFIG_X86
364
+ static u64 azx_scale64 (u64 base , u32 num , u32 den )
365
+ {
366
+ u64 rem ;
367
+
368
+ rem = do_div (base , den );
369
+
370
+ base *= num ;
371
+ rem *= num ;
372
+
373
+ do_div (rem , den );
374
+
375
+ return base + rem ;
376
+ }
377
+
378
+ static int azx_get_sync_time (ktime_t * device ,
379
+ struct system_counterval_t * system , void * ctx )
380
+ {
381
+ struct snd_pcm_substream * substream = ctx ;
382
+ struct azx_dev * azx_dev = get_azx_dev (substream );
383
+ struct azx_pcm * apcm = snd_pcm_substream_chip (substream );
384
+ struct azx * chip = apcm -> chip ;
385
+ struct snd_pcm_runtime * runtime ;
386
+ u64 ll_counter , ll_counter_l , ll_counter_h ;
387
+ u64 tsc_counter , tsc_counter_l , tsc_counter_h ;
388
+ u32 wallclk_ctr , wallclk_cycles ;
389
+ bool direction ;
390
+ u32 dma_select ;
391
+ u32 timeout = 200 ;
392
+ u32 retry_count = 0 ;
393
+
394
+ runtime = substream -> runtime ;
395
+
396
+ if (substream -> stream == SNDRV_PCM_STREAM_PLAYBACK )
397
+ direction = 1 ;
398
+ else
399
+ direction = 0 ;
400
+
401
+ /* 0th stream tag is not used, so DMA ch 0 is for 1st stream tag */
402
+ do {
403
+ timeout = 100 ;
404
+ dma_select = (direction << GTSCC_CDMAS_DMA_DIR_SHIFT ) |
405
+ (azx_dev -> core .stream_tag - 1 );
406
+ snd_hdac_chip_writel (azx_bus (chip ), GTSCC , dma_select );
407
+
408
+ /* Enable the capture */
409
+ snd_hdac_chip_updatel (azx_bus (chip ), GTSCC , 0 , GTSCC_TSCCI_MASK );
410
+
411
+ while (timeout ) {
412
+ if (snd_hdac_chip_readl (azx_bus (chip ), GTSCC ) &
413
+ GTSCC_TSCCD_MASK )
414
+ break ;
415
+
416
+ timeout -- ;
417
+ }
418
+
419
+ if (!timeout ) {
420
+ dev_err (chip -> card -> dev , "GTSCC capture Timedout!\n" );
421
+ return - EIO ;
422
+ }
423
+
424
+ /* Read wall clock counter */
425
+ wallclk_ctr = snd_hdac_chip_readl (azx_bus (chip ), WALFCC );
426
+
427
+ /* Read TSC counter */
428
+ tsc_counter_l = snd_hdac_chip_readl (azx_bus (chip ), TSCCL );
429
+ tsc_counter_h = snd_hdac_chip_readl (azx_bus (chip ), TSCCU );
430
+
431
+ /* Read Link counter */
432
+ ll_counter_l = snd_hdac_chip_readl (azx_bus (chip ), LLPCL );
433
+ ll_counter_h = snd_hdac_chip_readl (azx_bus (chip ), LLPCU );
434
+
435
+ /* Ack: registers read done */
436
+ snd_hdac_chip_writel (azx_bus (chip ), GTSCC , GTSCC_TSCCD_SHIFT );
437
+
438
+ tsc_counter = (tsc_counter_h << TSCCU_CCU_SHIFT ) |
439
+ tsc_counter_l ;
440
+
441
+ ll_counter = (ll_counter_h << LLPC_CCU_SHIFT ) | ll_counter_l ;
442
+ wallclk_cycles = wallclk_ctr & WALFCC_CIF_MASK ;
443
+
444
+ /*
445
+ * An error occurs near frame "rollover". The clocks in
446
+ * frame value indicates whether this error may have
447
+ * occurred. Here we use the value of 10 i.e.,
448
+ * HDA_MAX_CYCLE_OFFSET
449
+ */
450
+ if (wallclk_cycles < HDA_MAX_CYCLE_VALUE - HDA_MAX_CYCLE_OFFSET
451
+ && wallclk_cycles > HDA_MAX_CYCLE_OFFSET )
452
+ break ;
453
+
454
+ /*
455
+ * Sleep before we read again, else we may again get
456
+ * value near to MAX_CYCLE. Try to sleep for different
457
+ * amount of time so we dont hit the same number again
458
+ */
459
+ udelay (retry_count ++ );
460
+
461
+ } while (retry_count != HDA_MAX_CYCLE_READ_RETRY );
462
+
463
+ if (retry_count == HDA_MAX_CYCLE_READ_RETRY ) {
464
+ dev_err_ratelimited (chip -> card -> dev ,
465
+ "Error in WALFCC cycle count\n" );
466
+ return - EIO ;
467
+ }
468
+
469
+ * device = ns_to_ktime (azx_scale64 (ll_counter ,
470
+ NSEC_PER_SEC , runtime -> rate ));
471
+ * device = ktime_add_ns (* device , (wallclk_cycles * NSEC_PER_SEC ) /
472
+ ((HDA_MAX_CYCLE_VALUE + 1 ) * runtime -> rate ));
473
+
474
+ * system = convert_art_to_tsc (tsc_counter );
475
+
476
+ return 0 ;
477
+ }
478
+
479
+ #else
480
+ static int azx_get_sync_time (ktime_t * device ,
481
+ struct system_counterval_t * system , void * ctx )
482
+ {
483
+ return - ENXIO ;
484
+ }
485
+ #endif
486
+
487
+ static int azx_get_crosststamp (struct snd_pcm_substream * substream ,
488
+ struct system_device_crosststamp * xtstamp )
489
+ {
490
+ return get_device_system_crosststamp (azx_get_sync_time ,
491
+ substream , NULL , xtstamp );
492
+ }
493
+
494
+ static inline bool is_link_time_supported (struct snd_pcm_runtime * runtime ,
495
+ struct snd_pcm_audio_tstamp_config * ts )
496
+ {
497
+ if (runtime -> hw .info & SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME )
498
+ if (ts -> type_requested == SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED )
499
+ return true;
500
+
501
+ return false;
502
+ }
503
+
340
504
static int azx_get_time_info (struct snd_pcm_substream * substream ,
341
505
struct timespec * system_ts , struct timespec * audio_ts ,
342
506
struct snd_pcm_audio_tstamp_config * audio_tstamp_config ,
343
507
struct snd_pcm_audio_tstamp_report * audio_tstamp_report )
344
508
{
345
509
struct azx_dev * azx_dev = get_azx_dev (substream );
510
+ struct snd_pcm_runtime * runtime = substream -> runtime ;
511
+ struct system_device_crosststamp xtstamp ;
512
+ int ret ;
346
513
u64 nsec ;
347
514
348
515
if ((substream -> runtime -> hw .info & SNDRV_PCM_INFO_HAS_LINK_ATIME ) &&
@@ -361,8 +528,37 @@ static int azx_get_time_info(struct snd_pcm_substream *substream,
361
528
audio_tstamp_report -> accuracy_report = 1 ; /* rest of structure is valid */
362
529
audio_tstamp_report -> accuracy = 42 ; /* 24 MHz WallClock == 42ns resolution */
363
530
364
- } else
531
+ } else if (is_link_time_supported (runtime , audio_tstamp_config )) {
532
+
533
+ ret = azx_get_crosststamp (substream , & xtstamp );
534
+ if (ret )
535
+ return ret ;
536
+
537
+ switch (runtime -> tstamp_type ) {
538
+ case SNDRV_PCM_TSTAMP_TYPE_MONOTONIC :
539
+ return - EINVAL ;
540
+
541
+ case SNDRV_PCM_TSTAMP_TYPE_MONOTONIC_RAW :
542
+ * system_ts = ktime_to_timespec (xtstamp .sys_monoraw );
543
+ break ;
544
+
545
+ default :
546
+ * system_ts = ktime_to_timespec (xtstamp .sys_realtime );
547
+ break ;
548
+
549
+ }
550
+
551
+ * audio_ts = ktime_to_timespec (xtstamp .device );
552
+
553
+ audio_tstamp_report -> actual_type =
554
+ SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED ;
555
+ audio_tstamp_report -> accuracy_report = 1 ;
556
+ /* 24 MHz WallClock == 42ns resolution */
557
+ audio_tstamp_report -> accuracy = 42 ;
558
+
559
+ } else {
365
560
audio_tstamp_report -> actual_type = SNDRV_PCM_AUDIO_TSTAMP_TYPE_DEFAULT ;
561
+ }
366
562
367
563
return 0 ;
368
564
}
0 commit comments