soundwire: intel: add missing support for all clock stop modes
authorPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Tue, 1 Sep 2020 15:05:50 +0000 (23:05 +0800)
committerVinod Koul <vkoul@kernel.org>
Thu, 3 Sep 2020 10:44:39 +0000 (16:14 +0530)
Deal with the BUS_RESET case, which is the default. The only change is
to add support for the exit sequence using the syncArm/syncGo mode for
the exit reset sequence.

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/20200901150556.19432-5-yung-chuan.liao@linux.intel.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
drivers/soundwire/intel.c

index 259e3da98e42d88914f43351b664e529a1e88e7a..8634d33c388c573f2dc379ce00a4191c03f36704 100644 (file)
@@ -1868,11 +1868,6 @@ static int intel_resume_runtime(struct device *dev)
 
                if (!clock_stop0) {
 
-                       /*
-                        * Re-initialize the IP since it was powered-off
-                        */
-                       sdw_cdns_init(&sdw->cdns);
-
                        /*
                         * make sure all Slaves are tagged as UNATTACHED and
                         * provide reason for reinitialization
@@ -1880,13 +1875,31 @@ static int intel_resume_runtime(struct device *dev)
 
                        status = SDW_UNATTACH_REQUEST_MASTER_RESET;
                        sdw_clear_slave_status(bus, status);
-               }
 
+                       ret = sdw_cdns_enable_interrupt(cdns, true);
+                       if (ret < 0) {
+                               dev_err(dev, "cannot enable interrupts during resume\n");
+                               return ret;
+                       }
+
+                       /*
+                        * follow recommended programming flows to avoid
+                        * timeouts when gsync is enabled
+                        */
+                       if (multi_link)
+                               intel_shim_sync_arm(sdw);
 
-               ret = sdw_cdns_enable_interrupt(cdns, true);
-               if (ret < 0) {
-                       dev_err(dev, "cannot enable interrupts during resume\n");
-                       return ret;
+                       /*
+                        * Re-initialize the IP since it was powered-off
+                        */
+                       sdw_cdns_init(&sdw->cdns);
+
+               } else {
+                       ret = sdw_cdns_enable_interrupt(cdns, true);
+                       if (ret < 0) {
+                               dev_err(dev, "cannot enable interrupts during resume\n");
+                               return ret;
+                       }
                }
 
                ret = sdw_cdns_clock_restart(cdns, !clock_stop0);
@@ -1894,6 +1907,22 @@ static int intel_resume_runtime(struct device *dev)
                        dev_err(dev, "unable to restart clock during resume\n");
                        return ret;
                }
+
+               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;
+                       }
+
+                       if (multi_link) {
+                               ret = intel_shim_sync_go(sdw);
+                               if (ret < 0) {
+                                       dev_err(sdw->cdns.dev, "sync go failed during resume\n");
+                                       return ret;
+                               }
+                       }
+               }
        } else if (!clock_stop_quirks) {
                ret = intel_init(sdw);
                if (ret) {