stm32h7:dma Remove CPU lock on HW fail
This commit is contained in:
parent
8064f60a9e
commit
d2ea49109a
@ -241,6 +241,13 @@ static DMA_CHANNEL stm32_dma_channel_get(uint8_t channel,
|
|||||||
static void stm32_gdma_limits_get(uint8_t controller, uint8_t *first,
|
static void stm32_gdma_limits_get(uint8_t controller, uint8_t *first,
|
||||||
uint8_t *last);
|
uint8_t *last);
|
||||||
|
|
||||||
|
static inline void dmachan_modifyreg32(DMA_CHANNEL dmachan,
|
||||||
|
uint32_t offset, uint32_t clrbits,
|
||||||
|
uint32_t setbits)
|
||||||
|
{
|
||||||
|
modifyreg32(dmachan->base + offset, clrbits, setbits);
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Data
|
* Private Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -1210,6 +1217,7 @@ static int stm32_sdma_interrupt(int irq, void *context, void *arg)
|
|||||||
|
|
||||||
static void stm32_sdma_setup(DMA_HANDLE handle, stm32_dmacfg_t *cfg)
|
static void stm32_sdma_setup(DMA_HANDLE handle, stm32_dmacfg_t *cfg)
|
||||||
{
|
{
|
||||||
|
uint32_t timeout;
|
||||||
DMA_CHANNEL dmachan = (DMA_CHANNEL)handle;
|
DMA_CHANNEL dmachan = (DMA_CHANNEL)handle;
|
||||||
uint32_t regoffset = 0;
|
uint32_t regoffset = 0;
|
||||||
uint32_t regval = 0;
|
uint32_t regval = 0;
|
||||||
@ -1235,7 +1243,37 @@ static void stm32_sdma_setup(DMA_HANDLE handle, stm32_dmacfg_t *cfg)
|
|||||||
* for the EN bit to be cleared before starting any stream configuration."
|
* for the EN bit to be cleared before starting any stream configuration."
|
||||||
*/
|
*/
|
||||||
|
|
||||||
while ((dmachan_getreg(dmachan, STM32_DMA_SCR_OFFSET) & DMA_SCR_EN) != 0);
|
/* Drivers using DMA should manage the streams. If a DMA request
|
||||||
|
* is not made on an error or an abort occurs. The driver should
|
||||||
|
* stop the DMA. If it fails to do so we can not just hang waiting
|
||||||
|
* on the HW that will not change state.
|
||||||
|
*
|
||||||
|
* If at the end of waiting the HW is still not ready there is a HW problem
|
||||||
|
* or a SW usage problem.
|
||||||
|
*
|
||||||
|
* Enable DEBUGASSERT to detect this.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((dmachan_getreg(dmachan, STM32_DMA_SCR_OFFSET) & DMA_SCR_EN) != 0)
|
||||||
|
{
|
||||||
|
/* Attempt to disable the DMA stream and wait up to a 100 us for it
|
||||||
|
* to stop.
|
||||||
|
*/
|
||||||
|
|
||||||
|
dmachan_modifyreg32(dmachan, STM32_DMA_SCR_OFFSET, DMA_SCR_EN, 0);
|
||||||
|
timeout = 100;
|
||||||
|
while (timeout != 0 &&
|
||||||
|
(dmachan_getreg(dmachan, STM32_DMA_SCR_OFFSET) &
|
||||||
|
DMA_SCR_EN) != 0)
|
||||||
|
{
|
||||||
|
up_udelay(1);
|
||||||
|
timeout--;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGASSERT(timeout != 0 &&
|
||||||
|
(dmachan_getreg(dmachan, STM32_DMA_SCR_OFFSET) &
|
||||||
|
DMA_SCR_EN) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* "... All the stream dedicated bits set in the status register (DMA_LISR
|
/* "... All the stream dedicated bits set in the status register (DMA_LISR
|
||||||
* and DMA_HISR) from the previous data block DMA transfer should be
|
* and DMA_HISR) from the previous data block DMA transfer should be
|
||||||
@ -1804,6 +1842,7 @@ static inline int32_t stm32_sdma_scr_2_bdma_ccr(int32_t scr)
|
|||||||
|
|
||||||
static void stm32_bdma_setup(DMA_HANDLE handle, stm32_dmacfg_t *cfg)
|
static void stm32_bdma_setup(DMA_HANDLE handle, stm32_dmacfg_t *cfg)
|
||||||
{
|
{
|
||||||
|
uint32_t timeout;
|
||||||
DMA_CHANNEL dmachan = (DMA_CHANNEL)handle;
|
DMA_CHANNEL dmachan = (DMA_CHANNEL)handle;
|
||||||
uint32_t regval = 0;
|
uint32_t regval = 0;
|
||||||
uint32_t scr = cfg->cfg1;
|
uint32_t scr = cfg->cfg1;
|
||||||
@ -1829,12 +1868,37 @@ static void stm32_bdma_setup(DMA_HANDLE handle, stm32_dmacfg_t *cfg)
|
|||||||
* for the EN bit to be cleared before starting any stream configuration."
|
* for the EN bit to be cleared before starting any stream configuration."
|
||||||
*/
|
*/
|
||||||
|
|
||||||
regval = dmachan_getreg(dmachan, STM32_BDMACH_CCR_OFFSET);
|
/* Drivers using DMA should manage the streams. If a DMA request
|
||||||
regval &= ~BDMA_CCR_EN;
|
* is not made on an error or an abort occurs. The driver should
|
||||||
dmachan_putreg(dmachan, STM32_BDMACH_CCR_OFFSET, regval);
|
* stop the DMA. If it fails to do so we can not just hang waiting
|
||||||
|
* on the HW that will not change state.
|
||||||
|
*
|
||||||
|
* If at the end of waiting the HW is still not ready there is a HW problem
|
||||||
|
* or a SW usage problem.
|
||||||
|
*
|
||||||
|
* Enable DEBUGASSERT to detect this.
|
||||||
|
*/
|
||||||
|
|
||||||
while ((dmachan_getreg(dmachan, STM32_BDMACH_CCR_OFFSET) &
|
if ((dmachan_getreg(dmachan, STM32_BDMACH_CCR_OFFSET) & BDMA_CCR_EN) != 0)
|
||||||
BDMA_CCR_EN) != 0);
|
{
|
||||||
|
/* Attempt to disable the DMA stream and wait up to a 100 us for it
|
||||||
|
* to stop.
|
||||||
|
*/
|
||||||
|
|
||||||
|
dmachan_modifyreg32(dmachan, STM32_BDMACH_CCR_OFFSET, BDMA_CCR_EN, 0);
|
||||||
|
timeout = 100;
|
||||||
|
while (timeout != 0 &&
|
||||||
|
(dmachan_getreg(dmachan, STM32_BDMACH_CCR_OFFSET) &
|
||||||
|
BDMA_CCR_EN) != 0)
|
||||||
|
{
|
||||||
|
up_udelay(1);
|
||||||
|
timeout--;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGASSERT(timeout != 0 &&
|
||||||
|
(dmachan_getreg(dmachan, STM32_BDMACH_CCR_OFFSET) &
|
||||||
|
BDMA_CCR_EN) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* "... All the stream dedicated bits set in the status register BDMA_ISR
|
/* "... All the stream dedicated bits set in the status register BDMA_ISR
|
||||||
* from the previous data block DMA transfer should be cleared before the
|
* from the previous data block DMA transfer should be cleared before the
|
||||||
|
Loading…
x
Reference in New Issue
Block a user