Skip to content

Commit

Permalink
Merge tag 'asoc-v3.15-rc5-intel' of git://git.kernel.org/pub/scm/linu…
Browse files Browse the repository at this point in the history
…x/kernel/git/broonie/sound into for-linus

ASoC: Intel fixes for v3.15

This is a relatively large batch of fixes for the newly added
Haswell/Baytrail drivers from Intel.  It's a bit larger than is good for
this point in the cycle but it's all for a newly added driver so not so
worrying as it might otherwise be.  Some of it's integration problems,
some of it's the sort of problem usually turned up in stress tests.
  • Loading branch information
Takashi Iwai committed May 14, 2014
2 parents 7ca33c7 + cffd666 commit ff2354b
Show file tree
Hide file tree
Showing 11 changed files with 126 additions and 59 deletions.
1 change: 1 addition & 0 deletions sound/soc/intel/sst-acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ static int sst_acpi_probe(struct platform_device *pdev)

sst_pdata = &sst_acpi->sst_pdata;
sst_pdata->id = desc->sst_id;
sst_pdata->dma_dev = dev;
sst_acpi->desc = desc;
sst_acpi->mach = mach;

Expand Down
2 changes: 1 addition & 1 deletion sound/soc/intel/sst-baytrail-dsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ static int sst_byt_init(struct sst_dsp *sst, struct sst_pdata *pdata)
memcpy_toio(sst->addr.lpe + SST_BYT_MAILBOX_OFFSET,
&pdata->fw_base, sizeof(u32));

ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
ret = dma_coerce_mask_and_coherent(sst->dma_dev, DMA_BIT_MASK(32));
if (ret)
return ret;

