diff options
-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__ */ |