This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 6ac28d5526 xtensa/esp32s3: LCD controller driver
6ac28d5526 is described below

commit 6ac28d552629c4cf6fdbc657b22383192372fa64
Author: Dong Heng <[email protected]>
AuthorDate: Fri Aug 25 19:32:02 2023 +0800

    xtensa/esp32s3: LCD controller driver
---
 arch/xtensa/src/esp32s3/Kconfig                    |  157 +++
 arch/xtensa/src/esp32s3/Make.defs                  |    4 +
 arch/xtensa/src/esp32s3/esp32s3_dma.c              |   41 +
 arch/xtensa/src/esp32s3/esp32s3_dma.h              |   26 +
 arch/xtensa/src/esp32s3/esp32s3_idle.c             |   31 +-
 arch/xtensa/src/esp32s3/esp32s3_lcd.c              | 1010 +++++++++++++++
 arch/xtensa/src/esp32s3/hardware/esp32s3_lcd_cam.h | 1349 ++++++++++++++++++++
 boards/xtensa/esp32s3/common/Kconfig               |   11 +
 .../esp32s3/common/scripts/esp32s3_aliases.ld      |    2 +
 .../esp32s3/common/scripts/legacy_sections.ld      |   25 +
 boards/xtensa/esp32s3/esp32s3-lcd-ev/Kconfig       |   26 +
 .../esp32s3/esp32s3-lcd-ev/configs/lcd/defconfig   |   63 +
 .../esp32s3/esp32s3-lcd-ev/configs/lvgl/defconfig  |   78 ++
 boards/xtensa/esp32s3/esp32s3-lcd-ev/src/Make.defs |   12 +
 .../esp32s3/esp32s3-lcd-ev/src/esp32s3-lcd-ev.h    |   98 ++
 .../esp32s3/esp32s3-lcd-ev/src/esp32s3_bringup.c   |   16 +
 .../esp32s3-lcd-ev/src/esp32s3_ioexpander.c        |  171 +++
 .../esp32s3/esp32s3-lcd-ev/src/esp32s3_lcd.c       |  683 ++++++++++
 .../esp32s3-lcd-ev/src/esp32s3_touchscreen.c       |  191 +++
 19 files changed, 3984 insertions(+), 10 deletions(-)

diff --git a/arch/xtensa/src/esp32s3/Kconfig b/arch/xtensa/src/esp32s3/Kconfig
index 78c297df52..af41c2da75 100644
--- a/arch/xtensa/src/esp32s3/Kconfig
+++ b/arch/xtensa/src/esp32s3/Kconfig
@@ -715,6 +715,16 @@ config ESP32S3_WCL
        select ARCH_USE_MPU
        select XTENSA_HAVE_GENERAL_EXCEPTION_HOOKS if BUILD_PROTECTED
 
+config ESP32S3_LCD
+       bool "LCD"
+       default n
+       select DRIVERS_VIDEO
+       select VIDEO_FB
+       select FB_UPDATE
+       help
+       ---help---
+               LCD controller that outputs parallel data and supports RGB 
interface.
+
 endmenu # ESP32-S3 Peripheral Selection
 
 menuconfig ESP32S3_WIFI_BT_COEXIST
@@ -1713,6 +1723,153 @@ config ESP32S3_OTG_DEBUG_REGISTER
 
 endmenu # USB OTG Configuration
 
+menu "LCD Controller Configuration"
+       depends on ESP32S3_LCD
+
+menu "LCD Pin Configuration"
+
+config ESP32S3_LCD_PCLK_PIN
+       int "LCD Pixel Clock Signal Pin"
+       default 9
+
+config ESP32S3_LCD_VSYNC_PIN
+       int "LCD Vertical Synchronization Pin"
+       default 3
+
+config ESP32S3_LCD_HSYNC_PIN
+       int "LCD Horizontal Synchronization Pin"
+       default 46
+
+config ESP32S3_LCD_HE_PIN
+       int "LCD Horizontal Enable Pin"
+       default 17
+
+config ESP32S3_LCD_DATA0_PIN
+    int "LCD Parallel Output Data Bit-0 Pin"
+       default 10
+
+config ESP32S3_LCD_DATA1_PIN
+    int "LCD Parallel Output Data Bit-1 Pin"
+       default 11
+
+config ESP32S3_LCD_DATA2_PIN
+    int "LCD Parallel Output Data Bit-2 Pin"
+       default 12
+
+config ESP32S3_LCD_DATA3_PIN
+    int "LCD Parallel Output Data Bit-3 Pin"
+       default 13
+
+config ESP32S3_LCD_DATA4_PIN
+    int "LCD Parallel Output Data Bit-4 Pin"
+       default 14
+
+config ESP32S3_LCD_DATA5_PIN
+    int "LCD Parallel Output Data Bit-5 Pin"
+       default 21
+
+config ESP32S3_LCD_DATA6_PIN
+    int "LCD Parallel Output Data Bit-6 Pin"
+       default 47
+
+config ESP32S3_LCD_DATA7_PIN
+    int "LCD Parallel Output Data Bit-7 Pin"
+       default 48
+
+config ESP32S3_LCD_DATA8_PIN
+    int "LCD Parallel Output Data Bit-8 Pin"
+       default 45
+
+config ESP32S3_LCD_DATA9_PIN
+    int "LCD Parallel Output Data Bit-9 Pin"
+       default 38
+
+config ESP32S3_LCD_DATA10_PIN
+    int "LCD Parallel Output Data Bit-10 Pin"
+       default 39
+
+config ESP32S3_LCD_DATA11_PIN
+    int "LCD Parallel Output Data Bit-11 Pin"
+       default 40
+
+config ESP32S3_LCD_DATA12_PIN
+    int "LCD Parallel Output Data Bit-12 Pin"
+       default 41
+
+config ESP32S3_LCD_DATA13_PIN
+    int "LCD Parallel Output Data Bit-13 Pin"
+       default 42
+
+config ESP32S3_LCD_DATA14_PIN
+    int "LCD Parallel Output Data Bit-14 Pin"
+       default 2
+
+config ESP32S3_LCD_DATA15_PIN
+    int "LCD Parallel Output Data Bit-15 Pin"
+       default 1
+
+endmenu
+
+menu "LCD Display Configuration"
+       depends on ESP32S3_LCD
+
+config ESP32S3_LCD_VRES
+       int "LCD Vertical Resolution"
+       default 480
+
+config ESP32S3_LCD_HRES
+       int "LCD Horizontal Resolution"
+       default 480
+
+config ESP32S3_LCD_CLOCK_MHZ
+       int "LCD Pixel Clock Frequency in MHz"
+       default 2
+
+config ESP32S3_LCD_VFRONTPORCH
+       int "LCD Vertical Front Porch"
+       default 40
+
+config ESP32S3_LCD_VBACKPORCH
+       int "LCD Vertical Back Porch"
+       default 20
+
+config ESP32S3_LCD_VPULSEWIDTH
+       int "LCD Vertical Pulse Width"
+       default 13
+
+config ESP32S3_LCD_HFRONTPORCH
+       int "LCD Horizontal Front Porch"
+       default 40
+
+config ESP32S3_LCD_HBACKPORCH
+       int "LCD Horizontal Back Porch"
+       default 20
+
+config ESP32S3_LCD_HPULSEWIDTH
+       int "LCD Horizontal Pulse Width"
+       default 15
+
+config ESP32S3_LCD_BUFFER_LAYERS
+       int "LCD Buffer Layer Number"
+       default 1
+
+choice
+       prompt "LCD Data Width"
+       default ESP32S3_LCD_DATA_16BIT
+
+config ESP32S3_LCD_DATA_16BIT
+       bool "16-bit"
+
+endchoice # LCD Data Width
+
+endmenu
+
+config ESP32S3_LCD_REGDEBUG
+       bool "LCD Debug Registers"
+       default n
+
+endmenu
+
 menu "Application Image Configuration"
 
 choice
diff --git a/arch/xtensa/src/esp32s3/Make.defs 
b/arch/xtensa/src/esp32s3/Make.defs
index 0a9752a8ec..154c2fc675 100644
--- a/arch/xtensa/src/esp32s3/Make.defs
+++ b/arch/xtensa/src/esp32s3/Make.defs
@@ -158,6 +158,10 @@ ifeq ($(CONFIG_RTC_DRIVER),y)
 CHIP_CSRCS += esp32s3_rtc_lowerhalf.c
 endif
 
+ifeq ($(CONFIG_ESP32S3_LCD),y)
+CHIP_CSRCS += esp32s3_lcd.c
+endif
+
 #############################################################################
 # Espressif HAL for 3rd Party Platforms
 #############################################################################
diff --git a/arch/xtensa/src/esp32s3/esp32s3_dma.c 
b/arch/xtensa/src/esp32s3/esp32s3_dma.c
index bbd3af5e55..203ba7f130 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_dma.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_dma.c
@@ -391,6 +391,47 @@ void esp32s3_dma_wait_idle(int chan, bool tx)
   while ((waitbits & regval) == 0);
 }
 
+/****************************************************************************
+ * Name: esp32s3_dma_set_ext_memblk
+ *
+ * Description:
+ *   Configure DMA external memory block size.
+ *
+ * Input Parameters:
+ *   chan - DMA channel
+ *   tx   - true: TX mode; false: RX mode
+ *   type - block size type
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+void esp32s3_dma_set_ext_memblk(int chan, bool tx,
+                                enum esp32s3_dma_ext_memblk_e type)
+{
+  uint32_t val;
+
+  if (tx)
+    {
+      val = ((uint32_t)type << DMA_OUT_EXT_MEM_BK_SIZE_CH0_S);
+
+      CLR_GDMA_CH_BITS(DMA_OUT_CONF1_CH0_REG,
+                       chan,
+                       DMA_OUT_EXT_MEM_BK_SIZE_CH0_M);
+      SET_GDMA_CH_BITS(DMA_OUT_CONF1_CH0_REG, chan, val);
+    }
+  else
+    {
+      val = ((uint32_t)type << DMA_IN_EXT_MEM_BK_SIZE_CH0_S);
+
+      CLR_GDMA_CH_BITS(DMA_IN_CONF1_CH0_REG,
+                       chan,
+                       DMA_IN_EXT_MEM_BK_SIZE_CH0_M);
+      SET_GDMA_CH_BITS(DMA_IN_CONF1_CH0_REG, chan, val);
+    }
+}
+
 /****************************************************************************
  * Name: esp32s3_dma_init
  *
diff --git a/arch/xtensa/src/esp32s3/esp32s3_dma.h 
b/arch/xtensa/src/esp32s3/esp32s3_dma.h
index 2200ad72cd..db2c91899d 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_dma.h
+++ b/arch/xtensa/src/esp32s3/esp32s3_dma.h
@@ -104,6 +104,13 @@ enum esp32s3_dma_periph_e
   ESP32S3_DMA_PERIPH_NUM,
 };
 
+enum esp32s3_dma_ext_memblk_e
+{
+  ESP32S3_DMA_EXT_MEMBLK_16B = 0,
+  ESP32S3_DMA_EXT_MEMBLK_32B = 1,
+  ESP32S3_DMA_EXT_MEMBLK_64B = 2
+};
+
 /* DMA descriptor type */
 
 struct esp32s3_dmadesc_s
@@ -230,6 +237,25 @@ void esp32s3_dma_disable(int chan, bool tx);
 
 void esp32s3_dma_wait_idle(int chan, bool tx);
 
+/****************************************************************************
+ * Name: esp32s3_dma_set_ext_memblk
+ *
+ * Description:
+ *   Configure DMA external memory block size.
+ *
+ * Input Parameters:
+ *   chan - DMA channel
+ *   tx   - true: TX mode; false: RX mode
+ *   type - block size type
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+void esp32s3_dma_set_ext_memblk(int chan, bool tx,
+                                enum esp32s3_dma_ext_memblk_e type);
+
 /****************************************************************************
  * Name: esp32s3_dma_init
  *
diff --git a/arch/xtensa/src/esp32s3/esp32s3_idle.c 
b/arch/xtensa/src/esp32s3/esp32s3_idle.c
index d3c4167c7b..16b714e6af 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_idle.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_idle.c
@@ -63,21 +63,32 @@
 
 void up_idle(void)
 {
+  /* Report loop explanation here */
+
+#ifdef CONFIG_ESP32S3_SPEED_UP_ISR
+  for (; ; )
+    {
+#endif
+
 #if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS)
-  /* If the system is idle and there are no timer interrupts, then process
-   * "fake" timer interrupts. Hopefully, something will wake up.
-   */
+      /* If the system is idle and there are no timer interrupts, then
+       * process "fake" timer interrupts. Hopefully, something will wake up.
+       */
 
-  nxsched_process_timer();
+      nxsched_process_timer();
 #else
 
-  /* This would be an appropriate place to put some MCU-specific logic to
-   * sleep in a reduced power mode until an interrupt occurs to save power
-   */
+      /* This would be an appropriate place to put some MCU-specific logic
+       * to sleep in a reduced power mode until an interrupt occurs to save
+       * power.
+       */
 
-#if XCHAL_HAVE_INTERRUPTS
-  __asm__ __volatile__ ("waiti 0");
-#endif
+#  if XCHAL_HAVE_INTERRUPTS
+      __asm__ __volatile__ ("waiti 0");
+#  endif
+#endif /* CONFIG_SUPPRESS_INTERRUPTS || CONFIG_SUPPRESS_TIMER_INTS */
 
+#ifdef CONFIG_ESP32S3_SPEED_UP_ISR
+    }
 #endif
 }
