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 00000000000..e54c25a560a --- /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 224eaa3c734..2310fe137d7 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 5504636ddf4..d1ef431895a 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 00000000000..f036cf73b2e --- /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 8bc69a92c1c..3be17c5917c 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 f4a9b084208..81c511cdc18 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 00000000000..69991e85116 --- /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 b8809e3bf54..5a52edde31d 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 b6be8002d20..4c83a8bf035 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 beb7fa396ea..b10ca4b6771 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 9c4714d50a5..a0607cf4336 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 9c67b63bf45..9388859da7e 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 0f2d113a6f1..ad4af5283a9 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 945b30acb01..fbd2f92457e 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 42070d76366..2517d39d414 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 9519ceaf98b..f7e27f8477b 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 |