stm32: Define second DMA controller present on STM32F3

Define second DMA controller, to be used by SPI3 on STM32F373.

BRANCH=smaug
TEST=Check with dmahelp the DMA engine is activated.
BUG=chrome-os-partner:42304

Change-Id: Id2490ab91092b1ed738f5318bdeebfbe93f09171
Signed-off-by: Gwendal Grignou <gwendal@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/288511
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
This commit is contained in:
Gwendal Grignou
2015-07-24 16:55:42 -07:00
committed by ChromeOS Commit Bot
parent 909fccfd5a
commit 324a2716d4
2 changed files with 49 additions and 11 deletions

View File

@@ -23,6 +23,7 @@ static struct {
void *cb_data; /* Callback data for callback function */
} dma_irq[STM32_DMAC_COUNT];
/**
* Return the IRQ for the DMA channel
*
@@ -39,7 +40,11 @@ static int dma_get_irq(enum dma_channel channel)
STM32_IRQ_DMA_CHANNEL_4_7 :
STM32_IRQ_DMA_CHANNEL_2_3;
#else
return STM32_IRQ_DMA_CHANNEL_1 + channel;
if (channel < STM32_DMAC_PER_CTLR)
return STM32_IRQ_DMA_CHANNEL_1 + channel;
else
return STM32_IRQ_DMA2_CHANNEL1 +
(channel - STM32_DMAC_PER_CTLR);
#endif
}
@@ -49,9 +54,9 @@ static int dma_get_irq(enum dma_channel channel)
*/
stm32_dma_chan_t *dma_get_channel(enum dma_channel channel)
{
stm32_dma_regs_t *dma = STM32_DMA1_REGS;
stm32_dma_regs_t *dma = STM32_DMA_REGS(channel);
return &dma->chan[channel];
return &dma->chan[channel % STM32_DMAC_PER_CTLR];
}
void dma_disable(enum dma_channel channel)
@@ -143,15 +148,15 @@ int dma_bytes_done(stm32_dma_chan_t *chan, int orig_count)
#ifdef CONFIG_DMA_HELP
void dma_dump(enum dma_channel channel)
{
stm32_dma_regs_t *dma = STM32_DMA1_REGS;
stm32_dma_regs_t *dma = STM32_DMA_REGS(channel);
stm32_dma_chan_t *chan = dma_get_channel(channel);
CPRINTF("ccr=%x, cndtr=%x, cpar=%x, cmar=%x\n", chan->ccr,
chan->cndtr, chan->cpar, chan->cmar);
CPRINTF("chan %d, isr=%x, ifcr=%x\n",
channel,
(dma->isr >> (channel * 4)) & 0xf,
(dma->ifcr >> (channel * 4)) & 0xf);
(dma->isr >> ((channel % STM32_DMAC_PER_CTLR) * 4)) & 0xf,
(dma->ifcr >> ((channel % STM32_DMAC_PER_CTLR) * 4)) & 0xf);
}
void dma_check(enum dma_channel channel, char *buf)
@@ -209,15 +214,17 @@ void dma_test(enum dma_channel channel)
void dma_init(void)
{
/* Enable DMA1; current chips don't have DMA2 */
STM32_RCC_AHBENR |= STM32_RCC_HB_DMA1;
#ifdef CHIP_FAMILY_STM32F3
STM32_RCC_AHBENR |= STM32_RCC_HB_DMA2;
#endif
/* Delay 1 AHB clock cycle after the clock is enabled */
clock_wait_bus_cycles(BUS_AHB, 1);
}
int dma_wait(enum dma_channel channel)
{
stm32_dma_regs_t *dma = STM32_DMA1_REGS;
stm32_dma_regs_t *dma = STM32_DMA_REGS(channel);
const uint32_t mask = STM32_DMA_ISR_TCIF(channel);
timestamp_t deadline;
@@ -270,7 +277,7 @@ void dma_disable_tc_interrupt(enum dma_channel channel)
void dma_clear_isr(enum dma_channel channel)
{
stm32_dma_regs_t *dma = STM32_DMA1_REGS;
stm32_dma_regs_t *dma = STM32_DMA_REGS(channel);
dma->ifcr |= STM32_DMA_ISR_ALL(channel);
}
@@ -336,6 +343,10 @@ DECLARE_DMA_IRQ(4);
DECLARE_DMA_IRQ(5);
DECLARE_DMA_IRQ(6);
DECLARE_DMA_IRQ(7);
#ifdef CHIP_FAMILY_STM32F3
DECLARE_DMA_IRQ(9);
DECLARE_DMA_IRQ(10);
#endif
#endif /* CHIP_FAMILY_STM32F0 */
#endif /* CONFIG_DMA_DEFAULT_HANDLERS */

View File

@@ -144,6 +144,10 @@
#define STM32_IRQ_TIM19 78 /* STM32F373 only */
#define STM32_IRQ_FPU 81 /* STM32F373 only */
/* To simplify code generation, define DMA channel 9..10 */
#define STM32_IRQ_DMA_CHANNEL_9 STM32_IRQ_DMA2_CHANNEL1
#define STM32_IRQ_DMA_CHANNEL_10 STM32_IRQ_DMA2_CHANNEL2
/* aliases for easier code sharing */
#define STM32_IRQ_I2C1 STM32_IRQ_I2C1_EV
#define STM32_IRQ_I2C2 STM32_IRQ_I2C2_EV
@@ -565,6 +569,8 @@ typedef volatile struct timer_ctlr timer_ctlr_t;
#define STM32_RCC_CR2 REG32(STM32_RCC_BASE + 0x34) /* STM32F0XX */
#define STM32_RCC_HB_DMA1 (1 << 0)
/* STM32F373 */
#define STM32_RCC_HB_DMA2 (1 << 1)
#define STM32_RCC_PB2_TIM1 (1 << 11) /* Except STM32F373 */
#define STM32_RCC_PB2_TIM15 (1 << 16) /* STM32F0XX and STM32F373 */
#define STM32_RCC_PB2_TIM16 (1 << 17) /* STM32F0XX and STM32F373 */
@@ -1102,6 +1108,7 @@ typedef volatile struct stm32_spi_regs stm32_spi_regs_t;
#define STM32_DMA1_BASE 0x40026000
#elif defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3)
#define STM32_DMA1_BASE 0x40020000
#define STM32_DMA2_BASE 0x40020400
#else
#error Unsupported chip variant
#endif
@@ -1126,6 +1133,12 @@ enum dma_channel {
STM32_DMAC_CH5 = 4,
STM32_DMAC_CH6 = 5,
STM32_DMAC_CH7 = 6,
/*
* Skip CH8, it should belong to DMA engine 1.
* Sharing code with STM32s that have 16 engines will be easier.
*/
STM32_DMAC_CH9 = 8,
STM32_DMAC_CH10 = 9,
/* Channel functions */
STM32_DMAC_ADC = STM32_DMAC_CH1,
@@ -1147,19 +1160,23 @@ enum dma_channel {
#ifdef CHIP_VARIANT_STM32F373
STM32_DMAC_SPI2_RX = STM32_DMAC_CH4,
STM32_DMAC_SPI2_TX = STM32_DMAC_CH5,
STM32_DMAC_COUNT = 10,
#else
STM32_DMAC_SPI2_RX = STM32_DMAC_CH6,
STM32_DMAC_SPI2_TX = STM32_DMAC_CH7,
#endif
/* Only DMA1 (with 7 channels) is present on STM32L151x */
STM32_DMAC_COUNT = 7,
#endif
#else /* stm32f03x and stm32f05x have only 5 channels */
STM32_DMAC_COUNT = 5,
#endif
};
#define STM32_DMAC_PER_CTLR 8
/* Registers for a single channel of the DMA controller */
struct stm32_dma_chan {
uint32_t ccr; /* Control */
@@ -1187,8 +1204,18 @@ typedef volatile struct stm32_dma_regs stm32_dma_regs_t;
#define STM32_DMA1_REGS ((stm32_dma_regs_t *)STM32_DMA1_BASE)
#ifdef CHIP_FAMILY_STM32F3
#define STM32_DMA2_REGS ((stm32_dma_regs_t *)STM32_DMA2_BASE)
#define STM32_DMA_REGS(channel) \
((channel) < STM32_DMAC_PER_CTLR ? STM32_DMA1_REGS : STM32_DMA2_REGS)
#else
#define STM32_DMA_REGS(channel) STM32_DMA1_REGS
#endif
/* Bits for DMA controller regs (isr and ifcr) */
#define STM32_DMA_ISR_MASK(channel, mask) ((mask) << (4 * (channel)))
#define STM32_DMA_ISR_MASK(channel, mask) \
((mask) << (4 * ((channel) % STM32_DMAC_PER_CTLR)))
#define STM32_DMA_ISR_GIF(channel) STM32_DMA_ISR_MASK(channel, 1 << 0)
#define STM32_DMA_ISR_TCIF(channel) STM32_DMA_ISR_MASK(channel, 1 << 1)
#define STM32_DMA_ISR_HTIF(channel) STM32_DMA_ISR_MASK(channel, 1 << 2)