Lines Matching +full:soundwire +full:- +full:controller
1 // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
2 // Copyright(c) 2015-22 Intel Corporation.
5 * Soundwire Intel Manager Driver
18 #include <linux/soundwire/sdw_registers.h>
19 #include <linux/soundwire/sdw.h>
20 #include <linux/soundwire/sdw_intel.h>
29 * debug/config flags for the Intel SoundWire Master.
32 * flags reused in each byte, with master0 using the ls-byte, etc.
42 MODULE_PARM_DESC(sdw_md_flags, "SoundWire Intel Master device flags (0x0 all off)");
72 if (slave->id.part_id == wake_capable_list[i].part_id && in is_wake_capable()
73 slave->id.mfg_id == wake_capable_list[i].mfg_id) in is_wake_capable()
83 return sdw->link_res->hw_ops->pre_bank_switch(sdw); in generic_pre_bank_switch()
91 return sdw->link_res->hw_ops->post_bank_switch(sdw); in generic_post_bank_switch()
102 bool wake_capable = slave->prop.wake_capable || is_wake_capable(slave); in generic_new_peripheral_assigned()
109 dev_num_max = SDW_INTEL_DEV_NUM_IDA_MIN - 1; in generic_new_peripheral_assigned()
114 dev_err(bus->dev, "%s: invalid dev_num %d, wake supported %d\n", in generic_new_peripheral_assigned()
115 __func__, dev_num, slave->prop.wake_capable); in generic_new_peripheral_assigned()
119 if (sdw->link_res->hw_ops->program_sdi && wake_capable) in generic_new_peripheral_assigned()
120 sdw->link_res->hw_ops->program_sdi(sdw, dev_num); in generic_new_peripheral_assigned()
125 struct sdw_master_prop *prop = &bus->prop; in sdw_master_read_intel_prop()
133 "mipi-sdw-link-%d-subproperties", bus->link_id); in sdw_master_read_intel_prop()
135 link = device_get_named_child_node(bus->dev, name); in sdw_master_read_intel_prop()
137 dev_err(bus->dev, "Master node %s not found\n", name); in sdw_master_read_intel_prop()
138 return -EIO; in sdw_master_read_intel_prop()
142 "intel-sdw-ip-clock", in sdw_master_read_intel_prop()
143 &prop->mclk_freq); in sdw_master_read_intel_prop()
146 prop->mclk_freq /= 2; in sdw_master_read_intel_prop()
149 "intel-quirk-mask", in sdw_master_read_intel_prop()
153 prop->hw_disabled = true; in sdw_master_read_intel_prop()
155 prop->quirks = SDW_MASTER_QUIRKS_CLEAR_INITIAL_CLASH | in sdw_master_read_intel_prop()
158 intel_prop = devm_kzalloc(bus->dev, sizeof(*intel_prop), GFP_KERNEL); in sdw_master_read_intel_prop()
161 return -ENOMEM; in sdw_master_read_intel_prop()
165 intel_prop->clde = 0x0; in sdw_master_read_intel_prop()
166 intel_prop->doaise2 = 0x0; in sdw_master_read_intel_prop()
167 intel_prop->dodse2 = 0x0; in sdw_master_read_intel_prop()
168 intel_prop->clds = 0x0; in sdw_master_read_intel_prop()
169 intel_prop->clss = 0x0; in sdw_master_read_intel_prop()
170 intel_prop->doaise = 0x1; in sdw_master_read_intel_prop()
171 intel_prop->doais = 0x3; in sdw_master_read_intel_prop()
172 intel_prop->dodse = 0x0; in sdw_master_read_intel_prop()
173 intel_prop->dods = 0x1; in sdw_master_read_intel_prop()
176 "intel-sdw-clde", in sdw_master_read_intel_prop()
177 &intel_prop->clde); in sdw_master_read_intel_prop()
179 "intel-sdw-doaise2", in sdw_master_read_intel_prop()
180 &intel_prop->doaise2); in sdw_master_read_intel_prop()
182 "intel-sdw-dodse2", in sdw_master_read_intel_prop()
183 &intel_prop->dodse2); in sdw_master_read_intel_prop()
185 "intel-sdw-clds", in sdw_master_read_intel_prop()
186 &intel_prop->clds); in sdw_master_read_intel_prop()
188 "intel-sdw-clss", in sdw_master_read_intel_prop()
189 &intel_prop->clss); in sdw_master_read_intel_prop()
191 "intel-sdw-doaise", in sdw_master_read_intel_prop()
192 &intel_prop->doaise); in sdw_master_read_intel_prop()
194 "intel-sdw-doais", in sdw_master_read_intel_prop()
195 &intel_prop->doais); in sdw_master_read_intel_prop()
197 "intel-sdw-dodse", in sdw_master_read_intel_prop()
198 &intel_prop->dodse); in sdw_master_read_intel_prop()
200 "intel-sdw-dods", in sdw_master_read_intel_prop()
201 &intel_prop->dods); in sdw_master_read_intel_prop()
202 bus->vendor_specific_prop = intel_prop; in sdw_master_read_intel_prop()
204 dev_dbg(bus->dev, "doaise %#x doais %#x dodse %#x dods %#x\n", in sdw_master_read_intel_prop()
205 intel_prop->doaise, in sdw_master_read_intel_prop()
206 intel_prop->doais, in sdw_master_read_intel_prop()
207 intel_prop->dodse, in sdw_master_read_intel_prop()
208 intel_prop->dods); in sdw_master_read_intel_prop()
226 prop = &bus->prop; in intel_prop_read()
227 if (prop->clk_freq && prop->num_clk_freq > 1) { in intel_prop_read()
231 prop->default_frame_rate * in intel_prop_read()
232 prop->default_row * in intel_prop_read()
233 prop->default_col / in intel_prop_read()
236 prop->num_clk_freq = 1; in intel_prop_read()
237 prop->clk_freq[0] = default_bus_frequency; in intel_prop_read()
238 prop->max_clk_freq = default_bus_frequency; in intel_prop_read()
241 /* read Intel-specific properties */ in intel_prop_read()
253 if (slave->prop.wake_capable || is_wake_capable(slave)) in intel_get_device_num_ida()
258 bit = find_first_zero_bit(slave->bus->assigned, SDW_MAX_DEVICES); in intel_get_device_num_ida()
260 return -ENODEV; in intel_get_device_num_ida()
267 if (slave->prop.wake_capable || is_wake_capable(slave)) in intel_put_device_num_ida()
268 ida_free(&intel_peripheral_ida, slave->dev_num); in intel_put_device_num_ida()
292 struct device *dev = &auxdev->dev; in intel_link_probe()
301 return -ENOMEM; in intel_link_probe()
303 cdns = &sdw->cdns; in intel_link_probe()
304 bus = &cdns->bus; in intel_link_probe()
306 sdw->instance = auxdev->id; in intel_link_probe()
307 sdw->link_res = &ldev->link_res; in intel_link_probe()
308 cdns->dev = dev; in intel_link_probe()
309 cdns->registers = sdw->link_res->registers; in intel_link_probe()
310 cdns->ip_offset = sdw->link_res->ip_offset; in intel_link_probe()
311 cdns->instance = sdw->instance; in intel_link_probe()
312 cdns->msg_count = 0; in intel_link_probe()
314 /* single controller for all SoundWire links */ in intel_link_probe()
315 bus->controller_id = 0; in intel_link_probe()
317 bus->link_id = auxdev->id; in intel_link_probe()
318 bus->clk_stop_timeout = 1; in intel_link_probe()
321 * paranoia check: make sure ACPI-reported number of links is aligned with in intel_link_probe()
329 if (ret <= sdw->instance) { in intel_link_probe()
330 dev_err(dev, "%s: invalid link id %d, link count %d\n", __func__, auxdev->id, ret); in intel_link_probe()
331 return -EINVAL; in intel_link_probe()
337 bus->ops = &sdw_intel_ops; in intel_link_probe()
343 sdw->cdns.bus.compute_params = sdw_compute_params; in intel_link_probe()
348 ret = sdw_bus_master_add(bus, dev, dev->fwnode); in intel_link_probe()
354 if (bus->prop.hw_disabled) in intel_link_probe()
356 "SoundWire master %d is disabled, will be ignored\n", in intel_link_probe()
357 bus->link_id); in intel_link_probe()
362 bus->prop.err_threshold = 0; in intel_link_probe()
369 struct device *dev = &auxdev->dev; in intel_link_startup()
372 struct sdw_bus *bus = &cdns->bus; in intel_link_startup()
378 if (bus->prop.hw_disabled) { in intel_link_startup()
380 "SoundWire master %d is disabled, ignoring\n", in intel_link_startup()
381 sdw->instance); in intel_link_startup()
385 link_flags = md_flags >> (bus->link_id * 8); in intel_link_startup()
388 dev_dbg(dev, "Multi-link is disabled\n"); in intel_link_startup()
391 * hardware-based synchronization is required regardless in intel_link_startup()
392 * of the number of segments used by a stream: SSP-based in intel_link_startup()
393 * synchronization is gated by gsync when the multi-master in intel_link_startup()
396 bus->hw_sync_min_links = 1; in intel_link_startup()
398 bus->multi_link = multi_link; in intel_link_startup()
400 /* Initialize shim, controller */ in intel_link_startup()
424 pm_runtime_resume(bus->dev); in intel_link_startup()
434 clock_stop_quirks = sdw->link_res->clock_stop_quirks; in intel_link_startup()
451 * there are no Slave devices populated or if the power-on is in intel_link_startup()
455 * Conditionally force the pm_runtime core to re-evaluate the in intel_link_startup()
462 pm_runtime_mark_last_busy(bus->dev); in intel_link_startup()
467 sdw->startup_done = true; in intel_link_startup()
483 struct sdw_bus *bus = &cdns->bus; in intel_link_remove()
490 if (!bus->prop.hw_disabled) { in intel_link_remove()
492 cancel_delayed_work_sync(&cdns->attach_dwork); in intel_link_remove()
500 struct device *dev = &auxdev->dev; in intel_link_process_wakeen_event()
505 bus = &sdw->cdns.bus; in intel_link_process_wakeen_event()
507 if (bus->prop.hw_disabled || !sdw->startup_done) { in intel_link_process_wakeen_event()
508 dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n", in intel_link_process_wakeen_event()
509 bus->link_id); in intel_link_process_wakeen_event()
521 * Slaves re-attaching and be re-enumerated. The SoundWire physical in intel_link_process_wakeen_event()
540 if (!slave->probed) { in intel_resume_child_device()
544 if (!slave->dev_num_sticky) { in intel_resume_child_device()
562 struct sdw_bus *bus = &cdns->bus; in intel_pm_prepare()
566 if (bus->prop.hw_disabled || !sdw->startup_done) { in intel_pm_prepare()
567 dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n", in intel_pm_prepare()
568 bus->link_id); in intel_pm_prepare()
572 clock_stop_quirks = sdw->link_res->clock_stop_quirks; in intel_pm_prepare()
575 pm_runtime_suspended(dev->parent) && in intel_pm_prepare()
603 * this is a no-op. in intel_pm_prepare()
605 * step in SoundWire codec drivers. This would however require a lot in intel_pm_prepare()
606 * of code to handle an Intel-specific corner case. It is simpler in in intel_pm_prepare()
609 ret = device_for_each_child(bus->dev, NULL, intel_resume_child_device); in intel_pm_prepare()
622 struct sdw_bus *bus = &cdns->bus; in intel_suspend()
626 if (bus->prop.hw_disabled || !sdw->startup_done) { in intel_suspend()
627 dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n", in intel_suspend()
628 bus->link_id); in intel_suspend()
635 clock_stop_quirks = sdw->link_res->clock_stop_quirks; in intel_suspend()
640 if (pm_runtime_suspended(dev->parent)) { in intel_suspend()
667 struct sdw_bus *bus = &cdns->bus; in intel_suspend_runtime()
671 if (bus->prop.hw_disabled || !sdw->startup_done) { in intel_suspend_runtime()
672 dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n", in intel_suspend_runtime()
673 bus->link_id); in intel_suspend_runtime()
677 clock_stop_quirks = sdw->link_res->clock_stop_quirks; in intel_suspend_runtime()
696 ret = -EINVAL; in intel_suspend_runtime()
706 struct sdw_bus *bus = &cdns->bus; in intel_resume()
710 if (bus->prop.hw_disabled || !sdw->startup_done) { in intel_resume()
711 dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n", in intel_resume()
712 bus->link_id); in intel_resume()
725 pm_runtime_resume(bus->dev); in intel_resume()
727 link_flags = md_flags >> (bus->link_id * 8); in intel_resume()
762 pm_runtime_mark_last_busy(bus->dev); in intel_resume()
772 struct sdw_bus *bus = &cdns->bus; in intel_resume_runtime()
776 if (bus->prop.hw_disabled || !sdw->startup_done) { in intel_resume_runtime()
777 dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n", in intel_resume_runtime()
778 bus->link_id); in intel_resume_runtime()
785 clock_stop_quirks = sdw->link_res->clock_stop_quirks; in intel_resume_runtime()
839 ret = -EINVAL; in intel_resume_runtime()
869 MODULE_DESCRIPTION("Intel Soundwire Link Driver");