soundwire: cadence_master: always set CMD_ACCEPT
authorPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Tue, 11 May 2021 02:52:47 +0000 (10:52 +0800)
committerVinod Koul <vkoul@kernel.org>
Tue, 11 May 2021 12:20:33 +0000 (17:50 +0530)
The Cadence IP can be configured in two different ways to deal with
CMD_IGNORED replies to broadcast commands. The CMD_ACCEPT bitfield
controls whether the command is discarded or if the IP proceeds with
the change (typically a bank switch or clock stop command).

The existing code seems to be inconsistent:
a) For some historical reason, we set this CMD_ACCEPT bitfield during
the initialization, but we don't during a resume from a clock-stoppped
state.
b) In addition, the loop used in the clock-stop sequence is quite
racy, it's possible that a device has lost sync but it's still tagged
as ATTACHED.
c) If somehow a Device loses sync and is unable to ack a broadcast
command, we do not have an error handling mechanism anyways. The IP
should go ahead and let the Device regain sync at a later time.

Make sure the CMD_ACCEPT bit is always set.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski@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/20210511025247.25339-1-yung-chuan.liao@linux.intel.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
drivers/soundwire/cadence_master.c

index 192dac1..2595042 100644 (file)
@@ -1428,20 +1428,6 @@ int sdw_cdns_clock_stop(struct sdw_cdns *cdns, bool block_wake)
                }
        }
 
-       /*
-        * This CMD_ACCEPT should be used when there are no devices
-        * attached on the link when entering clock stop mode. If this is
-        * not set and there is a broadcast write then the command ignored
-        * will be treated as a failure
-        */
-       if (!slave_present)
-               cdns_updatel(cdns, CDNS_MCP_CONTROL,
-                            CDNS_MCP_CONTROL_CMD_ACCEPT,
-                            CDNS_MCP_CONTROL_CMD_ACCEPT);
-       else
-               cdns_updatel(cdns, CDNS_MCP_CONTROL,
-                            CDNS_MCP_CONTROL_CMD_ACCEPT, 0);
-
        /* commit changes */
        ret = cdns_config_update(cdns);
        if (ret < 0) {
@@ -1508,11 +1494,8 @@ int sdw_cdns_clock_restart(struct sdw_cdns *cdns, bool bus_reset)
        cdns_updatel(cdns, CDNS_MCP_CONTROL,
                     CDNS_MCP_CONTROL_BLOCK_WAKEUP, 0);
 
-       /*
-        * clear CMD_ACCEPT so that the command ignored
-        * will be treated as a failure during a broadcast write
-        */
-       cdns_updatel(cdns, CDNS_MCP_CONTROL, CDNS_MCP_CONTROL_CMD_ACCEPT, 0);
+       cdns_updatel(cdns, CDNS_MCP_CONTROL, CDNS_MCP_CONTROL_CMD_ACCEPT,
+                    CDNS_MCP_CONTROL_CMD_ACCEPT);
 
        if (!bus_reset) {