1*876a25d2SStefano Babic /* 2*876a25d2SStefano Babic * Copyright (C) 2016 Stefano Babic <sbabic@denx.de> 3*876a25d2SStefano Babic * 4*876a25d2SStefano Babic * SPDX-License-Identifier: GPL-2.0+ 5*876a25d2SStefano Babic */ 6*876a25d2SStefano Babic 7*876a25d2SStefano Babic /* 8*876a25d2SStefano Babic * Please note: there are two version of the board 9*876a25d2SStefano Babic * one with NAND and the other with eMMC. 10*876a25d2SStefano Babic * Both NAND and eMMC cannot be set because they share the 11*876a25d2SStefano Babic * same pins (SD4) 12*876a25d2SStefano Babic */ 13*876a25d2SStefano Babic #include <common.h> 14*876a25d2SStefano Babic #include <asm/io.h> 15*876a25d2SStefano Babic #include <asm/arch/clock.h> 16*876a25d2SStefano Babic #include <asm/arch/imx-regs.h> 17*876a25d2SStefano Babic #include <asm/arch/crm_regs.h> 18*876a25d2SStefano Babic #include <asm/arch/mx6-ddr.h> 19*876a25d2SStefano Babic #include <asm/arch/iomux.h> 20*876a25d2SStefano Babic #include <asm/arch/mx6-pins.h> 21*876a25d2SStefano Babic #include <asm/imx-common/iomux-v3.h> 22*876a25d2SStefano Babic #include <asm/imx-common/boot_mode.h> 23*876a25d2SStefano Babic #include <asm/imx-common/mxc_i2c.h> 24*876a25d2SStefano Babic #include <asm/imx-common/spi.h> 25*876a25d2SStefano Babic #include <asm/errno.h> 26*876a25d2SStefano Babic #include <asm/gpio.h> 27*876a25d2SStefano Babic #include <mmc.h> 28*876a25d2SStefano Babic #include <i2c.h> 29*876a25d2SStefano Babic #include <fsl_esdhc.h> 30*876a25d2SStefano Babic #include <nand.h> 31*876a25d2SStefano Babic #include <miiphy.h> 32*876a25d2SStefano Babic #include <netdev.h> 33*876a25d2SStefano Babic #include <asm/arch/sys_proto.h> 34*876a25d2SStefano Babic #include <asm/sections.h> 35*876a25d2SStefano Babic 36*876a25d2SStefano Babic DECLARE_GLOBAL_DATA_PTR; 37*876a25d2SStefano Babic 38*876a25d2SStefano Babic #define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ 39*876a25d2SStefano Babic PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \ 40*876a25d2SStefano Babic PAD_CTL_SRE_FAST | PAD_CTL_HYS) 41*876a25d2SStefano Babic 42*876a25d2SStefano Babic #define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | \ 43*876a25d2SStefano Babic PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm | \ 44*876a25d2SStefano Babic PAD_CTL_SRE_FAST | PAD_CTL_HYS) 45*876a25d2SStefano Babic 46*876a25d2SStefano Babic #define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ 47*876a25d2SStefano Babic PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS) 48*876a25d2SStefano Babic 49*876a25d2SStefano Babic #define SPI_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_SPEED_MED | \ 50*876a25d2SStefano Babic PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST) 51*876a25d2SStefano Babic 52*876a25d2SStefano Babic #define I2C_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ 53*876a25d2SStefano Babic PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \ 54*876a25d2SStefano Babic PAD_CTL_ODE | PAD_CTL_SRE_FAST) 55*876a25d2SStefano Babic 56*876a25d2SStefano Babic #define I2C_PAD MUX_PAD_CTRL(I2C_PAD_CTRL) 57*876a25d2SStefano Babic 58*876a25d2SStefano Babic #define ASRC_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | \ 59*876a25d2SStefano Babic PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST) 60*876a25d2SStefano Babic 61*876a25d2SStefano Babic #define NAND_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ 62*876a25d2SStefano Babic PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST) 63*876a25d2SStefano Babic 64*876a25d2SStefano Babic #define ENET_PHY_RESET_GPIO IMX_GPIO_NR(1, 14) 65*876a25d2SStefano Babic #define USDHC1_CD_GPIO IMX_GPIO_NR(6, 31) 66*876a25d2SStefano Babic #define USER_LED IMX_GPIO_NR(1, 4) 67*876a25d2SStefano Babic #define IMX6Q_DRIVE_STRENGTH 0x30 68*876a25d2SStefano Babic 69*876a25d2SStefano Babic int dram_init(void) 70*876a25d2SStefano Babic { 71*876a25d2SStefano Babic gd->ram_size = imx_ddr_size(); 72*876a25d2SStefano Babic return 0; 73*876a25d2SStefano Babic } 74*876a25d2SStefano Babic 75*876a25d2SStefano Babic void board_turn_off_led(void) 76*876a25d2SStefano Babic { 77*876a25d2SStefano Babic gpio_direction_output(USER_LED, 0); 78*876a25d2SStefano Babic } 79*876a25d2SStefano Babic 80*876a25d2SStefano Babic static iomux_v3_cfg_t const uart1_pads[] = { 81*876a25d2SStefano Babic MX6_PAD_EIM_D26__UART2_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), 82*876a25d2SStefano Babic MX6_PAD_EIM_D27__UART2_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), 83*876a25d2SStefano Babic }; 84*876a25d2SStefano Babic 85*876a25d2SStefano Babic static iomux_v3_cfg_t const enet_pads[] = { 86*876a25d2SStefano Babic MX6_PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL), 87*876a25d2SStefano Babic MX6_PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL), 88*876a25d2SStefano Babic MX6_PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL), 89*876a25d2SStefano Babic MX6_PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL), 90*876a25d2SStefano Babic MX6_PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL), 91*876a25d2SStefano Babic MX6_PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL), 92*876a25d2SStefano Babic MX6_PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL), 93*876a25d2SStefano Babic MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL), 94*876a25d2SStefano Babic MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL), 95*876a25d2SStefano Babic MX6_PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL), 96*876a25d2SStefano Babic MX6_PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL), 97*876a25d2SStefano Babic MX6_PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL), 98*876a25d2SStefano Babic MX6_PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL), 99*876a25d2SStefano Babic MX6_PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL), 100*876a25d2SStefano Babic MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL), 101*876a25d2SStefano Babic MX6_PAD_SD2_DAT1__GPIO1_IO14 | MUX_PAD_CTRL(NO_PAD_CTRL), 102*876a25d2SStefano Babic }; 103*876a25d2SStefano Babic 104*876a25d2SStefano Babic static iomux_v3_cfg_t const ecspi1_pads[] = { 105*876a25d2SStefano Babic MX6_PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL), 106*876a25d2SStefano Babic MX6_PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL), 107*876a25d2SStefano Babic MX6_PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL), 108*876a25d2SStefano Babic MX6_PAD_EIM_D19__GPIO3_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL), 109*876a25d2SStefano Babic }; 110*876a25d2SStefano Babic 111*876a25d2SStefano Babic /* NAND */ 112*876a25d2SStefano Babic static iomux_v3_cfg_t const nfc_pads[] = { 113*876a25d2SStefano Babic MX6_PAD_NANDF_CLE__NAND_CLE | MUX_PAD_CTRL(NAND_PAD_CTRL), 114*876a25d2SStefano Babic MX6_PAD_NANDF_ALE__NAND_ALE | MUX_PAD_CTRL(NAND_PAD_CTRL), 115*876a25d2SStefano Babic MX6_PAD_NANDF_WP_B__NAND_WP_B | MUX_PAD_CTRL(NAND_PAD_CTRL), 116*876a25d2SStefano Babic MX6_PAD_NANDF_RB0__NAND_READY_B | MUX_PAD_CTRL(NAND_PAD_CTRL), 117*876a25d2SStefano Babic MX6_PAD_NANDF_CS0__NAND_CE0_B | MUX_PAD_CTRL(NAND_PAD_CTRL), 118*876a25d2SStefano Babic MX6_PAD_NANDF_CS1__NAND_CE1_B | MUX_PAD_CTRL(NAND_PAD_CTRL), 119*876a25d2SStefano Babic MX6_PAD_NANDF_CS2__NAND_CE2_B | MUX_PAD_CTRL(NAND_PAD_CTRL), 120*876a25d2SStefano Babic MX6_PAD_NANDF_CS3__NAND_CE3_B | MUX_PAD_CTRL(NAND_PAD_CTRL), 121*876a25d2SStefano Babic MX6_PAD_SD4_CMD__NAND_RE_B | MUX_PAD_CTRL(NAND_PAD_CTRL), 122*876a25d2SStefano Babic MX6_PAD_SD4_CLK__NAND_WE_B | MUX_PAD_CTRL(NAND_PAD_CTRL), 123*876a25d2SStefano Babic MX6_PAD_NANDF_D0__NAND_DATA00 | MUX_PAD_CTRL(NAND_PAD_CTRL), 124*876a25d2SStefano Babic MX6_PAD_NANDF_D1__NAND_DATA01 | MUX_PAD_CTRL(NAND_PAD_CTRL), 125*876a25d2SStefano Babic MX6_PAD_NANDF_D2__NAND_DATA02 | MUX_PAD_CTRL(NAND_PAD_CTRL), 126*876a25d2SStefano Babic MX6_PAD_NANDF_D3__NAND_DATA03 | MUX_PAD_CTRL(NAND_PAD_CTRL), 127*876a25d2SStefano Babic MX6_PAD_NANDF_D4__NAND_DATA04 | MUX_PAD_CTRL(NAND_PAD_CTRL), 128*876a25d2SStefano Babic MX6_PAD_NANDF_D5__NAND_DATA05 | MUX_PAD_CTRL(NAND_PAD_CTRL), 129*876a25d2SStefano Babic MX6_PAD_NANDF_D6__NAND_DATA06 | MUX_PAD_CTRL(NAND_PAD_CTRL), 130*876a25d2SStefano Babic MX6_PAD_NANDF_D7__NAND_DATA07 | MUX_PAD_CTRL(NAND_PAD_CTRL), 131*876a25d2SStefano Babic MX6_PAD_SD4_DAT0__NAND_DQS | MUX_PAD_CTRL(NAND_PAD_CTRL), 132*876a25d2SStefano Babic }; 133*876a25d2SStefano Babic 134*876a25d2SStefano Babic 135*876a25d2SStefano Babic /* GPIOS */ 136*876a25d2SStefano Babic static iomux_v3_cfg_t const gpios_pads[] = { 137*876a25d2SStefano Babic }; 138*876a25d2SStefano Babic 139*876a25d2SStefano Babic static struct i2c_pads_info i2c_pad_info2 = { 140*876a25d2SStefano Babic .scl = { 141*876a25d2SStefano Babic .i2c_mode = MX6_PAD_GPIO_5__I2C3_SCL | I2C_PAD, 142*876a25d2SStefano Babic .gpio_mode = MX6_PAD_GPIO_5__GPIO1_IO05 | I2C_PAD, 143*876a25d2SStefano Babic .gp = IMX_GPIO_NR(1, 5) 144*876a25d2SStefano Babic }, 145*876a25d2SStefano Babic .sda = { 146*876a25d2SStefano Babic .i2c_mode = MX6_PAD_GPIO_6__I2C3_SDA | I2C_PAD, 147*876a25d2SStefano Babic .gpio_mode = MX6_PAD_GPIO_6__GPIO1_IO06 | I2C_PAD, 148*876a25d2SStefano Babic .gp = IMX_GPIO_NR(1, 6) 149*876a25d2SStefano Babic } 150*876a25d2SStefano Babic }; 151*876a25d2SStefano Babic 152*876a25d2SStefano Babic static struct fsl_esdhc_cfg usdhc_cfg[] = { 153*876a25d2SStefano Babic {.esdhc_base = USDHC1_BASE_ADDR, 154*876a25d2SStefano Babic .max_bus_width = 4}, 155*876a25d2SStefano Babic #ifndef CONFIG_CMD_NAND 156*876a25d2SStefano Babic {USDHC4_BASE_ADDR}, 157*876a25d2SStefano Babic #endif 158*876a25d2SStefano Babic }; 159*876a25d2SStefano Babic 160*876a25d2SStefano Babic static iomux_v3_cfg_t const usdhc1_pads[] = { 161*876a25d2SStefano Babic MX6_PAD_SD1_CLK__SD1_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), 162*876a25d2SStefano Babic MX6_PAD_SD1_CMD__SD1_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), 163*876a25d2SStefano Babic MX6_PAD_SD1_DAT0__SD1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 164*876a25d2SStefano Babic MX6_PAD_SD1_DAT1__SD1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 165*876a25d2SStefano Babic MX6_PAD_SD1_DAT2__SD1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 166*876a25d2SStefano Babic MX6_PAD_SD1_DAT3__SD1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 167*876a25d2SStefano Babic MX6_PAD_EIM_BCLK__GPIO6_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */ 168*876a25d2SStefano Babic }; 169*876a25d2SStefano Babic 170*876a25d2SStefano Babic #ifndef CONFIG_CMD_NAND 171*876a25d2SStefano Babic static iomux_v3_cfg_t const usdhc4_pads[] = { 172*876a25d2SStefano Babic MX6_PAD_SD4_CLK__SD4_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), 173*876a25d2SStefano Babic MX6_PAD_SD4_CMD__SD4_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), 174*876a25d2SStefano Babic MX6_PAD_SD4_DAT0__SD4_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 175*876a25d2SStefano Babic MX6_PAD_SD4_DAT1__SD4_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 176*876a25d2SStefano Babic MX6_PAD_SD4_DAT2__SD4_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 177*876a25d2SStefano Babic MX6_PAD_SD4_DAT3__SD4_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 178*876a25d2SStefano Babic MX6_PAD_SD4_DAT4__SD4_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 179*876a25d2SStefano Babic MX6_PAD_SD4_DAT5__SD4_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 180*876a25d2SStefano Babic MX6_PAD_SD4_DAT6__SD4_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 181*876a25d2SStefano Babic MX6_PAD_SD4_DAT7__SD4_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 182*876a25d2SStefano Babic }; 183*876a25d2SStefano Babic #endif 184*876a25d2SStefano Babic 185*876a25d2SStefano Babic int board_mmc_get_env_dev(int devno) 186*876a25d2SStefano Babic { 187*876a25d2SStefano Babic return devno - 1; 188*876a25d2SStefano Babic } 189*876a25d2SStefano Babic 190*876a25d2SStefano Babic int board_mmc_getcd(struct mmc *mmc) 191*876a25d2SStefano Babic { 192*876a25d2SStefano Babic struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; 193*876a25d2SStefano Babic int ret = 0; 194*876a25d2SStefano Babic 195*876a25d2SStefano Babic switch (cfg->esdhc_base) { 196*876a25d2SStefano Babic case USDHC1_BASE_ADDR: 197*876a25d2SStefano Babic ret = !gpio_get_value(USDHC1_CD_GPIO); 198*876a25d2SStefano Babic break; 199*876a25d2SStefano Babic case USDHC4_BASE_ADDR: 200*876a25d2SStefano Babic ret = 1; /* eMMC/uSDHC4 is always present */ 201*876a25d2SStefano Babic break; 202*876a25d2SStefano Babic } 203*876a25d2SStefano Babic 204*876a25d2SStefano Babic return ret; 205*876a25d2SStefano Babic } 206*876a25d2SStefano Babic 207*876a25d2SStefano Babic int board_mmc_init(bd_t *bis) 208*876a25d2SStefano Babic { 209*876a25d2SStefano Babic #ifndef CONFIG_SPL_BUILD 210*876a25d2SStefano Babic int ret; 211*876a25d2SStefano Babic int i; 212*876a25d2SStefano Babic 213*876a25d2SStefano Babic for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) { 214*876a25d2SStefano Babic switch (i) { 215*876a25d2SStefano Babic case 0: 216*876a25d2SStefano Babic imx_iomux_v3_setup_multiple_pads( 217*876a25d2SStefano Babic usdhc1_pads, ARRAY_SIZE(usdhc1_pads)); 218*876a25d2SStefano Babic gpio_direction_input(USDHC1_CD_GPIO); 219*876a25d2SStefano Babic usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); 220*876a25d2SStefano Babic break; 221*876a25d2SStefano Babic #ifndef CONFIG_CMD_NAND 222*876a25d2SStefano Babic case 1: 223*876a25d2SStefano Babic imx_iomux_v3_setup_multiple_pads( 224*876a25d2SStefano Babic usdhc4_pads, ARRAY_SIZE(usdhc4_pads)); 225*876a25d2SStefano Babic usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK); 226*876a25d2SStefano Babic break; 227*876a25d2SStefano Babic #endif 228*876a25d2SStefano Babic default: 229*876a25d2SStefano Babic printf("Warning: you configured more USDHC controllers" 230*876a25d2SStefano Babic "(%d) then supported by the board (%d)\n", 231*876a25d2SStefano Babic i + 1, CONFIG_SYS_FSL_USDHC_NUM); 232*876a25d2SStefano Babic return -EINVAL; 233*876a25d2SStefano Babic } 234*876a25d2SStefano Babic 235*876a25d2SStefano Babic ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]); 236*876a25d2SStefano Babic if (ret) 237*876a25d2SStefano Babic return ret; 238*876a25d2SStefano Babic } 239*876a25d2SStefano Babic 240*876a25d2SStefano Babic return 0; 241*876a25d2SStefano Babic #else 242*876a25d2SStefano Babic struct src *psrc = (struct src *)SRC_BASE_ADDR; 243*876a25d2SStefano Babic unsigned reg = readl(&psrc->sbmr1) >> 11; 244*876a25d2SStefano Babic /* 245*876a25d2SStefano Babic * Upon reading BOOT_CFG register the following map is done: 246*876a25d2SStefano Babic * Bit 11 and 12 of BOOT_CFG register can determine the current 247*876a25d2SStefano Babic * mmc port 248*876a25d2SStefano Babic * 0x1 SD1 249*876a25d2SStefano Babic * 0x2 SD2 250*876a25d2SStefano Babic * 0x3 SD4 251*876a25d2SStefano Babic */ 252*876a25d2SStefano Babic 253*876a25d2SStefano Babic switch (reg & 0x3) { 254*876a25d2SStefano Babic case 0x0: 255*876a25d2SStefano Babic imx_iomux_v3_setup_multiple_pads( 256*876a25d2SStefano Babic usdhc1_pads, ARRAY_SIZE(usdhc1_pads)); 257*876a25d2SStefano Babic gpio_direction_input(USDHC1_CD_GPIO); 258*876a25d2SStefano Babic usdhc_cfg[0].esdhc_base = USDHC1_BASE_ADDR; 259*876a25d2SStefano Babic usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); 260*876a25d2SStefano Babic usdhc_cfg[0].max_bus_width = 4; 261*876a25d2SStefano Babic gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk; 262*876a25d2SStefano Babic break; 263*876a25d2SStefano Babic } 264*876a25d2SStefano Babic return fsl_esdhc_initialize(bis, &usdhc_cfg[0]); 265*876a25d2SStefano Babic #endif 266*876a25d2SStefano Babic } 267*876a25d2SStefano Babic 268*876a25d2SStefano Babic static void setup_iomux_uart(void) 269*876a25d2SStefano Babic { 270*876a25d2SStefano Babic imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads)); 271*876a25d2SStefano Babic } 272*876a25d2SStefano Babic 273*876a25d2SStefano Babic static void setup_iomux_enet(void) 274*876a25d2SStefano Babic { 275*876a25d2SStefano Babic imx_iomux_v3_setup_multiple_pads(enet_pads, ARRAY_SIZE(enet_pads)); 276*876a25d2SStefano Babic 277*876a25d2SStefano Babic gpio_direction_output(ENET_PHY_RESET_GPIO, 0); 278*876a25d2SStefano Babic mdelay(10); 279*876a25d2SStefano Babic gpio_set_value(ENET_PHY_RESET_GPIO, 1); 280*876a25d2SStefano Babic mdelay(30); 281*876a25d2SStefano Babic } 282*876a25d2SStefano Babic 283*876a25d2SStefano Babic static void setup_spi(void) 284*876a25d2SStefano Babic { 285*876a25d2SStefano Babic gpio_request(IMX_GPIO_NR(3, 19), "spi_cs0"); 286*876a25d2SStefano Babic gpio_direction_output(IMX_GPIO_NR(3, 19), 1); 287*876a25d2SStefano Babic 288*876a25d2SStefano Babic imx_iomux_v3_setup_multiple_pads(ecspi1_pads, ARRAY_SIZE(ecspi1_pads)); 289*876a25d2SStefano Babic 290*876a25d2SStefano Babic enable_spi_clk(true, 0); 291*876a25d2SStefano Babic } 292*876a25d2SStefano Babic 293*876a25d2SStefano Babic #ifdef CONFIG_CMD_NAND 294*876a25d2SStefano Babic static void setup_gpmi_nand(void) 295*876a25d2SStefano Babic { 296*876a25d2SStefano Babic struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; 297*876a25d2SStefano Babic 298*876a25d2SStefano Babic /* config gpmi nand iomux */ 299*876a25d2SStefano Babic imx_iomux_v3_setup_multiple_pads(nfc_pads, ARRAY_SIZE(nfc_pads)); 300*876a25d2SStefano Babic 301*876a25d2SStefano Babic /* gate ENFC_CLK_ROOT clock first,before clk source switch */ 302*876a25d2SStefano Babic clrbits_le32(&mxc_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK); 303*876a25d2SStefano Babic 304*876a25d2SStefano Babic /* config gpmi and bch clock to 100 MHz */ 305*876a25d2SStefano Babic clrsetbits_le32(&mxc_ccm->cs2cdr, 306*876a25d2SStefano Babic MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK | 307*876a25d2SStefano Babic MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK | 308*876a25d2SStefano Babic MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK, 309*876a25d2SStefano Babic MXC_CCM_CS2CDR_ENFC_CLK_PODF(0) | 310*876a25d2SStefano Babic MXC_CCM_CS2CDR_ENFC_CLK_PRED(3) | 311*876a25d2SStefano Babic MXC_CCM_CS2CDR_ENFC_CLK_SEL(3)); 312*876a25d2SStefano Babic 313*876a25d2SStefano Babic /* enable ENFC_CLK_ROOT clock */ 314*876a25d2SStefano Babic setbits_le32(&mxc_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK); 315*876a25d2SStefano Babic 316*876a25d2SStefano Babic /* enable gpmi and bch clock gating */ 317*876a25d2SStefano Babic setbits_le32(&mxc_ccm->CCGR4, 318*876a25d2SStefano Babic MXC_CCM_CCGR4_RAWNAND_U_BCH_INPUT_APB_MASK | 319*876a25d2SStefano Babic MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_BCH_MASK | 320*876a25d2SStefano Babic MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK | 321*876a25d2SStefano Babic MXC_CCM_CCGR4_RAWNAND_U_GPMI_INPUT_APB_MASK | 322*876a25d2SStefano Babic MXC_CCM_CCGR4_PL301_MX6QPER1_BCH_OFFSET); 323*876a25d2SStefano Babic 324*876a25d2SStefano Babic /* enable apbh clock gating */ 325*876a25d2SStefano Babic setbits_le32(&mxc_ccm->CCGR0, MXC_CCM_CCGR0_APBHDMA_MASK); 326*876a25d2SStefano Babic } 327*876a25d2SStefano Babic #endif 328*876a25d2SStefano Babic 329*876a25d2SStefano Babic int board_spi_cs_gpio(unsigned bus, unsigned cs) 330*876a25d2SStefano Babic { 331*876a25d2SStefano Babic if (bus != 0 || (cs != 0)) 332*876a25d2SStefano Babic return -EINVAL; 333*876a25d2SStefano Babic 334*876a25d2SStefano Babic return IMX_GPIO_NR(3, 19); 335*876a25d2SStefano Babic } 336*876a25d2SStefano Babic 337*876a25d2SStefano Babic int board_eth_init(bd_t *bis) 338*876a25d2SStefano Babic { 339*876a25d2SStefano Babic setup_iomux_enet(); 340*876a25d2SStefano Babic 341*876a25d2SStefano Babic return cpu_eth_init(bis); 342*876a25d2SStefano Babic } 343*876a25d2SStefano Babic 344*876a25d2SStefano Babic int board_early_init_f(void) 345*876a25d2SStefano Babic { 346*876a25d2SStefano Babic setup_iomux_uart(); 347*876a25d2SStefano Babic 348*876a25d2SStefano Babic return 0; 349*876a25d2SStefano Babic } 350*876a25d2SStefano Babic 351*876a25d2SStefano Babic int board_init(void) 352*876a25d2SStefano Babic { 353*876a25d2SStefano Babic /* address of boot parameters */ 354*876a25d2SStefano Babic gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; 355*876a25d2SStefano Babic 356*876a25d2SStefano Babic #ifdef CONFIG_SYS_I2C_MXC 357*876a25d2SStefano Babic setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2); 358*876a25d2SStefano Babic #endif 359*876a25d2SStefano Babic 360*876a25d2SStefano Babic #ifdef CONFIG_MXC_SPI 361*876a25d2SStefano Babic setup_spi(); 362*876a25d2SStefano Babic #endif 363*876a25d2SStefano Babic 364*876a25d2SStefano Babic #ifdef CONFIG_CMD_NAND 365*876a25d2SStefano Babic setup_gpmi_nand(); 366*876a25d2SStefano Babic #endif 367*876a25d2SStefano Babic return 0; 368*876a25d2SStefano Babic } 369*876a25d2SStefano Babic 370*876a25d2SStefano Babic 371*876a25d2SStefano Babic #ifdef CONFIG_CMD_BMODE 372*876a25d2SStefano Babic /* 373*876a25d2SStefano Babic * BOOT_CFG1, BOOT_CFG2, BOOT_CFG3, BOOT_CFG4 374*876a25d2SStefano Babic * see Table 8-11 and Table 5-9 375*876a25d2SStefano Babic * BOOT_CFG1[7] = 1 (boot from NAND) 376*876a25d2SStefano Babic * BOOT_CFG1[5] = 0 - raw NAND 377*876a25d2SStefano Babic * BOOT_CFG1[4] = 0 - default pad settings 378*876a25d2SStefano Babic * BOOT_CFG1[3:2] = 00 - devices = 1 379*876a25d2SStefano Babic * BOOT_CFG1[1:0] = 00 - Row Address Cycles = 3 380*876a25d2SStefano Babic * BOOT_CFG2[4:3] = 00 - Boot Search Count = 2 381*876a25d2SStefano Babic * BOOT_CFG2[2:1] = 01 - Pages In Block = 64 382*876a25d2SStefano Babic * BOOT_CFG2[0] = 0 - Reset time 12ms 383*876a25d2SStefano Babic */ 384*876a25d2SStefano Babic static const struct boot_mode board_boot_modes[] = { 385*876a25d2SStefano Babic /* NAND: 64pages per block, 3 row addr cycles, 2 copies of FCB/DBBT */ 386*876a25d2SStefano Babic {"nand", MAKE_CFGVAL(0x80, 0x02, 0x00, 0x00)}, 387*876a25d2SStefano Babic {"mmc0", MAKE_CFGVAL(0x40, 0x20, 0x00, 0x00)}, 388*876a25d2SStefano Babic {NULL, 0}, 389*876a25d2SStefano Babic }; 390*876a25d2SStefano Babic #endif 391*876a25d2SStefano Babic 392*876a25d2SStefano Babic int board_late_init(void) 393*876a25d2SStefano Babic { 394*876a25d2SStefano Babic #ifdef CONFIG_CMD_BMODE 395*876a25d2SStefano Babic add_board_boot_modes(board_boot_modes); 396*876a25d2SStefano Babic #endif 397*876a25d2SStefano Babic 398*876a25d2SStefano Babic return 0; 399*876a25d2SStefano Babic } 400*876a25d2SStefano Babic 401*876a25d2SStefano Babic #ifdef CONFIG_SPL_BUILD 402*876a25d2SStefano Babic #include <spl.h> 403*876a25d2SStefano Babic #include <libfdt.h> 404*876a25d2SStefano Babic 405*876a25d2SStefano Babic static const struct mx6dq_iomux_ddr_regs mx6_ddr_ioregs = { 406*876a25d2SStefano Babic .dram_sdclk_0 = 0x00000030, 407*876a25d2SStefano Babic .dram_sdclk_1 = 0x00000030, 408*876a25d2SStefano Babic .dram_cas = 0x00000030, 409*876a25d2SStefano Babic .dram_ras = 0x00000030, 410*876a25d2SStefano Babic .dram_reset = 0x00000030, 411*876a25d2SStefano Babic .dram_sdcke0 = 0x00000030, 412*876a25d2SStefano Babic .dram_sdcke1 = 0x00000030, 413*876a25d2SStefano Babic .dram_sdba2 = 0x00000000, 414*876a25d2SStefano Babic .dram_sdodt0 = 0x00000030, 415*876a25d2SStefano Babic .dram_sdodt1 = 0x00000030, 416*876a25d2SStefano Babic .dram_sdqs0 = 0x00000030, 417*876a25d2SStefano Babic .dram_sdqs1 = 0x00000030, 418*876a25d2SStefano Babic .dram_sdqs2 = 0x00000030, 419*876a25d2SStefano Babic .dram_sdqs3 = 0x00000030, 420*876a25d2SStefano Babic .dram_sdqs4 = 0x00000030, 421*876a25d2SStefano Babic .dram_sdqs5 = 0x00000030, 422*876a25d2SStefano Babic .dram_sdqs6 = 0x00000030, 423*876a25d2SStefano Babic .dram_sdqs7 = 0x00000030, 424*876a25d2SStefano Babic .dram_dqm0 = 0x00000030, 425*876a25d2SStefano Babic .dram_dqm1 = 0x00000030, 426*876a25d2SStefano Babic .dram_dqm2 = 0x00000030, 427*876a25d2SStefano Babic .dram_dqm3 = 0x00000030, 428*876a25d2SStefano Babic .dram_dqm4 = 0x00000030, 429*876a25d2SStefano Babic .dram_dqm5 = 0x00000030, 430*876a25d2SStefano Babic .dram_dqm6 = 0x00000030, 431*876a25d2SStefano Babic .dram_dqm7 = 0x00000030, 432*876a25d2SStefano Babic }; 433*876a25d2SStefano Babic 434*876a25d2SStefano Babic static const struct mx6dq_iomux_grp_regs mx6_grp_ioregs = { 435*876a25d2SStefano Babic .grp_ddr_type = 0x000C0000, 436*876a25d2SStefano Babic .grp_ddrmode_ctl = 0x00020000, 437*876a25d2SStefano Babic .grp_ddrpke = 0x00000000, 438*876a25d2SStefano Babic .grp_addds = IMX6Q_DRIVE_STRENGTH, 439*876a25d2SStefano Babic .grp_ctlds = IMX6Q_DRIVE_STRENGTH, 440*876a25d2SStefano Babic .grp_ddrmode = 0x00020000, 441*876a25d2SStefano Babic .grp_b0ds = IMX6Q_DRIVE_STRENGTH, 442*876a25d2SStefano Babic .grp_b1ds = IMX6Q_DRIVE_STRENGTH, 443*876a25d2SStefano Babic .grp_b2ds = IMX6Q_DRIVE_STRENGTH, 444*876a25d2SStefano Babic .grp_b3ds = IMX6Q_DRIVE_STRENGTH, 445*876a25d2SStefano Babic .grp_b4ds = IMX6Q_DRIVE_STRENGTH, 446*876a25d2SStefano Babic .grp_b5ds = IMX6Q_DRIVE_STRENGTH, 447*876a25d2SStefano Babic .grp_b6ds = IMX6Q_DRIVE_STRENGTH, 448*876a25d2SStefano Babic .grp_b7ds = IMX6Q_DRIVE_STRENGTH, 449*876a25d2SStefano Babic }; 450*876a25d2SStefano Babic 451*876a25d2SStefano Babic static const struct mx6_mmdc_calibration mx6_mmcd_calib = { 452*876a25d2SStefano Babic .p0_mpwldectrl0 = 0x00140014, 453*876a25d2SStefano Babic .p0_mpwldectrl1 = 0x000A0015, 454*876a25d2SStefano Babic .p1_mpwldectrl0 = 0x000A001E, 455*876a25d2SStefano Babic .p1_mpwldectrl1 = 0x000A0015, 456*876a25d2SStefano Babic .p0_mpdgctrl0 = 0x43080314, 457*876a25d2SStefano Babic .p0_mpdgctrl1 = 0x02680300, 458*876a25d2SStefano Babic .p1_mpdgctrl0 = 0x430C0318, 459*876a25d2SStefano Babic .p1_mpdgctrl1 = 0x03000254, 460*876a25d2SStefano Babic .p0_mprddlctl = 0x3A323234, 461*876a25d2SStefano Babic .p1_mprddlctl = 0x3E3C3242, 462*876a25d2SStefano Babic .p0_mpwrdlctl = 0x2A2E3632, 463*876a25d2SStefano Babic .p1_mpwrdlctl = 0x3C323E34, 464*876a25d2SStefano Babic }; 465*876a25d2SStefano Babic 466*876a25d2SStefano Babic static struct mx6_ddr3_cfg mem_ddr = { 467*876a25d2SStefano Babic .mem_speed = 1600, 468*876a25d2SStefano Babic .density = 2, 469*876a25d2SStefano Babic .width = 16, 470*876a25d2SStefano Babic .banks = 8, 471*876a25d2SStefano Babic .rowaddr = 14, 472*876a25d2SStefano Babic .coladdr = 10, 473*876a25d2SStefano Babic .pagesz = 2, 474*876a25d2SStefano Babic .trcd = 1375, 475*876a25d2SStefano Babic .trcmin = 4875, 476*876a25d2SStefano Babic .trasmin = 3500, 477*876a25d2SStefano Babic .SRT = 1, 478*876a25d2SStefano Babic }; 479*876a25d2SStefano Babic 480*876a25d2SStefano Babic static void ccgr_init(void) 481*876a25d2SStefano Babic { 482*876a25d2SStefano Babic struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; 483*876a25d2SStefano Babic 484*876a25d2SStefano Babic writel(0x00C03F3F, &ccm->CCGR0); 485*876a25d2SStefano Babic writel(0x0030FC03, &ccm->CCGR1); 486*876a25d2SStefano Babic writel(0x0FFFC000, &ccm->CCGR2); 487*876a25d2SStefano Babic writel(0x3FF00000, &ccm->CCGR3); 488*876a25d2SStefano Babic writel(0x00FFF300, &ccm->CCGR4); 489*876a25d2SStefano Babic writel(0x0F0000C3, &ccm->CCGR5); 490*876a25d2SStefano Babic writel(0x000003FF, &ccm->CCGR6); 491*876a25d2SStefano Babic } 492*876a25d2SStefano Babic 493*876a25d2SStefano Babic static void gpr_init(void) 494*876a25d2SStefano Babic { 495*876a25d2SStefano Babic struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR; 496*876a25d2SStefano Babic 497*876a25d2SStefano Babic /* enable AXI cache for VDOA/VPU/IPU */ 498*876a25d2SStefano Babic writel(0xF00000CF, &iomux->gpr[4]); 499*876a25d2SStefano Babic /* set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7 */ 500*876a25d2SStefano Babic writel(0x007F007F, &iomux->gpr[6]); 501*876a25d2SStefano Babic writel(0x007F007F, &iomux->gpr[7]); 502*876a25d2SStefano Babic } 503*876a25d2SStefano Babic 504*876a25d2SStefano Babic 505*876a25d2SStefano Babic static void spl_dram_init(void) 506*876a25d2SStefano Babic { 507*876a25d2SStefano Babic struct mx6_ddr_sysinfo sysinfo = { 508*876a25d2SStefano Babic /* width of data bus:0=16,1=32,2=64 */ 509*876a25d2SStefano Babic .dsize = 2, 510*876a25d2SStefano Babic /* config for full 4GB range so that get_mem_size() works */ 511*876a25d2SStefano Babic .cs_density = 32, /* 32Gb per CS */ 512*876a25d2SStefano Babic /* single chip select */ 513*876a25d2SStefano Babic .ncs = 1, 514*876a25d2SStefano Babic .cs1_mirror = 0, 515*876a25d2SStefano Babic .rtt_wr = 1 /*DDR3_RTT_60_OHM*/, /* RTT_Wr = RZQ/4 */ 516*876a25d2SStefano Babic .rtt_nom = 1 /*DDR3_RTT_60_OHM*/, /* RTT_Nom = RZQ/4 */ 517*876a25d2SStefano Babic .walat = 1, /* Write additional latency */ 518*876a25d2SStefano Babic .ralat = 5, /* Read additional latency */ 519*876a25d2SStefano Babic .mif3_mode = 3, /* Command prediction working mode */ 520*876a25d2SStefano Babic .bi_on = 1, /* Bank interleaving enabled */ 521*876a25d2SStefano Babic .sde_to_rst = 0x10, /* 14 cycles, 200us (JEDEC default) */ 522*876a25d2SStefano Babic .rst_to_cke = 0x23, /* 33 cycles, 500us (JEDEC default) */ 523*876a25d2SStefano Babic .ddr_type = DDR_TYPE_DDR3, 524*876a25d2SStefano Babic }; 525*876a25d2SStefano Babic 526*876a25d2SStefano Babic mx6dq_dram_iocfg(64, &mx6_ddr_ioregs, &mx6_grp_ioregs); 527*876a25d2SStefano Babic mx6_dram_cfg(&sysinfo, &mx6_mmcd_calib, &mem_ddr); 528*876a25d2SStefano Babic } 529*876a25d2SStefano Babic 530*876a25d2SStefano Babic void board_boot_order(u32 *spl_boot_list) 531*876a25d2SStefano Babic { 532*876a25d2SStefano Babic spl_boot_list[0] = spl_boot_device(); 533*876a25d2SStefano Babic printf("Boot device %x\n", spl_boot_list[0]); 534*876a25d2SStefano Babic switch (spl_boot_list[0]) { 535*876a25d2SStefano Babic case BOOT_DEVICE_SPI: 536*876a25d2SStefano Babic spl_boot_list[1] = BOOT_DEVICE_UART; 537*876a25d2SStefano Babic break; 538*876a25d2SStefano Babic case BOOT_DEVICE_MMC1: 539*876a25d2SStefano Babic spl_boot_list[1] = BOOT_DEVICE_SPI; 540*876a25d2SStefano Babic spl_boot_list[2] = BOOT_DEVICE_UART; 541*876a25d2SStefano Babic break; 542*876a25d2SStefano Babic default: 543*876a25d2SStefano Babic printf("Boot device %x\n", spl_boot_list[0]); 544*876a25d2SStefano Babic } 545*876a25d2SStefano Babic } 546*876a25d2SStefano Babic 547*876a25d2SStefano Babic void board_init_f(ulong dummy) 548*876a25d2SStefano Babic { 549*876a25d2SStefano Babic #ifdef CONFIG_CMD_NAND 550*876a25d2SStefano Babic /* Enable NAND */ 551*876a25d2SStefano Babic setup_gpmi_nand(); 552*876a25d2SStefano Babic #endif 553*876a25d2SStefano Babic 554*876a25d2SStefano Babic /* setup clock gating */ 555*876a25d2SStefano Babic ccgr_init(); 556*876a25d2SStefano Babic 557*876a25d2SStefano Babic /* setup AIPS and disable watchdog */ 558*876a25d2SStefano Babic arch_cpu_init(); 559*876a25d2SStefano Babic 560*876a25d2SStefano Babic /* setup AXI */ 561*876a25d2SStefano Babic gpr_init(); 562*876a25d2SStefano Babic 563*876a25d2SStefano Babic board_early_init_f(); 564*876a25d2SStefano Babic 565*876a25d2SStefano Babic /* setup GP timer */ 566*876a25d2SStefano Babic timer_init(); 567*876a25d2SStefano Babic 568*876a25d2SStefano Babic setup_spi(); 569*876a25d2SStefano Babic 570*876a25d2SStefano Babic /* UART clocks enabled and gd valid - init serial console */ 571*876a25d2SStefano Babic preloader_console_init(); 572*876a25d2SStefano Babic 573*876a25d2SStefano Babic /* DDR initialization */ 574*876a25d2SStefano Babic spl_dram_init(); 575*876a25d2SStefano Babic 576*876a25d2SStefano Babic /* Clear the BSS. */ 577*876a25d2SStefano Babic memset(__bss_start, 0, __bss_end - __bss_start); 578*876a25d2SStefano Babic 579*876a25d2SStefano Babic /* load/boot image from boot device */ 580*876a25d2SStefano Babic board_init_r(NULL, 0); 581*876a25d2SStefano Babic } 582*876a25d2SStefano Babic #endif 583