cache: stm32: add new cache API to display and i2s

Use sys_cache API to handle cache flush/invalidate.

Signed-off-by: Emil Lindqvist <emil@lindq.gr>
This commit is contained in:
Emil Lindqvist 2024-01-24 12:42:36 +01:00 committed by Fabio Baltieri
parent b898541809
commit 548fb97142
4 changed files with 9 additions and 31 deletions

View file

@ -8,6 +8,7 @@ menuconfig STM32_LTDC
default y
depends on DT_HAS_ST_STM32_LTDC_ENABLED
select USE_STM32_HAL_LTDC
select CACHE_MANAGEMENT if CPU_HAS_DCACHE
help
Enable driver for STM32 LCT-TFT display controller periheral.

View file

@ -18,6 +18,7 @@
#include <zephyr/drivers/clock_control.h>
#include <zephyr/pm/device.h>
#include <zephyr/sys/barrier.h>
#include <zephyr/cache.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(display_stm32_ltdc, CONFIG_DISPLAY_LOG_LEVEL);
@ -54,22 +55,6 @@ LOG_MODULE_REGISTER(display_stm32_ltdc, CONFIG_DISPLAY_LOG_LEVEL);
#error "Invalid LTDC pixel format chosen"
#endif
#if defined(CONFIG_HAS_CMSIS_CORE_M)
#include <cmsis_core.h>
#if defined(CONFIG_DCACHE)
#define CACHE_INVALIDATE(addr, size) SCB_InvalidateDCache_by_Addr((addr), (size))
#define CACHE_CLEAN(addr, size) SCB_CleanDCache_by_Addr((addr), (size))
#else
#define CACHE_INVALIDATE(addr, size)
#define CACHE_CLEAN(addr, size) barrier_dsync_fence_full();
#endif /* CONFIG_DCACHE */
#else
#define CACHE_INVALIDATE(addr, size)
#define CACHE_CLEAN(addr, size)
#endif /* CONFIG_HAS_CMSIS_CORE_M */
struct display_stm32_ltdc_data {
LTDC_HandleTypeDef hltdc;
enum display_pixel_format current_pixel_format;
@ -215,7 +200,7 @@ static int stm32_ltdc_write(const struct device *dev, const uint16_t x,
for (row = 0; row < desc->height; row++) {
(void) memcpy(dst, src, desc->width * data->current_pixel_size);
CACHE_CLEAN(dst, desc->width * data->current_pixel_size);
sys_cache_data_flush_range(dst, desc->width * data->current_pixel_size);
dst += (config->width * data->current_pixel_size);
src += (desc->pitch * data->current_pixel_size);
}
@ -252,7 +237,7 @@ static int stm32_ltdc_read(const struct device *dev, const uint16_t x,
for (row = 0; row < desc->height; row++) {
(void) memcpy(dst, src, desc->width * data->current_pixel_size);
CACHE_CLEAN(dst, desc->width * data->current_pixel_size);
sys_cache_data_flush_range(dst, desc->width * data->current_pixel_size);
src += (config->width * data->current_pixel_size);
dst += (desc->pitch * data->current_pixel_size);
}

View file

@ -7,6 +7,7 @@ menuconfig I2S_STM32
bool "STM32 MCU I2S controller driver"
default y
depends on DT_HAS_ST_STM32_I2S_ENABLED
select CACHE_MANAGEMENT if CPU_HAS_DCACHE
select DMA
help
Enable I2S support on the STM32 family of processors.

View file

@ -16,22 +16,13 @@
#include <zephyr/drivers/clock_control/stm32_clock_control.h>
#include <zephyr/drivers/clock_control.h>
#include <zephyr/drivers/pinctrl.h>
#include <zephyr/cache.h>
#include "i2s_ll_stm32.h"
#include <zephyr/logging/log.h>
#include <zephyr/irq.h>
LOG_MODULE_REGISTER(i2s_ll_stm32);
#if __DCACHE_PRESENT == 1
#define DCACHE_INVALIDATE(addr, size) \
SCB_InvalidateDCache_by_Addr((uint32_t *)addr, size)
#define DCACHE_CLEAN(addr, size) \
SCB_CleanDCache_by_Addr((uint32_t *)addr, size)
#else
#define DCACHE_INVALIDATE(addr, size) {; }
#define DCACHE_CLEAN(addr, size) {; }
#endif
#define MODULO_INC(val, max) { val = (++val < max) ? val : 0; }
static unsigned int div_round_closest(uint32_t dividend, uint32_t divisor)
@ -561,7 +552,7 @@ static void dma_rx_callback(const struct device *dma_dev, void *arg,
}
/* Assure cache coherency after DMA write operation */
DCACHE_INVALIDATE(mblk_tmp, stream->cfg.block_size);
sys_cache_data_invd_range(mblk_tmp, stream->cfg.block_size);
/* All block data received */
ret = queue_put(&stream->mem_block_queue, mblk_tmp,
@ -632,7 +623,7 @@ static void dma_tx_callback(const struct device *dma_dev, void *arg,
k_sem_give(&stream->sem);
/* Assure cache coherency before DMA read operation */
DCACHE_CLEAN(stream->mem_block, mem_block_size);
sys_cache_data_flush_range(stream->mem_block, mem_block_size);
ret = reload_dma(stream->dev_dma, stream->dma_channel,
&stream->dma_cfg,
@ -794,7 +785,7 @@ static int tx_stream_start(struct stream *stream, const struct device *dev)
k_sem_give(&stream->sem);
/* Assure cache coherency before DMA read operation */
DCACHE_CLEAN(stream->mem_block, mem_block_size);
sys_cache_data_flush_range(stream->mem_block, mem_block_size);
if (stream->master) {
LL_I2S_SetTransferMode(cfg->i2s, LL_I2S_MODE_MASTER_TX);