]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_A53_64-bit_UltraScale_MPSoC/RTOSDemo_A53_bsp/psu_cortexa53_0/libsrc/dpdma_v1_0/src/xdpdma.c
Update Zynq, MPSoc Cortex-A53 and MPSoc Cortex-R5 demo projects to build with the...
[freertos] / FreeRTOS / Demo / CORTEX_A53_64-bit_UltraScale_MPSoC / RTOSDemo_A53_bsp / psu_cortexa53_0 / libsrc / dpdma_v1_0 / src / xdpdma.c
1 /******************************************************************************
2 *
3 * Copyright (C) 2010 - 2017 Xilinx, Inc. All rights reserved.
4 *
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:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
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.
18 *
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
25 * SOFTWARE.
26 *
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.
30 *
31
32 *******************************************************************************/
33 /*****************************************************************************/
34 /**
35  *
36  * @file xdpdma.c
37  *
38  * This file contains the implementation of the interface functions of the
39  * XDpDma driver. Refer to xdpdma.h for detailed information.
40  *
41  * @note        None.
42  *
43  * <pre>
44  * MODIFICATION HISTORY:
45  *
46  * Ver  Who   Date     Changes
47  * ---- ----- -------- ----------------------------------------------------
48  * 1.0  aad   04/12/16 Initial release.
49  *
50  *****************************************************************************/
51
52 /***************************** Include Files **********************************/
53 #include "xdpdma.h"
54 #include "xavbuf.h"
55
56 /************************** Constant Definitions ******************************/
57 #define XDPDMA_CH_OFFSET                0x100
58 #define XDPDMA_WAIT_TIMEOUT             10000
59
60 #define XDPDMA_AUDIO_ALIGNMENT          128
61
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
68
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
77
78 /*************************************************************************/
79 /**
80  *
81  * This function returns the number of outstanding transactions on a given
82  * channel.
83  *
84  * @param    InstancePtr is a pointer to the driver instance.
85  * @param    ChannelNum is the channel number on which the operation is
86  *           being carried out.
87  *
88  * @return   Number of pending transactions.
89  *
90  * @note     None.
91  *
92  * **************************************************************************/
93 static int XDpDma_GetPendingTransaction(XDpDma *InstancePtr, u32 ChannelNum)
94 {
95         u32 RegVal;
96         RegVal = XDpDma_ReadReg(InstancePtr->Config.BaseAddr,
97                                 XDPDMA_CH0_STATUS + 0x100 * ChannelNum);
98         return (RegVal & XDPDMA_CH_STATUS_OTRAN_CNT_MASK);
99 }
100
101 /*************************************************************************/
102 /**
103  *
104  * This function waits until the outstanding transactions are completed.
105  *
106  * @param    InstancePtr is a pointer to the driver instance.
107  * @param    ChannelNum is the channel number on which the operation is
108  *           being carried out.
109  *
110  * @return   XST_SUCCESS when all the pending transactions are complete
111  *           before timeout.
112  *           XST_FAILURE if timeout occurs before pending transactions are
113  *           completed.
114  *
115  * @note     None.
116  *
117  * **************************************************************************/
118 static int XDpDma_WaitPendingTransaction(XDpDma *InstancePtr, u8 ChannelNum)
119 {
120         /* Verify arguments. */
121         Xil_AssertNonvoid(InstancePtr != NULL);
122         Xil_AssertNonvoid(ChannelNum <= XDPDMA_AUDIO_CHANNEL1);
123
124         u32 Timeout = 0;
125         u32 Count;
126         do {
127                 Count = XDpDma_GetPendingTransaction(InstancePtr, ChannelNum);
128                 Timeout++;
129         } while((Timeout != XDPDMA_WAIT_TIMEOUT) && Count);
130
131         if(Timeout ==  XDPDMA_WAIT_TIMEOUT) {
132                 return XST_FAILURE;
133         }
134
135         return XST_SUCCESS;
136 }
137
138 /*************************************************************************/
139 /**
140  *
141  * This function controls the hardware channels of the DPDMA.
142  *
143  *
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.
147  *
148  * @return   XST_SUCCESS when the mentioned channel is enabled successfully.
149  *           XST_FAILURE when the mentioned channel fails to be enabled.
150  *
151  * @note     None.
152  *
153  * **************************************************************************/
154 static int XDpDma_ConfigChannelState(XDpDma *InstancePtr, u8 ChannelNum,
155                                      XDpDma_ChannelState Enable)
156 {
157         u32 Mask = 0;
158         u32 RegVal = 0;
159         u32 Status = 0;
160         /* Verify arguments. */
161         Xil_AssertNonvoid(InstancePtr != NULL);
162         Xil_AssertNonvoid(ChannelNum <= XDPDMA_AUDIO_CHANNEL1);
163
164         Mask = XDPDMA_CH_CNTL_EN_MASK | XDPDMA_CH_CNTL_PAUSE_MASK;
165         switch(Enable) {
166                 case XDPDMA_ENABLE:
167                         RegVal = XDPDMA_CH_CNTL_EN_MASK;
168                         break;
169                 case XDPDMA_DISABLE:
170                         XDpDma_ConfigChannelState(InstancePtr, ChannelNum,
171                                                   XDPDMA_PAUSE);
172                         Status = XDpDma_WaitPendingTransaction(InstancePtr,
173                                                                ChannelNum);
174                         if(Status == XST_FAILURE) {
175                                 return XST_FAILURE;
176                         }
177
178                         RegVal = XDPDMA_DISABLE;
179                         Mask = XDPDMA_CH_CNTL_EN_MASK;
180                         break;
181                 case XDPDMA_IDLE:
182                         Status = XDpDma_ConfigChannelState(InstancePtr,
183                                                            ChannelNum,
184                                                            XDPDMA_DISABLE);
185                         if(Status == XST_FAILURE) {
186                                 return XST_FAILURE;
187                         }
188
189                         RegVal = 0;
190                         break;
191                 case XDPDMA_PAUSE:
192                         RegVal = XDPDMA_PAUSE;
193                         break;
194         }
195         XDpDma_ReadModifyWrite(InstancePtr->Config.BaseAddr,
196                                XDPDMA_CH0_CNTL + XDPDMA_CH_OFFSET * ChannelNum,
197                                RegVal, Mask);
198         return XST_SUCCESS;
199 }
200
201 /*************************************************************************/
202 /**
203  *
204  * This function updates the descriptor that is not currently active on a
205  * Video/Graphics channel.
206  *
207  * @param    InstancePtr is a pointer to the driver instance.
208  * @param    Channel is a pointer to the channel on which the operation is
209  *           to be carried out.
210  *
211  * @return   Descriptor for next operation.
212  *
213  * @note     None.
214  *
215  * **************************************************************************/
216 static XDpDma_Descriptor *XDpDma_UpdateVideoDescriptor(XDpDma_Channel *Channel)
217 {
218         if(Channel->Current == NULL) {
219                 Channel->Current = &Channel->Descriptor0;
220         }
221         else if(Channel->Current == &Channel->Descriptor0) {
222                 Channel->Current = &Channel->Descriptor1;
223         }
224         else if(Channel->Current == &Channel->Descriptor1) {
225                 Channel->Current = &Channel->Descriptor0;
226         }
227         return Channel->Current;
228 }
229
230 /*************************************************************************/
231 /**
232  * This function programs the address of the descriptor about to be active
233  *
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.
237  *
238  * @return   Descriptor for next operation.
239  *
240  * @note     None.
241  *
242  * **************************************************************************/
243 static void XDpDma_SetDescriptorAddress(XDpDma *InstancePtr, u8 ChannelNum)
244 {
245         u32 AddrOffset;
246         u32 AddrEOffset;
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);
252
253         XDpDma_Descriptor *Descriptor = NULL;
254         switch(ChannelNum) {
255         case XDPDMA_VIDEO_CHANNEL0:
256                 Descriptor = InstancePtr->Video.Channel[ChannelNum].Current;
257                 break;
258         case XDPDMA_VIDEO_CHANNEL1:
259                 Descriptor = InstancePtr->Video.Channel[ChannelNum].Current;
260                 break;
261         case XDPDMA_VIDEO_CHANNEL2:
262                 Descriptor = InstancePtr->Video.Channel[ChannelNum].Current;
263                 break;
264         case XDPDMA_GRAPHICS_CHANNEL:
265                 Descriptor = InstancePtr->Gfx.Channel.Current;
266                 break;
267         case XDPDMA_AUDIO_CHANNEL0:
268                 Descriptor = InstancePtr->Audio[0].Current;
269                 break;
270         case XDPDMA_AUDIO_CHANNEL1:
271                 Descriptor = InstancePtr->Audio[1].Current;
272                 break;
273         }
274
275         XDpDma_WriteReg(InstancePtr->Config.BaseAddr, AddrEOffset,
276                         (INTPTR) Descriptor >> 32);
277         XDpDma_WriteReg(InstancePtr->Config.BaseAddr, AddrOffset,
278                         (INTPTR) Descriptor);
279 }
280
281 /*************************************************************************/
282 /**
283  *
284  * This functions sets the Audio Descriptor for Data Transfer.
285  *
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
289  *
290  * @return   None.
291  *
292  * @note     None.
293  *
294  * **************************************************************************/
295 static void XDpDma_SetupAudioDescriptor(XDpDma_Descriptor *CurrDesc,
296                                         u64 DataSize, u64 BuffAddr,
297                                         XDpDma_Descriptor *NextDesc)
298 {
299         Xil_AssertVoid(CurrDesc != NULL);
300         Xil_AssertVoid(DataSize != 0);
301         Xil_AssertVoid(BuffAddr != 0);
302
303         if(NextDesc == NULL) {
304                 CurrDesc->Control = XDPDMA_DESC_PREAMBLE |
305                         XDPDMA_DESC_UPDATE | XDPDMA_DESC_IGNR_DONE |
306                         XDPDMA_DESC_COMP_INTR;
307
308         }
309         else {
310                 CurrDesc->Control = XDPDMA_DESC_PREAMBLE |
311                         XDPDMA_DESC_UPDATE | XDPDMA_DESC_IGNR_DONE;
312         }
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;
324 }
325
326 /*************************************************************************/
327 /**
328  *
329  * This functions retrieves the configuration for this DPDMA driver and
330  * fills in the InstancePtr->Config structure.
331  *
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.
335  *
336  * @return   None.
337  *
338  * @note     None.
339  *
340  * **************************************************************************/
341 void XDpDma_CfgInitialize(XDpDma *InstancePtr, XDpDma_Config *CfgPtr)
342 {
343         InstancePtr->Config.DeviceId = CfgPtr->DeviceId;
344         InstancePtr->Config.BaseAddr = CfgPtr->BaseAddr;
345
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;
354
355         InstancePtr->Gfx.Channel.Current = NULL;
356         InstancePtr->Gfx.TriggerStatus = XDPDMA_TRIGGER_DONE;
357         InstancePtr->Gfx.VideoInfo = NULL;
358         InstancePtr->Gfx.FrameBuffer = NULL;
359 }
360
361 /*************************************************************************/
362 /**
363  *
364  * This functions controls the states in which a channel should go into.
365  *
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.
369  *
370  * @return   XST_SUCCESS when the mentioned channel is enabled successfully.
371  *           XST_FAILURE when the mentioned channel fails to be enabled.
372  *
373  * @note     None.
374  *
375  * **************************************************************************/
376 int XDpDma_SetChannelState(XDpDma *InstancePtr, XDpDma_ChannelType Channel,
377                                         XDpDma_ChannelState ChannelState)
378 {
379         u32 Index = 0;
380         u32 NumPlanes = 0;
381         u32 Status = 0;
382         /* Verify arguments. */
383         Xil_AssertNonvoid(InstancePtr != NULL);
384
385         switch(Channel) {
386         case VideoChan:
387                 if(InstancePtr->Video.VideoInfo == NULL) {
388                         return XST_FAILURE;
389                 }
390                 else {
391                         NumPlanes = InstancePtr->Video.VideoInfo->Mode;
392                         for(Index = 0; Index <= NumPlanes; Index++) {
393                                 Status = XDpDma_ConfigChannelState(InstancePtr,
394                                                                 Index,
395                                                                 ChannelState);
396                                 if(Status == XST_FAILURE) {
397                                         return XST_FAILURE;
398                                 }
399                         }
400                 }
401                 break;
402         case GraphicsChan:
403                 if(InstancePtr->Gfx.VideoInfo == NULL) {
404                         return XST_FAILURE;
405                 }
406                 else {
407                         return  XDpDma_ConfigChannelState(InstancePtr,
408                                               XDPDMA_GRAPHICS_CHANNEL,
409                                               ChannelState);
410                 }
411                 break;
412         case AudioChan0:
413                 return  XDpDma_ConfigChannelState(InstancePtr,
414                                                   XDPDMA_AUDIO_CHANNEL0,
415                                                   ChannelState);
416                 break;
417         case AudioChan1:
418                 return XDpDma_ConfigChannelState(InstancePtr,
419                                                  XDPDMA_AUDIO_CHANNEL1,
420                                                  ChannelState);
421                 break;
422         default:
423                 return XST_FAILURE;
424                 break;
425         }
426
427         return XST_SUCCESS;
428 }
429
430 /*************************************************************************/
431 /**
432  *
433  * This function allocates DPDMA Video Channels depending on the number of
434  * planes in the video
435  *
436  * @param       InstancePtr is a pointer to the driver instance.
437  * @params      Format is the video format to be used for the DPDMA transfer
438  *
439  * @return      XST_SUCCESS, When the format is valid Video Format.
440  *              XST_FAILURE, When the format is not valid Video Format
441  *
442  * @note        None.
443  *
444  * **************************************************************************/
445 int XDpDma_SetVideoFormat(XDpDma *InstancePtr, XAVBuf_VideoFormat Format)
446 {
447         /* Verify arguments. */
448         Xil_AssertNonvoid(InstancePtr != NULL);
449
450         InstancePtr->Video.VideoInfo = XAVBuf_GetNLiveVideoAttribute(Format);
451         if(InstancePtr->Video.VideoInfo == NULL) {
452                 return XST_FAILURE;
453         }
454
455         return XST_SUCCESS;
456 }
457
458 /*************************************************************************/
459 /**
460  *
461  * This function allocates DPDMA Graphics Channels.
462  *
463  * @param       InstancePtr is a pointer to the driver instance.
464  * @params      Format is the video format to be used for the DPDMA transfer
465  *
466  * @return      XST_SUCCESS, When the format is a valid Graphics Format.
467  *              XST_FAILURE, When the format is not valid Graphics Format.
468  *
469  * @note        None.
470  *
471  * **************************************************************************/
472 int XDpDma_SetGraphicsFormat(XDpDma *InstancePtr, XAVBuf_VideoFormat Format)
473 {
474
475         /* Verify arguments. */
476         Xil_AssertNonvoid(InstancePtr != NULL);
477
478         InstancePtr->Gfx.VideoInfo = XAVBuf_GetNLGraphicsAttribute(Format);
479         if(InstancePtr->Gfx.VideoInfo == NULL) {
480                 return XST_FAILURE;
481         }
482
483         return XST_SUCCESS;
484 }
485
486 /*************************************************************************/
487 /**
488  *
489  * This function starts the operation on the a given channel
490  *
491  * @param    InstancePtr is a pointer to the driver instance.
492  * @param    QOS is the Quality of Service value to be selected.
493  *
494  * @return   None.
495  *
496  * @note     .
497  *
498  * **************************************************************************/
499 void XDpDma_SetQOS(XDpDma *InstancePtr, u8 QOS)
500 {
501         u8 Index;
502         u32 RegVal = 0;
503
504         Xil_AssertVoid(QOS >= XDPDMA_QOS_MIN && QOS <= XDPDMA_QOS_MAX);
505
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));
509
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;
513
514         for(Index = 0; Index <= XDPDMA_AUDIO_CHANNEL1; Index++) {
515                 XDpDma_ReadModifyWrite(InstancePtr->Config.BaseAddr,
516                                 XDPDMA_CH0_CNTL + (XDPDMA_CH_OFFSET * Index),
517                                 RegVal, Mask);
518         }
519
520 }
521
522 /*************************************************************************/
523 /**
524  *
525  * This function Triggers DPDMA to start the transaction.
526  *
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.
530  *
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.
534  *
535  * @note        None.
536  *
537  * **************************************************************************/
538 int XDpDma_Trigger(XDpDma *InstancePtr, XDpDma_ChannelType Channel)
539 {
540         u32 Trigger = 0;
541         u8 Index = 0;
542         u8 NumPlanes = 0;
543         switch(Channel) {
544         case VideoChan:
545                 if(InstancePtr->Video.VideoInfo == NULL) {
546                         return XST_FAILURE;
547                 }
548                 else {
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 =
553                                         XDPDMA_TRIGGER_DONE;
554                         }
555                 }
556                 break;
557         case GraphicsChan:
558                 if(InstancePtr->Gfx.VideoInfo == NULL) {
559                         return XST_FAILURE;
560                 }
561                 Trigger = XDPDMA_GBL_TRG_CH3_MASK;
562                 InstancePtr->Gfx.TriggerStatus = XDPDMA_TRIGGER_DONE;
563                 break;
564         case AudioChan0:
565                 Trigger = XDPDMA_GBL_TRG_CH4_MASK;
566                 InstancePtr->Audio[0].TriggerStatus = XDPDMA_TRIGGER_DONE;
567                 break;
568         case AudioChan1:
569                 Trigger = XDPDMA_GBL_TRG_CH5_MASK;
570                 InstancePtr->Audio[1].TriggerStatus = XDPDMA_TRIGGER_DONE;
571                 break;
572         }
573         XDpDma_WriteReg(InstancePtr->Config.BaseAddr, XDPDMA_GBL, Trigger);
574
575         return XST_SUCCESS;
576
577 }
578
579 /*************************************************************************/
580 /**
581  *
582  * This function Retriggers DPDMA to fetch data from new descriptor.
583  *
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.
587  *
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.
591  *
592  * @note        None.
593  *
594  * **************************************************************************/
595 int XDpDma_ReTrigger(XDpDma *InstancePtr, XDpDma_ChannelType Channel)
596 {
597         u32 Trigger = 0;
598         u8 NumPlanes;
599         u8 Index;
600         switch(Channel) {
601         case VideoChan:
602                 if(InstancePtr->Video.VideoInfo == NULL) {
603                         return XST_FAILURE;
604                 }
605                 else {
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;
611                         }
612                 }
613                 break;
614         case GraphicsChan:
615                 if(InstancePtr->Gfx.VideoInfo == NULL) {
616                         return XST_FAILURE;
617                 }
618                 Trigger = XDPDMA_GBL_RTRG_CH3_MASK;
619                 InstancePtr->Gfx.TriggerStatus = XDPDMA_RETRIGGER_DONE;
620                 break;
621         case AudioChan0:
622                 Trigger = XDPDMA_GBL_RTRG_CH4_MASK;
623                 InstancePtr->Audio[0].TriggerStatus = XDPDMA_RETRIGGER_DONE;
624                 break;
625         case AudioChan1:
626                 Trigger = XDPDMA_GBL_RTRG_CH5_MASK;
627                 InstancePtr->Audio[1].TriggerStatus = XDPDMA_RETRIGGER_DONE;
628                 break;
629         }
630         XDpDma_WriteReg(InstancePtr->Config.BaseAddr, XDPDMA_GBL, Trigger);
631
632         return XST_SUCCESS;
633 }
634
635 /*************************************************************************/
636 /**
637  *
638  * This function intializes Video Descriptor for Video and Graphics channel
639  *
640  * @param    Channel is a pointer to the current Descriptor of Video or
641  *           Graphics Channel.
642  * @param    FrameBuffer is a pointer to the Frame Buffer structure
643  *
644  * @return   None.
645  *
646  * @note     None.
647  *
648  * **************************************************************************/
649 void XDpDma_InitVideoDescriptor(XDpDma_Descriptor *CurrDesc,
650                                 XDpDma_FrameBuffer *FrameBuffer)
651 {
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;
669 }
670
671 /*************************************************************************/
672 /**
673  *
674  * This function intializes Descriptors for transactions on Audio Channel
675  *
676  * @param    Channel is a pointer to the XDpDma_AudioChannel instance
677  *
678  * @param    AudioBuffer is a pointer to the Audio Buffer structure
679  *
680  * @return   None.
681  *
682  * @note     None.
683  *
684  * **************************************************************************/
685 void XDpDma_InitAudioDescriptor(XDpDma_AudioChannel *Channel,
686                                XDpDma_AudioBuffer *AudioBuffer)
687 {
688         u32 Size;
689         u64 Address;
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);
694
695         Size = AudioBuffer->Size / 4;
696         Address = AudioBuffer->Address;
697         if(Channel->Current == &Channel->Descriptor4) {
698                 XDpDma_SetupAudioDescriptor(&Channel->Descriptor4, Size,
699                                             Address,
700                                             &Channel->Descriptor5);
701                 XDpDma_SetupAudioDescriptor(&Channel->Descriptor5, Size,
702                                             Address + 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);
709         }
710
711         else if(Channel->Current == &Channel->Descriptor0) {
712                 XDpDma_SetupAudioDescriptor(&Channel->Descriptor0, Size,
713                                             Address,
714                                             &Channel->Descriptor1);
715                 XDpDma_SetupAudioDescriptor(&Channel->Descriptor1, Size,
716                                             Address + 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);
723
724         }
725 }
726
727 /*************************************************************************/
728 /**
729  *
730  * This function sets the next Frame Buffers to be displayed on the Video
731  * Channel.
732  *
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.
737  *
738  * @return   None.
739  *
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
743  *
744  * **************************************************************************/
745 void  XDpDma_DisplayVideoFrameBuffer(XDpDma *InstancePtr,
746                                      XDpDma_FrameBuffer *Plane0,
747                                      XDpDma_FrameBuffer *Plane1,
748                                      XDpDma_FrameBuffer *Plane2)
749 {
750         u8 NumPlanes;
751         Xil_AssertVoid(InstancePtr != NULL);
752         Xil_AssertVoid(InstancePtr->Video.VideoInfo != NULL);
753
754         NumPlanes = InstancePtr->Video.VideoInfo->Mode;
755
756         switch(NumPlanes) {
757                 case XDPDMA_VIDEO_CHANNEL2:
758                         Xil_AssertVoid(Plane2 != NULL);
759                         InstancePtr->Video.FrameBuffer[XDPDMA_VIDEO_CHANNEL2] =
760                                 Plane2;
761                 case XDPDMA_VIDEO_CHANNEL1:
762                         Xil_AssertVoid(Plane1 != NULL);
763                         InstancePtr->Video.FrameBuffer[XDPDMA_VIDEO_CHANNEL1] =
764                                 Plane1;
765                 case XDPDMA_VIDEO_CHANNEL0:
766                         Xil_AssertVoid(Plane0 != NULL);
767                         InstancePtr->Video.FrameBuffer[XDPDMA_VIDEO_CHANNEL0] =
768                                 Plane0;
769                         break;
770         }
771
772         if(InstancePtr->Video.Channel[XDPDMA_VIDEO_CHANNEL0].Current == NULL) {
773                 InstancePtr->Video.TriggerStatus = XDPDMA_TRIGGER_EN;
774         }
775         else {
776                 InstancePtr->Video.TriggerStatus = XDPDMA_RETRIGGER_EN;
777         }
778 }
779
780 /*************************************************************************/
781 /**
782  *
783  * This function sets the next Frame Buffers to be displayed on the Graphics
784  * Channel.
785  *
786  * @param    InstancePtr is pointer to the instance of DPDMA.
787  * @param    Plane is a pointer to the Frame Buffer structure.
788  *
789  * @return   None.
790  *
791  * @note     None.
792  *
793  **************************************************************************/
794 void XDpDma_DisplayGfxFrameBuffer(XDpDma *InstancePtr,
795                                   XDpDma_FrameBuffer *Plane)
796 {
797         Xil_AssertVoid(InstancePtr != NULL);
798         Xil_AssertVoid(Plane != NULL);
799
800         InstancePtr->Gfx.FrameBuffer = Plane;
801
802         if(InstancePtr->Gfx.Channel.Current == NULL) {
803                 InstancePtr->Gfx.TriggerStatus = XDPDMA_TRIGGER_EN;
804         }
805         else {
806                 InstancePtr->Gfx.TriggerStatus = XDPDMA_RETRIGGER_EN;
807         }
808 }
809 /*************************************************************************/
810 /**
811  *
812  * This function sets the next Audio Buffer to be played on Audio Channel 0
813  *
814  * @param    InstancePtr is pointer to the instance of DPDMA.
815  * @param    Buffer is a pointer to the attributes of the Audio information
816  *           to be played.
817  * @param    ChannelNum selects between Audio Channel 0 and Audio Channel 1
818  *
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.
822  *
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.
825  *
826  **************************************************************************/
827 int XDpDma_PlayAudio(XDpDma *InstancePtr, XDpDma_AudioBuffer *Buffer,
828                       u8 ChannelNum)
829 {
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);
836
837         Channel = &InstancePtr->Audio[ChannelNum];
838         Channel->Buffer = Buffer;
839
840         if(Channel->Current == NULL) {
841                 Channel->TriggerStatus = XDPDMA_TRIGGER_EN;
842                 Channel->Current = &Channel->Descriptor0;
843                 Channel->Used = 0;
844         }
845
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;
851                         return XST_FAILURE;
852                 }
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;
864                         Channel->Used = 1;
865                         XDpDma_InitAudioDescriptor(Channel, Buffer);
866                 }
867                 else {
868                         return XST_FAILURE;
869                 }
870         }
871
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;
877                         return XST_FAILURE;
878                 }
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);
891                 }
892                 else {
893                         return XST_FAILURE;
894                 }
895         }
896
897         return XST_SUCCESS;
898
899 }
900 /*************************************************************************/
901 /**
902  *
903  * This function sets the channel with the latest framebuffer and the
904  * available descriptor for transfer on the next Vsync.
905  *
906  * @param    InstancePtr is pointer to the instance of DPDMA.
907  * @param    Channel indicates which channels are being setup for transfer.
908  *
909  * @return   None.
910  *
911  * @note     None.
912  *
913  **************************************************************************/
914 void XDpDma_SetupChannel(XDpDma *InstancePtr, XDpDma_ChannelType Channel)
915 {
916         XDpDma_Channel *Chan;
917         XDpDma_AudioChannel *AudChan;
918         XDpDma_FrameBuffer *FB;
919         XDpDma_AudioBuffer *AudioBuffer;
920         u8 Index, NumPlanes;
921         Xil_AssertVoid(InstancePtr != NULL);
922
923         switch(Channel) {
924                 case VideoChan:
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,
934                                                             Index);
935                         }
936                         break;
937
938                 case GraphicsChan:
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);
947                         break;
948
949                 case AudioChan0:
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);
956                         break;
957                 case AudioChan1:
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);
964                         break;
965         }
966 }