1 /* 2 * (C) Copyright 2011 Freescale Semiconductor, Inc. 3 * 4 * Author: Fabio Estevam <fabio.estevam@freescale.com> 5 * 6 * SPDX-License-Identifier: GPL-2.0+ 7 */ 8 9 #include <common.h> 10 #include <asm/io.h> 11 #include <asm/gpio.h> 12 #include <asm/arch/imx-regs.h> 13 #include <asm/arch/iomux-mx25.h> 14 #include <asm/arch/clock.h> 15 #include <mmc.h> 16 #include <fsl_esdhc.h> 17 #include <i2c.h> 18 #include <power/pmic.h> 19 #include <fsl_pmic.h> 20 #include <mc34704.h> 21 22 #define FEC_RESET_B IMX_GPIO_NR(4, 8) 23 #define FEC_ENABLE_B IMX_GPIO_NR(2, 3) 24 #define CARD_DETECT IMX_GPIO_NR(2, 1) 25 26 DECLARE_GLOBAL_DATA_PTR; 27 28 #ifdef CONFIG_FSL_ESDHC 29 struct fsl_esdhc_cfg esdhc_cfg[1] = { 30 {IMX_MMC_SDHC1_BASE}, 31 }; 32 #endif 33 34 /* 35 * FIXME: need to revisit this 36 * The original code enabled PUE and 100-k pull-down without PKE, so the right 37 * value here is likely: 38 * 0 for no pull 39 * or: 40 * PAD_CTL_PUS_100K_DOWN for 100-k pull-down 41 */ 42 #define FEC_OUT_PAD_CTRL 0 43 44 #define I2C_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | \ 45 PAD_CTL_ODE) 46 47 static void mx25pdk_fec_init(void) 48 { 49 static const iomux_v3_cfg_t fec_pads[] = { 50 MX25_PAD_FEC_TX_CLK__FEC_TX_CLK, 51 MX25_PAD_FEC_RX_DV__FEC_RX_DV, 52 MX25_PAD_FEC_RDATA0__FEC_RDATA0, 53 NEW_PAD_CTRL(MX25_PAD_FEC_TDATA0__FEC_TDATA0, FEC_OUT_PAD_CTRL), 54 NEW_PAD_CTRL(MX25_PAD_FEC_TX_EN__FEC_TX_EN, FEC_OUT_PAD_CTRL), 55 NEW_PAD_CTRL(MX25_PAD_FEC_MDC__FEC_MDC, FEC_OUT_PAD_CTRL), 56 MX25_PAD_FEC_MDIO__FEC_MDIO, 57 MX25_PAD_FEC_RDATA1__FEC_RDATA1, 58 NEW_PAD_CTRL(MX25_PAD_FEC_TDATA1__FEC_TDATA1, FEC_OUT_PAD_CTRL), 59 60 NEW_PAD_CTRL(MX25_PAD_D12__GPIO_4_8, 0), /* FEC_RESET_B */ 61 NEW_PAD_CTRL(MX25_PAD_A17__GPIO_2_3, 0), /* FEC_ENABLE_B */ 62 }; 63 64 static const iomux_v3_cfg_t i2c_pads[] = { 65 NEW_PAD_CTRL(MX25_PAD_I2C1_CLK__I2C1_CLK, I2C_PAD_CTRL), 66 NEW_PAD_CTRL(MX25_PAD_I2C1_DAT__I2C1_DAT, I2C_PAD_CTRL), 67 }; 68 69 imx_iomux_v3_setup_multiple_pads(fec_pads, ARRAY_SIZE(fec_pads)); 70 71 /* Assert RESET and ENABLE low */ 72 gpio_direction_output(FEC_RESET_B, 0); 73 gpio_direction_output(FEC_ENABLE_B, 0); 74 75 udelay(10); 76 77 /* Deassert RESET and ENABLE */ 78 gpio_set_value(FEC_RESET_B, 1); 79 gpio_set_value(FEC_ENABLE_B, 1); 80 81 /* Setup I2C pins so that PMIC can turn on PHY supply */ 82 imx_iomux_v3_setup_multiple_pads(i2c_pads, ARRAY_SIZE(i2c_pads)); 83 } 84 85 int dram_init(void) 86 { 87 /* dram_init must store complete ramsize in gd->ram_size */ 88 gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE, 89 PHYS_SDRAM_1_SIZE); 90 return 0; 91 } 92 93 /* 94 * Set up input pins with hysteresis and 100-k pull-ups 95 */ 96 #define UART1_IN_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PUS_100K_UP) 97 /* 98 * FIXME: need to revisit this 99 * The original code enabled PUE and 100-k pull-down without PKE, so the right 100 * value here is likely: 101 * 0 for no pull 102 * or: 103 * PAD_CTL_PUS_100K_DOWN for 100-k pull-down 104 */ 105 #define UART1_OUT_PAD_CTRL 0 106 107 static void mx25pdk_uart1_init(void) 108 { 109 static const iomux_v3_cfg_t uart1_pads[] = { 110 NEW_PAD_CTRL(MX25_PAD_UART1_RXD__UART1_RXD, UART1_IN_PAD_CTRL), 111 NEW_PAD_CTRL(MX25_PAD_UART1_TXD__UART1_TXD, UART1_OUT_PAD_CTRL), 112 NEW_PAD_CTRL(MX25_PAD_UART1_RTS__UART1_RTS, UART1_OUT_PAD_CTRL), 113 NEW_PAD_CTRL(MX25_PAD_UART1_CTS__UART1_CTS, UART1_IN_PAD_CTRL), 114 }; 115 116 imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads)); 117 } 118 119 int board_early_init_f(void) 120 { 121 mx25pdk_uart1_init(); 122 123 return 0; 124 } 125 126 int board_init(void) 127 { 128 /* address of boot parameters */ 129 gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; 130 131 return 0; 132 } 133 134 int board_late_init(void) 135 { 136 struct pmic *p; 137 int ret; 138 139 mx25pdk_fec_init(); 140 141 ret = pmic_init(I2C_0); 142 if (ret) 143 return ret; 144 145 p = pmic_get("FSL_PMIC"); 146 if (!p) 147 return -ENODEV; 148 149 /* Turn on Ethernet PHY and LCD supplies */ 150 pmic_reg_write(p, MC34704_GENERAL2_REG, ONOFFE | ONOFFA); 151 152 return 0; 153 } 154 155 #ifdef CONFIG_FSL_ESDHC 156 int board_mmc_getcd(struct mmc *mmc) 157 { 158 /* Set up the Card Detect pin. */ 159 imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX25_PAD_A15__GPIO_2_1, 0)); 160 161 gpio_direction_input(CARD_DETECT); 162 return !gpio_get_value(CARD_DETECT); 163 } 164 165 int board_mmc_init(bd_t *bis) 166 { 167 static const iomux_v3_cfg_t sdhc1_pads[] = { 168 NEW_PAD_CTRL(MX25_PAD_SD1_CMD__SD1_CMD, NO_PAD_CTRL), 169 NEW_PAD_CTRL(MX25_PAD_SD1_CLK__SD1_CLK, NO_PAD_CTRL), 170 NEW_PAD_CTRL(MX25_PAD_SD1_DATA0__SD1_DATA0, NO_PAD_CTRL), 171 NEW_PAD_CTRL(MX25_PAD_SD1_DATA1__SD1_DATA1, NO_PAD_CTRL), 172 NEW_PAD_CTRL(MX25_PAD_SD1_DATA2__SD1_DATA2, NO_PAD_CTRL), 173 NEW_PAD_CTRL(MX25_PAD_SD1_DATA3__SD1_DATA3, NO_PAD_CTRL), 174 }; 175 176 imx_iomux_v3_setup_multiple_pads(sdhc1_pads, ARRAY_SIZE(sdhc1_pads)); 177 178 /* 179 * Set the eSDHC1 PER clock to the maximum frequency lower than or equal 180 * to 50 MHz that can be obtained, which requires to use UPLL as the 181 * clock source. This actually gives 48 MHz. 182 */ 183 imx_set_perclk(MXC_ESDHC1_CLK, true, 50000000); 184 esdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC1_CLK); 185 return fsl_esdhc_initialize(bis, &esdhc_cfg[0]); 186 } 187 #endif 188 189 int checkboard(void) 190 { 191 puts("Board: MX25PDK\n"); 192 193 return 0; 194 } 195 196 /* Lowlevel init isn't used on mx25pdk, so just provide a dummy one here */ 197 void lowlevel_init(void) {} 198