1/****************************************************************************** 2* 3* Author: Xilinx, Inc. 4* 5* 6* This program is free software; you can redistribute it and/or modify it 7* under the terms of the GNU General Public License as published by the 8* Free Software Foundation; either version 2 of the License, or (at your 9* option) any later version. 10* 11* 12* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A 13* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS 14* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD, 15* XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE 16* FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING 17* ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION. 18* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO 19* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY 20* WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM 21* CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND 22* FITNESS FOR A PARTICULAR PURPOSE. 23* 24* 25* Xilinx hardware products are not intended for use in life support 26* appliances, devices, or systems. Use in such applications is 27* expressly prohibited. 28* 29* 30* (c) Copyright 2002-2004 Xilinx Inc. 31* All rights reserved. 32* 33* 34* You should have received a copy of the GNU General Public License along 35* with this program; if not, write to the Free Software Foundation, Inc., 36* 675 Mass Ave, Cambridge, MA 02139, USA. 37* 38* FILENAME: 39* 40* xdma_channel.c 41* 42* DESCRIPTION: 43* 44* This file contains the DMA channel component. This component supports 45* a distributed DMA design in which each device can have it's own dedicated 46* DMA channel, as opposed to a centralized DMA design. This component 47* performs processing for DMA on all devices. 48* 49* See xdma_channel.h for more information about this component. 50* 51* NOTES: 52* 53* None. 54* 55******************************************************************************/ 56 57/***************************** Include Files *********************************/ 58 59#include "xdma_channel.h" 60#include "xbasic_types.h" 61#include "xio.h" 62 63/************************** Constant Definitions *****************************/ 64 65/**************************** Type Definitions *******************************/ 66 67/***************** Macros (Inline Functions) Definitions *********************/ 68 69/************************** Function Prototypes ******************************/ 70 71/****************************************************************************** 72* 73* FUNCTION: 74* 75* XDmaChannel_Initialize 76* 77* DESCRIPTION: 78* 79* This function initializes a DMA channel. This function must be called 80* prior to using a DMA channel. Initialization of a channel includes setting 81* up the registers base address, and resetting the channel such that it's in a 82* known state. Interrupts for the channel are disabled when the channel is 83* reset. 84* 85* ARGUMENTS: 86* 87* InstancePtr contains a pointer to the DMA channel to operate on. 88* 89* BaseAddress contains the base address of the registers for the DMA channel. 90* 91* RETURN VALUE: 92* 93* XST_SUCCESS indicating initialization was successful. 94* 95* NOTES: 96* 97* None. 98* 99******************************************************************************/ 100XStatus 101XDmaChannel_Initialize(XDmaChannel * InstancePtr, u32 BaseAddress) 102{ 103 /* assert to verify input arguments, don't assert base address */ 104 105 XASSERT_NONVOID(InstancePtr != NULL); 106 107 /* setup the base address of the registers for the DMA channel such 108 * that register accesses can be done 109 */ 110 InstancePtr->RegBaseAddress = BaseAddress; 111 112 /* initialize the scatter gather list such that it indicates it has not 113 * been created yet and the DMA channel is ready to use (initialized) 114 */ 115 InstancePtr->GetPtr = NULL; 116 InstancePtr->PutPtr = NULL; 117 InstancePtr->CommitPtr = NULL; 118 InstancePtr->LastPtr = NULL; 119 120 InstancePtr->TotalDescriptorCount = 0; 121 InstancePtr->ActiveDescriptorCount = 0; 122 InstancePtr->IsReady = XCOMPONENT_IS_READY; 123 124 /* initialize the version of the component 125 */ 126 XVersion_FromString(&InstancePtr->Version, (s8 *)"1.00a"); 127 128 /* reset the DMA channel such that it's in a known state and ready 129 * and indicate the initialization occured with no errors, note that 130 * the is ready variable must be set before this call or reset will assert 131 */ 132 XDmaChannel_Reset(InstancePtr); 133 134 return XST_SUCCESS; 135} 136 137/****************************************************************************** 138* 139* FUNCTION: 140* 141* XDmaChannel_IsReady 142* 143* DESCRIPTION: 144* 145* This function determines if a DMA channel component has been successfully 146* initialized such that it's ready to use. 147* 148* ARGUMENTS: 149* 150* InstancePtr contains a pointer to the DMA channel to operate on. 151* 152* RETURN VALUE: 153* 154* TRUE if the DMA channel component is ready, FALSE otherwise. 155* 156* NOTES: 157* 158* None. 159* 160******************************************************************************/ 161u32 162XDmaChannel_IsReady(XDmaChannel * InstancePtr) 163{ 164 /* assert to verify input arguments used by the base component */ 165 166 XASSERT_NONVOID(InstancePtr != NULL); 167 168 return InstancePtr->IsReady == XCOMPONENT_IS_READY; 169} 170 171/****************************************************************************** 172* 173* FUNCTION: 174* 175* XDmaChannel_GetVersion 176* 177* DESCRIPTION: 178* 179* This function gets the software version for the specified DMA channel 180* component. 181* 182* ARGUMENTS: 183* 184* InstancePtr contains a pointer to the DMA channel to operate on. 185* 186* RETURN VALUE: 187* 188* A pointer to the software version of the specified DMA channel. 189* 190* NOTES: 191* 192* None. 193* 194******************************************************************************/ 195XVersion * 196XDmaChannel_GetVersion(XDmaChannel * InstancePtr) 197{ 198 /* assert to verify input arguments */ 199 200 XASSERT_NONVOID(InstancePtr != NULL); 201 XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); 202 203 /* return a pointer to the version of the DMA channel */ 204 205 return &InstancePtr->Version; 206} 207 208/****************************************************************************** 209* 210* FUNCTION: 211* 212* XDmaChannel_SelfTest 213* 214* DESCRIPTION: 215* 216* This function performs a self test on the specified DMA channel. This self 217* test is destructive as the DMA channel is reset and a register default is 218* verified. 219* 220* ARGUMENTS: 221* 222* InstancePtr is a pointer to the DMA channel to be operated on. 223* 224* RETURN VALUE: 225* 226* XST_SUCCESS is returned if the self test is successful, or one of the 227* following errors. 228* 229* XST_DMA_RESET_REGISTER_ERROR Indicates the control register value 230* after a reset was not correct 231* 232* NOTES: 233* 234* This test does not performs a DMA transfer to test the channel because the 235* DMA hardware will not currently allow a non-local memory transfer to non-local 236* memory (memory copy), but only allows a non-local memory to or from the device 237* memory (typically a FIFO). 238* 239******************************************************************************/ 240 241#define XDC_CONTROL_REG_RESET_MASK 0x98000000UL /* control reg reset value */ 242 243XStatus 244XDmaChannel_SelfTest(XDmaChannel * InstancePtr) 245{ 246 u32 ControlReg; 247 248 /* assert to verify input arguments */ 249 250 XASSERT_NONVOID(InstancePtr != NULL); 251 XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); 252 253 /* reset the DMA channel such that it's in a known state before the test 254 * it resets to no interrupts enabled, the desired state for the test 255 */ 256 XDmaChannel_Reset(InstancePtr); 257 258 /* this should be the first test to help prevent a lock up with the polling 259 * loop that occurs later in the test, check the reset value of the DMA 260 * control register to make sure it's correct, return with an error if not 261 */ 262 ControlReg = XDmaChannel_GetControl(InstancePtr); 263 if (ControlReg != XDC_CONTROL_REG_RESET_MASK) { 264 return XST_DMA_RESET_REGISTER_ERROR; 265 } 266 267 return XST_SUCCESS; 268} 269 270/****************************************************************************** 271* 272* FUNCTION: 273* 274* XDmaChannel_Reset 275* 276* DESCRIPTION: 277* 278* This function resets the DMA channel. This is a destructive operation such 279* that it should not be done while a channel is being used. If the DMA channel 280* is transferring data into other blocks, such as a FIFO, it may be necessary 281* to reset other blocks. This function does not modify the contents of a 282* scatter gather list for a DMA channel such that the user is responsible for 283* getting buffer descriptors from the list if necessary. 284* 285* ARGUMENTS: 286* 287* InstancePtr contains a pointer to the DMA channel to operate on. 288* 289* RETURN VALUE: 290* 291* None. 292* 293* NOTES: 294* 295* None. 296* 297******************************************************************************/ 298void 299XDmaChannel_Reset(XDmaChannel * InstancePtr) 300{ 301 /* assert to verify input arguments */ 302 303 XASSERT_VOID(InstancePtr != NULL); 304 XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); 305 306 /* reset the DMA channel such that it's in a known state, the reset 307 * register is self clearing such that it only has to be set 308 */ 309 XIo_Out32(InstancePtr->RegBaseAddress + XDC_RST_REG_OFFSET, 310 XDC_RESET_MASK); 311} 312 313/****************************************************************************** 314* 315* FUNCTION: 316* 317* XDmaChannel_GetControl 318* 319* DESCRIPTION: 320* 321* This function gets the control register contents of the DMA channel. 322* 323* ARGUMENTS: 324* 325* InstancePtr contains a pointer to the DMA channel to operate on. 326* 327* RETURN VALUE: 328* 329* The control register contents of the DMA channel. One or more of the 330* following values may be contained the register. Each of the values are 331* unique bit masks. 332* 333* XDC_DMACR_SOURCE_INCR_MASK Increment the source address 334* XDC_DMACR_DEST_INCR_MASK Increment the destination address 335* XDC_DMACR_SOURCE_LOCAL_MASK Local source address 336* XDC_DMACR_DEST_LOCAL_MASK Local destination address 337* XDC_DMACR_SG_ENABLE_MASK Scatter gather enable 338* XDC_DMACR_GEN_BD_INTR_MASK Individual buffer descriptor interrupt 339* XDC_DMACR_LAST_BD_MASK Last buffer descriptor in a packet 340* 341* NOTES: 342* 343* None. 344* 345******************************************************************************/ 346u32 347XDmaChannel_GetControl(XDmaChannel * InstancePtr) 348{ 349 /* assert to verify input arguments */ 350 351 XASSERT_NONVOID(InstancePtr != NULL); 352 XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); 353 354 /* return the contents of the DMA control register */ 355 356 return XIo_In32(InstancePtr->RegBaseAddress + XDC_DMAC_REG_OFFSET); 357} 358 359/****************************************************************************** 360* 361* FUNCTION: 362* 363* XDmaChannel_SetControl 364* 365* DESCRIPTION: 366* 367* This function sets the control register of the specified DMA channel. 368* 369* ARGUMENTS: 370* 371* InstancePtr contains a pointer to the DMA channel to operate on. 372* 373* Control contains the value to be written to the control register of the DMA 374* channel. One or more of the following values may be contained the register. 375* Each of the values are unique bit masks such that they may be ORed together 376* to enable multiple bits or inverted and ANDed to disable multiple bits. 377* 378* XDC_DMACR_SOURCE_INCR_MASK Increment the source address 379* XDC_DMACR_DEST_INCR_MASK Increment the destination address 380* XDC_DMACR_SOURCE_LOCAL_MASK Local source address 381* XDC_DMACR_DEST_LOCAL_MASK Local destination address 382* XDC_DMACR_SG_ENABLE_MASK Scatter gather enable 383* XDC_DMACR_GEN_BD_INTR_MASK Individual buffer descriptor interrupt 384* XDC_DMACR_LAST_BD_MASK Last buffer descriptor in a packet 385* 386* RETURN VALUE: 387* 388* None. 389* 390* NOTES: 391* 392* None. 393* 394******************************************************************************/ 395void 396XDmaChannel_SetControl(XDmaChannel * InstancePtr, u32 Control) 397{ 398 /* assert to verify input arguments except the control which can't be 399 * asserted since all values are valid 400 */ 401 XASSERT_VOID(InstancePtr != NULL); 402 XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); 403 404 /* set the DMA control register to the specified value */ 405 406 XIo_Out32(InstancePtr->RegBaseAddress + XDC_DMAC_REG_OFFSET, Control); 407} 408 409/****************************************************************************** 410* 411* FUNCTION: 412* 413* XDmaChannel_GetStatus 414* 415* DESCRIPTION: 416* 417* This function gets the status register contents of the DMA channel. 418* 419* ARGUMENTS: 420* 421* InstancePtr contains a pointer to the DMA channel to operate on. 422* 423* RETURN VALUE: 424* 425* The status register contents of the DMA channel. One or more of the 426* following values may be contained the register. Each of the values are 427* unique bit masks. 428* 429* XDC_DMASR_BUSY_MASK The DMA channel is busy 430* XDC_DMASR_BUS_ERROR_MASK A bus error occurred 431* XDC_DMASR_BUS_TIMEOUT_MASK A bus timeout occurred 432* XDC_DMASR_LAST_BD_MASK The last buffer descriptor of a packet 433* 434* NOTES: 435* 436* None. 437* 438******************************************************************************/ 439u32 440XDmaChannel_GetStatus(XDmaChannel * InstancePtr) 441{ 442 /* assert to verify input arguments */ 443 444 XASSERT_NONVOID(InstancePtr != NULL); 445 XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); 446 447 /* return the contents of the DMA status register */ 448 449 return XIo_In32(InstancePtr->RegBaseAddress + XDC_DMAS_REG_OFFSET); 450} 451 452/****************************************************************************** 453* 454* FUNCTION: 455* 456* XDmaChannel_SetIntrStatus 457* 458* DESCRIPTION: 459* 460* This function sets the interrupt status register of the specified DMA channel. 461* Setting any bit of the interrupt status register will clear the bit to 462* indicate the interrupt processing has been completed. The definitions of each 463* bit in the register match the definition of the bits in the interrupt enable 464* register. 465* 466* ARGUMENTS: 467* 468* InstancePtr contains a pointer to the DMA channel to operate on. 469* 470* Status contains the value to be written to the status register of the DMA 471* channel. One or more of the following values may be contained the register. 472* Each of the values are unique bit masks such that they may be ORed together 473* to enable multiple bits or inverted and ANDed to disable multiple bits. 474* 475* XDC_IXR_DMA_DONE_MASK The dma operation is done 476* XDC_IXR_DMA_ERROR_MASK The dma operation had an error 477* XDC_IXR_PKT_DONE_MASK A packet is complete 478* XDC_IXR_PKT_THRESHOLD_MASK The packet count threshold reached 479* XDC_IXR_PKT_WAIT_BOUND_MASK The packet wait bound reached 480* XDC_IXR_SG_DISABLE_ACK_MASK The scatter gather disable completed 481* XDC_IXR_BD_MASK A buffer descriptor is done 482* 483* RETURN VALUE: 484* 485* None. 486* 487* NOTES: 488* 489* None. 490* 491******************************************************************************/ 492void 493XDmaChannel_SetIntrStatus(XDmaChannel * InstancePtr, u32 Status) 494{ 495 /* assert to verify input arguments except the status which can't be 496 * asserted since all values are valid 497 */ 498 XASSERT_VOID(InstancePtr != NULL); 499 XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); 500 501 /* set the interrupt status register with the specified value such that 502 * all bits which are set in the register are cleared effectively clearing 503 * any active interrupts 504 */ 505 XIo_Out32(InstancePtr->RegBaseAddress + XDC_IS_REG_OFFSET, Status); 506} 507 508/****************************************************************************** 509* 510* FUNCTION: 511* 512* XDmaChannel_GetIntrStatus 513* 514* DESCRIPTION: 515* 516* This function gets the interrupt status register of the specified DMA channel. 517* The interrupt status register indicates which interrupts are active 518* for the DMA channel. If an interrupt is active, the status register must be 519* set (written) with the bit set for each interrupt which has been processed 520* in order to clear the interrupts. The definitions of each bit in the register 521* match the definition of the bits in the interrupt enable register. 522* 523* ARGUMENTS: 524* 525* InstancePtr contains a pointer to the DMA channel to operate on. 526* 527* RETURN VALUE: 528* 529* The interrupt status register contents of the specified DMA channel. 530* One or more of the following values may be contained the register. 531* Each of the values are unique bit masks. 532* 533* XDC_IXR_DMA_DONE_MASK The dma operation is done 534* XDC_IXR_DMA_ERROR_MASK The dma operation had an error 535* XDC_IXR_PKT_DONE_MASK A packet is complete 536* XDC_IXR_PKT_THRESHOLD_MASK The packet count threshold reached 537* XDC_IXR_PKT_WAIT_BOUND_MASK The packet wait bound reached 538* XDC_IXR_SG_DISABLE_ACK_MASK The scatter gather disable completed 539* XDC_IXR_SG_END_MASK Current descriptor was the end of the list 540* XDC_IXR_BD_MASK A buffer descriptor is done 541* 542* NOTES: 543* 544* None. 545* 546******************************************************************************/ 547u32 548XDmaChannel_GetIntrStatus(XDmaChannel * InstancePtr) 549{ 550 /* assert to verify input arguments */ 551 552 XASSERT_NONVOID(InstancePtr != NULL); 553 XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); 554 555 /* return the contents of the interrupt status register */ 556 557 return XIo_In32(InstancePtr->RegBaseAddress + XDC_IS_REG_OFFSET); 558} 559 560/****************************************************************************** 561* 562* FUNCTION: 563* 564* XDmaChannel_SetIntrEnable 565* 566* DESCRIPTION: 567* 568* This function sets the interrupt enable register of the specified DMA 569* channel. The interrupt enable register contains bits which enable 570* individual interrupts for the DMA channel. The definitions of each bit 571* in the register match the definition of the bits in the interrupt status 572* register. 573* 574* ARGUMENTS: 575* 576* InstancePtr contains a pointer to the DMA channel to operate on. 577* 578* Enable contains the interrupt enable register contents to be written 579* in the DMA channel. One or more of the following values may be contained 580* the register. Each of the values are unique bit masks such that they may be 581* ORed together to enable multiple bits or inverted and ANDed to disable 582* multiple bits. 583* 584* XDC_IXR_DMA_DONE_MASK The dma operation is done 585* XDC_IXR_DMA_ERROR_MASK The dma operation had an error 586* XDC_IXR_PKT_DONE_MASK A packet is complete 587* XDC_IXR_PKT_THRESHOLD_MASK The packet count threshold reached 588* XDC_IXR_PKT_WAIT_BOUND_MASK The packet wait bound reached 589* XDC_IXR_SG_DISABLE_ACK_MASK The scatter gather disable completed 590* XDC_IXR_SG_END_MASK Current descriptor was the end of the list 591* XDC_IXR_BD_MASK A buffer descriptor is done 592* 593* RETURN VALUE: 594* 595* None. 596* 597* NOTES: 598* 599* None. 600* 601******************************************************************************/ 602void 603XDmaChannel_SetIntrEnable(XDmaChannel * InstancePtr, u32 Enable) 604{ 605 /* assert to verify input arguments except the enable which can't be 606 * asserted since all values are valid 607 */ 608 XASSERT_VOID(InstancePtr != NULL); 609 XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); 610 611 /* set the interrupt enable register to the specified value */ 612 613 XIo_Out32(InstancePtr->RegBaseAddress + XDC_IE_REG_OFFSET, Enable); 614} 615 616/****************************************************************************** 617* 618* FUNCTION: 619* 620* XDmaChannel_GetIntrEnable 621* 622* DESCRIPTION: 623* 624* This function gets the interrupt enable of the DMA channel. The 625* interrupt enable contains flags which enable individual interrupts for the 626* DMA channel. The definitions of each bit in the register match the definition 627* of the bits in the interrupt status register. 628* 629* ARGUMENTS: 630* 631* InstancePtr contains a pointer to the DMA channel to operate on. 632* 633* RETURN VALUE: 634* 635* The interrupt enable of the DMA channel. One or more of the following values 636* may be contained the register. Each of the values are unique bit masks. 637* 638* XDC_IXR_DMA_DONE_MASK The dma operation is done 639* XDC_IXR_DMA_ERROR_MASK The dma operation had an error 640* XDC_IXR_PKT_DONE_MASK A packet is complete 641* XDC_IXR_PKT_THRESHOLD_MASK The packet count threshold reached 642* XDC_IXR_PKT_WAIT_BOUND_MASK The packet wait bound reached 643* XDC_IXR_SG_DISABLE_ACK_MASK The scatter gather disable completed 644* XDC_IXR_BD_MASK A buffer descriptor is done 645* 646* NOTES: 647* 648* None. 649* 650******************************************************************************/ 651u32 652XDmaChannel_GetIntrEnable(XDmaChannel * InstancePtr) 653{ 654 /* assert to verify input arguments */ 655 656 XASSERT_NONVOID(InstancePtr != NULL); 657 XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); 658 659 /* return the contents of the interrupt enable register */ 660 661 return XIo_In32(InstancePtr->RegBaseAddress + XDC_IE_REG_OFFSET); 662} 663 664/****************************************************************************** 665* 666* FUNCTION: 667* 668* XDmaChannel_Transfer 669* 670* DESCRIPTION: 671* 672* This function starts the DMA channel transferring data from a memory source 673* to a memory destination. This function only starts the operation and returns 674* before the operation may be complete. If the interrupt is enabled, an 675* interrupt will be generated when the operation is complete, otherwise it is 676* necessary to poll the channel status to determine when it's complete. It is 677* the responsibility of the caller to determine when the operation is complete 678* by handling the generated interrupt or polling the status. It is also the 679* responsibility of the caller to ensure that the DMA channel is not busy with 680* another transfer before calling this function. 681* 682* ARGUMENTS: 683* 684* InstancePtr contains a pointer to the DMA channel to operate on. 685* 686* SourcePtr contains a pointer to the source memory where the data is to 687* be tranferred from and must be 32 bit aligned. 688* 689* DestinationPtr contains a pointer to the destination memory where the data 690* is to be transferred and must be 32 bit aligned. 691* 692* ByteCount contains the number of bytes to transfer during the DMA operation. 693* 694* RETURN VALUE: 695* 696* None. 697* 698* NOTES: 699* 700* The DMA h/w will not currently allow a non-local memory transfer to non-local 701* memory (memory copy), but only allows a non-local memory to or from the device 702* memory (typically a FIFO). 703* 704* It is the responsibility of the caller to ensure that the cache is 705* flushed and invalidated both before and after the DMA operation completes 706* if the memory pointed to is cached. The caller must also ensure that the 707* pointers contain a physical address rather than a virtual address 708* if address translation is being used. 709* 710******************************************************************************/ 711void 712XDmaChannel_Transfer(XDmaChannel * InstancePtr, 713 u32 * SourcePtr, u32 * DestinationPtr, u32 ByteCount) 714{ 715 /* assert to verify input arguments and the alignment of any arguments 716 * which have expected alignments 717 */ 718 XASSERT_VOID(InstancePtr != NULL); 719 XASSERT_VOID(SourcePtr != NULL); 720 XASSERT_VOID(((u32) SourcePtr & 3) == 0); 721 XASSERT_VOID(DestinationPtr != NULL); 722 XASSERT_VOID(((u32) DestinationPtr & 3) == 0); 723 XASSERT_VOID(ByteCount != 0); 724 XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); 725 726 /* setup the source and destination address registers for the transfer */ 727 728 XIo_Out32(InstancePtr->RegBaseAddress + XDC_SA_REG_OFFSET, 729 (u32) SourcePtr); 730 731 XIo_Out32(InstancePtr->RegBaseAddress + XDC_DA_REG_OFFSET, 732 (u32) DestinationPtr); 733 734 /* start the DMA transfer to copy from the source buffer to the 735 * destination buffer by writing the length to the length register 736 */ 737 XIo_Out32(InstancePtr->RegBaseAddress + XDC_LEN_REG_OFFSET, ByteCount); 738} 739