123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- This page describes the structures and procedures used by the cx2341x DMA
- engine.
- Introduction
- ============
- The cx2341x PCI interface is busmaster capable. This means it has a DMA
- engine to efficiently transfer large volumes of data between the card and main
- memory without requiring help from a CPU. Like most hardware, it must operate
- on contiguous physical memory. This is difficult to come by in large quantities
- on virtual memory machines.
- Therefore, it also supports a technique called "scatter-gather". The card can
- transfer multiple buffers in one operation. Instead of allocating one large
- contiguous buffer, the driver can allocate several smaller buffers.
- In practice, I've seen the average transfer to be roughly 80K, but transfers
- above 128K were not uncommon, particularly at startup. The 128K figure is
- important, because that is the largest block that the kernel can normally
- allocate. Even still, 128K blocks are hard to come by, so the driver writer is
- urged to choose a smaller block size and learn the scatter-gather technique.
- Mailbox #10 is reserved for DMA transfer information.
- Note: the hardware expects little-endian data ('intel format').
- Flow
- ====
- This section describes, in general, the order of events when handling DMA
- transfers. Detailed information follows this section.
- - The card raises the Encoder interrupt.
- - The driver reads the transfer type, offset and size from Mailbox #10.
- - The driver constructs the scatter-gather array from enough free dma buffers
- to cover the size.
- - The driver schedules the DMA transfer via the ScheduleDMAtoHost API call.
- - The card raises the DMA Complete interrupt.
- - The driver checks the DMA status register for any errors.
- - The driver post-processes the newly transferred buffers.
- NOTE! It is possible that the Encoder and DMA Complete interrupts get raised
- simultaneously. (End of the last, start of the next, etc.)
- Mailbox #10
- ===========
- The Flags, Command, Return Value and Timeout fields are ignored.
- Name: Mailbox #10
- Results[0]: Type: 0: MPEG.
- Results[1]: Offset: The position relative to the card's memory space.
- Results[2]: Size: The exact number of bytes to transfer.
- My speculation is that since the StartCapture API has a capture type of "RAW"
- available, that the type field will have other values that correspond to YUV
- and PCM data.
- Scatter-Gather Array
- ====================
- The scatter-gather array is a contiguously allocated block of memory that
- tells the card the source and destination of each data-block to transfer.
- Card "addresses" are derived from the offset supplied by Mailbox #10. Host
- addresses are the physical memory location of the target DMA buffer.
- Each S-G array element is a struct of three 32-bit words. The first word is
- the source address, the second is the destination address. Both take up the
- entire 32 bits. The lowest 18 bits of the third word is the transfer byte
- count. The high-bit of the third word is the "last" flag. The last-flag tells
- the card to raise the DMA_DONE interrupt. From hard personal experience, if
- you forget to set this bit, the card will still "work" but the stream will
- most likely get corrupted.
- The transfer count must be a multiple of 256. Therefore, the driver will need
- to track how much data in the target buffer is valid and deal with it
- accordingly.
- Array Element:
- - 32-bit Source Address
- - 32-bit Destination Address
- - 14-bit reserved (high bit is the last flag)
- - 18-bit byte count
- DMA Transfer Status
- ===================
- Register 0x0004 holds the DMA Transfer Status:
- Bit
- 0 read completed
- 1 write completed
- 2 DMA read error
- 3 DMA write error
- 4 Scatter-Gather array error
|