diff --git a/arch/xtensa/src/esp32s3/esp32s3_lcd.c 
b/arch/xtensa/src/esp32s3/esp32s3_lcd.c
new file mode 100644
index 0000000000..6fd1be2a0f
--- /dev/null
+++ b/arch/xtensa/src/esp32s3/esp32s3_lcd.c
@@ -0,0 +1,1010 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32s3/esp32s3_lcd.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <inttypes.h>
+#include <stdint.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/spinlock.h>
+#include <nuttx/video/fb.h>
+#include <nuttx/kmalloc.h>
+
+#include <arch/board/board.h>
+
+#include "esp32s3_clockconfig.h"
+#include "esp32s3_gpio.h"
+#include "esp32s3_dma.h"
+#include "esp32s3_irq.h"
+#include "esp32s3_periph.h"
+
+#include "xtensa.h"
+#include "hardware/esp32s3_system.h"
+#include "hardware/esp32s3_gpio_sigmap.h"
+#include "hardware/esp32s3_lcd_cam.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Configuration ************************************************************/
+
+/* LCD RGB Mapping */
+
+#ifdef CONFIG_FB_CMAP
+#  error "RGB color mapping not supported by this driver"
+#endif
+
+/* Cursor Controls */
+
+#ifdef CONFIG_FB_HWCURSOR
+#  error "Cursor control not supported by this driver"
+#endif
+
+#ifdef CONFIG_ESP32S3_LCD_DATA_16BIT
+#  define ESP32S3_LCD_DATA_WIDTH  2
+#  define ESP32S3_LCD_DATA_BPP    16
+#else
+#  error "Configure LCD data width is not supported"
+#endif
+
+#if CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240
+#  if (CONFIG_ESP32S3_LCD_CLOCK_MHZ % 3) == 0
+    /* Use PLL=240MHz as clock resource */
+#    define ESP32S3_LCD_CLK_SEL   2
+#    define ESP32S3_LCD_CLK_MHZ   240
+#  else
+    /* Use PLL=160MHz as clock resource */
+#    define ESP32S3_LCD_CLK_SEL   3
+#    define ESP32S3_LCD_CLK_MHZ   160
+#  endif
+#else
+  /* Use PLL=160MHz as clock resource */
+#  define ESP32S3_LCD_CLK_SEL     3
+#  define ESP32S3_LCD_CLK_MHZ     160
+#endif
+
+/* Total Pins */
+
+#define ESP32S3_LCD_PINS          20
+
+/* LCD configuration parameters */
+
+#define ESP32S3_LCD_CLK_N         (ESP32S3_LCD_CLK_MHZ / \
+                                   CONFIG_ESP32S3_LCD_CLOCK_MHZ)
+#define ESP32S3_LCD_CLK_RES       (ESP32S3_LCD_CLK_MHZ % \
+                                   CONFIG_ESP32S3_LCD_CLOCK_MHZ)
+
+#define ESP32S3_LCD_VT_HIGHT      (CONFIG_ESP32S3_LCD_VRES + \
+                                   CONFIG_ESP32S3_LCD_VBACKPORCH + \
+                                   CONFIG_ESP32S3_LCD_VFRONTPORCH + \
+                                   CONFIG_ESP32S3_LCD_VPULSEWIDTH - 1)
+
+#define ESP32S3_LCD_HT_WIDTH      (CONFIG_ESP32S3_LCD_HRES + \
+                                   CONFIG_ESP32S3_LCD_HBACKPORCH + \
+                                   CONFIG_ESP32S3_LCD_HFRONTPORCH + \
+                                   CONFIG_ESP32S3_LCD_HPULSEWIDTH - 1)
+
+#define ESP32S3_LCD_VA_HIGHT      (CONFIG_ESP32S3_LCD_VRES - 1)
+
+#define ESP32S3_LCD_HA_WIDTH      (CONFIG_ESP32S3_LCD_HRES - 1)
+
+#define ESP32S3_LCD_VA_FRONT      (CONFIG_ESP32S3_LCD_VBACKPORCH + \
+                                   CONFIG_ESP32S3_LCD_VPULSEWIDTH - 1)
+
+#define ESP32S3_LCD_HB_FRONT      (CONFIG_ESP32S3_LCD_HBACKPORCH + \
+                                   CONFIG_ESP32S3_LCD_HPULSEWIDTH -1)
+
+#define ESP32S3_LCD_HSYNC_WIDTH   (CONFIG_ESP32S3_LCD_HPULSEWIDTH - 1)
+
+#define ESP32S3_LCD_VSYNC_WIDTH   (CONFIG_ESP32S3_LCD_VPULSEWIDTH - 1)
+
+#define ESP32S3_LCD_COLOR_FMT     (FB_FMT_RGB16_565)
+#define ESP32S3_LCD_STRIDE        (CONFIG_ESP32S3_LCD_HRES * \
+                                   ESP32S3_LCD_DATA_WIDTH)
+
+/* Display memory buffer and DMA */
+
+#define ESP32S3_LCD_FB_SIZE       (CONFIG_ESP32S3_LCD_HRES * \
+                                   CONFIG_ESP32S3_LCD_VRES * \
+                                   ESP32S3_LCD_DATA_WIDTH)
+
+#define ESP32S3_LCD_DMADESC_NUM   (ESP32S3_LCD_FB_SIZE / \
+                                   ESP32S3_DMA_DATALEN_MAX + 1)
+
+#define ESP32S3_LCD_LAYERS        CONFIG_ESP32S3_LCD_BUFFER_LAYERS
+
+/* Get current layer pointer */
+
+#define CURRENT_LAYER(p)          (&((p)->layer[(p)->cur_layer]))
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Pin Configuration */
+
+struct pin_config_s
+{
+  uint8_t num;
+  uint8_t signal;
+};
+
+/* Hardware Configuration */
+
+struct esp32s3_lcd_config_s
+{
+  struct pin_config_s pins_config[ESP32S3_LCD_PINS];
+};
+
+/* LCD General Layer information */
+
+struct esp32s3_layer_s
+{
+  /* DMA descriptor(s) */
+
+  struct esp32s3_dmadesc_s dmadesc[ESP32S3_LCD_DMADESC_NUM];
+
+  /* DMA framebuffer memory */
+
+  uint8_t *framebuffer;
+};
+
+/* This structure provides the overall state of the LCD */
+
+struct esp32s3_lcd_s
+{
+  int ref;
+
+  /* Layer information */
+
+  struct esp32s3_layer_s layer[ESP32S3_LCD_LAYERS];
+
+  uint8_t cur_layer;              /* Current layer number */
+
+  int cpuint;                     /* CPU interrupt assigned to this LCD */
+  uint8_t cpu;                    /* CPU ID */
+  int32_t dma_channel;            /* DMA channel */
+
+  spinlock_t lock;                /* Device specific lock. */
+
+  /* Debug stuff */
+
+#ifdef CONFIG_ESP32S3_LCD_REGDEBUG
+  bool wrlast;            /* True: Last access was a write */
+  uintptr_t addrlast;     /* Last address accessed */
+  uint32_t vallast;       /* Last value read or written */
+  int ntimes;             /* Number of consecutive accesses */
+#endif
+};
+
+/****************************************************************************
+ * External Functions
+ ****************************************************************************/
+
+extern void esp_rom_delay_us(uint32_t us);
+extern void cache_writeback_addr(void *addr_ptr, uint32_t size);
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Register operations ******************************************************/
+
+#ifdef CONFIG_ESP32S3_LCD_REGDEBUG
+static bool esp32s3_lcd_checkreg(bool wr,
+                                 uint32_t regval,
+                                 uintptr_t address);
+static uint32_t esp32s3_lcd_getreg(uintptr_t addr);
+static void esp32s3_lcd_putreg(uintptr_t addr, uint32_t val);
+#else
+#  define esp32s3_lcd_getreg(addr)      getreg32(addr)
+#  define esp32s3_lcd_putreg(addr,val)  putreg32(val,addr)
+#endif
+
+/* Frame buffer interface ***************************************************/
+
+/* Get information about the video controller configuration and the
+ * configuration of each color plane.
+ */
+
+static int esp32s3_lcd_base_getvideoinfo(struct fb_vtable_s *vtable,
+                                         struct fb_videoinfo_s *vinfo);
+static int esp32s3_lcd_base_getplaneinfo(struct fb_vtable_s *vtable,
+                                         int planeno,
+                                         struct fb_planeinfo_s *pinfo);
+#ifdef CONFIG_FB_UPDATE
+static int esp32s3_lcd_base_updatearea(struct fb_vtable_s *vtable,
+                                       const struct fb_area_s *area);
+#endif
+
+/* Initialization ***********************************************************/
+
+static void esp32s3_lcd_dmasetup(void);
+static void esp32s3_lcd_gpio_config(void);
+static void esp32s3_lcd_disable(void);
+static void esp32s3_lcd_enable(void);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* This structure describes LCD controller configuration */
+
+static const struct esp32s3_lcd_config_s g_lcd_config =
+{
+  .pins_config =
+  {
+    { CONFIG_ESP32S3_LCD_PCLK_PIN,   LCD_PCLK_IDX       },
+    { CONFIG_ESP32S3_LCD_VSYNC_PIN,  LCD_V_SYNC_IDX     },
+    { CONFIG_ESP32S3_LCD_HSYNC_PIN,  LCD_H_SYNC_IDX     },
+    { CONFIG_ESP32S3_LCD_HE_PIN,     LCD_H_ENABLE_IDX   },
+    { CONFIG_ESP32S3_LCD_DATA0_PIN,  LCD_DATA_OUT0_IDX  },
+    { CONFIG_ESP32S3_LCD_DATA1_PIN,  LCD_DATA_OUT1_IDX  },
+    { CONFIG_ESP32S3_LCD_DATA2_PIN,  LCD_DATA_OUT2_IDX  },
+    { CONFIG_ESP32S3_LCD_DATA3_PIN,  LCD_DATA_OUT3_IDX  },
+    { CONFIG_ESP32S3_LCD_DATA4_PIN,  LCD_DATA_OUT4_IDX  },
+    { CONFIG_ESP32S3_LCD_DATA5_PIN,  LCD_DATA_OUT5_IDX  },
+    { CONFIG_ESP32S3_LCD_DATA6_PIN,  LCD_DATA_OUT6_IDX  },
+    { CONFIG_ESP32S3_LCD_DATA7_PIN,  LCD_DATA_OUT7_IDX  },
+    { CONFIG_ESP32S3_LCD_DATA8_PIN,  LCD_DATA_OUT8_IDX  },
+    { CONFIG_ESP32S3_LCD_DATA9_PIN,  LCD_DATA_OUT9_IDX  },
+    { CONFIG_ESP32S3_LCD_DATA10_PIN, LCD_DATA_OUT10_IDX },
+    { CONFIG_ESP32S3_LCD_DATA11_PIN, LCD_DATA_OUT11_IDX },
+    { CONFIG_ESP32S3_LCD_DATA12_PIN, LCD_DATA_OUT12_IDX },
+    { CONFIG_ESP32S3_LCD_DATA13_PIN, LCD_DATA_OUT13_IDX },
+    { CONFIG_ESP32S3_LCD_DATA14_PIN, LCD_DATA_OUT14_IDX },
+    { CONFIG_ESP32S3_LCD_DATA15_PIN, LCD_DATA_OUT15_IDX }
+  }
+};
+
+/* This structure provides the overall state of the LCD */
+
+static struct esp32s3_lcd_s g_lcd_priv;
+
+/* This structure describes the simulated video controller */
+
+static const struct fb_videoinfo_s g_base_videoinfo =
+{
+  .fmt      = ESP32S3_LCD_COLOR_FMT,
+  .xres     = CONFIG_ESP32S3_LCD_VRES,
+  .yres     = CONFIG_ESP32S3_LCD_HRES,
+  .nplanes  = 1
+};
+
+/* This structure provides the base layer interface */
+
+static const struct fb_vtable_s g_base_vtable =
+{
+  .getvideoinfo  = esp32s3_lcd_base_getvideoinfo,
+  .getplaneinfo  = esp32s3_lcd_base_getplaneinfo,
+#ifdef CONFIG_FB_UPDATE
+  .updatearea    = esp32s3_lcd_base_updatearea,
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: max_common_divisor
+ *
+ * Description:
+ *   Calculate maxium common divisor.
+ *
+ * Input Parameters:
+ *   a - Calculation parameter a
+ *   b - Calculation parameter b
+ *
+ * Returned Value:
+ *   Maxium common divisor.
+ *
+ ****************************************************************************/
+
+static inline uint32_t max_common_divisor(uint32_t a, uint32_t b)
+{
+  uint32_t c = a % b;
+
+  while (c)
+    {
+      a = b;
+      b = c;
+      c = a % b;
+    }
+
+  return b;
+}
+
+/****************************************************************************
+ * Name: esp32s3_lcd_checkreg
+ *
+ * Description:
+ *   Check if the current register access is a duplicate of the preceding.
+ *
+ * Input Parameters:
+ *   wr      - true: write operation; false: read operation
+ *   regval  - The value to be written
+ *   address - The address of the register to write to
+ *
+ * Returned Value:
+ *   true:  This is the first register access of this type.
+ *   flase: This is the same as the preceding register access.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP32S3_LCD_REGDEBUG
+static bool esp32s3_lcd_checkreg(bool wr,
+                                 uint32_t regval,
+                                 uintptr_t address)
+{
+  struct esp32s3_lcd_s *priv = &g_lcd_priv;
+
+  if (wr      == priv->wrlast &&   /* Same kind of access? */
+      regval  == priv->vallast &&  /* Same value? */
+      address == priv->addrlast)   /* Same address? */
+    {
+      /* Yes, then just keep a count of the number of times we did this. */
+
+      priv->ntimes++;
+      return false;
+    }
+  else
+    {
+      /* Did we do the previous operation more than once? */
+
+      if (priv->ntimes > 0)
+        {
+          /* Yes... show how many times we did it */
+
+          lcdinfo("...[Repeats %d times]...\n", priv->ntimes);
+        }
+
+      /* Save information about the new access */
+
+      priv->wrlast   = wr;
+      priv->vallast  = regval;
+      priv->addrlast = address;
+      priv->ntimes   = 0;
+    }
+
+  /* Return true if this is the first time that we have done this operation */
+
+  return true;
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32s3_lcd_getreg
+ *
+ * Description:
+ *  Read any 32-bit register using an absolute
+ *
+ * Input Parameters:
+ *  address - Regster address
+ *
+ * Returned Value:
+ *  Regster value.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP32S3_LCD_REGDEBUG
+static uint32_t esp32s3_lcd_getreg(uintptr_t address)
+{
+  uint32_t regval = getreg32(address);
+
+  if (esp32s3_lcd_checkreg(false, regval, address))
+    {
+      lcdinfo("%" PRIx32 " ->%" PRIx32 "\n", address, regval);
+    }
+
+  return regval;
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32s3_lcd_putreg
+ *
+ * Description:
+ *  Write to any 32-bit register using an absolute address
+ *
+ * Input Parameters:
+ *  address - Regster address
+ *  regval  - Regster value
+ *
+ * Returned Value:
+ *  None
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP32S3_LCD_REGDEBUG
+static void esp32s3_lcd_putreg(uintptr_t address, uint32_t regval)
+{
+  if (esp32s3_lcd_checkreg(true, regval, address))
+    {
+      lcdinfo("%" PRIx32 " <-%" PRIx32 "\n", address, regval);
+    }
+
+  putreg32(regval, address);
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32s3_lcd_base_getvideoinfo
+ *
+ * Description:
+ *   Entrypoint ioctl FBIOGET_VIDEOINFO
+ *   Get the videoinfo for the framebuffer
+ *
+ * Input Parameters:
+ *   vtable - The framebuffer driver object
+ *   vinfo  - The videoinfo object
+ *
+ * Returned Value:
+ *   Zero is returned on success; a negated errno value is returned on any
+ *   failure.
+ *
+ ****************************************************************************/
+
+static int esp32s3_lcd_base_getvideoinfo(struct fb_vtable_s *vtable,
+                                         struct fb_videoinfo_s *vinfo)
+{
+  lcdinfo("vtable=%p vinfo=%p\n", vtable, vinfo);
+  if (vtable && vinfo)
+    {
+      memcpy(vinfo, &g_base_videoinfo, sizeof(struct fb_videoinfo_s));
+      return OK;
+    }
+
+  lcderr("ERROR: Returning EINVAL\n");
+  return -EINVAL;
+}
+
+/****************************************************************************
+ * Name: esp32s3_lcd_base_getplaneinfo
+ *
+ * Description:
+ *   Entrypoint ioctl FBIOGET_PLANEINFO
+ *   Get the planeinfo for the framebuffer
+ *
+ * Input Parameters:
+ *   vtable - The framebuffer driver object
+ *   pinfo  - the planeinfo object
+ *
+ * Returned Value:
+ *   Zero is returned on success; a negated errno value is returned on any
+ *   failure.
+ *
+ ****************************************************************************/
+
+static int esp32s3_lcd_base_getplaneinfo(struct fb_vtable_s *vtable,
+                                         int planeno,
+                                         struct fb_planeinfo_s *pinfo)
+{
+  lcdinfo("vtable=%p planeno=%d pinfo=%p\n", vtable, planeno, pinfo);
+  if (vtable && planeno == 0 && pinfo)
+    {
+      struct esp32s3_lcd_s *priv = &g_lcd_priv;
+      struct esp32s3_layer_s *layer = CURRENT_LAYER(priv);
+
+      pinfo->display = 0;
+      pinfo->fbmem   = (void *)layer->framebuffer;
+      pinfo->fblen   = ESP32S3_LCD_FB_SIZE;
+      pinfo->stride  = ESP32S3_LCD_STRIDE;
+      pinfo->bpp     = ESP32S3_LCD_DATA_BPP;
+      return OK;
+    }
+
+  lcderr("ERROR: Returning EINVAL\n");
+  return -EINVAL;
+}
+
+/****************************************************************************
+ * Name: esp32s3_lcd_base_updatearea
+ *
+ * Description:
+ *   Flush data from cache to PSRAM so that LCD DMA can access it.
+ *
+ * Input Parameters:
+ *   vtable - The framebuffer driver object
+ *   area   - Reference to the overlay area
+ *
+ * Returned Value:
+ *   Zero is returned on success; a negated errno value is returned on any
+ *   failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_FB_UPDATE
+static int esp32s3_lcd_base_updatearea(struct fb_vtable_s *vtable,
+                                       const struct fb_area_s *area)
+{
+  struct esp32s3_lcd_s *priv = &g_lcd_priv;
+
+  cache_writeback_addr(CURRENT_LAYER(priv)->framebuffer,
+                       ESP32S3_LCD_FB_SIZE);
+
+  return 0;
+}
+#endif
+
+/****************************************************************************
+ * Name: lcd_interrupt
+ *
+ * Description:
+ *   Start sending next frame to LCD.
+ *
+ * Input Parameters:
+ *   irq     - The IRQ number of the interrupt.
+ *   context - The register state save array at the time of the interrupt.
+ *   arg     - Not used
+ *
+ * Returned Value:
+ *   Zero on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int IRAM_ATTR lcd_interrupt(int irq, void *context, void *arg)
+{
+  uint32_t regval;
+  struct esp32s3_lcd_s *priv = &g_lcd_priv;
+  uint32_t status = esp32s3_lcd_getreg(LCD_CAM_LC_DMA_INT_ST_REG);
+
+  esp32s3_lcd_putreg(LCD_CAM_LC_DMA_INT_CLR_REG, status);
+  if (status & LCD_CAM_LCD_VSYNC_INT_ST_M)
+    {
+      /* Stop TX */
+
+      regval  = esp32s3_lcd_getreg(LCD_CAM_LCD_USER_REG);
+      regval &= ~LCD_CAM_LCD_START_M;
+      esp32s3_lcd_putreg(LCD_CAM_LCD_USER_REG, regval);
+
+      regval  = esp32s3_lcd_getreg(LCD_CAM_LCD_USER_REG);
+      regval |= LCD_CAM_LCD_UPDATE_REG_M;
+      esp32s3_lcd_putreg(LCD_CAM_LCD_USER_REG, regval);
+
+      /* Clear TX fifo */
+
+      regval  = esp32s3_lcd_getreg(LCD_CAM_LCD_MISC_REG);
+      regval |= LCD_CAM_LCD_AFIFO_RESET_M;
+      esp32s3_lcd_putreg(LCD_CAM_LCD_MISC_REG, regval);
+
+#if ESP32S3_LCD_LAYERS > 1
+      priv->cur_layer = (priv->cur_layer + 1) % ESP32S3_LCD_LAYERS;
+
+      esp32s3_dma_load(CURRENT_LAYER(priv)->dmadesc,
+                       priv->dma_channel,
+                       true);
+#endif
+
+#ifndef CONFIG_FB_UPDATE
+      /* Write framebuffer data from D-cache to PSRAM */
+
+      cache_writeback_addr(CURRENT_LAYER(priv)->framebuffer,
+                           ESP32S3_LCD_FB_SIZE);
+#endif
+
+      /* Enable DMA TX */
+
+      esp32s3_dma_enable(priv->dma_channel, true);
+
+      /* Update LCD parameters and start TX */
+
+      regval  = esp32s3_lcd_getreg(LCD_CAM_LCD_USER_REG);
+      regval |= LCD_CAM_LCD_UPDATE_REG_M;
+      esp32s3_lcd_putreg(LCD_CAM_LCD_USER_REG, regval);
+
+      regval  = esp32s3_lcd_getreg(LCD_CAM_LCD_USER_REG);
+      regval |= LCD_CAM_LCD_START_M;
+      esp32s3_lcd_putreg(LCD_CAM_LCD_USER_REG, regval);
+    }
+
+  return 0;
+}
+
+/****************************************************************************
+ * Name: esp32s3_lcd_dmasetup
+ *
+ * Description:
+ *   Configure the channel DMA
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp32s3_lcd_dmasetup(void)
+{
+  struct esp32s3_lcd_s *priv = &g_lcd_priv;
+
+  esp32s3_dma_init();
+
+  priv->dma_channel = esp32s3_dma_request(ESP32S3_DMA_PERIPH_LCDCAM,
+                                          10, 1, true);
+  DEBUGASSERT(priv->dma_channel >= 0);
+  esp32s3_dma_set_ext_memblk(priv->dma_channel,
+                             true,
+                             ESP32S3_DMA_EXT_MEMBLK_64B);
+
+  for (int i = 0; i < ESP32S3_LCD_LAYERS; i++)
+    {
+      struct esp32s3_layer_s *layer = &priv->layer[i];
+
+      layer->framebuffer = memalign(64, ESP32S3_LCD_FB_SIZE);
+      DEBUGASSERT(layer->framebuffer != NULL);
+      memset(layer->framebuffer, 0, ESP32S3_LCD_FB_SIZE);
+
+      esp32s3_dma_setup(layer->dmadesc,
+                        ESP32S3_LCD_DMADESC_NUM,
+                        layer->framebuffer,
+                        ESP32S3_LCD_FB_SIZE,
+                        true);
+    }
+}
+
+/****************************************************************************
+ * Name: esp32s3_lcd_gpio_config
+ *
+ * Description:
+ *   Configure GPIO pins for use with the LCD
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp32s3_lcd_gpio_config(void)
+{
+  const struct esp32s3_lcd_config_s *config = &g_lcd_config;
+
+  lcdinfo("Configuring pins\n");
+
+  /* Configure each pin */
+
+  for (int i = 0; i < ESP32S3_LCD_PINS; i++)
+    {
+      const struct pin_config_s *pins_config = &config->pins_config[i];
+
+      esp32s3_configgpio(pins_config->num, OUTPUT);
+      esp32s3_gpio_matrix_out(pins_config->num, pins_config->signal, 0, 0);
+    }
+}
+
+/****************************************************************************
+ * Name: esp32s3_lcd_enableclk
+ *
+ * Description:
+ *   Enable LCD clock
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp32s3_lcd_enableclk(void)
+{
+  uint32_t regval;
+  uint32_t clk_a;
+  uint32_t clk_b;
+
+#if ESP32S3_LCD_CLK_RES != 0
+    uint32_t divisor = max_common_divisor(ESP32S3_LCD_CLK_RES,
+                                          CONFIG_ESP32S3_LCD_CLOCK_MHZ);
+    clk_b = ESP32S3_LCD_CLK_RES / divisor;
+    clk_a = CONFIG_ESP32S3_LCD_CLOCK_MHZ / divisor;
+
+    lcdinfo("divisor=%d\n", divisor);
+#else
+    clk_b = clk_a = 0;
+#endif
+
+  lcdinfo("PCLK=%d/(%d + %d/%d)\n", ESP32S3_LCD_CLK_MHZ,
+          ESP32S3_LCD_CLK_N, clk_b, clk_a);
+
+  esp32s3_periph_module_enable(PERIPH_LCD_CAM_MODULE);
+
+  regval = (1 << LCD_CAM_LCD_CLKCNT_N_S) |
+           LCD_CAM_CLK_EN_M |
+           LCD_CAM_LCD_CLK_EQU_SYSCLK_M |
+           (ESP32S3_LCD_CLK_SEL << LCD_CAM_LCD_CLK_SEL_S) |
+           (ESP32S3_LCD_CLK_N << LCD_CAM_LCD_CLKM_DIV_NUM_S) |
+           (clk_a << LCD_CAM_LCD_CLKM_DIV_A_S) |
+           (clk_b << LCD_CAM_LCD_CLKM_DIV_B_S);
+  esp32s3_lcd_putreg(LCD_CAM_LCD_CLOCK_REG, regval);
+}
+
+/****************************************************************************
+ * Name: esp32s3_lcd_config
+ *
+ * Description:
+ *   Configure LCD controller.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp32s3_lcd_config(void)
+{
+  uint32_t regval;
+  irqstate_t flags;
+  struct esp32s3_lcd_s *priv = &g_lcd_priv;
+
+  /* Enable TX done interrupt */
+
+  regval  = esp32s3_lcd_getreg(LCD_CAM_LC_DMA_INT_ENA_REG);
+  regval |= LCD_CAM_LCD_VSYNC_INT_ENA_M;
+  esp32s3_lcd_putreg(LCD_CAM_LC_DMA_INT_ENA_REG, regval);
+
+  /**
+   * Set LCD screem parameters:
+   *    1. RGB mode, ouput VSYNC/HSYNC/DE signal
+   *    2. VT height
+   *    3. VA height
+   *    4. HB front
+   *    5. HT width
+   *    6. HA width
+   *    7. VB front
+   *    8. VSYNC width
+   *    9. HSYNC width
+   */
+
+  regval  = esp32s3_lcd_getreg(LCD_CAM_LCD_CTRL_REG);
+  regval |= LCD_CAM_LCD_RGB_MODE_EN_M |
+            (ESP32S3_LCD_VT_HIGHT << LCD_CAM_LCD_VT_HEIGHT_S) |
+            (ESP32S3_LCD_VA_HIGHT << LCD_CAM_LCD_VA_HEIGHT_S) |
+            (ESP32S3_LCD_HB_FRONT << LCD_CAM_LCD_HB_FRONT_S);
+  esp32s3_lcd_putreg(LCD_CAM_LCD_CTRL_REG, regval);
+
+  regval = (ESP32S3_LCD_HT_WIDTH << LCD_CAM_LCD_HT_WIDTH_S) |
+           (ESP32S3_LCD_HA_WIDTH << LCD_CAM_LCD_HA_WIDTH_S) |
+           (ESP32S3_LCD_VA_FRONT << LCD_CAM_LCD_VB_FRONT_S);
+  esp32s3_lcd_putreg(LCD_CAM_LCD_CTRL1_REG, regval);
+
+  regval = (ESP32S3_LCD_HSYNC_WIDTH << LCD_CAM_LCD_HSYNC_WIDTH_S) |
+           (ESP32S3_LCD_VSYNC_WIDTH << LCD_CAM_LCD_VSYNC_WIDTH_S) |
+           LCD_CAM_LCD_HSYNC_IDLE_POL_M |
+           LCD_CAM_LCD_HS_BLANK_EN_M |
+           LCD_CAM_LCD_VSYNC_IDLE_POL_M;
+  esp32s3_lcd_putreg(LCD_CAM_LCD_CTRL2_REG, regval);
+
+  /**
+   * Configure output mode:
+   *    1. always output
+   *    2. 16-bit word
+   *    3. LCD mode
+   *    4. 3-bit dummy
+   */
+
+  regval = LCD_CAM_LCD_ALWAYS_OUT_EN_M |
+           LCD_CAM_LCD_2BYTE_EN_M |
+           LCD_CAM_LCD_DOUT_M |
+           (3 << LCD_CAM_LCD_DUMMY_CYCLELEN_S);
+  esp32s3_lcd_putreg(LCD_CAM_LCD_USER_REG, regval);
+
+  regval = LCD_CAM_LCD_AFIFO_THRESHOLD_NUM_M |
+           LCD_CAM_LCD_BK_EN_M;
+  esp32s3_lcd_putreg(LCD_CAM_LCD_MISC_REG, regval);
+
+  /* Update registers */
+
+  regval  = esp32s3_lcd_getreg(LCD_CAM_LCD_USER_REG);
+  regval |= LCD_CAM_LCD_UPDATE_REG_M;
+  esp32s3_lcd_putreg(LCD_CAM_LCD_USER_REG, regval);
+
+  /* Set GDMA */
+
+  esp32s3_lcd_dmasetup();
+
+  /* Configure interrupt */
+
+  regval = LCD_CAM_LCD_VSYNC_INT_ENA_M;
+  esp32s3_lcd_putreg(LCD_CAM_LC_DMA_INT_ENA_REG, regval);
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  priv->cpu = up_cpu_index();
+  priv->cpuint = esp32s3_setup_irq(priv->cpu,
+                                   ESP32S3_PERIPH_LCD_CAM,
+                                   ESP32S3_INT_PRIO_DEF,
+                                   ESP32S3_CPUINT_LEVEL);
+  DEBUGASSERT(priv->cpuint >= 0);
+
+  DEBUGASSERT(irq_attach(ESP32S3_IRQ_LCD_CAM, lcd_interrupt, priv) == 0);
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  up_enable_irq(ESP32S3_IRQ_LCD_CAM);
+}
+
+/****************************************************************************
+ * Name: esp32s3_lcd_enable
+ *
+ * Description:
+ *   Enable LCD display.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp32s3_lcd_enable(void)
+{
+  uint32_t regval;
+  struct esp32s3_lcd_s *priv = &g_lcd_priv;
+  struct esp32s3_layer_s *layer = CURRENT_LAYER(priv);
+
+  esp32s3_dma_load(layer->dmadesc, priv->dma_channel, true);
+  esp32s3_dma_enable(priv->dma_channel, true);
+
+  /* Delay 1 microsecond to wait the DMA start */
+
+  esp_rom_delay_us(1);
+
+  /* Update LCD parameters before start */
+
+  regval  = esp32s3_lcd_getreg(LCD_CAM_LCD_USER_REG);
+  regval |= LCD_CAM_LCD_UPDATE_REG_M;
+  esp32s3_lcd_putreg(LCD_CAM_LCD_USER_REG, regval);
+
+  regval  = esp32s3_lcd_getreg(LCD_CAM_LCD_USER_REG);
+  regval |= LCD_CAM_LCD_START_M;
+  esp32s3_lcd_putreg(LCD_CAM_LCD_USER_REG, regval);
+}
+
+/****************************************************************************
+ * Name: esp32s3_lcd_disable
+ *
+ * Description:
+ *   Disable the LCD peripheral
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp32s3_lcd_disable(void)
+{
+  uint32_t regval;
+
+  regval  = esp32s3_lcd_getreg(LCD_CAM_LCD_USER_REG);
+  regval &= ~LCD_CAM_LCD_START_M;
+  esp32s3_lcd_putreg(LCD_CAM_LCD_USER_REG, regval);
+
+  /* Update LCD parameters before start */
+
+  regval  = esp32s3_lcd_getreg(LCD_CAM_LCD_USER_REG);
+  regval |= LCD_CAM_LCD_UPDATE_REG_M;
+  esp32s3_lcd_putreg(LCD_CAM_LCD_USER_REG, regval);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_fbinitialize
+ *
+ * Description:
+ *   Initialize the framebuffer video hardware associated with the display.
+ *
+ * Input Parameters:
+ *   display - In the case of hardware with multiple displays, this
+ *     specifies the display.  Normally this is zero.
+ *
+ * Returned Value:
+ *   Zero is returned on success; a negated errno value is returned on any
+ *   failure.
+ *
+ ****************************************************************************/
+
+int up_fbinitialize(int display)
+{
+  lcdinfo("Entry\n");
+
+  if (g_lcd_priv.ref++ != 0)
+    {
+      return 0;
+    }
+
+  DEBUGASSERT(display == 0);
+
+  /* Disable the LCD */
+
+  esp32s3_lcd_disable();
+
+  /* Configure GPIO pins */
+
+  esp32s3_lcd_gpio_config();
+
+  /* Enable the LCD peripheral clock */
+
+  esp32s3_lcd_enableclk();
+
+  /* Configure LCD controller */
+
+  esp32s3_lcd_config();
+
+  /* And turn the LCD on */
+
+  esp32s3_lcd_enable();
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: up_fbgetvplane
+ *
+ * Description:
+ *   Return a a reference to the framebuffer object for the specified video
+ *   plane of the specified plane.  Many OSDs support multiple planes of
+ *   video.
+ *
+ * Input Parameters:
+ *   display - In the case of hardware with multiple displays, this
+ *     specifies the display.  Normally this is zero.
+ *   vplane - Identifies the plane being queried.
+ *
+ * Returned Value:
+ *   A non-NULL pointer to the frame buffer access structure is returned on
+ *   success; NULL is returned on any failure.
+ *
+ ****************************************************************************/
+
+struct fb_vtable_s *up_fbgetvplane(int display, int vplane)
+{
+  DEBUGASSERT(display == 0);
+
+  lcdinfo("vplane: %d\n", vplane);
+  if (vplane == 0)
+    {
+      return (struct fb_vtable_s *)&g_base_vtable;
+    }
+  else
+    {
+      return NULL;
+    }
+}
diff --git a/arch/xtensa/src/esp32s3/hardware/esp32s3_lcd_cam.h 
b/arch/xtensa/src/esp32s3/hardware/esp32s3_lcd_cam.h
new file mode 100644
index 0000000000..5865a42d18
--- /dev/null
+++ b/arch/xtensa/src/esp32s3/hardware/esp32s3_lcd_cam.h
@@ -0,0 +1,1349 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32s3/hardware/esp32s3_lcd_cam.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you 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.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_XTENSA_SRC_ESP32S3_HARDWARE_ESP32S3_LCD_CAM_H
+#define __ARCH_XTENSA_SRC_ESP32S3_HARDWARE_ESP32S3_LCD_CAM_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "esp32s3_soc.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* LCD_CAM_LCD_CLOCK_REG register
+ * LCD clock register
+ */
+
+#define LCD_CAM_LCD_CLOCK_REG (DR_REG_LCD_CAM_BASE + 0x0)
+
+/* LCD_CAM_CLK_EN : R/W; bitpos: [31]; default: 0;
+ * Set this bit to enable clk gate
+ */
+
+#define LCD_CAM_CLK_EN    (BIT(31))
+#define LCD_CAM_CLK_EN_M  (LCD_CAM_CLK_EN_V << LCD_CAM_CLK_EN_S)
+#define LCD_CAM_CLK_EN_V  0x00000001
+#define LCD_CAM_CLK_EN_S  31
+
+/* LCD_CAM_LCD_CLK_SEL : R/W; bitpos: [30:29]; default: 0;
+ * Select LCD module source clock. 0: no clock. 1: APLL. 2: CLK160. 3: no
+ * clock.
+ */
+
+#define LCD_CAM_LCD_CLK_SEL    0x00000003
+#define LCD_CAM_LCD_CLK_SEL_M  (LCD_CAM_LCD_CLK_SEL_V << LCD_CAM_LCD_CLK_SEL_S)
+#define LCD_CAM_LCD_CLK_SEL_V  0x00000003
+#define LCD_CAM_LCD_CLK_SEL_S  29
+
+/* LCD_CAM_LCD_CLKM_DIV_A : R/W; bitpos: [28:23]; default: 0;
+ * Fractional clock divider denominator value
+ */
+
+#define LCD_CAM_LCD_CLKM_DIV_A    0x0000003f
+#define LCD_CAM_LCD_CLKM_DIV_A_M  (LCD_CAM_LCD_CLKM_DIV_A_V << 
LCD_CAM_LCD_CLKM_DIV_A_S)
+#define LCD_CAM_LCD_CLKM_DIV_A_V  0x0000003f
+#define LCD_CAM_LCD_CLKM_DIV_A_S  23
+
+/* LCD_CAM_LCD_CLKM_DIV_B : R/W; bitpos: [22:17]; default: 0;
+ * Fractional clock divider numerator value
+ */
+
+#define LCD_CAM_LCD_CLKM_DIV_B    0x0000003f
+#define LCD_CAM_LCD_CLKM_DIV_B_M  (LCD_CAM_LCD_CLKM_DIV_B_V << 
LCD_CAM_LCD_CLKM_DIV_B_S)
+#define LCD_CAM_LCD_CLKM_DIV_B_V  0x0000003f
+#define LCD_CAM_LCD_CLKM_DIV_B_S  17
+
+/* LCD_CAM_LCD_CLKM_DIV_NUM : R/W; bitpos: [16:9]; default: 4;
+ * Integral LCD clock divider value
+ */
+
+#define LCD_CAM_LCD_CLKM_DIV_NUM    0x000000ff
+#define LCD_CAM_LCD_CLKM_DIV_NUM_M  (LCD_CAM_LCD_CLKM_DIV_NUM_V << 
LCD_CAM_LCD_CLKM_DIV_NUM_S)
+#define LCD_CAM_LCD_CLKM_DIV_NUM_V  0x000000ff
+#define LCD_CAM_LCD_CLKM_DIV_NUM_S  9
+
+/* LCD_CAM_LCD_CK_OUT_EDGE : R/W; bitpos: [8]; default: 0;
+ * 1: LCD_PCLK high in first half clock cycle. 0: LCD_PCLK low in first half
+ * clock cycle.
+ */
+
+#define LCD_CAM_LCD_CK_OUT_EDGE    (BIT(8))
+#define LCD_CAM_LCD_CK_OUT_EDGE_M  (LCD_CAM_LCD_CK_OUT_EDGE_V << 
LCD_CAM_LCD_CK_OUT_EDGE_S)
+#define LCD_CAM_LCD_CK_OUT_EDGE_V  0x00000001
+#define LCD_CAM_LCD_CK_OUT_EDGE_S  8
+
+/* LCD_CAM_LCD_CK_IDLE_EDGE : R/W; bitpos: [7]; default: 0;
+ * 1: LCD_PCLK line is high when idle     0: LCD_PCLK line is low when idle.
+ */
+
+#define LCD_CAM_LCD_CK_IDLE_EDGE    (BIT(7))
+#define LCD_CAM_LCD_CK_IDLE_EDGE_M  (LCD_CAM_LCD_CK_IDLE_EDGE_V << 
LCD_CAM_LCD_CK_IDLE_EDGE_S)
+#define LCD_CAM_LCD_CK_IDLE_EDGE_V  0x00000001
+#define LCD_CAM_LCD_CK_IDLE_EDGE_S  7
+
+/* LCD_CAM_LCD_CLK_EQU_SYSCLK : R/W; bitpos: [6]; default: 1;
+ * 1: f_LCD_PCLK = f_LCD_CLK. 0: f_LCD_PCLK = f_LCD_CLK / (reg_clkcnt_N + 1).
+ */
+
+#define LCD_CAM_LCD_CLK_EQU_SYSCLK    (BIT(6))
+#define LCD_CAM_LCD_CLK_EQU_SYSCLK_M  (LCD_CAM_LCD_CLK_EQU_SYSCLK_V << 
LCD_CAM_LCD_CLK_EQU_SYSCLK_S)
+#define LCD_CAM_LCD_CLK_EQU_SYSCLK_V  0x00000001
+#define LCD_CAM_LCD_CLK_EQU_SYSCLK_S  6
+
+/* LCD_CAM_LCD_CLKCNT_N : R/W; bitpos: [5:0]; default: 3;
+ * f_LCD_PCLK = f_LCD_CLK / (reg_clkcnt_N + 1) when reg_clk_equ_sysclk is 0.
+ */
+
+#define LCD_CAM_LCD_CLKCNT_N    0x0000003f
+#define LCD_CAM_LCD_CLKCNT_N_M  (LCD_CAM_LCD_CLKCNT_N_V << 
LCD_CAM_LCD_CLKCNT_N_S)
+#define LCD_CAM_LCD_CLKCNT_N_V  0x0000003f
+#define LCD_CAM_LCD_CLKCNT_N_S  0
+
+/* LCD_CAM_CAM_CTRL_REG register
+ * Camera configuration register
+ */
+
+#define LCD_CAM_CAM_CTRL_REG (DR_REG_LCD_CAM_BASE + 0x4)
+
+/* LCD_CAM_CAM_CLK_SEL : R/W; bitpos: [30:29]; default: 0;
+ * Select Camera module source clock. 0: no clock. 1: APLL. 2: CLK160. 3: no
+ * clock.
+ */
+
+#define LCD_CAM_CAM_CLK_SEL    0x00000003
+#define LCD_CAM_CAM_CLK_SEL_M  (LCD_CAM_CAM_CLK_SEL_V << LCD_CAM_CAM_CLK_SEL_S)
+#define LCD_CAM_CAM_CLK_SEL_V  0x00000003
+#define LCD_CAM_CAM_CLK_SEL_S  29
+
+/* LCD_CAM_CAM_CLKM_DIV_A : R/W; bitpos: [28:23]; default: 0;
+ * Fractional clock divider denominator value
+ */
+
+#define LCD_CAM_CAM_CLKM_DIV_A    0x0000003f
+#define LCD_CAM_CAM_CLKM_DIV_A_M  (LCD_CAM_CAM_CLKM_DIV_A_V << 
LCD_CAM_CAM_CLKM_DIV_A_S)
+#define LCD_CAM_CAM_CLKM_DIV_A_V  0x0000003f
+#define LCD_CAM_CAM_CLKM_DIV_A_S  23
+
+/* LCD_CAM_CAM_CLKM_DIV_B : R/W; bitpos: [22:17]; default: 0;
+ * Fractional clock divider numerator value
+ */
+
+#define LCD_CAM_CAM_CLKM_DIV_B    0x0000003f
+#define LCD_CAM_CAM_CLKM_DIV_B_M  (LCD_CAM_CAM_CLKM_DIV_B_V << 
LCD_CAM_CAM_CLKM_DIV_B_S)
+#define LCD_CAM_CAM_CLKM_DIV_B_V  0x0000003f
+#define LCD_CAM_CAM_CLKM_DIV_B_S  17
+
+/* LCD_CAM_CAM_CLKM_DIV_NUM : R/W; bitpos: [16:9]; default: 4;
+ * Integral Camera clock divider value
+ */
+
+#define LCD_CAM_CAM_CLKM_DIV_NUM    0x000000ff
+#define LCD_CAM_CAM_CLKM_DIV_NUM_M  (LCD_CAM_CAM_CLKM_DIV_NUM_V << 
LCD_CAM_CAM_CLKM_DIV_NUM_S)
+#define LCD_CAM_CAM_CLKM_DIV_NUM_V  0x000000ff
+#define LCD_CAM_CAM_CLKM_DIV_NUM_S  9
+
+/* LCD_CAM_CAM_VS_EOF_EN : R/W; bitpos: [8]; default: 0;
+ * 1: CAM_VSYNC to generate in_suc_eof. 0: in_suc_eof is controlled by
+ * reg_cam_rec_data_cyclelen.
+ */
+
+#define LCD_CAM_CAM_VS_EOF_EN    (BIT(8))
+#define LCD_CAM_CAM_VS_EOF_EN_M  (LCD_CAM_CAM_VS_EOF_EN_V << 
LCD_CAM_CAM_VS_EOF_EN_S)
+#define LCD_CAM_CAM_VS_EOF_EN_V  0x00000001
+#define LCD_CAM_CAM_VS_EOF_EN_S  8
+
+/* LCD_CAM_CAM_LINE_INT_EN : R/W; bitpos: [7]; default: 0;
+ * 1: Enable to generate CAM_HS_INT. 0: Disable.
+ */
+
+#define LCD_CAM_CAM_LINE_INT_EN    (BIT(7))
+#define LCD_CAM_CAM_LINE_INT_EN_M  (LCD_CAM_CAM_LINE_INT_EN_V << 
LCD_CAM_CAM_LINE_INT_EN_S)
+#define LCD_CAM_CAM_LINE_INT_EN_V  0x00000001
+#define LCD_CAM_CAM_LINE_INT_EN_S  7
+
+/* LCD_CAM_CAM_BIT_ORDER : R/W; bitpos: [6]; default: 0;
+ * 1: invert data byte order, only valid in 2 byte mode. 0: Not change.
+ */
+
+#define LCD_CAM_CAM_BIT_ORDER    (BIT(6))
+#define LCD_CAM_CAM_BIT_ORDER_M  (LCD_CAM_CAM_BIT_ORDER_V << 
LCD_CAM_CAM_BIT_ORDER_S)
+#define LCD_CAM_CAM_BIT_ORDER_V  0x00000001
+#define LCD_CAM_CAM_BIT_ORDER_S  6
+
+/* LCD_CAM_CAM_BYTE_ORDER : R/W; bitpos: [5]; default: 0;
+ * 1: Change data bit order, change CAM_DATA_in[7:0] to CAM_DATA_in[0:7] in
+ * one byte mode, and bits[15:0] to bits[0:15] in two byte mode.  0: Not
+ * change.
+ */
+
+#define LCD_CAM_CAM_BYTE_ORDER    (BIT(5))
+#define LCD_CAM_CAM_BYTE_ORDER_M  (LCD_CAM_CAM_BYTE_ORDER_V << 
LCD_CAM_CAM_BYTE_ORDER_S)
+#define LCD_CAM_CAM_BYTE_ORDER_V  0x00000001
+#define LCD_CAM_CAM_BYTE_ORDER_S  5
+
+/* LCD_CAM_CAM_UPDATE_REG : R/W; bitpos: [4]; default: 0;
+ * 1: Update Camera registers, will be cleared by hardware. 0 : Not care.
+ */
+
+#define LCD_CAM_CAM_UPDATE_REG    (BIT(4))
+#define LCD_CAM_CAM_UPDATE_REG_M  (LCD_CAM_CAM_UPDATE_REG_V << 
LCD_CAM_CAM_UPDATE_REG_S)
+#define LCD_CAM_CAM_UPDATE_REG_V  0x00000001
+#define LCD_CAM_CAM_UPDATE_REG_S  4
+
+/* LCD_CAM_CAM_VSYNC_FILTER_THRES : R/W; bitpos: [3:1]; default: 0;
+ * Filter threshold value for CAM_VSYNC signal.
+ */
+
+#define LCD_CAM_CAM_VSYNC_FILTER_THRES    0x00000007
+#define LCD_CAM_CAM_VSYNC_FILTER_THRES_M  (LCD_CAM_CAM_VSYNC_FILTER_THRES_V << 
LCD_CAM_CAM_VSYNC_FILTER_THRES_S)
+#define LCD_CAM_CAM_VSYNC_FILTER_THRES_V  0x00000007
+#define LCD_CAM_CAM_VSYNC_FILTER_THRES_S  1
+
+/* LCD_CAM_CAM_STOP_EN : R/W; bitpos: [0]; default: 0;
+ * Camera stop enable signal, 1: camera stops when DMA Rx FIFO is full. 0:
+ * Not stop.
+ */
+
+#define LCD_CAM_CAM_STOP_EN    (BIT(0))
+#define LCD_CAM_CAM_STOP_EN_M  (LCD_CAM_CAM_STOP_EN_V << LCD_CAM_CAM_STOP_EN_S)
+#define LCD_CAM_CAM_STOP_EN_V  0x00000001
+#define LCD_CAM_CAM_STOP_EN_S  0
+
+/* LCD_CAM_CAM_CTRL1_REG register
+ * Camera configuration register
+ */
+
+#define LCD_CAM_CAM_CTRL1_REG (DR_REG_LCD_CAM_BASE + 0x8)
+
+/* LCD_CAM_CAM_AFIFO_RESET : WO; bitpos: [31]; default: 0;
+ * Camera AFIFO reset signal.
+ */
+
+#define LCD_CAM_CAM_AFIFO_RESET    (BIT(31))
+#define LCD_CAM_CAM_AFIFO_RESET_M  (LCD_CAM_CAM_AFIFO_RESET_V << 
LCD_CAM_CAM_AFIFO_RESET_S)
+#define LCD_CAM_CAM_AFIFO_RESET_V  0x00000001
+#define LCD_CAM_CAM_AFIFO_RESET_S  31
+
+/* LCD_CAM_CAM_RESET : WO; bitpos: [30]; default: 0;
+ * Camera module reset signal.
+ */
+
+#define LCD_CAM_CAM_RESET    (BIT(30))
+#define LCD_CAM_CAM_RESET_M  (LCD_CAM_CAM_RESET_V << LCD_CAM_CAM_RESET_S)
+#define LCD_CAM_CAM_RESET_V  0x00000001
+#define LCD_CAM_CAM_RESET_S  30
+
+/* LCD_CAM_CAM_START : R/W; bitpos: [29]; default: 0;
+ * Camera module start signal.
+ */
+
+#define LCD_CAM_CAM_START    (BIT(29))
+#define LCD_CAM_CAM_START_M  (LCD_CAM_CAM_START_V << LCD_CAM_CAM_START_S)
+#define LCD_CAM_CAM_START_V  0x00000001
+#define LCD_CAM_CAM_START_S  29
+
+/* LCD_CAM_CAM_VH_DE_MODE_EN : R/W; bitpos: [28]; default: 0;
+ * 1: Input control signals are CAM_DE CAM_HSYNC and CAM_VSYNC is 1. 0:
+ * Input control signals are CAM_DE and CAM_VSYNC. CAM_HSYNC and CAM_DE are
+ * all 1 the the same time.
+ */
+
+#define LCD_CAM_CAM_VH_DE_MODE_EN    (BIT(28))
+#define LCD_CAM_CAM_VH_DE_MODE_EN_M  (LCD_CAM_CAM_VH_DE_MODE_EN_V << 
LCD_CAM_CAM_VH_DE_MODE_EN_S)
+#define LCD_CAM_CAM_VH_DE_MODE_EN_V  0x00000001
+#define LCD_CAM_CAM_VH_DE_MODE_EN_S  28
+
+/* LCD_CAM_CAM_VSYNC_INV : R/W; bitpos: [27]; default: 0;
+ * CAM_VSYNC invert enable signal, valid in high level.
+ */
+
+#define LCD_CAM_CAM_VSYNC_INV    (BIT(27))
+#define LCD_CAM_CAM_VSYNC_INV_M  (LCD_CAM_CAM_VSYNC_INV_V << 
LCD_CAM_CAM_VSYNC_INV_S)
+#define LCD_CAM_CAM_VSYNC_INV_V  0x00000001
+#define LCD_CAM_CAM_VSYNC_INV_S  27
+
+/* LCD_CAM_CAM_HSYNC_INV : R/W; bitpos: [26]; default: 0;
+ * CAM_HSYNC invert enable signal, valid in high level.
+ */
+
+#define LCD_CAM_CAM_HSYNC_INV    (BIT(26))
+#define LCD_CAM_CAM_HSYNC_INV_M  (LCD_CAM_CAM_HSYNC_INV_V << 
LCD_CAM_CAM_HSYNC_INV_S)
+#define LCD_CAM_CAM_HSYNC_INV_V  0x00000001
+#define LCD_CAM_CAM_HSYNC_INV_S  26
+
+/* LCD_CAM_CAM_DE_INV : R/W; bitpos: [25]; default: 0;
+ * CAM_DE invert enable signal, valid in high level.
+ */
+
+#define LCD_CAM_CAM_DE_INV    (BIT(25))
+#define LCD_CAM_CAM_DE_INV_M  (LCD_CAM_CAM_DE_INV_V << LCD_CAM_CAM_DE_INV_S)
+#define LCD_CAM_CAM_DE_INV_V  0x00000001
+#define LCD_CAM_CAM_DE_INV_S  25
+
+/* LCD_CAM_CAM_2BYTE_EN : R/W; bitpos: [24]; default: 0;
+ * 1: The bit number of input data is 9~16.  0: The bit number of input data
+ * is 0~8.
+ */
+
+#define LCD_CAM_CAM_2BYTE_EN    (BIT(24))
+#define LCD_CAM_CAM_2BYTE_EN_M  (LCD_CAM_CAM_2BYTE_EN_V << 
LCD_CAM_CAM_2BYTE_EN_S)
+#define LCD_CAM_CAM_2BYTE_EN_V  0x00000001
+#define LCD_CAM_CAM_2BYTE_EN_S  24
+
+/* LCD_CAM_CAM_VSYNC_FILTER_EN : R/W; bitpos: [23]; default: 0;
+ * 1: Enable CAM_VSYNC filter function. 0: bypass.
+ */
+
+#define LCD_CAM_CAM_VSYNC_FILTER_EN    (BIT(23))
+#define LCD_CAM_CAM_VSYNC_FILTER_EN_M  (LCD_CAM_CAM_VSYNC_FILTER_EN_V << 
LCD_CAM_CAM_VSYNC_FILTER_EN_S)
+#define LCD_CAM_CAM_VSYNC_FILTER_EN_V  0x00000001
+#define LCD_CAM_CAM_VSYNC_FILTER_EN_S  23
+
+/* LCD_CAM_CAM_CLK_INV : R/W; bitpos: [22]; default: 0;
+ * 1: Invert  the input signal CAM_PCLK. 0: Not invert.
+ */
+
+#define LCD_CAM_CAM_CLK_INV    (BIT(22))
+#define LCD_CAM_CAM_CLK_INV_M  (LCD_CAM_CAM_CLK_INV_V << LCD_CAM_CAM_CLK_INV_S)
+#define LCD_CAM_CAM_CLK_INV_V  0x00000001
+#define LCD_CAM_CAM_CLK_INV_S  22
+
+/* LCD_CAM_CAM_LINE_INT_NUM : R/W; bitpos: [21:16]; default: 0;
+ * The line number minus 1 to generate cam_hs_int.
+ */
+
+#define LCD_CAM_CAM_LINE_INT_NUM    0x0000003f
+#define LCD_CAM_CAM_LINE_INT_NUM_M  (LCD_CAM_CAM_LINE_INT_NUM_V << 
LCD_CAM_CAM_LINE_INT_NUM_S)
+#define LCD_CAM_CAM_LINE_INT_NUM_V  0x0000003f
+#define LCD_CAM_CAM_LINE_INT_NUM_S  16
+
+/* LCD_CAM_CAM_REC_DATA_BYTELEN : R/W; bitpos: [15:0]; default: 0;
+ * Camera receive data byte length minus 1 to set DMA in_suc_eof_int.
+ */
+
+#define LCD_CAM_CAM_REC_DATA_BYTELEN    0x0000ffff
+#define LCD_CAM_CAM_REC_DATA_BYTELEN_M  (LCD_CAM_CAM_REC_DATA_BYTELEN_V << 
LCD_CAM_CAM_REC_DATA_BYTELEN_S)
+#define LCD_CAM_CAM_REC_DATA_BYTELEN_V  0x0000ffff
+#define LCD_CAM_CAM_REC_DATA_BYTELEN_S  0
+
+/* LCD_CAM_CAM_RGB_YUV_REG register
+ * Camera configuration register
+ */
+
+#define LCD_CAM_CAM_RGB_YUV_REG (DR_REG_LCD_CAM_BASE + 0xc)
+
+/* LCD_CAM_CAM_CONV_BYPASS : R/W; bitpos: [31]; default: 0;
+ * 0: Bypass converter. 1: Enable converter.
+ */
+
+#define LCD_CAM_CAM_CONV_BYPASS    (BIT(31))
+#define LCD_CAM_CAM_CONV_BYPASS_M  (LCD_CAM_CAM_CONV_BYPASS_V << 
LCD_CAM_CAM_CONV_BYPASS_S)
+#define LCD_CAM_CAM_CONV_BYPASS_V  0x00000001
+#define LCD_CAM_CAM_CONV_BYPASS_S  31
+
+/* LCD_CAM_CAM_CONV_TRANS_MODE : R/W; bitpos: [30]; default: 0;
+ * 0: YUV to RGB. 1: RGB to YUV.
+ */
+
+#define LCD_CAM_CAM_CONV_TRANS_MODE    (BIT(30))
+#define LCD_CAM_CAM_CONV_TRANS_MODE_M  (LCD_CAM_CAM_CONV_TRANS_MODE_V << 
LCD_CAM_CAM_CONV_TRANS_MODE_S)
+#define LCD_CAM_CAM_CONV_TRANS_MODE_V  0x00000001
+#define LCD_CAM_CAM_CONV_TRANS_MODE_S  30
+
+/* LCD_CAM_CAM_CONV_MODE_8BITS_ON : R/W; bitpos: [29]; default: 0;
+ * 0: 16bits mode. 1: 8bits mode.
+ */
+
+#define LCD_CAM_CAM_CONV_MODE_8BITS_ON    (BIT(29))
+#define LCD_CAM_CAM_CONV_MODE_8BITS_ON_M  (LCD_CAM_CAM_CONV_MODE_8BITS_ON_V << 
LCD_CAM_CAM_CONV_MODE_8BITS_ON_S)
+#define LCD_CAM_CAM_CONV_MODE_8BITS_ON_V  0x00000001
+#define LCD_CAM_CAM_CONV_MODE_8BITS_ON_S  29
+
+/* LCD_CAM_CAM_CONV_DATA_IN_MODE : R/W; bitpos: [28]; default: 0;
+ * LIMIT or FULL mode of Data in. 0: limit. 1: full
+ */
+
+#define LCD_CAM_CAM_CONV_DATA_IN_MODE    (BIT(28))
+#define LCD_CAM_CAM_CONV_DATA_IN_MODE_M  (LCD_CAM_CAM_CONV_DATA_IN_MODE_V << 
LCD_CAM_CAM_CONV_DATA_IN_MODE_S)
+#define LCD_CAM_CAM_CONV_DATA_IN_MODE_V  0x00000001
+#define LCD_CAM_CAM_CONV_DATA_IN_MODE_S  28
+
+/* LCD_CAM_CAM_CONV_DATA_OUT_MODE : R/W; bitpos: [27]; default: 0;
+ * LIMIT or FULL mode of Data out. 0: limit. 1: full
+ */
+
+#define LCD_CAM_CAM_CONV_DATA_OUT_MODE    (BIT(27))
+#define LCD_CAM_CAM_CONV_DATA_OUT_MODE_M  (LCD_CAM_CAM_CONV_DATA_OUT_MODE_V << 
LCD_CAM_CAM_CONV_DATA_OUT_MODE_S)
+#define LCD_CAM_CAM_CONV_DATA_OUT_MODE_V  0x00000001
+#define LCD_CAM_CAM_CONV_DATA_OUT_MODE_S  27
+
+/* LCD_CAM_CAM_CONV_PROTOCOL_MODE : R/W; bitpos: [26]; default: 0;
+ * 0:BT601. 1:BT709.
+ */
+
+#define LCD_CAM_CAM_CONV_PROTOCOL_MODE    (BIT(26))
+#define LCD_CAM_CAM_CONV_PROTOCOL_MODE_M  (LCD_CAM_CAM_CONV_PROTOCOL_MODE_V << 
LCD_CAM_CAM_CONV_PROTOCOL_MODE_S)
+#define LCD_CAM_CAM_CONV_PROTOCOL_MODE_V  0x00000001
+#define LCD_CAM_CAM_CONV_PROTOCOL_MODE_S  26
+
+/* LCD_CAM_CAM_CONV_YUV_MODE : R/W; bitpos: [25:24]; default: 0;
+ * 0: yuv422. 1: yuv420. 2: yuv411. When in yuv2yuv mode, yuv_mode decides
+ * the yuv mode of Data_in
+ */
+
+#define LCD_CAM_CAM_CONV_YUV_MODE    0x00000003
+#define LCD_CAM_CAM_CONV_YUV_MODE_M  (LCD_CAM_CAM_CONV_YUV_MODE_V << 
LCD_CAM_CAM_CONV_YUV_MODE_S)
+#define LCD_CAM_CAM_CONV_YUV_MODE_V  0x00000003
+#define LCD_CAM_CAM_CONV_YUV_MODE_S  24
+
+/* LCD_CAM_CAM_CONV_YUV2YUV_MODE : R/W; bitpos: [23:22]; default: 3;
+ * 0: to yuv422. 1: to yuv420. 2: to yuv411. 3: disabled.  To enable yuv2yuv
+ * mode, trans_mode must be set to 1.
+ */
+
+#define LCD_CAM_CAM_CONV_YUV2YUV_MODE    0x00000003
+#define LCD_CAM_CAM_CONV_YUV2YUV_MODE_M  (LCD_CAM_CAM_CONV_YUV2YUV_MODE_V << 
LCD_CAM_CAM_CONV_YUV2YUV_MODE_S)
+#define LCD_CAM_CAM_CONV_YUV2YUV_MODE_V  0x00000003
+#define LCD_CAM_CAM_CONV_YUV2YUV_MODE_S  22
+
+/* LCD_CAM_CAM_CONV_8BITS_DATA_INV : R/W; bitpos: [21]; default: 0;
+ * 1:invert every two 8bits input data. 2. disabled.
+ */
+
+#define LCD_CAM_CAM_CONV_8BITS_DATA_INV    (BIT(21))
+#define LCD_CAM_CAM_CONV_8BITS_DATA_INV_M  (LCD_CAM_CAM_CONV_8BITS_DATA_INV_V 
<< LCD_CAM_CAM_CONV_8BITS_DATA_INV_S)
+#define LCD_CAM_CAM_CONV_8BITS_DATA_INV_V  0x00000001
+#define LCD_CAM_CAM_CONV_8BITS_DATA_INV_S  21
+
+/* LCD_CAM_LCD_RGB_YUV_REG register
+ * LCD configuration register
+ */
+
+#define LCD_CAM_LCD_RGB_YUV_REG (DR_REG_LCD_CAM_BASE + 0x10)
+
+/* LCD_CAM_LCD_CONV_BYPASS : R/W; bitpos: [31]; default: 0;
+ * 0: Bypass converter. 1: Enable converter.
+ */
+
+#define LCD_CAM_LCD_CONV_BYPASS    (BIT(31))
+#define LCD_CAM_LCD_CONV_BYPASS_M  (LCD_CAM_LCD_CONV_BYPASS_V << 
LCD_CAM_LCD_CONV_BYPASS_S)
+#define LCD_CAM_LCD_CONV_BYPASS_V  0x00000001
+#define LCD_CAM_LCD_CONV_BYPASS_S  31
+
+/* LCD_CAM_LCD_CONV_TRANS_MODE : R/W; bitpos: [30]; default: 0;
+ * 0: YUV to RGB. 1: RGB to YUV.
+ */
+
+#define LCD_CAM_LCD_CONV_TRANS_MODE    (BIT(30))
+#define LCD_CAM_LCD_CONV_TRANS_MODE_M  (LCD_CAM_LCD_CONV_TRANS_MODE_V << 
LCD_CAM_LCD_CONV_TRANS_MODE_S)
+#define LCD_CAM_LCD_CONV_TRANS_MODE_V  0x00000001
+#define LCD_CAM_LCD_CONV_TRANS_MODE_S  30
+
+/* LCD_CAM_LCD_CONV_MODE_8BITS_ON : R/W; bitpos: [29]; default: 0;
+ * 0: 16bits mode. 1: 8bits mode.
+ */
+
+#define LCD_CAM_LCD_CONV_MODE_8BITS_ON    (BIT(29))
+#define LCD_CAM_LCD_CONV_MODE_8BITS_ON_M  (LCD_CAM_LCD_CONV_MODE_8BITS_ON_V << 
LCD_CAM_LCD_CONV_MODE_8BITS_ON_S)
+#define LCD_CAM_LCD_CONV_MODE_8BITS_ON_V  0x00000001
+#define LCD_CAM_LCD_CONV_MODE_8BITS_ON_S  29
+
+/* LCD_CAM_LCD_CONV_DATA_IN_MODE : R/W; bitpos: [28]; default: 0;
+ * LIMIT or FULL mode of Data in. 0: limit. 1: full
+ */
+
+#define LCD_CAM_LCD_CONV_DATA_IN_MODE    (BIT(28))
+#define LCD_CAM_LCD_CONV_DATA_IN_MODE_M  (LCD_CAM_LCD_CONV_DATA_IN_MODE_V << 
LCD_CAM_LCD_CONV_DATA_IN_MODE_S)
+#define LCD_CAM_LCD_CONV_DATA_IN_MODE_V  0x00000001
+#define LCD_CAM_LCD_CONV_DATA_IN_MODE_S  28
+
+/* LCD_CAM_LCD_CONV_DATA_OUT_MODE : R/W; bitpos: [27]; default: 0;
+ * LIMIT or FULL mode of Data out. 0: limit. 1: full
+ */
+
+#define LCD_CAM_LCD_CONV_DATA_OUT_MODE    (BIT(27))
+#define LCD_CAM_LCD_CONV_DATA_OUT_MODE_M  (LCD_CAM_LCD_CONV_DATA_OUT_MODE_V << 
LCD_CAM_LCD_CONV_DATA_OUT_MODE_S)
+#define LCD_CAM_LCD_CONV_DATA_OUT_MODE_V  0x00000001
+#define LCD_CAM_LCD_CONV_DATA_OUT_MODE_S  27
+
+/* LCD_CAM_LCD_CONV_PROTOCOL_MODE : R/W; bitpos: [26]; default: 0;
+ * 0:BT601. 1:BT709.
+ */
+
+#define LCD_CAM_LCD_CONV_PROTOCOL_MODE    (BIT(26))
+#define LCD_CAM_LCD_CONV_PROTOCOL_MODE_M  (LCD_CAM_LCD_CONV_PROTOCOL_MODE_V << 
LCD_CAM_LCD_CONV_PROTOCOL_MODE_S)
+#define LCD_CAM_LCD_CONV_PROTOCOL_MODE_V  0x00000001
+#define LCD_CAM_LCD_CONV_PROTOCOL_MODE_S  26
+
+/* LCD_CAM_LCD_CONV_YUV_MODE : R/W; bitpos: [25:24]; default: 0;
+ * 0: yuv422. 1: yuv420. 2: yuv411. When in yuv2yuv mode, yuv_mode decides
+ * the yuv mode of Data_in
+ */
+
+#define LCD_CAM_LCD_CONV_YUV_MODE    0x00000003
+#define LCD_CAM_LCD_CONV_YUV_MODE_M  (LCD_CAM_LCD_CONV_YUV_MODE_V << 
LCD_CAM_LCD_CONV_YUV_MODE_S)
+#define LCD_CAM_LCD_CONV_YUV_MODE_V  0x00000003
+#define LCD_CAM_LCD_CONV_YUV_MODE_S  24
+
+/* LCD_CAM_LCD_CONV_YUV2YUV_MODE : R/W; bitpos: [23:22]; default: 3;
+ * 0: to yuv422. 1: to yuv420. 2: to yuv411. 3: disabled.  To enable yuv2yuv
+ * mode, trans_mode must be set to 1.
+ */
+
+#define LCD_CAM_LCD_CONV_YUV2YUV_MODE    0x00000003
+#define LCD_CAM_LCD_CONV_YUV2YUV_MODE_M  (LCD_CAM_LCD_CONV_YUV2YUV_MODE_V << 
LCD_CAM_LCD_CONV_YUV2YUV_MODE_S)
+#define LCD_CAM_LCD_CONV_YUV2YUV_MODE_V  0x00000003
+#define LCD_CAM_LCD_CONV_YUV2YUV_MODE_S  22
+
+/* LCD_CAM_LCD_CONV_TXTORX : R/W; bitpos: [21]; default: 0;
+ * 0: txtorx mode off. 1: txtorx mode on.
+ */
+
+#define LCD_CAM_LCD_CONV_TXTORX    (BIT(21))
+#define LCD_CAM_LCD_CONV_TXTORX_M  (LCD_CAM_LCD_CONV_TXTORX_V << 
LCD_CAM_LCD_CONV_TXTORX_S)
+#define LCD_CAM_LCD_CONV_TXTORX_V  0x00000001
+#define LCD_CAM_LCD_CONV_TXTORX_S  21
+
+/* LCD_CAM_LCD_CONV_8BITS_DATA_INV : R/W; bitpos: [20]; default: 0;
+ * 1:invert every two 8bits input data. 2. disabled.
+ */
+
+#define LCD_CAM_LCD_CONV_8BITS_DATA_INV    (BIT(20))
+#define LCD_CAM_LCD_CONV_8BITS_DATA_INV_M  (LCD_CAM_LCD_CONV_8BITS_DATA_INV_V 
<< LCD_CAM_LCD_CONV_8BITS_DATA_INV_S)
+#define LCD_CAM_LCD_CONV_8BITS_DATA_INV_V  0x00000001
+#define LCD_CAM_LCD_CONV_8BITS_DATA_INV_S  20
+
+/* LCD_CAM_LCD_USER_REG register
+ * LCD configuration register
+ */
+
+#define LCD_CAM_LCD_USER_REG (DR_REG_LCD_CAM_BASE + 0x14)
+
+/* LCD_CAM_LCD_CMD_2_CYCLE_EN : R/W; bitpos: [31]; default: 0;
+ * The cycle length of command phase.  1: 2 cycles. 0: 1 cycle.
+ */
+
+#define LCD_CAM_LCD_CMD_2_CYCLE_EN    (BIT(31))
+#define LCD_CAM_LCD_CMD_2_CYCLE_EN_M  (LCD_CAM_LCD_CMD_2_CYCLE_EN_V << 
LCD_CAM_LCD_CMD_2_CYCLE_EN_S)
+#define LCD_CAM_LCD_CMD_2_CYCLE_EN_V  0x00000001
+#define LCD_CAM_LCD_CMD_2_CYCLE_EN_S  31
+
+/* LCD_CAM_LCD_DUMMY_CYCLELEN : R/W; bitpos: [30:29]; default: 0;
+ * The dummy cycle length minus 1.
+ */
+
+#define LCD_CAM_LCD_DUMMY_CYCLELEN    0x00000003
+#define LCD_CAM_LCD_DUMMY_CYCLELEN_M  (LCD_CAM_LCD_DUMMY_CYCLELEN_V << 
LCD_CAM_LCD_DUMMY_CYCLELEN_S)
+#define LCD_CAM_LCD_DUMMY_CYCLELEN_V  0x00000003
+#define LCD_CAM_LCD_DUMMY_CYCLELEN_S  29
+
+/* LCD_CAM_LCD_RESET : WO; bitpos: [28]; default: 0;
+ * The value of  command.
+ */
+
+#define LCD_CAM_LCD_RESET    (BIT(28))
+#define LCD_CAM_LCD_RESET_M  (LCD_CAM_LCD_RESET_V << LCD_CAM_LCD_RESET_S)
+#define LCD_CAM_LCD_RESET_V  0x00000001
+#define LCD_CAM_LCD_RESET_S  28
+
+/* LCD_CAM_LCD_START : R/W; bitpos: [27]; default: 0;
+ * LCD start sending data enable signal, valid in high level.
+ */
+
+#define LCD_CAM_LCD_START    (BIT(27))
+#define LCD_CAM_LCD_START_M  (LCD_CAM_LCD_START_V << LCD_CAM_LCD_START_S)
+#define LCD_CAM_LCD_START_V  0x00000001
+#define LCD_CAM_LCD_START_S  27
+
+/* LCD_CAM_LCD_CMD : R/W; bitpos: [26]; default: 0;
+ * 1: Be able to send command in LCD sequence when LCD starts. 0: Disable.
+ */
+
+#define LCD_CAM_LCD_CMD    (BIT(26))
+#define LCD_CAM_LCD_CMD_M  (LCD_CAM_LCD_CMD_V << LCD_CAM_LCD_CMD_S)
+#define LCD_CAM_LCD_CMD_V  0x00000001
+#define LCD_CAM_LCD_CMD_S  26
+
+/* LCD_CAM_LCD_DUMMY : R/W; bitpos: [25]; default: 0;
+ * 1: Enable DUMMY phase in LCD sequence when LCD starts. 0: Disable.
+ */
+
+#define LCD_CAM_LCD_DUMMY    (BIT(25))
+#define LCD_CAM_LCD_DUMMY_M  (LCD_CAM_LCD_DUMMY_V << LCD_CAM_LCD_DUMMY_S)
+#define LCD_CAM_LCD_DUMMY_V  0x00000001
+#define LCD_CAM_LCD_DUMMY_S  25
+
+/* LCD_CAM_LCD_DOUT : R/W; bitpos: [24]; default: 0;
+ * 1: Be able to send data out in LCD sequence when LCD starts. 0: Disable.
+ */
+
+#define LCD_CAM_LCD_DOUT    (BIT(24))
+#define LCD_CAM_LCD_DOUT_M  (LCD_CAM_LCD_DOUT_V << LCD_CAM_LCD_DOUT_S)
+#define LCD_CAM_LCD_DOUT_V  0x00000001
+#define LCD_CAM_LCD_DOUT_S  24
+
+/* LCD_CAM_LCD_2BYTE_EN : R/W; bitpos: [23]; default: 0;
+ * 1: The bit number of output LCD data is 9~16.  0: The bit number of
+ * output LCD data is 0~8.
+ */
+
+#define LCD_CAM_LCD_2BYTE_EN    (BIT(23))
+#define LCD_CAM_LCD_2BYTE_EN_M  (LCD_CAM_LCD_2BYTE_EN_V << 
LCD_CAM_LCD_2BYTE_EN_S)
+#define LCD_CAM_LCD_2BYTE_EN_V  0x00000001
+#define LCD_CAM_LCD_2BYTE_EN_S  23
+
+/* LCD_CAM_LCD_BYTE_ORDER : R/W; bitpos: [22]; default: 0;
+ * 1: invert data byte order, only valid in 2 byte mode. 0: Not change.
+ */
+
+#define LCD_CAM_LCD_BYTE_ORDER    (BIT(22))
+#define LCD_CAM_LCD_BYTE_ORDER_M  (LCD_CAM_LCD_BYTE_ORDER_V << 
LCD_CAM_LCD_BYTE_ORDER_S)
+#define LCD_CAM_LCD_BYTE_ORDER_V  0x00000001
+#define LCD_CAM_LCD_BYTE_ORDER_S  22
+
+/* LCD_CAM_LCD_BIT_ORDER : R/W; bitpos: [21]; default: 0;
+ * 1: Change data bit order, change LCD_DATA_out[7:0] to LCD_DATA_out[0:7]
+ * in one byte mode, and bits[15:0] to bits[0:15] in two byte mode.  0: Not
+ * change.
+ */
+
+#define LCD_CAM_LCD_BIT_ORDER    (BIT(21))
+#define LCD_CAM_LCD_BIT_ORDER_M  (LCD_CAM_LCD_BIT_ORDER_V << 
LCD_CAM_LCD_BIT_ORDER_S)
+#define LCD_CAM_LCD_BIT_ORDER_V  0x00000001
+#define LCD_CAM_LCD_BIT_ORDER_S  21
+
+/* LCD_CAM_LCD_UPDATE_REG : R/W; bitpos: [20]; default: 0;
+ * 1: Update LCD registers, will be cleared by hardware. 0 : Not care.
+ */
+
+#define LCD_CAM_LCD_UPDATE_REG    (BIT(20))
+#define LCD_CAM_LCD_UPDATE_REG_M  (LCD_CAM_LCD_UPDATE_REG_V << 
LCD_CAM_LCD_UPDATE_REG_S)
+#define LCD_CAM_LCD_UPDATE_REG_V  0x00000001
+#define LCD_CAM_LCD_UPDATE_REG_S  20
+
+/* LCD_CAM_LCD_8BITS_ORDER : R/W; bitpos: [19]; default: 0;
+ * 1: invert every two data byte, valid in 1 byte mode. 0: Not change.
+ */
+
+#define LCD_CAM_LCD_8BITS_ORDER    (BIT(19))
+#define LCD_CAM_LCD_8BITS_ORDER_M  (LCD_CAM_LCD_8BITS_ORDER_V << 
LCD_CAM_LCD_8BITS_ORDER_S)
+#define LCD_CAM_LCD_8BITS_ORDER_V  0x00000001
+#define LCD_CAM_LCD_8BITS_ORDER_S  19
+
+/* LCD_CAM_LCD_ALWAYS_OUT_EN : R/W; bitpos: [13]; default: 0;
+ * LCD always output when LCD is in LCD_DOUT state, unless reg_lcd_start is
+ * cleared or reg_lcd_reset is set.
+ */
+
+#define LCD_CAM_LCD_ALWAYS_OUT_EN    (BIT(13))
+#define LCD_CAM_LCD_ALWAYS_OUT_EN_M  (LCD_CAM_LCD_ALWAYS_OUT_EN_V << 
LCD_CAM_LCD_ALWAYS_OUT_EN_S)
+#define LCD_CAM_LCD_ALWAYS_OUT_EN_V  0x00000001
+#define LCD_CAM_LCD_ALWAYS_OUT_EN_S  13
+
+/* LCD_CAM_LCD_DOUT_CYCLELEN : R/W; bitpos: [12:0]; default: 1;
+ * The output data cycles minus 1 of LCD module.
+ */
+
+#define LCD_CAM_LCD_DOUT_CYCLELEN    0x00001fff
+#define LCD_CAM_LCD_DOUT_CYCLELEN_M  (LCD_CAM_LCD_DOUT_CYCLELEN_V << 
LCD_CAM_LCD_DOUT_CYCLELEN_S)
+#define LCD_CAM_LCD_DOUT_CYCLELEN_V  0x00001fff
+#define LCD_CAM_LCD_DOUT_CYCLELEN_S  0
+
+/* LCD_CAM_LCD_MISC_REG register
+ * LCD configuration register
+ */
+
+#define LCD_CAM_LCD_MISC_REG (DR_REG_LCD_CAM_BASE + 0x18)
+
+/* LCD_CAM_LCD_CD_IDLE_EDGE : R/W; bitpos: [31]; default: 0;
+ * The default value of LCD_CD.
+ */
+
+#define LCD_CAM_LCD_CD_IDLE_EDGE    (BIT(31))
+#define LCD_CAM_LCD_CD_IDLE_EDGE_M  (LCD_CAM_LCD_CD_IDLE_EDGE_V << 
LCD_CAM_LCD_CD_IDLE_EDGE_S)
+#define LCD_CAM_LCD_CD_IDLE_EDGE_V  0x00000001
+#define LCD_CAM_LCD_CD_IDLE_EDGE_S  31
+
+/* LCD_CAM_LCD_CD_CMD_SET : R/W; bitpos: [30]; default: 0;
+ * 1: LCD_CD = !reg_cd_idle_edge when lcd_st[2:0] is in LCD_CMD state.  0:
+ * LCD_CD = reg_cd_idle_edge.
+ */
+
+#define LCD_CAM_LCD_CD_CMD_SET    (BIT(30))
+#define LCD_CAM_LCD_CD_CMD_SET_M  (LCD_CAM_LCD_CD_CMD_SET_V << 
LCD_CAM_LCD_CD_CMD_SET_S)
+#define LCD_CAM_LCD_CD_CMD_SET_V  0x00000001
+#define LCD_CAM_LCD_CD_CMD_SET_S  30
+
+/* LCD_CAM_LCD_CD_DUMMY_SET : R/W; bitpos: [29]; default: 0;
+ * 1: LCD_CD = !reg_cd_idle_edge when lcd_st[2:0] is in LCD_DUMMY state.  0:
+ * LCD_CD = reg_cd_idle_edge.
+ */
+
+#define LCD_CAM_LCD_CD_DUMMY_SET    (BIT(29))
+#define LCD_CAM_LCD_CD_DUMMY_SET_M  (LCD_CAM_LCD_CD_DUMMY_SET_V << 
LCD_CAM_LCD_CD_DUMMY_SET_S)
+#define LCD_CAM_LCD_CD_DUMMY_SET_V  0x00000001
+#define LCD_CAM_LCD_CD_DUMMY_SET_S  29
+
+/* LCD_CAM_LCD_CD_DATA_SET : R/W; bitpos: [28]; default: 0;
+ * 1: LCD_CD = !reg_cd_idle_edge when lcd_st[2:0] is in LCD_DOUT state.  0:
+ * LCD_CD = reg_cd_idle_edge.
+ */
+
+#define LCD_CAM_LCD_CD_DATA_SET    (BIT(28))
+#define LCD_CAM_LCD_CD_DATA_SET_M  (LCD_CAM_LCD_CD_DATA_SET_V << 
LCD_CAM_LCD_CD_DATA_SET_S)
+#define LCD_CAM_LCD_CD_DATA_SET_V  0x00000001
+#define LCD_CAM_LCD_CD_DATA_SET_S  28
+
+/* LCD_CAM_LCD_AFIFO_RESET : WO; bitpos: [27]; default: 0;
+ * LCD AFIFO reset signal.
+ */
+
+#define LCD_CAM_LCD_AFIFO_RESET    (BIT(27))
+#define LCD_CAM_LCD_AFIFO_RESET_M  (LCD_CAM_LCD_AFIFO_RESET_V << 
LCD_CAM_LCD_AFIFO_RESET_S)
+#define LCD_CAM_LCD_AFIFO_RESET_V  0x00000001
+#define LCD_CAM_LCD_AFIFO_RESET_S  27
+
+/* LCD_CAM_LCD_BK_EN : R/W; bitpos: [26]; default: 0;
+ * 1: Enable blank region when LCD sends data out. 0: No blank region.
+ */
+
+#define LCD_CAM_LCD_BK_EN    (BIT(26))
+#define LCD_CAM_LCD_BK_EN_M  (LCD_CAM_LCD_BK_EN_V << LCD_CAM_LCD_BK_EN_S)
+#define LCD_CAM_LCD_BK_EN_V  0x00000001
+#define LCD_CAM_LCD_BK_EN_S  26
+
+/* LCD_CAM_LCD_NEXT_FRAME_EN : R/W; bitpos: [25]; default: 0;
+ * 1: Send the next frame data when the current frame is sent out. 0: LCD
+ * stops when the current frame is sent out.
+ */
+
+#define LCD_CAM_LCD_NEXT_FRAME_EN    (BIT(25))
+#define LCD_CAM_LCD_NEXT_FRAME_EN_M  (LCD_CAM_LCD_NEXT_FRAME_EN_V << 
LCD_CAM_LCD_NEXT_FRAME_EN_S)
+#define LCD_CAM_LCD_NEXT_FRAME_EN_V  0x00000001
+#define LCD_CAM_LCD_NEXT_FRAME_EN_S  25
+
+/* LCD_CAM_LCD_VBK_CYCLELEN : R/W; bitpos: [24:12]; default: 0;
+ * The vertical back blank region cycle length minus 1 in LCD RGB mode, or
+ * the hold time cycle length in LCD non-RGB mode.
+ */
+
+#define LCD_CAM_LCD_VBK_CYCLELEN    0x00001fff
+#define LCD_CAM_LCD_VBK_CYCLELEN_M  (LCD_CAM_LCD_VBK_CYCLELEN_V << 
LCD_CAM_LCD_VBK_CYCLELEN_S)
+#define LCD_CAM_LCD_VBK_CYCLELEN_V  0x00001fff
+#define LCD_CAM_LCD_VBK_CYCLELEN_S  12
+
+/* LCD_CAM_LCD_VFK_CYCLELEN : R/W; bitpos: [11:6]; default: 3;
+ * The setup cycle length minus 1 in LCD non-RGB mode.
+ */
+
+#define LCD_CAM_LCD_VFK_CYCLELEN    0x0000003f
+#define LCD_CAM_LCD_VFK_CYCLELEN_M  (LCD_CAM_LCD_VFK_CYCLELEN_V << 
LCD_CAM_LCD_VFK_CYCLELEN_S)
+#define LCD_CAM_LCD_VFK_CYCLELEN_V  0x0000003f
+#define LCD_CAM_LCD_VFK_CYCLELEN_S  6
+
+/* LCD_CAM_LCD_AFIFO_THRESHOLD_NUM : R/W; bitpos: [5:1]; default: 11;
+ * The awfull threshold number of lcd_afifo.
+ */
+
+#define LCD_CAM_LCD_AFIFO_THRESHOLD_NUM    0x0000001f
+#define LCD_CAM_LCD_AFIFO_THRESHOLD_NUM_M  (LCD_CAM_LCD_AFIFO_THRESHOLD_NUM_V 
<< LCD_CAM_LCD_AFIFO_THRESHOLD_NUM_S)
+#define LCD_CAM_LCD_AFIFO_THRESHOLD_NUM_V  0x0000001f
+#define LCD_CAM_LCD_AFIFO_THRESHOLD_NUM_S  1
+
+/* LCD_CAM_LCD_CTRL_REG register
+ * LCD configuration register
+ */
+
+#define LCD_CAM_LCD_CTRL_REG (DR_REG_LCD_CAM_BASE + 0x1c)
+
+/* LCD_CAM_LCD_RGB_MODE_EN : R/W; bitpos: [31]; default: 0;
+ * 1: Enable reg mode input vsync, hsync, de. 0: Disable.
+ */
+
+#define LCD_CAM_LCD_RGB_MODE_EN    (BIT(31))
+#define LCD_CAM_LCD_RGB_MODE_EN_M  (LCD_CAM_LCD_RGB_MODE_EN_V << 
LCD_CAM_LCD_RGB_MODE_EN_S)
+#define LCD_CAM_LCD_RGB_MODE_EN_V  0x00000001
+#define LCD_CAM_LCD_RGB_MODE_EN_S  31
+
+/* LCD_CAM_LCD_VT_HEIGHT : R/W; bitpos: [30:21]; default: 0;
+ * It is the vertical total height of a frame.
+ */
+
+#define LCD_CAM_LCD_VT_HEIGHT    0x000003ff
+#define LCD_CAM_LCD_VT_HEIGHT_M  (LCD_CAM_LCD_VT_HEIGHT_V << 
LCD_CAM_LCD_VT_HEIGHT_S)
+#define LCD_CAM_LCD_VT_HEIGHT_V  0x000003ff
+#define LCD_CAM_LCD_VT_HEIGHT_S  21
+
+/* LCD_CAM_LCD_VA_HEIGHT : R/W; bitpos: [20:11]; default: 0;
+ * It is the vertical active height of a frame.
+ */
+
+#define LCD_CAM_LCD_VA_HEIGHT    0x000003ff
+#define LCD_CAM_LCD_VA_HEIGHT_M  (LCD_CAM_LCD_VA_HEIGHT_V << 
LCD_CAM_LCD_VA_HEIGHT_S)
+#define LCD_CAM_LCD_VA_HEIGHT_V  0x000003ff
+#define LCD_CAM_LCD_VA_HEIGHT_S  11
+
+/* LCD_CAM_LCD_HB_FRONT : R/W; bitpos: [10:0]; default: 0;
+ * It is the horizontal blank front porch of a frame.
+ */
+
+#define LCD_CAM_LCD_HB_FRONT    0x000007ff
+#define LCD_CAM_LCD_HB_FRONT_M  (LCD_CAM_LCD_HB_FRONT_V << 
LCD_CAM_LCD_HB_FRONT_S)
+#define LCD_CAM_LCD_HB_FRONT_V  0x000007ff
+#define LCD_CAM_LCD_HB_FRONT_S  0
+
+/* LCD_CAM_LCD_CTRL1_REG register
+ * LCD configuration register
+ */
+
+#define LCD_CAM_LCD_CTRL1_REG (DR_REG_LCD_CAM_BASE + 0x20)
+
+/* LCD_CAM_LCD_HT_WIDTH : R/W; bitpos: [31:20]; default: 0;
+ * It is the horizontal total width of a frame.
+ */
+
+#define LCD_CAM_LCD_HT_WIDTH    0x00000fff
+#define LCD_CAM_LCD_HT_WIDTH_M  (LCD_CAM_LCD_HT_WIDTH_V << 
LCD_CAM_LCD_HT_WIDTH_S)
+#define LCD_CAM_LCD_HT_WIDTH_V  0x00000fff
+#define LCD_CAM_LCD_HT_WIDTH_S  20
+
+/* LCD_CAM_LCD_HA_WIDTH : R/W; bitpos: [19:8]; default: 0;
+ * It is the horizontal active width of a frame.
+ */
+
+#define LCD_CAM_LCD_HA_WIDTH    0x00000fff
+#define LCD_CAM_LCD_HA_WIDTH_M  (LCD_CAM_LCD_HA_WIDTH_V << 
LCD_CAM_LCD_HA_WIDTH_S)
+#define LCD_CAM_LCD_HA_WIDTH_V  0x00000fff
+#define LCD_CAM_LCD_HA_WIDTH_S  8
+
+/* LCD_CAM_LCD_VB_FRONT : R/W; bitpos: [7:0]; default: 0;
+ * It is the vertical blank front porch of a frame.
+ */
+
+#define LCD_CAM_LCD_VB_FRONT    0x000000ff
+#define LCD_CAM_LCD_VB_FRONT_M  (LCD_CAM_LCD_VB_FRONT_V << 
LCD_CAM_LCD_VB_FRONT_S)
+#define LCD_CAM_LCD_VB_FRONT_V  0x000000ff
+#define LCD_CAM_LCD_VB_FRONT_S  0
+
+/* LCD_CAM_LCD_CTRL2_REG register
+ * LCD configuration register
+ */
+
+#define LCD_CAM_LCD_CTRL2_REG (DR_REG_LCD_CAM_BASE + 0x24)
+
+/* LCD_CAM_LCD_HSYNC_POSITION : R/W; bitpos: [31:24]; default: 0;
+ * It is the position of LCD_HSYNC active pulse in a line.
+ */
+
+#define LCD_CAM_LCD_HSYNC_POSITION    0x000000ff
+#define LCD_CAM_LCD_HSYNC_POSITION_M  (LCD_CAM_LCD_HSYNC_POSITION_V << 
LCD_CAM_LCD_HSYNC_POSITION_S)
+#define LCD_CAM_LCD_HSYNC_POSITION_V  0x000000ff
+#define LCD_CAM_LCD_HSYNC_POSITION_S  24
+
+/* LCD_CAM_LCD_HSYNC_IDLE_POL : R/W; bitpos: [23]; default: 0;
+ * It is the idle value of LCD_HSYNC.
+ */
+
+#define LCD_CAM_LCD_HSYNC_IDLE_POL    (BIT(23))
+#define LCD_CAM_LCD_HSYNC_IDLE_POL_M  (LCD_CAM_LCD_HSYNC_IDLE_POL_V << 
LCD_CAM_LCD_HSYNC_IDLE_POL_S)
+#define LCD_CAM_LCD_HSYNC_IDLE_POL_V  0x00000001
+#define LCD_CAM_LCD_HSYNC_IDLE_POL_S  23
+
+/* LCD_CAM_LCD_HSYNC_WIDTH : R/W; bitpos: [22:16]; default: 1;
+ * It is the position of LCD_HSYNC active pulse in a line.
+ */
+
+#define LCD_CAM_LCD_HSYNC_WIDTH    0x0000007f
+#define LCD_CAM_LCD_HSYNC_WIDTH_M  (LCD_CAM_LCD_HSYNC_WIDTH_V << 
LCD_CAM_LCD_HSYNC_WIDTH_S)
+#define LCD_CAM_LCD_HSYNC_WIDTH_V  0x0000007f
+#define LCD_CAM_LCD_HSYNC_WIDTH_S  16
+
+/* LCD_CAM_LCD_HS_BLANK_EN : R/W; bitpos: [9]; default: 0;
+ * 1: The pulse of LCD_HSYNC is out in vertical blanking lines RGB mode. 0:
+ * LCD_HSYNC pulse is valid only in active region lines in RGB mode.
+ */
+
+#define LCD_CAM_LCD_HS_BLANK_EN    (BIT(9))
+#define LCD_CAM_LCD_HS_BLANK_EN_M  (LCD_CAM_LCD_HS_BLANK_EN_V << 
LCD_CAM_LCD_HS_BLANK_EN_S)
+#define LCD_CAM_LCD_HS_BLANK_EN_V  0x00000001
+#define LCD_CAM_LCD_HS_BLANK_EN_S  9
+
+/* LCD_CAM_LCD_DE_IDLE_POL : R/W; bitpos: [8]; default: 0;
+ * It is the idle value of LCD_DE.
+ */
+
+#define LCD_CAM_LCD_DE_IDLE_POL    (BIT(8))
+#define LCD_CAM_LCD_DE_IDLE_POL_M  (LCD_CAM_LCD_DE_IDLE_POL_V << 
LCD_CAM_LCD_DE_IDLE_POL_S)
+#define LCD_CAM_LCD_DE_IDLE_POL_V  0x00000001
+#define LCD_CAM_LCD_DE_IDLE_POL_S  8
+
+/* LCD_CAM_LCD_VSYNC_IDLE_POL : R/W; bitpos: [7]; default: 0;
+ * It is the idle value of LCD_VSYNC.
+ */
+
+#define LCD_CAM_LCD_VSYNC_IDLE_POL    (BIT(7))
+#define LCD_CAM_LCD_VSYNC_IDLE_POL_M  (LCD_CAM_LCD_VSYNC_IDLE_POL_V << 
LCD_CAM_LCD_VSYNC_IDLE_POL_S)
+#define LCD_CAM_LCD_VSYNC_IDLE_POL_V  0x00000001
+#define LCD_CAM_LCD_VSYNC_IDLE_POL_S  7
+
+/* LCD_CAM_LCD_VSYNC_WIDTH : R/W; bitpos: [6:0]; default: 1;
+ * It is the position of LCD_VSYNC active pulse in a line.
+ */
+
+#define LCD_CAM_LCD_VSYNC_WIDTH    0x0000007f
+#define LCD_CAM_LCD_VSYNC_WIDTH_M  (LCD_CAM_LCD_VSYNC_WIDTH_V << 
LCD_CAM_LCD_VSYNC_WIDTH_S)
+#define LCD_CAM_LCD_VSYNC_WIDTH_V  0x0000007f
+#define LCD_CAM_LCD_VSYNC_WIDTH_S  0
+
+/* LCD_CAM_LCD_CMD_VAL_REG register
+ * LCD configuration register
+ */
+
+#define LCD_CAM_LCD_CMD_VAL_REG (DR_REG_LCD_CAM_BASE + 0x28)
+
+/* LCD_CAM_LCD_CMD_VALUE : R/W; bitpos: [31:0]; default: 0;
+ * The LCD write command value.
+ */
+
+#define LCD_CAM_LCD_CMD_VALUE    0xffffffff
+#define LCD_CAM_LCD_CMD_VALUE_M  (LCD_CAM_LCD_CMD_VALUE_V << 
LCD_CAM_LCD_CMD_VALUE_S)
+#define LCD_CAM_LCD_CMD_VALUE_V  0xffffffff
+#define LCD_CAM_LCD_CMD_VALUE_S  0
+
+/* LCD_CAM_LCD_DLY_MODE_REG register
+ * LCD configuration register
+ */
+
+#define LCD_CAM_LCD_DLY_MODE_REG (DR_REG_LCD_CAM_BASE + 0x30)
+
+/* LCD_CAM_LCD_VSYNC_MODE : R/W; bitpos: [7:6]; default: 0;
+ * The output LCD_VSYNC is delayed by module clock LCD_CLK. 0: output
+ * without delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by
+ * the negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_LCD_VSYNC_MODE    0x00000003
+#define LCD_CAM_LCD_VSYNC_MODE_M  (LCD_CAM_LCD_VSYNC_MODE_V << 
LCD_CAM_LCD_VSYNC_MODE_S)
+#define LCD_CAM_LCD_VSYNC_MODE_V  0x00000003
+#define LCD_CAM_LCD_VSYNC_MODE_S  6
+
+/* LCD_CAM_LCD_HSYNC_MODE : R/W; bitpos: [5:4]; default: 0;
+ * The output LCD_HSYNC is delayed by module clock LCD_CLK. 0: output
+ * without delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by
+ * the negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_LCD_HSYNC_MODE    0x00000003
+#define LCD_CAM_LCD_HSYNC_MODE_M  (LCD_CAM_LCD_HSYNC_MODE_V << 
LCD_CAM_LCD_HSYNC_MODE_S)
+#define LCD_CAM_LCD_HSYNC_MODE_V  0x00000003
+#define LCD_CAM_LCD_HSYNC_MODE_S  4
+
+/* LCD_CAM_LCD_DE_MODE : R/W; bitpos: [3:2]; default: 0;
+ * The output LCD_DE is delayed by module clock LCD_CLK. 0: output without
+ * delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by the
+ * negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_LCD_DE_MODE    0x00000003
+#define LCD_CAM_LCD_DE_MODE_M  (LCD_CAM_LCD_DE_MODE_V << LCD_CAM_LCD_DE_MODE_S)
+#define LCD_CAM_LCD_DE_MODE_V  0x00000003
+#define LCD_CAM_LCD_DE_MODE_S  2
+
+/* LCD_CAM_LCD_CD_MODE : R/W; bitpos: [1:0]; default: 0;
+ * The output LCD_CD is delayed by module clock LCD_CLK. 0: output without
+ * delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by the
+ * negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_LCD_CD_MODE    0x00000003
+#define LCD_CAM_LCD_CD_MODE_M  (LCD_CAM_LCD_CD_MODE_V << LCD_CAM_LCD_CD_MODE_S)
+#define LCD_CAM_LCD_CD_MODE_V  0x00000003
+#define LCD_CAM_LCD_CD_MODE_S  0
+
+/* LCD_CAM_LCD_DATA_DOUT_MODE_REG register
+ * LCD configuration register
+ */
+
+#define LCD_CAM_LCD_DATA_DOUT_MODE_REG (DR_REG_LCD_CAM_BASE + 0x38)
+
+/* LCD_CAM_DOUT15_MODE : R/W; bitpos: [31:30]; default: 0;
+ * The output data bit $n is delayed by module clock LCD_CLK. 0: output
+ * without delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by
+ * the negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_DOUT15_MODE    0x00000003
+#define LCD_CAM_DOUT15_MODE_M  (LCD_CAM_DOUT15_MODE_V << LCD_CAM_DOUT15_MODE_S)
+#define LCD_CAM_DOUT15_MODE_V  0x00000003
+#define LCD_CAM_DOUT15_MODE_S  30
+
+/* LCD_CAM_DOUT14_MODE : R/W; bitpos: [29:28]; default: 0;
+ * The output data bit $n is delayed by module clock LCD_CLK. 0: output
+ * without delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by
+ * the negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_DOUT14_MODE    0x00000003
+#define LCD_CAM_DOUT14_MODE_M  (LCD_CAM_DOUT14_MODE_V << LCD_CAM_DOUT14_MODE_S)
+#define LCD_CAM_DOUT14_MODE_V  0x00000003
+#define LCD_CAM_DOUT14_MODE_S  28
+
+/* LCD_CAM_DOUT13_MODE : R/W; bitpos: [27:26]; default: 0;
+ * The output data bit $n is delayed by module clock LCD_CLK. 0: output
+ * without delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by
+ * the negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_DOUT13_MODE    0x00000003
+#define LCD_CAM_DOUT13_MODE_M  (LCD_CAM_DOUT13_MODE_V << LCD_CAM_DOUT13_MODE_S)
+#define LCD_CAM_DOUT13_MODE_V  0x00000003
+#define LCD_CAM_DOUT13_MODE_S  26
+
+/* LCD_CAM_DOUT12_MODE : R/W; bitpos: [25:24]; default: 0;
+ * The output data bit $n is delayed by module clock LCD_CLK. 0: output
+ * without delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by
+ * the negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_DOUT12_MODE    0x00000003
+#define LCD_CAM_DOUT12_MODE_M  (LCD_CAM_DOUT12_MODE_V << LCD_CAM_DOUT12_MODE_S)
+#define LCD_CAM_DOUT12_MODE_V  0x00000003
+#define LCD_CAM_DOUT12_MODE_S  24
+
+/* LCD_CAM_DOUT11_MODE : R/W; bitpos: [23:22]; default: 0;
+ * The output data bit $n is delayed by module clock LCD_CLK. 0: output
+ * without delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by
+ * the negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_DOUT11_MODE    0x00000003
+#define LCD_CAM_DOUT11_MODE_M  (LCD_CAM_DOUT11_MODE_V << LCD_CAM_DOUT11_MODE_S)
+#define LCD_CAM_DOUT11_MODE_V  0x00000003
+#define LCD_CAM_DOUT11_MODE_S  22
+
+/* LCD_CAM_DOUT10_MODE : R/W; bitpos: [21:20]; default: 0;
+ * The output data bit $n is delayed by module clock LCD_CLK. 0: output
+ * without delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by
+ * the negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_DOUT10_MODE    0x00000003
+#define LCD_CAM_DOUT10_MODE_M  (LCD_CAM_DOUT10_MODE_V << LCD_CAM_DOUT10_MODE_S)
+#define LCD_CAM_DOUT10_MODE_V  0x00000003
+#define LCD_CAM_DOUT10_MODE_S  20
+
+/* LCD_CAM_DOUT9_MODE : R/W; bitpos: [19:18]; default: 0;
+ * The output data bit $n is delayed by module clock LCD_CLK. 0: output
+ * without delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by
+ * the negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_DOUT9_MODE    0x00000003
+#define LCD_CAM_DOUT9_MODE_M  (LCD_CAM_DOUT9_MODE_V << LCD_CAM_DOUT9_MODE_S)
+#define LCD_CAM_DOUT9_MODE_V  0x00000003
+#define LCD_CAM_DOUT9_MODE_S  18
+
+/* LCD_CAM_DOUT8_MODE : R/W; bitpos: [17:16]; default: 0;
+ * The output data bit $n is delayed by module clock LCD_CLK. 0: output
+ * without delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by
+ * the negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_DOUT8_MODE    0x00000003
+#define LCD_CAM_DOUT8_MODE_M  (LCD_CAM_DOUT8_MODE_V << LCD_CAM_DOUT8_MODE_S)
+#define LCD_CAM_DOUT8_MODE_V  0x00000003
+#define LCD_CAM_DOUT8_MODE_S  16
+
+/* LCD_CAM_DOUT7_MODE : R/W; bitpos: [15:14]; default: 0;
+ * The output data bit $n is delayed by module clock LCD_CLK. 0: output
+ * without delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by
+ * the negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_DOUT7_MODE    0x00000003
+#define LCD_CAM_DOUT7_MODE_M  (LCD_CAM_DOUT7_MODE_V << LCD_CAM_DOUT7_MODE_S)
+#define LCD_CAM_DOUT7_MODE_V  0x00000003
+#define LCD_CAM_DOUT7_MODE_S  14
+
+/* LCD_CAM_DOUT6_MODE : R/W; bitpos: [13:12]; default: 0;
+ * The output data bit $n is delayed by module clock LCD_CLK. 0: output
+ * without delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by
+ * the negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_DOUT6_MODE    0x00000003
+#define LCD_CAM_DOUT6_MODE_M  (LCD_CAM_DOUT6_MODE_V << LCD_CAM_DOUT6_MODE_S)
+#define LCD_CAM_DOUT6_MODE_V  0x00000003
+#define LCD_CAM_DOUT6_MODE_S  12
+
+/* LCD_CAM_DOUT5_MODE : R/W; bitpos: [11:10]; default: 0;
+ * The output data bit $n is delayed by module clock LCD_CLK. 0: output
+ * without delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by
+ * the negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_DOUT5_MODE    0x00000003
+#define LCD_CAM_DOUT5_MODE_M  (LCD_CAM_DOUT5_MODE_V << LCD_CAM_DOUT5_MODE_S)
+#define LCD_CAM_DOUT5_MODE_V  0x00000003
+#define LCD_CAM_DOUT5_MODE_S  10
+
+/* LCD_CAM_DOUT4_MODE : R/W; bitpos: [9:8]; default: 0;
+ * The output data bit $n is delayed by module clock LCD_CLK. 0: output
+ * without delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by
+ * the negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_DOUT4_MODE    0x00000003
+#define LCD_CAM_DOUT4_MODE_M  (LCD_CAM_DOUT4_MODE_V << LCD_CAM_DOUT4_MODE_S)
+#define LCD_CAM_DOUT4_MODE_V  0x00000003
+#define LCD_CAM_DOUT4_MODE_S  8
+
+/* LCD_CAM_DOUT3_MODE : R/W; bitpos: [7:6]; default: 0;
+ * The output data bit $n is delayed by module clock LCD_CLK. 0: output
+ * without delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by
+ * the negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_DOUT3_MODE    0x00000003
+#define LCD_CAM_DOUT3_MODE_M  (LCD_CAM_DOUT3_MODE_V << LCD_CAM_DOUT3_MODE_S)
+#define LCD_CAM_DOUT3_MODE_V  0x00000003
+#define LCD_CAM_DOUT3_MODE_S  6
+
+/* LCD_CAM_DOUT2_MODE : R/W; bitpos: [5:4]; default: 0;
+ * The output data bit $n is delayed by module clock LCD_CLK. 0: output
+ * without delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by
+ * the negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_DOUT2_MODE    0x00000003
+#define LCD_CAM_DOUT2_MODE_M  (LCD_CAM_DOUT2_MODE_V << LCD_CAM_DOUT2_MODE_S)
+#define LCD_CAM_DOUT2_MODE_V  0x00000003
+#define LCD_CAM_DOUT2_MODE_S  4
+
+/* LCD_CAM_DOUT1_MODE : R/W; bitpos: [3:2]; default: 0;
+ * The output data bit $n is delayed by module clock LCD_CLK. 0: output
+ * without delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by
+ * the negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_DOUT1_MODE    0x00000003
+#define LCD_CAM_DOUT1_MODE_M  (LCD_CAM_DOUT1_MODE_V << LCD_CAM_DOUT1_MODE_S)
+#define LCD_CAM_DOUT1_MODE_V  0x00000003
+#define LCD_CAM_DOUT1_MODE_S  2
+
+/* LCD_CAM_DOUT0_MODE : R/W; bitpos: [1:0]; default: 0;
+ * The output data bit $n is delayed by module clock LCD_CLK. 0: output
+ * without delayed. 1: delay by the positive edge of LCD_CLK. 2: delay by
+ * the negative edge of LCD_CLK.
+ */
+
+#define LCD_CAM_DOUT0_MODE    0x00000003
+#define LCD_CAM_DOUT0_MODE_M  (LCD_CAM_DOUT0_MODE_V << LCD_CAM_DOUT0_MODE_S)
+#define LCD_CAM_DOUT0_MODE_V  0x00000003
+#define LCD_CAM_DOUT0_MODE_S  0
+
+/* LCD_CAM_LC_DMA_INT_ENA_REG register
+ * LCD_camera DMA inturrupt enable register
+ */
+
+#define LCD_CAM_LC_DMA_INT_ENA_REG (DR_REG_LCD_CAM_BASE + 0x64)
+
+/* LCD_CAM_CAM_HS_INT_ENA : R/W; bitpos: [3]; default: 0;
+ * The enable bit for Camera line interrupt.
+ */
+
+#define LCD_CAM_CAM_HS_INT_ENA    (BIT(3))
+#define LCD_CAM_CAM_HS_INT_ENA_M  (LCD_CAM_CAM_HS_INT_ENA_V << 
LCD_CAM_CAM_HS_INT_ENA_S)
+#define LCD_CAM_CAM_HS_INT_ENA_V  0x00000001
+#define LCD_CAM_CAM_HS_INT_ENA_S  3
+
+/* LCD_CAM_CAM_VSYNC_INT_ENA : R/W; bitpos: [2]; default: 0;
+ * The enable bit for Camera frame end interrupt.
+ */
+
+#define LCD_CAM_CAM_VSYNC_INT_ENA    (BIT(2))
+#define LCD_CAM_CAM_VSYNC_INT_ENA_M  (LCD_CAM_CAM_VSYNC_INT_ENA_V << 
LCD_CAM_CAM_VSYNC_INT_ENA_S)
+#define LCD_CAM_CAM_VSYNC_INT_ENA_V  0x00000001
+#define LCD_CAM_CAM_VSYNC_INT_ENA_S  2
+
+/* LCD_CAM_LCD_TRANS_DONE_INT_ENA : R/W; bitpos: [1]; default: 0;
+ * The enable bit for lcd transfer end interrupt.
+ */
+
+#define LCD_CAM_LCD_TRANS_DONE_INT_ENA    (BIT(1))
+#define LCD_CAM_LCD_TRANS_DONE_INT_ENA_M  (LCD_CAM_LCD_TRANS_DONE_INT_ENA_V << 
LCD_CAM_LCD_TRANS_DONE_INT_ENA_S)
+#define LCD_CAM_LCD_TRANS_DONE_INT_ENA_V  0x00000001
+#define LCD_CAM_LCD_TRANS_DONE_INT_ENA_S  1
+
+/* LCD_CAM_LCD_VSYNC_INT_ENA : R/W; bitpos: [0]; default: 0;
+ * The enable bit for LCD frame end interrupt.
+ */
+
+#define LCD_CAM_LCD_VSYNC_INT_ENA    (BIT(0))
+#define LCD_CAM_LCD_VSYNC_INT_ENA_M  (LCD_CAM_LCD_VSYNC_INT_ENA_V << 
LCD_CAM_LCD_VSYNC_INT_ENA_S)
+#define LCD_CAM_LCD_VSYNC_INT_ENA_V  0x00000001
+#define LCD_CAM_LCD_VSYNC_INT_ENA_S  0
+
+/* LCD_CAM_LC_DMA_INT_RAW_REG register
+ * LCD_camera DMA raw inturrupt status register
+ */
+
+#define LCD_CAM_LC_DMA_INT_RAW_REG (DR_REG_LCD_CAM_BASE + 0x68)
+
+/* LCD_CAM_CAM_HS_INT_RAW : RO; bitpos: [3]; default: 0;
+ * The raw bit for Camera line interrupt.
+ */
+
+#define LCD_CAM_CAM_HS_INT_RAW    (BIT(3))
+#define LCD_CAM_CAM_HS_INT_RAW_M  (LCD_CAM_CAM_HS_INT_RAW_V << 
LCD_CAM_CAM_HS_INT_RAW_S)
+#define LCD_CAM_CAM_HS_INT_RAW_V  0x00000001
+#define LCD_CAM_CAM_HS_INT_RAW_S  3
+
+/* LCD_CAM_CAM_VSYNC_INT_RAW : RO; bitpos: [2]; default: 0;
+ * The raw bit for Camera frame end interrupt.
+ */
+
+#define LCD_CAM_CAM_VSYNC_INT_RAW    (BIT(2))
+#define LCD_CAM_CAM_VSYNC_INT_RAW_M  (LCD_CAM_CAM_VSYNC_INT_RAW_V << 
LCD_CAM_CAM_VSYNC_INT_RAW_S)
+#define LCD_CAM_CAM_VSYNC_INT_RAW_V  0x00000001
+#define LCD_CAM_CAM_VSYNC_INT_RAW_S  2
+
+/* LCD_CAM_LCD_TRANS_DONE_INT_RAW : RO; bitpos: [1]; default: 0;
+ * The raw bit for lcd transfer end interrupt.
+ */
+
+#define LCD_CAM_LCD_TRANS_DONE_INT_RAW    (BIT(1))
+#define LCD_CAM_LCD_TRANS_DONE_INT_RAW_M  (LCD_CAM_LCD_TRANS_DONE_INT_RAW_V << 
LCD_CAM_LCD_TRANS_DONE_INT_RAW_S)
+#define LCD_CAM_LCD_TRANS_DONE_INT_RAW_V  0x00000001
+#define LCD_CAM_LCD_TRANS_DONE_INT_RAW_S  1
+
+/* LCD_CAM_LCD_VSYNC_INT_RAW : RO; bitpos: [0]; default: 0;
+ * The raw bit for LCD frame end interrupt.
+ */
+
+#define LCD_CAM_LCD_VSYNC_INT_RAW    (BIT(0))
+#define LCD_CAM_LCD_VSYNC_INT_RAW_M  (LCD_CAM_LCD_VSYNC_INT_RAW_V << 
LCD_CAM_LCD_VSYNC_INT_RAW_S)
+#define LCD_CAM_LCD_VSYNC_INT_RAW_V  0x00000001
+#define LCD_CAM_LCD_VSYNC_INT_RAW_S  0
+
+/* LCD_CAM_LC_DMA_INT_ST_REG register
+ * LCD_camera DMA masked inturrupt status register
+ */
+
+#define LCD_CAM_LC_DMA_INT_ST_REG (DR_REG_LCD_CAM_BASE + 0x6c)
+
+/* LCD_CAM_CAM_HS_INT_ST : RO; bitpos: [3]; default: 0;
+ * The status bit for Camera transfer end interrupt.
+ */
+
+#define LCD_CAM_CAM_HS_INT_ST    (BIT(3))
+#define LCD_CAM_CAM_HS_INT_ST_M  (LCD_CAM_CAM_HS_INT_ST_V << 
LCD_CAM_CAM_HS_INT_ST_S)
+#define LCD_CAM_CAM_HS_INT_ST_V  0x00000001
+#define LCD_CAM_CAM_HS_INT_ST_S  3
+
+/* LCD_CAM_CAM_VSYNC_INT_ST : RO; bitpos: [2]; default: 0;
+ * The status bit for Camera frame end interrupt.
+ */
+
+#define LCD_CAM_CAM_VSYNC_INT_ST    (BIT(2))
+#define LCD_CAM_CAM_VSYNC_INT_ST_M  (LCD_CAM_CAM_VSYNC_INT_ST_V << 
LCD_CAM_CAM_VSYNC_INT_ST_S)
+#define LCD_CAM_CAM_VSYNC_INT_ST_V  0x00000001
+#define LCD_CAM_CAM_VSYNC_INT_ST_S  2
+
+/* LCD_CAM_LCD_TRANS_DONE_INT_ST : RO; bitpos: [1]; default: 0;
+ * The status bit for lcd transfer end interrupt.
+ */
+
+#define LCD_CAM_LCD_TRANS_DONE_INT_ST    (BIT(1))
+#define LCD_CAM_LCD_TRANS_DONE_INT_ST_M  (LCD_CAM_LCD_TRANS_DONE_INT_ST_V << 
LCD_CAM_LCD_TRANS_DONE_INT_ST_S)
+#define LCD_CAM_LCD_TRANS_DONE_INT_ST_V  0x00000001
+#define LCD_CAM_LCD_TRANS_DONE_INT_ST_S  1
+
+/* LCD_CAM_LCD_VSYNC_INT_ST : RO; bitpos: [0]; default: 0;
+ * The status bit for LCD frame end interrupt.
+ */
+
+#define LCD_CAM_LCD_VSYNC_INT_ST    (BIT(0))
+#define LCD_CAM_LCD_VSYNC_INT_ST_M  (LCD_CAM_LCD_VSYNC_INT_ST_V << 
LCD_CAM_LCD_VSYNC_INT_ST_S)
+#define LCD_CAM_LCD_VSYNC_INT_ST_V  0x00000001
+#define LCD_CAM_LCD_VSYNC_INT_ST_S  0
+
+/* LCD_CAM_LC_DMA_INT_CLR_REG register
+ * LCD_camera DMA inturrupt clear register
+ */
+
+#define LCD_CAM_LC_DMA_INT_CLR_REG (DR_REG_LCD_CAM_BASE + 0x70)
+
+/* LCD_CAM_CAM_HS_INT_CLR : WO; bitpos: [3]; default: 0;
+ * The clear bit for Camera line interrupt.
+ */
+
+#define LCD_CAM_CAM_HS_INT_CLR    (BIT(3))
+#define LCD_CAM_CAM_HS_INT_CLR_M  (LCD_CAM_CAM_HS_INT_CLR_V << 
LCD_CAM_CAM_HS_INT_CLR_S)
+#define LCD_CAM_CAM_HS_INT_CLR_V  0x00000001
+#define LCD_CAM_CAM_HS_INT_CLR_S  3
+
+/* LCD_CAM_CAM_VSYNC_INT_CLR : WO; bitpos: [2]; default: 0;
+ * The clear bit for Camera frame end interrupt.
+ */
+
+#define LCD_CAM_CAM_VSYNC_INT_CLR    (BIT(2))
+#define LCD_CAM_CAM_VSYNC_INT_CLR_M  (LCD_CAM_CAM_VSYNC_INT_CLR_V << 
LCD_CAM_CAM_VSYNC_INT_CLR_S)
+#define LCD_CAM_CAM_VSYNC_INT_CLR_V  0x00000001
+#define LCD_CAM_CAM_VSYNC_INT_CLR_S  2
+
+/* LCD_CAM_LCD_TRANS_DONE_INT_CLR : WO; bitpos: [1]; default: 0;
+ * The clear bit for lcd transfer end interrupt.
+ */
+
+#define LCD_CAM_LCD_TRANS_DONE_INT_CLR    (BIT(1))
+#define LCD_CAM_LCD_TRANS_DONE_INT_CLR_M  (LCD_CAM_LCD_TRANS_DONE_INT_CLR_V << 
LCD_CAM_LCD_TRANS_DONE_INT_CLR_S)
+#define LCD_CAM_LCD_TRANS_DONE_INT_CLR_V  0x00000001
+#define LCD_CAM_LCD_TRANS_DONE_INT_CLR_S  1
+
+/* LCD_CAM_LCD_VSYNC_INT_CLR : WO; bitpos: [0]; default: 0;
+ * The clear bit for LCD frame end interrupt.
+ */
+
+#define LCD_CAM_LCD_VSYNC_INT_CLR    (BIT(0))
+#define LCD_CAM_LCD_VSYNC_INT_CLR_M  (LCD_CAM_LCD_VSYNC_INT_CLR_V << 
LCD_CAM_LCD_VSYNC_INT_CLR_S)
+#define LCD_CAM_LCD_VSYNC_INT_CLR_V  0x00000001
+#define LCD_CAM_LCD_VSYNC_INT_CLR_S  0
+
+/* LCD_CAM_LC_REG_DATE_REG register
+ * Version register
+ */
+
+#define LCD_CAM_LC_REG_DATE_REG (DR_REG_LCD_CAM_BASE + 0xfc)
+
+/* LCD_CAM_LC_DATE : R/W; bitpos: [27:0]; default: 33566752;
+ * LCD_CAM version control register
+ */
+
+#define LCD_CAM_LC_DATE    0x0fffffff
+#define LCD_CAM_LC_DATE_M  (LCD_CAM_LC_DATE_V << LCD_CAM_LC_DATE_S)
+#define LCD_CAM_LC_DATE_V  0x0fffffff
+#define LCD_CAM_LC_DATE_S  0
+
+#endif /* __ARCH_XTENSA_SRC_ESP32S3_HARDWARE_ESP32S3_LCD_CAM_H */
diff --git a/boards/xtensa/esp32s3/common/Kconfig 
b/boards/xtensa/esp32s3/common/Kconfig
index d22831a996..97c7c69bd0 100644
--- a/boards/xtensa/esp32s3/common/Kconfig
+++ b/boards/xtensa/esp32s3/common/Kconfig
@@ -11,3 +11,14 @@ config ESP32S3_MERGE_BINS
                device.
                This is only useful when the path to binary files (e.g. 
bootloader)
                is provided via the ESPTOOL_BINDIR variable.
+
+config ESP32S3_SPEED_UP_ISR
+       bool "Speed up ISR"
+       default n
+       ---help---
+               Move ESP32-S3's interrupt, OS timer tick, and scheduler 
functions
+               from Flash to IRAM. This can speed up interrupt service 
processing
+               and also reduce reading data from Flash.
+
+               If you run applications that need continue reading data from 
PSRAM,
+               such as LCD display, please select this option.
diff --git a/boards/xtensa/esp32s3/common/scripts/esp32s3_aliases.ld 
b/boards/xtensa/esp32s3/common/scripts/esp32s3_aliases.ld
index fa3c4e8118..26a937e2d9 100644
--- a/boards/xtensa/esp32s3/common/scripts/esp32s3_aliases.ld
+++ b/boards/xtensa/esp32s3/common/scripts/esp32s3_aliases.ld
@@ -27,3 +27,5 @@
   api_vhci_host_send_packet = API_vhci_host_send_packet;
   api_vhci_host_register_callback = API_vhci_host_register_callback;
 #endif
+
+PROVIDE( cache_writeback_addr = Cache_WriteBack_Addr );
\ No newline at end of file
diff --git a/boards/xtensa/esp32s3/common/scripts/legacy_sections.ld 
b/boards/xtensa/esp32s3/common/scripts/legacy_sections.ld
index e565c9b1fe..8745dc1595 100644
--- a/boards/xtensa/esp32s3/common/scripts/legacy_sections.ld
+++ b/boards/xtensa/esp32s3/common/scripts/legacy_sections.ld
@@ -88,6 +88,31 @@ SECTIONS
     *libsched.a:sched_thistask.*(.literal .text .literal.* .text.*)
     *libsched.a:spinlock.*(.literal .text .literal.* .text.*)
 
