60
60
61
61
#define SAI_MCLK_NAME_LEN 32
62
62
#define SAI_RATE_11K 11025
63
+ #define SAI_MAX_SAMPLE_RATE_8K 192000
64
+ #define SAI_MAX_SAMPLE_RATE_11K 176400
65
+ #define SAI_CK_RATE_TOLERANCE 1000 /* ppm */
63
66
64
67
/**
65
68
* struct stm32_sai_sub_data - private data of SAI sub block (block A or B)
80
83
* @dir: SAI block direction (playback or capture). set at init
81
84
* @master: SAI block mode flag. (true=master, false=slave) set at init
82
85
* @spdif: SAI S/PDIF iec60958 mode flag. set at init
86
+ * @sai_ck_used: flag set while exclusivity on SAI kernel clock is active
83
87
* @fmt: SAI block format. relevant only for custom protocols. set at init
84
88
* @sync: SAI block synchronization mode. (none, internal or external)
85
89
* @synco: SAI block ext sync source (provider setting). (none, sub-block A/B)
93
97
* @iec958: iec958 data
94
98
* @ctrl_lock: control lock
95
99
* @irq_lock: prevent race condition with IRQ
100
+ * @set_sai_ck_rate: set SAI kernel clock rate
101
+ * @put_sai_ck_rate: put SAI kernel clock rate
96
102
*/
97
103
struct stm32_sai_sub_data {
98
104
struct platform_device * pdev ;
@@ -112,6 +118,7 @@ struct stm32_sai_sub_data {
112
118
int dir ;
113
119
bool master ;
114
120
bool spdif ;
121
+ bool sai_ck_used ;
115
122
int fmt ;
116
123
int sync ;
117
124
int synco ;
@@ -125,6 +132,8 @@ struct stm32_sai_sub_data {
125
132
struct snd_aes_iec958 iec958 ;
126
133
struct mutex ctrl_lock ; /* protect resources accessed by controls */
127
134
spinlock_t irq_lock ; /* used to prevent race condition with IRQ */
135
+ int (* set_sai_ck_rate )(struct stm32_sai_sub_data * sai , unsigned int rate );
136
+ void (* put_sai_ck_rate )(struct stm32_sai_sub_data * sai );
128
137
};
129
138
130
139
enum stm32_sai_fifo_th {
@@ -351,8 +360,26 @@ static int stm32_sai_set_clk_div(struct stm32_sai_sub_data *sai,
351
360
return ret ;
352
361
}
353
362
354
- static int stm32_sai_set_parent_clock (struct stm32_sai_sub_data * sai ,
355
- unsigned int rate )
363
+ static bool stm32_sai_rate_accurate (unsigned int max_rate , unsigned int rate )
364
+ {
365
+ u64 delta , dividend ;
366
+ int ratio ;
367
+
368
+ ratio = DIV_ROUND_CLOSEST (max_rate , rate );
369
+ if (!ratio )
370
+ return false;
371
+
372
+ dividend = mul_u32_u32 (1000000 , abs (max_rate - (ratio * rate )));
373
+ delta = div_u64 (dividend , max_rate );
374
+
375
+ if (delta <= SAI_CK_RATE_TOLERANCE )
376
+ return true;
377
+
378
+ return false;
379
+ }
380
+
381
+ static int stm32_sai_set_parent_clk (struct stm32_sai_sub_data * sai ,
382
+ unsigned int rate )
356
383
{
357
384
struct platform_device * pdev = sai -> pdev ;
358
385
struct clk * parent_clk = sai -> pdata -> clk_x8k ;
@@ -370,6 +397,92 @@ static int stm32_sai_set_parent_clock(struct stm32_sai_sub_data *sai,
370
397
return ret ;
371
398
}
372
399
400
+ static void stm32_sai_put_parent_rate (struct stm32_sai_sub_data * sai )
401
+ {
402
+ if (sai -> sai_ck_used ) {
403
+ sai -> sai_ck_used = false;
404
+ clk_rate_exclusive_put (sai -> sai_ck );
405
+ }
406
+ }
407
+
408
+ static int stm32_sai_set_parent_rate (struct stm32_sai_sub_data * sai ,
409
+ unsigned int rate )
410
+ {
411
+ struct platform_device * pdev = sai -> pdev ;
412
+ unsigned int sai_ck_rate , sai_ck_max_rate , sai_curr_rate , sai_new_rate ;
413
+ int div , ret ;
414
+
415
+ /*
416
+ * Set maximum expected kernel clock frequency
417
+ * - mclk on or spdif:
418
+ * f_sai_ck = MCKDIV * mclk-fs * fs
419
+ * Here typical 256 ratio is assumed for mclk-fs
420
+ * - mclk off:
421
+ * f_sai_ck = MCKDIV * FRL * fs
422
+ * Where FRL=[8..256], MCKDIV=[1..n] (n depends on SAI version)
423
+ * Set constraint MCKDIV * FRL <= 256, to ensure MCKDIV is in available range
424
+ * f_sai_ck = sai_ck_max_rate * pow_of_two(FRL) / 256
425
+ */
426
+ if (!(rate % SAI_RATE_11K ))
427
+ sai_ck_max_rate = SAI_MAX_SAMPLE_RATE_11K * 256 ;
428
+ else
429
+ sai_ck_max_rate = SAI_MAX_SAMPLE_RATE_8K * 256 ;
430
+
431
+ if (!sai -> sai_mclk && !STM_SAI_PROTOCOL_IS_SPDIF (sai ))
432
+ sai_ck_max_rate /= DIV_ROUND_CLOSEST (256 , roundup_pow_of_two (sai -> fs_length ));
433
+
434
+ /*
435
+ * Request exclusivity, as the clock is shared by SAI sub-blocks and by
436
+ * some SAI instances. This allows to ensure that the rate cannot be
437
+ * changed while one or more SAIs are using the clock.
438
+ */
439
+ clk_rate_exclusive_get (sai -> sai_ck );
440
+ sai -> sai_ck_used = true;
441
+
442
+ /*
443
+ * Check current kernel clock rate. If it gives the expected accuracy
444
+ * return immediately.
445
+ */
446
+ sai_curr_rate = clk_get_rate (sai -> sai_ck );
447
+ if (stm32_sai_rate_accurate (sai_ck_max_rate , sai_curr_rate ))
448
+ return 0 ;
449
+
450
+ /*
451
+ * Otherwise try to set the maximum rate and check the new actual rate.
452
+ * If the new rate does not give the expected accuracy, try to set
453
+ * lower rates for the kernel clock.
454
+ */
455
+ sai_ck_rate = sai_ck_max_rate ;
456
+ div = 1 ;
457
+ do {
458
+ /* Check new rate accuracy. Return if ok */
459
+ sai_new_rate = clk_round_rate (sai -> sai_ck , sai_ck_rate );
460
+ if (stm32_sai_rate_accurate (sai_ck_rate , sai_new_rate )) {
461
+ ret = clk_set_rate (sai -> sai_ck , sai_ck_rate );
462
+ if (ret ) {
463
+ dev_err (& pdev -> dev , "Error %d setting sai_ck rate. %s" ,
464
+ ret , ret == - EBUSY ?
465
+ "Active stream rates may be in conflict\n" : "\n" );
466
+ goto err ;
467
+ }
468
+
469
+ return 0 ;
470
+ }
471
+
472
+ /* Try a lower frequency */
473
+ div ++ ;
474
+ sai_ck_rate = sai_ck_max_rate / div ;
475
+ } while (sai_ck_rate > rate );
476
+
477
+ /* No accurate rate found */
478
+ dev_err (& pdev -> dev , "Failed to find an accurate rate" );
479
+
480
+ err :
481
+ stm32_sai_put_parent_rate (sai );
482
+
483
+ return - EINVAL ;
484
+ }
485
+
373
486
static long stm32_sai_mclk_round_rate (struct clk_hw * hw , unsigned long rate ,
374
487
unsigned long * prate )
375
488
{
@@ -565,11 +678,15 @@ static int stm32_sai_set_sysclk(struct snd_soc_dai *cpu_dai,
565
678
clk_rate_exclusive_put (sai -> sai_mclk );
566
679
sai -> mclk_rate = 0 ;
567
680
}
681
+
682
+ if (sai -> put_sai_ck_rate )
683
+ sai -> put_sai_ck_rate (sai );
684
+
568
685
return 0 ;
569
686
}
570
687
571
- /* If master clock is used, set parent clock now */
572
- ret = stm32_sai_set_parent_clock (sai , freq );
688
+ /* If master clock is used, configure SAI kernel clock now */
689
+ ret = sai -> set_sai_ck_rate (sai , freq );
573
690
if (ret )
574
691
return ret ;
575
692
@@ -993,7 +1110,7 @@ static int stm32_sai_configure_clock(struct snd_soc_dai *cpu_dai,
993
1110
int ret ;
994
1111
995
1112
if (!sai -> sai_mclk ) {
996
- ret = stm32_sai_set_parent_clock (sai , rate );
1113
+ ret = sai -> set_sai_ck_rate (sai , rate );
997
1114
if (ret )
998
1115
return ret ;
999
1116
}
@@ -1154,6 +1271,14 @@ static void stm32_sai_shutdown(struct snd_pcm_substream *substream,
1154
1271
1155
1272
clk_disable_unprepare (sai -> sai_ck );
1156
1273
1274
+ /*
1275
+ * Release kernel clock if following conditions are fulfilled
1276
+ * - Master clock is not used. Kernel clock won't be released trough sysclk
1277
+ * - Put handler is defined. Involve that clock is managed exclusively
1278
+ */
1279
+ if (!sai -> sai_mclk && sai -> put_sai_ck_rate )
1280
+ sai -> put_sai_ck_rate (sai );
1281
+
1157
1282
spin_lock_irqsave (& sai -> irq_lock , flags );
1158
1283
sai -> substream = NULL ;
1159
1284
spin_unlock_irqrestore (& sai -> irq_lock , flags );
@@ -1188,7 +1313,7 @@ static int stm32_sai_dai_probe(struct snd_soc_dai *cpu_dai)
1188
1313
* constraints).
1189
1314
*/
1190
1315
sai -> dma_params .maxburst = 4 ;
1191
- if (sai -> pdata -> conf .fifo_size < 8 )
1316
+ if (sai -> pdata -> conf .fifo_size < 8 || sai -> pdata -> conf . no_dma_burst )
1192
1317
sai -> dma_params .maxburst = 1 ;
1193
1318
/* Buswidth will be set by framework at runtime */
1194
1319
sai -> dma_params .addr_width = DMA_SLAVE_BUSWIDTH_UNDEFINED ;
@@ -1526,6 +1651,13 @@ static int stm32_sai_sub_probe(struct platform_device *pdev)
1526
1651
return - EINVAL ;
1527
1652
}
1528
1653
1654
+ if (sai -> pdata -> conf .get_sai_ck_parent ) {
1655
+ sai -> set_sai_ck_rate = stm32_sai_set_parent_clk ;
1656
+ } else {
1657
+ sai -> set_sai_ck_rate = stm32_sai_set_parent_rate ;
1658
+ sai -> put_sai_ck_rate = stm32_sai_put_parent_rate ;
1659
+ }
1660
+
1529
1661
ret = stm32_sai_sub_parse_of (pdev , sai );
1530
1662
if (ret )
1531
1663
return ret ;
0 commit comments