diff options
| -rw-r--r-- | README | 5 | ||||
| -rw-r--r-- | arch/arm/include/asm/imx-common/mx5_video.h | 21 | ||||
| -rw-r--r-- | board/freescale/mx51evk/Makefile | 4 | ||||
| -rw-r--r-- | board/freescale/mx51evk/mx51evk.c | 57 | ||||
| -rw-r--r-- | board/freescale/mx51evk/mx51evk_video.c | 81 | ||||
| -rw-r--r-- | board/freescale/mx53loco/Makefile | 4 | ||||
| -rw-r--r-- | board/freescale/mx53loco/mx53loco.c | 66 | ||||
| -rw-r--r-- | board/freescale/mx53loco/mx53loco_video.c | 94 | ||||
| -rw-r--r-- | common/cmd_bmp.c | 5 | ||||
| -rw-r--r-- | common/lcd.c | 178 | ||||
| -rw-r--r-- | drivers/video/atmel_hlcdfb.c | 12 | ||||
| -rw-r--r-- | drivers/video/bus_vcxk.c | 2 | ||||
| -rw-r--r-- | drivers/video/cfb_console.c | 49 | ||||
| -rw-r--r-- | drivers/video/ipu_common.c | 10 | ||||
| -rw-r--r-- | include/atmel_hlcdc.h | 7 | ||||
| -rw-r--r-- | include/lcd.h | 36 | ||||
| -rw-r--r-- | include/video.h | 48 | 
17 files changed, 550 insertions, 129 deletions
| @@ -1469,6 +1469,11 @@ CBFS (Coreboot Filesystem) support  		Normally display is black on white background; define  		CONFIG_SYS_WHITE_ON_BLACK to get it inverted. +		CONFIG_LCD_BMP_RLE8 + +		Support drawing of RLE8-compressed bitmaps on the LCD. + +  - Splash Screen Support: CONFIG_SPLASH_SCREEN  		If this option is set, the environment is checked for diff --git a/arch/arm/include/asm/imx-common/mx5_video.h b/arch/arm/include/asm/imx-common/mx5_video.h new file mode 100644 index 000000000..e54c25a56 --- /dev/null +++ b/arch/arm/include/asm/imx-common/mx5_video.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2012 + * Anatolij Gustschin, DENX Software Engineering, <agust@denx.de> + * + * 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. + */ +#ifndef __MX5_VIDEO_H +#define __MX5_VIDEO_H + +#ifdef CONFIG_VIDEO +void lcd_enable(void); +void setup_iomux_lcd(void); +#else +static inline void lcd_enable(void) { } +static inline void setup_iomux_lcd(void) { } +#endif + +#endif diff --git a/board/freescale/mx51evk/Makefile b/board/freescale/mx51evk/Makefile index 224eaa3c7..2310fe137 100644 --- a/board/freescale/mx51evk/Makefile +++ b/board/freescale/mx51evk/Makefile @@ -23,8 +23,10 @@ include $(TOPDIR)/config.mk  LIB	= $(obj)lib$(BOARD).o -COBJS	:= mx51evk.o +COBJS-y			+= mx51evk.o +COBJS-$(CONFIG_VIDEO)	+= mx51evk_video.o +COBJS	:= $(COBJS-y)  SRCS	:= $(COBJS:.o=.c)  OBJS	:= $(addprefix $(obj),$(COBJS)) diff --git a/board/freescale/mx51evk/mx51evk.c b/board/freescale/mx51evk/mx51evk.c index 5504636dd..d1ef43189 100644 --- a/board/freescale/mx51evk/mx51evk.c +++ b/board/freescale/mx51evk/mx51evk.c @@ -30,6 +30,7 @@  #include <asm/arch/sys_proto.h>  #include <asm/arch/crm_regs.h>  #include <asm/arch/clock.h> +#include <asm/imx-common/mx5_video.h>  #include <i2c.h>  #include <mmc.h>  #include <fsl_esdhc.h> @@ -37,12 +38,6 @@  #include <fsl_pmic.h>  #include <mc13892.h>  #include <usb/ehci-fsl.h> -#include <linux/fb.h> -#include <ipu_pixfmt.h> - -#define MX51EVK_LCD_3V3		IMX_GPIO_NR(4, 9) -#define MX51EVK_LCD_5V		IMX_GPIO_NR(4, 10) -#define MX51EVK_LCD_BACKLIGHT	IMX_GPIO_NR(3, 4)  DECLARE_GLOBAL_DATA_PTR; @@ -477,54 +472,6 @@ int board_mmc_init(bd_t *bis)  }  #endif -static struct fb_videomode const claa_wvga = { -	.name		= "CLAA07LC0ACW", -	.refresh	= 57, -	.xres		= 800, -	.yres		= 480, -	.pixclock	= 37037, -	.left_margin	= 40, -	.right_margin	= 60, -	.upper_margin	= 10, -	.lower_margin	= 10, -	.hsync_len	= 20, -	.vsync_len	= 10, -	.sync		= 0, -	.vmode		= FB_VMODE_NONINTERLACED -}; - -void lcd_iomux(void) -{ -	/* DI2_PIN15 */ -	mxc_request_iomux(MX51_PIN_DI_GP4, IOMUX_CONFIG_ALT4); - -	/* Pad settings for MX51_PIN_DI2_DISP_CLK */ -	mxc_iomux_set_pad(MX51_PIN_DI2_DISP_CLK, PAD_CTL_HYS_NONE | -			  PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_KEEPER | -			  PAD_CTL_DRV_MAX | PAD_CTL_SRE_SLOW); - -	/* Turn on 3.3V voltage for LCD */ -	mxc_request_iomux(MX51_PIN_CSI2_D12, IOMUX_CONFIG_ALT3); -	gpio_direction_output(MX51EVK_LCD_3V3, 1); - -	/* Turn on 5V voltage for LCD */ -	mxc_request_iomux(MX51_PIN_CSI2_D13, IOMUX_CONFIG_ALT3); -	gpio_direction_output(MX51EVK_LCD_5V, 1); - -	/* Turn on GPIO backlight */ -	mxc_request_iomux(MX51_PIN_DI1_D1_CS, IOMUX_CONFIG_ALT4); -	mxc_iomux_set_input(MX51_GPIO3_IPP_IND_G_IN_4_SELECT_INPUT, -							INPUT_CTL_PATH1); -	gpio_direction_output(MX51EVK_LCD_BACKLIGHT, 1); -} - -void lcd_enable(void) -{ -	int ret = ipuv3_fb_init(&claa_wvga, 1, IPU_PIX_FMT_RGB565); -	if (ret) -		printf("LCD cannot be configured: %d\n", ret); -} -  int board_early_init_f(void)  {  	setup_iomux_uart(); @@ -532,7 +479,7 @@ int board_early_init_f(void)  #ifdef CONFIG_USB_EHCI_MX5  	setup_usb_h1();  #endif -	lcd_iomux(); +	setup_iomux_lcd();  	return 0;  } diff --git a/board/freescale/mx51evk/mx51evk_video.c b/board/freescale/mx51evk/mx51evk_video.c new file mode 100644 index 000000000..f036cf73b --- /dev/null +++ b/board/freescale/mx51evk/mx51evk_video.c @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2012 Freescale Semiconductor, Inc. + * Fabio Estevam <fabio.estevam@freescale.com> + * + * 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 <linux/list.h> +#include <asm/gpio.h> +#include <asm/arch/iomux.h> +#include <linux/fb.h> +#include <ipu_pixfmt.h> + +#define MX51EVK_LCD_3V3		IMX_GPIO_NR(4, 9) +#define MX51EVK_LCD_5V		IMX_GPIO_NR(4, 10) +#define MX51EVK_LCD_BACKLIGHT	IMX_GPIO_NR(3, 4) + +static struct fb_videomode const claa_wvga = { +	.name		= "CLAA07LC0ACW", +	.refresh	= 57, +	.xres		= 800, +	.yres		= 480, +	.pixclock	= 37037, +	.left_margin	= 40, +	.right_margin	= 60, +	.upper_margin	= 10, +	.lower_margin	= 10, +	.hsync_len	= 20, +	.vsync_len	= 10, +	.sync		= 0, +	.vmode		= FB_VMODE_NONINTERLACED +}; + +void setup_iomux_lcd(void) +{ +	/* DI2_PIN15 */ +	mxc_request_iomux(MX51_PIN_DI_GP4, IOMUX_CONFIG_ALT4); + +	/* Pad settings for MX51_PIN_DI2_DISP_CLK */ +	mxc_iomux_set_pad(MX51_PIN_DI2_DISP_CLK, PAD_CTL_HYS_NONE | +			  PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_KEEPER | +			  PAD_CTL_DRV_MAX | PAD_CTL_SRE_SLOW); + +	/* Turn on 3.3V voltage for LCD */ +	mxc_request_iomux(MX51_PIN_CSI2_D12, IOMUX_CONFIG_ALT3); +	gpio_direction_output(MX51EVK_LCD_3V3, 1); + +	/* Turn on 5V voltage for LCD */ +	mxc_request_iomux(MX51_PIN_CSI2_D13, IOMUX_CONFIG_ALT3); +	gpio_direction_output(MX51EVK_LCD_5V, 1); + +	/* Turn on GPIO backlight */ +	mxc_request_iomux(MX51_PIN_DI1_D1_CS, IOMUX_CONFIG_ALT4); +	mxc_iomux_set_input(MX51_GPIO3_IPP_IND_G_IN_4_SELECT_INPUT, +							INPUT_CTL_PATH1); +	gpio_direction_output(MX51EVK_LCD_BACKLIGHT, 1); +} + +void lcd_enable(void) +{ +	int ret = ipuv3_fb_init(&claa_wvga, 1, IPU_PIX_FMT_RGB565); +	if (ret) +		printf("LCD cannot be configured: %d\n", ret); +} diff --git a/board/freescale/mx53loco/Makefile b/board/freescale/mx53loco/Makefile index 8bc69a92c..3be17c591 100644 --- a/board/freescale/mx53loco/Makefile +++ b/board/freescale/mx53loco/Makefile @@ -22,8 +22,10 @@ include $(TOPDIR)/config.mk  LIB	= $(obj)lib$(BOARD).o -COBJS	:= mx53loco.o +COBJS-y			+= mx53loco.o +COBJS-$(CONFIG_VIDEO)	+= mx53loco_video.o +COBJS	:= $(COBJS-y)  SRCS	:= $(COBJS:.o=.c)  OBJS	:= $(addprefix $(obj),$(COBJS)) diff --git a/board/freescale/mx53loco/mx53loco.c b/board/freescale/mx53loco/mx53loco.c index f4a9b0842..81c511cdc 100644 --- a/board/freescale/mx53loco/mx53loco.c +++ b/board/freescale/mx53loco/mx53loco.c @@ -31,6 +31,7 @@  #include <asm/arch/iomux.h>  #include <asm/arch/clock.h>  #include <asm/errno.h> +#include <asm/imx-common/mx5_video.h>  #include <netdev.h>  #include <i2c.h>  #include <mmc.h> @@ -423,74 +424,11 @@ static void clock_1GHz(void)  		printf("CPU:   Switch DDR clock to 400MHz failed\n");  } -static struct fb_videomode const claa_wvga = { -	.name		= "CLAA07LC0ACW", -	.refresh	= 57, -	.xres		= 800, -	.yres		= 480, -	.pixclock	= 37037, -	.left_margin	= 40, -	.right_margin	= 60, -	.upper_margin	= 10, -	.lower_margin	= 10, -	.hsync_len	= 20, -	.vsync_len	= 10, -	.sync		= 0, -	.vmode		= FB_VMODE_NONINTERLACED -}; - -void lcd_iomux(void) -{ -	mxc_request_iomux(MX53_PIN_DI0_DISP_CLK, IOMUX_CONFIG_ALT0); -	mxc_request_iomux(MX53_PIN_DI0_PIN15, IOMUX_CONFIG_ALT0); -	mxc_request_iomux(MX53_PIN_DI0_PIN2, IOMUX_CONFIG_ALT0); -	mxc_request_iomux(MX53_PIN_DI0_PIN3, IOMUX_CONFIG_ALT0); -	mxc_request_iomux(MX53_PIN_DISP0_DAT0, IOMUX_CONFIG_ALT0); -	mxc_request_iomux(MX53_PIN_DISP0_DAT1, IOMUX_CONFIG_ALT0); -	mxc_request_iomux(MX53_PIN_DISP0_DAT2, IOMUX_CONFIG_ALT0); -	mxc_request_iomux(MX53_PIN_DISP0_DAT3, IOMUX_CONFIG_ALT0); -	mxc_request_iomux(MX53_PIN_DISP0_DAT4, IOMUX_CONFIG_ALT0); -	mxc_request_iomux(MX53_PIN_DISP0_DAT5, IOMUX_CONFIG_ALT0); -	mxc_request_iomux(MX53_PIN_DISP0_DAT6, IOMUX_CONFIG_ALT0); -	mxc_request_iomux(MX53_PIN_DISP0_DAT7, IOMUX_CONFIG_ALT0); -	mxc_request_iomux(MX53_PIN_DISP0_DAT8, IOMUX_CONFIG_ALT0); -	mxc_request_iomux(MX53_PIN_DISP0_DAT9, IOMUX_CONFIG_ALT0); -	mxc_request_iomux(MX53_PIN_DISP0_DAT10, IOMUX_CONFIG_ALT0); -	mxc_request_iomux(MX53_PIN_DISP0_DAT11, IOMUX_CONFIG_ALT0); -	mxc_request_iomux(MX53_PIN_DISP0_DAT12, IOMUX_CONFIG_ALT0); -	mxc_request_iomux(MX53_PIN_DISP0_DAT13, IOMUX_CONFIG_ALT0); -	mxc_request_iomux(MX53_PIN_DISP0_DAT14, IOMUX_CONFIG_ALT0); -	mxc_request_iomux(MX53_PIN_DISP0_DAT15, IOMUX_CONFIG_ALT0); -	mxc_request_iomux(MX53_PIN_DISP0_DAT16, IOMUX_CONFIG_ALT0); -	mxc_request_iomux(MX53_PIN_DISP0_DAT17, IOMUX_CONFIG_ALT0); -	mxc_request_iomux(MX53_PIN_DISP0_DAT18, IOMUX_CONFIG_ALT0); -	mxc_request_iomux(MX53_PIN_DISP0_DAT19, IOMUX_CONFIG_ALT0); -	mxc_request_iomux(MX53_PIN_DISP0_DAT20, IOMUX_CONFIG_ALT0); -	mxc_request_iomux(MX53_PIN_DISP0_DAT21, IOMUX_CONFIG_ALT0); -	mxc_request_iomux(MX53_PIN_DISP0_DAT22, IOMUX_CONFIG_ALT0); -	mxc_request_iomux(MX53_PIN_DISP0_DAT23, IOMUX_CONFIG_ALT0); - -	/* Turn on GPIO backlight */ -	mxc_request_iomux(MX53_PIN_EIM_D24, IOMUX_CONFIG_ALT1); -	gpio_direction_output(MX53LOCO_LCD_POWER, 1); - -	/* Turn on display contrast */ -	mxc_request_iomux(MX53_PIN_GPIO_1, IOMUX_CONFIG_ALT1); -	gpio_direction_output(IOMUX_TO_GPIO(MX53_PIN_GPIO_1), 1); -} - -void lcd_enable(void) -{ -	int ret = ipuv3_fb_init(&claa_wvga, 0, IPU_PIX_FMT_RGB565); -	if (ret) -		printf("LCD cannot be configured: %d\n", ret); -} -  int board_early_init_f(void)  {  	setup_iomux_uart();  	setup_iomux_fec(); -	lcd_iomux(); +	setup_iomux_lcd();  	return 0;  } diff --git a/board/freescale/mx53loco/mx53loco_video.c b/board/freescale/mx53loco/mx53loco_video.c new file mode 100644 index 000000000..69991e851 --- /dev/null +++ b/board/freescale/mx53loco/mx53loco_video.c @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2012 Freescale Semiconductor, Inc. + * Fabio Estevam <fabio.estevam@freescale.com> + * + * 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 <linux/list.h> +#include <asm/gpio.h> +#include <asm/arch/iomux.h> +#include <linux/fb.h> +#include <ipu_pixfmt.h> + +#define MX53LOCO_LCD_POWER		IMX_GPIO_NR(3, 24) + +static struct fb_videomode const claa_wvga = { +	.name		= "CLAA07LC0ACW", +	.refresh	= 57, +	.xres		= 800, +	.yres		= 480, +	.pixclock	= 37037, +	.left_margin	= 40, +	.right_margin	= 60, +	.upper_margin	= 10, +	.lower_margin	= 10, +	.hsync_len	= 20, +	.vsync_len	= 10, +	.sync		= 0, +	.vmode		= FB_VMODE_NONINTERLACED +}; + +void setup_iomux_lcd(void) +{ +	mxc_request_iomux(MX53_PIN_DI0_DISP_CLK, IOMUX_CONFIG_ALT0); +	mxc_request_iomux(MX53_PIN_DI0_PIN15, IOMUX_CONFIG_ALT0); +	mxc_request_iomux(MX53_PIN_DI0_PIN2, IOMUX_CONFIG_ALT0); +	mxc_request_iomux(MX53_PIN_DI0_PIN3, IOMUX_CONFIG_ALT0); +	mxc_request_iomux(MX53_PIN_DISP0_DAT0, IOMUX_CONFIG_ALT0); +	mxc_request_iomux(MX53_PIN_DISP0_DAT1, IOMUX_CONFIG_ALT0); +	mxc_request_iomux(MX53_PIN_DISP0_DAT2, IOMUX_CONFIG_ALT0); +	mxc_request_iomux(MX53_PIN_DISP0_DAT3, IOMUX_CONFIG_ALT0); +	mxc_request_iomux(MX53_PIN_DISP0_DAT4, IOMUX_CONFIG_ALT0); +	mxc_request_iomux(MX53_PIN_DISP0_DAT5, IOMUX_CONFIG_ALT0); +	mxc_request_iomux(MX53_PIN_DISP0_DAT6, IOMUX_CONFIG_ALT0); +	mxc_request_iomux(MX53_PIN_DISP0_DAT7, IOMUX_CONFIG_ALT0); +	mxc_request_iomux(MX53_PIN_DISP0_DAT8, IOMUX_CONFIG_ALT0); +	mxc_request_iomux(MX53_PIN_DISP0_DAT9, IOMUX_CONFIG_ALT0); +	mxc_request_iomux(MX53_PIN_DISP0_DAT10, IOMUX_CONFIG_ALT0); +	mxc_request_iomux(MX53_PIN_DISP0_DAT11, IOMUX_CONFIG_ALT0); +	mxc_request_iomux(MX53_PIN_DISP0_DAT12, IOMUX_CONFIG_ALT0); +	mxc_request_iomux(MX53_PIN_DISP0_DAT13, IOMUX_CONFIG_ALT0); +	mxc_request_iomux(MX53_PIN_DISP0_DAT14, IOMUX_CONFIG_ALT0); +	mxc_request_iomux(MX53_PIN_DISP0_DAT15, IOMUX_CONFIG_ALT0); +	mxc_request_iomux(MX53_PIN_DISP0_DAT16, IOMUX_CONFIG_ALT0); +	mxc_request_iomux(MX53_PIN_DISP0_DAT17, IOMUX_CONFIG_ALT0); +	mxc_request_iomux(MX53_PIN_DISP0_DAT18, IOMUX_CONFIG_ALT0); +	mxc_request_iomux(MX53_PIN_DISP0_DAT19, IOMUX_CONFIG_ALT0); +	mxc_request_iomux(MX53_PIN_DISP0_DAT20, IOMUX_CONFIG_ALT0); +	mxc_request_iomux(MX53_PIN_DISP0_DAT21, IOMUX_CONFIG_ALT0); +	mxc_request_iomux(MX53_PIN_DISP0_DAT22, IOMUX_CONFIG_ALT0); +	mxc_request_iomux(MX53_PIN_DISP0_DAT23, IOMUX_CONFIG_ALT0); + +	/* Turn on GPIO backlight */ +	mxc_request_iomux(MX53_PIN_EIM_D24, IOMUX_CONFIG_ALT1); +	gpio_direction_output(MX53LOCO_LCD_POWER, 1); + +	/* Turn on display contrast */ +	mxc_request_iomux(MX53_PIN_GPIO_1, IOMUX_CONFIG_ALT1); +	gpio_direction_output(IOMUX_TO_GPIO(MX53_PIN_GPIO_1), 1); +} + +void lcd_enable(void) +{ +	int ret = ipuv3_fb_init(&claa_wvga, 0, IPU_PIX_FMT_RGB565); +	if (ret) +		printf("LCD cannot be configured: %d\n", ret); +} diff --git a/common/cmd_bmp.c b/common/cmd_bmp.c index b8809e3bf..5a52edde3 100644 --- a/common/cmd_bmp.c +++ b/common/cmd_bmp.c @@ -31,6 +31,7 @@  #include <command.h>  #include <asm/byteorder.h>  #include <malloc.h> +#include <video.h>  static int bmp_info (ulong addr); @@ -238,9 +239,7 @@ int bmp_display(ulong addr, int x, int y)  #if defined(CONFIG_LCD)  	ret = lcd_display_bitmap((ulong)bmp, x, y);  #elif defined(CONFIG_VIDEO) -	extern int video_display_bitmap (ulong, int, int); - -	ret = video_display_bitmap ((unsigned long)bmp, x, y); +	ret = video_display_bitmap((unsigned long)bmp, x, y);  #else  # error bmp_display() requires CONFIG_LCD or CONFIG_VIDEO  #endif diff --git a/common/lcd.c b/common/lcd.c index b6be8002d..4c83a8bf0 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -642,6 +642,138 @@ static void splash_align_axis(int *axis, unsigned long panel_size,  }  #endif + +#ifdef CONFIG_LCD_BMP_RLE8 + +#define BMP_RLE8_ESCAPE		0 +#define BMP_RLE8_EOL		0 +#define BMP_RLE8_EOBMP		1 +#define BMP_RLE8_DELTA		2 + +static void draw_unencoded_bitmap(ushort **fbp, uchar *bmap, ushort *cmap, +				  int cnt) +{ +	while (cnt > 0) { +		*(*fbp)++ = cmap[*bmap++]; +		cnt--; +	} +} + +static void draw_encoded_bitmap(ushort **fbp, ushort c, int cnt) +{ +	ushort *fb = *fbp; +	int cnt_8copy = cnt >> 3; + +	cnt -= cnt_8copy << 3; +	while (cnt_8copy > 0) { +		*fb++ = c; +		*fb++ = c; +		*fb++ = c; +		*fb++ = c; +		*fb++ = c; +		*fb++ = c; +		*fb++ = c; +		*fb++ = c; +		cnt_8copy--; +	} +	while (cnt > 0) { +		*fb++ = c; +		cnt--; +	} +	(*fbp) = fb; +} + +/* + * Do not call this function directly, must be called from + * lcd_display_bitmap. + */ +static void lcd_display_rle8_bitmap(bmp_image_t *bmp, ushort *cmap, uchar *fb, +				    int x_off, int y_off) +{ +	uchar *bmap; +	ulong width, height; +	ulong cnt, runlen; +	int x, y; +	int decode = 1; + +	width = le32_to_cpu(bmp->header.width); +	height = le32_to_cpu(bmp->header.height); +	bmap = (uchar *)bmp + le32_to_cpu(bmp->header.data_offset); + +	x = 0; +	y = height - 1; + +	while (decode) { +		if (bmap[0] == BMP_RLE8_ESCAPE) { +			switch (bmap[1]) { +			case BMP_RLE8_EOL: +				/* end of line */ +				bmap += 2; +				x = 0; +				y--; +				/* 16bpix, 2-byte per pixel, width should *2 */ +				fb -= (width * 2 + lcd_line_length); +				break; +			case BMP_RLE8_EOBMP: +				/* end of bitmap */ +				decode = 0; +				break; +			case BMP_RLE8_DELTA: +				/* delta run */ +				x += bmap[2]; +				y -= bmap[3]; +				/* 16bpix, 2-byte per pixel, x should *2 */ +				fb = (uchar *) (lcd_base + (y + y_off - 1) +					* lcd_line_length + (x + x_off) * 2); +				bmap += 4; +				break; +			default: +				/* unencoded run */ +				runlen = bmap[1]; +				bmap += 2; +				if (y < height) { +					if (x < width) { +						if (x + runlen > width) +							cnt = width - x; +						else +							cnt = runlen; +						draw_unencoded_bitmap( +							(ushort **)&fb, +							bmap, cmap, cnt); +					} +					x += runlen; +				} +				bmap += runlen; +				if (runlen & 1) +					bmap++; +			} +		} else { +			/* encoded run */ +			if (y < height) { +				runlen = bmap[0]; +				if (x < width) { +					/* aggregate the same code */ +					while (bmap[0] == 0xff && +					       bmap[2] != BMP_RLE8_ESCAPE && +					       bmap[1] == bmap[3]) { +						runlen += bmap[2]; +						bmap += 2; +					} +					if (x + runlen > width) +						cnt = width - x; +					else +						cnt = runlen; +					draw_encoded_bitmap((ushort **)&fb, +						cmap[bmap[1]], cnt); +				} +				x += runlen; +			} +			bmap += 2; +		} +	} +} +#endif +  #if defined(CONFIG_MPC823) || defined(CONFIG_MCC200)  #define FB_PUT_BYTE(fb, from) *(fb)++ = (255 - *(from)++)  #else @@ -675,7 +807,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)  	uchar *fb;  	bmp_image_t *bmp=(bmp_image_t *)bmp_image;  	uchar *bmap; -	ushort padded_line; +	ushort padded_width;  	unsigned long width, height, byte_width;  	unsigned long pwidth = panel_info.vl_col;  	unsigned colors, bpix, bmp_bpix; @@ -762,7 +894,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)  	}  #endif -	padded_line = (width&0x3) ? ((width&~0x3)+4) : (width); +	padded_width = (width&0x3) ? ((width&~0x3)+4) : (width);  #ifdef CONFIG_SPLASH_SCREEN_ALIGN  	splash_align_axis(&x, pwidth, width); @@ -781,6 +913,18 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)  	switch (bmp_bpix) {  	case 1: /* pass through */  	case 8: +#ifdef CONFIG_LCD_BMP_RLE8 +		if (le32_to_cpu(bmp->header.compression) == BMP_BI_RLE8) { +			if (bpix != 16) { +				/* TODO implement render code for bpix != 16 */ +				printf("Error: only support 16 bpix"); +				return 1; +			} +			lcd_display_rle8_bitmap(bmp, cmap_base, fb, x, y); +			break; +		} +#endif +  		if (bpix != 16)  			byte_width = width;  		else @@ -796,7 +940,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)  					fb += sizeof(uint16_t) / sizeof(*fb);  				}  			} -			bmap += (width - padded_line); +			bmap += (padded_width - width);  			fb   -= (byte_width + lcd_line_length);  		}  		break; @@ -808,7 +952,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)  			for (j = 0; j < width; j++)  				fb_put_word(&fb, &bmap); -			bmap += (padded_line - width) * 2; +			bmap += (padded_width - width) * 2;  			fb   -= (width * 2 + lcd_line_length);  		}  		break; @@ -885,5 +1029,31 @@ static void *lcd_logo(void)  #endif /* CONFIG_LCD_LOGO && !CONFIG_LCD_INFO_BELOW_LOGO */  } +void lcd_position_cursor(unsigned col, unsigned row) +{ +	console_col = min(col, CONSOLE_COLS - 1); +	console_row = min(row, CONSOLE_ROWS - 1); +} + +int lcd_get_pixel_width(void) +{ +	return panel_info.vl_col; +} + +int lcd_get_pixel_height(void) +{ +	return panel_info.vl_row; +} + +int lcd_get_screen_rows(void) +{ +	return CONSOLE_ROWS; +} + +int lcd_get_screen_columns(void) +{ +	return CONSOLE_COLS; +} +  /************************************************************************/  /************************************************************************/ diff --git a/drivers/video/atmel_hlcdfb.c b/drivers/video/atmel_hlcdfb.c index beb7fa396..b10ca4b67 100644 --- a/drivers/video/atmel_hlcdfb.c +++ b/drivers/video/atmel_hlcdfb.c @@ -51,6 +51,18 @@ short console_row;  #define lcdc_readl(reg)		__raw_readl((reg))  #define lcdc_writel(reg, val)	__raw_writel((val), (reg)) +/* + * the CLUT register map as following + * RCLUT(24 ~ 16), GCLUT(15 ~ 8), BCLUT(7 ~ 0) + */ +void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue) +{ +	lcdc_writel(((red << LCDC_BASECLUT_RCLUT_Pos) & LCDC_BASECLUT_RCLUT_Msk) +		| ((green << LCDC_BASECLUT_GCLUT_Pos) & LCDC_BASECLUT_GCLUT_Msk) +		| ((blue << LCDC_BASECLUT_BCLUT_Pos) & LCDC_BASECLUT_BCLUT_Msk), +		panel_info.mmio + ATMEL_LCDC_LUT(regno)); +} +  void lcd_ctrl_init(void *lcdbase)  {  	unsigned long value; diff --git a/drivers/video/bus_vcxk.c b/drivers/video/bus_vcxk.c index 9c4714d50..a0607cf43 100644 --- a/drivers/video/bus_vcxk.c +++ b/drivers/video/bus_vcxk.c @@ -153,7 +153,7 @@ int vcxk_init(unsigned long width, unsigned long height)  #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); +	debug("%px %px %px\n", double_bws, double_bws_word, double_bws_long);  #endif  	display_width  = width;  	display_height = height; diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c index 9c67b63bf..9388859da 100644 --- a/drivers/video/cfb_console.c +++ b/drivers/video/cfb_console.c @@ -1515,6 +1515,13 @@ int video_display_bitmap(ulong bmp_image, int x, int y)  	padded_line = (((width * bpp + 7) / 8) + 3) & ~0x3; +	/* +	 * Just ignore elements which are completely beyond screen +	 * dimensions. +	 */ +	if ((x >= VIDEO_VISIBLE_COLS) || (y >= VIDEO_VISIBLE_ROWS)) +		return 0; +  #ifdef CONFIG_SPLASH_SCREEN_ALIGN  	if (x == BMP_ALIGN_CENTER)  		x = max(0, (VIDEO_VISIBLE_COLS - width) / 2); @@ -2257,3 +2264,45 @@ int drv_video_init(void)  	/* Return success */  	return 1;  } + +void video_position_cursor(unsigned col, unsigned row) +{ +	console_col = min(col, CONSOLE_COLS - 1); +	console_row = min(row, CONSOLE_ROWS - 1); +} + +int video_get_pixel_width(void) +{ +	return VIDEO_VISIBLE_COLS; +} + +int video_get_pixel_height(void) +{ +	return VIDEO_VISIBLE_ROWS; +} + +int video_get_screen_rows(void) +{ +	return CONSOLE_ROWS; +} + +int video_get_screen_columns(void) +{ +	return CONSOLE_COLS; +} + +void video_clear(void) +{ +#ifdef VIDEO_HW_RECTFILL +	video_hw_rectfill(VIDEO_PIXEL_SIZE,	/* bytes per pixel */ +			  0,			/* dest pos x */ +			  0,			/* dest pos y */ +			  VIDEO_VISIBLE_COLS,	/* frame width */ +			  VIDEO_VISIBLE_ROWS,	/* frame height */ +			  bgx			/* fill color */ +	); +#else +	memsetl(video_fb_address, +		(VIDEO_VISIBLE_ROWS * VIDEO_LINE_LEN) / sizeof(int), bgx); +#endif +} diff --git a/drivers/video/ipu_common.c b/drivers/video/ipu_common.c index 0f2d113a6..ad4af5283 100644 --- a/drivers/video/ipu_common.c +++ b/drivers/video/ipu_common.c @@ -94,6 +94,7 @@ struct ipu_ch_param {  	temp1; \  }) +#define IPU_SW_RST_TOUT_USEC	(10000)  void clk_enable(struct clk *clk)  { @@ -398,11 +399,20 @@ void ipu_reset(void)  {  	u32 *reg;  	u32 value; +	int timeout = IPU_SW_RST_TOUT_USEC;  	reg = (u32 *)SRC_BASE_ADDR;  	value = __raw_readl(reg);  	value = value | SW_IPU_RST;  	__raw_writel(value, reg); + +	while (__raw_readl(reg) & SW_IPU_RST) { +		udelay(1); +		if (!(timeout--)) { +			printf("ipu software reset timeout\n"); +			break; +		} +	};  }  /* diff --git a/include/atmel_hlcdc.h b/include/atmel_hlcdc.h index 945b30acb..fbd2f9245 100644 --- a/include/atmel_hlcdc.h +++ b/include/atmel_hlcdc.h @@ -217,6 +217,13 @@ struct atmel_hlcd_regs {  #define LCDC_BASECFG3_RDEF(value) \  	((LCDC_BASECFG3_RDEF_Msk & ((value) << LCDC_BASECFG3_RDEF_Pos))) +#define LCDC_BASECLUT_BCLUT_Pos 0 +#define LCDC_BASECLUT_BCLUT_Msk (0xff << LCDC_BASECLUT_BCLUT_Pos) +#define LCDC_BASECLUT_GCLUT_Pos 8 +#define LCDC_BASECLUT_GCLUT_Msk (0xff << LCDC_BASECLUT_GCLUT_Pos) +#define LCDC_BASECLUT_RCLUT_Pos 16 +#define LCDC_BASECLUT_RCLUT_Msk (0xff << LCDC_BASECLUT_RCLUT_Pos) +  #define LCDC_BASECFG4_DMA	(0x1 << 8)  #define LCDC_BASECFG4_REP	(0x1 << 9) diff --git a/include/lcd.h b/include/lcd.h index 42070d763..2517d39d4 100644 --- a/include/lcd.h +++ b/include/lcd.h @@ -294,6 +294,42 @@ void	lcd_printf	(const char *fmt, ...);  void	lcd_clear(void);  int	lcd_display_bitmap(ulong bmp_image, int x, int y); +/** + * Get the width of the LCD in pixels + * + * @return width of LCD in pixels + */ +int lcd_get_pixel_width(void); + +/** + * Get the height of the LCD in pixels + * + * @return height of LCD in pixels + */ +int lcd_get_pixel_height(void); + +/** + * Get the number of text lines/rows on the LCD + * + * @return number of rows + */ +int lcd_get_screen_rows(void); + +/** + * Get the number of text columns on the LCD + * + * @return number of columns + */ +int lcd_get_screen_columns(void); + +/** + * Set the position of the text cursor + * + * @param col	Column to place cursor (0 = left side) + * @param row	Row to place cursor (0 = top line) + */ +void lcd_position_cursor(unsigned col, unsigned row); +  /* Allow boards to customize the information displayed */  void lcd_show_board_info(void); diff --git a/include/video.h b/include/video.h index 9519ceaf9..f7e27f847 100644 --- a/include/video.h +++ b/include/video.h @@ -15,4 +15,52 @@ int	video_init	(void *videobase);  void	video_putc	(const char c);  void	video_puts	(const char *s); +/** + * Display a BMP format bitmap on the screen + * + * @param bmp_image	Address of BMP image + * @param x		X position to draw image + * @param y		Y position to draw image + */ +int video_display_bitmap(ulong bmp_image, int x, int y); + +/** + * Get the width of the screen in pixels + * + * @return width of screen in pixels + */ +int video_get_pixel_width(void); + +/** + * Get the height of the screen in pixels + * + * @return height of screen in pixels + */ +int video_get_pixel_height(void); + +/** + * Get the number of text lines/rows on the screen + * + * @return number of rows + */ +int video_get_screen_rows(void); + +/** + * Get the number of text columns on the screen + * + * @return number of columns + */ +int video_get_screen_columns(void); + +/** + * Set the position of the text cursor + * + * @param col	Column to place cursor (0 = left side) + * @param row	Row to place cursor (0 = top line) + */ +void video_position_cursor(unsigned col, unsigned row); + +/* Clear the display */ +void video_clear(void); +  #endif |