+#ifdef CONFIG_ESP32S3_SPEED_UP_ISR
+    *libarch.a:xtensa_irqdispatch.*(.literal.xtensa_irq_dispatch 
.text.xtensa_irq_dispatch)
+    *libarch.a:xtensa_switchcontext.*(.literal.up_switch_context 
.text.up_switch_context)
+    *libarch.a:xtensa_modifyreg32.*(.literal.modifyreg32 .text.modifyreg32)
+
+    *libarch.a:esp32s3_irq.*(.literal.xtensa_int_decode 
.text.xtensa_int_decode)
+    *libarch.a:esp32s3_timerisr.*(.literal.systimer_isr .text.systimer_isr)
+    *libarch.a:esp32s3_idle.*(.literal.up_idle .text.up_idle)
+    *libarch.a:esp32s3_dma.*(.literal.esp32s3_dma_load .text.esp32s3_dma_load \
+                             .literal.esp32s3_dma_enable 
.text.esp32s3_dma_enable)
+
+    *libsched.a:sched_processtimer.*(.literal.nxsched_process_timer 
.text.nxsched_process_timer)
+    *libsched.a:clock_initialize.*(.literal.clock_timer .text.clock_timer)
+    *libsched.a:wd_start.*(.literal.wd_timer .text.wd_timer)
+    *libsched.a:sched_roundrobin.*(.literal.nxsched_process_roundrobin 
.text.nxsched_process_roundrobin)
+    *libsched.a:sched_reprioritizertr.*(.literal.nxsched_reprioritize_rtr 
.text.nxsched_reprioritize_rtr)
+    *libsched.a:sched_removereadytorun.*(.literal.nxsched_remove_readytorun 
.text.nxsched_remove_readytorun)
+    *libsched.a:sched_addreadytorun.*(.literal.nxsched_add_readytorun 
.text.nxsched_add_readytorun)
+    *libsched.a:sched_addprioritized.*(.literal.nxsched_add_prioritized 
.text.nxsched_add_prioritized)
+    *libsched.a:sched_mergepending.*(.literal.nxsched_merge_pending 
.text.nxsched_merge_pending)
+    *libsched.a:sched_resumescheduler.*(.literal.nxsched_resume_scheduler 
.text.nxsched_resume_scheduler)
+
+    *libc.a:bin/sq_remfirst.*(.literal.sq_remfirst .text.sq_remfirst)
+#endif
+
     *(.wifirxiram .wifirxiram.*)
     *(.wifi0iram  .wifi0iram.*)
     *(.wifiorslpiram .wifiorslpiram.*)
