blob: ca9a94427f9852004241fd717d4f491babce41d7 [file] [log] [blame]
wdenkc6097192002-11-03 00:24:07 +00001/*
stroese6f4474e2003-03-20 15:31:19 +00002 * (C) Copyright 2001-2003
wdenkc6097192002-11-03 00:24:07 +00003 * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
4 *
Wolfgang Denk1a459662013-07-08 09:37:19 +02005 * SPDX-License-Identifier: GPL-2.0+
wdenkc6097192002-11-03 00:24:07 +00006 */
wdenkc6097192002-11-03 00:24:07 +00007#include <common.h>
Simon Glass24b852a2015-11-08 23:47:45 -07008#include <console.h>
Matthias Fuchs600fe462009-01-02 12:18:12 +01009#include <libfdt.h>
10#include <fdt_support.h>
wdenkc6097192002-11-03 00:24:07 +000011#include <asm/processor.h>
Matthias Fuchs6f35c532007-06-24 17:41:21 +020012#include <asm/io.h>
wdenkc6097192002-11-03 00:24:07 +000013#include <command.h>
wdenkc6097192002-11-03 00:24:07 +000014#include <malloc.h>
stroese87663b12004-12-16 18:27:05 +000015#include <net.h>
Matthias Fuchs6f35c532007-06-24 17:41:21 +020016#include <pci.h>
wdenkc6097192002-11-03 00:24:07 +000017
Wolfgang Denkd87080b2006-03-31 18:32:53 +020018DECLARE_GLOBAL_DATA_PTR;
19
Matthias Fuchsf6a1f492009-01-02 12:17:36 +010020extern void __ft_board_setup(void *blob, bd_t *bd);
21
22#undef FPGA_DEBUG
wdenkc6097192002-11-03 00:24:07 +000023
24/* fpga configuration data - generated by bin2cc */
25const unsigned char fpgadata[] =
26{
Matthias Fuchsf6a1f492009-01-02 12:17:36 +010027#if defined(CONFIG_CPCI405_VER2)
Matthias Fuchs7eaeb082015-01-12 22:47:31 +010028# include "fpgadata_cpci4052.c"
wdenkc6097192002-11-03 00:24:07 +000029#endif
30};
31
32/*
33 * include common fpga code (for esd boards)
34 */
35#include "../common/fpga.c"
stroese87663b12004-12-16 18:27:05 +000036
wdenkc6097192002-11-03 00:24:07 +000037/* Prototypes */
stroese6f4474e2003-03-20 15:31:19 +000038int cpci405_version(void);
stroese87663b12004-12-16 18:27:05 +000039void lxt971_no_sleep(void);
wdenkc6097192002-11-03 00:24:07 +000040
Matthias Fuchsf6a1f492009-01-02 12:17:36 +010041int board_early_init_f(void)
wdenkc6097192002-11-03 00:24:07 +000042{
43#ifndef CONFIG_CPCI405_VER2
44 int index, len, i;
45 int status;
46#endif
47
48#ifdef FPGA_DEBUG
wdenkc6097192002-11-03 00:24:07 +000049 /* set up serial port with default baudrate */
Matthias Fuchsf6a1f492009-01-02 12:17:36 +010050 (void)get_clocks();
wdenkc6097192002-11-03 00:24:07 +000051 gd->baudrate = CONFIG_BAUDRATE;
Matthias Fuchsf6a1f492009-01-02 12:17:36 +010052 serial_init();
wdenkc6097192002-11-03 00:24:07 +000053 console_init_f();
54#endif
55
56 /*
Matthias Fuchsf6a1f492009-01-02 12:17:36 +010057 * First pull fpga-prg pin low,
58 * to disable fpga logic (on version 2 board)
wdenkc6097192002-11-03 00:24:07 +000059 */
Matthias Fuchs049216f2009-02-20 10:19:18 +010060 out_be32((void *)GPIO0_ODR, 0x00000000); /* no open drain pins */
61 out_be32((void *)GPIO0_TCR, CONFIG_SYS_FPGA_PRG); /* setup for output */
62 out_be32((void *)GPIO0_OR, CONFIG_SYS_FPGA_PRG); /* set output pins to high */
63 out_be32((void *)GPIO0_OR, 0); /* pull prg low */
wdenkc6097192002-11-03 00:24:07 +000064
65 /*
66 * Boot onboard FPGA
67 */
68#ifndef CONFIG_CPCI405_VER2
stroese6f4474e2003-03-20 15:31:19 +000069 if (cpci405_version() == 1) {
wdenkc6097192002-11-03 00:24:07 +000070 status = fpga_boot((unsigned char *)fpgadata, sizeof(fpgadata));
71 if (status != 0) {
72 /* booting FPGA failed */
73#ifndef FPGA_DEBUG
wdenkc6097192002-11-03 00:24:07 +000074 /* set up serial port with default baudrate */
Matthias Fuchsf6a1f492009-01-02 12:17:36 +010075 (void)get_clocks();
wdenkc6097192002-11-03 00:24:07 +000076 gd->baudrate = CONFIG_BAUDRATE;
Matthias Fuchsf6a1f492009-01-02 12:17:36 +010077 serial_init();
wdenkc6097192002-11-03 00:24:07 +000078 console_init_f();
79#endif
80 printf("\nFPGA: Booting failed ");
81 switch (status) {
82 case ERROR_FPGA_PRG_INIT_LOW:
Matthias Fuchsf6a1f492009-01-02 12:17:36 +010083 printf("(Timeout: INIT not low after "
84 "asserting PROGRAM*)\n ");
wdenkc6097192002-11-03 00:24:07 +000085 break;
86 case ERROR_FPGA_PRG_INIT_HIGH:
Matthias Fuchsf6a1f492009-01-02 12:17:36 +010087 printf("(Timeout: INIT not high after "
88 "deasserting PROGRAM*)\n ");
wdenkc6097192002-11-03 00:24:07 +000089 break;
90 case ERROR_FPGA_PRG_DONE:
Matthias Fuchsf6a1f492009-01-02 12:17:36 +010091 printf("(Timeout: DONE not high after "
92 "programming FPGA)\n ");
wdenkc6097192002-11-03 00:24:07 +000093 break;
94 }
95
96 /* display infos on fpgaimage */
97 index = 15;
Matthias Fuchsf6a1f492009-01-02 12:17:36 +010098 for (i = 0; i < 4; i++) {
wdenkc6097192002-11-03 00:24:07 +000099 len = fpgadata[index];
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100100 printf("FPGA: %s\n", &(fpgadata[index + 1]));
101 index += len + 3;
wdenkc6097192002-11-03 00:24:07 +0000102 }
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100103 putc('\n');
wdenkc6097192002-11-03 00:24:07 +0000104 /* delayed reboot */
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100105 for (i = 20; i > 0; i--) {
wdenkc6097192002-11-03 00:24:07 +0000106 printf("Rebooting in %2d seconds \r",i);
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100107 for (index = 0; index < 1000; index++)
wdenkc6097192002-11-03 00:24:07 +0000108 udelay(1000);
109 }
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100110 putc('\n');
wdenkc6097192002-11-03 00:24:07 +0000111 do_reset(NULL, 0, 0, NULL);
112 }
113 }
114#endif /* !CONFIG_CPCI405_VER2 */
115
116 /*
117 * IRQ 0-15 405GP internally generated; active high; level sensitive
118 * IRQ 16 405GP internally generated; active low; level sensitive
119 * IRQ 17-24 RESERVED
120 * IRQ 25 (EXT IRQ 0) CAN0; active low; level sensitive
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100121 * IRQ 26 (EXT IRQ 1) CAN1 (+FPGA on CPCI4052); active low; level sens.
wdenkc6097192002-11-03 00:24:07 +0000122 * IRQ 27 (EXT IRQ 2) PCI SLOT 0; active low; level sensitive
123 * IRQ 28 (EXT IRQ 3) PCI SLOT 1; active low; level sensitive
124 * IRQ 29 (EXT IRQ 4) PCI SLOT 2; active low; level sensitive
125 * IRQ 30 (EXT IRQ 5) PCI SLOT 3; active low; level sensitive
126 * IRQ 31 (EXT IRQ 6) COMPACT FLASH; active high; level sensitive
127 */
Stefan Roese952e7762009-09-24 09:55:50 +0200128 mtdcr(UIC0SR, 0xFFFFFFFF); /* clear all ints */
129 mtdcr(UIC0ER, 0x00000000); /* disable all ints */
130 mtdcr(UIC0CR, 0x00000000); /* set all to be non-critical*/
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100131#if defined(CONFIG_CPCI405_6U)
stroese6f4474e2003-03-20 15:31:19 +0000132 if (cpci405_version() == 3) {
Stefan Roese952e7762009-09-24 09:55:50 +0200133 mtdcr(UIC0PR, 0xFFFFFF99); /* set int polarities */
stroese6f4474e2003-03-20 15:31:19 +0000134 } else {
Stefan Roese952e7762009-09-24 09:55:50 +0200135 mtdcr(UIC0PR, 0xFFFFFF81); /* set int polarities */
stroese6f4474e2003-03-20 15:31:19 +0000136 }
Matthias Fuchs6f35c532007-06-24 17:41:21 +0200137#else
Stefan Roese952e7762009-09-24 09:55:50 +0200138 mtdcr(UIC0PR, 0xFFFFFF81); /* set int polarities */
Matthias Fuchs6f35c532007-06-24 17:41:21 +0200139#endif
Stefan Roese952e7762009-09-24 09:55:50 +0200140 mtdcr(UIC0TR, 0x10000000); /* set int trigger levels */
141 mtdcr(UIC0VCR, 0x00000001); /* set vect base=0,
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100142 * INT0 highest priority */
Stefan Roese952e7762009-09-24 09:55:50 +0200143 mtdcr(UIC0SR, 0xFFFFFFFF); /* clear all ints */
wdenkc6097192002-11-03 00:24:07 +0000144
145 return 0;
146}
147
wdenkc6097192002-11-03 00:24:07 +0000148int ctermm2(void)
149{
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100150#if defined(CONFIG_CPCI405_VER2)
Wolfgang Denk4ef218f2007-07-10 00:01:28 +0200151 return 0; /* no, board is cpci405 */
wdenkc6097192002-11-03 00:24:07 +0000152#else
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100153 if ((in_8((void*)0xf0000400) == 0x00) &&
154 (in_8((void*)0xf0000401) == 0x01))
Wolfgang Denk4ef218f2007-07-10 00:01:28 +0200155 return 0; /* no, board is cpci405 */
wdenkc6097192002-11-03 00:24:07 +0000156 else
Wolfgang Denk4ef218f2007-07-10 00:01:28 +0200157 return -1; /* yes, board is cterm-m2 */
wdenkc6097192002-11-03 00:24:07 +0000158#endif
159}
160
wdenkc6097192002-11-03 00:24:07 +0000161int cpci405_host(void)
162{
Stefan Roesed1c3b272009-09-09 16:25:29 +0200163 if (mfdcr(CPC0_PSR) & PSR_PCI_ARBIT_EN)
Wolfgang Denk4ef218f2007-07-10 00:01:28 +0200164 return -1; /* yes, board is cpci405 host */
wdenkc6097192002-11-03 00:24:07 +0000165 else
Wolfgang Denk4ef218f2007-07-10 00:01:28 +0200166 return 0; /* no, board is cpci405 adapter */
wdenkc6097192002-11-03 00:24:07 +0000167}
168
stroese6f4474e2003-03-20 15:31:19 +0000169int cpci405_version(void)
wdenkc6097192002-11-03 00:24:07 +0000170{
Stefan Roesed1c3b272009-09-09 16:25:29 +0200171 unsigned long CPC0_CR0Reg;
wdenkc6097192002-11-03 00:24:07 +0000172 unsigned long value;
173
174 /*
stroese6f4474e2003-03-20 15:31:19 +0000175 * Setup GPIO pins (CS2/GPIO11 and CS3/GPIO12 as GPIO)
wdenkc6097192002-11-03 00:24:07 +0000176 */
Stefan Roesed1c3b272009-09-09 16:25:29 +0200177 CPC0_CR0Reg = mfdcr(CPC0_CR0);
178 mtdcr(CPC0_CR0, CPC0_CR0Reg | 0x03000000);
Matthias Fuchs6f35c532007-06-24 17:41:21 +0200179 out_be32((void*)GPIO0_ODR, in_be32((void*)GPIO0_ODR) & ~0x00180000);
180 out_be32((void*)GPIO0_TCR, in_be32((void*)GPIO0_TCR) & ~0x00180000);
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100181 udelay(1000); /* wait some time before reading input */
182 value = in_be32((void*)GPIO0_IR) & 0x00180000; /* get config bits */
wdenkc6097192002-11-03 00:24:07 +0000183
184 /*
stroese6f4474e2003-03-20 15:31:19 +0000185 * Restore GPIO settings
wdenkc6097192002-11-03 00:24:07 +0000186 */
Stefan Roesed1c3b272009-09-09 16:25:29 +0200187 mtdcr(CPC0_CR0, CPC0_CR0Reg);
wdenkc6097192002-11-03 00:24:07 +0000188
stroese6f4474e2003-03-20 15:31:19 +0000189 switch (value) {
190 case 0x00180000:
191 /* CS2==1 && CS3==1 -> version 1 */
192 return 1;
193 case 0x00080000:
194 /* CS2==0 && CS3==1 -> version 2 */
195 return 2;
196 case 0x00100000:
Matthias Fuchs6f35c532007-06-24 17:41:21 +0200197 /* CS2==1 && CS3==0 -> version 3 or 6U board */
stroese6f4474e2003-03-20 15:31:19 +0000198 return 3;
199 case 0x00000000:
200 /* CS2==0 && CS3==0 -> version 4 */
201 return 4;
202 default:
203 /* should not be reached! */
204 return 2;
205 }
wdenkc6097192002-11-03 00:24:07 +0000206}
207
wdenkc6097192002-11-03 00:24:07 +0000208int misc_init_r (void)
209{
Stefan Roesed1c3b272009-09-09 16:25:29 +0200210 unsigned long CPC0_CR0Reg;
wdenkc6097192002-11-03 00:24:07 +0000211
stroese87663b12004-12-16 18:27:05 +0000212 /* adjust flash start and offset */
213 gd->bd->bi_flashstart = 0 - gd->bd->bi_flashsize;
214 gd->bd->bi_flashoffset = 0;
215
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100216#if defined(CONFIG_CPCI405_VER2)
stroese87663b12004-12-16 18:27:05 +0000217 {
wdenkc6097192002-11-03 00:24:07 +0000218 unsigned char *dst;
219 ulong len = sizeof(fpgadata);
220 int status;
221 int index;
222 int i;
wdenkc6097192002-11-03 00:24:07 +0000223
224 /*
225 * On CPCI-405 version 2 the environment is saved in eeprom!
226 * FPGA can be gzip compressed (malloc) and booted this late.
227 */
stroese6f4474e2003-03-20 15:31:19 +0000228 if (cpci405_version() >= 2) {
wdenkc6097192002-11-03 00:24:07 +0000229 /*
230 * Setup GPIO pins (CS6+CS7 as GPIO)
231 */
Stefan Roesed1c3b272009-09-09 16:25:29 +0200232 CPC0_CR0Reg = mfdcr(CPC0_CR0);
233 mtdcr(CPC0_CR0, CPC0_CR0Reg | 0x00300000);
wdenkc6097192002-11-03 00:24:07 +0000234
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200235 dst = malloc(CONFIG_SYS_FPGA_MAX_SIZE);
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100236 if (gunzip(dst, CONFIG_SYS_FPGA_MAX_SIZE,
237 (uchar *)fpgadata, &len) != 0) {
238 printf("GUNZIP ERROR - must RESET board to recover\n");
239 do_reset(NULL, 0, 0, NULL);
wdenkc6097192002-11-03 00:24:07 +0000240 }
241
242 status = fpga_boot(dst, len);
243 if (status != 0) {
244 printf("\nFPGA: Booting failed ");
245 switch (status) {
246 case ERROR_FPGA_PRG_INIT_LOW:
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100247 printf("(Timeout: INIT not low after "
248 "asserting PROGRAM*)\n ");
wdenkc6097192002-11-03 00:24:07 +0000249 break;
250 case ERROR_FPGA_PRG_INIT_HIGH:
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100251 printf("(Timeout: INIT not high after "
252 "deasserting PROGRAM*)\n ");
wdenkc6097192002-11-03 00:24:07 +0000253 break;
254 case ERROR_FPGA_PRG_DONE:
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100255 printf("(Timeout: DONE not high after "
256 "programming FPGA)\n ");
wdenkc6097192002-11-03 00:24:07 +0000257 break;
258 }
259
260 /* display infos on fpgaimage */
261 index = 15;
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100262 for (i = 0; i < 4; i++) {
wdenkc6097192002-11-03 00:24:07 +0000263 len = dst[index];
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100264 printf("FPGA: %s\n", &(dst[index + 1]));
265 index += len + 3;
wdenkc6097192002-11-03 00:24:07 +0000266 }
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100267 putc('\n');
wdenkc6097192002-11-03 00:24:07 +0000268 /* delayed reboot */
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100269 for (i = 20; i > 0; i--) {
270 printf("Rebooting in %2d seconds \r", i);
271 for (index = 0; index < 1000; index++)
wdenkc6097192002-11-03 00:24:07 +0000272 udelay(1000);
273 }
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100274 putc('\n');
wdenkc6097192002-11-03 00:24:07 +0000275 do_reset(NULL, 0, 0, NULL);
276 }
277
278 /* restore gpio/cs settings */
Stefan Roesed1c3b272009-09-09 16:25:29 +0200279 mtdcr(CPC0_CR0, CPC0_CR0Reg);
wdenkc6097192002-11-03 00:24:07 +0000280
281 puts("FPGA: ");
282
283 /* display infos on fpgaimage */
284 index = 15;
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100285 for (i = 0; i < 4; i++) {
wdenkc6097192002-11-03 00:24:07 +0000286 len = dst[index];
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100287 printf("%s ", &(dst[index + 1]));
288 index += len + 3;
wdenkc6097192002-11-03 00:24:07 +0000289 }
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100290 putc('\n');
wdenkc6097192002-11-03 00:24:07 +0000291
292 free(dst);
stroese6f4474e2003-03-20 15:31:19 +0000293
294 /*
295 * Reset FPGA via FPGA_DATA pin
296 */
297 SET_FPGA(FPGA_PRG | FPGA_CLK);
298 udelay(1000); /* wait 1ms */
299 SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);
300 udelay(1000); /* wait 1ms */
301
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100302#if defined(CONFIG_CPCI405_6U)
303#error HIER GETH ES WEITER MIT IO ACCESSORS
stroese6f4474e2003-03-20 15:31:19 +0000304 if (cpci405_version() == 3) {
stroese6f4474e2003-03-20 15:31:19 +0000305 /*
306 * Enable outputs in fpga on version 3 board
307 */
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100308 out_be16((void*)CONFIG_SYS_FPGA_BASE_ADDR,
309 in_be16((void*)CONFIG_SYS_FPGA_BASE_ADDR) |
310 CONFIG_SYS_FPGA_MODE_ENABLE_OUTPUT);
stroese6f4474e2003-03-20 15:31:19 +0000311
312 /*
313 * Set outputs to 0
314 */
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100315 out_8((void*)CONFIG_SYS_LED_ADDR, 0x00);
stroese6f4474e2003-03-20 15:31:19 +0000316
317 /*
318 * Reset external DUART
319 */
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100320 out_be16((void*)CONFIG_SYS_FPGA_BASE_ADDR,
321 in_be16((void*)CONFIG_SYS_FPGA_BASE_ADDR) |
322 CONFIG_SYS_FPGA_MODE_DUART_RESET);
stroese6f4474e2003-03-20 15:31:19 +0000323 udelay(100);
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100324 out_be16((void*)CONFIG_SYS_FPGA_BASE_ADDR,
325 in_be16((void*)CONFIG_SYS_FPGA_BASE_ADDR) &
326 ~CONFIG_SYS_FPGA_MODE_DUART_RESET);
stroese6f4474e2003-03-20 15:31:19 +0000327 }
Matthias Fuchs6f35c532007-06-24 17:41:21 +0200328#endif
wdenkc6097192002-11-03 00:24:07 +0000329 }
330 else {
stroese6f4474e2003-03-20 15:31:19 +0000331 puts("\n*** U-Boot Version does not match Board Version!\n");
332 puts("*** CPCI-405 Version 1.x detected!\n");
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100333 puts("*** Please use correct U-Boot version "
334 "(CPCI405 instead of CPCI4052)!\n\n");
wdenkc6097192002-11-03 00:24:07 +0000335 }
stroese87663b12004-12-16 18:27:05 +0000336 }
wdenkc6097192002-11-03 00:24:07 +0000337#else /* CONFIG_CPCI405_VER2 */
stroese6f4474e2003-03-20 15:31:19 +0000338 if (cpci405_version() >= 2) {
339 puts("\n*** U-Boot Version does not match Board Version!\n");
340 puts("*** CPCI-405 Board Version 2.x detected!\n");
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100341 puts("*** Please use correct U-Boot version "
342 "(CPCI4052 instead of CPCI405)!\n\n");
wdenkc6097192002-11-03 00:24:07 +0000343 }
wdenkc6097192002-11-03 00:24:07 +0000344#endif /* CONFIG_CPCI405_VER2 */
345
346 /*
stroeseafcc4a72003-04-04 16:52:57 +0000347 * Select cts (and not dsr) on uart1
348 */
Stefan Roesed1c3b272009-09-09 16:25:29 +0200349 CPC0_CR0Reg = mfdcr(CPC0_CR0);
350 mtdcr(CPC0_CR0, CPC0_CR0Reg | 0x00001000);
stroeseafcc4a72003-04-04 16:52:57 +0000351
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100352 return 0;
wdenkc6097192002-11-03 00:24:07 +0000353}
354
wdenkc6097192002-11-03 00:24:07 +0000355/*
356 * Check Board Identity:
357 */
358
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100359int checkboard(void)
wdenkc6097192002-11-03 00:24:07 +0000360{
361#ifndef CONFIG_CPCI405_VER2
362 int index;
363 int len;
364#endif
Wolfgang Denk77ddac92005-10-13 16:45:02 +0200365 char str[64];
Wolfgang Denkcdb74972010-07-24 21:55:43 +0200366 int i = getenv_f("serial#", str, sizeof(str));
stroese6f4474e2003-03-20 15:31:19 +0000367 unsigned short ver;
wdenkc6097192002-11-03 00:24:07 +0000368
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100369 puts("Board: ");
wdenkc6097192002-11-03 00:24:07 +0000370
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100371 if (i == -1)
372 puts("### No HW ID - assuming CPCI405");
373 else
wdenkc6097192002-11-03 00:24:07 +0000374 puts(str);
wdenkc6097192002-11-03 00:24:07 +0000375
stroese6f4474e2003-03-20 15:31:19 +0000376 ver = cpci405_version();
377 printf(" (Ver %d.x, ", ver);
wdenkc6097192002-11-03 00:24:07 +0000378
wdenkc6097192002-11-03 00:24:07 +0000379 if (ctermm2()) {
Wolfgang Denk77ddac92005-10-13 16:45:02 +0200380 char str[4];
stroese1b554402003-09-12 08:44:46 +0000381
382 /*
383 * Read board-id and save in env-variable
384 */
385 sprintf(str, "%d", *(unsigned char *)0xf0000400);
386 setenv("boardid", str);
387 printf("CTERM-M2 - Id=%s)", str);
wdenkc6097192002-11-03 00:24:07 +0000388 } else {
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100389 if (cpci405_host())
390 puts("PCI Host Version)");
391 else
392 puts("PCI Adapter Version)");
wdenkc6097192002-11-03 00:24:07 +0000393 }
394
395#ifndef CONFIG_CPCI405_VER2
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100396 puts("\nFPGA: ");
wdenkc6097192002-11-03 00:24:07 +0000397
398 /* display infos on fpgaimage */
399 index = 15;
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100400 for (i = 0; i < 4; i++) {
wdenkc6097192002-11-03 00:24:07 +0000401 len = fpgadata[index];
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100402 printf("%s ", &(fpgadata[index + 1]));
403 index += len + 3;
wdenkc6097192002-11-03 00:24:07 +0000404 }
405#endif
406
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100407 putc('\n');
wdenkc6097192002-11-03 00:24:07 +0000408 return 0;
409}
410
Matthias Fuchs6f35c532007-06-24 17:41:21 +0200411void reset_phy(void)
wdenkc6097192002-11-03 00:24:07 +0000412{
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100413#if defined(CONFIG_LXT971_NO_SLEEP)
wdenkc6097192002-11-03 00:24:07 +0000414
Matthias Fuchs6f35c532007-06-24 17:41:21 +0200415 /*
416 * Disable sleep mode in LXT971
417 */
418 lxt971_no_sleep();
419#endif
wdenkc6097192002-11-03 00:24:07 +0000420}
421
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100422#if defined(CONFIG_CPCI405_VER2) && defined (CONFIG_IDE_RESET)
wdenkc6097192002-11-03 00:24:07 +0000423void ide_set_reset(int on)
424{
wdenkc6097192002-11-03 00:24:07 +0000425 /*
426 * Assert or deassert CompactFlash Reset Pin
427 */
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100428 if (on) { /* assert RESET */
429 out_be16((void*)CONFIG_SYS_FPGA_BASE_ADDR,
430 in_be16((void*)CONFIG_SYS_FPGA_BASE_ADDR) &
431 ~CONFIG_SYS_FPGA_MODE_CF_RESET);
432 } else { /* release RESET */
433 out_be16((void*)CONFIG_SYS_FPGA_BASE_ADDR,
434 in_be16((void*)CONFIG_SYS_FPGA_BASE_ADDR) |
435 CONFIG_SYS_FPGA_MODE_CF_RESET);
wdenkc6097192002-11-03 00:24:07 +0000436 }
437}
438
Matthias Fuchsf6a1f492009-01-02 12:17:36 +0100439#endif /* CONFIG_IDE_RESET && CONFIG_CPCI405_VER2 */
wdenkc6097192002-11-03 00:24:07 +0000440
Stefan Roese466fff12007-06-25 15:57:39 +0200441#if defined(CONFIG_PCI)
Matthias Fuchs6f35c532007-06-24 17:41:21 +0200442void cpci405_pci_fixup_irq(struct pci_controller *hose, pci_dev_t dev)
443{
444 unsigned char int_line = 0xff;
445
446 /*
447 * Write pci interrupt line register (cpci405 specific)
448 */
449 switch (PCI_DEV(dev) & 0x03) {
450 case 0:
451 int_line = 27 + 2;
452 break;
453 case 1:
454 int_line = 27 + 3;
455 break;
456 case 2:
457 int_line = 27 + 0;
458 break;
459 case 3:
460 int_line = 27 + 1;
461 break;
462 }
463
464 pci_hose_write_config_byte(hose, dev, PCI_INTERRUPT_LINE, int_line);
465}
466
467int pci_pre_init(struct pci_controller *hose)
468{
469 hose->fixup_irq = cpci405_pci_fixup_irq;
470 return 1;
471}
Stefan Roese466fff12007-06-25 15:57:39 +0200472#endif /* defined(CONFIG_PCI) */
Matthias Fuchs6f35c532007-06-24 17:41:21 +0200473
Matthias Fuchs600fe462009-01-02 12:18:12 +0100474#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
Simon Glasse895a4b2014-10-23 18:58:47 -0600475int ft_board_setup(void *blob, bd_t *bd)
Matthias Fuchs600fe462009-01-02 12:18:12 +0100476{
477 int rc;
478
479 __ft_board_setup(blob, bd);
480
481 /*
482 * Disable PCI in adapter mode.
483 */
484 if (!cpci405_host()) {
485 rc = fdt_find_and_setprop(blob, "/plb/pci@ec000000", "status",
486 "disabled", sizeof("disabled"), 1);
487 if (rc) {
488 printf("Unable to update property status in PCI node, "
489 "err=%s\n",
490 fdt_strerror(rc));
491 }
492 }
Simon Glasse895a4b2014-10-23 18:58:47 -0600493
494 return 0;
Matthias Fuchs600fe462009-01-02 12:18:12 +0100495}
496#endif /* defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) */