Re: [PATCH] DMA : Added DMA API for Raspberrypi
Hello Mudit Jain, I have tried to test the DMA API code I have setup temporary branch on my RTEMS tests repo https://github.com/ppisa/rtems/tree/rtems-rpi-devel-dma-test I have applied patches extracted from your GitHub repository Re: [PATCH] Mailbox : Extending functionality https://github.com/ppisa/rtems/commit/640071d0e16f0a29019e09c0308a364373b4b0e1 with changes in alignment and padding which I have described in review [PATCH] DMA : Added DMA API for Raspberrypi https://github.com/ppisa/rtems/commit/d1f1ed30f918789b3ed91771ab743c7a1e6bf649 I have added missing defines to c/src/lib/libbsp/arm/raspberrypi/include/irq.h which has been probably lost during your rebasing to master. Without these code cannot compile. My patches arm/raspberrypi: DMA API: correct obvious errors https://github.com/ppisa/rtems/commit/ec34b48b9b87462276f93ab07f7522b84c1819bd Correct your code to at least initialization call suceed arm/raspberrypi: DMA API: ensure that channel is enabled when it is configured. https://github.com/ppisa/rtems/commit/ec34b48b9b87462276f93ab07f7522b84c1819bd Because even after above correction I have not observed channel activity, I have added code to ensure that channel is enabled in a global enable register arm/raspberrypi: DMA API: add simple memory to memory transfer test https://github.com/ppisa/rtems/commit/6c7d9463c83ee2d084a88235dbdaabd32b60b1a0 Quite dirty test integrated into RTEMS samples ticker application to check if DMA API works. System does not crash/stuck during testing, operations returns success status but even after more ticks there data do not appear in destination position albeit DMA request 0 should be permanently assigned according to the manual so data should be copied. rpi_dma_init ... rpi_dma_init 0 rpi_dma_allocate ... rpi_dma_allocate 0 rpi_dma_setup_src ... rpi_dma_setup_src 0 rpi_dma_setup_dst ... rpi_dma_setup_dst 0 rpi_dma_setup_intr ... rpi_dma_setup_intr 0 rpi_dma_start ... rpi_dma_start 0 dma test result 11>00 22>00 33>00 44>00 55>00 66>00 77>00 88>00 simple mem2mem DMA test has FAILED It is important that at least some functional tests run to prove that code development heads in the right direction. Please, check if I use API intended way and try to help us to make code more acceptable for mainline. We need to declare the state for project evaluation forms. See see remarks inlined in the following DMA patch On Saturday 20 of August 2016 17:33:18 Mudit Jain wrote: > Brief API Description > > rpi_dma_init -> Initializes the channel structure > and its members for that particular channel, gets > the physical address of the control block structure > and installs the interrupt handler. > > rpi_dma_allocate -> Allocates the channel if it is > not busy > > rpi_dma_setup_dst & rpi_dma_setup_src -> These setup > src and dst parameters like dreq, width. Basically they > configure the info section of the control block structure > of that particular channel. > > rpi_dma_setup_intr -> These will assign the handler > function for channel interrupt. This basically again > updates the channel structure with that function. > Note : rpi_dma_intr is the callback function for the > interrupt controller and calls this function internally. > > rpi_dma_start -> Here you provide the virtual address, > the channel to be used and the width. Internally, it > converts the address to physical address and configures > the control block for that channel. > It flushes and invalidates the cache and writes the physical > address of the control block to a particular register > corresponding to the channel. > > rpi_dma_free -> Frees the channel > --- > c/src/lib/libbsp/arm/raspberrypi/Makefile.am | 4 + > c/src/lib/libbsp/arm/raspberrypi/include/dma.h | 200 > c/src/lib/libbsp/arm/raspberrypi/misc/dma.c| 618 > + 3 files changed, 822 insertions(+) > create mode 100644 c/src/lib/libbsp/arm/raspberrypi/include/dma.h > create mode 100644 c/src/lib/libbsp/arm/raspberrypi/misc/dma.c > > diff --git a/c/src/lib/libbsp/arm/raspberrypi/Makefile.am > b/c/src/lib/libbsp/arm/raspberrypi/Makefile.am index 4b111ad..5b0e92e > 100644 > --- a/c/src/lib/libbsp/arm/raspberrypi/Makefile.am > +++ b/c/src/lib/libbsp/arm/raspberrypi/Makefile.am > @@ -51,6 +51,7 @@ include_bsp_HEADERS += include/rpi-gpio.h > include_bsp_HEADERS += include/i2c.h > include_bsp_HEADERS += include/spi.h > include_bsp_HEADERS += include/mailbox.h > +include_bsp_HEADERS += include/dma.h > include_bsp_HEADERS += include/vc.h > include_bsp_HEADERS += include/rpi-fb.h > include_bsp_HEADERS += console/fbcons.h > @@ -124,6 +125,9 @@ libbsp_a_SOURCES += console/fb.c > libb
[PATCH] DMA : Added DMA API for Raspberrypi
Brief API Description rpi_dma_init -> Initializes the channel structure and its members for that particular channel, gets the physical address of the control block structure and installs the interrupt handler. rpi_dma_allocate -> Allocates the channel if it is not busy rpi_dma_setup_dst & rpi_dma_setup_src -> These setup src and dst parameters like dreq, width. Basically they configure the info section of the control block structure of that particular channel. rpi_dma_setup_intr -> These will assign the handler function for channel interrupt. This basically again updates the channel structure with that function. Note : rpi_dma_intr is the callback function for the interrupt controller and calls this function internally. rpi_dma_start -> Here you provide the virtual address, the channel to be used and the width. Internally, it converts the address to physical address and configures the control block for that channel. It flushes and invalidates the cache and writes the physical address of the control block to a particular register corresponding to the channel. rpi_dma_free -> Frees the channel --- c/src/lib/libbsp/arm/raspberrypi/Makefile.am | 4 + c/src/lib/libbsp/arm/raspberrypi/include/dma.h | 200 c/src/lib/libbsp/arm/raspberrypi/misc/dma.c| 618 + 3 files changed, 822 insertions(+) create mode 100644 c/src/lib/libbsp/arm/raspberrypi/include/dma.h create mode 100644 c/src/lib/libbsp/arm/raspberrypi/misc/dma.c diff --git a/c/src/lib/libbsp/arm/raspberrypi/Makefile.am b/c/src/lib/libbsp/arm/raspberrypi/Makefile.am index 4b111ad..5b0e92e 100644 --- a/c/src/lib/libbsp/arm/raspberrypi/Makefile.am +++ b/c/src/lib/libbsp/arm/raspberrypi/Makefile.am @@ -51,6 +51,7 @@ include_bsp_HEADERS += include/rpi-gpio.h include_bsp_HEADERS += include/i2c.h include_bsp_HEADERS += include/spi.h include_bsp_HEADERS += include/mailbox.h +include_bsp_HEADERS += include/dma.h include_bsp_HEADERS += include/vc.h include_bsp_HEADERS += include/rpi-fb.h include_bsp_HEADERS += console/fbcons.h @@ -124,6 +125,9 @@ libbsp_a_SOURCES += console/fb.c libbsp_a_SOURCES += console/fbcons.c libbsp_a_SOURCES += console/outch.c +# DMA +libbsp_a_SOURCES += misc/dma.c + # Mailbox libbsp_a_SOURCES += misc/mailbox.c diff --git a/c/src/lib/libbsp/arm/raspberrypi/include/dma.h b/c/src/lib/libbsp/arm/raspberrypi/include/dma.h new file mode 100644 index 000..c49a575 --- /dev/null +++ b/c/src/lib/libbsp/arm/raspberrypi/include/dma.h @@ -0,0 +1,200 @@ +/** + * @file + * + * @ingroup raspberrypi_dma + * + * @brief Direct memory access (DMA) support. + */ + +#ifndef LIBBSP_ARM_RASPBERRYPI_DMA_H +#define LIBBSP_ARM_RASPBERRYPI_DMA_H + +#define BCM_DMA_BLOCK_SIZE 512 + +/* DMA0-DMA15 but DMA15 is special */ +#define BCM_DMA_CH_MAX 12 + +/* request CH for any nubmer */ +#define BCM_DMA_CH_INVALID ( -1 ) +#define BCM_DMA_CH_ANY ( -1 ) + +/* Peripheral DREQ Signals (4.2.1.3) */ +#define BCM_DMA_DREQ_NONE 0 +#define BCM_DMA_DREQ_EMMC 11 +#define BCM_DMA_DREQ_SDHOST 13 + +#define BCM_DMA_SAME_ADDR 0 +#define BCM_DMA_INC_ADDR 1 + +#define BCM_DMA_32BIT 0 +#define BCM_DMA_128BIT 1 + +/* + * Defines for converting physical address to VideoCore bus address and back + */ +#define BCM2835_VCBUS_SDRAM_CACHED 0x4000 +#define BCM2835_VCBUS_IO_BASE 0x7E00 +#define BCM2835_VCBUS_SDRAM_UNCACHED 0xC000 + +#ifdef SOC_BCM2836 +#define BCM2835_VCBUS_SDRAM_BASE BCM2835_VCBUS_SDRAM_UNCACHED +#else +#define BCM2835_VCBUS_SDRAM_BASE BCM2835_VCBUS_SDRAM_CACHED +#endif +#define BCM2835_ARM_IO_SIZE 0x0100 + +/* + * Convert physical address to VC bus address. Should be used + * when submitting address over mailbox interface + */ +#define PHYS_TO_VCBUS( pa ) ( ( pa ) + BCM2835_VCBUS_SDRAM_BASE ) + +/* Check whether pa bellong top IO window */ +#define BCM2835_ARM_IS_IO( pa ) ( ( ( pa ) >= RPI_PERIPHERAL_BASE ) && \ + ( ( pa ) < RPI_PERIPHERAL_BASE + \ +BCM2835_ARM_IO_SIZE ) ) + +/* + * Convert physical address in IO space to VC bus address. + */ +#define IO_TO_VCBUS( pa ) ( ( ( pa ) - RPI_PERIPHERAL_BASE ) + \ +BCM2835_VCBUS_IO_BASE ) + +/* + * Convert address from VC bus space to physical. Should be used + * when address is returned by VC over mailbox interface. e.g. + * framebuffer base + */ +#define VCBUS_TO_PHYS( vca ) ( ( vca ) & ~( BCM2835_VCBUS_SDRAM_BASE ) ) + +struct bus_dmamap { + void *buffer_begin; + uint32_t buffer_size; +}; + +typedef struct bus_dmamap *bus_dmamap_t; + +/* + * bus_dma_segment_t + * + * Describes a single contiguous DMA transaction. Values + * are suitable for programming into DMA registers. + */ +typedef struct bus_dma_segment { + unsigned int ds_addr; /* DMA address */ + unsigned int ds_len; /* length of transfer */ +} bus_dma_segment_t; + +/* DMA Control Block - 256bit aligned (p.40) */ +struct bcm_dma_cb { + uint32_t