diff options
author | Peng Fan <Peng.Fan@freescale.com> | 2015-07-31 10:38:38 +0800 |
---|---|---|
committer | Peng Fan <Peng.Fan@freescale.com> | 2015-08-03 18:29:02 +0800 |
commit | 738ace15de626866604ee927dc378c602de01fc8 (patch) | |
tree | e26d27ed97dc4051afb587ec57462fdfef8c5c43 | |
parent | 1eb44fca8789cc1aa605cbfcc7691829b188629e (diff) | |
download | u-boot-imx-738ace15de626866604ee927dc378c602de01fc8.zip u-boot-imx-738ace15de626866604ee927dc378c602de01fc8.tar.gz u-boot-imx-738ace15de626866604ee927dc378c602de01fc8.tar.bz2 |
MLK-11263-1 video: epdc: support display logo on E-Ink screen
Support draw image on E-ink screen.
1. The image format should be PGM-P5 raw data format.
2. The image should be named epdc_logo.pgm.
3. If no epdc_logo.pgm found in the first partition(FAT), will choose
to draw black border on the screen.
4. Default configuration is to draw image at pos (0,0). If 'splashpos'
env is set, will choose the pos from 'splashpos'.
5. The image size should not be bigger than screen total pixel size.
6. Implement board_setup_logo_file in board/freescale/common/epdc_setup.c
7. Introudce function prototype for board_setup_logo_file.
Note: i.MX7D EPDC supports advanced mode and standard mode. Since current
PXP in uboot for i.MX7D not ready, only support standard mode now.
advanced and standard mode needs waveform firmware's support.
Signed-off-by: Peng Fan <Peng.Fan@freescale.com>
-rw-r--r-- | board/freescale/common/Makefile | 1 | ||||
-rw-r--r-- | board/freescale/common/epdc_setup.c | 183 | ||||
-rw-r--r-- | drivers/video/mxc_epdc_fb.c | 16 | ||||
-rw-r--r-- | include/common.h | 3 | ||||
-rw-r--r-- | include/mxc_epdc_fb.h | 3 |
5 files changed, 194 insertions, 12 deletions
diff --git a/board/freescale/common/Makefile b/board/freescale/common/Makefile index 7edb758..0c7fa21 100644 --- a/board/freescale/common/Makefile +++ b/board/freescale/common/Makefile @@ -61,6 +61,7 @@ obj-$(CONFIG_VSC_CROSSBAR) += vsc3316_3308.o obj-$(CONFIG_IDT8T49N222A) += idt8t49n222a_serdes_clk.o obj-$(CONFIG_ZM7300) += zm7300.o obj-$(CONFIG_POWER_PFUZE100) += pfuze.o +obj-$(CONFIG_MXC_EPDC) += epdc_setup.o ifdef CONFIG_FSL_FASTBOOT obj-${CONFIG_ANDROID_RECOVERY} += recovery.o endif diff --git a/board/freescale/common/epdc_setup.c b/board/freescale/common/epdc_setup.c new file mode 100644 index 0000000..30622b8 --- /dev/null +++ b/board/freescale/common/epdc_setup.c @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2015 Freescale Semiconductor, Inc. All Rights Reserved. + * + * Peng Fan <Peng.Fan@freescale.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <common.h> +#include <lcd.h> +#include <linux/err.h> +#include <linux/types.h> +#include <malloc.h> +#include <mxc_epdc_fb.h> + +#define is_digit(c) ((c) >= '0' && (c) <= '9') +__weak int mmc_get_env_devno(void) +{ + return 0; +} +__weak int check_mmc_autodetect(void) +{ + return 0; +} + +int board_setup_logo_file(void *display_buf) +{ + int logo_width, logo_height; + char *fs_argv[5]; + char addr[17]; + int array[3]; + ulong file_len, mmc_dev; + char *buf, *s; + int arg = 0, val = 0, pos = 0; + int i, j, max_check_length; + int row, col, row_end, col_end; + + if (!display_buf) + return -EINVAL; + + /* Assume PGM header not exceeds 128 bytes */ + max_check_length = 128; + + if (!check_mmc_autodetect()) + mmc_dev = getenv_ulong("mmcdev", 10, 0); + else + mmc_dev = mmc_get_env_devno(); + + memset(display_buf, 0xFF, panel_info.vl_col * panel_info.vl_row); + + fs_argv[0] = "fatsize"; + fs_argv[1] = "mmc"; + fs_argv[2] = simple_itoa(mmc_dev); + fs_argv[3] = getenv("epdc_logo"); + if (!fs_argv[3]) + fs_argv[3] = "epdc_logo.pgm"; + if (do_fat_size(NULL, 0, 4, fs_argv)) { + debug("File %s not found on MMC Device %lu, use black border\n", fs_argv[3], mmc_dev); + /* Draw black border around framebuffer*/ + memset(lcd_base, 0x0, 24 * panel_info.vl_col); + for (i = 24; i < (panel_info.vl_row - 24); i++) { + memset((u8 *)lcd_base + i * panel_info.vl_col, + 0x00, 24); + memset((u8 *)lcd_base + i * panel_info.vl_col + + panel_info.vl_col - 24, 0x00, 24); + } + memset((u8 *)lcd_base + + panel_info.vl_col * (panel_info.vl_row - 24), + 0x00, 24 * panel_info.vl_col); + return 0; + } + + file_len = getenv_hex("filesize", 0); + if (!file_len) + return -EINVAL; + + buf = memalign(ARCH_DMA_MINALIGN, file_len); + if (!buf) + return -ENOMEM; + + sprintf(addr, "%lx", (ulong)buf); + + fs_argv[0] = "fatload"; + fs_argv[1] = "mmc"; + fs_argv[2] = simple_itoa(mmc_dev); + fs_argv[3] = addr; + fs_argv[4] = getenv("epdc_logo"); + + if (!fs_argv[4]) + fs_argv[4] = "epdc_logo.pgm"; + + if (do_fat_fsload(NULL, 0, 5, fs_argv)) { + printf("File %s not found on MMC Device %lu!\n", fs_argv[4], mmc_dev); + free(buf); + return -1; + } + + if (strncmp(buf, "P5", 2)) { + printf("Wrong format for epdc logo, use PGM-P5 format.\n"); + free(buf); + return -EINVAL; + } + /* Skip P5\n */ + pos += 3; + arg = 0; + for (i = 3; i < max_check_length; ) { + /* skip \n \t and space */ + if ((buf[i] == '\n') || (buf[i] == '\t') || (buf[i] == ' ')) { + i++; + continue; + } + /* skip comment */ + if (buf[i] == '#') { + while (buf[i++] != '\n') + ; + continue; + } + + /* HEIGTH, WIDTH, MAX PIXEL VLAUE total 3 args */ + if (arg > 2) + break; + val = 0; + while (is_digit(buf[i])) { + val = val * 10 + buf[i] - '0'; + i++; + } + array[arg++] = val; + + i++; + } + + /* Point to data area */ + pos = i; + + logo_width = array[0]; + logo_height = array[1]; + + if ((logo_width > panel_info.vl_col) || + (logo_height > panel_info.vl_row)) { + printf("Picture: too big\n"); + free(buf); + return -EINVAL; + } + + /* m,m means center of screen */ + row = 0; + col = 0; + s = getenv("splashpos"); + if (s) { + if (s[0] == 'm') + col = (panel_info.vl_col - logo_width) >> 1; + else + col = simple_strtol(s, NULL, 0); + s = strchr(s + 1, ','); + if (s != NULL) { + if (s[1] == 'm') + row = (panel_info.vl_row - logo_height) >> 1; + else + row = simple_strtol(s + 1, NULL, 0); + } + } + if ((col + logo_width > panel_info.vl_col) || + (row + logo_height > panel_info.vl_row)) { + printf("Incorrect pos, use (0, 0)\n"); + row = 0; + col = 0; + } + + /* Draw picture at the center of screen */ + row_end = row + logo_height; + col_end = col + logo_width; + for (i = row; i < row_end; i++) { + for (j = col; j < col_end; j++) { + *((u8 *)display_buf + i * (panel_info.vl_col) + j) = + buf[pos++]; + } + } + + free(buf); + + flush_cache((ulong)display_buf, file_len - pos - 1); + + return 0; +} diff --git a/drivers/video/mxc_epdc_fb.c b/drivers/video/mxc_epdc_fb.c index cd18058..f50c509 100644 --- a/drivers/video/mxc_epdc_fb.c +++ b/drivers/video/mxc_epdc_fb.c @@ -350,21 +350,13 @@ static void draw_splash_screen(void) void lcd_enable(void) { - int i; + if (board_setup_logo_file(lcd_base)) { + debug("Load logo failed!\n"); + return; + } epdc_power_on(); - /* Draw black border around framebuffer*/ - memset(lcd_base, 0xFF, panel_info.vl_col * panel_info.vl_row); - memset(lcd_base, 0x0, 24 * panel_info.vl_col); - for (i = 24; i < (panel_info.vl_row - 24); i++) { - memset((u8 *)lcd_base + i * panel_info.vl_col, 0x00, 24); - memset((u8 *)lcd_base + i * panel_info.vl_col - + panel_info.vl_col - 24, 0x00, 24); - } - memset((u8 *)lcd_base + panel_info.vl_col * (panel_info.vl_row - 24), - 0x00, 24 * panel_info.vl_col); - flush_cache((ulong)lcd_base, panel_info.vl_col * panel_info.vl_row); /* Draw data to display */ diff --git a/include/common.h b/include/common.h index 6df05b8..179392b 100644 --- a/include/common.h +++ b/include/common.h @@ -306,6 +306,9 @@ void doc_probe(unsigned long physadr); int do_tftpb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); /* common/cmd_fat.c */ +int do_fat_size(cmd_tbl_t *, int, int, char * const []); + +/* common/cmd_fat.c */ int do_fat_fsload(cmd_tbl_t *, int, int, char * const []); /* common/cmd_ext2.c */ diff --git a/include/mxc_epdc_fb.h b/include/mxc_epdc_fb.h index 5aa942e..4f16a96 100644 --- a/include/mxc_epdc_fb.h +++ b/include/mxc_epdc_fb.h @@ -556,7 +556,10 @@ enum { }; int setup_waveform_file(ulong waveform_buf); +int board_setup_logo_file(void *display_buf); void epdc_power_on(void); void epdc_power_off(void); +extern void *lcd_base; + #endif /* __EPDC_REGS_INCLUDED__ */ |