ipe_private.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #ifndef _PCILIB_DMA_IPE_PRIVATE_H
  2. #define _PCILIB_DMA_IPE_PRIVATE_H
  3. #include "dma.h"
  4. //#define IPEDMA_ENFORCE_64BIT_MODE 1 /**< enforce 64-bit mode addressing (otherwise it is used only if register 0x18 specifies PCIe gen3 as required by DMA engine) */
  5. #define IPEDMA_CORES 1
  6. #define IPEDMA_MAX_TLP_SIZE 256 /**< Defines maximum TLP in bytes supported by device */
  7. //#define IPEDMA_TLP_SIZE 128 /**< If set, enforces the specified TLP size */
  8. #define IPEDMA_STREAMING_MODE /**< Enables streaming DMA operation mode instead of ring-buffer, the page is written once and forgotten and need to be pushed in queue again */
  9. //#define IPEDMA_STREAMING_CHECKS /**< Enables status checks in streaming mode (it will cause _significant_ performance penalty, max ~ 2 GB/s) */
  10. #define IPEDMA_DMA_PROGRESS_THRESHOLD 1 /**< how many pages the DMA engine should fill before reporting progress */
  11. #define IPEDMA_DESCRIPTOR_SIZE 128
  12. #define IPEDMA_DESCRIPTOR_ALIGNMENT 64
  13. //#define IPEDMA_BUG_LAST_READ /**< We should forbid writting the second last available DMA buffer (the last is forbidden by design) */
  14. //#define IPEDMA_DETECT_PACKETS /**< Using empty_deceted flag */
  15. #define IPEDMA_SUPPORT_EMPTY_DETECTED /**< Avoid waiting for data when empty_detected flag is set in hardware */
  16. #define IPEDMA_CONFIGURE_DMA_MASK /**< Enforce maximal DMA mask (to avoid bounce-buffers) */
  17. #define IPEDMA_REG_ADDR_MASK 0xFFF
  18. #define IPEDMA_REG_BANK_MASK 0xF000
  19. #define IPEDMA_REG_BANK_SHIFT 12
  20. #define REG2VIRT(reg) (ctx->base_addr[(reg&IPEDMA_REG_BANK_MASK)>>IPEDMA_REG_BANK_SHIFT] + (reg&IPEDMA_REG_ADDR_MASK))
  21. #define REG(bank, addr) ((bank<<IPEDMA_REG_BANK_SHIFT)|addr)
  22. #define CONFREG(addr) REG(2, addr)
  23. #define IPEDMA_REG_VERSION 0x18
  24. #define IPEDMA_REG_APPVERSION REG(1, 0x20)
  25. #define IPEDMA_GENERATION(ver) (ver&0xF)
  26. #define IPEDMA_STREAMING(ver) ((ver>>4)&0x1)
  27. #define IPEDMA_VERSION(ver) ((ver>>16)&0xFFFF)
  28. #define IPEDMA_REG_RESET 0x00
  29. #define IPEDMA_REG_CONTROL 0x04
  30. #define IPEDMA_REG_TLP_SIZE 0x0C
  31. #define IPEDMA_REG_TLP_COUNT 0x10
  32. #define IPEDMA_REG_UPDATE_THRESHOLD 0x60
  33. #define IPEDMA_REG_STREAMING_STATUS 0x68
  34. // PCIe gen2
  35. #define IPEDMA_REG2_PAGE_ADDR 0x50
  36. #define IPEDMA_REG2_UPDATE_ADDR 0x54
  37. #define IPEDMA_REG2_LAST_READ 0x58 /**< In streaming mode, we can use it freely to track current status */
  38. #define IPEDMA_REG2_PAGE_COUNT 0x5C
  39. // PCIe gen3
  40. #define IPEDMA_REG3_PAGE_COUNT 0x40 /**< Read-only now */
  41. #define IPEDMA_REG3_PAGE_ADDR 0x50
  42. #define IPEDMA_REG3_UPDATE_ADDR 0x58
  43. #define IPEDMA_REG3_LAST_READ CONFREG(0x80)
  44. #define IPEDMA_FLAG_NOSYNC 0x01 /**< Do not call kernel space for page synchronization */
  45. #define IPEDMA_FLAG_NOSLEEP 0x02 /**< Do not sleep in the loop while waiting for the data */
  46. //#define IPEDMA_MASK_PCIE_GEN 0xF
  47. //#define IPEDMA_MASK_STREAMING_MODE 0x10
  48. #define IPEDMA_RESET_DELAY 10000 /**< Sleep between accessing DMA control and reset registers */
  49. #define IPEDMA_ADD_PAGE_DELAY 1000 /**< Delay between submitting successive DMA pages into IPEDMA_REG_PAGE_ADDR register */
  50. #define IPEDMA_NODATA_SLEEP 100 /**< To keep CPU free, in nanoseconds */
  51. #define WR(addr, value) { *(uint32_t*)(REG2VIRT(addr)) = value; }
  52. #define RD(addr, value) { value = *(uint32_t*)(REG2VIRT(addr)); }
  53. #define WR64(addr, value) { *(uint64_t*)(REG2VIRT(addr)) = value; }
  54. #define RD64(addr, value) { value = *(uint64_t*)(REG2VIRT(addr)); }
  55. #define DEREF(ptr) ((ctx->addr64)?(*(uint64_t*)ptr):(*(uint32_t*)ptr))
  56. typedef uint32_t reg_t;
  57. typedef struct ipe_dma_s ipe_dma_t;
  58. struct ipe_dma_s {
  59. pcilib_dma_context_t dmactx;
  60. //pcilib_dma_engine_description_t engine[2];
  61. const pcilib_register_bank_description_t *dma_bank;
  62. char *base_addr[3];
  63. pcilib_irq_type_t irq_enabled; /**< indicates that IRQs are enabled */
  64. pcilib_irq_type_t irq_preserve; /**< indicates that IRQs should not be disabled during clean-up */
  65. int irq_started; /**< indicates that IRQ subsystem is initialized (detecting which types should be preserverd) */
  66. uint32_t gen; /**< hardware generation, currently corresponds to PCIe generation 2/3 */
  67. uint32_t version; /**< hardware revision */
  68. int mode64; /**< indicates 64-bit operation mode (for gen2, gen3 always operates in 64-bit mode) */
  69. int addr64; /**< indicates that 64-bit addressing mode is used (gen3 only) */
  70. int streaming; /**< indicates if DMA is operating in streaming or ring-buffer mode (gen3 only) */
  71. int started; /**< indicates that DMA buffers are initialized and reading is allowed */
  72. int writting; /**< indicates that we are in middle of writting packet */
  73. int reused; /**< indicates that DMA was found intialized, buffers were reused, and no additional initialization is needed */
  74. int preserve; /**< indicates that DMA should not be stopped during clean-up */
  75. uint32_t dma_flags; /**< Various operation flags, see IPEDMA_FLAG_* */
  76. size_t dma_timeout; /**< DMA timeout,IPEDMA_DMA_TIMEOUT is used by default */
  77. size_t dma_pages; /**< Number of DMA pages in ring buffer to allocate */
  78. pcilib_kmem_handle_t *desc; /**< in-memory status descriptor written by DMA engine upon operation progess */
  79. pcilib_kmem_handle_t *pages; /**< collection of memory-locked pages for DMA operation */
  80. size_t ring_size, page_size; /**< Number of pages in ring buffer and the size of a single DMA page */
  81. size_t last_read, last_written;
  82. uintptr_t last_read_addr;
  83. reg_t reg_last_read; /**< actual location of last_read register (removed from hardware for version 3) */
  84. };
  85. #endif /* _PCILIB_DMA_IPE_PRIVATE_H */