Merge tag 'u-boot-imx-20190415' of git://git.denx.de/u-boot-imx
[oweals/u-boot.git] / board / mscc / jr2 / jr2.c
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 #include <miiphy.h>
10
11 enum {
12         BOARD_TYPE_PCB110 = 0xAABBCE00,
13         BOARD_TYPE_PCB111,
14         BOARD_TYPE_PCB112,
15 };
16
17 int board_early_init_r(void)
18 {
19         /* Prepare SPI controller to be used in master mode */
20         writel(0, BASE_CFG + ICPU_SW_MODE);
21         clrsetbits_le32(BASE_CFG + ICPU_GENERAL_CTRL,
22                         ICPU_GENERAL_CTRL_IF_SI_OWNER_M,
23                         ICPU_GENERAL_CTRL_IF_SI_OWNER(2));
24
25         /* Address of boot parameters */
26         gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE;
27
28         /* LED setup */
29         if (IS_ENABLED(CONFIG_LED))
30                 led_default_state();
31
32         return 0;
33 }
34
35 static void vcoreiii_gpio_set_alternate(int gpio, int mode)
36 {
37         u32 mask;
38         u32 val0, val1;
39         void __iomem *reg0, *reg1;
40
41         if (gpio < 32) {
42                 mask = BIT(gpio);
43                 reg0 = BASE_DEVCPU_GCB + GPIO_GPIO_ALT(0);
44                 reg1 = BASE_DEVCPU_GCB + GPIO_GPIO_ALT(1);
45         } else {
46                 gpio -= 32;
47                 mask = BIT(gpio);
48                 reg0 = BASE_DEVCPU_GCB + GPIO_GPIO_ALT1(0);
49                 reg1 = BASE_DEVCPU_GCB + GPIO_GPIO_ALT1(1);
50         }
51         val0 = readl(reg0);
52         val1 = readl(reg1);
53         if (mode == 1) {
54                 writel(val0 | mask, reg0);
55                 writel(val1 & ~mask, reg1);
56         } else if (mode == 2) {
57                 writel(val0 & ~mask, reg0);
58                 writel(val1 | mask, reg1);
59         } else if (mode == 3) {
60                 writel(val0 | mask, reg0);
61                 writel(val1 | mask, reg1);
62         } else {
63                 writel(val0 & ~mask, reg0);
64                 writel(val1 & ~mask, reg1);
65         }
66 }
67
68 int board_phy_config(struct phy_device *phydev)
69 {
70         if (gd->board_type == BOARD_TYPE_PCB110 ||
71             gd->board_type == BOARD_TYPE_PCB112) {
72                 phy_write(phydev, 0, 31, 0x10);
73                 phy_write(phydev, 0, 18, 0x80F0);
74                 while (phy_read(phydev, 0, 18) & 0x8000)
75                         ;
76                 phy_write(phydev, 0, 31, 0);
77         }
78         if (gd->board_type == BOARD_TYPE_PCB111) {
79                 phy_write(phydev, 0, 31, 0x10);
80                 phy_write(phydev, 0, 18, 0x80A0);
81                 while (phy_read(phydev, 0, 18) & 0x8000)
82                         ;
83                 phy_write(phydev, 0, 14, 0x800);
84                 phy_write(phydev, 0, 31, 0);
85         }
86
87         return 0;
88 }
89
90 void board_debug_uart_init(void)
91 {
92         /* too early for the pinctrl driver, so configure the UART pins here */
93         vcoreiii_gpio_set_alternate(10, 1);
94         vcoreiii_gpio_set_alternate(11, 1);
95 }
96
97 static void do_board_detect(void)
98 {
99         int i;
100         u16 pval;
101
102         /* MIIM 1 + 2  MDC/MDIO */
103         for (i = 56; i < 60; i++)
104                 vcoreiii_gpio_set_alternate(i, 1);
105
106         /* small delay for settling the pins */
107         mdelay(30);
108
109         if (mscc_phy_rd(0, 0x10, 0x3, &pval) == 0 &&
110             ((pval >> 4) & 0x3F) == 0x3c) {
111                 gd->board_type = BOARD_TYPE_PCB112; /* Serval2-NID */
112         } else if (mscc_phy_rd(1, 0x0, 0x3, &pval) == 0 &&
113                    ((pval >> 4) & 0x3F) == 0x3c) {
114                 gd->board_type = BOARD_TYPE_PCB110; /* Jr2-24 */
115         } else {
116                 /* Fall-back */
117                 gd->board_type = BOARD_TYPE_PCB111; /* Jr2-48 */
118         }
119 }
120
121 #if defined(CONFIG_MULTI_DTB_FIT)
122 int board_fit_config_name_match(const char *name)
123 {
124         if (gd->board_type == BOARD_TYPE_PCB110 &&
125             strcmp(name, "jr2_pcb110") == 0)
126                 return 0;
127
128         if (gd->board_type == BOARD_TYPE_PCB111 &&
129             strcmp(name, "jr2_pcb111") == 0)
130                 return 0;
131
132         if (gd->board_type == BOARD_TYPE_PCB112 &&
133             strcmp(name, "serval2_pcb112") == 0)
134                 return 0;
135
136         return -1;
137 }
138 #endif
139
140 #if defined(CONFIG_DTB_RESELECT)
141 int embedded_dtb_select(void)
142 {
143         do_board_detect();
144         fdtdec_setup();
145
146         return 0;
147 }
148 #endif