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