summaryrefslogtreecommitdiff
path: root/board
diff options
context:
space:
mode:
authorNitin Garg <nitin.garg@freescale.com>2014-05-27 13:00:28 -0500
committerNitin Garg <nitin.garg@freescale.com>2014-05-27 22:18:35 -0500
commitb8ab9b3eabb94bbbc1eea63e7c0e2a87d2d645f4 (patch)
tree4cf9268347e096288a54a49df79ebed78d09a3ec /board
parentd0912be964679ada052bcd07a03d4689e84dce2e (diff)
downloadu-boot-imx-b8ab9b3eabb94bbbc1eea63e7c0e2a87d2d645f4.zip
u-boot-imx-b8ab9b3eabb94bbbc1eea63e7c0e2a87d2d645f4.tar.gz
u-boot-imx-b8ab9b3eabb94bbbc1eea63e7c0e2a87d2d645f4.tar.bz2
ENGR00315499-7 Add EPDC splash screen for MX 6DL SabreSD and 6SL EVK
Add EPDC splash screen feature for MX6SL EVK, and MX6DL SABRESD board. - Currently, splash screen consists of a simple black border around a white screen. Done this way to save in memory footprint. - EPDC splash screen is disabled by default in the config file for MX6DL_SABRESD and MX6SL_EVK. If left enabled, the U-Boot image will not boot correctly (hang), since some additional content on the boot device (waveform file) is required for EPDC splash to work correctly. Please refer to Linux Reference Manual for how to flash WAVEFORM file. Signed-off-by: Robby Cai <R63905@freescale.com> Signed-off-by: Nitin Garg <nitin.garg@freescale.com>
Diffstat (limited to 'board')
-rw-r--r--board/freescale/mx6sabresd/mx6sabresd.c326
-rw-r--r--board/freescale/mx6slevk/mx6slevk.c321
2 files changed, 647 insertions, 0 deletions
diff --git a/board/freescale/mx6sabresd/mx6sabresd.c b/board/freescale/mx6sabresd/mx6sabresd.c
index df7df77..26859ee 100644
--- a/board/freescale/mx6sabresd/mx6sabresd.c
+++ b/board/freescale/mx6sabresd/mx6sabresd.c
@@ -18,6 +18,11 @@
#include <fsl_esdhc.h>
#include <miiphy.h>
#include <netdev.h>
+
+#if defined(CONFIG_MX6DL) && defined(CONFIG_MXC_EPDC)
+#include <lcd.h>
+#include <mxc_epdc_fb.h>
+#endif
#include <asm/arch/mxc_hdmi.h>
#include <asm/arch/crm_regs.h>
#include <linux/fb.h>
@@ -44,6 +49,9 @@ DECLARE_GLOBAL_DATA_PTR;
#define SPI_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_SPEED_MED | \
PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST)
+#define EPDC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
+
int dram_init(void)
{
gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE);
@@ -155,6 +163,54 @@ iomux_v3_cfg_t const di0_pads[] = {
MX6_PAD_DI0_PIN3__IPU1_DI0_PIN03, /* DISP0_VSYNC */
};
+#if defined(CONFIG_MX6DL) && defined(CONFIG_MXC_EPDC)
+static iomux_v3_cfg_t const epdc_enable_pads[] = {
+ MX6_PAD_EIM_A16__EPDC_SDDO_0 | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EIM_DA10__EPDC_SDDO_1 | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EIM_DA12__EPDC_SDDO_2 | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EIM_DA11__EPDC_SDDO_3 | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EIM_LBA__EPDC_SDDO_4 | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EIM_EB2__EPDC_SDDO_5 | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EIM_CS0__EPDC_SDDO_6 | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EIM_RW__EPDC_SDDO_7 | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EIM_A21__EPDC_GDCLK | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EIM_A22__EPDC_GDSP | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EIM_A23__EPDC_GDOE | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EIM_A24__EPDC_GDRL | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EIM_D31__EPDC_SDCLK | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EIM_D27__EPDC_SDOE | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EIM_DA1__EPDC_SDLE | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EIM_EB1__EPDC_SDSHR | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EIM_DA2__EPDC_BDR_0 | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EIM_DA4__EPDC_SDCE_0 | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EIM_DA5__EPDC_SDCE_1 | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EIM_DA6__EPDC_SDCE_2 | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+};
+
+static iomux_v3_cfg_t const epdc_disable_pads[] = {
+ MX6_PAD_EIM_A16__GPIO_2_22,
+ MX6_PAD_EIM_DA10__GPIO_3_10,
+ MX6_PAD_EIM_DA12__GPIO_3_12,
+ MX6_PAD_EIM_DA11__GPIO_3_11,
+ MX6_PAD_EIM_LBA__GPIO_2_27,
+ MX6_PAD_EIM_EB2__GPIO_2_30,
+ MX6_PAD_EIM_CS0__GPIO_2_23,
+ MX6_PAD_EIM_RW__GPIO_2_26,
+ MX6_PAD_EIM_A21__GPIO_2_17,
+ MX6_PAD_EIM_A22__GPIO_2_16,
+ MX6_PAD_EIM_A23__GPIO_6_6,
+ MX6_PAD_EIM_A24__GPIO_5_4,
+ MX6_PAD_EIM_D31__GPIO_3_31,
+ MX6_PAD_EIM_D27__GPIO_3_27,
+ MX6_PAD_EIM_DA1__GPIO_3_1,
+ MX6_PAD_EIM_EB1__GPIO_2_29,
+ MX6_PAD_EIM_DA2__GPIO_3_2,
+ MX6_PAD_EIM_DA4__GPIO_3_4,
+ MX6_PAD_EIM_DA5__GPIO_3_5,
+ MX6_PAD_EIM_DA6__GPIO_3_6,
+};
+#endif
+
static void setup_iomux_uart(void)
{
imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads));
@@ -554,6 +610,10 @@ int board_init(void)
setup_spi();
#endif
+#if defined(CONFIG_MX6DL) && defined(CONFIG_MXC_EPDC)
+ setup_epdc();
+#endif
+
return 0;
}
@@ -583,6 +643,272 @@ int checkboard(void)
return 0;
}
+#if defined(CONFIG_MX6DL) && defined(CONFIG_MXC_EPDC)
+#ifdef CONFIG_SPLASH_SCREEN
+extern int mmc_get_env_devno(void);
+int setup_splash_img(void)
+{
+#ifdef CONFIG_SPLASH_IS_IN_MMC
+ int mmc_dev = mmc_get_env_devno();
+ ulong offset = CONFIG_SPLASH_IMG_OFFSET;
+ ulong size = CONFIG_SPLASH_IMG_SIZE;
+ ulong addr = 0;
+ char *s = NULL;
+ struct mmc *mmc = find_mmc_device(mmc_dev);
+ uint blk_start, blk_cnt, n;
+
+ s = getenv("splashimage");
+
+ if (NULL == s) {
+ puts("env splashimage not found!\n");
+ return -1;
+ }
+ addr = simple_strtoul(s, NULL, 16);
+
+ if (!mmc) {
+ printf("MMC Device %d not found\n", mmc_dev);
+ return -1;
+ }
+
+ if (mmc_init(mmc)) {
+ puts("MMC init failed\n");
+ return -1;
+ }
+
+ blk_start = ALIGN(offset, mmc->read_bl_len) / mmc->read_bl_len;
+ blk_cnt = ALIGN(size, mmc->read_bl_len) / mmc->read_bl_len;
+ n = mmc->block_dev.block_read(mmc_dev, blk_start,
+ blk_cnt, (u_char *)addr);
+ flush_cache((ulong)addr, blk_cnt * mmc->read_bl_len);
+
+ return (n == blk_cnt) ? 0 : -1;
+#endif
+
+ return 0;
+}
+#endif
+
+vidinfo_t panel_info = {
+ .vl_refresh = 85,
+ .vl_col = 800,
+ .vl_row = 600,
+ .vl_pixclock = 26666667,
+ .vl_left_margin = 8,
+ .vl_right_margin = 100,
+ .vl_upper_margin = 4,
+ .vl_lower_margin = 8,
+ .vl_hsync = 4,
+ .vl_vsync = 1,
+ .vl_sync = 0,
+ .vl_mode = 0,
+ .vl_flag = 0,
+ .vl_bpix = 3,
+ .cmap = 0,
+};
+
+struct epdc_timing_params panel_timings = {
+ .vscan_holdoff = 4,
+ .sdoed_width = 10,
+ .sdoed_delay = 20,
+ .sdoez_width = 10,
+ .sdoez_delay = 20,
+ .gdclk_hp_offs = 419,
+ .gdsp_offs = 20,
+ .gdoe_offs = 0,
+ .gdclk_offs = 5,
+ .num_ce = 1,
+};
+
+static void setup_epdc_power(void)
+{
+ /* Setup epdc voltage */
+
+ /* EIM_A17 - GPIO2[21] for PWR_GOOD status */
+ imx_iomux_v3_setup_pad(MX6_PAD_EIM_A17__GPIO_2_21 |
+ MUX_PAD_CTRL(EPDC_PAD_CTRL));
+ /* Set as input */
+ gpio_direction_input(IMX_GPIO_NR(2, 21));
+
+ /* EIM_D17 - GPIO3[17] for VCOM control */
+ imx_iomux_v3_setup_pad(MX6_PAD_EIM_D17__GPIO_3_17 |
+ MUX_PAD_CTRL(EPDC_PAD_CTRL));
+
+ /* Set as output */
+ gpio_direction_output(IMX_GPIO_NR(3, 17), 1);
+
+ /* EIM_D20 - GPIO3[20] for EPD PMIC WAKEUP */
+ imx_iomux_v3_setup_pad(MX6_PAD_EIM_D20__GPIO_3_20 |
+ MUX_PAD_CTRL(EPDC_PAD_CTRL));
+ /* Set as output */
+ gpio_direction_output(IMX_GPIO_NR(3, 20), 1);
+
+ /* EIM_A18 - GPIO2[20] for EPD PWR CTL0 */
+ imx_iomux_v3_setup_pad(MX6_PAD_EIM_A18__GPIO_2_20 |
+ MUX_PAD_CTRL(EPDC_PAD_CTRL));
+ /* Set as output */
+ gpio_direction_output(IMX_GPIO_NR(2, 20), 1);
+}
+
+int setup_waveform_file(void)
+{
+#ifdef CONFIG_WAVEFORM_FILE_IN_MMC
+ int mmc_dev = mmc_get_env_devno();
+ ulong offset = CONFIG_WAVEFORM_FILE_OFFSET;
+ ulong size = CONFIG_WAVEFORM_FILE_SIZE;
+ ulong addr = CONFIG_WAVEFORM_BUF_ADDR;
+ struct mmc *mmc = find_mmc_device(mmc_dev);
+ uint blk_start, blk_cnt, n;
+
+ if (!mmc) {
+ printf("MMC Device %d not found\n", mmc_dev);
+ return -1;
+ }
+
+ if (mmc_init(mmc)) {
+ puts("MMC init failed\n");
+ return -1;
+ }
+
+ blk_start = ALIGN(offset, mmc->read_bl_len) / mmc->read_bl_len;
+ blk_cnt = ALIGN(size, mmc->read_bl_len) / mmc->read_bl_len;
+ n = mmc->block_dev.block_read(mmc_dev, blk_start,
+ blk_cnt, (u_char *)addr);
+ flush_cache((ulong)addr, blk_cnt * mmc->read_bl_len);
+
+ return (n == blk_cnt) ? 0 : -1;
+#else
+ return -1;
+#endif
+}
+
+static void epdc_enable_pins(void)
+{
+ /* epdc iomux settings */
+ imx_iomux_v3_setup_multiple_pads(epdc_enable_pads,
+ ARRAY_SIZE(epdc_enable_pads));
+}
+
+static void epdc_disable_pins(void)
+{
+ /* Configure MUX settings for EPDC pins to GPIO */
+ imx_iomux_v3_setup_multiple_pads(epdc_disable_pads,
+ ARRAY_SIZE(epdc_disable_pads));
+}
+
+static void setup_epdc(void)
+{
+ unsigned int reg;
+
+ /*** epdc Maxim PMIC settings ***/
+
+ /* EPDC PWRSTAT - GPIO2[21] for PWR_GOOD status */
+ imx_iomux_v3_setup_pad(MX6_PAD_EIM_A17__GPIO_2_21 |
+ MUX_PAD_CTRL(EPDC_PAD_CTRL));
+
+ /* EPDC VCOM0 - GPIO3[17] for VCOM control */
+ imx_iomux_v3_setup_pad(MX6_PAD_EIM_D17__GPIO_3_17 |
+ MUX_PAD_CTRL(EPDC_PAD_CTRL));
+
+ /* UART4 TXD - GPIO3[20] for EPD PMIC WAKEUP */
+ imx_iomux_v3_setup_pad(MX6_PAD_EIM_D20__GPIO_3_20 |
+ MUX_PAD_CTRL(EPDC_PAD_CTRL));
+
+ /* EIM_A18 - GPIO2[20] for EPD PWR CTL0 */
+ imx_iomux_v3_setup_pad(MX6_PAD_EIM_A18__GPIO_2_20 |
+ MUX_PAD_CTRL(EPDC_PAD_CTRL));
+
+ /*** Set pixel clock rates for EPDC ***/
+
+ /* EPDC AXI clk (IPU2_CLK) from PFD_400M, set to 396/2 = 198MHz */
+ reg = readl(CCM_BASE_ADDR + CLKCTL_CSCDR3);
+ reg &= ~0x7C000;
+ reg |= (1 << 16) | (1 << 14);
+ writel(reg, CCM_BASE_ADDR + CLKCTL_CSCDR3);
+
+ /* EPDC AXI clk enable */
+ reg = readl(CCM_BASE_ADDR + CLKCTL_CCGR3);
+ reg |= 0x00C0;
+ writel(reg, CCM_BASE_ADDR + CLKCTL_CCGR3);
+
+ /* EPDC PIX clk (IPU2_DI1_CLK) from PLL5, set to 650/4/6 = ~27MHz */
+ reg = readl(CCM_BASE_ADDR + CLKCTL_CSCDR2);
+ reg &= ~0x3FE00;
+ reg |= (2 << 15) | (5 << 12);
+ writel(reg, CCM_BASE_ADDR + CLKCTL_CSCDR2);
+
+ /* PLL5 enable (defaults to 650) */
+ reg = readl(ANATOP_BASE_ADDR + ANATOP_PLL_VIDEO);
+ reg &= ~((1 << 16) | (1 << 12));
+ reg |= (1 << 13);
+ writel(reg, ANATOP_BASE_ADDR + ANATOP_PLL_VIDEO);
+
+ /* EPDC PIX clk enable */
+ reg = readl(CCM_BASE_ADDR + CLKCTL_CCGR3);
+ reg |= 0x0C00;
+ writel(reg, CCM_BASE_ADDR + CLKCTL_CCGR3);
+
+ panel_info.epdc_data.working_buf_addr = CONFIG_WORKING_BUF_ADDR;
+ panel_info.epdc_data.waveform_buf_addr = CONFIG_WAVEFORM_BUF_ADDR;
+
+ panel_info.epdc_data.wv_modes.mode_init = 0;
+ panel_info.epdc_data.wv_modes.mode_du = 1;
+ panel_info.epdc_data.wv_modes.mode_gc4 = 3;
+ panel_info.epdc_data.wv_modes.mode_gc8 = 2;
+ panel_info.epdc_data.wv_modes.mode_gc16 = 2;
+ panel_info.epdc_data.wv_modes.mode_gc32 = 2;
+
+ panel_info.epdc_data.epdc_timings = panel_timings;
+
+ setup_epdc_power();
+
+ /* Assign fb_base */
+ gd->fb_base = CONFIG_FB_BASE;
+}
+
+void epdc_power_on(void)
+{
+ unsigned int reg;
+
+ /* Set EPD_PWR_CTL0 to high - enable EINK_VDD (3.15) */
+ gpio_set_value(IMX_GPIO_NR(2, 20), 1);
+ udelay(1000);
+
+ /* Enable epdc signal pin */
+ epdc_enable_pins();
+
+ /* Set PMIC Wakeup to high - enable Display power */
+ gpio_set_value(IMX_GPIO_NR(3, 20), 1);
+
+ /* Wait for PWRGOOD == 1 */
+ while (1) {
+ reg = readl(GPIO2_BASE_ADDR + GPIO_PSR);
+ if (!(reg & (1 << 21)))
+ break;
+
+ udelay(100);
+ }
+
+ /* Enable VCOM */
+ gpio_set_value(IMX_GPIO_NR(3, 17), 1);
+
+ udelay(500);
+}
+
+void epdc_power_off(void)
+{
+ /* Set PMIC Wakeup to low - disable Display power */
+ gpio_set_value(IMX_GPIO_NR(3, 20), 0);
+
+ /* Disable VCOM */
+ gpio_set_value(IMX_GPIO_NR(3, 17), 0);
+
+ epdc_disable_pins();
+
+ /* Set EPD_PWR_CTL0 to low - disable EINK_VDD (3.15) */
+ gpio_set_value(IMX_GPIO_NR(2, 20), 0);
+}
+#endif
+
#ifdef CONFIG_IMX_UDC
iomux_v3_cfg_t const otg_udc_pads[] = {
(MX6_PAD_ENET_RX_ER__USB_OTG_ID | MUX_PAD_CTRL(NO_PAD_CTRL)),
diff --git a/board/freescale/mx6slevk/mx6slevk.c b/board/freescale/mx6slevk/mx6slevk.c
index afd3a06..95763b4 100644
--- a/board/freescale/mx6slevk/mx6slevk.c
+++ b/board/freescale/mx6slevk/mx6slevk.c
@@ -23,6 +23,10 @@
#include <i2c.h>
#include <asm/imx-common/mxc_i2c.h>
#endif
+#if defined(CONFIG_MXC_EPDC)
+#include <lcd.h>
+#include <mxc_epdc_fb.h>
+#endif
DECLARE_GLOBAL_DATA_PTR;
@@ -38,6 +42,9 @@ DECLARE_GLOBAL_DATA_PTR;
PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
+#define EPDC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
+
#define ETH_PHY_RESET IMX_GPIO_NR(4, 21)
int dram_init(void)
@@ -75,6 +82,52 @@ static iomux_v3_cfg_t const fec_pads[] = {
MX6_PAD_FEC_TX_CLK__GPIO_4_21 | MUX_PAD_CTRL(NO_PAD_CTRL),
};
+static iomux_v3_cfg_t const epdc_enable_pads[] = {
+ MX6_PAD_EPDC_D0__EPDC_SDDO_0 | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EPDC_D1__EPDC_SDDO_1 | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EPDC_D2__EPDC_SDDO_2 | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EPDC_D3__EPDC_SDDO_3 | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EPDC_D4__EPDC_SDDO_4 | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EPDC_D5__EPDC_SDDO_5 | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EPDC_D6__EPDC_SDDO_6 | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EPDC_D7__EPDC_SDDO_7 | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EPDC_GDCLK__EPDC_GDCLK | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EPDC_GDSP__EPDC_GDSP | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EPDC_GDOE__EPDC_GDOE | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EPDC_GDRL__EPDC_GDRL | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EPDC_SDCLK__EPDC_SDCLK | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EPDC_SDOE__EPDC_SDOE | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EPDC_SDLE__EPDC_SDLE | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EPDC_SDSHR__EPDC_SDSHR | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EPDC_BDR0__EPDC_BDR_0 | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EPDC_SDCE0__EPDC_SDCE_0 | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EPDC_SDCE1__EPDC_SDCE_1 | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+ MX6_PAD_EPDC_SDCE2__EPDC_SDCE_2 | MUX_PAD_CTRL(EPDC_PAD_CTRL),
+};
+
+static iomux_v3_cfg_t const epdc_disable_pads[] = {
+ MX6_PAD_EPDC_D0__GPIO_1_7,
+ MX6_PAD_EPDC_D1__GPIO_1_8,
+ MX6_PAD_EPDC_D2__GPIO_1_9,
+ MX6_PAD_EPDC_D3__GPIO_1_10,
+ MX6_PAD_EPDC_D4__GPIO_1_11,
+ MX6_PAD_EPDC_D5__GPIO_1_12,
+ MX6_PAD_EPDC_D6__GPIO_1_13,
+ MX6_PAD_EPDC_D7__GPIO_1_14,
+ MX6_PAD_EPDC_GDCLK__GPIO_1_31,
+ MX6_PAD_EPDC_GDSP__GPIO_2_2,
+ MX6_PAD_EPDC_GDOE__GPIO_2_0,
+ MX6_PAD_EPDC_GDRL__GPIO_2_1,
+ MX6_PAD_EPDC_SDCLK__GPIO_1_23,
+ MX6_PAD_EPDC_SDOE__GPIO_1_25,
+ MX6_PAD_EPDC_SDLE__GPIO_1_24,
+ MX6_PAD_EPDC_SDSHR__GPIO_1_26,
+ MX6_PAD_EPDC_BDR0__GPIO_2_5,
+ MX6_PAD_EPDC_SDCE0__GPIO_1_27,
+ MX6_PAD_EPDC_SDCE1__GPIO_1_28,
+ MX6_PAD_EPDC_SDCE2__GPIO_1_29,
+};
+
static void setup_iomux_uart(void)
{
imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads));
@@ -107,6 +160,270 @@ int board_mmc_init(bd_t *bis)
return fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
}
+#ifdef CONFIG_MXC_EPDC
+#ifdef CONFIG_SPLASH_SCREEN
+extern int mmc_get_env_devno(void);
+int setup_splash_img(void)
+{
+#ifdef CONFIG_SPLASH_IS_IN_MMC
+ int mmc_dev = mmc_get_env_devno();
+ ulong offset = CONFIG_SPLASH_IMG_OFFSET;
+ ulong size = CONFIG_SPLASH_IMG_SIZE;
+ ulong addr = 0;
+ char *s = NULL;
+ struct mmc *mmc = find_mmc_device(mmc_dev);
+ uint blk_start, blk_cnt, n;
+
+ s = getenv("splashimage");
+
+ if (NULL == s) {
+ puts("env splashimage not found!\n");
+ return -1;
+ }
+ addr = simple_strtoul(s, NULL, 16);
+
+ if (!mmc) {
+ printf("MMC Device %d not found\n", mmc_dev);
+ return -1;
+ }
+
+ if (mmc_init(mmc)) {
+ puts("MMC init failed\n");
+ return -1;
+ }
+
+ blk_start = ALIGN(offset, mmc->read_bl_len) / mmc->read_bl_len;
+ blk_cnt = ALIGN(size, mmc->read_bl_len) / mmc->read_bl_len;
+ n = mmc->block_dev.block_read(mmc_dev, blk_start,
+ blk_cnt, (u_char *)addr);
+ flush_cache((ulong)addr, blk_cnt * mmc->read_bl_len);
+
+ return (n == blk_cnt) ? 0 : -1;
+#endif
+
+ return 0;
+}
+#endif
+
+vidinfo_t panel_info = {
+ .vl_refresh = 85,
+ .vl_col = 800,
+ .vl_row = 600,
+ .vl_pixclock = 26666667,
+ .vl_left_margin = 8,
+ .vl_right_margin = 100,
+ .vl_upper_margin = 4,
+ .vl_lower_margin = 8,
+ .vl_hsync = 4,
+ .vl_vsync = 1,
+ .vl_sync = 0,
+ .vl_mode = 0,
+ .vl_flag = 0,
+ .vl_bpix = 3,
+ .cmap = 0,
+};
+
+struct epdc_timing_params panel_timings = {
+ .vscan_holdoff = 4,
+ .sdoed_width = 10,
+ .sdoed_delay = 20,
+ .sdoez_width = 10,
+ .sdoez_delay = 20,
+ .gdclk_hp_offs = 419,
+ .gdsp_offs = 20,
+ .gdoe_offs = 0,
+ .gdclk_offs = 5,
+ .num_ce = 1,
+};
+
+static void setup_epdc_power(void)
+{
+ /* Setup epdc voltage */
+
+ /* EPDC_PWRSTAT - GPIO2[13] for PWR_GOOD status */
+ imx_iomux_v3_setup_pad(MX6_PAD_EPDC_PWRSTAT__GPIO_2_13 |
+ MUX_PAD_CTRL(EPDC_PAD_CTRL));
+ gpio_direction_input(IMX_GPIO_NR(2, 13));
+
+ /* EPDC_VCOM0 - GPIO2[3] for VCOM control */
+ imx_iomux_v3_setup_pad(MX6_PAD_EPDC_VCOM0__GPIO_2_3 |
+ MUX_PAD_CTRL(EPDC_PAD_CTRL));
+
+ /* Set as output */
+ gpio_direction_output(IMX_GPIO_NR(2, 3), 1);
+
+ /* EPDC_PWRWAKEUP - GPIO2[14] for EPD PMIC WAKEUP */
+ imx_iomux_v3_setup_pad(MX6_PAD_EPDC_PWRWAKEUP__GPIO_2_14 |
+ MUX_PAD_CTRL(EPDC_PAD_CTRL));
+ /* Set as output */
+ gpio_direction_output(IMX_GPIO_NR(2, 14), 1);
+
+ /* EPDC_PWRCTRL0 - GPIO2[7] for EPD PWR CTL0 */
+ imx_iomux_v3_setup_pad(MX6_PAD_EPDC_PWRCTRL0__GPIO_2_7 |
+ MUX_PAD_CTRL(EPDC_PAD_CTRL));
+ /* Set as output */
+ gpio_direction_output(IMX_GPIO_NR(2, 7), 1);
+}
+
+int setup_waveform_file(void)
+{
+#ifdef CONFIG_WAVEFORM_FILE_IN_MMC
+ int mmc_dev = mmc_get_env_devno();
+ ulong offset = CONFIG_WAVEFORM_FILE_OFFSET;
+ ulong size = CONFIG_WAVEFORM_FILE_SIZE;
+ ulong addr = CONFIG_WAVEFORM_BUF_ADDR;
+ struct mmc *mmc = find_mmc_device(mmc_dev);
+ uint blk_start, blk_cnt, n;
+
+ if (!mmc) {
+ printf("MMC Device %d not found\n", mmc_dev);
+ return -1;
+ }
+
+ if (mmc_init(mmc)) {
+ puts("MMC init failed\n");
+ return -1;
+ }
+
+ blk_start = ALIGN(offset, mmc->read_bl_len) / mmc->read_bl_len;
+ blk_cnt = ALIGN(size, mmc->read_bl_len) / mmc->read_bl_len;
+ n = mmc->block_dev.block_read(mmc_dev, blk_start,
+ blk_cnt, (u_char *)addr);
+ flush_cache((ulong)addr, blk_cnt * mmc->read_bl_len);
+
+ return (n == blk_cnt) ? 0 : -1;
+#else
+ return -1;
+#endif
+}
+
+static void epdc_enable_pins(void)
+{
+ /* epdc iomux settings */
+ imx_iomux_v3_setup_multiple_pads(epdc_enable_pads,
+ ARRAY_SIZE(epdc_enable_pads));
+}
+
+static void epdc_disable_pins(void)
+{
+ /* Configure MUX settings for EPDC pins to GPIO and drive to 0 */
+ imx_iomux_v3_setup_multiple_pads(epdc_disable_pads,
+ ARRAY_SIZE(epdc_disable_pads));
+}
+
+static void setup_epdc(void)
+{
+ unsigned int reg;
+
+ /*** epdc Maxim PMIC settings ***/
+
+ /* EPDC PWRSTAT - GPIO2[13] for PWR_GOOD status */
+ imx_iomux_v3_setup_pad(MX6_PAD_EPDC_PWRSTAT__GPIO_2_13 |
+ MUX_PAD_CTRL(EPDC_PAD_CTRL));
+
+ /* EPDC VCOM0 - GPIO2[3] for VCOM control */
+ imx_iomux_v3_setup_pad(MX6_PAD_EPDC_VCOM0__GPIO_2_3 |
+ MUX_PAD_CTRL(EPDC_PAD_CTRL));
+
+ /* UART4 TXD - GPIO2[14] for EPD PMIC WAKEUP */
+ imx_iomux_v3_setup_pad(MX6_PAD_EPDC_PWRWAKEUP__GPIO_2_14 |
+ MUX_PAD_CTRL(EPDC_PAD_CTRL));
+
+ /* EIM_A18 - GPIO2[7] for EPD PWR CTL0 */
+ imx_iomux_v3_setup_pad(MX6_PAD_EPDC_PWRCTRL0__GPIO_2_7 |
+ MUX_PAD_CTRL(EPDC_PAD_CTRL));
+
+ /*** Set pixel clock rates for EPDC ***/
+
+ /* EPDC AXI clk from PFD_400M, set to 396/2 = 198MHz */
+ reg = readl(CCM_BASE_ADDR + CLKCTL_CHSCCDR);
+ reg &= ~0x3F000;
+ reg |= (0x4 << 15) | (1 << 12);
+ writel(reg, CCM_BASE_ADDR + CLKCTL_CHSCCDR);
+
+ /* EPDC AXI clk enable */
+ reg = readl(CCM_BASE_ADDR + CLKCTL_CCGR3);
+ reg |= 0x0030;
+ writel(reg, CCM_BASE_ADDR + CLKCTL_CCGR3);
+
+ /* EPDC PIX clk from PFD_540M, set to 540/4/5 = 27MHz */
+ reg = readl(CCM_BASE_ADDR + CLKCTL_CSCDR2);
+ reg &= ~0x03F000;
+ reg |= (0x5 << 15) | (4 << 12);
+ writel(reg, CCM_BASE_ADDR + CLKCTL_CSCDR2);
+
+ reg = readl(CCM_BASE_ADDR + CLKCTL_CBCMR);
+ reg &= ~0x03800000;
+ reg |= (0x3 << 23);
+ writel(reg, CCM_BASE_ADDR + CLKCTL_CBCMR);
+
+ /* EPDC PIX clk enable */
+ reg = readl(CCM_BASE_ADDR + CLKCTL_CCGR3);
+ reg |= 0x0C00;
+ writel(reg, CCM_BASE_ADDR + CLKCTL_CCGR3);
+
+ panel_info.epdc_data.working_buf_addr = CONFIG_WORKING_BUF_ADDR;
+ panel_info.epdc_data.waveform_buf_addr = CONFIG_WAVEFORM_BUF_ADDR;
+
+ panel_info.epdc_data.wv_modes.mode_init = 0;
+ panel_info.epdc_data.wv_modes.mode_du = 1;
+ panel_info.epdc_data.wv_modes.mode_gc4 = 3;
+ panel_info.epdc_data.wv_modes.mode_gc8 = 2;
+ panel_info.epdc_data.wv_modes.mode_gc16 = 2;
+ panel_info.epdc_data.wv_modes.mode_gc32 = 2;
+
+ panel_info.epdc_data.epdc_timings = panel_timings;
+
+ setup_epdc_power();
+
+ /* Assign fb_base */
+ gd->fb_base = CONFIG_FB_BASE;
+}
+
+void epdc_power_on(void)
+{
+ unsigned int reg;
+
+ /* Set EPD_PWR_CTL0 to high - enable EINK_VDD (3.15) */
+ gpio_set_value(IMX_GPIO_NR(2, 7), 1);
+ udelay(1000);
+
+ /* Enable epdc signal pin */
+ epdc_enable_pins();
+
+ /* Set PMIC Wakeup to high - enable Display power */
+ gpio_set_value(IMX_GPIO_NR(2, 14), 1);
+
+ /* Wait for PWRGOOD == 1 */
+ while (1) {
+ reg = readl(GPIO2_BASE_ADDR + GPIO_PSR);
+ if (!(reg & (1 << 13)))
+ break;
+
+ udelay(100);
+ }
+
+ /* Enable VCOM */
+ gpio_set_value(IMX_GPIO_NR(2, 3), 1);
+
+ udelay(500);
+}
+
+void epdc_power_off(void)
+{
+ /* Set PMIC Wakeup to low - disable Display power */
+ gpio_set_value(IMX_GPIO_NR(2, 14), 0);
+
+ /* Disable VCOM */
+ gpio_set_value(IMX_GPIO_NR(2, 3), 0);
+
+ epdc_disable_pins();
+
+ /* Set EPD_PWR_CTL0 to low - disable EINK_VDD (3.15) */
+ gpio_set_value(IMX_GPIO_NR(2, 7), 0);
+}
+#endif
+
#ifdef CONFIG_FEC_MXC
int board_eth_init(bd_t *bis)
{
@@ -182,6 +499,10 @@ int board_init(void)
#ifdef CONFIG_FEC_MXC
setup_fec();
#endif
+
+#ifdef CONFIG_MXC_EPDC
+ setup_epdc();
+#endif
return 0;
}