1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
2 // Copyright(c) 2015-2023 Intel Corporation. All rights reserved.
4 #include <linux/acpi.h>
5 #include <linux/soundwire/sdw_registers.h>
6 #include <linux/soundwire/sdw.h>
7 #include <linux/soundwire/sdw_intel.h>
8 #include "cadence_master.h"
12 int intel_start_bus(struct sdw_intel *sdw)
14 struct device *dev = sdw->cdns.dev;
15 struct sdw_cdns *cdns = &sdw->cdns;
16 struct sdw_bus *bus = &cdns->bus;
19 ret = sdw_cdns_enable_interrupt(cdns, true);
21 dev_err(dev, "%s: cannot enable interrupts: %d\n", __func__, ret);
26 * follow recommended programming flows to avoid timeouts when
30 sdw_intel_sync_arm(sdw);
32 ret = sdw_cdns_init(cdns);
34 dev_err(dev, "%s: unable to initialize Cadence IP: %d\n", __func__, ret);
38 ret = sdw_cdns_exit_reset(cdns);
40 dev_err(dev, "%s: unable to exit bus reset sequence: %d\n", __func__, ret);
44 if (bus->multi_link) {
45 ret = sdw_intel_sync_go(sdw);
47 dev_err(dev, "%s: sync go failed: %d\n", __func__, ret);
51 sdw_cdns_check_self_clearing_bits(cdns, __func__,
52 true, INTEL_MASTER_RESET_ITERATIONS);
57 sdw_cdns_enable_interrupt(cdns, false);
61 int intel_start_bus_after_reset(struct sdw_intel *sdw)
63 struct device *dev = sdw->cdns.dev;
64 struct sdw_cdns *cdns = &sdw->cdns;
65 struct sdw_bus *bus = &cdns->bus;
71 * An exception condition occurs for the CLK_STOP_BUS_RESET
72 * case if one or more masters remain active. In this condition,
73 * all the masters are powered on for they are in the same power
74 * domain. Master can preserve its context for clock stop0, so
75 * there is no need to clear slave status and reset bus.
77 clock_stop0 = sdw_cdns_is_clock_stop(&sdw->cdns);
82 * make sure all Slaves are tagged as UNATTACHED and
83 * provide reason for reinitialization
86 status = SDW_UNATTACH_REQUEST_MASTER_RESET;
87 sdw_clear_slave_status(bus, status);
89 ret = sdw_cdns_enable_interrupt(cdns, true);
91 dev_err(dev, "cannot enable interrupts during resume\n");
96 * follow recommended programming flows to avoid
97 * timeouts when gsync is enabled
100 sdw_intel_sync_arm(sdw);
103 * Re-initialize the IP since it was powered-off
105 sdw_cdns_init(&sdw->cdns);
108 ret = sdw_cdns_enable_interrupt(cdns, true);
110 dev_err(dev, "cannot enable interrupts during resume\n");
115 ret = sdw_cdns_clock_restart(cdns, !clock_stop0);
117 dev_err(dev, "unable to restart clock during resume\n");
122 ret = sdw_cdns_exit_reset(cdns);
124 dev_err(dev, "unable to exit bus reset sequence during resume\n");
128 if (bus->multi_link) {
129 ret = sdw_intel_sync_go(sdw);
131 dev_err(sdw->cdns.dev, "sync go failed during resume\n");
136 sdw_cdns_check_self_clearing_bits(cdns, __func__, true, INTEL_MASTER_RESET_ITERATIONS);
141 sdw_cdns_enable_interrupt(cdns, false);
145 void intel_check_clock_stop(struct sdw_intel *sdw)
147 struct device *dev = sdw->cdns.dev;
150 clock_stop0 = sdw_cdns_is_clock_stop(&sdw->cdns);
152 dev_err(dev, "%s: invalid configuration, clock was not stopped\n", __func__);
155 int intel_start_bus_after_clock_stop(struct sdw_intel *sdw)
157 struct device *dev = sdw->cdns.dev;
158 struct sdw_cdns *cdns = &sdw->cdns;
161 ret = sdw_cdns_enable_interrupt(cdns, true);
163 dev_err(dev, "%s: cannot enable interrupts: %d\n", __func__, ret);
167 ret = sdw_cdns_clock_restart(cdns, false);
169 dev_err(dev, "%s: unable to restart clock: %d\n", __func__, ret);
170 sdw_cdns_enable_interrupt(cdns, false);
174 sdw_cdns_check_self_clearing_bits(cdns, "intel_resume_runtime no_quirks",
175 true, INTEL_MASTER_RESET_ITERATIONS);
180 int intel_stop_bus(struct sdw_intel *sdw, bool clock_stop)
182 struct device *dev = sdw->cdns.dev;
183 struct sdw_cdns *cdns = &sdw->cdns;
184 bool wake_enable = false;
188 ret = sdw_cdns_clock_stop(cdns, true);
190 dev_err(dev, "%s: cannot stop clock: %d\n", __func__, ret);
195 ret = sdw_cdns_enable_interrupt(cdns, false);
197 dev_err(dev, "%s: cannot disable interrupts: %d\n", __func__, ret);
201 ret = sdw_intel_link_power_down(sdw);
203 dev_err(dev, "%s: Link power down failed: %d\n", __func__, ret);
207 sdw_intel_shim_wake(sdw, wake_enable);
213 * bank switch routines
216 int intel_pre_bank_switch(struct sdw_intel *sdw)
218 struct sdw_cdns *cdns = &sdw->cdns;
219 struct sdw_bus *bus = &cdns->bus;
221 /* Write to register only for multi-link */
222 if (!bus->multi_link)
225 sdw_intel_sync_arm(sdw);
230 int intel_post_bank_switch(struct sdw_intel *sdw)
232 struct sdw_cdns *cdns = &sdw->cdns;
233 struct sdw_bus *bus = &cdns->bus;
236 /* Write to register only for multi-link */
237 if (!bus->multi_link)
240 mutex_lock(sdw->link_res->shim_lock);
243 * post_bank_switch() ops is called from the bus in loop for
244 * all the Masters in the steam with the expectation that
245 * we trigger the bankswitch for the only first Master in the list
246 * and do nothing for the other Masters
248 * So, set the SYNCGO bit only if CMDSYNC bit is set for any Master.
250 if (sdw_intel_sync_check_cmdsync_unlocked(sdw))
251 ret = sdw_intel_sync_go_unlocked(sdw);
253 mutex_unlock(sdw->link_res->shim_lock);
256 dev_err(sdw->cdns.dev, "Post bank switch failed: %d\n", ret);