summaryrefslogtreecommitdiff
path: root/board
diff options
context:
space:
mode:
authorPeng Fan <peng.fan@nxp.com>2016-02-23 10:14:34 +0800
committerYe Li <ye.li@nxp.com>2017-04-05 14:04:28 +0800
commit79a86adf2279336617ad7d4f0813f040b17318d4 (patch)
tree0e1a0a8af665bb83a40552091f6464bb0d93fc82 /board
parent27e20dc28570d710ecaa0db9db508c8ee750d1ae (diff)
downloadu-boot-imx-79a86adf2279336617ad7d4f0813f040b17318d4.zip
u-boot-imx-79a86adf2279336617ad7d4f0813f040b17318d4.tar.gz
u-boot-imx-79a86adf2279336617ad7d4f0813f040b17318d4.tar.bz2
MLK-12425-2: video: epdc: introduce epdc support
Support EPDC. E-Ink feature is supported by i.MX6DL/SL and i.MX7D. For now this driver only supports i.MX6DL/SL, because the i.MX7D EPDC driver needs pxp support which is not included in U-Boot. Support user defined logo file, if there is no logo file, it will draw a black border around a white screen. If need to enable EPDC, a waveform file is required to let all work. Since we need LCD_MONOCHROME mode for EPDC, we introduce LCD_MONOCHROME support. Please refer to Linux Reference Manual for how to flash WAVEFORM file. Signed-off-by: Peng Fan <peng.fan@nxp.com> Signed-off-by: Robby Cai <R63905@freescale.com> Signed-off-by: Nitin Garg <nitin.garg@freescale.com> Signed-off-by: Ye.Li <B37916@freescale.com> (cherry picked from commit a7244f279cc3c3994bcd103f5e9a183b1075ae71)
Diffstat (limited to 'board')
-rw-r--r--board/freescale/common/Makefile1
-rw-r--r--board/freescale/common/epdc_setup.c219
2 files changed, 220 insertions, 0 deletions
diff --git a/board/freescale/common/Makefile b/board/freescale/common/Makefile
index 802b490..7df6af2 100644
--- a/board/freescale/common/Makefile
+++ b/board/freescale/common/Makefile
@@ -63,6 +63,7 @@ obj-$(CONFIG_ZM7300) += zm7300.o
obj-$(CONFIG_POWER_PFUZE100) += pfuze.o
obj-$(CONFIG_POWER_MC34VR500) += mc34vr500.o
obj-$(CONFIG_DM_PMIC_PFUZE100) += pfuze_dm.o
+obj-$(CONFIG_MXC_EPDC) += epdc_setup.o
obj-$(CONFIG_LS102XA_STREAM_ID) += ls102xa_stream_id.o
diff --git a/board/freescale/common/epdc_setup.c b/board/freescale/common/epdc_setup.c
new file mode 100644
index 0000000..cd92167
--- /dev/null
+++ b/board/freescale/common/epdc_setup.c
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2016 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_waveform_file(ulong waveform_buf)
+{
+ char *fs_argv[5];
+ char addr[17];
+ ulong file_len, mmc_dev;
+
+ if (!check_mmc_autodetect())
+ mmc_dev = getenv_ulong("mmcdev", 10, 0);
+ else
+ mmc_dev = mmc_get_env_devno();
+
+ sprintf(addr, "%lx", waveform_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_waveform");
+
+ if (!fs_argv[4])
+ fs_argv[4] = "epdc_splash.bin";
+
+ if (do_fat_fsload(NULL, 0, 5, fs_argv)) {
+ printf("File %s not found on MMC Device %lu!\n", fs_argv[4], mmc_dev);
+ return -1;
+ }
+
+ file_len = getenv_hex("filesize", 0);
+ if (!file_len)
+ return -1;
+
+ flush_cache(waveform_buf, file_len);
+
+ 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(display_buf, 0x0, 24 * panel_info.vl_col);
+ for (i = 24; i < (panel_info.vl_row - 24); i++) {
+ memset((u8 *)display_buf + i * panel_info.vl_col,
+ 0x00, 24);
+ memset((u8 *)display_buf + i * panel_info.vl_col
+ + panel_info.vl_col - 24, 0x00, 24);
+ }
+ memset((u8 *)display_buf +
+ 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;
+}