summaryrefslogtreecommitdiff
path: root/board/eltec/bab7xx/bab7xx.c
blob: 8c561161c579c1703a70dedcc5f5a653a75a2a60 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
/*
 * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
 * Andreas Heppel <aheppel@sysgo.de>
 * (C) Copyright 2001 ELTEC Elektronik AG
 * Frank Gottschling <fgottschling@eltec.de>
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <common.h>
#include <command.h>
#include <mpc106.h>
#include <mk48t59.h>
#include <74xx_7xx.h>
#include <ns87308.h>
#include <video_fb.h>
#include <netdev.h>

DECLARE_GLOBAL_DATA_PTR;

/*---------------------------------------------------------------------------*/
/*
 * Get Bus clock frequency
 */
ulong bab7xx_get_bus_freq (void)
{
	/*
	 * The GPIO Port 1 on BAB7xx reflects the bus speed.
	 */
	volatile struct GPIO *gpio =
		(struct GPIO *) (CFG_ISA_IO + CFG_NS87308_GPIO_BASE);

	unsigned char data = gpio->dta1;

	if (data & 0x02)
		return 66666666;

	return 83333333;
}

/*---------------------------------------------------------------------------*/

/*
 * Measure CPU clock speed (core clock GCLK1) (Approx. GCLK frequency in Hz)
 */
ulong bab7xx_get_gclk_freq (void)
{
	static const int pllratio_to_factor[] = {
		00, 75, 70, 00, 20, 65, 100, 45, 30, 55, 40, 50, 80, 60, 35,
			00,
	};

	return pllratio_to_factor[get_hid1 () >> 28] *
		(bab7xx_get_bus_freq () / 10);
}

/*----------------------------------------------------------------------------*/

int checkcpu (void)
{
	uint pvr = get_pvr ();

	printf ("MPC7xx V%d.%d", (pvr >> 8) & 0xFF, pvr & 0xFF);
	printf (" at %ld / %ld MHz\n", bab7xx_get_gclk_freq () / 1000000,
		bab7xx_get_bus_freq () / 1000000);

	return (0);
}

/* ------------------------------------------------------------------------- */

int checkboard (void)
{
#ifdef CFG_ADDRESS_MAP_A
	puts ("Board: ELTEC BAB7xx PReP\n");
#else
	puts ("Board: ELTEC BAB7xx CHRP\n");
#endif
	return (0);
}

/* ------------------------------------------------------------------------- */

int checkflash (void)
{
	/* TODO: XXX XXX XXX */
	printf ("2 MB ## Test not implemented yet ##\n");
	return (0);
}

/* ------------------------------------------------------------------------- */


static unsigned int mpc106_read_cfg_dword (unsigned int reg)
{
	unsigned int reg_addr = MPC106_REG | (reg & 0xFFFFFFFC);

	out32r (MPC106_REG_ADDR, reg_addr);

	return (in32r (MPC106_REG_DATA | (reg & 0x3)));
}

/* ------------------------------------------------------------------------- */

long int dram_size (int board_type)
{
	/* No actual initialisation to do - done when setting up
	 * PICRs MCCRs ME/SARs etc in ram_init.S.
	 */

	register unsigned long i, msar1, mear1, memSize;

#if defined(CFG_MEMTEST)
	register unsigned long reg;

	printf ("Testing DRAM\n");

	/* write each mem addr with it's address */
	for (reg = CFG_MEMTEST_START; reg < CFG_MEMTEST_END; reg += 4)
		*reg = reg;

	for (reg = CFG_MEMTEST_START; reg < CFG_MEMTEST_END; reg += 4) {
		if (*reg != reg)
			return -1;
	}
#endif

	/*
	 * Since MPC106 memory controller chip has already been set to
	 * control all memory, just read and interpret its memory boundery register.
	 */
	memSize = 0;
	msar1 = mpc106_read_cfg_dword (MPC106_MSAR1);
	mear1 = mpc106_read_cfg_dword (MPC106_MEAR1);
	i = mpc106_read_cfg_dword (MPC106_MBER) & 0xf;

	do {
		if (i & 0x01)	/* is bank enabled ? */
			memSize += (mear1 & 0xff) - (msar1 & 0xff) + 1;
		msar1 >>= 8;
		mear1 >>= 8;
		i >>= 1;
	} while (i);

	return (memSize * 0x100000);
}

/* ------------------------------------------------------------------------- */

phys_size_t initdram (int board_type)
{
	return dram_size (board_type);
}

/* ------------------------------------------------------------------------- */

void after_reloc (ulong dest_addr)
{
	/*
	 * Jump to the main U-Boot board init code
	 */
	board_init_r ((gd_t *) gd, dest_addr);
}

/* ------------------------------------------------------------------------- */

/*
 * do_reset is done here because in this case it is board specific, since the
 * 7xx CPUs can only be reset by external HW (the RTC in this case).
 */
void do_reset (cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[])
{
#if defined(CONFIG_RTC_MK48T59)
	/* trigger watchdog immediately */
	rtc_set_watchdog (1, RTC_WD_RB_16TH);
#else
#error "You must define the macro CONFIG_RTC_MK48T59."
#endif
}

/* ------------------------------------------------------------------------- */

#if defined(CONFIG_WATCHDOG)
/*
 * Since the 7xx CPUs don't have an internal watchdog, this function is
 * board specific.  We use the RTC here.
 */
void watchdog_reset (void)
{
#if defined(CONFIG_RTC_MK48T59)
	/* we use a 32 sec watchdog timer */
	rtc_set_watchdog (8, RTC_WD_RB_4);
#else
#error "You must define the macro CONFIG_RTC_MK48T59."
#endif
}
#endif /* CONFIG_WATCHDOG */

/* ------------------------------------------------------------------------- */

#ifdef CONFIG_CONSOLE_EXTRA_INFO
extern GraphicDevice smi;

void video_get_info_str (int line_number, char *info)
{
	/* init video info strings for graphic console */
	switch (line_number) {
	case 1:
		sprintf (info, " MPC7xx V%d.%d at %ld / %ld MHz",
			 (get_pvr () >> 8) & 0xFF,
			 get_pvr () & 0xFF,
			 bab7xx_get_gclk_freq () / 1000000,
			 bab7xx_get_bus_freq () / 1000000);
		return;
	case 2:
		sprintf (info,
			 " ELTEC BAB7xx with %ld MB DRAM and %ld MB FLASH",
			 dram_size (0) / 0x100000, flash_init () / 0x100000);
		return;
	case 3:
		sprintf (info, " %s", smi.modeIdent);
		return;
	}

	/* no more info lines */
	*info = 0;
	return;
}
#endif

/*---------------------------------------------------------------------------*/

int board_eth_init(bd_t *bis)
{
	return pci_eth_init(bis);
}