]> git.ipfire.org Git - people/ms/u-boot.git/blame - board/lwmon/lwmon.c
* Patches by Yuli Barcohen, 13 Jul 2003:
[people/ms/u-boot.git] / board / lwmon / lwmon.c
CommitLineData
e2211743
WD
1/***********************************************************************
2 *
3M* Modul: lwmon.c
4M*
5M* Content: LWMON specific U-Boot commands.
6 *
7 * (C) Copyright 2001, 2002
8 * DENX Software Engineering
9 * Wolfgang Denk, wd@denx.de
10 * All rights reserved.
11 *
12D* Design: wd@denx.de
13C* Coding: wd@denx.de
14V* Verification: dzu@denx.de
15 *
16 * See file CREDITS for list of people who contributed to this
17 * project.
18 *
19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU General Public License as
21 * published by the Free Software Foundation; either version 2 of
22 * the License, or (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
32 * MA 02111-1307 USA
33 ***********************************************************************/
34
35/*---------------------------- Headerfiles ----------------------------*/
36#include <common.h>
37#include <mpc8xx.h>
38#include <commproc.h>
39#include <i2c.h>
40#include <command.h>
e2211743
WD
41#include <malloc.h>
42#include <post.h>
43
44#include <linux/types.h>
45#include <linux/string.h> /* for strdup */
46
47/*------------------------ Local prototypes ---------------------------*/
48static long int dram_size (long int, long int *, long int);
4532cb69
WD
49static void kbd_init (void);
50static int compare_magic (uchar *kbd_data, uchar *str);
e2211743
WD
51
52
53/*--------------------- Local macros and constants --------------------*/
54#define _NOT_USED_ 0xFFFFFFFF
55
4532cb69
WD
56#ifdef CONFIG_MODEM_SUPPORT
57static int key_pressed(void);
58extern void disable_putc(void);
59#endif /* CONFIG_MODEM_SUPPORT */
60
e2211743
WD
61/*
62 * 66 MHz SDRAM access using UPM A
63 */
64const uint sdram_table[] =
65{
66#if defined(CFG_MEMORY_75) || defined(CFG_MEMORY_8E)
67 /*
68 * Single Read. (Offset 0 in UPM RAM)
69 */
70 0x1F0DFC04, 0xEEAFBC04, 0x11AF7C04, 0xEFBAFC00,
71 0x1FF5FC47, /* last */
72 /*
73 * SDRAM Initialization (offset 5 in UPM RAM)
74 *
8bde7f77
WD
75 * This is no UPM entry point. The following definition uses
76 * the remaining space to establish an initialization
77 * sequence, which is executed by a RUN command.
e2211743
WD
78 *
79 */
80 0x1FF5FC34, 0xEFEABC34, 0x1FB57C35, /* last */
81 /*
82 * Burst Read. (Offset 8 in UPM RAM)
83 */
84 0x1F0DFC04, 0xEEAFBC04, 0x10AF7C04, 0xF0AFFC00,
85 0xF0AFFC00, 0xF1AFFC00, 0xEFBAFC00, 0x1FF5FC47, /* last */
86 _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
87 _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
88 /*
89 * Single Write. (Offset 18 in UPM RAM)
90 */
91 0x1F2DFC04, 0xEEABBC00, 0x01B27C04, 0x1FF5FC47, /* last */
92 _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
93 /*
94 * Burst Write. (Offset 20 in UPM RAM)
95 */
96 0x1F0DFC04, 0xEEABBC00, 0x10A77C00, 0xF0AFFC00,
97 0xF0AFFC00, 0xE1BAFC04, 0x01FF5FC47, /* last */
98 _NOT_USED_,
99 _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
100 _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
101 /*
102 * Refresh (Offset 30 in UPM RAM)
103 */
104 0x1FFD7C84, 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC04,
105 0xFFFFFC84, 0xFFFFFC07, /* last */
106 _NOT_USED_, _NOT_USED_,
107 _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
108 /*
109 * Exception. (Offset 3c in UPM RAM)
110 */
111 0x7FFFFC07, /* last */
112 0xFFFFFCFF, 0xFFFFFCFF, 0xFFFFFCFF,
113#endif
114#ifdef CFG_MEMORY_7E
115 /*
116 * Single Read. (Offset 0 in UPM RAM)
117 */
118 0x0E2DBC04, 0x11AF7C04, 0xEFBAFC00, 0x1FF5FC47, /* last */
119 _NOT_USED_,
120 /*
121 * SDRAM Initialization (offset 5 in UPM RAM)
122 *
8bde7f77
WD
123 * This is no UPM entry point. The following definition uses
124 * the remaining space to establish an initialization
125 * sequence, which is executed by a RUN command.
e2211743
WD
126 *
127 */
128 0x1FF5FC34, 0xEFEABC34, 0x1FB57C35, /* last */
129 /*
130 * Burst Read. (Offset 8 in UPM RAM)
131 */
132 0x0E2DBC04, 0x10AF7C04, 0xF0AFFC00, 0xF0AFFC00,
133 0xF1AFFC00, 0xEFBAFC00, 0x1FF5FC47, /* last */
8bde7f77 134 _NOT_USED_,
e2211743
WD
135 _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
136 _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
137 /*
138 * Single Write. (Offset 18 in UPM RAM)
139 */
140 0x0E29BC04, 0x01B27C04, 0x1FF5FC47, /* last */
141 _NOT_USED_,
142 _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
143 /*
144 * Burst Write. (Offset 20 in UPM RAM)
145 */
146 0x0E29BC04, 0x10A77C00, 0xF0AFFC00, 0xF0AFFC00,
147 0xE1BAFC04, 0x1FF5FC47, /* last */
8bde7f77 148 _NOT_USED_, _NOT_USED_,
e2211743
WD
149 _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
150 _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
151 /*
152 * Refresh (Offset 30 in UPM RAM)
153 */
154 0x1FFD7C84, 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC04,
155 0xFFFFFC84, 0xFFFFFC07, /* last */
156 _NOT_USED_, _NOT_USED_,
157 _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
158 /*
159 * Exception. (Offset 3c in UPM RAM)
160 */
161 0x7FFFFC07, /* last */
162 0xFFFFFCFF, 0xFFFFFCFF, 0xFFFFFCFF,
163#endif
164};
165
166/*
167 * Check Board Identity:
168 *
169 */
170
171/***********************************************************************
172F* Function: int checkboard (void) P*A*Z*
173 *
174P* Parameters: none
175P*
176P* Returnvalue: int - 0 is always returned
177 *
178Z* Intention: This function is the checkboard() method implementation
179Z* for the lwmon board. Only a standard message is printed.
180 *
181D* Design: wd@denx.de
182C* Coding: wd@denx.de
183V* Verification: dzu@denx.de
184 ***********************************************************************/
185int checkboard (void)
186{
8564acf9 187 puts ("Board: LICCON Konsole LCD2\n");
e2211743
WD
188 return (0);
189}
190
191/***********************************************************************
192F* Function: long int initdram (int board_type) P*A*Z*
193 *
194P* Parameters: int board_type
195P* - Usually type of the board - ignored here.
196P*
197P* Returnvalue: long int
198P* - Size of initialized memory
199 *
200Z* Intention: This function is the initdram() method implementation
201Z* for the lwmon board.
202Z* The memory controller is initialized to access the
203Z* DRAM.
204 *
205D* Design: wd@denx.de
206C* Coding: wd@denx.de
207V* Verification: dzu@denx.de
208 ***********************************************************************/
209long int initdram (int board_type)
210{
211 volatile immap_t *immr = (immap_t *) CFG_IMMR;
212 volatile memctl8xx_t *memctl = &immr->im_memctl;
213 long int size_b0;
214 long int size8, size9;
215 int i;
216
217 /*
218 * Configure UPMA for SDRAM
219 */
220 upmconfig (UPMA, (uint *)sdram_table, sizeof(sdram_table)/sizeof(uint));
221
222 memctl->memc_mptpr = CFG_MPTPR;
223
224 /* burst length=4, burst type=sequential, CAS latency=2 */
225 memctl->memc_mar = CFG_MAR;
226
227 /*
228 * Map controller bank 3 to the SDRAM bank at preliminary address.
229 */
230 memctl->memc_or3 = CFG_OR3_PRELIM;
231 memctl->memc_br3 = CFG_BR3_PRELIM;
232
233 /* initialize memory address register */
234 memctl->memc_mamr = CFG_MAMR_8COL; /* refresh not enabled yet */
235
236 /* mode initialization (offset 5) */
237 udelay (200); /* 0x80006105 */
238 memctl->memc_mcr = MCR_OP_RUN | MCR_MB_CS3 | MCR_MLCF (1) | MCR_MAD (0x05);
239
240 /* run 2 refresh sequence with 4-beat refresh burst (offset 0x30) */
241 udelay (1); /* 0x80006130 */
242 memctl->memc_mcr = MCR_OP_RUN | MCR_MB_CS3 | MCR_MLCF (1) | MCR_MAD (0x30);
243 udelay (1); /* 0x80006130 */
244 memctl->memc_mcr = MCR_OP_RUN | MCR_MB_CS3 | MCR_MLCF (1) | MCR_MAD (0x30);
245
246 udelay (1); /* 0x80006106 */
247 memctl->memc_mcr = MCR_OP_RUN | MCR_MB_CS3 | MCR_MLCF (1) | MCR_MAD (0x06);
248
249 memctl->memc_mamr |= MAMR_PTBE; /* refresh enabled */
250
251 udelay (200);
252
253 /* Need at least 10 DRAM accesses to stabilize */
254 for (i = 0; i < 10; ++i) {
255 volatile unsigned long *addr =
256 (volatile unsigned long *) SDRAM_BASE3_PRELIM;
257 unsigned long val;
258
259 val = *(addr + i);
260 *(addr + i) = val;
261 }
262
263 /*
264 * Check Bank 0 Memory Size for re-configuration
265 *
266 * try 8 column mode
267 */
268 size8 = dram_size (CFG_MAMR_8COL, (ulong *)SDRAM_BASE3_PRELIM, SDRAM_MAX_SIZE);
269
270 udelay (1000);
271
272 /*
273 * try 9 column mode
274 */
275 size9 = dram_size (CFG_MAMR_9COL, (ulong *)SDRAM_BASE3_PRELIM, SDRAM_MAX_SIZE);
276
277 if (size8 < size9) { /* leave configuration at 9 columns */
278 size_b0 = size9;
279 memctl->memc_mamr = CFG_MAMR_9COL | MAMR_PTBE;
280 udelay (500);
281 } else { /* back to 8 columns */
282 size_b0 = size8;
283 memctl->memc_mamr = CFG_MAMR_8COL | MAMR_PTBE;
284 udelay (500);
285 }
286
287 /*
288 * Final mapping:
289 */
290
291 memctl->memc_or3 = ((-size_b0) & 0xFFFF0000) |
292 OR_CSNT_SAM | OR_G5LS | SDRAM_TIMING;
293 memctl->memc_br3 = (CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V;
294 udelay (1000);
295
296 return (size_b0);
297}
298
299/***********************************************************************
300F* Function: static long int dram_size (long int mamr_value,
301F* long int *base,
302F* long int maxsize) P*A*Z*
303 *
304P* Parameters: long int mamr_value
305P* - Value for MAMR for the test
306P* long int *base
307P* - Base address for the test
308P* long int maxsize
309P* - Maximum size to test for
310P*
311P* Returnvalue: long int
312P* - Size of probed memory
313 *
314Z* Intention: Check memory range for valid RAM. A simple memory test
315Z* determines the actually available RAM size between
316Z* addresses `base' and `base + maxsize'. Some (not all)
317Z* hardware errors are detected:
318Z* - short between address lines
319Z* - short between data lines
320 *
321D* Design: wd@denx.de
322C* Coding: wd@denx.de
323V* Verification: dzu@denx.de
324 ***********************************************************************/
325static long int dram_size (long int mamr_value, long int *base, long int maxsize)
326{
327 volatile immap_t *immr = (immap_t *) CFG_IMMR;
328 volatile memctl8xx_t *memctl = &immr->im_memctl;
329 volatile long int *addr;
330 ulong cnt, val;
331 ulong save[32]; /* to make test non-destructive */
332 unsigned char i = 0;
333
334 memctl->memc_mamr = mamr_value;
335
336 for (cnt = maxsize / sizeof (long); cnt > 0; cnt >>= 1) {
337 addr = base + cnt; /* pointer arith! */
338
339 save[i++] = *addr;
340 *addr = ~cnt;
341 }
342
343 /* write 0 to base address */
344 addr = base;
345 save[i] = *addr;
346 *addr = 0;
347
348 /* check at base address */
349 if ((val = *addr) != 0) {
350 *addr = save[i];
351 return (0);
352 }
353
354 for (cnt = 1; cnt <= maxsize / sizeof (long); cnt <<= 1) {
355 addr = base + cnt; /* pointer arith! */
356
357 val = *addr;
358 *addr = save[--i];
359
360 if (val != (~cnt)) {
361 return (cnt * sizeof (long));
362 }
363 }
364 return (maxsize);
365}
366
367/* ------------------------------------------------------------------------- */
368
369#ifndef PB_ENET_TENA
370# define PB_ENET_TENA ((uint)0x00002000) /* PB 18 */
371#endif
372
373/***********************************************************************
374F* Function: int board_pre_init (void) P*A*Z*
375 *
376P* Parameters: none
377P*
378P* Returnvalue: int
379P* - 0 is always returned.
380 *
381Z* Intention: This function is the board_pre_init() method implementation
382Z* for the lwmon board.
383Z* Disable Ethernet TENA on Port B.
384 *
385D* Design: wd@denx.de
386C* Coding: wd@denx.de
387V* Verification: dzu@denx.de
388 ***********************************************************************/
389int board_pre_init (void)
390{
391 volatile immap_t *immr = (immap_t *) CFG_IMMR;
392
393 /* Disable Ethernet TENA on Port B
394 * Necessary because of pull up in COM3 port.
395 *
396 * This is just a preliminary fix, intended to turn off TENA
397 * as soon as possible to avoid noise on the network. Once
398