1 /******************************************************************************
3 * Copyright (C) 2010 - 2017 Xilinx, Inc. All rights reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * Use of the Software is limited solely to applications:
16 * (a) running on a Xilinx device, or
17 * (b) that interact with a Xilinx device through a bus or interconnect.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
24 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 * Except as contained in this notice, the name of the Xilinx shall not be used
28 * in advertising or otherwise to promote the sale, use or other dealings in
29 * this Software without prior written authorization from Xilinx.
32 *******************************************************************************/
33 /*****************************************************************************/
38 * This file contains the implementation of the interface functions of the
39 * XDpDma driver. Refer to xdpdma.h for detailed information.
44 * MODIFICATION HISTORY:
46 * Ver Who Date Changes
47 * ---- ----- -------- ----------------------------------------------------
48 * 1.0 aad 04/12/16 Initial release.
50 *****************************************************************************/
52 /***************************** Include Files **********************************/
56 /************************** Constant Definitions ******************************/
57 #define XDPDMA_CH_OFFSET 0x100
58 #define XDPDMA_WAIT_TIMEOUT 10000
60 #define XDPDMA_AUDIO_ALIGNMENT 128
62 #define XDPDMA_VIDEO_CHANNEL0 0
63 #define XDPDMA_VIDEO_CHANNEL1 1
64 #define XDPDMA_VIDEO_CHANNEL2 2
65 #define XDPDMA_GRAPHICS_CHANNEL 3
66 #define XDPDMA_AUDIO_CHANNEL0 4
67 #define XDPDMA_AUDIO_CHANNEL1 5
69 #define XDPDMA_DESC_PREAMBLE 0xA5
70 #define XDPDMA_DESC_IGNR_DONE 0x400
71 #define XDPDMA_DESC_UPDATE 0x200
72 #define XDPDMA_DESC_COMP_INTR 0x100
73 #define XDPDMA_DESC_LAST_FRAME 0x200000
74 #define XDPDMA_DESC_DONE_SHIFT 31
75 #define XDPDMA_QOS_MIN 4
76 #define XDPDMA_QOS_MAX 11
78 /*************************************************************************/
81 * This function returns the number of outstanding transactions on a given
84 * @param InstancePtr is a pointer to the driver instance.
85 * @param ChannelNum is the channel number on which the operation is
88 * @return Number of pending transactions.
92 * **************************************************************************/
93 static int XDpDma_GetPendingTransaction(XDpDma *InstancePtr, u32 ChannelNum)
96 RegVal = XDpDma_ReadReg(InstancePtr->Config.BaseAddr,
97 XDPDMA_CH0_STATUS + 0x100 * ChannelNum);
98 return (RegVal & XDPDMA_CH_STATUS_OTRAN_CNT_MASK);
101 /*************************************************************************/
104 * This function waits until the outstanding transactions are completed.
106 * @param InstancePtr is a pointer to the driver instance.
107 * @param ChannelNum is the channel number on which the operation is
110 * @return XST_SUCCESS when all the pending transactions are complete
112 * XST_FAILURE if timeout occurs before pending transactions are
117 * **************************************************************************/
118 static int XDpDma_WaitPendingTransaction(XDpDma *InstancePtr, u8 ChannelNum)
120 /* Verify arguments. */
121 Xil_AssertNonvoid(InstancePtr != NULL);
122 Xil_AssertNonvoid(ChannelNum <= XDPDMA_AUDIO_CHANNEL1);
127 Count = XDpDma_GetPendingTransaction(InstancePtr, ChannelNum);
129 } while((Timeout != XDPDMA_WAIT_TIMEOUT) && Count);
131 if(Timeout == XDPDMA_WAIT_TIMEOUT) {
138 /*************************************************************************/
141 * This function controls the hardware channels of the DPDMA.
144 * @param InstancePtr is a pointer to the driver instance.
145 * @param ChannelNum is the physical channel number of the DPDMA.
146 * @param ChannelState is an enum of type XDpDma_ChannelState.
148 * @return XST_SUCCESS when the mentioned channel is enabled successfully.
149 * XST_FAILURE when the mentioned channel fails to be enabled.
153 * **************************************************************************/
154 static int XDpDma_ConfigChannelState(XDpDma *InstancePtr, u8 ChannelNum,
155 XDpDma_ChannelState Enable)
160 /* Verify arguments. */
161 Xil_AssertNonvoid(InstancePtr != NULL);
162 Xil_AssertNonvoid(ChannelNum <= XDPDMA_AUDIO_CHANNEL1);
164 Mask = XDPDMA_CH_CNTL_EN_MASK | XDPDMA_CH_CNTL_PAUSE_MASK;
167 RegVal = XDPDMA_CH_CNTL_EN_MASK;
170 XDpDma_ConfigChannelState(InstancePtr, ChannelNum,
172 Status = XDpDma_WaitPendingTransaction(InstancePtr,
174 if(Status == XST_FAILURE) {
178 RegVal = XDPDMA_DISABLE;
179 Mask = XDPDMA_CH_CNTL_EN_MASK;
182 Status = XDpDma_ConfigChannelState(InstancePtr,
185 if(Status == XST_FAILURE) {
192 RegVal = XDPDMA_PAUSE;
195 XDpDma_ReadModifyWrite(InstancePtr->Config.BaseAddr,
196 XDPDMA_CH0_CNTL + XDPDMA_CH_OFFSET * ChannelNum,
201 /*************************************************************************/
204 * This function updates the descriptor that is not currently active on a
205 * Video/Graphics channel.
207 * @param InstancePtr is a pointer to the driver instance.
208 * @param Channel is a pointer to the channel on which the operation is
211 * @return Descriptor for next operation.
215 * **************************************************************************/
216 static XDpDma_Descriptor *XDpDma_UpdateVideoDescriptor(XDpDma_Channel *Channel)
218 if(Channel->Current == NULL) {
219 Channel->Current = &Channel->Descriptor0;
221 else if(Channel->Current == &Channel->Descriptor0) {
222 Channel->Current = &Channel->Descriptor1;
224 else if(Channel->Current == &Channel->Descriptor1) {
225 Channel->Current = &Channel->Descriptor0;
227 return Channel->Current;
230 /*************************************************************************/
232 * This function programs the address of the descriptor about to be active
234 * @param InstancePtr is a pointer to the DPDMA instance.
235 * @param Channel is an enum of the channel for which the descriptor
236 * address is to be set.
238 * @return Descriptor for next operation.
242 * **************************************************************************/
243 static void XDpDma_SetDescriptorAddress(XDpDma *InstancePtr, u8 ChannelNum)
247 Xil_AssertVoid(ChannelNum <= XDPDMA_AUDIO_CHANNEL1);
248 AddrOffset = XDPDMA_CH0_DSCR_STRT_ADDR +
249 (XDPDMA_CH_OFFSET * ChannelNum);
250 AddrEOffset = XDPDMA_CH0_DSCR_STRT_ADDRE +
251 (XDPDMA_CH_OFFSET * ChannelNum);
253 XDpDma_Descriptor *Descriptor = NULL;
255 case XDPDMA_VIDEO_CHANNEL0:
256 Descriptor = InstancePtr->Video.Channel[ChannelNum].Current;
258 case XDPDMA_VIDEO_CHANNEL1:
259 Descriptor = InstancePtr->Video.Channel[ChannelNum].Current;
261 case XDPDMA_VIDEO_CHANNEL2:
262 Descriptor = InstancePtr->Video.Channel[ChannelNum].Current;
264 case XDPDMA_GRAPHICS_CHANNEL:
265 Descriptor = InstancePtr->Gfx.Channel.Current;
267 case XDPDMA_AUDIO_CHANNEL0:
268 Descriptor = InstancePtr->Audio[0].Current;
270 case XDPDMA_AUDIO_CHANNEL1:
271 Descriptor = InstancePtr->Audio[1].Current;
275 XDpDma_WriteReg(InstancePtr->Config.BaseAddr, AddrEOffset,
276 (INTPTR) Descriptor >> 32);
277 XDpDma_WriteReg(InstancePtr->Config.BaseAddr, AddrOffset,
278 (INTPTR) Descriptor);
281 /*************************************************************************/
284 * This functions sets the Audio Descriptor for Data Transfer.
286 * @param CurrDesc is a pointer to the descriptor to be initialized
287 * @param DataSize is the payload size of the buffer to be transferred
288 * @param BuffAddr is the payload address
294 * **************************************************************************/
295 static void XDpDma_SetupAudioDescriptor(XDpDma_Descriptor *CurrDesc,
296 u64 DataSize, u64 BuffAddr,
297 XDpDma_Descriptor *NextDesc)
299 Xil_AssertVoid(CurrDesc != NULL);
300 Xil_AssertVoid(DataSize != 0);
301 Xil_AssertVoid(BuffAddr != 0);
303 if(NextDesc == NULL) {
304 CurrDesc->Control = XDPDMA_DESC_PREAMBLE |
305 XDPDMA_DESC_UPDATE | XDPDMA_DESC_IGNR_DONE |
306 XDPDMA_DESC_COMP_INTR;
310 CurrDesc->Control = XDPDMA_DESC_PREAMBLE |
311 XDPDMA_DESC_UPDATE | XDPDMA_DESC_IGNR_DONE;
313 CurrDesc->DSCR_ID = 0;
314 CurrDesc->XFER_SIZE = DataSize;
315 CurrDesc->LINE_SIZE_STRIDE = 0;
316 CurrDesc->LSB_Timestamp = 0;
317 CurrDesc->MSB_Timestamp = 0;
318 CurrDesc->ADDR_EXT = ((BuffAddr >> XDPDMA_DESCRIPTOR_SRC_ADDR_WIDTH) <<
319 XDPDMA_DESCRIPTOR_ADDR_EXT_SRC_ADDR_EXT_SHIFT) |
320 ((INTPTR) NextDesc >>
321 XDPDMA_DESCRIPTOR_NEXT_DESR_WIDTH);
322 CurrDesc->NEXT_DESR = (INTPTR) NextDesc;
323 CurrDesc->SRC_ADDR = BuffAddr;
326 /*************************************************************************/
329 * This functions retrieves the configuration for this DPDMA driver and
330 * fills in the InstancePtr->Config structure.
332 * @param InstancePtr is a pointer to the driver instance.
333 * @param ConfigPtr is a pointer to the configuration structure that will
334 * be used to copy the settings from.
340 * **************************************************************************/
341 void XDpDma_CfgInitialize(XDpDma *InstancePtr, XDpDma_Config *CfgPtr)
343 InstancePtr->Config.DeviceId = CfgPtr->DeviceId;
344 InstancePtr->Config.BaseAddr = CfgPtr->BaseAddr;
346 InstancePtr->Video.Channel[XDPDMA_VIDEO_CHANNEL0].Current = NULL;
347 InstancePtr->Video.Channel[XDPDMA_VIDEO_CHANNEL1].Current = NULL;
348 InstancePtr->Video.Channel[XDPDMA_VIDEO_CHANNEL2].Current = NULL;
349 InstancePtr->Video.TriggerStatus = XDPDMA_TRIGGER_DONE;
350 InstancePtr->Video.VideoInfo = NULL;
351 InstancePtr->Video.FrameBuffer[XDPDMA_VIDEO_CHANNEL0] = NULL;
352 InstancePtr->Video.FrameBuffer[XDPDMA_VIDEO_CHANNEL1] = NULL;
353 InstancePtr->Video.FrameBuffer[XDPDMA_VIDEO_CHANNEL2] = NULL;
355 InstancePtr->Gfx.Channel.Current = NULL;
356 InstancePtr->Gfx.TriggerStatus = XDPDMA_TRIGGER_DONE;
357 InstancePtr->Gfx.VideoInfo = NULL;
358 InstancePtr->Gfx.FrameBuffer = NULL;
361 /*************************************************************************/
364 * This functions controls the states in which a channel should go into.
366 * @param InstancePtr is a pointer to the driver instance.
367 * @param ChannelType is an enum of XDpDma_ChannelType.
368 * @param ChannelState is an enum of type XDpDma_ChannelState.
370 * @return XST_SUCCESS when the mentioned channel is enabled successfully.
371 * XST_FAILURE when the mentioned channel fails to be enabled.
375 * **************************************************************************/
376 int XDpDma_SetChannelState(XDpDma *InstancePtr, XDpDma_ChannelType Channel,
377 XDpDma_ChannelState ChannelState)
382 /* Verify arguments. */
383 Xil_AssertNonvoid(InstancePtr != NULL);
387 if(InstancePtr->Video.VideoInfo == NULL) {
391 NumPlanes = InstancePtr->Video.VideoInfo->Mode;
392 for(Index = 0; Index <= NumPlanes; Index++) {
393 Status = XDpDma_ConfigChannelState(InstancePtr,
396 if(Status == XST_FAILURE) {
403 if(InstancePtr->Gfx.VideoInfo == NULL) {
407 return XDpDma_ConfigChannelState(InstancePtr,
408 XDPDMA_GRAPHICS_CHANNEL,
413 return XDpDma_ConfigChannelState(InstancePtr,
414 XDPDMA_AUDIO_CHANNEL0,
418 return XDpDma_ConfigChannelState(InstancePtr,
419 XDPDMA_AUDIO_CHANNEL1,
430 /*************************************************************************/
433 * This function allocates DPDMA Video Channels depending on the number of
434 * planes in the video
436 * @param InstancePtr is a pointer to the driver instance.
437 * @params Format is the video format to be used for the DPDMA transfer
439 * @return XST_SUCCESS, When the format is valid Video Format.
440 * XST_FAILURE, When the format is not valid Video Format
444 * **************************************************************************/
445 int XDpDma_SetVideoFormat(XDpDma *InstancePtr, XAVBuf_VideoFormat Format)
447 /* Verify arguments. */
448 Xil_AssertNonvoid(InstancePtr != NULL);
450 InstancePtr->Video.VideoInfo = XAVBuf_GetNLiveVideoAttribute(Format);
451 if(InstancePtr->Video.VideoInfo == NULL) {
458 /*************************************************************************/
461 * This function allocates DPDMA Graphics Channels.
463 * @param InstancePtr is a pointer to the driver instance.
464 * @params Format is the video format to be used for the DPDMA transfer
466 * @return XST_SUCCESS, When the format is a valid Graphics Format.
467 * XST_FAILURE, When the format is not valid Graphics Format.
471 * **************************************************************************/
472 int XDpDma_SetGraphicsFormat(XDpDma *InstancePtr, XAVBuf_VideoFormat Format)
475 /* Verify arguments. */
476 Xil_AssertNonvoid(InstancePtr != NULL);
478 InstancePtr->Gfx.VideoInfo = XAVBuf_GetNLGraphicsAttribute(Format);
479 if(InstancePtr->Gfx.VideoInfo == NULL) {
486 /*************************************************************************/
489 * This function starts the operation on the a given channel
491 * @param InstancePtr is a pointer to the driver instance.
492 * @param QOS is the Quality of Service value to be selected.
498 * **************************************************************************/
499 void XDpDma_SetQOS(XDpDma *InstancePtr, u8 QOS)
504 Xil_AssertVoid(QOS >= XDPDMA_QOS_MIN && QOS <= XDPDMA_QOS_MAX);
506 RegVal = ((QOS << XDPDMA_CH_CNTL_QOS_DATA_RD_SHIFT) |
507 (QOS << XDPDMA_CH_CNTL_QOS_DSCR_RD_SHIFT) |
508 (QOS << XDPDMA_CH_CNTL_QOS_DSCR_WR_SHIFT));
510 u32 Mask = XDPDMA_CH_CNTL_QOS_DATA_RD_MASK |
511 XDPDMA_CH_CNTL_QOS_DSCR_RD_MASK |
512 XDPDMA_CH_CNTL_QOS_DSCR_WR_MASK;
514 for(Index = 0; Index <= XDPDMA_AUDIO_CHANNEL1; Index++) {
515 XDpDma_ReadModifyWrite(InstancePtr->Config.BaseAddr,
516 XDPDMA_CH0_CNTL + (XDPDMA_CH_OFFSET * Index),
522 /*************************************************************************/
525 * This function Triggers DPDMA to start the transaction.
527 * @param InstancePtr is a pointer to the XDpDma instance.
528 * @param Channel is the XDpDma_ChannelType on which the transaction
529 * is to be triggered.
531 * @return XST_SUCCESS The channel has successfully been Triggered.
532 * XST_FAILURE When the triggering Video and Graphics channel
533 * without setting the Video Formats.
537 * **************************************************************************/
538 int XDpDma_Trigger(XDpDma *InstancePtr, XDpDma_ChannelType Channel)
545 if(InstancePtr->Video.VideoInfo == NULL) {
549 NumPlanes = InstancePtr->Video.VideoInfo->Mode;
550 for(Index = 0; Index <= NumPlanes; Index++) {
551 Trigger |= XDPDMA_GBL_TRG_CH0_MASK << Index;
552 InstancePtr->Video.TriggerStatus =
558 if(InstancePtr->Gfx.VideoInfo == NULL) {
561 Trigger = XDPDMA_GBL_TRG_CH3_MASK;
562 InstancePtr->Gfx.TriggerStatus = XDPDMA_TRIGGER_DONE;
565 Trigger = XDPDMA_GBL_TRG_CH4_MASK;
566 InstancePtr->Audio[0].TriggerStatus = XDPDMA_TRIGGER_DONE;
569 Trigger = XDPDMA_GBL_TRG_CH5_MASK;
570 InstancePtr->Audio[1].TriggerStatus = XDPDMA_TRIGGER_DONE;
573 XDpDma_WriteReg(InstancePtr->Config.BaseAddr, XDPDMA_GBL, Trigger);
579 /*************************************************************************/
582 * This function Retriggers DPDMA to fetch data from new descriptor.
584 * @param InstancePtr is a pointer to the XDpDma instance.
585 * @param Channel is the XDpDma_ChannelType on which the transaction
586 * is to be retriggered.
588 * @return XST_SUCCESS The channel has successfully been Triggered.
589 * XST_FAILURE When the triggering Video and Graphics channel
590 * without setting the Video Formats.
594 * **************************************************************************/
595 int XDpDma_ReTrigger(XDpDma *InstancePtr, XDpDma_ChannelType Channel)
602 if(InstancePtr->Video.VideoInfo == NULL) {
606 NumPlanes = InstancePtr->Video.VideoInfo->Mode;
607 for(Index = 0; Index <= NumPlanes; Index++) {
608 Trigger |= XDPDMA_GBL_RTRG_CH0_MASK << Index;
609 InstancePtr->Video.TriggerStatus =
610 XDPDMA_RETRIGGER_DONE;
615 if(InstancePtr->Gfx.VideoInfo == NULL) {
618 Trigger = XDPDMA_GBL_RTRG_CH3_MASK;
619 InstancePtr->Gfx.TriggerStatus = XDPDMA_RETRIGGER_DONE;
622 Trigger = XDPDMA_GBL_RTRG_CH4_MASK;
623 InstancePtr->Audio[0].TriggerStatus = XDPDMA_RETRIGGER_DONE;
626 Trigger = XDPDMA_GBL_RTRG_CH5_MASK;
627 InstancePtr->Audio[1].TriggerStatus = XDPDMA_RETRIGGER_DONE;
630 XDpDma_WriteReg(InstancePtr->Config.BaseAddr, XDPDMA_GBL, Trigger);
635 /*************************************************************************/
638 * This function intializes Video Descriptor for Video and Graphics channel
640 * @param Channel is a pointer to the current Descriptor of Video or
642 * @param FrameBuffer is a pointer to the Frame Buffer structure
648 * **************************************************************************/
649 void XDpDma_InitVideoDescriptor(XDpDma_Descriptor *CurrDesc,
650 XDpDma_FrameBuffer *FrameBuffer)
652 Xil_AssertVoid(CurrDesc != NULL);
653 Xil_AssertVoid(FrameBuffer != NULL);
654 Xil_AssertVoid((FrameBuffer->Stride) % XDPDMA_DESCRIPTOR_ALIGN == 0);
655 CurrDesc->Control = XDPDMA_DESC_PREAMBLE | XDPDMA_DESC_IGNR_DONE |
656 XDPDMA_DESC_LAST_FRAME;
657 CurrDesc->DSCR_ID = 0;
658 CurrDesc->XFER_SIZE = FrameBuffer->Size;
659 CurrDesc->LINE_SIZE_STRIDE = ((FrameBuffer->Stride >> 4) <<
660 XDPDMA_DESCRIPTOR_LINE_SIZE_STRIDE_SHIFT) |
661 (FrameBuffer->LineSize);
662 CurrDesc->ADDR_EXT = (((FrameBuffer->Address >>
663 XDPDMA_DESCRIPTOR_SRC_ADDR_WIDTH) <<
664 XDPDMA_DESCRIPTOR_ADDR_EXT_SRC_ADDR_EXT_SHIFT) |
665 ((INTPTR) CurrDesc >>
666 XDPDMA_DESCRIPTOR_NEXT_DESR_WIDTH));
667 CurrDesc->NEXT_DESR = (INTPTR) CurrDesc;
668 CurrDesc->SRC_ADDR = FrameBuffer->Address;
671 /*************************************************************************/
674 * This function intializes Descriptors for transactions on Audio Channel
676 * @param Channel is a pointer to the XDpDma_AudioChannel instance
678 * @param AudioBuffer is a pointer to the Audio Buffer structure
684 * **************************************************************************/
685 void XDpDma_InitAudioDescriptor(XDpDma_AudioChannel *Channel,
686 XDpDma_AudioBuffer *AudioBuffer)
690 Xil_AssertVoid(Channel != NULL);
691 Xil_AssertVoid(AudioBuffer != NULL);
692 Xil_AssertVoid((AudioBuffer->Size) % XDPDMA_AUDIO_ALIGNMENT == 0);
693 Xil_AssertVoid((AudioBuffer->Address) % XDPDMA_AUDIO_ALIGNMENT == 0);
695 Size = AudioBuffer->Size / 4;
696 Address = AudioBuffer->Address;
697 if(Channel->Current == &Channel->Descriptor4) {
698 XDpDma_SetupAudioDescriptor(&Channel->Descriptor4, Size,
700 &Channel->Descriptor5);
701 XDpDma_SetupAudioDescriptor(&Channel->Descriptor5, Size,
703 &Channel->Descriptor6);
704 XDpDma_SetupAudioDescriptor(&Channel->Descriptor6, Size,
705 Address + (Size * 2),
706 &Channel->Descriptor7);
707 XDpDma_SetupAudioDescriptor(&Channel->Descriptor7, Size,
708 Address + (Size * 3), NULL);
711 else if(Channel->Current == &Channel->Descriptor0) {
712 XDpDma_SetupAudioDescriptor(&Channel->Descriptor0, Size,
714 &Channel->Descriptor1);
715 XDpDma_SetupAudioDescriptor(&Channel->Descriptor1, Size,
717 &Channel->Descriptor2);
718 XDpDma_SetupAudioDescriptor(&Channel->Descriptor2, Size,
719 Address + (Size * 2),
720 &Channel->Descriptor3);
721 XDpDma_SetupAudioDescriptor(&Channel->Descriptor3, Size,
722 Address + (Size * 3), NULL);
727 /*************************************************************************/
730 * This function sets the next Frame Buffers to be displayed on the Video
733 * @param InstancePtr is pointer to the instance of DPDMA.
734 * @param Plane0 is a pointer to the Frame Buffer structure.
735 * @param Plane1 is a pointer to the Frame Buffer structure.
736 * @param Plane2 is a pointer to the Frame Buffer structure.
740 * @note For interleaved mode use Plane0.
741 * For semi-planar mode use Plane0 and Plane1.
742 * For planar mode use Plane0, Plane1 and Plane2
744 * **************************************************************************/
745 void XDpDma_DisplayVideoFrameBuffer(XDpDma *InstancePtr,
746 XDpDma_FrameBuffer *Plane0,
747 XDpDma_FrameBuffer *Plane1,
748 XDpDma_FrameBuffer *Plane2)
751 Xil_AssertVoid(InstancePtr != NULL);
752 Xil_AssertVoid(InstancePtr->Video.VideoInfo != NULL);
754 NumPlanes = InstancePtr->Video.VideoInfo->Mode;
757 case XDPDMA_VIDEO_CHANNEL2:
758 Xil_AssertVoid(Plane2 != NULL);
759 InstancePtr->Video.FrameBuffer[XDPDMA_VIDEO_CHANNEL2] =
761 case XDPDMA_VIDEO_CHANNEL1:
762 Xil_AssertVoid(Plane1 != NULL);
763 InstancePtr->Video.FrameBuffer[XDPDMA_VIDEO_CHANNEL1] =
765 case XDPDMA_VIDEO_CHANNEL0:
766 Xil_AssertVoid(Plane0 != NULL);
767 InstancePtr->Video.FrameBuffer[XDPDMA_VIDEO_CHANNEL0] =
772 if(InstancePtr->Video.Channel[XDPDMA_VIDEO_CHANNEL0].Current == NULL) {
773 InstancePtr->Video.TriggerStatus = XDPDMA_TRIGGER_EN;
776 InstancePtr->Video.TriggerStatus = XDPDMA_RETRIGGER_EN;
780 /*************************************************************************/
783 * This function sets the next Frame Buffers to be displayed on the Graphics
786 * @param InstancePtr is pointer to the instance of DPDMA.
787 * @param Plane is a pointer to the Frame Buffer structure.
793 **************************************************************************/
794 void XDpDma_DisplayGfxFrameBuffer(XDpDma *InstancePtr,
795 XDpDma_FrameBuffer *Plane)
797 Xil_AssertVoid(InstancePtr != NULL);
798 Xil_AssertVoid(Plane != NULL);
800 InstancePtr->Gfx.FrameBuffer = Plane;
802 if(InstancePtr->Gfx.Channel.Current == NULL) {
803 InstancePtr->Gfx.TriggerStatus = XDPDMA_TRIGGER_EN;
806 InstancePtr->Gfx.TriggerStatus = XDPDMA_RETRIGGER_EN;
809 /*************************************************************************/
812 * This function sets the next Audio Buffer to be played on Audio Channel 0
814 * @param InstancePtr is pointer to the instance of DPDMA.
815 * @param Buffer is a pointer to the attributes of the Audio information
817 * @param ChannelNum selects between Audio Channel 0 and Audio Channel 1
819 * @return XST_SUCCESS when the play audio request is successful.
820 * XST_FAILURE when the play audio request fails, user has to
821 * retry to play the audio.
823 * @note The user has to schedule new audio buffer before half the audio
824 * information is consumed by DPDMA to have a seamless playback.
826 **************************************************************************/
827 int XDpDma_PlayAudio(XDpDma *InstancePtr, XDpDma_AudioBuffer *Buffer,
830 XDpDma_AudioChannel *Channel;
831 Xil_AssertNonvoid(InstancePtr != NULL);
832 Xil_AssertNonvoid(Buffer != NULL);
833 Xil_AssertNonvoid(Buffer->Size >= 512);
834 Xil_AssertNonvoid(Buffer->Size % 128 == 0);
835 Xil_AssertNonvoid(Buffer->Address % 128 == 0);
837 Channel = &InstancePtr->Audio[ChannelNum];
838 Channel->Buffer = Buffer;
840 if(Channel->Current == NULL) {
841 Channel->TriggerStatus = XDPDMA_TRIGGER_EN;
842 Channel->Current = &Channel->Descriptor0;
846 else if(Channel->Current == &Channel->Descriptor0) {
847 /* Check if descriptor chain can be updated */
848 if(Channel->Descriptor1.MSB_Timestamp >>
849 XDPDMA_DESC_DONE_SHIFT) {
850 Channel->Current = NULL;
853 else if(Channel->Descriptor7.MSB_Timestamp >>
854 XDPDMA_DESC_DONE_SHIFT || !(Channel->Used)) {
855 Channel->Descriptor3.Control = XDPDMA_DESC_PREAMBLE |
856 XDPDMA_DESC_UPDATE | XDPDMA_DESC_IGNR_DONE;
857 Channel->Descriptor3.NEXT_DESR =
858 (INTPTR) &Channel->Descriptor4;
859 Channel->Descriptor3.ADDR_EXT &=
860 ~XDPDMA_DESCRIPTOR_ADDR_EXT_DSC_NXT_MASK;
861 Channel->Descriptor3.ADDR_EXT |=
862 (INTPTR) &Channel->Descriptor4 >> 32;
863 Channel->Current = &Channel->Descriptor4;
865 XDpDma_InitAudioDescriptor(Channel, Buffer);
872 else if(Channel->Current == &Channel->Descriptor4) {
873 /* Check if descriptor chain can be updated */
874 if(Channel->Descriptor5.MSB_Timestamp >>
875 XDPDMA_DESC_DONE_SHIFT) {
876 Channel->Current = NULL;
879 else if(Channel->Descriptor3.MSB_Timestamp >>
880 XDPDMA_DESC_DONE_SHIFT) {
881 Channel->Descriptor7.Control = XDPDMA_DESC_PREAMBLE |
882 XDPDMA_DESC_UPDATE | XDPDMA_DESC_IGNR_DONE;
883 Channel->Descriptor7.NEXT_DESR =
884 (INTPTR) &Channel->Descriptor0;
885 Channel->Descriptor7.ADDR_EXT &=
886 ~XDPDMA_DESCRIPTOR_ADDR_EXT_DSC_NXT_MASK;
887 Channel->Descriptor7.ADDR_EXT |=
888 (INTPTR) &Channel->Descriptor0 >> 32;
889 Channel->Current = &Channel->Descriptor0;
890 XDpDma_InitAudioDescriptor(Channel, Buffer);
900 /*************************************************************************/
903 * This function sets the channel with the latest framebuffer and the
904 * available descriptor for transfer on the next Vsync.
906 * @param InstancePtr is pointer to the instance of DPDMA.
907 * @param Channel indicates which channels are being setup for transfer.
913 **************************************************************************/
914 void XDpDma_SetupChannel(XDpDma *InstancePtr, XDpDma_ChannelType Channel)
916 XDpDma_Channel *Chan;
917 XDpDma_AudioChannel *AudChan;
918 XDpDma_FrameBuffer *FB;
919 XDpDma_AudioBuffer *AudioBuffer;
921 Xil_AssertVoid(InstancePtr != NULL);
925 Xil_AssertVoid(InstancePtr->Video.VideoInfo != NULL);
926 Xil_AssertVoid(InstancePtr->Video.FrameBuffer != NULL);
927 NumPlanes = InstancePtr->Video.VideoInfo->Mode;
928 for(Index = 0; Index <= NumPlanes; Index++) {
929 Chan = &InstancePtr->Video.Channel[Index];
930 FB = InstancePtr->Video.FrameBuffer[Index];
931 XDpDma_UpdateVideoDescriptor(Chan);
932 XDpDma_InitVideoDescriptor(Chan->Current, FB);
933 XDpDma_SetDescriptorAddress(InstancePtr,
939 Xil_AssertVoid(InstancePtr->Gfx.VideoInfo != NULL);
940 Xil_AssertVoid(InstancePtr->Gfx.FrameBuffer != NULL);
941 Chan = &InstancePtr->Gfx.Channel;
942 FB = InstancePtr->Gfx.FrameBuffer;
943 XDpDma_UpdateVideoDescriptor(Chan);
944 XDpDma_InitVideoDescriptor(Chan->Current, FB);
945 XDpDma_SetDescriptorAddress(InstancePtr,
946 XDPDMA_GRAPHICS_CHANNEL);
950 Xil_AssertVoid(InstancePtr->Audio[0].Buffer != NULL);
951 AudChan = &InstancePtr->Audio[0];
952 AudioBuffer = InstancePtr->Audio[0].Buffer;
953 XDpDma_InitAudioDescriptor(AudChan, AudioBuffer);
954 XDpDma_SetDescriptorAddress(InstancePtr,
955 XDPDMA_AUDIO_CHANNEL0);
958 Xil_AssertVoid(InstancePtr->Audio[1].Buffer != NULL);
959 AudChan = &InstancePtr->Audio[1];
960 AudioBuffer = InstancePtr->Audio[1].Buffer;
961 XDpDma_InitAudioDescriptor(AudChan, AudioBuffer);
962 XDpDma_SetDescriptorAddress(InstancePtr,
963 XDPDMA_AUDIO_CHANNEL1);