1440 lines
44 KiB
C
1440 lines
44 KiB
C
/****************************************************************************
|
|
* arch/arm/src/dm320/dm320_framebuffer.c
|
|
*
|
|
* Copyright (C) 2008-2009, 2013 Gregory Nutt. All rights reserved.
|
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
|
*
|
|
* 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 <stdint.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <debug.h>
|
|
|
|
#include <nuttx/video/fb.h>
|
|
#include <nuttx/kmalloc.h>
|
|
#include <nuttx/nx/nxglib.h>
|
|
|
|
#include "up_arch.h"
|
|
#include "dm320_memorymap.h"
|
|
#include "dm320_osd.h"
|
|
|
|
/************************************************************************
|
|
* Pre-processor 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 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 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 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 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(uint8_t *buffer, int len)
|
|
{
|
|
memset(buffer, 0xff, len);
|
|
}
|
|
|
|
static inline uint32_t dm320_physaddr(FAR void *fb_vaddr)
|
|
{
|
|
return (uint32_t)fb_vaddr - DM320_SDRAM_VADDR;
|
|
}
|
|
|
|
#ifndef CONFIG_DM320_VID0_DISABLE
|
|
static inline uint32_t dm320_vid0upperoffset(void)
|
|
{
|
|
return (((dm320_physaddr(g_vid0base) / 32) >> 16) & 0xff);
|
|
}
|
|
|
|
static inline uint32_t dm320_vid0loweroffset(void)
|
|
{
|
|
return ((dm320_physaddr(g_vid0base) / 32) & 0xffff);
|
|
}
|
|
|
|
#ifndef CONFIG_DM320_DISABLE_PINGPONG
|
|
static inline uint32_t dm320_vid0ppupperoffset(void)
|
|
{
|
|
return (((dm320_physaddr(g_vid0ppbase) / 32) >> 16) & 0xff);
|
|
}
|
|
|
|
static inline uint32_t dm320_vid0pploweroffset(void)
|
|
{
|
|
return ((dm320_physaddr(g_vid0ppbase) / 32) & 0xffff);
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
#ifndef CONFIG_DM320_VID1_DISABLE
|
|
static inline uint32_t dm320_vid1upperoffset(void)
|
|
{
|
|
return (((dm320_physaddr(g_vid1base) / 32) >> 16) & 0xff);
|
|
}
|
|
|
|
static inline uint32_t dm320_vid1loweroffset(void)
|
|
{
|
|
return ((dm320_physaddr(g_vid1base) / 32) & 0xffff);
|
|
}
|
|
#endif
|
|
|
|
#ifndef CONFIG_DM320_OSD0_DISABLE
|
|
static inline uint32_t dm320_osd0upperoffset(void)
|
|
{
|
|
return (((dm320_physaddr(g_osd0base) / 32) >> 16) & 0xff);
|
|
}
|
|
|
|
static inline uint32_t dm320_osd0loweroffset(void)
|
|
{
|
|
return ((dm320_physaddr(g_osd0base) / 32) & 0xffff);
|
|
}
|
|
#endif
|
|
|
|
#ifndef CONFIG_DM320_OSD1_DISABLE
|
|
static inline uint32_t dm320_osd1upperoffset(void)
|
|
{
|
|
return (((dm320_physaddr(g_osd1base) / 32) >> 16) & 0xff);
|
|
}
|
|
|
|
static inline uint32_t 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 *)kmalloc(2 * DM320_VID0_FBLEN);
|
|
g_vid0ppbase = (FAR char*)g_vid0base + DM320_VID0_FBLEN;
|
|
#else
|
|
g_vid0base = (FAR void *)kmalloc(DM320_VID0_FBLEN);
|
|
#endif
|
|
if (!g_vid0base)
|
|
{
|
|
goto errout;
|
|
}
|
|
#endif
|
|
|
|
#ifndef CONFIG_DM320_VID1_DISABLE
|
|
g_vid1base = (FAR void *)kmalloc(DM320_VID1_FBLEN);
|
|
if (!g_vid1base)
|
|
{
|
|
goto errout;
|
|
}
|
|
#endif
|
|
|
|
#ifndef CONFIG_DM320_OSD0_DISABLE
|
|
g_osd0base = (FAR void *)kmalloc(DM320_OSD0_FBLEN);
|
|
if (!g_osd0base)
|
|
{
|
|
goto errout;
|
|
}
|
|
#endif
|
|
|
|
#ifndef CONFIG_DM320_OSD1_DISABLE
|
|
g_osd1base = (FAR void *)kmalloc(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)
|
|
{
|
|
kfree(g_vid0base);
|
|
g_vid0base = NULL;
|
|
#ifndef CONFIG_DM320_DISABLE_PINGPONG
|
|
g_vid0ppbase = NULL;
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
#ifndef CONFIG_DM320_VID1_DISABLE
|
|
if (g_vid1base != 0)
|
|
{
|
|
kfree(g_vid1base);
|
|
g_vid1base = NULL;
|
|
}
|
|
#endif
|
|
|
|
#ifndef CONFIG_DM320_OSD0_DISABLE
|
|
if (g_osd0base != 0)
|
|
{
|
|
kfree(g_osd0base);
|
|
g_osd0base = NULL;
|
|
}
|
|
#endif
|
|
|
|
#ifndef CONFIG_DM320_OSD1_DISABLE
|
|
if (g_osd1base != 0)
|
|
{
|
|
kfree(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((uint8_t *)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((uint8_t *)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((uint8_t *)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((uint8_t *)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((uint8_t *)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_t regval;
|
|
uint8_t y;
|
|
uint8_t u;
|
|
uint8_t 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 */
|
|
|
|
nxgl_rgb2yuv(cmap->red[i], cmap->green[i], cmap->blue[i], &y, &u, &v);
|
|
|
|
/* Program the CLUT */
|
|
|
|
while (getreg16(DM320_OSD_MISCCTL) & 0x8);
|
|
putreg16(((uint16_t)y) << 8 | uint16_t(u)), DM320_OSD_CLUTRAMYCB);
|
|
putreg16(((uint16_t)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_t 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
|
|
*
|
|
* Description:
|
|
* Initialize the video hardware
|
|
*
|
|
****************************************************************************/
|
|
|
|
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_fbgetvplane
|
|
*
|
|
* Description:
|
|
* Return a a reference to the framebuffer object for the specified video plane.
|
|
*
|
|
* Input parameters:
|
|
* None
|
|
*
|
|
* Returned value:
|
|
* Reference to the framebuffer object (NULL on failure)
|
|
*
|
|
***************************************************************************/
|
|
|
|
FAR struct fb_vtable_s *up_fbgetvplane(int vplane)
|
|
{
|
|
switch (vplane)
|
|
{
|
|
#ifndef CONFIG_DM320_VID0_DISABLE
|
|
case DM320_VIDWIN0: /* VID0 window */
|
|
return &g_vid0vtable;
|
|
#endif
|
|
#ifndef CONFIG_DM320_VID1_DISABLE
|
|
case DM320_VIDWIN1: /* VID1 window */
|
|
return &g_vid1vtable;
|
|
#endif
|
|
#ifndef CONFIG_DM320_OSD0_DISABLE
|
|
case DM320_OSDWIN0: /* OSD2 window */
|
|
return &g_osd0vtable;
|
|
#endif
|
|
#ifndef CONFIG_DM320_OSD1_DISABLE
|
|
case DM320_OSDWIN1: /* OSD2 window */
|
|
return &g_osd1vtable;
|
|
#endif
|
|
default:
|
|
break;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: up_fbteardown
|
|
****************************************************************************/
|
|
|
|
void fb_teardown(void)
|
|
{
|
|
/* Disable the hardware */
|
|
|
|
dm320_disable();
|
|
|
|
/* Free the video buffers */
|
|
|
|
dm320_freevideomemory();
|
|
}
|