SAMA3,4,A5: Misc corrections to DMA and HSMCI drivers

This commit is contained in:
Gregory Nutt 2013-08-07 11:32:08 -06:00
parent 159635bc2a
commit e015c6edd6
6 changed files with 233 additions and 182 deletions

View file

@ -953,7 +953,7 @@ static inline int sam_single(struct sam_dma_s *dmach)
/* Set up the CTRLB register */
putreg32(llhead->ctrlb, dmach->base + SAM_DMACHAN_CTRLA_OFFSET);
putreg32(llhead->ctrlb, dmach->base + SAM_DMACHAN_CTRLB_OFFSET);
/* Both the DST and SRC DSCR bits should be '1' in CTRLB */
@ -1005,13 +1005,13 @@ static inline int sam_multiple(struct sam_dma_s *dmach)
(void)getreg32(SAM_DMAC_EBCISR);
/* Set up the initial CTRLB register (to enable descriptors) */
/* Set up the initial CTRLA register */
putreg32(llhead->ctrlb, dmach->base + SAM_DMACHAN_CTRLA_OFFSET);
putreg32(llhead->ctrla, dmach->base + SAM_DMACHAN_CTRLA_OFFSET);
/* Set up the CTRLB register */
/* Set up the CTRLB register (will enable descriptors) */
putreg32(llhead->ctrlb, dmach->base + SAM_DMACHAN_CTRLA_OFFSET);
putreg32(llhead->ctrlb, dmach->base + SAM_DMACHAN_CTRLB_OFFSET);
/* Write the channel configuration information into the CFG register */

View file

@ -267,19 +267,44 @@ config SAMA5_HSMCI_RDPROOF
integrity, not bandwidth.
config SAMA5_HSMCI_WRPROOF
bool " Write Proof Enable"
bool "Write Proof Enable"
default n
---help---
Enabling Write Proof allows to stop the HSMCI Clock during write
access if the internal FIFO is full. This will guarantee data
integrity, not bandwidth.
config SAMA5_HSMCI_XFRDEBUG
bool "HSMCI transfer debug"
depends on DEBUG_FS && DEBUG_VERBOSE
default n
---help---
Enable special debug instrumentation analyze HSMCI data transfers.
This logic is as non-invasive as possible: It samples HSMCI
registers at key points in the data transfer and then dumps all of
the registers at the end of the transfer. If DEBUG_DMA is also
enabled, then DMA register will be collected as well. Requires also
DEBUG_FS and DEBUG_VERBOSE.
config SAMA5_HSMCI_CMDDEBUG
bool "HSMCI command debug"
depends on DEBUG_FS && DEBUG_VERBOSE
default n
---help---
Enable special debug instrumentation analyze HSMCI commands. This
logic is as non-invasive as possible: It samples HSMCI registers at
key points in the data transfer and then dumps all of the registers
at the end of the transfer. If DEBUG_DMA is also enabled, then DMA
register will be collected as well. Requires also DEBUG_FS and
DEBUG_VERBOSE.
config SAMA5_HSMCI_REGDEBUG
bool "SPI Register level debug"
bool "HSMCI Register level debug"
depends on DEBUG
default n
---help---
Output detailed register-level HSCMI device debug information. Requires also DEBUG.
Output detailed register-level HSCMI device debug information.
Very invasive! Requires also DEBUG.
endmenu # HSMCI device driver options
endif # SAMA5_HSMCI0 || SAMA5_HSMCI1 || SAMA5_HSMCI2

View file

@ -647,11 +647,11 @@
# define DMAC_CH_CTRLA_SCSIZE_4 (1 << DMAC_CH_CTRLA_SCSIZE_SHIFT)
# define DMAC_CH_CTRLA_SCSIZE_8 (2 << DMAC_CH_CTRLA_SCSIZE_SHIFT)
# define DMAC_CH_CTRLA_SCSIZE_16 (3 << DMAC_CH_CTRLA_SCSIZE_SHIFT)
#define DMAC_CH_CTRLA_DCSIZE_SHIFT (10) /* Bits 2021: Destination Chunk Transfer size */
#define DMAC_CH_CTRLA_DCSIZE_SHIFT (20) /* Bits 20-21: Destination Chunk Transfer size */
#define DMAC_CH_CTRLA_DCSIZE_MASK (7 << DMAC_CH_CTRLA_DCSIZE_SHIFT)
# define DMAC_CH_CTRLA_DCSIZE_1 (0 << DMAC_CH_CTRLA_DCSIZE_SHIFT)
# define DMAC_CH_CTRLA_DCSIZE_4 (1 << DMAC_CH_CTRLA_DCSIZE_SHIFT)
# define DMAC_CH_CTRLA_DCSIZE_6 (2 << DMAC_CH_CTRLA_DCSIZE_SHIFT)
# define DMAC_CH_CTRLA_DCSIZE_8 (2 << DMAC_CH_CTRLA_DCSIZE_SHIFT)
# define DMAC_CH_CTRLA_DCSIZE_16 (3 << DMAC_CH_CTRLA_DCSIZE_SHIFT)
#define DMAC_CH_CTRLA_SRCWIDTH_SHIFT (24) /* Bits 24-25 */
#define DMAC_CH_CTRLA_SRCWIDTH_MASK (3 << DMAC_CH_CTRLA_SRCWIDTH_SHIFT)

View file

