summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGwendal Grignou <gwendal@chromium.org>2015-07-24 16:55:42 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-07-27 22:19:21 +0000
commit324a2716d4da7efbe014c8dceb6df0a16c792eea (patch)
tree46c453d1fe8bbc386b4057348a25212ea6900a12
parent909fccfd5a340d5f683f9d2b5f1406b931239ec5 (diff)
downloadchrome-ec-324a2716d4da7efbe014c8dceb6df0a16c792eea.tar.gz
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>
-rw-r--r--chip/stm32/dma.c29
-rw-r--r--chip/stm32/registers.h31
2 files changed, 49 insertions, 11 deletions
diff --git a/chip/stm32/dma.c b/chip/stm32/dma.c
index f6f7be0871..56723e1be1 100644
--- a/chip/stm32/dma.c
+++ b/chip/stm32/dma.c
@@ -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 */
diff --git a/chip/stm32/registers.h b/chip/stm32/registers.h
index f4416d9fc6..4970ea5f4b 100644
--- a/chip/stm32/registers.h
+++ b/chip/stm32/registers.h
@@ -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)