1876a25d2SStefano Babic /* 2876a25d2SStefano Babic * Copyright (C) 2016 Stefano Babic <sbabic@denx.de> 3876a25d2SStefano Babic * 4876a25d2SStefano Babic * SPDX-License-Identifier: GPL-2.0+ 5876a25d2SStefano Babic */ 6876a25d2SStefano Babic 7876a25d2SStefano Babic /* 8876a25d2SStefano Babic * Please note: there are two version of the board 9876a25d2SStefano Babic * one with NAND and the other with eMMC. 10876a25d2SStefano Babic * Both NAND and eMMC cannot be set because they share the 11876a25d2SStefano Babic * same pins (SD4) 12876a25d2SStefano Babic */ 13876a25d2SStefano Babic #include <common.h> 14876a25d2SStefano Babic #include <asm/io.h> 15876a25d2SStefano Babic #include <asm/arch/clock.h> 16876a25d2SStefano Babic #include <asm/arch/imx-regs.h> 17876a25d2SStefano Babic #include <asm/arch/crm_regs.h> 18876a25d2SStefano Babic #include <asm/arch/mx6-ddr.h> 19876a25d2SStefano Babic #include <asm/arch/iomux.h> 20876a25d2SStefano Babic #include <asm/arch/mx6-pins.h> 21876a25d2SStefano Babic #include <asm/imx-common/iomux-v3.h> 22876a25d2SStefano Babic #include <asm/imx-common/boot_mode.h> 23876a25d2SStefano Babic #include <asm/imx-common/mxc_i2c.h> 24876a25d2SStefano Babic #include <asm/imx-common/spi.h> 251221ce45SMasahiro Yamada #include <linux/errno.h> 26876a25d2SStefano Babic #include <asm/gpio.h> 27876a25d2SStefano Babic #include <mmc.h> 28876a25d2SStefano Babic #include <i2c.h> 29876a25d2SStefano Babic #include <fsl_esdhc.h> 30876a25d2SStefano Babic #include <nand.h> 31876a25d2SStefano Babic #include <miiphy.h> 32876a25d2SStefano Babic #include <netdev.h> 33876a25d2SStefano Babic #include <asm/arch/sys_proto.h> 34876a25d2SStefano Babic #include <asm/sections.h> 35876a25d2SStefano Babic 36876a25d2SStefano Babic DECLARE_GLOBAL_DATA_PTR; 37876a25d2SStefano Babic 38876a25d2SStefano Babic #define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ 39876a25d2SStefano Babic PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \ 40876a25d2SStefano Babic PAD_CTL_SRE_FAST | PAD_CTL_HYS) 41876a25d2SStefano Babic 42876a25d2SStefano Babic #define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | \ 43876a25d2SStefano Babic PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm | \ 44876a25d2SStefano Babic PAD_CTL_SRE_FAST | PAD_CTL_HYS) 45876a25d2SStefano Babic 46876a25d2SStefano Babic #define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ 47876a25d2SStefano Babic PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS) 48876a25d2SStefano Babic 49876a25d2SStefano Babic #define SPI_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_SPEED_MED | \ 50876a25d2SStefano Babic PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST) 51876a25d2SStefano Babic 52876a25d2SStefano Babic #define I2C_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ 53876a25d2SStefano Babic PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \ 54876a25d2SStefano Babic PAD_CTL_ODE | PAD_CTL_SRE_FAST) 55876a25d2SStefano Babic 56876a25d2SStefano Babic #define I2C_PAD MUX_PAD_CTRL(I2C_PAD_CTRL) 57876a25d2SStefano Babic 58876a25d2SStefano Babic #define ASRC_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | \ 59876a25d2SStefano Babic PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST) 60876a25d2SStefano Babic 61876a25d2SStefano Babic #define NAND_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ 62876a25d2SStefano Babic PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST) 63876a25d2SStefano Babic 64876a25d2SStefano Babic #define ENET_PHY_RESET_GPIO IMX_GPIO_NR(1, 14) 65876a25d2SStefano Babic #define USDHC1_CD_GPIO IMX_GPIO_NR(6, 31) 66876a25d2SStefano Babic #define USER_LED IMX_GPIO_NR(1, 4) 67876a25d2SStefano Babic #define IMX6Q_DRIVE_STRENGTH 0x30 68876a25d2SStefano Babic 69876a25d2SStefano Babic int dram_init(void) 70876a25d2SStefano Babic { 71876a25d2SStefano Babic gd->ram_size = imx_ddr_size(); 72876a25d2SStefano Babic return 0; 73876a25d2SStefano Babic } 74876a25d2SStefano Babic 75876a25d2SStefano Babic void board_turn_off_led(void) 76876a25d2SStefano Babic { 77876a25d2SStefano Babic gpio_direction_output(USER_LED, 0); 78876a25d2SStefano Babic } 79876a25d2SStefano Babic 80876a25d2SStefano Babic static iomux_v3_cfg_t const uart1_pads[] = { 81876a25d2SStefano Babic MX6_PAD_EIM_D26__UART2_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), 82876a25d2SStefano Babic MX6_PAD_EIM_D27__UART2_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), 83876a25d2SStefano Babic }; 84876a25d2SStefano Babic 85876a25d2SStefano Babic static iomux_v3_cfg_t const enet_pads[] = { 86876a25d2SStefano Babic MX6_PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL), 87876a25d2SStefano Babic MX6_PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL), 88876a25d2SStefano Babic MX6_PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL), 89876a25d2SStefano Babic MX6_PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL), 90876a25d2SStefano Babic MX6_PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL), 91876a25d2SStefano Babic MX6_PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL), 92876a25d2SStefano Babic MX6_PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL), 93876a25d2SStefano Babic MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL), 94876a25d2SStefano Babic MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL), 95876a25d2SStefano Babic MX6_PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL), 96876a25d2SStefano Babic MX6_PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL), 97876a25d2SStefano Babic MX6_PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL), 98876a25d2SStefano Babic MX6_PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL), 99876a25d2SStefano Babic MX6_PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL), 100876a25d2SStefano Babic MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL), 101876a25d2SStefano Babic MX6_PAD_SD2_DAT1__GPIO1_IO14 | MUX_PAD_CTRL(NO_PAD_CTRL), 102876a25d2SStefano Babic }; 103876a25d2SStefano Babic 104876a25d2SStefano Babic static iomux_v3_cfg_t const ecspi1_pads[] = { 105876a25d2SStefano Babic MX6_PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL), 106876a25d2SStefano Babic MX6_PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL), 107876a25d2SStefano Babic MX6_PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL), 108876a25d2SStefano Babic MX6_PAD_EIM_D19__GPIO3_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL), 109876a25d2SStefano Babic }; 110876a25d2SStefano Babic 111*b3cf4339STom Rini #ifdef CONFIG_CMD_NAND 112876a25d2SStefano Babic /* NAND */ 113876a25d2SStefano Babic static iomux_v3_cfg_t const nfc_pads[] = { 114876a25d2SStefano Babic MX6_PAD_NANDF_CLE__NAND_CLE | MUX_PAD_CTRL(NAND_PAD_CTRL), 115876a25d2SStefano Babic MX6_PAD_NANDF_ALE__NAND_ALE | MUX_PAD_CTRL(NAND_PAD_CTRL), 116876a25d2SStefano Babic MX6_PAD_NANDF_WP_B__NAND_WP_B | MUX_PAD_CTRL(NAND_PAD_CTRL), 117876a25d2SStefano Babic MX6_PAD_NANDF_RB0__NAND_READY_B | MUX_PAD_CTRL(NAND_PAD_CTRL), 118876a25d2SStefano Babic MX6_PAD_NANDF_CS0__NAND_CE0_B | MUX_PAD_CTRL(NAND_PAD_CTRL), 119876a25d2SStefano Babic MX6_PAD_NANDF_CS1__NAND_CE1_B | MUX_PAD_CTRL(NAND_PAD_CTRL), 120876a25d2SStefano Babic MX6_PAD_NANDF_CS2__NAND_CE2_B | MUX_PAD_CTRL(NAND_PAD_CTRL), 121876a25d2SStefano Babic MX6_PAD_NANDF_CS3__NAND_CE3_B | MUX_PAD_CTRL(NAND_PAD_CTRL), 122876a25d2SStefano Babic MX6_PAD_SD4_CMD__NAND_RE_B | MUX_PAD_CTRL(NAND_PAD_CTRL), 123876a25d2SStefano Babic MX6_PAD_SD4_CLK__NAND_WE_B | MUX_PAD_CTRL(NAND_PAD_CTRL), 124876a25d2SStefano Babic MX6_PAD_NANDF_D0__NAND_DATA00 | MUX_PAD_CTRL(NAND_PAD_CTRL), 125876a25d2SStefano Babic MX6_PAD_NANDF_D1__NAND_DATA01 | MUX_PAD_CTRL(NAND_PAD_CTRL), 126876a25d2SStefano Babic MX6_PAD_NANDF_D2__NAND_DATA02 | MUX_PAD_CTRL(NAND_PAD_CTRL), 127876a25d2SStefano Babic MX6_PAD_NANDF_D3__NAND_DATA03 | MUX_PAD_CTRL(NAND_PAD_CTRL), 128876a25d2SStefano Babic MX6_PAD_NANDF_D4__NAND_DATA04 | MUX_PAD_CTRL(NAND_PAD_CTRL), 129876a25d2SStefano Babic MX6_PAD_NANDF_D5__NAND_DATA05 | MUX_PAD_CTRL(NAND_PAD_CTRL), 130876a25d2SStefano Babic MX6_PAD_NANDF_D6__NAND_DATA06 | MUX_PAD_CTRL(NAND_PAD_CTRL), 131876a25d2SStefano Babic MX6_PAD_NANDF_D7__NAND_DATA07 | MUX_PAD_CTRL(NAND_PAD_CTRL), 132876a25d2SStefano Babic MX6_PAD_SD4_DAT0__NAND_DQS | MUX_PAD_CTRL(NAND_PAD_CTRL), 133876a25d2SStefano Babic }; 134*b3cf4339STom Rini #endif 135876a25d2SStefano Babic 136876a25d2SStefano Babic static struct i2c_pads_info i2c_pad_info2 = { 137876a25d2SStefano Babic .scl = { 138876a25d2SStefano Babic .i2c_mode = MX6_PAD_GPIO_5__I2C3_SCL | I2C_PAD, 139876a25d2SStefano Babic .gpio_mode = MX6_PAD_GPIO_5__GPIO1_IO05 | I2C_PAD, 140876a25d2SStefano Babic .gp = IMX_GPIO_NR(1, 5) 141876a25d2SStefano Babic }, 142876a25d2SStefano Babic .sda = { 143876a25d2SStefano Babic .i2c_mode = MX6_PAD_GPIO_6__I2C3_SDA | I2C_PAD, 144876a25d2SStefano Babic .gpio_mode = MX6_PAD_GPIO_6__GPIO1_IO06 | I2C_PAD, 145876a25d2SStefano Babic .gp = IMX_GPIO_NR(1, 6) 146876a25d2SStefano Babic } 147876a25d2SStefano Babic }; 148876a25d2SStefano Babic 149876a25d2SStefano Babic static struct fsl_esdhc_cfg usdhc_cfg[] = { 150876a25d2SStefano Babic {.esdhc_base = USDHC1_BASE_ADDR, 151876a25d2SStefano Babic .max_bus_width = 4}, 152876a25d2SStefano Babic #ifndef CONFIG_CMD_NAND 153876a25d2SStefano Babic {USDHC4_BASE_ADDR}, 154876a25d2SStefano Babic #endif 155876a25d2SStefano Babic }; 156876a25d2SStefano Babic 157876a25d2SStefano Babic static iomux_v3_cfg_t const usdhc1_pads[] = { 158876a25d2SStefano Babic MX6_PAD_SD1_CLK__SD1_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), 159876a25d2SStefano Babic MX6_PAD_SD1_CMD__SD1_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), 160876a25d2SStefano Babic MX6_PAD_SD1_DAT0__SD1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 161876a25d2SStefano Babic MX6_PAD_SD1_DAT1__SD1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 162876a25d2SStefano Babic MX6_PAD_SD1_DAT2__SD1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 163876a25d2SStefano Babic MX6_PAD_SD1_DAT3__SD1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 164876a25d2SStefano Babic MX6_PAD_EIM_BCLK__GPIO6_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */ 165876a25d2SStefano Babic }; 166876a25d2SStefano Babic 167*b3cf4339STom Rini #if !defined(CONFIG_CMD_NAND) && !defined(CONFIG_SPL_BUILD) 168876a25d2SStefano Babic static iomux_v3_cfg_t const usdhc4_pads[] = { 169876a25d2SStefano Babic MX6_PAD_SD4_CLK__SD4_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), 170876a25d2SStefano Babic MX6_PAD_SD4_CMD__SD4_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), 171876a25d2SStefano Babic MX6_PAD_SD4_DAT0__SD4_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 172876a25d2SStefano Babic MX6_PAD_SD4_DAT1__SD4_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 173876a25d2SStefano Babic MX6_PAD_SD4_DAT2__SD4_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 174876a25d2SStefano Babic MX6_PAD_SD4_DAT3__SD4_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 175876a25d2SStefano Babic MX6_PAD_SD4_DAT4__SD4_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 176876a25d2SStefano Babic MX6_PAD_SD4_DAT5__SD4_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 177876a25d2SStefano Babic MX6_PAD_SD4_DAT6__SD4_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 178876a25d2SStefano Babic MX6_PAD_SD4_DAT7__SD4_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL), 179876a25d2SStefano Babic }; 180876a25d2SStefano Babic #endif 181876a25d2SStefano Babic 182876a25d2SStefano Babic int board_mmc_get_env_dev(int devno) 183876a25d2SStefano Babic { 184876a25d2SStefano Babic return devno - 1; 185876a25d2SStefano Babic } 186876a25d2SStefano Babic 187876a25d2SStefano Babic int board_mmc_getcd(struct mmc *mmc) 188876a25d2SStefano Babic { 189876a25d2SStefano Babic struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; 190876a25d2SStefano Babic int ret = 0; 191876a25d2SStefano Babic 192876a25d2SStefano Babic switch (cfg->esdhc_base) { 193876a25d2SStefano Babic case USDHC1_BASE_ADDR: 194876a25d2SStefano Babic ret = !gpio_get_value(USDHC1_CD_GPIO); 195876a25d2SStefano Babic break; 196876a25d2SStefano Babic case USDHC4_BASE_ADDR: 197876a25d2SStefano Babic ret = 1; /* eMMC/uSDHC4 is always present */ 198876a25d2SStefano Babic break; 199876a25d2SStefano Babic } 200876a25d2SStefano Babic 201876a25d2SStefano Babic return ret; 202876a25d2SStefano Babic } 203876a25d2SStefano Babic 204876a25d2SStefano Babic int board_mmc_init(bd_t *bis) 205876a25d2SStefano Babic { 206876a25d2SStefano Babic #ifndef CONFIG_SPL_BUILD 207876a25d2SStefano Babic int ret; 208876a25d2SStefano Babic int i; 209876a25d2SStefano Babic 210876a25d2SStefano Babic for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) { 211876a25d2SStefano Babic switch (i) { 212876a25d2SStefano Babic case 0: 213876a25d2SStefano Babic imx_iomux_v3_setup_multiple_pads( 214876a25d2SStefano Babic usdhc1_pads, ARRAY_SIZE(usdhc1_pads)); 215876a25d2SStefano Babic gpio_direction_input(USDHC1_CD_GPIO); 216876a25d2SStefano Babic usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); 217876a25d2SStefano Babic break; 218876a25d2SStefano Babic #ifndef CONFIG_CMD_NAND 219876a25d2SStefano Babic case 1: 220876a25d2SStefano Babic imx_iomux_v3_setup_multiple_pads( 221876a25d2SStefano Babic usdhc4_pads, ARRAY_SIZE(usdhc4_pads)); 222876a25d2SStefano Babic usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK); 223876a25d2SStefano Babic break; 224876a25d2SStefano Babic #endif 225876a25d2SStefano Babic default: 226876a25d2SStefano Babic printf("Warning: you configured more USDHC controllers" 227876a25d2SStefano Babic "(%d) then supported by the board (%d)\n", 228876a25d2SStefano Babic i + 1, CONFIG_SYS_FSL_USDHC_NUM); 229876a25d2SStefano Babic return -EINVAL; 230876a25d2SStefano Babic } 231876a25d2SStefano Babic 232876a25d2SStefano Babic ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]); 233876a25d2SStefano Babic if (ret) 234876a25d2SStefano Babic return ret; 235876a25d2SStefano Babic } 236876a25d2SStefano Babic 237876a25d2SStefano Babic return 0; 238876a25d2SStefano Babic #else 239876a25d2SStefano Babic struct src *psrc = (struct src *)SRC_BASE_ADDR; 240876a25d2SStefano Babic unsigned reg = readl(&psrc->sbmr1) >> 11; 241876a25d2SStefano Babic /* 242876a25d2SStefano Babic * Upon reading BOOT_CFG register the following map is done: 243876a25d2SStefano Babic * Bit 11 and 12 of BOOT_CFG register can determine the current 244876a25d2SStefano Babic * mmc port 245876a25d2SStefano Babic * 0x1 SD1 246876a25d2SStefano Babic * 0x2 SD2 247876a25d2SStefano Babic * 0x3 SD4 248876a25d2SStefano Babic */ 249876a25d2SStefano Babic 250876a25d2SStefano Babic switch (reg & 0x3) { 251876a25d2SStefano Babic case 0x0: 252876a25d2SStefano Babic imx_iomux_v3_setup_multiple_pads( 253876a25d2SStefano Babic usdhc1_pads, ARRAY_SIZE(usdhc1_pads)); 254876a25d2SStefano Babic gpio_direction_input(USDHC1_CD_GPIO); 255876a25d2SStefano Babic usdhc_cfg[0].esdhc_base = USDHC1_BASE_ADDR; 256876a25d2SStefano Babic usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); 257876a25d2SStefano Babic usdhc_cfg[0].max_bus_width = 4; 258876a25d2SStefano Babic gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk; 259876a25d2SStefano Babic break; 260876a25d2SStefano Babic } 261876a25d2SStefano Babic return fsl_esdhc_initialize(bis, &usdhc_cfg[0]); 262876a25d2SStefano Babic #endif 263876a25d2SStefano Babic } 264876a25d2SStefano Babic 265876a25d2SStefano Babic static void setup_iomux_uart(void) 266876a25d2SStefano Babic { 267876a25d2SStefano Babic imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads)); 268876a25d2SStefano Babic } 269876a25d2SStefano Babic 270876a25d2SStefano Babic static void setup_iomux_enet(void) 271876a25d2SStefano Babic { 272876a25d2SStefano Babic imx_iomux_v3_setup_multiple_pads(enet_pads, ARRAY_SIZE(enet_pads)); 273876a25d2SStefano Babic 274876a25d2SStefano Babic gpio_direction_output(ENET_PHY_RESET_GPIO, 0); 275876a25d2SStefano Babic mdelay(10); 276876a25d2SStefano Babic gpio_set_value(ENET_PHY_RESET_GPIO, 1); 277876a25d2SStefano Babic mdelay(30); 278876a25d2SStefano Babic } 279876a25d2SStefano Babic 280876a25d2SStefano Babic static void setup_spi(void) 281876a25d2SStefano Babic { 282876a25d2SStefano Babic gpio_request(IMX_GPIO_NR(3, 19), "spi_cs0"); 283876a25d2SStefano Babic gpio_direction_output(IMX_GPIO_NR(3, 19), 1); 284876a25d2SStefano Babic 285876a25d2SStefano Babic imx_iomux_v3_setup_multiple_pads(ecspi1_pads, ARRAY_SIZE(ecspi1_pads)); 286876a25d2SStefano Babic 287876a25d2SStefano Babic enable_spi_clk(true, 0); 288876a25d2SStefano Babic } 289876a25d2SStefano Babic 290876a25d2SStefano Babic #ifdef CONFIG_CMD_NAND 291876a25d2SStefano Babic static void setup_gpmi_nand(void) 292876a25d2SStefano Babic { 293876a25d2SStefano Babic struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; 294876a25d2SStefano Babic 295876a25d2SStefano Babic /* config gpmi nand iomux */ 296876a25d2SStefano Babic imx_iomux_v3_setup_multiple_pads(nfc_pads, ARRAY_SIZE(nfc_pads)); 297876a25d2SStefano Babic 298876a25d2SStefano Babic /* gate ENFC_CLK_ROOT clock first,before clk source switch */ 299876a25d2SStefano Babic clrbits_le32(&mxc_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK); 300876a25d2SStefano Babic 301876a25d2SStefano Babic /* config gpmi and bch clock to 100 MHz */ 302876a25d2SStefano Babic clrsetbits_le32(&mxc_ccm->cs2cdr, 303876a25d2SStefano Babic MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK | 304876a25d2SStefano Babic MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK | 305876a25d2SStefano Babic MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK, 306876a25d2SStefano Babic MXC_CCM_CS2CDR_ENFC_CLK_PODF(0) | 307876a25d2SStefano Babic MXC_CCM_CS2CDR_ENFC_CLK_PRED(3) | 308876a25d2SStefano Babic MXC_CCM_CS2CDR_ENFC_CLK_SEL(3)); 309876a25d2SStefano Babic 310876a25d2SStefano Babic /* enable ENFC_CLK_ROOT clock */ 311876a25d2SStefano Babic setbits_le32(&mxc_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK); 312876a25d2SStefano Babic 313876a25d2SStefano Babic /* enable gpmi and bch clock gating */ 314876a25d2SStefano Babic setbits_le32(&mxc_ccm->CCGR4, 315876a25d2SStefano Babic MXC_CCM_CCGR4_RAWNAND_U_BCH_INPUT_APB_MASK | 316876a25d2SStefano Babic MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_BCH_MASK | 317876a25d2SStefano Babic MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK | 318876a25d2SStefano Babic MXC_CCM_CCGR4_RAWNAND_U_GPMI_INPUT_APB_MASK | 319876a25d2SStefano Babic MXC_CCM_CCGR4_PL301_MX6QPER1_BCH_OFFSET); 320876a25d2SStefano Babic 321876a25d2SStefano Babic /* enable apbh clock gating */ 322876a25d2SStefano Babic setbits_le32(&mxc_ccm->CCGR0, MXC_CCM_CCGR0_APBHDMA_MASK); 323876a25d2SStefano Babic } 324876a25d2SStefano Babic #endif 325876a25d2SStefano Babic 326876a25d2SStefano Babic int board_spi_cs_gpio(unsigned bus, unsigned cs) 327876a25d2SStefano Babic { 328876a25d2SStefano Babic if (bus != 0 || (cs != 0)) 329876a25d2SStefano Babic return -EINVAL; 330876a25d2SStefano Babic 331876a25d2SStefano Babic return IMX_GPIO_NR(3, 19); 332876a25d2SStefano Babic } 333876a25d2SStefano Babic 334876a25d2SStefano Babic int board_eth_init(bd_t *bis) 335876a25d2SStefano Babic { 336876a25d2SStefano Babic setup_iomux_enet(); 337876a25d2SStefano Babic 338876a25d2SStefano Babic return cpu_eth_init(bis); 339876a25d2SStefano Babic } 340876a25d2SStefano Babic 341876a25d2SStefano Babic int board_early_init_f(void) 342876a25d2SStefano Babic { 343876a25d2SStefano Babic setup_iomux_uart(); 344876a25d2SStefano Babic 345876a25d2SStefano Babic return 0; 346876a25d2SStefano Babic } 347876a25d2SStefano Babic 348876a25d2SStefano Babic int board_init(void) 349876a25d2SStefano Babic { 350876a25d2SStefano Babic /* address of boot parameters */ 351876a25d2SStefano Babic gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; 352876a25d2SStefano Babic 353876a25d2SStefano Babic #ifdef CONFIG_SYS_I2C_MXC 354876a25d2SStefano Babic setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2); 355876a25d2SStefano Babic #endif 356876a25d2SStefano Babic 357876a25d2SStefano Babic #ifdef CONFIG_MXC_SPI 358876a25d2SStefano Babic setup_spi(); 359876a25d2SStefano Babic #endif 360876a25d2SStefano Babic 361876a25d2SStefano Babic #ifdef CONFIG_CMD_NAND 362876a25d2SStefano Babic setup_gpmi_nand(); 363876a25d2SStefano Babic #endif 364876a25d2SStefano Babic return 0; 365876a25d2SStefano Babic } 366876a25d2SStefano Babic 367876a25d2SStefano Babic 368876a25d2SStefano Babic #ifdef CONFIG_CMD_BMODE 369876a25d2SStefano Babic /* 370876a25d2SStefano Babic * BOOT_CFG1, BOOT_CFG2, BOOT_CFG3, BOOT_CFG4 371876a25d2SStefano Babic * see Table 8-11 and Table 5-9 372876a25d2SStefano Babic * BOOT_CFG1[7] = 1 (boot from NAND) 373876a25d2SStefano Babic * BOOT_CFG1[5] = 0 - raw NAND 374876a25d2SStefano Babic * BOOT_CFG1[4] = 0 - default pad settings 375876a25d2SStefano Babic * BOOT_CFG1[3:2] = 00 - devices = 1 376876a25d2SStefano Babic * BOOT_CFG1[1:0] = 00 - Row Address Cycles = 3 377876a25d2SStefano Babic * BOOT_CFG2[4:3] = 00 - Boot Search Count = 2 378876a25d2SStefano Babic * BOOT_CFG2[2:1] = 01 - Pages In Block = 64 379876a25d2SStefano Babic * BOOT_CFG2[0] = 0 - Reset time 12ms 380876a25d2SStefano Babic */ 381876a25d2SStefano Babic static const struct boot_mode board_boot_modes[] = { 382876a25d2SStefano Babic /* NAND: 64pages per block, 3 row addr cycles, 2 copies of FCB/DBBT */ 383876a25d2SStefano Babic {"nand", MAKE_CFGVAL(0x80, 0x02, 0x00, 0x00)}, 384876a25d2SStefano Babic {"mmc0", MAKE_CFGVAL(0x40, 0x20, 0x00, 0x00)}, 385876a25d2SStefano Babic {NULL, 0}, 386876a25d2SStefano Babic }; 387876a25d2SStefano Babic #endif 388876a25d2SStefano Babic 389876a25d2SStefano Babic int board_late_init(void) 390876a25d2SStefano Babic { 391876a25d2SStefano Babic #ifdef CONFIG_CMD_BMODE 392876a25d2SStefano Babic add_board_boot_modes(board_boot_modes); 393876a25d2SStefano Babic #endif 394876a25d2SStefano Babic 395876a25d2SStefano Babic return 0; 396876a25d2SStefano Babic } 397876a25d2SStefano Babic 398876a25d2SStefano Babic #ifdef CONFIG_SPL_BUILD 399876a25d2SStefano Babic #include <spl.h> 400876a25d2SStefano Babic #include <libfdt.h> 401876a25d2SStefano Babic 402876a25d2SStefano Babic static const struct mx6dq_iomux_ddr_regs mx6_ddr_ioregs = { 403876a25d2SStefano Babic .dram_sdclk_0 = 0x00000030, 404876a25d2SStefano Babic .dram_sdclk_1 = 0x00000030, 405876a25d2SStefano Babic .dram_cas = 0x00000030, 406876a25d2SStefano Babic .dram_ras = 0x00000030, 407876a25d2SStefano Babic .dram_reset = 0x00000030, 408876a25d2SStefano Babic .dram_sdcke0 = 0x00000030, 409876a25d2SStefano Babic .dram_sdcke1 = 0x00000030, 410876a25d2SStefano Babic .dram_sdba2 = 0x00000000, 411876a25d2SStefano Babic .dram_sdodt0 = 0x00000030, 412876a25d2SStefano Babic .dram_sdodt1 = 0x00000030, 413876a25d2SStefano Babic .dram_sdqs0 = 0x00000030, 414876a25d2SStefano Babic .dram_sdqs1 = 0x00000030, 415876a25d2SStefano Babic .dram_sdqs2 = 0x00000030, 416876a25d2SStefano Babic .dram_sdqs3 = 0x00000030, 417876a25d2SStefano Babic .dram_sdqs4 = 0x00000030, 418876a25d2SStefano Babic .dram_sdqs5 = 0x00000030, 419876a25d2SStefano Babic .dram_sdqs6 = 0x00000030, 420876a25d2SStefano Babic .dram_sdqs7 = 0x00000030, 421876a25d2SStefano Babic .dram_dqm0 = 0x00000030, 422876a25d2SStefano Babic .dram_dqm1 = 0x00000030, 423876a25d2SStefano Babic .dram_dqm2 = 0x00000030, 424876a25d2SStefano Babic .dram_dqm3 = 0x00000030, 425876a25d2SStefano Babic .dram_dqm4 = 0x00000030, 426876a25d2SStefano Babic .dram_dqm5 = 0x00000030, 427876a25d2SStefano Babic .dram_dqm6 = 0x00000030, 428876a25d2SStefano Babic .dram_dqm7 = 0x00000030, 429876a25d2SStefano Babic }; 430876a25d2SStefano Babic 431876a25d2SStefano Babic static const struct mx6dq_iomux_grp_regs mx6_grp_ioregs = { 432876a25d2SStefano Babic .grp_ddr_type = 0x000C0000, 433876a25d2SStefano Babic .grp_ddrmode_ctl = 0x00020000, 434876a25d2SStefano Babic .grp_ddrpke = 0x00000000, 435876a25d2SStefano Babic .grp_addds = IMX6Q_DRIVE_STRENGTH, 436876a25d2SStefano Babic .grp_ctlds = IMX6Q_DRIVE_STRENGTH, 437876a25d2SStefano Babic .grp_ddrmode = 0x00020000, 438876a25d2SStefano Babic .grp_b0ds = IMX6Q_DRIVE_STRENGTH, 439876a25d2SStefano Babic .grp_b1ds = IMX6Q_DRIVE_STRENGTH, 440876a25d2SStefano Babic .grp_b2ds = IMX6Q_DRIVE_STRENGTH, 441876a25d2SStefano Babic .grp_b3ds = IMX6Q_DRIVE_STRENGTH, 442876a25d2SStefano Babic .grp_b4ds = IMX6Q_DRIVE_STRENGTH, 443876a25d2SStefano Babic .grp_b5ds = IMX6Q_DRIVE_STRENGTH, 444876a25d2SStefano Babic .grp_b6ds = IMX6Q_DRIVE_STRENGTH, 445876a25d2SStefano Babic .grp_b7ds = IMX6Q_DRIVE_STRENGTH, 446876a25d2SStefano Babic }; 447876a25d2SStefano Babic 448876a25d2SStefano Babic static const struct mx6_mmdc_calibration mx6_mmcd_calib = { 449876a25d2SStefano Babic .p0_mpwldectrl0 = 0x00140014, 450876a25d2SStefano Babic .p0_mpwldectrl1 = 0x000A0015, 451876a25d2SStefano Babic .p1_mpwldectrl0 = 0x000A001E, 452876a25d2SStefano Babic .p1_mpwldectrl1 = 0x000A0015, 453876a25d2SStefano Babic .p0_mpdgctrl0 = 0x43080314, 454876a25d2SStefano Babic .p0_mpdgctrl1 = 0x02680300, 455876a25d2SStefano Babic .p1_mpdgctrl0 = 0x430C0318, 456876a25d2SStefano Babic .p1_mpdgctrl1 = 0x03000254, 457876a25d2SStefano Babic .p0_mprddlctl = 0x3A323234, 458876a25d2SStefano Babic .p1_mprddlctl = 0x3E3C3242, 459876a25d2SStefano Babic .p0_mpwrdlctl = 0x2A2E3632, 460876a25d2SStefano Babic .p1_mpwrdlctl = 0x3C323E34, 461876a25d2SStefano Babic }; 462876a25d2SStefano Babic 463876a25d2SStefano Babic static struct mx6_ddr3_cfg mem_ddr = { 464876a25d2SStefano Babic .mem_speed = 1600, 465876a25d2SStefano Babic .density = 2, 466876a25d2SStefano Babic .width = 16, 467876a25d2SStefano Babic .banks = 8, 468876a25d2SStefano Babic .rowaddr = 14, 469876a25d2SStefano Babic .coladdr = 10, 470876a25d2SStefano Babic .pagesz = 2, 471876a25d2SStefano Babic .trcd = 1375, 472876a25d2SStefano Babic .trcmin = 4875, 473876a25d2SStefano Babic .trasmin = 3500, 474876a25d2SStefano Babic .SRT = 1, 475876a25d2SStefano Babic }; 476876a25d2SStefano Babic 477876a25d2SStefano Babic static void ccgr_init(void) 478876a25d2SStefano Babic { 479876a25d2SStefano Babic struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; 480876a25d2SStefano Babic 481876a25d2SStefano Babic writel(0x00C03F3F, &ccm->CCGR0); 482876a25d2SStefano Babic writel(0x0030FC03, &ccm->CCGR1); 483876a25d2SStefano Babic writel(0x0FFFC000, &ccm->CCGR2); 484876a25d2SStefano Babic writel(0x3FF00000, &ccm->CCGR3); 485876a25d2SStefano Babic writel(0x00FFF300, &ccm->CCGR4); 486876a25d2SStefano Babic writel(0x0F0000C3, &ccm->CCGR5); 487876a25d2SStefano Babic writel(0x000003FF, &ccm->CCGR6); 488876a25d2SStefano Babic } 489876a25d2SStefano Babic 490876a25d2SStefano Babic static void gpr_init(void) 491876a25d2SStefano Babic { 492876a25d2SStefano Babic struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR; 493876a25d2SStefano Babic 494876a25d2SStefano Babic /* enable AXI cache for VDOA/VPU/IPU */ 495876a25d2SStefano Babic writel(0xF00000CF, &iomux->gpr[4]); 496876a25d2SStefano Babic /* set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7 */ 497876a25d2SStefano Babic writel(0x007F007F, &iomux->gpr[6]); 498876a25d2SStefano Babic writel(0x007F007F, &iomux->gpr[7]); 499876a25d2SStefano Babic } 500876a25d2SStefano Babic 501876a25d2SStefano Babic 502876a25d2SStefano Babic static void spl_dram_init(void) 503876a25d2SStefano Babic { 504876a25d2SStefano Babic struct mx6_ddr_sysinfo sysinfo = { 505876a25d2SStefano Babic /* width of data bus:0=16,1=32,2=64 */ 506876a25d2SStefano Babic .dsize = 2, 507876a25d2SStefano Babic /* config for full 4GB range so that get_mem_size() works */ 508876a25d2SStefano Babic .cs_density = 32, /* 32Gb per CS */ 509876a25d2SStefano Babic /* single chip select */ 510876a25d2SStefano Babic .ncs = 1, 511876a25d2SStefano Babic .cs1_mirror = 0, 512876a25d2SStefano Babic .rtt_wr = 1 /*DDR3_RTT_60_OHM*/, /* RTT_Wr = RZQ/4 */ 513876a25d2SStefano Babic .rtt_nom = 1 /*DDR3_RTT_60_OHM*/, /* RTT_Nom = RZQ/4 */ 514876a25d2SStefano Babic .walat = 1, /* Write additional latency */ 515876a25d2SStefano Babic .ralat = 5, /* Read additional latency */ 516876a25d2SStefano Babic .mif3_mode = 3, /* Command prediction working mode */ 517876a25d2SStefano Babic .bi_on = 1, /* Bank interleaving enabled */ 518876a25d2SStefano Babic .sde_to_rst = 0x10, /* 14 cycles, 200us (JEDEC default) */ 519876a25d2SStefano Babic .rst_to_cke = 0x23, /* 33 cycles, 500us (JEDEC default) */ 520876a25d2SStefano Babic .ddr_type = DDR_TYPE_DDR3, 521edf00937SFabio Estevam .refsel = 1, /* Refresh cycles at 32KHz */ 522edf00937SFabio Estevam .refr = 7, /* 8 refresh commands per refresh cycle */ 523876a25d2SStefano Babic }; 524876a25d2SStefano Babic 525876a25d2SStefano Babic mx6dq_dram_iocfg(64, &mx6_ddr_ioregs, &mx6_grp_ioregs); 526876a25d2SStefano Babic mx6_dram_cfg(&sysinfo, &mx6_mmcd_calib, &mem_ddr); 527876a25d2SStefano Babic } 528876a25d2SStefano Babic 529876a25d2SStefano Babic void board_boot_order(u32 *spl_boot_list) 530876a25d2SStefano Babic { 531876a25d2SStefano Babic spl_boot_list[0] = spl_boot_device(); 532876a25d2SStefano Babic printf("Boot device %x\n", spl_boot_list[0]); 533876a25d2SStefano Babic switch (spl_boot_list[0]) { 534876a25d2SStefano Babic case BOOT_DEVICE_SPI: 535876a25d2SStefano Babic spl_boot_list[1] = BOOT_DEVICE_UART; 536876a25d2SStefano Babic break; 537876a25d2SStefano Babic case BOOT_DEVICE_MMC1: 538876a25d2SStefano Babic spl_boot_list[1] = BOOT_DEVICE_SPI; 539876a25d2SStefano Babic spl_boot_list[2] = BOOT_DEVICE_UART; 540876a25d2SStefano Babic break; 541876a25d2SStefano Babic default: 542876a25d2SStefano Babic printf("Boot device %x\n", spl_boot_list[0]); 543876a25d2SStefano Babic } 544876a25d2SStefano Babic } 545876a25d2SStefano Babic 546876a25d2SStefano Babic void board_init_f(ulong dummy) 547876a25d2SStefano Babic { 548876a25d2SStefano Babic #ifdef CONFIG_CMD_NAND 549876a25d2SStefano Babic /* Enable NAND */ 550876a25d2SStefano Babic setup_gpmi_nand(); 551876a25d2SStefano Babic #endif 552876a25d2SStefano Babic 553876a25d2SStefano Babic /* setup clock gating */ 554876a25d2SStefano Babic ccgr_init(); 555876a25d2SStefano Babic 556876a25d2SStefano Babic /* setup AIPS and disable watchdog */ 557876a25d2SStefano Babic arch_cpu_init(); 558876a25d2SStefano Babic 559876a25d2SStefano Babic /* setup AXI */ 560876a25d2SStefano Babic gpr_init(); 561876a25d2SStefano Babic 562876a25d2SStefano Babic board_early_init_f(); 563876a25d2SStefano Babic 564876a25d2SStefano Babic /* setup GP timer */ 565876a25d2SStefano Babic timer_init(); 566876a25d2SStefano Babic 567876a25d2SStefano Babic setup_spi(); 568876a25d2SStefano Babic 569876a25d2SStefano Babic /* UART clocks enabled and gd valid - init serial console */ 570876a25d2SStefano Babic preloader_console_init(); 571876a25d2SStefano Babic 572876a25d2SStefano Babic /* DDR initialization */ 573876a25d2SStefano Babic spl_dram_init(); 574876a25d2SStefano Babic 575876a25d2SStefano Babic /* Clear the BSS. */ 576876a25d2SStefano Babic memset(__bss_start, 0, __bss_end - __bss_start); 577876a25d2SStefano Babic 578876a25d2SStefano Babic /* load/boot image from boot device */ 579876a25d2SStefano Babic board_init_r(NULL, 0); 580876a25d2SStefano Babic } 581876a25d2SStefano Babic #endif 582