diff --git a/boards/xtensa/esp32s3/esp32s3-lcd-ev/Kconfig 
b/boards/xtensa/esp32s3/esp32s3-lcd-ev/Kconfig
index 015a5a087f..01a4b2e000 100644
--- a/boards/xtensa/esp32s3/esp32s3-lcd-ev/Kconfig
+++ b/boards/xtensa/esp32s3/esp32s3-lcd-ev/Kconfig
@@ -49,4 +49,30 @@ config ESP32S3_SPIFLASH_LITTLEFS
 
 endchoice # ESP32S3_SPIFLASH_FS
 
+config ESP32S3_BOARD_I2C
+       bool
+       default y if ESP32S3_I2C0 || ESP32S3_I2C1
+
+config ESP32S3_BOARD_IOEXPANDER
+       bool "Enable Board IO Expander"
+       default n
+       depends on ESP32S3_BOARD_I2C
+       ---help---
+               Enable board IO expander support, IC is TC9554. 
+
+config ESP32S3_BOARD_LCD
+       bool "Enable Board LCD"
+       default n
+       depends on ESP32S3_LCD
+       select ESP32S3_BOARD_IOEXPANDER
+       ---help---
+               Enable board LCD support, IC is GC9503CV. 
+
+config ESP32S3_BOARD_TOUCHPAD
+       bool "Enable Board Touchpad"
+       default n
+       depends on ESP32S3_BOARD_I2C
+       ---help---
+               Enable board touchpad support, IC is FT5X06. 
+
 endif # ARCH_BOARD_ESP32S3_LCD_EV
