MLK-12425-2 video: epdc: introduce epdc support
authorPeng Fan <peng.fan@nxp.com>
Tue, 23 Feb 2016 02:14:34 +0000 (10:14 +0800)
committerYe Li <ye.li@nxp.com>
Thu, 29 Apr 2021 05:03:35 +0000 (22:03 -0700)
Support EPDC.
E-Ink feature is supported by i.MX6DL/SL/SLL/ULL and i.MX7D.

This driver supports 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)
(cherry picked from commit 21bf1c38b7d75c31875fb02a972c458f25d9c33a)
(cherry picked from commit 237742f73998b35dd896592e19f1e119e72baa71)
(cherry picked from commit 3e788604343274e806510261aea407a9d916755b)

board/freescale/common/Makefile
board/freescale/common/epdc_setup.c [new file with mode: 0644]
common/lcd.c
common/lcd_console.c
drivers/video/Kconfig
drivers/video/Makefile
drivers/video/mxc_epdc_fb.c [new file with mode: 0644]
include/fs.h
include/lcd.h
include/mxc_epdc_fb.h [new file with mode: 0644]

index aef4975..572a89c 100644 (file)
@@ -59,6 +59,7 @@ obj-$(CONFIG_ZM7300)          += zm7300.o
 obj-$(CONFIG_POWER_PFUZE100)   += pfuze.o
 obj-$(CONFIG_DM_PMIC_PFUZE100) += pfuze.o
 obj-$(CONFIG_POWER_MC34VR500)  += mc34vr500.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 (file)
