1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-22 14:28:07 +00:00

refactor(core/embed): improve display driver init/deinit

[no changelog]
This commit is contained in:
cepetr 2024-05-31 15:16:35 +02:00 committed by cepetr
parent d558950950
commit 1d8b29e746
25 changed files with 221 additions and 208 deletions

View File

@ -274,7 +274,8 @@ int main(void) {
dma2d_init();
#endif
display_init();
display_init(DISPLAY_RESET_CONTENT);
display_clear();
display_refresh();
@ -324,6 +325,7 @@ int main(void) {
// This includes the version of bootloader potentially updated from SD card.
write_bootloader_min_version(hdr->monotonic);
display_deinit(DISPLAY_RETAIN_CONTENT);
ensure_compatible_settings();
mpu_config_off();

View File

@ -92,7 +92,7 @@ bool load_firmware(const char *filename, uint8_t *hash) {
}
__attribute__((noreturn)) int main(int argc, char **argv) {
display_init();
display_init(DISPLAY_RESET_CONTENT);
flash_init();
flash_otp_init();

View File

@ -330,7 +330,7 @@ void real_jump_to_firmware(void) {
ui_screen_boot_stage_1(false);
}
display_finish_actions();
display_deinit(DISPLAY_RETAIN_CONTENT);
ensure_compatible_settings();
mpu_config_off();
@ -339,7 +339,6 @@ void real_jump_to_firmware(void) {
#ifdef STM32U5
__attribute__((noreturn)) void jump_to_fw_through_reset(void) {
display_finish_actions();
display_fade(display_backlight(-1), 0, 200);
disable_irq();
@ -371,7 +370,7 @@ int bootloader_main(void) {
i2c_init();
#endif
display_reinit();
display_init(DISPLAY_RETAIN_CONTENT);
#ifdef USE_DMA2D
dma2d_init();

View File

@ -155,7 +155,7 @@ int main(void) {
dma2d_init();
#endif
display_reinit();
display_init(DISPLAY_RETAIN_CONTENT);
#ifdef STM32U5
check_oem_keys();

View File

@ -777,8 +777,7 @@ void cpuid_read(void) {
int main(void) {
svc_init();
display_reinit();
display_orientation(0);
display_init(DISPLAY_RETAIN_CONTENT);
random_delays_init();
#ifdef STM32U5
secure_aes_init();

View File

@ -63,7 +63,7 @@ int display_orientation(int degrees);
int display_get_orientation(void);
int display_backlight(int val);
void display_init(void);
void display_init_all(void);
void display_reinit(void);
void display_sync(void);
void display_refresh(void);
@ -77,5 +77,24 @@ uint8_t *display_get_wr_addr(void);
void display_shift_window(uint16_t pixels);
uint16_t display_get_window_offset(void);
typedef enum {
// Clear the display content
DISPLAY_RESET_CONTENT,
// Keeps the display without any changes
DISPLAY_RETAIN_CONTENT
} display_content_mode_t;
static inline void display_init(display_content_mode_t mode) {
if (mode == DISPLAY_RESET_CONTENT) {
display_init_all();
} else {
display_reinit();
}
}
static inline void display_deinit(display_content_mode_t mode) {
display_finish_actions();
}
#endif // NEW_RENDERING
#endif // TREZORHAL_DISPLAY_H

View File

@ -42,7 +42,7 @@ uint32_t systick_val_copy = 0;
extern void shutdown_privileged(void);
void __attribute__((noreturn)) trezor_shutdown(void) {
display_finish_actions();
display_deinit(DISPLAY_RETAIN_CONTENT);
#ifdef USE_SVC_SHUTDOWN
svc_shutdown();
#else

View File

@ -221,7 +221,7 @@ int display_backlight(int val) {
void display_init_seq(void) { display_unsleep(); }
void display_init(void) {
void display_init_all(void) {
GPIO_InitTypeDef GPIO_InitStructure = {0};
/* Enable the LTDC and DMA2D Clock */

View File

@ -389,7 +389,7 @@ void display_setup_te_interrupt(void) {
}
#endif
void display_init(void) {
void display_init_all(void) {
// init peripherals
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();

View File

@ -270,7 +270,7 @@ void display_init_seq(void) {
display_unsleep();
}
void display_init(void) {
void display_init_all(void) {
// init peripherals
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();

View File

@ -153,7 +153,7 @@ void display_handle_init(void) {
spi_handle.Init.Mode = SPI_MODE_MASTER;
}
void display_init(void) {
void display_init_all(void) {
OLED_DC_CLK_ENA();
OLED_CS_CLK_ENA();
OLED_RST_CLK_ENA();

View File

@ -31,6 +31,8 @@ __attribute__((noreturn)) static void _reboot_to_bootloader(
#else
__attribute__((noreturn)) static void _reboot_to_bootloader(
boot_command_t boot_command) {
display_deinit(DISPLAY_RETAIN_CONTENT);
ensure_compatible_settings();
mpu_config_bootloader();
jump_to_with_flag(IMAGE_CODE_ALIGN(BOOTLOADER_START + IMAGE_HEADER_SIZE),
boot_command);
@ -40,14 +42,12 @@ __attribute__((noreturn)) static void _reboot_to_bootloader(
#endif
void svc_reboot_to_bootloader(void) {
display_finish_actions();
boot_command_t boot_command = bootargs_get_command();
if (is_mode_unprivileged() && !is_mode_handler()) {
register uint32_t r0 __asm__("r0") = boot_command;
__asm__ __volatile__("svc %0" ::"i"(SVC_REBOOT_TO_BOOTLOADER), "r"(r0)
: "memory");
} else {
ensure_compatible_settings();
_reboot_to_bootloader(boot_command);
}
}
@ -83,7 +83,6 @@ void SVC_C_Handler(uint32_t *stack) {
;
break;
case SVC_REBOOT_TO_BOOTLOADER:
ensure_compatible_settings();
__asm__ volatile("msr control, %0" ::"r"(0x0));
__asm__ volatile("isb");

View File

@ -43,25 +43,17 @@
// Display driver instance
display_driver_t g_display_driver;
void display_init(void) {
void display_init(display_content_mode_t mode) {
display_driver_t* drv = &g_display_driver;
memset(drv, 0, sizeof(display_driver_t));
if (mode == DISPLAY_RESET_CONTENT) {
display_io_init_gpio();
display_io_init_fmc();
display_panel_init();
display_panel_set_little_endian();
backlight_pwm_init(BACKLIGHT_RESET);
#ifdef XFRAMEBUFFER
display_io_init_te_interrupt();
#endif
}
void display_reinit(void) {
display_driver_t* drv = &g_display_driver;
memset(drv, 0, sizeof(display_driver_t));
} else {
// Reinitialize FMC to set correct timing
// We have to do this in reinit because boardloader is fixed.
display_io_init_fmc();
@ -70,13 +62,14 @@ void display_reinit(void) {
display_panel_set_little_endian();
display_panel_reinit();
backlight_pwm_init(BACKLIGHT_RETAIN);
}
#ifdef XFRAMEBUFFER
display_io_init_te_interrupt();
#endif
}
void display_finish_actions(void) {
void display_deinit(display_content_mode_t mode) {
#ifdef XFRAMEBUFFER
#ifndef BOARDLOADER
display_ensure_refreshed();

View File

@ -44,24 +44,20 @@ typedef struct {
// Display driver instance
static display_driver_t g_display_driver;
void display_init(void) {
void display_init(display_content_mode_t mode) {
display_driver_t *drv = &g_display_driver;
memset(drv, 0, sizeof(display_driver_t));
drv->framebuf = (uint16_t *)FRAME_BUFFER_ADDR;
if (mode == DISPLAY_RESET_CONTENT) {
// Initialize LTDC controller
BSP_LCD_Init();
// Initialize external display controller
ili9341_init();
}
}
void display_reinit(void) {
display_driver_t *drv = &g_display_driver;
memset(drv, 0, sizeof(display_driver_t));
drv->framebuf = (uint16_t *)FRAME_BUFFER_ADDR;
}
void display_finish_actions(void) {
void display_deinit(display_content_mode_t mode) {
// Not used and intentionally left empty
}

View File

@ -291,25 +291,20 @@ static void display_init_interface(void) {
HAL_SRAM_Init(&display_sram, &normal_mode_timing, NULL);
}
void display_init(void) {
void display_init(display_content_mode_t mode) {
display_driver_t *drv = &g_display_driver;
memset(drv, 0, sizeof(display_driver_t));
if (mode == DISPLAY_RESET_CONTENT) {
// Initialize GPIO & FSMC controller
display_init_interface();
// Initialize display controller
display_init_controller();
}
}
void display_reinit(void) {
display_driver_t *drv = &g_display_driver;
memset(drv, 0, sizeof(display_driver_t));
// !@# TODO backlight level??
}
void display_finish_actions(void) {
/// Not used and intentionally left empty
void display_deinit(display_content_mode_t mode) {
// Not used and intentionally left empty
}
int display_set_backlight(int level) {

View File

@ -220,12 +220,13 @@ static void display_sync_with_fb(display_driver_t *drv) {
HAL_GPIO_WritePin(OLED_DC_PORT, OLED_DC_PIN, GPIO_PIN_RESET);
}
void display_init(void) {
void display_init(display_content_mode_t mode) {
display_driver_t *drv = &g_display_driver;
memset(drv, 0, sizeof(display_driver_t));
drv->backlight_level = 255;
if (mode == DISPLAY_RESET_CONTENT) {
OLED_DC_CLK_ENA();
OLED_CS_CLK_ENA();
OLED_RST_CLK_ENA();
@ -285,19 +286,13 @@ void display_init(void) {
// Clear display internal framebuffer
display_sync_with_fb(drv);
}
void display_reinit(void) {
display_driver_t *drv = &g_display_driver;
memset(drv, 0, sizeof(display_driver_t));
drv->backlight_level = 255;
} else {
display_init_spi(drv);
}
}
void display_finish_actions(void) {
/// Not used and intentionally left empty
void display_deinit(display_content_mode_t mode) {
// Not used and intentionally left empty
}
int display_set_backlight(int level) {

View File

@ -38,7 +38,7 @@ uint32_t systick_val_copy = 0;
extern void shutdown_privileged(void);
void __attribute__((noreturn)) trezor_shutdown(void) {
display_finish_actions();
display_deinit(DISPLAY_RETAIN_CONTENT);
__HAL_RCC_SAES_CLK_DISABLE();
// Erase all secrets

View File

@ -1654,7 +1654,7 @@ int display_orientation(int degrees) { return degrees; }
int display_get_orientation(void) { return 0; }
int display_backlight(int val) { return val; }
void display_init(void) {
void display_init_all(void) {
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** Initializes the common periph clock

View File

@ -41,7 +41,8 @@ typedef struct {
// Display driver instance
static display_driver_t g_display_driver;
void display_init(void) {
void display_init(display_content_mode_t mode) {
if (mode == DISPLAY_RESET_CONTENT) {
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
// Initializes the common periph clock
@ -66,19 +67,23 @@ void display_init(void) {
BSP_LCD_Init(0, LCD_ORIENTATION_PORTRAIT);
BSP_LCD_SetBrightness(0, 100);
BSP_LCD_DisplayOn(0);
}
void display_reinit(void) {
} else {
// Retain display content
BSP_LCD_Reinit(0);
if (current_frame_buffer == 0) {
BSP_LCD_SetFrameBuffer(0, GFXMMU_VIRTUAL_BUFFER1_BASE_S);
} else {
BSP_LCD_SetFrameBuffer(0, GFXMMU_VIRTUAL_BUFFER0_BASE_S);
}
}
}
void display_finish_actions(void) {
// Not used and intentionally left empty
void display_deinit(display_content_mode_t mode) {
if (mode == DISPLAY_RESET_CONTENT) {
BSP_LCD_DisplayOff(0);
BSP_LCD_SetBrightness(0, 0);
BSP_LCD_DeInit(0);
}
}
int display_set_backlight(int level) {
@ -112,8 +117,6 @@ int display_get_orientation(void) {
return drv->orientation_angle;
}
void display_set_compatible_settings() {}
void display_fill(const gfx_bitblt_t *bb) {
display_fb_info_t fb = display_get_frame_buffer();

View File

@ -50,9 +50,11 @@ extern uint32_t current_frame_buffer;
#define LCD_ORIENTATION_LANDSCAPE_ROT180 3U
int32_t BSP_LCD_Init(uint32_t Instance, uint32_t Orientation);
int32_t BSP_LCD_DeInit(uint32_t Instance);
int32_t BSP_LCD_Reinit(uint32_t Instance);
int32_t BSP_LCD_SetBrightness(uint32_t Instance, uint32_t Brightness);
int32_t BSP_LCD_DisplayOn(uint32_t Instance);
int32_t BSP_LCD_DisplayOff(uint32_t Instance);
int32_t BSP_LCD_SetFrameBuffer(uint32_t Instance, uint32_t fb_addr);
#endif // TREZOR_HAL_DISPLAY_INTERNAL_H

View File

@ -202,6 +202,11 @@ static void DSI_EndOfRefreshCallback(DSI_HandleTypeDef *hdsi);
* @retval BSP status.
*/
int32_t BSP_LCD_Init(uint32_t Instance, uint32_t Orientation) {
memset(&hlcd_gfxmmu, 0, sizeof(hlcd_gfxmmu));
memset(&hlcd_ltdc, 0, sizeof(hlcd_ltdc));
memset(&hlcd_dsi, 0, sizeof(hlcd_dsi));
memset(&DSIVidCfg, 0, sizeof(DSIVidCfg));
int32_t status = BSP_ERROR_NONE;
if ((Instance >= LCD_INSTANCES_NBR) ||

View File

@ -58,34 +58,18 @@ static display_driver_t g_display_driver;
int sdl_display_res_x = DISPLAY_RESX, sdl_display_res_y = DISPLAY_RESY;
int sdl_touch_offset_x, sdl_touch_offset_y;
void display_deinit(void) {
display_driver_t *drv = &g_display_driver;
SDL_FreeSurface(drv->prev_saved);
SDL_FreeSurface(drv->buffer);
if (drv->background != NULL) {
SDL_DestroyTexture(drv->background);
}
if (drv->texture != NULL) {
SDL_DestroyTexture(drv->texture);
}
if (drv->renderer != NULL) {
SDL_DestroyRenderer(drv->renderer);
}
if (drv->window != NULL) {
SDL_DestroyWindow(drv->window);
}
SDL_Quit();
static void display_exit_handler(void) {
display_deinit(DISPLAY_RESET_CONTENT);
}
void display_init(void) {
void display_init(display_content_mode_t mode) {
display_driver_t *drv = &g_display_driver;
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
printf("%s\n", SDL_GetError());
error_shutdown("SDL_Init error");
}
atexit(display_deinit);
atexit(display_exit_handler);
char *window_title = NULL;
char *window_title_alloc = NULL;
@ -162,12 +146,24 @@ void display_init(void) {
#endif
}
void display_reinit(void) {
// not used
}
void display_deinit(display_content_mode_t mode) {
display_driver_t *drv = &g_display_driver;
void display_finish_actions(void) {
// not used
SDL_FreeSurface(drv->prev_saved);
SDL_FreeSurface(drv->buffer);
if (drv->background != NULL) {
SDL_DestroyTexture(drv->background);
}
if (drv->texture != NULL) {
SDL_DestroyTexture(drv->texture);
}
if (drv->renderer != NULL) {
SDL_DestroyRenderer(drv->renderer);
}
if (drv->window != NULL) {
SDL_DestroyWindow(drv->window);
}
SDL_Quit();
}
int display_set_backlight(int level) {

View File

@ -46,18 +46,28 @@
// MIPI -
// - STM32U5A9J-DK Discovery Board
// Fully initializes the display controller.
void display_init(void);
// Specifies how display content should be handled during
// initialization or deinitialization.
typedef enum {
// Clear the display content
DISPLAY_RESET_CONTENT,
// Retain the display content
DISPLAY_RETAIN_CONTENT
} display_content_mode_t;
// Called in application or bootloader to reinitialize an already initialized
// display controller without any distrubing visible effect (blinking, etc.).
void display_reinit(void);
// Waits for any backround operations (such as DMA copying) and returns.
// Initializes the display controller.
//
// The function provides a barrier when jumping between
// boardloader/bootloader and firmware.
void display_finish_actions(void);
// If `mode` is `DISPLAY_RETAIN_CONTENT`, ensure the driver was previously
// initialized and `display_deinit(DISPLAY_RETAIN_CONTENT)` was called.
void display_init(display_content_mode_t mode);
// Deinitializes the display controller.
//
// If `mode` is `DISPLAY_RETAIN_CONTENT`, the function waits for
// background operations to complete and disables interrupts, so the
// application can safely proceed to the next boot stage and call
// `display_init(DISPLAY_RETAIN_CONTENT)`.
void display_deinit(display_content_mode_t mode);
// Sets display backlight level ranging from 0 (off)..255 (maximum).
//
@ -122,7 +132,7 @@ void display_refresh(void);
// This is used when switching between the firmware and the bootloader.
void display_set_compatible_settings(void);
// Following function define display's bitblt interface.
// Following functions define display's bitblt interface.
//
// These functions draw directly to to display or to the
// currently inactive framebuffer.

View File

@ -23,12 +23,12 @@
#include <buffers.h>
#include <stdint.h>
// These declarationscode emulates will be removed after the
// final cleanup of display drivers. They are here just to simplify
// integration with the legacy code.
// These declarations will be removed after the final cleanup
// of display drivers. They are here just to simplify integration
// with the legacy code.
//
// Most of these function are not called when NEW_RENDERING=1
// and they are only needed to for succesfully code compilation
// Most of these functions are not called when NEW_RENDERING=1,
// and they are only needed for successful code compilation.
#define DISPLAY_FRAMEBUFFER_WIDTH 768
#define DISPLAY_FRAMEBUFFER_HEIGHT 480

View File

@ -486,7 +486,7 @@ MP_NOINLINE int main_(int argc, char **argv) {
pre_process_options(argc, argv);
display_init();
display_init(DISPLAY_RESET_CONTENT);
#if USE_TOUCH
touch_init();