From 71dbb9dadd51c35dd558c900ca18ef70117a424f Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Mon, 22 Feb 2016 15:53:59 +0800 Subject: MLK-12425-4: mx6dlsabresd: support epdc Support epdc for mx6dlsabresd board. Introduce a new configuration file mx6dlsabresd_epdc_defconfig. Add related settings. Signed-off-by: Peng Fan (cherry picked from commit 467974ffda4b874e16f0c84974c3d65d85f84f6a) --- board/freescale/mx6sabresd/mx6sabresd.c | 231 ++++++++++++++++++++++++++++++++ 1 file changed, 231 insertions(+) (limited to 'board') diff --git a/board/freescale/mx6sabresd/mx6sabresd.c b/board/freescale/mx6sabresd/mx6sabresd.c index 040bfaa..d079fc4 100644 --- a/board/freescale/mx6sabresd/mx6sabresd.c +++ b/board/freescale/mx6sabresd/mx6sabresd.c @@ -30,6 +30,10 @@ #include "../common/pfuze.h" #include #include +#if defined(CONFIG_MX6DL) && defined(CONFIG_MXC_EPDC) +#include +#include +#endif DECLARE_GLOBAL_DATA_PTR; @@ -51,6 +55,9 @@ DECLARE_GLOBAL_DATA_PTR; PAD_CTL_SPEED_MED | 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) + #define I2C_PMIC 1 #define I2C_PAD MUX_PAD_CTRL(I2C_PAD_CTRL) @@ -248,6 +255,54 @@ static void setup_iomux_uart(void) imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads)); } +#if defined(CONFIG_MX6DL) && defined(CONFIG_MXC_EPDC) +static iomux_v3_cfg_t const epdc_enable_pads[] = { + MX6_PAD_EIM_A16__EPDC_DATA00 | MUX_PAD_CTRL(EPDC_PAD_CTRL), + MX6_PAD_EIM_DA10__EPDC_DATA01 | MUX_PAD_CTRL(EPDC_PAD_CTRL), + MX6_PAD_EIM_DA12__EPDC_DATA02 | MUX_PAD_CTRL(EPDC_PAD_CTRL), + MX6_PAD_EIM_DA11__EPDC_DATA03 | MUX_PAD_CTRL(EPDC_PAD_CTRL), + MX6_PAD_EIM_LBA__EPDC_DATA04 | MUX_PAD_CTRL(EPDC_PAD_CTRL), + MX6_PAD_EIM_EB2__EPDC_DATA05 | MUX_PAD_CTRL(EPDC_PAD_CTRL), + MX6_PAD_EIM_CS0__EPDC_DATA06 | MUX_PAD_CTRL(EPDC_PAD_CTRL), + MX6_PAD_EIM_RW__EPDC_DATA07 | 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_P | 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_BDR0 | MUX_PAD_CTRL(EPDC_PAD_CTRL), + MX6_PAD_EIM_DA4__EPDC_SDCE0 | MUX_PAD_CTRL(EPDC_PAD_CTRL), + MX6_PAD_EIM_DA5__EPDC_SDCE1 | MUX_PAD_CTRL(EPDC_PAD_CTRL), + MX6_PAD_EIM_DA6__EPDC_SDCE2 | MUX_PAD_CTRL(EPDC_PAD_CTRL), +}; + +static iomux_v3_cfg_t const epdc_disable_pads[] = { + MX6_PAD_EIM_A16__GPIO2_IO22, + MX6_PAD_EIM_DA10__GPIO3_IO10, + MX6_PAD_EIM_DA12__GPIO3_IO12, + MX6_PAD_EIM_DA11__GPIO3_IO11, + MX6_PAD_EIM_LBA__GPIO2_IO27, + MX6_PAD_EIM_EB2__GPIO2_IO30, + MX6_PAD_EIM_CS0__GPIO2_IO23, + MX6_PAD_EIM_RW__GPIO2_IO26, + MX6_PAD_EIM_A21__GPIO2_IO17, + MX6_PAD_EIM_A22__GPIO2_IO16, + MX6_PAD_EIM_A23__GPIO6_IO06, + MX6_PAD_EIM_A24__GPIO5_IO04, + MX6_PAD_EIM_D31__GPIO3_IO31, + MX6_PAD_EIM_D27__GPIO3_IO27, + MX6_PAD_EIM_DA1__GPIO3_IO01, + MX6_PAD_EIM_EB1__GPIO2_IO29, + MX6_PAD_EIM_DA2__GPIO3_IO02, + MX6_PAD_EIM_DA4__GPIO3_IO04, + MX6_PAD_EIM_DA5__GPIO3_IO05, + MX6_PAD_EIM_DA6__GPIO3_IO06, +}; +#endif + #ifdef CONFIG_FSL_ESDHC struct fsl_esdhc_cfg usdhc_cfg[3] = { {USDHC2_BASE_ADDR}, @@ -404,6 +459,178 @@ int board_phy_config(struct phy_device *phydev) return 0; } +#if defined(CONFIG_MX6DL) && defined(CONFIG_MXC_EPDC) +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__GPIO2_IO21 | + MUX_PAD_CTRL(EPDC_PAD_CTRL)); + /* Set as input */ + gpio_request(IMX_GPIO_NR(2, 21), "EPDC PWRSTAT"); + gpio_direction_input(IMX_GPIO_NR(2, 21)); + + /* EIM_D17 - GPIO3[17] for VCOM control */ + imx_iomux_v3_setup_pad(MX6_PAD_EIM_D17__GPIO3_IO17 | + MUX_PAD_CTRL(EPDC_PAD_CTRL)); + + /* Set as output */ + gpio_request(IMX_GPIO_NR(3, 17), "EPDC VCOM0"); + 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__GPIO3_IO20 | + MUX_PAD_CTRL(EPDC_PAD_CTRL)); + /* Set as output */ + gpio_request(IMX_GPIO_NR(3, 20), "EPDC PWR WAKEUP"); + 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__GPIO2_IO20 | + MUX_PAD_CTRL(EPDC_PAD_CTRL)); + /* Set as output */ + gpio_request(IMX_GPIO_NR(2, 20), "EPDC PWR CTRL0"); + gpio_direction_output(IMX_GPIO_NR(2, 20), 1); +} + +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; + struct mxc_ccm_reg *ccm_regs = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + + /*** Set pixel clock rates for EPDC ***/ + + /* EPDC AXI clk (IPU2_CLK) from PFD_400M, set to 396/2 = 198MHz */ + reg = readl(&ccm_regs->cscdr3); + reg &= ~0x7C000; + reg |= (1 << 16) | (1 << 14); + writel(reg, &ccm_regs->cscdr3); + + /* EPDC AXI clk enable */ + reg = readl(&ccm_regs->CCGR3); + reg |= 0x00C0; + writel(reg, &ccm_regs->CCGR3); + + /* EPDC PIX clk (IPU2_DI1_CLK) from PLL5, set to 650/4/6 = ~27MHz */ + reg = readl(&ccm_regs->cscdr2); + reg &= ~0x3FE00; + reg |= (2 << 15) | (5 << 12); + writel(reg, &ccm_regs->cscdr2); + + /* PLL5 enable (defaults to 650) */ + reg = readl(&ccm_regs->analog_pll_video); + reg &= ~((1 << 16) | (1 << 12)); + reg |= (1 << 13); + writel(reg, &ccm_regs->analog_pll_video); + + /* EPDC PIX clk enable */ + reg = readl(&ccm_regs->CCGR3); + reg |= 0x0C00; + writel(reg, &ccm_regs->CCGR3); + + 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(); +} + +void epdc_power_on(void) +{ + unsigned int reg; + struct gpio_regs *gpio_regs = (struct gpio_regs *)GPIO2_BASE_ADDR; + + /* 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(&gpio_regs->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 + #if defined(CONFIG_VIDEO_IPUV3) static void disable_lvds(struct display_info_t const *dev) { @@ -653,6 +880,10 @@ int board_init(void) setup_pcie(); #endif +#if defined(CONFIG_MX6DL) && defined(CONFIG_MXC_EPDC) + setup_epdc(); +#endif + return 0; } -- cgit v1.1