hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/drivers/soundwire/intel.c
....@@ -6,16 +6,39 @@
66 */
77
88 #include <linux/acpi.h>
9
+#include <linux/debugfs.h>
910 #include <linux/delay.h>
11
+#include <linux/module.h>
1012 #include <linux/interrupt.h>
13
+#include <linux/io.h>
1114 #include <linux/platform_device.h>
1215 #include <sound/pcm_params.h>
16
+#include <linux/pm_runtime.h>
1317 #include <sound/soc.h>
1418 #include <linux/soundwire/sdw_registers.h>
1519 #include <linux/soundwire/sdw.h>
1620 #include <linux/soundwire/sdw_intel.h>
1721 #include "cadence_master.h"
22
+#include "bus.h"
1823 #include "intel.h"
24
+
25
+#define INTEL_MASTER_SUSPEND_DELAY_MS 3000
26
+
27
+/*
28
+ * debug/config flags for the Intel SoundWire Master.
29
+ *
30
+ * Since we may have multiple masters active, we can have up to 8
31
+ * flags reused in each byte, with master0 using the ls-byte, etc.
32
+ */
33
+
34
+#define SDW_INTEL_MASTER_DISABLE_PM_RUNTIME BIT(0)
35
+#define SDW_INTEL_MASTER_DISABLE_CLOCK_STOP BIT(1)
36
+#define SDW_INTEL_MASTER_DISABLE_PM_RUNTIME_IDLE BIT(2)
37
+#define SDW_INTEL_MASTER_DISABLE_MULTI_LINK BIT(3)
38
+
39
+static int md_flags;
40
+module_param_named(sdw_md_flags, md_flags, int, 0444);
41
+MODULE_PARM_DESC(sdw_md_flags, "SoundWire Intel Master device flags (0x0 all off)");
1942
2043 /* Intel SHIM Registers Definition */
2144 #define SDW_SHIM_LCAP 0x0
....@@ -23,26 +46,29 @@
2346 #define SDW_SHIM_IPPTR 0x8
2447 #define SDW_SHIM_SYNC 0xC
2548
26
-#define SDW_SHIM_CTLSCAP(x) (0x010 + 0x60 * x)
27
-#define SDW_SHIM_CTLS0CM(x) (0x012 + 0x60 * x)
28
-#define SDW_SHIM_CTLS1CM(x) (0x014 + 0x60 * x)
29
-#define SDW_SHIM_CTLS2CM(x) (0x016 + 0x60 * x)
30
-#define SDW_SHIM_CTLS3CM(x) (0x018 + 0x60 * x)
31
-#define SDW_SHIM_PCMSCAP(x) (0x020 + 0x60 * x)
49
+#define SDW_SHIM_CTLSCAP(x) (0x010 + 0x60 * (x))
50
+#define SDW_SHIM_CTLS0CM(x) (0x012 + 0x60 * (x))
51
+#define SDW_SHIM_CTLS1CM(x) (0x014 + 0x60 * (x))
52
+#define SDW_SHIM_CTLS2CM(x) (0x016 + 0x60 * (x))
53
+#define SDW_SHIM_CTLS3CM(x) (0x018 + 0x60 * (x))
54
+#define SDW_SHIM_PCMSCAP(x) (0x020 + 0x60 * (x))
3255
33
-#define SDW_SHIM_PCMSYCHM(x, y) (0x022 + (0x60 * x) + (0x2 * y))
34
-#define SDW_SHIM_PCMSYCHC(x, y) (0x042 + (0x60 * x) + (0x2 * y))
35
-#define SDW_SHIM_PDMSCAP(x) (0x062 + 0x60 * x)
36
-#define SDW_SHIM_IOCTL(x) (0x06C + 0x60 * x)
37
-#define SDW_SHIM_CTMCTL(x) (0x06E + 0x60 * x)
56
+#define SDW_SHIM_PCMSYCHM(x, y) (0x022 + (0x60 * (x)) + (0x2 * (y)))
57
+#define SDW_SHIM_PCMSYCHC(x, y) (0x042 + (0x60 * (x)) + (0x2 * (y)))
58
+#define SDW_SHIM_PDMSCAP(x) (0x062 + 0x60 * (x))
59
+#define SDW_SHIM_IOCTL(x) (0x06C + 0x60 * (x))
60
+#define SDW_SHIM_CTMCTL(x) (0x06E + 0x60 * (x))
3861
3962 #define SDW_SHIM_WAKEEN 0x190
4063 #define SDW_SHIM_WAKESTS 0x192
4164
4265 #define SDW_SHIM_LCTL_SPA BIT(0)
66
+#define SDW_SHIM_LCTL_SPA_MASK GENMASK(3, 0)
4367 #define SDW_SHIM_LCTL_CPA BIT(8)
68
+#define SDW_SHIM_LCTL_CPA_MASK GENMASK(11, 8)
4469
45
-#define SDW_SHIM_SYNC_SYNCPRD_VAL 0x176F
70
+#define SDW_SHIM_SYNC_SYNCPRD_VAL_24 (24000 / SDW_CADENCE_GSYNC_KHZ - 1)
71
+#define SDW_SHIM_SYNC_SYNCPRD_VAL_38_4 (38400 / SDW_CADENCE_GSYNC_KHZ - 1)
4672 #define SDW_SHIM_SYNC_SYNCPRD GENMASK(14, 0)
4773 #define SDW_SHIM_SYNC_SYNCCPU BIT(15)
4874 #define SDW_SHIM_SYNC_CMDSYNC_MASK GENMASK(19, 16)
....@@ -81,7 +107,8 @@
81107 #define SDW_SHIM_WAKESTS_STATUS BIT(0)
82108
83109 /* Intel ALH Register definitions */
84
-#define SDW_ALH_STRMZCFG(x) (0x000 + (0x4 * x))
110
+#define SDW_ALH_STRMZCFG(x) (0x000 + (0x4 * (x)))
111
+#define SDW_ALH_NUM_STREAMS 64
85112
86113 #define SDW_ALH_STRMZCFG_DMAT_VAL 0x3
87114 #define SDW_ALH_STRMZCFG_DMAT GENMASK(7, 0)
....@@ -91,12 +118,6 @@
91118 INTEL_PDI_IN = 0,
92119 INTEL_PDI_OUT = 1,
93120 INTEL_PDI_BD = 2,
94
-};
95
-
96
-struct sdw_intel {
97
- struct sdw_cdns cdns;
98
- int instance;
99
- struct sdw_intel_link_res *res;
100121 };
101122
102123 #define cdns_to_intel(_cdns) container_of(_cdns, struct sdw_intel, cdns)
....@@ -124,41 +145,188 @@
124145 writew(value, base + offset);
125146 }
126147
127
-static int intel_clear_bit(void __iomem *base, int offset, u32 value, u32 mask)
148
+static int intel_wait_bit(void __iomem *base, int offset, u32 mask, u32 target)
128149 {
129150 int timeout = 10;
130151 u32 reg_read;
131152
132
- writel(value, base + offset);
133153 do {
134154 reg_read = readl(base + offset);
135
- if (!(reg_read & mask))
155
+ if ((reg_read & mask) == target)
136156 return 0;
137157
138158 timeout--;
139
- udelay(50);
159
+ usleep_range(50, 100);
140160 } while (timeout != 0);
141161
142162 return -EAGAIN;
163
+}
164
+
165
+static int intel_clear_bit(void __iomem *base, int offset, u32 value, u32 mask)
166
+{
167
+ writel(value, base + offset);
168
+ return intel_wait_bit(base, offset, mask, 0);
143169 }
144170
145171 static int intel_set_bit(void __iomem *base, int offset, u32 value, u32 mask)
146172 {
147
- int timeout = 10;
148
- u32 reg_read;
149
-
150173 writel(value, base + offset);
151
- do {
152
- reg_read = readl(base + offset);
153
- if (reg_read & mask)
154
- return 0;
155
-
156
- timeout--;
157
- udelay(50);
158
- } while (timeout != 0);
159
-
160
- return -EAGAIN;
174
+ return intel_wait_bit(base, offset, mask, mask);
161175 }
176
+
177
+/*
178
+ * debugfs
179
+ */
180
+#ifdef CONFIG_DEBUG_FS
181
+
182
+#define RD_BUF (2 * PAGE_SIZE)
183
+
184
+static ssize_t intel_sprintf(void __iomem *mem, bool l,
185
+ char *buf, size_t pos, unsigned int reg)
186
+{
187
+ int value;
188
+
189
+ if (l)
190
+ value = intel_readl(mem, reg);
191
+ else
192
+ value = intel_readw(mem, reg);
193
+
194
+ return scnprintf(buf + pos, RD_BUF - pos, "%4x\t%4x\n", reg, value);
195
+}
196
+
197
+static int intel_reg_show(struct seq_file *s_file, void *data)
198
+{
199
+ struct sdw_intel *sdw = s_file->private;
200
+ void __iomem *s = sdw->link_res->shim;
201
+ void __iomem *a = sdw->link_res->alh;
202
+ char *buf;
203
+ ssize_t ret;
204
+ int i, j;
205
+ unsigned int links, reg;
206
+
207
+ buf = kzalloc(RD_BUF, GFP_KERNEL);
208
+ if (!buf)
209
+ return -ENOMEM;
210
+
211
+ links = intel_readl(s, SDW_SHIM_LCAP) & GENMASK(2, 0);
212
+
213
+ ret = scnprintf(buf, RD_BUF, "Register Value\n");
214
+ ret += scnprintf(buf + ret, RD_BUF - ret, "\nShim\n");
215
+
216
+ for (i = 0; i < links; i++) {
217
+ reg = SDW_SHIM_LCAP + i * 4;
218
+ ret += intel_sprintf(s, true, buf, ret, reg);
219
+ }
220
+
221
+ for (i = 0; i < links; i++) {
222
+ ret += scnprintf(buf + ret, RD_BUF - ret, "\nLink%d\n", i);
223
+ ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_CTLSCAP(i));
224
+ ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_CTLS0CM(i));
225
+ ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_CTLS1CM(i));
226
+ ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_CTLS2CM(i));
227
+ ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_CTLS3CM(i));
228
+ ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_PCMSCAP(i));
229
+
230
+ ret += scnprintf(buf + ret, RD_BUF - ret, "\n PCMSyCH registers\n");
231
+
232
+ /*
233
+ * the value 10 is the number of PDIs. We will need a
234
+ * cleanup to remove hard-coded Intel configurations
235
+ * from cadence_master.c
236
+ */
237
+ for (j = 0; j < 10; j++) {
238
+ ret += intel_sprintf(s, false, buf, ret,
239
+ SDW_SHIM_PCMSYCHM(i, j));
240
+ ret += intel_sprintf(s, false, buf, ret,
241
+ SDW_SHIM_PCMSYCHC(i, j));
242
+ }
243
+ ret += scnprintf(buf + ret, RD_BUF - ret, "\n PDMSCAP, IOCTL, CTMCTL\n");
244
+
245
+ ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_PDMSCAP(i));
246
+ ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_IOCTL(i));
247
+ ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_CTMCTL(i));
248
+ }
249
+
250
+ ret += scnprintf(buf + ret, RD_BUF - ret, "\nWake registers\n");
251
+ ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_WAKEEN);
252
+ ret += intel_sprintf(s, false, buf, ret, SDW_SHIM_WAKESTS);
253
+
254
+ ret += scnprintf(buf + ret, RD_BUF - ret, "\nALH STRMzCFG\n");
255
+ for (i = 0; i < SDW_ALH_NUM_STREAMS; i++)
256
+ ret += intel_sprintf(a, true, buf, ret, SDW_ALH_STRMZCFG(i));
257
+
258
+ seq_printf(s_file, "%s", buf);
259
+ kfree(buf);
260
+
261
+ return 0;
262
+}
263
+DEFINE_SHOW_ATTRIBUTE(intel_reg);
264
+
265
+static int intel_set_m_datamode(void *data, u64 value)
266
+{
267
+ struct sdw_intel *sdw = data;
268
+ struct sdw_bus *bus = &sdw->cdns.bus;
269
+
270
+ if (value > SDW_PORT_DATA_MODE_STATIC_1)
271
+ return -EINVAL;
272
+
273
+ /* Userspace changed the hardware state behind the kernel's back */
274
+ add_taint(TAINT_USER, LOCKDEP_STILL_OK);
275
+
276
+ bus->params.m_data_mode = value;
277
+
278
+ return 0;
279
+}
280
+DEFINE_DEBUGFS_ATTRIBUTE(intel_set_m_datamode_fops, NULL,
281
+ intel_set_m_datamode, "%llu\n");
282
+
283
+static int intel_set_s_datamode(void *data, u64 value)
284
+{
285
+ struct sdw_intel *sdw = data;
286
+ struct sdw_bus *bus = &sdw->cdns.bus;
287
+
288
+ if (value > SDW_PORT_DATA_MODE_STATIC_1)
289
+ return -EINVAL;
290
+
291
+ /* Userspace changed the hardware state behind the kernel's back */
292
+ add_taint(TAINT_USER, LOCKDEP_STILL_OK);
293
+
294
+ bus->params.s_data_mode = value;
295
+
296
+ return 0;
297
+}
298
+DEFINE_DEBUGFS_ATTRIBUTE(intel_set_s_datamode_fops, NULL,
299
+ intel_set_s_datamode, "%llu\n");
300
+
301
+static void intel_debugfs_init(struct sdw_intel *sdw)
302
+{
303
+ struct dentry *root = sdw->cdns.bus.debugfs;
304
+
305
+ if (!root)
306
+ return;
307
+
308
+ sdw->debugfs = debugfs_create_dir("intel-sdw", root);
309
+
310
+ debugfs_create_file("intel-registers", 0400, sdw->debugfs, sdw,
311
+ &intel_reg_fops);
312
+
313
+ debugfs_create_file("intel-m-datamode", 0200, sdw->debugfs, sdw,
314
+ &intel_set_m_datamode_fops);
315
+
316
+ debugfs_create_file("intel-s-datamode", 0200, sdw->debugfs, sdw,
317
+ &intel_set_s_datamode_fops);
318
+
319
+ sdw_cdns_debugfs_init(&sdw->cdns, sdw->debugfs);
320
+}
321
+
322
+static void intel_debugfs_exit(struct sdw_intel *sdw)
323
+{
324
+ debugfs_remove_recursive(sdw->debugfs);
325
+}
326
+#else
327
+static void intel_debugfs_init(struct sdw_intel *sdw) {}
328
+static void intel_debugfs_exit(struct sdw_intel *sdw) {}
329
+#endif /* CONFIG_DEBUG_FS */
162330
163331 /*
164332 * shim ops
....@@ -167,77 +335,298 @@
167335 static int intel_link_power_up(struct sdw_intel *sdw)
168336 {
169337 unsigned int link_id = sdw->instance;
170
- void __iomem *shim = sdw->res->shim;
171
- int spa_mask, cpa_mask;
172
- int link_control, ret;
338
+ void __iomem *shim = sdw->link_res->shim;
339
+ u32 *shim_mask = sdw->link_res->shim_mask;
340
+ struct sdw_bus *bus = &sdw->cdns.bus;
341
+ struct sdw_master_prop *prop = &bus->prop;
342
+ u32 spa_mask, cpa_mask;
343
+ u32 link_control;
344
+ int ret = 0;
345
+ u32 syncprd;
346
+ u32 sync_reg;
173347
174
- /* Link power up sequence */
175
- link_control = intel_readl(shim, SDW_SHIM_LCTL);
176
- spa_mask = (SDW_SHIM_LCTL_SPA << link_id);
177
- cpa_mask = (SDW_SHIM_LCTL_CPA << link_id);
178
- link_control |= spa_mask;
348
+ mutex_lock(sdw->link_res->shim_lock);
179349
180
- ret = intel_set_bit(shim, SDW_SHIM_LCTL, link_control, cpa_mask);
181
- if (ret < 0)
182
- return ret;
350
+ /*
351
+ * The hardware relies on an internal counter, typically 4kHz,
352
+ * to generate the SoundWire SSP - which defines a 'safe'
353
+ * synchronization point between commands and audio transport
354
+ * and allows for multi link synchronization. The SYNCPRD value
355
+ * is only dependent on the oscillator clock provided to
356
+ * the IP, so adjust based on _DSD properties reported in DSDT
357
+ * tables. The values reported are based on either 24MHz
358
+ * (CNL/CML) or 38.4 MHz (ICL/TGL+).
359
+ */
360
+ if (prop->mclk_freq % 6000000)
361
+ syncprd = SDW_SHIM_SYNC_SYNCPRD_VAL_38_4;
362
+ else
363
+ syncprd = SDW_SHIM_SYNC_SYNCPRD_VAL_24;
364
+
365
+ if (!*shim_mask) {
366
+ dev_dbg(sdw->cdns.dev, "%s: powering up all links\n", __func__);
367
+
368
+ /* we first need to program the SyncPRD/CPU registers */
369
+ dev_dbg(sdw->cdns.dev,
370
+ "%s: first link up, programming SYNCPRD\n", __func__);
371
+
372
+ /* set SyncPRD period */
373
+ sync_reg = intel_readl(shim, SDW_SHIM_SYNC);
374
+ u32p_replace_bits(&sync_reg, syncprd, SDW_SHIM_SYNC_SYNCPRD);
375
+
376
+ /* Set SyncCPU bit */
377
+ sync_reg |= SDW_SHIM_SYNC_SYNCCPU;
378
+ intel_writel(shim, SDW_SHIM_SYNC, sync_reg);
379
+
380
+ /* Link power up sequence */
381
+ link_control = intel_readl(shim, SDW_SHIM_LCTL);
382
+
383
+ /* only power-up enabled links */
384
+ spa_mask = FIELD_PREP(SDW_SHIM_LCTL_SPA_MASK, sdw->link_res->link_mask);
385
+ cpa_mask = FIELD_PREP(SDW_SHIM_LCTL_CPA_MASK, sdw->link_res->link_mask);
386
+
387
+ link_control |= spa_mask;
388
+
389
+ ret = intel_set_bit(shim, SDW_SHIM_LCTL, link_control, cpa_mask);
390
+ if (ret < 0) {
391
+ dev_err(sdw->cdns.dev, "Failed to power up link: %d\n", ret);
392
+ goto out;
393
+ }
394
+
395
+ /* SyncCPU will change once link is active */
396
+ ret = intel_wait_bit(shim, SDW_SHIM_SYNC,
397
+ SDW_SHIM_SYNC_SYNCCPU, 0);
398
+ if (ret < 0) {
399
+ dev_err(sdw->cdns.dev,
400
+ "Failed to set SHIM_SYNC: %d\n", ret);
401
+ goto out;
402
+ }
403
+ }
404
+
405
+ *shim_mask |= BIT(link_id);
183406
184407 sdw->cdns.link_up = true;
185
- return 0;
408
+out:
409
+ mutex_unlock(sdw->link_res->shim_lock);
410
+
411
+ return ret;
186412 }
187413
188
-static int intel_shim_init(struct sdw_intel *sdw)
414
+/* this needs to be called with shim_lock */
415
+static void intel_shim_glue_to_master_ip(struct sdw_intel *sdw)
189416 {
190
- void __iomem *shim = sdw->res->shim;
417
+ void __iomem *shim = sdw->link_res->shim;
191418 unsigned int link_id = sdw->instance;
192
- int sync_reg, ret;
193
- u16 ioctl = 0, act = 0;
194
-
195
- /* Initialize Shim */
196
- ioctl |= SDW_SHIM_IOCTL_BKE;
197
- intel_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
198
-
199
- ioctl |= SDW_SHIM_IOCTL_WPDD;
200
- intel_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
201
-
202
- ioctl |= SDW_SHIM_IOCTL_DO;
203
- intel_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
204
-
205
- ioctl |= SDW_SHIM_IOCTL_DOE;
206
- intel_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
419
+ u16 ioctl;
207420
208421 /* Switch to MIP from Glue logic */
209422 ioctl = intel_readw(shim, SDW_SHIM_IOCTL(link_id));
210423
211424 ioctl &= ~(SDW_SHIM_IOCTL_DOE);
212425 intel_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
426
+ usleep_range(10, 15);
213427
214428 ioctl &= ~(SDW_SHIM_IOCTL_DO);
215429 intel_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
430
+ usleep_range(10, 15);
216431
217432 ioctl |= (SDW_SHIM_IOCTL_MIF);
218433 intel_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
434
+ usleep_range(10, 15);
219435
220436 ioctl &= ~(SDW_SHIM_IOCTL_BKE);
221437 ioctl &= ~(SDW_SHIM_IOCTL_COE);
222
-
223438 intel_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
439
+ usleep_range(10, 15);
224440
225
- act |= 0x1 << SDW_REG_SHIFT(SDW_SHIM_CTMCTL_DOAIS);
441
+ /* at this point Master IP has full control of the I/Os */
442
+}
443
+
444
+/* this needs to be called with shim_lock */
445
+static void intel_shim_master_ip_to_glue(struct sdw_intel *sdw)
446
+{
447
+ unsigned int link_id = sdw->instance;
448
+ void __iomem *shim = sdw->link_res->shim;
449
+ u16 ioctl;
450
+
451
+ /* Glue logic */
452
+ ioctl = intel_readw(shim, SDW_SHIM_IOCTL(link_id));
453
+ ioctl |= SDW_SHIM_IOCTL_BKE;
454
+ ioctl |= SDW_SHIM_IOCTL_COE;
455
+ intel_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
456
+ usleep_range(10, 15);
457
+
458
+ ioctl &= ~(SDW_SHIM_IOCTL_MIF);
459
+ intel_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
460
+ usleep_range(10, 15);
461
+
462
+ /* at this point Integration Glue has full control of the I/Os */
463
+}
464
+
465
+static int intel_shim_init(struct sdw_intel *sdw, bool clock_stop)
466
+{
467
+ void __iomem *shim = sdw->link_res->shim;
468
+ unsigned int link_id = sdw->instance;
469
+ int ret = 0;
470
+ u16 ioctl = 0, act = 0;
471
+
472
+ mutex_lock(sdw->link_res->shim_lock);
473
+
474
+ /* Initialize Shim */
475
+ ioctl |= SDW_SHIM_IOCTL_BKE;
476
+ intel_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
477
+ usleep_range(10, 15);
478
+
479
+ ioctl |= SDW_SHIM_IOCTL_WPDD;
480
+ intel_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
481
+ usleep_range(10, 15);
482
+
483
+ ioctl |= SDW_SHIM_IOCTL_DO;
484
+ intel_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
485
+ usleep_range(10, 15);
486
+
487
+ ioctl |= SDW_SHIM_IOCTL_DOE;
488
+ intel_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
489
+ usleep_range(10, 15);
490
+
491
+ intel_shim_glue_to_master_ip(sdw);
492
+
493
+ u16p_replace_bits(&act, 0x1, SDW_SHIM_CTMCTL_DOAIS);
226494 act |= SDW_SHIM_CTMCTL_DACTQE;
227495 act |= SDW_SHIM_CTMCTL_DODS;
228496 intel_writew(shim, SDW_SHIM_CTMCTL(link_id), act);
497
+ usleep_range(10, 15);
229498
230
- /* Now set SyncPRD period */
499
+ mutex_unlock(sdw->link_res->shim_lock);
500
+
501
+ return ret;
502
+}
503
+
504
+static void intel_shim_wake(struct sdw_intel *sdw, bool wake_enable)
505
+{
506
+ void __iomem *shim = sdw->link_res->shim;
507
+ unsigned int link_id = sdw->instance;
508
+ u16 wake_en, wake_sts;
509
+
510
+ mutex_lock(sdw->link_res->shim_lock);
511
+ wake_en = intel_readw(shim, SDW_SHIM_WAKEEN);
512
+
513
+ if (wake_enable) {
514
+ /* Enable the wakeup */
515
+ wake_en |= (SDW_SHIM_WAKEEN_ENABLE << link_id);
516
+ intel_writew(shim, SDW_SHIM_WAKEEN, wake_en);
517
+ } else {
518
+ /* Disable the wake up interrupt */
519
+ wake_en &= ~(SDW_SHIM_WAKEEN_ENABLE << link_id);
520
+ intel_writew(shim, SDW_SHIM_WAKEEN, wake_en);
521
+
522
+ /* Clear wake status */
523
+ wake_sts = intel_readw(shim, SDW_SHIM_WAKESTS);
524
+ wake_sts |= (SDW_SHIM_WAKESTS_STATUS << link_id);
525
+ intel_writew(shim, SDW_SHIM_WAKESTS, wake_sts);
526
+ }
527
+ mutex_unlock(sdw->link_res->shim_lock);
528
+}
529
+
530
+static int intel_link_power_down(struct sdw_intel *sdw)
531
+{
532
+ u32 link_control, spa_mask, cpa_mask;
533
+ unsigned int link_id = sdw->instance;
534
+ void __iomem *shim = sdw->link_res->shim;
535
+ u32 *shim_mask = sdw->link_res->shim_mask;
536
+ int ret = 0;
537
+
538
+ mutex_lock(sdw->link_res->shim_lock);
539
+
540
+ if (!(*shim_mask & BIT(link_id)))
541
+ dev_err(sdw->cdns.dev,
542
+ "%s: Unbalanced power-up/down calls\n", __func__);
543
+
544
+ sdw->cdns.link_up = false;
545
+
546
+ intel_shim_master_ip_to_glue(sdw);
547
+
548
+ *shim_mask &= ~BIT(link_id);
549
+
550
+ if (!*shim_mask) {
551
+
552
+ dev_dbg(sdw->cdns.dev, "%s: powering down all links\n", __func__);
553
+
554
+ /* Link power down sequence */
555
+ link_control = intel_readl(shim, SDW_SHIM_LCTL);
556
+
557
+ /* only power-down enabled links */
558
+ spa_mask = FIELD_PREP(SDW_SHIM_LCTL_SPA_MASK, ~sdw->link_res->link_mask);
559
+ cpa_mask = FIELD_PREP(SDW_SHIM_LCTL_CPA_MASK, sdw->link_res->link_mask);
560
+
561
+ link_control &= spa_mask;
562
+
563
+ ret = intel_clear_bit(shim, SDW_SHIM_LCTL, link_control, cpa_mask);
564
+ if (ret < 0) {
565
+ dev_err(sdw->cdns.dev, "%s: could not power down link\n", __func__);
566
+
567
+ /*
568
+ * we leave the sdw->cdns.link_up flag as false since we've disabled
569
+ * the link at this point and cannot handle interrupts any longer.
570
+ */
571
+ }
572
+ }
573
+
574
+ link_control = intel_readl(shim, SDW_SHIM_LCTL);
575
+
576
+ mutex_unlock(sdw->link_res->shim_lock);
577
+
578
+ return ret;
579
+}
580
+
581
+static void intel_shim_sync_arm(struct sdw_intel *sdw)
582
+{
583
+ void __iomem *shim = sdw->link_res->shim;
584
+ u32 sync_reg;
585
+
586
+ mutex_lock(sdw->link_res->shim_lock);
587
+
588
+ /* update SYNC register */
231589 sync_reg = intel_readl(shim, SDW_SHIM_SYNC);
232
- sync_reg |= (SDW_SHIM_SYNC_SYNCPRD_VAL <<
233
- SDW_REG_SHIFT(SDW_SHIM_SYNC_SYNCPRD));
590
+ sync_reg |= (SDW_SHIM_SYNC_CMDSYNC << sdw->instance);
591
+ intel_writel(shim, SDW_SHIM_SYNC, sync_reg);
234592
235
- /* Set SyncCPU bit */
236
- sync_reg |= SDW_SHIM_SYNC_SYNCCPU;
593
+ mutex_unlock(sdw->link_res->shim_lock);
594
+}
595
+
596
+static int intel_shim_sync_go_unlocked(struct sdw_intel *sdw)
597
+{
598
+ void __iomem *shim = sdw->link_res->shim;
599
+ u32 sync_reg;
600
+ int ret;
601
+
602
+ /* Read SYNC register */
603
+ sync_reg = intel_readl(shim, SDW_SHIM_SYNC);
604
+
605
+ /*
606
+ * Set SyncGO bit to synchronously trigger a bank switch for
607
+ * all the masters. A write to SYNCGO bit clears CMDSYNC bit for all
608
+ * the Masters.
609
+ */
610
+ sync_reg |= SDW_SHIM_SYNC_SYNCGO;
611
+
237612 ret = intel_clear_bit(shim, SDW_SHIM_SYNC, sync_reg,
238
- SDW_SHIM_SYNC_SYNCCPU);
613
+ SDW_SHIM_SYNC_SYNCGO);
614
+
239615 if (ret < 0)
240
- dev_err(sdw->cdns.dev, "Failed to set sync period: %d", ret);
616
+ dev_err(sdw->cdns.dev, "SyncGO clear failed: %d\n", ret);
617
+
618
+ return ret;
619
+}
620
+
621
+static int intel_shim_sync_go(struct sdw_intel *sdw)
622
+{
623
+ int ret;
624
+
625
+ mutex_lock(sdw->link_res->shim_lock);
626
+
627
+ ret = intel_shim_sync_go_unlocked(sdw);
628
+
629
+ mutex_unlock(sdw->link_res->shim_lock);
241630
242631 return ret;
243632 }
....@@ -246,37 +635,37 @@
246635 * PDI routines
247636 */
248637 static void intel_pdi_init(struct sdw_intel *sdw,
249
- struct sdw_cdns_stream_config *config)
638
+ struct sdw_cdns_stream_config *config)
250639 {
251
- void __iomem *shim = sdw->res->shim;
640
+ void __iomem *shim = sdw->link_res->shim;
252641 unsigned int link_id = sdw->instance;
253642 int pcm_cap, pdm_cap;
254643
255644 /* PCM Stream Capability */
256645 pcm_cap = intel_readw(shim, SDW_SHIM_PCMSCAP(link_id));
257646
258
- config->pcm_bd = (pcm_cap & SDW_SHIM_PCMSCAP_BSS) >>
259
- SDW_REG_SHIFT(SDW_SHIM_PCMSCAP_BSS);
260
- config->pcm_in = (pcm_cap & SDW_SHIM_PCMSCAP_ISS) >>
261
- SDW_REG_SHIFT(SDW_SHIM_PCMSCAP_ISS);
262
- config->pcm_out = (pcm_cap & SDW_SHIM_PCMSCAP_OSS) >>
263
- SDW_REG_SHIFT(SDW_SHIM_PCMSCAP_OSS);
647
+ config->pcm_bd = FIELD_GET(SDW_SHIM_PCMSCAP_BSS, pcm_cap);
648
+ config->pcm_in = FIELD_GET(SDW_SHIM_PCMSCAP_ISS, pcm_cap);
649
+ config->pcm_out = FIELD_GET(SDW_SHIM_PCMSCAP_OSS, pcm_cap);
650
+
651
+ dev_dbg(sdw->cdns.dev, "PCM cap bd:%d in:%d out:%d\n",
652
+ config->pcm_bd, config->pcm_in, config->pcm_out);
264653
265654 /* PDM Stream Capability */
266655 pdm_cap = intel_readw(shim, SDW_SHIM_PDMSCAP(link_id));
267656
268
- config->pdm_bd = (pdm_cap & SDW_SHIM_PDMSCAP_BSS) >>
269
- SDW_REG_SHIFT(SDW_SHIM_PDMSCAP_BSS);
270
- config->pdm_in = (pdm_cap & SDW_SHIM_PDMSCAP_ISS) >>
271
- SDW_REG_SHIFT(SDW_SHIM_PDMSCAP_ISS);
272
- config->pdm_out = (pdm_cap & SDW_SHIM_PDMSCAP_OSS) >>
273
- SDW_REG_SHIFT(SDW_SHIM_PDMSCAP_OSS);
657
+ config->pdm_bd = FIELD_GET(SDW_SHIM_PDMSCAP_BSS, pdm_cap);
658
+ config->pdm_in = FIELD_GET(SDW_SHIM_PDMSCAP_ISS, pdm_cap);
659
+ config->pdm_out = FIELD_GET(SDW_SHIM_PDMSCAP_OSS, pdm_cap);
660
+
661
+ dev_dbg(sdw->cdns.dev, "PDM cap bd:%d in:%d out:%d\n",
662
+ config->pdm_bd, config->pdm_in, config->pdm_out);
274663 }
275664
276665 static int
277666 intel_pdi_get_ch_cap(struct sdw_intel *sdw, unsigned int pdi_num, bool pcm)
278667 {
279
- void __iomem *shim = sdw->res->shim;
668
+ void __iomem *shim = sdw->link_res->shim;
280669 unsigned int link_id = sdw->instance;
281670 int count;
282671
....@@ -294,8 +683,7 @@
294683
295684 } else {
296685 count = intel_readw(shim, SDW_SHIM_PDMSCAP(link_id));
297
- count = ((count & SDW_SHIM_PDMSCAP_CPSS) >>
298
- SDW_REG_SHIFT(SDW_SHIM_PDMSCAP_CPSS));
686
+ count = FIELD_GET(SDW_SHIM_PDMSCAP_CPSS, count);
299687 }
300688
301689 /* zero based values for channel count in register */
....@@ -305,9 +693,9 @@
305693 }
306694
307695 static int intel_pdi_get_ch_update(struct sdw_intel *sdw,
308
- struct sdw_cdns_pdi *pdi,
309
- unsigned int num_pdi,
310
- unsigned int *num_ch, bool pcm)
696
+ struct sdw_cdns_pdi *pdi,
697
+ unsigned int num_pdi,
698
+ unsigned int *num_ch, bool pcm)
311699 {
312700 int i, ch_count = 0;
313701
....@@ -322,16 +710,16 @@
322710 }
323711
324712 static int intel_pdi_stream_ch_update(struct sdw_intel *sdw,
325
- struct sdw_cdns_streams *stream, bool pcm)
713
+ struct sdw_cdns_streams *stream, bool pcm)
326714 {
327715 intel_pdi_get_ch_update(sdw, stream->bd, stream->num_bd,
328
- &stream->num_ch_bd, pcm);
716
+ &stream->num_ch_bd, pcm);
329717
330718 intel_pdi_get_ch_update(sdw, stream->in, stream->num_in,
331
- &stream->num_ch_in, pcm);
719
+ &stream->num_ch_in, pcm);
332720
333721 intel_pdi_get_ch_update(sdw, stream->out, stream->num_out,
334
- &stream->num_ch_out, pcm);
722
+ &stream->num_ch_out, pcm);
335723
336724 return 0;
337725 }
....@@ -348,7 +736,7 @@
348736 static void
349737 intel_pdi_shim_configure(struct sdw_intel *sdw, struct sdw_cdns_pdi *pdi)
350738 {
351
- void __iomem *shim = sdw->res->shim;
739
+ void __iomem *shim = sdw->link_res->shim;
352740 unsigned int link_id = sdw->instance;
353741 int pdi_conf = 0;
354742
....@@ -369,10 +757,9 @@
369757 else
370758 pdi_conf &= ~(SDW_SHIM_PCMSYCM_DIR);
371759
372
- pdi_conf |= (pdi->intel_alh_id <<
373
- SDW_REG_SHIFT(SDW_SHIM_PCMSYCM_STREAM));
374
- pdi_conf |= (pdi->l_ch_num << SDW_REG_SHIFT(SDW_SHIM_PCMSYCM_LCHN));
375
- pdi_conf |= (pdi->h_ch_num << SDW_REG_SHIFT(SDW_SHIM_PCMSYCM_HCHN));
760
+ u32p_replace_bits(&pdi_conf, pdi->intel_alh_id, SDW_SHIM_PCMSYCM_STREAM);
761
+ u32p_replace_bits(&pdi_conf, pdi->l_ch_num, SDW_SHIM_PCMSYCM_LCHN);
762
+ u32p_replace_bits(&pdi_conf, pdi->h_ch_num, SDW_SHIM_PCMSYCM_HCHN);
376763
377764 intel_writew(shim, SDW_SHIM_PCMSYCHM(link_id, pdi->num), pdi_conf);
378765 }
....@@ -380,7 +767,7 @@
380767 static void
381768 intel_pdi_alh_configure(struct sdw_intel *sdw, struct sdw_cdns_pdi *pdi)
382769 {
383
- void __iomem *alh = sdw->res->alh;
770
+ void __iomem *alh = sdw->link_res->alh;
384771 unsigned int link_id = sdw->instance;
385772 unsigned int conf;
386773
....@@ -392,101 +779,142 @@
392779 /* Program Stream config ALH register */
393780 conf = intel_readl(alh, SDW_ALH_STRMZCFG(pdi->intel_alh_id));
394781
395
- conf |= (SDW_ALH_STRMZCFG_DMAT_VAL <<
396
- SDW_REG_SHIFT(SDW_ALH_STRMZCFG_DMAT));
397
-
398
- conf |= ((pdi->ch_count - 1) <<
399
- SDW_REG_SHIFT(SDW_ALH_STRMZCFG_CHN));
782
+ u32p_replace_bits(&conf, SDW_ALH_STRMZCFG_DMAT_VAL, SDW_ALH_STRMZCFG_DMAT);
783
+ u32p_replace_bits(&conf, pdi->ch_count - 1, SDW_ALH_STRMZCFG_CHN);
400784
401785 intel_writel(alh, SDW_ALH_STRMZCFG(pdi->intel_alh_id), conf);
402786 }
403787
404
-static int intel_config_stream(struct sdw_intel *sdw,
405
- struct snd_pcm_substream *substream,
406
- struct snd_soc_dai *dai,
407
- struct snd_pcm_hw_params *hw_params, int link_id)
788
+static int intel_params_stream(struct sdw_intel *sdw,
789
+ struct snd_pcm_substream *substream,
790
+ struct snd_soc_dai *dai,
791
+ struct snd_pcm_hw_params *hw_params,
792
+ int link_id, int alh_stream_id)
408793 {
409
- if (sdw->res->ops && sdw->res->ops->config_stream)
410
- return sdw->res->ops->config_stream(sdw->res->arg,
411
- substream, dai, hw_params, link_id);
794
+ struct sdw_intel_link_res *res = sdw->link_res;
795
+ struct sdw_intel_stream_params_data params_data;
412796
797
+ params_data.substream = substream;
798
+ params_data.dai = dai;
799
+ params_data.hw_params = hw_params;
800
+ params_data.link_id = link_id;
801
+ params_data.alh_stream_id = alh_stream_id;
802
+
803
+ if (res->ops && res->ops->params_stream && res->dev)
804
+ return res->ops->params_stream(res->dev,
805
+ &params_data);
413806 return -EIO;
807
+}
808
+
809
+static int intel_free_stream(struct sdw_intel *sdw,
810
+ struct snd_pcm_substream *substream,
811
+ struct snd_soc_dai *dai,
812
+ int link_id)
813
+{
814
+ struct sdw_intel_link_res *res = sdw->link_res;
815
+ struct sdw_intel_stream_free_data free_data;
816
+
817
+ free_data.substream = substream;
818
+ free_data.dai = dai;
819
+ free_data.link_id = link_id;
820
+
821
+ if (res->ops && res->ops->free_stream && res->dev)
822
+ return res->ops->free_stream(res->dev,
823
+ &free_data);
824
+
825
+ return 0;
826
+}
827
+
828
+/*
829
+ * bank switch routines
830
+ */
831
+
832
+static int intel_pre_bank_switch(struct sdw_bus *bus)
833
+{
834
+ struct sdw_cdns *cdns = bus_to_cdns(bus);
835
+ struct sdw_intel *sdw = cdns_to_intel(cdns);
836
+
837
+ /* Write to register only for multi-link */
838
+ if (!bus->multi_link)
839
+ return 0;
840
+
841
+ intel_shim_sync_arm(sdw);
842
+
843
+ return 0;
844
+}
845
+
846
+static int intel_post_bank_switch(struct sdw_bus *bus)
847
+{
848
+ struct sdw_cdns *cdns = bus_to_cdns(bus);
849
+ struct sdw_intel *sdw = cdns_to_intel(cdns);
850
+ void __iomem *shim = sdw->link_res->shim;
851
+ int sync_reg, ret;
852
+
853
+ /* Write to register only for multi-link */
854
+ if (!bus->multi_link)
855
+ return 0;
856
+
857
+ mutex_lock(sdw->link_res->shim_lock);
858
+
859
+ /* Read SYNC register */
860
+ sync_reg = intel_readl(shim, SDW_SHIM_SYNC);
861
+
862
+ /*
863
+ * post_bank_switch() ops is called from the bus in loop for
864
+ * all the Masters in the steam with the expectation that
865
+ * we trigger the bankswitch for the only first Master in the list
866
+ * and do nothing for the other Masters
867
+ *
868
+ * So, set the SYNCGO bit only if CMDSYNC bit is set for any Master.
869
+ */
870
+ if (!(sync_reg & SDW_SHIM_SYNC_CMDSYNC_MASK)) {
871
+ ret = 0;
872
+ goto unlock;
873
+ }
874
+
875
+ ret = intel_shim_sync_go_unlocked(sdw);
876
+unlock:
877
+ mutex_unlock(sdw->link_res->shim_lock);
878
+
879
+ if (ret < 0)
880
+ dev_err(sdw->cdns.dev, "Post bank switch failed: %d\n", ret);
881
+
882
+ return ret;
414883 }
415884
416885 /*
417886 * DAI routines
418887 */
419888
420
-static struct sdw_cdns_port *intel_alloc_port(struct sdw_intel *sdw,
421
- u32 ch, u32 dir, bool pcm)
889
+static int intel_startup(struct snd_pcm_substream *substream,
890
+ struct snd_soc_dai *dai)
422891 {
423
- struct sdw_cdns *cdns = &sdw->cdns;
424
- struct sdw_cdns_port *port = NULL;
425
- int i, ret = 0;
892
+ struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
893
+ int ret;
426894
427
- for (i = 0; i < cdns->num_ports; i++) {
428
- if (cdns->ports[i].assigned == true)
429
- continue;
430
-
431
- port = &cdns->ports[i];
432
- port->assigned = true;
433
- port->direction = dir;
434
- port->ch = ch;
435
- break;
895
+ ret = pm_runtime_get_sync(cdns->dev);
896
+ if (ret < 0 && ret != -EACCES) {
897
+ dev_err_ratelimited(cdns->dev,
898
+ "pm_runtime_get_sync failed in %s, ret %d\n",
899
+ __func__, ret);
900
+ pm_runtime_put_noidle(cdns->dev);
901
+ return ret;
436902 }
437
-
438
- if (!port) {
439
- dev_err(cdns->dev, "Unable to find a free port\n");
440
- return NULL;
441
- }
442
-
443
- if (pcm) {
444
- ret = sdw_cdns_alloc_stream(cdns, &cdns->pcm, port, ch, dir);
445
- if (ret)
446
- goto out;
447
-
448
- intel_pdi_shim_configure(sdw, port->pdi);
449
- sdw_cdns_config_stream(cdns, port, ch, dir, port->pdi);
450
-
451
- intel_pdi_alh_configure(sdw, port->pdi);
452
-
453
- } else {
454
- ret = sdw_cdns_alloc_stream(cdns, &cdns->pdm, port, ch, dir);
455
- }
456
-
457
-out:
458
- if (ret) {
459
- port->assigned = false;
460
- port = NULL;
461
- }
462
-
463
- return port;
464
-}
465
-
466
-static void intel_port_cleanup(struct sdw_cdns_dma_data *dma)
467
-{
468
- int i;
469
-
470
- for (i = 0; i < dma->nr_ports; i++) {
471
- if (dma->port[i]) {
472
- dma->port[i]->pdi->assigned = false;
473
- dma->port[i]->pdi = NULL;
474
- dma->port[i]->assigned = false;
475
- dma->port[i] = NULL;
476
- }
477
- }
903
+ return 0;
478904 }
479905
480906 static int intel_hw_params(struct snd_pcm_substream *substream,
481
- struct snd_pcm_hw_params *params,
482
- struct snd_soc_dai *dai)
907
+ struct snd_pcm_hw_params *params,
908
+ struct snd_soc_dai *dai)
483909 {
484910 struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
485911 struct sdw_intel *sdw = cdns_to_intel(cdns);
486912 struct sdw_cdns_dma_data *dma;
913
+ struct sdw_cdns_pdi *pdi;
487914 struct sdw_stream_config sconfig;
488915 struct sdw_port_config *pconfig;
489
- int ret, i, ch, dir;
916
+ int ch, dir;
917
+ int ret;
490918 bool pcm = true;
491919
492920 dma = snd_soc_dai_get_dma_data(dai, substream);
....@@ -499,38 +927,35 @@
499927 else
500928 dir = SDW_DATA_DIR_TX;
501929
502
- if (dma->stream_type == SDW_STREAM_PDM) {
503
- /* TODO: Check whether PDM decimator is already in use */
504
- dma->nr_ports = sdw_cdns_get_stream(cdns, &cdns->pdm, ch, dir);
930
+ if (dma->stream_type == SDW_STREAM_PDM)
505931 pcm = false;
506
- } else {
507
- dma->nr_ports = sdw_cdns_get_stream(cdns, &cdns->pcm, ch, dir);
932
+
933
+ if (pcm)
934
+ pdi = sdw_cdns_alloc_pdi(cdns, &cdns->pcm, ch, dir, dai->id);
935
+ else
936
+ pdi = sdw_cdns_alloc_pdi(cdns, &cdns->pdm, ch, dir, dai->id);
937
+
938
+ if (!pdi) {
939
+ ret = -EINVAL;
940
+ goto error;
508941 }
509942
510
- if (!dma->nr_ports) {
511
- dev_err(dai->dev, "ports/resources not available");
512
- return -EINVAL;
513
- }
943
+ /* do run-time configurations for SHIM, ALH and PDI/PORT */
944
+ intel_pdi_shim_configure(sdw, pdi);
945
+ intel_pdi_alh_configure(sdw, pdi);
946
+ sdw_cdns_config_stream(cdns, ch, dir, pdi);
514947
515
- dma->port = kcalloc(dma->nr_ports, sizeof(*dma->port), GFP_KERNEL);
516
- if (!dma->port)
517
- return -ENOMEM;
518
-
519
- for (i = 0; i < dma->nr_ports; i++) {
520
- dma->port[i] = intel_alloc_port(sdw, ch, dir, pcm);
521
- if (!dma->port[i]) {
522
- ret = -EINVAL;
523
- goto port_error;
524
- }
525
- }
948
+ /* store pdi and hw_params, may be needed in prepare step */
949
+ dma->suspended = false;
950
+ dma->pdi = pdi;
951
+ dma->hw_params = params;
526952
527953 /* Inform DSP about PDI stream number */
528
- for (i = 0; i < dma->nr_ports; i++) {
529
- ret = intel_config_stream(sdw, substream, dai, params,
530
- dma->port[i]->pdi->intel_alh_id);
531
- if (ret)
532
- goto port_error;
533
- }
954
+ ret = intel_params_stream(sdw, substream, dai, params,
955
+ sdw->instance,
956
+ pdi->intel_alh_id);
957
+ if (ret)
958
+ goto error;
534959
535960 sconfig.direction = dir;
536961 sconfig.ch_count = ch;
....@@ -545,32 +970,70 @@
545970 }
546971
547972 /* Port configuration */
548
- pconfig = kcalloc(dma->nr_ports, sizeof(*pconfig), GFP_KERNEL);
973
+ pconfig = kcalloc(1, sizeof(*pconfig), GFP_KERNEL);
549974 if (!pconfig) {
550975 ret = -ENOMEM;
551
- goto port_error;
976
+ goto error;
552977 }
553978
554
- for (i = 0; i < dma->nr_ports; i++) {
555
- pconfig[i].num = dma->port[i]->num;
556
- pconfig[i].ch_mask = (1 << ch) - 1;
557
- }
979
+ pconfig->num = pdi->num;
980
+ pconfig->ch_mask = (1 << ch) - 1;
558981
559982 ret = sdw_stream_add_master(&cdns->bus, &sconfig,
560
- pconfig, dma->nr_ports, dma->stream);
561
- if (ret) {
562
- dev_err(cdns->dev, "add master to stream failed:%d", ret);
563
- goto stream_error;
983
+ pconfig, 1, dma->stream);
984
+ if (ret)
985
+ dev_err(cdns->dev, "add master to stream failed:%d\n", ret);
986
+
987
+ kfree(pconfig);
988
+error:
989
+ return ret;
990
+}
991
+
992
+static int intel_prepare(struct snd_pcm_substream *substream,
993
+ struct snd_soc_dai *dai)
994
+{
995
+ struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
996
+ struct sdw_intel *sdw = cdns_to_intel(cdns);
997
+ struct sdw_cdns_dma_data *dma;
998
+ int ch, dir;
999
+ int ret = 0;
1000
+
1001
+ dma = snd_soc_dai_get_dma_data(dai, substream);
1002
+ if (!dma) {
1003
+ dev_err(dai->dev, "failed to get dma data in %s",
1004
+ __func__);
1005
+ return -EIO;
5641006 }
5651007
566
- kfree(pconfig);
567
- return ret;
1008
+ if (dma->suspended) {
1009
+ dma->suspended = false;
5681010
569
-stream_error:
570
- kfree(pconfig);
571
-port_error:
572
- intel_port_cleanup(dma);
573
- kfree(dma->port);
1011
+ /*
1012
+ * .prepare() is called after system resume, where we
1013
+ * need to reinitialize the SHIM/ALH/Cadence IP.
1014
+ * .prepare() is also called to deal with underflows,
1015
+ * but in those cases we cannot touch ALH/SHIM
1016
+ * registers
1017
+ */
1018
+
1019
+ /* configure stream */
1020
+ ch = params_channels(dma->hw_params);
1021
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
1022
+ dir = SDW_DATA_DIR_RX;
1023
+ else
1024
+ dir = SDW_DATA_DIR_TX;
1025
+
1026
+ intel_pdi_shim_configure(sdw, dma->pdi);
1027
+ intel_pdi_alh_configure(sdw, dma->pdi);
1028
+ sdw_cdns_config_stream(cdns, ch, dir, dma->pdi);
1029
+
1030
+ /* Inform DSP about PDI stream number */
1031
+ ret = intel_params_stream(sdw, substream, dai,
1032
+ dma->hw_params,
1033
+ sdw->instance,
1034
+ dma->pdi->intel_alh_id);
1035
+ }
1036
+
5741037 return ret;
5751038 }
5761039
....@@ -578,6 +1041,7 @@
5781041 intel_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
5791042 {
5801043 struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
1044
+ struct sdw_intel *sdw = cdns_to_intel(cdns);
5811045 struct sdw_cdns_dma_data *dma;
5821046 int ret;
5831047
....@@ -585,50 +1049,120 @@
5851049 if (!dma)
5861050 return -EIO;
5871051
1052
+ /*
1053
+ * The sdw stream state will transition to RELEASED when stream->
1054
+ * master_list is empty. So the stream state will transition to
1055
+ * DEPREPARED for the first cpu-dai and to RELEASED for the last
1056
+ * cpu-dai.
1057
+ */
5881058 ret = sdw_stream_remove_master(&cdns->bus, dma->stream);
589
- if (ret < 0)
590
- dev_err(dai->dev, "remove master from stream %s failed: %d",
591
- dma->stream->name, ret);
1059
+ if (ret < 0) {
1060
+ dev_err(dai->dev, "remove master from stream %s failed: %d\n",
1061
+ dma->stream->name, ret);
1062
+ return ret;
1063
+ }
5921064
593
- intel_port_cleanup(dma);
594
- kfree(dma->port);
595
- return ret;
1065
+ ret = intel_free_stream(sdw, substream, dai, sdw->instance);
1066
+ if (ret < 0) {
1067
+ dev_err(dai->dev, "intel_free_stream: failed %d", ret);
1068
+ return ret;
1069
+ }
1070
+
1071
+ dma->hw_params = NULL;
1072
+ dma->pdi = NULL;
1073
+
1074
+ return 0;
1075
+}
1076
+
1077
+static void intel_shutdown(struct snd_pcm_substream *substream,
1078
+ struct snd_soc_dai *dai)
1079
+{
1080
+ struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
1081
+
1082
+ pm_runtime_mark_last_busy(cdns->dev);
1083
+ pm_runtime_put_autosuspend(cdns->dev);
1084
+}
1085
+
1086
+static int intel_component_dais_suspend(struct snd_soc_component *component)
1087
+{
1088
+ struct sdw_cdns_dma_data *dma;
1089
+ struct snd_soc_dai *dai;
1090
+
1091
+ for_each_component_dais(component, dai) {
1092
+ /*
1093
+ * we don't have a .suspend dai_ops, and we don't have access
1094
+ * to the substream, so let's mark both capture and playback
1095
+ * DMA contexts as suspended
1096
+ */
1097
+ dma = dai->playback_dma_data;
1098
+ if (dma)
1099
+ dma->suspended = true;
1100
+
1101
+ dma = dai->capture_dma_data;
1102
+ if (dma)
1103
+ dma->suspended = true;
1104
+ }
1105
+
1106
+ return 0;
5961107 }
5971108
5981109 static int intel_pcm_set_sdw_stream(struct snd_soc_dai *dai,
599
- void *stream, int direction)
1110
+ void *stream, int direction)
6001111 {
6011112 return cdns_set_sdw_stream(dai, stream, true, direction);
6021113 }
6031114
6041115 static int intel_pdm_set_sdw_stream(struct snd_soc_dai *dai,
605
- void *stream, int direction)
1116
+ void *stream, int direction)
6061117 {
6071118 return cdns_set_sdw_stream(dai, stream, false, direction);
6081119 }
6091120
610
-static struct snd_soc_dai_ops intel_pcm_dai_ops = {
1121
+static void *intel_get_sdw_stream(struct snd_soc_dai *dai,
1122
+ int direction)
1123
+{
1124
+ struct sdw_cdns_dma_data *dma;
1125
+
1126
+ if (direction == SNDRV_PCM_STREAM_PLAYBACK)
1127
+ dma = dai->playback_dma_data;
1128
+ else
1129
+ dma = dai->capture_dma_data;
1130
+
1131
+ if (!dma)
1132
+ return ERR_PTR(-EINVAL);
1133
+
1134
+ return dma->stream;
1135
+}
1136
+
1137
+static const struct snd_soc_dai_ops intel_pcm_dai_ops = {
1138
+ .startup = intel_startup,
6111139 .hw_params = intel_hw_params,
1140
+ .prepare = intel_prepare,
6121141 .hw_free = intel_hw_free,
613
- .shutdown = sdw_cdns_shutdown,
1142
+ .shutdown = intel_shutdown,
6141143 .set_sdw_stream = intel_pcm_set_sdw_stream,
1144
+ .get_sdw_stream = intel_get_sdw_stream,
6151145 };
6161146
617
-static struct snd_soc_dai_ops intel_pdm_dai_ops = {
1147
+static const struct snd_soc_dai_ops intel_pdm_dai_ops = {
1148
+ .startup = intel_startup,
6181149 .hw_params = intel_hw_params,
1150
+ .prepare = intel_prepare,
6191151 .hw_free = intel_hw_free,
620
- .shutdown = sdw_cdns_shutdown,
1152
+ .shutdown = intel_shutdown,
6211153 .set_sdw_stream = intel_pdm_set_sdw_stream,
1154
+ .get_sdw_stream = intel_get_sdw_stream,
6221155 };
6231156
6241157 static const struct snd_soc_component_driver dai_component = {
6251158 .name = "soundwire",
1159
+ .suspend = intel_component_dais_suspend
6261160 };
6271161
6281162 static int intel_create_dai(struct sdw_cdns *cdns,
629
- struct snd_soc_dai_driver *dais,
630
- enum intel_pdi_type type,
631
- u32 num, u32 off, u32 max_ch, bool pcm)
1163
+ struct snd_soc_dai_driver *dais,
1164
+ enum intel_pdi_type type,
1165
+ u32 num, u32 off, u32 max_ch, bool pcm)
6321166 {
6331167 int i;
6341168
....@@ -637,20 +1171,13 @@
6371171
6381172 /* TODO: Read supported rates/formats from hardware */
6391173 for (i = off; i < (off + num); i++) {
640
- dais[i].name = kasprintf(GFP_KERNEL, "SDW%d Pin%d",
641
- cdns->instance, i);
1174
+ dais[i].name = devm_kasprintf(cdns->dev, GFP_KERNEL,
1175
+ "SDW%d Pin%d",
1176
+ cdns->instance, i);
6421177 if (!dais[i].name)
6431178 return -ENOMEM;
6441179
6451180 if (type == INTEL_PDI_BD || type == INTEL_PDI_OUT) {
646
- dais[i].playback.stream_name = kasprintf(GFP_KERNEL,
647
- "SDW%d Tx%d",
648
- cdns->instance, i);
649
- if (!dais[i].playback.stream_name) {
650
- kfree(dais[i].name);
651
- return -ENOMEM;
652
- }
653
-
6541181 dais[i].playback.channels_min = 1;
6551182 dais[i].playback.channels_max = max_ch;
6561183 dais[i].playback.rates = SNDRV_PCM_RATE_48000;
....@@ -658,22 +1185,11 @@
6581185 }
6591186
6601187 if (type == INTEL_PDI_BD || type == INTEL_PDI_IN) {
661
- dais[i].capture.stream_name = kasprintf(GFP_KERNEL,
662
- "SDW%d Rx%d",
663
- cdns->instance, i);
664
- if (!dais[i].capture.stream_name) {
665
- kfree(dais[i].name);
666
- kfree(dais[i].playback.stream_name);
667
- return -ENOMEM;
668
- }
669
-
6701188 dais[i].capture.channels_min = 1;
6711189 dais[i].capture.channels_max = max_ch;
6721190 dais[i].capture.rates = SNDRV_PCM_RATE_48000;
6731191 dais[i].capture.formats = SNDRV_PCM_FMTBIT_S16_LE;
6741192 }
675
-
676
- dais[i].id = SDW_DAI_ID_RANGE_START + i;
6771193
6781194 if (pcm)
6791195 dais[i].ops = &intel_pcm_dai_ops;
....@@ -701,45 +1217,79 @@
7011217 /* Create PCM DAIs */
7021218 stream = &cdns->pcm;
7031219
704
- ret = intel_create_dai(cdns, dais, INTEL_PDI_IN,
705
- stream->num_in, off, stream->num_ch_in, true);
1220
+ ret = intel_create_dai(cdns, dais, INTEL_PDI_IN, cdns->pcm.num_in,
1221
+ off, stream->num_ch_in, true);
7061222 if (ret)
7071223 return ret;
7081224
7091225 off += cdns->pcm.num_in;
710
- ret = intel_create_dai(cdns, dais, INTEL_PDI_OUT,
711
- cdns->pcm.num_out, off, stream->num_ch_out, true);
1226
+ ret = intel_create_dai(cdns, dais, INTEL_PDI_OUT, cdns->pcm.num_out,
1227
+ off, stream->num_ch_out, true);
7121228 if (ret)
7131229 return ret;
7141230
7151231 off += cdns->pcm.num_out;
716
- ret = intel_create_dai(cdns, dais, INTEL_PDI_BD,
717
- cdns->pcm.num_bd, off, stream->num_ch_bd, true);
1232
+ ret = intel_create_dai(cdns, dais, INTEL_PDI_BD, cdns->pcm.num_bd,
1233
+ off, stream->num_ch_bd, true);
7181234 if (ret)
7191235 return ret;
7201236
7211237 /* Create PDM DAIs */
7221238 stream = &cdns->pdm;
7231239 off += cdns->pcm.num_bd;
724
- ret = intel_create_dai(cdns, dais, INTEL_PDI_IN,
725
- cdns->pdm.num_in, off, stream->num_ch_in, false);
1240
+ ret = intel_create_dai(cdns, dais, INTEL_PDI_IN, cdns->pdm.num_in,
1241
+ off, stream->num_ch_in, false);
7261242 if (ret)
7271243 return ret;
7281244
7291245 off += cdns->pdm.num_in;
730
- ret = intel_create_dai(cdns, dais, INTEL_PDI_OUT,
731
- cdns->pdm.num_out, off, stream->num_ch_out, false);
1246
+ ret = intel_create_dai(cdns, dais, INTEL_PDI_OUT, cdns->pdm.num_out,
1247
+ off, stream->num_ch_out, false);
7321248 if (ret)
7331249 return ret;
7341250
735
- off += cdns->pdm.num_bd;
736
- ret = intel_create_dai(cdns, dais, INTEL_PDI_BD,
737
- cdns->pdm.num_bd, off, stream->num_ch_bd, false);
1251
+ off += cdns->pdm.num_out;
1252
+ ret = intel_create_dai(cdns, dais, INTEL_PDI_BD, cdns->pdm.num_bd,
1253
+ off, stream->num_ch_bd, false);
7381254 if (ret)
7391255 return ret;
7401256
7411257 return snd_soc_register_component(cdns->dev, &dai_component,
742
- dais, num_dai);
1258
+ dais, num_dai);
1259
+}
1260
+
1261
+static int sdw_master_read_intel_prop(struct sdw_bus *bus)
1262
+{
1263
+ struct sdw_master_prop *prop = &bus->prop;
1264
+ struct fwnode_handle *link;
1265
+ char name[32];
1266
+ u32 quirk_mask;
1267
+
1268
+ /* Find master handle */
1269
+ snprintf(name, sizeof(name),
1270
+ "mipi-sdw-link-%d-subproperties", bus->link_id);
1271
+
1272
+ link = device_get_named_child_node(bus->dev, name);
1273
+ if (!link) {
1274
+ dev_err(bus->dev, "Master node %s not found\n", name);
1275
+ return -EIO;
1276
+ }
1277
+
1278
+ fwnode_property_read_u32(link,
1279
+ "intel-sdw-ip-clock",
1280
+ &prop->mclk_freq);
1281
+
1282
+ /* the values reported by BIOS are the 2x clock, not the bus clock */
1283
+ prop->mclk_freq /= 2;
1284
+
1285
+ fwnode_property_read_u32(link,
1286
+ "intel-quirk-mask",
1287
+ &quirk_mask);
1288
+
1289
+ if (quirk_mask & SDW_INTEL_QUIRK_MASK_BUS_DISABLE)
1290
+ prop->hw_disabled = true;
1291
+
1292
+ return 0;
7431293 }
7441294
7451295 static int intel_prop_read(struct sdw_bus *bus)
....@@ -747,15 +1297,8 @@
7471297 /* Initialize with default handler to read all DisCo properties */
7481298 sdw_master_read_prop(bus);
7491299
750
- /* BIOS is not giving some values correctly. So, lets override them */
751
- bus->prop.num_freq = 1;
752
- bus->prop.freq = devm_kcalloc(bus->dev, sizeof(*bus->prop.freq),
753
- bus->prop.num_freq, GFP_KERNEL);
754
- if (!bus->prop.freq)
755
- return -ENOMEM;
756
-
757
- bus->prop.freq[0] = bus->prop.max_freq;
758
- bus->prop.err_threshold = 5;
1300
+ /* read Intel-specific properties */
1301
+ sdw_master_read_intel_prop(bus);
7591302
7601303 return 0;
7611304 }
....@@ -766,117 +1309,686 @@
7661309 .xfer_msg_defer = cdns_xfer_msg_defer,
7671310 .reset_page_addr = cdns_reset_page_addr,
7681311 .set_bus_conf = cdns_bus_conf,
1312
+ .pre_bank_switch = intel_pre_bank_switch,
1313
+ .post_bank_switch = intel_post_bank_switch,
7691314 };
1315
+
1316
+static int intel_init(struct sdw_intel *sdw)
1317
+{
1318
+ bool clock_stop;
1319
+
1320
+ /* Initialize shim and controller */
1321
+ intel_link_power_up(sdw);
1322
+
1323
+ clock_stop = sdw_cdns_is_clock_stop(&sdw->cdns);
1324
+
1325
+ intel_shim_init(sdw, clock_stop);
1326
+
1327
+ return 0;
1328
+}
7701329
7711330 /*
7721331 * probe and init
7731332 */
774
-static int intel_probe(struct platform_device *pdev)
1333
+static int intel_master_probe(struct platform_device *pdev)
7751334 {
776
- struct sdw_cdns_stream_config config;
1335
+ struct device *dev = &pdev->dev;
7771336 struct sdw_intel *sdw;
1337
+ struct sdw_cdns *cdns;
1338
+ struct sdw_bus *bus;
7781339 int ret;
7791340
780
- sdw = devm_kzalloc(&pdev->dev, sizeof(*sdw), GFP_KERNEL);
1341
+ sdw = devm_kzalloc(dev, sizeof(*sdw), GFP_KERNEL);
7811342 if (!sdw)
7821343 return -ENOMEM;
7831344
784
- sdw->instance = pdev->id;
785
- sdw->res = dev_get_platdata(&pdev->dev);
786
- sdw->cdns.dev = &pdev->dev;
787
- sdw->cdns.registers = sdw->res->registers;
788
- sdw->cdns.instance = sdw->instance;
789
- sdw->cdns.msg_count = 0;
790
- sdw->cdns.bus.dev = &pdev->dev;
791
- sdw->cdns.bus.link_id = pdev->id;
1345
+ cdns = &sdw->cdns;
1346
+ bus = &cdns->bus;
7921347
793
- sdw_cdns_probe(&sdw->cdns);
1348
+ sdw->instance = pdev->id;
1349
+ sdw->link_res = dev_get_platdata(dev);
1350
+ cdns->dev = dev;
1351
+ cdns->registers = sdw->link_res->registers;
1352
+ cdns->instance = sdw->instance;
1353
+ cdns->msg_count = 0;
1354
+
1355
+ bus->link_id = pdev->id;
1356
+
1357
+ sdw_cdns_probe(cdns);
7941358
7951359 /* Set property read ops */
7961360 sdw_intel_ops.read_prop = intel_prop_read;
797
- sdw->cdns.bus.ops = &sdw_intel_ops;
1361
+ bus->ops = &sdw_intel_ops;
7981362
799
- sdw_intel_ops.read_prop = intel_prop_read;
800
- sdw->cdns.bus.ops = &sdw_intel_ops;
1363
+ /* set driver data, accessed by snd_soc_dai_get_drvdata() */
1364
+ dev_set_drvdata(dev, cdns);
8011365
802
- platform_set_drvdata(pdev, sdw);
1366
+ /* use generic bandwidth allocation algorithm */
1367
+ sdw->cdns.bus.compute_params = sdw_compute_params;
8031368
804
- ret = sdw_add_bus_master(&sdw->cdns.bus);
1369
+ ret = sdw_bus_master_add(bus, dev, dev->fwnode);
8051370 if (ret) {
806
- dev_err(&pdev->dev, "sdw_add_bus_master fail: %d\n", ret);
807
- goto err_master_reg;
1371
+ dev_err(dev, "sdw_bus_master_add fail: %d\n", ret);
1372
+ return ret;
8081373 }
8091374
810
- /* Initialize shim and controller */
811
- intel_link_power_up(sdw);
812
- intel_shim_init(sdw);
1375
+ if (bus->prop.hw_disabled)
1376
+ dev_info(dev,
1377
+ "SoundWire master %d is disabled, will be ignored\n",
1378
+ bus->link_id);
1379
+ /*
1380
+ * Ignore BIOS err_threshold, it's a really bad idea when dealing
1381
+ * with multiple hardware synchronized links
1382
+ */
1383
+ bus->prop.err_threshold = 0;
8131384
814
- ret = sdw_cdns_init(&sdw->cdns);
1385
+ return 0;
1386
+}
1387
+
1388
+int intel_master_startup(struct platform_device *pdev)
1389
+{
1390
+ struct sdw_cdns_stream_config config;
1391
+ struct device *dev = &pdev->dev;
1392
+ struct sdw_cdns *cdns = dev_get_drvdata(dev);
1393
+ struct sdw_intel *sdw = cdns_to_intel(cdns);
1394
+ struct sdw_bus *bus = &cdns->bus;
1395
+ int link_flags;
1396
+ bool multi_link;
1397
+ u32 clock_stop_quirks;
1398
+ int ret;
1399
+
1400
+ if (bus->prop.hw_disabled) {
1401
+ dev_info(dev,
1402
+ "SoundWire master %d is disabled, ignoring\n",
1403
+ sdw->instance);
1404
+ return 0;
1405
+ }
1406
+
1407
+ link_flags = md_flags >> (bus->link_id * 8);
1408
+ multi_link = !(link_flags & SDW_INTEL_MASTER_DISABLE_MULTI_LINK);
1409
+ if (!multi_link) {
1410
+ dev_dbg(dev, "Multi-link is disabled\n");
1411
+ bus->multi_link = false;
1412
+ } else {
1413
+ /*
1414
+ * hardware-based synchronization is required regardless
1415
+ * of the number of segments used by a stream: SSP-based
1416
+ * synchronization is gated by gsync when the multi-master
1417
+ * mode is set.
1418
+ */
1419
+ bus->multi_link = true;
1420
+ bus->hw_sync_min_links = 1;
1421
+ }
1422
+
1423
+ /* Initialize shim, controller */
1424
+ ret = intel_init(sdw);
8151425 if (ret)
8161426 goto err_init;
8171427
818
- ret = sdw_cdns_enable_interrupt(&sdw->cdns);
819
-
8201428 /* Read the PDI config and initialize cadence PDI */
8211429 intel_pdi_init(sdw, &config);
822
- ret = sdw_cdns_pdi_init(&sdw->cdns, config);
1430
+ ret = sdw_cdns_pdi_init(cdns, config);
8231431 if (ret)
8241432 goto err_init;
8251433
8261434 intel_pdi_ch_update(sdw);
8271435
828
- /* Acquire IRQ */
829
- ret = request_threaded_irq(sdw->res->irq, sdw_cdns_irq,
830
- sdw_cdns_thread, IRQF_SHARED, KBUILD_MODNAME,
831
- &sdw->cdns);
1436
+ ret = sdw_cdns_enable_interrupt(cdns, true);
8321437 if (ret < 0) {
833
- dev_err(sdw->cdns.dev, "unable to grab IRQ %d, disabling device\n",
834
- sdw->res->irq);
1438
+ dev_err(dev, "cannot enable interrupts\n");
8351439 goto err_init;
1440
+ }
1441
+
1442
+ /*
1443
+ * follow recommended programming flows to avoid timeouts when
1444
+ * gsync is enabled
1445
+ */
1446
+ if (multi_link)
1447
+ intel_shim_sync_arm(sdw);
1448
+
1449
+ ret = sdw_cdns_init(cdns);
1450
+ if (ret < 0) {
1451
+ dev_err(dev, "unable to initialize Cadence IP\n");
1452
+ goto err_interrupt;
1453
+ }
1454
+
1455
+ ret = sdw_cdns_exit_reset(cdns);
1456
+ if (ret < 0) {
1457
+ dev_err(dev, "unable to exit bus reset sequence\n");
1458
+ goto err_interrupt;
1459
+ }
1460
+
1461
+ if (multi_link) {
1462
+ ret = intel_shim_sync_go(sdw);
1463
+ if (ret < 0) {
1464
+ dev_err(dev, "sync go failed: %d\n", ret);
1465
+ goto err_interrupt;
1466
+ }
8361467 }
8371468
8381469 /* Register DAIs */
8391470 ret = intel_register_dai(sdw);
8401471 if (ret) {
841
- dev_err(sdw->cdns.dev, "DAI registration failed: %d", ret);
842
- snd_soc_unregister_component(sdw->cdns.dev);
843
- goto err_dai;
1472
+ dev_err(dev, "DAI registration failed: %d\n", ret);
1473
+ goto err_interrupt;
8441474 }
1475
+
1476
+ intel_debugfs_init(sdw);
1477
+
1478
+ /* Enable runtime PM */
1479
+ if (!(link_flags & SDW_INTEL_MASTER_DISABLE_PM_RUNTIME)) {
1480
+ pm_runtime_set_autosuspend_delay(dev,
1481
+ INTEL_MASTER_SUSPEND_DELAY_MS);
1482
+ pm_runtime_use_autosuspend(dev);
1483
+ pm_runtime_mark_last_busy(dev);
1484
+
1485
+ pm_runtime_set_active(dev);
1486
+ pm_runtime_enable(dev);
1487
+ }
1488
+
1489
+ clock_stop_quirks = sdw->link_res->clock_stop_quirks;
1490
+ if (clock_stop_quirks & SDW_INTEL_CLK_STOP_NOT_ALLOWED) {
1491
+ /*
1492
+ * To keep the clock running we need to prevent
1493
+ * pm_runtime suspend from happening by increasing the
1494
+ * reference count.
1495
+ * This quirk is specified by the parent PCI device in
1496
+ * case of specific latency requirements. It will have
1497
+ * no effect if pm_runtime is disabled by the user via
1498
+ * a module parameter for testing purposes.
1499
+ */
1500
+ pm_runtime_get_noresume(dev);
1501
+ }
1502
+
1503
+ /*
1504
+ * The runtime PM status of Slave devices is "Unsupported"
1505
+ * until they report as ATTACHED. If they don't, e.g. because
1506
+ * there are no Slave devices populated or if the power-on is
1507
+ * delayed or dependent on a power switch, the Master will
1508
+ * remain active and prevent its parent from suspending.
1509
+ *
1510
+ * Conditionally force the pm_runtime core to re-evaluate the
1511
+ * Master status in the absence of any Slave activity. A quirk
1512
+ * is provided to e.g. deal with Slaves that may be powered on
1513
+ * with a delay. A more complete solution would require the
1514
+ * definition of Master properties.
1515
+ */
1516
+ if (!(link_flags & SDW_INTEL_MASTER_DISABLE_PM_RUNTIME_IDLE))
1517
+ pm_runtime_idle(dev);
8451518
8461519 return 0;
8471520
848
-err_dai:
849
- free_irq(sdw->res->irq, sdw);
1521
+err_interrupt:
1522
+ sdw_cdns_enable_interrupt(cdns, false);
8501523 err_init:
851
- sdw_delete_bus_master(&sdw->cdns.bus);
852
-err_master_reg:
8531524 return ret;
8541525 }
8551526
856
-static int intel_remove(struct platform_device *pdev)
1527
+static int intel_master_remove(struct platform_device *pdev)
8571528 {
858
- struct sdw_intel *sdw;
1529
+ struct device *dev = &pdev->dev;
1530
+ struct sdw_cdns *cdns = dev_get_drvdata(dev);
1531
+ struct sdw_intel *sdw = cdns_to_intel(cdns);
1532
+ struct sdw_bus *bus = &cdns->bus;
8591533
860
- sdw = platform_get_drvdata(pdev);
861
-
862
- free_irq(sdw->res->irq, sdw);
863
- snd_soc_unregister_component(sdw->cdns.dev);
864
- sdw_delete_bus_master(&sdw->cdns.bus);
1534
+ /*
1535
+ * Since pm_runtime is already disabled, we don't decrease
1536
+ * the refcount when the clock_stop_quirk is
1537
+ * SDW_INTEL_CLK_STOP_NOT_ALLOWED
1538
+ */
1539
+ if (!bus->prop.hw_disabled) {
1540
+ intel_debugfs_exit(sdw);
1541
+ sdw_cdns_enable_interrupt(cdns, false);
1542
+ snd_soc_unregister_component(dev);
1543
+ }
1544
+ sdw_bus_master_delete(bus);
8651545
8661546 return 0;
8671547 }
8681548
869
-static struct platform_driver sdw_intel_drv = {
870
- .probe = intel_probe,
871
- .remove = intel_remove,
872
- .driver = {
873
- .name = "int-sdw",
1549
+int intel_master_process_wakeen_event(struct platform_device *pdev)
1550
+{
1551
+ struct device *dev = &pdev->dev;
1552
+ struct sdw_intel *sdw;
1553
+ struct sdw_bus *bus;
1554
+ void __iomem *shim;
1555
+ u16 wake_sts;
8741556
875
- },
1557
+ sdw = platform_get_drvdata(pdev);
1558
+ bus = &sdw->cdns.bus;
1559
+
1560
+ if (bus->prop.hw_disabled) {
1561
+ dev_dbg(dev, "SoundWire master %d is disabled, ignoring\n", bus->link_id);
1562
+ return 0;
1563
+ }
1564
+
1565
+ shim = sdw->link_res->shim;
1566
+ wake_sts = intel_readw(shim, SDW_SHIM_WAKESTS);
1567
+
1568
+ if (!(wake_sts & BIT(sdw->instance)))
1569
+ return 0;
1570
+
1571
+ /* disable WAKEEN interrupt ASAP to prevent interrupt flood */
1572
+ intel_shim_wake(sdw, false);
1573
+
1574
+ /*
1575
+ * resume the Master, which will generate a bus reset and result in
1576
+ * Slaves re-attaching and be re-enumerated. The SoundWire physical
1577
+ * device which generated the wake will trigger an interrupt, which
1578
+ * will in turn cause the corresponding Linux Slave device to be
1579
+ * resumed and the Slave codec driver to check the status.
1580
+ */
1581
+ pm_request_resume(dev);
1582
+
1583
+ return 0;
1584
+}
1585
+
1586
+/*
1587
+ * PM calls
1588
+ */
1589
+
1590
+#ifdef CONFIG_PM
1591
+
1592
+static int __maybe_unused intel_suspend(struct device *dev)
1593
+{
1594
+ struct sdw_cdns *cdns = dev_get_drvdata(dev);
1595
+ struct sdw_intel *sdw = cdns_to_intel(cdns);
1596
+ struct sdw_bus *bus = &cdns->bus;
1597
+ u32 clock_stop_quirks;
1598
+ int ret;
1599
+
1600
+ if (bus->prop.hw_disabled) {
1601
+ dev_dbg(dev, "SoundWire master %d is disabled, ignoring\n",
1602
+ bus->link_id);
1603
+ return 0;
1604
+ }
1605
+
1606
+ if (pm_runtime_suspended(dev)) {
1607
+ dev_dbg(dev, "%s: pm_runtime status: suspended\n", __func__);
1608
+
1609
+ clock_stop_quirks = sdw->link_res->clock_stop_quirks;
1610
+
1611
+ if ((clock_stop_quirks & SDW_INTEL_CLK_STOP_BUS_RESET ||
1612
+ !clock_stop_quirks) &&
1613
+ !pm_runtime_suspended(dev->parent)) {
1614
+
1615
+ /*
1616
+ * if we've enabled clock stop, and the parent
1617
+ * is still active, disable shim wake. The
1618
+ * SHIM registers are not accessible if the
1619
+ * parent is already pm_runtime suspended so
1620
+ * it's too late to change that configuration
1621
+ */
1622
+
1623
+ intel_shim_wake(sdw, false);
1624
+ }
1625
+
1626
+ return 0;
1627
+ }
1628
+
1629
+ ret = sdw_cdns_enable_interrupt(cdns, false);
1630
+ if (ret < 0) {
1631
+ dev_err(dev, "cannot disable interrupts on suspend\n");
1632
+ return ret;
1633
+ }
1634
+
1635
+ ret = intel_link_power_down(sdw);
1636
+ if (ret) {
1637
+ dev_err(dev, "Link power down failed: %d", ret);
1638
+ return ret;
1639
+ }
1640
+
1641
+ intel_shim_wake(sdw, false);
1642
+
1643
+ return 0;
1644
+}
1645
+
1646
+static int intel_suspend_runtime(struct device *dev)
1647
+{
1648
+ struct sdw_cdns *cdns = dev_get_drvdata(dev);
1649
+ struct sdw_intel *sdw = cdns_to_intel(cdns);
1650
+ struct sdw_bus *bus = &cdns->bus;
1651
+ u32 clock_stop_quirks;
1652
+ int ret;
1653
+
1654
+ if (bus->prop.hw_disabled) {
1655
+ dev_dbg(dev, "SoundWire master %d is disabled, ignoring\n",
1656
+ bus->link_id);
1657
+ return 0;
1658
+ }
1659
+
1660
+ clock_stop_quirks = sdw->link_res->clock_stop_quirks;
1661
+
1662
+ if (clock_stop_quirks & SDW_INTEL_CLK_STOP_TEARDOWN) {
1663
+
1664
+ ret = sdw_cdns_enable_interrupt(cdns, false);
1665
+ if (ret < 0) {
1666
+ dev_err(dev, "cannot disable interrupts on suspend\n");
1667
+ return ret;
1668
+ }
1669
+
1670
+ ret = intel_link_power_down(sdw);
1671
+ if (ret) {
1672
+ dev_err(dev, "Link power down failed: %d", ret);
1673
+ return ret;
1674
+ }
1675
+
1676
+ intel_shim_wake(sdw, false);
1677
+
1678
+ } else if (clock_stop_quirks & SDW_INTEL_CLK_STOP_BUS_RESET ||
1679
+ !clock_stop_quirks) {
1680
+ ret = sdw_cdns_clock_stop(cdns, true);
1681
+ if (ret < 0) {
1682
+ dev_err(dev, "cannot enable clock stop on suspend\n");
1683
+ return ret;
1684
+ }
1685
+
1686
+ ret = sdw_cdns_enable_interrupt(cdns, false);
1687
+ if (ret < 0) {
1688
+ dev_err(dev, "cannot disable interrupts on suspend\n");
1689
+ return ret;
1690
+ }
1691
+
1692
+ ret = intel_link_power_down(sdw);
1693
+ if (ret) {
1694
+ dev_err(dev, "Link power down failed: %d", ret);
1695
+ return ret;
1696
+ }
1697
+
1698
+ intel_shim_wake(sdw, true);
1699
+ } else {
1700
+ dev_err(dev, "%s clock_stop_quirks %x unsupported\n",
1701
+ __func__, clock_stop_quirks);
1702
+ ret = -EINVAL;
1703
+ }
1704
+
1705
+ return ret;
1706
+}
1707
+
1708
+static int __maybe_unused intel_resume(struct device *dev)
1709
+{
1710
+ struct sdw_cdns *cdns = dev_get_drvdata(dev);
1711
+ struct sdw_intel *sdw = cdns_to_intel(cdns);
1712
+ struct sdw_bus *bus = &cdns->bus;
1713
+ int link_flags;
1714
+ bool multi_link;
1715
+ int ret;
1716
+
1717
+ if (bus->prop.hw_disabled) {
1718
+ dev_dbg(dev, "SoundWire master %d is disabled, ignoring\n",
1719
+ bus->link_id);
1720
+ return 0;
1721
+ }
1722
+
1723
+ link_flags = md_flags >> (bus->link_id * 8);
1724
+ multi_link = !(link_flags & SDW_INTEL_MASTER_DISABLE_MULTI_LINK);
1725
+
1726
+ if (pm_runtime_suspended(dev)) {
1727
+ dev_dbg(dev, "%s: pm_runtime status was suspended, forcing active\n", __func__);
1728
+
1729
+ /* follow required sequence from runtime_pm.rst */
1730
+ pm_runtime_disable(dev);
1731
+ pm_runtime_set_active(dev);
1732
+ pm_runtime_mark_last_busy(dev);
1733
+ pm_runtime_enable(dev);
1734
+
1735
+ link_flags = md_flags >> (bus->link_id * 8);
1736
+
1737
+ if (!(link_flags & SDW_INTEL_MASTER_DISABLE_PM_RUNTIME_IDLE))
1738
+ pm_runtime_idle(dev);
1739
+ }
1740
+
1741
+ ret = intel_init(sdw);
1742
+ if (ret) {
1743
+ dev_err(dev, "%s failed: %d", __func__, ret);
1744
+ return ret;
1745
+ }
1746
+
1747
+ /*
1748
+ * make sure all Slaves are tagged as UNATTACHED and provide
1749
+ * reason for reinitialization
1750
+ */
1751
+ sdw_clear_slave_status(bus, SDW_UNATTACH_REQUEST_MASTER_RESET);
1752
+
1753
+ ret = sdw_cdns_enable_interrupt(cdns, true);
1754
+ if (ret < 0) {
1755
+ dev_err(dev, "cannot enable interrupts during resume\n");
1756
+ return ret;
1757
+ }
1758
+
1759
+ /*
1760
+ * follow recommended programming flows to avoid timeouts when
1761
+ * gsync is enabled
1762
+ */
1763
+ if (multi_link)
1764
+ intel_shim_sync_arm(sdw);
1765
+
1766
+ ret = sdw_cdns_init(&sdw->cdns);
1767
+ if (ret < 0) {
1768
+ dev_err(dev, "unable to initialize Cadence IP during resume\n");
1769
+ return ret;
1770
+ }
1771
+
1772
+ ret = sdw_cdns_exit_reset(cdns);
1773
+ if (ret < 0) {
1774
+ dev_err(dev, "unable to exit bus reset sequence during resume\n");
1775
+ return ret;
1776
+ }
1777
+
1778
+ if (multi_link) {
1779
+ ret = intel_shim_sync_go(sdw);
1780
+ if (ret < 0) {
1781
+ dev_err(dev, "sync go failed during resume\n");
1782
+ return ret;
1783
+ }
1784
+ }
1785
+
1786
+ /*
1787
+ * after system resume, the pm_runtime suspend() may kick in
1788
+ * during the enumeration, before any children device force the
1789
+ * master device to remain active. Using pm_runtime_get()
1790
+ * routines is not really possible, since it'd prevent the
1791
+ * master from suspending.
1792
+ * A reasonable compromise is to update the pm_runtime
1793
+ * counters and delay the pm_runtime suspend by several
1794
+ * seconds, by when all enumeration should be complete.
1795
+ */
1796
+ pm_runtime_mark_last_busy(dev);
1797
+
1798
+ return ret;
1799
+}
1800
+
1801
+static int intel_resume_runtime(struct device *dev)
1802
+{
1803
+ struct sdw_cdns *cdns = dev_get_drvdata(dev);
1804
+ struct sdw_intel *sdw = cdns_to_intel(cdns);
1805
+ struct sdw_bus *bus = &cdns->bus;
1806
+ u32 clock_stop_quirks;
1807
+ bool clock_stop0;
1808
+ int link_flags;
1809
+ bool multi_link;
1810
+ int status;
1811
+ int ret;
1812
+
1813
+ if (bus->prop.hw_disabled) {
1814
+ dev_dbg(dev, "SoundWire master %d is disabled, ignoring\n",
1815
+ bus->link_id);
1816
+ return 0;
1817
+ }
1818
+
1819
+ link_flags = md_flags >> (bus->link_id * 8);
1820
+ multi_link = !(link_flags & SDW_INTEL_MASTER_DISABLE_MULTI_LINK);
1821
+
1822
+ clock_stop_quirks = sdw->link_res->clock_stop_quirks;
1823
+
1824
+ if (clock_stop_quirks & SDW_INTEL_CLK_STOP_TEARDOWN) {
1825
+ ret = intel_init(sdw);
1826
+ if (ret) {
1827
+ dev_err(dev, "%s failed: %d", __func__, ret);
1828
+ return ret;
1829
+ }
1830
+
1831
+ /*
1832
+ * make sure all Slaves are tagged as UNATTACHED and provide
1833
+ * reason for reinitialization
1834
+ */
1835
+ sdw_clear_slave_status(bus, SDW_UNATTACH_REQUEST_MASTER_RESET);
1836
+
1837
+ ret = sdw_cdns_enable_interrupt(cdns, true);
1838
+ if (ret < 0) {
1839
+ dev_err(dev, "cannot enable interrupts during resume\n");
1840
+ return ret;
1841
+ }
1842
+
1843
+ /*
1844
+ * follow recommended programming flows to avoid
1845
+ * timeouts when gsync is enabled
1846
+ */
1847
+ if (multi_link)
1848
+ intel_shim_sync_arm(sdw);
1849
+
1850
+ ret = sdw_cdns_init(&sdw->cdns);
1851
+ if (ret < 0) {
1852
+ dev_err(dev, "unable to initialize Cadence IP during resume\n");
1853
+ return ret;
1854
+ }
1855
+
1856
+ ret = sdw_cdns_exit_reset(cdns);
1857
+ if (ret < 0) {
1858
+ dev_err(dev, "unable to exit bus reset sequence during resume\n");
1859
+ return ret;
1860
+ }
1861
+
1862
+ if (multi_link) {
1863
+ ret = intel_shim_sync_go(sdw);
1864
+ if (ret < 0) {
1865
+ dev_err(dev, "sync go failed during resume\n");
1866
+ return ret;
1867
+ }
1868
+ }
1869
+ } else if (clock_stop_quirks & SDW_INTEL_CLK_STOP_BUS_RESET) {
1870
+ ret = intel_init(sdw);
1871
+ if (ret) {
1872
+ dev_err(dev, "%s failed: %d", __func__, ret);
1873
+ return ret;
1874
+ }
1875
+
1876
+ /*
1877
+ * An exception condition occurs for the CLK_STOP_BUS_RESET
1878
+ * case if one or more masters remain active. In this condition,
1879
+ * all the masters are powered on for they are in the same power
1880
+ * domain. Master can preserve its context for clock stop0, so
1881
+ * there is no need to clear slave status and reset bus.
1882
+ */
1883
+ clock_stop0 = sdw_cdns_is_clock_stop(&sdw->cdns);
1884
+
1885
+ if (!clock_stop0) {
1886
+
1887
+ /*
1888
+ * make sure all Slaves are tagged as UNATTACHED and
1889
+ * provide reason for reinitialization
1890
+ */
1891
+
1892
+ status = SDW_UNATTACH_REQUEST_MASTER_RESET;
1893
+ sdw_clear_slave_status(bus, status);
1894
+
1895
+ ret = sdw_cdns_enable_interrupt(cdns, true);
1896
+ if (ret < 0) {
1897
+ dev_err(dev, "cannot enable interrupts during resume\n");
1898
+ return ret;
1899
+ }
1900
+
1901
+ /*
1902
+ * follow recommended programming flows to avoid
1903
+ * timeouts when gsync is enabled
1904
+ */
1905
+ if (multi_link)
1906
+ intel_shim_sync_arm(sdw);
1907
+
1908
+ /*
1909
+ * Re-initialize the IP since it was powered-off
1910
+ */
1911
+ sdw_cdns_init(&sdw->cdns);
1912
+
1913
+ } else {
1914
+ ret = sdw_cdns_enable_interrupt(cdns, true);
1915
+ if (ret < 0) {
1916
+ dev_err(dev, "cannot enable interrupts during resume\n");
1917
+ return ret;
1918
+ }
1919
+ }
1920
+
1921
+ ret = sdw_cdns_clock_restart(cdns, !clock_stop0);
1922
+ if (ret < 0) {
1923
+ dev_err(dev, "unable to restart clock during resume\n");
1924
+ return ret;
1925
+ }
1926
+
1927
+ if (!clock_stop0) {
1928
+ ret = sdw_cdns_exit_reset(cdns);
1929
+ if (ret < 0) {
1930
+ dev_err(dev, "unable to exit bus reset sequence during resume\n");
1931
+ return ret;
1932
+ }
1933
+
1934
+ if (multi_link) {
1935
+ ret = intel_shim_sync_go(sdw);
1936
+ if (ret < 0) {
1937
+ dev_err(sdw->cdns.dev, "sync go failed during resume\n");
1938
+ return ret;
1939
+ }
1940
+ }
1941
+ }
1942
+ } else if (!clock_stop_quirks) {
1943
+
1944
+ clock_stop0 = sdw_cdns_is_clock_stop(&sdw->cdns);
1945
+ if (!clock_stop0)
1946
+ dev_err(dev, "%s invalid configuration, clock was not stopped", __func__);
1947
+
1948
+ ret = intel_init(sdw);
1949
+ if (ret) {
1950
+ dev_err(dev, "%s failed: %d", __func__, ret);
1951
+ return ret;
1952
+ }
1953
+
1954
+ ret = sdw_cdns_enable_interrupt(cdns, true);
1955
+ if (ret < 0) {
1956
+ dev_err(dev, "cannot enable interrupts during resume\n");
1957
+ return ret;
1958
+ }
1959
+
1960
+ ret = sdw_cdns_clock_restart(cdns, false);
1961
+ if (ret < 0) {
1962
+ dev_err(dev, "unable to resume master during resume\n");
1963
+ return ret;
1964
+ }
1965
+ } else {
1966
+ dev_err(dev, "%s clock_stop_quirks %x unsupported\n",
1967
+ __func__, clock_stop_quirks);
1968
+ ret = -EINVAL;
1969
+ }
1970
+
1971
+ return ret;
1972
+}
1973
+
1974
+#endif
1975
+
1976
+static const struct dev_pm_ops intel_pm = {
1977
+ SET_SYSTEM_SLEEP_PM_OPS(intel_suspend, intel_resume)
1978
+ SET_RUNTIME_PM_OPS(intel_suspend_runtime, intel_resume_runtime, NULL)
1979
+};
1980
+
1981
+static struct platform_driver sdw_intel_drv = {
1982
+ .probe = intel_master_probe,
1983
+ .remove = intel_master_remove,
1984
+ .driver = {
1985
+ .name = "intel-sdw",
1986
+ .pm = &intel_pm,
1987
+ }
8761988 };
8771989
8781990 module_platform_driver(sdw_intel_drv);
8791991
8801992 MODULE_LICENSE("Dual BSD/GPL");
881
-MODULE_ALIAS("platform:int-sdw");
1993
+MODULE_ALIAS("platform:intel-sdw");
8821994 MODULE_DESCRIPTION("Intel Soundwire Master Driver");