xref: /openbmc/u-boot/board/gdsys/mpc8308/mpc8308.c (revision d38826a3)
150dcf89dSDirk Eibach /*
250dcf89dSDirk Eibach  * (C) Copyright 2014
3*d38826a3SMario Six  * Dirk Eibach,  Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc
450dcf89dSDirk Eibach  *
550dcf89dSDirk Eibach  * SPDX-License-Identifier:	GPL-2.0+
650dcf89dSDirk Eibach  */
750dcf89dSDirk Eibach 
850dcf89dSDirk Eibach #include <common.h>
950dcf89dSDirk Eibach #include <command.h>
1050dcf89dSDirk Eibach #include <asm/processor.h>
1150dcf89dSDirk Eibach #include <asm/io.h>
1250dcf89dSDirk Eibach #include <asm/global_data.h>
1350dcf89dSDirk Eibach 
1450dcf89dSDirk Eibach #include "mpc8308.h"
1550dcf89dSDirk Eibach #include <gdsys_fpga.h>
1650dcf89dSDirk Eibach 
1750dcf89dSDirk Eibach #define REFLECTION_TESTPATTERN 0xdede
1850dcf89dSDirk Eibach #define REFLECTION_TESTPATTERN_INV (~REFLECTION_TESTPATTERN & 0xffff)
1950dcf89dSDirk Eibach 
2050dcf89dSDirk Eibach #ifdef CONFIG_SYS_FPGA_NO_RFL_HI
2150dcf89dSDirk Eibach #define REFLECTION_TESTREG reflection_low
2250dcf89dSDirk Eibach #else
2350dcf89dSDirk Eibach #define REFLECTION_TESTREG reflection_high
2450dcf89dSDirk Eibach #endif
2550dcf89dSDirk Eibach 
2650dcf89dSDirk Eibach DECLARE_GLOBAL_DATA_PTR;
2750dcf89dSDirk Eibach 
2850dcf89dSDirk Eibach int get_fpga_state(unsigned dev)
2950dcf89dSDirk Eibach {
3050dcf89dSDirk Eibach 	return gd->arch.fpga_state[dev];
3150dcf89dSDirk Eibach }
3250dcf89dSDirk Eibach 
3350dcf89dSDirk Eibach int board_early_init_f(void)
3450dcf89dSDirk Eibach {
3550dcf89dSDirk Eibach 	unsigned k;
3650dcf89dSDirk Eibach 
3750dcf89dSDirk Eibach 	for (k = 0; k < CONFIG_SYS_FPGA_COUNT; ++k)
3850dcf89dSDirk Eibach 		gd->arch.fpga_state[k] = 0;
3950dcf89dSDirk Eibach 
4050dcf89dSDirk Eibach 	return 0;
4150dcf89dSDirk Eibach }
4250dcf89dSDirk Eibach 
4350dcf89dSDirk Eibach int board_early_init_r(void)
4450dcf89dSDirk Eibach {
4550dcf89dSDirk Eibach 	unsigned k;
4650dcf89dSDirk Eibach 	unsigned ctr;
4750dcf89dSDirk Eibach 
4850dcf89dSDirk Eibach 	for (k = 0; k < CONFIG_SYS_FPGA_COUNT; ++k)
4950dcf89dSDirk Eibach 		gd->arch.fpga_state[k] = 0;
5050dcf89dSDirk Eibach 
5150dcf89dSDirk Eibach 	/*
5250dcf89dSDirk Eibach 	 * reset FPGA
5350dcf89dSDirk Eibach 	 */
5450dcf89dSDirk Eibach 	mpc8308_init();
5550dcf89dSDirk Eibach 
5650dcf89dSDirk Eibach 	mpc8308_set_fpga_reset(1);
5750dcf89dSDirk Eibach 
5850dcf89dSDirk Eibach 	mpc8308_setup_hw();
5950dcf89dSDirk Eibach 
6050dcf89dSDirk Eibach 	for (k = 0; k < CONFIG_SYS_FPGA_COUNT; ++k) {
6150dcf89dSDirk Eibach 		ctr = 0;
6250dcf89dSDirk Eibach 		while (!mpc8308_get_fpga_done(k)) {
6350dcf89dSDirk Eibach 			udelay(100000);
6450dcf89dSDirk Eibach 			if (ctr++ > 5) {
6550dcf89dSDirk Eibach 				gd->arch.fpga_state[k] |=
6650dcf89dSDirk Eibach 					FPGA_STATE_DONE_FAILED;
6750dcf89dSDirk Eibach 				break;
6850dcf89dSDirk Eibach 			}
6950dcf89dSDirk Eibach 		}
7050dcf89dSDirk Eibach 	}
7150dcf89dSDirk Eibach 
7250dcf89dSDirk Eibach 	udelay(10);
7350dcf89dSDirk Eibach 
7450dcf89dSDirk Eibach 	mpc8308_set_fpga_reset(0);
7550dcf89dSDirk Eibach 
7650dcf89dSDirk Eibach 	for (k = 0; k < CONFIG_SYS_FPGA_COUNT; ++k) {
7750dcf89dSDirk Eibach 		/*
7850dcf89dSDirk Eibach 		 * wait for fpga out of reset
7950dcf89dSDirk Eibach 		 */
8050dcf89dSDirk Eibach 		ctr = 0;
8150dcf89dSDirk Eibach 		while (1) {
8250dcf89dSDirk Eibach 			u16 val;
8350dcf89dSDirk Eibach 
8450dcf89dSDirk Eibach 			FPGA_SET_REG(k, reflection_low, REFLECTION_TESTPATTERN);
8550dcf89dSDirk Eibach 
8650dcf89dSDirk Eibach 			FPGA_GET_REG(k, REFLECTION_TESTREG, &val);
8750dcf89dSDirk Eibach 			if (val == REFLECTION_TESTPATTERN_INV)
8850dcf89dSDirk Eibach 				break;
8950dcf89dSDirk Eibach 
9050dcf89dSDirk Eibach 			udelay(100000);
9150dcf89dSDirk Eibach 			if (ctr++ > 5) {
9250dcf89dSDirk Eibach 				gd->arch.fpga_state[k] |=
9350dcf89dSDirk Eibach 					FPGA_STATE_REFLECTION_FAILED;
9450dcf89dSDirk Eibach 				break;
9550dcf89dSDirk Eibach 			}
9650dcf89dSDirk Eibach 		}
9750dcf89dSDirk Eibach 	}
9850dcf89dSDirk Eibach 
9950dcf89dSDirk Eibach 	return 0;
10050dcf89dSDirk Eibach }
101