summaryrefslogtreecommitdiff
path: root/drivers/soundwire/cadence_master.h
diff options
context:
space:
mode:
authorPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>2021-07-14 13:13:49 +0800
committerVinod Koul <vkoul@kernel.org>2021-08-02 09:19:45 +0530
commitff560946ef15fb05b18a660f6b25e9c26fe050e1 (patch)
treebd0df194b4ac7988c17d7e5308682482ea66cbd2 /drivers/soundwire/cadence_master.h
parentcaa15c8dcb00f9dfe9f304e6e0955c5b29cf2499 (diff)
soundwire: cadence: add paranoid check on self-clearing bits
The Cadence IP exposes a small number of self-clearing bits in the MCP_CONTROL and MCP_CONFIG_UPDATE registers. We currently do not check that those bits are indeed cleared, e.g. during resume operations. That could lead to resuming peripheral devices too early. In addition, if we happen to read these registers, update one of the fields and write the register back, we may be writing stale data that might have been cleared in hardware. These sort of race conditions could lead to e.g. doing a hw_reset twice or stopping a clock that just restarted. There is no clear way of avoiding these potential race conditions other than making sure that these registers fields are cleared before any read-modify-write sequence. If we detect this sort of errors, we only log them since there is no clear recovery possible. The only way out is likely to restart the IP with a suspend/resume cycle. Note that the checks are performed before updating the registers, as well as after the Intel 'sync go' sequence in multi-link mode. That should cover both the start and end of suspend/resume hardware configurations. The Multi-Master mode gates the configuration updates until the 'sync go' signal is asserted, so we only check on init and after the end of the 'sync go' sequence. The duration of the usleep_range() was defined by the GSYNC frequency used in multi-master mode. With a 4kHz frequency, any configuration change might be deferred by up to 250us. Extending the range to 1000-1500us should guarantee that the configuration change is completed without any significant impact on the overall resume time. Suggested-by: Bard Liao <yung-chuan.liao@linux.intel.com> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com> Link: https://lore.kernel.org/r/20210714051349.13064-1-yung-chuan.liao@linux.intel.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
Diffstat (limited to 'drivers/soundwire/cadence_master.h')
-rw-r--r--drivers/soundwire/cadence_master.h4
1 files changed, 4 insertions, 0 deletions
diff --git a/drivers/soundwire/cadence_master.h b/drivers/soundwire/cadence_master.h
index 0e7f8b35bb21..b54c161a837f 100644
--- a/drivers/soundwire/cadence_master.h
+++ b/drivers/soundwire/cadence_master.h
@@ -184,4 +184,8 @@ int cdns_bus_conf(struct sdw_bus *bus, struct sdw_bus_params *params);
int cdns_set_sdw_stream(struct snd_soc_dai *dai,
void *stream, bool pcm, int direction);
+
+void sdw_cdns_check_self_clearing_bits(struct sdw_cdns *cdns, const char *string,
+ bool initial_delay, int reset_iterations);
+
#endif /* __SDW_CADENCE_H */