index 0000000..78935c6
--- /dev/null
@@ -0,0 +1,226 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * Peng Fan <Peng.Fan@freescale.com>
+ */
+#include <common.h>
+#include <lcd.h>
+#include <linux/err.h>
+#include <linux/types.h>
+#include <malloc.h>
+#include <mxc_epdc_fb.h>
+#include <fs.h>
+#include <cpu_func.h>
+#include <env.h>
+#include <asm/cache.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 = env_get_ulong("mmcdev", 10, 0);
+       else
+               mmc_dev = mmc_get_env_devno();
+
+       sprintf(addr, "%lx", (ulong)CONFIG_SYS_LOAD_ADDR);
+
+       fs_argv[0] = "fatload";
+       fs_argv[1] = "mmc";
+       fs_argv[2] = simple_itoa(mmc_dev);
+       fs_argv[3] = addr;
+       fs_argv[4] = env_get("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 = env_get_hex("filesize", 0);
+       if (!file_len)
+               return -1;
+
+       memcpy((void *)waveform_buf, (const void *)CONFIG_SYS_LOAD_ADDR, file_len);
+
+       flush_cache(waveform_buf, roundup(file_len, ARCH_DMA_MINALIGN));
+
+       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 = env_get_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] = env_get("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 = env_get_hex("filesize", 0);
+       if (!file_len)
+               return -EINVAL;
+
+       buf = memalign(ARCH_DMA_MINALIGN, file_len);
+       if (!buf)
+               return -ENOMEM;
+
+       sprintf(addr, "%lx", (ulong)CONFIG_SYS_LOAD_ADDR);
+
+       fs_argv[0] = "fatload";
+       fs_argv[1] = "mmc";
+       fs_argv[2] = simple_itoa(mmc_dev);
+       fs_argv[3] = addr;
+       fs_argv[4] = env_get("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;
+       }
+
+       memcpy((void *)buf, (const void *)CONFIG_SYS_LOAD_ADDR, file_len);
+
+       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 = env_get("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;
+}
index ab5614a..4b17a23 100644 (file)
 #define CONFIG_LCD_ALIGNMENT PAGE_SIZE
 #endif
 
-#if (LCD_BPP != LCD_COLOR8) && (LCD_BPP != LCD_COLOR16) && \
-       (LCD_BPP != LCD_COLOR32)
-#error Unsupported LCD BPP.
-#endif
-
 DECLARE_GLOBAL_DATA_PTR;
 
 static int lcd_init(void *lcdbase);
@@ -175,10 +170,13 @@ int drv_lcd_init(void)
 
 void lcd_clear(void)
 {
-       int bg_color;
        __maybe_unused ulong addr;
        static int do_splash = 1;
-#if LCD_BPP == LCD_COLOR8
+#if LCD_BPP == LCD_MONOCHROME
+       /* Setting the palette */
+       lcd_initcolregs();
+
+#elif LCD_BPP == LCD_COLOR8
        /* Setting the palette */
        lcd_setcolreg(CONSOLE_COLOR_BLACK, 0, 0, 0);
        lcd_setcolreg(CONSOLE_COLOR_RED, 0xFF, 0, 0);
@@ -194,11 +192,9 @@ void lcd_clear(void)
 #ifndef CONFIG_SYS_WHITE_ON_BLACK
        lcd_setfgcolor(CONSOLE_COLOR_BLACK);
        lcd_setbgcolor(CONSOLE_COLOR_WHITE);
-       bg_color = CONSOLE_COLOR_WHITE;
 #else
        lcd_setfgcolor(CONSOLE_COLOR_WHITE);
        lcd_setbgcolor(CONSOLE_COLOR_BLACK);
-       bg_color = CONSOLE_COLOR_BLACK;
 #endif /* CONFIG_SYS_WHITE_ON_BLACK */
 
 #ifdef LCD_TEST_PATTERN
@@ -206,14 +202,15 @@ void lcd_clear(void)
 #else
        /* set framebuffer to background color */
 #if (LCD_BPP != LCD_COLOR32)
-       memset((char *)lcd_base, bg_color, lcd_line_length * panel_info.vl_row);
+       memset((char *)lcd_base, COLOR_MASK(lcd_getbgcolor()),
+              lcd_line_length * panel_info.vl_row);
 #else
        u32 *ppix = lcd_base;
        u32 i;
        for (i = 0;
           i < (lcd_line_length * panel_info.vl_row)/NBYTES(panel_info.vl_bpix);
           i++) {
-               *ppix++ = bg_color;
+               *ppix++ = COLOR_MASK(lcd_getbgcolor());
        }
 #endif
 #endif
@@ -286,7 +283,7 @@ ulong lcd_setmem(ulong addr)
        ulong size;
        int line_length;
 
-       debug("LCD panel info: %d x %d, %d bit/pix\n", panel_info.vl_col,
+       debug("LCD panel info: %lu x %lu, %d bit/pix\n", panel_info.vl_col,
                panel_info.vl_row, NBITS(panel_info.vl_bpix));
 
        size = lcd_get_size(&line_length);
index 1a246c4..a70d44d 100644 (file)
@@ -48,17 +48,34 @@ static void lcd_putc_xy0(struct console_t *pcons, ushort x, ushort y, char c)
 {
        int fg_color = lcd_getfgcolor();
        int bg_color = lcd_getbgcolor();
-       int i, row;
+       int row;
+#if LCD_BPP == LCD_MONOCHROME
+       ushort off  = x * (1 << LCD_BPP) % 8;
+#else
+       int i;
+#endif
+
        fbptr_t *dst = (fbptr_t *)pcons->fbbase +
                                  y * pcons->lcdsizex +
                                  x;
 
        for (row = 0; row < VIDEO_FONT_HEIGHT; row++) {
                uchar bits = video_fontdata[c * VIDEO_FONT_HEIGHT + row];
+#if LCD_BPP == LCD_MONOCHROME
+               uchar rest = *dst & -(1 << (8 - off));
+               uchar sym;
+
+               sym  = (COLOR_MASK(fg_color) & bits) |
+                       (COLOR_MASK(bg_color) & ~bits);
+               *dst++ = rest | (sym >> off);
+               rest = sym << (8 - off);
+               *dst  = rest | (*dst & ((1 << (8 - off)) - 1));
+#else /* LCD_BPP == LCD_COLOR8 or LCD_COLOR16 or LCD_COLOR32 */
                for (i = 0; i < VIDEO_FONT_WIDTH; ++i) {
                        *dst++ = (bits & 0x80) ? fg_color : bg_color;
                        bits <<= 1;
                }
+#endif
                dst += (pcons->lcdsizex - VIDEO_FONT_WIDTH);
        }
 }
@@ -116,7 +133,7 @@ static inline void console_newline(void)
                for (i = 0; i < cons.rows-rows; i++)
                        cons.fp_console_moverow(&cons, i, i+rows);
                for (i = 0; i < rows; i++)
-                       cons.fp_console_setrow(&cons, cons.rows-i-1, bg_color);
+                       cons.fp_console_setrow(&cons, cons.rows-i-1, COLOR_MASK(bg_color));
                cons.curr_row -= rows;
        }
        lcd_sync();
index 667157c..b480979 100644 (file)
@@ -686,6 +686,18 @@ config VIDEO
          model. Video drivers typically provide a colour text console and
          cursor.
 
+config MXC_EPDC
+       bool "i.MX EPDC support"
+       depends on LCD && (MX7 || MX6)
+       help
+         This enable the E-ink EPD panel controller support for i.MX processors
+
+config WAVEFORM_BUF_SIZE
+       bool "The buffer size allocated for i.MX EPDC waveform file"
+       depends on MXC_EPDC
+       help
+         Set the buffer size for loading waveform file.
+
 config CFB_CONSOLE
        bool "Enable colour frame buffer console"
        depends on VIDEO || ARCH_OMAP2PLUS
index 933f06e..94a4581 100644 (file)
@@ -72,6 +72,7 @@ obj-$(CONFIG_VIDEO_TEGRA20) += tegra.o
 obj-$(CONFIG_VIDEO_VCXK) += bus_vcxk.o
 obj-$(CONFIG_VIDEO_VESA) += vesa.o
 obj-$(CONFIG_VIDEO_SEPS525) += seps525.o
+obj-$(CONFIG_MXC_EPDC) += mxc_epdc_fb.o
 
 obj-y += bridge/
 obj-y += sunxi/
diff --git a/drivers/video/mxc_epdc_fb.c b/drivers/video/mxc_epdc_fb.c
new file mode 100644 (file)
index 0000000..b4c91be
--- /dev/null
@@ -0,0 +1,469 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2010-2016 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+/*
+ * Based on STMP378X LCDIF
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+#include <common.h>
+#include <lcd.h>
+#include <linux/list.h>
+#include <linux/err.h>
+#include <linux/types.h>
+#include <malloc.h>
+
+#include <mxc_epdc_fb.h>
+#include <cpu_func.h>
+#include <asm/cache.h>
+#include <asm/global_data.h>
+#include <linux/delay.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void *lcd_base;                        /* Start of framebuffer memory  */
+void *lcd_console_address;     /* Start of console buffer      */
+
+int lcd_color_fg;
+int lcd_color_bg;
+
+short console_col;
+short console_row;
+
+int rev;
+
+void lcd_initcolregs(void)
+{
+}
+
+void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue)
+{
+}
+
+#define TEMP_USE_DEFAULT 8
+
+#define UPDATE_MODE_PARTIAL                    0x0
+#define UPDATE_MODE_FULL                       0x1
+
+#define TRUE 1
+#define FALSE 0
+
+#define msleep(a)      udelay(a * 1000)
+
+
+/********************************************************
+ * Start Low-Level EPDC Functions
+ ********************************************************/
+
+static inline void epdc_set_screen_res(u32 width, u32 height)
+{
+       u32 val = (height << EPDC_RES_VERTICAL_OFFSET) | width;
+
+       REG_WR(EPDC_BASE, EPDC_RES, val);
+}
+
+static inline void epdc_set_update_coord(u32 x, u32 y)
+{
+       u32 val = (y << EPDC_UPD_CORD_YCORD_OFFSET) | x;
+
+       REG_WR(EPDC_BASE, EPDC_UPD_CORD, val);
+}
+
+static inline void epdc_set_update_dimensions(u32 width, u32 height)
+{
+       u32 val = (height << EPDC_UPD_SIZE_HEIGHT_OFFSET) | width;
+
+       REG_WR(EPDC_BASE, EPDC_UPD_SIZE, val);
+}
+
+static void epdc_submit_update(u32 lut_num, u32 waveform_mode, u32 update_mode,
+                              int use_test_mode, u32 np_val)
+{
+       u32 reg_val = 0;
+
+       if (use_test_mode) {
+               reg_val |=
+                       ((np_val << EPDC_UPD_FIXED_FIXNP_OFFSET) &
+                       EPDC_UPD_FIXED_FIXNP_MASK) | EPDC_UPD_FIXED_FIXNP_EN;
+
+               REG_WR(EPDC_BASE, EPDC_UPD_FIXED, reg_val);
+
+               reg_val = EPDC_UPD_CTRL_USE_FIXED;
+       } else {
+               REG_WR(EPDC_BASE, EPDC_UPD_FIXED, reg_val);
+       }
+
+       reg_val |=
+               ((lut_num << EPDC_UPD_CTRL_LUT_SEL_OFFSET) &
+               EPDC_UPD_CTRL_LUT_SEL_MASK) |
+               ((waveform_mode << EPDC_UPD_CTRL_WAVEFORM_MODE_OFFSET) &
+               EPDC_UPD_CTRL_WAVEFORM_MODE_MASK) |
+               update_mode;
+
+       REG_WR(EPDC_BASE, EPDC_UPD_CTRL, reg_val);
+}
+
+static inline int epdc_is_lut_active(u32 lut_num)
+{
+       u32 val = REG_RD(EPDC_BASE, EPDC_STATUS_LUTS);
+       int is_active = val & (1 << lut_num) ? TRUE : FALSE;
+
+       return is_active;
+}
+
+static void epdc_set_horizontal_timing(u32 horiz_start, u32 horiz_end,
+                                      u32 hsync_width, u32 hsync_line_length)
+{
+       u32 reg_val =
+               ((hsync_width << EPDC_TCE_HSCAN1_LINE_SYNC_WIDTH_OFFSET) &
+               EPDC_TCE_HSCAN1_LINE_SYNC_WIDTH_MASK)
+               | ((hsync_line_length << EPDC_TCE_HSCAN1_LINE_SYNC_OFFSET) &
+               EPDC_TCE_HSCAN1_LINE_SYNC_MASK);
+       REG_WR(EPDC_BASE, EPDC_TCE_HSCAN1, reg_val);
+
+       reg_val =
+               ((horiz_start << EPDC_TCE_HSCAN2_LINE_BEGIN_OFFSET) &
+               EPDC_TCE_HSCAN2_LINE_BEGIN_MASK)
+               | ((horiz_end << EPDC_TCE_HSCAN2_LINE_END_OFFSET) &
+               EPDC_TCE_HSCAN2_LINE_END_MASK);
+       REG_WR(EPDC_BASE, EPDC_TCE_HSCAN2, reg_val);
+}
+
+static void epdc_set_vertical_timing(u32 vert_start, u32 vert_end,
+                                       u32 vsync_width)
+{
+       u32 reg_val =
+               ((vert_start << EPDC_TCE_VSCAN_FRAME_BEGIN_OFFSET) &
+               EPDC_TCE_VSCAN_FRAME_BEGIN_MASK)
+               | ((vert_end << EPDC_TCE_VSCAN_FRAME_END_OFFSET) &
+               EPDC_TCE_VSCAN_FRAME_END_MASK)
+               | ((vsync_width << EPDC_TCE_VSCAN_FRAME_SYNC_OFFSET) &
+               EPDC_TCE_VSCAN_FRAME_SYNC_MASK);
+       REG_WR(EPDC_BASE, EPDC_TCE_VSCAN, reg_val);
+}
+
+static void epdc_init_settings(void)
+{
+       u32 reg_val;
+       int num_ce;
+
+       /* EPDC_CTRL */
+       reg_val = REG_RD(EPDC_BASE, EPDC_CTRL);
+       reg_val &= ~EPDC_CTRL_UPD_DATA_SWIZZLE_MASK;
+       reg_val |= EPDC_CTRL_UPD_DATA_SWIZZLE_NO_SWAP;
+       reg_val &= ~EPDC_CTRL_LUT_DATA_SWIZZLE_MASK;
+       reg_val |= EPDC_CTRL_LUT_DATA_SWIZZLE_NO_SWAP;
+       REG_SET(EPDC_BASE, EPDC_CTRL, reg_val);
+
+       /* EPDC_FORMAT - 2bit TFT and 4bit Buf pixel format */
+       reg_val = EPDC_FORMAT_TFT_PIXEL_FORMAT_2BIT
+               | EPDC_FORMAT_BUF_PIXEL_FORMAT_P4N
+               | ((0x0 << EPDC_FORMAT_DEFAULT_TFT_PIXEL_OFFSET) &
+               EPDC_FORMAT_DEFAULT_TFT_PIXEL_MASK);
+       REG_WR(EPDC_BASE, EPDC_FORMAT, reg_val);
+
+       /* EPDC_FIFOCTRL (disabled) */
+       reg_val =
+               ((100 << EPDC_FIFOCTRL_FIFO_INIT_LEVEL_OFFSET) &
+               EPDC_FIFOCTRL_FIFO_INIT_LEVEL_MASK)
+               | ((200 << EPDC_FIFOCTRL_FIFO_H_LEVEL_OFFSET) &
+               EPDC_FIFOCTRL_FIFO_H_LEVEL_MASK)
+               | ((100 << EPDC_FIFOCTRL_FIFO_L_LEVEL_OFFSET) &
+               EPDC_FIFOCTRL_FIFO_L_LEVEL_MASK);
+       REG_WR(EPDC_BASE, EPDC_FIFOCTRL, reg_val);
+
+       /* EPDC_TEMP - Use default temperature */
+       REG_WR(EPDC_BASE, EPDC_TEMP, TEMP_USE_DEFAULT);
+
+       /* EPDC_RES */
+       epdc_set_screen_res(panel_info.vl_col, panel_info.vl_row);
+
+       /*
+        * EPDC_TCE_CTRL
+        * VSCAN_HOLDOFF = 4
+        * VCOM_MODE = MANUAL
+        * VCOM_VAL = 0
+        * DDR_MODE = DISABLED
+        * LVDS_MODE_CE = DISABLED
+        * LVDS_MODE = DISABLED
+        * DUAL_SCAN = DISABLED
+        * SDDO_WIDTH = 8bit
+        * PIXELS_PER_SDCLK = 4
+        */
+       reg_val =
+               ((panel_info.epdc_data.epdc_timings.vscan_holdoff <<
+                       EPDC_TCE_CTRL_VSCAN_HOLDOFF_OFFSET) &
+                       EPDC_TCE_CTRL_VSCAN_HOLDOFF_MASK)
+               | EPDC_TCE_CTRL_PIXELS_PER_SDCLK_4;
+       REG_WR(EPDC_BASE, EPDC_TCE_CTRL, reg_val);
+
+       /* EPDC_TCE_HSCAN */
+       epdc_set_horizontal_timing(panel_info.vl_left_margin,
+                               panel_info.vl_right_margin,
+                               panel_info.vl_hsync,
+                               panel_info.vl_hsync);
+
+       /* EPDC_TCE_VSCAN */
+       epdc_set_vertical_timing(panel_info.vl_upper_margin,
+                                panel_info.vl_lower_margin,
+                                panel_info.vl_vsync);
+
+       /* EPDC_TCE_OE */
+       reg_val =
+               ((panel_info.epdc_data.epdc_timings.sdoed_width <<
+                       EPDC_TCE_OE_SDOED_WIDTH_OFFSET) &
+                       EPDC_TCE_OE_SDOED_WIDTH_MASK)
+               | ((panel_info.epdc_data.epdc_timings.sdoed_delay <<
+                       EPDC_TCE_OE_SDOED_DLY_OFFSET) &
+                       EPDC_TCE_OE_SDOED_DLY_MASK)
+               | ((panel_info.epdc_data.epdc_timings.sdoez_width <<
+                       EPDC_TCE_OE_SDOEZ_WIDTH_OFFSET) &
+                       EPDC_TCE_OE_SDOEZ_WIDTH_MASK)
+               | ((panel_info.epdc_data.epdc_timings.sdoez_delay <<
+                       EPDC_TCE_OE_SDOEZ_DLY_OFFSET) &
+                       EPDC_TCE_OE_SDOEZ_DLY_MASK);
+       REG_WR(EPDC_BASE, EPDC_TCE_OE, reg_val);
+
+       /* EPDC_TCE_TIMING1 */
+       REG_WR(EPDC_BASE, EPDC_TCE_TIMING1, 0x0);
+
+       /* EPDC_TCE_TIMING2 */
+       reg_val =
+               ((panel_info.epdc_data.epdc_timings.gdclk_hp_offs <<
+                       EPDC_TCE_TIMING2_GDCLK_HP_OFFSET) &
+                       EPDC_TCE_TIMING2_GDCLK_HP_MASK)
+               | ((panel_info.epdc_data.epdc_timings.gdsp_offs <<
+                       EPDC_TCE_TIMING2_GDSP_OFFSET_OFFSET) &
+                       EPDC_TCE_TIMING2_GDSP_OFFSET_MASK);
+       REG_WR(EPDC_BASE, EPDC_TCE_TIMING2, reg_val);
+
+       /* EPDC_TCE_TIMING3 */
+       reg_val =
+               ((panel_info.epdc_data.epdc_timings.gdoe_offs <<
+                       EPDC_TCE_TIMING3_GDOE_OFFSET_OFFSET) &
+                       EPDC_TCE_TIMING3_GDOE_OFFSET_MASK)
+               | ((panel_info.epdc_data.epdc_timings.gdclk_offs <<
+                       EPDC_TCE_TIMING3_GDCLK_OFFSET_OFFSET) &
+                       EPDC_TCE_TIMING3_GDCLK_OFFSET_MASK);
+       REG_WR(EPDC_BASE, EPDC_TCE_TIMING3, reg_val);
+
+       /*
+        * EPDC_TCE_SDCFG
+        * SDCLK_HOLD = 1
+        * SDSHR = 1
+        * NUM_CE = 1
+        * SDDO_REFORMAT = FLIP_PIXELS
+        * SDDO_INVERT = DISABLED
+        * PIXELS_PER_CE = display horizontal resolution
+        */
+       num_ce = panel_info.epdc_data.epdc_timings.num_ce;
+       if (num_ce == 0)
+               num_ce = 1;
+       reg_val = EPDC_TCE_SDCFG_SDCLK_HOLD | EPDC_TCE_SDCFG_SDSHR
+               | ((num_ce << EPDC_TCE_SDCFG_NUM_CE_OFFSET) & EPDC_TCE_SDCFG_NUM_CE_MASK)
+               | EPDC_TCE_SDCFG_SDDO_REFORMAT_FLIP_PIXELS
+               | ((panel_info.vl_col << EPDC_TCE_SDCFG_PIXELS_PER_CE_OFFSET) &
+               EPDC_TCE_SDCFG_PIXELS_PER_CE_MASK);
+       REG_WR(EPDC_BASE, EPDC_TCE_SDCFG, reg_val);
+
+       /*
+        * EPDC_TCE_GDCFG
+        * GDRL = 1
+        * GDOE_MODE = 0;
+        * GDSP_MODE = 0;
+        */
+       reg_val = EPDC_TCE_SDCFG_GDRL;
+       REG_WR(EPDC_BASE, EPDC_TCE_GDCFG, reg_val);
+
+       /*
+        * EPDC_TCE_POLARITY
+        * SDCE_POL = ACTIVE LOW
+        * SDLE_POL = ACTIVE HIGH
+        * SDOE_POL = ACTIVE HIGH
+        * GDOE_POL = ACTIVE HIGH
+        * GDSP_POL = ACTIVE LOW
+        */
+       reg_val = EPDC_TCE_POLARITY_SDLE_POL_ACTIVE_HIGH
+               | EPDC_TCE_POLARITY_SDOE_POL_ACTIVE_HIGH
+               | EPDC_TCE_POLARITY_GDOE_POL_ACTIVE_HIGH;
+       REG_WR(EPDC_BASE, EPDC_TCE_POLARITY, reg_val);
+
+       /* EPDC_IRQ_MASK */
+       REG_WR(EPDC_BASE, EPDC_IRQ_MASK,
+               EPDC_IRQ_TCE_UNDERRUN_IRQ);
+
+       /*
+        * EPDC_GPIO
+        * PWRCOM = ?
+        * PWRCTRL = ?
+        * BDR = ?
+        */
+       reg_val = ((0 << EPDC_GPIO_PWRCTRL_OFFSET) & EPDC_GPIO_PWRCTRL_MASK)
+               | ((0 << EPDC_GPIO_BDR_OFFSET) & EPDC_GPIO_BDR_MASK);
+       REG_WR(EPDC_BASE, EPDC_GPIO, reg_val);
+}
+
+static void draw_mode0(void)
+{
+       int i;
+
+       /* Program EPDC update to process buffer */
+       epdc_set_update_coord(0, 0);
+       epdc_set_update_dimensions(panel_info.vl_col, panel_info.vl_row);
+       epdc_submit_update(0, panel_info.epdc_data.wv_modes.mode_init,
+                               UPDATE_MODE_FULL, FALSE, 0);
+
+       debug("Mode0 update - Waiting for LUT to complete...\n");
+
+       /* Will timeout after ~4-5 seconds */
+
+       for (i = 0; i < 40; i++) {
+               if (!epdc_is_lut_active(0)) {
+                       debug("Mode0 init complete\n");
+                       return;
+               }
+               msleep(100);
+       }
+
+       debug("Mode0 init failed!\n");
+
+}
+
+static void draw_splash_screen(void)
+{
+       int i;
+       int lut_num = 0;
+
+       /* Program EPDC update to process buffer */
+       epdc_set_update_coord(0, 0);
+       epdc_set_update_dimensions(panel_info.vl_col, panel_info.vl_row);
+       epdc_submit_update(lut_num, panel_info.epdc_data.wv_modes.mode_gc16,
+               UPDATE_MODE_FULL, FALSE, 0);
+
+       for (i = 0; i < 40; i++) {
+               if (!epdc_is_lut_active(lut_num)) {
+                       debug("Splash screen update complete\n");
+                       return;
+               }
+               msleep(100);
+       }
+       debug("Splash screen update failed!\n");
+}
+
+void lcd_enable(void)
+{
+       if (board_setup_logo_file(lcd_base)) {
+               debug("Load logo failed!\n");
+               return;
+       }
+
+       epdc_power_on();
+
+       flush_cache((ulong)lcd_base, panel_info.vl_col * panel_info.vl_row);
+
+       /* Draw data to display */
+       draw_mode0();
+
+       draw_splash_screen();
+}
+
+void lcd_disable(void)
+{
+       debug("lcd_disable\n");
+
+       /* Disable clocks to EPDC */
+       REG_SET(EPDC_BASE, EPDC_CTRL, EPDC_CTRL_CLKGATE);
+}
+
+void lcd_panel_disable(void)
+{
+       epdc_power_off();
+}
+
+void lcd_ctrl_init(void *lcdbase)
+{
+       unsigned int val;
+
+       /*
+        * We rely on lcdbase being a physical address, i.e., either MMU off,
+        * or 1-to-1 mapping. Might want to add some virt2phys here.
+        */
+       if (!lcdbase)
+               return;
+
+       panel_info.epdc_data.working_buf_addr = (u_long)memalign(ARCH_DMA_MINALIGN,
+               panel_info.vl_col * panel_info.vl_row * 2);
+
+       if (!panel_info.epdc_data.working_buf_addr) {
+               printf("EPDC: Error allocating working buffer!\n");
+               return;
+       }
+
+       panel_info.epdc_data.waveform_buf_addr = (u_long)memalign(ARCH_DMA_MINALIGN,
+               CONFIG_WAVEFORM_BUF_SIZE);
+
+       if (!panel_info.epdc_data.waveform_buf_addr) {
+               printf("EPDC: Error allocating waveform buffer!\n");
+               return;
+       }
+
+       lcd_color_fg = 0xFF;
+       lcd_color_bg = 0xFF;
+
+       /* Reset */
+       REG_SET(EPDC_BASE, EPDC_CTRL, EPDC_CTRL_SFTRST);
+       while (!(REG_RD(EPDC_BASE, EPDC_CTRL) & EPDC_CTRL_CLKGATE))
+               ;
+       REG_CLR(EPDC_BASE, EPDC_CTRL, EPDC_CTRL_SFTRST);
+
+       /* Enable clock gating (clear to enable) */
+       REG_CLR(EPDC_BASE, EPDC_CTRL, EPDC_CTRL_CLKGATE);
+       while (REG_RD(EPDC_BASE, EPDC_CTRL) &
+              (EPDC_CTRL_SFTRST | EPDC_CTRL_CLKGATE))
+               ;
+
+       debug("resolution %dx%d, bpp %d\n", (int)panel_info.vl_col,
+               (int)panel_info.vl_row, NBITS(panel_info.vl_bpix));
+
+       /* Get EPDC version */
+       val = REG_RD(EPDC_BASE, EPDC_VERSION);
+       rev = ((val & EPDC_VERSION_MAJOR_MASK) >>
+                               EPDC_VERSION_MAJOR_OFFSET) * 10
+                       + ((val & EPDC_VERSION_MINOR_MASK) >>
+                               EPDC_VERSION_MINOR_OFFSET);
+
+       /* Set framebuffer pointer */
+       REG_WR(EPDC_BASE, EPDC_UPD_ADDR, (u32)lcdbase);
+
+       /* Set Working Buffer pointer */
+       REG_WR(EPDC_BASE, EPDC_WB_ADDR, panel_info.epdc_data.working_buf_addr);
+       if (rev > 20)
+               REG_WR(EPDC_BASE, EPDC_WB_ADDR_TCE, panel_info.epdc_data.working_buf_addr);
+
+       /* Get waveform data address and offset */
+       if (board_setup_waveform_file(panel_info.epdc_data.waveform_buf_addr)) {
+               printf("Can't load waveform data!\n");
+               return;
+       }
+
+       /* Set Waveform Buffer pointer */
+       REG_WR(EPDC_BASE, EPDC_WVADDR,
+               panel_info.epdc_data.waveform_buf_addr);
+
+       /* Initialize EPDC, passing pointer to EPDC registers */
+       epdc_init_settings();
+
+       lcd_base = lcdbase;
+
+       return;
+}
+
+ulong calc_fbsize(void)
+{
+       return panel_info.vl_row * panel_info.vl_col * 2 \
+               * NBITS(panel_info.vl_bpix) / 8;
+}
+
+
+
index 0794b50..acaa553 100644 (file)
@@ -19,6 +19,8 @@ struct cmd_tbl;
 
 struct blk_desc;
 
+int do_fat_size(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
+
 /**
  * do_fat_fsload - Run the fatload command
  *
index 9a4c0da..b9c94cd 100644 (file)
@@ -30,6 +30,7 @@ extern struct vidinfo panel_info;
 void lcd_ctrl_init(void *lcdbase);
 void lcd_enable(void);
 void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue);
+void lcd_initcolregs (void);
 ulong lcd_setmem(ulong addr);
 
 /**
@@ -47,6 +48,64 @@ void lcd_set_flush_dcache(int flush);
 #include <atmel_lcd.h>
 #elif defined(CONFIG_EXYNOS_FB)
 #include <exynos_lcd.h>
+#elif defined(CONFIG_MXC_EPDC)
+
+struct waveform_modes {
+       int mode_init;
+       int mode_du;
+       int mode_gc4;
+       int mode_gc8;
+       int mode_gc16;
+       int mode_gc32;
+};
+
+struct epdc_timing_params {
+    int vscan_holdoff;
+    int sdoed_width;
+    int sdoed_delay;
+    int sdoez_width;
+    int sdoez_delay;
+    int gdclk_hp_offs;
+    int gdsp_offs;
+    int gdoe_offs;
+    int gdclk_offs;
+    int num_ce;
+};
+
+struct epdc_data_struct {
+       /* EPDC buffer pointers */
+       u_long working_buf_addr;
+       u_long waveform_buf_addr;
+
+       /* Waveform mode definitions */
+       struct waveform_modes wv_modes;
+       struct epdc_timing_params epdc_timings;
+};
+
+typedef struct vidinfo {
+       u_long vl_refresh;      /* Refresh Rate Hz */
+       u_long vl_row;          /* resolution in x */
+       u_long vl_col;          /* resolution in y */
+       u_long vl_rot;
+       u_long vl_pixclock;     /* pixel clock in picoseconds */
+       u_long vl_left_margin;  /* Horizontal back porch */
+       u_long vl_right_margin; /* Horizontal front porch */
+       u_long vl_upper_margin; /* Vertical back porch */
+       u_long vl_lower_margin; /* Vertical front porch */
+       u_long vl_hsync;        /* Horizontal sync pulse length */
+       u_long vl_vsync;        /* Vertical sync pulse length */
+       u_long vl_sync;         /* Polarity on data enable */
+       u_long vl_mode;         /* Video Mode */
+       u_long vl_flag;
+       u_char  vl_bpix;
+       ushort  *cmap;
+       struct epdc_data_struct epdc_data;
+} vidinfo_t;
+
+static __maybe_unused ushort *configuration_get_cmap(void)
+{
+       return panel_info.cmap;
+}
 #else
 typedef struct vidinfo {
        ushort  vl_col;         /* Number of columns (i.e. 160) */
@@ -163,6 +222,16 @@ void lcd_sync(void);
 #define LCD_BPP                        LCD_COLOR8
 #endif
 
+#if LCD_BPP == LCD_MONOCHROME
+# define COLOR_MASK(c)         ((c)      | (c) << 1 | (c) << 2 | (c) << 3 | \
+                                (c) << 4 | (c) << 5 | (c) << 6 | (c) << 7)
+#elif (LCD_BPP == LCD_COLOR8) || (LCD_BPP == LCD_COLOR16) || \
+       (LCD_BPP == LCD_COLOR32)
+# define COLOR_MASK(c)         (c)
+#else
+#error Unsupported LCD BPP.
+#endif
+
 #ifndef LCD_DF
 #define LCD_DF                 1
 #endif
@@ -171,7 +240,14 @@ void lcd_sync(void);
 #define NBITS(bit_code)                (1 << (bit_code))
 #define NCOLORS(bit_code)      (1 << NBITS(bit_code))
 
-#if LCD_BPP == LCD_COLOR8
+#if LCD_BPP == LCD_MONOCHROME
+/*
+ * Simple black/white definitions
+ */
+# define CONSOLE_COLOR_BLACK   0
+# define CONSOLE_COLOR_WHITE   1       /* Must remain last / highest   */
+
+#elif LCD_BPP == LCD_COLOR8
 # define CONSOLE_COLOR_BLACK   0
 # define CONSOLE_COLOR_RED     1
 # define CONSOLE_COLOR_GREEN   2
diff --git a/include/mxc_epdc_fb.h b/include/mxc_epdc_fb.h
new file mode 100644 (file)
index 0000000..9aef8a1
--- /dev/null
@@ -0,0 +1,552 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2010-2016 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ */
+#ifndef __EPDC_REGS_INCLUDED__
+#define __EPDC_REGS_INCLUDED__
+
+#include <linux/types.h>
+#include <linux/list.h>
+#include <asm/arch/imx-regs.h>
+
+/*************************************
+ * Register addresses
+ *************************************/
+#define EPDC_BASE                      (EPDC_BASE_ADDR)
+
+#define EPDC_CTRL                      0x000
+#define EPDC_CTRL_SET                  0x004
+#define EPDC_CTRL_CLR                  0x008
+#define EPDC_CTRL_TOG          0x00C
+#define EPDC_WVADDR                    0x020
+#define EPDC_WB_ADDR                   0x030
+#define EPDC_RES                       0x040
+#define EPDC_FORMAT                    0x050
+#define EPDC_FORMAT_SET                        0x054
+#define EPDC_FORMAT_CLR                0x058
+#define EPDC_FORMAT_TOG                0x05C
+#define EPDC_WB_FIELD0                 0x060
+#define EPDC_WB_FIELD0_SET             0x064
+#define EPDC_WB_FIELD0_CLR             0x068
+#define EPDC_WB_FIELD0_TOG             0x06C
+#define EPDC_WB_FIELD1                 0x070
+#define EPDC_WB_FIELD1_SET             0x074
+#define EPDC_WB_FIELD1_CLR             0x078
+#define EPDC_WB_FIELD1_TOG             0x07C
+#define EPDC_WB_FIELD2                 0x080
+#define EPDC_WB_FIELD2_SET             0x084
+#define EPDC_WB_FIELD2_CLR             0x088
+#define EPDC_WB_FIELD2_TOG             0x08C
+#define EPDC_WB_FIELD3                 0x090
+#define EPDC_WB_FIELD3_SET             0x094
+#define EPDC_WB_FIELD3_CLR             0x098
+#define EPDC_WB_FIELD3_TOG             0x09C
+#define EPDC_FIFOCTRL                  0x0A0
+#define EPDC_FIFOCTRL_SET              0x0A4
+#define EPDC_FIFOCTRL_CLR              0x0A8
+#define EPDC_FIFOCTRL_TOG              0x0AC
+#define EPDC_UPD_ADDR                  0x100
+#define EPDC_UPD_STRIDE                        0x110
+#define EPDC_UPD_CORD                  0x120
+#define EPDC_UPD_SIZE                  0x140
+#define EPDC_UPD_CTRL                  0x160
+#define EPDC_UPD_FIXED                 0x180
+#define EPDC_TEMP                      0x1A0
+#define EPDC_AUTOWV_LUT                        0x1C0
+#define EPDC_LUT_STANDBY1              0x1E0
+#define EPDC_LUT_STANDBY1_SET          0x1E4
+#define EPDC_LUT_STANDBY1_CLR          0x1E8
+#define EPDC_LUT_STANDBY1_TOG  0x1EC
+#define EPDC_LUT_STANDBY2              0x1F0
+#define EPDC_LUT_STANDBY2_SET          0x1F4
+#define EPDC_LUT_STANDBY2_CLR          0x1F8
+#define EPDC_LUT_STANDBY2_TOG  0x1FC
+#define EPDC_TCE_CTRL                  0x200
+#define EPDC_TCE_SDCFG                 0x220
+#define EPDC_TCE_GDCFG                 0x240
+#define EPDC_TCE_HSCAN1                        0x260
+#define EPDC_TCE_HSCAN2                        0x280
+#define EPDC_TCE_VSCAN                 0x2A0
+#define EPDC_TCE_OE                    0x2C0
+#define EPDC_TCE_POLARITY              0x2E0
+#define EPDC_TCE_TIMING1               0x300
+#define EPDC_TCE_TIMING2               0x310
+#define EPDC_TCE_TIMING3               0x320
+#define EPDC_PIGEON_CTRL0              0x380
+#define EPDC_PIGEON_CTRL1              0x390
+#define EPDC_IRQ_MASK1                 0x3C0
+#define EPDC_IRQ_MASK1_SET             0x3C4
+#define EPDC_IRQ_MASK1_CLR             0x3C8
+#define EPDC_IRQ_MASK1_TOG             0x3CC
+#define EPDC_IRQ_MASK2                 0x3D0
+#define EPDC_IRQ_MASK2_SET             0x3D4
+#define EPDC_IRQ_MASK2_CLR             0x3D8
+#define EPDC_IRQ_MASK2_TOG             0x3DC
+#define EPDC_IRQ1                      0x3E0
+#define EPDC_IRQ1_SET                  0x3E4
+#define EPDC_IRQ1_CLR                  0x3E8
+#define EPDC_IRQ1_TOG          0x3EC
+#define EPDC_IRQ2                      0x3F0
+#define EPDC_IRQ2_SET                  0x3F4
+#define EPDC_IRQ2_CLR                  0x3F8
+#define EPDC_IRQ2_TOG          0x3FC
+#define EPDC_IRQ_MASK                  0x400
+#define EPDC_IRQ_MASK_SET              0x404
+#define EPDC_IRQ_MASK_CLR              0x408
+#define EPDC_IRQ_MASK_TOG              0x40C
+#define EPDC_IRQ                       0x420
+#define EPDC_IRQ_SET                   0x424
+#define EPDC_IRQ_CLR                   0x428
+#define EPDC_IRQ_TOG                   0x42C
+#define EPDC_STATUS_LUTS               0x440
+#define EPDC_STATUS_LUTS_SET           0x444
+#define EPDC_STATUS_LUTS_CLR           0x448
+#define EPDC_STATUS_LUTS_TOG           0x44C
+#define EPDC_STATUS_LUTS2              0x450
+#define EPDC_STATUS_LUTS2_SET          0x454
+#define EPDC_STATUS_LUTS2_CLR          0x458
+#define EPDC_STATUS_LUTS2_TOG  0x45C
+#define EPDC_STATUS_NEXTLUT            0x460
+#define EPDC_STATUS_COL                        0x480
+#define EPDC_STATUS_COL2               0x490
+#define EPDC_STATUS                    0x4A0
+#define EPDC_STATUS_SET                        0x4A4
+#define EPDC_STATUS_CLR                0x4A8
+#define EPDC_STATUS_TOG                0x4AC
+#define EPDC_UPD_COL_CORD              0x4C0
+#define EPDC_UPD_COL_SIZE              0x4E0
+#define EPDC_DEBUG                     0x500
+#define EPDC_DEBUG_LUT                 0x530
+#define EPDC_HIST1_PARAM               0x600
+#define EPDC_HIST2_PARAM               0x610
+#define EPDC_HIST4_PARAM               0x620
+#define EPDC_HIST8_PARAM0              0x630
+#define EPDC_HIST8_PARAM1              0x640
+#define EPDC_HIST16_PARAM0             0x650
+#define EPDC_HIST16_PARAM1             0x660
+#define EPDC_HIST16_PARAM2             0x670
+#define EPDC_HIST16_PARAM3             0x680
+#define EPDC_GPIO                      0x700
+#define EPDC_VERSION                   0x7F0
+#define EPDC_PIGEON_0_0                        0x800
+#define EPDC_PIGEON_0_1                        0x810
+#define EPDC_PIGEON_0_2                        0x820
+#define EPDC_PIGEON_1_0                        0x840
+#define EPDC_PIGEON_1_1                        0x850
+#define EPDC_PIGEON_1_2                        0x860
+#define EPDC_PIGEON_2_0                        0x880
+#define EPDC_PIGEON_2_1                        0x890
+#define EPDC_PIGEON_2_2                        0x8A0
+#define EPDC_PIGEON_3_0                        0x8C0
+#define EPDC_PIGEON_3_1                        0x8D0
+#define EPDC_PIGEON_3_2                        0x8E0
+#define EPDC_PIGEON_4_0                        0x900
+#define EPDC_PIGEON_4_1                        0x910
+#define EPDC_PIGEON_4_2                        0x920
+#define EPDC_PIGEON_5_0                        0x940
+#define EPDC_PIGEON_5_1                        0x950
+#define EPDC_PIGEON_5_2                        0x960
+#define EPDC_PIGEON_6_0                        0x980
+#define EPDC_PIGEON_6_1                        0x990
+#define EPDC_PIGEON_6_2                        0x9A0
+#define EPDC_PIGEON_7_0                        0x9C0
+#define EPDC_PIGEON_7_1                        0x9D0
+#define EPDC_PIGEON_7_2                        0x9E0
+#define EPDC_PIGEON_8_0                        0xA00
+#define EPDC_PIGEON_8_1                        0xA10
+#define EPDC_PIGEON_8_2                        0xA20
+#define EPDC_PIGEON_9_0                        0xA40
+#define EPDC_PIGEON_9_1                        0xA50
+#define EPDC_PIGEON_9_2                        0xA60
+#define EPDC_PIGEON_10_0               0xA80
+#define EPDC_PIGEON_10_1               0xA90
+#define EPDC_PIGEON_10_2               0xAA0
+#define EPDC_PIGEON_11_0               0xAC0
+#define EPDC_PIGEON_11_1               0xAD0
+#define EPDC_PIGEON_11_2               0xAE0
+#define EPDC_PIGEON_12_0               0xB00
+#define EPDC_PIGEON_12_1               0xB10
+#define EPDC_PIGEON_12_2               0xB20
+#define EPDC_PIGEON_13_0               0xB40
+#define EPDC_PIGEON_13_1               0xB50
+#define EPDC_PIGEON_13_2               0xB60
+#define EPDC_PIGEON_14_0               0xB80
+#define EPDC_PIGEON_14_1               0xB90
+#define EPDC_PIGEON_14_2               0xBA0
+#define EPDC_PIGEON_15_0               0xBC0
+#define EPDC_PIGEON_15_1               0xBD0
+#define EPDC_PIGEON_15_2               0xBE0
+#define EPDC_PIGEON_16_0               0xC00
+#define EPDC_PIGEON_16_1               0xC10
+#define EPDC_PIGEON_16_2               0xC20
+#if defined(CONFIG_MX7) || defined(CONFIG_MX6ULL) || defined(CONFIG_MX6SLL)
+#define EPDC_WB_ADDR_TCE               0x010
+#else
+#define EPDC_WB_ADDR_TCE               0xC10
+#endif
+
+#define REG_RD(base, reg) \
+       (*(volatile unsigned int *)((base) + (reg)))
+#define REG_WR(base, reg, value) \
+       ((*(volatile unsigned int *)((base) + (reg))) = (value))
+#define REG_SET(base, reg, value) \
+       ((*(volatile unsigned int *)((base) + (reg ## _SET))) = (value))
+#define REG_CLR(base, reg, value) \
+       ((*(volatile unsigned int *)((base) + (reg ## _CLR))) = (value))
+#define REG_TOG(base, reg, value) \
+       ((*(volatile unsigned int *)((base) + (reg ## _TOG))) = (value))
+/*
+ * Register field definitions
+ */
+
+enum {
+/* EPDC_CTRL field values */
+       EPDC_CTRL_SFTRST = 0x80000000,
+       EPDC_CTRL_CLKGATE = 0x40000000,
+       EPDC_CTRL_SRAM_POWERDOWN = 0x100,
+       EPDC_CTRL_UPD_DATA_SWIZZLE_MASK = 0xC0,
+       EPDC_CTRL_UPD_DATA_SWIZZLE_NO_SWAP = 0,
+       EPDC_CTRL_UPD_DATA_SWIZZLE_ALL_BYTES_SWAP = 0x40,
+       EPDC_CTRL_UPD_DATA_SWIZZLE_HWD_SWAP = 0x80,
+       EPDC_CTRL_UPD_DATA_SWIZZLE_HWD_BYTE_SWAP = 0xC0,
+       EPDC_CTRL_LUT_DATA_SWIZZLE_MASK = 0x30,
+       EPDC_CTRL_LUT_DATA_SWIZZLE_NO_SWAP = 0,
+       EPDC_CTRL_LUT_DATA_SWIZZLE_ALL_BYTES_SWAP = 0x10,
+       EPDC_CTRL_LUT_DATA_SWIZZLE_HWD_SWAP = 0x20,
+       EPDC_CTRL_LUT_DATA_SWIZZLE_HWD_BYTE_SWAP = 0x30,
+       EPDC_CTRL_BURST_LEN_8_8 = 0x1,
+       EPDC_CTRL_BURST_LEN_8_16 = 0,
+
+/* EPDC_RES field values */
+       EPDC_RES_VERTICAL_MASK = 0x1FFF0000,
+       EPDC_RES_VERTICAL_OFFSET = 16,
+       EPDC_RES_HORIZONTAL_MASK = 0x1FFF,
+       EPDC_RES_HORIZONTAL_OFFSET = 0,
+
+/* EPDC_FORMAT field values */
+       EPDC_FORMAT_BUF_PIXEL_SCALE_ROUND = 0x1000000,
+       EPDC_FORMAT_DEFAULT_TFT_PIXEL_MASK = 0xFF0000,
+       EPDC_FORMAT_DEFAULT_TFT_PIXEL_OFFSET = 16,
+       EPDC_FORMAT_WB_ADDR_NO_COPY = 0x4000,
+       EPDC_FORMAT_WB_TYPE_MASK = 0x3000,
+       EPDC_FORMAT_WB_TYPE_OFFSET = 12,
+       EPDC_FORMAT_WB_TYPE_WB_INTERNAL = 0x0,
+       EPDC_FORMAT_WB_TYPE_WB_WAVEFORM = 0x1000,
+       EPDC_FORMAT_WB_TYPE_WB_EXTERNAL16 = 0x2000,
+       EPDC_FORMAT_WB_TYPE_WB_EXTERNAL32 = 0x3000,
+       EPDC_FORMAT_WB_COMPRESS = 0x800,
+       EPDC_FORMAT_BUF_PIXEL_FORMAT_MASK = 0x700,
+       EPDC_FORMAT_BUF_PIXEL_FORMAT_P2N = 0x200,
+       EPDC_FORMAT_BUF_PIXEL_FORMAT_P3N = 0x300,
+       EPDC_FORMAT_BUF_PIXEL_FORMAT_P4N = 0x400,
+       EPDC_FORMAT_BUF_PIXEL_FORMAT_P5N = 0x500,
+       EPDC_FORMAT_TFT_PIXEL_FORMAT_2BIT = 0x0,
+       EPDC_FORMAT_TFT_PIXEL_FORMAT_2BIT_VCOM = 0x1,
+       EPDC_FORMAT_TFT_PIXEL_FORMAT_4BIT = 0x2,
+       EPDC_FORMAT_TFT_PIXEL_FORMAT_4BIT_VCOM = 0x3,
+
+/* EPDC_WB_FIELD field values */
+       EPDC_WB_FIELD_FIXED_MASK = 0xFF000000,
+       EPDC_WB_FIELD_FIXED_OFFSET = 24,
+       EPDC_WB_FIELD_USE_FIXED_MASK = 0x30000,
+       EPDC_WB_FIELD_USE_FIXED_OFFSET = 16,
+       EPDC_WB_FIELD_USE_FIXED_NO_FIXED = 0x0,
+       EPDC_WB_FIELD_USE_FIXED_USE_FIXED = 0x1,
+       EPDC_WB_FIELD_USE_FIXED_NE_FIXED = 0x2,
+       EPDC_WB_FIELD_USE_FIXED_EQ_FIXED = 0x3,
+       EPDC_WB_FIELD_USAGE_MASK = 0xE000,
+       EPDC_WB_FIELD_USAGE_OFFSET = 13,
+       EPDC_WB_FIELD_USAGE_NOT_USED = 0x0,
+       EPDC_WB_FIELD_USAGE_PARTIAL = 0x3,
+       EPDC_WB_FIELD_USAGE_LUT = 0x4,
+       EPDC_WB_FIELD_USAGE_CP = 0x5,
+       EPDC_WB_FIELD_USAGE_NP = 0x6,
+       EPDC_WB_FIELD_USAGE_PTS = 0x7,
+       EPDC_WB_FIELD_FROM_MASK = 0x1F00,
+       EPDC_WB_FIELD_FROM_OFFSET = 8,
+       EPDC_WB_FIELD_TO_MASK = 0xF0,
+       EPDC_WB_FIELD_TO_OFFSET = 4,
+       EPDC_WB_FIELD_LEN_MASK = 0xF,
+       EPDC_WB_FIELD_LEN_OFFSET = 0,
+
+/* EPDC_FIFOCTRL field values */
+       EPDC_FIFOCTRL_ENABLE_PRIORITY = 0x80000000,
+       EPDC_FIFOCTRL_FIFO_INIT_LEVEL_MASK = 0xFF0000,
+       EPDC_FIFOCTRL_FIFO_INIT_LEVEL_OFFSET = 16,
+       EPDC_FIFOCTRL_FIFO_H_LEVEL_MASK = 0xFF00,
+       EPDC_FIFOCTRL_FIFO_H_LEVEL_OFFSET = 8,
+       EPDC_FIFOCTRL_FIFO_L_LEVEL_MASK = 0xFF,
+       EPDC_FIFOCTRL_FIFO_L_LEVEL_OFFSET = 0,
+
+/* EPDC_UPD_CORD field values */
+       EPDC_UPD_CORD_YCORD_MASK = 0x1FFF0000,
+       EPDC_UPD_CORD_YCORD_OFFSET = 16,
+       EPDC_UPD_CORD_XCORD_MASK = 0x1FFF,
+       EPDC_UPD_CORD_XCORD_OFFSET = 0,
+
+/* EPDC_UPD_SIZE field values */
+       EPDC_UPD_SIZE_HEIGHT_MASK = 0x1FFF0000,
+       EPDC_UPD_SIZE_HEIGHT_OFFSET = 16,
+       EPDC_UPD_SIZE_WIDTH_MASK = 0x1FFF,
+       EPDC_UPD_SIZE_WIDTH_OFFSET = 0,
+
+/* EPDC_UPD_CTRL field values */
+       EPDC_UPD_CTRL_USE_FIXED = 0x80000000,
+#if defined(CONFIG_MX7) || defined(CONFIG_MX6ULL) || defined(CONFIG_MX6SLL)
+       EPDC_UPD_CTRL_LUT_SEL_MASK = 0x3F0000,
+#else
+       EPDC_UPD_CTRL_LUT_SEL_MASK = 0xF0000,
+#endif
+       EPDC_UPD_CTRL_LUT_SEL_OFFSET = 16,
+       EPDC_UPD_CTRL_WAVEFORM_MODE_MASK = 0xFF00,
+       EPDC_UPD_CTRL_WAVEFORM_MODE_OFFSET = 8,
+       EPDC_UPD_CTRL_NO_LUT_CANCEL = 0x10,
+       EPDC_UPD_CTRL_AUTOWV_PAUSE = 0x8,
+       EPDC_UPD_CTRL_AUTOWV = 0x4,
+       EPDC_UPD_CTRL_DRY_RUN = 0x2,
+       EPDC_UPD_CTRL_UPDATE_MODE_FULL = 0x1,
+
+/* EPDC_UPD_FIXED field values */
+       EPDC_UPD_FIXED_FIXNP_EN = 0x80000000,
+       EPDC_UPD_FIXED_FIXCP_EN = 0x40000000,
+       EPDC_UPD_FIXED_FIXNP_MASK = 0xFF00,
+       EPDC_UPD_FIXED_FIXNP_OFFSET = 8,
+       EPDC_UPD_FIXED_FIXCP_MASK = 0xFF,
+       EPDC_UPD_FIXED_FIXCP_OFFSET = 0,
+
+/* EPDC_AUTOWV_LUT field values */
+       EPDC_AUTOWV_LUT_DATA_MASK = 0xFF0000,
+       EPDC_AUTOWV_LUT_DATA_OFFSET = 16,
+#if defined(CONFIG_MX7) || defined(CONFIG_MX6ULL) || defined(CONFIG_MX6SLL)
+       EPDC_AUTOWV_LUT_ADDR_MASK = 0x7,
+#else
+       EPDC_AUTOWV_LUT_ADDR_MASK = 0xFF,
+#endif
+       EPDC_AUTOWV_LUT_ADDR_OFFSET = 0,
+
+/* EPDC_TCE_CTRL field values */
+       EPDC_TCE_CTRL_VSCAN_HOLDOFF_MASK = 0x1FF0000,
+       EPDC_TCE_CTRL_VSCAN_HOLDOFF_OFFSET = 16,
+       EPDC_TCE_CTRL_VCOM_VAL_MASK = 0xC00,
+       EPDC_TCE_CTRL_VCOM_VAL_OFFSET = 10,
+       EPDC_TCE_CTRL_VCOM_MODE_AUTO = 0x200,
+       EPDC_TCE_CTRL_VCOM_MODE_MANUAL = 0x000,
+       EPDC_TCE_CTRL_DDR_MODE_ENABLE = 0x100,
+       EPDC_TCE_CTRL_LVDS_MODE_CE_ENABLE = 0x80,
+       EPDC_TCE_CTRL_LVDS_MODE_ENABLE = 0x40,
+       EPDC_TCE_CTRL_SCAN_DIR_1_UP = 0x20,
+       EPDC_TCE_CTRL_SCAN_DIR_0_UP = 0x10,
+       EPDC_TCE_CTRL_DUAL_SCAN_ENABLE = 0x8,
+       EPDC_TCE_CTRL_SDDO_WIDTH_16BIT = 0x4,
+       EPDC_TCE_CTRL_PIXELS_PER_SDCLK_2 = 1,
+       EPDC_TCE_CTRL_PIXELS_PER_SDCLK_4 = 2,
+       EPDC_TCE_CTRL_PIXELS_PER_SDCLK_8 = 3,
+
+/* EPDC_TCE_SDCFG field values */
+       EPDC_TCE_SDCFG_SDCLK_HOLD = 0x200000,
+       EPDC_TCE_SDCFG_SDSHR = 0x100000,
+       EPDC_TCE_SDCFG_NUM_CE_MASK = 0xF0000,
+       EPDC_TCE_SDCFG_NUM_CE_OFFSET = 16,
+       EPDC_TCE_SDCFG_SDDO_REFORMAT_STANDARD = 0,
+       EPDC_TCE_SDCFG_SDDO_REFORMAT_FLIP_PIXELS = 0x4000,
+       EPDC_TCE_SDCFG_SDDO_INVERT_ENABLE = 0x2000,
+       EPDC_TCE_SDCFG_PIXELS_PER_CE_MASK = 0x1FFF,
+       EPDC_TCE_SDCFG_PIXELS_PER_CE_OFFSET = 0,
+
+/* EPDC_TCE_GDCFG field values */
+       EPDC_TCE_SDCFG_GDRL = 0x10,
+       EPDC_TCE_SDCFG_GDOE_MODE_DELAYED_GDCLK = 0x2,
+       EPDC_TCE_SDCFG_GDSP_MODE_FRAME_SYNC = 0x1,
+       EPDC_TCE_SDCFG_GDSP_MODE_ONE_LINE = 0x0,
+
+/* EPDC_TCE_HSCAN1 field values */
+       EPDC_TCE_HSCAN1_LINE_SYNC_WIDTH_MASK = 0xFFF0000,
+       EPDC_TCE_HSCAN1_LINE_SYNC_WIDTH_OFFSET = 16,
+       EPDC_TCE_HSCAN1_LINE_SYNC_MASK = 0xFFF,
+       EPDC_TCE_HSCAN1_LINE_SYNC_OFFSET = 0,
+
+/* EPDC_TCE_HSCAN2 field values */
+       EPDC_TCE_HSCAN2_LINE_END_MASK = 0xFFF0000,
+       EPDC_TCE_HSCAN2_LINE_END_OFFSET = 16,
+       EPDC_TCE_HSCAN2_LINE_BEGIN_MASK = 0xFFF,
+       EPDC_TCE_HSCAN2_LINE_BEGIN_OFFSET = 0,
+
+/* EPDC_TCE_VSCAN field values */
+       EPDC_TCE_VSCAN_FRAME_END_MASK = 0xFF0000,
+       EPDC_TCE_VSCAN_FRAME_END_OFFSET = 16,
+       EPDC_TCE_VSCAN_FRAME_BEGIN_MASK = 0xFF00,
+       EPDC_TCE_VSCAN_FRAME_BEGIN_OFFSET = 8,
+       EPDC_TCE_VSCAN_FRAME_SYNC_MASK = 0xFF,
+       EPDC_TCE_VSCAN_FRAME_SYNC_OFFSET = 0,
+
+/* EPDC_TCE_OE field values */
+       EPDC_TCE_OE_SDOED_WIDTH_MASK = 0xFF000000,
+       EPDC_TCE_OE_SDOED_WIDTH_OFFSET = 24,
+       EPDC_TCE_OE_SDOED_DLY_MASK = 0xFF0000,
+       EPDC_TCE_OE_SDOED_DLY_OFFSET = 16,
+       EPDC_TCE_OE_SDOEZ_WIDTH_MASK = 0xFF00,
+       EPDC_TCE_OE_SDOEZ_WIDTH_OFFSET = 8,
+       EPDC_TCE_OE_SDOEZ_DLY_MASK = 0xFF,
+       EPDC_TCE_OE_SDOEZ_DLY_OFFSET = 0,
+
+/* EPDC_TCE_POLARITY field values */
+       EPDC_TCE_POLARITY_GDSP_POL_ACTIVE_HIGH = 0x10,
+       EPDC_TCE_POLARITY_GDOE_POL_ACTIVE_HIGH = 0x8,
+       EPDC_TCE_POLARITY_SDOE_POL_ACTIVE_HIGH = 0x4,
+       EPDC_TCE_POLARITY_SDLE_POL_ACTIVE_HIGH = 0x2,
+       EPDC_TCE_POLARITY_SDCE_POL_ACTIVE_HIGH = 0x1,
+
+/* EPDC_TCE_TIMING1 field values */
+       EPDC_TCE_TIMING1_SDLE_SHIFT_NONE = 0x00,
+       EPDC_TCE_TIMING1_SDLE_SHIFT_1 = 0x10,
+       EPDC_TCE_TIMING1_SDLE_SHIFT_2 = 0x20,
+       EPDC_TCE_TIMING1_SDLE_SHIFT_3 = 0x30,
+       EPDC_TCE_TIMING1_SDCLK_INVERT = 0x8,
+       EPDC_TCE_TIMING1_SDCLK_SHIFT_NONE = 0,
+       EPDC_TCE_TIMING1_SDCLK_SHIFT_1CYCLE = 1,
+       EPDC_TCE_TIMING1_SDCLK_SHIFT_2CYCLES = 2,
+       EPDC_TCE_TIMING1_SDCLK_SHIFT_3CYCLES = 3,
+
+/* EPDC_TCE_TIMING2 field values */
+       EPDC_TCE_TIMING2_GDCLK_HP_MASK = 0xFFFF0000,
+       EPDC_TCE_TIMING2_GDCLK_HP_OFFSET = 16,
+       EPDC_TCE_TIMING2_GDSP_OFFSET_MASK = 0xFFFF,
+       EPDC_TCE_TIMING2_GDSP_OFFSET_OFFSET = 0,
+
+/* EPDC_TCE_TIMING3 field values */
+       EPDC_TCE_TIMING3_GDOE_OFFSET_MASK = 0xFFFF0000,
+       EPDC_TCE_TIMING3_GDOE_OFFSET_OFFSET = 16,
+       EPDC_TCE_TIMING3_GDCLK_OFFSET_MASK = 0xFFFF,
+       EPDC_TCE_TIMING3_GDCLK_OFFSET_OFFSET = 0,
+
+/* EPDC EPDC_PIGEON_CTRL0 field values */
+       EPDC_PIGEON_CTRL0_LD_PERIOD_MASK = 0xFFF0000,
+       EPDC_PIGEON_CTRL0_LD_PERIOD_OFFSET = 16,
+       EPDC_PIGEON_CTRL0_FD_PERIOD_MASK = 0xFFF,
+       EPDC_PIGEON_CTRL0_FD_PERIOD_OFFSET = 0,
+
+/* EPDC EPDC_PIGEON_CTRL1 field values */
+       EPDC_PIGEON_CTRL1_LD_PERIOD_MASK = 0xFFF0000,
+       EPDC_PIGEON_CTRL1_LD_PERIOD_OFFSET = 16,
+       EPDC_PIGEON_CTRL1_FD_PERIOD_MASK = 0xFFF,
+       EPDC_PIGEON_CTRL1_FD_PERIOD_OFFSET = 0,
+
+/* EPDC_IRQ_MASK/EPDC_IRQ field values */
+       EPDC_IRQ_WB_CMPLT_IRQ = 0x10000,
+       EPDC_IRQ_LUT_COL_IRQ = 0x20000,
+       EPDC_IRQ_TCE_UNDERRUN_IRQ = 0x40000,
+       EPDC_IRQ_FRAME_END_IRQ = 0x80000,
+       EPDC_IRQ_BUS_ERROR_IRQ = 0x100000,
+       EPDC_IRQ_TCE_IDLE_IRQ = 0x200000,
+       EPDC_IRQ_UPD_DONE_IRQ = 0x400000,
+       EPDC_IRQ_PWR_IRQ = 0x800000,
+
+/* EPDC_STATUS_NEXTLUT field values */
+       EPDC_STATUS_NEXTLUT_NEXT_LUT_VALID = 0x100,
+       EPDC_STATUS_NEXTLUT_NEXT_LUT_MASK = 0x3F,
+       EPDC_STATUS_NEXTLUT_NEXT_LUT_OFFSET = 0,
+
+/* EPDC_STATUS field values */
+       EPDC_STATUS_HISTOGRAM_CP_MASK = 0x1F0000,
+       EPDC_STATUS_HISTOGRAM_CP_OFFSET = 16,
+       EPDC_STATUS_HISTOGRAM_NP_MASK = 0x1F00,
+       EPDC_STATUS_HISTOGRAM_NP_OFFSET = 8,
+       EPDC_STATUS_UPD_VOID = 0x8,
+       EPDC_STATUS_LUTS_UNDERRUN = 0x4,
+       EPDC_STATUS_LUTS_BUSY = 0x2,
+       EPDC_STATUS_WB_BUSY = 0x1,
+
+/* EPDC_UPD_COL_CORD field values */
+       EPDC_UPD_COL_CORD_YCORD_MASK = 0x1FFF0000,
+       EPDC_UPD_COL_CORD_YCORD_OFFSET = 16,
+       EPDC_UPD_COL_CORD_XCORD_MASK = 0x1FFF,
+       EPDC_UPD_COL_CORD_XCORD_OFFSET = 0,
+
+/* EPDC_UPD_COL_SIZE field values */
+       EPDC_UPD_COL_SIZE_HEIGHT_MASK = 0x1FFF0000,
+       EPDC_UPD_COL_SIZE_HEIGHT_OFFSET = 16,
+       EPDC_UPD_COL_SIZE_WIDTH_MASK = 0x1FFF,
+       EPDC_UPD_COL_SIZE_WIDTH_OFFSET = 0,
+
+/* EPDC_DEBUG field values */
+       EPDC_DEBUG_DEBUG_LUT_SEL_MASK = 0x3F00000,
+       EPDC_DEBUG_DEBUG_LUT_SEL_OFFSET = 24,
+       EPDC_DEBUG_UBW_BURST_LEN_MASK = 0xF000,
+       EPDC_DEBUG_UBW_BURST_LEN_OFFSET = 12,
+       EPDC_DEBUG_UBR_BURST_LEN_MASK = 0xF00,
+       EPDC_DEBUG_UBR_BURST_LEN = 8,
+       EPDC_DEBUG_UPD_BURST_LEN_MASK = 0xF0,
+       EPDC_DEBUG_UPD_BURST_LEN_OFFSET = 4,
+       EPDC_DEBUG_UPDATE_SAME = 0x4,
+       EPDC_DEBUG_UNDERRUN_RECOVER = 0x2,
+       EPDC_DEBUG_COLLISION_OFF = 0x1,
+
+/* EPDC_DEBUG_LUT field values */
+       EPDC_DEBUG_LUT_LUTADDR_MASK = 0x3FF0000,
+       EPDC_DEBUG_LUT_LUTADDR_OFFSET = 16,
+       EPDC_DEBUG_LUT_FRAME_MASK = 0x7FE0,
+       EPDC_DEBUG_LUT_FRAME_OFFSET = 5,
+       EPDC_DEBUG_LUT_STATEMACHINE_MASK = 0x1F,
+       EPDC_DEBUG_LUT_STATEMACHINE_OFFSET = 0,
+
+/* EPDC_HISTx_PARAM field values */
+       EPDC_HIST_PARAM_VALUE0_MASK = 0x1F,
+       EPDC_HIST_PARAM_VALUE0_OFFSET = 0,
+       EPDC_HIST_PARAM_VALUE1_MASK = 0x1F00,
+       EPDC_HIST_PARAM_VALUE1_OFFSET = 8,
+       EPDC_HIST_PARAM_VALUE2_MASK = 0x1F0000,
+       EPDC_HIST_PARAM_VALUE2_OFFSET = 16,
+       EPDC_HIST_PARAM_VALUE3_MASK = 0x1F000000,
+       EPDC_HIST_PARAM_VALUE3_OFFSET = 24,
+       EPDC_HIST_PARAM_VALUE4_MASK = 0x1F,
+       EPDC_HIST_PARAM_VALUE4_OFFSET = 0,
+       EPDC_HIST_PARAM_VALUE5_MASK = 0x1F00,
+       EPDC_HIST_PARAM_VALUE5_OFFSET = 8,
+       EPDC_HIST_PARAM_VALUE6_MASK = 0x1F0000,
+       EPDC_HIST_PARAM_VALUE6_OFFSET = 16,
+       EPDC_HIST_PARAM_VALUE7_MASK = 0x1F000000,
+       EPDC_HIST_PARAM_VALUE7_OFFSET = 24,
+       EPDC_HIST_PARAM_VALUE8_MASK = 0x1F,
+       EPDC_HIST_PARAM_VALUE8_OFFSET = 0,
+       EPDC_HIST_PARAM_VALUE9_MASK = 0x1F00,
+       EPDC_HIST_PARAM_VALUE9_OFFSET = 8,
+       EPDC_HIST_PARAM_VALUE10_MASK = 0x1F0000,
+       EPDC_HIST_PARAM_VALUE10_OFFSET = 16,
+       EPDC_HIST_PARAM_VALUE11_MASK = 0x1F000000,
+       EPDC_HIST_PARAM_VALUE11_OFFSET = 24,
+       EPDC_HIST_PARAM_VALUE12_MASK = 0x1F,
+       EPDC_HIST_PARAM_VALUE12_OFFSET = 0,
+       EPDC_HIST_PARAM_VALUE13_MASK = 0x1F00,
+       EPDC_HIST_PARAM_VALUE13_OFFSET = 8,
+       EPDC_HIST_PARAM_VALUE14_MASK = 0x1F0000,
+       EPDC_HIST_PARAM_VALUE14_OFFSET = 16,
+       EPDC_HIST_PARAM_VALUE15_MASK = 0x1F000000,
+       EPDC_HIST_PARAM_VALUE15_OFFSET = 24,
+
+/* EPDC_GPIO field values */
+       EPDC_GPIO_PWRSTAT = 0x100,
+       EPDC_GPIO_PWRWAKE = 0x80,
+       EPDC_GPIO_PWRCOM = 0x40,
+       EPDC_GPIO_PWRCTRL_MASK = 0x3C,
+       EPDC_GPIO_PWRCTRL_OFFSET = 2,
+       EPDC_GPIO_BDR_MASK = 0x3,
+       EPDC_GPIO_BDR_OFFSET = 0,
+
+/* EPDC_VERSION field values */
+       EPDC_VERSION_MAJOR_MASK = 0xFF000000,
+       EPDC_VERSION_MAJOR_OFFSET = 24,
+       EPDC_VERSION_MINOR_MASK = 0xFF0000,
+       EPDC_VERSION_MINOR_OFFSET = 16,
+       EPDC_VERSION_STEP_MASK = 0xFFFF,
+       EPDC_VERSION_STEP_OFFSET = 0,
+};
+
+int board_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__ */