diff --git a/boards/xtensa/esp32s3/esp32s3-lcd-ev/configs/lcd/defconfig 
b/boards/xtensa/esp32s3/esp32s3-lcd-ev/configs/lcd/defconfig
new file mode 100644
index 0000000000..f3e5bd4731
--- /dev/null
+++ b/boards/xtensa/esp32s3/esp32s3-lcd-ev/configs/lcd/defconfig
@@ -0,0 +1,63 @@
+#
+# This file is autogenerated: PLEASE DO NOT EDIT IT.
+#
+# You can use "make menuconfig" to make any modifications to the installed 
.config file.
+# You can then do "make savedefconfig" to generate a new defconfig file that 
includes your
+# modifications.
+#
+# CONFIG_ARCH_LEDS is not set
+# CONFIG_NSH_ARGCAT is not set
+# CONFIG_NSH_CMDOPT_HEXDUMP is not set
+CONFIG_ARCH="xtensa"
+CONFIG_ARCH_BOARD="esp32s3-lcd-ev"
+CONFIG_ARCH_BOARD_COMMON=y
+CONFIG_ARCH_BOARD_ESP32S3_LCD_EV=y
+CONFIG_ARCH_CHIP="esp32s3"
+CONFIG_ARCH_CHIP_ESP32S3=y
+CONFIG_ARCH_CHIP_ESP32S3WROOM2=y
+CONFIG_ARCH_INTERRUPTSTACK=2048
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_ARCH_XTENSA=y
+CONFIG_BOARD_LOOPSPERMSEC=16717
+CONFIG_BUILTIN=y
+CONFIG_DEBUG_ASSERTIONS=y
+CONFIG_DEBUG_ASSERTIONS_EXPRESSION=y
+CONFIG_DEBUG_FEATURES=y
+CONFIG_ESP32S3_BOARD_LCD=y
+CONFIG_ESP32S3_DMA=y
+CONFIG_ESP32S3_I2C0=y
+CONFIG_ESP32S3_I2C0_SCLPIN=18
+CONFIG_ESP32S3_I2C0_SDAPIN=8
+CONFIG_ESP32S3_LCD=y
+CONFIG_ESP32S3_LCD_CLOCK_MHZ=3
+CONFIG_ESP32S3_SPEED_UP_ISR=y
+CONFIG_ESP32S3_SPIRAM=y
+CONFIG_ESP32S3_SPIRAM_MODE_OCT=y
+CONFIG_ESP32S3_SPIRAM_SPEED_80M=y
+CONFIG_ESP32S3_UART0=y
+CONFIG_EXAMPLES_FB=y
+CONFIG_FS_PROCFS=y
+CONFIG_HAVE_CXX=y
+CONFIG_HAVE_CXXINITIALIZE=y
+CONFIG_IDLETHREAD_STACKSIZE=3072
+CONFIG_INIT_ENTRYPOINT="nsh_main"
+CONFIG_INIT_STACKSIZE=3072
+CONFIG_INTELHEX_BINARY=y
+CONFIG_MM_REGIONS=2
+CONFIG_NDEBUG=y
+CONFIG_NSH_ARCHINIT=y
+CONFIG_NSH_BUILTIN_APPS=y
+CONFIG_NSH_FILEIOSIZE=512
+CONFIG_NSH_LINELEN=64
+CONFIG_NSH_READLINE=y
+CONFIG_PREALLOC_TIMERS=4
+CONFIG_RAM_SIZE=114688
+CONFIG_RAM_START=0x20000000
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_WAITPID=y
+CONFIG_START_DAY=6
+CONFIG_START_MONTH=12
+CONFIG_START_YEAR=2011
+CONFIG_SYSLOG_BUFFER=y
+CONFIG_SYSTEM_NSH=y
+CONFIG_UART0_SERIAL_CONSOLE=y
diff --git a/boards/xtensa/esp32s3/esp32s3-lcd-ev/configs/lvgl/defconfig 
b/boards/xtensa/esp32s3/esp32s3-lcd-ev/configs/lvgl/defconfig
new file mode 100644
index 0000000000..d23d82c408
--- /dev/null
+++ b/boards/xtensa/esp32s3/esp32s3-lcd-ev/configs/lvgl/defconfig
@@ -0,0 +1,78 @@
+#
+# This file is autogenerated: PLEASE DO NOT EDIT IT.
+#
+# You can use "make menuconfig" to make any modifications to the installed 
.config file.
+# You can then do "make savedefconfig" to generate a new defconfig file that 
includes your
+# modifications.
+#
+# CONFIG_ARCH_LEDS is not set
+# CONFIG_NSH_ARGCAT is not set
+# CONFIG_NSH_CMDOPT_HEXDUMP is not set
+CONFIG_ARCH="xtensa"
+CONFIG_ARCH_BOARD="esp32s3-lcd-ev"
+CONFIG_ARCH_BOARD_COMMON=y
+CONFIG_ARCH_BOARD_ESP32S3_LCD_EV=y
+CONFIG_ARCH_CHIP="esp32s3"
+CONFIG_ARCH_CHIP_ESP32S3=y
+CONFIG_ARCH_CHIP_ESP32S3WROOM2=y
+CONFIG_ARCH_INTERRUPTSTACK=2048
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_ARCH_XTENSA=y
+CONFIG_BOARD_LOOPSPERMSEC=16717
+CONFIG_BUILTIN=y
+CONFIG_DEBUG_ASSERTIONS=y
+CONFIG_DEBUG_ASSERTIONS_EXPRESSION=y
+CONFIG_DEBUG_FEATURES=y
+CONFIG_ESP32S3_BOARD_LCD=y
+CONFIG_ESP32S3_BOARD_TOUCHPAD=y
+CONFIG_ESP32S3_DMA=y
+CONFIG_ESP32S3_I2C0=y
+CONFIG_ESP32S3_I2C0_SCLPIN=18
+CONFIG_ESP32S3_I2C0_SDAPIN=8
+CONFIG_ESP32S3_LCD=y
+CONFIG_ESP32S3_LCD_CLOCK_MHZ=3
+CONFIG_ESP32S3_SPEED_UP_ISR=y
+CONFIG_ESP32S3_SPIRAM=y
+CONFIG_ESP32S3_SPIRAM_MODE_OCT=y
+CONFIG_ESP32S3_SPIRAM_SPEED_80M=y
+CONFIG_ESP32S3_UART0=y
+CONFIG_EXAMPLES_LVGLDEMO=y
+CONFIG_FS_PROCFS=y
+CONFIG_FT5X06_POLLMODE=y
+CONFIG_FT5X06_SINGLEPOINT=y
+CONFIG_GRAPHICS_LVGL=y
+CONFIG_HAVE_CXX=y
+CONFIG_HAVE_CXXINITIALIZE=y
+CONFIG_IDLETHREAD_STACKSIZE=3072
+CONFIG_INIT_ENTRYPOINT="nsh_main"
+CONFIG_INIT_STACKSIZE=3072
+CONFIG_INPUT=y
+CONFIG_INPUT_FT5X06=y
+CONFIG_INTELHEX_BINARY=y
+CONFIG_LV_FONT_MONTSERRAT_20=y
+CONFIG_LV_MEMCPY_MEMSET_STD=y
+CONFIG_LV_MEM_CUSTOM=y
+CONFIG_LV_PORT_USE_FBDEV=y
+CONFIG_LV_PORT_USE_TOUCHPAD=y
+CONFIG_LV_TICK_CUSTOM=y
+CONFIG_LV_TICK_CUSTOM_INCLUDE="port/lv_port_tick.h"
+CONFIG_LV_USE_DEMO_WIDGETS=y
+CONFIG_MM_REGIONS=2
+CONFIG_NDEBUG=y
+CONFIG_NSH_ARCHINIT=y
+CONFIG_NSH_BUILTIN_APPS=y
+CONFIG_NSH_FILEIOSIZE=512
+CONFIG_NSH_LINELEN=64
+CONFIG_NSH_READLINE=y
+CONFIG_PREALLOC_TIMERS=4
+CONFIG_RAM_SIZE=114688
+CONFIG_RAM_START=0x20000000
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_LPWORK=y
+CONFIG_SCHED_WAITPID=y
+CONFIG_START_DAY=6
+CONFIG_START_MONTH=12
+CONFIG_START_YEAR=2011
+CONFIG_SYSLOG_BUFFER=y
+CONFIG_SYSTEM_NSH=y
+CONFIG_UART0_SERIAL_CONSOLE=y
diff --git a/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/Make.defs 
b/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/Make.defs
index 586a3324e1..a1dcc41aed 100644
--- a/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/Make.defs
+++ b/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/Make.defs
@@ -41,6 +41,18 @@ ifeq ($(CONFIG_WS2812),y)
 CSRCS += esp32s3_ws2812.c
 endif
 
