1 // SPDX-License-Identifier: (GPL-2.0+ OR MIT) 2 /* 3 * Copyright (c) 2018 Microsemi Corporation 4 */ 5 6 #include <common.h> 7 #include <asm/io.h> 8 #include <led.h> 9 10 enum { 11 BOARD_TYPE_PCB110 = 0xAABBCE00, 12 BOARD_TYPE_PCB111, 13 BOARD_TYPE_PCB112, 14 }; 15 16 int board_early_init_r(void) 17 { 18 /* Prepare SPI controller to be used in master mode */ 19 writel(0, BASE_CFG + ICPU_SW_MODE); 20 clrsetbits_le32(BASE_CFG + ICPU_GENERAL_CTRL, 21 ICPU_GENERAL_CTRL_IF_SI_OWNER_M, 22 ICPU_GENERAL_CTRL_IF_SI_OWNER(2)); 23 24 /* Address of boot parameters */ 25 gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE; 26 27 /* LED setup */ 28 if (IS_ENABLED(CONFIG_LED)) 29 led_default_state(); 30 31 return 0; 32 } 33 34 static void vcoreiii_gpio_set_alternate(int gpio, int mode) 35 { 36 u32 mask; 37 u32 val0, val1; 38 void __iomem *reg0, *reg1; 39 40 if (gpio < 32) { 41 mask = BIT(gpio); 42 reg0 = BASE_DEVCPU_GCB + GPIO_GPIO_ALT(0); 43 reg1 = BASE_DEVCPU_GCB + GPIO_GPIO_ALT(1); 44 } else { 45 gpio -= 32; 46 mask = BIT(gpio); 47 reg0 = BASE_DEVCPU_GCB + GPIO_GPIO_ALT1(0); 48 reg1 = BASE_DEVCPU_GCB + GPIO_GPIO_ALT1(1); 49 } 50 val0 = readl(reg0); 51 val1 = readl(reg1); 52 if (mode == 1) { 53 writel(val0 | mask, reg0); 54 writel(val1 & ~mask, reg1); 55 } else if (mode == 2) { 56 writel(val0 & ~mask, reg0); 57 writel(val1 | mask, reg1); 58 } else if (mode == 3) { 59 writel(val0 | mask, reg0); 60 writel(val1 | mask, reg1); 61 } else { 62 writel(val0 & ~mask, reg0); 63 writel(val1 & ~mask, reg1); 64 } 65 } 66 67 void board_debug_uart_init(void) 68 { 69 /* too early for the pinctrl driver, so configure the UART pins here */ 70 vcoreiii_gpio_set_alternate(10, 1); 71 vcoreiii_gpio_set_alternate(11, 1); 72 } 73 74 static void do_board_detect(void) 75 { 76 int i; 77 u16 pval; 78 79 /* MIIM 1 + 2 MDC/MDIO */ 80 for (i = 56; i < 60; i++) 81 vcoreiii_gpio_set_alternate(i, 1); 82 83 /* small delay for settling the pins */ 84 mdelay(30); 85 86 if (mscc_phy_rd(0, 0x10, 0x3, &pval) == 0 && 87 ((pval >> 4) & 0x3F) == 0x3c) { 88 gd->board_type = BOARD_TYPE_PCB112; /* Serval2-NID */ 89 } else if (mscc_phy_rd(1, 0x0, 0x3, &pval) == 0 && 90 ((pval >> 4) & 0x3F) == 0x3c) { 91 gd->board_type = BOARD_TYPE_PCB110; /* Jr2-24 */ 92 } else { 93 /* Fall-back */ 94 gd->board_type = BOARD_TYPE_PCB111; /* Jr2-48 */ 95 } 96 } 97 98 #if defined(CONFIG_MULTI_DTB_FIT) 99 int board_fit_config_name_match(const char *name) 100 { 101 if (gd->board_type == BOARD_TYPE_PCB110 && 102 strcmp(name, "jr2_pcb110") == 0) 103 return 0; 104 105 if (gd->board_type == BOARD_TYPE_PCB111 && 106 strcmp(name, "jr2_pcb111") == 0) 107 return 0; 108 109 if (gd->board_type == BOARD_TYPE_PCB112 && 110 strcmp(name, "serval2_pcb112") == 0) 111 return 0; 112 113 return -1; 114 } 115 #endif 116 117 #if defined(CONFIG_DTB_RESELECT) 118 int embedded_dtb_select(void) 119 { 120 do_board_detect(); 121 fdtdec_setup(); 122 123 return 0; 124 } 125 #endif 126