1313#include <linux/io.h>
1414#include <linux/lcm.h>
1515#include <linux/list.h>
16+ #include <linux/minmax.h>
1617#include <linux/module.h>
1718#include <linux/slab.h>
1819
@@ -365,7 +366,6 @@ struct mchp_asrc_be_rtm {
365366 struct mchp_asrc_be_trigger * trig ; /* backpointer */
366367 struct snd_pcm_hw_params * hw_params ; // used by the links that are not BE
367368 struct mchp_asrc_slot const * slot ;
368- int maxburst ;
369369 struct list_head list ;
370370};
371371
@@ -388,6 +388,7 @@ struct mchp_asrc_pcm_priv {
388388 struct xmit_ch * tc ;
389389 struct mchp_asrc_be_rtm rtm_fe ; /* used for FE --- BEs links */
390390 int refcount ;
391+ int maxburst ;
391392 bool is_hostless ;
392393};
393394
@@ -405,18 +406,18 @@ struct mchp_asrc_dev {
405406 int rhr_opmode ;
406407};
407408
408- static inline int mchp_asrc_period_to_burst (int period_size )
409+ static inline int mchp_asrc_period_to_burst (int period_size , int sample_size )
409410{
410- if (!(period_size % 16 ))
411+ if (!(period_size % ( sample_size * 16 ) ))
411412 return 16 ;
412413
413- if (!(period_size % 8 ))
414+ if (!(period_size % ( sample_size * 8 ) ))
414415 return 8 ;
415416
416- if (!(period_size % 4 ))
417+ if (!(period_size % ( sample_size * 4 ) ))
417418 return 4 ;
418419
419- if (!(period_size % 2 ))
420+ if (!(period_size % ( sample_size * 2 ) ))
420421 return 2 ;
421422
422423 return 1 ;
@@ -700,7 +701,6 @@ static int mchp_asrc_bes_get(struct mchp_asrc_dev *priv, struct snd_pcm_substrea
700701 struct snd_soc_pcm_runtime * be = dpcm -> be ;
701702 struct snd_soc_dai * dai = asoc_rtd_to_cpu (be , 0 );
702703 struct snd_pcm_substream * substream_be ;
703- int period_bytes ;
704704
705705 if (dpcm -> fe != rtd )
706706 continue ;
@@ -717,7 +717,6 @@ static int mchp_asrc_bes_get(struct mchp_asrc_dev *priv, struct snd_pcm_substrea
717717 params_width (& be -> dpcm [substream -> stream ].hw_params ),
718718 params_channels (& be -> dpcm [substream -> stream ].hw_params ));
719719
720- period_bytes = snd_pcm_lib_period_bytes (substream_be );
721720 for (i = 0 ; i < priv -> trig_count ; i ++ ) {
722721 struct mchp_asrc_be_trigger * trig_be = & priv -> trig [i ];
723722 struct mchp_asrc_be_rtm * rtm_be ;
@@ -731,8 +730,8 @@ static int mchp_asrc_bes_get(struct mchp_asrc_dev *priv, struct snd_pcm_substrea
731730 rtm_be = trig_be -> rtm [substream -> stream ];
732731 if (set_trig )
733732 rtm_be -> trig = trig_be ;
733+
734734 rtm_be -> hw_params = & be -> dpcm [substream -> stream ].hw_params ;
735- rtm_be -> maxburst = mchp_asrc_period_to_burst (period_bytes );
736735
737736 /* keep the order */
738737 list_add_tail (& rtm_be -> list , head );
@@ -989,11 +988,11 @@ static void mchp_asrc_tc_free(struct mchp_asrc_dev *priv, struct mchp_asrc_pcm_p
989988 MCHP_ASRC_CH_CONF_THROPMODE_MASK | MCHP_ASRC_CH_CONF_RHROPMODE_MASK , 0 );
990989}
991990
992- static void mchp_asrc_maxburst_limit ( int thr_opmode , int rhr_opmode ,
993- int dsps_used , bool is_mono ,
991+ /* apply HW DMA Chunk Size limitations */
992+ static void mchp_asrc_maxburst_limit ( int thr_opmode , int rhr_opmode , bool is_mono ,
994993 int * maxburst )
995994{
996- if ((thr_opmode == 0 || rhr_opmode == 0 || dsps_used == 1 ) &&
995+ if ((thr_opmode == 0 || rhr_opmode == 0 ) &&
997996 * maxburst > 4 ) {
998997 if (is_mono )
999998 * maxburst = 4 ;
@@ -1032,9 +1031,9 @@ static int mchp_asrc_hw_params(struct snd_pcm_substream *substream,
10321031 int ratio_min ;
10331032 struct list_head * list_head_bes ;
10341033 int i ;
1035- int maxburst [MCHP_ASRC_NB_STEREO_CH ] = {0 };
10361034 struct opmode_to_slot const * be_opm ;
10371035 struct xmit_ch * tc ;
1036+ bool is_mono = false;
10381037
10391038 dev_dbg (priv -> dev , "%s() DAI %s id %d rate=%u format=%#x width=%u channels=%u\n" ,
10401039 __func__ , dai -> name , dai -> id , fs , params ? params_format (params ) : 0 ,
@@ -1092,11 +1091,8 @@ static int mchp_asrc_hw_params(struct snd_pcm_substream *substream,
10921091 goto __cleanup_bes ;
10931092
10941093 if (!pcm -> is_hostless ) {
1095- int period_size = snd_pcm_lib_period_bytes (substream );
1096-
10971094 pcm -> rtm_fe .hw_params = params ;
10981095 pcm -> rtm_fe .trig = NULL ;
1099- pcm -> rtm_fe .maxburst = mchp_asrc_period_to_burst (period_size );
11001096
11011097 /* keep the order */
11021098 if (is_playback )
@@ -1166,12 +1162,17 @@ static int mchp_asrc_hw_params(struct snd_pcm_substream *substream,
11661162 struct mchp_asrc_slot const * slot_be = rtm_be -> slot ;
11671163 int chan_be = params_channels (rtm_be -> hw_params );
11681164 u32 idx = trig_be ? trig_be -> idx : 0 ;
1165+ int physical_width = params_physical_width (rtm_be -> hw_params ) / 8 ;
1166+ int period_bytes = params_period_size (rtm_be -> hw_params ) *
1167+ params_channels (rtm_be -> hw_params ) * physical_width ;
1168+ int maxburst = mchp_asrc_period_to_burst (period_bytes , physical_width );
11691169
11701170 /* treat odd streams, set only last DSP as mono */
11711171 if (chan_be % 2 ) {
11721172 dsp = slot_be -> first_dsp + slot_be -> dsp_count - 1 ;
11731173 ch_conf |= MCHP_ASRC_CH_CONF_MONO (dsp );
11741174 ch_conf_mask |= MCHP_ASRC_CH_CONF_MONO (dsp );
1175+ is_mono = true;
11751176 }
11761177
11771178 for (dsp = slot_be -> first_dsp ;
@@ -1190,23 +1191,32 @@ static int mchp_asrc_hw_params(struct snd_pcm_substream *substream,
11901191 if (max_sr < params_rate (rtm_be -> hw_params ))
11911192 max_sr = params_rate (rtm_be -> hw_params );
11921193
1193- maxburst [slot_be -> slot_id ] = rtm_be -> maxburst ;
1194+ if (pcm -> maxburst )
1195+ pcm -> maxburst = min (pcm -> maxburst , maxburst );
1196+ else
1197+ pcm -> maxburst = maxburst ;
11941198
1195- mchp_asrc_maxburst_limit (priv -> thr_opmode , priv -> rhr_opmode , slot_be -> dsp_count ,
1196- chan_be % 2 , & maxburst [slot_be -> slot_id ]);
1199+ dev_dbg (priv -> dev , "%s: period bytes %d, width %d -> maxburst %d\n" ,
1200+ trig_be ? trig_be -> phandle -> np -> full_name : dai -> name ,
1201+ period_bytes , physical_width , maxburst );
11971202 }
11981203
11991204 list_for_each_entry (rtm_be , & pcm -> list_head_out , list ) {
12001205 struct mchp_asrc_be_trigger * trig_be = rtm_be -> trig ;
12011206 struct mchp_asrc_slot const * slot_be = rtm_be -> slot ;
12021207 int chan_be = params_channels (rtm_be -> hw_params );
1208+ int physical_width = params_physical_width (rtm_be -> hw_params ) / 8 ;
1209+ int period_bytes = params_period_size (rtm_be -> hw_params ) *
1210+ params_channels (rtm_be -> hw_params ) * physical_width ;
1211+ int maxburst = mchp_asrc_period_to_burst (period_bytes , physical_width );
12031212 u32 idx = trig_be ? trig_be -> idx : 0 ;
12041213
12051214 /* treat odd streams, set only last DSP as mono */
12061215 if (chan_be % 2 ) {
12071216 dsp = slot_be -> first_dsp + slot_be -> dsp_count - 1 ;
12081217 ch_conf |= MCHP_ASRC_CH_CONF_MONO (dsp );
12091218 ch_conf_mask |= MCHP_ASRC_CH_CONF_MONO (dsp );
1219+ is_mono = true;
12101220 }
12111221
12121222 for (dsp = slot_be -> first_dsp ;
@@ -1225,15 +1235,19 @@ static int mchp_asrc_hw_params(struct snd_pcm_substream *substream,
12251235 if (max_sr < params_rate (rtm_be -> hw_params ))
12261236 max_sr = params_rate (rtm_be -> hw_params );
12271237
1228- if (!maxburst [slot_be -> slot_id ] ||
1229- maxburst [slot_be -> slot_id ] > rtm_be -> maxburst )
1230- maxburst [slot_be -> slot_id ] = rtm_be -> maxburst ;
1238+ if (pcm -> maxburst )
1239+ pcm -> maxburst = min (pcm -> maxburst , maxburst );
1240+ else
1241+ pcm -> maxburst = maxburst ;
12311242
1232- mchp_asrc_maxburst_limit (priv -> thr_opmode , priv -> rhr_opmode ,
1233- slot_be -> dsp_count , chan_be % 2 ,
1234- & maxburst [ slot_be -> slot_id ] );
1243+ dev_dbg (priv -> dev , "%s: period bytes %d, width %d -> maxburst %d\n" ,
1244+ trig_be ? trig_be -> phandle -> np -> full_name : dai -> name ,
1245+ period_bytes , physical_width , maxburst );
12351246 }
12361247
1248+ mchp_asrc_maxburst_limit (priv -> thr_opmode , priv -> rhr_opmode , is_mono , & pcm -> maxburst );
1249+ dev_dbg (priv -> dev , "maxburst value to be used by all DSPs: %d\n" , pcm -> maxburst );
1250+
12371251 /* set DMAengine data for each IN/OUT AIF */
12381252 INIT_LIST_HEAD (& dma -> dma_in_list );
12391253 list_for_each_entry (rtm_be , & pcm -> list_head_in , list ) {
@@ -1255,7 +1269,7 @@ static int mchp_asrc_hw_params(struct snd_pcm_substream *substream,
12551269 ret = - ENOMEM ;
12561270 goto __cleanup_dma_bes ;
12571271 }
1258- dma_data_be -> maxburst = maxburst [ slot_be -> slot_id ] ;
1272+ dma_data_be -> maxburst = pcm -> maxburst ;
12591273
12601274 /* keep the order of the BEs */
12611275 list_add_tail (& dma_be -> list , & dma -> dma_in_list );
@@ -1287,13 +1301,13 @@ static int mchp_asrc_hw_params(struct snd_pcm_substream *substream,
12871301 ret = - ENOMEM ;
12881302 goto __cleanup_dma_bes ;
12891303 }
1290- dma_data_be -> maxburst = maxburst [ slot_be -> slot_id ] ;
1304+ dma_data_be -> maxburst = pcm -> maxburst ;
12911305
12921306 /* needed only once, since the same DPSs are used for IN and OUT AIFs */
12931307 for (dsp = slot_be -> first_dsp ; dsp < slot_be -> first_dsp + slot_be -> dsp_count ;
12941308 dsp ++ ) {
12951309 ch_conf |= mchp_asrc_burst_to_chunk (dsp ,
1296- maxburst [ slot_be -> slot_id ] );
1310+ pcm -> maxburst );
12971311 ch_conf_mask |= MCHP_ASRC_CH_CONF_CHUNK_MASK (dsp );
12981312 }
12991313
0 commit comments