Expand Down
8 changes: 8 additions & 0 deletions sound/soc/intel/sst-baytrail-ipc.c
Original file line number Diff line number Diff line change
Expand Up @@ -542,16 +542,20 @@ struct sst_byt_stream *sst_byt_stream_new(struct sst_byt *byt, int id,
void *data)
{
struct sst_byt_stream *stream;
struct sst_dsp *sst = byt->dsp;
unsigned long flags;

stream = kzalloc(sizeof(*stream), GFP_KERNEL);
if (stream == NULL)
return NULL;

spin_lock_irqsave(&sst->spinlock, flags);
list_add(&stream->node, &byt->stream_list);
stream->notify_position = notify_position;
stream->pdata = data;
stream->byt = byt;
stream->str_id = id;
spin_unlock_irqrestore(&sst->spinlock, flags);

return stream;
}
Expand Down Expand Up @@ -630,6 +634,8 @@ int sst_byt_stream_free(struct sst_byt *byt, struct sst_byt_stream *stream)
{
u64 header;
int ret = 0;
struct sst_dsp *sst = byt->dsp;
unsigned long flags;

if (!stream->commited)
goto out;
Expand All @@ -644,8 +650,10 @@ int sst_byt_stream_free(struct sst_byt *byt, struct sst_byt_stream *stream)

stream->commited = false;
out:
spin_lock_irqsave(&sst->spinlock, flags);
list_del(&stream->node);
kfree(stream);
spin_unlock_irqrestore(&sst->spinlock, flags);

return ret;
}
Expand Down
1 change: 1 addition & 0 deletions sound/soc/intel/sst-dsp-priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ struct sst_dsp {
spinlock_t spinlock; /* IPC locking */
struct mutex mutex; /* DSP FW lock */
struct device *dev;
struct device *dma_dev;
void *thread_context;
int irq;
u32 id;
Expand Down
1 change: 1 addition & 0 deletions sound/soc/intel/sst-dsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ struct sst_dsp *sst_dsp_new(struct device *dev,
spin_lock_init(&sst->spinlock);
mutex_init(&sst->mutex);
sst->dev = dev;
sst->dma_dev = pdata->dma_dev;
sst->thread_context = sst_dev->thread_context;
sst->sst_dev = sst_dev;
sst->id = pdata->id;
Expand Down
1 change: 1 addition & 0 deletions sound/soc/intel/sst-dsp.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ struct sst_pdata {
u32 dma_base;
u32 dma_size;
int dma_engine;
struct device *dma_dev;

/* DSP */
u32 id;
Expand Down
25 changes: 8 additions & 17 deletions sound/soc/intel/sst-firmware.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,8 @@ struct sst_fw *sst_fw_new(struct sst_dsp *dsp,
sst_fw->private = private;
sst_fw->size = fw->size;

err = dma_coerce_mask_and_coherent(dsp->dev, DMA_BIT_MASK(32));
if (err < 0) {
kfree(sst_fw);
return NULL;
}

/* allocate DMA buffer to store FW data */
sst_fw->dma_buf = dma_alloc_coherent(dsp->dev, sst_fw->size,
sst_fw->dma_buf = dma_alloc_coherent(dsp->dma_dev, sst_fw->size,
&sst_fw->dmable_fw_paddr, GFP_DMA | GFP_KERNEL);
if (!sst_fw->dma_buf) {
dev_err(dsp->dev, "error: DMA alloc failed\n");
Expand Down Expand Up @@ -106,7 +100,7 @@ void sst_fw_free(struct sst_fw *sst_fw)
list_del(&sst_fw->list);
mutex_unlock(&dsp->mutex);

dma_free_coherent(dsp->dev, sst_fw->size, sst_fw->dma_buf,
dma_free_coherent(dsp->dma_dev, sst_fw->size, sst_fw->dma_buf,
sst_fw->dmable_fw_paddr);
kfree(sst_fw);
}
Expand Down Expand Up @@ -202,6 +196,9 @@ static int block_alloc_contiguous(struct sst_module *module,
size -= block->size;
}

list_for_each_entry(block, &tmp, list)
list_add(&block->module_list, &module->block_list);

list_splice(&tmp, &dsp->used_block_list);
return 0;
}
Expand Down Expand Up @@ -247,8 +244,7 @@ static int block_alloc(struct sst_module *module,
/* do we span > 1 blocks */
if (data->size > block->size) {
ret = block_alloc_contiguous(module, data,
block->offset + block->size,
data->size - block->size);
block->offset, data->size);
if (ret == 0)
return ret;
}
Expand Down Expand Up @@ -344,7 +340,7 @@ static int block_alloc_fixed(struct sst_module *module,

err = block_alloc_contiguous(module, data,
block->offset + block->size,
data->size - block->size + data->offset - block->offset);
data->size - block->size);
if (err < 0)
return -ENOMEM;

Expand All @@ -371,15 +367,10 @@ static int block_alloc_fixed(struct sst_module *module,
if (data->offset >= block->offset && data->offset < block_end) {

err = block_alloc_contiguous(module, data,
block->offset + block->size,
data->size - block->size);
block->offset, data->size);
if (err < 0)
return -ENOMEM;

/* add block */
block->data_type = data->data_type;
list_move(&block->list, &dsp->used_block_list);
list_add(&block->module_list, &module->block_list);
return 0;
}

Expand Down
4 changes: 2 additions & 2 deletions sound/soc/intel/sst-haswell-dsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,7 @@ static int hsw_init(struct sst_dsp *sst, struct sst_pdata *pdata)
int ret = -ENODEV, i, j, region_count;
u32 offset, size;

dev = sst->dev;
dev = sst->dma_dev;

switch (sst->id) {
case SST_DEV_ID_LYNX_POINT:
Expand Down Expand Up @@ -466,7 +466,7 @@ static int hsw_init(struct sst_dsp *sst, struct sst_pdata *pdata)
return ret;
}

ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(31));
if (ret)
return ret;

Expand Down
31 changes: 29 additions & 2 deletions sound/soc/intel/sst-haswell-ipc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1159,11 +1159,14 @@ struct sst_hsw_stream *sst_hsw_stream_new(struct sst_hsw *hsw, int id,
void *data)
{
struct sst_hsw_stream *stream;
struct sst_dsp *sst = hsw->dsp;
unsigned long flags;

stream = kzalloc(sizeof(*stream), GFP_KERNEL);
if (stream == NULL)
return NULL;

spin_lock_irqsave(&sst->spinlock, flags);
list_add(&stream->node, &hsw->stream_list);
stream->notify_position = notify_position;
stream->pdata = data;
Expand All @@ -1172,6 +1175,7 @@ struct sst_hsw_stream *sst_hsw_stream_new(struct sst_hsw *hsw, int id,

/* work to process notification messages */
INIT_WORK(&stream->notify_work, hsw_notification_work);
spin_unlock_irqrestore(&sst->spinlock, flags);

return stream;
}
Expand All @@ -1180,6 +1184,8 @@ int sst_hsw_stream_free(struct sst_hsw *hsw, struct sst_hsw_stream *stream)
{
u32 header;
int ret = 0;
struct sst_dsp *sst = hsw->dsp;
unsigned long flags;

/* dont free DSP streams that are not commited */
if (!stream->commited)
Expand All @@ -1201,8 +1207,11 @@ int sst_hsw_stream_free(struct sst_hsw *hsw, struct sst_hsw_stream *stream)
trace_hsw_stream_free_req(stream, &stream->free_req);

out:
cancel_work_sync(&stream->notify_work);
spin_lock_irqsave(&sst->spinlock, flags);
list_del(&stream->node);
kfree(stream);
spin_unlock_irqrestore(&sst->spinlock, flags);

return ret;
}
Expand Down Expand Up @@ -1538,10 +1547,28 @@ int sst_hsw_stream_reset(struct sst_hsw *hsw, struct sst_hsw_stream *stream)
}

/* Stream pointer positions */
int sst_hsw_get_dsp_position(struct sst_hsw *hsw,
u32 sst_hsw_get_dsp_position(struct sst_hsw *hsw,
struct sst_hsw_stream *stream)
{
return stream->rpos.position;
u32 rpos;

sst_dsp_read(hsw->dsp, &rpos,
stream->reply.read_position_register_address, sizeof(rpos));

return rpos;
}

/* Stream presentation (monotonic) positions */
u64 sst_hsw_get_dsp_presentation_position(struct sst_hsw *hsw,
struct sst_hsw_stream *stream)
{
u64 ppos;

sst_dsp_read(hsw->dsp, &ppos,
stream->reply.presentation_position_register_address,
sizeof(ppos));

return ppos;
}

int sst_hsw_stream_set_write_position(struct sst_hsw *hsw,
Expand Down
4 changes: 3 additions & 1 deletion sound/soc/intel/sst-haswell-ipc.h
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,9 @@ int sst_hsw_stream_get_write_pos(struct sst_hsw *hsw,
struct sst_hsw_stream *stream, u32 *position);
int sst_hsw_stream_set_write_position(struct sst_hsw *hsw,
struct sst_hsw_stream *stream, u32 stage_id, u32 position);
int sst_hsw_get_dsp_position(struct sst_hsw *hsw,
u32 sst_hsw_get_dsp_position(struct sst_hsw *hsw,
struct sst_hsw_stream *stream);
u64 sst_hsw_get_dsp_presentation_position(struct sst_hsw *hsw,
struct sst_hsw_stream *stream);

/* HW port config */
Expand Down
Loading

0 comments on commit ff2354b

Please sign in to comment.