1// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
2// Copyright(c) 2015-17 Intel Corporation.
3
4/*
5 * Soundwire Intel Master Driver
6 */
7
8#include <linux/acpi.h>
9#include <linux/debugfs.h>
10#include <linux/delay.h>
11#include <linux/io.h>
12#include <sound/pcm_params.h>
13#include <linux/pm_runtime.h>
14#include <sound/soc.h>
15#include <linux/soundwire/sdw_registers.h>
16#include <linux/soundwire/sdw.h>
17#include <linux/soundwire/sdw_intel.h>
18#include "cadence_master.h"
19#include "bus.h"
20#include "intel.h"
21
22static int intel_wait_bit(void __iomem *base, int offset, u32 mask, u32 target)
23{
24	int timeout = 10;
25	u32 reg_read;
26
27	do {
28		reg_read = readl(base + offset);
29		if ((reg_read & mask) == target)
30			return 0;
31
32		timeout--;
33		usleep_range(50, 100);
34	} while (timeout != 0);
35
36	return -EAGAIN;
37}
38
39static int intel_clear_bit(void __iomem *base, int offset, u32 value, u32 mask)
40{
41	writel(value, base + offset);
42	return intel_wait_bit(base, offset, mask, 0);
43}
44
45static int intel_set_bit(void __iomem *base, int offset, u32 value, u32 mask)
46{
47	writel(value, base + offset);
48	return intel_wait_bit(base, offset, mask, mask);
49}
50
51/*
52 * debugfs
53 */
54#ifdef CONFIG_DEBUG_FS
55
56#define RD_BUF (2 * PAGE_SIZE)
57
58static ssize_t intel_sprintf(void __iomem *mem, bool l,
59			     char *buf, size_t pos, unsigned int reg)
60{
61	int value;
62
63	if (l)
64		value = intel_readl(mem, reg);
65	else
66		value = intel_readw(mem, reg);
67
68	return scnprintf(buf + pos, RD_BUF - pos, "%4x\t%4x\n", reg, value);
69}
70
71static int intel_reg_show(struct seq_file *s_file, void *data)
72{
73	struct sdw_intel *sdw = s_file->private;
74	void __iomem *s = sdw->link_res->shim;
75	void __iomem *a = sdw->link_res->alh;
76	char *buf;
77	ssize_t ret;
78	int i, j;
79	unsigned int links, reg;
80
81	buf = kzalloc(RD_BUF, GFP_KERNEL);
82	if (!buf)
83		return -ENOMEM;
84
85	links = intel_readl(s, SDW_SHIM_LCAP) & SDW_SHIM_LCAP_LCOUNT_MASK;
86
87	ret = scnprintf(buf, RD_BUF, "Register  Value\n");
88	ret += scnprintf(buf + ret, RD_BUF - ret, "\nShim\n");
89
90	for (i = 0; i < links; i++) {
91		reg = SDW_SHIM_LCAP + i * 4;
92		ret += intel_sprintf(s, true, buf, ret, reg);
93	}
94
95	for (i = 0; i < links; i++) {
96		ret += scnprintf(buf + ret, RD_BUF - ret, "\nLink%d\n", i);
97		ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_CTLSCAP(i));
98		ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_CTLS0CM(i));
99		ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_CTLS1CM(i));
100		ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_CTLS2CM(i));
101		ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_CTLS3CM(i));
102		ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_PCMSCAP(i));
103
104		ret += scnprintf(buf + ret, RD_BUF - ret, "\n PCMSyCH registers\n");
105
106		/*
107		 * the value 10 is the number of PDIs. We will need a
108		 * cleanup to remove hard-coded Intel configurations
109		 * from cadence_master.c
110		 */
111		for (j = 0; j < 10; j++) {
112			ret += intel_sprintf(s, false, buf, ret,
113					SDW_SHIM_PCMSYCHM(i, j));
114			ret += intel_sprintf(s, false, buf, ret,
115					SDW_SHIM_PCMSYCHC(i, j));
116		}
117		ret += scnprintf(buf + ret, RD_BUF - ret, "\n IOCTL, CTMCTL\n");
118
119		ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_IOCTL(i));
120		ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_CTMCTL(i));
121	}
122
123	ret += scnprintf(buf + ret, RD_BUF - ret, "\nWake registers\n");
124	ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_WAKEEN);
125	ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_WAKESTS);
126
127	ret += scnprintf(buf + ret, RD_BUF - ret, "\nALH STRMzCFG\n");
128	for (i = 0; i < SDW_ALH_NUM_STREAMS; i++)
129		ret += intel_sprintf(a, true, buf, ret, SDW_ALH_STRMZCFG(i));
130
131	seq_printf(s_file, "%s", buf);
132	kfree(buf);
133
134	return 0;
135}
136DEFINE_SHOW_ATTRIBUTE(intel_reg);
137
138static int intel_set_m_datamode(void *data, u64 value)
139{
140	struct sdw_intel *sdw = data;
141	struct sdw_bus *bus = &sdw->cdns.bus;
142
143	if (value > SDW_PORT_DATA_MODE_STATIC_1)
144		return -EINVAL;
145
146	/* Userspace changed the hardware state behind the kernel's back */
147	add_taint(TAINT_USER, LOCKDEP_STILL_OK);
148
149	bus->params.m_data_mode = value;
150
151	return 0;
152}
153DEFINE_DEBUGFS_ATTRIBUTE(intel_set_m_datamode_fops, NULL,
154			 intel_set_m_datamode, "%llu\n");
155
156static int intel_set_s_datamode(void *data, u64 value)
157{
158	struct sdw_intel *sdw = data;
159	struct sdw_bus *bus = &sdw->cdns.bus;
160
161	if (value > SDW_PORT_DATA_MODE_STATIC_1)
162		return -EINVAL;
163
164	/* Userspace changed the hardware state behind the kernel's back */
165	add_taint(TAINT_USER, LOCKDEP_STILL_OK);
166
167	bus->params.s_data_mode = value;
168
169	return 0;
170}
171DEFINE_DEBUGFS_ATTRIBUTE(intel_set_s_datamode_fops, NULL,
172			 intel_set_s_datamode, "%llu\n");
173
174static void intel_debugfs_init(struct sdw_intel *sdw)
175{
176	struct dentry *root = sdw->cdns.bus.debugfs;
177
178	if (!root)
179		return;
180
181	sdw->debugfs = debugfs_create_dir("intel-sdw", root);
182
183	debugfs_create_file("intel-registers", 0400, sdw->debugfs, sdw,
184			    &intel_reg_fops);
185
186	debugfs_create_file("intel-m-datamode", 0200, sdw->debugfs, sdw,
187			    &intel_set_m_datamode_fops);
188
189	debugfs_create_file("intel-s-datamode", 0200, sdw->debugfs, sdw,
190			    &intel_set_s_datamode_fops);
191
192	sdw_cdns_debugfs_init(&sdw->cdns, sdw->debugfs);
193}
194
195static void intel_debugfs_exit(struct sdw_intel *sdw)
196{
197	debugfs_remove_recursive(sdw->debugfs);
198}
199#else
200static void intel_debugfs_init(struct sdw_intel *sdw) {}
201static void intel_debugfs_exit(struct sdw_intel *sdw) {}
202#endif /* CONFIG_DEBUG_FS */
203
204/*
205 * shim ops
206 */
207/* this needs to be called with shim_lock */
208static void intel_shim_glue_to_master_ip(struct sdw_intel *sdw)
209{
210	void __iomem *shim = sdw->link_res->shim;
211	unsigned int link_id = sdw->instance;
212	u16 ioctl;
213
214	/* Switch to MIP from Glue logic */
215	ioctl = intel_readw(shim,  SDW_SHIM_IOCTL(link_id));
216
217	ioctl &= ~(SDW_SHIM_IOCTL_DOE);
218	intel_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
219	usleep_range(10, 15);
220
221	ioctl &= ~(SDW_SHIM_IOCTL_DO);
222	intel_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
223	usleep_range(10, 15);
224
225	ioctl |= (SDW_SHIM_IOCTL_MIF);
226	intel_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
227	usleep_range(10, 15);
228
229	ioctl &= ~(SDW_SHIM_IOCTL_BKE);
230	ioctl &= ~(SDW_SHIM_IOCTL_COE);
231	intel_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
232	usleep_range(10, 15);
233
234	/* at this point Master IP has full control of the I/Os */
235}
236
237/* this needs to be called with shim_lock */
238static void intel_shim_master_ip_to_glue(struct sdw_intel *sdw)
239{
240	unsigned int link_id = sdw->instance;
241	void __iomem *shim = sdw->link_res->shim;
242	u16 ioctl;
243
244	/* Glue logic */
245	ioctl = intel_readw(shim, SDW_SHIM_IOCTL(link_id));
246	ioctl |= SDW_SHIM_IOCTL_BKE;
247	ioctl |= SDW_SHIM_IOCTL_COE;
248	intel_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
249	usleep_range(10, 15);
250
251	ioctl &= ~(SDW_SHIM_IOCTL_MIF);
252	intel_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
253	usleep_range(10, 15);
254
255	/* at this point Integration Glue has full control of the I/Os */
256}
257
258/* this needs to be called with shim_lock */
259static void intel_shim_init(struct sdw_intel *sdw)
260{
261	void __iomem *shim = sdw->link_res->shim;
262	unsigned int link_id = sdw->instance;
263	u16 ioctl = 0, act;
264
265	/* Initialize Shim */
266	ioctl |= SDW_SHIM_IOCTL_BKE;
267	intel_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
268	usleep_range(10, 15);
269
270	ioctl |= SDW_SHIM_IOCTL_WPDD;
271	intel_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
272	usleep_range(10, 15);
273
274	ioctl |= SDW_SHIM_IOCTL_DO;
275	intel_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
276	usleep_range(10, 15);
277
278	ioctl |= SDW_SHIM_IOCTL_DOE;
279	intel_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
280	usleep_range(10, 15);
281
282	intel_shim_glue_to_master_ip(sdw);
283
284	act = intel_readw(shim, SDW_SHIM_CTMCTL(link_id));
285	u16p_replace_bits(&act, 0x1, SDW_SHIM_CTMCTL_DOAIS);
286	act |= SDW_SHIM_CTMCTL_DACTQE;
287	act |= SDW_SHIM_CTMCTL_DODS;
288	intel_writew(shim, SDW_SHIM_CTMCTL(link_id), act);
289	usleep_range(10, 15);
290}
291
292static int intel_shim_check_wake(struct sdw_intel *sdw)
293{
294	void __iomem *shim;
295	u16 wake_sts;
296
297	shim = sdw->link_res->shim;
298	wake_sts = intel_readw(shim, SDW_SHIM_WAKESTS);
299
300	return wake_sts & BIT(sdw->instance);
301}
302
303static void intel_shim_wake(struct sdw_intel *sdw, bool wake_enable)
304{
305	void __iomem *shim = sdw->link_res->shim;
306	unsigned int link_id = sdw->instance;
307	u16 wake_en, wake_sts;
308
309	mutex_lock(sdw->link_res->shim_lock);
310	wake_en = intel_readw(shim, SDW_SHIM_WAKEEN);
311
312	if (wake_enable) {
313		/* Enable the wakeup */
314		wake_en |= (SDW_SHIM_WAKEEN_ENABLE << link_id);
315		intel_writew(shim, SDW_SHIM_WAKEEN, wake_en);
316	} else {
317		/* Disable the wake up interrupt */
318		wake_en &= ~(SDW_SHIM_WAKEEN_ENABLE << link_id);
319		intel_writew(shim, SDW_SHIM_WAKEEN, wake_en);
320
321		/* Clear wake status */
322		wake_sts = intel_readw(shim, SDW_SHIM_WAKESTS);
323		wake_sts |= (SDW_SHIM_WAKESTS_STATUS << link_id);
324		intel_writew(shim, SDW_SHIM_WAKESTS, wake_sts);
325	}
326	mutex_unlock(sdw->link_res->shim_lock);
327}
328
329static bool intel_check_cmdsync_unlocked(struct sdw_intel *sdw)
330{
331	void __iomem *shim = sdw->link_res->shim;
332	int sync_reg;
333
334	sync_reg = intel_readl(shim, SDW_SHIM_SYNC);
335	return !!(sync_reg & SDW_SHIM_SYNC_CMDSYNC_MASK);
336}
337
338static int intel_link_power_up(struct sdw_intel *sdw)
339{
340	unsigned int link_id = sdw->instance;
341	void __iomem *shim = sdw->link_res->shim;
342	u32 *shim_mask = sdw->link_res->shim_mask;
343	struct sdw_bus *bus = &sdw->cdns.bus;
344	struct sdw_master_prop *prop = &bus->prop;
345	u32 spa_mask, cpa_mask;
346	u32 link_control;
347	int ret = 0;
348	u32 syncprd;
349	u32 sync_reg;
350
351	mutex_lock(sdw->link_res->shim_lock);
352
353	/*
354	 * The hardware relies on an internal counter, typically 4kHz,
355	 * to generate the SoundWire SSP - which defines a 'safe'
356	 * synchronization point between commands and audio transport
357	 * and allows for multi link synchronization. The SYNCPRD value
358	 * is only dependent on the oscillator clock provided to
359	 * the IP, so adjust based on _DSD properties reported in DSDT
360	 * tables. The values reported are based on either 24MHz
361	 * (CNL/CML) or 38.4 MHz (ICL/TGL+).
362	 */
363	if (prop->mclk_freq % 6000000)
364		syncprd = SDW_SHIM_SYNC_SYNCPRD_VAL_38_4;
365	else
366		syncprd = SDW_SHIM_SYNC_SYNCPRD_VAL_24;
367
368	if (!*shim_mask) {
369		dev_dbg(sdw->cdns.dev, "powering up all links\n");
370
371		/* we first need to program the SyncPRD/CPU registers */
372		dev_dbg(sdw->cdns.dev,
373			"first link up, programming SYNCPRD\n");
374
375		/* set SyncPRD period */
376		sync_reg = intel_readl(shim, SDW_SHIM_SYNC);
377		u32p_replace_bits(&sync_reg, syncprd, SDW_SHIM_SYNC_SYNCPRD);
378
379		/* Set SyncCPU bit */
380		sync_reg |= SDW_SHIM_SYNC_SYNCCPU;
381		intel_writel(shim, SDW_SHIM_SYNC, sync_reg);
382
383		/* Link power up sequence */
384		link_control = intel_readl(shim, SDW_SHIM_LCTL);
385
386		/* only power-up enabled links */
387		spa_mask = FIELD_PREP(SDW_SHIM_LCTL_SPA_MASK, sdw->link_res->link_mask);
388		cpa_mask = FIELD_PREP(SDW_SHIM_LCTL_CPA_MASK, sdw->link_res->link_mask);
389
390		link_control |=  spa_mask;
391
392		ret = intel_set_bit(shim, SDW_SHIM_LCTL, link_control, cpa_mask);
393		if (ret < 0) {
394			dev_err(sdw->cdns.dev, "Failed to power up link: %d\n", ret);
395			goto out;
396		}
397
398		/* SyncCPU will change once link is active */
399		ret = intel_wait_bit(shim, SDW_SHIM_SYNC,
400				     SDW_SHIM_SYNC_SYNCCPU, 0);
401		if (ret < 0) {
402			dev_err(sdw->cdns.dev,
403				"Failed to set SHIM_SYNC: %d\n", ret);
404			goto out;
405		}
406	}
407
408	*shim_mask |= BIT(link_id);
409
410	sdw->cdns.link_up = true;
411
412	intel_shim_init(sdw);
413
414out:
415	mutex_unlock(sdw->link_res->shim_lock);
416
417	return ret;
418}
419
420static int intel_link_power_down(struct sdw_intel *sdw)
421{
422	u32 link_control, spa_mask, cpa_mask;
423	unsigned int link_id = sdw->instance;
424	void __iomem *shim = sdw->link_res->shim;
425	u32 *shim_mask = sdw->link_res->shim_mask;
426	int ret = 0;
427
428	mutex_lock(sdw->link_res->shim_lock);
429
430	if (!(*shim_mask & BIT(link_id)))
431		dev_err(sdw->cdns.dev,
432			"%s: Unbalanced power-up/down calls\n", __func__);
433
434	sdw->cdns.link_up = false;
435
436	intel_shim_master_ip_to_glue(sdw);
437
438	*shim_mask &= ~BIT(link_id);
439
440	if (!*shim_mask) {
441
442		dev_dbg(sdw->cdns.dev, "powering down all links\n");
443
444		/* Link power down sequence */
445		link_control = intel_readl(shim, SDW_SHIM_LCTL);
446
447		/* only power-down enabled links */
448		spa_mask = FIELD_PREP(SDW_SHIM_LCTL_SPA_MASK, ~sdw->link_res->link_mask);
449		cpa_mask = FIELD_PREP(SDW_SHIM_LCTL_CPA_MASK, sdw->link_res->link_mask);
450
451		link_control &=  spa_mask;
452
453		ret = intel_clear_bit(shim, SDW_SHIM_LCTL, link_control, cpa_mask);
454		if (ret < 0) {
455			dev_err(sdw->cdns.dev, "%s: could not power down link\n", __func__);
456
457			/*
458			 * we leave the sdw->cdns.link_up flag as false since we've disabled
459			 * the link at this point and cannot handle interrupts any longer.
460			 */
461		}
462	}
463
464	mutex_unlock(sdw->link_res->shim_lock);
465
466	return ret;
467}
468
469static void intel_shim_sync_arm(struct sdw_intel *sdw)
470{
471	void __iomem *shim = sdw->link_res->shim;
472	u32 sync_reg;
473
474	mutex_lock(sdw->link_res->shim_lock);
475
476	/* update SYNC register */
477	sync_reg = intel_readl(shim, SDW_SHIM_SYNC);
478	sync_reg |= (SDW_SHIM_SYNC_CMDSYNC << sdw->instance);
479	intel_writel(shim, SDW_SHIM_SYNC, sync_reg);
480
481	mutex_unlock(sdw->link_res->shim_lock);
482}
483
484static int intel_shim_sync_go_unlocked(struct sdw_intel *sdw)
485{
486	void __iomem *shim = sdw->link_res->shim;
487	u32 sync_reg;
488
489	/* Read SYNC register */
490	sync_reg = intel_readl(shim, SDW_SHIM_SYNC);
491
492	/*
493	 * Set SyncGO bit to synchronously trigger a bank switch for
494	 * all the masters. A write to SYNCGO bit clears CMDSYNC bit for all
495	 * the Masters.
496	 */
497	sync_reg |= SDW_SHIM_SYNC_SYNCGO;
498
499	intel_writel(shim, SDW_SHIM_SYNC, sync_reg);
500
501	return 0;
502}
503
504static int intel_shim_sync_go(struct sdw_intel *sdw)
505{
506	int ret;
507
508	mutex_lock(sdw->link_res->shim_lock);
509
510	ret = intel_shim_sync_go_unlocked(sdw);
511
512	mutex_unlock(sdw->link_res->shim_lock);
513
514	return ret;
515}
516
517/*
518 * PDI routines
519 */
520static void intel_pdi_init(struct sdw_intel *sdw,
521			   struct sdw_cdns_stream_config *config)
522{
523	void __iomem *shim = sdw->link_res->shim;
524	unsigned int link_id = sdw->instance;
525	int pcm_cap;
526
527	/* PCM Stream Capability */
528	pcm_cap = intel_readw(shim, SDW_SHIM_PCMSCAP(link_id));
529
530	config->pcm_bd = FIELD_GET(SDW_SHIM_PCMSCAP_BSS, pcm_cap);
531	config->pcm_in = FIELD_GET(SDW_SHIM_PCMSCAP_ISS, pcm_cap);
532	config->pcm_out = FIELD_GET(SDW_SHIM_PCMSCAP_OSS, pcm_cap);
533
534	dev_dbg(sdw->cdns.dev, "PCM cap bd:%d in:%d out:%d\n",
535		config->pcm_bd, config->pcm_in, config->pcm_out);
536}
537
538static int
539intel_pdi_get_ch_cap(struct sdw_intel *sdw, unsigned int pdi_num)
540{
541	void __iomem *shim = sdw->link_res->shim;
542	unsigned int link_id = sdw->instance;
543	int count;
544
545	count = intel_readw(shim, SDW_SHIM_PCMSYCHC(link_id, pdi_num));
546
547	/*
548	 * WORKAROUND: on all existing Intel controllers, pdi
549	 * number 2 reports channel count as 1 even though it
550	 * supports 8 channels. Performing hardcoding for pdi
551	 * number 2.
552	 */
553	if (pdi_num == 2)
554		count = 7;
555
556	/* zero based values for channel count in register */
557	count++;
558
559	return count;
560}
561
562static int intel_pdi_get_ch_update(struct sdw_intel *sdw,
563				   struct sdw_cdns_pdi *pdi,
564				   unsigned int num_pdi,
565				   unsigned int *num_ch)
566{
567	int i, ch_count = 0;
568
569	for (i = 0; i < num_pdi; i++) {
570		pdi->ch_count = intel_pdi_get_ch_cap(sdw, pdi->num);
571		ch_count += pdi->ch_count;
572		pdi++;
573	}
574
575	*num_ch = ch_count;
576	return 0;
577}
578
579static int intel_pdi_stream_ch_update(struct sdw_intel *sdw,
580				      struct sdw_cdns_streams *stream)
581{
582	intel_pdi_get_ch_update(sdw, stream->bd, stream->num_bd,
583				&stream->num_ch_bd);
584
585	intel_pdi_get_ch_update(sdw, stream->in, stream->num_in,
586				&stream->num_ch_in);
587
588	intel_pdi_get_ch_update(sdw, stream->out, stream->num_out,
589				&stream->num_ch_out);
590
591	return 0;
592}
593
594static void
595intel_pdi_shim_configure(struct sdw_intel *sdw, struct sdw_cdns_pdi *pdi)
596{
597	void __iomem *shim = sdw->link_res->shim;
598	unsigned int link_id = sdw->instance;
599	int pdi_conf = 0;
600
601	/* the Bulk and PCM streams are not contiguous */
602	pdi->intel_alh_id = (link_id * 16) + pdi->num + 3;
603	if (pdi->num >= 2)
604		pdi->intel_alh_id += 2;
605
606	/*
607	 * Program stream parameters to stream SHIM register
608	 * This is applicable for PCM stream only.
609	 */
610	if (pdi->type != SDW_STREAM_PCM)
611		return;
612
613	if (pdi->dir == SDW_DATA_DIR_RX)
614		pdi_conf |= SDW_SHIM_PCMSYCM_DIR;
615	else
616		pdi_conf &= ~(SDW_SHIM_PCMSYCM_DIR);
617
618	u32p_replace_bits(&pdi_conf, pdi->intel_alh_id, SDW_SHIM_PCMSYCM_STREAM);
619	u32p_replace_bits(&pdi_conf, pdi->l_ch_num, SDW_SHIM_PCMSYCM_LCHN);
620	u32p_replace_bits(&pdi_conf, pdi->h_ch_num, SDW_SHIM_PCMSYCM_HCHN);
621
622	intel_writew(shim, SDW_SHIM_PCMSYCHM(link_id, pdi->num), pdi_conf);
623}
624
625static void
626intel_pdi_alh_configure(struct sdw_intel *sdw, struct sdw_cdns_pdi *pdi)
627{
628	void __iomem *alh = sdw->link_res->alh;
629	unsigned int link_id = sdw->instance;
630	unsigned int conf;
631
632	/* the Bulk and PCM streams are not contiguous */
633	pdi->intel_alh_id = (link_id * 16) + pdi->num + 3;
634	if (pdi->num >= 2)
635		pdi->intel_alh_id += 2;
636
637	/* Program Stream config ALH register */
638	conf = intel_readl(alh, SDW_ALH_STRMZCFG(pdi->intel_alh_id));
639
640	u32p_replace_bits(&conf, SDW_ALH_STRMZCFG_DMAT_VAL, SDW_ALH_STRMZCFG_DMAT);
641	u32p_replace_bits(&conf, pdi->ch_count - 1, SDW_ALH_STRMZCFG_CHN);
642
643	intel_writel(alh, SDW_ALH_STRMZCFG(pdi->intel_alh_id), conf);
644}
645
646static int intel_params_stream(struct sdw_intel *sdw,
647			       struct snd_pcm_substream *substream,
648			       struct snd_soc_dai *dai,
649			       struct snd_pcm_hw_params *hw_params,
650			       int link_id, int alh_stream_id)
651{
652	struct sdw_intel_link_res *res = sdw->link_res;
653	struct sdw_intel_stream_params_data params_data;
654
655	params_data.substream = substream;
656	params_data.dai = dai;
657	params_data.hw_params = hw_params;
658	params_data.link_id = link_id;
659	params_data.alh_stream_id = alh_stream_id;
660
661	if (res->ops && res->ops->params_stream && res->dev)
662		return res->ops->params_stream(res->dev,
663					       &params_data);
664	return -EIO;
665}
666
667/*
668 * DAI routines
669 */
670
671static int intel_hw_params(struct snd_pcm_substream *substream,
672			   struct snd_pcm_hw_params *params,
673			   struct snd_soc_dai *dai)
674{
675	struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
676	struct sdw_intel *sdw = cdns_to_intel(cdns);
677	struct sdw_cdns_dai_runtime *dai_runtime;
678	struct sdw_cdns_pdi *pdi;
679	struct sdw_stream_config sconfig;
680	struct sdw_port_config *pconfig;
681	int ch, dir;
682	int ret;
683
684	dai_runtime = cdns->dai_runtime_array[dai->id];
685	if (!dai_runtime)
686		return -EIO;
687
688	ch = params_channels(params);
689	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
690		dir = SDW_DATA_DIR_RX;
691	else
692		dir = SDW_DATA_DIR_TX;
693
694	pdi = sdw_cdns_alloc_pdi(cdns, &cdns->pcm, ch, dir, dai->id);
695
696	if (!pdi) {
697		ret = -EINVAL;
698		goto error;
699	}
700
701	/* do run-time configurations for SHIM, ALH and PDI/PORT */
702	intel_pdi_shim_configure(sdw, pdi);
703	intel_pdi_alh_configure(sdw, pdi);
704	sdw_cdns_config_stream(cdns, ch, dir, pdi);
705
706	/* store pdi and hw_params, may be needed in prepare step */
707	dai_runtime->paused = false;
708	dai_runtime->suspended = false;
709	dai_runtime->pdi = pdi;
710
711	/* Inform DSP about PDI stream number */
712	ret = intel_params_stream(sdw, substream, dai, params,
713				  sdw->instance,
714				  pdi->intel_alh_id);
715	if (ret)
716		goto error;
717
718	sconfig.direction = dir;
719	sconfig.ch_count = ch;
720	sconfig.frame_rate = params_rate(params);
721	sconfig.type = dai_runtime->stream_type;
722
723	sconfig.bps = snd_pcm_format_width(params_format(params));
724
725	/* Port configuration */
726	pconfig = kzalloc(sizeof(*pconfig), GFP_KERNEL);
727	if (!pconfig) {
728		ret =  -ENOMEM;
729		goto error;
730	}
731
732	pconfig->num = pdi->num;
733	pconfig->ch_mask = (1 << ch) - 1;
734
735	ret = sdw_stream_add_master(&cdns->bus, &sconfig,
736				    pconfig, 1, dai_runtime->stream);
737	if (ret)
738		dev_err(cdns->dev, "add master to stream failed:%d\n", ret);
739
740	kfree(pconfig);
741error:
742	return ret;
743}
744
745static int intel_prepare(struct snd_pcm_substream *substream,
746			 struct snd_soc_dai *dai)
747{
748	struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
749	struct sdw_intel *sdw = cdns_to_intel(cdns);
750	struct sdw_cdns_dai_runtime *dai_runtime;
751	int ch, dir;
752	int ret = 0;
753
754	dai_runtime = cdns->dai_runtime_array[dai->id];
755	if (!dai_runtime) {
756		dev_err(dai->dev, "failed to get dai runtime in %s\n",
757			__func__);
758		return -EIO;
759	}
760
761	if (dai_runtime->suspended) {
762		struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
763		struct snd_pcm_hw_params *hw_params;
764
765		hw_params = &rtd->dpcm[substream->stream].hw_params;
766
767		dai_runtime->suspended = false;
768
769		/*
770		 * .prepare() is called after system resume, where we
771		 * need to reinitialize the SHIM/ALH/Cadence IP.
772		 * .prepare() is also called to deal with underflows,
773		 * but in those cases we cannot touch ALH/SHIM
774		 * registers
775		 */
776
777		/* configure stream */
778		ch = params_channels(hw_params);
779		if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
780			dir = SDW_DATA_DIR_RX;
781		else
782			dir = SDW_DATA_DIR_TX;
783
784		intel_pdi_shim_configure(sdw, dai_runtime->pdi);
785		intel_pdi_alh_configure(sdw, dai_runtime->pdi);
786		sdw_cdns_config_stream(cdns, ch, dir, dai_runtime->pdi);
787
788		/* Inform DSP about PDI stream number */
789		ret = intel_params_stream(sdw, substream, dai,
790					  hw_params,
791					  sdw->instance,
792					  dai_runtime->pdi->intel_alh_id);
793	}
794
795	return ret;
796}
797
798static int
799intel_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
800{
801	struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
802	struct sdw_cdns_dai_runtime *dai_runtime;
803	int ret;
804
805	dai_runtime = cdns->dai_runtime_array[dai->id];
806	if (!dai_runtime)
807		return -EIO;
808
809	/*
810	 * The sdw stream state will transition to RELEASED when stream->
811	 * master_list is empty. So the stream state will transition to
812	 * DEPREPARED for the first cpu-dai and to RELEASED for the last
813	 * cpu-dai.
814	 */
815	ret = sdw_stream_remove_master(&cdns->bus, dai_runtime->stream);
816	if (ret < 0) {
817		dev_err(dai->dev, "remove master from stream %s failed: %d\n",
818			dai_runtime->stream->name, ret);
819		return ret;
820	}
821
822	dai_runtime->pdi = NULL;
823
824	return 0;
825}
826
827static int intel_pcm_set_sdw_stream(struct snd_soc_dai *dai,
828				    void *stream, int direction)
829{
830	return cdns_set_sdw_stream(dai, stream, direction);
831}
832
833static void *intel_get_sdw_stream(struct snd_soc_dai *dai,
834				  int direction)
835{
836	struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
837	struct sdw_cdns_dai_runtime *dai_runtime;
838
839	dai_runtime = cdns->dai_runtime_array[dai->id];
840	if (!dai_runtime)
841		return ERR_PTR(-EINVAL);
842
843	return dai_runtime->stream;
844}
845
846static int intel_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai)
847{
848	struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
849	struct sdw_cdns_dai_runtime *dai_runtime;
850	int ret = 0;
851
852	dai_runtime = cdns->dai_runtime_array[dai->id];
853	if (!dai_runtime) {
854		dev_err(dai->dev, "failed to get dai runtime in %s\n",
855			__func__);
856		return -EIO;
857	}
858
859	switch (cmd) {
860	case SNDRV_PCM_TRIGGER_SUSPEND:
861
862		/*
863		 * The .prepare callback is used to deal with xruns and resume operations.
864		 * In the case of xruns, the DMAs and SHIM registers cannot be touched,
865		 * but for resume operations the DMAs and SHIM registers need to be initialized.
866		 * the .trigger callback is used to track the suspend case only.
867		 */
868
869		dai_runtime->suspended = true;
870
871		break;
872
873	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
874		dai_runtime->paused = true;
875		break;
876	case SNDRV_PCM_TRIGGER_STOP:
877	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
878		dai_runtime->paused = false;
879		break;
880	default:
881		break;
882	}
883
884	return ret;
885}
886
887static int intel_component_probe(struct snd_soc_component *component)
888{
889	int ret;
890
891	/*
892	 * make sure the device is pm_runtime_active before initiating
893	 * bus transactions during the card registration.
894	 * We use pm_runtime_resume() here, without taking a reference
895	 * and releasing it immediately.
896	 */
897	ret = pm_runtime_resume(component->dev);
898	if (ret < 0 && ret != -EACCES)
899		return ret;
900
901	return 0;
902}
903
904static int intel_component_dais_suspend(struct snd_soc_component *component)
905{
906	struct snd_soc_dai *dai;
907
908	/*
909	 * In the corner case where a SUSPEND happens during a PAUSE, the ALSA core
910	 * does not throw the TRIGGER_SUSPEND. This leaves the DAIs in an unbalanced state.
911	 * Since the component suspend is called last, we can trap this corner case
912	 * and force the DAIs to release their resources.
913	 */
914	for_each_component_dais(component, dai) {
915		struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
916		struct sdw_cdns_dai_runtime *dai_runtime;
917
918		dai_runtime = cdns->dai_runtime_array[dai->id];
919
920		if (!dai_runtime)
921			continue;
922
923		if (dai_runtime->suspended)
924			continue;
925
926		if (dai_runtime->paused)
927			dai_runtime->suspended = true;
928	}
929
930	return 0;
931}
932
933static const struct snd_soc_dai_ops intel_pcm_dai_ops = {
934	.hw_params = intel_hw_params,
935	.prepare = intel_prepare,
936	.hw_free = intel_hw_free,
937	.trigger = intel_trigger,
938	.set_stream = intel_pcm_set_sdw_stream,
939	.get_stream = intel_get_sdw_stream,
940};
941
942static const struct snd_soc_component_driver dai_component = {
943	.name			= "soundwire",
944	.probe			= intel_component_probe,
945	.suspend		= intel_component_dais_suspend,
946	.legacy_dai_naming	= 1,
947};
948
949static int intel_create_dai(struct sdw_cdns *cdns,
950			    struct snd_soc_dai_driver *dais,
951			    enum intel_pdi_type type,
952			    u32 num, u32 off, u32 max_ch)
953{
954	int i;
955
956	if (num == 0)
957		return 0;
958
959	for (i = off; i < (off + num); i++) {
960		dais[i].name = devm_kasprintf(cdns->dev, GFP_KERNEL,
961					      "SDW%d Pin%d",
962					      cdns->instance, i);
963		if (!dais[i].name)
964			return -ENOMEM;
965
966		if (type == INTEL_PDI_BD || type == INTEL_PDI_OUT) {
967			dais[i].playback.channels_min = 1;
968			dais[i].playback.channels_max = max_ch;
969		}
970
971		if (type == INTEL_PDI_BD || type == INTEL_PDI_IN) {
972			dais[i].capture.channels_min = 1;
973			dais[i].capture.channels_max = max_ch;
974		}
975
976		dais[i].ops = &intel_pcm_dai_ops;
977	}
978
979	return 0;
980}
981
982static int intel_register_dai(struct sdw_intel *sdw)
983{
984	struct sdw_cdns_dai_runtime **dai_runtime_array;
985	struct sdw_cdns_stream_config config;
986	struct sdw_cdns *cdns = &sdw->cdns;
987	struct sdw_cdns_streams *stream;
988	struct snd_soc_dai_driver *dais;
989	int num_dai, ret, off = 0;
990
991	/* Read the PDI config and initialize cadence PDI */
992	intel_pdi_init(sdw, &config);
993	ret = sdw_cdns_pdi_init(cdns, config);
994	if (ret)
995		return ret;
996
997	intel_pdi_stream_ch_update(sdw, &sdw->cdns.pcm);
998
999	/* DAIs are created based on total number of PDIs supported */
1000	num_dai = cdns->pcm.num_pdi;
1001
1002	dai_runtime_array = devm_kcalloc(cdns->dev, num_dai,
1003					 sizeof(struct sdw_cdns_dai_runtime *),
1004					 GFP_KERNEL);
1005	if (!dai_runtime_array)
1006		return -ENOMEM;
1007	cdns->dai_runtime_array = dai_runtime_array;
1008
1009	dais = devm_kcalloc(cdns->dev, num_dai, sizeof(*dais), GFP_KERNEL);
1010	if (!dais)
1011		return -ENOMEM;
1012
1013	/* Create PCM DAIs */
1014	stream = &cdns->pcm;
1015
1016	ret = intel_create_dai(cdns, dais, INTEL_PDI_IN, cdns->pcm.num_in,
1017			       off, stream->num_ch_in);
1018	if (ret)
1019		return ret;
1020
1021	off += cdns->pcm.num_in;
1022	ret = intel_create_dai(cdns, dais, INTEL_PDI_OUT, cdns->pcm.num_out,
1023			       off, stream->num_ch_out);
1024	if (ret)
1025		return ret;
1026
1027	off += cdns->pcm.num_out;
1028	ret = intel_create_dai(cdns, dais, INTEL_PDI_BD, cdns->pcm.num_bd,
1029			       off, stream->num_ch_bd);
1030	if (ret)
1031		return ret;
1032
1033	return devm_snd_soc_register_component(cdns->dev, &dai_component,
1034					       dais, num_dai);
1035}
1036
1037
1038const struct sdw_intel_hw_ops sdw_intel_cnl_hw_ops = {
1039	.debugfs_init = intel_debugfs_init,
1040	.debugfs_exit = intel_debugfs_exit,
1041
1042	.register_dai = intel_register_dai,
1043
1044	.check_clock_stop = intel_check_clock_stop,
1045	.start_bus = intel_start_bus,
1046	.start_bus_after_reset = intel_start_bus_after_reset,
1047	.start_bus_after_clock_stop = intel_start_bus_after_clock_stop,
1048	.stop_bus = intel_stop_bus,
1049
1050	.link_power_up = intel_link_power_up,
1051	.link_power_down = intel_link_power_down,
1052
1053	.shim_check_wake = intel_shim_check_wake,
1054	.shim_wake = intel_shim_wake,
1055
1056	.pre_bank_switch = intel_pre_bank_switch,
1057	.post_bank_switch = intel_post_bank_switch,
1058
1059	.sync_arm = intel_shim_sync_arm,
1060	.sync_go_unlocked = intel_shim_sync_go_unlocked,
1061	.sync_go = intel_shim_sync_go,
1062	.sync_check_cmdsync_unlocked = intel_check_cmdsync_unlocked,
1063};
1064EXPORT_SYMBOL_NS(sdw_intel_cnl_hw_ops, SOUNDWIRE_INTEL);
1065
1066