diff options
author | Peng Fan <Peng.Fan@freescale.com> | 2014-05-27 13:00:28 -0500 |
---|---|---|
committer | Peng Fan <Peng.Fan@freescale.com> | 2015-04-29 14:44:19 +0800 |
commit | b2b2982a756b1b2809e928bc122be92a537e0aad (patch) | |
tree | 1e71f135d025d0b69c3eaef085487f100fd7aeb8 /board | |
parent | 0e0e5d57593ce4d03056a13087ee292ff0e3ec81 (diff) | |
download | u-boot-imx-b2b2982a756b1b2809e928bc122be92a537e0aad.zip u-boot-imx-b2b2982a756b1b2809e928bc122be92a537e0aad.tar.gz u-boot-imx-b2b2982a756b1b2809e928bc122be92a537e0aad.tar.bz2 |
MLK-10774-5 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>
(cherry picked from commit b8ab9b3eabb94bbbc1eea63e7c0e2a87d2d645f4)
Signed-off-by: Peng Fan <Peng.Fan@freescale.com>
Conflicts:
arch/arm/include/asm/arch-mx6/mx6sl_pins.h
board/freescale/mx6sabresd/mx6sabresd.c
board/freescale/mx6slevk/mx6slevk.c
drivers/video/Makefile
include/configs/mx6sabresd.h
include/configs/mx6slevk.h
include/lcd.h
drivers/video/Makefile
Diffstat (limited to 'board')
-rw-r--r-- | board/freescale/mx6sabresd/mx6sabresd.c | 331 | ||||
-rw-r--r-- | board/freescale/mx6slevk/mx6slevk.c | 326 |
2 files changed, 657 insertions, 0 deletions
diff --git a/board/freescale/mx6sabresd/mx6sabresd.c b/board/freescale/mx6sabresd/mx6sabresd.c index b813f6f..562355d 100644 --- a/board/freescale/mx6sabresd/mx6sabresd.c +++ b/board/freescale/mx6sabresd/mx6sabresd.c @@ -20,6 +20,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 <asm/io.h> @@ -56,6 +61,8 @@ DECLARE_GLOBAL_DATA_PTR; #define I2C_PAD MUX_PAD_CTRL(I2C_PAD_CTRL) #define DISP0_PWR_EN IMX_GPIO_NR(1, 21) +#define EPDC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_SPEED_MED | \ + PAD_CTL_DSE_40ohm | PAD_CTL_HYS) int dram_init(void) { @@ -219,6 +226,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)); @@ -611,6 +666,272 @@ int board_early_init_f(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 + int board_init(void) { /* address of boot parameters */ @@ -625,6 +946,10 @@ int board_init(void) setup_usb(); #endif +#if defined(CONFIG_MX6DL) && defined(CONFIG_MXC_EPDC) + setup_epdc(); +#endif + return 0; } @@ -688,6 +1013,12 @@ int checkboard(void) return 0; } +#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)), +}; +#endif + #ifdef CONFIG_SPL_BUILD #include <spl.h> #include <libfdt.h> diff --git a/board/freescale/mx6slevk/mx6slevk.c b/board/freescale/mx6slevk/mx6slevk.c index 7c18c90..314dcc9 100644 --- a/board/freescale/mx6slevk/mx6slevk.c +++ b/board/freescale/mx6slevk/mx6slevk.c @@ -27,6 +27,10 @@ #include "../common/pfuze.h" #include <usb.h> #include <usb/ehci-fsl.h> +#if defined(CONFIG_MXC_EPDC) +#include <lcd.h> +#include <mxc_epdc_fb.h> +#endif DECLARE_GLOBAL_DATA_PTR; @@ -54,6 +58,8 @@ DECLARE_GLOBAL_DATA_PTR; PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_LOW |\ PAD_CTL_DSE_80ohm | PAD_CTL_HYS | \ PAD_CTL_SRE_FAST) +#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) @@ -143,6 +149,52 @@ static void setup_spi(void) } #endif +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)); @@ -335,6 +387,270 @@ int board_early_init_f(void) return 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 + int board_init(void) { /* address of boot parameters */ @@ -348,6 +664,11 @@ int board_init(void) setup_fec(); #endif +#ifdef CONFIG_MXC_EPDC + setup_epdc(); +#endif + return 0; + #ifdef CONFIG_USB_EHCI_MX6 setup_usb(); #endif @@ -355,6 +676,11 @@ int board_init(void) return 0; } +u32 get_board_rev(void) +{ + return get_cpu_rev(); +} + int checkboard(void) { puts("Board: MX6SLEVK\n"); |