mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 03:00:34 +03:00
feat(dma2d,ppa): Support flash encryption for DMA2D and PPA
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -118,6 +118,7 @@ bool ppa_blend_transaction_on_picked(uint32_t num_chans, const dma2d_trans_chann
|
||||
dma2d_connect(dma2d_rx_chan, &trig_periph);
|
||||
|
||||
dma2d_transfer_ability_t dma_transfer_ability = {
|
||||
.access_ext_mem = true, // in most cases the buffers are located in external memory, will not bother checking the memory region of the buffers
|
||||
.data_burst_length = blend_trans_desc->data_burst_length,
|
||||
.desc_burst_en = true,
|
||||
.mb_size = DMA2D_MACRO_BLOCK_SIZE_NONE,
|
||||
@@ -187,9 +188,6 @@ esp_err_t ppa_do_blend(ppa_client_handle_t ppa_client, const ppa_blend_oper_conf
|
||||
ESP_RETURN_ON_FALSE(config->mode <= PPA_TRANS_MODE_NON_BLOCKING, ESP_ERR_INVALID_ARG, TAG, "invalid mode");
|
||||
// in_buffer could be anywhere (ram, flash, psram), out_buffer ptr cannot in flash region
|
||||
ESP_RETURN_ON_FALSE(esp_ptr_internal(config->out.buffer) || esp_ptr_external_ram(config->out.buffer), ESP_ERR_INVALID_ARG, TAG, "invalid out.buffer addr");
|
||||
uint32_t buf_alignment_size = (uint32_t)ppa_client->engine->platform->buf_alignment_size;
|
||||
ESP_RETURN_ON_FALSE(((uint32_t)config->out.buffer & (buf_alignment_size - 1)) == 0 && (config->out.buffer_size & (buf_alignment_size - 1)) == 0,
|
||||
ESP_ERR_INVALID_ARG, TAG, "out.buffer addr or out.buffer_size not aligned to cache line size");
|
||||
ESP_RETURN_ON_FALSE(ppa_ll_blend_is_color_mode_supported(config->in_bg.blend_cm) && ppa_ll_blend_is_color_mode_supported(config->in_fg.blend_cm) && ppa_ll_blend_is_color_mode_supported(config->out.blend_cm), ESP_ERR_INVALID_ARG, TAG, "unsupported color mode");
|
||||
// For YUV420 input/output: in desc, ha/hb/va/vb/x/y must be even number
|
||||
// For YUV422 input/output: in desc, ha/hb/x must be even number
|
||||
@@ -236,6 +234,13 @@ esp_err_t ppa_do_blend(ppa_client_handle_t ppa_client, const ppa_blend_oper_conf
|
||||
ESP_RETURN_ON_FALSE(config->in_fg.block_w <= (config->out.pic_w - config->out.block_offset_x) &&
|
||||
config->in_fg.block_h <= (config->out.pic_h - config->out.block_offset_y),
|
||||
ESP_ERR_INVALID_ARG, TAG, "block does not fit in the out pic");
|
||||
|
||||
if (!ppa_check_buffer_alignment(ppa_client, &config->in_bg, true, config->in_bg.block_w) ||
|
||||
!ppa_check_buffer_alignment(ppa_client, &config->in_fg, true, config->in_fg.block_w) ||
|
||||
!ppa_check_buffer_alignment(ppa_client, &config->out, false, config->in_fg.block_w)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (config->bg_byte_swap) {
|
||||
PPA_CHECK_CM_SUPPORT_BYTE_SWAP("in_bg.blend", (uint32_t)config->in_bg.blend_cm);
|
||||
}
|
||||
@@ -268,6 +273,7 @@ esp_err_t ppa_do_blend(ppa_client_handle_t ppa_client, const ppa_blend_oper_conf
|
||||
|
||||
// Write back and invalidate necessary data (note that the window content is not continuous in the buffer)
|
||||
// Write back in_bg_buffer, in_fg_buffer extended windows (alignment not necessary on C2M direction)
|
||||
uint32_t buf_alignment_size = (uint32_t)ppa_client->engine->platform->buf_alignment_size;
|
||||
color_space_pixel_format_t in_bg_pixel_format = {
|
||||
.color_type_id = config->in_bg.blend_cm,
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "freertos/queue.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "esp_cache.h"
|
||||
#include "esp_memory_utils.h"
|
||||
#include "esp_private/esp_cache_private.h"
|
||||
#include "hal/cache_hal.h"
|
||||
#include "hal/cache_ll.h"
|
||||
@@ -30,7 +31,11 @@
|
||||
#include "hal/ppa_hal.h"
|
||||
#include "hal/ppa_ll.h"
|
||||
#include "hal/ppa_types.h"
|
||||
#include "hal/color_hal.h"
|
||||
#include "hal/color_types.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "hal/efuse_hal.h"
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
static const char *TAG = "ppa_core";
|
||||
|
||||
@@ -276,6 +281,10 @@ esp_err_t ppa_register_client(const ppa_client_config_t *config, ppa_client_hand
|
||||
client->oper_type = config->oper_type;
|
||||
client->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED;
|
||||
client->data_burst_length = config->data_burst_length ? config->data_burst_length : PPA_DATA_BURST_LENGTH_128;
|
||||
if (efuse_hal_flash_encryption_enabled() && (client->data_burst_length < SOC_MEMSPI_ENCRYPTION_ALIGNMENT)) {
|
||||
ESP_LOGW(TAG, "flash encryption is enabled, but selected data burst length does not meet encryption alignment restriction if accessing external memory, will be automatically adjusted later on");
|
||||
}
|
||||
|
||||
if (config->oper_type == PPA_OPERATION_SRM) {
|
||||
ppa_engine_config_t engine_config = {
|
||||
.engine = PPA_ENGINE_TYPE_SRM,
|
||||
@@ -525,3 +534,47 @@ esp_err_t ppa_set_rgb2gray_formula(uint8_t r_weight, uint8_t g_weight, uint8_t b
|
||||
_lock_release(&s_platform.mutex);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
bool ppa_check_buffer_alignment(ppa_client_handle_t ppa_client, const void *pic_blk_config, bool is_input, uint32_t block_width)
|
||||
{
|
||||
// 1. check with cache line size alignment (output buffer only)
|
||||
uint32_t buf_alignment_size = (uint32_t)ppa_client->engine->platform->buf_alignment_size;
|
||||
if (!is_input) {
|
||||
ppa_out_pic_blk_config_t *out_pic_blk_config = (ppa_out_pic_blk_config_t *)pic_blk_config;
|
||||
if (((uint32_t)out_pic_blk_config->buffer & (buf_alignment_size - 1)) != 0 || (out_pic_blk_config->buffer_size & (buf_alignment_size - 1)) != 0) {
|
||||
ESP_LOGE(TAG, "out.buffer addr or out.buffer_size not aligned to cache line size");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. check with mspi encryption alignment
|
||||
// When flash encryption is enabled, and in/out buffer are in PSRAM (if located in internal RAM, there is no alignment restriction due to encryption):
|
||||
// - The width of the window multiply byte number of one pixel should align to SOC_MEMSPI_ENCRYPTION_ALIGNMENT
|
||||
// - The starting address of every row of the window should align to SOC_MEMSPI_ENCRYPTION_ALIGNMENT
|
||||
// (which also implies the address and size of the in/out buffer will align to SOC_MEMSPI_ENCRYPTION_ALIGNMENT)
|
||||
|
||||
// check pic_width, block_width, block_head
|
||||
const void *buffer = (is_input) ? ((ppa_in_pic_blk_config_t *)pic_blk_config)->buffer : ((ppa_out_pic_blk_config_t *)pic_blk_config)->buffer;
|
||||
if (efuse_hal_flash_encryption_enabled() && !esp_ptr_internal(buffer)) {
|
||||
if (ppa_client->engine->type == PPA_ENGINE_TYPE_SRM) {
|
||||
ESP_LOGE(TAG, "SRM processes by macro blocks, where alignment is uncontrollable, makes it unable to work with flash encrypted if buffer is in external memory");
|
||||
return false;
|
||||
}
|
||||
uint32_t pic_width = (is_input) ? ((ppa_in_pic_blk_config_t *)pic_blk_config)->pic_w : ((ppa_out_pic_blk_config_t *)pic_blk_config)->pic_w;
|
||||
uint32_t block_offset_x = (is_input) ? ((ppa_in_pic_blk_config_t *)pic_blk_config)->block_offset_x : ((ppa_out_pic_blk_config_t *)pic_blk_config)->block_offset_x;
|
||||
uint32_t color_mode = (is_input) ? ((ppa_in_pic_blk_config_t *)pic_blk_config)->cm : ((ppa_out_pic_blk_config_t *)pic_blk_config)->cm;
|
||||
color_space_pixel_format_t pixel_format = {
|
||||
.color_type_id = color_mode,
|
||||
};
|
||||
uint32_t pixel_depth_bytes = color_hal_pixel_format_get_bit_depth(pixel_format) / 8; // bytes
|
||||
|
||||
if (((pic_width * pixel_depth_bytes) & (SOC_MEMSPI_ENCRYPTION_ALIGNMENT - 1)) != 0 ||
|
||||
((block_width * pixel_depth_bytes) & (SOC_MEMSPI_ENCRYPTION_ALIGNMENT - 1)) != 0 ||
|
||||
((block_offset_x * pixel_depth_bytes) & (SOC_MEMSPI_ENCRYPTION_ALIGNMENT - 1)) != 0) {
|
||||
ESP_LOGE(TAG, "(pic_width/block_width/block_offset_x * pixel_depth_bytes) not aligned to SOC_MEMSPI_ENCRYPTION_ALIGNMENT");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -62,6 +62,7 @@ bool ppa_fill_transaction_on_picked(uint32_t num_chans, const dma2d_trans_channe
|
||||
dma2d_connect(dma2d_rx_chan, &trig_periph);
|
||||
|
||||
dma2d_transfer_ability_t dma_transfer_ability = {
|
||||
.access_ext_mem = true, // in most cases the buffer is located in external memory, will not bother checking the memory region of the buffer
|
||||
.data_burst_length = fill_trans_desc->data_burst_length,
|
||||
.desc_burst_en = true,
|
||||
.mb_size = DMA2D_MACRO_BLOCK_SIZE_NONE,
|
||||
@@ -93,9 +94,6 @@ esp_err_t ppa_do_fill(ppa_client_handle_t ppa_client, const ppa_fill_oper_config
|
||||
ESP_RETURN_ON_FALSE(config->mode <= PPA_TRANS_MODE_NON_BLOCKING, ESP_ERR_INVALID_ARG, TAG, "invalid mode");
|
||||
// out_buffer ptr cannot in flash region
|
||||
ESP_RETURN_ON_FALSE(esp_ptr_internal(config->out.buffer) || esp_ptr_external_ram(config->out.buffer), ESP_ERR_INVALID_ARG, TAG, "invalid out.buffer addr");
|
||||
uint32_t buf_alignment_size = (uint32_t)ppa_client->engine->platform->buf_alignment_size;
|
||||
ESP_RETURN_ON_FALSE(((uint32_t)config->out.buffer & (buf_alignment_size - 1)) == 0 && (config->out.buffer_size & (buf_alignment_size - 1)) == 0,
|
||||
ESP_ERR_INVALID_ARG, TAG, "out.buffer addr or out.buffer_size not aligned to cache line size");
|
||||
ESP_RETURN_ON_FALSE(ppa_ll_blend_is_color_mode_supported((ppa_blend_color_mode_t)config->out.fill_cm), ESP_ERR_INVALID_ARG, TAG, "unsupported color mode");
|
||||
// For YUV420 output: in desc, ha/hb/va/vb/x/y must be even number
|
||||
// For YUV422 output: in desc, ha/hb/x must be even number
|
||||
@@ -117,10 +115,15 @@ esp_err_t ppa_do_fill(ppa_client_handle_t ppa_client, const ppa_fill_oper_config
|
||||
ESP_RETURN_ON_FALSE(config->fill_block_w <= (config->out.pic_w - config->out.block_offset_x) &&
|
||||
config->fill_block_h <= (config->out.pic_h - config->out.block_offset_y),
|
||||
ESP_ERR_INVALID_ARG, TAG, "block does not fit in the out pic");
|
||||
|
||||
if (!ppa_check_buffer_alignment(ppa_client, &config->out, false, config->fill_block_w)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
// To reduce complexity, specific color_mode, fill_block_w/h correctness are checked in their corresponding LL functions
|
||||
|
||||
// Write back and invalidate necessary data (note that the window content is not continuous in the buffer)
|
||||
// Write back and invalidate buffer extended window (alignment not necessary on C2M direction, but alignment strict on M2C direction)
|
||||
uint32_t buf_alignment_size = (uint32_t)ppa_client->engine->platform->buf_alignment_size;
|
||||
uint32_t out_ext_window = (uint32_t)config->out.buffer + config->out.block_offset_y * config->out.pic_w * out_pixel_depth / 8;
|
||||
uint32_t out_ext_window_aligned = PPA_ALIGN_DOWN(out_ext_window, buf_alignment_size);
|
||||
uint32_t out_ext_window_len = config->out.pic_w * config->fill_block_h * out_pixel_depth / 8;
|
||||
|
||||
@@ -225,6 +225,8 @@ bool ppa_transaction_done_cb(dma2d_channel_handle_t dma2d_chan, dma2d_event_data
|
||||
|
||||
bool ppa_recycle_transaction(ppa_client_handle_t ppa_client, ppa_trans_t *trans_elm);
|
||||
|
||||
bool ppa_check_buffer_alignment(ppa_client_handle_t ppa_client, const void *pic_blk_config, bool is_input, uint32_t block_width);
|
||||
|
||||
/****************************** PPA DRIVER ***********************************/
|
||||
|
||||
struct ppa_platform_t {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -93,6 +93,7 @@ bool ppa_srm_transaction_on_picked(uint32_t num_chans, const dma2d_trans_channel
|
||||
dma2d_connect(dma2d_rx_chan, &trig_periph);
|
||||
|
||||
dma2d_transfer_ability_t dma_transfer_ability = {
|
||||
.access_ext_mem = true, // in most cases the buffers are located in external memory, will not bother checking the memory region of the buffers
|
||||
.data_burst_length = srm_trans_desc->data_burst_length,
|
||||
.desc_burst_en = true,
|
||||
.mb_size = DMA2D_MACRO_BLOCK_SIZE_NONE,
|
||||
@@ -191,9 +192,6 @@ esp_err_t ppa_do_scale_rotate_mirror(ppa_client_handle_t ppa_client, const ppa_s
|
||||
ESP_RETURN_ON_FALSE(config->mode <= PPA_TRANS_MODE_NON_BLOCKING, ESP_ERR_INVALID_ARG, TAG, "invalid mode");
|
||||
// in_buffer could be anywhere (ram, flash, psram), out_buffer ptr cannot in flash region
|
||||
ESP_RETURN_ON_FALSE(esp_ptr_internal(config->out.buffer) || esp_ptr_external_ram(config->out.buffer), ESP_ERR_INVALID_ARG, TAG, "invalid out.buffer addr");
|
||||
uint32_t buf_alignment_size = (uint32_t)ppa_client->engine->platform->buf_alignment_size;
|
||||
ESP_RETURN_ON_FALSE(((uint32_t)config->out.buffer & (buf_alignment_size - 1)) == 0 && (config->out.buffer_size & (buf_alignment_size - 1)) == 0,
|
||||
ESP_ERR_INVALID_ARG, TAG, "out.buffer addr or out.buffer_size not aligned to cache line size");
|
||||
ESP_RETURN_ON_FALSE(ppa_ll_srm_is_color_mode_supported(config->in.srm_cm) &&
|
||||
(ppa_ll_srm_is_color_mode_supported(config->out.srm_cm) && config->out.srm_cm != PPA_SRM_COLOR_MODE_YUV444),
|
||||
ESP_ERR_INVALID_ARG, TAG, "unsupported color mode");
|
||||
@@ -228,18 +226,28 @@ esp_err_t ppa_do_scale_rotate_mirror(ppa_client_handle_t ppa_client, const ppa_s
|
||||
ESP_RETURN_ON_FALSE(config->scale_x < PPA_LL_SRM_SCALING_INT_MAX && config->scale_x >= (1.0 / PPA_LL_SRM_SCALING_FRAG_MAX) &&
|
||||
config->scale_y < PPA_LL_SRM_SCALING_INT_MAX && config->scale_y >= (1.0 / PPA_LL_SRM_SCALING_FRAG_MAX),
|
||||
ESP_ERR_INVALID_ARG, TAG, "invalid scale");
|
||||
uint32_t scale_x_int = (uint32_t)config->scale_x;
|
||||
uint32_t scale_x_frag = (uint32_t)(config->scale_x * PPA_LL_SRM_SCALING_FRAG_MAX) & (PPA_LL_SRM_SCALING_FRAG_MAX - 1);
|
||||
uint32_t scale_y_int = (uint32_t)config->scale_y;
|
||||
uint32_t scale_y_frag = (uint32_t)(config->scale_y * PPA_LL_SRM_SCALING_FRAG_MAX) & (PPA_LL_SRM_SCALING_FRAG_MAX - 1);
|
||||
uint32_t new_block_w = 0;
|
||||
uint32_t new_block_h = 0;
|
||||
if (config->rotation_angle == PPA_SRM_ROTATION_ANGLE_0 || config->rotation_angle == PPA_SRM_ROTATION_ANGLE_180) {
|
||||
new_block_w = (uint32_t)(config->scale_x * config->in.block_w);
|
||||
new_block_h = (uint32_t)(config->scale_y * config->in.block_h);
|
||||
new_block_w = (uint32_t)(scale_x_int * config->in.block_w + scale_x_frag * config->in.block_w / PPA_LL_SRM_SCALING_FRAG_MAX);
|
||||
new_block_h = (uint32_t)(scale_y_int * config->in.block_h + scale_y_frag * config->in.block_h / PPA_LL_SRM_SCALING_FRAG_MAX);
|
||||
} else {
|
||||
new_block_w = (uint32_t)(config->scale_y * config->in.block_h);
|
||||
new_block_h = (uint32_t)(config->scale_x * config->in.block_w);
|
||||
new_block_w = (uint32_t)(scale_y_int * config->in.block_h + scale_y_frag * config->in.block_h / PPA_LL_SRM_SCALING_FRAG_MAX);
|
||||
new_block_h = (uint32_t)(scale_x_int * config->in.block_w + scale_x_frag * config->in.block_w / PPA_LL_SRM_SCALING_FRAG_MAX);
|
||||
}
|
||||
ESP_RETURN_ON_FALSE(new_block_w <= (config->out.pic_w - config->out.block_offset_x) &&
|
||||
new_block_h <= (config->out.pic_h - config->out.block_offset_y),
|
||||
ESP_ERR_INVALID_ARG, TAG, "scale does not fit in the out pic");
|
||||
|
||||
if (!ppa_check_buffer_alignment(ppa_client, &config->in, true, config->in.block_w) ||
|
||||
!ppa_check_buffer_alignment(ppa_client, &config->out, false, new_block_w)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (config->byte_swap) {
|
||||
PPA_CHECK_CM_SUPPORT_BYTE_SWAP("in.srm", (uint32_t)config->in.srm_cm);
|
||||
}
|
||||
@@ -258,6 +266,7 @@ esp_err_t ppa_do_scale_rotate_mirror(ppa_client_handle_t ppa_client, const ppa_s
|
||||
|
||||
// Write back and invalidate necessary data (note that the window content is not continuous in the buffer)
|
||||
// Write back in_buffer extended window (alignment not necessary on C2M direction)
|
||||
uint32_t buf_alignment_size = (uint32_t)ppa_client->engine->platform->buf_alignment_size;
|
||||
color_space_pixel_format_t in_pixel_format = {
|
||||
.color_type_id = config->in.srm_cm,
|
||||
};
|
||||
@@ -282,10 +291,10 @@ esp_err_t ppa_do_scale_rotate_mirror(ppa_client_handle_t ppa_client, const ppa_s
|
||||
|
||||
ppa_srm_oper_t *srm_trans_desc = (ppa_srm_oper_t *)trans_on_picked_desc->srm_desc;
|
||||
memcpy(srm_trans_desc, config, sizeof(ppa_srm_oper_config_t));
|
||||
srm_trans_desc->scale_x_int = (uint32_t)srm_trans_desc->scale_x;
|
||||
srm_trans_desc->scale_x_frag = (uint32_t)(srm_trans_desc->scale_x * PPA_LL_SRM_SCALING_FRAG_MAX) & (PPA_LL_SRM_SCALING_FRAG_MAX - 1);
|
||||
srm_trans_desc->scale_y_int = (uint32_t)srm_trans_desc->scale_y;
|
||||
srm_trans_desc->scale_y_frag = (uint32_t)(srm_trans_desc->scale_y * PPA_LL_SRM_SCALING_FRAG_MAX) & (PPA_LL_SRM_SCALING_FRAG_MAX - 1);
|
||||
srm_trans_desc->scale_x_int = scale_x_int;
|
||||
srm_trans_desc->scale_x_frag = scale_x_frag;
|
||||
srm_trans_desc->scale_y_int = scale_y_int;
|
||||
srm_trans_desc->scale_y_frag = scale_y_frag;
|
||||
// SRM processes in blocks. Block x/(y) cannot be scaled to odd number when YUV422/YUV420 is the output color mode
|
||||
// When block size is 16x16, odd number is possible, so needs to make them even
|
||||
// When block size is 32x32, calculated frag values are always even
|
||||
|
||||
Reference in New Issue
Block a user