blob: 61950b83b8c9f86bf12260bb331da8d660145adb [file] [log] [blame]
Thomas Gleixner457c8992019-05-19 13:08:55 +01001// SPDX-License-Identifier: GPL-2.0-only
Takashi Iwai14752412015-04-14 12:15:47 +02002/*
3 * HD-audio controller helpers
4 */
5
6#include <linux/kernel.h>
7#include <linux/delay.h>
8#include <linux/export.h>
9#include <sound/core.h>
10#include <sound/hdaudio.h>
11#include <sound/hda_register.h>
12
13/* clear CORB read pointer properly */
14static void azx_clear_corbrp(struct hdac_bus *bus)
15{
16 int timeout;
17
18 for (timeout = 1000; timeout > 0; timeout--) {
19 if (snd_hdac_chip_readw(bus, CORBRP) & AZX_CORBRP_RST)
20 break;
21 udelay(1);
22 }
23 if (timeout <= 0)
24 dev_err(bus->dev, "CORB reset timeout#1, CORBRP = %d\n",
25 snd_hdac_chip_readw(bus, CORBRP));
26
27 snd_hdac_chip_writew(bus, CORBRP, 0);
28 for (timeout = 1000; timeout > 0; timeout--) {
29 if (snd_hdac_chip_readw(bus, CORBRP) == 0)
30 break;
31 udelay(1);
32 }
33 if (timeout <= 0)
34 dev_err(bus->dev, "CORB reset timeout#2, CORBRP = %d\n",
35 snd_hdac_chip_readw(bus, CORBRP));
36}
37
38/**
39 * snd_hdac_bus_init_cmd_io - set up CORB/RIRB buffers
40 * @bus: HD-audio core bus
41 */
42void snd_hdac_bus_init_cmd_io(struct hdac_bus *bus)
43{
Yu Zhaob61749a2018-09-11 15:14:04 -060044 WARN_ON_ONCE(!bus->rb.area);
45
Takashi Iwai14752412015-04-14 12:15:47 +020046 spin_lock_irq(&bus->reg_lock);
47 /* CORB set up */
48 bus->corb.addr = bus->rb.addr;
49 bus->corb.buf = (__le32 *)bus->rb.area;
50 snd_hdac_chip_writel(bus, CORBLBASE, (u32)bus->corb.addr);
51 snd_hdac_chip_writel(bus, CORBUBASE, upper_32_bits(bus->corb.addr));
52
53 /* set the corb size to 256 entries (ULI requires explicitly) */
54 snd_hdac_chip_writeb(bus, CORBSIZE, 0x02);
55 /* set the corb write pointer to 0 */
56 snd_hdac_chip_writew(bus, CORBWP, 0);
57
58 /* reset the corb hw read pointer */
59 snd_hdac_chip_writew(bus, CORBRP, AZX_CORBRP_RST);
60 if (!bus->corbrp_self_clear)
61 azx_clear_corbrp(bus);
62
63 /* enable corb dma */
64 snd_hdac_chip_writeb(bus, CORBCTL, AZX_CORBCTL_RUN);
65
66 /* RIRB set up */
67 bus->rirb.addr = bus->rb.addr + 2048;
68 bus->rirb.buf = (__le32 *)(bus->rb.area + 2048);
69 bus->rirb.wp = bus->rirb.rp = 0;
70 memset(bus->rirb.cmds, 0, sizeof(bus->rirb.cmds));
71 snd_hdac_chip_writel(bus, RIRBLBASE, (u32)bus->rirb.addr);
72 snd_hdac_chip_writel(bus, RIRBUBASE, upper_32_bits(bus->rirb.addr));
73
74 /* set the rirb size to 256 entries (ULI requires explicitly) */
75 snd_hdac_chip_writeb(bus, RIRBSIZE, 0x02);
76 /* reset the rirb hw write pointer */
77 snd_hdac_chip_writew(bus, RIRBWP, AZX_RIRBWP_RST);
78 /* set N=1, get RIRB response interrupt for new entry */
79 snd_hdac_chip_writew(bus, RINTCNT, 1);
80 /* enable rirb dma and response irq */
81 snd_hdac_chip_writeb(bus, RIRBCTL, AZX_RBCTL_DMA_EN | AZX_RBCTL_IRQ_EN);
Rander Wang7c2b3622019-07-01 15:46:30 +080082 /* Accept unsolicited responses */
83 snd_hdac_chip_updatel(bus, GCTL, AZX_GCTL_UNSOL, AZX_GCTL_UNSOL);
Takashi Iwai14752412015-04-14 12:15:47 +020084 spin_unlock_irq(&bus->reg_lock);
85}
86EXPORT_SYMBOL_GPL(snd_hdac_bus_init_cmd_io);
87
Jeeja KP38b19ed2016-05-05 11:24:43 +053088/* wait for cmd dmas till they are stopped */
89static void hdac_wait_for_cmd_dmas(struct hdac_bus *bus)
90{
91 unsigned long timeout;
92
93 timeout = jiffies + msecs_to_jiffies(100);
94 while ((snd_hdac_chip_readb(bus, RIRBCTL) & AZX_RBCTL_DMA_EN)
95 && time_before(jiffies, timeout))
96 udelay(10);
97
98 timeout = jiffies + msecs_to_jiffies(100);
99 while ((snd_hdac_chip_readb(bus, CORBCTL) & AZX_CORBCTL_RUN)
100 && time_before(jiffies, timeout))
101 udelay(10);
102}
103
Takashi Iwai14752412015-04-14 12:15:47 +0200104/**
105 * snd_hdac_bus_stop_cmd_io - clean up CORB/RIRB buffers
106 * @bus: HD-audio core bus
107 */
108void snd_hdac_bus_stop_cmd_io(struct hdac_bus *bus)
109{
110 spin_lock_irq(&bus->reg_lock);
111 /* disable ringbuffer DMAs */
112 snd_hdac_chip_writeb(bus, RIRBCTL, 0);
113 snd_hdac_chip_writeb(bus, CORBCTL, 0);
Jeeja KP96001372017-05-10 11:51:58 +0530114 spin_unlock_irq(&bus->reg_lock);
115
Jeeja KP38b19ed2016-05-05 11:24:43 +0530116 hdac_wait_for_cmd_dmas(bus);
Jeeja KP96001372017-05-10 11:51:58 +0530117
118 spin_lock_irq(&bus->reg_lock);
Takashi Iwai14752412015-04-14 12:15:47 +0200119 /* disable unsolicited responses */
120 snd_hdac_chip_updatel(bus, GCTL, AZX_GCTL_UNSOL, 0);
121 spin_unlock_irq(&bus->reg_lock);
122}
123EXPORT_SYMBOL_GPL(snd_hdac_bus_stop_cmd_io);
124
125static unsigned int azx_command_addr(u32 cmd)
126{
127 unsigned int addr = cmd >> 28;
128
129 if (snd_BUG_ON(addr >= HDA_MAX_CODECS))
130 addr = 0;
131 return addr;
132}
133
134/**
135 * snd_hdac_bus_send_cmd - send a command verb via CORB
136 * @bus: HD-audio core bus
137 * @val: encoded verb value to send
138 *
139 * Returns zero for success or a negative error code.
140 */
141int snd_hdac_bus_send_cmd(struct hdac_bus *bus, unsigned int val)
142{
143 unsigned int addr = azx_command_addr(val);
144 unsigned int wp, rp;
145
146 spin_lock_irq(&bus->reg_lock);
147
148 bus->last_cmd[azx_command_addr(val)] = val;
149
150 /* add command to corb */
151 wp = snd_hdac_chip_readw(bus, CORBWP);
152 if (wp == 0xffff) {
153 /* something wrong, controller likely turned to D3 */
154 spin_unlock_irq(&bus->reg_lock);
155 return -EIO;
156 }
157 wp++;
158 wp %= AZX_MAX_CORB_ENTRIES;
159
160 rp = snd_hdac_chip_readw(bus, CORBRP);
161 if (wp == rp) {
162 /* oops, it's full */
163 spin_unlock_irq(&bus->reg_lock);
164 return -EAGAIN;
165 }
166
167 bus->rirb.cmds[addr]++;
168 bus->corb.buf[wp] = cpu_to_le32(val);
169 snd_hdac_chip_writew(bus, CORBWP, wp);
170
171 spin_unlock_irq(&bus->reg_lock);
172
173 return 0;
174}
175EXPORT_SYMBOL_GPL(snd_hdac_bus_send_cmd);
176
177#define AZX_RIRB_EX_UNSOL_EV (1<<4)
178
179/**
180 * snd_hdac_bus_update_rirb - retrieve RIRB entries
181 * @bus: HD-audio core bus
182 *
183 * Usually called from interrupt handler.
184 */
185void snd_hdac_bus_update_rirb(struct hdac_bus *bus)
186{
187 unsigned int rp, wp;
188 unsigned int addr;
189 u32 res, res_ex;
190
191 wp = snd_hdac_chip_readw(bus, RIRBWP);
192 if (wp == 0xffff) {
193 /* something wrong, controller likely turned to D3 */
194 return;
195 }
196
197 if (wp == bus->rirb.wp)
198 return;
199 bus->rirb.wp = wp;
200
201 while (bus->rirb.rp != wp) {
202 bus->rirb.rp++;
203 bus->rirb.rp %= AZX_MAX_RIRB_ENTRIES;
204
205 rp = bus->rirb.rp << 1; /* an RIRB entry is 8-bytes */
206 res_ex = le32_to_cpu(bus->rirb.buf[rp + 1]);
207 res = le32_to_cpu(bus->rirb.buf[rp]);
208 addr = res_ex & 0xf;
209 if (addr >= HDA_MAX_CODECS) {
210 dev_err(bus->dev,
211 "spurious response %#x:%#x, rp = %d, wp = %d",
212 res, res_ex, bus->rirb.rp, wp);
213 snd_BUG();
214 } else if (res_ex & AZX_RIRB_EX_UNSOL_EV)
215 snd_hdac_bus_queue_event(bus, res, res_ex);
216 else if (bus->rirb.cmds[addr]) {
217 bus->rirb.res[addr] = res;
218 bus->rirb.cmds[addr]--;
Takashi Iwai88452da2019-12-10 15:57:27 +0100219 if (!bus->rirb.cmds[addr] &&
220 waitqueue_active(&bus->rirb_wq))
221 wake_up(&bus->rirb_wq);
Takashi Iwai14752412015-04-14 12:15:47 +0200222 } else {
223 dev_err_ratelimited(bus->dev,
224 "spurious response %#x:%#x, last cmd=%#08x\n",
225 res, res_ex, bus->last_cmd[addr]);
226 }
227 }
228}
229EXPORT_SYMBOL_GPL(snd_hdac_bus_update_rirb);
230
231/**
232 * snd_hdac_bus_get_response - receive a response via RIRB
233 * @bus: HD-audio core bus
234 * @addr: codec address
235 * @res: pointer to store the value, NULL when not needed
236 *
237 * Returns zero if a value is read, or a negative error code.
238 */
239int snd_hdac_bus_get_response(struct hdac_bus *bus, unsigned int addr,
240 unsigned int *res)
241{
242 unsigned long timeout;
243 unsigned long loopcounter;
Takashi Iwai89698ed2019-12-12 20:11:00 +0100244 wait_queue_entry_t wait;
Takashi Iwai14752412015-04-14 12:15:47 +0200245
Takashi Iwai89698ed2019-12-12 20:11:00 +0100246 init_wait_entry(&wait, 0);
Takashi Iwai14752412015-04-14 12:15:47 +0200247 timeout = jiffies + msecs_to_jiffies(1000);
248
249 for (loopcounter = 0;; loopcounter++) {
Bard Liaoee8829d2019-05-30 04:59:00 +0800250 spin_lock_irq(&bus->reg_lock);
Takashi Iwai89698ed2019-12-12 20:11:00 +0100251 if (!bus->polling_mode)
252 prepare_to_wait(&bus->rirb_wq, &wait,
253 TASK_UNINTERRUPTIBLE);
Bard Liao5e13cf62019-05-27 00:58:35 +0800254 if (bus->polling_mode)
255 snd_hdac_bus_update_rirb(bus);
Takashi Iwai14752412015-04-14 12:15:47 +0200256 if (!bus->rirb.cmds[addr]) {
257 if (res)
258 *res = bus->rirb.res[addr]; /* the last value */
Takashi Iwai89698ed2019-12-12 20:11:00 +0100259 if (!bus->polling_mode)
260 finish_wait(&bus->rirb_wq, &wait);
Takashi Iwai14752412015-04-14 12:15:47 +0200261 spin_unlock_irq(&bus->reg_lock);
262 return 0;
263 }
264 spin_unlock_irq(&bus->reg_lock);
265 if (time_after(jiffies, timeout))
266 break;
Takashi Iwai89698ed2019-12-12 20:11:00 +0100267 if (!bus->polling_mode) {
268 schedule_timeout(msecs_to_jiffies(2));
269 } else if (loopcounter > 3000) {
Takashi Iwai14752412015-04-14 12:15:47 +0200270 msleep(2); /* temporary workaround */
Takashi Iwai89698ed2019-12-12 20:11:00 +0100271 } else {
Takashi Iwai14752412015-04-14 12:15:47 +0200272 udelay(10);
273 cond_resched();
274 }
275 }
276
Takashi Iwai89698ed2019-12-12 20:11:00 +0100277 if (!bus->polling_mode)
278 finish_wait(&bus->rirb_wq, &wait);
279
Takashi Iwai14752412015-04-14 12:15:47 +0200280 return -EIO;
281}
282EXPORT_SYMBOL_GPL(snd_hdac_bus_get_response);
283
Vinod Koul6720b382016-08-04 15:46:00 +0530284#define HDAC_MAX_CAPS 10
285/**
286 * snd_hdac_bus_parse_capabilities - parse capability structure
287 * @bus: the pointer to bus object
288 *
289 * Returns 0 if successful, or a negative error code.
290 */
291int snd_hdac_bus_parse_capabilities(struct hdac_bus *bus)
292{
293 unsigned int cur_cap;
294 unsigned int offset;
295 unsigned int counter = 0;
296
B, Jayachandranccfdf9f2017-03-24 23:10:24 +0530297 offset = snd_hdac_chip_readw(bus, LLCH);
Vinod Koul6720b382016-08-04 15:46:00 +0530298
299 /* Lets walk the linked capabilities list */
300 do {
Takashi Iwai2c1f8132017-03-29 08:27:15 +0200301 cur_cap = _snd_hdac_chip_readl(bus, offset);
Vinod Koul6720b382016-08-04 15:46:00 +0530302
303 dev_dbg(bus->dev, "Capability version: 0x%x\n",
304 (cur_cap & AZX_CAP_HDR_VER_MASK) >> AZX_CAP_HDR_VER_OFF);
305
306 dev_dbg(bus->dev, "HDA capability ID: 0x%x\n",
307 (cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF);
308
Takashi Iwai098a0a62017-10-17 16:38:55 +0200309 if (cur_cap == -1) {
310 dev_dbg(bus->dev, "Invalid capability reg read\n");
311 break;
312 }
313
Vinod Koul6720b382016-08-04 15:46:00 +0530314 switch ((cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF) {
315 case AZX_ML_CAP_ID:
316 dev_dbg(bus->dev, "Found ML capability\n");
317 bus->mlcap = bus->remap_addr + offset;
318 break;
319
320 case AZX_GTS_CAP_ID:
321 dev_dbg(bus->dev, "Found GTS capability offset=%x\n", offset);
322 bus->gtscap = bus->remap_addr + offset;
323 break;
324
325 case AZX_PP_CAP_ID:
326 /* PP capability found, the Audio DSP is present */
327 dev_dbg(bus->dev, "Found PP capability offset=%x\n", offset);
328 bus->ppcap = bus->remap_addr + offset;
329 break;
330
331 case AZX_SPB_CAP_ID:
332 /* SPIB capability found, handler function */
333 dev_dbg(bus->dev, "Found SPB capability\n");
334 bus->spbcap = bus->remap_addr + offset;
335 break;
336
337 case AZX_DRSM_CAP_ID:
338 /* DMA resume capability found, handler function */
339 dev_dbg(bus->dev, "Found DRSM capability\n");
340 bus->drsmcap = bus->remap_addr + offset;
341 break;
342
343 default:
Rakesh Ughrejab676da72017-10-24 18:26:47 +0530344 dev_err(bus->dev, "Unknown capability %d\n", cur_cap);
345 cur_cap = 0;
Vinod Koul6720b382016-08-04 15:46:00 +0530346 break;
347 }
348
349 counter++;
350
351 if (counter > HDAC_MAX_CAPS) {
352 dev_err(bus->dev, "We exceeded HDAC capabilities!!!\n");
353 break;
354 }
355
356 /* read the offset of next capability */
357 offset = cur_cap & AZX_CAP_HDR_NXT_PTR_MASK;
358
359 } while (offset);
360
361 return 0;
362}
363EXPORT_SYMBOL_GPL(snd_hdac_bus_parse_capabilities);
364
Takashi Iwai14752412015-04-14 12:15:47 +0200365/*
366 * Lowlevel interface
367 */
368
369/**
370 * snd_hdac_bus_enter_link_reset - enter link reset
371 * @bus: HD-audio core bus
372 *
373 * Enter to the link reset state.
374 */
375void snd_hdac_bus_enter_link_reset(struct hdac_bus *bus)
376{
377 unsigned long timeout;
378
379 /* reset controller */
380 snd_hdac_chip_updatel(bus, GCTL, AZX_GCTL_RESET, 0);
381
382 timeout = jiffies + msecs_to_jiffies(100);
383 while ((snd_hdac_chip_readb(bus, GCTL) & AZX_GCTL_RESET) &&
384 time_before(jiffies, timeout))
385 usleep_range(500, 1000);
386}
387EXPORT_SYMBOL_GPL(snd_hdac_bus_enter_link_reset);
388
389/**
390 * snd_hdac_bus_exit_link_reset - exit link reset
391 * @bus: HD-audio core bus
392 *
393 * Exit from the link reset state.
394 */
395void snd_hdac_bus_exit_link_reset(struct hdac_bus *bus)
396{
397 unsigned long timeout;
398
Keyon Jie081e01f2019-01-09 16:20:50 +0800399 snd_hdac_chip_updateb(bus, GCTL, AZX_GCTL_RESET, AZX_GCTL_RESET);
Takashi Iwai14752412015-04-14 12:15:47 +0200400
401 timeout = jiffies + msecs_to_jiffies(100);
402 while (!snd_hdac_chip_readb(bus, GCTL) && time_before(jiffies, timeout))
403 usleep_range(500, 1000);
404}
405EXPORT_SYMBOL_GPL(snd_hdac_bus_exit_link_reset);
406
407/* reset codec link */
Yu Zhao75383f82018-09-11 15:15:16 -0600408int snd_hdac_bus_reset_link(struct hdac_bus *bus, bool full_reset)
Takashi Iwai14752412015-04-14 12:15:47 +0200409{
410 if (!full_reset)
411 goto skip_reset;
412
413 /* clear STATESTS */
414 snd_hdac_chip_writew(bus, STATESTS, STATESTS_INT_MASK);
415
416 /* reset controller */
417 snd_hdac_bus_enter_link_reset(bus);
418
419 /* delay for >= 100us for codec PLL to settle per spec
420 * Rev 0.9 section 5.5.1
421 */
422 usleep_range(500, 1000);
423
424 /* Bring controller out of reset */
425 snd_hdac_bus_exit_link_reset(bus);
426
427 /* Brent Chartrand said to wait >= 540us for codecs to initialize */
428 usleep_range(1000, 1200);
429
430 skip_reset:
431 /* check to see if controller is ready */
432 if (!snd_hdac_chip_readb(bus, GCTL)) {
Yu Zhao75383f82018-09-11 15:15:16 -0600433 dev_dbg(bus->dev, "controller not ready!\n");
Takashi Iwai14752412015-04-14 12:15:47 +0200434 return -EBUSY;
435 }
436
Takashi Iwai14752412015-04-14 12:15:47 +0200437 /* detect codecs */
438 if (!bus->codec_mask) {
439 bus->codec_mask = snd_hdac_chip_readw(bus, STATESTS);
440 dev_dbg(bus->dev, "codec_mask = 0x%lx\n", bus->codec_mask);
441 }
442
443 return 0;
444}
Yu Zhao75383f82018-09-11 15:15:16 -0600445EXPORT_SYMBOL_GPL(snd_hdac_bus_reset_link);
Takashi Iwai14752412015-04-14 12:15:47 +0200446
447/* enable interrupts */
448static void azx_int_enable(struct hdac_bus *bus)
449{
450 /* enable controller CIE and GIE */
Keyon Jie081e01f2019-01-09 16:20:50 +0800451 snd_hdac_chip_updatel(bus, INTCTL,
452 AZX_INT_CTRL_EN | AZX_INT_GLOBAL_EN,
453 AZX_INT_CTRL_EN | AZX_INT_GLOBAL_EN);
Takashi Iwai14752412015-04-14 12:15:47 +0200454}
455
456/* disable interrupts */
457static void azx_int_disable(struct hdac_bus *bus)
458{
459 struct hdac_stream *azx_dev;
460
461 /* disable interrupts in stream descriptor */
462 list_for_each_entry(azx_dev, &bus->stream_list, list)
463 snd_hdac_stream_updateb(azx_dev, SD_CTL, SD_INT_MASK, 0);
464
465 /* disable SIE for all streams */
466 snd_hdac_chip_writeb(bus, INTCTL, 0);
467
468 /* disable controller CIE and GIE */
469 snd_hdac_chip_updatel(bus, INTCTL, AZX_INT_CTRL_EN | AZX_INT_GLOBAL_EN, 0);
470}
471
472/* clear interrupts */
473static void azx_int_clear(struct hdac_bus *bus)
474{
475 struct hdac_stream *azx_dev;
476
477 /* clear stream status */
478 list_for_each_entry(azx_dev, &bus->stream_list, list)
479 snd_hdac_stream_writeb(azx_dev, SD_STS, SD_INT_MASK);
480
481 /* clear STATESTS */
482 snd_hdac_chip_writew(bus, STATESTS, STATESTS_INT_MASK);
483
484 /* clear rirb status */
485 snd_hdac_chip_writeb(bus, RIRBSTS, RIRB_INT_MASK);
486
487 /* clear int status */
488 snd_hdac_chip_writel(bus, INTSTS, AZX_INT_CTRL_EN | AZX_INT_ALL_STREAM);
489}
490
491/**
492 * snd_hdac_bus_init_chip - reset and start the controller registers
493 * @bus: HD-audio core bus
494 * @full_reset: Do full reset
495 */
496bool snd_hdac_bus_init_chip(struct hdac_bus *bus, bool full_reset)
497{
498 if (bus->chip_init)
499 return false;
500
501 /* reset controller */
Yu Zhao75383f82018-09-11 15:15:16 -0600502 snd_hdac_bus_reset_link(bus, full_reset);
Takashi Iwai14752412015-04-14 12:15:47 +0200503
Yu Zhaob61749a2018-09-11 15:14:04 -0600504 /* clear interrupts */
Takashi Iwai14752412015-04-14 12:15:47 +0200505 azx_int_clear(bus);
Takashi Iwai14752412015-04-14 12:15:47 +0200506
507 /* initialize the codec command I/O */
508 snd_hdac_bus_init_cmd_io(bus);
509
Yu Zhaob61749a2018-09-11 15:14:04 -0600510 /* enable interrupts after CORB/RIRB buffers are initialized above */
511 azx_int_enable(bus);
512
Takashi Iwai14752412015-04-14 12:15:47 +0200513 /* program the position buffer */
514 if (bus->use_posbuf && bus->posbuf.addr) {
515 snd_hdac_chip_writel(bus, DPLBASE, (u32)bus->posbuf.addr);
516 snd_hdac_chip_writel(bus, DPUBASE, upper_32_bits(bus->posbuf.addr));
517 }
518
519 bus->chip_init = true;
520 return true;
521}
522EXPORT_SYMBOL_GPL(snd_hdac_bus_init_chip);
523
524/**
525 * snd_hdac_bus_stop_chip - disable the whole IRQ and I/Os
526 * @bus: HD-audio core bus
527 */
528void snd_hdac_bus_stop_chip(struct hdac_bus *bus)
529{
530 if (!bus->chip_init)
531 return;
532
533 /* disable interrupts */
534 azx_int_disable(bus);
535 azx_int_clear(bus);
536
537 /* disable CORB/RIRB */
538 snd_hdac_bus_stop_cmd_io(bus);
539
540 /* disable position buffer */
541 if (bus->posbuf.addr) {
542 snd_hdac_chip_writel(bus, DPLBASE, 0);
543 snd_hdac_chip_writel(bus, DPUBASE, 0);
544 }
545
546 bus->chip_init = false;
547}
548EXPORT_SYMBOL_GPL(snd_hdac_bus_stop_chip);
549
550/**
551 * snd_hdac_bus_handle_stream_irq - interrupt handler for streams
552 * @bus: HD-audio core bus
553 * @status: INTSTS register value
554 * @ask: callback to be called for woken streams
Takashi Iwai473f4142016-02-23 15:54:47 +0100555 *
556 * Returns the bits of handled streams, or zero if no stream is handled.
Takashi Iwai14752412015-04-14 12:15:47 +0200557 */
Takashi Iwai473f4142016-02-23 15:54:47 +0100558int snd_hdac_bus_handle_stream_irq(struct hdac_bus *bus, unsigned int status,
Takashi Iwai14752412015-04-14 12:15:47 +0200559 void (*ack)(struct hdac_bus *,
560 struct hdac_stream *))
561{
562 struct hdac_stream *azx_dev;
563 u8 sd_status;
Takashi Iwai473f4142016-02-23 15:54:47 +0100564 int handled = 0;
Takashi Iwai14752412015-04-14 12:15:47 +0200565
566 list_for_each_entry(azx_dev, &bus->stream_list, list) {
567 if (status & azx_dev->sd_int_sta_mask) {
568 sd_status = snd_hdac_stream_readb(azx_dev, SD_STS);
569 snd_hdac_stream_writeb(azx_dev, SD_STS, SD_INT_MASK);
Takashi Iwai473f4142016-02-23 15:54:47 +0100570 handled |= 1 << azx_dev->index;
Takashi Iwai14752412015-04-14 12:15:47 +0200571 if (!azx_dev->substream || !azx_dev->running ||
572 !(sd_status & SD_INT_COMPLETE))
573 continue;
574 if (ack)
575 ack(bus, azx_dev);
576 }
577 }
Takashi Iwai473f4142016-02-23 15:54:47 +0100578 return handled;
Takashi Iwai14752412015-04-14 12:15:47 +0200579}
580EXPORT_SYMBOL_GPL(snd_hdac_bus_handle_stream_irq);
Jeeja KP304dad32015-04-12 18:06:13 +0530581
582/**
583 * snd_hdac_bus_alloc_stream_pages - allocate BDL and other buffers
584 * @bus: HD-audio core bus
585 *
586 * Call this after assigning the all streams.
587 * Returns zero for success, or a negative error code.
588 */
589int snd_hdac_bus_alloc_stream_pages(struct hdac_bus *bus)
590{
591 struct hdac_stream *s;
592 int num_streams = 0;
Takashi Iwai619a1f12019-08-07 20:02:31 +0200593 int dma_type = bus->dma_type ? bus->dma_type : SNDRV_DMA_TYPE_DEV;
Jeeja KP304dad32015-04-12 18:06:13 +0530594 int err;
595
596 list_for_each_entry(s, &bus->stream_list, list) {
597 /* allocate memory for the BDL for each stream */
Takashi Iwai619a1f12019-08-07 20:02:31 +0200598 err = snd_dma_alloc_pages(dma_type, bus->dev,
599 BDL_SIZE, &s->bdl);
Jeeja KP304dad32015-04-12 18:06:13 +0530600 num_streams++;
601 if (err < 0)
602 return -ENOMEM;
603 }
604
605 if (WARN_ON(!num_streams))
606 return -EINVAL;
607 /* allocate memory for the position buffer */
Takashi Iwai619a1f12019-08-07 20:02:31 +0200608 err = snd_dma_alloc_pages(dma_type, bus->dev,
609 num_streams * 8, &bus->posbuf);
Jeeja KP304dad32015-04-12 18:06:13 +0530610 if (err < 0)
611 return -ENOMEM;
612 list_for_each_entry(s, &bus->stream_list, list)
613 s->posbuf = (__le32 *)(bus->posbuf.area + s->index * 8);
614
615 /* single page (at least 4096 bytes) must suffice for both ringbuffes */
Takashi Iwai619a1f12019-08-07 20:02:31 +0200616 return snd_dma_alloc_pages(dma_type, bus->dev, PAGE_SIZE, &bus->rb);
Jeeja KP304dad32015-04-12 18:06:13 +0530617}
618EXPORT_SYMBOL_GPL(snd_hdac_bus_alloc_stream_pages);
619
620/**
621 * snd_hdac_bus_free_stream_pages - release BDL and other buffers
622 * @bus: HD-audio core bus
623 */
624void snd_hdac_bus_free_stream_pages(struct hdac_bus *bus)
625{
626 struct hdac_stream *s;
627
628 list_for_each_entry(s, &bus->stream_list, list) {
629 if (s->bdl.area)
Takashi Iwai619a1f12019-08-07 20:02:31 +0200630 snd_dma_free_pages(&s->bdl);
Jeeja KP304dad32015-04-12 18:06:13 +0530631 }
632
633 if (bus->rb.area)
Takashi Iwai619a1f12019-08-07 20:02:31 +0200634 snd_dma_free_pages(&bus->rb);
Jeeja KP304dad32015-04-12 18:06:13 +0530635 if (bus->posbuf.area)
Takashi Iwai619a1f12019-08-07 20:02:31 +0200636 snd_dma_free_pages(&bus->posbuf);
Jeeja KP304dad32015-04-12 18:06:13 +0530637}
638EXPORT_SYMBOL_GPL(snd_hdac_bus_free_stream_pages);