/* * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ #include #include #include #include #if defined(CONFIG_SECURE_BOOT) #include #endif #include #include #include #ifdef CONFIG_MXC_FEC #include #endif #if defined(CONFIG_VIDEO_MX5) #include #include #include #include #endif #if defined(CONFIG_VIDEO_MX5) || defined(CONFIG_MXC_EPDC) #include #endif #include "../../../drivers/video/mxc_epdc_fb.h" #ifdef CONFIG_IMX_ECSPI #include #endif #if CONFIG_I2C_MXC #include #endif #ifdef CONFIG_CMD_MMC #include #include #endif #ifdef CONFIG_ARCH_MMU #include #include #endif #ifdef CONFIG_CMD_CLOCK #include #endif #ifdef CONFIG_MXC_GPIO #include #include #endif #ifdef CONFIG_DWC_AHSATA #include #endif DECLARE_GLOBAL_DATA_PTR; static u32 system_rev; static enum boot_device boot_dev; extern int sata_curr_device; #ifdef CONFIG_VIDEO_MX5 extern unsigned char fsl_bmp_600x400[]; extern int fsl_bmp_600x400_size; extern int g_ipu_hw_rev; #if defined(CONFIG_BMP_8BPP) unsigned short colormap[256]; #elif defined(CONFIG_BMP_16BPP) unsigned short colormap[65536]; #else unsigned short colormap[16777216]; #endif static int di = 1; extern int ipuv3_fb_init(struct fb_videomode *mode, int di, int interface_pix_fmt, ipu_di_clk_parent_t di_clk_parent, int di_clk_val); static struct fb_videomode lvds_xga = { "XGA", 60, 1024, 768, 15385, 220, 40, 21, 7, 60, 10, FB_SYNC_EXT, FB_VMODE_NONINTERLACED, 0, }; vidinfo_t panel_info; #endif static inline void setup_boot_device(void) { uint soc_sbmr = readl(SRC_BASE_ADDR + 0x4); uint bt_mem_ctl = (soc_sbmr & 0x000000FF) >> 4 ; uint bt_mem_type = (soc_sbmr & 0x00000008) >> 3; switch (bt_mem_ctl) { case 0x0: if (bt_mem_type) boot_dev = ONE_NAND_BOOT; else boot_dev = WEIM_NOR_BOOT; break; case 0x2: boot_dev = SATA_BOOT; break; case 0x3: if (bt_mem_type) boot_dev = I2C_BOOT; else boot_dev = SPI_NOR_BOOT; break; case 0x4: case 0x5: boot_dev = SD_BOOT; break; case 0x6: case 0x7: boot_dev = MMC_BOOT; break; case 0x8 ... 0xf: boot_dev = NAND_BOOT; break; default: boot_dev = UNKNOWN_BOOT; break; } } enum boot_device get_boot_device(void) { return boot_dev; } u32 get_board_rev(void) { return fsl_system_rev; } #ifdef CONFIG_ARCH_MMU void board_mmu_init(void) { unsigned long ttb_base = PHYS_SDRAM_1 + 0x4000; unsigned long i; /* * Set the TTB register */ asm volatile ("mcr p15,0,%0,c2,c0,0" : : "r"(ttb_base) /*:*/); /* * Set the Domain Access Control Register */ i = ARM_ACCESS_DACR_DEFAULT; asm volatile ("mcr p15,0,%0,c3,c0,0" : : "r"(i) /*:*/); /* * First clear all TT entries - ie Set them to Faulting */ memset((void *)ttb_base, 0, ARM_FIRST_LEVEL_PAGE_TABLE_SIZE); /* Actual Virtual Size Attributes Function */ /* Base Base MB cached? buffered? access permissions */ /* xxx00000 xxx00000 */ X_ARM_MMU_SECTION(0x000, 0x000, 0x001, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* ROM, 1M */ X_ARM_MMU_SECTION(0x001, 0x001, 0x008, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* 8M */ X_ARM_MMU_SECTION(0x009, 0x009, 0x001, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* IRAM */ X_ARM_MMU_SECTION(0x00A, 0x00A, 0x0F6, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* 246M */ #ifndef CONFIG_MX6Q_ARM2_LPDDR2POP /* 2 GB memory starting at 0x10000000, only map 1.875 GB */ X_ARM_MMU_SECTION(0x100, 0x100, 0x780, ARM_CACHEABLE, ARM_BUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* uncached alias of the same 1.875 GB memory */ X_ARM_MMU_SECTION(0x100, 0x880, 0x780, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); #else /* * Phys Virtual Size Property * ---------- ---------- -------- ---------- * 0x10000000 0x10000000 256M cacheable * 0x80000000 0x20000000 16M uncacheable * 0x81000000 0x21000000 240M cacheable */ /* Reserve the first 256MB of bank 1 as cacheable memory */ X_ARM_MMU_SECTION(0x100, 0x100, 0x100, ARM_CACHEABLE, ARM_BUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* Reserve the first 16MB of bank 2 uncachable memory*/ X_ARM_MMU_SECTION(0x800, 0x200, 0x010, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* Reserve the remaining 240MB of bank 2 as cacheable memory */ X_ARM_MMU_SECTION(0x810, 0x210, 0x0F0, ARM_CACHEABLE, ARM_BUFFERABLE, ARM_ACCESS_PERM_RW_RW); #endif /* Enable MMU */ MMU_ON(); } #endif #define ANATOP_PLL_LOCK 0x80000000 #define ANATOP_PLL_ENABLE_MASK 0x00002000 #define ANATOP_PLL_BYPASS_MASK 0x00010000 #define ANATOP_PLL_PWDN_MASK 0x00001000 #define ANATOP_PLL_HOLD_RING_OFF_MASK 0x00000800 #define ANATOP_SATA_CLK_ENABLE_MASK 0x00100000 #ifdef CONFIG_DWC_AHSATA /* Staggered Spin-up */ #define HOST_CAP_SSS (1 << 27) /* host version register*/ #define HOST_VERSIONR 0xfc #define PORT_SATA_SR 0x128 int sata_initialize(void) { u32 reg = 0; u32 iterations = 1000000; if (sata_curr_device == -1) { /* Reset HBA */ writel(HOST_RESET, SATA_ARB_BASE_ADDR + HOST_CTL); reg = 0; while (readl(SATA_ARB_BASE_ADDR + HOST_VERSIONR) == 0) { reg++; if (reg > 1000000) break; } reg = readl(SATA_ARB_BASE_ADDR + HOST_CAP); if (!(reg & HOST_CAP_SSS)) { reg |= HOST_CAP_SSS; writel(reg, SATA_ARB_BASE_ADDR + HOST_CAP); } reg = readl(SATA_ARB_BASE_ADDR + HOST_PORTS_IMPL); if (!(reg & 0x1)) writel((reg | 0x1), SATA_ARB_BASE_ADDR + HOST_PORTS_IMPL); /* Release resources when there is no device on the port */ do { reg = readl(SATA_ARB_BASE_ADDR + PORT_SATA_SR) & 0xF; if ((reg & 0xF) == 0) iterations--; else break; } while (iterations > 0); } return __sata_initialize(); } #endif static int setup_sata(void) { u32 reg = 0; s32 timeout = 100000; /* Enable sata clock */ reg = readl(CCM_BASE_ADDR + 0x7c); /* CCGR5 */ reg |= 0x30; writel(reg, CCM_BASE_ADDR + 0x7c); /* Enable PLLs */ reg = readl(ANATOP_BASE_ADDR + 0xe0); /* ENET PLL */ reg &= ~ANATOP_PLL_PWDN_MASK; writel(reg, ANATOP_BASE_ADDR + 0xe0); reg |= ANATOP_PLL_ENABLE_MASK; while (timeout--) { if (readl(ANATOP_BASE_ADDR + 0xe0) & ANATOP_PLL_LOCK) break; } if (timeout <= 0) return -1; reg &= ~ANATOP_PLL_BYPASS_MASK; writel(reg, ANATOP_BASE_ADDR + 0xe0); reg |= ANATOP_SATA_CLK_ENABLE_MASK; writel(reg, ANATOP_BASE_ADDR + 0xe0); /* Enable sata phy */ reg = readl(IOMUXC_BASE_ADDR + 0x34); /* GPR13 */ reg &= ~0x07ffffff; /* * rx_eq_val_0 = 5 [26:24] * los_lvl = 0x12 [23:19] * rx_dpll_mode_0 = 0x3 [18:16] * mpll_ss_en = 0x0 [14] * tx_atten_0 = 0x4 [13:11] * tx_boost_0 = 0x0 [10:7] * tx_lvl = 0x11 [6:2] * mpll_ck_off_b = 0x1 [1] * tx_edgerate_0 = 0x0 [0] * */ reg |= 0x59124c6; writel(reg, IOMUXC_BASE_ADDR + 0x34); return 0; } int dram_init(void) { /* * Switch PL301_FAST2 to DDR Dual-channel mapping * however this block the boot up, temperory redraw */ /* * u32 reg = 1; * writel(reg, GPV0_BASE_ADDR); */ gd->bd->bi_dram[0].start = PHYS_SDRAM_1; gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; #if defined(CONFIG_MX6Q_ARM2_LPDDR2POP) || defined(CONFIG_MX6DL_LPDDR2) gd->bd->bi_dram[1].start = PHYS_SDRAM_2; gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE; #endif return 0; } static void setup_uart(void) { #if defined CONFIG_MX6Q /* UART4 TXD */ mxc_iomux_v3_setup_pad(MX6Q_PAD_KEY_COL0__UART4_TXD); /* UART4 RXD */ mxc_iomux_v3_setup_pad(MX6Q_PAD_KEY_ROW0__UART4_RXD); #elif defined CONFIG_MX6DL /* UART4 TXD */ mxc_iomux_v3_setup_pad(MX6DL_PAD_KEY_COL0__UART4_TXD); /* UART4 RXD */ mxc_iomux_v3_setup_pad(MX6DL_PAD_KEY_ROW0__UART4_RXD); #endif } #ifdef CONFIG_VIDEO_MX5 #ifdef CONFIG_I2C_MXC static void setup_i2c(unsigned int module_base) { unsigned int reg; switch (module_base) { case I2C1_BASE_ADDR: #if defined CONFIG_MX6Q /* i2c1 SDA */ mxc_iomux_v3_setup_pad(MX6Q_PAD_CSI0_DAT8__I2C1_SDA); /* i2c1 SCL */ mxc_iomux_v3_setup_pad(MX6Q_PAD_CSI0_DAT9__I2C1_SCL); #elif defined CONFIG_MX6DL /* i2c1 SDA */ mxc_iomux_v3_setup_pad(MX6DL_PAD_CSI0_DAT8__I2C1_SDA); /* i2c1 SCL */ mxc_iomux_v3_setup_pad(MX6DL_PAD_CSI0_DAT9__I2C1_SCL); #endif /* Enable i2c clock */ reg = readl(CCM_BASE_ADDR + CLKCTL_CCGR2); reg |= 0xC0; writel(reg, CCM_BASE_ADDR + CLKCTL_CCGR2); break; case I2C2_BASE_ADDR: #if defined CONFIG_MX6Q /* i2c2 SDA */ mxc_iomux_v3_setup_pad(MX6Q_PAD_KEY_ROW3__I2C2_SDA); /* i2c2 SCL */ mxc_iomux_v3_setup_pad(MX6Q_PAD_KEY_COL3__I2C2_SCL); #elif defined CONFIG_MX6DL /* i2c2 SDA */ mxc_iomux_v3_setup_pad(MX6DL_PAD_KEY_ROW3__I2C2_SDA); /* i2c2 SCL */ mxc_iomux_v3_setup_pad(MX6DL_PAD_KEY_COL3__I2C2_SCL); #endif /* Enable i2c clock */ reg = readl(CCM_BASE_ADDR + CLKCTL_CCGR2); reg |= 0x300; writel(reg, CCM_BASE_ADDR + CLKCTL_CCGR2); break; case I2C3_BASE_ADDR: #if defined CONFIG_MX6Q /* GPIO_5 for I2C3_SCL */ mxc_iomux_v3_setup_pad(MX6Q_PAD_GPIO_5__I2C3_SCL); /* GPIO_16 for I2C3_SDA */ mxc_iomux_v3_setup_pad(MX6Q_PAD_GPIO_16__I2C3_SDA); #elif defined CONFIG_MX6DL /* GPIO_5 for I2C3_SCL */ mxc_iomux_v3_setup_pad(MX6DL_PAD_GPIO_5__I2C3_SCL); /* GPIO_16 for I2C3_SDA */ mxc_iomux_v3_setup_pad(MX6DL_PAD_GPIO_16__I2C3_SDA); #endif /* Enable i2c clock */ reg = readl(CCM_BASE_ADDR + CLKCTL_CCGR2); reg |= 0xC00; writel(reg, CCM_BASE_ADDR + CLKCTL_CCGR2); break; default: printf("Invalid I2C base: 0x%x\n", module_base); break; } } void setup_lvds_poweron(void) { uchar value; i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); i2c_read(0x1f, 3, 1, &value, 1); value &= ~0x2; i2c_write(0x1f, 3, 1, &value, 1); i2c_read(0x1f, 1, 1, &value, 1); value |= 0x2; i2c_write(0x1f, 1, 1, &value, 1); } #endif #endif #ifdef CONFIG_IMX_ECSPI s32 spi_get_cfg(struct imx_spi_dev_t *dev) { switch (dev->slave.cs) { case 0: /* SPI-NOR */ dev->base = ECSPI1_BASE_ADDR; dev->freq = 25000000; dev->ss_pol = IMX_SPI_ACTIVE_LOW; dev->ss = 0; dev->fifo_sz = 64 * 4; dev->us_delay = 0; break; case 1: /* SPI-NOR */ dev->base = ECSPI1_BASE_ADDR; dev->freq = 25000000; dev->ss_pol = IMX_SPI_ACTIVE_LOW; dev->ss = 1; dev->fifo_sz = 64 * 4; dev->us_delay = 0; break; default: printf("Invalid Bus ID!\n"); } return 0; } void spi_io_init(struct imx_spi_dev_t *dev) { u32 reg; switch (dev->base) { case ECSPI1_BASE_ADDR: /* Enable clock */ reg = readl(CCM_BASE_ADDR + CLKCTL_CCGR1); reg |= 0x3; writel(reg, CCM_BASE_ADDR + CLKCTL_CCGR1); #if defined CONFIG_MX6Q /* SCLK */ mxc_iomux_v3_setup_pad(MX6Q_PAD_EIM_D16__ECSPI1_SCLK); /* MISO */ mxc_iomux_v3_setup_pad(MX6Q_PAD_EIM_D17__ECSPI1_MISO); /* MOSI */ mxc_iomux_v3_setup_pad(MX6Q_PAD_EIM_D18__ECSPI1_MOSI); if (dev->ss == 0) mxc_iomux_v3_setup_pad(MX6Q_PAD_EIM_EB2__ECSPI1_SS0); else if (dev->ss == 1) mxc_iomux_v3_setup_pad(MX6Q_PAD_EIM_D19__ECSPI1_SS1); #elif defined CONFIG_MX6DL /* SCLK */ mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_D16__ECSPI1_SCLK); /* MISO */ mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_D17__ECSPI1_MISO); /* MOSI */ mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_D18__ECSPI1_MOSI); if (dev->ss == 0) mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_EB2__ECSPI1_SS0); else if (dev->ss == 1) mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_D19__ECSPI1_SS1); #endif break; case ECSPI2_BASE_ADDR: case ECSPI3_BASE_ADDR: /* ecspi2-3 fall through */ break; default: break; } } #endif #ifdef CONFIG_NAND_GPMI #if defined CONFIG_MX6Q iomux_v3_cfg_t nfc_pads[] = { MX6Q_PAD_NANDF_CLE__RAWNAND_CLE, MX6Q_PAD_NANDF_ALE__RAWNAND_ALE, MX6Q_PAD_NANDF_WP_B__RAWNAND_RESETN, MX6Q_PAD_NANDF_RB0__RAWNAND_READY0, MX6Q_PAD_NANDF_CS0__RAWNAND_CE0N, MX6Q_PAD_NANDF_CS1__RAWNAND_CE1N, MX6Q_PAD_NANDF_CS2__RAWNAND_CE2N, MX6Q_PAD_NANDF_CS3__RAWNAND_CE3N, MX6Q_PAD_SD4_CMD__RAWNAND_RDN, MX6Q_PAD_SD4_CLK__RAWNAND_WRN, MX6Q_PAD_NANDF_D0__RAWNAND_D0, MX6Q_PAD_NANDF_D1__RAWNAND_D1, MX6Q_PAD_NANDF_D2__RAWNAND_D2, MX6Q_PAD_NANDF_D3__RAWNAND_D3, MX6Q_PAD_NANDF_D4__RAWNAND_D4, MX6Q_PAD_NANDF_D5__RAWNAND_D5, MX6Q_PAD_NANDF_D6__RAWNAND_D6, MX6Q_PAD_NANDF_D7__RAWNAND_D7, MX6Q_PAD_SD4_DAT0__RAWNAND_DQS, }; #elif defined CONFIG_MX6DL iomux_v3_cfg_t nfc_pads[] = { MX6DL_PAD_NANDF_CLE__RAWNAND_CLE, MX6DL_PAD_NANDF_ALE__RAWNAND_ALE, MX6DL_PAD_NANDF_WP_B__RAWNAND_RESETN, MX6DL_PAD_NANDF_RB0__RAWNAND_READY0, MX6DL_PAD_NANDF_CS0__RAWNAND_CE0N, MX6DL_PAD_NANDF_CS1__RAWNAND_CE1N, MX6DL_PAD_NANDF_CS2__RAWNAND_CE2N, MX6DL_PAD_NANDF_CS3__RAWNAND_CE3N, MX6DL_PAD_SD4_CMD__RAWNAND_RDN, MX6DL_PAD_SD4_CLK__RAWNAND_WRN, MX6DL_PAD_NANDF_D0__RAWNAND_D0, MX6DL_PAD_NANDF_D1__RAWNAND_D1, MX6DL_PAD_NANDF_D2__RAWNAND_D2, MX6DL_PAD_NANDF_D3__RAWNAND_D3, MX6DL_PAD_NANDF_D4__RAWNAND_D4, MX6DL_PAD_NANDF_D5__RAWNAND_D5, MX6DL_PAD_NANDF_D6__RAWNAND_D6, MX6DL_PAD_NANDF_D7__RAWNAND_D7, MX6DL_PAD_SD4_DAT0__RAWNAND_DQS, }; #endif int setup_gpmi_nand(void) { unsigned int reg; /* config gpmi nand iomux */ mxc_iomux_v3_setup_multiple_pads(nfc_pads, ARRAY_SIZE(nfc_pads)); /* config gpmi and bch clock to 11Mhz*/ reg = readl(CCM_BASE_ADDR + CLKCTL_CS2CDR); reg &= 0xF800FFFF; reg |= 0x01E40000; writel(reg, CCM_BASE_ADDR + CLKCTL_CS2CDR); /* enable gpmi and bch clock gating */ reg = readl(CCM_BASE_ADDR + CLKCTL_CCGR4); reg |= 0xFF003000; writel(reg, CCM_BASE_ADDR + CLKCTL_CCGR4); /* enable apbh clock gating */ reg = readl(CCM_BASE_ADDR + CLKCTL_CCGR0); reg |= 0x0030; writel(reg, CCM_BASE_ADDR + CLKCTL_CCGR0); } #endif #ifdef CONFIG_NET_MULTI int board_eth_init(bd_t *bis) { int rc = -ENODEV; return rc; } #endif #ifdef CONFIG_CMD_MMC /* On this board, only SD3 can support 1.8V signalling * that is required for UHS-I mode of operation. * Last element in struct is used to indicate 1.8V support. */ struct fsl_esdhc_cfg usdhc_cfg[4] = { {USDHC1_BASE_ADDR, 1, 1, 1, 0}, {USDHC2_BASE_ADDR, 1, 1, 1, 0}, {USDHC3_BASE_ADDR, 1, 1, 1, 1}, {USDHC4_BASE_ADDR, 1, 1, 1, 0}, }; #if defined CONFIG_MX6Q iomux_v3_cfg_t usdhc1_pads[] = { MX6Q_PAD_SD1_CLK__USDHC1_CLK, MX6Q_PAD_SD1_CMD__USDHC1_CMD, MX6Q_PAD_SD1_DAT0__USDHC1_DAT0, MX6Q_PAD_SD1_DAT1__USDHC1_DAT1, MX6Q_PAD_SD1_DAT2__USDHC1_DAT2, MX6Q_PAD_SD1_DAT3__USDHC1_DAT3, }; iomux_v3_cfg_t usdhc2_pads[] = { MX6Q_PAD_SD2_CLK__USDHC2_CLK, MX6Q_PAD_SD2_CMD__USDHC2_CMD, MX6Q_PAD_SD2_DAT0__USDHC2_DAT0, MX6Q_PAD_SD2_DAT1__USDHC2_DAT1, MX6Q_PAD_SD2_DAT2__USDHC2_DAT2, MX6Q_PAD_SD2_DAT3__USDHC2_DAT3, }; iomux_v3_cfg_t usdhc3_pads[] = { MX6Q_PAD_SD3_CLK__USDHC3_CLK, MX6Q_PAD_SD3_CMD__USDHC3_CMD, MX6Q_PAD_SD3_DAT0__USDHC3_DAT0, MX6Q_PAD_SD3_DAT1__USDHC3_DAT1, MX6Q_PAD_SD3_DAT2__USDHC3_DAT2, MX6Q_PAD_SD3_DAT3__USDHC3_DAT3, MX6Q_PAD_SD3_DAT4__USDHC3_DAT4, MX6Q_PAD_SD3_DAT5__USDHC3_DAT5, MX6Q_PAD_SD3_DAT6__USDHC3_DAT6, MX6Q_PAD_SD3_DAT7__USDHC3_DAT7, MX6Q_PAD_GPIO_18__USDHC3_VSELECT, }; iomux_v3_cfg_t usdhc4_pads[] = { MX6Q_PAD_SD4_CLK__USDHC4_CLK, MX6Q_PAD_SD4_CMD__USDHC4_CMD, MX6Q_PAD_SD4_DAT0__USDHC4_DAT0, MX6Q_PAD_SD4_DAT1__USDHC4_DAT1, MX6Q_PAD_SD4_DAT2__USDHC4_DAT2, MX6Q_PAD_SD4_DAT3__USDHC4_DAT3, MX6Q_PAD_SD4_DAT4__USDHC4_DAT4, MX6Q_PAD_SD4_DAT5__USDHC4_DAT5, MX6Q_PAD_SD4_DAT6__USDHC4_DAT6, MX6Q_PAD_SD4_DAT7__USDHC4_DAT7, }; #elif defined CONFIG_MX6DL iomux_v3_cfg_t usdhc1_pads[] = { MX6DL_PAD_SD1_CLK__USDHC1_CLK, MX6DL_PAD_SD1_CMD__USDHC1_CMD, MX6DL_PAD_SD1_DAT0__USDHC1_DAT0, MX6DL_PAD_SD1_DAT1__USDHC1_DAT1, MX6DL_PAD_SD1_DAT2__USDHC1_DAT2, MX6DL_PAD_SD1_DAT3__USDHC1_DAT3, }; iomux_v3_cfg_t usdhc2_pads[] = { MX6DL_PAD_SD2_CLK__USDHC2_CLK, MX6DL_PAD_SD2_CMD__USDHC2_CMD, MX6DL_PAD_SD2_DAT0__USDHC2_DAT0, MX6DL_PAD_SD2_DAT1__USDHC2_DAT1, MX6DL_PAD_SD2_DAT2__USDHC2_DAT2, MX6DL_PAD_SD2_DAT3__USDHC2_DAT3, }; iomux_v3_cfg_t usdhc3_pads[] = { MX6DL_PAD_SD3_CLK__USDHC3_CLK, MX6DL_PAD_SD3_CMD__USDHC3_CMD, MX6DL_PAD_SD3_DAT0__USDHC3_DAT0, MX6DL_PAD_SD3_DAT1__USDHC3_DAT1, MX6DL_PAD_SD3_DAT2__USDHC3_DAT2, MX6DL_PAD_SD3_DAT3__USDHC3_DAT3, MX6DL_PAD_SD3_DAT4__USDHC3_DAT4, MX6DL_PAD_SD3_DAT5__USDHC3_DAT5, MX6DL_PAD_SD3_DAT6__USDHC3_DAT6, MX6DL_PAD_SD3_DAT7__USDHC3_DAT7, MX6DL_PAD_GPIO_18__USDHC3_VSELECT, }; iomux_v3_cfg_t usdhc4_pads[] = { MX6DL_PAD_SD4_CLK__USDHC4_CLK, MX6DL_PAD_SD4_CMD__USDHC4_CMD, MX6DL_PAD_SD4_DAT0__USDHC4_DAT0, MX6DL_PAD_SD4_DAT1__USDHC4_DAT1, MX6DL_PAD_SD4_DAT2__USDHC4_DAT2, MX6DL_PAD_SD4_DAT3__USDHC4_DAT3, MX6DL_PAD_SD4_DAT4__USDHC4_DAT4, MX6DL_PAD_SD4_DAT5__USDHC4_DAT5, MX6DL_PAD_SD4_DAT6__USDHC4_DAT6, MX6DL_PAD_SD4_DAT7__USDHC4_DAT7, }; #endif int usdhc_gpio_init(bd_t *bis) { s32 status = 0; u32 index = 0; for (index = 0; index < CONFIG_SYS_FSL_USDHC_NUM; ++index) { switch (index) { case 0: mxc_iomux_v3_setup_multiple_pads(usdhc1_pads, ARRAY_SIZE(usdhc1_pads)); break; case 1: mxc_iomux_v3_setup_multiple_pads(usdhc2_pads, ARRAY_SIZE(usdhc2_pads)); break; case 2: mxc_iomux_v3_setup_multiple_pads(usdhc3_pads, ARRAY_SIZE(usdhc3_pads)); break; case 3: mxc_iomux_v3_setup_multiple_pads(usdhc4_pads, ARRAY_SIZE(usdhc4_pads)); break; default: printf("Warning: you configured more USDHC controllers" "(%d) then supported by the board (%d)\n", index+1, CONFIG_SYS_FSL_USDHC_NUM); return status; } status |= fsl_esdhc_initialize(bis, &usdhc_cfg[index]); } return status; } int board_mmc_init(bd_t *bis) { if (!usdhc_gpio_init(bis)) return 0; else return -1; } #ifdef CONFIG_MXC_EPDC #ifdef CONFIG_SPLASH_SCREEN int setup_splash_img(void) { #ifdef CONFIG_SPLASH_IS_IN_MMC int mmc_dev = get_mmc_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) { unsigned int reg; /* Setup epdc voltage */ /* EIM_A17 - GPIO2[21] for PWR_GOOD status */ mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_A17__GPIO_2_21); /* EIM_D17 - GPIO3[17] for VCOM control */ mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_D17__GPIO_3_17); /* Set as output */ reg = readl(GPIO3_BASE_ADDR + GPIO_GDIR); reg |= (1 << 17); writel(reg, GPIO3_BASE_ADDR + GPIO_GDIR); /* EIM_D20 - GPIO3[20] for EPD PMIC WAKEUP */ mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_D20__GPIO_3_20); /* Set as output */ reg = readl(GPIO3_BASE_ADDR + GPIO_GDIR); reg |= (1 << 20); writel(reg, GPIO3_BASE_ADDR + GPIO_GDIR); /* EIM_A18 - GPIO2[20] for EPD PWR CTL0 */ mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_A18__GPIO_2_20); /* Set as output */ reg = readl(GPIO2_BASE_ADDR + GPIO_GDIR); reg |= (1 << 20); writel(reg, GPIO2_BASE_ADDR + GPIO_GDIR); } int setup_waveform_file(void) { #ifdef CONFIG_WAVEFORM_FILE_IN_MMC int mmc_dev = get_mmc_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 */ mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_A16__EPDC_SDDO_0); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_DA10__EPDC_SDDO_1); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_DA12__EPDC_SDDO_2); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_DA11__EPDC_SDDO_3); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_LBA__EPDC_SDDO_4); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_EB2__EPDC_SDDO_5); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_CS0__EPDC_SDDO_6); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_RW__EPDC_SDDO_7); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_A21__EPDC_GDCLK); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_A22__EPDC_GDSP); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_A23__EPDC_GDOE); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_A24__EPDC_GDRL); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_D31__EPDC_SDCLK); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_D27__EPDC_SDOE); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_DA1__EPDC_SDLE); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_EB1__EPDC_SDSHR); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_DA2__EPDC_BDR_0); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_DA4__EPDC_SDCE_0); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_DA5__EPDC_SDCE_1); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_DA6__EPDC_SDCE_2); } static void epdc_disable_pins(void) { /* Configure MUX settings for EPDC pins to GPIO */ mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_A16__GPIO_2_22); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_DA10__GPIO_3_10); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_DA12__GPIO_3_12); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_DA11__GPIO_3_11); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_LBA__GPIO_2_27); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_EB2__GPIO_2_30); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_CS0__GPIO_2_23); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_RW__GPIO_2_26); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_A21__GPIO_2_17); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_A22__GPIO_2_16); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_A23__GPIO_6_6); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_A24__GPIO_5_4); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_D31__GPIO_3_31); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_D27__GPIO_3_27); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_DA1__GPIO_3_1); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_EB1__GPIO_2_29); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_DA2__GPIO_3_2); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_DA4__GPIO_3_4); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_DA5__GPIO_3_5); mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_DA6__GPIO_3_6); } static void setup_epdc(void) { unsigned int reg; /*** epdc Maxim PMIC settings ***/ /* EPDC PWRSTAT - GPIO2[21] for PWR_GOOD status */ mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_A17__GPIO_2_21); /* EPDC VCOM0 - GPIO3[17] for VCOM control */ mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_D17__GPIO_3_17); /* UART4 TXD - GPIO3[20] for EPD PMIC WAKEUP */ mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_D20__GPIO_3_20); /* EIM_A18 - GPIO2[20] for EPD PWR CTL0 */ mxc_iomux_v3_setup_pad(MX6DL_PAD_EIM_A18__GPIO_2_20); /*** 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); /* EPDC PIX clk enable */ reg = readl(CCM_BASE_ADDR + CLKCTL_CCGR3); reg |= 0x0C00; writel(reg, CCM_BASE_ADDR + CLKCTL_CCGR3); /* 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); 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() { unsigned int reg; /* Set EPD_PWR_CTL0 to high - enable EINK_VDD (3.15) */ reg = readl(GPIO2_BASE_ADDR + GPIO_DR); reg |= (1 << 20); writel(reg, GPIO2_BASE_ADDR + GPIO_DR); udelay(1000); /* Enable epdc signal pin */ epdc_enable_pins(); /* Set PMIC Wakeup to high - enable Display power */ reg = readl(GPIO3_BASE_ADDR + GPIO_DR); reg |= (1 << 20); writel(reg, GPIO3_BASE_ADDR + GPIO_DR); /* Wait for PWRGOOD == 1 */ while (1) { reg = readl(GPIO2_BASE_ADDR + GPIO_DR); if (!(reg & (1 << 21))) break; udelay(100); } /* Enable VCOM */ reg = readl(GPIO3_BASE_ADDR + GPIO_DR); reg |= (1 << 17); writel(reg, GPIO3_BASE_ADDR + GPIO_DR); reg = readl(GPIO3_BASE_ADDR + GPIO_DR); udelay(500); } void epdc_power_off() { unsigned int reg; /* Set PMIC Wakeup to low - disable Display power */ reg = readl(GPIO3_BASE_ADDR + GPIO_DR); reg &= ~(1 << 20); writel(reg, GPIO3_BASE_ADDR + GPIO_DR); /* Disable VCOM */ reg = readl(GPIO3_BASE_ADDR + GPIO_DR); reg &= ~(1 << 17); writel(reg, GPIO3_BASE_ADDR + GPIO_DR); epdc_disable_pins(); /* Set EPD_PWR_CTL0 to low - disable EINK_VDD (3.15) */ reg = readl(GPIO2_BASE_ADDR + GPIO_DR); reg &= ~(1 << 20); writel(reg, GPIO2_BASE_ADDR + GPIO_DR); } #endif /* For DDR mode operation, provide target delay parameter for each SD port. * Use cfg->esdhc_base to distinguish the SD port #. The delay for each port * is dependent on signal layout for that particular port. If the following * CONFIG is not defined, then the default target delay value will be used. */ #ifdef CONFIG_GET_DDR_TARGET_DELAY u32 get_ddr_delay(struct fsl_esdhc_cfg *cfg) { /* No delay required on ARM2 board SD ports */ return 0; } #endif #endif #ifndef CONFIG_MXC_EPDC #ifdef CONFIG_LCD void lcd_enable(void) { char *s; int ret; unsigned int reg; s = getenv("lvds_num"); di = simple_strtol(s, NULL, 10); /* * hw_rev 2: IPUV3DEX * hw_rev 3: IPUV3M * hw_rev 4: IPUV3H */ g_ipu_hw_rev = IPUV3_HW_REV_IPUV3H; /* set GPIO_9 to high so that backlight control could be high */ #if defined CONFIG_MX6Q mxc_iomux_v3_setup_pad(MX6Q_PAD_GPIO_9__GPIO_1_9); #elif defined CONFIG_MX6DL mxc_iomux_v3_setup_pad(MX6DL_PAD_GPIO_9__GPIO_1_9); #endif reg = readl(GPIO1_BASE_ADDR + GPIO_GDIR); reg |= (1 << 9); writel(reg, GPIO1_BASE_ADDR + GPIO_GDIR); reg = readl(GPIO1_BASE_ADDR + GPIO_DR); reg |= (1 << 9); writel(reg, GPIO1_BASE_ADDR + GPIO_DR); /* Enable IPU clock */ if (di == 1) { reg = readl(CCM_BASE_ADDR + CLKCTL_CCGR3); reg |= 0xC033; writel(reg, CCM_BASE_ADDR + CLKCTL_CCGR3); } else { reg = readl(CCM_BASE_ADDR + CLKCTL_CCGR3); reg |= 0x300F; writel(reg, CCM_BASE_ADDR + CLKCTL_CCGR3); } ret = ipuv3_fb_init(&lvds_xga, di, IPU_PIX_FMT_RGB666, DI_PCLK_LDB, 65000000); if (ret) puts("LCD cannot be configured\n"); reg = readl(ANATOP_BASE_ADDR + 0xF0); reg &= ~0x00003F00; reg |= 0x00001300; writel(reg, ANATOP_BASE_ADDR + 0xF4); reg = readl(CCM_BASE_ADDR + CLKCTL_CS2CDR); reg &= ~0x00007E00; reg |= 0x00003600; writel(reg, CCM_BASE_ADDR + CLKCTL_CS2CDR); reg = readl(CCM_BASE_ADDR + CLKCTL_CSCMR2); reg |= 0x00000C00; writel(reg, CCM_BASE_ADDR + CLKCTL_CSCMR2); reg = 0x0002A953; writel(reg, CCM_BASE_ADDR + CLKCTL_CHSCCDR); if (di == 1) writel(0x40C, IOMUXC_BASE_ADDR + 0x8); else writel(0x201, IOMUXC_BASE_ADDR + 0x8); } #endif #ifdef CONFIG_VIDEO_MX5 void panel_info_init(void) { panel_info.vl_bpix = LCD_BPP; panel_info.vl_col = lvds_xga.xres; panel_info.vl_row = lvds_xga.yres; panel_info.cmap = colormap; } #endif #ifdef CONFIG_SPLASH_SCREEN void setup_splash_image(void) { char *s; ulong addr; s = getenv("splashimage"); if (s != NULL) { addr = simple_strtoul(s, NULL, 16); #if defined(CONFIG_ARCH_MMU) addr = ioremap_nocache(iomem_to_phys(addr), fsl_bmp_600x400_size); #endif memcpy((char *)addr, (char *)fsl_bmp_600x400, fsl_bmp_600x400_size); } } #endif #endif /* !CONFIG_MXC_EPDC */ int board_init(void) { mxc_iomux_v3_init((void *)IOMUXC_BASE_ADDR); setup_boot_device(); fsl_set_system_rev(); /* board id for linux */ gd->bd->bi_arch_number = MACH_TYPE_MX6Q_ARM2; /* address of boot parameters */ gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; setup_uart(); if (cpu_is_mx6q()) setup_sata(); #ifdef CONFIG_VIDEO_MX5 #ifdef CONFIG_I2C_MXC setup_i2c(CONFIG_SYS_I2C_PORT); /* Enable lvds power */ setup_lvds_poweron(); #endif panel_info_init(); gd->fb_base = CONFIG_FB_BASE; #ifdef CONFIG_ARCH_MMU gd->fb_base = ioremap_nocache(iomem_to_phys(gd->fb_base), 0); #endif #endif #ifdef CONFIG_NAND_GPMI setup_gpmi_nand(); #endif #ifdef CONFIG_MXC_EPDC setup_epdc(); #endif return 0; } #ifdef CONFIG_ANDROID_RECOVERY int check_recovery_cmd_file(void) { /*not realized*/ return 0; } #endif int board_late_init(void) { return 0; } #ifdef CONFIG_MXC_FEC static int phy_read(char *devname, unsigned char addr, unsigned char reg, unsigned short *pdata) { int ret = miiphy_read(devname, addr, reg, pdata); if (ret) printf("Error reading from %s PHY addr=%02x reg=%02x\n", devname, addr, reg); return ret; } static int phy_write(char *devname, unsigned char addr, unsigned char reg, unsigned short value) { int ret = miiphy_write(devname, addr, reg, value); if (ret) printf("Error writing to %s PHY addr=%02x reg=%02x\n", devname, addr, reg); return ret; } int mx6_rgmii_rework(char *devname, int phy_addr) { unsigned short val; /* To enable AR8031 ouput a 125MHz clk from CLK_25M */ phy_write(devname, phy_addr, 0xd, 0x7); phy_write(devname, phy_addr, 0xe, 0x8016); phy_write(devname, phy_addr, 0xd, 0x4007); phy_read(devname, phy_addr, 0xe, &val); val &= 0xffe3; val |= 0x18; phy_write(devname, phy_addr, 0xe, val); /* introduce tx clock delay */ phy_write(devname, phy_addr, 0x1d, 0x5); phy_read(devname, phy_addr, 0x1e, &val); val |= 0x0100; phy_write(devname, phy_addr, 0x1e, val); return 0; } #if defined CONFIG_MX6Q iomux_v3_cfg_t enet_pads[] = { MX6Q_PAD_KEY_COL1__ENET_MDIO, MX6Q_PAD_KEY_COL2__ENET_MDC, MX6Q_PAD_RGMII_TXC__ENET_RGMII_TXC, MX6Q_PAD_RGMII_TD0__ENET_RGMII_TD0, MX6Q_PAD_RGMII_TD1__ENET_RGMII_TD1, MX6Q_PAD_RGMII_TD2__ENET_RGMII_TD2, MX6Q_PAD_RGMII_TD3__ENET_RGMII_TD3, MX6Q_PAD_RGMII_TX_CTL__ENET_RGMII_TX_CTL, MX6Q_PAD_ENET_REF_CLK__ENET_TX_CLK, MX6Q_PAD_RGMII_RXC__ENET_RGMII_RXC, MX6Q_PAD_RGMII_RD0__ENET_RGMII_RD0, MX6Q_PAD_RGMII_RD1__ENET_RGMII_RD1, MX6Q_PAD_RGMII_RD2__ENET_RGMII_RD2, MX6Q_PAD_RGMII_RD3__ENET_RGMII_RD3, MX6Q_PAD_RGMII_RX_CTL__ENET_RGMII_RX_CTL, MX6Q_PAD_GPIO_0__CCM_CLKO, MX6Q_PAD_GPIO_3__CCM_CLKO2, }; #elif defined CONFIG_MX6DL iomux_v3_cfg_t enet_pads[] = { MX6DL_PAD_KEY_COL1__ENET_MDIO, MX6DL_PAD_KEY_COL2__ENET_MDC, MX6DL_PAD_RGMII_TXC__ENET_RGMII_TXC, MX6DL_PAD_RGMII_TD0__ENET_RGMII_TD0, MX6DL_PAD_RGMII_TD1__ENET_RGMII_TD1, MX6DL_PAD_RGMII_TD2__ENET_RGMII_TD2, MX6DL_PAD_RGMII_TD3__ENET_RGMII_TD3, MX6DL_PAD_RGMII_TX_CTL__ENET_RGMII_TX_CTL, MX6DL_PAD_ENET_REF_CLK__ENET_TX_CLK, MX6DL_PAD_RGMII_RXC__ENET_RGMII_RXC, MX6DL_PAD_RGMII_RD0__ENET_RGMII_RD0, MX6DL_PAD_RGMII_RD1__ENET_RGMII_RD1, MX6DL_PAD_RGMII_RD2__ENET_RGMII_RD2, MX6DL_PAD_RGMII_RD3__ENET_RGMII_RD3, MX6DL_PAD_RGMII_RX_CTL__ENET_RGMII_RX_CTL, MX6DL_PAD_GPIO_0__CCM_CLKO, MX6DL_PAD_GPIO_3__CCM_CLKO2, }; #endif void enet_board_init(void) { unsigned int reg; iomux_v3_cfg_t enet_reset; #if defined CONFIG_MX6Q enet_reset = (MX6Q_PAD_KEY_ROW4__GPIO_4_15 & ~MUX_PAD_CTRL_MASK) | MUX_PAD_CTRL(0x84); #elif defined CONFIG_MX6DL enet_reset = (MX6DL_PAD_KEY_ROW4__GPIO_4_15 & ~MUX_PAD_CTRL_MASK) | MUX_PAD_CTRL(0x84); #endif mxc_iomux_v3_setup_multiple_pads(enet_pads, ARRAY_SIZE(enet_pads)); mxc_iomux_v3_setup_pad(enet_reset); /* phy reset: gpio4-15 */ reg = readl(GPIO4_BASE_ADDR + 0x0); reg &= ~0x8000; writel(reg, GPIO4_BASE_ADDR + 0x0); reg = readl(GPIO4_BASE_ADDR + 0x4); reg |= 0x8000; writel(reg, GPIO4_BASE_ADDR + 0x4); udelay(500); reg = readl(GPIO4_BASE_ADDR + 0x0); reg |= 0x8000; writel(reg, GPIO4_BASE_ADDR + 0x0); } #endif int checkboard(void) { printf("Board: MX6Q/SDL-ARM2:[ "); switch (__REG(SRC_BASE_ADDR + 0x8)) { case 0x0001: printf("POR"); break; case 0x0009: printf("RST"); break; case 0x0010: case 0x0011: printf("WDOG"); break; default: printf("unknown"); } printf(" ]\n"); printf("Boot Device: "); switch (get_boot_device()) { case WEIM_NOR_BOOT: printf("NOR\n"); break; case ONE_NAND_BOOT: printf("ONE NAND\n"); break; case PATA_BOOT: printf("PATA\n"); break; case SATA_BOOT: printf("SATA\n"); break; case I2C_BOOT: printf("I2C\n"); break; case SPI_NOR_BOOT: printf("SPI NOR\n"); break; case SD_BOOT: printf("SD\n"); break; case MMC_BOOT: printf("MMC\n"); break; case NAND_BOOT: printf("NAND\n"); break; case UNKNOWN_BOOT: default: printf("UNKNOWN\n"); break; } #ifdef CONFIG_SECURE_BOOT if (check_hab_enable() == 1) get_hab_status(); #endif return 0; } #ifdef CONFIG_IMX_UDC #define USB_H1_POWER IMX_GPIO_NR(3, 31) #define USB_OTG_PWR0 IMX_GPIO_NR(3, 22) #define USB_OTG_PWR1 IMX_GPIO_NR(4, 15) void udc_pins_setting(void) { mxc_iomux_v3_setup_pad(MX6X_IOMUX(PAD_GPIO_1__USBOTG_ID)); mxc_iomux_set_gpr_register(1, 13, 1, 1); /*USB_HOST_VBUS EIM_D31 LED D5*/ gpio_direction_output(USB_H1_POWER, 1); mxc_iomux_v3_setup_pad(MX6X_IOMUX(PAD_EIM_D31__GPIO_3_31)); /*USB_OTG_VBUS EIM_D22 KEY_ROW4 LED D6*/ /* there are two pads to control OTG power supply, but only one pads acturally used, in case of different hardware setting, two pads function as gpio, and set to 0. In case of 1-pluse when set the pad as gpio, set the pad to 0 before setting it as gpio*/ gpio_direction_output(USB_OTG_PWR0, 0); mxc_iomux_v3_setup_pad(MX6X_IOMUX(PAD_EIM_D22__GPIO_3_22)); gpio_direction_output(USB_OTG_PWR1, 0); mxc_iomux_v3_setup_pad(MX6X_IOMUX(PAD_KEY_ROW4__GPIO_4_15)); } #endif