1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * (C) Copyright 2010, 2018
4 * Allied Telesis <www.alliedtelesis.com>
5 */
6
7 #include <common.h>
8 #include <linux/io.h>
9 #include <miiphy.h>
10 #include <netdev.h>
11 #include <status_led.h>
12 #include <asm/arch/cpu.h>
13 #include <asm/arch/soc.h>
14 #include <asm/arch/mpp.h>
15 #include <asm/arch/gpio.h>
16
17 /* Note: GPIO differences between specific boards
18 *
19 * We're trying to avoid having multiple build targets for all the Kirkwood
20 * based boards one area where things tend to differ is GPIO usage. For the
21 * most part the GPIOs driven by the bootloader are similar enough in function
22 * that there is no harm in driving them.
23 *
24 * XZ4 XS6 XS16 GS24A GT40 GP24A GT24A
25 * GPIO39 - INT(<) NC MUX_RST_N(>) NC POE_DIS_N(>) NC
26 */
27
28 #define SBX81LIFKW_OE_LOW ~(BIT(31) | BIT(30) | BIT(28) | BIT(27) | \
29 BIT(18) | BIT(17) | BIT(13) | BIT(12) | \
30 BIT(10))
31 #define SBX81LIFKW_OE_HIGH ~(BIT(0) | BIT(1) | BIT(7))
32 #define SBX81LIFKW_OE_VAL_LOW (BIT(31) | BIT(30) | BIT(28) | BIT(27))
33 #define SBX81LIFKW_OE_VAL_HIGH (BIT(0) | BIT(1))
34
35 #define MV88E6097_RESET 27
36
37 DECLARE_GLOBAL_DATA_PTR;
38
39 struct led {
40 u32 reg;
41 u32 value;
42 u32 mask;
43 };
44
45 struct led amber_solid = {
46 MVEBU_GPIO0_BASE,
47 BIT(10),
48 BIT(18) | BIT(10)
49 };
50
51 struct led green_solid = {
52 MVEBU_GPIO0_BASE,
53 BIT(18) | BIT(10),
54 BIT(18) | BIT(10)
55 };
56
57 struct led amber_flash = {
58 MVEBU_GPIO0_BASE,
59 0,
60 BIT(18) | BIT(10)
61 };
62
63 struct led green_flash = {
64 MVEBU_GPIO0_BASE,
65 BIT(18),
66 BIT(18) | BIT(10)
67 };
68
status_led_set(struct led * led)69 static void status_led_set(struct led *led)
70 {
71 clrsetbits_le32(led->reg, led->mask, led->value);
72 }
73
board_early_init_f(void)74 int board_early_init_f(void)
75 {
76 /*
77 * default gpio configuration
78 * There are maximum 64 gpios controlled through 2 sets of registers
79 * the below configuration configures mainly initial LED status
80 */
81 mvebu_config_gpio(SBX81LIFKW_OE_VAL_LOW,
82 SBX81LIFKW_OE_VAL_HIGH,
83 SBX81LIFKW_OE_LOW, SBX81LIFKW_OE_HIGH);
84
85 /* Multi-Purpose Pins Functionality configuration */
86 static const u32 kwmpp_config[] = {
87 MPP0_SPI_SCn,
88 MPP1_SPI_MOSI,
89 MPP2_SPI_SCK,
90 MPP3_SPI_MISO,
91 MPP4_UART0_RXD,
92 MPP5_UART0_TXD,
93 MPP6_SYSRST_OUTn,
94 MPP7_PEX_RST_OUTn,
95 MPP8_TW_SDA,
96 MPP9_TW_SCK,
97 MPP10_GPO,
98 MPP11_GPIO,
99 MPP12_GPO,
100 MPP13_GPIO,
101 MPP14_GPIO,
102 MPP15_UART0_RTS,
103 MPP16_UART0_CTS,
104 MPP17_GPIO,
105 MPP18_GPO,
106 MPP19_GPO,
107 MPP20_GPIO,
108 MPP21_GPIO,
109 MPP22_GPIO,
110 MPP23_GPIO,
111 MPP24_GPIO,
112 MPP25_GPIO,
113 MPP26_GPIO,
114 MPP27_GPIO,
115 MPP28_GPIO,
116 MPP29_GPIO,
117 MPP30_GPIO,
118 MPP31_GPIO,
119 MPP32_GPIO,
120 MPP33_GPIO,
121 MPP34_GPIO,
122 MPP35_GPIO,
123 MPP36_GPIO,
124 MPP37_GPIO,
125 MPP38_GPIO,
126 MPP39_GPIO,
127 MPP40_GPIO,
128 MPP41_GPIO,
129 MPP42_GPIO,
130 MPP43_GPIO,
131 MPP44_GPIO,
132 MPP45_GPIO,
133 MPP46_GPIO,
134 MPP47_GPIO,
135 MPP48_GPIO,
136 MPP49_GPIO,
137 0
138 };
139
140 kirkwood_mpp_conf(kwmpp_config, NULL);
141 return 0;
142 }
143
board_init(void)144 int board_init(void)
145 {
146 /* Power-down unused subsystems. The required
147 * subsystems are:
148 *
149 * GE0 b0
150 * PEX0 PHY b1
151 * PEX0.0 b2
152 * TSU b5
153 * SDRAM b6
154 * RUNIT b7
155 */
156 writel((BIT(0) | BIT(1) | BIT(2) |
157 BIT(5) | BIT(6) | BIT(7)),
158 KW_CPU_REG_BASE + 0x1c);
159
160 /* address of boot parameters */
161 gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
162
163 status_led_set(&amber_solid);
164
165 return 0;
166 }
167
168 #ifdef CONFIG_RESET_PHY_R
169 /* automatically defined by kirkwood config.h */
reset_phy(void)170 void reset_phy(void)
171 {
172 }
173 #endif
174
175 #ifdef CONFIG_MV88E61XX_SWITCH
mv88e61xx_hw_reset(struct phy_device * phydev)176 int mv88e61xx_hw_reset(struct phy_device *phydev)
177 {
178 /* Ensure the 88e6097 gets at least 10ms Reset
179 */
180 kw_gpio_set_value(MV88E6097_RESET, 0);
181 mdelay(20);
182 kw_gpio_set_value(MV88E6097_RESET, 1);
183 mdelay(20);
184
185 phydev->advertising = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full;
186
187 return 0;
188 }
189 #endif
190
191 #ifdef CONFIG_MISC_INIT_R
misc_init_r(void)192 int misc_init_r(void)
193 {
194 status_led_set(&green_flash);
195
196 return 0;
197 }
198 #endif
199