Commit fe83df23 authored by Federico Vaga's avatar Federico Vaga

sw:drv: data from FPGA is always little-endian

The data coming out from the FMC-ADC-110M FPGA is always using the
little-endian byte order. This means that we need to fix the byte
order only on big-endian CPUs.

This allows to improve performances on SVEC-based designs since there
is no need anymore to fix the endianness in software becuase it is
already done in hardware.
Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
parent a7b1c459
...@@ -4,53 +4,40 @@ ...@@ -4,53 +4,40 @@
* Author: Federico Vaga <federico.vaga@cern.ch> * Author: Federico Vaga <federico.vaga@cern.ch>
*/ */
#include <linux/kernel.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/types.h>
#ifdef CONFIG_FMC_ADC_SVEC #ifdef CONFIG_FMC_ADC_SVEC
#include "vmebus.h" #include "vmebus.h"
#endif #endif
#include "fmc-adc-100m14b4cha-private.h" #include "fmc-adc-100m14b4cha-private.h"
/* Endianess */
#ifndef LITTLE_ENDIAN
#define LITTLE_ENDIAN 0
#endif
#ifndef BIG_ENDIAN
#define BIG_ENDIAN 1
#endif
static void zfad_dma_done(struct zio_cset *cset); static void zfad_dma_done(struct zio_cset *cset);
static int __get_endian(void)
{
int i = 1;
char *p = (char *)&i;
if (p[0] == 1)
return LITTLE_ENDIAN;
else
return BIG_ENDIAN;
}
/** /**
* Fix endianess from big to host endianess (32bit) * Fix endianness from little to host endianess (32bit)
* @byte_lenght: number of bytes to fix (32bit aligned)
* @buffer: buffer to fix
*
* Data coming from the ADC IP-CORE are little-endian, so on big endian CPUs
* we have to swap the byte order.
*/ */
static void __endianness(unsigned int byte_length, void *buffer) #ifdef __BIG_ENDIAN
static void fix_endianness(unsigned int byte_length, void *buffer)
{ {
/* CPU may be little endian, VME is big endian */ /* swap samples and trig timetag all seen as 32bits words */
if (__get_endian() == LITTLE_ENDIAN) { int i;
/* swap samples and trig timetag all seen as 32bits words */ int size = byte_length / 4;
int i; uint32_t *ptr = buffer;
int size = byte_length / 4;
uint32_t *ptr = buffer;
for (i = 0; i < size; ++i, ++ptr) for (i = 0; i < size; ++i, ++ptr)
*ptr = __be32_to_cpu(*ptr); le32_to_cpus(ptr);
}
} }
#else
static void fix_endianness(unsigned int byte_length, void *buffer){ return; }
#endif
struct zfad_timetag { struct zfad_timetag {
uint32_t sec_low; uint32_t sec_low;
...@@ -320,12 +307,7 @@ static int zfad_dma_block_to_pages(struct page **pages, unsigned int nr_pages, ...@@ -320,12 +307,7 @@ static int zfad_dma_block_to_pages(struct page **pages, unsigned int nr_pages,
static void zfad_dma_context_exit_svec(struct zio_cset *cset, static void zfad_dma_context_exit_svec(struct zio_cset *cset,
struct zfad_block *zfad_block) struct zfad_block *zfad_block)
{ {
struct fa_dev *fa = cset->zdev->priv_d;
kfree(zfad_block->dma_ctx); kfree(zfad_block->dma_ctx);
if (fa_is_flag_set(fa, FMC_ADC_DATA_NO_SWAP))
return;
__endianness(zfad_block->block->datalen, zfad_block->block->data);
} }
static void zfad_dma_context_exit(struct zio_cset *cset, static void zfad_dma_context_exit(struct zio_cset *cset,
...@@ -333,6 +315,7 @@ static void zfad_dma_context_exit(struct zio_cset *cset, ...@@ -333,6 +315,7 @@ static void zfad_dma_context_exit(struct zio_cset *cset,
{ {
struct fa_dev *fa = cset->zdev->priv_d; struct fa_dev *fa = cset->zdev->priv_d;
fix_endianness(zfad_block->block->datalen, zfad_block->block->data);
if (fa_is_flag_set(fa, FMC_ADC_SVEC)) if (fa_is_flag_set(fa, FMC_ADC_SVEC))
zfad_dma_context_exit_svec(cset, zfad_block); zfad_dma_context_exit_svec(cset, zfad_block);
} }
......
...@@ -7,9 +7,8 @@ ...@@ -7,9 +7,8 @@
#ifndef __FMC_ADC_PDATA_H__ #ifndef __FMC_ADC_PDATA_H__
#define __FMC_ADC_PDATA_H__ #define __FMC_ADC_PDATA_H__
#define FMC_ADC_BIG_ENDIAN BIT(0) #define FMC_ADC_BIG_ENDIAN BIT(0) /* Registers are in BIG ENDIAN */
#define FMC_ADC_NOSQUASH_SCATTERLIST BIT(1) #define FMC_ADC_NOSQUASH_SCATTERLIST BIT(1)
#define FMC_ADC_DATA_NO_SWAP BIT(2)
/* /*
* In principle this should not be necessary. The two variants should * In principle this should not be necessary. The two variants should
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment