Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.15.
  1// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
  2// Copyright(c) 2015-17 Intel Corporation.
  3
  4/*
  5 * SDW Intel Init Routines
  6 *
  7 * Initializes and creates SDW devices based on ACPI and Hardware values
  8 */
  9
 10#include <linux/acpi.h>
 11#include <linux/export.h>
 12#include <linux/interrupt.h>
 13#include <linux/io.h>
 14#include <linux/module.h>
 15#include <linux/auxiliary_bus.h>
 16#include <linux/pm_runtime.h>
 17#include <linux/soundwire/sdw_intel.h>
 18#include "cadence_master.h"
 19#include "intel.h"
 20
 21#define SDW_SHIM_LCAP		0x0
 22#define SDW_SHIM_BASE		0x2C000
 23#define SDW_ALH_BASE		0x2C800
 24#define SDW_LINK_BASE		0x30000
 25#define SDW_LINK_SIZE		0x10000
 26
 27static void intel_link_dev_release(struct device *dev)
 28{
 29	struct auxiliary_device *auxdev = to_auxiliary_dev(dev);
 30	struct sdw_intel_link_dev *ldev = auxiliary_dev_to_sdw_intel_link_dev(auxdev);
 31
 32	kfree(ldev);
 33}
 34
 35/* alloc, init and add link devices */
 36static struct sdw_intel_link_dev *intel_link_dev_register(struct sdw_intel_res *res,
 37							  struct sdw_intel_ctx *ctx,
 38							  struct fwnode_handle *fwnode,
 39							  const char *name,
 40							  int link_id)
 41{
 42	struct sdw_intel_link_dev *ldev;
 43	struct sdw_intel_link_res *link;
 44	struct auxiliary_device *auxdev;
 45	int ret;
 46
 47	ldev = kzalloc(sizeof(*ldev), GFP_KERNEL);
 48	if (!ldev)
 49		return ERR_PTR(-ENOMEM);
 50
 51	auxdev = &ldev->auxdev;
 52	auxdev->name = name;
 53	auxdev->dev.parent = res->parent;
 54	auxdev->dev.fwnode = fwnode;
 55	auxdev->dev.release = intel_link_dev_release;
 56
 57	/* we don't use an IDA since we already have a link ID */
 58	auxdev->id = link_id;
 59
 60	/*
 61	 * keep a handle on the allocated memory, to be used in all other functions.
 62	 * Since the same pattern is used to skip links that are not enabled, there is
 63	 * no need to check if ctx->ldev[i] is NULL later on.
 64	 */
 65	ctx->ldev[link_id] = ldev;
 66
 67	/* Add link information used in the driver probe */
 68	link = &ldev->link_res;
 69	link->mmio_base = res->mmio_base;
 70	link->registers = res->mmio_base + SDW_LINK_BASE
 71		+ (SDW_LINK_SIZE * link_id);
 72	link->shim = res->mmio_base + SDW_SHIM_BASE;
 73	link->alh = res->mmio_base + SDW_ALH_BASE;
 74
 75	link->ops = res->ops;
 76	link->dev = res->dev;
 77
 78	link->clock_stop_quirks = res->clock_stop_quirks;
 79	link->shim_lock = &ctx->shim_lock;
 80	link->shim_mask = &ctx->shim_mask;
 81	link->link_mask = ctx->link_mask;
 82
 83	/* now follow the two-step init/add sequence */
 84	ret = auxiliary_device_init(auxdev);
 85	if (ret < 0) {
 86		dev_err(res->parent, "failed to initialize link dev %s link_id %d\n",
 87			name, link_id);
 88		kfree(ldev);
 89		return ERR_PTR(ret);
 90	}
 91
 92	ret = auxiliary_device_add(&ldev->auxdev);
 93	if (ret < 0) {
 94		dev_err(res->parent, "failed to add link dev %s link_id %d\n",
 95			ldev->auxdev.name, link_id);
 96		/* ldev will be freed with the put_device() and .release sequence */
 97		auxiliary_device_uninit(&ldev->auxdev);
 98		return ERR_PTR(ret);
 99	}
100
101	return ldev;
102}
103
104static void intel_link_dev_unregister(struct sdw_intel_link_dev *ldev)
105{
106	auxiliary_device_delete(&ldev->auxdev);
107	auxiliary_device_uninit(&ldev->auxdev);
108}
109
110static int sdw_intel_cleanup(struct sdw_intel_ctx *ctx)
111{
112	struct sdw_intel_link_dev *ldev;
113	u32 link_mask;
114	int i;
115
116	link_mask = ctx->link_mask;
117
118	for (i = 0; i < ctx->count; i++) {
119		if (!(link_mask & BIT(i)))
120			continue;
121
122		ldev = ctx->ldev[i];
123
124		pm_runtime_disable(&ldev->auxdev.dev);
125		if (!ldev->link_res.clock_stop_quirks)
126			pm_runtime_put_noidle(ldev->link_res.dev);
127
128		intel_link_dev_unregister(ldev);
129	}
130
131	return 0;
132}
133
134#define HDA_DSP_REG_ADSPIC2             (0x10)
135#define HDA_DSP_REG_ADSPIS2             (0x14)
136#define HDA_DSP_REG_ADSPIC2_SNDW        BIT(5)
137
138/**
139 * sdw_intel_enable_irq() - enable/disable Intel SoundWire IRQ
140 * @mmio_base: The mmio base of the control register
141 * @enable: true if enable
142 */
143void sdw_intel_enable_irq(void __iomem *mmio_base, bool enable)
144{
145	u32 val;
146
147	val = readl(mmio_base + HDA_DSP_REG_ADSPIC2);
148
149	if (enable)
150		val |= HDA_DSP_REG_ADSPIC2_SNDW;
151	else
152		val &= ~HDA_DSP_REG_ADSPIC2_SNDW;
153
154	writel(val, mmio_base + HDA_DSP_REG_ADSPIC2);
155}
156EXPORT_SYMBOL_NS(sdw_intel_enable_irq, SOUNDWIRE_INTEL_INIT);
157
158irqreturn_t sdw_intel_thread(int irq, void *dev_id)
159{
160	struct sdw_intel_ctx *ctx = dev_id;
161	struct sdw_intel_link_res *link;
162
163	list_for_each_entry(link, &ctx->link_list, list)
164		sdw_cdns_irq(irq, link->cdns);
165
166	sdw_intel_enable_irq(ctx->mmio_base, true);
167	return IRQ_HANDLED;
168}
169EXPORT_SYMBOL_NS(sdw_intel_thread, SOUNDWIRE_INTEL_INIT);
170
171static struct sdw_intel_ctx
172*sdw_intel_probe_controller(struct sdw_intel_res *res)
173{
174	struct sdw_intel_link_res *link;
175	struct sdw_intel_link_dev *ldev;
176	struct sdw_intel_ctx *ctx;
177	struct acpi_device *adev;
178	struct sdw_slave *slave;
179	struct list_head *node;
180	struct sdw_bus *bus;
181	u32 link_mask;
182	int num_slaves = 0;
183	int count;
184	int i;
185
186	if (!res)
187		return NULL;
188
189	if (acpi_bus_get_device(res->handle, &adev))
190		return NULL;
191
192	if (!res->count)
193		return NULL;
194
195	count = res->count;
196	dev_dbg(&adev->dev, "Creating %d SDW Link devices\n", count);
197
198	/*
199	 * we need to alloc/free memory manually and can't use devm:
200	 * this routine may be called from a workqueue, and not from
201	 * the parent .probe.
202	 * If devm_ was used, the memory might never be freed on errors.
203	 */
204	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
205	if (!ctx)
206		return NULL;
207
208	ctx->count = count;
209
210	/*
211	 * allocate the array of pointers. The link-specific data is allocated
212	 * as part of the first loop below and released with the auxiliary_device_uninit().
213	 * If some links are disabled, the link pointer will remain NULL. Given that the
214	 * number of links is small, this is simpler than using a list to keep track of links.
215	 */
216	ctx->ldev = kcalloc(ctx->count, sizeof(*ctx->ldev), GFP_KERNEL);
217	if (!ctx->ldev) {
218		kfree(ctx);
219		return NULL;
220	}
221
222	ctx->mmio_base = res->mmio_base;
223	ctx->link_mask = res->link_mask;
224	ctx->handle = res->handle;
225	mutex_init(&ctx->shim_lock);
226
227	link_mask = ctx->link_mask;
228
229	INIT_LIST_HEAD(&ctx->link_list);
230
231	for (i = 0; i < count; i++) {
232		if (!(link_mask & BIT(i)))
233			continue;
234
235		/*
236		 * init and add a device for each link
237		 *
238		 * The name of the device will be soundwire_intel.link.[i],
239		 * with the "soundwire_intel" module prefix automatically added
240		 * by the auxiliary bus core.
241		 */
242		ldev = intel_link_dev_register(res,
243					       ctx,
244					       acpi_fwnode_handle(adev),
245					       "link",
246					       i);
247		if (IS_ERR(ldev))
248			goto err;
249
250		link = &ldev->link_res;
251		link->cdns = dev_get_drvdata(&ldev->auxdev.dev);
252
253		if (!link->cdns) {
254			dev_err(&adev->dev, "failed to get link->cdns\n");
255			/*
256			 * 1 will be subtracted from i in the err label, but we need to call
257			 * intel_link_dev_unregister for this ldev, so plus 1 now
258			 */
259			i++;
260			goto err;
261		}
262		list_add_tail(&link->list, &ctx->link_list);
263		bus = &link->cdns->bus;
264		/* Calculate number of slaves */
265		list_for_each(node, &bus->slaves)
266			num_slaves++;
267	}
268
269	ctx->ids = kcalloc(num_slaves, sizeof(*ctx->ids), GFP_KERNEL);
270	if (!ctx->ids)
271		goto err;
272
273	ctx->num_slaves = num_slaves;
274	i = 0;
275	list_for_each_entry(link, &ctx->link_list, list) {
276		bus = &link->cdns->bus;
277		list_for_each_entry(slave, &bus->slaves, node) {
278			ctx->ids[i].id = slave->id;
279			ctx->ids[i].link_id = bus->link_id;
280			i++;
281		}
282	}
283
284	return ctx;
285
286err:
287	while (i--) {
288		if (!(link_mask & BIT(i)))
289			continue;
290		ldev = ctx->ldev[i];
291		intel_link_dev_unregister(ldev);
292	}
293	kfree(ctx->ldev);
294	kfree(ctx);
295	return NULL;
296}
297
298static int
299sdw_intel_startup_controller(struct sdw_intel_ctx *ctx)
300{
301	struct acpi_device *adev;
302	struct sdw_intel_link_dev *ldev;
303	u32 caps;
304	u32 link_mask;
305	int i;
306
307	if (acpi_bus_get_device(ctx->handle, &adev))
308		return -EINVAL;
309
310	/* Check SNDWLCAP.LCOUNT */
311	caps = ioread32(ctx->mmio_base + SDW_SHIM_BASE + SDW_SHIM_LCAP);
312	caps &= GENMASK(2, 0);
313
314	/* Check HW supported vs property value */
315	if (caps < ctx->count) {
316		dev_err(&adev->dev,
317			"BIOS master count is larger than hardware capabilities\n");
318		return -EINVAL;
319	}
320
321	if (!ctx->ldev)
322		return -EINVAL;
323
324	link_mask = ctx->link_mask;
325
326	/* Startup SDW Master devices */
327	for (i = 0; i < ctx->count; i++) {
328		if (!(link_mask & BIT(i)))
329			continue;
330
331		ldev = ctx->ldev[i];
332
333		intel_link_startup(&ldev->auxdev);
334
335		if (!ldev->link_res.clock_stop_quirks) {
336			/*
337			 * we need to prevent the parent PCI device
338			 * from entering pm_runtime suspend, so that
339			 * power rails to the SoundWire IP are not
340			 * turned off.
341			 */
342			pm_runtime_get_noresume(ldev->link_res.dev);
343		}
344	}
345
346	return 0;
347}
348
349/**
350 * sdw_intel_probe() - SoundWire Intel probe routine
351 * @res: resource data
352 *
353 * This registers an auxiliary device for each Master handled by the controller,
354 * and SoundWire Master and Slave devices will be created by the auxiliary
355 * device probe. All the information necessary is stored in the context, and
356 * the res argument pointer can be freed after this step.
357 * This function will be called after sdw_intel_acpi_scan() by SOF probe.
358 */
359struct sdw_intel_ctx
360*sdw_intel_probe(struct sdw_intel_res *res)
361{
362	return sdw_intel_probe_controller(res);
363}
364EXPORT_SYMBOL_NS(sdw_intel_probe, SOUNDWIRE_INTEL_INIT);
365
366/**
367 * sdw_intel_startup() - SoundWire Intel startup
368 * @ctx: SoundWire context allocated in the probe
369 *
370 * Startup Intel SoundWire controller. This function will be called after
371 * Intel Audio DSP is powered up.
372 */
373int sdw_intel_startup(struct sdw_intel_ctx *ctx)
374{
375	return sdw_intel_startup_controller(ctx);
376}
377EXPORT_SYMBOL_NS(sdw_intel_startup, SOUNDWIRE_INTEL_INIT);
378/**
379 * sdw_intel_exit() - SoundWire Intel exit
380 * @ctx: SoundWire context allocated in the probe
381 *
382 * Delete the controller instances created and cleanup
383 */
384void sdw_intel_exit(struct sdw_intel_ctx *ctx)
385{
386	sdw_intel_cleanup(ctx);
387	kfree(ctx->ids);
388	kfree(ctx->ldev);
389	kfree(ctx);
390}
391EXPORT_SYMBOL_NS(sdw_intel_exit, SOUNDWIRE_INTEL_INIT);
392
393void sdw_intel_process_wakeen_event(struct sdw_intel_ctx *ctx)
394{
395	struct sdw_intel_link_dev *ldev;
396	u32 link_mask;
397	int i;
398
399	if (!ctx->ldev)
400		return;
401
402	link_mask = ctx->link_mask;
403
404	/* Startup SDW Master devices */
405	for (i = 0; i < ctx->count; i++) {
406		if (!(link_mask & BIT(i)))
407			continue;
408
409		ldev = ctx->ldev[i];
410
411		intel_link_process_wakeen_event(&ldev->auxdev);
412	}
413}
414EXPORT_SYMBOL_NS(sdw_intel_process_wakeen_event, SOUNDWIRE_INTEL_INIT);
415
416MODULE_LICENSE("Dual BSD/GPL");
417MODULE_DESCRIPTION("Intel Soundwire Init Library");