@ -545,15 +545,20 @@ static inline uint32_t sam_fifocfg(struct sam_dmach_s *dmach)
static inline uint32_t sam_txcfg(struct sam_dmach_s *dmach)
{
uint32_t regval;
unsigned int pid;
/* Set transfer (memory to peripheral) DMA channel configuration register */
regval = (((dmach->flags & DMACH_FLAG_MEMPID_MASK) >> DMACH_FLAG_MEMPID_SHIFT)
<< DMAC_CH_CFG_SRCPER_SHIFT);
pid = (dmach->flags & DMACH_FLAG_MEMPID_MASK) >> DMACH_FLAG_MEMPID_SHIFT;
regval = ((pid & 0x0f) << DMAC_CH_CFG_SRCPER_SHIFT);
regval |= ((pid & 0x30) << (DMAC_CH_CFG_SRCPERMSB_SHIFT-4));
regval |= (dmach->flags & DMACH_FLAG_MEMH2SEL) != 0 ? DMAC_CH_CFG_SRCH2SEL : 0;
regval |= (((dmach->flags & DMACH_FLAG_PERIPHPID_MASK) >> DMACH_FLAG_PERIPHPID_SHIFT)
<< DMAC_CH_CFG_DSTPER_SHIFT);
regval |= (dmach->flags & DMACH_FLAG_PERIPHH2SEL) != 0 ? DMAC_CH_CFG_DSTH2SEL : 0;
pid = (dmach->flags & DMACH_FLAG_PERIPHPID_MASK) >> DMACH_FLAG_PERIPHPID_SHIFT;
regval |= ((pid & 0x0f) << DMAC_CH_CFG_DSTPER_SHIFT);
regval |= ((pid & 0x30) << (DMAC_CH_CFG_DSTPERMSB_SHIFT-4));
regval |= (dmach->flags & DMACH_FLAG_PERIPHH2SEL) != 0 ? DMAC_CH_CFG_DSTH2SEL : 0;
regval |= sam_fifocfg(dmach);
return regval;
}
@ -570,15 +575,20 @@ static inline uint32_t sam_txcfg(struct sam_dmach_s *dmach)
static inline uint32_t sam_rxcfg(struct sam_dmach_s *dmach)
{
uint32_t regval;
unsigned int pid;
/* Set received (peripheral to memory) DMA channel config */
regval = (((dmach->flags & DMACH_FLAG_PERIPHPID_MASK) >> DMACH_FLAG_PERIPHPID_SHIFT)
<< DMAC_CH_CFG_SRCPER_SHIFT);
regval |= (dmach->flags & DMACH_FLAG_PERIPHH2SEL) != 0 ? DMAC_CH_CFG_SRCH2SEL : 0;
regval |= (((dmach->flags & DMACH_FLAG_MEMPID_MASK) >> DMACH_FLAG_MEMPID_SHIFT)
<< DMAC_CH_CFG_DSTPER_SHIFT);
regval |= (dmach->flags & DMACH_FLAG_MEMH2SEL) != 0 ? DMAC_CH_CFG_DSTH2SEL : 0;
pid = (dmach->flags & DMACH_FLAG_PERIPHPID_MASK) >> DMACH_FLAG_PERIPHPID_SHIFT;
regval = ((pid & 0x0f) << DMAC_CH_CFG_SRCPER_SHIFT);
regval |= ((pid & 0x30) << (DMAC_CH_CFG_SRCPERMSB_SHIFT-4));
regval |= (dmach->flags & DMACH_FLAG_PERIPHH2SEL) != 0 ? DMAC_CH_CFG_SRCH2SEL : 0;
pid = (dmach->flags & DMACH_FLAG_MEMPID_MASK) >> DMACH_FLAG_MEMPID_SHIFT;
regval |= ((pid & 0x0f) << DMAC_CH_CFG_DSTPER_SHIFT);
regval |= ((pid & 0x30) << (DMAC_CH_CFG_DSTPERMSB_SHIFT-4));
regval |= (dmach->flags & DMACH_FLAG_MEMH2SEL) != 0 ? DMAC_CH_CFG_DSTH2SEL : 0;
regval |= sam_fifocfg(dmach);
return regval;
}
@ -598,6 +608,7 @@ static inline uint32_t sam_txctrlabits(struct sam_dmach_s *dmach)
{
uint32_t regval;
unsigned int ndx;
unsigned int chunksize;
DEBUGASSERT(dmach);
@ -611,16 +622,9 @@ static inline uint32_t sam_txctrlabits(struct sam_dmach_s *dmach)
/* Set the source chuck size (memory chunk size) */
if ((dmach->flags & DMACH_FLAG_MEMCHUNKSIZE) == DMACH_FLAG_MEMCHUNKSIZE_4)
{
regval |= DMAC_CH_CTRLA_SCSIZE_4;
}
#if 0 /* DMAC_CH_CTRLA_SCSIZE_1 is zero */
else
{
regval |= DMAC_CH_CTRLA_SCSIZE_1;
}
#endif
chunksize = (dmach->flags & DMACH_FLAG_MEMCHUNKSIZE_MASK)
>> DMACH_FLAG_MEMCHUNKSIZE_SHIFT;
regval |= chunksize << DMAC_CH_CTRLA_SCSIZE_SHIFT;
/* Since this is a transmit, the destination is described by the peripheral selections.
* Set the destination width (peripheral width).
@ -632,16 +636,9 @@ static inline uint32_t sam_txctrlabits(struct sam_dmach_s *dmach)
/* Set the destination chuck size (peripheral chunk size) */
if ((dmach->flags & DMACH_FLAG_PERIPHCHUNKSIZE) == DMACH_FLAG_PERIPHCHUNKSIZE_4)
{
regval |= DMAC_CH_CTRLA_DCSIZE_4;
}
#if 0 /* DMAC_CH_CTRLA_DCSIZE_1 is zero */
else
{
regval |= DMAC_CH_CTRLA_DCSIZE_1;
}
#endif
chunksize = (dmach->flags & DMACH_FLAG_PERIPHCHUNKSIZE_MASK)
>> DMACH_FLAG_PERIPHCHUNKSIZE_SHIFT;
regval |= chunksize << DMAC_CH_CTRLA_DCSIZE_SHIFT;
return regval;
}
@ -657,6 +654,8 @@ static inline uint32_t sam_txctrlabits(struct sam_dmach_s *dmach)
static inline uint32_t sam_txctrla(struct sam_dmach_s *dmach,
uint32_t dmasize, uint32_t txctrlabits)
{
unsigned int chunksize;
/* Set the buffer transfer size field. This is the number of transfers to
* be performed, that is, the number of source width transfers to perform.
*/
@ -665,9 +664,25 @@ static inline uint32_t sam_txctrla(struct sam_dmach_s *dmach,
* chunk size)
*/
if ((dmach->flags & DMACH_FLAG_MEMCHUNKSIZE) == DMACH_FLAG_MEMCHUNKSIZE_4)
chunksize = (dmach->flags & DMACH_FLAG_MEMCHUNKSIZE_MASK)
>> DMACH_FLAG_MEMCHUNKSIZE_SHIFT;
switch (chunksize)
{
dmasize >>= 2;
default:
case 0: /* 1 byte */
break;
case 1: /* 4 bytes */
dmasize >>= 2;
break;
case 2: /* 8 bytes */
dmasize >>= 3;
break;
case 3: /* 16 bytes */
dmasize >>= 4;
break;
}
DEBUGASSERT(dmasize <= DMAC_CH_CTRLA_BTSIZE_MAX);
@ -690,6 +705,7 @@ static inline uint32_t sam_rxctrlabits(struct sam_dmach_s *dmach)
{
uint32_t regval;
unsigned int ndx;
unsigned int chunksize;
DEBUGASSERT(dmach);
@ -705,17 +721,9 @@ static inline uint32_t sam_rxctrlabits(struct sam_dmach_s *dmach)
/* Set the source chuck size (peripheral chunk size) */
if ((dmach->flags & DMACH_FLAG_PERIPHCHUNKSIZE) ==
DMACH_FLAG_PERIPHCHUNKSIZE_4)
{
regval |= DMAC_CH_CTRLA_SCSIZE_4;
}
#if 0 /* DMAC_CH_CTRLA_SCSIZE_1 is zero */
else
{
regval |= DMAC_CH_CTRLA_SCSIZE_1;
}
#endif
chunksize = (dmach->flags & DMACH_FLAG_PERIPHCHUNKSIZE_MASK)
>> DMACH_FLAG_PERIPHCHUNKSIZE_SHIFT;
regval |= chunksize << DMAC_CH_CTRLA_SCSIZE_SHIFT;
/* Since this is a receive, the destination is described by the memory
* selections. Set the destination width (memory width).
@ -729,16 +737,9 @@ static inline uint32_t sam_rxctrlabits(struct sam_dmach_s *dmach)
/* Set the destination chuck size (memory chunk size) */
if ((dmach->flags & DMACH_FLAG_MEMCHUNKSIZE) == DMACH_FLAG_MEMCHUNKSIZE_4)
{
regval |= DMAC_CH_CTRLA_DCSIZE_4;
}
#if 0 /* DMAC_CH_CTRLA_DCSIZE_1 is zero */
else
{
regval |= DMAC_CH_CTRLA_DCSIZE_1;
}
#endif
chunksize = (dmach->flags & DMACH_FLAG_MEMCHUNKSIZE_MASK)
>> DMACH_FLAG_MEMCHUNKSIZE_SHIFT;
regval |= chunksize << DMAC_CH_CTRLA_DCSIZE_SHIFT;
return regval;
}
@ -754,6 +755,8 @@ static inline uint32_t sam_rxctrlabits(struct sam_dmach_s *dmach)
static inline uint32_t sam_rxctrla(struct sam_dmach_s *dmach,
uint32_t dmasize, uint32_t txctrlabits)
{
unsigned int chunksize;
/* Set the buffer transfer size field. This is the number of transfers to
* be performed, that is, the number of source width transfers to perform.
*/
@ -762,10 +765,25 @@ static inline uint32_t sam_rxctrla(struct sam_dmach_s *dmach,
* chunk size)
*/
if ((dmach->flags & DMACH_FLAG_PERIPHCHUNKSIZE) ==
DMACH_FLAG_PERIPHCHUNKSIZE_4)
chunksize = (dmach->flags & DMACH_FLAG_PERIPHCHUNKSIZE_MASK)
>> DMACH_FLAG_PERIPHCHUNKSIZE_SHIFT;
switch (chunksize)
{
dmasize >>= 2;
default:
case 0: /* 1 byte */
break;
case 1: /* 4 bytes */
dmasize >>= 2;
break;
case 2: /* 8 bytes */
dmasize >>= 3;
break;
case 3: /* 16 bytes */
dmasize >>= 4;
break;
}
DEBUGASSERT(dmasize <= DMAC_CH_CTRLA_BTSIZE_MAX);
@ -1209,7 +1227,7 @@ static inline int sam_single(struct sam_dmach_s *dmach)
/* Set up the CTRLB register */
sam_putdmach(dmach, llhead->ctrlb, SAM_DMAC_CH_CTRLA_OFFSET);
sam_putdmach(dmach, llhead->ctrlb, SAM_DMAC_CH_CTRLB_OFFSET);
/* Both the DST and SRC DSCR bits should be '1' in CTRLB */
@ -1264,13 +1282,13 @@ static inline int sam_multiple(struct sam_dmach_s *dmach)
(void)sam_getdmac(dmac, SAM_DMAC_EBCISR_OFFSET);
/* Set up the initial CTRLB register (to enable descriptors) */
/* Set up the initial CTRLA register */
sam_putdmach(dmach, llhead->ctrlb, SAM_DMAC_CH_CTRLA_OFFSET);
sam_putdmach(dmach, llhead->ctrla, SAM_DMAC_CH_CTRLA_OFFSET);
/* Set up the CTRLB register */
/* Set up the CTRLB register (will enable descriptors) */
sam_putdmach(dmach, llhead->ctrlb, SAM_DMAC_CH_CTRLA_OFFSET);
sam_putdmach(dmach, llhead->ctrlb, SAM_DMAC_CH_CTRLB_OFFSET);
/* Write the channel configuration information into the CFG register */

View file

@ -78,37 +78,43 @@
/* Peripheral endpoint characteristics */
#define DMACH_FLAG_PERIPHPID_SHIFT (2) /* Bits 2-5: Peripheral PID */
#define DMACH_FLAG_PERIPHPID_MASK (15 << DMACH_FLAG_PERIPHPID_SHIFT)
#define DMACH_FLAG_PERIPHH2SEL (1 << 6) /* Bits 6: HW handshaking */
#define DMACH_FLAG_PERIPHISPERIPH (1 << 7) /* Bits 7: 0=memory; 1=peripheral */
#define DMACH_FLAG_PERIPHWIDTH_SHIFT (8) /* Bits 8-9: Peripheral width */
#define DMACH_FLAG_PERIPHPID_SHIFT (2) /* Bits 2-7: Peripheral PID */
#define DMACH_FLAG_PERIPHPID_MASK (63 << DMACH_FLAG_PERIPHPID_SHIFT)
#define DMACH_FLAG_PERIPHH2SEL (1 << 8) /* Bits 8: HW handshaking */
#define DMACH_FLAG_PERIPHISPERIPH (1 << 9) /* Bits 9: 0=memory; 1=peripheral */
#define DMACH_FLAG_PERIPHWIDTH_SHIFT (10) /* Bits 10-11: Peripheral width */
#define DMACH_FLAG_PERIPHWIDTH_MASK (3 << DMACH_FLAG_PERIPHWIDTH_SHIFT)
# define DMACH_FLAG_PERIPHWIDTH_8BITS (0 << DMACH_FLAG_PERIPHWIDTH_SHIFT) /* 8 bits */
# define DMACH_FLAG_PERIPHWIDTH_16BITS (1 << DMACH_FLAG_PERIPHWIDTH_SHIFT) /* 16 bits */
# define DMACH_FLAG_PERIPHWIDTH_32BITS (2 << DMACH_FLAG_PERIPHWIDTH_SHIFT) /* 32 bits */
# define DMACH_FLAG_PERIPHWIDTH_64BITS (3 << DMACH_FLAG_PERIPHWIDTH_SHIFT) /* 64 bits */
#define DMACH_FLAG_PERIPHINCREMENT (1 << 10) /* Bit 10: Autoincrement peripheral address */
#define DMACH_FLAG_PERIPHCHUNKSIZE (1 << 11) /* Bit 11: Peripheral chunk size */
# define DMACH_FLAG_PERIPHCHUNKSIZE_1 (0) /* Peripheral chunksize = 1 */
# define DMACH_FLAG_PERIPHCHUNKSIZE_4 DMACH_FLAG_PERIPHCHUNKSIZE /* Peripheral chunksize = 4 */
#define DMACH_FLAG_PERIPHINCREMENT (1 << 12) /* Bit 12: Autoincrement peripheral address */
#define DMACH_FLAG_PERIPHCHUNKSIZE_SHIFT (13) /* Bits 13-14: Peripheral chunk size */
#define DMACH_FLAG_PERIPHCHUNKSIZE_MASK (3 << DMACH_FLAG_PERIPHCHUNKSIZE_SHIFT)
# define DMACH_FLAG_PERIPHCHUNKSIZE_1 (0 << DMACH_FLAG_PERIPHCHUNKSIZE_SHIFT) /* Peripheral chunksize = 1 */
# define DMACH_FLAG_PERIPHCHUNKSIZE_4 (1 << DMACH_FLAG_PERIPHCHUNKSIZE_SHIFT) /* Peripheral chunksize = 4 */
# define DMACH_FLAG_PERIPHCHUNKSIZE_8 (3 << DMACH_FLAG_PERIPHCHUNKSIZE_SHIFT) /* Peripheral chunksize = 8 */
# define DMACH_FLAG_PERIPHCHUNKSIZE_16 (4 << DMACH_FLAG_PERIPHCHUNKSIZE_SHIFT) /* Peripheral chunksize = 16 */
/* Memory endpoint characteristics */
#define DMACH_FLAG_MEMPID_SHIFT (12) /* Bits 12-15: Memory PID */
#define DMACH_FLAG_MEMPID_MASK (15 << DMACH_FLAG_PERIPHPID_SHIFT)
#define DMACH_FLAG_MEMH2SEL (1 << 16) /* Bits 16: HW handshaking */
#define DMACH_FLAG_MEMISPERIPH (1 << 17) /* Bits 17: 0=memory; 1=peripheral */
#define DMACH_FLAG_MEMWIDTH_SHIFT (18) /* Bits 18-19: Memory width */
#define DMACH_FLAG_MEMPID_SHIFT (15) /* Bits 15-20: Memory PID */
#define DMACH_FLAG_MEMPID_MASK (63 << DMACH_FLAG_PERIPHPID_SHIFT)
#define DMACH_FLAG_MEMH2SEL (1 << 21) /* Bits 21: HW handshaking */
#define DMACH_FLAG_MEMISPERIPH (1 << 22) /* Bits 22: 0=memory; 1=peripheral */
#define DMACH_FLAG_MEMWIDTH_SHIFT (23) /* Bits 23-24: Memory width */
#define DMACH_FLAG_MEMWIDTH_MASK (3 << DMACH_FLAG_MEMWIDTH_SHIFT)
# define DMACH_FLAG_MEMWIDTH_8BITS (0 << DMACH_FLAG_MEMWIDTH_SHIFT) /* 8 bits */
# define DMACH_FLAG_MEMWIDTH_16BITS (1 << DMACH_FLAG_MEMWIDTH_SHIFT) /* 16 bits */
# define DMACH_FLAG_MEMWIDTH_32BITS (2 << DMACH_FLAG_MEMWIDTH_SHIFT) /* 32 bits */
# define DMACH_FLAG_MEMWIDTH_64BITS (3 << DMACH_FLAG_MEMWIDTH_SHIFT) /* 64 bits */
#define DMACH_FLAG_MEMINCREMENT (1 << 20) /* Bit 20: Autoincrement memory address */
#define DMACH_FLAG_MEMCHUNKSIZE (1 << 21) /* Bit 21: Memory chunk size */
# define DMACH_FLAG_MEMCHUNKSIZE_1 (0) /* Memory chunksize = 1 */
# define DMACH_FLAG_MEMCHUNKSIZE_4 DMACH_FLAG_MEMCHUNKSIZE /* Memory chunksize = 4 */
#define DMACH_FLAG_MEMINCREMENT (1 << 25) /* Bit 25: Autoincrement memory address */
#define DMACH_FLAG_MEMCHUNKSIZE_SHIFT (26) /* Bit 26-27: Memory chunk size */
#define DMACH_FLAG_MEMCHUNKSIZE_MASK (3 << DMACH_FLAG_MEMCHUNKSIZE_SHIFT)
# define DMACH_FLAG_MEMCHUNKSIZE_1 (0 << DMACH_FLAG_MEMCHUNKSIZE_SHIFT) /* Peripheral chunksize = 1 */
# define DMACH_FLAG_MEMCHUNKSIZE_4 (1 << DMACH_FLAG_MEMCHUNKSIZE_SHIFT) /* Peripheral chunksize = 4 */
# define DMACH_FLAG_MEMCHUNKSIZE_8 (3 << DMACH_FLAG_MEMCHUNKSIZE_SHIFT) /* Peripheral chunksize = 8 */
# define DMACH_FLAG_MEMCHUNKSIZE_16 (4 << DMACH_FLAG_MEMCHUNKSIZE_SHIFT) /* Peripheral chunksize = 16 */
/************************************************************************************
* Public Types

View file

@ -99,8 +99,8 @@
#endif
#if !defined(CONFIG_DEBUG_FS) || !defined(CONFIG_DEBUG_VERBOSE)
# undef CONFIG_HSMCI_CMDDEBUG
# undef CONFIG_HSMCI_XFRDEBUG
# undef CONFIG_SAMA5_HSMCI_CMDDEBUG
# undef CONFIG_SAMA5_HSMCI_XFRDEBUG
#endif
#ifdef CONFIG_SAMA5_HSMCI_RDPROOF
@ -233,7 +233,7 @@
/* Register logging support */
#ifdef CONFIG_HSMCI_XFRDEBUG
#ifdef CONFIG_SAMA5_HSMCI_XFRDEBUG
# ifdef CONFIG_DEBUG_DMA
# define SAMPLENDX_BEFORE_SETUP 0
# define SAMPLENDX_BEFORE_ENABLE 1
@ -249,7 +249,7 @@
# endif
#endif
#ifdef CONFIG_HSMCI_CMDDEBUG
#ifdef CONFIG_SAMA5_HSMCI_CMDDEBUG
# define SAMPLENDX_AFTER_CMDR 0
# define SAMPLENDX_AT_WAKEUP 1
# define DEBUG_NCMDSAMPLES 2
@ -259,6 +259,40 @@
* Private Types
****************************************************************************/
/* Register logging support */
#if defined(CONFIG_SAMA5_HSMCI_XFRDEBUG) || defined(CONFIG_SAMA5_HSMCI_CMDDEBUG)
struct sam_hsmciregs_s
{
uint32_t mr; /* Mode Register */
uint32_t dtor; /* Data Timeout Register */
uint32_t sdcr; /* SD/SDIO Card Register */
uint32_t argr; /* Argument Register */
uint32_t blkr; /* Block Register */
uint32_t cstor; /* Completion Signal Timeout Register */
uint32_t rsp0; /* Response Register 0 */
uint32_t rsp1; /* Response Register 1 */
uint32_t rsp2; /* Response Register 2 */
uint32_t rsp3; /* Response Register 3 */
uint32_t sr; /* Status Register */
uint32_t imr; /* Interrupt Mask Register */
uint32_t dma; /* DMA Configuration Register */
uint32_t cfg; /* Configuration Register */
uint32_t wpmr; /* Write Protection Mode Register */
uint32_t wpsr; /* Write Protection Status Register */
};
#endif
#ifdef CONFIG_SAMA5_HSMCI_XFRDEBUG
struct sam_xfrregs_s
{
struct sam_hsmciregs_s hsmci;
#ifdef CONFIG_DEBUG_DMA
struct sam_dmaregs_s dma;
#endif
};
#endif
/* This structure defines the state of the SAMA5 HSMCI interface */
struct sam_dev_s
@ -305,52 +339,18 @@ struct sam_dev_s
/* Register logging support */
#ifdef CONFIG_HSMCI_XFRDEBUG
#if defined(CONFIG_SAMA5_HSMCI_CMDDEBUG) && defined(CONFIG_SAMA5_HSMCI_XFRDEBUG)
bool xfrinitialized;
bool cmdinitialized;
#endif
#ifdef CONFIG_SAMA5_HSMCI_XFRDEBUG
struct sam_xfrregs_s xfrsamples[DEBUG_NDMASAMPLES];
#endif
#ifdef CONFIG_HSMCI_CMDDEBUG
#ifdef CONFIG_SAMA5_HSMCI_CMDDEBUG
struct sam_hsmciregs_s cmdsamples[DEBUG_NCMDSAMPLES];
#endif
#if defined(CONFIG_HSMCI_XFRDEBUG) && defined(CONFIG_HSMCI_CMDDEBUG)
static bool g_xfrinitialized;
static bool g_cmdinitialized;
#endif
};
/* Register logging support */
#if defined(CONFIG_HSMCI_XFRDEBUG) || defined(CONFIG_HSMCI_CMDDEBUG)
struct sam_hsmciregs_s
{
uint32_t mr; /* Mode Register */
uint32_t dtor; /* Data Timeout Register */
uint32_t sdcr; /* SD/SDIO Card Register */
uint32_t argr; /* Argument Register */
uint32_t blkr; /* Block Register */
uint32_t cstor; /* Completion Signal Timeout Register */
uint32_t rsp0; /* Response Register 0 */
uint32_t rsp1; /* Response Register 1 */
uint32_t rsp2; /* Response Register 2 */
uint32_t rsp3; /* Response Register 3 */
uint32_t sr; /* Status Register */
uint32_t imr; /* Interrupt Mask Register */
uint32_t dma; /* DMA Configuration Register */
uint32_t cfg; /* Configuration Register */
uint32_t wpmr; /* Write Protection Mode Register */
uint32_t wpsr; /* Write Protection Status Register */
};
#endif
#ifdef CONFIG_HSMCI_XFRDEBUG
struct sam_xfrregs_s
{
struct sam_hsmciregs_s hsmci;
#ifdef CONFIG_DEBUG_DMA
struct sam_dmaregs_s dma;
#endif
};
#endif
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
@ -383,13 +383,14 @@ static inline void sam_enable(struct sam_dev_s *priv);
/* Register Sampling ********************************************************/
#if defined(CONFIG_HSMCI_XFRDEBUG) || defined(CONFIG_HSMCI_CMDDEBUG)
#if defined(CONFIG_SAMA5_HSMCI_XFRDEBUG) || defined(CONFIG_SAMA5_HSMCI_CMDDEBUG)
static void sam_hsmcisample(struct sam_dev_s *priv,
struct sam_hsmciregs_s *regs);
static void sam_hsmcidump(struct sam_hsmciregs_s *regs, const char *msg);
static void sam_hsmcidump(struct sam_dev_s *priv,
struct sam_hsmciregs_s *regs, const char *msg);
#endif
#ifdef CONFIG_HSMCI_XFRDEBUG
#ifdef CONFIG_SAMA5_HSMCI_XFRDEBUG
static void sam_xfrsampleinit(struct sam_dev_s *priv);
static void sam_xfrsample(struct sam_dev_s *priv, int index);
static void sam_xfrdumpone(struct sam_dev_s *priv,
@ -401,7 +402,7 @@ static void sam_xfrdump(struct sam_dev_s *priv);
# define sam_xfrdump(priv)
#endif
#ifdef CONFIG_HSMCI_CMDDEBUG
#ifdef CONFIG_SAMA5_HSMCI_CMDDEBUG
static void sam_cmdsampleinit(struct sam_dev_s *priv);
static inline void sam_cmdsample1(struct sam_dev_s *priv, int index3);
static inline void sam_cmdsample2(struct sam_dev_s *priv, int index,
@ -832,7 +833,7 @@ static inline void sam_enable(struct sam_dev_s *priv)
*
****************************************************************************/
#if defined(CONFIG_HSMCI_XFRDEBUG) || defined(CONFIG_HSMCI_CMDDEBUG)
#if defined(CONFIG_SAMA5_HSMCI_XFRDEBUG) || defined(CONFIG_SAMA5_HSMCI_CMDDEBUG)
static void sam_hsmcisample(struct sam_dev_s *priv,
struct sam_hsmciregs_s *regs)
{
@ -863,26 +864,27 @@ static void sam_hsmcisample(struct sam_dev_s *priv,
*
****************************************************************************/
#if defined(CONFIG_HSMCI_XFRDEBUG) || defined(CONFIG_HSMCI_CMDDEBUG)
static void sam_hsmcidump(struct sam_hsmciregs_s *regs, const char *msg)
#if defined(CONFIG_SAMA5_HSMCI_XFRDEBUG) || defined(CONFIG_SAMA5_HSMCI_CMDDEBUG)
static void sam_hsmcidump(struct sam_dev_s *priv,
struct sam_hsmciregs_s *regs, const char *msg)
{
fdbg("HSMCI Registers: %s\n", msg);
fdbg(" MR[%08x]: %08x\n", SAM_HSMCI_MR, regs->mr);
fdbg(" DTOR[%08x]: %08x\n", SAM_HSMCI_DTOR, regs->dtor);
fdbg(" SDCR[%08x]: %08x\n", SAM_HSMCI_SDCR, regs->sdcr);
fdbg(" ARGR[%08x]: %08x\n", SAM_HSMCI_ARGR, regs->argr);
fdbg(" BLKR[%08x]: %08x\n", SAM_HSMCI_BLKR, regs->blkr);
fdbg(" CSTOR[%08x]: %08x\n", SAM_HSMCI_CSTOR, regs->cstor);
fdbg(" RSPR0[%08x]: %08x\n", SAM_HSMCI_RSPR0, regs->rsp0);
fdbg(" RSPR1[%08x]: %08x\n", SAM_HSMCI_RSPR1, regs->rsp1);
fdbg(" RSPR2[%08x]: %08x\n", SAM_HSMCI_RSPR2, regs->rsp2);
fdbg(" RSPR3[%08x]: %08x\n", SAM_HSMCI_RSPR3, regs->rsp3);
fdbg(" SR[%08x]: %08x\n", SAM_HSMCI_SR, regs->sr);
fdbg(" IMR[%08x]: %08x\n", SAM_HSMCI_IMR, regs->imr);
fdbg(" DMA[%08x]: %08x\n", SAM_HSMCI_DMA, regs->dma);
fdbg(" CFG[%08x]: %08x\n", SAM_HSMCI_CFG, regs->cfg);
fdbg(" WPMR[%08x]: %08x\n", SAM_HSMCI_WPMR, regs->wpmr);
fdbg(" WPSR[%08x]: %08x\n", SAM_HSMCI_WPSR, regs->wpsr);
fdbg(" MR[%08x]: %08x\n", priv->base + SAM_HSMCI_MR_OFFSET, regs->mr);
fdbg(" DTOR[%08x]: %08x\n", priv->base + SAM_HSMCI_DTOR_OFFSET, regs->dtor);
fdbg(" SDCR[%08x]: %08x\n", priv->base + SAM_HSMCI_SDCR_OFFSET, regs->sdcr);
fdbg(" ARGR[%08x]: %08x\n", priv->base + SAM_HSMCI_ARGR_OFFSET, regs->argr);
fdbg(" BLKR[%08x]: %08x\n", priv->base + SAM_HSMCI_BLKR_OFFSET, regs->blkr);
fdbg(" CSTOR[%08x]: %08x\n", priv->base + SAM_HSMCI_CSTOR_OFFSET, regs->cstor);
fdbg(" RSPR0[%08x]: %08x\n", priv->base + SAM_HSMCI_RSPR0_OFFSET, regs->rsp0);
fdbg(" RSPR1[%08x]: %08x\n", priv->base + SAM_HSMCI_RSPR1_OFFSET, regs->rsp1);
fdbg(" RSPR2[%08x]: %08x\n", priv->base + SAM_HSMCI_RSPR2_OFFSET, regs->rsp2);
fdbg(" RSPR3[%08x]: %08x\n", priv->base + SAM_HSMCI_RSPR3_OFFSET, regs->rsp3);
fdbg(" SR[%08x]: %08x\n", priv->base + SAM_HSMCI_SR_OFFSET, regs->sr);
fdbg(" IMR[%08x]: %08x\n", priv->base + SAM_HSMCI_IMR_OFFSET, regs->imr);
fdbg(" DMA[%08x]: %08x\n", priv->base + SAM_HSMCI_DMA_OFFSET, regs->dma);
fdbg(" CFG[%08x]: %08x\n", priv->base + SAM_HSMCI_CFG_OFFSET, regs->cfg);
fdbg(" WPMR[%08x]: %08x\n", priv->base + SAM_HSMCI_WPMR_OFFSET, regs->wpmr);
fdbg(" WPSR[%08x]: %08x\n", priv->base + SAM_HSMCI_WPSR_OFFSET, regs->wpsr);
}
#endif
@ -894,7 +896,7 @@ static void sam_hsmcidump(struct sam_hsmciregs_s *regs, const char *msg)
*
****************************************************************************/
#ifdef CONFIG_HSMCI_XFRDEBUG
#ifdef CONFIG_SAMA5_HSMCI_XFRDEBUG
static void sam_xfrsample(struct sam_dev_s *priv, int index)
{
struct sam_xfrregs_s *regs = &priv->xfrsamples[index];
@ -914,14 +916,14 @@ static void sam_xfrsample(struct sam_dev_s *priv, int index)
*
****************************************************************************/
#ifdef CONFIG_HSMCI_XFRDEBUG
#ifdef CONFIG_SAMA5_HSMCI_XFRDEBUG
static void sam_xfrsampleinit(struct sam_dev_s *priv)
{
memset(priv->xfrsamples, 0xff,
DEBUG_NDMASAMPLES * sizeof(struct sam_xfrregs_s));
#ifdef CONFIG_HSMCI_CMDDEBUG
g_xfrinitialized = true;
#ifdef CONFIG_SAMA5_HSMCI_CMDDEBUG
priv->xfrinitialized = true;
#endif
}
#endif
@ -934,14 +936,14 @@ static void sam_xfrsampleinit(struct sam_dev_s *priv)
*
****************************************************************************/
#ifdef CONFIG_HSMCI_XFRDEBUG
#ifdef CONFIG_SAMA5_HSMCI_XFRDEBUG
static void sam_xfrdumpone(struct sam_dev_s *priv,
struct sam_xfrregs_s *regs, const char *msg)
{
#ifdef CONFIG_DEBUG_DMA
sam_dmadump(priv->dma, &regs->dma, msg);
#endif
sam_hsmcidump(&regs->hsmci, msg);
sam_hsmcidump(priv, &regs->hsmci, msg);
}
#endif
@ -953,11 +955,11 @@ static void sam_xfrdumpone(struct sam_dev_s *priv,
*
****************************************************************************/
#ifdef CONFIG_HSMCI_XFRDEBUG
#ifdef CONFIG_SAMA5_HSMCI_XFRDEBUG
static void sam_xfrdump(struct sam_dev_s *priv)
{
#ifdef CONFIG_HSMCI_CMDDEBUG
if (g_xfrinitialized)
#ifdef CONFIG_SAMA5_HSMCI_CMDDEBUG
if (priv->xfrinitialized)
#endif
{
sam_xfrdumpone(priv, &priv->xfrsamples[SAMPLENDX_BEFORE_SETUP],
@ -974,8 +976,8 @@ static void sam_xfrdump(struct sam_dev_s *priv)
sam_xfrdumpone(priv, &priv->xfrsamples[SAMPLENDX_DMA_CALLBACK],
"DMA Callback");
#endif
#ifdef CONFIG_HSMCI_CMDDEBUG
g_xfrinitialized = false;
#ifdef CONFIG_SAMA5_HSMCI_CMDDEBUG
priv->xfrinitialized = false;
#endif
}
}
@ -989,14 +991,14 @@ static void sam_xfrdump(struct sam_dev_s *priv)
*
****************************************************************************/
#ifdef CONFIG_HSMCI_CMDDEBUG
#ifdef CONFIG_SAMA5_HSMCI_CMDDEBUG
static void sam_cmdsampleinit(struct sam_dev_s *priv)
{
memset(priv->cmdsamples, 0xff,
DEBUG_NCMDSAMPLES * sizeof(struct sam_hsmciregs_s));
#ifdef CONFIG_HSMCI_XFRDEBUG
g_cmdinitialized = true;
#ifdef CONFIG_SAMA5_HSMCI_XFRDEBUG
priv->cmdinitialized = true;
#endif
}
#endif
@ -1009,7 +1011,7 @@ static void sam_cmdsampleinit(struct sam_dev_s *priv)
*
****************************************************************************/
#ifdef CONFIG_HSMCI_CMDDEBUG
#ifdef CONFIG_SAMA5_HSMCI_CMDDEBUG
static inline void sam_cmdsample1(struct sam_dev_s *priv, int index)
{
sam_hsmcisample(priv, &priv->cmdsamples[index]);
@ -1031,19 +1033,19 @@ static inline void sam_cmdsample2(struct sam_dev_s *priv, int index,
*
****************************************************************************/
#ifdef CONFIG_HSMCI_CMDDEBUG
#ifdef CONFIG_SAMA5_HSMCI_CMDDEBUG
static void sam_cmddump(struct sam_dev_s *priv)
{
#ifdef CONFIG_HSMCI_XFRDEBUG
if (g_cmdinitialized)
#ifdef CONFIG_SAMA5_HSMCI_XFRDEBUG
if (priv->cmdinitialized)
#endif
{
sam_hsmcidump(&priv->cmdsamples[SAMPLENDX_AFTER_CMDR],
sam_hsmcidump(priv, &priv->cmdsamples[SAMPLENDX_AFTER_CMDR],
"After command setup");
sam_hsmcidump(&g_cmdsamples[SAMPLENDX_AT_WAKEUP],
sam_hsmcidump(priv, &g_cmdsamples[SAMPLENDX_AT_WAKEUP],
"After wakeup");
#ifdef CONFIG_HSMCI_XFRDEBUG
g_cmdinitialized = false;
#ifdef CONFIG_SAMA5_HSMCI_XFRDEBUG
priv->cmdinitialized = false;
#endif
}
}
@ -2728,7 +2730,7 @@ FAR struct sdio_dev_s *sdio_initialize(int slotno)
/* For DMA channel selection */
dmac = 0;
pid = SAM_PID_HSMCI0;
pid = DMAC0_CH_HSMCI0;
}
else
#endif
@ -2765,7 +2767,7 @@ FAR struct sdio_dev_s *sdio_initialize(int slotno)
/* For DMA channel selection */
dmac = 1;
pid = SAM_PID_HSMCI1;
pid = DMAC1_CH_HSMCI1;
}
else
#endif
@ -2802,7 +2804,7 @@ FAR struct sdio_dev_s *sdio_initialize(int slotno)
/* For DMA channel selection */
dmac = 1;
pid = SAM_PID_HSMCI2;
pid = DMAC1_CH_HSMCI2;
}
else
#endif