Garbage displayed when using DMA2D on a SM32H753

Hello,

When I port Lvgl using DMA2D on stm32H753, several lines at the top of the screen show garbage.
Also, if I display something simple that doesn’t need to be refreshed on the screen, then the screen doesn’t show any incorrect garbage content. If I add a screen that needs to be refreshed, such as displaying the frame rate, then the screen displays some garbage content on top of the screen that seems to vary depending on the size of the refresh area.
I’m not sure if it’s an LVGL problem or an LCD problem or an RTthread problem, I just thought it might be a problem with the lcd_fb_flush refresh function, but after tossing it around I couldn’t figure it out.
Does anyone had the same problem and know what it is and if you could guide me I would be very grateful!
I used an external sdram as a framebuffer, and the lcd pixel format is ARGB8888.

void * lv_disp_buf1 = (lv_color_t *)(SDRAM_BANK_ADDR);
void * lv_disp_buf2 = (lv_color_t *)(SDRAM_BANK_ADDR +  (DISP_BUF_SIZE) * sizeof(lv_color_t));

static void lvgl_dma_config(void)
{
    __HAL_RCC_DMA2D_CLK_ENABLE();
    HAL_NVIC_SetPriority(DMA2D_IRQn, 2, 0);
    HAL_NVIC_EnableIRQ(DMA2D_IRQn);
}

static void lcd_fb_flush(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
{   
    uint32_t OffLineSrc = LV_HOR_RES_MAX - (area->x2 - area->x1 + 1);

    uint32_t addr = (uint32_t) (SDRAM_BANK_ADDR) + 4 * (LV_HOR_RES_MAX * area->y1 + area->x1);

    __HAL_RCC_DMA2D_CLK_ENABLE();  

    DMA2D->CR &= ~ DMA2D_CR_START;  
    DMA2D->CR = DMA2D_M2M;

    DMA2D->FGPFCCR = DMA2D_INPUT_ARGB8888; 

    DMA2D->FGMAR = (uint32_t) ((uint32_t*) color_p);
    DMA2D->OMAR = (uint32_t) addr; 

    DMA2D->FGOR = 0; 

    DMA2D->OOR = OffLineSrc;
    DMA2D->NLR = (area->y2 - area->y1 + 1) | ((area->x2 - area->x1 + 1) << 16);

    DMA2D->CR |= DMA2D_IT_TC | DMA2D_IT_TE | DMA2D_IT_CE; 
    DMA2D->CR |= DMA2D_CR_START; 

    g_gpu_state = RT_TRUE;
}

void DMA2D_IRQHandler(void)
{
    rt_interrupt_enter();
    // rt_enter_critical();
    if ((DMA2D->ISR & DMA2D_FLAG_TC) != 0U)
    {
        if ((DMA2D->CR & DMA2D_IT_TC) != 0U)
        {
            DMA2D->CR &= ~DMA2D_IT_TC;
            DMA2D->IFCR = DMA2D_FLAG_TC;
            if (g_gpu_state == RT_TRUE)
            {
                g_gpu_state = RT_FALSE;
                lv_disp_flush_ready(&g_disp_drv);
            }
        }
    }
    // rt_exit_critical();
    rt_interrupt_leave();
}

maybe you can use SCB_CleanInvalidateDCache();
if(lv_display_flush_is_last(disp_drv))
{
SCB_CleanInvalidateDCache();
while (!(LTDC->CDSR & LTDC_CDSR_VSYNCS));
HAL_LTDC_SetAddress(&hltdc, (uint32_t)(lv_display_get_buf_active(lv_display_get_default())->data), LTDC_LAYER_1);
}

I tried it, but it didn’t seem to work. I also wondered if the SDRAM frequency was too low, but I also adjusted it to the maximum frequency of the SDRAM and still had the problem. :sob: