boards: arm: mimxrt595_evk_cm33: configure LVGL for improved performance

Configure LVGL to improve performance on the RT595 EVK, with the
following changes:

- Allocate two rendering buffers for LVGL, both the entire size of the
  display
- Force LVGL full refresh bit
- Locate LVGL rendering buffers in external PSRAM (since they will not
  fit on onboard SRAM)

Signed-off-by: Daniel DeGrasse <daniel.degrasse@nxp.com>
diff --git a/boards/arm/mimxrt595_evk/CMakeLists.txt b/boards/arm/mimxrt595_evk/CMakeLists.txt
index c101c12..51294de 100644
--- a/boards/arm/mimxrt595_evk/CMakeLists.txt
+++ b/boards/arm/mimxrt595_evk/CMakeLists.txt
@@ -1,5 +1,5 @@
 #
-# Copyright 2022 NXP
+# Copyright 2022-2023 NXP
 #
 # SPDX-License-Identifier: Apache-2.0
 #
@@ -23,3 +23,7 @@
   zephyr_library_sources(${RT595_BOARD_DIR}/flash_config/flash_config.c)
   zephyr_library_include_directories(${RT595_BOARD_DIR}/flash_config)
 endif()
+
+# Add custom linker section to relocate framebuffers to PSRAM
+zephyr_linker_sources_ifdef(CONFIG_LV_Z_VBD_CUSTOM_SECTION
+  SECTIONS dc_ram.ld)
diff --git a/boards/arm/mimxrt595_evk/Kconfig.defconfig b/boards/arm/mimxrt595_evk/Kconfig.defconfig
index f9b0b56..f3fa4bd 100644
--- a/boards/arm/mimxrt595_evk/Kconfig.defconfig
+++ b/boards/arm/mimxrt595_evk/Kconfig.defconfig
@@ -31,6 +31,8 @@
 	default y
 # Use FlexSPI2 base address for framebuffer (pSRAM is present on this bus)
 config MCUX_DCNANO_LCDIF_EXTERNAL_FB_ADDR
+	# Move DCNANO framebuffer if LVGL framebuffers are also in PSRAM
+	default 0x38400000 if LV_Z_VBD_CUSTOM_SECTION
 	default 0x38000000
 # M33 core and LCDIF both access FlexSPI2 through the same cache,
 # so coherency does not need to be managed.
@@ -44,6 +46,34 @@
 
 if LVGL
 
+# LVGL should allocate buffers equal to size of display
+config LV_Z_VDB_SIZE
+	default 100
+
+# Enable double buffering
+config LV_Z_DOUBLE_VDB
+	default y
+
+# Force full refresh. This prevents memory copy associated with partial
+# display refreshes, which is not necessary for the eLCDIF driver
+config LV_Z_FULL_REFRESH
+	default y
+
+config LV_Z_DPI
+	default 128
+
+config LV_Z_BITS_PER_PIXEL
+	default 16
+
+# Force display buffers to be aligned for DCNANO LCDIF (128 byte alignment)
+config LV_Z_VDB_ALIGN
+	default 128
+
+# LVGL display buffers will be too large for internal SRAM, locate in
+# custom section within PSRAM
+config LV_Z_VBD_CUSTOM_SECTION
+	default y
+
 config LV_Z_POINTER_KSCAN
 	default y
 
diff --git a/boards/arm/mimxrt595_evk/board.c b/boards/arm/mimxrt595_evk/board.c
index cae2a72..42095c4 100644
--- a/boards/arm/mimxrt595_evk/board.c
+++ b/boards/arm/mimxrt595_evk/board.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2022,  NXP
+ * Copyright 2022-2023 NXP
  * SPDX-License-Identifier: Apache-2.0
  */
 
@@ -127,9 +127,33 @@
 	return 0;
 }
 
+
+#ifdef CONFIG_LV_Z_VBD_CUSTOM_SECTION
+extern char __flexspi2_start[];
+extern char __flexspi2_end[];
+
+static int init_psram_framebufs(void)
+{
+	/*
+	 * Framebuffers will be stored in PSRAM, within FlexSPI2 linker
+	 * section. Zero out BSS section.
+	 */
+	memset(__flexspi2_start, 0, __flexspi2_end - __flexspi2_start);
+	return 0;
+}
+
+#endif /* CONFIG_LV_Z_VBD_CUSTOM_SECTION */
+
 #if CONFIG_REGULATOR
 /* PMIC setup is dependent on the regulator API */
 SYS_INIT(board_config_pmic, POST_KERNEL, CONFIG_APPLICATION_INIT_PRIORITY);
 #endif
 
+#ifdef CONFIG_LV_Z_VBD_CUSTOM_SECTION
+/* Framebuffers should be setup after PSRAM is initialized but before
+ * Graphics framework init
+ */
+SYS_INIT(init_psram_framebufs, POST_KERNEL, CONFIG_APPLICATION_INIT_PRIORITY);
+#endif
+
 SYS_INIT(mimxrt595_evk_init, PRE_KERNEL_1, CONFIG_BOARD_INIT_PRIORITY);
diff --git a/boards/arm/mimxrt595_evk/dc_ram.ld b/boards/arm/mimxrt595_evk/dc_ram.ld
new file mode 100644
index 0000000..86ced30
--- /dev/null
+++ b/boards/arm/mimxrt595_evk/dc_ram.ld
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2023 NXP
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <zephyr/linker/linker-tool.h>
+
+
+GROUP_START(FLEXSPI2)
+	SECTION_PROLOGUE(.flexspi2_bss,(NOLOAD),SUBALIGN(4))
+	{
+		__flexspi2_start = .;
+		*(.lvgl_buf);
+		__flexspi2_end = .;
+	} GROUP_LINK_IN(FLEXSPI2)