6060
6161#define SAI_MCLK_NAME_LEN 32
6262#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 */
6366
6467/**
6568 * struct stm32_sai_sub_data - private data of SAI sub block (block A or B)
8083 * @dir: SAI block direction (playback or capture). set at init
8184 * @master: SAI block mode flag. (true=master, false=slave) set at init
8285 * @spdif: SAI S/PDIF iec60958 mode flag. set at init
86+ * @sai_ck_used: flag set while exclusivity on SAI kernel clock is active
8387 * @fmt: SAI block format. relevant only for custom protocols. set at init
8488 * @sync: SAI block synchronization mode. (none, internal or external)
8589 * @synco: SAI block ext sync source (provider setting). (none, sub-block A/B)
9397 * @iec958: iec958 data
9498 * @ctrl_lock: control lock
9599 * @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
96102 */
97103struct stm32_sai_sub_data {
98104 struct platform_device * pdev ;
@@ -112,6 +118,7 @@ struct stm32_sai_sub_data {
112118 int dir ;
113119 bool master ;
114120 bool spdif ;
121+ bool sai_ck_used ;
115122 int fmt ;
116123 int sync ;
117124 int synco ;
@@ -125,6 +132,8 @@ struct stm32_sai_sub_data {
125132 struct snd_aes_iec958 iec958 ;
126133 struct mutex ctrl_lock ; /* protect resources accessed by controls */
127134 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 );
128137};
129138
130139enum stm32_sai_fifo_th {
@@ -351,8 +360,26 @@ static int stm32_sai_set_clk_div(struct stm32_sai_sub_data *sai,
351360 return ret ;
352361}
353362
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 )
356383{
357384 struct platform_device * pdev = sai -> pdev ;
358385 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,
370397 return ret ;
371398}
372399
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+
373486static long stm32_sai_mclk_round_rate (struct clk_hw * hw , unsigned long rate ,
374487 unsigned long * prate )
375488{
@@ -565,11 +678,15 @@ static int stm32_sai_set_sysclk(struct snd_soc_dai *cpu_dai,
565678 clk_rate_exclusive_put (sai -> sai_mclk );
566679 sai -> mclk_rate = 0 ;
567680 }
681+
682+ if (sai -> put_sai_ck_rate )
683+ sai -> put_sai_ck_rate (sai );
684+
568685 return 0 ;
569686 }
570687
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 );
573690 if (ret )
574691 return ret ;
575692
@@ -993,7 +1110,7 @@ static int stm32_sai_configure_clock(struct snd_soc_dai *cpu_dai,
9931110 int ret ;
9941111
9951112 if (!sai -> sai_mclk ) {
996- ret = stm32_sai_set_parent_clock (sai , rate );
1113+ ret = sai -> set_sai_ck_rate (sai , rate );
9971114 if (ret )
9981115 return ret ;
9991116 }
@@ -1154,6 +1271,14 @@ static void stm32_sai_shutdown(struct snd_pcm_substream *substream,
11541271
11551272 clk_disable_unprepare (sai -> sai_ck );
11561273
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+
11571282 spin_lock_irqsave (& sai -> irq_lock , flags );
11581283 sai -> substream = NULL ;
11591284 spin_unlock_irqrestore (& sai -> irq_lock , flags );
@@ -1188,7 +1313,7 @@ static int stm32_sai_dai_probe(struct snd_soc_dai *cpu_dai)
11881313 * constraints).
11891314 */
11901315 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 )
11921317 sai -> dma_params .maxburst = 1 ;
11931318 /* Buswidth will be set by framework at runtime */
11941319 sai -> dma_params .addr_width = DMA_SLAVE_BUSWIDTH_UNDEFINED ;
@@ -1526,6 +1651,13 @@ static int stm32_sai_sub_probe(struct platform_device *pdev)
15261651 return - EINVAL ;
15271652 }
15281653
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+
15291661 ret = stm32_sai_sub_parse_of (pdev , sai );
15301662 if (ret )
15311663 return ret ;
0 commit comments