427 lines
15 KiB
C
Raw Normal View History

2025-10-10 16:07:00 +08:00
// Copyright 2021-2022 Beken
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <common/bk_include.h>
#include <soc/soc.h>
#include <driver/dma2d_types.h>
//#include "dma2d_ll.h"
#include "dma2d_hal.h"
#include "dma2d_ll_macro_def.h"
#include "bk_misc.h"
bk_err_t dma2d_hal_soft_reset(void)
{
#if CONFIG_SOC_BK7236XX
dma2d_ll_set_module_control_soft_reset(1);
delay_us(10);
dma2d_ll_set_module_control_soft_reset(0);
#endif
return BK_OK;
}
void dma2d_hal_transfes_ability(dma2d_trans_ability_t trans_ability)
{
#if CONFIG_SOC_BK7236XX
dma2d_ll_set_dma2d_control_reg_dma2d_ahb_burst_len(trans_ability);
#endif
}
bk_err_t dma2d_hal_init(dma2d_config_t *dma2d)
{
// 000:m2m; 001:m2m pixel convert with fg; 010:m2m blend; 011:r2m.only with output; 100: m2m blend fix fg; 101:m2m blend fix bg;
dma2d_ll_set_dma2d_control_reg_mode(dma2d->init.mode);
#if CONFIG_SOC_BK7256XX
dma2d_ll_set_dma2d_control_reg_master_tran_length(dma2d->init.trans_ability);
#elif CONFIG_SOC_BK7236XX
//dma2d_ll_set_dma2d_control_reg_dma2d_ahb_burst_len(dma2d->init.trans_ability);
dma2d_ll_set_module_control_clk_gate(1);
#endif
dma2d_ll_set_dma2d_control_reg_out_byte_revese(dma2d->init.out_byte_by_byte_reverse);
dma2d_ll_set_dma2d_control_reg_line_offset_mode(dma2d->init.line_offset_mode);
//0:argb888; 1:rgb888; 010:rgb565; 011:argb1555; 100:argb444; 101 YUYV
if (dma2d->init.mode == DMA2D_M2M)
dma2d_ll_set_out_pfc_contrl_out_color_mode(0);
else
dma2d_ll_set_out_pfc_contrl_out_color_mode(dma2d->init.color_mode);
#if CONFIG_SOC_BK7236XX
dma2d_ll_set_out_pfc_contrl_out_r2y_yuv_fmt( dma2d->init.color_mode - DMA2D_OUTPUT_YUYV);
#endif
dma2d_ll_set_out_pfc_contrl_out_alpha_invert(dma2d->init.alpha_inverted);
dma2d_ll_set_output_offset_out_line_offset(dma2d->init.output_offset);
dma2d_ll_set_dma2d_fg_pfc_ctrl_fg_rb_swap(dma2d->init.red_blue_swap);
return BK_OK;
}
bk_err_t dma2d_hal_deinit(void)
{
// 000:m2m; 001:m2m pixel convert with fg; 010:m2m blend; 011:r2m.only with output; 100: m2m blend fix fg; 101:m2m blend fix bg;
dma2d_ll_set_dma2d_control_reg_value(0);
dma2d_ll_set_dma2d_int_clear_value(0x3f);
//0:argb888; 1:rgb888; 010:rgb565; 011:argb1555; 100:argb444
dma2d_ll_set_out_pfc_contrl_value(0);
dma2d_ll_set_output_offset_value(0);
dma2d_ll_set_dma2d_fg_address_value(0);
dma2d_ll_set_dma2d_bg_address_value(0);
dma2d_ll_set_dma2d_fg_pfc_ctrl_value(0);
dma2d_ll_set_dma2d_fg_pfc_ctrl_value(0);
dma2d_ll_set_module_control_clk_gate(0);
return BK_OK;
}
/**
* @brief Set the DMA2D transfer parameters.
* @param dma2d Pointer to a dma2d_config_t structure that contains
* the configuration information for the specified DMA2D.
* @param src_addr The source memory Buffer address
* @param DstAddress The destination memory Buffer address
* @param Width The width of data to be transferred from source to destination.(number of pixel every line)
* @param Height The height of data to be transferred from source to destination.(number of line)
* @retval HAL status, uint32_t src_addr, uint32_t dst_addr, uint32_t width, uint32_t height
*/
bk_err_t dma2d_hal_config(dma2d_config_t *dma2d, uint32_t src_addr, uint32_t dst_addr, uint32_t width, uint32_t height)
{
dma2d_ll_set_dma2d_number_of_line_pexel_line(width);
dma2d_ll_set_dma2d_number_of_line_number_line(height);
dma2d_ll_set_dma2d_out_mem_address_out_mem_address(dst_addr);
// os_printf("dma2d dst_addr = %p %d %d\n", dst_addr, width, height);
if (dma2d->init.mode == DMA2D_R2M) {
#if(0)
uint32_t tmp;
uint32_t tmp1;
uint32_t tmp2;
uint32_t tmp3;
uint32_t tmp4;
tmp1 = src_addr & DMA2D_OCOLR_ALPHA_1;
tmp2 = src_addr & DMA2D_OCOLR_RED_1;
tmp3 = src_addr & DMA2D_OCOLR_GREEN_1;
tmp4 = src_addr & DMA2D_OCOLR_BLUE_1;
/* Prepare the value to be written to the OCOLR register according to the color mode */
if (dma2d->init.ColorMode == DMA2D_OUTPUT_ARGB8888) {
tmp = (tmp3 | tmp2 | tmp1| tmp4);
}
else if (dma2d->init.ColorMode == DMA2D_OUTPUT_RGB888) {
tmp = (tmp3 | tmp2 | tmp4);
}
else if (dma2d->init.ColorMode == DMA2D_OUTPUT_RGB565) {
tmp2 = (tmp2 >> 19U);
tmp3 = (tmp3 >> 10U);
tmp4 = (tmp4 >> 3U );
tmp = ((tmp3 << 5U) | (tmp2 << 11U) | tmp4);
}
else if (dma2d->init.ColorMode == DMA2D_OUTPUT_ARGB1555) {
tmp1 = (tmp1 >> 31U);
tmp2 = (tmp2 >> 19U);
tmp3 = (tmp3 >> 11U);
tmp4 = (tmp4 >> 3U );
tmp = ((tmp3 << 5U) | (tmp2 << 10U) | (tmp1 << 15U) | tmp4);
}
else /* Ddma2d->Init.ColorMode = DMA2D_OUTPUT_ARGB4444 */ {
tmp1 = (tmp1 >> 28U);
tmp2 = (tmp2 >> 20U);
tmp3 = (tmp3 >> 12U);
tmp4 = (tmp4 >> 4U );
tmp = ((tmp3 << 4U) | (tmp2 << 8U) | (tmp1 << 12U) | tmp4);
}
#endif
dma2d_ll_set_out_color_reg_output_clor_reg(src_addr);
}
else if (dma2d->init.mode == DMA2D_M2M_BLEND_FG) /*M2M_blending with fixed color FG DMA2D Mode selected*/ {
dma2d_ll_set_dma2d_bg_address_value(src_addr);
}
else /* M2M, M2M_PFC,M2M_Blending or M2M_blending with fixed color BG DMA2D Mode */ {
/* Configure DMA2D source address */
dma2d_ll_set_dma2d_fg_address_value(src_addr);
}
return BK_OK;
}
bk_err_t dma2d_hal_start_transfer(bool start_transfer)
{
dma2d_ll_set_dma2d_control_reg_tran_start(start_transfer);
return BK_OK;
}
bool dma2d_hal_is_transfer_done(void)
{
return dma2d_ll_get_dma2d_control_reg_tran_start();
}
/**
* @brief Start the multi-source DMA2D Transfer with interrupt enabled.
* @param dma2d Pointer to a dma2d_config_t structure that contains
* the configuration information for the DMA2D.
* @param src_addr1 The source memory Buffer address for the foreground layer.
* @param src_addr2 The source memory Buffer address for the background layer.
* @param dst_addr The destination memory Buffer address.
* @param Width The width of data to be transferred from source to destination (expressed in number of pixels per line).
* @param Height The height of data to be transferred from source to destination (expressed in number of lines).
* @retval HAL status
*/
bk_err_t dma2d_hal_blending_start(dma2d_config_t *dma2d, uint32_t src_addr1, uint32_t src_addr2, uint32_t dst_addr, uint32_t Width, uint32_t Height)
{
if(dma2d->init.mode == DMA2D_M2M_BLEND_FG)
{
/*blending & fixed FG*/
dma2d_ll_set_dma2d_fg_color_reg_value(src_addr1);
/* Configure the source, destination address and the data size */
dma2d_hal_config(dma2d, src_addr2, dst_addr, Width, Height);
}
else if (dma2d->init.mode == DMA2D_M2M_BLEND_BG)
{
/*blending & fixed BG*/
dma2d_ll_set_dma2d_bg_color_reg_value(src_addr2);
/* Configure the source, destination address and the data size */
dma2d_hal_config(dma2d, src_addr1, dst_addr, Width, Height);
}
else
{
dma2d_ll_set_dma2d_bg_address_bg_address(src_addr2);
/* Configure the source, destination address and the data size */
dma2d_hal_config(dma2d, src_addr1, dst_addr, Width, Height);
}
// dma2d_ll_set_dma2d_control_reg_tran_start(1);
return BK_OK;
}
bk_err_t dma2d_hal_suspend(bool suspend)
{
dma2d_ll_set_dma2d_control_reg_tran_suspend(suspend);
return BK_OK;
}
/**
* @brief Configure the DMA2D CLUT Transfer.
* @param dma2d Pointer to a dma2d_config_t structure that contains
* the configuration information for the DMA2D.
* @param CLUTCfg Pointer to a DMA2D_CLUTCfgTypeDef structure that contains
* the configuration information for the color look up table.
* @param LayerIdx DMA2D Layer index.
* This parameter can be one of the following values:
* DMA2D_BACKGROUND_LAYER(0) / DMA2D_FOREGROUND_LAYER(1)
* @note API obsolete and maintained for compatibility with legacy. User is invited
* to resort to HAL_DMA2D_CLUTStartLoad() instead to benefit from code compactness,
* code size and improved heap usage.
* @retval HAL status
*/
bk_err_t dma2d_hal_clut_config(dma2d_clut_cfg_t clut_cfg, uint32_t layer_idx)
{
if(layer_idx == DMA2D_BACKGROUND_LAYER)
{
/* Write background CLUT memory address */
dma2d_ll_set_bg_clut_mem_address_value((uint32_t)clut_cfg.pclut);
/* Write background CLUT size and CLUT color mode */
dma2d_ll_set_dma2d_bg_pfc_ctrl_bg_clut_color_mode(clut_cfg.club_color_mode);
// dma2d_ll_set_dma2d_bg_pfc_ctrl_bg_start_clut();
dma2d_ll_set_dma2d_bg_pfc_ctrl_bg_clut_size(clut_cfg.size);
}
/* Configure the CLUT of the foreground DMA2D layer */
else
{
/* Write foreground CLUT memory address */
dma2d_ll_set_fg_clut_mem_address_value( (uint32_t)clut_cfg.pclut);
/* Write foreground CLUT size and CLUT color mode */
dma2d_ll_set_dma2d_fg_pfc_ctrl_fg_color_mode(clut_cfg.club_color_mode);
dma2d_ll_set_dma2d_fg_pfc_ctrl_fg_clut_size(clut_cfg.size);
}
return BK_OK;
}
/**
* @brief Configure the DMA2D Layer according to the specified
* parameters in the dma2d_config_t.
* @param dma2d Pointer to a dma2d_config_t structure that contains
* the configuration information for the DMA2D.
* @param LayerIdx DMA2D Layer index.
* This parameter can be one of the following values:
* DMA2D_BACKGROUND_LAYER(0) / DMA2D_FOREGROUND_LAYER(1)
* @retval HAL status
*/
bk_err_t dma2d_hal_layer_config(dma2d_config_t *dma2d, uint32_t LayerIdx)
{
dma2d_layer_cfg_t *pLayerCfg;
pLayerCfg = &dma2d->layer_cfg[LayerIdx];
/* Configure the background DMA2D layer */
if (LayerIdx == DMA2D_BACKGROUND_LAYER) {
/* Write DMA2D BGPFCCR register */
#if CONFIG_SOC_BK7236XX
if(pLayerCfg->input_color_mode > DMA2D_INPUT_A4)
{
dma2d_ll_set_dma2d_bg_pfc_ctrl_bg_color_mode(DMA2D_INPUT_YUYV);
dma2d_ll_set_dma2d_bg_pfc_ctrl_bg_y2r_yuv_fmt(4 - (DMA2D_INPUT_VUYY - pLayerCfg->input_color_mode));
}
else
#endif
{
dma2d_ll_set_dma2d_bg_pfc_ctrl_bg_color_mode(pLayerCfg->input_color_mode);
}
dma2d_ll_set_dma2d_bg_pfc_ctrl_bg_alpha_mode(pLayerCfg->alpha_mode);
dma2d_ll_set_dma2d_bg_pfc_ctrl_alpha_invert(pLayerCfg->alpha_inverted);
dma2d_ll_set_dma2d_bg_pfc_ctrl_bg_rb_swap(pLayerCfg->red_blue_swap);
dma2d_ll_set_dma2d_bg_pfc_ctrl_bg_alpha(pLayerCfg->input_alpha);
/* DMA2D BGOR register configuration -------------------------------------*/
dma2d_ll_set_dma2d_bg_offset_bg_line_offset(pLayerCfg->input_offset);
#if CONFIG_SOC_BK7236XX
if (pLayerCfg->input_data_reverse == BYTE_BY_BYTE_REVERSE)
{
dma2d_ll_set_dma2d_bg_pfc_ctrl_bg_y2r_byte_reve(1);
dma2d_ll_set_dma2d_bg_pfc_ctrl_bg_y2r_hword_reve(0);
}
else if (pLayerCfg->input_data_reverse == HFWORD_BY_HFWORD_REVERSE)
{
dma2d_ll_set_dma2d_bg_pfc_ctrl_bg_y2r_byte_reve(0);
dma2d_ll_set_dma2d_bg_pfc_ctrl_bg_y2r_hword_reve(1);
}
else
{
dma2d_ll_set_dma2d_bg_pfc_ctrl_bg_y2r_byte_reve(0);
dma2d_ll_set_dma2d_bg_pfc_ctrl_bg_y2r_hword_reve(0);
}
#endif
/* DMA2D BGCOLR register configuration -------------------------------------*/
if ((pLayerCfg->input_color_mode == DMA2D_INPUT_A4) || (pLayerCfg->input_color_mode == DMA2D_INPUT_A8))
{
dma2d_ll_set_dma2d_bg_color_reg_value(pLayerCfg->input_color);
}
}
/* Configure the foreground DMA2D layer */
else {
/* Write DMA2D FGPFCCR register */
#if CONFIG_SOC_BK7236XX
if(pLayerCfg->input_color_mode > DMA2D_INPUT_A4)
{
dma2d_ll_set_dma2d_fg_pfc_ctrl_fg_color_mode(DMA2D_INPUT_YUYV);
dma2d_ll_set_dma2d_fg_pfc_ctrl_fg_y2r_yuv_fmt(4 - (DMA2D_INPUT_VUYY - pLayerCfg->input_color_mode));
}
else
#endif
dma2d_ll_set_dma2d_fg_pfc_ctrl_fg_color_mode(pLayerCfg->input_color_mode);
dma2d_ll_set_dma2d_fg_pfc_ctrl_fg_alpha_mode(pLayerCfg->alpha_mode);
dma2d_ll_set_dma2d_fg_pfc_ctrl_alpha_invert(pLayerCfg->alpha_inverted);
dma2d_ll_set_dma2d_fg_pfc_ctrl_fg_rb_swap(pLayerCfg->red_blue_swap);
dma2d_ll_set_dma2d_fg_pfc_ctrl_fg_alpha(pLayerCfg->input_alpha);
/* DMA2D FGOR register configuration -------------------------------------*/
dma2d_ll_set_dma2d_fg_offset_fg_line_offset(pLayerCfg->input_offset);
#if CONFIG_SOC_BK7236XX
if (pLayerCfg->input_data_reverse == BYTE_BY_BYTE_REVERSE)
{
dma2d_ll_set_dma2d_fg_pfc_ctrl_fg_y2r_byte_reve(1);
dma2d_ll_set_dma2d_fg_pfc_ctrl_fg_y2r_hword_reve(0);
}
else if (pLayerCfg->input_data_reverse == HFWORD_BY_HFWORD_REVERSE)
{
dma2d_ll_set_dma2d_fg_pfc_ctrl_fg_y2r_byte_reve(0);
dma2d_ll_set_dma2d_fg_pfc_ctrl_fg_y2r_hword_reve(1);
}
else
{
dma2d_ll_set_dma2d_fg_pfc_ctrl_fg_y2r_byte_reve(0);
dma2d_ll_set_dma2d_fg_pfc_ctrl_fg_y2r_hword_reve(0);
}
#endif
/* DMA2D FGCOLR register configuration -------------------------------------*/
if ((pLayerCfg->input_color_mode == DMA2D_INPUT_A4) || (pLayerCfg->input_color_mode == DMA2D_INPUT_A8)) {
dma2d_ll_set_dma2d_bg_color_reg_value(pLayerCfg->input_color);
}
}
return BK_OK;
}
bk_err_t dma2d_hal_abort(bool abort)
{
dma2d_ll_set_dma2d_control_reg_tran_abort(abort);
return BK_OK;
}
bk_err_t dma2d_hal_int_config(dma2d_int_type_t int_type, bool enable)
{
uint32_t int_value;
int_value = dma2d_ll_get_dma2d_control_reg_value();
if (1 == enable) {
dma2d_ll_set_dma2d_control_reg_value(int_value | int_type);
}
else {
dma2d_ll_set_dma2d_control_reg_value(int_value & ~(int_type));
}
return BK_OK;
}
bk_err_t dma2d_hal_int_status_get(void)
{
return dma2d_ll_get_dma2d_int_status_value();
}
bk_err_t dma2d_hal_int_status_clear(dma2d_int_status_t int_status)
{
dma2d_ll_set_dma2d_int_clear_value(int_status);
return BK_OK;
}
/**
* @brief Configure the line watermark.
* @param Line Line Watermark configuration (maximum 16-bit long value expected).
* @note dma2d_hal_line_Watermar_cfg() API used with the transfer watermark interrupt.
* @note The transfer watermark interrupt is disabled once it has occurred.
* @retval HAL status
*/
bk_err_t dma2d_hal_line_Watermar_cfg(uint32_t Line)
{
if (Line > 0xFFFF) {
return BK_FAIL;
}
else {
dma2d_ll_set_dma2d_line_watermark_line_watermark(Line); }
return BK_OK;
}
/**
* @brief Start the multi-source DMA2D Transfer.
* @param dma2d Pointer to a dma2d_config_t structure that contains
* the configuration information for the DMA2D.
* @param SrcAddress1 The source memory Buffer address for the foreground layer.
* @param SrcAddress2 The source memory Buffer address for the background layer.
* @param DstAddress The destination memory Buffer address.
* @param Width The width of data to be transferred from source to destination (expressed in number of pixels per line).
* @param Height The height of data to be transferred from source to destination (expressed in number of lines).
* @retval HAL status
*/
bk_err_t dma2d_hal_blending_config(uint32_t SrcAddress1, uint32_t SrcAddress2, uint32_t DstAddress, uint32_t Width, uint32_t Height)
{
return dma2d_ll_get_dma2d_int_status_value();
return BK_OK;
}