+ifeq ($(CONFIG_ESP32S3_BOARD_IOEXPANDER),y)
+CSRCS += esp32s3_ioexpander.c
+endif
+
+ifeq ($(CONFIG_ESP32S3_BOARD_LCD),y)
+CSRCS += esp32s3_lcd.c
+endif
+
+ifeq ($(CONFIG_ESP32S3_BOARD_TOUCHPAD),y)
+CSRCS += esp32s3_touchscreen.c
+endif
+
 DEPPATH += --dep-path board
 VPATH += :board
 CFLAGS += 
${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)board
diff --git a/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3-lcd-ev.h 
b/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3-lcd-ev.h
index 138cd63211..cbef32d288 100644
--- a/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3-lcd-ev.h
+++ b/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3-lcd-ev.h
@@ -39,6 +39,10 @@
 
 #define BUTTON_BOOT         0
 
+/* I2C Port */
+
+#define I2C_PORT            0
+
 /****************************************************************************
  * Public Types
  ****************************************************************************/
@@ -94,5 +98,99 @@ int board_spiflash_init(void);
 int board_ws2812_initialize(int devno, int spino, uint16_t nleds);
 #endif
 
+/****************************************************************************
+ * Name: board_lcd_initialize
+ *
+ * Description:
+ *   Initialize LCD.
+ *
+ * Input Parameters:
+ *   None.
+ *
+ * Returned Value:
+ *   Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_ESP32S3_LCD) && defined(CONFIG_ESP32S3_BOARD_IOEXPANDER)
+int board_lcd_initialize(void);
+#endif
+
+/****************************************************************************
+ * Name: board_touchscreen_initialize
+ *
+ * Description:
+ *   Initialize touchpad.
+ *
+ * Input Parameters:
+ *   None.
+ *
+ * Returned Value:
+ *   Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP32S3_BOARD_TOUCHPAD
+int board_touchscreen_initialize(void);
+#endif
+
+/****************************************************************************
+ * Name: board_ioexpander_set_pin
+ *
+ * Description:
+ *   Configure pin mode through the IO expander.
+ *
+ * Input Parameters:
+ *   input_mask  - pin bit mask which need to be set input, if set pin 0 to
+ *                 to be input, please make: input_mask = (1 << 0)
+ *   output_mask - pin bit mask which need to be set output, if set pin 1 to
+ *                 to be input, please make: output_mask = (1 << 1)
+ *
+ * Returned Value:
+ *   Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP32S3_BOARD_IOEXPANDER
+int board_ioexpander_set_pin(uint8_t input_mask, uint8_t output_mask);
+#endif
+
+/****************************************************************************
+ * Name: board_ioexpander_output
+ *
+ * Description:
+ *   Set pin output level through the IO expander.
+ *
+ * Input Parameters:
+ *   pin   - pin number
+ *   level - true for high level, false for low.
+ *
+ * Returned Value:
+ *   Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP32S3_BOARD_IOEXPANDER
+int board_ioexpander_output(int pin, bool level);
+#endif
+
+/****************************************************************************
+ * Name: board_ioexpander_initialize
+ *
+ * Description:
+ *   Initialize IO expander driver.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP32S3_BOARD_IOEXPANDER
+int board_ioexpander_initialize(void);
+#endif
+
 #endif /* __ASSEMBLY__ */
 #endif /* __BOARDS_XTENSA_ESP32S3_ESP32S3_LCD_EV_SRC_ESP32S3_LCD_EV_H */
diff --git a/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3_bringup.c 
b/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3_bringup.c
index a3427b897c..3f38147e1b 100644
--- a/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3_bringup.c
+++ b/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3_bringup.c
@@ -225,6 +225,22 @@ int esp32s3_bringup(void)
     }
 #endif
 
