summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeng Fan <Peng.Fan@freescale.com>2015-07-31 10:38:38 +0800
committerMax Krummenacher <max.krummenacher@toradex.com>2016-02-17 10:54:00 +0100
commit7db08c874041592b633703b4f95c008007c84f58 (patch)
tree35b7151c3c4d13aac61a03d6b722d90f351b2ac8
parentf834ffe797d8e052a69ee9476148f788f3e9bfc2 (diff)
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/Makefile1
-rw-r--r--board/freescale/common/epdc_setup.c183
-rw-r--r--drivers/video/mxc_epdc_fb.c16
-rw-r--r--include/common.h3
-rw-r--r--include/mxc_epdc_fb.h3
5 files changed, 194 insertions, 12 deletions
diff --git a/board/freescale/common/Makefile b/board/freescale/common/Makefile
index 7edb7588c0..0c7fa21d3b 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 0000000000..30622b8bc8
--- /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 cd18058cb7..f50c5097ff 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 6df05b8bb1..179392b465 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 5aa942e3d4..4f16a96b51 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__ */