The LCD controller has two fully-independent DMA channels. These are used to transfer frame buffer data (relating to each frame displayed) from off-chip memory to the LCD’s palette RAM and the input FIFO. DMA channel 1 is used for single-panel display mode, and for the upper screen in dual-panel mode. DMA channel 2 is used exclusively for the lower screen in dual-panel mode. Both DMA channels contain a base address pointer and current address pointer register.
The LCD’s DMA engine has the highest priority on the AMBA bus as a bus master in order to prevent other bus masters from starving the LCD screen.
The two DMA channels use a separate set of base address and current address pointers. The user must initialize the base address pointer registers before enabling the LCD. Once enabled, the base address is transferred to the current address pointer.
After the LCD is enabled, the input FIFO requests a DMA transfer and the DMA makes a four-word burst access from off-chip memory using the address contained within the current address pointer. The pointer is incremented by four (bytes) each time a word is read from memory (ie. bit 2 of the pointer is incremented). Each of the four words from the burst are loaded into the top of the input FIFO. The LCD then takes one value at a time from the bottom of the FIFO, unpacks it into individual encoded pixel values and uses the values to index into the palette. Each time the input FIFO contains four empty entries, another DMA request is made and another four-word burst is performed. To calculate the frame buffer end address, the DMA controller uses the values programmed in the pixels-per-line (PPL), Lines Per Panel (LPP), LCD Dual Panel (LcdDP), LCD Black and White (LcdBW) and Mono Eight Bit (M8B) bit-fields within the control registers, as well as the bits-per-pixel (BPP) field contained within the first entry of the palette buffer from the off-chip frame buffer. When the current address pointer reaches the calculated end of buffer address, the value in the base address pointer is again transferred to the current address pointer.