]> git.ipfire.org Git - people/ms/u-boot.git/blob - board/gdsys/405ex/io64.c
drivers, block: remove sil680 driver
[people/ms/u-boot.git] / board / gdsys / 405ex / io64.c
1 /*
2 * (C) Copyright 2010
3 * Dirk Eibach, Guntermann & Drunck GmbH, eibach@gdsys.de
4 *
5 * based on kilauea.c
6 * by Stefan Roese, DENX Software Engineering, sr@denx.de.
7 *
8 * SPDX-License-Identifier: GPL-2.0+
9 */
10
11 #include <common.h>
12 #include <asm/ppc4xx.h>
13 #include <asm/ppc405.h>
14 #include <libfdt.h>
15 #include <fdt_support.h>
16 #include <asm/processor.h>
17 #include <asm/io.h>
18 #include <linux/errno.h>
19 #include <asm/ppc4xx-gpio.h>
20 #include <flash.h>
21
22 #include <pca9698.h>
23
24 #include "405ex.h"
25 #include <gdsys_fpga.h>
26
27 #include <miiphy.h>
28 #include <i2c.h>
29
30 DECLARE_GLOBAL_DATA_PTR;
31
32 #define PHYREG_CONTROL 0
33 #define PHYREG_PAGE_ADDRESS 22
34 #define PHYREG_PG0_COPPER_SPECIFIC_CONTROL_1 16
35 #define PHYREG_PG2_COPPER_SPECIFIC_CONTROL_2 26
36 #define PHYREG_PG2_MAC_SPECIFIC_STATUS_1 17
37 #define PHYREG_PG2_MAC_SPECIFIC_CONTROL 21
38
39 #define LATCH0_BASE (CONFIG_SYS_LATCH_BASE)
40 #define LATCH1_BASE (CONFIG_SYS_LATCH_BASE + 0x100)
41 #define LATCH2_BASE (CONFIG_SYS_LATCH_BASE + 0x200)
42 #define LATCH3_BASE (CONFIG_SYS_LATCH_BASE + 0x300)
43
44 enum {
45 UNITTYPE_CCD_SWITCH = 1,
46 };
47
48 enum {
49 HWVER_100 = 0,
50 HWVER_110 = 1,
51 };
52
53 struct ihs_fpga *fpga_ptr[] = CONFIG_SYS_FPGA_PTR;
54
55 static inline void blank_string(int size)
56 {
57 int i;
58
59 for (i = 0; i < size; i++)
60 putc('\b');
61 for (i = 0; i < size; i++)
62 putc(' ');
63 for (i = 0; i < size; i++)
64 putc('\b');
65 }
66
67 /*
68 * Board early initialization function
69 */
70 int misc_init_r(void)
71 {
72 /*
73 * Note: DTT has been removed. Please use UCLASS_THERMAL.
74 *
75 * startup fans
76 *
77 * dtt_init();
78 */
79
80 #ifdef CONFIG_ENV_IS_IN_FLASH
81 /* Monitor protection ON by default */
82 flash_protect(FLAG_PROTECT_SET,
83 -CONFIG_SYS_MONITOR_LEN,
84 0xffffffff,
85 &flash_info[0]);
86 #endif
87
88 return 0;
89 }
90
91 static void print_fpga_info(unsigned dev)
92 {
93 u16 versions;
94 u16 fpga_version;
95 u16 fpga_features;
96 int fpga_state = get_fpga_state(dev);
97
98 unsigned unit_type;
99 unsigned hardware_version;
100 unsigned feature_channels;
101 unsigned feature_expansion;
102
103 FPGA_GET_REG(dev, versions, &versions);
104 FPGA_GET_REG(dev, fpga_version, &fpga_version);
105 FPGA_GET_REG(dev, fpga_features, &fpga_features);
106
107 printf("FPGA%d: ", dev);
108 if (fpga_state & FPGA_STATE_PLATFORM)
109 printf("(legacy) ");
110
111 if (fpga_state & FPGA_STATE_DONE_FAILED) {
112 printf(" done timed out\n");
113 return;
114 }
115
116 if (fpga_state & FPGA_STATE_REFLECTION_FAILED) {
117 printf(" refelectione test failed\n");
118 return;
119 }
120
121 unit_type = (versions & 0xf000) >> 12;
122 hardware_version = versions & 0x000f;
123 feature_channels = fpga_features & 0x007f;
124 feature_expansion = fpga_features & (1<<15);
125
126 switch (unit_type) {
127 case UNITTYPE_CCD_SWITCH:
128 printf("CCD-Switch");
129 break;
130
131 default:
132 printf("UnitType %d(not supported)", unit_type);
133 break;
134 }
135
136 switch (hardware_version) {
137 case HWVER_100:
138 printf(" HW-Ver 1.00\n");
139 break;
140
141 case HWVER_110:
142 printf(" HW-Ver 1.10\n");
143 break;
144
145 default:
146 printf(" HW-Ver %d(not supported)\n",
147 hardware_version);
148 break;
149 }
150
151 printf(" FPGA V %d.%02d, features:",
152 fpga_version / 100, fpga_version % 100);
153
154 printf(" %d channel(s)", feature_channels);
155
156 printf(", expansion %ssupported\n", feature_expansion ? "" : "un");
157 }
158
159 int checkboard(void)
160 {
161 char *s = getenv("serial#");
162
163 printf("Board: CATCenter Io64\n");
164
165 if (s != NULL) {
166 puts(", serial# ");
167 puts(s);
168 }
169
170 return 0;
171 }
172
173 int configure_gbit_phy(char *bus, unsigned char addr)
174 {
175 unsigned short value;
176
177 /* select page 0 */
178 if (miiphy_write(bus, addr, PHYREG_PAGE_ADDRESS, 0x0000))
179 goto err_out;
180 /* switch to powerdown */
181 if (miiphy_read(bus, addr, PHYREG_PG0_COPPER_SPECIFIC_CONTROL_1,
182 &value))
183 goto err_out;
184 if (miiphy_write(bus, addr, PHYREG_PG0_COPPER_SPECIFIC_CONTROL_1,
185 value | 0x0004))
186 goto err_out;
187 /* select page 2 */
188 if (miiphy_write(bus, addr, PHYREG_PAGE_ADDRESS, 0x0002))
189 goto err_out;
190 /* disable SGMII autonegotiation */
191 if (miiphy_write(bus, addr, PHYREG_PG2_MAC_SPECIFIC_CONTROL, 48))
192 goto err_out;
193 /* select page 0 */
194 if (miiphy_write(bus, addr, PHYREG_PAGE_ADDRESS, 0x0000))
195 goto err_out;
196 /* switch from powerdown to normal operation */
197 if (miiphy_read(bus, addr, PHYREG_PG0_COPPER_SPECIFIC_CONTROL_1,
198 &value))
199 goto err_out;
200 if (miiphy_write(bus, addr, PHYREG_PG0_COPPER_SPECIFIC_CONTROL_1,
201 value & ~0x0004))
202 goto err_out;
203 /* reset phy so settings take effect */
204 if (miiphy_write(bus, addr, PHYREG_CONTROL, 0x9140))
205 goto err_out;
206
207 return 0;
208
209 err_out:
210 printf("Error writing to the PHY addr=%02x\n", addr);
211 return -1;
212 }
213
214 int verify_gbit_phy(char *bus, unsigned char addr)
215 {
216 unsigned short value;
217
218 /* select page 2 */
219 if (miiphy_write(bus, addr, PHYREG_PAGE_ADDRESS, 0x0002))
220 goto err_out;
221 /* verify SGMII link status */
222 if (miiphy_read(bus, addr, PHYREG_PG2_MAC_SPECIFIC_STATUS_1, &value))
223 goto err_out;
224 if (!(value & (1 << 10)))
225 return -2;
226
227 return 0;
228
229 err_out:
230 printf("Error writing to the PHY addr=%02x\n", addr);
231 return -1;
232 }
233
234 int last_stage_init(void)
235 {
236 unsigned int k;
237 unsigned int fpga;
238 int failed = 0;
239 char str_phys[] = "Setup PHYs -";
240 char str_serdes[] = "Start SERDES blocks";
241 char str_channels[] = "Start FPGA channels";
242 char str_locks[] = "Verify SERDES locks";
243 char str_hicb[] = "Verify HICB status";
244 char str_status[] = "Verify PHY status -";
245 char slash[] = "\\|/-\\|/-";
246
247 print_fpga_info(0);
248 print_fpga_info(1);
249
250 /* setup Gbit PHYs */
251 puts("TRANS: ");
252 puts(str_phys);
253 int retval;
254 struct mii_dev *mdiodev = mdio_alloc();
255 if (!mdiodev)
256 return -ENOMEM;
257 strncpy(mdiodev->name, CONFIG_SYS_GBIT_MII_BUSNAME, MDIO_NAME_LEN);
258 mdiodev->read = bb_miiphy_read;
259 mdiodev->write = bb_miiphy_write;
260
261 retval = mdio_register(mdiodev);
262 if (retval < 0)
263 return retval;
264
265 for (k = 0; k < 32; ++k) {
266 configure_gbit_phy(CONFIG_SYS_GBIT_MII_BUSNAME, k);
267 putc('\b');
268 putc(slash[k % 8]);
269 }
270
271 mdiodev = mdio_alloc();
272 if (!mdiodev)
273 return -ENOMEM;
274 strncpy(mdiodev->name, CONFIG_SYS_GBIT_MII1_BUSNAME, MDIO_NAME_LEN);
275 mdiodev->read = bb_miiphy_read;
276 mdiodev->write = bb_miiphy_write;
277
278 retval = mdio_register(mdiodev);
279 if (retval < 0)
280 return retval;
281
282 for (k = 0; k < 32; ++k) {
283 configure_gbit_phy(CONFIG_SYS_GBIT_MII1_BUSNAME, k);
284 putc('\b');
285 putc(slash[k % 8]);
286 }
287 blank_string(strlen(str_phys));
288
289 /* take fpga serdes blocks out of reset */
290 puts(str_serdes);
291 udelay(500000);
292 FPGA_SET_REG(0, quad_serdes_reset, 0);
293 FPGA_SET_REG(1, quad_serdes_reset, 0);
294 blank_string(strlen(str_serdes));
295
296 /* take channels out of reset */
297 puts(str_channels);
298 udelay(500000);
299 for (fpga = 0; fpga < 2; ++fpga) {
300 for (k = 0; k < 32; ++k)
301 FPGA_SET_REG(fpga, ch[k].config_int, 0);
302 }
303 blank_string(strlen(str_channels));
304
305 /* verify channels serdes lock */
306 puts(str_locks);
307 udelay(500000);
308 for (fpga = 0; fpga < 2; ++fpga) {
309 for (k = 0; k < 32; ++k) {
310 u16 status;
311 FPGA_GET_REG(fpga, ch[k].status_int, &status);
312 if (!(status & (1 << 4))) {
313 failed = 1;
314 printf("fpga %d channel %d: no serdes lock\n",
315 fpga, k);
316 }
317 /* reset events */
318 FPGA_SET_REG(fpga, ch[k].status_int, 0);
319 }
320 }
321 blank_string(strlen(str_locks));
322
323 /* verify hicb_status */
324 puts(str_hicb);
325 for (fpga = 0; fpga < 2; ++fpga) {
326 for (k = 0; k < 32; ++k) {
327 u16 status;
328 FPGA_GET_REG(fpga, hicb_ch[k].status_int, &status);
329 if (status)
330 printf("fpga %d hicb %d: hicb status %04x\n",
331 fpga, k, status);
332 /* reset events */
333 FPGA_SET_REG(fpga, hicb_ch[k].status_int, 0);
334 }
335 }
336 blank_string(strlen(str_hicb));
337
338 /* verify phy status */
339 puts(str_status);
340 for (k = 0; k < 32; ++k) {
341 if (verify_gbit_phy(CONFIG_SYS_GBIT_MII_BUSNAME, k)) {
342 printf("verify baseboard phy %d failed\n", k);
343 failed = 1;
344 }
345 putc('\b');
346 putc(slash[k % 8]);
347 }
348 for (k = 0; k < 32; ++k) {
349 if (verify_gbit_phy(CONFIG_SYS_GBIT_MII1_BUSNAME, k)) {
350 printf("verify extensionboard phy %d failed\n", k);
351 failed = 1;
352 }
353 putc('\b');
354 putc(slash[k % 8]);
355 }
356 blank_string(strlen(str_status));
357
358 printf("Starting 64 channels %s\n", failed ? "failed" : "ok");
359
360 return 0;
361 }
362
363 void gd405ex_init(void)
364 {
365 unsigned int k;
366
367 if (i2c_probe(0x22)) { /* i2c_probe returns 0 on success */
368 for (k = 0; k < CONFIG_SYS_FPGA_COUNT; ++k)
369 gd->arch.fpga_state[k] |= FPGA_STATE_PLATFORM;
370 } else {
371 pca9698_direction_output(0x22, 39, 1);
372 }
373 }
374
375 void gd405ex_set_fpga_reset(unsigned state)
376 {
377 int legacy = get_fpga_state(0) & FPGA_STATE_PLATFORM;
378
379 if (legacy) {
380 if (state) {
381 out_le16((void *)LATCH0_BASE, CONFIG_SYS_LATCH0_RESET);
382 out_le16((void *)LATCH1_BASE, CONFIG_SYS_LATCH1_RESET);
383 } else {
384 out_le16((void *)LATCH0_BASE, CONFIG_SYS_LATCH0_BOOT);
385 out_le16((void *)LATCH1_BASE, CONFIG_SYS_LATCH1_BOOT);
386 }
387 } else {
388 pca9698_set_value(0x22, 39, state ? 0 : 1);
389 }
390 }
391
392 void gd405ex_setup_hw(void)
393 {
394 gpio_write_bit(CONFIG_SYS_GPIO_STARTUP_FINISHED_N, 0);
395 gpio_write_bit(CONFIG_SYS_GPIO_STARTUP_FINISHED, 1);
396 }
397
398 int gd405ex_get_fpga_done(unsigned fpga)
399 {
400 int legacy = get_fpga_state(0) & FPGA_STATE_PLATFORM;
401
402 if (legacy)
403 return in_le16((void *)LATCH3_BASE)
404 & CONFIG_SYS_FPGA_DONE(fpga);
405 else
406 return pca9698_get_value(0x22, fpga ? 9 : 8);
407 }