mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 04:18:39 +08:00
soundwire: intel/cadence: update hardware reset sequence
Combining hardware reset with the multi-link mode leads to a shortened hardware reset pattern observed on the bus. The updated hardware programming sequence is to first enable the clock with the sync_arm/sync_go pattern, and only in a second step to issue the hardware reset sequence. Since there is no longer a dependency between sync_arm/sync_go and hw_reset, the behavior of sdw_cdns_exit_reset() is changed to wait for the self-clearing CONFIG_UPDATE to go back to zero, Link: https://github.com/thesofproject/linux/issues/4170 Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Reviewed-by: Rander Wang <rander.wang@intel.com> Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com> Link: https://lore.kernel.org/r/20230518024119.164160-3-yung-chuan.liao@linux.intel.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
parent
46b56a5cd2
commit
ffc363d970
@ -283,6 +283,29 @@ static int cdns_config_update(struct sdw_cdns *cdns)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* sdw_cdns_config_update() - Update configurations
|
||||
* @cdns: Cadence instance
|
||||
*/
|
||||
void sdw_cdns_config_update(struct sdw_cdns *cdns)
|
||||
{
|
||||
/* commit changes */
|
||||
cdns_writel(cdns, CDNS_MCP_CONFIG_UPDATE, CDNS_MCP_CONFIG_UPDATE_BIT);
|
||||
}
|
||||
EXPORT_SYMBOL(sdw_cdns_config_update);
|
||||
|
||||
/**
|
||||
* sdw_cdns_config_update_set_wait() - wait until configuration update bit is self-cleared
|
||||
* @cdns: Cadence instance
|
||||
*/
|
||||
int sdw_cdns_config_update_set_wait(struct sdw_cdns *cdns)
|
||||
{
|
||||
/* the hardware recommendation is to wait at least 300us */
|
||||
return cdns_set_wait(cdns, CDNS_MCP_CONFIG_UPDATE,
|
||||
CDNS_MCP_CONFIG_UPDATE_BIT, 0);
|
||||
}
|
||||
EXPORT_SYMBOL(sdw_cdns_config_update_set_wait);
|
||||
|
||||
/*
|
||||
* debugfs
|
||||
*/
|
||||
@ -1116,13 +1139,7 @@ int sdw_cdns_exit_reset(struct sdw_cdns *cdns)
|
||||
CDNS_MCP_CONTROL_HW_RST);
|
||||
|
||||
/* commit changes */
|
||||
cdns_updatel(cdns, CDNS_MCP_CONFIG_UPDATE,
|
||||
CDNS_MCP_CONFIG_UPDATE_BIT,
|
||||
CDNS_MCP_CONFIG_UPDATE_BIT);
|
||||
|
||||
/* don't wait here */
|
||||
return 0;
|
||||
|
||||
return cdns_config_update(cdns);
|
||||
}
|
||||
EXPORT_SYMBOL(sdw_cdns_exit_reset);
|
||||
|
||||
|
@ -199,4 +199,7 @@ int cdns_set_sdw_stream(struct snd_soc_dai *dai,
|
||||
void sdw_cdns_check_self_clearing_bits(struct sdw_cdns *cdns, const char *string,
|
||||
bool initial_delay, int reset_iterations);
|
||||
|
||||
void sdw_cdns_config_update(struct sdw_cdns *cdns);
|
||||
int sdw_cdns_config_update_set_wait(struct sdw_cdns *cdns);
|
||||
|
||||
#endif /* __SDW_CADENCE_H */
|
||||
|
@ -29,11 +29,7 @@ int intel_start_bus(struct sdw_intel *sdw)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = sdw_cdns_exit_reset(cdns);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "%s: unable to exit bus reset sequence: %d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
sdw_cdns_config_update(cdns);
|
||||
|
||||
if (bus->multi_link) {
|
||||
ret = sdw_intel_sync_go(sdw);
|
||||
@ -43,6 +39,18 @@ int intel_start_bus(struct sdw_intel *sdw)
|
||||
}
|
||||
}
|
||||
|
||||
ret = sdw_cdns_config_update_set_wait(cdns);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "%s: CONFIG_UPDATE BIT still set\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = sdw_cdns_exit_reset(cdns);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "%s: unable to exit bus reset sequence: %d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = sdw_cdns_enable_interrupt(cdns, true);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "%s: cannot enable interrupts: %d\n", __func__, ret);
|
||||
@ -112,11 +120,7 @@ int intel_start_bus_after_reset(struct sdw_intel *sdw)
|
||||
}
|
||||
|
||||
if (!clock_stop0) {
|
||||
ret = sdw_cdns_exit_reset(cdns);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "unable to exit bus reset sequence during resume\n");
|
||||
return ret;
|
||||
}
|
||||
sdw_cdns_config_update(cdns);
|
||||
|
||||
if (bus->multi_link) {
|
||||
ret = sdw_intel_sync_go(sdw);
|
||||
@ -126,6 +130,18 @@ int intel_start_bus_after_reset(struct sdw_intel *sdw)
|
||||
}
|
||||
}
|
||||
|
||||
ret = sdw_cdns_config_update_set_wait(cdns);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "%s: CONFIG_UPDATE BIT still set\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = sdw_cdns_exit_reset(cdns);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "unable to exit bus reset sequence during resume\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = sdw_cdns_enable_interrupt(cdns, true);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "cannot enable interrupts during resume\n");
|
||||
|
Loading…
Reference in New Issue
Block a user