soundwire: stream: don't program ports when a stream that has not been prepared
In the Intel QA multi-pipelines test case, there are two pipelines for playback and capture on the same bus. The test fails with an error when setting port params: [ 599.224812] rt711 sdw:0:25d:711:0: invalid dpn_prop direction 1 port_num 0 [ 599.224815] sdw_program_slave_port_params failed -22 [ 599.224819] intel-sdw sdw-master-0: Program transport params failed: -22 [ 599.224822] intel-sdw sdw-master-0: Program params failed: -22 [ 599.224828] sdw_enable_stream: SDW0 Pin2-Playback: done This problem is root-caused to the programming of the capture stream ports while it is not yet prepared, the calling sequence is: (1) hw_params for playback. The playback stream provide the port information to Bus. (2) stream_prepare for playback, Transport and port parameters are computed for playback. (3) hw_params for capture. The capture stream provide the port information to Bus, but it has not been prepared so is not accounted for in the bandwidth allocation. (4) stream_enable for playback. Program transport and port parameters for all masters and slaves. Since the transport and port parameters are not computed for capture stream, sdw_program_slave_port_params will generate a error when setting port params for capture. in step (4), we should only program the ports for the stream that have been prepared. A stream that is only in CONFIGURED state should be ignored, its ports will be programmed when it becomes PREPARED. Tested on Comet Lake. GitHub issue: https://github.com/thesofproject/linux/issues/1637 Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Signed-off-by: Rander Wang <rander.wang@intel.com> Link: https://lore.kernel.org/r/20200114235227.14502-6-pierre-louis.bossart@linux.intel.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
Родитель
60835022e1
Коммит
bfaa354954
|
@ -603,13 +603,25 @@ static int sdw_notify_config(struct sdw_master_runtime *m_rt)
|
|||
* and Slave(s)
|
||||
*
|
||||
* @bus: SDW bus instance
|
||||
* @prepare: true if sdw_program_params() is called by _prepare.
|
||||
*/
|
||||
static int sdw_program_params(struct sdw_bus *bus)
|
||||
static int sdw_program_params(struct sdw_bus *bus, bool prepare)
|
||||
{
|
||||
struct sdw_master_runtime *m_rt;
|
||||
int ret = 0;
|
||||
|
||||
list_for_each_entry(m_rt, &bus->m_rt_list, bus_node) {
|
||||
|
||||
/*
|
||||
* this loop walks through all master runtimes for a
|
||||
* bus, but the ports can only be configured while
|
||||
* explicitly preparing a stream or handling an
|
||||
* already-prepared stream otherwise.
|
||||
*/
|
||||
if (!prepare &&
|
||||
m_rt->stream->state == SDW_STREAM_CONFIGURED)
|
||||
continue;
|
||||
|
||||
ret = sdw_program_port_params(m_rt);
|
||||
if (ret < 0) {
|
||||
dev_err(bus->dev,
|
||||
|
@ -1502,7 +1514,7 @@ static int _sdw_prepare_stream(struct sdw_stream_runtime *stream,
|
|||
|
||||
program_params:
|
||||
/* Program params */
|
||||
ret = sdw_program_params(bus);
|
||||
ret = sdw_program_params(bus, true);
|
||||
if (ret < 0) {
|
||||
dev_err(bus->dev, "Program params failed: %d\n", ret);
|
||||
goto restore_params;
|
||||
|
@ -1602,7 +1614,7 @@ static int _sdw_enable_stream(struct sdw_stream_runtime *stream)
|
|||
bus = m_rt->bus;
|
||||
|
||||
/* Program params */
|
||||
ret = sdw_program_params(bus);
|
||||
ret = sdw_program_params(bus, false);
|
||||
if (ret < 0) {
|
||||
dev_err(bus->dev, "Program params failed: %d\n", ret);
|
||||
return ret;
|
||||
|
@ -1687,7 +1699,7 @@ static int _sdw_disable_stream(struct sdw_stream_runtime *stream)
|
|||
struct sdw_bus *bus = m_rt->bus;
|
||||
|
||||
/* Program params */
|
||||
ret = sdw_program_params(bus);
|
||||
ret = sdw_program_params(bus, false);
|
||||
if (ret < 0) {
|
||||
dev_err(bus->dev, "Program params failed: %d\n", ret);
|
||||
return ret;
|
||||
|
@ -1769,7 +1781,7 @@ static int _sdw_deprepare_stream(struct sdw_stream_runtime *stream)
|
|||
m_rt->ch_count * m_rt->stream->params.bps;
|
||||
|
||||
/* Program params */
|
||||
ret = sdw_program_params(bus);
|
||||
ret = sdw_program_params(bus, false);
|
||||
if (ret < 0) {
|
||||
dev_err(bus->dev, "Program params failed: %d\n", ret);
|
||||
return ret;
|
||||
|
|
Загрузка…
Ссылка в новой задаче