[SOLVED] HD Audio Stream DMA engine not working
Posted: Fri Oct 27, 2017 1:36 am
Hello!
I am currently implementing HD Audio driver in my Thinkpad X220i. I have managed to make CORB and RIRB working well. However, I have been stuck in making stream DMA engine work for about two weeks. The problem is that DMA position is 0 and no interrupt has been fired, whereas Link Position in Buffer (LPIB) is changing.
Here is what I did:
1. enumerate PCI devices and find hda controller, Memory space and bus master bits are set in PCI Command register.
2. enable MSI support
3. reset controller
4. setup CORB and RIRB
5. enable interrupt
6. use verbs to find the correct DAC and pin widgets nodes.
7. reset output stream
8. initialize BDLE
*(PULONG64)(bdle+i*16) = 0x1000000+i*0x1000; //data buffer
*(PULONG)(bdle+i*16+8) = 0x800; // length
*(PULONG)(bdle+i*16+0xc) = 1; //IOC
9. set stream id 1 in sd control
10. set stream format 0x4011
11. set CBL 0x800*0x70
12. set LVI 0x6f
13. set BDL Pointer
14. set DMA Position
15. set afg, DAC and pin widgets powerstate
16. set format, stream id and channel for the DAC
17. unmute each widgets
18. turn on HP node
19. enable Interrupt On Completion and start stream
I have dumped some of the registers value in my timer isr. SDLPIB is changing and SDSTS is always 0x20.
GCAP:4401 SSYNC:00000000
SDCTL:0014001E SDSTS:20 SDLPIB:(0000DD34,00015734,00001138...) SDCBL:00038000 SDLVI:006F SDFIFOS:00C0 SDFMT:4011 SDBDPL:03000000 SDBDPU:00000000
Did I set things up correctly or maybe I forget something?
Thank You!
I am currently implementing HD Audio driver in my Thinkpad X220i. I have managed to make CORB and RIRB working well. However, I have been stuck in making stream DMA engine work for about two weeks. The problem is that DMA position is 0 and no interrupt has been fired, whereas Link Position in Buffer (LPIB) is changing.
Here is what I did:
1. enumerate PCI devices and find hda controller, Memory space and bus master bits are set in PCI Command register.
2. enable MSI support
3. reset controller
4. setup CORB and RIRB
5. enable interrupt
6. use verbs to find the correct DAC and pin widgets nodes.
7. reset output stream
8. initialize BDLE
*(PULONG64)(bdle+i*16) = 0x1000000+i*0x1000; //data buffer
*(PULONG)(bdle+i*16+8) = 0x800; // length
*(PULONG)(bdle+i*16+0xc) = 1; //IOC
9. set stream id 1 in sd control
10. set stream format 0x4011
11. set CBL 0x800*0x70
12. set LVI 0x6f
13. set BDL Pointer
14. set DMA Position
15. set afg, DAC and pin widgets powerstate
16. set format, stream id and channel for the DAC
17. unmute each widgets
18. turn on HP node
19. enable Interrupt On Completion and start stream
I have dumped some of the registers value in my timer isr. SDLPIB is changing and SDSTS is always 0x20.
GCAP:4401 SSYNC:00000000
SDCTL:0014001E SDSTS:20 SDLPIB:(0000DD34,00015734,00001138...) SDCBL:00038000 SDLVI:006F SDFIFOS:00C0 SDFMT:4011 SDBDPL:03000000 SDBDPU:00000000
Did I set things up correctly or maybe I forget something?
Thank You!