1 /* 2 * (C) Copyright 2015 Savoir-faire Linux Inc. 3 * 4 * Derived from MX51EVK code by 5 * Freescale Semiconductor, Inc. 6 * 7 * SPDX-License-Identifier: GPL-2.0+ 8 */ 9 10 #include <common.h> 11 #include <asm/io.h> 12 #include <asm/gpio.h> 13 #include <asm/arch/imx-regs.h> 14 #include <asm/arch/iomux-mx51.h> 15 #include <linux/errno.h> 16 #include <asm/arch/sys_proto.h> 17 #include <asm/arch/crm_regs.h> 18 #include <asm/arch/clock.h> 19 #include <asm/mach-imx/mx5_video.h> 20 #include <mmc.h> 21 #include <fsl_esdhc.h> 22 #include <mc13892.h> 23 24 #include <malloc.h> 25 #include <netdev.h> 26 #include <phy.h> 27 #include "ts4800.h" 28 29 DECLARE_GLOBAL_DATA_PTR; 30 31 #ifdef CONFIG_FSL_ESDHC 32 struct fsl_esdhc_cfg esdhc_cfg[2] = { 33 {MMC_SDHC1_BASE_ADDR}, 34 {MMC_SDHC2_BASE_ADDR}, 35 }; 36 #endif 37 38 int dram_init(void) 39 { 40 /* dram_init must store complete ramsize in gd->ram_size */ 41 gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE, 42 PHYS_SDRAM_1_SIZE); 43 return 0; 44 } 45 46 u32 get_board_rev(void) 47 { 48 u32 rev = get_cpu_rev(); 49 if (!gpio_get_value(IMX_GPIO_NR(1, 22))) 50 rev |= BOARD_REV_2_0 << BOARD_VER_OFFSET; 51 return rev; 52 } 53 54 #define UART_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN | PAD_CTL_DSE_HIGH) 55 56 static void setup_iomux_uart(void) 57 { 58 static const iomux_v3_cfg_t uart_pads[] = { 59 MX51_PAD_UART1_RXD__UART1_RXD, 60 MX51_PAD_UART1_TXD__UART1_TXD, 61 NEW_PAD_CTRL(MX51_PAD_UART1_RTS__UART1_RTS, UART_PAD_CTRL), 62 NEW_PAD_CTRL(MX51_PAD_UART1_CTS__UART1_CTS, UART_PAD_CTRL), 63 }; 64 65 imx_iomux_v3_setup_multiple_pads(uart_pads, ARRAY_SIZE(uart_pads)); 66 } 67 68 static void setup_iomux_fec(void) 69 { 70 static const iomux_v3_cfg_t fec_pads[] = { 71 NEW_PAD_CTRL(MX51_PAD_EIM_EB2__FEC_MDIO, 72 PAD_CTL_HYS | 73 PAD_CTL_PUS_22K_UP | 74 PAD_CTL_DSE_HIGH | PAD_CTL_SRE_FAST), 75 MX51_PAD_EIM_EB3__FEC_RDATA1, 76 NEW_PAD_CTRL(MX51_PAD_EIM_CS2__FEC_RDATA2, PAD_CTL_HYS), 77 MX51_PAD_EIM_CS3__FEC_RDATA3, 78 MX51_PAD_NANDF_CS2__FEC_TX_ER, 79 MX51_PAD_EIM_CS5__FEC_CRS, 80 MX51_PAD_EIM_CS4__FEC_RX_ER, 81 /* PAD used on TS4800 */ 82 MX51_PAD_DI2_PIN2__FEC_MDC, 83 MX51_PAD_DISP2_DAT14__FEC_RDAT0, 84 MX51_PAD_DISP2_DAT10__FEC_COL, 85 MX51_PAD_DISP2_DAT11__FEC_RXCLK, 86 MX51_PAD_DISP2_DAT15__FEC_TDAT0, 87 MX51_PAD_DISP2_DAT6__FEC_TDAT1, 88 MX51_PAD_DISP2_DAT7__FEC_TDAT2, 89 MX51_PAD_DISP2_DAT8__FEC_TDAT3, 90 MX51_PAD_DISP2_DAT9__FEC_TX_EN, 91 MX51_PAD_DISP2_DAT13__FEC_TX_CLK, 92 MX51_PAD_DISP2_DAT12__FEC_RX_DV, 93 }; 94 95 imx_iomux_v3_setup_multiple_pads(fec_pads, ARRAY_SIZE(fec_pads)); 96 } 97 98 #ifdef CONFIG_FSL_ESDHC 99 int board_mmc_getcd(struct mmc *mmc) 100 { 101 struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; 102 int ret; 103 104 imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_GPIO1_0__GPIO1_0, 105 NO_PAD_CTRL)); 106 gpio_direction_input(IMX_GPIO_NR(1, 0)); 107 imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX51_PAD_GPIO1_6__GPIO1_6, 108 NO_PAD_CTRL)); 109 gpio_direction_input(IMX_GPIO_NR(1, 6)); 110 111 if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR) 112 ret = !gpio_get_value(IMX_GPIO_NR(1, 0)); 113 else 114 ret = !gpio_get_value(IMX_GPIO_NR(1, 6)); 115 116 return ret; 117 } 118 119 int board_mmc_init(bd_t *bis) 120 { 121 static const iomux_v3_cfg_t sd1_pads[] = { 122 NEW_PAD_CTRL(MX51_PAD_SD1_CMD__SD1_CMD, PAD_CTL_DSE_MAX | 123 PAD_CTL_HYS | PAD_CTL_PUS_47K_UP | PAD_CTL_SRE_FAST), 124 NEW_PAD_CTRL(MX51_PAD_SD1_CLK__SD1_CLK, PAD_CTL_DSE_MAX | 125 PAD_CTL_PUS_47K_UP | PAD_CTL_SRE_FAST), 126 NEW_PAD_CTRL(MX51_PAD_SD1_DATA0__SD1_DATA0, PAD_CTL_DSE_MAX | 127 PAD_CTL_HYS | PAD_CTL_PUS_47K_UP | PAD_CTL_SRE_FAST), 128 NEW_PAD_CTRL(MX51_PAD_SD1_DATA1__SD1_DATA1, PAD_CTL_DSE_MAX | 129 PAD_CTL_HYS | PAD_CTL_PUS_47K_UP | PAD_CTL_SRE_FAST), 130 NEW_PAD_CTRL(MX51_PAD_SD1_DATA2__SD1_DATA2, PAD_CTL_DSE_MAX | 131 PAD_CTL_HYS | PAD_CTL_PUS_47K_UP | PAD_CTL_SRE_FAST), 132 NEW_PAD_CTRL(MX51_PAD_SD1_DATA3__SD1_DATA3, PAD_CTL_DSE_MAX | 133 PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN | PAD_CTL_SRE_FAST), 134 NEW_PAD_CTRL(MX51_PAD_GPIO1_0__SD1_CD, PAD_CTL_HYS), 135 NEW_PAD_CTRL(MX51_PAD_GPIO1_1__SD1_WP, PAD_CTL_HYS), 136 }; 137 138 esdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); 139 140 imx_iomux_v3_setup_multiple_pads(sd1_pads, ARRAY_SIZE(sd1_pads)); 141 142 return fsl_esdhc_initialize(bis, &esdhc_cfg[0]); 143 } 144 #endif 145 146 int board_early_init_f(void) 147 { 148 setup_iomux_uart(); 149 setup_iomux_fec(); 150 151 return 0; 152 } 153 154 int board_init(void) 155 { 156 /* address of boot parameters */ 157 gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; 158 159 return 0; 160 } 161 162 /* 163 * Read the MAC address from FEC's registers PALR PAUR. 164 * User is supposed to configure these registers when MAC address is known 165 * from another source (fuse), but on TS4800, MAC address is not fused and 166 * the bootrom configure these registers on startup. 167 */ 168 static int fec_get_mac_from_register(uint32_t base_addr) 169 { 170 unsigned char ethaddr[6]; 171 u32 reg_mac[2]; 172 int i; 173 174 reg_mac[0] = in_be32(base_addr + 0xE4); 175 reg_mac[1] = in_be32(base_addr + 0xE8); 176 177 for(i = 0; i < 6; i++) 178 ethaddr[i] = (reg_mac[i / 4] >> ((i % 4) * 8)) & 0xFF; 179 180 if (is_valid_ethaddr(ethaddr)) { 181 eth_setenv_enetaddr("ethaddr", ethaddr); 182 return 0; 183 } 184 185 return -1; 186 } 187 188 #define TS4800_GPIO_FEC_PHY_RES IMX_GPIO_NR(2, 14) 189 int board_eth_init(bd_t *bd) 190 { 191 int dev_id = -1; 192 int phy_id = 0xFF; 193 uint32_t addr = IMX_FEC_BASE; 194 195 uint32_t base_mii; 196 struct mii_dev *bus = NULL; 197 struct phy_device *phydev = NULL; 198 int ret; 199 200 /* reset FEC phy */ 201 imx_iomux_v3_setup_pad(MX51_PAD_EIM_A20__GPIO2_14); 202 gpio_direction_output(TS4800_GPIO_FEC_PHY_RES, 0); 203 mdelay(1); 204 gpio_set_value(TS4800_GPIO_FEC_PHY_RES, 1); 205 mdelay(1); 206 207 base_mii = addr; 208 debug("eth_init: fec_probe(bd, %i, %i) @ %08x\n", dev_id, phy_id, addr); 209 bus = fec_get_miibus(base_mii, dev_id); 210 if (!bus) 211 return -ENOMEM; 212 213 phydev = phy_find_by_mask(bus, phy_id, PHY_INTERFACE_MODE_MII); 214 if (!phydev) { 215 free(bus); 216 return -ENOMEM; 217 } 218 219 if (fec_get_mac_from_register(addr)) 220 printf("eth_init: failed to get MAC address\n"); 221 222 ret = fec_probe(bd, dev_id, addr, bus, phydev); 223 if (ret) { 224 free(phydev); 225 free(bus); 226 } 227 228 return ret; 229 } 230 231 /* 232 * Do not overwrite the console 233 * Use always serial for U-Boot console 234 */ 235 int overwrite_console(void) 236 { 237 return 1; 238 } 239 240 int checkboard(void) 241 { 242 puts("Board: TS4800\n"); 243 244 return 0; 245 } 246 247 void hw_watchdog_reset(void) 248 { 249 struct ts4800_wtd_regs *wtd = (struct ts4800_wtd_regs *) (TS4800_SYSCON_BASE + 0xE); 250 /* feed the watchdog for another 10s */ 251 writew(0x2, &wtd->feed); 252 } 253 254 void hw_watchdog_init(void) 255 { 256 return; 257 } 258