mirror of
https://github.com/espressif/esp-idf
synced 2025-03-09 09:09:10 -04:00
Merge branch 'bugfix/ppa_srm_scale_frag_yuv420' into 'master'
fix(ppa): fix ppa srm potentially get blocked when scaling to YUV420 Closes IDF-12468 See merge request espressif/esp-idf!37318
This commit is contained in:
commit
65044efa22
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -263,6 +263,13 @@ esp_err_t ppa_do_scale_rotate_mirror(ppa_client_handle_t ppa_client, const ppa_s
|
||||
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 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
|
||||
if (config->out.srm_cm == PPA_SRM_COLOR_MODE_YUV420) {
|
||||
srm_trans_desc->scale_x_frag = srm_trans_desc->scale_x_frag & ~1;
|
||||
srm_trans_desc->scale_y_frag = srm_trans_desc->scale_y_frag & ~1;
|
||||
}
|
||||
srm_trans_desc->alpha_value = new_alpha_value;
|
||||
srm_trans_desc->data_burst_length = ppa_client->data_burst_length;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -298,7 +298,7 @@ static NOINLINE_ATTR bool _dma2d_default_rx_isr(dma2d_group_t *group, int channe
|
||||
}
|
||||
}
|
||||
|
||||
// If last transcation completes (regardless success or not), free the channels
|
||||
// If last transaction completes (regardless success or not), free the channels
|
||||
if (intr_status & (DMA2D_LL_EVENT_RX_SUC_EOF | DMA2D_LL_EVENT_RX_ERR_EOF | DMA2D_LL_EVENT_RX_DESC_ERROR)) {
|
||||
if (!(intr_status & DMA2D_LL_EVENT_RX_ERR_EOF)) {
|
||||
assert(dma2d_ll_rx_is_fsm_idle(group->hal.dev, channel_id));
|
||||
@ -957,12 +957,14 @@ esp_err_t dma2d_force_end(dma2d_trans_t *trans, bool *need_yield)
|
||||
dma2d_group_t *group = trans->rx_chan->group;
|
||||
|
||||
bool in_flight = false;
|
||||
// We judge whether the transaction is in-flight by checking the RX channel it uses is in-use or free
|
||||
// We judge whether the transaction is in-flight by checking the RX channel it uses is being occupied or free
|
||||
portENTER_CRITICAL_SAFE(&group->spinlock);
|
||||
if (!(group->rx_channel_free_mask & (1 << trans->rx_chan->channel_id))) {
|
||||
in_flight = true;
|
||||
dma2d_ll_rx_enable_interrupt(group->hal.dev, trans->rx_chan->channel_id, UINT32_MAX, false);
|
||||
assert(!dma2d_ll_rx_is_fsm_idle(group->hal.dev, trans->rx_chan->channel_id));
|
||||
// DMA consumer could generate an error in both cases:
|
||||
// 1. when TX or RX is transferring data (channel not in idle state)
|
||||
// 2. TX successfully passed data to the module, but module cannot process the data, so RX has no data to delivery (RX channel in idle state)
|
||||
}
|
||||
portEXIT_CRITICAL_SAFE(&group->spinlock);
|
||||
ESP_RETURN_ON_FALSE_ISR(in_flight, ESP_ERR_INVALID_STATE, TAG, "transaction not in-flight");
|
||||
|
Loading…
x
Reference in New Issue
Block a user