On Fri, 03 Feb 2017 20:47:55 +0100, Pierre-Louis Bossart wrote:
On 2/3/17 10:44 AM, Takashi Iwai wrote:
This is again a big rewrite of the driver; now it touches the code to process PCM stream transfers.
The most fundamental change is that now the driver supports more than four periods. Instead of keeping the same index between the ring buffers (from A to D) and the PCM buffer periods, now we keep difference indices for both. Also, for the cases with less periods than four, we track the head index, too. That is, we now have four indices: ringbuf_head, pcm_head, ringbuf_filled, and pcm_filled.
Well that's not completely right. The DMA can only generate an interrupt once the buffer you submit was played, and with 4 descriptors you can't have more than 4 points where interrupts are generated. If you program different values in different descriptors then the notion of periodic hardware interrupts will be lost.
There is a standard trick such as used for ICH or other drivers. With this kind of hardware, the address to be written to each buffer descriptor can be changed dynamically while streaming. (BTW, on some hardware like HD-audio, it's not allowed, but HD-audio has a larger table, so it doesn't matter.)
That is, each BD maps to each period on the PCM buffer, and it moves there. A picture like below would illustrate:
At time=0
PCM | 0 | 1 | 2 | 3 | 4 | 5 | .... |n-1| BD | A | B | C | D |
At time=1 (period elapsed)
PCM | 0 | 1 | 2 | 3 | 4 | 5 | .... |n-1| BD | B | C | D | A |
At time=2
PCM | 0 | 1 | 2 | 3 | 4 | 5 | .... |n-1| BD | C | D | A | B |
and so on.
For the case periods < 4, it works other way round:
t=0 PCM | 0 | 1 | BD | A | B | - | - |
t=1 PCM | 1 | 0 | BD | - | B | C | - |
t=2 PCM | 0 | 1 | BD | - | - | C | D |
By this flexibility, we can use even dmix, which requires 16 periods as default.
The buffer size could be up to 20bit, so it's set to that value. But the pre-allocation is limited to 128k as default. It's because the chip requires the continuous pages (unfortunately no-SG possible), thus we don't want too much continuous pages.
No, that's not true. You need contiguous regions for each descriptor, but the entire buffer doesn't need to be contiguous.
Yeah, in theory, it's possible, but it actually doesn't help much with only four descriptors. Usually SG buffer management is per page. And if we fix the size per descriptor, it won't fit what user-space apps want in most cases. So practically it mandates the continuous pages.
Takashi