This patch adds a new video driver * adds common bus_vcxk framebuffer driver
Signed-off-by: Jens Scharsig <e...@bus-elektronik.de> --- diff --git a/doc/README.bus_vcxk b/doc/README.bus_vcxk new file mode 100644 index 0000000..4eb8fe8 --- /dev/null +++ b/doc/README.bus_vcxk @@ -0,0 +1,85 @@ +/* + * (C) Copyright 2008-2009 + * BuS Elektronik GmbH & Co. KG <www.bus-elektronik.de> + * Jens Scharsig <e...@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 + diff --git a/drivers/video/Makefile b/drivers/video/Makefile index bc00852..bb6b5a0 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -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) diff --git a/drivers/video/bus_vcxk.c b/drivers/video/bus_vcxk.c new file mode 100644 index 0000000..51c15f8 --- /dev/null +++ b/drivers/video/bus_vcxk.c @@ -0,0 +1,436 @@ +/* + * (C) Copyright 2005-2009 + * Jens Scharsig @ BuS Elektronik GmbH & Co. KG, <e...@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_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 xcnt,ycnt; + unsigned long linewidth; + + unsigned long cp_width; + unsigned long cp_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)) + { + cp_width = display_width - x; + } + else + { + cp_width = width; + } + if (display_height < (height + y)) + { + cp_height = display_height - y; + } + else + { + cp_height = height; + } + linewidth = (((width + 7) / 8) + 3) & ~0x3; + if (cp_height < height) + { + dataptr=dataptr + linewidth * (height - cp_height); + } + switch (bpp) + { + case 1: + 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 */ + 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 */ diff --git a/include/bus_vcxk.h b/include/bus_vcxk.h new file mode 100644 index 0000000..8d6a25c --- /dev/null +++ b/include/bus_vcxk.h @@ -0,0 +1,36 @@ +/* + * (C) Copyright 2005-2009 + * Jens Scharsig @ BuS Elektronik GmbH & Co. KG, <e...@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 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot