new video driver for bus vcxk framebuffers

This patch adds a new video driver

* adds common bus_vcxk framebuffer driver

Signed-off-by: Jens Scharsig <esw@bus-elektronik.de>
[agust@denx.de: fixed lots of style issues before applying]
Signed-off-by: Anatolij Gustschin <agust@denx.de>
master
Jens Scharsig 16 years ago committed by Anatolij Gustschin
parent 60e9741924
commit 50217deeb0
  1. 85
      doc/README.bus_vcxk
  2. 1
      drivers/video/Makefile
  3. 436
      drivers/video/bus_vcxk.c
  4. 36
      include/bus_vcxk.h

@ -0,0 +1,85 @@
/*
* (C) Copyright 2008-2009
* BuS Elektronik GmbH & Co. KG <www.bus-elektronik.de>
* Jens Scharsig <esw@bus-elektronik.de>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
U-Boot vcxk video controller driver
======================================
By defining CONFIG_VIDEO_VCXK this driver can be used with VC2K, VC4K and
VC8K devices on following boards:
board | ARCH | Vendor
-----------------------------------------------------------------------
EB+CPU5282-T1 | MCF5282 | BuS Elektronik GmbH & Co. KG
EB+MCF-EVB123 | MCF5282 | BuS Elektronik GmbH & Co. KG
EB+CPUx9K2 | AT91RM9200 | BuS Elektronik GmbH & Co. KG
ZLSA | AT91RM9200 | Ruf Telematik AG
Driver configuration
--------------------
The driver needs some defines to describe the target hardware:
CONFIG_SYS_VCXK_BASE
base address of VCxK hardware memory
CONFIG_SYS_VCXK_DEFAULT_LINEALIGN
defines the physical alignment of a pixel row
CONFIG_SYS_VCXK_DOUBLEBUFFERED
some boards that use vcxk prevent read from framebuffer memory.
define this option to enable double buffering (needs 16KiB RAM)
CONFIG_SYS_VCXK_<xxxx>_PIN
defines the number of the I/O line PIN in the port
valid values for <xxxx> are:
ACKNOWLEDGE
describes the acknowledge line from vcxk hardware
ENABLE
describes the enable line to vcxk hardware
INVERT
describes the invert line to vcxk hardware
RESET
describes the reset line to vcxk hardware
REQUEST
describes the request line to vcxk hardware
CONFIG_SYS_VCXK_<xxxx>_PORT
defines the I/O port which is connected with the line
for valid values for <xxxx> see CONFIG_SYS_VCXK_<xxxx>_PIN
CONFIG_SYS_VCXK_<xxxx>_DDR
defines the register which configures the direction
for valid values for <xxxx> see CONFIG_SYS_VCXK_<xxxx>_PIN

@ -36,6 +36,7 @@ COBJS-$(CONFIG_VIDEO_SED13806) += sed13806.o
COBJS-$(CONFIG_SED156X) += sed156x.o
COBJS-$(CONFIG_VIDEO_SM501) += sm501.o
COBJS-$(CONFIG_VIDEO_SMI_LYNXEM) += smiLynxEM.o
COBJS-$(CONFIG_VIDEO_VCXK) += bus_vcxk.o
COBJS-y += videomodes.o
COBJS := $(COBJS-y)

@ -0,0 +1,436 @@
/*
* (C) Copyright 2005-2009
* Jens Scharsig @ BuS Elektronik GmbH & Co. KG, <esw@bus-elektronik.de>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <bmp_layout.h>
#include <asm/io.h>
vu_char *vcxk_bws = ((vu_char *) (CONFIG_SYS_VCXK_BASE));
vu_short *vcxk_bws_word = ((vu_short *)(CONFIG_SYS_VCXK_BASE));
vu_long *vcxk_bws_long = ((vu_long *) (CONFIG_SYS_VCXK_BASE));
#ifdef CONFIG_AT91RM9200
#include <asm/arch/hardware.h>
#ifndef VCBITMASK
#define VCBITMASK(bitno) (0x0001 << (bitno % 16))
#endif
#define VCXK_INIT_PIN(PORT, PIN, DDR, I0O1) \
((AT91PS_PIO) PORT)->PIO_PER = PIN; \
((AT91PS_PIO) PORT)->DDR = PIN; \
((AT91PS_PIO) PORT)->PIO_MDDR = PIN; \
if (!I0O1) ((AT91PS_PIO) PORT)->PIO_PPUER = PIN;
#define VCXK_SET_PIN(PORT, PIN) ((AT91PS_PIO) PORT)->PIO_SODR = PIN;
#define VCXK_CLR_PIN(PORT, PIN) ((AT91PS_PIO) PORT)->PIO_CODR = PIN;
#define VCXK_ACKNOWLEDGE \
(!(((AT91PS_PIO) CONFIG_SYS_VCXK_ACKNOWLEDGE_PORT)->\
PIO_PDSR & CONFIG_SYS_VCXK_ACKNOWLEDGE_PIN))
#elif defined(CONFIG_MCF52x2)
#include <asm/m5282.h>
#ifndef VCBITMASK
#define VCBITMASK(bitno) (0x8000 >> (bitno % 16))
#endif
#define VCXK_INIT_PIN(PORT, PIN, DDR, I0O1) \
if (I0O1) DDR |= PIN; else DDR &= ~PIN;
#define VCXK_SET_PIN(PORT, PIN) PORT |= PIN;
#define VCXK_CLR_PIN(PORT, PIN) PORT &= ~PIN;
#define VCXK_ACKNOWLEDGE \
(!(CONFIG_SYS_VCXK_ACKNOWLEDGE_PORT & \
CONFIG_SYS_VCXK_ACKNOWLEDGE_PIN))
#else
#error no vcxk support for selected ARCH
#endif
#define VCXK_DISABLE\
VCXK_SET_PIN(CONFIG_SYS_VCXK_ENABLE_PORT, CONFIG_SYS_VCXK_ENABLE_PIN)
#define VCXK_ENABLE\
VCXK_CLR_PIN(CONFIG_SYS_VCXK_ENABLE_PORT, CONFIG_SYS_VCXK_ENABLE_PIN)
#ifndef CONFIG_SYS_VCXK_DOUBLEBUFFERED
#define VCXK_BWS(x, data) vcxk_bws[x] = data;
#define VCXK_BWS_WORD_SET(x, mask) vcxk_bws_word[x] |= mask;
#define VCXK_BWS_WORD_CLEAR(x, mask) vcxk_bws_word[x] &= ~mask;
#define VCXK_BWS_LONG(x, data) vcxk_bws_long[x] = data;
#else
u_char double_bws[16384];
u_short *double_bws_word;
u_long *double_bws_long;
#define VCXK_BWS(x,data) \
double_bws[x] = data; vcxk_bws[x] = data;
#define VCXK_BWS_WORD_SET(x,mask) \
double_bws_word[x] |= mask; \
vcxk_bws_word[x] = double_bws_word[x];
#define VCXK_BWS_WORD_CLEAR(x,mask) \
double_bws_word[x] &= ~mask; \
vcxk_bws_word[x] = double_bws_word[x];
#define VCXK_BWS_LONG(x,data) \
double_bws_long[x] = data; vcxk_bws_long[x] = data;
#endif
#define VC4K16_Bright1 vcxk_bws_word[0x20004 / 2]
#define VC4K16_Bright2 vcxk_bws_word[0x20006 / 2]
#define VC2K_Bright vcxk_bws[0x8000]
#define VC8K_BrightH vcxk_bws[0xC000]
#define VC8K_BrightL vcxk_bws[0xC001]
vu_char VC4K16;
u_long display_width;
u_long display_height;
u_long display_bwidth;
ulong search_vcxk_driver(void);
void vcxk_cls(void);
void vcxk_setbrightness(unsigned int side, short brightness);
int vcxk_request(void);
int vcxk_acknowledge_wait(void);
void vcxk_clear(void);
/*
****f* bus_vcxk/vcxk_init
* FUNCTION
* initialalize Video Controller
* PARAMETERS
* width visible display width in pixel
* height visible display height in pixel
***
*/
int vcxk_init(unsigned long width, unsigned long height)
{
#ifdef CONFIG_SYS_VCXK_RESET_PORT
VCXK_INIT_PIN(CONFIG_SYS_VCXK_RESET_PORT,
CONFIG_SYS_VCXK_RESET_PIN, CONFIG_SYS_VCXK_RESET_DDR, 1)
VCXK_SET_PIN(CONFIG_SYS_VCXK_RESET_PORT, CONFIG_SYS_VCXK_RESET_PIN);
#endif
#ifdef CONFIG_SYS_VCXK_DOUBLEBUFFERED
double_bws_word = (u_short *) double_bws;
double_bws_long = (u_long *)double_bws;
debug("%lx %lx %lx \n", double_bws, double_bws_word, double_bws_long);
#endif
display_width = width;
display_height = height;
#if (CONFIG_SYS_VCXK_DEFAULT_LINEALIGN == 4)
display_bwidth = ((width + 31) / 8) & ~0x3;
#elif (CONFIG_SYS_VCXK_DEFAULT_LINEALIGN == 2)
display_bwidth = ((width + 15) / 8) & ~0x1;
#else
#error CONFIG_SYS_VCXK_DEFAULT_LINEALIGN is invalid
#endif
debug("linesize ((%d + 15) / 8 & ~0x1) = %d\n",
display_width, display_bwidth);
#ifdef CONFIG_SYS_VCXK_AUTODETECT
VC4K16 = 0;
vcxk_bws_long[1] = 0x0;
vcxk_bws_long[1] = 0x55AAAA55;
vcxk_bws_long[5] = 0x0;
if (vcxk_bws_long[1] == 0x55AAAA55) VC4K16 = 1;
#else
VC4K16 = 1;
debug("No autodetect: use vc4k\n");
#endif
VCXK_INIT_PIN(CONFIG_SYS_VCXK_INVERT_PORT,
CONFIG_SYS_VCXK_INVERT_PIN, CONFIG_SYS_VCXK_INVERT_DDR, 1)
VCXK_SET_PIN(CONFIG_SYS_VCXK_INVERT_PORT, CONFIG_SYS_VCXK_INVERT_PIN)
VCXK_SET_PIN(CONFIG_SYS_VCXK_REQUEST_PORT, CONFIG_SYS_VCXK_REQUEST_PIN);
VCXK_INIT_PIN(CONFIG_SYS_VCXK_REQUEST_PORT,
CONFIG_SYS_VCXK_REQUEST_PIN, CONFIG_SYS_VCXK_REQUEST_DDR, 1)
VCXK_INIT_PIN(CONFIG_SYS_VCXK_ACKNOWLEDGE_PORT,
CONFIG_SYS_VCXK_ACKNOWLEDGE_PIN,
CONFIG_SYS_VCXK_ACKNOWLEDGE_DDR, 0)
VCXK_DISABLE;
VCXK_INIT_PIN(CONFIG_SYS_VCXK_ENABLE_PORT,
CONFIG_SYS_VCXK_ENABLE_PIN, CONFIG_SYS_VCXK_ENABLE_DDR, 1)
vcxk_cls();
vcxk_cls(); /* clear second/hidden page */
vcxk_setbrightness(3, 1000);
VCXK_ENABLE;
return 1;
}
/*
****f* bus_vcxk/vcxk_setpixel
* FUNCTION
* set the pixel[x,y] with the given color
* PARAMETER
* x pixel colum
* y pixel row
* color <0x40 off/black
* >0x40 on
***
*/
void vcxk_setpixel(int x, int y, unsigned long color)
{
vu_short dataptr;
if ((x < display_width) && (y < display_height)) {
dataptr = ((x / 16)) + (y * (display_bwidth >> 1));
color = ((color >> 16) & 0xFF) |
((color >> 8) & 0xFF) | (color & 0xFF);
if (color > 0x40) {
VCXK_BWS_WORD_SET(dataptr, VCBITMASK(x));
} else {
VCXK_BWS_WORD_CLEAR(dataptr, VCBITMASK(x));
}
}
}
/*
****f* bus_vcxk/vcxk_loadimage
* FUNCTION
* copies a binary image to display memory
***
*/
void vcxk_loadimage(ulong source)
{
int cnt;
vcxk_acknowledge_wait();
if (VC4K16) {
for (cnt = 0; cnt < (16384 / 4); cnt++) {
VCXK_BWS_LONG(cnt, (*(ulong *) source));
source = source + 4;
}
} else {
for (cnt = 0; cnt < 16384; cnt++) {
VCXK_BWS_LONG(cnt*2, (*(vu_char *) source));
source++;
}
}
vcxk_request();
}
/*
****f* bus_vcxk/vcxk_cls
* FUNCTION
* clear the display
***
*/
void vcxk_cls(void)
{
vcxk_acknowledge_wait();
vcxk_clear();
vcxk_request();
}
/*
****f* bus_vcxk/vcxk_clear(void)
* FUNCTION
* clear the display memory
***
*/
void vcxk_clear(void)
{
int cnt;
for (cnt = 0; cnt < (16384 / 4); cnt++) {
VCXK_BWS_LONG(cnt, 0)
}
}
/*
****f* bus_vcxk/vcxk_setbrightness
* FUNCTION
* set the display brightness
* PARAMETER
* side 1 set front side brightness
* 2 set back side brightness
* 3 set brightness for both sides
* brightness 0..1000
***
*/
void vcxk_setbrightness(unsigned int side, short brightness)
{
if (VC4K16) {
if ((side == 0) || (side & 0x1))
VC4K16_Bright1 = brightness + 23;
if ((side == 0) || (side & 0x2))
VC4K16_Bright2 = brightness + 23;
} else {
VC2K_Bright = (brightness >> 4) + 2;
VC8K_BrightH = (brightness + 23) >> 8;
VC8K_BrightL = (brightness + 23) & 0xFF;
}
}
/*
****f* bus_vcxk/vcxk_request
* FUNCTION
* requests viewing of display memory
***
*/
int vcxk_request(void)
{
VCXK_CLR_PIN(CONFIG_SYS_VCXK_REQUEST_PORT,
CONFIG_SYS_VCXK_REQUEST_PIN)
VCXK_SET_PIN(CONFIG_SYS_VCXK_REQUEST_PORT,
CONFIG_SYS_VCXK_REQUEST_PIN);
return 1;
}
/*
****f* bus_vcxk/vcxk_acknowledge_wait
* FUNCTION
* wait for acknowledge viewing requests
***
*/
int vcxk_acknowledge_wait(void)
{
while (VCXK_ACKNOWLEDGE);
return 1;
}
/*
****f* bus_vcxk/vcxk_draw_mono
* FUNCTION
* copies a monochrom bitmap (BMP-Format) from given memory
* PARAMETER
* dataptr pointer to bitmap
* x output bitmap @ columne
* y output bitmap @ row
***
*/
void vcxk_draw_mono(unsigned char *dataptr, unsigned long linewidth,
unsigned long cp_width, unsigned long cp_height)
{
unsigned char *lineptr;
unsigned long xcnt, ycnt;
for (ycnt = cp_height; ycnt > 0; ycnt--) {
lineptr = dataptr;
for (xcnt = 0; xcnt < cp_width; xcnt++) {
if ((*lineptr << (xcnt % 8)) & 0x80)
vcxk_setpixel(xcnt, ycnt - 1, 0xFFFFFF);
else
vcxk_setpixel(xcnt, ycnt-1, 0);
if ((xcnt % 8) == 7) lineptr++;
} /* endfor xcnt */
dataptr = dataptr + linewidth;
} /* endfor ycnt */
}
/*
****f* bus_vcxk/vcxk_display_bitmap
* FUNCTION
* copies a bitmap (BMP-Format) to the given position
* PARAMETER
* addr pointer to bitmap
* x output bitmap @ columne
* y output bitmap @ row
***
*/
int vcxk_display_bitmap(ulong addr, int x, int y)
{
bmp_image_t *bmp;
unsigned long width;
unsigned long height;
unsigned long bpp;
unsigned long compression;
unsigned long lw;
unsigned long c_width;
unsigned long c_height;
unsigned char *dataptr;
unsigned char *lineptr;
bmp = (bmp_image_t *) addr;
if ((bmp->header.signature[0] == 'B') &&
(bmp->header.signature[1] == 'M')) {
compression = le32_to_cpu(bmp->header.compression);
width = le32_to_cpu(bmp->header.width);
height = le32_to_cpu(bmp->header.height);
bpp = le16_to_cpu(bmp->header.bit_count);
dataptr = (unsigned char *) bmp +
le32_to_cpu(bmp->header.data_offset);
if (display_width < (width + x))
c_width = display_width - x;
else
c_width = width;
if (display_height < (height + y))
c_height = display_height - y;
else
c_height = height;
lw = (((width + 7) / 8) + 3) & ~0x3;
if (c_height < height)
dataptr = dataptr + lw * (height - c_height);
switch (bpp) {
case 1:
vcxk_draw_mono(dataptr, lw, c_width, c_height);
break;
default:
printf("Error: %ld bit per pixel "
"not supported by VCxK\n", bpp);
return 0;
}
} else {
printf("Error: no valid bmp at %lx\n", (ulong) bmp);
return 0;
}
return 1;
}
/*
****f* bus_vcxk/video_display_bitmap
***
*/
int video_display_bitmap(ulong addr, int x, int y)
{
vcxk_acknowledge_wait();
if (vcxk_display_bitmap(addr, x, y)) {
vcxk_request();
return 0;
}
return 1;
}
/* EOF */

@ -0,0 +1,36 @@
/*
* (C) Copyright 2005-2009
* Jens Scharsig @ BuS Elektronik GmbH & Co. KG, <esw@bus-elektronik.de>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#ifndef __BUS_VCXK_H_
#define __BUS_VCXK_H_
extern int vcxk_init(unsigned long width, unsigned long height);
extern void vcxk_setpixel(int x, int y, unsigned long color);
extern int vcxk_acknowledge_wait(void);
extern int vcxk_request(void);
extern void vcxk_loadimage(ulong source);
extern int vcxk_display_bitmap(ulong addr, int x, int y);
extern void vcxk_setbrightness(unsigned int side, short brightness);
extern int video_display_bitmap(ulong addr, int x, int y);
#endif
Loading…
Cancel
Save