[alsa-devel] [PATCH 4/4] ALSA: x86: Refactor PCM process engine

Takashi Iwai tiwai at suse.de
Fri Feb 3 21:11:05 CET 2017


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


More information about the Alsa-devel mailing list