hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/soundwire/intel_init.c
....@@ -8,10 +8,17 @@
88 */
99
1010 #include <linux/acpi.h>
11
+#include <linux/export.h>
12
+#include <linux/interrupt.h>
13
+#include <linux/io.h>
14
+#include <linux/module.h>
1115 #include <linux/platform_device.h>
16
+#include <linux/pm_runtime.h>
1217 #include <linux/soundwire/sdw_intel.h>
18
+#include "cadence_master.h"
1319 #include "intel.h"
1420
21
+#define SDW_LINK_TYPE 4 /* from Intel ACPI documentation */
1522 #define SDW_MAX_LINKS 4
1623 #define SDW_SHIM_LCAP 0x0
1724 #define SDW_SHIM_BASE 0x2C000
....@@ -19,183 +26,459 @@
1926 #define SDW_LINK_BASE 0x30000
2027 #define SDW_LINK_SIZE 0x10000
2128
22
-struct sdw_link_data {
23
- struct sdw_intel_link_res res;
24
- struct platform_device *pdev;
25
-};
29
+static int ctrl_link_mask;
30
+module_param_named(sdw_link_mask, ctrl_link_mask, int, 0444);
31
+MODULE_PARM_DESC(sdw_link_mask, "Intel link mask (one bit per link)");
2632
27
-struct sdw_intel_ctx {
28
- int count;
29
- struct sdw_link_data *links;
30
-};
31
-
32
-static int sdw_intel_cleanup_pdev(struct sdw_intel_ctx *ctx)
33
+static bool is_link_enabled(struct fwnode_handle *fw_node, int i)
3334 {
34
- struct sdw_link_data *link = ctx->links;
35
+ struct fwnode_handle *link;
36
+ char name[32];
37
+ u32 quirk_mask = 0;
38
+
39
+ /* Find master handle */
40
+ snprintf(name, sizeof(name),
41
+ "mipi-sdw-link-%d-subproperties", i);
42
+
43
+ link = fwnode_get_named_child_node(fw_node, name);
44
+ if (!link)
45
+ return false;
46
+
47
+ fwnode_property_read_u32(link,
48
+ "intel-quirk-mask",
49
+ &quirk_mask);
50
+
51
+ if (quirk_mask & SDW_INTEL_QUIRK_MASK_BUS_DISABLE)
52
+ return false;
53
+
54
+ return true;
55
+}
56
+
57
+static int sdw_intel_cleanup(struct sdw_intel_ctx *ctx)
58
+{
59
+ struct sdw_intel_link_res *link = ctx->links;
60
+ u32 link_mask;
3561 int i;
3662
3763 if (!link)
3864 return 0;
3965
40
- for (i = 0; i < ctx->count; i++) {
41
- if (link->pdev)
42
- platform_device_unregister(link->pdev);
43
- link++;
44
- }
66
+ link_mask = ctx->link_mask;
4567
46
- kfree(ctx->links);
47
- ctx->links = NULL;
68
+ for (i = 0; i < ctx->count; i++, link++) {
69
+ if (!(link_mask & BIT(i)))
70
+ continue;
71
+
72
+ if (link->pdev) {
73
+ pm_runtime_disable(&link->pdev->dev);
74
+ platform_device_unregister(link->pdev);
75
+ }
76
+
77
+ if (!link->clock_stop_quirks)
78
+ pm_runtime_put_noidle(link->dev);
79
+ }
4880
4981 return 0;
5082 }
5183
52
-static struct sdw_intel_ctx
53
-*sdw_intel_add_controller(struct sdw_intel_res *res)
84
+static int
85
+sdw_intel_scan_controller(struct sdw_intel_acpi_info *info)
5486 {
55
- struct platform_device_info pdevinfo;
56
- struct platform_device *pdev;
57
- struct sdw_link_data *link;
58
- struct sdw_intel_ctx *ctx;
5987 struct acpi_device *adev;
6088 int ret, i;
6189 u8 count;
62
- u32 caps;
6390
64
- if (acpi_bus_get_device(res->handle, &adev))
65
- return NULL;
91
+ if (acpi_bus_get_device(info->handle, &adev))
92
+ return -EINVAL;
6693
6794 /* Found controller, find links supported */
6895 count = 0;
6996 ret = fwnode_property_read_u8_array(acpi_fwnode_handle(adev),
70
- "mipi-sdw-master-count", &count, 1);
97
+ "mipi-sdw-master-count", &count, 1);
7198
72
- /* Don't fail on error, continue and use hw value */
99
+ /*
100
+ * In theory we could check the number of links supported in
101
+ * hardware, but in that step we cannot assume SoundWire IP is
102
+ * powered.
103
+ *
104
+ * In addition, if the BIOS doesn't even provide this
105
+ * 'master-count' property then all the inits based on link
106
+ * masks will fail as well.
107
+ *
108
+ * We will check the hardware capabilities in the startup() step
109
+ */
110
+
73111 if (ret) {
74112 dev_err(&adev->dev,
75113 "Failed to read mipi-sdw-master-count: %d\n", ret);
76
- count = SDW_MAX_LINKS;
114
+ return -EINVAL;
77115 }
78
-
79
- /* Check SNDWLCAP.LCOUNT */
80
- caps = ioread32(res->mmio_base + SDW_SHIM_BASE + SDW_SHIM_LCAP);
81
-
82
- /* Check HW supported vs property value and use min of two */
83
- count = min_t(u8, caps, count);
84116
85117 /* Check count is within bounds */
86118 if (count > SDW_MAX_LINKS) {
87119 dev_err(&adev->dev, "Link count %d exceeds max %d\n",
88
- count, SDW_MAX_LINKS);
89
- return NULL;
120
+ count, SDW_MAX_LINKS);
121
+ return -EINVAL;
90122 }
91123
124
+ if (!count) {
125
+ dev_warn(&adev->dev, "No SoundWire links detected\n");
126
+ return -EINVAL;
127
+ }
128
+ dev_dbg(&adev->dev, "ACPI reports %d SDW Link devices\n", count);
129
+
130
+ info->count = count;
131
+ info->link_mask = 0;
132
+
133
+ for (i = 0; i < count; i++) {
134
+ if (ctrl_link_mask && !(ctrl_link_mask & BIT(i))) {
135
+ dev_dbg(&adev->dev,
136
+ "Link %d masked, will not be enabled\n", i);
137
+ continue;
138
+ }
139
+
140
+ if (!is_link_enabled(acpi_fwnode_handle(adev), i)) {
141
+ dev_dbg(&adev->dev,
142
+ "Link %d not selected in firmware\n", i);
143
+ continue;
144
+ }
145
+
146
+ info->link_mask |= BIT(i);
147
+ }
148
+
149
+ return 0;
150
+}
151
+
152
+#define HDA_DSP_REG_ADSPIC2 (0x10)
153
+#define HDA_DSP_REG_ADSPIS2 (0x14)
154
+#define HDA_DSP_REG_ADSPIC2_SNDW BIT(5)
155
+
156
+/**
157
+ * sdw_intel_enable_irq() - enable/disable Intel SoundWire IRQ
158
+ * @mmio_base: The mmio base of the control register
159
+ * @enable: true if enable
160
+ */
161
+void sdw_intel_enable_irq(void __iomem *mmio_base, bool enable)
162
+{
163
+ u32 val;
164
+
165
+ val = readl(mmio_base + HDA_DSP_REG_ADSPIC2);
166
+
167
+ if (enable)
168
+ val |= HDA_DSP_REG_ADSPIC2_SNDW;
169
+ else
170
+ val &= ~HDA_DSP_REG_ADSPIC2_SNDW;
171
+
172
+ writel(val, mmio_base + HDA_DSP_REG_ADSPIC2);
173
+}
174
+EXPORT_SYMBOL_NS(sdw_intel_enable_irq, SOUNDWIRE_INTEL_INIT);
175
+
176
+irqreturn_t sdw_intel_thread(int irq, void *dev_id)
177
+{
178
+ struct sdw_intel_ctx *ctx = dev_id;
179
+ struct sdw_intel_link_res *link;
180
+
181
+ list_for_each_entry(link, &ctx->link_list, list)
182
+ sdw_cdns_irq(irq, link->cdns);
183
+
184
+ sdw_intel_enable_irq(ctx->mmio_base, true);
185
+ return IRQ_HANDLED;
186
+}
187
+EXPORT_SYMBOL_NS(sdw_intel_thread, SOUNDWIRE_INTEL_INIT);
188
+
189
+static struct sdw_intel_ctx
190
+*sdw_intel_probe_controller(struct sdw_intel_res *res)
191
+{
192
+ struct platform_device_info pdevinfo;
193
+ struct platform_device *pdev;
194
+ struct sdw_intel_link_res *link;
195
+ struct sdw_intel_ctx *ctx;
196
+ struct acpi_device *adev;
197
+ struct sdw_slave *slave;
198
+ struct list_head *node;
199
+ struct sdw_bus *bus;
200
+ u32 link_mask;
201
+ int num_slaves = 0;
202
+ int count;
203
+ int i;
204
+
205
+ if (!res)
206
+ return NULL;
207
+
208
+ if (acpi_bus_get_device(res->handle, &adev))
209
+ return NULL;
210
+
211
+ if (!res->count)
212
+ return NULL;
213
+
214
+ count = res->count;
92215 dev_dbg(&adev->dev, "Creating %d SDW Link devices\n", count);
93216
94
- ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
217
+ ctx = devm_kzalloc(&adev->dev, sizeof(*ctx), GFP_KERNEL);
95218 if (!ctx)
96219 return NULL;
97220
98221 ctx->count = count;
99
- ctx->links = kcalloc(ctx->count, sizeof(*ctx->links), GFP_KERNEL);
222
+ ctx->links = devm_kcalloc(&adev->dev, ctx->count,
223
+ sizeof(*ctx->links), GFP_KERNEL);
100224 if (!ctx->links)
101
- goto link_err;
225
+ return NULL;
226
+
227
+ ctx->count = count;
228
+ ctx->mmio_base = res->mmio_base;
229
+ ctx->link_mask = res->link_mask;
230
+ ctx->handle = res->handle;
231
+ mutex_init(&ctx->shim_lock);
102232
103233 link = ctx->links;
234
+ link_mask = ctx->link_mask;
235
+
236
+ INIT_LIST_HEAD(&ctx->link_list);
104237
105238 /* Create SDW Master devices */
106
- for (i = 0; i < count; i++) {
239
+ for (i = 0; i < count; i++, link++) {
240
+ if (!(link_mask & BIT(i))) {
241
+ dev_dbg(&adev->dev,
242
+ "Link %d masked, will not be enabled\n", i);
243
+ continue;
244
+ }
107245
108
- link->res.irq = res->irq;
109
- link->res.registers = res->mmio_base + SDW_LINK_BASE
110
- + (SDW_LINK_SIZE * i);
111
- link->res.shim = res->mmio_base + SDW_SHIM_BASE;
112
- link->res.alh = res->mmio_base + SDW_ALH_BASE;
246
+ link->mmio_base = res->mmio_base;
247
+ link->registers = res->mmio_base + SDW_LINK_BASE
248
+ + (SDW_LINK_SIZE * i);
249
+ link->shim = res->mmio_base + SDW_SHIM_BASE;
250
+ link->alh = res->mmio_base + SDW_ALH_BASE;
113251
114
- link->res.ops = res->ops;
115
- link->res.arg = res->arg;
252
+ link->ops = res->ops;
253
+ link->dev = res->dev;
254
+
255
+ link->clock_stop_quirks = res->clock_stop_quirks;
256
+ link->shim_lock = &ctx->shim_lock;
257
+ link->shim_mask = &ctx->shim_mask;
258
+ link->link_mask = link_mask;
116259
117260 memset(&pdevinfo, 0, sizeof(pdevinfo));
118261
119262 pdevinfo.parent = res->parent;
120
- pdevinfo.name = "int-sdw";
263
+ pdevinfo.name = "intel-sdw";
121264 pdevinfo.id = i;
122265 pdevinfo.fwnode = acpi_fwnode_handle(adev);
123
- pdevinfo.data = &link->res;
124
- pdevinfo.size_data = sizeof(link->res);
266
+ pdevinfo.data = link;
267
+ pdevinfo.size_data = sizeof(*link);
125268
126269 pdev = platform_device_register_full(&pdevinfo);
127270 if (IS_ERR(pdev)) {
128271 dev_err(&adev->dev,
129272 "platform device creation failed: %ld\n",
130273 PTR_ERR(pdev));
131
- goto pdev_err;
274
+ goto err;
132275 }
133
-
134276 link->pdev = pdev;
135
- link++;
277
+ link->cdns = platform_get_drvdata(pdev);
278
+
279
+ list_add_tail(&link->list, &ctx->link_list);
280
+ bus = &link->cdns->bus;
281
+ /* Calculate number of slaves */
282
+ list_for_each(node, &bus->slaves)
283
+ num_slaves++;
284
+ }
285
+
286
+ ctx->ids = devm_kcalloc(&adev->dev, num_slaves,
287
+ sizeof(*ctx->ids), GFP_KERNEL);
288
+ if (!ctx->ids)
289
+ goto err;
290
+
291
+ ctx->num_slaves = num_slaves;
292
+ i = 0;
293
+ list_for_each_entry(link, &ctx->link_list, list) {
294
+ bus = &link->cdns->bus;
295
+ list_for_each_entry(slave, &bus->slaves, node) {
296
+ ctx->ids[i].id = slave->id;
297
+ ctx->ids[i].link_id = bus->link_id;
298
+ i++;
299
+ }
136300 }
137301
138302 return ctx;
139303
140
-pdev_err:
141
- sdw_intel_cleanup_pdev(ctx);
142
-link_err:
143
- kfree(ctx);
304
+err:
305
+ ctx->count = i;
306
+ sdw_intel_cleanup(ctx);
144307 return NULL;
145308 }
146309
147
-static acpi_status sdw_intel_acpi_cb(acpi_handle handle, u32 level,
148
- void *cdata, void **return_value)
310
+static int
311
+sdw_intel_startup_controller(struct sdw_intel_ctx *ctx)
149312 {
150
- struct sdw_intel_res *res = cdata;
151313 struct acpi_device *adev;
314
+ struct sdw_intel_link_res *link;
315
+ u32 caps;
316
+ u32 link_mask;
317
+ int i;
318
+
319
+ if (acpi_bus_get_device(ctx->handle, &adev))
320
+ return -EINVAL;
321
+
322
+ /* Check SNDWLCAP.LCOUNT */
323
+ caps = ioread32(ctx->mmio_base + SDW_SHIM_BASE + SDW_SHIM_LCAP);
324
+ caps &= GENMASK(2, 0);
325
+
326
+ /* Check HW supported vs property value */
327
+ if (caps < ctx->count) {
328
+ dev_err(&adev->dev,
329
+ "BIOS master count is larger than hardware capabilities\n");
330
+ return -EINVAL;
331
+ }
332
+
333
+ if (!ctx->links)
334
+ return -EINVAL;
335
+
336
+ link = ctx->links;
337
+ link_mask = ctx->link_mask;
338
+
339
+ /* Startup SDW Master devices */
340
+ for (i = 0; i < ctx->count; i++, link++) {
341
+ if (!(link_mask & BIT(i)))
342
+ continue;
343
+
344
+ intel_master_startup(link->pdev);
345
+
346
+ if (!link->clock_stop_quirks) {
347
+ /*
348
+ * we need to prevent the parent PCI device
349
+ * from entering pm_runtime suspend, so that
350
+ * power rails to the SoundWire IP are not
351
+ * turned off.
352
+ */
353
+ pm_runtime_get_noresume(link->dev);
354
+ }
355
+ }
356
+
357
+ return 0;
358
+}
359
+
360
+static acpi_status sdw_intel_acpi_cb(acpi_handle handle, u32 level,
361
+ void *cdata, void **return_value)
362
+{
363
+ struct sdw_intel_acpi_info *info = cdata;
364
+ struct acpi_device *adev;
365
+ acpi_status status;
366
+ u64 adr;
367
+
368
+ status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
369
+ if (ACPI_FAILURE(status))
370
+ return AE_OK; /* keep going */
152371
153372 if (acpi_bus_get_device(handle, &adev)) {
154373 pr_err("%s: Couldn't find ACPI handle\n", __func__);
155374 return AE_NOT_FOUND;
156375 }
157376
158
- res->handle = handle;
159
- return AE_OK;
377
+ info->handle = handle;
378
+
379
+ /*
380
+ * On some Intel platforms, multiple children of the HDAS
381
+ * device can be found, but only one of them is the SoundWire
382
+ * controller. The SNDW device is always exposed with
383
+ * Name(_ADR, 0x40000000), with bits 31..28 representing the
384
+ * SoundWire link so filter accordingly
385
+ */
386
+ if (FIELD_GET(GENMASK(31, 28), adr) != SDW_LINK_TYPE)
387
+ return AE_OK; /* keep going */
388
+
389
+ /* device found, stop namespace walk */
390
+ return AE_CTRL_TERMINATE;
160391 }
161392
162393 /**
163
- * sdw_intel_init() - SoundWire Intel init routine
394
+ * sdw_intel_acpi_scan() - SoundWire Intel init routine
164395 * @parent_handle: ACPI parent handle
165
- * @res: resource data
396
+ * @info: description of what firmware/DSDT tables expose
166397 *
167
- * This scans the namespace and creates SoundWire link controller devices
168
- * based on the info queried.
398
+ * This scans the namespace and queries firmware to figure out which
399
+ * links to enable. A follow-up use of sdw_intel_probe() and
400
+ * sdw_intel_startup() is required for creation of devices and bus
401
+ * startup
169402 */
170
-void *sdw_intel_init(acpi_handle *parent_handle, struct sdw_intel_res *res)
403
+int sdw_intel_acpi_scan(acpi_handle *parent_handle,
404
+ struct sdw_intel_acpi_info *info)
171405 {
172406 acpi_status status;
173407
408
+ info->handle = NULL;
174409 status = acpi_walk_namespace(ACPI_TYPE_DEVICE,
175
- parent_handle, 1,
176
- sdw_intel_acpi_cb,
177
- NULL, res, NULL);
178
- if (ACPI_FAILURE(status))
179
- return NULL;
410
+ parent_handle, 1,
411
+ sdw_intel_acpi_cb,
412
+ NULL, info, NULL);
413
+ if (ACPI_FAILURE(status) || info->handle == NULL)
414
+ return -ENODEV;
180415
181
- return sdw_intel_add_controller(res);
416
+ return sdw_intel_scan_controller(info);
182417 }
183
-EXPORT_SYMBOL(sdw_intel_init);
418
+EXPORT_SYMBOL_NS(sdw_intel_acpi_scan, SOUNDWIRE_INTEL_INIT);
184419
185420 /**
421
+ * sdw_intel_probe() - SoundWire Intel probe routine
422
+ * @res: resource data
423
+ *
424
+ * This registers a platform device for each Master handled by the controller,
425
+ * and SoundWire Master and Slave devices will be created by the platform
426
+ * device probe. All the information necessary is stored in the context, and
427
+ * the res argument pointer can be freed after this step.
428
+ * This function will be called after sdw_intel_acpi_scan() by SOF probe.
429
+ */
430
+struct sdw_intel_ctx
431
+*sdw_intel_probe(struct sdw_intel_res *res)
432
+{
433
+ return sdw_intel_probe_controller(res);
434
+}
435
+EXPORT_SYMBOL_NS(sdw_intel_probe, SOUNDWIRE_INTEL_INIT);
436
+
437
+/**
438
+ * sdw_intel_startup() - SoundWire Intel startup
439
+ * @ctx: SoundWire context allocated in the probe
440
+ *
441
+ * Startup Intel SoundWire controller. This function will be called after
442
+ * Intel Audio DSP is powered up.
443
+ */
444
+int sdw_intel_startup(struct sdw_intel_ctx *ctx)
445
+{
446
+ return sdw_intel_startup_controller(ctx);
447
+}
448
+EXPORT_SYMBOL_NS(sdw_intel_startup, SOUNDWIRE_INTEL_INIT);
449
+/**
186450 * sdw_intel_exit() - SoundWire Intel exit
187
- * @arg: callback context
451
+ * @ctx: SoundWire context allocated in the probe
188452 *
189453 * Delete the controller instances created and cleanup
190454 */
191
-void sdw_intel_exit(void *arg)
455
+void sdw_intel_exit(struct sdw_intel_ctx *ctx)
192456 {
193
- struct sdw_intel_ctx *ctx = arg;
194
-
195
- sdw_intel_cleanup_pdev(ctx);
196
- kfree(ctx);
457
+ sdw_intel_cleanup(ctx);
197458 }
198
-EXPORT_SYMBOL(sdw_intel_exit);
459
+EXPORT_SYMBOL_NS(sdw_intel_exit, SOUNDWIRE_INTEL_INIT);
460
+
461
+void sdw_intel_process_wakeen_event(struct sdw_intel_ctx *ctx)
462
+{
463
+ struct sdw_intel_link_res *link;
464
+ u32 link_mask;
465
+ int i;
466
+
467
+ if (!ctx->links)
468
+ return;
469
+
470
+ link = ctx->links;
471
+ link_mask = ctx->link_mask;
472
+
473
+ /* Startup SDW Master devices */
474
+ for (i = 0; i < ctx->count; i++, link++) {
475
+ if (!(link_mask & BIT(i)))
476
+ continue;
477
+
478
+ intel_master_process_wakeen_event(link->pdev);
479
+ }
480
+}
481
+EXPORT_SYMBOL_NS(sdw_intel_process_wakeen_event, SOUNDWIRE_INTEL_INIT);
199482
200483 MODULE_LICENSE("Dual BSD/GPL");
201484 MODULE_DESCRIPTION("Intel Soundwire Init Library");