Skip to content

Commit 18150de

Browse files
committed
Merge branch 'v4.14-adsp' into 'v4.14-tacna'
Change-Id: I67fb9ae5571d5694c28c53b910ca98c3b66f4a8d Signed-off-by: Andrew Ford <[email protected]>
2 parents 727c979 + 40a027d commit 18150de

File tree

2 files changed

+99
-37
lines changed

2 files changed

+99
-37
lines changed

sound/soc/codecs/wm_adsp.c

Lines changed: 97 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -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

585588
struct 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+
647672
struct 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

654677
static 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

34363461
err:
@@ -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
}
38923920
EXPORT_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
}
39163947
EXPORT_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
}
39333967
EXPORT_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

41014137
static 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

41064142
int 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

42034243
static 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

42104250
static 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

43234366
static 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

44674526
static 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

46514710
out:
@@ -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

sound/soc/codecs/wm_adsp.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ struct wm_adsp {
114114
char *wmfw_file_name;
115115
char *bin_file_name;
116116
#endif
117+
unsigned int data_word_mask;
118+
int data_word_size;
117119
};
118120

119121
#define WM_ADSP_PRELOADER(wname, num, event_fn) \

0 commit comments

Comments
 (0)