Skip to content

Commit 6ae7f18

Browse files
committed
Merge branch 'bugfix/ppa_buffer_writeback_invalidate_fix2_v5.3' into 'release/v5.3'
fix(ppa): fix a few minor issues for ppa driver (v5.3) See merge request espressif/esp-idf!34407
2 parents deed35c + 5a0eb90 commit 6ae7f18

File tree

4 files changed

+25
-12
lines changed

4 files changed

+25
-12
lines changed

components/esp_driver_ppa/src/ppa_blend.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -234,20 +234,27 @@ esp_err_t ppa_do_blend(ppa_client_handle_t ppa_client, const ppa_blend_oper_conf
234234
.color_type_id = config->in_bg.blend_cm,
235235
};
236236
uint32_t in_bg_pixel_depth = color_hal_pixel_format_get_bit_depth(in_bg_pixel_format); // bits
237+
// Usually C2M can let the msync do alignment internally, however, it only do L1-cacheline-size alignment for L1->L2, and then L2-cacheline-size alignment for L2->mem
238+
// While M2C direction manual alignment is L2-cacheline-size alignment for mem->L2->L1
239+
// Mismatching writeback and invalidate data size could cause synchronization error if in_bg/fg_buffer and out_buffer are the same one
237240
uint32_t in_bg_ext_window = (uint32_t)config->in_bg.buffer + config->in_bg.block_offset_y * config->in_bg.pic_w * in_bg_pixel_depth / 8;
241+
uint32_t in_bg_ext_window_aligned = PPA_ALIGN_DOWN(in_bg_ext_window, buf_alignment_size);
238242
uint32_t in_bg_ext_window_len = config->in_bg.pic_w * config->in_bg.block_h * in_bg_pixel_depth / 8;
239-
esp_cache_msync((void *)in_bg_ext_window, in_bg_ext_window_len, ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED);
243+
esp_cache_msync((void *)in_bg_ext_window_aligned, PPA_ALIGN_UP(in_bg_ext_window_len + (in_bg_ext_window - in_bg_ext_window_aligned), buf_alignment_size), ESP_CACHE_MSYNC_FLAG_DIR_C2M);
240244
color_space_pixel_format_t in_fg_pixel_format = {
241245
.color_type_id = config->in_fg.blend_cm,
242246
};
243247
uint32_t in_fg_pixel_depth = color_hal_pixel_format_get_bit_depth(in_fg_pixel_format); // bits
244248
uint32_t in_fg_ext_window = (uint32_t)config->in_fg.buffer + config->in_fg.block_offset_y * config->in_fg.pic_w * in_fg_pixel_depth / 8;
249+
// Same for fg_buffer msync, do manual alignment
250+
uint32_t in_fg_ext_window_aligned = PPA_ALIGN_DOWN(in_fg_ext_window, buf_alignment_size);
245251
uint32_t in_fg_ext_window_len = config->in_fg.pic_w * config->in_fg.block_h * in_fg_pixel_depth / 8;
246-
esp_cache_msync((void *)in_fg_ext_window, in_fg_ext_window_len, ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED);
252+
esp_cache_msync((void *)in_fg_ext_window_aligned, PPA_ALIGN_UP(in_fg_ext_window_len + (in_fg_ext_window - in_fg_ext_window_aligned), buf_alignment_size), ESP_CACHE_MSYNC_FLAG_DIR_C2M);
247253
// Invalidate out_buffer extended window (alignment strict on M2C direction)
248254
uint32_t out_ext_window = (uint32_t)config->out.buffer + config->out.block_offset_y * config->out.pic_w * out_pixel_depth / 8;
255+
uint32_t out_ext_window_aligned = PPA_ALIGN_DOWN(out_ext_window, buf_alignment_size);
249256
uint32_t out_ext_window_len = config->out.pic_w * config->in_bg.block_h * out_pixel_depth / 8;
250-
esp_cache_msync((void *)PPA_ALIGN_DOWN(out_ext_window, buf_alignment_size), PPA_ALIGN_UP(out_ext_window_len, buf_alignment_size), ESP_CACHE_MSYNC_FLAG_DIR_M2C);
257+
esp_cache_msync((void *)out_ext_window_aligned, PPA_ALIGN_UP(out_ext_window_len + (out_ext_window - out_ext_window_aligned), buf_alignment_size), ESP_CACHE_MSYNC_FLAG_DIR_M2C);
251258