+#ifdef CONFIG_ESP32S3_BOARD_LCD
+  ret = board_lcd_initialize();
+  if (ret < 0)
+    {
+      syslog(LOG_ERR, "Failed to initialize LCD driver\n");
+    }
+#endif
+
+#ifdef CONFIG_ESP32S3_BOARD_TOUCHPAD
+  ret = board_touchscreen_initialize();
+  if (ret < 0)
+    {
+      syslog(LOG_ERR, "Failed to initialize touchscreen driver\n");
+    }
+#endif
+
   /* If we got here then perhaps not all initialization was successful, but
    * at least enough succeeded to bring-up NSH with perhaps reduced
    * capabilities.
diff --git a/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3_ioexpander.c 
b/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3_ioexpander.c
new file mode 100644
index 0000000000..8f606bf189
--- /dev/null
+++ b/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3_ioexpander.c
@@ -0,0 +1,171 @@
+/****************************************************************************
+ * boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3_ioexpander.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <debug.h>
+#include <assert.h>
+#include <nuttx/arch.h>
+#include <nuttx/board.h>
+
+#include "esp32s3_i2c.h"
+#include "esp32s3-lcd-ev.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define BOARD_IOEXPANDER_I2C_PORT       I2C_PORT
+
+#define BOARD_IOEXPANDER_I2C_ADDR       (0x20)
+#define BOARD_IOEXPANDER_I2C_CLOCK      (400 * 1000)
+
+#define BOARD_IOEXPANDER_SET_DIRECTION  (3)
+#define BOARD_IOEXPANDER_SET_OUTPUT     (1)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct ioexpander
+{
+  struct i2c_master_s *i2c;
+  uint8_t output_val;
+};
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct i2c_config_s g_i2c_config =
+{
+  .frequency = BOARD_IOEXPANDER_I2C_CLOCK,
+  .address   = BOARD_IOEXPANDER_I2C_ADDR,
+  .addrlen   = 7
+};
+static struct ioexpander g_ioexpander;
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: board_ioexpander_set_pin
+ *
+ * Description:
+ *   Configure pin mode through the IO expander.
+ *
+ * Input Parameters:
+ *   input_mask  - pin bit mask which need to be set input, if set pin 0 to
+ *                 to be input, please make: input_mask = (1 << 0)
+ *   output_mask - pin bit mask which need to be set output, if set pin 1 to
+ *                 to be input, please make: output_mask = (1 << 1)
+ *
+ * Returned Value:
+ *   Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int board_ioexpander_set_pin(uint8_t input_mask, uint8_t output_mask)
+{
+  uint8_t data[2] =
+  {
+    BOARD_IOEXPANDER_SET_DIRECTION, 0
+  };
+
+  if (input_mask & output_mask)
+    {
+      return -EINVAL;
+    }
+
+  data[1] |= input_mask;
+  data[1] &= ~output_mask;
+
+  return i2c_write(g_ioexpander.i2c, &g_i2c_config, data, 2);
+}
+
+/****************************************************************************
+ * Name: board_ioexpander_output
+ *
+ * Description:
+ *   Set pin output level through the IO expander.
+ *
+ * Input Parameters:
+ *   pin   - pin number
+ *   level - true for high level, false for low.
+ *
+ * Returned Value:
+ *   Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int board_ioexpander_output(int pin, bool level)
+{
+  uint8_t data[2] =
+  {
+    BOARD_IOEXPANDER_SET_OUTPUT, 0
+  };
+
+  DEBUGASSERT(pin < 8);
+
+  if (level)
+    {
+      g_ioexpander.output_val |= 1 << pin;
+    }
+  else
+    {
+      g_ioexpander.output_val &= ~(1 << pin);
+    }
+
+  data[1] = g_ioexpander.output_val;
+
+  return i2c_write(g_ioexpander.i2c, &g_i2c_config, data, 2);
+}
+
+/****************************************************************************
+ * Name: board_ioexpander_initialize
+ *
+ * Description:
+ *   Initialize IO expander driver.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int board_ioexpander_initialize(void)
+{
+  g_ioexpander.i2c = esp32s3_i2cbus_initialize(BOARD_IOEXPANDER_I2C_PORT);
+  if (!g_ioexpander.i2c)
+    {
+      return -EINVAL;
+    }
+
+  return 0;
+}
diff --git a/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3_lcd.c 
b/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3_lcd.c
new file mode 100644
index 0000000000..32b9c454c4
--- /dev/null
+++ b/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3_lcd.c
@@ -0,0 +1,683 @@
+/****************************************************************************
+ * boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3_lcd.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <debug.h>
+#include <assert.h>
+#include <sys/param.h>
+#include <unistd.h>
+#include <nuttx/arch.h>
+#include <nuttx/board.h>
+#include <nuttx/video/fb.h>
+#include <nuttx/signal.h>
+
+#include "esp32s3_gpio.h"
+#include "esp32s3-lcd-ev.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define CS_PIN      1
+#define SCK_PIN     2
+#define SDO_PIN     3
+
+#define DELAY(us)   esp_rom_delay_us(us)
+#define CS(v)       DEBUGASSERT(board_ioexpander_output(CS_PIN, v ? 1 : 0) == 
0)
+#define SCK(v)      DEBUGASSERT(board_ioexpander_output(SCK_PIN, v ? 1 : 0) == 
0)
+#define SDO(v)      DEBUGASSERT(board_ioexpander_output(SDO_PIN, v ? 1 : 0) == 
0)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct lcd_config_data
+{
+  uint8_t cmd;
+  uint8_t data_bytes;
+  uint8_t data[52];
+};
+
+/****************************************************************************
+ * External Functions
+ ****************************************************************************/
+
+extern void esp_rom_delay_us(uint32_t us);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* LCD GC9503CV configuration parameters */
+
+static const struct lcd_config_data g_lcd_config[] =
+{
+  {
+    /* Enable manufacture command set in page 0 */
+
+    0xf0, 5,
+    {
+      0x55, 0xaa, 0x52, 0x08, 0x00
+    }
+  },
+  {
+    /* Unknown */
+
+    0xf6, 2,
+    {
+      0x5a, 0x87
+    }
+  },
+  {
+    /* Unknown */
+
+    0xc1, 1,
+    {
+      0x3f
+    }
+  },
+  {
+    /* Unknown */
+
+    0xc2, 1,
+    {
+      0x0e
+    }
+  },
+  {
+    /* Unknown */
+
+    0xc6, 1,
+    {
+      0xf8
+    }
+  },
+  {
+    /* Unknown */
+
+    0xc9, 1,
+    {
+      0x10
+    }
+  },
+  {
+    /* Unknown */
+
+    0xcd, 1,
+    {
+      0x25
+    }
+  },
+  {
+    /* Unknown */
+
+    0xf8, 1,
+    {
+      0x8a
+    }
+  },
+  {
+    /* Unknown */
+
+    0xac, 1,
+    {
+      0x45
+    }
+  },
+  {
+    /* Set VGH to be 13(15.00) */
+
+    0xa0, 1,
+    {
+      0xdd
+    }
+  },
+  {
+    /* Unknown */
+
+    0xa7, 1,
+    {
+      0x47
+    }
+  },
+  {
+    /* Unknown */
+
+    0xfa, 4,
+    {
+      0x00, 0x00, 0x00, 0x04
+    }
+  },
+  {
+    /* Set VGL to be 5(-10.5) */
+
+    0x86, 4,
+    {
+      0x99, 0xa3, 0xa3, 0x51
+    }
+  },
+  {
+    /* Unknown */
+
+    0xa3, 1,
+    {
+      0xee
+    }
+  },
+  {
+    /* Unknown */
+
+    0xfd, 3,
+    {
+      0x3c, 0x3c, 0x00
+    }
+  },
+  {
+    /* Unknown */
+
+    0x71, 1,
+    {
+      0x48
+    }
+  },
+  {
+    /* Unknown */
+
+    0x72, 1,
+    {
+      0x48
+    }
+  },
+  {
+    /* Unknown */
+
+    0x73, 2,
+    {
+      0x00, 0x44
+    }
+  },
+  {
+    /* Unknown */
+
+    0x97, 1,
+    {
+      0xee
+    }
+  },
+  {
+    /* Unknown */
+
+    0x83, 1,
+    {
+      0x93
+    }
+  },
+  {
+    /* Set adjustment of VGMP */
+
+    0x9a, 1,
+    {
+      0x72
+    }
+  },
+  {
+    /* Set adjustment of VGMN */
+
+    0x9b, 1,
+    {
+      0x5a
+    }
+  },
+  {
+    /* Set adjustment of VGSPN */
+
+    0x82, 2,
+    {
+      0x2c, 0x2c
+    }
+  },
+  {
+    /* Unknown */
+
+    0x6d, 32,
+    {
+      0x00, 0x1f, 0x19, 0x1a, 0x10, 0x0e, 0x0c, 0x0a,
+      0x02, 0x07, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+      0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x08, 0x01,
+      0x09, 0x0b, 0x0d, 0x0f, 0x1a, 0x19, 0x1f, 0x00
+    }
+  },
+  {
+    /* Unknown */
+
+    0x64, 16,
+    {
+      0x38, 0x05, 0x01, 0xdb, 0x03, 0x03, 0x38, 0x04,
+      0x01, 0xdc, 0x03, 0x03, 0x7a, 0x7a, 0x7a, 0x7a
+    }
+  },
+  {
+    /* Unknown */
+
+    0x65, 16,
+    {
+      0x38, 0x03, 0x01, 0xdd, 0x03, 0x03, 0x38, 0x02,
+      0x01, 0xde, 0x03, 0x03, 0x7a, 0x7a, 0x7a, 0x7a
+    }
+  },
+  {
+    /* Unknown */
+
+    0x66, 16,
+    {
+      0x38, 0x01, 0x01, 0xdf, 0x03, 0x03, 0x38, 0x00,
+      0x01, 0xe0, 0x03, 0x03, 0x7a, 0x7a, 0x7a, 0x7a
+    }
+  },
+  {
+    /* Unknown */
+
+    0x67, 16,
+    {
+      0x30, 0x01, 0x01, 0xe1, 0x03, 0x03, 0x30, 0x02,
+      0x01, 0xe2, 0x03, 0x03, 0x7a, 0x7a, 0x7a, 0x7a
+    }
+  },
+  {
+    /* Unknown */
+
+    0x68, 13,
+    {
+      0x00, 0x08, 0x15, 0x08, 0x15, 0x7a, 0x7a, 0x08,
+      0x15, 0x08, 0x15, 0x7a, 0x7a
+    }
+  },
+  {
+    /* Unknown */
+
+    0x60, 8,
+    {
+      0x38, 0x08, 0x7a, 0x7a, 0x38, 0x09, 0x7a, 0x7a
+    }
+  },
+  {
+    /* Unknown */
+
+    0x63, 8,
+    {
+      0x31, 0xe4, 0x7a, 0x7a, 0x31, 0xe5, 0x7a, 0x7a
+    }
+  },
+  {
+    /* Unknown */
+
+    0x69, 7,
+    {
+      0x04, 0x22, 0x14, 0x22, 0x14, 0x22, 0x08
+    }
+  },
+  {
+    /* Unknown */
+
+    0x6b, 1,
+    {
+      0x07
+    }
+  },
+  {
+    /* Unknown */
+
+    0x7a, 2,
+    {
+      0x08, 0x13
+    }
+  },
+  {
+    /* Unknown */
+
+    0x7b, 2,
+    {
+      0x08, 0x13
+    }
+  },
+  {
+    /* Unknown */
+
+    0xd1, 52,
+    {
+      0x00, 0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x18,
+      0x00, 0x21, 0x00, 0x2a, 0x00, 0x35, 0x00, 0x47,
+      0x00, 0x56, 0x00, 0x90, 0x00, 0xe5, 0x01, 0x68,
+      0x01, 0xd5, 0x01, 0xd7, 0x02, 0x36, 0x02, 0xa6,
+      0x02, 0xee, 0x03, 0x48, 0x03, 0xa0, 0x03, 0xba,
+      0x03, 0xc5, 0x03, 0xd0, 0x03, 0xe0, 0x03, 0xea,
+      0x03, 0xfa, 0x03, 0xff
+    }
+  },
+  {
+    /* Unknown */
+
+    0xd2, 52,
+    {
+      0x00, 0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x18,
+      0x00, 0x21, 0x00, 0x2a, 0x00, 0x35, 0x00, 0x47,
+      0x00, 0x56, 0x00, 0x90, 0x00, 0xe5, 0x01, 0x68,
+      0x01, 0xd5, 0x01, 0xd7, 0x02, 0x36, 0x02, 0xa6,
+      0x02, 0xee, 0x03, 0x48, 0x03, 0xa0, 0x03, 0xba,
+      0x03, 0xc5, 0x03, 0xd0, 0x03, 0xe0, 0x03, 0xea,
+      0x03, 0xfa, 0x03, 0xff
+    }
+  },
+  {
+    /* Unknown */
+
+    0xd3, 52,
+    {
+      0x00, 0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x18,
+      0x00, 0x21, 0x00, 0x2a, 0x00, 0x35, 0x00, 0x47,
+      0x00, 0x56, 0x00, 0x90, 0x00, 0xe5, 0x01, 0x68,
+      0x01, 0xd5, 0x01, 0xd7, 0x02, 0x36, 0x02, 0xa6,
+      0x02, 0xee, 0x03, 0x48, 0x03, 0xa0, 0x03, 0xba,
+      0x03, 0xc5, 0x03, 0xd0, 0x03, 0xe0, 0x03, 0xea,
+      0x03, 0xfa, 0x03, 0xff
+    }
+  },
+  {
+    /* Unknown */
+
+    0xd4, 52,
+    {
+      0x00, 0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x18,
+      0x00, 0x21, 0x00, 0x2a, 0x00, 0x35, 0x00, 0x47,
+      0x00, 0x56, 0x00, 0x90, 0x00, 0xe5, 0x01, 0x68,
+      0x01, 0xd5, 0x01, 0xd7, 0x02, 0x36, 0x02, 0xa6,
+      0x02, 0xee, 0x03, 0x48, 0x03, 0xa0, 0x03, 0xba,
+      0x03, 0xc5, 0x03, 0xd0, 0x03, 0xe0, 0x03, 0xea,
+      0x03, 0xfa, 0x03, 0xff
+    }
+  },
+  {
+    /* Unknown */
+
+    0xd5, 52,
+    {
+      0x00, 0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x18,
+      0x00, 0x21, 0x00, 0x2a, 0x00, 0x35, 0x00, 0x47,
+      0x00, 0x56, 0x00, 0x90, 0x00, 0xe5, 0x01, 0x68,
+      0x01, 0xd5, 0x01, 0xd7, 0x02, 0x36, 0x02, 0xa6,
+      0x02, 0xee, 0x03, 0x48, 0x03, 0xa0, 0x03, 0xba,
+      0x03, 0xc5, 0x03, 0xd0, 0x03, 0xe0, 0x03, 0xea,
+      0x03, 0xfa, 0x03, 0xff
+    },
+  },
+  {
+    /* Unknown */
+
+    0xd6, 52,
+    {
+      0x00, 0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x18,
+      0x00, 0x21, 0x00, 0x2a, 0x00, 0x35, 0x00, 0x47,
+      0x00, 0x56, 0x00, 0x90, 0x00, 0xe5, 0x01, 0x68,
+      0x01, 0xd5, 0x01, 0xd7, 0x02, 0x36, 0x02, 0xa6,
+      0x02, 0xee, 0x03, 0x48, 0x03, 0xa0, 0x03, 0xba,
+      0x03, 0xc5, 0x03, 0xd0, 0x03, 0xe0, 0x03, 0xea,
+      0x03, 0xfa, 0x03, 0xff
+    },
+  },
+  {
+    /* 18-bit Pixel */
+
+    0x3a, 1,
+    {
+      0x60
+    }
+  },
+  {
+    /* Enter sleep out mode, no parameters */
+
+    0x11, 0
+  },
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * 9-bit SPI Rising Mode
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: send_byte
+ *
+ * Description:
+ *   Send 9-bit data to LCD.
+ *
+ * Input Parameters:
+ *   data - TX data
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+static void send_byte(uint16_t data)
+{
+  for (int n = 0; n < 9; n++)
+    {
+      if (data & 0x0100)
+        {
+          SDO(1);
+        }
+      else
+        {
+          SDO(0);
+        }
+
+      data = data << 1;
+
+      SCK(0);
+      DELAY(10);
+      SCK(1);
+      DELAY(10);
+    }
+}
+
+/****************************************************************************
+ * Name: send_cmd
+ *
+ * Description:
+ *   Send command to LCD.
+ *
+ * Input Parameters:
+ *   cmd - TX command
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+static void send_cmd(uint8_t cmd)
+{
+  uint16_t spi_data = cmd;
+
+  CS(0);
+  DELAY(10);
+
+  send_byte(spi_data);
+
+  DELAY(10);
+  CS(1);
+  SCK(0);
+  SDO(0);
+  DELAY(10);
+}
+
+/****************************************************************************
+ * Name: send_data
+ *
+ * Description:
+ *   Send data to LCD.
+ *
+ * Input Parameters:
+ *   cmd - TX command
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+static void send_data(uint8_t data)
+{
+  uint16_t spi_data = data;
+
+  CS(0);
+  DELAY(10);
+
+  spi_data &= 0x00ff;
+  spi_data |= 0x0100;
+  send_byte(spi_data);
+
+  DELAY(10);
+  CS(1);
+  SCK(0);
+  SDO(0);
+  DELAY(10);
+}
+
+/****************************************************************************
+ * Name: lcd_initialize_spi
+ *
+ * Description:
+ *   Initialize write only SPI interface by IO expander.
+ *
+ * Input Parameters:
+ *   None.
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+static void lcd_initialize_spi(void)
+{
+  uint8_t pin_mask = (1 << CS_PIN) |
+                     (1 << SCK_PIN) |
+                     (1 << SDO_PIN);
+
+  DEBUGASSERT(board_ioexpander_initialize() == 0);
+  DEBUGASSERT(board_ioexpander_set_pin(0, pin_mask) == 0);
+
+  CS(1);
+  SCK(1);
+  SDO(1);
+}
+
+/****************************************************************************
+ * Name: lcd_configure_display
+ *
+ * Description:
+ *   Configure LCD with global configuration parameters.
+ *
+ * Input Parameters:
+ *   None.
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+static void lcd_configure_display(void)
+{
+  /* Pull-up V-SYNC pin to start configurating LCD */
+
+  esp32s3_configgpio(CONFIG_ESP32S3_LCD_VSYNC_PIN, OUTPUT | PULLUP);
+  esp32s3_gpiowrite(CONFIG_ESP32S3_LCD_VSYNC_PIN, 1);
+
+  for (int i = 0; i < nitems(g_lcd_config); i++)
+    {
+      send_cmd(g_lcd_config[i].cmd);
+
+      for (int j = 0; j < g_lcd_config[i].data_bytes; j++)
+        {
+          send_data(g_lcd_config[i].data[j]);
+        }
+    }
+
+  /* Wait until LCD is ready */
+
+  nxsig_usleep(120 * 1000);
+
+  /* Display on */
+
+  send_cmd(0x29);
+
+  /* Wait until LCD is on */
+
+  nxsig_usleep(20 * 1000);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: board_lcd_initialize
+ *
+ * Description:
+ *   Initialize LCD.
+ *
+ * Input Parameters:
+ *   None.
+ *
+ * Returned Value:
+ *   Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int board_lcd_initialize(void)
+{
+  int ret;
+
+  lcd_initialize_spi();
+  lcd_configure_display();
+
+#ifdef CONFIG_VIDEO_FB
+  /* Initialize and register the framebuffer driver */
+
+  ret = fb_register(0, 0);
+  if (ret < 0)
+    {
+      syslog(LOG_ERR, "ERROR: fb_register() failed: %d\n", ret);
+      return ret;
+    }
+#else
+  UNUSED(ret);
+#endif
+
+  return 0;
+}
diff --git a/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3_touchscreen.c 
b/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3_touchscreen.c
new file mode 100644
index 0000000000..06e1ffeceb
--- /dev/null
+++ b/boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3_touchscreen.c
@@ -0,0 +1,191 @@
+/****************************************************************************
+ * boards/xtensa/esp32s3/esp32s3-lcd-ev/src/esp32s3_touchscreen.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <syslog.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <nuttx/input/ft5x06.h>
+
+#include "esp32s3_i2c.h"
+#include "esp32s3-lcd-ev.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define BOARD_TOUCHSCREEN_I2C_PORT    I2C_PORT
+
+#define BOARD_TOUCHSCREEN_I2C_ADDR    (0x38)
+#define BOARD_TOUCHSCREEN_I2C_CLOCK   (400 * 1000)
+
+/****************************************************************************
+ * Private Function Ptototypes
+ ****************************************************************************/
+
+#ifndef CONFIG_FT5X06_POLLMODE
+static int  esp32s3_ft5x06_attach(const struct ft5x06_config_s *config,
+                                  xcpt_t isr, void *arg);
+static void esp32s3_ft5x06_enable(const struct ft5x06_config_s *config,
+                                  bool enable);
+static void esp32s3_ft5x06_clear(const struct ft5x06_config_s *config);
+#endif
+static void esp32s3_ft5x06_wakeup(const struct ft5x06_config_s *config);
+static void esp32s3_ft5x06_nreset(const struct ft5x06_config_s *config,
+                                  bool state);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct ft5x06_config_s g_ft5x06_config =
+{
+  .address   = BOARD_TOUCHSCREEN_I2C_ADDR,
+  .frequency = BOARD_TOUCHSCREEN_I2C_CLOCK,
+#ifndef CONFIG_FT5X06_POLLMODE
+  .attach    = esp32s3_ft5x06_attach,
+  .enable    = esp32s3_ft5x06_enable,
+  .clear     = esp32s3_ft5x06_clear,
+#endif
+  .wakeup    = esp32s3_ft5x06_wakeup,
+  .nreset    = esp32s3_ft5x06_nreset
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+#ifndef CONFIG_FT5X06_POLLMODE
+
+/****************************************************************************
+ * Name: esp32s3_ft5x06_attach
+ *
+ * Description:
+ *   Attach an FT5x06 interrupt handler to a GPIO interrupt
+ *
+ ****************************************************************************/
+
+static int  esp32s3_ft5x06_attach(const struct ft5x06_config_s *config,
+                                  xcpt_t isr, void *arg)
+{
+  /* We do not have interrupt pin in the implementation */
+
+  return 0;
+}
+
+/****************************************************************************
+ * Name: esp32s3_ft5x06_enable
+ *
+ * Description:
+ *   Enable or disable a GPIO interrupt
+ *
+ ****************************************************************************/
+
+static void esp32s3_ft5x06_enable(const struct ft5x06_config_s *config,
+                                  bool enable)
+{
+  /* We do not have interrupt pin in the implementation */
+}
+
+/****************************************************************************
+ * Name: esp32s3_ft5x06_clear
+ *
+ * Description:
+ *   Acknowledge/clear any pending GPIO interrupt
+ *
+ ****************************************************************************/
+
+static void esp32s3_ft5x06_clear(const struct ft5x06_config_s *config)
+{
+  /* We do not have interrupt pin in the implementation */
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32s3_ft5x06_wakeup
+ *
+ * Description:
+ *   Issue WAKE interrupt to FT5x06 to change the FT5x06 from Hibernate to
+ *   Active mode.
+ *
+ ****************************************************************************/
+
+static void esp32s3_ft5x06_wakeup(const struct ft5x06_config_s *config)
+{
+  /* We do not have access to the WAKE pin in the implementation */
+}
+
+/****************************************************************************
+ * Name: esp32s3_ft5x06_nreset
+ *
+ * Description:
+ *   Control the chip reset pin
+ *
+ ****************************************************************************/
+
+static void esp32s3_ft5x06_nreset(const struct ft5x06_config_s *config,
+                                  bool state)
+{
+  /* We do not have access to the RESET pin in the implementation */
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: board_touchscreen_initialize
+ *
+ * Description:
+ *   Initialize touchpad.
+ *
+ * Input Parameters:
+ *   None.
+ *
+ * Returned Value:
+ *   Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int board_touchscreen_initialize(void)
+{
+  int ret;
+  struct i2c_master_s *i2c;
+
+  i2c = esp32s3_i2cbus_initialize(BOARD_TOUCHSCREEN_I2C_PORT);
+  if (!i2c)
+    {
+      return -EINVAL;
+    }
+
+  ret = ft5x06_register(i2c, &g_ft5x06_config, 0);
+  if (ret != 0)
+    {
+      return ret;
+    }
+
+  return 0;
+}

Reply via email to