@@ -580,6 +580,9 @@ struct wm_adsp_compr_buf {
580580 u32 irq_count ;
581581 int read_index ;
582582 int avail ;
583+ int host_buf_mem_type ;
584+ int num_regions ;
585+ const struct wm_adsp_buffer_region_def * region_def ;
583586};
584587
585588struct wm_adsp_compr {
@@ -595,12 +598,16 @@ struct wm_adsp_compr {
595598 unsigned int sample_rate ;
596599};
597600
598- #define WM_ADSP_DATA_WORD_SIZE 3
601+ #define WM_ADSP_DATA_WORD_SIZE_DEFAULT 3
602+ #define WM_ADSP_DATA_WORD_SIZE_VPU 4
603+
604+ #define WM_ADSP_DATA_WORD_MASK_DEFAULT 0x00ffffffu
605+ #define WM_ADSP_DATA_WORD_MASK_VPU 0xffffffffu
599606
600- #define WM_ADSP_MIN_FRAGMENTS 1
601- #define WM_ADSP_MAX_FRAGMENTS 256
602- #define WM_ADSP_MIN_FRAGMENT_SIZE (64 * WM_ADSP_DATA_WORD_SIZE)
603- #define WM_ADSP_MAX_FRAGMENT_SIZE ( 4096 * WM_ADSP_DATA_WORD_SIZE)
607+ #define WM_ADSP_MIN_FRAGMENTS 1
608+ #define WM_ADSP_MAX_FRAGMENTS 256
609+ #define WM_ADSP_MIN_FRAGMENT_SIZE_WORDS 64
610+ #define WM_ADSP_MAX_FRAGMENT_SIZE_WORDS 4096
604611
605612#define WM_ADSP_ALG_XM_STRUCT_MAGIC 0x49aec7
606613
@@ -644,11 +651,27 @@ static const struct wm_adsp_buffer_region_def default_regions[] = {
644651 },
645652};
646653
654+ static const struct wm_adsp_buffer_region_def vpu_regions [] = {
655+ {
656+ .mem_type = WMFW_VPU_DM ,
657+ .base_offset = HOST_BUFFER_FIELD (buf1_base ),
658+ .size_offset = HOST_BUFFER_FIELD (buf1_size ),
659+ },
660+ {
661+ .mem_type = WMFW_VPU_DM ,
662+ .base_offset = HOST_BUFFER_FIELD (buf2_base ),
663+ .size_offset = HOST_BUFFER_FIELD (buf1_buf2_size ),
664+ },
665+ {
666+ .mem_type = WMFW_VPU_DM ,
667+ .base_offset = HOST_BUFFER_FIELD (buf3_base ),
668+ .size_offset = HOST_BUFFER_FIELD (buf_total_size ),
669+ },
670+ };
671+
647672struct wm_adsp_fw_caps {
648673 u32 id ;
649674 struct snd_codec_desc desc ;
650- int num_regions ;
651- const struct wm_adsp_buffer_region_def * region_defs ;
652675};
653676
654677static const struct wm_adsp_fw_caps ctrl_caps [] = {
@@ -660,8 +683,6 @@ static const struct wm_adsp_fw_caps ctrl_caps[] = {
660683 .num_sample_rates = 1 ,
661684 .formats = SNDRV_PCM_FMTBIT_S16_LE ,
662685 },
663- .num_regions = ARRAY_SIZE (default_regions ),
664- .region_defs = default_regions ,
665686 },
666687};
667688
@@ -678,8 +699,6 @@ static const struct wm_adsp_fw_caps trace_caps[] = {
678699 .num_sample_rates = 15 ,
679700 .formats = SNDRV_PCM_FMTBIT_S16_LE ,
680701 },
681- .num_regions = ARRAY_SIZE (default_regions ),
682- .region_defs = default_regions ,
683702 },
684703};
685704
@@ -3431,6 +3450,12 @@ static void wm_vpu_boot_work(struct work_struct *work)
34313450 if (ret != 0 )
34323451 goto err ;
34333452
3453+ if (wm_adsp_fw [vpu -> fw ].num_caps != 0 ) {
3454+ ret = wm_adsp_buffer_init (vpu );
3455+ if (ret < 0 )
3456+ goto err ;
3457+ }
3458+
34343459 vpu -> booted = true;
34353460
34363461err :
@@ -3887,6 +3912,9 @@ int wm_adsp2_init(struct wm_adsp *dsp)
38873912
38883913 mutex_init (& dsp -> pwr_lock );
38893914
3915+ dsp -> data_word_size = WM_ADSP_DATA_WORD_SIZE_DEFAULT ;
3916+ dsp -> data_word_mask = WM_ADSP_DATA_WORD_MASK_DEFAULT ;
3917+
38903918 return 0 ;
38913919}
38923920EXPORT_SYMBOL_GPL (wm_adsp2_init );
@@ -3911,6 +3939,9 @@ int wm_halo_init(struct wm_adsp *dsp, struct mutex *rate_lock)
39113939 dsp -> tx_rate_cache = kcalloc (dsp -> n_tx_channels , sizeof (u8 ),
39123940 GFP_KERNEL );
39133941
3942+ dsp -> data_word_size = WM_ADSP_DATA_WORD_SIZE_DEFAULT ;
3943+ dsp -> data_word_mask = WM_ADSP_DATA_WORD_MASK_DEFAULT ;
3944+
39143945 return 0 ;
39153946}
39163947EXPORT_SYMBOL_GPL (wm_halo_init );
@@ -3928,6 +3959,9 @@ int wm_vpu_init(struct wm_adsp *vpu)
39283959 INIT_WORK (& vpu -> boot_work , wm_vpu_boot_work );
39293960 mutex_init (& vpu -> pwr_lock );
39303961
3962+ vpu -> data_word_size = WM_ADSP_DATA_WORD_SIZE_VPU ;
3963+ vpu -> data_word_mask = WM_ADSP_DATA_WORD_MASK_VPU ;
3964+
39313965 return 0 ;
39323966}
39333967EXPORT_SYMBOL_GPL (wm_vpu_init );
@@ -4057,11 +4091,13 @@ static int wm_adsp_compr_check_params(struct snd_compr_stream *stream,
40574091 const struct snd_codec_desc * desc ;
40584092 int i , j ;
40594093
4060- if (params -> buffer .fragment_size < WM_ADSP_MIN_FRAGMENT_SIZE ||
4061- params -> buffer .fragment_size > WM_ADSP_MAX_FRAGMENT_SIZE ||
4094+ if (params -> buffer .fragment_size < (WM_ADSP_MIN_FRAGMENT_SIZE_WORDS
4095+ * dsp -> data_word_size ) ||
4096+ params -> buffer .fragment_size > (WM_ADSP_MAX_FRAGMENT_SIZE_WORDS
4097+ * dsp -> data_word_size ) ||
40624098 params -> buffer .fragments < WM_ADSP_MIN_FRAGMENTS ||
40634099 params -> buffer .fragments > WM_ADSP_MAX_FRAGMENTS ||
4064- params -> buffer .fragment_size % WM_ADSP_DATA_WORD_SIZE ) {
4100+ params -> buffer .fragment_size % dsp -> data_word_size ) {
40654101 adsp_err (dsp , "Invalid buffer fragsize=%d fragments=%d\n" ,
40664102 params -> buffer .fragment_size ,
40674103 params -> buffer .fragments );
@@ -4100,7 +4136,7 @@ static int wm_adsp_compr_check_params(struct snd_compr_stream *stream,
41004136
41014137static inline unsigned int wm_adsp_compr_frag_words (struct wm_adsp_compr * compr )
41024138{
4103- return compr -> size .fragment_size / WM_ADSP_DATA_WORD_SIZE ;
4139+ return compr -> size .fragment_size / compr -> dsp -> data_word_size ;
41044140}
41054141
41064142int wm_adsp_compr_set_params (struct snd_compr_stream * stream ,
@@ -4134,6 +4170,7 @@ int wm_adsp_compr_get_caps(struct snd_compr_stream *stream,
41344170 struct snd_compr_caps * caps )
41354171{
41364172 struct wm_adsp_compr * compr = stream -> runtime -> private_data ;
4173+ struct wm_adsp * dsp = compr -> dsp ;
41374174 int fw = compr -> dsp -> fw ;
41384175 int i ;
41394176
@@ -4144,8 +4181,10 @@ int wm_adsp_compr_get_caps(struct snd_compr_stream *stream,
41444181 caps -> num_codecs = i ;
41454182 caps -> direction = wm_adsp_fw [fw ].compr_direction ;
41464183
4147- caps -> min_fragment_size = WM_ADSP_MIN_FRAGMENT_SIZE ;
4148- caps -> max_fragment_size = WM_ADSP_MAX_FRAGMENT_SIZE ;
4184+ caps -> min_fragment_size = WM_ADSP_MIN_FRAGMENT_SIZE_WORDS
4185+ * dsp -> data_word_size ;
4186+ caps -> max_fragment_size = WM_ADSP_MAX_FRAGMENT_SIZE_WORDS
4187+ * dsp -> data_word_size ;
41494188 caps -> min_fragments = WM_ADSP_MIN_FRAGMENTS ;
41504189 caps -> max_fragments = WM_ADSP_MAX_FRAGMENTS ;
41514190 }
@@ -4160,6 +4199,7 @@ static int wm_adsp_read_data_block(struct wm_adsp *dsp, int mem_type,
41604199{
41614200 struct wm_adsp_region const * mem = wm_adsp_find_region (dsp , mem_type );
41624201 unsigned int i , reg ;
4202+ unsigned int data_word_mask = dsp -> data_word_mask ;
41634203 int ret ;
41644204
41654205 if (!mem )
@@ -4173,7 +4213,7 @@ static int wm_adsp_read_data_block(struct wm_adsp *dsp, int mem_type,
41734213 return ret ;
41744214
41754215 for (i = 0 ; i < num_words ; ++ i )
4176- data [i ] = be32_to_cpu (data [i ]) & 0x00ffffffu ;
4216+ data [i ] = be32_to_cpu (data [i ]) & data_word_mask ;
41774217
41784218 return 0 ;
41794219}
@@ -4195,22 +4235,22 @@ static int wm_adsp_write_data_word(struct wm_adsp *dsp, int mem_type,
41954235
41964236 reg = wm_adsp_region_to_reg (dsp , mem , mem_addr );
41974237
4198- data = cpu_to_be32 (data & 0x00ffffffu );
4238+ data = cpu_to_be32 (data & dsp -> data_word_mask );
41994239
42004240 return regmap_raw_write (dsp -> regmap , reg , & data , sizeof (data ));
42014241}
42024242
42034243static inline int wm_adsp_buffer_read (struct wm_adsp_compr_buf * buf ,
42044244 unsigned int field_offset , u32 * data )
42054245{
4206- return wm_adsp_read_data_word (buf -> dsp , WMFW_ADSP2_XM ,
4246+ return wm_adsp_read_data_word (buf -> dsp , buf -> host_buf_mem_type ,
42074247 buf -> host_buf_ptr + field_offset , data );
42084248}
42094249
42104250static inline int wm_adsp_buffer_write (struct wm_adsp_compr_buf * buf ,
42114251 unsigned int field_offset , u32 data )
42124252{
4213- return wm_adsp_write_data_word (buf -> dsp , WMFW_ADSP2_XM ,
4253+ return wm_adsp_write_data_word (buf -> dsp , buf -> host_buf_mem_type ,
42144254 buf -> host_buf_ptr + field_offset , data );
42154255}
42164256
@@ -4260,6 +4300,8 @@ static int wm_adsp_legacy_host_buf_addr(struct wm_adsp_compr_buf *buf)
42604300 if (!buf -> host_buf_ptr )
42614301 return - EIO ;
42624302
4303+ buf -> host_buf_mem_type = WMFW_ADSP2_XM ;
4304+
42634305 adsp_dbg (dsp , "host_buf_ptr=%x\n" , buf -> host_buf_ptr );
42644306
42654307 return 0 ;
@@ -4278,6 +4320,7 @@ static struct wm_coeff_ctl *wm_adsp_find_host_buffer_ctrl(
42784320 if (!ctl -> enabled )
42794321 continue ;
42804322
4323+ buf -> host_buf_mem_type = ctl -> alg_region .type ;
42814324 return ctl ;
42824325 }
42834326
@@ -4322,23 +4365,22 @@ static int wm_adsp_buffer_locate(struct wm_adsp_compr_buf *buf)
43224365
43234366static int wm_adsp_buffer_populate (struct wm_adsp_compr_buf * buf )
43244367{
4325- const struct wm_adsp_fw_caps * caps = wm_adsp_fw [buf -> dsp -> fw ].caps ;
43264368 struct wm_adsp_buffer_region * region ;
43274369 u32 offset = 0 ;
43284370 int i , ret ;
43294371
4330- for (i = 0 ; i < caps -> num_regions ; ++ i ) {
4372+ for (i = 0 ; i < buf -> num_regions ; ++ i ) {
43314373 region = & buf -> regions [i ];
43324374
43334375 region -> offset = offset ;
4334- region -> mem_type = caps -> region_defs [i ].mem_type ;
4376+ region -> mem_type = buf -> region_def [i ].mem_type ;
43354377
4336- ret = wm_adsp_buffer_read (buf , caps -> region_defs [i ].base_offset ,
4378+ ret = wm_adsp_buffer_read (buf , buf -> region_def [i ].base_offset ,
43374379 & region -> base_addr );
43384380 if (ret < 0 )
43394381 return ret ;
43404382
4341- ret = wm_adsp_buffer_read (buf , caps -> region_defs [i ].size_offset ,
4383+ ret = wm_adsp_buffer_read (buf , buf -> region_def [i ].size_offset ,
43424384 & offset );
43434385 if (ret < 0 )
43444386 return ret ;
@@ -4374,14 +4416,31 @@ static int wm_adsp_buffer_init(struct wm_adsp *dsp)
43744416
43754417 wm_adsp_buffer_clear (buf );
43764418
4419+ switch (dsp -> type ) {
4420+ case WMFW_ADSP1 :
4421+ case WMFW_ADSP2 :
4422+ case WMFW_HALO :
4423+ buf -> num_regions = ARRAY_SIZE (default_regions );
4424+ buf -> region_def = default_regions ;
4425+ break ;
4426+ case WMFW_VPU :
4427+ buf -> num_regions = ARRAY_SIZE (vpu_regions );
4428+ buf -> region_def = vpu_regions ;
4429+ break ;
4430+ default :
4431+ adsp_err (dsp , "Unknown DSP type:%d\n" , dsp -> type );
4432+ ret = - EINVAL ;
4433+ goto err_buffer ;
4434+ }
4435+
43774436 ret = wm_adsp_buffer_locate (buf );
43784437 if (ret < 0 ) {
43794438 adsp_err (dsp , "Failed to acquire host buffer: %d\n" , ret );
43804439 goto err_buffer ;
43814440 }
43824441
4383- buf -> regions = kcalloc (wm_adsp_fw [ dsp -> fw ]. caps -> num_regions ,
4384- sizeof ( * buf -> regions ), GFP_KERNEL );
4442+ buf -> regions = kcalloc (buf -> num_regions , sizeof ( * buf -> regions ) ,
4443+ GFP_KERNEL );
43854444 if (!buf -> regions ) {
43864445 ret = - ENOMEM ;
43874446 goto err_buffer ;
@@ -4466,7 +4525,7 @@ EXPORT_SYMBOL_GPL(wm_adsp_compr_trigger);
44664525
44674526static inline int wm_adsp_buffer_size (struct wm_adsp_compr_buf * buf )
44684527{
4469- int last_region = wm_adsp_fw [ buf -> dsp -> fw ]. caps -> num_regions - 1 ;
4528+ int last_region = buf -> num_regions - 1 ;
44704529
44714530 return buf -> regions [last_region ].cumulative_size ;
44724531}
@@ -4507,7 +4566,7 @@ static int wm_adsp_buffer_update_avail(struct wm_adsp_compr_buf *buf)
45074566 avail += wm_adsp_buffer_size (buf );
45084567
45094568 adsp_dbg (buf -> dsp , "readindex=0x%x, writeindex=0x%x, avail=%d\n" ,
4510- buf -> read_index , write_index , avail * WM_ADSP_DATA_WORD_SIZE );
4569+ buf -> read_index , write_index , avail * buf -> dsp -> data_word_size );
45114570
45124571 buf -> avail = avail ;
45134572
@@ -4645,7 +4704,7 @@ int wm_adsp_compr_pointer(struct snd_compr_stream *stream,
46454704 }
46464705
46474706 tstamp -> copied_total = compr -> copied_total ;
4648- tstamp -> copied_total += buf -> avail * WM_ADSP_DATA_WORD_SIZE ;
4707+ tstamp -> copied_total += buf -> avail * dsp -> data_word_size ;
46494708 tstamp -> sampling_rate = compr -> sample_rate ;
46504709
46514710out :
@@ -4663,13 +4722,14 @@ static int wm_adsp_buffer_capture_block(struct wm_adsp_compr *compr, int target)
46634722 unsigned int adsp_addr ;
46644723 int mem_type , nwords , max_read ;
46654724 int i , j , ret ;
4725+ int data_word_size = buf -> dsp -> data_word_size ;
46664726
46674727 /* Calculate read parameters */
4668- for (i = 0 ; i < wm_adsp_fw [ buf -> dsp -> fw ]. caps -> num_regions ; ++ i )
4728+ for (i = 0 ; i < buf -> num_regions ; ++ i )
46694729 if (buf -> read_index < buf -> regions [i ].cumulative_size )
46704730 break ;
46714731
4672- if (i == wm_adsp_fw [ buf -> dsp -> fw ]. caps -> num_regions )
4732+ if (i == buf -> num_regions )
46734733 return - EINVAL ;
46744734
46754735 mem_type = buf -> regions [i ].mem_type ;
@@ -4696,10 +4756,10 @@ static int wm_adsp_buffer_capture_block(struct wm_adsp_compr *compr, int target)
46964756
46974757 /* Remove the padding bytes from the data read from the DSP */
46984758 for (i = 0 ; i < nwords ; i ++ ) {
4699- for (j = 0 ; j < WM_ADSP_DATA_WORD_SIZE ; j ++ )
4759+ for (j = 0 ; j < data_word_size ; j ++ )
47004760 * pack_out ++ = * pack_in ++ ;
47014761
4702- pack_in += sizeof (* (compr -> raw_buf )) - WM_ADSP_DATA_WORD_SIZE ;
4762+ pack_in += sizeof (* (compr -> raw_buf )) - data_word_size ;
47034763 }
47044764
47054765 /* update read index to account for words read */
@@ -4732,7 +4792,7 @@ static int wm_adsp_compr_read(struct wm_adsp_compr *compr,
47324792 return - EIO ;
47334793 }
47344794
4735- count /= WM_ADSP_DATA_WORD_SIZE ;
4795+ count /= dsp -> data_word_size ;
47364796
47374797 do {
47384798 nwords = wm_adsp_buffer_capture_block (compr , count );
@@ -4741,7 +4801,7 @@ static int wm_adsp_compr_read(struct wm_adsp_compr *compr,
47414801 return nwords ;
47424802 }
47434803
4744- nbytes = nwords * WM_ADSP_DATA_WORD_SIZE ;
4804+ nbytes = nwords * dsp -> data_word_size ;
47454805
47464806 adsp_dbg (dsp , "Read %d bytes\n" , nbytes );
47474807
0 commit comments