252259
esp_err_t ret = ESP_OK;
253260
ppa_trans_t *trans_elm = NULL;

components/esp_driver_ppa/src/ppa_fill.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,9 @@ esp_err_t ppa_do_fill(ppa_client_handle_t ppa_client, const ppa_fill_oper_config
107107
// Write back and invalidate necessary data (note that the window content is not continuous in the buffer)
108108
// Write back and invalidate buffer extended window (alignment not necessary on C2M direction, but alignment strict on M2C direction)
109109
uint32_t out_ext_window = (uint32_t)config->out.buffer + config->out.block_offset_y * config->out.pic_w * out_pixel_depth / 8;
110+
uint32_t out_ext_window_aligned = PPA_ALIGN_DOWN(out_ext_window, buf_alignment_size);
110111
uint32_t out_ext_window_len = config->out.pic_w * config->fill_block_h * out_pixel_depth / 8;
111-
esp_cache_msync((void *)PPA_ALIGN_DOWN(out_ext_window, buf_alignment_size), PPA_ALIGN_UP(out_ext_window_len, buf_alignment_size), ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_INVALIDATE);
112+
esp_cache_msync((void *)out_ext_window_aligned, PPA_ALIGN_UP(out_ext_window_len + (out_ext_window - out_ext_window_aligned), buf_alignment_size), ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_INVALIDATE);
112113

113114
esp_err_t ret = ESP_OK;
114115
ppa_trans_t *trans_elm = NULL;

components/esp_driver_ppa/src/ppa_srm.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -194,14 +194,17 @@ esp_err_t ppa_do_scale_rotate_mirror(ppa_client_handle_t ppa_client, const ppa_s
194194
config->out.block_offset_x % 2 == 0 && config->out.block_offset_y % 2 == 0,
195195
ESP_ERR_INVALID_ARG, TAG, "YUV420 output does not support odd h/w/offset_x/offset_y");
196196
}
197+
ESP_RETURN_ON_FALSE(config->in.block_w <= (config->in.pic_w - config->in.block_offset_x) &&
198+
config->in.block_h <= (config->in.pic_h - config->in.block_offset_y),
199+
ESP_ERR_INVALID_ARG, TAG, "in.block_w/h + in.block_offset_x/y does not fit in the in pic");
197200
color_space_pixel_format_t out_pixel_format = {
198201
.color_type_id = config->out.srm_cm,
199202
};
200203
uint32_t out_pixel_depth = color_hal_pixel_format_get_bit_depth(out_pixel_format); // bits
201204
uint32_t out_pic_len = config->out.pic_w * config->out.pic_h * out_pixel_depth / 8;
202205
ESP_RETURN_ON_FALSE(out_pic_len <= config->out.buffer_size, ESP_ERR_INVALID_ARG, TAG, "out.pic_w/h mismatch with out.buffer_size");
203-
ESP_RETURN_ON_FALSE(config->scale_x < (PPA_LL_SRM_SCALING_INT_MAX + 1) && config->scale_x >= (1.0 / PPA_LL_SRM_SCALING_FRAG_MAX) &&
204-
config->scale_y < (PPA_LL_SRM_SCALING_INT_MAX + 1) && config->scale_y >= (1.0 / PPA_LL_SRM_SCALING_FRAG_MAX),
206+
ESP_RETURN_ON_FALSE(config->scale_x < PPA_LL_SRM_SCALING_INT_MAX && config->scale_x >= (1.0 / PPA_LL_SRM_SCALING_FRAG_MAX) &&
207+
config->scale_y < PPA_LL_SRM_SCALING_INT_MAX && config->scale_y >= (1.0 / PPA_LL_SRM_SCALING_FRAG_MAX),
205208
ESP_ERR_INVALID_ARG, TAG, "invalid scale");
206209
uint32_t new_block_w = 0;
207210
uint32_t new_block_h = 0;
@@ -242,8 +245,10 @@ esp_err_t ppa_do_scale_rotate_mirror(ppa_client_handle_t ppa_client, const ppa_s
242245
esp_cache_msync((void *)in_ext_window, in_ext_window_len, ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED);
243246
// Invalidate out_buffer extended window (alignment strict on M2C direction)
244247
uint32_t out_ext_window = (uint32_t)config->out.buffer + config->out.block_offset_y * config->out.pic_w * out_pixel_depth / 8;
245-
uint32_t out_ext_window_len = config->out.pic_w * config->in.block_h * out_pixel_depth / 8;
246-
esp_cache_msync((void *)PPA_ALIGN_DOWN(out_ext_window, buf_alignment_size), PPA_ALIGN_UP(out_ext_window_len, buf_alignment_size), ESP_CACHE_MSYNC_FLAG_DIR_M2C);
248+
uint32_t out_ext_window_aligned = PPA_ALIGN_DOWN(out_ext_window, buf_alignment_size);
249+
uint32_t out_ext_window_len = config->out.pic_w * new_block_h * out_pixel_depth / 8; // actual ext_window_len must be less than or equal to this, since actual block_h <= new_block_h (may round down)
250+
assert(out_ext_window + out_ext_window_len <= (uint32_t)config->out.buffer + config->out.buffer_size);
251+
esp_cache_msync((void *)out_ext_window_aligned, PPA_ALIGN_UP(out_ext_window_len + (out_ext_window - out_ext_window_aligned), buf_alignment_size), ESP_CACHE_MSYNC_FLAG_DIR_M2C);
247252

248253
esp_err_t ret = ESP_OK;
249254
ppa_trans_t *trans_elm = NULL;
@@ -255,9 +260,9 @@ esp_err_t ppa_do_scale_rotate_mirror(ppa_client_handle_t ppa_client, const ppa_s
255260
ppa_srm_oper_t *srm_trans_desc = (ppa_srm_oper_t *)trans_on_picked_desc->srm_desc;
256261
memcpy(srm_trans_desc, config, sizeof(ppa_srm_oper_config_t));
257262
srm_trans_desc->scale_x_int = (uint32_t)srm_trans_desc->scale_x;
258-
srm_trans_desc->scale_x_frag = (uint32_t)(srm_trans_desc->scale_x * (PPA_LL_SRM_SCALING_FRAG_MAX + 1)) & PPA_LL_SRM_SCALING_FRAG_MAX;
263+
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);
259264
srm_trans_desc->scale_y_int = (uint32_t)srm_trans_desc->scale_y;
260-
srm_trans_desc->scale_y_frag = (uint32_t)(srm_trans_desc->scale_y * (PPA_LL_SRM_SCALING_FRAG_MAX + 1)) & PPA_LL_SRM_SCALING_FRAG_MAX;
265+
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);
261266
srm_trans_desc->alpha_value = new_alpha_value;
262267
srm_trans_desc->data_burst_length = ppa_client->data_burst_length;
263268

components/hal/esp32p4/include/hal/ppa_ll.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ extern "C" {
2424
#define PPA_LL_BLEND0_CLUT_MEM_ADDR_OFFSET 0x400
2525
#define PPA_LL_BLEND1_CLUT_MEM_ADDR_OFFSET 0x800
2626

27-
#define PPA_LL_SRM_SCALING_INT_MAX PPA_SR_SCAL_X_INT_V
28-
#define PPA_LL_SRM_SCALING_FRAG_MAX PPA_SR_SCAL_X_FRAG_V
27+
#define PPA_LL_SRM_SCALING_INT_MAX (PPA_SR_SCAL_X_INT_V + 1)
28+
#define PPA_LL_SRM_SCALING_FRAG_MAX (PPA_SR_SCAL_X_FRAG_V + 1)
2929

3030
// TODO: On P4 ECO2, SRM block size needs update
3131
#define PPA_LL_SRM_DEFAULT_BLOCK_SIZE 18 // 18 x 18 block size

0 commit comments

Comments
 (0)