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 ;
@@ -715,7 +715,6 @@ static int mchp_asrc_bes_get(struct mchp_asrc_dev *priv, struct snd_pcm_substrea
715715 params_format (& dpcm -> hw_params ), params_width (& dpcm -> hw_params ),
716716 params_channels (& dpcm -> hw_params ));
717717
718- period_bytes = snd_pcm_lib_period_bytes (substream_be );
719718 for (i = 0 ; i < priv -> trig_count ; i ++ ) {
720719 struct mchp_asrc_be_trigger * trig_be = & priv -> trig [i ];
721720 struct mchp_asrc_be_rtm * rtm_be ;
@@ -730,7 +729,6 @@ static int mchp_asrc_bes_get(struct mchp_asrc_dev *priv, struct snd_pcm_substrea
730729 if (set_trig )
731730 rtm_be -> trig = trig_be ;
732731 rtm_be -> hw_params = & dpcm -> hw_params ;
733- rtm_be -> maxburst = mchp_asrc_period_to_burst (period_bytes );
734732
735733 /* keep the order */
736734 list_add_tail (& rtm_be -> list , head );
@@ -987,11 +985,11 @@ static void mchp_asrc_tc_free(struct mchp_asrc_dev *priv, struct mchp_asrc_pcm_p
987985 MCHP_ASRC_CH_CONF_THROPMODE_MASK | MCHP_ASRC_CH_CONF_RHROPMODE_MASK , 0 );
988986}
989987
990- static void mchp_asrc_maxburst_limit ( int thr_opmode , int rhr_opmode ,
991- int dsps_used , bool is_mono ,
988+ /* apply HW DMA Chunk Size limitations */
989+ static void mchp_asrc_maxburst_limit ( int thr_opmode , int rhr_opmode , bool is_mono ,
992990 int * maxburst )
993991{
994- if ((thr_opmode == 0 || rhr_opmode == 0 || dsps_used == 1 ) &&
992+ if ((thr_opmode == 0 || rhr_opmode == 0 ) &&
995993 * maxburst > 4 ) {
996994 if (is_mono )
997995 * maxburst = 4 ;
@@ -1031,9 +1029,9 @@ static int mchp_asrc_hw_params(struct snd_pcm_substream *substream,
10311029 int ratio_min ;
10321030 struct list_head * list_head_bes ;
10331031 int i ;
1034- int maxburst [MCHP_ASRC_NB_STEREO_CH ] = {0 };
10351032 struct opmode_to_slot const * be_opm ;
10361033 struct xmit_ch * tc ;
1034+ bool is_mono = false;
10371035
10381036 dev_dbg (priv -> dev , "%s() DAI %s id %d rate=%u format=%#x width=%u channels=%u\n" ,
10391037 __func__ , dai -> name , dai -> id , fs , params ? params_format (params ) : 0 ,
@@ -1093,11 +1091,8 @@ static int mchp_asrc_hw_params(struct snd_pcm_substream *substream,
10931091 dsps_req = (ret + 1 ) / 2 ;
10941092
10951093 if (!pcm -> is_hostless ) {
1096- int period_size = snd_pcm_lib_period_bytes (substream );
1097-
10981094 pcm -> rtm_fe .hw_params = params ;
10991095 pcm -> rtm_fe .trig = NULL ;
1100- pcm -> rtm_fe .maxburst = mchp_asrc_period_to_burst (period_size );
11011096
11021097 /* keep the order */
11031098 if (is_playback )
@@ -1167,12 +1162,17 @@ static int mchp_asrc_hw_params(struct snd_pcm_substream *substream,
11671162 struct mchp_asrc_slot const * slot_be = rtm_be -> slot ;
11681163 int chan_be = params_channels (rtm_be -> hw_params );
11691164 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 );
11701169
11711170 /* treat odd streams, set only last DSP as mono */
11721171 if (chan_be % 2 ) {
11731172 dsp = slot_be -> first_dsp + slot_be -> dsp_count - 1 ;
11741173 ch_conf |= MCHP_ASRC_CH_CONF_MONO (dsp );
11751174 ch_conf_mask |= MCHP_ASRC_CH_CONF_MONO (dsp );
1175+ is_mono = true;
11761176 }
11771177
11781178 for (dsp = slot_be -> first_dsp ;
@@ -1191,23 +1191,32 @@ static int mchp_asrc_hw_params(struct snd_pcm_substream *substream,
11911191 if (max_sr < params_rate (rtm_be -> hw_params ))
11921192 max_sr = params_rate (rtm_be -> hw_params );
11931193
1194- 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 ;
11951198
1196- mchp_asrc_maxburst_limit (priv -> thr_opmode , priv -> rhr_opmode , slot_be -> dsp_count ,
1197- 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 );
11981202 }
11991203
12001204 list_for_each_entry (rtm_be , & pcm -> list_head_out , list ) {
12011205 struct mchp_asrc_be_trigger * trig_be = rtm_be -> trig ;
12021206 struct mchp_asrc_slot const * slot_be = rtm_be -> slot ;
12031207 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 );
12041212 u32 idx = trig_be ? trig_be -> idx : 0 ;
12051213
12061214 /* treat odd streams, set only last DSP as mono */
12071215 if (chan_be % 2 ) {
12081216 dsp = slot_be -> first_dsp + slot_be -> dsp_count - 1 ;
12091217 ch_conf |= MCHP_ASRC_CH_CONF_MONO (dsp );
12101218 ch_conf_mask |= MCHP_ASRC_CH_CONF_MONO (dsp );
1219+ is_mono = true;
12111220 }
12121221
12131222 for (dsp = slot_be -> first_dsp ;
@@ -1226,15 +1235,19 @@ static int mchp_asrc_hw_params(struct snd_pcm_substream *substream,
12261235 if (max_sr < params_rate (rtm_be -> hw_params ))
12271236 max_sr = params_rate (rtm_be -> hw_params );
12281237
1229- if (!maxburst [slot_be -> slot_id ] ||
1230- maxburst [slot_be -> slot_id ] > rtm_be -> maxburst )
1231- 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 ;
12321242
1233- mchp_asrc_maxburst_limit (priv -> thr_opmode , priv -> rhr_opmode ,
1234- slot_be -> dsp_count , chan_be % 2 ,
1235- & 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 );
12361246 }
12371247
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+
12381251 /* set DMAengine data for each IN/OUT AIF */
12391252 INIT_LIST_HEAD (& dma -> dma_in_list );
12401253 list_for_each_entry (rtm_be , & pcm -> list_head_in , list ) {
@@ -1256,7 +1269,7 @@ static int mchp_asrc_hw_params(struct snd_pcm_substream *substream,
12561269 ret = - ENOMEM ;
12571270 goto __cleanup_dma_bes ;
12581271 }
1259- dma_data_be -> maxburst = maxburst [ slot_be -> slot_id ] ;
1272+ dma_data_be -> maxburst = pcm -> maxburst ;
12601273
12611274 /* keep the order of the BEs */
12621275 list_add_tail (& dma_be -> list , & dma -> dma_in_list );
@@ -1288,13 +1301,13 @@ static int mchp_asrc_hw_params(struct snd_pcm_substream *substream,
12881301 ret = - ENOMEM ;
12891302 goto __cleanup_dma_bes ;
12901303 }
1291- dma_data_be -> maxburst = maxburst [ slot_be -> slot_id ] ;
1304+ dma_data_be -> maxburst = pcm -> maxburst ;
12921305
12931306 /* needed only once, since the same DPSs are used for IN and OUT AIFs */
12941307 for (dsp = slot_be -> first_dsp ; dsp < slot_be -> first_dsp + slot_be -> dsp_count ;
12951308 dsp ++ ) {
12961309 ch_conf |= mchp_asrc_burst_to_chunk (dsp ,
1297- maxburst [ slot_be -> slot_id ] );
1310+ pcm -> maxburst );
12981311 ch_conf_mask |= MCHP_ASRC_CH_CONF_CHUNK_MASK (dsp );
12991312 }
13001313
0 commit comments