Home | History | Annotate | Download | only in mx6sxsabresd
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * Copyright (C) 2014 Freescale Semiconductor, Inc.
      4  *
      5  * Author: Fabio Estevam <fabio.estevam (at) freescale.com>
      6  */
      7 
      8 #include <asm/arch/clock.h>
      9 #include <asm/arch/crm_regs.h>
     10 #include <asm/arch/iomux.h>
     11 #include <asm/arch/imx-regs.h>
     12 #include <asm/arch/mx6-pins.h>
     13 #include <asm/arch/sys_proto.h>
     14 #include <asm/gpio.h>
     15 #include <asm/mach-imx/iomux-v3.h>
     16 #include <asm/io.h>
     17 #include <asm/mach-imx/mxc_i2c.h>
     18 #include <linux/sizes.h>
     19 #include <common.h>
     20 #include <fsl_esdhc.h>
     21 #include <mmc.h>
     22 #include <i2c.h>
     23 #include <miiphy.h>
     24 #include <netdev.h>
     25 #include <power/pmic.h>
     26 #include <power/pfuze100_pmic.h>
     27 #include "../common/pfuze.h"
     28 
     29 DECLARE_GLOBAL_DATA_PTR;
     30 
     31 #define UART_PAD_CTRL  (PAD_CTL_PKE | PAD_CTL_PUE |		\
     32 	PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |		\
     33 	PAD_CTL_DSE_40ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
     34 
     35 #define USDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE |		\
     36 	PAD_CTL_PUS_22K_UP  | PAD_CTL_SPEED_LOW |		\
     37 	PAD_CTL_DSE_80ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
     38 
     39 #define ENET_PAD_CTRL  (PAD_CTL_PUS_100K_UP | PAD_CTL_PUE |     \
     40 	PAD_CTL_SPEED_HIGH   |                                   \
     41 	PAD_CTL_DSE_48ohm   | PAD_CTL_SRE_FAST)
     42 
     43 #define ENET_CLK_PAD_CTRL  (PAD_CTL_SPEED_MED | \
     44 	PAD_CTL_DSE_120ohm   | PAD_CTL_SRE_FAST)
     45 
     46 #define ENET_RX_PAD_CTRL  (PAD_CTL_PKE | PAD_CTL_PUE |          \
     47 	PAD_CTL_SPEED_HIGH   | PAD_CTL_SRE_FAST)
     48 
     49 #define LCD_PAD_CTRL    (PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | PAD_CTL_PUE | \
     50 	PAD_CTL_PKE | PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm)
     51 
     52 #define WDOG_PAD_CTRL (PAD_CTL_PUE | PAD_CTL_PKE | PAD_CTL_SPEED_MED |	\
     53 	PAD_CTL_DSE_40ohm)
     54 
     55 int dram_init(void)
     56 {
     57 	gd->ram_size = imx_ddr_size();
     58 
     59 	return 0;
     60 }
     61 
     62 static iomux_v3_cfg_t const uart1_pads[] = {
     63 	MX6_PAD_GPIO1_IO04__UART1_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
     64 	MX6_PAD_GPIO1_IO05__UART1_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
     65 };
     66 
     67 static iomux_v3_cfg_t const wdog_b_pad = {
     68 	MX6_PAD_GPIO1_IO13__GPIO1_IO_13 | MUX_PAD_CTRL(WDOG_PAD_CTRL),
     69 };
     70 static iomux_v3_cfg_t const fec1_pads[] = {
     71 	MX6_PAD_ENET1_MDC__ENET1_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
     72 	MX6_PAD_ENET1_MDIO__ENET1_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL),
     73 	MX6_PAD_RGMII1_RX_CTL__ENET1_RX_EN | MUX_PAD_CTRL(ENET_RX_PAD_CTRL),
     74 	MX6_PAD_RGMII1_RD0__ENET1_RX_DATA_0 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL),
     75 	MX6_PAD_RGMII1_RD1__ENET1_RX_DATA_1 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL),
     76 	MX6_PAD_RGMII1_RD2__ENET1_RX_DATA_2 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL),
     77 	MX6_PAD_RGMII1_RD3__ENET1_RX_DATA_3 | MUX_PAD_CTRL(ENET_RX_PAD_CTRL),
     78 	MX6_PAD_RGMII1_RXC__ENET1_RX_CLK | MUX_PAD_CTRL(ENET_RX_PAD_CTRL),
     79 	MX6_PAD_RGMII1_TX_CTL__ENET1_TX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),
     80 	MX6_PAD_RGMII1_TD0__ENET1_TX_DATA_0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
     81 	MX6_PAD_RGMII1_TD1__ENET1_TX_DATA_1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
     82 	MX6_PAD_RGMII1_TD2__ENET1_TX_DATA_2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
     83 	MX6_PAD_RGMII1_TD3__ENET1_TX_DATA_3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
     84 	MX6_PAD_RGMII1_TXC__ENET1_RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
     85 };
     86 
     87 static iomux_v3_cfg_t const peri_3v3_pads[] = {
     88 	MX6_PAD_QSPI1A_DATA0__GPIO4_IO_16 | MUX_PAD_CTRL(NO_PAD_CTRL),
     89 };
     90 
     91 static iomux_v3_cfg_t const phy_control_pads[] = {
     92 	/* 25MHz Ethernet PHY Clock */
     93 	MX6_PAD_ENET2_RX_CLK__ENET2_REF_CLK_25M | MUX_PAD_CTRL(ENET_CLK_PAD_CTRL),
     94 
     95 	/* ENET PHY Power */
     96 	MX6_PAD_ENET2_COL__GPIO2_IO_6 | MUX_PAD_CTRL(NO_PAD_CTRL),
     97 
     98 	/* AR8031 PHY Reset */
     99 	MX6_PAD_ENET2_CRS__GPIO2_IO_7 | MUX_PAD_CTRL(NO_PAD_CTRL),
    100 };
    101 
    102 static void setup_iomux_uart(void)
    103 {
    104 	imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads));
    105 }
    106 
    107 static int setup_fec(void)
    108 {
    109 	struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
    110 	struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
    111 	int reg, ret;
    112 
    113 	/* Use 125MHz anatop loopback REF_CLK1 for ENET1 */
    114 	clrsetbits_le32(&iomuxc_regs->gpr[1], IOMUX_GPR1_FEC1_MASK, 0);
    115 
    116 	ret = enable_fec_anatop_clock(0, ENET_125MHZ);
    117 	if (ret)
    118 		return ret;
    119 
    120 	imx_iomux_v3_setup_multiple_pads(phy_control_pads,
    121 					 ARRAY_SIZE(phy_control_pads));
    122 
    123 	/* Enable the ENET power, active low */
    124 	gpio_request(IMX_GPIO_NR(2, 6), "enet_rst");
    125 	gpio_direction_output(IMX_GPIO_NR(2, 6) , 0);
    126 
    127 	/* Reset AR8031 PHY */
    128 	gpio_request(IMX_GPIO_NR(2, 7), "phy_rst");
    129 	gpio_direction_output(IMX_GPIO_NR(2, 7) , 0);
    130 	mdelay(10);
    131 	gpio_set_value(IMX_GPIO_NR(2, 7), 1);
    132 
    133 	reg = readl(&anatop->pll_enet);
    134 	reg |= BM_ANADIG_PLL_ENET_REF_25M_ENABLE;
    135 	writel(reg, &anatop->pll_enet);
    136 
    137 	return 0;
    138 }
    139 
    140 int board_eth_init(bd_t *bis)
    141 {
    142 	imx_iomux_v3_setup_multiple_pads(fec1_pads, ARRAY_SIZE(fec1_pads));
    143 	setup_fec();
    144 
    145 	return cpu_eth_init(bis);
    146 }
    147 
    148 int power_init_board(void)
    149 {
    150 	struct udevice *dev;
    151 	unsigned int reg;
    152 	int ret;
    153 
    154 	dev = pfuze_common_init();
    155 	if (!dev)
    156 		return -ENODEV;
    157 
    158 	ret = pfuze_mode_init(dev, APS_PFM);
    159 	if (ret < 0)
    160 		return ret;
    161 
    162 	/* Enable power of VGEN5 3V3, needed for SD3 */
    163 	reg = pmic_reg_read(dev, PFUZE100_VGEN5VOL);
    164 	reg &= ~LDO_VOL_MASK;
    165 	reg |= (LDOB_3_30V | (1 << LDO_EN));
    166 	pmic_reg_write(dev, PFUZE100_VGEN5VOL, reg);
    167 
    168 	return 0;
    169 }
    170 
    171 int board_phy_config(struct phy_device *phydev)
    172 {
    173 	/*
    174 	 * Enable 1.8V(SEL_1P5_1P8_POS_REG) on
    175 	 * Phy control debug reg 0
    176 	 */
    177 	phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f);
    178 	phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x8);
    179 
    180 	/* rgmii tx clock delay enable */
    181 	phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05);
    182 	phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100);
    183 
    184 	if (phydev->drv->config)
    185 		phydev->drv->config(phydev);
    186 
    187 	return 0;
    188 }
    189 
    190 int board_early_init_f(void)
    191 {
    192 	setup_iomux_uart();
    193 
    194 	/* Enable PERI_3V3, which is used by SD2, ENET, LVDS, BT */
    195 	imx_iomux_v3_setup_multiple_pads(peri_3v3_pads,
    196 					 ARRAY_SIZE(peri_3v3_pads));
    197 
    198 	return 0;
    199 }
    200 
    201 int board_mmc_get_env_dev(int devno)
    202 {
    203 	return devno;
    204 }
    205 
    206 #ifdef CONFIG_FSL_QSPI
    207 
    208 #define QSPI_PAD_CTRL1	\
    209 	(PAD_CTL_SRE_FAST | PAD_CTL_SPEED_HIGH | \
    210 	 PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_47K_UP | PAD_CTL_DSE_40ohm)
    211 
    212 static iomux_v3_cfg_t const quadspi_pads[] = {
    213 	MX6_PAD_NAND_WP_B__QSPI2_A_DATA_0	| MUX_PAD_CTRL(QSPI_PAD_CTRL1),
    214 	MX6_PAD_NAND_READY_B__QSPI2_A_DATA_1	| MUX_PAD_CTRL(QSPI_PAD_CTRL1),
    215 	MX6_PAD_NAND_CE0_B__QSPI2_A_DATA_2	| MUX_PAD_CTRL(QSPI_PAD_CTRL1),
    216 	MX6_PAD_NAND_CE1_B__QSPI2_A_DATA_3	| MUX_PAD_CTRL(QSPI_PAD_CTRL1),
    217 	MX6_PAD_NAND_ALE__QSPI2_A_SS0_B		| MUX_PAD_CTRL(QSPI_PAD_CTRL1),
    218 	MX6_PAD_NAND_CLE__QSPI2_A_SCLK		| MUX_PAD_CTRL(QSPI_PAD_CTRL1),
    219 	MX6_PAD_NAND_DATA07__QSPI2_A_DQS	| MUX_PAD_CTRL(QSPI_PAD_CTRL1),
    220 	MX6_PAD_NAND_DATA01__QSPI2_B_DATA_0	| MUX_PAD_CTRL(QSPI_PAD_CTRL1),
    221 	MX6_PAD_NAND_DATA00__QSPI2_B_DATA_1	| MUX_PAD_CTRL(QSPI_PAD_CTRL1),
    222 	MX6_PAD_NAND_WE_B__QSPI2_B_DATA_2	| MUX_PAD_CTRL(QSPI_PAD_CTRL1),
    223 	MX6_PAD_NAND_RE_B__QSPI2_B_DATA_3	| MUX_PAD_CTRL(QSPI_PAD_CTRL1),
    224 	MX6_PAD_NAND_DATA03__QSPI2_B_SS0_B	| MUX_PAD_CTRL(QSPI_PAD_CTRL1),
    225 	MX6_PAD_NAND_DATA02__QSPI2_B_SCLK	| MUX_PAD_CTRL(QSPI_PAD_CTRL1),
    226 	MX6_PAD_NAND_DATA05__QSPI2_B_DQS	| MUX_PAD_CTRL(QSPI_PAD_CTRL1),
    227 };
    228 
    229 int board_qspi_init(void)
    230 {
    231 	/* Set the iomux */
    232 	imx_iomux_v3_setup_multiple_pads(quadspi_pads,
    233 					 ARRAY_SIZE(quadspi_pads));
    234 
    235 	/* Set the clock */
    236 	enable_qspi_clk(1);
    237 
    238 	return 0;
    239 }
    240 #endif
    241 
    242 #ifdef CONFIG_VIDEO_MXS
    243 static iomux_v3_cfg_t const lcd_pads[] = {
    244 	MX6_PAD_LCD1_CLK__LCDIF1_CLK | MUX_PAD_CTRL(LCD_PAD_CTRL),
    245 	MX6_PAD_LCD1_ENABLE__LCDIF1_ENABLE | MUX_PAD_CTRL(LCD_PAD_CTRL),
    246 	MX6_PAD_LCD1_HSYNC__LCDIF1_HSYNC | MUX_PAD_CTRL(LCD_PAD_CTRL),
    247 	MX6_PAD_LCD1_VSYNC__LCDIF1_VSYNC | MUX_PAD_CTRL(LCD_PAD_CTRL),
    248 	MX6_PAD_LCD1_DATA00__LCDIF1_DATA_0 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    249 	MX6_PAD_LCD1_DATA01__LCDIF1_DATA_1 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    250 	MX6_PAD_LCD1_DATA02__LCDIF1_DATA_2 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    251 	MX6_PAD_LCD1_DATA03__LCDIF1_DATA_3 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    252 	MX6_PAD_LCD1_DATA04__LCDIF1_DATA_4 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    253 	MX6_PAD_LCD1_DATA05__LCDIF1_DATA_5 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    254 	MX6_PAD_LCD1_DATA06__LCDIF1_DATA_6 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    255 	MX6_PAD_LCD1_DATA07__LCDIF1_DATA_7 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    256 	MX6_PAD_LCD1_DATA08__LCDIF1_DATA_8 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    257 	MX6_PAD_LCD1_DATA09__LCDIF1_DATA_9 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    258 	MX6_PAD_LCD1_DATA10__LCDIF1_DATA_10 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    259 	MX6_PAD_LCD1_DATA11__LCDIF1_DATA_11 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    260 	MX6_PAD_LCD1_DATA12__LCDIF1_DATA_12 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    261 	MX6_PAD_LCD1_DATA13__LCDIF1_DATA_13 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    262 	MX6_PAD_LCD1_DATA14__LCDIF1_DATA_14 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    263 	MX6_PAD_LCD1_DATA15__LCDIF1_DATA_15 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    264 	MX6_PAD_LCD1_DATA16__LCDIF1_DATA_16 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    265 	MX6_PAD_LCD1_DATA17__LCDIF1_DATA_17 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    266 	MX6_PAD_LCD1_DATA18__LCDIF1_DATA_18 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    267 	MX6_PAD_LCD1_DATA19__LCDIF1_DATA_19 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    268 	MX6_PAD_LCD1_DATA20__LCDIF1_DATA_20 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    269 	MX6_PAD_LCD1_DATA21__LCDIF1_DATA_21 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    270 	MX6_PAD_LCD1_DATA22__LCDIF1_DATA_22 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    271 	MX6_PAD_LCD1_DATA23__LCDIF1_DATA_23 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    272 	MX6_PAD_LCD1_RESET__GPIO3_IO_27 | MUX_PAD_CTRL(NO_PAD_CTRL),
    273 
    274 	/* Use GPIO for Brightness adjustment, duty cycle = period */
    275 	MX6_PAD_SD1_DATA2__GPIO6_IO_4 | MUX_PAD_CTRL(NO_PAD_CTRL),
    276 };
    277 
    278 static int setup_lcd(void)
    279 {
    280 	enable_lcdif_clock(LCDIF1_BASE_ADDR, 1);
    281 
    282 	imx_iomux_v3_setup_multiple_pads(lcd_pads, ARRAY_SIZE(lcd_pads));
    283 
    284 	/* Reset the LCD */
    285 	gpio_request(IMX_GPIO_NR(3, 27), "lcd_rst");
    286 	gpio_direction_output(IMX_GPIO_NR(3, 27) , 0);
    287 	udelay(500);
    288 	gpio_direction_output(IMX_GPIO_NR(3, 27) , 1);
    289 
    290 	/* Set Brightness to high */
    291 	gpio_request(IMX_GPIO_NR(6, 4), "lcd_bright");
    292 	gpio_direction_output(IMX_GPIO_NR(6, 4) , 1);
    293 
    294 	return 0;
    295 }
    296 #endif
    297 
    298 int board_init(void)
    299 {
    300 	/* Address of boot parameters */
    301 	gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
    302 
    303 	/*
    304 	 * Because kernel set WDOG_B mux before pad with the common pinctrl
    305 	 * framwork now and wdog reset will be triggered once set WDOG_B mux
    306 	 * with default pad setting, we set pad setting here to workaround this.
    307 	 * Since imx_iomux_v3_setup_pad also set mux before pad setting, we set
    308 	 * as GPIO mux firstly here to workaround it.
    309 	 */
    310 	imx_iomux_v3_setup_pad(wdog_b_pad);
    311 
    312 	/* Active high for ncp692 */
    313 	gpio_request(IMX_GPIO_NR(4, 16), "ncp692_en");
    314 	gpio_direction_output(IMX_GPIO_NR(4, 16), 1);
    315 
    316 #ifdef CONFIG_FSL_QSPI
    317 	board_qspi_init();
    318 #endif
    319 
    320 #ifdef CONFIG_VIDEO_MXS
    321 	setup_lcd();
    322 #endif
    323 
    324 	return 0;
    325 }
    326 
    327 static bool is_reva(void)
    328 {
    329 	return (nxp_board_rev() == 1);
    330 }
    331 
    332 int board_late_init(void)
    333 {
    334 #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
    335 	if (is_reva())
    336 		env_set("board_rev", "REVA");
    337 #endif
    338 	return 0;
    339 }
    340 
    341 int checkboard(void)
    342 {
    343 	printf("Board: MX6SX SABRE SDB rev%c\n", nxp_board_rev_string());
    344 
    345 	return 0;
    346 }
    347 
    348 #ifdef CONFIG_SPL_BUILD
    349 #include <linux/libfdt.h>
    350 #include <spl.h>
    351 #include <asm/arch/mx6-ddr.h>
    352 
    353 static struct fsl_esdhc_cfg usdhc_cfg[3] = {
    354 	{USDHC2_BASE_ADDR, 0, 4},
    355 	{USDHC3_BASE_ADDR},
    356 	{USDHC4_BASE_ADDR},
    357 };
    358 
    359 #define USDHC3_CD_GPIO	IMX_GPIO_NR(2, 10)
    360 #define USDHC3_PWR_GPIO	IMX_GPIO_NR(2, 11)
    361 #define USDHC4_CD_GPIO	IMX_GPIO_NR(6, 21)
    362 
    363 static iomux_v3_cfg_t const usdhc2_pads[] = {
    364 	MX6_PAD_SD2_CLK__USDHC2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    365 	MX6_PAD_SD2_CMD__USDHC2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    366 	MX6_PAD_SD2_DATA0__USDHC2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    367 	MX6_PAD_SD2_DATA1__USDHC2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    368 	MX6_PAD_SD2_DATA2__USDHC2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    369 	MX6_PAD_SD2_DATA3__USDHC2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    370 };
    371 
    372 static iomux_v3_cfg_t const usdhc3_pads[] = {
    373 	MX6_PAD_SD3_CLK__USDHC3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    374 	MX6_PAD_SD3_CMD__USDHC3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    375 	MX6_PAD_SD3_DATA0__USDHC3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    376 	MX6_PAD_SD3_DATA1__USDHC3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    377 	MX6_PAD_SD3_DATA2__USDHC3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    378 	MX6_PAD_SD3_DATA3__USDHC3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    379 	MX6_PAD_SD3_DATA4__USDHC3_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    380 	MX6_PAD_SD3_DATA5__USDHC3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    381 	MX6_PAD_SD3_DATA6__USDHC3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    382 	MX6_PAD_SD3_DATA7__USDHC3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    383 
    384 	/* CD pin */
    385 	MX6_PAD_KEY_COL0__GPIO2_IO_10 | MUX_PAD_CTRL(NO_PAD_CTRL),
    386 
    387 	/* RST_B, used for power reset cycle */
    388 	MX6_PAD_KEY_COL1__GPIO2_IO_11 | MUX_PAD_CTRL(NO_PAD_CTRL),
    389 };
    390 
    391 static iomux_v3_cfg_t const usdhc4_pads[] = {
    392 	MX6_PAD_SD4_CLK__USDHC4_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    393 	MX6_PAD_SD4_CMD__USDHC4_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    394 	MX6_PAD_SD4_DATA0__USDHC4_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    395 	MX6_PAD_SD4_DATA1__USDHC4_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    396 	MX6_PAD_SD4_DATA2__USDHC4_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    397 	MX6_PAD_SD4_DATA3__USDHC4_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    398 	MX6_PAD_SD4_DATA7__GPIO6_IO_21 | MUX_PAD_CTRL(NO_PAD_CTRL),
    399 };
    400 
    401 int board_mmc_init(bd_t *bis)
    402 {
    403 	struct src *src_regs = (struct src *)SRC_BASE_ADDR;
    404 	u32 val;
    405 	u32 port;
    406 
    407 	val = readl(&src_regs->sbmr1);
    408 
    409 	if ((val & 0xc0) != 0x40) {
    410 		printf("Not boot from USDHC!\n");
    411 		return -EINVAL;
    412 	}
    413 
    414 	port = (val >> 11) & 0x3;
    415 	printf("port %d\n", port);
    416 	switch (port) {
    417 	case 1:
    418 		imx_iomux_v3_setup_multiple_pads(
    419 			usdhc2_pads, ARRAY_SIZE(usdhc2_pads));
    420 		usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
    421 		usdhc_cfg[0].esdhc_base = USDHC2_BASE_ADDR;
    422 		break;
    423 	case 2:
    424 		imx_iomux_v3_setup_multiple_pads(
    425 			usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
    426 		gpio_direction_input(USDHC3_CD_GPIO);
    427 		gpio_direction_output(USDHC3_PWR_GPIO, 1);
    428 		usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
    429 		usdhc_cfg[0].esdhc_base = USDHC3_BASE_ADDR;
    430 		break;
    431 	case 3:
    432 		imx_iomux_v3_setup_multiple_pads(
    433 			usdhc4_pads, ARRAY_SIZE(usdhc4_pads));
    434 		gpio_direction_input(USDHC4_CD_GPIO);
    435 		usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
    436 		usdhc_cfg[0].esdhc_base = USDHC4_BASE_ADDR;
    437 		break;
    438 	}
    439 
    440 	gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
    441 	return fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
    442 }
    443 
    444 int board_mmc_getcd(struct mmc *mmc)
    445 {
    446 	struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
    447 	int ret = 0;
    448 
    449 	switch (cfg->esdhc_base) {
    450 	case USDHC2_BASE_ADDR:
    451 		ret = 1; /* Assume uSDHC2 is always present */
    452 		break;
    453 	case USDHC3_BASE_ADDR:
    454 		ret = !gpio_get_value(USDHC3_CD_GPIO);
    455 		break;
    456 	case USDHC4_BASE_ADDR:
    457 		ret = !gpio_get_value(USDHC4_CD_GPIO);
    458 		break;
    459 	}
    460 
    461 	return ret;
    462 }
    463 
    464 const struct mx6sx_iomux_ddr_regs mx6_ddr_ioregs = {
    465 	.dram_dqm0 = 0x00000028,
    466 	.dram_dqm1 = 0x00000028,
    467 	.dram_dqm2 = 0x00000028,
    468 	.dram_dqm3 = 0x00000028,
    469 	.dram_ras = 0x00000020,
    470 	.dram_cas = 0x00000020,
    471 	.dram_odt0 = 0x00000020,
    472 	.dram_odt1 = 0x00000020,
    473 	.dram_sdba2 = 0x00000000,
    474 	.dram_sdcke0 = 0x00003000,
    475 	.dram_sdcke1 = 0x00003000,
    476 	.dram_sdclk_0 = 0x00000030,
    477 	.dram_sdqs0 = 0x00000028,
    478 	.dram_sdqs1 = 0x00000028,
    479 	.dram_sdqs2 = 0x00000028,
    480 	.dram_sdqs3 = 0x00000028,
    481 	.dram_reset = 0x00000020,
    482 };
    483 
    484 const struct mx6sx_iomux_grp_regs mx6_grp_ioregs = {
    485 	.grp_addds = 0x00000020,
    486 	.grp_ddrmode_ctl = 0x00020000,
    487 	.grp_ddrpke = 0x00000000,
    488 	.grp_ddrmode = 0x00020000,
    489 	.grp_b0ds = 0x00000028,
    490 	.grp_b1ds = 0x00000028,
    491 	.grp_ctlds = 0x00000020,
    492 	.grp_ddr_type = 0x000c0000,
    493 	.grp_b2ds = 0x00000028,
    494 	.grp_b3ds = 0x00000028,
    495 };
    496 
    497 const struct mx6_mmdc_calibration mx6_mmcd_calib = {
    498 	.p0_mpwldectrl0 = 0x00290025,
    499 	.p0_mpwldectrl1 = 0x00220022,
    500 	.p0_mpdgctrl0 = 0x41480144,
    501 	.p0_mpdgctrl1 = 0x01340130,
    502 	.p0_mprddlctl = 0x3C3E4244,
    503 	.p0_mpwrdlctl = 0x34363638,
    504 };
    505 
    506 static struct mx6_ddr3_cfg mem_ddr = {
    507 	.mem_speed = 1600,
    508 	.density = 4,
    509 	.width = 32,
    510 	.banks = 8,
    511 	.rowaddr = 15,
    512 	.coladdr = 10,
    513 	.pagesz = 2,
    514 	.trcd = 1375,
    515 	.trcmin = 4875,
    516 	.trasmin = 3500,
    517 };
    518 
    519 static void ccgr_init(void)
    520 {
    521 	struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
    522 
    523 	writel(0xFFFFFFFF, &ccm->CCGR0);
    524 	writel(0xFFFFFFFF, &ccm->CCGR1);
    525 	writel(0xFFFFFFFF, &ccm->CCGR2);
    526 	writel(0xFFFFFFFF, &ccm->CCGR3);
    527 	writel(0xFFFFFFFF, &ccm->CCGR4);
    528 	writel(0xFFFFFFFF, &ccm->CCGR5);
    529 	writel(0xFFFFFFFF, &ccm->CCGR6);
    530 	writel(0xFFFFFFFF, &ccm->CCGR7);
    531 }
    532 
    533 static void spl_dram_init(void)
    534 {
    535 	struct mx6_ddr_sysinfo sysinfo = {
    536 		.dsize = mem_ddr.width/32,
    537 		.cs_density = 24,
    538 		.ncs = 1,
    539 		.cs1_mirror = 0,
    540 		.rtt_wr = 2,
    541 		.rtt_nom = 2,		/* RTT_Nom = RZQ/2 */
    542 		.walat = 1,		/* Write additional latency */
    543 		.ralat = 5,		/* Read additional latency */
    544 		.mif3_mode = 3,		/* Command prediction working mode */
    545 		.bi_on = 1,		/* Bank interleaving enabled */
    546 		.sde_to_rst = 0x10,	/* 14 cycles, 200us (JEDEC default) */
    547 		.rst_to_cke = 0x23,	/* 33 cycles, 500us (JEDEC default) */
    548 		.ddr_type = DDR_TYPE_DDR3,
    549 		.refsel = 1,	/* Refresh cycles at 32KHz */
    550 		.refr = 7,	/* 8 refresh commands per refresh cycle */
    551 	};
    552 
    553 	mx6sx_dram_iocfg(mem_ddr.width, &mx6_ddr_ioregs, &mx6_grp_ioregs);
    554 	mx6_dram_cfg(&sysinfo, &mx6_mmcd_calib, &mem_ddr);
    555 }
    556 
    557 void board_init_f(ulong dummy)
    558 {
    559 	/* setup AIPS and disable watchdog */
    560 	arch_cpu_init();
    561 
    562 	ccgr_init();
    563 
    564 	/* iomux and setup of i2c */
    565 	board_early_init_f();
    566 
    567 	/* setup GP timer */
    568 	timer_init();
    569 
    570 	/* UART clocks enabled and gd valid - init serial console */
    571 	preloader_console_init();
    572 
    573 	/* DDR initialization */
    574 	spl_dram_init();
    575 
    576 	/* Clear the BSS. */
    577 	memset(__bss_start, 0, __bss_end - __bss_start);
    578 
    579 	/* load/boot image from boot device */
    580 	board_init_r(NULL, 0);
    581 }
    582 #endif
    583