1 /* 2 * Copyright 2013-2015 Arcturus Networks, Inc. 3 * http://www.arcturusnetworks.com/products/ucp1020/ 4 * by Oleksandr G Zhadan et al. 5 * based on board/freescale/p1_p2_rdb_pc/spl.c 6 * original copyright follows: 7 * Copyright 2013 Freescale Semiconductor, Inc. 8 * 9 * SPDX-License-Identifier: GPL-2.0+ 10 */ 11 12 #include <common.h> 13 #include <command.h> 14 #include <hwconfig.h> 15 #include <pci.h> 16 #include <i2c.h> 17 #include <miiphy.h> 18 #include <libfdt.h> 19 #include <fdt_support.h> 20 #include <fsl_mdio.h> 21 #include <tsec.h> 22 #include <ioports.h> 23 #include <netdev.h> 24 #include <micrel.h> 25 #include <spi_flash.h> 26 #include <mmc.h> 27 #include <linux/ctype.h> 28 #include <asm/fsl_serdes.h> 29 #include <asm/gpio.h> 30 #include <asm/processor.h> 31 #include <asm/mmu.h> 32 #include <asm/cache.h> 33 #include <asm/immap_85xx.h> 34 #include <asm/fsl_pci.h> 35 #include <fsl_ddr_sdram.h> 36 #include <asm/io.h> 37 #include <asm/fsl_law.h> 38 #include <asm/fsl_lbc.h> 39 #include <asm/mp.h> 40 #include "ucp1020.h" 41 42 void spi_set_speed(struct spi_slave *slave, uint hz) 43 { 44 /* TO DO: It's actially have to be in spi/ */ 45 } 46 47 /* 48 * To be compatible with cmd_gpio 49 */ 50 int name_to_gpio(const char *name) 51 { 52 int gpio = 31 - simple_strtoul(name, NULL, 10); 53 54 if (gpio < 16) 55 gpio = -1; 56 57 return gpio; 58 } 59 60 void board_gpio_init(void) 61 { 62 int i; 63 char envname[8], *val; 64 65 for (i = 0; i < GPIO_MAX_NUM; i++) { 66 sprintf(envname, "GPIO%d", i); 67 val = getenv(envname); 68 if (val) { 69 char direction = toupper(val[0]); 70 char level = toupper(val[1]); 71 72 if (direction == 'I') { 73 gpio_direction_input(i); 74 } else { 75 if (direction == 'O') { 76 if (level == '1') 77 gpio_direction_output(i, 1); 78 else 79 gpio_direction_output(i, 0); 80 } 81 } 82 } 83 } 84 85 val = getenv("PCIE_OFF"); 86 if (val) { 87 gpio_direction_input(GPIO_PCIE1_EN); 88 gpio_direction_input(GPIO_PCIE2_EN); 89 } else { 90 gpio_direction_output(GPIO_PCIE1_EN, 1); 91 gpio_direction_output(GPIO_PCIE2_EN, 1); 92 } 93 94 val = getenv("SDHC_CDWP_OFF"); 95 if (!val) { 96 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); 97 98 setbits_be32(&gur->pmuxcr, 99 (MPC85xx_PMUXCR_SDHC_CD | MPC85xx_PMUXCR_SDHC_WP)); 100 } 101 } 102 103 int board_early_init_f(void) 104 { 105 return 0; /* Just in case. Could be disable in config file */ 106 } 107 108 int checkboard(void) 109 { 110 printf("Board: %s\n", CONFIG_BOARDNAME_LOCAL); 111 board_gpio_init(); 112 printf("SD/MMC: 4-bit Mode\n"); 113 114 return 0; 115 } 116 117 #ifdef CONFIG_PCI 118 void pci_init_board(void) 119 { 120 fsl_pcie_init_board(0); 121 } 122 #endif 123 124 int board_early_init_r(void) 125 { 126 const unsigned int flashbase = CONFIG_SYS_FLASH_BASE; 127 const u8 flash_esel = find_tlb_idx((void *)flashbase, 1); 128 129 /* 130 * Remap Boot flash region to caching-inhibited 131 * so that flash can be erased properly. 132 */ 133 134 /* Flush d-cache and invalidate i-cache of any FLASH data */ 135 flush_dcache(); 136 invalidate_icache(); 137 138 /* invalidate existing TLB entry for flash */ 139 disable_tlb(flash_esel); 140 141 set_tlb(1, flashbase, CONFIG_SYS_FLASH_BASE_PHYS, /* tlb, epn, rpn */ 142 MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G, /* perms, wimge */ 143 0, flash_esel, BOOKE_PAGESZ_64M, 1);/* ts, esel, tsize, iprot */ 144 145 return 0; 146 } 147 148 int board_phy_config(struct phy_device *phydev) 149 { 150 #if defined(CONFIG_PHY_MICREL_KSZ9021) 151 int regval; 152 static int cnt; 153 154 if (cnt++ == 0) 155 printf("PHYs address ["); 156 157 if (phydev->addr == TSEC1_PHY_ADDR || phydev->addr == TSEC3_PHY_ADDR) { 158 regval = 159 ksz9021_phy_extended_read(phydev, 160 MII_KSZ9021_EXT_STRAP_STATUS); 161 /* 162 * min rx data delay 163 */ 164 ksz9021_phy_extended_write(phydev, 165 MII_KSZ9021_EXT_RGMII_RX_DATA_SKEW, 166 0x6666); 167 /* 168 * max rx/tx clock delay, min rx/tx control 169 */ 170 ksz9021_phy_extended_write(phydev, 171 MII_KSZ9021_EXT_RGMII_CLOCK_SKEW, 172 0xf6f6); 173 printf("0x%x", (regval & 0x1f)); 174 } else { 175 printf("0x%x", (TSEC2_PHY_ADDR & 0x1f)); 176 } 177 if (cnt == 3) 178 printf("] "); 179 else 180 printf(","); 181 #endif 182 183 #if defined(CONFIG_PHY_MICREL_KSZ9031_DEBUG) 184 regval = ksz9031_phy_extended_read(phydev, 2, 0x01, 0x4000); 185 if (regval >= 0) 186 printf(" (ADDR 0x%x) ", regval & 0x1f); 187 #endif 188 189 return 0; 190 } 191 192 int last_stage_init(void) 193 { 194 static char newkernelargs[256]; 195 static u8 id1[16]; 196 static u8 id2; 197 struct mmc *mmc; 198 char *sval, *kval; 199 200 if (i2c_read(CONFIG_SYS_I2C_IDT6V49205B, 7, 1, &id1[0], 2) < 0) { 201 printf("Error reading i2c IDT6V49205B information!\n"); 202 } else { 203 printf("IDT6V49205B(0x%02x): ready\n", id1[1]); 204 i2c_read(CONFIG_SYS_I2C_IDT6V49205B, 4, 1, &id1[0], 2); 205 if (!(id1[1] & 0x02)) { 206 id1[1] |= 0x02; 207 i2c_write(CONFIG_SYS_I2C_IDT6V49205B, 4, 1, &id1[0], 2); 208 asm("nop; nop"); 209 } 210 } 211 212 if (i2c_read(CONFIG_SYS_I2C_NCT72_ADDR, 0xFE, 1, &id2, 1) < 0) 213 printf("Error reading i2c NCT72 information!\n"); 214 else 215 printf("NCT72(0x%x): ready\n", id2); 216 217 kval = getenv("kernelargs"); 218 219 mmc = find_mmc_device(0); 220 if (mmc) 221 if (!mmc_init(mmc)) { 222 printf("MMC/SD card detected\n"); 223 if (kval) { 224 int n = strlen(defkargs); 225 char *tmp = strstr(kval, defkargs); 226 227 *tmp = 0; 228 strcpy(newkernelargs, kval); 229 strcat(newkernelargs, " "); 230 strcat(newkernelargs, mmckargs); 231 strcat(newkernelargs, " "); 232 strcat(newkernelargs, &tmp[n]); 233 setenv("kernelargs", newkernelargs); 234 } else { 235 setenv("kernelargs", mmckargs); 236 } 237 } 238 get_arc_info(); 239 240 if (kval) { 241 sval = getenv("SERIAL"); 242 if (sval) { 243 strcpy(newkernelargs, "SN="); 244 strcat(newkernelargs, sval); 245 strcat(newkernelargs, " "); 246 strcat(newkernelargs, kval); 247 setenv("kernelargs", newkernelargs); 248 } 249 } else { 250 printf("Error reading kernelargs env variable!\n"); 251 } 252 253 return 0; 254 } 255 256 int board_eth_init(bd_t *bis) 257 { 258 struct fsl_pq_mdio_info mdio_info; 259 struct tsec_info_struct tsec_info[4]; 260 #ifdef CONFIG_TSEC2 261 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); 262 #endif 263 int num = 0; 264 265 #ifdef CONFIG_TSEC1 266 SET_STD_TSEC_INFO(tsec_info[num], 1); 267 num++; 268 #endif 269 #ifdef CONFIG_TSEC2 270 SET_STD_TSEC_INFO(tsec_info[num], 2); 271 if (is_serdes_configured(SGMII_TSEC2)) { 272 if (!(in_be32(&gur->pordevsr) & MPC85xx_PORDEVSR_SGMII2_DIS)) { 273 puts("eTSEC2 is in sgmii mode.\n"); 274 tsec_info[num].flags |= TSEC_SGMII; 275 tsec_info[num].phyaddr = TSEC2_PHY_ADDR_SGMII; 276 } 277 } 278 num++; 279 #endif 280 #ifdef CONFIG_TSEC3 281 SET_STD_TSEC_INFO(tsec_info[num], 3); 282 num++; 283 #endif 284 285 if (!num) { 286 printf("No TSECs initialized\n"); 287 return 0; 288 } 289 290 mdio_info.regs = (struct tsec_mii_mng *)CONFIG_SYS_MDIO_BASE_ADDR; 291 mdio_info.name = DEFAULT_MII_NAME; 292 293 fsl_pq_mdio_init(bis, &mdio_info); 294 295 tsec_eth_init(bis, tsec_info, num); 296 297 return pci_eth_init(bis); 298 } 299 300 #ifdef CONFIG_OF_BOARD_SETUP 301 int ft_board_setup(void *blob, bd_t *bd) 302 { 303 phys_addr_t base; 304 phys_size_t size; 305 const char *soc_usb_compat = "fsl-usb2-dr"; 306 int err, usb1_off, usb2_off; 307 308 ft_cpu_setup(blob, bd); 309 310 base = getenv_bootm_low(); 311 size = getenv_bootm_size(); 312 313 fdt_fixup_memory(blob, (u64)base, (u64)size); 314 315 FT_FSL_PCI_SETUP; 316 317 #if defined(CONFIG_HAS_FSL_DR_USB) 318 fdt_fixup_dr_usb(blob, bd); 319 #endif 320 321 #if defined(CONFIG_SDCARD) || defined(CONFIG_SPIFLASH) 322 /* Delete eLBC node as it is muxed with USB2 controller */ 323 if (hwconfig("usb2")) { 324 const char *soc_elbc_compat = "fsl,p1020-elbc"; 325 int off = fdt_node_offset_by_compatible(blob, -1, 326 soc_elbc_compat); 327 if (off < 0) { 328 printf 329 ("WARNING: could not find compatible node %s: %s\n", 330 soc_elbc_compat, fdt_strerror(off)); 331 return off; 332 } 333 err = fdt_del_node(blob, off); 334 if (err < 0) { 335 printf("WARNING: could not remove %s: %s\n", 336 soc_elbc_compat, fdt_strerror(err)); 337 } 338 return err; 339 } 340 #endif 341 342 /* Delete USB2 node as it is muxed with eLBC */ 343 usb1_off = fdt_node_offset_by_compatible(blob, -1, soc_usb_compat); 344 if (usb1_off < 0) { 345 printf("WARNING: could not find compatible node %s: %s.\n", 346 soc_usb_compat, fdt_strerror(usb1_off)); 347 return usb1_off; 348 } 349 usb2_off = 350 fdt_node_offset_by_compatible(blob, usb1_off, soc_usb_compat); 351 if (usb2_off < 0) { 352 printf("WARNING: could not find compatible node %s: %s.\n", 353 soc_usb_compat, fdt_strerror(usb2_off)); 354 return usb2_off; 355 } 356 err = fdt_del_node(blob, usb2_off); 357 if (err < 0) { 358 printf("WARNING: could not remove %s: %s.\n", 359 soc_usb_compat, fdt_strerror(err)); 360 } 361 return 0; 362 } 363 #endif 364