feat(ppa): add PPA driver support for ESP32P4
Fix pm_lock assert and assign to NULL Alpha value union Tested with CONFIG_PM_ENABLE
This commit is contained in:
@@ -199,7 +199,22 @@ esp_err_t ppa_do_blend(ppa_client_handle_t ppa_client, const ppa_blend_oper_conf
|
||||
if (config->fg_rgb_swap) {
|
||||
PPA_CHECK_CM_SUPPORT_RGB_SWAP("in_fg.blend", (uint32_t)config->in_fg.blend_cm);
|
||||
}
|
||||
ESP_RETURN_ON_FALSE(config->bg_alpha_value <= 0xFF && config->fg_alpha_value <= 0xFF, ESP_ERR_INVALID_ARG, TAG, "invalid bg/fg_alpha_value");
|
||||
uint32_t new_bg_alpha_value = 0;
|
||||
if (config->bg_alpha_update_mode == PPA_ALPHA_FIX_VALUE) {
|
||||
ESP_RETURN_ON_FALSE(config->bg_alpha_fix_val <= 0xFF, ESP_ERR_INVALID_ARG, TAG, "invalid bg_alpha_fix_val");
|
||||
new_bg_alpha_value = config->bg_alpha_fix_val;
|
||||
} else if (config->bg_alpha_update_mode == PPA_ALPHA_SCALE) {
|
||||
ESP_RETURN_ON_FALSE(config->bg_alpha_scale_ratio > 0 && config->bg_alpha_scale_ratio < 1, ESP_ERR_INVALID_ARG, TAG, "invalid bg_alpha_scale_ratio");
|
||||
new_bg_alpha_value = (uint32_t)(config->bg_alpha_scale_ratio * 256);
|
||||
}
|
||||
uint32_t new_fg_alpha_value = 0;
|
||||
if (config->fg_alpha_update_mode == PPA_ALPHA_FIX_VALUE) {
|
||||
ESP_RETURN_ON_FALSE(config->fg_alpha_fix_val <= 0xFF, ESP_ERR_INVALID_ARG, TAG, "invalid fg_alpha_fix_val");
|
||||
new_fg_alpha_value = config->fg_alpha_fix_val;
|
||||
} else if (config->fg_alpha_update_mode == PPA_ALPHA_SCALE) {
|
||||
ESP_RETURN_ON_FALSE(config->fg_alpha_scale_ratio > 0 && config->fg_alpha_scale_ratio < 1, ESP_ERR_INVALID_ARG, TAG, "invalid fg_alpha_scale_ratio");
|
||||
new_fg_alpha_value = (uint32_t)(config->fg_alpha_scale_ratio * 256);
|
||||
}
|
||||
if (config->in_bg.blend_cm == PPA_BLEND_COLOR_MODE_L4) {
|
||||
ESP_RETURN_ON_FALSE(config->in_bg.block_w % 2 == 0 && config->in_bg.block_offset_x % 2 == 0,
|
||||
ESP_ERR_INVALID_ARG, TAG, "in_bg.block_w and in_bg.block_offset_x must be even");
|
||||
@@ -234,6 +249,8 @@ esp_err_t ppa_do_blend(ppa_client_handle_t ppa_client, const ppa_blend_oper_conf
|
||||
|
||||
ppa_blend_oper_t *blend_trans_desc = (ppa_blend_oper_t *)trans_on_picked_desc->blend_desc;
|
||||
memcpy(blend_trans_desc, config, sizeof(ppa_blend_oper_config_t));
|
||||
blend_trans_desc->bg_alpha_value = new_bg_alpha_value;
|
||||
blend_trans_desc->fg_alpha_value = new_fg_alpha_value;
|
||||
|
||||
trans_on_picked_desc->ppa_engine = ppa_client->engine;
|
||||
trans_on_picked_desc->trigger_periph = DMA2D_TRIG_PERIPH_PPA_BLEND;
|
||||
|
||||
@@ -220,7 +220,8 @@ static esp_err_t ppa_engine_release(ppa_engine_t *ppa_engine)
|
||||
vSemaphoreDeleteWithCaps(srm_engine->base.sem);
|
||||
#if CONFIG_PM_ENABLE
|
||||
if (srm_engine->base.pm_lock) {
|
||||
assert(esp_pm_lock_delete(srm_engine->base.pm_lock) == ESP_OK);
|
||||
ret = esp_pm_lock_delete(srm_engine->base.pm_lock);
|
||||
assert(ret == ESP_OK);
|
||||
}
|
||||
#endif
|
||||
free(srm_engine);
|
||||
@@ -238,7 +239,8 @@ static esp_err_t ppa_engine_release(ppa_engine_t *ppa_engine)
|
||||
vSemaphoreDeleteWithCaps(blending_engine->base.sem);
|
||||
#if CONFIG_PM_ENABLE
|
||||
if (blending_engine->base.pm_lock) {
|
||||
assert(esp_pm_lock_delete(blending_engine->base.pm_lock) == ESP_OK);
|
||||
ret = esp_pm_lock_delete(blending_engine->base.pm_lock);
|
||||
assert(ret == ESP_OK);
|
||||
}
|
||||
#endif
|
||||
free(blending_engine);
|
||||
@@ -250,7 +252,9 @@ static esp_err_t ppa_engine_release(ppa_engine_t *ppa_engine)
|
||||
|
||||
#if CONFIG_PM_ENABLE
|
||||
if (s_platform.pm_lock) {
|
||||
assert(esp_pm_lock_delete(s_platform.pm_lock) == ESP_OK);
|
||||
ret = esp_pm_lock_delete(s_platform.pm_lock);
|
||||
assert(ret == ESP_OK);
|
||||
s_platform.pm_lock = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -389,7 +393,8 @@ static bool ppa_malloc_transaction(QueueHandle_t trans_elm_ptr_queue, uint32_t t
|
||||
new_trans_elm->sem = ppa_trans_sem;
|
||||
|
||||
// Fill the ring buffer with allocated transaction element pointer
|
||||
assert(xQueueSend(trans_elm_ptr_queue, &new_trans_elm, 0));
|
||||
BaseType_t sent = xQueueSend(trans_elm_ptr_queue, &new_trans_elm, 0);
|
||||
assert(sent);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@@ -409,16 +414,19 @@ bool ppa_recycle_transaction(ppa_client_handle_t ppa_client, ppa_trans_t *trans_
|
||||
// Reset transaction and send back to client's trans_elm_ptr_queue
|
||||
// TODO: To be very safe, we shall memset all to 0, and reconnect necessary pointers?
|
||||
BaseType_t HPTaskAwoken;
|
||||
assert(xQueueSendFromISR(ppa_client->trans_elm_ptr_queue, &trans_elm, &HPTaskAwoken));
|
||||
BaseType_t sent = xQueueSendFromISR(ppa_client->trans_elm_ptr_queue, &trans_elm, &HPTaskAwoken);
|
||||
assert(sent);
|
||||
return HPTaskAwoken;
|
||||
}
|
||||
|
||||
esp_err_t ppa_do_operation(ppa_client_handle_t ppa_client, ppa_engine_t *ppa_engine_base, ppa_trans_t *trans_elm, ppa_trans_mode_t mode)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
esp_err_t pm_lock_ret __attribute__((unused));
|
||||
|
||||
#if CONFIG_PM_ENABLE
|
||||
assert((esp_pm_lock_acquire(s_platform.pm_lock) == ESP_OK) && "acquire pm_lock failed");
|
||||
pm_lock_ret = esp_pm_lock_acquire(s_platform.pm_lock);
|
||||
assert((pm_lock_ret == ESP_OK) && "acquire pm_lock failed");
|
||||
#endif
|
||||
|
||||
portENTER_CRITICAL(&ppa_client->spinlock);
|
||||
@@ -453,7 +461,8 @@ esp_err_t ppa_do_operation(ppa_client_handle_t ppa_client, ppa_engine_t *ppa_eng
|
||||
portEXIT_CRITICAL(&ppa_engine_base->spinlock);
|
||||
if (found) {
|
||||
#if CONFIG_PM_ENABLE
|
||||
assert((esp_pm_lock_acquire(ppa_engine_base->pm_lock) == ESP_OK) && "acquire pm_lock failed");
|
||||
pm_lock_ret = esp_pm_lock_acquire(ppa_engine_base->pm_lock);
|
||||
assert((pm_lock_ret == ESP_OK) && "acquire pm_lock failed");
|
||||
#endif
|
||||
ret = ppa_dma2d_enqueue(trans_elm);
|
||||
if (ret != ESP_OK) {
|
||||
@@ -461,7 +470,8 @@ esp_err_t ppa_do_operation(ppa_client_handle_t ppa_client, ppa_engine_t *ppa_eng
|
||||
STAILQ_REMOVE(&ppa_engine_base->trans_stailq, trans_elm, ppa_trans_s, entry);
|
||||
portEXIT_CRITICAL(&ppa_engine_base->spinlock);
|
||||
#if CONFIG_PM_ENABLE
|
||||
assert((esp_pm_lock_release(ppa_engine_base->pm_lock) == ESP_OK) && "release pm_lock failed");
|
||||
pm_lock_ret = esp_pm_lock_release(ppa_engine_base->pm_lock);
|
||||
assert((pm_lock_ret == ESP_OK) && "release pm_lock failed");
|
||||
#endif
|
||||
xSemaphoreGive(ppa_engine_base->sem);
|
||||
portENTER_CRITICAL(&ppa_client->spinlock);
|
||||
@@ -484,7 +494,8 @@ esp_err_t ppa_do_operation(ppa_client_handle_t ppa_client, ppa_engine_t *ppa_eng
|
||||
}
|
||||
|
||||
#if CONFIG_PM_ENABLE
|
||||
assert((esp_pm_lock_release(s_platform.pm_lock) == ESP_OK) && "release pm_lock failed");
|
||||
pm_lock_ret = esp_pm_lock_release(s_platform.pm_lock);
|
||||
assert((pm_lock_ret == ESP_OK) && "release pm_lock failed");
|
||||
#endif
|
||||
|
||||
err:
|
||||
@@ -517,7 +528,8 @@ bool ppa_transaction_done_cb(dma2d_channel_handle_t dma2d_chan, dma2d_event_data
|
||||
ppa_dma2d_enqueue(next_start_trans);
|
||||
} else {
|
||||
#if CONFIG_PM_ENABLE
|
||||
assert((esp_pm_lock_release(engine_base->pm_lock) == ESP_OK));
|
||||
esp_err_t pm_lock_ret = esp_pm_lock_release(engine_base->pm_lock);
|
||||
assert(pm_lock_ret == ESP_OK);
|
||||
#endif
|
||||
xSemaphoreGiveFromISR(engine_base->sem, &HPTaskAwoken);
|
||||
need_yield |= (HPTaskAwoken == pdTRUE);
|
||||
|
||||
@@ -86,7 +86,7 @@ struct ppa_client_t {
|
||||
/****************************** OPERATION ************************************/
|
||||
|
||||
// The elements in this structure listed first are identical to the elements in structure `ppa_srm_oper_config_t`
|
||||
// With adding a few extra elements in the end
|
||||
// With adding a few extra elements at the end
|
||||
// This allows memcpy
|
||||
typedef struct {
|
||||
ppa_in_pic_blk_config_t in;
|
||||
@@ -103,19 +103,62 @@ typedef struct {
|
||||
bool rgb_swap;
|
||||
bool byte_swap;
|
||||
ppa_alpha_update_mode_t alpha_update_mode;
|
||||
uint32_t alpha_value;
|
||||
union {
|
||||
uint32_t alpha_fix_val;
|
||||
float alpha_scale_ratio;
|
||||
};
|
||||
|
||||
ppa_trans_mode_t mode;
|
||||
// uint32_t timeout;
|
||||
void *user_data;
|
||||
|
||||
uint32_t scale_x_int;
|
||||
uint32_t scale_x_frag;
|
||||
uint32_t scale_y_int;
|
||||
uint32_t scale_y_frag;
|
||||
uint32_t scale_x_int; // Calculation result for the integral part of the scale_x to be directly written to register
|
||||
uint32_t scale_x_frag; // Calculation result for the fractional part of the scale_x to be directly written to register
|
||||
uint32_t scale_y_int; // Calculation result for the integral part of the scale_y to be directly written to register
|
||||
uint32_t scale_y_frag; // Calculation result for the fractional part of the scale_y to be directly written to register
|
||||
uint32_t alpha_value; // Calculation result for the fix alpha value to be directly written to register
|
||||
} ppa_srm_oper_t;
|
||||
|
||||
typedef ppa_blend_oper_config_t ppa_blend_oper_t;
|
||||
// The elements in this structure listed first are identical to the elements in structure `ppa_blend_oper_config_t`
|
||||
// With adding a few extra elements at the end
|
||||
// This allows memcpy
|
||||
typedef struct {
|
||||
ppa_in_pic_blk_config_t in_bg;
|
||||
ppa_in_pic_blk_config_t in_fg;
|
||||
ppa_out_pic_blk_config_t out;
|
||||
|
||||
// input data manipulation
|
||||
bool bg_rgb_swap;
|
||||
bool bg_byte_swap;
|
||||
ppa_alpha_update_mode_t bg_alpha_update_mode;
|
||||
union {
|
||||
uint32_t bg_alpha_fix_val;
|
||||
float bg_alpha_scale_ratio;
|
||||
};
|
||||
bool fg_rgb_swap;
|
||||
bool fg_byte_swap;
|
||||
ppa_alpha_update_mode_t fg_alpha_update_mode;
|
||||
union {
|
||||
uint32_t fg_alpha_fix_val;
|
||||
float fg_alpha_scale_ratio;
|
||||
};
|
||||
uint32_t fg_fix_rgb_val;
|
||||
|
||||
// color-keying
|
||||
bool bg_ck_en;
|
||||
uint32_t bg_ck_rgb_low_thres;
|
||||
uint32_t bg_ck_rgb_high_thres;
|
||||
bool fg_ck_en;
|
||||
uint32_t fg_ck_rgb_low_thres;
|
||||
uint32_t fg_ck_rgb_high_thres;
|
||||
uint32_t ck_rgb_default_val;
|
||||
bool ck_reverse_bg2fg;
|
||||
|
||||
ppa_trans_mode_t mode;
|
||||
void *user_data;
|
||||
|
||||
uint32_t bg_alpha_value; // Calculation result for the fix alpha value for BG to be directly written to register
|
||||
uint32_t fg_alpha_value; // Calculation result for the fix alpha value for FG to be directly written to register
|
||||
} ppa_blend_oper_t;
|
||||
|
||||
typedef ppa_fill_oper_config_t ppa_fill_oper_t;
|
||||
|
||||
|
||||
@@ -208,7 +208,14 @@ esp_err_t ppa_do_scale_rotate_mirror(ppa_client_handle_t ppa_client, const ppa_s
|
||||
if (config->rgb_swap) {
|
||||
PPA_CHECK_CM_SUPPORT_RGB_SWAP("in.srm", (uint32_t)config->in.srm_cm);
|
||||
}
|
||||
ESP_RETURN_ON_FALSE(config->alpha_value <= 0xFF, ESP_ERR_INVALID_ARG, TAG, "invalid alpha_value");
|
||||
uint32_t new_alpha_value = 0;
|
||||
if (config->alpha_update_mode == PPA_ALPHA_FIX_VALUE) {
|
||||
ESP_RETURN_ON_FALSE(config->alpha_fix_val <= 0xFF, ESP_ERR_INVALID_ARG, TAG, "invalid alpha_fix_val");
|
||||
new_alpha_value = config->alpha_fix_val;
|
||||
} else if (config->alpha_update_mode == PPA_ALPHA_SCALE) {
|
||||
ESP_RETURN_ON_FALSE(config->alpha_scale_ratio > 0 && config->alpha_scale_ratio < 1, ESP_ERR_INVALID_ARG, TAG, "invalid alpha_scale_ratio");
|
||||
new_alpha_value = (uint32_t)(config->alpha_scale_ratio * 256);
|
||||
}
|
||||
// To reduce complexity, rotation_angle, color_mode, alpha_update_mode correctness are checked in their corresponding LL functions
|
||||
// TODO:
|
||||
// YUV420: in desc, ha/hb/va/vb/x/y must be even number
|
||||
@@ -237,6 +244,7 @@ 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 + 1)) & PPA_LL_SRM_SCALING_FRAG_MAX;
|
||||
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 + 1)) & PPA_LL_SRM_SCALING_FRAG_MAX;
|
||||
srm_trans_desc->alpha_value = new_alpha_value;
|
||||
|
||||
trans_on_picked_desc->ppa_engine = ppa_client->engine;
|
||||
trans_on_picked_desc->trigger_periph = DMA2D_TRIG_PERIPH_PPA_SRM;
|
||||
|
||||
Reference in New Issue
Block a user