diff options
author | Robby Cai <R63905@freescale.com> | 2013-11-18 18:05:22 +0800 |
---|---|---|
committer | Robby Cai <R63905@freescale.com> | 2013-11-21 20:02:46 +0800 |
commit | b934091a04e11e96281b10cf63830851fd096fdd (patch) | |
tree | c3d54192916a24bbc427bd6ab71db6f5b2ad1c3d /board/freescale | |
parent | fa9f30b03b65b253ba292020f3ebbe70220e3c29 (diff) | |
download | u-boot-imx-b934091a04e11e96281b10cf63830851fd096fdd.zip u-boot-imx-b934091a04e11e96281b10cf63830851fd096fdd.tar.gz u-boot-imx-b934091a04e11e96281b10cf63830851fd096fdd.tar.bz2 |
ENGR00288418 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>
Diffstat (limited to 'board/freescale')
-rw-r--r-- | board/freescale/mx6qsabresd/mx6qsabresd.c | 324 | ||||
-rw-r--r-- | board/freescale/mx6slevk/mx6slevk.c | 320 |
2 files changed, 644 insertions, 0 deletions
diff --git a/board/freescale/mx6qsabresd/mx6qsabresd.c b/board/freescale/mx6qsabresd/mx6qsabresd.c index aa53541..8617228 100644 --- a/board/freescale/mx6qsabresd/mx6qsabresd.c +++ b/board/freescale/mx6qsabresd/mx6qsabresd.c @@ -38,6 +38,11 @@ #include <miiphy.h> #include <netdev.h> +#if defined(CONFIG_MXC_EPDC) +#include <lcd.h> +#include <mxc_epdc_fb.h> +#endif + DECLARE_GLOBAL_DATA_PTR; #define UART_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ @@ -61,6 +66,9 @@ DECLARE_GLOBAL_DATA_PTR; PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \ PAD_CTL_ODE | PAD_CTL_SRE_FAST) +#define EPDC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_SPEED_MED | \ + PAD_CTL_DSE_40ohm | PAD_CTL_HYS) + #if CONFIG_I2C_MXC #define PC MUX_PAD_CTRL(I2C_PAD_CTRL) /* I2C2 Camera, MIPI, pfuze */ @@ -177,6 +185,52 @@ iomux_v3_cfg_t const usdhc4_pads[] = { MX6_PAD_SD4_DAT7__USDHC4_DAT7 | MUX_PAD_CTRL(USDHC_PAD_CTRL), }; +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, +}; + static void setup_iomux_uart(void) { imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads)); @@ -434,6 +488,272 @@ int board_mmc_init(bd_t *bis) } #endif +#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 */ + + /* 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_CMD_SATA int setup_sata(void) { @@ -524,6 +844,10 @@ int board_init(void) /* address of boot parameters */ gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; +#ifdef CONFIG_MXC_EPDC + setup_epdc(); +#endif + return 0; } diff --git a/board/freescale/mx6slevk/mx6slevk.c b/board/freescale/mx6slevk/mx6slevk.c index 4cc9604..334c49f 100644 --- a/board/freescale/mx6slevk/mx6slevk.c +++ b/board/freescale/mx6slevk/mx6slevk.c @@ -26,6 +26,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; @@ -46,6 +50,9 @@ DECLARE_GLOBAL_DATA_PTR; PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \ PAD_CTL_ODE | PAD_CTL_SRE_FAST) +#define EPDC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_SPEED_MED | \ + PAD_CTL_DSE_40ohm | PAD_CTL_HYS) + #if CONFIG_I2C_MXC #define PC MUX_PAD_CTRL(I2C_PAD_CTRL) /* I2C1 for PMIC */ @@ -98,6 +105,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)); @@ -130,6 +183,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) { @@ -282,6 +599,9 @@ int board_init(void) setup_fec(); #endif +#ifdef CONFIG_MXC_EPDC + setup_epdc(); +#endif return 0; } |