From cb0d8108e5a5b630ec05a8d21a824cb601246bf5 Mon Sep 17 00:00:00 2001 From: Daisuke Nojiri Date: Thu, 21 Apr 2016 11:14:03 -0700 Subject: STM32: Add dma_select_channel dma_select_channel selects which stream (peripheral) to be used on a specific channel. Some STM32 chips simply logically OR requests, thus do not require this selection. BUG=none BRANCH=tot TEST=make buildall && make tests. Verified on stm32l476g-eval. Change-Id: I7b64b78bdec80658992f58cb4c94ade972a1081c Signed-off-by: Daisuke Nojiri Reviewed-on: https://chromium-review.googlesource.com/340107 Reviewed-by: Gwendal Grignou --- chip/stm32/config_chip.h | 3 +++ chip/stm32/dma.c | 16 ++++++++++++++++ chip/stm32/registers.h | 3 +++ chip/stm32/stm32-dma.h | 16 ++++++++++++++++ 4 files changed, 38 insertions(+) create mode 100644 chip/stm32/stm32-dma.h diff --git a/chip/stm32/config_chip.h b/chip/stm32/config_chip.h index f77fdf059e..87ebd21c09 100644 --- a/chip/stm32/config_chip.h +++ b/chip/stm32/config_chip.h @@ -96,6 +96,9 @@ /* Use DMA */ #define CONFIG_DMA +/* Number of peripheral request signals per DMA channel */ +#define STM32_DMA_PERIPHERALS_PER_CHANNEL 4 + /* * Use DMA for UART transmit for all platforms. DMA for UART receive is * enabled on a per-chip basis because it doesn't seem to work reliably on diff --git a/chip/stm32/dma.c b/chip/stm32/dma.c index 56723e1be1..d169cf7f45 100644 --- a/chip/stm32/dma.c +++ b/chip/stm32/dma.c @@ -59,6 +59,22 @@ stm32_dma_chan_t *dma_get_channel(enum dma_channel channel) return &dma->chan[channel % STM32_DMAC_PER_CTLR]; } +#ifdef STM32_DMA_CSELR +void dma_select_channel(enum dma_channel channel, unsigned char stream) +{ + /* Local channel # starting from 0 on each DMA controller */ + const unsigned char ch = channel % STM32_DMAC_PER_CTLR; + const unsigned char shift = STM32_DMA_PERIPHERALS_PER_CHANNEL; + const unsigned char mask = (1 << shift) - 1; + uint32_t val; + + ASSERT(ch < STM32_DMAC_PER_CTLR); + ASSERT(stream <= mask); + val = STM32_DMA_CSELR(channel) & ~(mask << ch * shift); + STM32_DMA_CSELR(channel) = val | (stream << ch * shift); +} +#endif + void dma_disable(enum dma_channel channel) { stm32_dma_chan_t *chan = dma_get_channel(channel); diff --git a/chip/stm32/registers.h b/chip/stm32/registers.h index 283fd44498..74eee526cb 100644 --- a/chip/stm32/registers.h +++ b/chip/stm32/registers.h @@ -1233,6 +1233,9 @@ typedef volatile struct stm32_dma_regs stm32_dma_regs_t; #define STM32_DMA_REGS(channel) \ ((channel) < STM32_DMAC_PER_CTLR ? STM32_DMA1_REGS : STM32_DMA2_REGS) +#define STM32_DMA_CSELR(channel) \ + REG32(((channel) < STM32_DMAC_PER_CTLR ? \ + STM32_DMA1_BASE : STM32_DMA2_BASE) + 0xA8) #else #define STM32_DMA_REGS(channel) STM32_DMA1_REGS #endif diff --git a/chip/stm32/stm32-dma.h b/chip/stm32/stm32-dma.h new file mode 100644 index 0000000000..06233b9c93 --- /dev/null +++ b/chip/stm32/stm32-dma.h @@ -0,0 +1,16 @@ +/* Copyright 2016 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/** + * Select DMA stream-channel mapping + * + * This selects which stream (peripheral) to be used on a specific channel. + * Some STM32 chips simply logically OR requests, thus do not require this + * selection. + * + * @param channel: (Global) channel # base 0 (Note some STM32s use base 1) + * @param peripheral: Refer to the TRM for 'peripheral request signals' + */ +void dma_select_channel(enum dma_channel channel, unsigned char stream); -- cgit v1.2.1