From 9d4d5a221f756a7280f3cc87373ac89ced7674b5 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Tue, 3 Apr 2018 01:53:04 -0700 Subject: [PATCH] MLK-18153-2 mx6slevk: Update board codes to align with v2020.04 Porting functions from v2020.04 in board level codes: 1. Add EPDC support 2. Update environment settings 3. Add LDO bypass and update PMIC settings 4. Add keypad support 5. Add plugin support 6. Add DM ethernet driver support Signed-off-by: Ye Li (cherry picked from commit 88232c1cbf9389e82f8e00c1cc3fcd6456292ed4) (cherry picked from commit 7dc7c5ebc16c5bf2f97d0d172f241615a98b55e0) --- board/freescale/mx6slevk/Kconfig | 2 + board/freescale/mx6slevk/imximage.cfg | 13 +- board/freescale/mx6slevk/mx6slevk.c | 591 +++++++++++++++++++++++++- board/freescale/mx6slevk/plugin.S | 189 ++++++++ include/configs/mx6slevk.h | 58 ++- 5 files changed, 819 insertions(+), 34 deletions(-) create mode 100644 board/freescale/mx6slevk/plugin.S diff --git a/board/freescale/mx6slevk/Kconfig b/board/freescale/mx6slevk/Kconfig index 18482b551e..42a2debf19 100644 --- a/board/freescale/mx6slevk/Kconfig +++ b/board/freescale/mx6slevk/Kconfig @@ -9,4 +9,6 @@ config SYS_VENDOR config SYS_CONFIG_NAME default "mx6slevk" +config SYS_TEXT_BASE + default 0x87800000 endif diff --git a/board/freescale/mx6slevk/imximage.cfg b/board/freescale/mx6slevk/imximage.cfg index b97761a516..9ea16ee079 100644 --- a/board/freescale/mx6slevk/imximage.cfg +++ b/board/freescale/mx6slevk/imximage.cfg @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0+ */ /* - * Copyright (C) 2013 Freescale Semiconductor, Inc. + * Copyright (C) 2013-2016 Freescale Semiconductor, Inc. + * Copyright 2017-2018 NXP * * Refer doc/imx/mkimage/imximage.txt for more details about how-to configure * and create imximage boot image @@ -21,9 +22,11 @@ IMAGE_VERSION 2 BOOT_FROM sd -/* - * Secure boot support - */ +#ifdef CONFIG_USE_IMXIMG_PLUGIN +/*PLUGIN plugin-binary-file IRAM_FREE_START_ADDR*/ +PLUGIN board/freescale/mx6slevk/plugin.bin 0x00907000 +#else + #ifdef CONFIG_IMX_HAB CSF CONFIG_CSF_SIZE #endif @@ -105,6 +108,7 @@ DATA 4 0x021b0038 0x00190778 DATA 4 0x021b0008 0x00000000 DATA 4 0x021b0040 0x0000004f DATA 4 0x021b0000 0xc3110000 +DATA 4 0x021b001c 0x00008010 DATA 4 0x021b001c 0x003f8030 DATA 4 0x021b001c 0xff0a8030 DATA 4 0x021b001c 0x82018030 @@ -121,3 +125,4 @@ DATA 4 0x021b08b8 0x00000800 DATA 4 0x021b0004 0x00025564 DATA 4 0x021b0404 0x00011006 DATA 4 0x021b001c 0x00000000 +#endif diff --git a/board/freescale/mx6slevk/mx6slevk.c b/board/freescale/mx6slevk/mx6slevk.c index 2c90a35e2c..99c89f9531 100644 --- a/board/freescale/mx6slevk/mx6slevk.c +++ b/board/freescale/mx6slevk/mx6slevk.c @@ -16,10 +16,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -27,6 +29,12 @@ #include #include #include "../common/pfuze.h" +#include +#include +#if defined(CONFIG_MXC_EPDC) +#include +#include +#endif DECLARE_GLOBAL_DATA_PTR; @@ -42,11 +50,22 @@ DECLARE_GLOBAL_DATA_PTR; PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ PAD_CTL_DSE_40ohm | PAD_CTL_HYS) +#define I2C_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ + PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ + PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \ + PAD_CTL_ODE | PAD_CTL_SRE_FAST) + #define OTGID_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_LOW |\ PAD_CTL_DSE_80ohm | PAD_CTL_HYS | \ PAD_CTL_SRE_FAST) +#define ELAN_INTR_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ + PAD_CTL_PUS_47K_UP | PAD_CTL_HYS) + +#define EPDC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_SPEED_MED | \ + PAD_CTL_DSE_40ohm | PAD_CTL_HYS) + #define ETH_PHY_POWER IMX_GPIO_NR(4, 21) int dram_init(void) @@ -56,6 +75,19 @@ int dram_init(void) return 0; } +phys_size_t get_effective_memsize(void) +{ + return SZ_512M; +} + +int dram_init_banksize(void) +{ + gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; + gd->bd->bi_dram[0].size = gd->ram_size; + + return 0; +} + static iomux_v3_cfg_t const uart1_pads[] = { MX6_PAD_UART1_TXD__UART1_TXD | MUX_PAD_CTRL(UART_PAD_CTRL), MX6_PAD_UART1_RXD__UART1_RXD | MUX_PAD_CTRL(UART_PAD_CTRL), @@ -104,6 +136,60 @@ static iomux_v3_cfg_t const usdhc3_pads[] = { }; #endif +static iomux_v3_cfg_t const elan_pads[] = { + MX6_PAD_EPDC_PWRCTRL2__GPIO_2_9 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_EPDC_PWRCTRL3__GPIO_2_10 | MUX_PAD_CTRL(ELAN_INTR_PAD_CTRL), + MX6_PAD_KEY_COL6__GPIO_4_4 | MUX_PAD_CTRL(EPDC_PAD_CTRL), +}; + +#ifdef CONFIG_MXC_EPDC +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, +}; +#endif + static void setup_iomux_uart(void) { imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads)); @@ -114,50 +200,204 @@ int board_mmc_get_env_dev(int devno) return devno; } -#ifdef CONFIG_DM_PMIC_PFUZE100 +#ifdef CONFIG_SYS_I2C +#define PC MUX_PAD_CTRL(I2C_PAD_CTRL) +/* I2C1 for PMIC */ +struct i2c_pads_info i2c_pad_info1 = { + .sda = { + .i2c_mode = MX6_PAD_I2C1_SDA__I2C1_SDA | PC, + .gpio_mode = MX6_PAD_I2C1_SDA__GPIO_3_13 | PC, + .gp = IMX_GPIO_NR(3, 13), + }, + .scl = { + .i2c_mode = MX6_PAD_I2C1_SCL__I2C1_SCL | PC, + .gpio_mode = MX6_PAD_I2C1_SCL__GPIO_3_12 | PC, + .gp = IMX_GPIO_NR(3, 12), + }, +}; +#endif + +#ifdef CONFIG_POWER int power_init_board(void) { - struct udevice *dev; + struct pmic *pfuze; + unsigned int reg; int ret; - u32 dev_id, rev_id, i; - u32 switch_num = 6; - u32 offset = PFUZE100_SW1CMODE; - ret = pmic_get("pfuze100@08", &dev); - if (ret == -ENODEV) - return 0; + pfuze = pfuze_common_init(I2C_PMIC); + if (!pfuze) + return -ENODEV; - if (ret != 0) + ret = pfuze_mode_init(pfuze, APS_PFM); + if (ret < 0) return ret; - dev_id = pmic_reg_read(dev, PFUZE100_DEVICEID); - rev_id = pmic_reg_read(dev, PFUZE100_REVID); - printf("PMIC: PFUZE100! DEV_ID=0x%x REV_ID=0x%x\n", dev_id, rev_id); - /* set SW1AB staby volatage 0.975V */ - pmic_clrsetbits(dev, PFUZE100_SW1ABSTBY, 0x3f, 0x1b); + pmic_reg_read(pfuze, PFUZE100_SW1ABSTBY, ®); + reg &= ~0x3f; + reg |= 0x1b; + pmic_reg_write(pfuze, PFUZE100_SW1ABSTBY, reg); /* set SW1AB/VDDARM step ramp up time from 16us to 4us/25mV */ - pmic_clrsetbits(dev, PFUZE100_SW1ABCONF, 0xc0, 0x40); + pmic_reg_read(pfuze, PFUZE100_SW1ABCONF, ®); + reg &= ~0xc0; + reg |= 0x40; + pmic_reg_write(pfuze, PFUZE100_SW1ABCONF, reg); /* set SW1C staby volatage 0.975V */ - pmic_clrsetbits(dev, PFUZE100_SW1CSTBY, 0x3f, 0x1b); + pmic_reg_read(pfuze, PFUZE100_SW1CSTBY, ®); + reg &= ~0x3f; + reg |= 0x1b; + pmic_reg_write(pfuze, PFUZE100_SW1CSTBY, reg); /* set SW1C/VDDSOC step ramp up time to from 16us to 4us/25mV */ - pmic_clrsetbits(dev, PFUZE100_SW1CCONF, 0xc0, 0x40); + pmic_reg_read(pfuze, PFUZE100_SW1CCONF, ®); + reg &= ~0xc0; + reg |= 0x40; + pmic_reg_write(pfuze, PFUZE100_SW1CCONF, reg); - /* Init mode to APS_PFM */ - pmic_reg_write(dev, PFUZE100_SW1ABMODE, APS_PFM); + return 0; +} +#elif defined(CONFIG_DM_PMIC_PFUZE100) +int power_init_board(void) +{ + struct udevice *dev; + unsigned int reg; + int ret; + + dev = pfuze_common_init(); + if (!dev) + return -ENODEV; + + ret = pfuze_mode_init(dev, APS_PFM); + if (ret < 0) + return ret; + + /* set SW1AB staby volatage 0.975V*/ + reg = pmic_reg_read(dev, PFUZE100_SW1ABSTBY); + reg &= ~0x3f; + reg |= 0x1b; + pmic_reg_write(dev, PFUZE100_SW1ABSTBY, reg); - for (i = 0; i < switch_num - 1; i++) - pmic_reg_write(dev, offset + i * SWITCH_SIZE, APS_PFM); + /* set SW1AB/VDDARM step ramp up time from 16us to 4us/25mV */ + reg = pmic_reg_read(dev, PFUZE100_SW1ABCONF); + reg &= ~0xc0; + reg |= 0x40; + pmic_reg_write(dev, PFUZE100_SW1ABCONF, reg); + + /* set SW1C staby volatage 0.975V*/ + reg = pmic_reg_read(dev, PFUZE100_SW1CSTBY); + reg &= ~0x3f; + reg |= 0x1b; + pmic_reg_write(dev, PFUZE100_SW1CSTBY, reg); + + /* set SW1C/VDDSOC step ramp up time to from 16us to 4us/25mV */ + reg = pmic_reg_read(dev, PFUZE100_SW1CCONF); + reg &= ~0xc0; + reg |= 0x40; + pmic_reg_write(dev, PFUZE100_SW1CCONF, reg); return 0; } #endif -#ifdef CONFIG_FEC_MXC +#ifdef CONFIG_LDO_BYPASS_CHECK +#ifdef CONFIG_POWER +void ldo_mode_set(int ldo_bypass) +{ + u32 value; + int is_400M; + struct pmic *p = pmic_get("PFUZE100"); + + if (!p) { + printf("No pmic!\n"); + return; + } + + /* swith to ldo_bypass mode */ + if (ldo_bypass) { + prep_anatop_bypass(); + + /* decrease VDDARM to 1.1V */ + pmic_reg_read(p, PFUZE100_SW1ABVOL, &value); + value &= ~0x3f; + value |= 0x20; + pmic_reg_write(p, PFUZE100_SW1ABVOL, value); + + /* increase VDDSOC to 1.3V */ + pmic_reg_read(p, PFUZE100_SW1CVOL, &value); + value &= ~0x3f; + value |= 0x28; + pmic_reg_write(p, PFUZE100_SW1CVOL, value); + + is_400M = set_anatop_bypass(0); + + /* + * MX6SL: VDDARM:1.175V@800M; VDDSOC:1.175V@800M + * VDDARM:0.975V@400M; VDDSOC:1.175V@400M + */ + pmic_reg_read(p, PFUZE100_SW1ABVOL, &value); + value &= ~0x3f; + if (is_400M) + value |= 0x1b; + else + value |= 0x23; + pmic_reg_write(p, PFUZE100_SW1ABVOL, value); + + /* decrease VDDSOC to 1.175V */ + pmic_reg_read(p, PFUZE100_SW1CVOL, &value); + value &= ~0x3f; + value |= 0x23; + pmic_reg_write(p, PFUZE100_SW1CVOL, value); + + finish_anatop_bypass(); + printf("switch to ldo_bypass mode!\n"); + } +} +#elif defined(CONFIG_DM_PMIC_PFUZE100) +void ldo_mode_set(int ldo_bypass) +{ + struct udevice *dev; + int ret; + int is_400M; + u32 vddarm; + ret = pmic_get("pfuze100@8", &dev); + if (ret == -ENODEV) { + printf("No PMIC found!\n"); + return; + } + + /* switch to ldo_bypass mode , boot on 800Mhz */ + if (ldo_bypass) { + prep_anatop_bypass(); + + /* decrease VDDARM for 400Mhz DQ:1.1V, DL:1.275V */ + pmic_clrsetbits(dev, PFUZE100_SW1ABVOL, 0x3f, 0x20); + + /* increase VDDSOC to 1.3V */ + pmic_clrsetbits(dev, PFUZE100_SW1CVOL, 0x3f, 0x28); + + is_400M = set_anatop_bypass(0); + if (is_400M) + vddarm = 0x1b; + else + vddarm = 0x23; + + pmic_clrsetbits(dev, PFUZE100_SW1ABVOL, 0x3f, vddarm); + + /* decrease VDDSOC to 1.175V */ + pmic_clrsetbits(dev, PFUZE100_SW1CVOL, 0x3f, 0x23); + + finish_anatop_bypass(); + printf("switch to ldo_bypass mode!\n"); + } +} +#endif + +#endif + +#ifdef CONFIG_FEC_MXC static int setup_fec(void) { struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR; @@ -169,6 +409,52 @@ static int setup_fec(void) } #endif +#ifdef CONFIG_USB_EHCI_MX6 +#ifndef CONFIG_DM_USB + +#define USB_OTHERREGS_OFFSET 0x800 +#define UCTRL_PWR_POL (1 << 9) + +static iomux_v3_cfg_t const usb_otg_pads[] = { + /* OTG1 */ + MX6_PAD_KEY_COL4__USB_USBOTG1_PWR | MUX_PAD_CTRL(NO_PAD_CTRL), + MX6_PAD_EPDC_PWRCOM__ANATOP_USBOTG1_ID | MUX_PAD_CTRL(OTGID_PAD_CTRL), + /* OTG2 */ + MX6_PAD_KEY_COL5__USB_USBOTG2_PWR | MUX_PAD_CTRL(NO_PAD_CTRL) +}; + +static void setup_usb(void) +{ + imx_iomux_v3_setup_multiple_pads(usb_otg_pads, + ARRAY_SIZE(usb_otg_pads)); +} + +int board_usb_phy_mode(int port) +{ + if (port == 1) + return USB_INIT_HOST; + else + return usb_phy_mode(port); +} + +int board_ehci_hcd_init(int port) +{ + u32 *usbnc_usb_ctrl; + + if (port > 1) + return -EINVAL; + + usbnc_usb_ctrl = (u32 *)(USB_BASE_ADDR + USB_OTHERREGS_OFFSET + + port * 4); + + /* Set Power polarity */ + setbits_le32(usbnc_usb_ctrl, UCTRL_PWR_POL); + + return 0; +} +#endif +#endif + int board_early_init_f(void) { setup_iomux_uart(); @@ -176,15 +462,252 @@ int board_early_init_f(void) return 0; } +#ifdef CONFIG_MXC_EPDC +vidinfo_t panel_info = { + .vl_refresh = 85, + .vl_col = 800, + .vl_row = 600, + .vl_rot = 0, + .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_request(IMX_GPIO_NR(2, 13), "EPDC PWRSTAT"); + 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_request(IMX_GPIO_NR(2, 3), "EPDC VCOM0"); + 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_request(IMX_GPIO_NR(2, 14), "EPDC PWR WAKEUP"); + 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_request(IMX_GPIO_NR(2, 7), "EPDC PWRCTRL0"); + gpio_direction_output(IMX_GPIO_NR(2, 7), 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 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; + struct mxc_ccm_reg *ccm_regs = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + + /*** Set pixel clock rates for EPDC ***/ + + /* EPDC AXI clk from PFD_400M, set to 396/2 = 198MHz */ + reg = readl(&ccm_regs->chsccdr); + reg &= ~0x3F000; + reg |= (0x4 << 15) | (1 << 12); + writel(reg, &ccm_regs->chsccdr); + + /* EPDC AXI clk enable */ + reg = readl(&ccm_regs->CCGR3); + reg |= 0x0030; + writel(reg, &ccm_regs->CCGR3); + + /* EPDC PIX clk from PFD_540M, set to 540/4/5 = 27MHz */ + reg = readl(&ccm_regs->cscdr2); + reg &= ~0x03F000; + reg |= (0x5 << 15) | (4 << 12); + writel(reg, &ccm_regs->cscdr2); + + reg = readl(&ccm_regs->cbcmr); + reg &= ~0x03800000; + reg |= (0x3 << 23); + writel(reg, &ccm_regs->cbcmr); + + /* 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, 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(&gpio_regs->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 + +void setup_elan_pads(void) +{ +#define TOUCH_CS IMX_GPIO_NR(2, 9) +#define TOUCH_INT IMX_GPIO_NR(2, 10) +#define TOUCH_RST IMX_GPIO_NR(4, 4) + imx_iomux_v3_setup_multiple_pads(elan_pads, ARRAY_SIZE(elan_pads)); + gpio_request(TOUCH_CS, "TOUCH CS"); + gpio_request(TOUCH_INT, "TOUCH Interrupt"); + gpio_request(TOUCH_RST, "TOUCH Reset"); +} + int board_init(void) { /* address of boot parameters */ gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; +#ifdef CONFIG_SYS_I2C + setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1); +#endif + + setup_elan_pads(); + #ifdef CONFIG_FEC_MXC setup_fec(); #endif +#ifdef CONFIG_MXC_EPDC + setup_epdc(); +#endif + +#ifdef CONFIG_USB_EHCI_MX6 +#ifndef CONFIG_DM_USB + setup_usb(); +#endif +#endif + + return 0; +} + +void elan_init(void) +{ + gpio_direction_input(TOUCH_INT); + /* + * If epdc panel not plugged in, gpio_get_value(TOUCH_INT) will + * return 1. And no need to mdelay, which will make i2c operation + * slow. + * If epdc panel plugged in, gpio_get_value(TOUCH_INT) will + * return 0. And elan init flow will be executed. + */ + if (gpio_get_value(TOUCH_INT)) + return; + gpio_direction_output(TOUCH_CS , 1); + gpio_set_value(TOUCH_CS, 0); + gpio_direction_output(TOUCH_RST , 1); + gpio_set_value(TOUCH_RST, 0); + mdelay(10); + gpio_set_value(TOUCH_RST, 1); + gpio_set_value(TOUCH_CS, 1); + mdelay(100); +} + +/* + * This function overwrite the function defined in + * drivers/i2c/mxc_i2c.c, which is a weak symbol + */ +void i2c_force_reset_slave(void) +{ + elan_init(); +} + +int board_late_init(void) +{ +#ifdef CONFIG_ENV_IS_IN_MMC + board_late_mmc_env_init(); +#endif return 0; } @@ -195,6 +718,30 @@ int checkboard(void) return 0; } +#ifdef CONFIG_MXC_KPD +#define MX6SL_KEYPAD_CTRL (PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_PUE | \ + PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_120ohm) + +iomux_v3_cfg_t const mxc_kpd_pads[] = { + (MX6_PAD_KEY_COL0__KPP_COL_0 | MUX_PAD_CTRL(NO_PAD_CTRL)), + (MX6_PAD_KEY_COL1__KPP_COL_1 | MUX_PAD_CTRL(NO_PAD_CTRL)), + (MX6_PAD_KEY_COL2__KPP_COL_2 | MUX_PAD_CTRL(NO_PAD_CTRL)), + (MX6_PAD_KEY_COL3__KPP_COL_3 | MUX_PAD_CTRL(NO_PAD_CTRL)), + + (MX6_PAD_KEY_ROW0__KPP_ROW_0 | MUX_PAD_CTRL(MX6SL_KEYPAD_CTRL)), + (MX6_PAD_KEY_ROW1__KPP_ROW_1 | MUX_PAD_CTRL(MX6SL_KEYPAD_CTRL)), + (MX6_PAD_KEY_ROW2__KPP_ROW_2 | MUX_PAD_CTRL(MX6SL_KEYPAD_CTRL)), + (MX6_PAD_KEY_ROW3__KPP_ROW_3 | MUX_PAD_CTRL(MX6SL_KEYPAD_CTRL)), +}; +int setup_mxc_kpd(void) +{ + imx_iomux_v3_setup_multiple_pads(mxc_kpd_pads, + ARRAY_SIZE(mxc_kpd_pads)); + + return 0; +} +#endif /*CONFIG_MXC_KPD*/ + #ifdef CONFIG_SPL_BUILD #include #include diff --git a/board/freescale/mx6slevk/plugin.S b/board/freescale/mx6slevk/plugin.S new file mode 100644 index 0000000000..e23146d74a --- /dev/null +++ b/board/freescale/mx6slevk/plugin.S @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2014-2016 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include + +/* DDR script */ +.macro imx6slevk_ddr_setting + ldr r0, =CCM_BASE_ADDR + ldr r1, =0x00260324 + str r1, [r0, #0x018] + + ldr r0, =IOMUXC_BASE_ADDR + ldr r1, =0x00020000 + str r1, [r0, #0x5c0] + ldr r1, =0x00000000 + str r1, [r0, #0x5b4] + + ldr r1, =0x00000028 + str r1, [r0, #0x338] + + ldr r1, =0x00000030 + str r1, [r0, #0x300] + str r1, [r0, #0x31c] + str r1, [r0, #0x320] + + ldr r1, =0x00000000 + str r1, [r0, #0x32c] + + ldr r1, =0x00000030 + str r1, [r0, #0x5ac] + str r1, [r0, #0x5c8] + + ldr r1, =0x00020000 + str r1, [r0, #0x5b0] + + ldr r1, =0x00003030 + str r1, [r0, #0x344] + str r1, [r0, #0x348] + str r1, [r0, #0x34c] + str r1, [r0, #0x350] + + ldr r1, =0x00080000 + str r1, [r0, #0x5d0] + + ldr r1, =0x00000030 + str r1, [r0, #0x5c4] + str r1, [r0, #0x5cc] + str r1, [r0, #0x5d4] + str r1, [r0, #0x5d8] + + str r1, [r0, #0x30c] + str r1, [r0, #0x310] + str r1, [r0, #0x314] + str r1, [r0, #0x318] + + ldr r0, =MMDC_P0_BASE_ADDR + ldr r2, =0x00008000 + str r2, [r0, #0x01c] + + ldr r2, =0x1b4700c7 + str r2, [r0, #0x85c] + + ldr r2, =0xa1390003 + str r2, [r0, #0x800] + + ldr r2, =0x00300000 + str r2, [r0, #0x890] + + ldr r2, =0x00000800 + str r2, [r0, #0x8b8] + + ldr r2, =0x33333333 + str r2, [r0, #0x81c] + str r2, [r0, #0x820] + str r2, [r0, #0x824] + str r2, [r0, #0x828] + str r2, [r0, #0x82c] + str r2, [r0, #0x830] + str r2, [r0, #0x834] + str r2, [r0, #0x838] + + ldr r2, =0x4241444a + str r2, [r0, #0x848] + + ldr r2, =0x3030312b + str r2, [r0, #0x850] + + ldr r2, =0x20000000 + str r2, [r0, #0x83c] + + ldr r2, =0x00000000 + str r2, [r0, #0x840] + + ldr r2, =0x00000800 + str r2, [r0, #0x8b8] + + ldr r2, =0x33374133 + str r2, [r0, #0x00c] + + ldr r2, =0x00020024 + str r2, [r0, #0x004] + + ldr r2, =0x00100A82 + str r2, [r0, #0x010] + ldr r2, =0x00000093 + str r2, [r0, #0x014] + ldr r2, =0x00001688 + str r2, [r0, #0x018] + ldr r2, =0x0F9F26D2 + str r2, [r0, #0x02c] + + ldr r2, =0x0000020E + str r2, [r0, #0x030] + ldr r2, =0x00190778 + str r2, [r0, #0x038] + ldr r2, =0x00000000 + str r2, [r0, #0x008] + ldr r2, =0x0000004F + str r2, [r0, #0x040] + ldr r2, =0xC3110000 + str r2, [r0, #0x000] + + ldr r2, =0x00008010 + str r2, [r0, #0x01c] + ldr r2, =0x003F8030 + str r2, [r0, #0x01c] + ldr r2, =0xFF0A8030 + str r2, [r0, #0x01c] + ldr r2, =0x82018030 + str r2, [r0, #0x01c] + ldr r2, =0x04028030 + str r2, [r0, #0x01c] + ldr r2, =0x02038030 + str r2, [r0, #0x01c] + ldr r2, =0xFF0A8038 + str r2, [r0, #0x01c] + ldr r2, =0x82018038 + str r2, [r0, #0x01c] + ldr r2, =0x04028038 + str r2, [r0, #0x01c] + ldr r2, =0x02038038 + str r2, [r0, #0x01c] + + ldr r2, =0xa1310003 + str r2, [r0, #0x800] + + ldr r2, =0x00001800 + str r2, [r0, #0x020] + + ldr r2, =0x00000000 + str r2, [r0, #0x818] + + ldr r2, =0x00000800 + str r2, [r0, #0x8b8] + + ldr r2, =0x00025564 + str r2, [r0, #0x004] + + ldr r2, =0x00011006 + str r2, [r0, #0x404] + + ldr r2, =0x00000000 + str r2, [r0, #0x01c] +.endm +.macro imx6_clock_gating + ldr r0, =CCM_BASE_ADDR + ldr r1, =0xffffffff + str r1, [r0, #0x068] + str r1, [r0, #0x06c] + str r1, [r0, #0x070] + str r1, [r0, #0x074] + str r1, [r0, #0x078] + str r1, [r0, #0x07c] + str r1, [r0, #0x080] + str r1, [r0, #0x084] +.endm + +.macro imx6_qos_setting +.endm + +.macro imx6_ddr_setting + imx6slevk_ddr_setting +.endm + +/* include the common plugin code here */ +#include diff --git a/include/configs/mx6slevk.h b/include/configs/mx6slevk.h index ab32f4e151..7fe98b6f83 100644 --- a/include/configs/mx6slevk.h +++ b/include/configs/mx6slevk.h @@ -17,7 +17,7 @@ #define CONFIG_MACH_TYPE MACH_TYPE_MX6SL_EVK /* Size of malloc() pool */ -#define CONFIG_SYS_MALLOC_LEN (3 * SZ_1M) +#define CONFIG_SYS_MALLOC_LEN (16 * SZ_1M) #define CONFIG_MXC_UART_BASE UART1_IPS_BASE_ADDR @@ -25,27 +25,58 @@ #define CONFIG_SYS_FSL_ESDHC_ADDR USDHC2_BASE_ADDR /* I2C Configs */ +#ifndef CONFIG_DM_I2C +#define CONFIG_SYS_I2C +#endif +#ifdef CONFIG_CMD_I2C #define CONFIG_SYS_I2C_MXC #define CONFIG_SYS_I2C_MXC_I2C1 /* enable I2C bus 1 */ #define CONFIG_SYS_I2C_MXC_I2C2 /* enable I2C bus 2 */ #define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */ #define CONFIG_SYS_I2C_SPEED 100000 +#endif + +/* PMIC */ +#ifndef CONFIG_DM_PMIC +#define CONFIG_POWER +#define CONFIG_POWER_I2C +#define CONFIG_POWER_PFUZE100 +#define CONFIG_POWER_PFUZE100_I2C_ADDR 0x08 +#endif + +#define CONFIG_FEC_XCV_TYPE RMII +#define CONFIG_ETHPRIME "eth0" + +#define CONFIG_MFG_ENV_SETTINGS \ + "mfgtool_args=setenv bootargs console=${console},${baudrate} " \ + "rdinit=/linuxrc " \ + "g_mass_storage.stall=0 g_mass_storage.removable=1 " \ + "g_mass_storage.file=/fat g_mass_storage.ro=1 " \ + "g_mass_storage.idVendor=0x066F g_mass_storage.idProduct=0x37FF "\ + "g_mass_storage.iSerialNumber=\"\" "\ + "\0" \ + "initrd_addr=0x83800000\0" \ + "initrd_high=0xffffffff\0" \ + "bootcmd_mfg=run mfgtool_args;bootz ${loadaddr} ${initrd_addr} ${fdt_addr};\0" \ #define CONFIG_EXTRA_ENV_SETTINGS \ + CONFIG_MFG_ENV_SETTINGS \ + "epdc_waveform=epdc_splash.bin\0" \ "script=boot.scr\0" \ "image=zImage\0" \ "console=ttymxc0\0" \ "fdt_high=0xffffffff\0" \ "initrd_high=0xffffffff\0" \ "fdt_file=imx6sl-evk.dtb\0" \ - "fdt_addr=0x88000000\0" \ + "fdt_addr=0x83000000\0" \ "boot_fdt=try\0" \ "ip_dyn=yes\0" \ - "mmcdev=1\0" \ + "mmcdev="__stringify(CONFIG_SYS_MMC_ENV_DEV)"\0" \ "mmcpart=1\0" \ - "finduuid=part uuid mmc 1:2 uuid\0" \ + "mmcroot=" CONFIG_MMCROOT " rootwait rw\0" \ + "mmcautodetect=yes\0" \ "mmcargs=setenv bootargs console=${console},${baudrate} " \ - "root=PARTUUID=${uuid} rootwait rw\0" \ + "root=${mmcroot}\0" \ "loadbootscript=" \ "fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};\0" \ "bootscript=echo Running bootscript from mmc ...; " \ @@ -53,7 +84,6 @@ "loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}\0" \ "loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}\0" \ "mmcboot=echo Booting from mmc ...; " \ - "run finduuid; " \ "run mmcargs; " \ "if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \ "if run loadfdt; then " \ @@ -120,8 +150,6 @@ #define CONFIG_SYS_INIT_SP_ADDR \ (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET) -/* Environment organization */ - /* USB Configs */ #ifdef CONFIG_CMD_USB #define CONFIG_EHCI_HCD_INIT_AFTER_RESET @@ -130,6 +158,20 @@ #define CONFIG_USB_MAX_CONTROLLER_COUNT 2 #endif +#define CONFIG_MMCROOT "/dev/mmcblk1p2" /* USDHC2 */ #define CONFIG_SYS_FSL_USDHC_NUM 3 +/* + * SPLASH SCREEN Configs + */ +#ifdef CONFIG_MXC_EPDC + /* + * Framebuffer and LCD + */ + #undef LCD_TEST_PATTERN + #define LCD_BPP LCD_MONOCHROME + + #define CONFIG_WAVEFORM_BUF_SIZE 0x400000 +#endif /* CONFIG_SPLASH_SCREEN */ + #endif /* __CONFIG_H */ -- 2.17.1