diff --git a/arch/arm/src/dm320/Make.defs b/arch/arm/src/dm320/Make.defs
index 6bacd3f111..029dda6cf6 100644
--- a/arch/arm/src/dm320/Make.defs
+++ b/arch/arm/src/dm320/Make.defs
@@ -47,7 +47,7 @@ CMN_CSRCS	= up_assert.c up_blocktask.c up_copystate.c up_createstack.c \
 
 CHIP_ASRCS	= dm320_lowputc.S dm320_restart.S
 CHIP_CSRCS	= dm320_allocateheap.c dm320_boot.c dm320_decodeirq.c \
-		  dm320_irq.c dm320_serial.c dm320_timerisr.c
+		  dm320_irq.c dm320_serial.c dm320_timerisr.c dm320_framebuffer.c
 
 ifeq ($(CONFIG_USBDEV),y)
 CHIP_CSRCS	+= dm320_usbdev.c
diff --git a/arch/arm/src/dm320/dm320_framebuffer.c b/arch/arm/src/dm320/dm320_framebuffer.c
new file mode 100644
index 0000000000..02f73061d6
--- /dev/null
+++ b/arch/arm/src/dm320/dm320_framebuffer.c
@@ -0,0 +1,1437 @@
+/****************************************************************************
+ * arch/arm/src/dm320/dm320_framebuffer.c
+ *
+ *   Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/fb.h>
+
+#include "up_arch.h"
+#include "dm320_memorymap.h"
+#include "dm320_osd.h"
+
+/************************************************************************
+ * Definitions
+ ************************************************************************/
+
+/* Configuration ********************************************************/
+
+/* Video (X,Y) base offset */
+
+#ifndef CONFIG_DM320_BASEX
+#  define CONFIG_DM320_BASEX 0x090
+#endif
+
+#ifndef CONFIG_DM320_BASEY
+#  define CONFIG_DM320_BASEY 0x010
+#endif
+
+/* Background color */
+
+#ifndef CONFIG_DM320_BKGDCLUT
+#  define CONFIG_DM320_BKGDCLUT 0x00ff
+#endif
+
+#ifdef CONFIG_FB_HWCURSORIMAGE
+#  error "Cursor image not supported"
+#endif
+
+/* Window selections */
+
+#if defined(CONFIG_DM320_OSD0_RGB16) && defined(CONFIG_DM320_OSD1_RGB16)
+#  error "Both CONFIG_DM320_OSD0_RGB16 and CONFIG_DM320_OSD1_RGB16 defined"
+#endif
+
+#if defined(CONFIG_DM320_VID0_DISABLE) && defined(CONFIG_DM320_VID1_DISABLE) && \
+    defined(CONFIG_DM320_OSD0_DISABLE)  && defined(CONFIG_DM320_OSD1_DISABLE)
+#  error "All windows are disabled, at least one window must be enabled"
+#endif
+
+#undef CONFIG_DM320_DISABLE_PINGPONG
+#define CONFIG_DM320_DISABLE_PINGPONG 1 /* Not supported by interface */
+
+/* Window positions and sizes */
+
+#define MAX_XRES 640
+#define MAX_YRES 480
+
+#ifndef CONFIG_DM320_VID0_DISABLE
+#  ifndef CONFIG_DM320_VID0_XRES
+#    define CONFIG_DM320_VID0_XRES MAX_XRES
+#  elif CONFIG_DM320_VID0_XRES > MAX_XRES
+#    error "VID0 XRES out of range"
+#  endif
+#  ifndef CONFIG_DM320_VID0_XPOS
+#    define CONFIG_DM320_VID0_XPOS 0
+#  elif CONFIG_DM320_VID0_XPOS + CONFIG_DM320_VID0_XRES > MAX_XRES
+#    error "VID0 XPOS out of range"
+#  endif
+#  ifndef CONFIG_DM320_VID0_YRES
+#    define CONFIG_DM320_VID0_YRES MAX_YRES
+#  elif CONFIG_DM320_VID0_YRES > MAX_YRES
+#    error "VID0 YRES out of range"
+#  endif
+#  ifndef CONFIG_DM320_VID0_YPOS
+#    define CONFIG_DM320_VID0_YPOS 0
+#  elif CONFIG_DM320_VID0_YPOS + CONFIG_DM320_VID0_YRES > MAX_YRES
+#    error "VID0 YPOS out of range"
+#  endif
+#endif
+
+#ifndef CONFIG_DM320_VID1_DISABLE
+#  ifndef CONFIG_DM320_VID1_XRES
+#    define CONFIG_DM320_VID1_XRES MAX_XRES
+#  elif CONFIG_DM320_VID1_XRES > MAX_XRES
+#    error "VID1 XRES out of range"
+#  endif
+#  ifndef CONFIG_DM320_VID1_XPOS
+#    define CONFIG_DM320_VID1_XPOS 0
+#  elif CONFIG_DM320_VID1_XPOS + CONFIG_DM320_VID1_XRES > MAX_XRES
+#    error "VID0 XPOS out of range"
+#  endif
+#  ifndef CONFIG_DM320_VID1_YRES
+#    define CONFIG_DM320_VID1_YRES MAX_YRES
+#  elif CONFIG_DM320_VID1_YRES > MAX_YRES
+#    error "VID1 YRES out of range"
+#  endif
+#  ifndef CONFIG_DM320_VID1_YPOS
+#    define CONFIG_DM320_VID1_YPOS 0
+#  elif CONFIG_DM320_VID1_YPOS + CONFIG_DM320_VID1_YRES > MAX_YRES
+#    error "VID1 YPOS out of range"
+#  endif
+#endif
+
+#ifndef CONFIG_DM320_OSD0_DISABLE
+#  ifndef CONFIG_DM320_OSD0_XRES
+#    define CONFIG_DM320_OSD0_XRES MAX_XRES
+#  elif CONFIG_DM320_OSD0_XRES > MAX_XRES
+#    error "OSD0 XRES out of range"
+#  endif
+#  ifndef CONFIG_DM320_OSD0_XPOS
+#    define CONFIG_DM320_OSD0_XPOS 0
+#  elif CONFIG_DM320_OSD0_XPOS + CONFIG_DM320_OSD0_XRES > MAX_XRES
+#    error "OSD0 XPOS out of range"
+#  endif
+#  ifndef CONFIG_DM320_OSD0_YRES
+#    define CONFIG_DM320_OSD0_YRES MAX_YRES
+#  elif CONFIG_DM320_OSD0_YRES > MAX_YRES
+#    error "OSD0 YRES out of range"
+#  endif
+#  ifndef CONFIG_DM320_OSD0_YPOS
+#    define CONFIG_DM320_OSD0_YPOS 0
+#  elif CONFIG_DM320_OSD0_YPOS + CONFIG_DM320_OSD0_YRES > MAX_YRES
+#    error "OSD0 YPOS out of range"
+#  endif
+#endif
+
+#ifndef CONFIG_DM320_OSD1_DISABLE
+#  ifndef CONFIG_DM320_OSD1_XRES
+#    define CONFIG_DM320_OSD1_XRES MAX_XRES
+#  elif CONFIG_DM320_OSD1_XRES > MAX_XRES
+#    error "OSD1 XRES out of range"
+#  endif
+#  ifndef CONFIG_DM320_OSD1_XPOS
+#    define CONFIG_DM320_OSD1_XPOS 0
+#  elif CONFIG_DM320_OSD1_XPOS + CONFIG_DM320_OSD1_XRES > MAX_XRES
+#    error "OSD1 XPOS out of range"
+#  endif
+#  ifndef CONFIG_DM320_OSD1_YRES
+#    define CONFIG_DM320_OSD1_YRES MAX_YRES
+#  elif CONFIG_DM320_OSD0_YRES > MAX_YRES
+#    error "OSD0 YRES out of range"
+#  endif
+#  ifndef CONFIG_DM320_OSD1_YPOS
+#    define CONFIG_DM320_OSD1_YPOS 0
+#  elif CONFIG_DM320_OSD1_YPOS + CONFIG_DM320_OSD1_YRES > MAX_YRES
+#    error "OSD1 YPOS out of range"
+#  endif
+#endif
+
+/* Cursor selections */
+
+#ifdef CONFIG_FB_HWCURSOR
+#  ifndef CONFIG_DM320_CURSORCLUT
+#    define CONFIG_DM320_CURSORCLUT 0x00
+#  endif
+#  ifndef CONFIG_DM320_CURSORLINEWIDTH
+#    define CONFIG_DM320_CURSORLINEWIDTH 1
+#  endif
+#  if CONFIG_DM320_CURSORLINEWIDTH > 7
+#    error "Rectangular cursor width is out of range"
+#  endif
+#  ifndef CONFIG_DM320_CURSORLINEHEIGHT
+#    define CONFIG_DM320_CURSORLINEHEIGHT 1
+#  endif
+#  if CONFIG_DM320_CURSORLINEHEIGHT > 7
+#    error "Rectangular cursor height is out of range"
+#  endif
+#  ifndef CONFIG_DM320_RECTCURSOR_WIDTH
+#    define CONFIG_DM320_RECTCURSOR_WIDTH MAX_XRES
+#  elif CONFIG_DM320_RECTCURSOR_WIDTH > MAX_XRES
+#    error "Cursor width out of range"
+#  endif
+#  ifndef CONFIG_DM320_RECTCURSOR_HEIGHT
+#    define CONFIG_DM320_RECTCURSOR_HEIGHT MAX_YRES
+#  elif CONFIG_DM320_RECTCURSOR_HEIGHT > MAX_YRES
+#    error "Cursor width out of range"
+#  endif
+#endif
+
+/* DM320 ****************************************************************/
+
+/* Video planes.  This long messy conditional compilation results in
+ * consecutive plane numbers assigned for enable planes and the total
+ * number of planes
+ */
+
+#ifndef CONFIG_DM320_VID0_DISABLE
+#  define DM320_VIDWIN0         (0)            /* Have VID0 */
+#  ifndef CONFIG_DM320_VID1_DISABLE
+#    define DM320_VIDWIN1       (1)            /* Have VID0+VID1 */
+#    ifndef CONFIG_DM320_OSD0_DISABLE
+#      define DM320_OSDWIN0     (2)            /* Have VID0+VID1+OSD0 */
+#      ifndef CONFIG_DM320_OSD1_DISABLE
+#        define DM320_OSDWIN1   (3)            /* Have VID0+VID1+OSD0+OSD1 */
+#        define DM320_NFRAMES   (4)
+#      else
+#        define DM320_NFRAMES   (3)            /* Have VID0+VID1+OSD0 but not OSD1 */
+#      endif
+#    else                                      /* Have VID0+VID1 but not OSD0 */
+#      ifndef CONFIG_DM320_OSD1_DISABLE
+#        define DM320_OSDWIN1   (2)            /* Have VID0+VID1+OSD1 but not OSD0 */
+#        define DM320_NFRAMES   (3)
+#      else
+#        define DM320_NFRAMES   (2)            /* Have VID0+VID1 but not OSD0 or OSD1 */
+#      endif
+#    endif
+#  else                                        /* Have VID0 but not VID1 */
+#    ifndef CONFIG_DM320_OSD0_DISABLE
+#      define DM320_OSDWIN0     (1)            /* Have VID0+OSD0 but not VID1 */
+#      ifndef CONFIG_DM320_OSD1_DISABLE
+#        define DM320_OSDWIN1   (2)            /* Have VID0+OSD0+OSD1 but not VID1 */
+#        define DM320_NFRAMES   (3)
+#      else
+#        define DM320_NFRAMES   (2)            /* Have VID0+OSD0 but not VID1 or OSD1 */
+#      endif
+#    else                                      /* Have VID0 but not VID1 or OSD0 */
+#        ifndef CONFIG_DM320_OSD1_DISABLE
+#          define DM320_OSDWIN1 (1)            /* Have VID0+OSD1 but not VID1 or OSD0 */
+#          define DM320_NFRAMES (3)
+#        else
+#          define DM320_NFRAMES (2)            /* Have VID0 but not VID1, OSD0, or OSD1 */
+#        endif
+#      endif
+#    endif
+#else                                          /* Don't have VID0 */
+#  ifndef CONFIG_DM320_VID1_DISABLE
+#    define DM320_VIDWIN1     (0)            /* Have VID1 but not VID0 */
+#    ifndef CONFIG_DM320_OSD0_DISABLE
+#     define DM320_OSDWIN0    (1)            /* Have VID1+OSD0 not VID0 */
+#      ifndef CONFIG_DM320_OSD1_DISABLE
+#        define DM320_OSDWIN1 (2)            /* Have VID1+OSD0+OSD1 not VID0 */
+#        define DM320_NFRAMES (3)
+#      else
+#        define DM320_NFRAMES (2)            /* Have VID1+OSD0 but not VID0 or OSD1 */
+#      endif
+#    else                                    /* Have VID1 but not VID0 or OSD0 */
+#      ifndef CONFIG_DM320_OSD1_DISABLE
+#        define DM320_OSDWIN1 (1)            /* Have VID1+OSD1 but not VID0 or OSD0 */
+#        define DM320_NFRAMES (2)
+#      else
+#        define DM320_NFRAMES (2)            /* Have VID1 but not VID0, OSD0 or OSD1 */
+#      endif
+#    endif
+#  else                                      /* Don't have VID0 or VID1 */
+#    ifndef CONFIG_DM320_OSD0_DISABLE
+#      define DM320_OSDWIN0   (0)            /* Have OSD0 but not VID0 or VID1 */
+#      ifndef CONFIG_DM320_OSD1_DISABLE
+#        define DM320_OSDWIN1 (1)            /* Have OSD0+OSD1 but not VID0 or VID1 */
+#        define DM320_NFRAMES (2)
+#      else
+#        define DM320_NFRAMES (1)            /* Have OSD0 but VID0, VID, or OSD1 */
+#      endif
+#    else                                    /* Don't have VID0, VID1, or OSD0 */
+#      ifndef CONFIG_DM320_OSD1_DISABLE
+#        define DM320_OSDWIN1 (0)            /* Have OSD1 but not VID0, VID1, or OSD0 */
+#        define DM320_NFRAMES (1)
+#      else
+#        error "No video planes enabled"
+#      endif
+#    endif
+#  endif
+#endif
+
+/* Bits per pixel */
+
+#define DM320_VID0_BPP          (16)
+#define DM320_VID1_BPP          (16)
+#ifdef CONFIG_DM320_OSD0_RGB16
+#  define DM320_OSD0_BPP        (16)
+#else
+#  define DM320_OSD0_BPP        (8)
+#endif
+#ifdef CONFIG_DM320_OSD1_RGB16
+#  define DM320_OSD1_BPP        (16)
+#else
+#  define DM320_OSD1_BPP        (8)
+#endif
+
+/* These are DM320-specific ranges for the BASEPX/Y registers */
+
+#define DM320_MIN_BASEPX        (24)
+#define DM320_MAX_BASEPX        (1023)
+#define DM320_MIN_BASEPY        (1)
+#define DM320_MAX_BASEPY        (511)
+
+#if (CONFIG_DM320_BASEX < DM320_MIN_BASEPX || CONFIG_DM320_BASEX > DM320_MAX_BASEPX)
+#  error "CONFIG_DM320_BASEX is out of range"
+#endif
+
+#if (CONFIG_DM320_BASEY < DM320_MIN_BASEPY || CONFIG_DM320_BASEY > DM320_MAX_BASEPY)
+#  error "CONFIG_DM320_BASEY is out of range"
+#endif
+
+/* The width of a line in bytes */
+
+#define DM320_VID0_STRIDE       (CONFIG_DM320_VID0_XRES * DM320_VID0_BPP / 8)
+#define DM320_VID1_STRIDE       (CONFIG_DM320_VID1_XRES * DM320_VID1_BPP / 8)
+#define DM320_OSD0_STRIDE       (CONFIG_DM320_OSD0_XRES * DM320_OSD0_BPP / 8)
+#define DM320_OSD1_STRIDE       (CONFIG_DM320_OSD1_XRES * DM320_OSD1_BPP / 8)
+
+/* The area of the screen in bytes */
+
+#define DM320_VID0_FBLEN        (DM320_VID0_STRIDE * CONFIG_DM320_VID0_YRES)
+#define DM320_VID1_FBLEN        (DM320_VID1_STRIDE * CONFIG_DM320_VID1_YRES)
+#define DM320_OSD0_FBLEN        (DM320_OSD0_STRIDE * CONFIG_DM320_OSD0_YRES)
+#define DM320_OSD1_FBLEN        (DM320_OSD1_STRIDE * CONFIG_DM320_OSD1_YRES)
+
+/* Video/OSD modes */
+
+#ifndef CONFIG_DM320_VID0_DISABLE
+#  ifdef CONFIG_DM320_VID0_FRAMEMODE
+#    define DM320_VID0MODE 0x0003
+#  else
+#    define DM320_VID0MODE 0x0001
+#  endif
+#else
+#  define DM320_VID0MODE   0x0000
+#endif
+
+#ifndef CONFIG_DM320_VID1_DISABLE
+#  ifdef CONFIG_DM320_VID1_FRAMEMODE
+#    define DM320_VID1MODE 0x0300
+#  else
+#    define DM320_VID1MODE 0x0100
+#  endif
+#else
+#  define DM320_VID1MODE   0x0000
+#endif
+
+#define DM320_VIDMODE (DM320_VID0MODE|DM320_VID1MODE)
+
+#ifndef CONFIG_DM320_OSD0_DISABLE
+#  ifdef CONFIG_DM320_OSD0_FRAMEMODE
+#    define OSD0MODE_FRAME 0x0002
+#  else
+#    define OSD0_FRAMEMODE 0x0000
+#  endif
+
+#  ifdef CONFIG_DM320_OSD0_TRANSPMODE
+#    ifdef CONFIG_DM320_OSD0_BLEND8THS
+#      if CONFIG_DM320_OSD0_BLEND8THS == 8
+#        define OSD0MODE_TRANSPMODE 0x0004
+#      elif CONFIG_DM320_OSD0_BLEND8THS == 7
+#        define OSD0MODE_TRANSPMODE 0x000c
+#      elif CONFIG_DM320_OSD0_BLEND8THS == 6
+#        define OSD0MODE_TRANSPMODE 0x0014
+#      elif CONFIG_DM320_OSD0_BLEND8THS == 5
+#        define OSD0MODE_TRANSPMODE 0x001c
+#      elif CONFIG_DM320_OSD0_BLEND8THS == 4
+#        define OSD0MODE_TRANSPMODE 0x0024
+#      elif CONFIG_DM320_OSD0_BLEND8THS == 3
+#        define OSD0MODE_TRANSPMODE 0x002c
+#      elif CONFIG_DM320_OSD0_BLEND8THS == 2
+#        define OSD0MODE_TRANSPMODE 0x0034
+#      elif CONFIG_DM320_OSD0_BLEND8THS == 0
+#        define OSD0MODE_TRANSPMODE 0x003c
+#      else
+#        error "Invalid OSD0 transparency selection"
+#      endif
+#    else
+#      define OSD0MODE_TRANSPMODE 0x0004
+#    endif
+#  else
+#    define OSD0MODE_TRANSPMODE 0x0000
+#  endif
+
+#  ifdef CONFIG_DM320_OSD0_RGB16
+#    define OSD0MODE_RGB16 0x2000
+#  else
+#    define OSD0MODE_RGB16 0x0000
+#  endif
+
+#  define INITIAL_OSD0MODE (0x00c1|OSD0MODE_TRANSPMODE|OSD0_FRAMEMODE|OSD0MODE_RGB16)
+#endif
+
+#ifndef CONFIG_DM320_OSD1_DISABLE
+#  ifdef CONFIG_DM320_OSD1_FRAMEMODE
+#    define OSD1MODE_FRAME 0x0002
+#  else
+#    define OSD1MODE_FRAME 0x0000
+#  endif
+
+#  ifdef CONFIG_DM320_OSD1_TRANSPMODE
+#    ifdef CONFIG_DM320_OSD1_BLEND8THS
+#      if CONFIG_DM320_OSD1_BLEND8THS == 8
+#        define OSD1MODE_TRANSPMODE 0x0004
+#      elif CONFIG_DM320_OSD1_BLEND8THS == 7
+#        define OSD1MODE_TRANSPMODE 0x000c
+#      elif CONFIG_DM320_OSD1_BLEND8THS == 6
+#        define OSD1MODE_TRANSPMODE 0x0014
+#      elif CONFIG_DM320_OSD1_BLEND8THS == 5
+#        define OSD1MODE_TRANSPMODE 0x001c
+#      elif CONFIG_DM320_OSD1_BLEND8THS == 4
+#        define OSD1MODE_TRANSPMODE 0x0024
+#      elif CONFIG_DM320_OSD1_BLEND8THS == 3
+#        define OSD1MODE_TRANSPMODE 0x002c
+#      elif CONFIG_DM320_OSD1_BLEND8THS == 2
+#        define OSD1MODE_TRANSPMODE 0x0034
+#      elif CONFIG_DM320_OSD1_BLEND8THS == 0
+#        define OSD1MODE_TRANSPMODE 0x003c
+#      else
+#        error "Invalid OSD1 transparency selection"
+#      endif
+#    else
+#      define OSD1MODE_TRANSPMODE 0x0004
+#    endif
+#  else
+#    define OSD1MODE_TRANSPMODE 0x0000
+#  endif
+
+#  ifdef CONFIG_DM320_OSD1_RGB16
+#    define OSD1MODE_RGB16 0x2000
+#  else
+#    define OSD1MODE_RGB16 0x0000
+#  endif
+
+#  ifdef CONFIG_DM32_OSD1_ATTRIB
+#    define OSD1MODE_ATTRIB 0x8000
+#  else
+#    define OSD1MODE_ATTRIB 0x0000
+#  endif
+
+#  define INITIAL_OSD1MODE (0x00c1|OSD1MODE_TRANSPMODE|OSD1MODE_FRAME|OSD1MODE_RGB16|OSD1MODE_ATTRIB)
+#endif
+
+/* Rectangular cursor mode */
+
+#ifdef CONFIG_FB_HWCURSOR
+#  define DM320_RECTCURSOR_SETUP \
+   ((CONFIG_DM320_CURSORLINEHEIGHT << 1) | \
+    (CONFIG_DM320_CURSORLINEWIDTH <<4) | \
+    (CONFIG_DM320_CURSORCLUT << 8))
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Initialization */
+
+static int  dm320_allocvideomemory(void);
+static void dm320_freevideomemory(void);
+static void dm320_hwinitialize(void);
+
+/* Framebuffer interface methods */
+
+#ifndef CONFIG_DM320_VID0_DISABLE
+static int dm320_getvid0videoinfo(FAR struct fb_vtable_s *vtable, FAR struct fb_videoinfo_s *vinfo);
+static int dm320_getvid0planeinfo(FAR struct fb_vtable_s *vtable, int planeno, FAR struct fb_planeinfo_s *pinfo);
+#endif
+#ifndef CONFIG_DM320_VID1_DISABLE
+static int dm320_getvid1videoinfo(FAR struct fb_vtable_s *vtable, FAR struct fb_videoinfo_s *vinfo);
+static int dm320_getvid1planeinfo(FAR struct fb_vtable_s *vtable, int planeno, FAR struct fb_planeinfo_s *pinfo);
+#endif
+#ifndef CONFIG_DM320_OSD0_DISABLE
+static int dm320_getosd0videoinfo(FAR struct fb_vtable_s *vtable, FAR struct fb_videoinfo_s *vinfo);
+static int dm320_getosd0planeinfo(FAR struct fb_vtable_s *vtable, int planeno, FAR struct fb_planeinfo_s *pinfo);
+#endif
+#ifndef CONFIG_DM320_OSD1_DISABLE
+static int dm320_getosd1videoinfo(FAR struct fb_vtable_s *vtable, FAR struct fb_videoinfo_s *vinfo);
+static int dm320_getosd1planeinfo(FAR struct fb_vtable_s *vtable, int planeno, FAR struct fb_planeinfo_s *pinfo);
+#endif
+#if defined(CONFIG_FB_CMAP) && (!defined(CONFIG_DM320_OSD0_DISABLE) && !defined(CONFIG_DM320_OSD1_DISABLE))
+static int dm320_getcmap(FAR struct fb_vtable_s *vtable, FAR struct fb_cmap_s *cmap);
+static int dm320_putcmap(FAR struct fb_vtable_s *vtable, FAR const struct fb_cmap_s *cmap);
+#endif
+#ifdef CONFIG_FB_HWCURSOR
+static int dm320_getcursor(FAR struct fb_vtable_s *vtable, FAR struct fb_cursorattrib_s *attrib);
+static int dm320_setcursor(FAR struct fb_vtable_s *vtable, FAR struct fb_setcursor_s *setttings);
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* These are the addresses of allocated framebuffer memory regions */
+
+#ifndef CONFIG_DM320_VID0_DISABLE
+static FAR void *g_vid0base = 0;
+#ifndef CONFIG_DM320_DISABLE_PINGPONG
+static FAR void *g_vid0ppbase = 0;
+#endif
+
+static const struct fb_vtable_s g_vid0vtable =
+{
+  .getvideoinfo = dm320_getvid0videoinfo,
+  .getplaneinfo = dm320_getvid0planeinfo,
+#ifdef CONFIG_FB_HWCURSOR
+  .getcursor    = dm320_getcursor,
+  .setcursor    = dm320_setcursor,
+#endif
+};
+
+#endif
+
+#ifndef CONFIG_DM320_VID1_DISABLE
+static FAR void *g_vid1base = 0;
+
+static const struct fb_vtable_s g_vid1vtable =
+{
+  .getvideoinfo = dm320_getvid1videoinfo,
+  .getplaneinfo = dm320_getvid1planeinfo,
+#ifdef CONFIG_FB_HWCURSOR
+  .getcursor    = dm320_getcursor,
+  .setcursor    = dm320_setcursor,
+#endif
+};
+#endif
+
+#ifndef CONFIG_DM320_OSD0_DISABLE
+static FAR void *g_osd0base = 0;
+static const struct fb_vtable_s g_osd0vtable =
+{
+  .getvideoinfo = dm320_getosd0videoinfo,
+  .getplaneinfo = dm320_getosd0planeinfo,
+#if defined(CONFIG_FB_CMAP) && (!defined(CONFIG_DM320_OSD0_DISABLE) && !defined(CONFIG_DM320_OSD1_DISABLE))
+  .getcmap      = dm320_getcmap,
+  .putcmap      = dm320_putcmap,
+#endif
+#ifdef CONFIG_FB_HWCURSOR
+  .getcursor    = dm320_getcursor,
+  .setcursor    = dm320_setcursor,
+#endif
+};
+
+#endif
+
+#ifndef CONFIG_DM320_OSD1_DISABLE
+static FAR void *g_osd1base = 0;
+static const struct fb_vtable_s g_osd1vtable =
+{
+  .getvideoinfo = dm320_getosd1videoinfo,
+  .getplaneinfo = dm320_getosd1planeinfo,
+#if defined(CONFIG_FB_CMAP) && (!defined(CONFIG_DM320_OSD0_DISABLE) && !defined(CONFIG_DM320_OSD1_DISABLE))
+  .getcmap      = dm320_getcmap,
+  .putcmap      = dm320_putcmap,
+#endif
+#ifdef CONFIG_FB_HWCURSOR
+  .getcursor    = dm320_getcursor,
+  .setcursor    = dm320_setcursor,
+#endif
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static inline void dm320_blankscreen(ubyte *buffer, int len)
+{
+  memset(buffer, 0xff, len);
+}
+
+static inline uint32 dm320_physaddr(FAR void *fb_vaddr)
+{
+  return (uint32)fb_vaddr - DM320_SDRAM_VADDR;
+}
+
+#ifndef CONFIG_DM320_VID0_DISABLE
+static inline uint32 dm320_vid0upperoffset(void)
+{
+  return (((dm320_physaddr(g_vid0base) / 32) >> 16) & 0xff);
+}
+
+static inline uint32 dm320_vid0loweroffset(void)
+{
+  return ((dm320_physaddr(g_vid0base) / 32) & 0xffff);
+}
+
+#ifndef CONFIG_DM320_DISABLE_PINGPONG
+static inline uint32 dm320_vid0ppupperoffset(void)
+{
+  return (((dm320_physaddr(g_vid0ppbase) / 32) >> 16) & 0xff);
+}
+
+static inline uint32 dm320_vid0pploweroffset(void)
+{
+  return ((dm320_physaddr(g_vid0ppbase) / 32) & 0xffff);
+}
+#endif
+#endif
+
+#ifndef CONFIG_DM320_VID1_DISABLE
+static inline uint32 dm320_vid1upperoffset(void)
+{
+  return (((dm320_physaddr(g_vid1base) / 32) >> 16) & 0xff);
+}
+
+static inline uint32 dm320_vid1loweroffset(void)
+{
+  return ((dm320_physaddr(g_vid1base) / 32) & 0xffff);
+}
+#endif
+
+#ifndef CONFIG_DM320_OSD0_DISABLE
+static inline uint32 dm320_osd0upperoffset(void)
+{
+  return (((dm320_physaddr(g_osd0base) / 32) >> 16) & 0xff);
+}
+
+static inline uint32 dm320_osd0loweroffset(void)
+{
+  return ((dm320_physaddr(g_osd0base) / 32) & 0xffff);
+}
+#endif
+
+#ifndef CONFIG_DM320_OSD1_DISABLE
+static inline uint32 dm320_osd1upperoffset(void)
+{
+  return (((dm320_physaddr(g_osd1base) / 32) >> 16) & 0xff);
+}
+
+static inline uint32 dm320_osd1loweroffset(void)
+{
+  return ((dm320_physaddr(g_osd1base) / 32) & 0xffff);
+}
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * dm320_allocvideomemory
+ ****************************************************************************/
+
+static int dm320_allocvideomemory(void)
+{
+#ifndef CONFIG_DM320_VID0_DISABLE
+#ifndef CONFIG_DM320_DISABLE_PINGPONG
+  g_vid0base   = (FAR void *)malloc(2 * DM320_VID0_FBLEN);
+  g_vid0ppbase = (FAR char*)g_vid0base + DM320_VID0_FBLEN;
+#else
+  g_vid0base   = (FAR void *)malloc(DM320_VID0_FBLEN);
+#endif
+  if (!g_vid0base)
+    {
+      goto errout;
+    }
+#endif
+
+#ifndef CONFIG_DM320_VID1_DISABLE
+  g_vid1base = (FAR void *)malloc(DM320_VID1_FBLEN);
+  if (!g_vid1base)
+    {
+      goto errout;
+    }
+#endif
+
+#ifndef CONFIG_DM320_OSD0_DISABLE
+  g_osd0base = (FAR void *)malloc(DM320_OSD0_FBLEN);
+  if (!g_osd0base)
+    {
+      goto errout;
+    }
+#endif
+
+#ifndef CONFIG_DM320_OSD1_DISABLE
+  g_osd1base = (FAR void *)malloc(DM320_OSD1_FBLEN);
+  if (!g_osd1base)
+    {
+      goto errout;
+    }
+#endif
+
+  return OK;
+
+errout:
+  dm320_freevideomemory();
+  return -ENOMEM;
+}
+
+/****************************************************************************
+ * Name: dm320_freevideomemory
+ ****************************************************************************/
+
+static void dm320_freevideomemory(void)
+{
+#ifndef CONFIG_DM320_VID0_DISABLE
+  if (g_vid0base)
+    {
+      free(g_vid0base);
+      g_vid0base = NULL;
+#ifndef CONFIG_DM320_DISABLE_PINGPONG
+      g_vid0ppbase = NULL;
+#endif
+    }
+#endif
+
+#ifndef CONFIG_DM320_VID1_DISABLE
+  if (g_vid1base != 0)
+    {
+      free(g_vid1base);
+      g_vid1base = NULL;
+    }
+#endif
+
+#ifndef CONFIG_DM320_OSD0_DISABLE
+  if (g_osd0base != 0)
+    {
+      free(g_osd0base);
+      g_osd0base = NULL;
+    }
+#endif
+
+#ifndef CONFIG_DM320_OSD1_DISABLE
+  if (g_osd1base != 0)
+    {
+      free(g_osd1base);
+      g_osd1base = NULL;
+    }
+#endif
+}
+
+/****************************************************************************
+ * Name: dm320_disable
+ ****************************************************************************/
+
+static void dm320_disable(void)
+{
+  /* Disable all planes */
+
+  gvdbg("Inactivate OSD:\n");
+
+  putreg16(0, DM320_OSD_OSDWIN0MD); /* Win0 mode = 0 (1:active) */
+  putreg16(0, DM320_OSD_OSDWIN1MD); /* Win1 mode = 0 (1:active) */
+  putreg16(0, DM320_OSD_RECTCUR);   /* Rectangular cursor mode = 0 (1:active) */
+
+  gvdbg("DM320_OSD_OSDWIN0MD:   %04x\n", getreg16(DM320_OSD_OSDWIN0MD));
+  gvdbg("DM320_OSD_OSDWIN1MD:   %04x\n", getreg16(DM320_OSD_OSDWIN1MD));
+  gvdbg("DM320_OSD_RECTCUR:     %04x\n", getreg16(DM320_OSD_RECTCUR));
+}
+
+/****************************************************************************
+ * Name: dm320_hwinitialize
+ ****************************************************************************/
+
+static void dm320_hwinitialize(void)
+{
+  /* Disable all planes */
+
+  dm320_disable();
+
+  /* Initialize the main video to correct the origin */
+
+  gvdbg("Setup main video origin:\n");
+
+  putreg16(CONFIG_DM320_BASEX, DM320_OSD_BASEPX);
+  putreg16(CONFIG_DM320_BASEY, DM320_OSD_BASEPY);
+
+  gvdbg("DM320_OSD_BASEPX:      %04x\n", getreg16(DM320_OSD_BASEPX));
+  gvdbg("DM320_OSD_BASEPY:      %04x\n", getreg16(DM320_OSD_BASEPY));
+
+  /* Set up the frame buffer address registers */
+
+  gvdbg("Setup framebuffer addresses:\n");
+
+
+  putreg16(((dm320_osd1upperoffset() << 8) |
+        dm320_osd0upperoffset()), DM320_OSD_OSDWINADH);
+  putreg16(dm320_osd0loweroffset(), DM320_OSD_OSDWIN0ADL);
+  putreg16(dm320_osd1loweroffset(), DM320_OSD_OSDWIN1ADL);
+
+  gvdbg("DM320_OSD_OSDWINADH:   %04x\n", getreg16(DM320_OSD_OSDWINADH));
+  gvdbg("DM320_OSD_OSDWIN0ADL:  %04x\n", getreg16(DM320_OSD_OSDWIN0ADL));
+  gvdbg("DM320_OSD_OSDWIN1ADL:  %04x\n", getreg16(DM320_OSD_OSDWIN1ADL));
+
+  /* Set up VID WIN0 */
+
+#if defined(CONFIG_DM320_VID0_DISABLE) || defined(CONFIG_DM320_VID1_DISABLE)
+  putreg16(((dm320_vid1upperoffset() << 8) | dm320_vid0upperoffset()), DM320_OSD_VIDWINADH);
+#endif
+
+#ifndef CONFIG_DM320_VID0_DISABLE
+  gvdbg("Initialize video win0:\n");
+  putreg16(dm320_vid0loweroffset(), DM320_OSD_VIDWIN0ADL);
+
+  gvdbg("DM320_OSD_VIDWINADH:   %04x\n", getreg16(DM320_OSD_VIDWINADH));
+  gvdbg("DM320_OSD_VIDWIN0ADL:  %04x\n", getreg16(DM320_OSD_VIDWIN0ADL));
+  dm320_blankscreen((ubyte *)g_vid0base, DM320_VID0_FBLEN);
+
+#ifndef CONFIG_DM320_DISABLE_PINGPONG
+  putreg16(dm320_vid0ppupperoffset(), DM320_OSD_PPVWIN0ADH);
+  putreg16(dm320_vid0pploweroffset(), DM320_OSD_PPVWIN0ADL);
+
+  gvdbg("DM320_OSD_PPVWIN0ADH:  %04x\n", getreg16(DM320_OSD_PPVWIN0ADH));
+  gvdbg("DM320_OSD_PPVWIN0ADL:  %04x\n", getreg16(DM320_OSD_PPVWIN0ADL));
+  dm320_blankscreen((ubyte *)g_vid0ppbase, DM320_VID0_FBLEN);
+#endif
+
+  putreg16(CONFIG_DM320_VID0_XPOS, DM320_OSD_VIDWIN0XP);
+  putreg16(CONFIG_DM320_VID0_YPOS, DM320_OSD_VIDWIN0YP);
+  putreg16((CONFIG_DM320_VID0_XRES >> 4), DM320_OSD_VIDWIN0OFST);
+  putreg16(CONFIG_DM320_VID0_XRES, DM320_OSD_VIDWIN0XL);
+  putreg16(CONFIG_DM320_VID0_YRES, DM320_OSD_VIDWIN0YL);
+
+  gvdbg("DM320_OSD_VIDWIN0XP:   %04x\n", getreg16(DM320_OSD_VIDWIN0XP));
+  gvdbg("DM320_OSD_VIDWIN0YP:   %04x\n", getreg16(DM320_OSD_VIDWIN0YP));
+  gvdbg("DM320_OSD_VIDWIN0OFST: %04x\n", getreg16(DM320_OSD_VIDWIN0OFST));
+  gvdbg("DM320_OSD_VIDWIN0XL:   %04x\n", getreg16(DM320_OSD_VIDWIN0XL));
+  gvdbg("DM320_OSD_VIDWIN0YL:   %04x\n", getreg16(DM320_OSD_VIDWIN0YL));
+#endif
+
+  /* Set up VID WIN1 */
+
+#ifndef CONFIG_DM320_VID1_DISABLE
+  gvdbg("Initialize video win1:\n");
+  putreg16(dm320_vid1loweroffset(), DM320_OSD_VIDWIN1ADL);
+
+  gvdbg("DM320_OSD_VIDWINADH:   %04x\n", getreg16(DM320_OSD_VIDWINADH));
+  gvdbg("DM320_OSD_VIDWIN1ADL:  %04x\n", getreg16(DM320_OSD_VIDWIN1ADL));
+  dm320_blankscreen((ubyte *)g_vid1base, DM320_VID1_FBLEN);
+
+  putreg16(CONFIG_DM320_VID1_XPOS, DM320_OSD_VIDWIN1XP);
+  putreg16(CONFIG_DM320_VID1_XPOS, DM320_OSD_VIDWIN1YP);
+  putreg16((CONFIG_DM320_VID1_XRES >> 4), DM320_OSD_VIDWIN1OFST);
+  putreg16(CONFIG_DM320_VID1_XRES, DM320_OSD_VIDWIN1XL);
+  putreg16(CONFIG_DM320_VID1_YRES, DM320_OSD_VIDWIN1YL);
+
+  gvdbg("DM320_OSD_VIDWIN1XP:   %04x\n", getreg16(DM320_OSD_VIDWIN1XP));
+  gvdbg("DM320_OSD_VIDWIN1YP:   %04x\n", getreg16(DM320_OSD_VIDWIN1YP));
+  gvdbg("DM320_OSD_VIDWIN1OFST: %04x\n", getreg16(DM320_OSD_VIDWIN1OFST));
+  gvdbg("DM320_OSD_VIDWIN1XL:   %04x\n", getreg16(DM320_OSD_VIDWIN1XL));
+  gvdbg("DM320_OSD_VIDWIN1YL:   %04x\n", getreg16(DM320_OSD_VIDWIN1YL));
+#endif
+
+  putreg16(DM320_VIDMODE, DM320_OSD_VIDWINMD);
+  gvdbg("DM320_OSD_VIDWINMD:    %04x\n", getreg16(DM320_OSD_VIDWINMD));
+
+  /* Set up OSD WIN0 */
+
+#ifndef CONFIG_DM320_OSD0_DISABLE
+  gvdbg("Initialize OSD win0:\n");
+  dm320_blankscreen((ubyte *)g_osd0base, DM320_OSD0_FBLEN);
+
+  putreg16(CONFIG_DM320_OSD0_XPOS, DM320_OSD_OSDWIN0XP);
+  putreg16(CONFIG_DM320_OSD0_YPOS, DM320_OSD_OSDWIN0YP);
+#ifdef CONFIG_DM320_OSD1_RGB16
+  putreg16((CONFIG_DM320_OSD0_XRES >> 4), DM320_OSD_OSDWIN0OFST);
+#else
+  putreg16((CONFIG_DM320_OSD0_XRES >> 5), DM320_OSD_OSDWIN0OFST);
+#endif
+  putreg16(CONFIG_DM320_OSD0_XRES, DM320_OSD_OSDWIN0XL);
+  putreg16(CONFIG_DM320_OSD0_YRES, DM320_OSD_OSDWIN0YL);
+  putreg16(INITIAL_OSD0MODE, DM320_OSD_OSDWIN0MD);
+
+  gvdbg("DM320_OSD_OSDWIN0XP:   %04x\n", getreg16(DM320_OSD_OSDWIN0XP));
+  gvdbg("DM320_OSD_OSDWIN0YP:   %04x\n", getreg16(DM320_OSD_OSDWIN0YP));
+  gvdbg("DM320_OSD_OSDWIN0OFST: %04x\n", getreg16(DM320_OSD_OSDWIN0OFST));
+  gvdbg("DM320_OSD_OSDWIN0XL:   %04x\n", getreg16(DM320_OSD_OSDWIN0XL));
+  gvdbg("DM320_OSD_OSDWIN0YL:   %04x\n", getreg16(DM320_OSD_OSDWIN0YL));
+  gvdbg("DM320_OSD_OSDWIN0MD:   %04x\n", getreg16(DM320_OSD_OSDWIN0MD));
+#endif
+
+  /* Set up OSD WIN1 */
+
+#ifndef CONFIG_DM320_OSD1_DISABLE
+  gvdbg("Initialize OSD win1\n");
+  dm320_blankscreen((ubyte *)g_osd1base, DM320_OSD1_FBLEN);
+
+  putreg16(CONFIG_DM320_OSD1_XPOS, DM320_OSD_OSDWIN1XP);
+  putreg16(CONFIG_DM320_OSD1_YPOS, DM320_OSD_OSDWIN1YP);
+#ifdef CONFIG_DM320_OSD1_RGB16
+  putreg16((CONFIG_DM320_OSD1_XRES >> 4), DM320_OSD_OSDWIN1OFST);
+#else
+  putreg16((CONFIG_DM320_OSD1_XRES >> 5), DM320_OSD_OSDWIN1OFST);
+#endif
+  putreg16(CONFIG_DM320_OSD1_XRES, DM320_OSD_OSDWIN1XL);
+  putreg16(CONFIG_DM320_OSD1_YRES, DM320_OSD_OSDWIN1YL);
+  putreg16(INITIAL_OSD1MODE, DM320_OSD_OSDWIN1MD);
+
+  gvdbg("DM320_OSD_OSDWIN1XP:   %04x\n", getreg16(DM320_OSD_OSDWIN1XP));
+  gvdbg("DM320_OSD_OSDWIN1YP:   %04x\n", getreg16(DM320_OSD_OSDWIN1YP));
+  gvdbg("DM320_OSD_OSDWIN1OFST: %04x\n", getreg16(DM320_OSD_OSDWIN1OFST));
+  gvdbg("DM320_OSD_OSDWIN1XL:   %04x\n", getreg16(DM320_OSD_OSDWIN1XL));
+  gvdbg("DM320_OSD_OSDWIN1YL:   %04x\n", getreg16(DM320_OSD_OSDWIN1YL));
+  gvdbg("DM320_OSD_OSDWIN1MD:   %04x\n", getreg16(DM320_OSD_OSDWIN1MD));
+#endif
+
+  /* Set up the rectangular cursor with defaults */
+
+#ifdef CONFIG_FB_HWCURSOR
+  gdbg("Initialize rectangular cursor\n");
+
+  putreg16(0, DM320_OSD_CURXP);
+  putreg16(0, DM320_OSD_CURYP);
+  putreg16(CONFIG_DM320_RECTCURSOR_WIDTH, DM320_OSD_CURXL);
+  putreg16(CONFIG_DM320_RECTCURSOR_HEIGHT, DM320_OSD_CURYL);
+
+  /* DM320_RECTCURSOR_SETUP:
+   *
+   * Bit 0: 0=rectangular cursor inactive 1=on             0
+   * Bits 113: Vertical line height: {1,2,4,6,8,10,12,14}  CONFIG_DM320_CURSORLINEHEIGHT
+   * 4:6: Horizontal line width: {1,4,8,16,20,24,28}       CONFIG_DM320_CURSORLINEWIDTH
+   * 7: 0=ROM lookup table, 1=RAM lookup table             0
+   * 8:15: Rectangular cursor color pallette address       CONFIG_DM320_CURSORCLUT
+   */
+
+  putreg16(DM320_RECTCURSOR_SETUP, DM320_OSD_RECTCUR);
+
+  gvdbg("DM320_OSD_CURXP:       %04x\n", getreg16(DM320_OSD_CURXP));
+  gvdbg("DM320_OSD_CURYP:       %04x\n", getreg16(DM320_OSD_CURYP));
+  gvdbg("DM320_OSD_CURXL:       %04x\n", getreg16(DM320_OSD_CURXL));
+  gvdbg("DM320_OSD_CURYL:       %04x\n", getreg16(DM320_OSD_CURYL));
+  gvdbg("DM320_OSD_RECTCUR:     %04x\n", getreg16(DM320_OSD_RECTCUR));
+#endif
+
+  /* Set main window to the hardware default state.  That initial
+   * state is:
+   *
+   * FIELD                                         SETTING
+   * Bits 0-7: background color clut               CONFIG_DM320_BKGDCLUT
+   * Bit 8: background clut 0=ROM 1=RAM            0
+   * Bit 9: field signal 0=normal 1=inverted       0
+   * Bit 10: vid window H expansion: 1=x9/8        0
+   * Bit 11: vid window V expansion: 1=x6/5        0
+   * Bit 12: expansion filter 0=off 1=on           0
+   * Bit 13: osd window H expansion: 1=x9/8        0
+   * Bit 14: osd window V expansion: 1=x6/5        0
+   * Bit 1515: 0=offset binary, 1=complement of 2  0
+   */
+
+  putreg16(CONFIG_DM320_BKGDCLUT, DM320_OSD_OSDMODE);
+  gvdbg("DM320_OSD_OSDMODE:     %04x\n", getreg16(DM320_OSD_OSDMODE));
+}
+
+/****************************************************************************
+ * Name: dm320_getvid0videoinfo
+ ****************************************************************************/
+
+#ifndef CONFIG_DM320_VID0_DISABLE
+static int dm320_getvid0videoinfo(FAR struct fb_vtable_s *vtable,
+                                  FAR struct fb_videoinfo_s *vinfo)
+{
+#ifdef CONFIG_DEBUG
+  if (!vtable || !vinfo)
+    {
+      return -EINVAL;
+    }
+#endif
+
+  vinfo->fmt     = FB_FMT_UYVY;
+  vinfo->xres    = CONFIG_DM320_VID0_XRES;
+  vinfo->yres    = CONFIG_DM320_VID0_YRES;
+  vinfo->nplanes = 1;
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: dm320_getvid0planeinfo
+ ****************************************************************************/
+
+#ifndef CONFIG_DM320_VID0_DISABLE
+static int dm320_getvid0planeinfo(FAR struct fb_vtable_s *vtable, int planeno,
+                                  FAR struct fb_planeinfo_s *pinfo)
+{
+#ifdef CONFIG_DEBUG
+  if (!vtable || !pinfo)
+    {
+      return -EINVAL;
+    }
+#endif
+
+  pinfo->fbmem  = g_vid0base;
+  pinfo->fblen  = DM320_VID0_FBLEN;
+  pinfo->stride = DM320_VID0_STRIDE;
+  pinfo->bpp    = DM320_VID0_BPP;
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: dm320_getvid1videoinfo
+ ****************************************************************************/
+
+#ifndef CONFIG_DM320_VID1_DISABLE
+static int dm320_getvid1videoinfo(FAR struct fb_vtable_s *vtable,
+                                  FAR struct fb_videoinfo_s *vinfo)
+{
+#ifdef CONFIG_DEBUG
+  if (!vtable || !vinfo)
+    {
+      return -EINVAL;
+    }
+#endif
+
+  vinfo->fmt     = FB_FMT_UYVY;
+  vinfo->xres    = CONFIG_DM320_VID1_XRES;
+  vinfo->yres    = CONFIG_DM320_VID1_YRES;
+  vinfo->nplanes = 1;
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: dm320_getvid1planeinfo
+ ****************************************************************************/
+
+#ifndef CONFIG_DM320_VID1_DISABLE
+static int dm320_getvid1planeinfo(FAR struct fb_vtable_s *vtable, int planeno,
+                                  FAR struct fb_planeinfo_s *pinfo)
+{
+#ifdef CONFIG_DEBUG
+  if (!vtable || !pinfo)
+    {
+      return -EINVAL;
+    }
+#endif
+
+  pinfo->fbmem  = g_vid1base;
+  pinfo->fblen  = DM320_VID1_FBLEN;
+  pinfo->stride = DM320_VID1_STRIDE;
+  pinfo->bpp    = DM320_VID1_BPP;
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: dm320_getosd0osdeoinfo
+ ****************************************************************************/
+
+#ifndef CONFIG_DM320_OSD0_DISABLE
+static int dm320_getosd0videoinfo(FAR struct fb_vtable_s *vtable,
+                                  FAR struct fb_videoinfo_s *vinfo)
+{
+#ifdef CONFIG_DEBUG
+  if (!vtable || !vinfo)
+    {
+      return -EINVAL;
+    }
+#endif
+
+#ifdef CONFIG_DM320_OSD0_RGB16
+  vinfo->fmt     = FB_FMT_RGB16_565;
+#else
+  vinfo->fmt     = FB_FMT_RGB8;
+#endif
+  vinfo->xres    = CONFIG_DM320_OSD0_XRES;
+  vinfo->yres    = CONFIG_DM320_OSD0_YRES;
+  vinfo->nplanes = 1;
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: dm320_getosd0planeinfo
+ ****************************************************************************/
+
+#ifndef CONFIG_DM320_OSD0_DISABLE
+static int dm320_getosd0planeinfo(FAR struct fb_vtable_s *vtable, int planeno,
+                                  FAR struct fb_planeinfo_s *pinfo)
+{
+#ifdef CONFIG_DEBUG
+  if (!vtable || !pinfo)
+    {
+      return -EINVAL;
+    }
+#endif
+
+  pinfo->fbmem  = g_osd0base;
+  pinfo->fblen  = DM320_OSD0_FBLEN;
+  pinfo->stride = DM320_OSD0_STRIDE;
+  pinfo->bpp    = DM320_OSD0_BPP;
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: dm320_getosd1osdeoinfo
+ ****************************************************************************/
+
+#ifndef CONFIG_DM320_OSD1_DISABLE
+static int dm320_getosd1videoinfo(FAR struct fb_vtable_s *vtable,
+                                  FAR struct fb_videoinfo_s *vinfo)
+{
+#ifdef CONFIG_DEBUG
+  if (!vtable || !vinfo)
+    {
+      return -EINVAL;
+    }
+#endif
+
+#ifdef CONFIG_DM320_OSD1_RGB16
+  vinfo->fmt     = FB_FMT_RGB16_565;
+#else
+  vinfo->fmt     = FB_FMT_RGB8;
+#endif
+  vinfo->xres    = CONFIG_DM320_OSD1_XRES;
+  vinfo->yres    = CONFIG_DM320_OSD1_YRES;
+  vinfo->nplanes = 1;
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: dm320_getosd1planeinfo
+ ****************************************************************************/
+
+#ifndef CONFIG_DM320_OSD1_DISABLE
+static int dm320_getosd1planeinfo(FAR struct fb_vtable_s *vtable, int planeno,
+                                  FAR struct fb_planeinfo_s *pinfo)
+{
+#ifdef CONFIG_DEBUG
+  if (!vtable || !pinfo)
+    {
+      return -EINVAL;
+    }
+#endif
+
+  pinfo->fbmem  = g_osd1base;
+  pinfo->fblen  = DM320_OSD1_FBLEN;
+  pinfo->stride = DM320_OSD1_STRIDE;
+  pinfo->bpp    = DM320_OSD1_BPP;
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: dm320_getcmap
+ ****************************************************************************/
+
+#if defined(CONFIG_FB_CMAP) && (!defined(CONFIG_DM320_OSD0_DISABLE) && !defined(CONFIG_DM320_OSD1_DISABLE))
+static int dm320_getcmap(FAR struct fb_vtable_s *vtable, FAR struct fb_cmap_s *cmap)
+{
+  /* I don't think the RAM clut is readable */
+
+  return -ENOSYS;
+}
+#endif
+
+/****************************************************************************
+ * Name: dm320_putcmap
+ ****************************************************************************/
+
+#if defined(CONFIG_FB_CMAP) && (!defined(CONFIG_DM320_OSD0_DISABLE) && !defined(CONFIG_DM320_OSD1_DISABLE))
+static int dm320_putcmap(FAR struct fb_vtable_s *vtable, FAR struct fb_cmap_s *cmap)
+{
+  irqstate_t flags;
+  uint16 regval;
+  ubyte y;
+  ubyte u;
+  ubyte v;
+  int   len
+  int   i;
+
+#ifdef CONFIG_DEBUG
+  if (!vtable || !cmap || !cmap->read || !cmap->green || !cmap->blue)
+    {
+      return -EINVAL;
+    }
+#endif
+
+  flags = irqsave();
+  for (i = cmap.first, len = 0; i < 256 && len < cmap.len, i++, len++)
+    {
+       /* Convert the RGB to YUV */
+
+       rgb2yuv(cmap->red[i], cmap->green[i], cmap->blue[i], &y, &u, &v);
+
+       /* Program the CLUT */
+
+       while (getreg16(DM320_OSD_MISCCTL) & 0x8);
+       putreg16(((uint16)y) << 8 | uint16(u)), DM320_OSD_CLUTRAMYCB);
+       putreg16(((uint16)v << 8 | i), DM320_OSD_CLUTRAMCR);
+    }
+
+  /* Select RAM clut */
+
+#if !defined(CONFIG_DM320_OSD0_DISABLE) && !defined(CONFIG_DM320_OSD0_RGB16)
+  regval = getreg16(DM320_OSD_OSDWIN0MD);
+  regval |= 0x1000;
+  putreg16(regval, DM320_OSD_OSDWIN0MD);
+#endif
+
+#if !defined(CONFIG_DM320_OSD1_DISABLE) && !defined(CONFIG_DM320_OSD1_RGB16)
+  regval = getreg16(DM320_OSD_OSDWIN1MD);
+  regval |= 0x1000;
+  putreg16(regval, DM320_OSD_OSDWIN1MD);
+#endif
+
+  return 0;
+}
+#endif
+
+/****************************************************************************
+ * Name: dm320_getcursor
+ ****************************************************************************/
+
+#ifdef CONFIG_FB_HWCURSOR
+static int dm320_getcursor(FAR struct fb_vtable_s *vtable, FAR struct fb_cursorattrib_s *attrib)
+{
+  irqstate_t flags;
+
+#ifdef CONFIG_DEBUG
+  if (!vtable || !attrib)
+    {
+      return -EINVAL;
+    }
+#endif
+
+  flags = irqsave();
+  attrib->pos.x = getreg16(DM320_OSD_CURXP);
+  attrib->pos.y = getreg16(DM320_OSD_CURYP);
+
+#ifdef CONFIG_FB_HWCURSORSIZE
+  attrib->size.w = getreg16(DM320_OSD_CURXL);
+  attrib->size.h = getreg16(DM320_OSD_CURYL);
+#endif
+  irqrestore();
+
+  attrib->mxsize.w = MAX_XRES;
+  attrib->mxsize.h = MAX_YRES;
+
+  gvdbg("DM320_OSD_CURXP:       %04x\n", attrib->pos.x);
+  gvdbg("DM320_OSD_CURYP:       %04x\n", attrib->pos.y);
+#ifdef CONFIG_FB_HWCURSORSIZE
+  gvdbg("DM320_OSD_CURXL:       %04x\n", attrib->size.w);
+  gvdbg("DM320_OSD_CURYL:       %04x\n", attrib->size.h);
+#else
+  gvdbg("DM320_OSD_CURXL:       %04x\n", getreg16(DM320_OSD_CURXL));
+  gvdbg("DM320_OSD_CURYL:       %04x\n", getreg16(DM320_OSD_CURYL));
+#endif
+  gvdbg("DM320_OSD_RECTCUR:     %04x\n", getreg16(DM320_OSD_RECTCUR));
+}
+#endif
+
+/****************************************************************************
+ * Name: dm320_setcursor
+ ****************************************************************************/
+
+#ifdef CONFIG_FB_HWCURSOR
+static int dm320_setcursor(FAR struct fb_vtable_s *vtable, FAR struct fb_setcursor_s *settings)
+{
+  irqstate_t flags;
+  uint16 regval;
+
+#ifdef CONFIG_DEBUG
+  if (!vtable || !settings)
+    {
+      return -EINVAL;
+    }
+#endif
+
+  /* Set cursor position */
+
+  flags = irqsave();
+  if ((settings->flags & FB_CUR_SETPOSITION) != 0)
+    {
+      gvdbg("x=%d y=%d\n", settings->pos.x, settings->pos.y);
+
+     if (settings->pos.x > MAX_YRES)
+       {
+          settings->pos.x = MAX_YRES;
+       }
+
+     if (settings->pos.y > MAX_YRES)
+       {
+          settings->pos.y = MAX_YRES;
+       }
+
+     putreg16(settings->pos.x, DM320_OSD_CURXP);
+     putreg16(settings->pos.y, DM320_OSD_CURYP);
+   }
+
+#ifdef CONFIG_FB_HWCURSORSIZE
+  if ((settings->flags & FB_CUR_SETSIZE) != 0)
+    {
+      gvdbg("h=%d w=%d\n", settings->size.h, settings->size.w);
+
+     if (settings->size.w > MAX_YRES)
+       {
+          settings->size.w = MAX_YRES;
+       }
+
+     if (settings->size.h > MAX_YRES)
+       {
+          settings->size.h = MAX_YRES;
+       }
+
+     flags = irqsave();
+     putreg16(settings->size.w, DM320_OSD_CURXL);
+     putreg16(settings->size.h, DM320_OSD_CURYL);
+     restore_flags(flags);
+   }
+#endif
+
+  regval = getreg16(DM320_OSD_RECTCUR);
+  if ((settings->flags & FB_CUR_ENABLE) != 0)
+    {
+      regval |= 1;
+    }
+  else
+    {
+      regval &= ~1;
+    }
+  putreg16(regval, DM320_OSD_RECTCUR);
+  restore_flags(flags);
+
+  gvdbg("DM320_OSD_CURXP:       %04x\n", getreg16(DM320_OSD_CURXP));
+  gvdbg("DM320_OSD_CURYP:       %04x\n", getreg16(DM320_OSD_CURYP));
+  gvdbg("DM320_OSD_CURXL:       %04x\n", getreg16(DM320_OSD_CURXL));
+  gvdbg("DM320_OSD_CURYL:       %04x\n", getreg16(DM320_OSD_CURYL));
+  gvdbg("DM320_OSD_RECTCUR:     %04x\n", getreg16(DM320_OSD_RECTCUR));
+}
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_fbinitialize
+ ****************************************************************************/
+
+int up_fbinitialize(void)
+{
+  int ret;
+
+  gvdbg("Allocating framebuffers\n");
+  ret = dm320_allocvideomemory();
+  if (ret != 0)
+    {
+      gdbg("Failed to allocate video buffers\n");
+      return ret;
+    }
+
+  /* Initialize the hardware */
+
+  gvdbg("Initializing hardware\n");
+  dm320_hwinitialize();
+  return 0;
+}
+
+/****************************************************************************
+ * Name: up_getvid0vtable
+ ****************************************************************************/
+
+#ifndef CONFIG_DM320_VID0_DISABLE
+FAR struct fb_vtable_s up_getvid0vtable(void)
+{
+  return g_vid0vtable;
+}
+#endif
+
+/****************************************************************************
+ * Name: up_getvid1vtable
+ ****************************************************************************/
+
+#ifndef CONFIG_DM320_VID1_DISABLE
+FAR struct fb_vtable_s up_getvid1vtable(void)
+{
+  return g_vid1vtable;
+}
+#endif
+
+/****************************************************************************
+ * Name: up_getosd0vtable
+ ****************************************************************************/
+
+#ifndef CONFIG_DM320_OSD0_DISABLE
+FAR struct fb_vtable_s up_getosd0vtable(void)
+{
+  return g_osd0vtable;
+}
+#endif
+
+/****************************************************************************
+ * Name: up_getosd1vtable
+ ****************************************************************************/
+
+#ifndef CONFIG_DM320_OSD1_DISABLE
+FAR struct fb_vtable_s up_getosd1vtable(void)
+{
+  return g_osd1vtable;
+}
+#endif
+
+/****************************************************************************
+ * Name: up_fbteardown
+ ****************************************************************************/
+
+void cleanup_module(void)
+{
+  /* Disable the hardware */
+
+  dm320_disable();
+
+  /* Free the video buffers */
+
+  dm320_freevideomemory();
+}
diff --git a/arch/arm/src/dm320/dm320_osd.h b/arch/arm/src/dm320/dm320_osd.h
new file mode 100644
index 0000000000..a7857590d0
--- /dev/null
+++ b/arch/arm/src/dm320/dm320_osd.h
@@ -0,0 +1,118 @@
+/************************************************************************************
+ * dm320/dm320_osd.h
+ *
+ *   Copyright (C) 2008 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_DM320_DM320_OSD_H
+#define __ARCH_ARM_SRC_DM320_DM320_OSD_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#ifndef __ASSEMBLY__
+# include <sys/types.h>
+#endif
+
+/************************************************************************************
+ * Definitions
+ ************************************************************************************/
+
+/* On Screen Display Register Map (OSD) *********************************************/
+
+#define DM320_OSD_OSDMODE     (DM320_OSD_REGISTER_BASE+0x0000) /* OSD Mode Setup */
+#define DM320_OSD_VIDWINMD    (DM320_OSD_REGISTER_BASE+0x0002) /* Video Window Mode Setup */
+#define DM320_OSD_OSDWIN0MD   (DM320_OSD_REGISTER_BASE+0x0004) /* OSD Window 0 Mode Setup */
+#define DM320_OSD_OSDWIN1MD   (DM320_OSD_REGISTER_BASE+0x0006) /* OSD Window 1 Mode Setup */
+#define DM320_OSD_OSDATRMD    (DM320_OSD_REGISTER_BASE+0x0006) /* OSD Attribute Window Mode Setup */
+#define DM320_OSD_RECTCUR     (DM320_OSD_REGISTER_BASE+0x0008) /* Rectangular Cursor Setup */
+#define DM320_OSD_VIDWIN0OFST (DM320_OSD_REGISTER_BASE+0x000c) /* Video Window 0 Offset */
+#define DM320_OSD_VIDWIN1OFST (DM320_OSD_REGISTER_BASE+0x000e) /* Video Window 1 Offset */
+#define DM320_OSD_OSDWIN0OFST (DM320_OSD_REGISTER_BASE+0x0010) /* OSD Window 0 Offset */
+#define DM320_OSD_OSDWIN1OFST (DM320_OSD_REGISTER_BASE+0x0012) /* OSD Window 1 Offset */
+#define DM320_OSD_VIDWINADH   (DM320_OSD_REGISTER_BASE+0x0014) /* Video Window 0/1 Address - High */
+#define DM320_OSD_VIDWIN0ADL  (DM320_OSD_REGISTER_BASE+0x0016) /* Video Window 0 Address - Low */
+#define DM320_OSD_VIDWIN1ADL  (DM320_OSD_REGISTER_BASE+0x0018) /* Video Window 1 Address - Low */
+#define DM320_OSD_OSDWINADH   (DM320_OSD_REGISTER_BASE+0x001a) /* OSD Window 0/1 Address - High */
+#define DM320_OSD_OSDWIN0ADL  (DM320_OSD_REGISTER_BASE+0x001c) /* OSD Window 0 Address - Low */
+#define DM320_OSD_OSDWIN1ADL  (DM320_OSD_REGISTER_BASE+0x001e) /* OSD Window 1 Address - Low */
+#define DM320_OSD_BASEPX      (DM320_OSD_REGISTER_BASE+0x0020) /* Base Pixel X */
+#define DM320_OSD_BASEPY      (DM320_OSD_REGISTER_BASE+0x0022) /* Base Pixel Y */
+#define DM320_OSD_VIDWIN0XP   (DM320_OSD_REGISTER_BASE+0x0024) /* Video Window 0 X-Position */
+#define DM320_OSD_VIDWIN0YP   (DM320_OSD_REGISTER_BASE+0x0026) /* Video Window 0 Y-Position */
+#define DM320_OSD_VIDWIN0XL   (DM320_OSD_REGISTER_BASE+0x0028) /* Video Window 0 X-Size */
+#define DM320_OSD_VIDWIN0YL   (DM320_OSD_REGISTER_BASE+0x002a) /* Video Window 0 Y-Size */
+#define DM320_OSD_VIDWIN1XP   (DM320_OSD_REGISTER_BASE+0x002c) /* Video Window 1 X-Position */
+#define DM320_OSD_VIDWIN1YP   (DM320_OSD_REGISTER_BASE+0x002e) /* Video Window 1 Y-Position */
+#define DM320_OSD_VIDWIN1XL   (DM320_OSD_REGISTER_BASE+0x0030) /* Video Window 1 X-Size */
+#define DM320_OSD_VIDWIN1YL   (DM320_OSD_REGISTER_BASE+0x0032) /* Video Window 1 Y-Size */
+#define DM320_OSD_OSDWIN0XP   (DM320_OSD_REGISTER_BASE+0x0034) /* OSD Bitmap Window 0 X-Position */
+#define DM320_OSD_OSDWIN0YP   (DM320_OSD_REGISTER_BASE+0x0036) /* OSD Bitmap Window 0 Y-Position */
+#define DM320_OSD_OSDWIN0XL   (DM320_OSD_REGISTER_BASE+0x0038) /* OSD Bitmap Window 0 X-Size */
+#define DM320_OSD_OSDWIN0YL   (DM320_OSD_REGISTER_BASE+0x003a) /* OSD Bitmap Window 0 Y-Size */
+#define DM320_OSD_OSDWIN1XP   (DM320_OSD_REGISTER_BASE+0x003c) /* OSD Bitmap Window 1 X-Position */
+#define DM320_OSD_OSDWIN1YP   (DM320_OSD_REGISTER_BASE+0x003e) /* OSD Bitmap Window 1 Y-Position */
+#define DM320_OSD_OSDWIN1XL   (DM320_OSD_REGISTER_BASE+0x0040) /* OSD Bitmap Window 1 X-Size */
+#define DM320_OSD_OSDWIN1YL   (DM320_OSD_REGISTER_BASE+0x0042) /* OSD Bitmap Window 1 Y-Size */
+#define DM320_OSD_CURXP       (DM320_OSD_REGISTER_BASE+0x0044) /* Rectangular Cursor Window X-Position */
+#define DM320_OSD_CURYP       (DM320_OSD_REGISTER_BASE+0x0046) /* Rectangular Cursor Window Y-Position */
+#define DM320_OSD_CURXL       (DM320_OSD_REGISTER_BASE+0x0048) /* Rectangular Cursor Window X-Size */
+#define DM320_OSD_CURYL       (DM320_OSD_REGISTER_BASE+0x004a) /* Rectangular Cursor Window Y-Size */
+#define DM320_OSD_W0BMP01     (DM320_OSD_REGISTER_BASE+0x0050) /* Window 0 Bitmap Value to Palette Map 0/1 */
+#define DM320_OSD_W0BMP23     (DM320_OSD_REGISTER_BASE+0x0052) /* Window 0 Bitmap Value to Palette Map 2/3 */
+#define DM320_OSD_W0BMP45     (DM320_OSD_REGISTER_BASE+0x0054) /* Window 0 Bitmap Value to Palette Map 4/5 */
+#define DM320_OSD_W0BMP67     (DM320_OSD_REGISTER_BASE+0x0056) /* Window 0 Bitmap Value to Palette Map 6/7 */
+#define DM320_OSD_W0BMP89     (DM320_OSD_REGISTER_BASE+0x0058) /* Window 0 Bitmap Value to Palette Map 8/9 */
+#define DM320_OSD_W0BMPAB     (DM320_OSD_REGISTER_BASE+0x005a) /* Window 0 Bitmap Value to Palette Map A/B */
+#define DM320_OSD_W0BMPCD     (DM320_OSD_REGISTER_BASE+0x005c) /* Window 0 Bitmap Value to Palette Map C/D */
+#define DM320_OSD_W0BMPEF     (DM320_OSD_REGISTER_BASE+0x005e) /* Window 0 Bitmap Value to Palette Map E/F */
+#define DM320_OSD_W1BMP01     (DM320_OSD_REGISTER_BASE+0x0060) /* Window 1 Bitmap Value to Palette Map 0/1 */
+#define DM320_OSD_W1BMP23     (DM320_OSD_REGISTER_BASE+0x0062) /* Window 1 Bitmap Value to Palette Map 2/3 */
+#define DM320_OSD_W1BMP45     (DM320_OSD_REGISTER_BASE+0x0064) /* Window 1 Bitmap Value to Palette Map 4/5 */
+#define DM320_OSD_W1BMP67     (DM320_OSD_REGISTER_BASE+0x0066) /* Window 1 Bitmap Value to Palette Map 6/7 */
+#define DM320_OSD_W1BMP89     (DM320_OSD_REGISTER_BASE+0x0068) /* Window 1 Bitmap Value to Palette Map 8/9 */
+#define DM320_OSD_W1BMPAB     (DM320_OSD_REGISTER_BASE+0x006a) /* Window 1 Bitmap Value to Palette Map A/B */
+#define DM320_OSD_W1BMPCD     (DM320_OSD_REGISTER_BASE+0x006c) /* Window 1 Bitmap Value to Palette Map C/D */
+#define DM320_OSD_W1BMPEF     (DM320_OSD_REGISTER_BASE+0x006e) /* Window 1 Bitmap Value to Palette Map E/F */
+#define DM320_OSD_MISCCTL     (DM320_OSD_REGISTER_BASE+0x0074) /* Miscellaneous Control */
+#define DM320_OSD_CLUTRAMYCB  (DM320_OSD_REGISTER_BASE+0x0076) /* CLUT RAM Y/Cb Setup */
+#define DM320_OSD_CLUTRAMCR   (DM320_OSD_REGISTER_BASE+0x0078) /* CLUT RAM Cr/Mapping Setup */
+#define DM320_OSD_RSV5        (DM320_OSD_REGISTER_BASE+0x007a) /* CLUT RAM Cr/Mapping Setup */
+#define DM320_OSD_PPVWIN0ADH  (DM320_OSD_REGISTER_BASE+0x007c) /* Ping-Pong Video Window 0 Address (High) */
+#define DM320_OSD_PPVWIN0ADL  (DM320_OSD_REGISTER_BASE+0x007e) /* Ping-Pong Video Window 0 Address (Low) */
+
+/************************************************************************************
+ * Inline Functions
+ ************************************************************************************/
+
+#endif  /* __ARCH_ARM_SRC_DM320_DM320_OSD_H */
diff --git a/arch/sim/src/up_framebuffer.c b/arch/sim/src/up_framebuffer.c
index da4261ee2f..ae7023b1a0 100644
--- a/arch/sim/src/up_framebuffer.c
+++ b/arch/sim/src/up_framebuffer.c
@@ -102,9 +102,9 @@ static int up_getplaneinfo(FAR struct fb_vtable_s *vtable, int planeno, FAR stru
 
   /* The following is provided only if the video hardware supports RGB color mapping */
 
-#if CONFIG_FB_CMAP
+#ifdef CONFIG_FB_CMAP
 static int up_getcmap(FAR struct fb_vtable_s *vtable, FAR struct fb_cmap_s *cmap);
-static int up_putcmap(FAR struct fb_vtable_s *vtable, FAR struct fb_cmap_s *cmap);
+static int up_putcmap(FAR struct fb_vtable_s *vtable, FAR const struct fb_cmap_s *cmap);
 #endif
   /* The following is provided only if the video hardware supports a hardware cursor */
 
@@ -141,7 +141,7 @@ static const struct fb_planeinfo_s g_planeinfo =
 
 /* Simulated RGB mapping */
 
-#if CONFIG_FB_CMAP
+#ifdef CONFIG_FB_CMAP
 static struct fb_cmap_s g_cmap;
 #endif
 
@@ -165,7 +165,7 @@ struct fb_vtable_s g_fbobject =
 {
   .getvideoinfo  = up_getvideoinfo,
   .getplaneinfo  = up_getplaneinfo,
-#if CONFIG_FB_CMAP
+#ifdef CONFIG_FB_CMAP
   .getcmap       = up_getcmap,
   .putcmap       = up_putcmap,
 #endif
@@ -221,16 +221,16 @@ static int up_getplaneinfo(FAR struct fb_vtable_s *vtable, int planeno,
  * Name: up_getcmap
  ****************************************************************************/
 
-#if CONFIG_FB_CMAP
+#ifdef CONFIG_FB_CMAP
 static int up_getcmap(FAR struct fb_vtable_s *vtable, FAR struct fb_cmap_s *cmap)
 {
+  int len
   int i;
 
   dbg("vtable=%p cmap=%p cmap->len\n", vtable, cmap, cmap->len);
   if (vtable && cmap)
     {
-      cmap->len = 256;
-      for (i = 0; i < 256, i++)
+      for (i = cmap.first, len = 0; i < 256 && len < cmap.len, i++, len++)
         {
           cmap->red[i]    = i;
           cmap->green[i]  = i;
@@ -239,6 +239,7 @@ static int up_getcmap(FAR struct fb_vtable_s *vtable, FAR struct fb_cmap_s *cmap
           cmap->transp[i] = i;
 #endif
         }
+      cmap.len = len;
       return OK;
     }
   dbg("Returning EINVAL\n");
@@ -250,8 +251,8 @@ static int up_getcmap(FAR struct fb_vtable_s *vtable, FAR struct fb_cmap_s *cmap
  * Name: up_putcmap
  ****************************************************************************/
 
-#if CONFIG_FB_CMAP
-static int up_putcmap(FAR struct fb_vtable_s *vtable, FAR struct fb_cmap_s *cmap)
+#ifdef CONFIG_FB_CMAP
+static int up_putcmap(FAR struct fb_vtable_s *vtable, FAR const struct fb_cmap_s *cmap)
 {
   dbg("vtable=%p cmap=%p cmap->len\n", vtable, cmap, cmap->len);
   if (vtable && cmap)