Re: [PATCH] DMA : Added DMA API for Raspberrypi

2016-08-25 Thread Pavel Pisa
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

2016-08-20 Thread Mudit Jain
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