]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/eltec/mhpc/mhpc.c
common: move extern char console_buffer[] to common.h
[karo-tx-uboot.git] / board / eltec / mhpc / mhpc.c
1 /*
2  * (C) Copyright 2001
3  * ELTEC Elektronik AG
4  * Frank Gottschling <fgottschling@eltec.de>
5  *
6  * Board specific routines for the miniHiPerCam
7  *
8  * - initialisation (eeprom)
9  * - memory controller
10  * - serial io initialisation
11  * - ethernet io initialisation
12  *
13  * -----------------------------------------------------------------
14  * See file CREDITS for list of people who contributed to this
15  * project.
16  *
17  * This program is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU General Public License as
19  * published by the Free Software Foundation; either version 2 of
20  * the License, or (at your option) any later version.
21  *
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
30  * MA 02111-1307 USA
31  */
32 #include <common.h>
33 #include <linux/ctype.h>
34 #include <commproc.h>
35 #include "mpc8xx.h"
36 #include <video_fb.h>
37
38 extern void eeprom_init (void);
39 extern int eeprom_read (unsigned dev_addr, unsigned offset,
40                         unsigned char *buffer, unsigned cnt);
41 extern int eeprom_write (unsigned dev_addr, unsigned offset,
42                          unsigned char *buffer, unsigned cnt);
43
44 /* globals */
45 void *video_hw_init (void);
46 void video_set_lut (unsigned int index, /* color number */
47                     unsigned char r,    /* red */
48                     unsigned char g,    /* green */
49                     unsigned char b     /* blue */
50         );
51
52 GraphicDevice gdev;
53
54 /* locals */
55 static void video_circle (char *center, int radius, int color, int pitch);
56 static void video_test_image (void);
57 static void video_default_lut (unsigned int clut_type);
58
59 /* revision info foer MHPC EEPROM offset 480 */
60 typedef struct {
61         char board[12];         /* 000 - Board Revision information */
62         char sensor;            /* 012 - Sensor Type information */
63         char serial[8];         /* 013 - Board serial number */
64         char etheraddr[6];      /* 021 - Ethernet node addresse */
65         char revision[2];       /* 027 - Revision code */
66         char option[3];         /* 029 - resevered for options */
67 } revinfo;
68
69 /* ------------------------------------------------------------------------- */
70
71 static const unsigned int sdram_table[] = {
72         /* read single beat cycle */
73         0xef0efc04, 0x0e2dac04, 0x01ba5c04, 0x1ff5fc00,
74         0xfffffc05, 0xeffafc34, 0x0ff0bc34, 0x1ff57c35,
75
76         /* read burst cycle */
77         0xef0efc04, 0x0e3dac04, 0x10ff5c04, 0xf0fffc00,
78         0xf0fffc00, 0xf1fffc00, 0xfffffc00, 0xfffffc05,
79         0xfffffc04, 0xfffffc04, 0xfffffc04, 0xfffffc04,
80         0xfffffc04, 0xfffffc04, 0xfffffc04, 0xfffffc04,
81
82         /* write single beat cycle */
83         0xef0efc04, 0x0e29ac00, 0x01b25c04, 0x1ff5fc05,
84         0xfffffc04, 0xfffffc04, 0xfffffc04, 0xfffffc04,
85
86         /* write burst cycle */
87         0xef0ef804, 0x0e39a000, 0x10f75000, 0xf0fff440,
88         0xf0fffc40, 0xf1fffc04, 0xfffffc05, 0xfffffc04,
89         0xfffffc04, 0xfffffc04, 0xfffffc04, 0xfffffc04,
90         0xfffffc04, 0xfffffc04, 0xfffffc04, 0xfffffc04,
91
92         /* periodic timer expired */
93         0xeffebc84, 0x1ffd7c04, 0xfffffc04, 0xfffffc84,
94         0xeffebc04, 0x1ffd7c04, 0xfffffc04, 0xfffffc05,
95         0xfffffc04, 0xfffffc04, 0xfffffc04, 0xfffffc04,
96
97         /* exception */
98         0xfffffc04, 0xfffffc05, 0xfffffc04, 0xfffffc04
99 };
100
101 /* ------------------------------------------------------------------------- */
102
103 int board_early_init_f (void)
104 {
105         volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
106         volatile cpm8xx_t *cp = &(im->im_cpm);
107         volatile iop8xx_t *ip = (iop8xx_t *) & (im->im_ioport);
108
109         /* reset the port A s.a. cpm-routines */
110         ip->iop_padat = 0x0000;
111         ip->iop_papar = 0x0000;
112         ip->iop_padir = 0x0800;
113         ip->iop_paodr = 0x0000;
114
115         /* reset the port B for digital and LCD output */
116         cp->cp_pbdat = 0x0300;
117         cp->cp_pbpar = 0x5001;
118         cp->cp_pbdir = 0x5301;
119         cp->cp_pbodr = 0x0000;
120
121         /* reset the port C configured for SMC1 serial port and aqc. control */
122         ip->iop_pcdat = 0x0800;
123         ip->iop_pcpar = 0x0000;
124         ip->iop_pcdir = 0x0e30;
125         ip->iop_pcso = 0x0000;
126
127         /* Config port D for LCD output */
128         ip->iop_pdpar = 0x1fff;
129         ip->iop_pddir = 0x1fff;
130
131         return (0);
132 }
133
134 /* ------------------------------------------------------------------------- */
135
136 /*
137  * Check Board Identity
138  */
139 int checkboard (void)
140 {
141         puts ("Board: ELTEC miniHiperCam\n");
142         return (0);
143 }
144
145 /* ------------------------------------------------------------------------- */
146
147 int misc_init_r (void)
148 {
149         revinfo mhpcRevInfo;
150         char nid[32];
151         char *mhpcSensorTypes[] = { "OMNIVISON OV7610/7620 color",
152                 "OMNIVISON OV7110 b&w", NULL
153         };
154         char hex[23] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0,
155                 0, 0, 0, 0, 10, 11, 12, 13, 14, 15
156         };
157         int i;
158
159         /* check revision data */
160         eeprom_read (CONFIG_SYS_I2C_EEPROM_ADDR, 480, (uchar *) &mhpcRevInfo, 32);
161
162         if (strncmp ((char *) &mhpcRevInfo.board[2], "MHPC", 4) != 0) {
163                 printf ("Enter revision number (0-9): %c  ",
164                         mhpcRevInfo.revision[0]);
165                 if (0 != readline (NULL)) {
166                         mhpcRevInfo.revision[0] =
167                                 (char) toupper (console_buffer[0]);
168                 }
169
170                 printf ("Enter revision character (A-Z): %c  ",
171                         mhpcRevInfo.revision[1]);
172                 if (1 == readline (NULL)) {
173                         mhpcRevInfo.revision[1] =
174                                 (char) toupper (console_buffer[0]);
175                 }
176
177                 printf ("Enter board name (V-XXXX-XXXX): %s  ",
178                         (char *) &mhpcRevInfo.board);
179                 if (11 == readline (NULL)) {
180                         for (i = 0; i < 11; i++) {
181                                 mhpcRevInfo.board[i] =
182                                         (char) toupper (console_buffer[i]);
183                                 mhpcRevInfo.board[11] = '\0';
184                         }
185                 }
186
187                 printf ("Supported sensor types:\n");
188                 i = 0;
189                 do {
190                         printf ("\n    \'%d\' : %s\n", i, mhpcSensorTypes[i]);
191                 } while (mhpcSensorTypes[++i] != NULL);
192
193                 do {
194                         printf ("\nEnter sensor number (0-255): %d  ",
195                                 (int) mhpcRevInfo.sensor);
196                         if (0 != readline (NULL)) {
197                                 mhpcRevInfo.sensor =
198                                         (unsigned char)
199                                         simple_strtoul (console_buffer, NULL,
200                                                         10);
201                         }
202                 } while (mhpcRevInfo.sensor >= i);
203
204                 printf ("Enter serial number: %s ",
205                         (char *) &mhpcRevInfo.serial);
206                 if (6 == readline (NULL)) {
207                         for (i = 0; i < 6; i++) {
208                                 mhpcRevInfo.serial[i] = console_buffer[i];
209                         }
210                         mhpcRevInfo.serial[6] = '\0';
211                 }
212
213                 printf ("Enter ether node ID with leading zero (HEX): %02x%02x%02x%02x%02x%02x  ", mhpcRevInfo.etheraddr[0], mhpcRevInfo.etheraddr[1], mhpcRevInfo.etheraddr[2], mhpcRevInfo.etheraddr[3], mhpcRevInfo.etheraddr[4], mhpcRevInfo.etheraddr[5]);
214                 if (12 == readline (NULL)) {
215                         for (i = 0; i < 12; i += 2) {
216                                 mhpcRevInfo.etheraddr[i >> 1] =
217                                         (char) (16 *
218                                                 hex[toupper
219                                                     (console_buffer[i]) -
220                                                     '0'] +
221                                                 hex[toupper
222                                                     (console_buffer[i + 1]) -
223                                                     '0']);
224                         }
225                 }
226
227                 /* setup new revision data */
228                 eeprom_write (CONFIG_SYS_I2C_EEPROM_ADDR, 480, (uchar *) &mhpcRevInfo,
229                               32);
230         }
231
232         /* set environment */
233         sprintf (nid, "%02x:%02x:%02x:%02x:%02x:%02x",
234                  mhpcRevInfo.etheraddr[0], mhpcRevInfo.etheraddr[1],
235                  mhpcRevInfo.etheraddr[2], mhpcRevInfo.etheraddr[3],
236                  mhpcRevInfo.etheraddr[4], mhpcRevInfo.etheraddr[5]);
237         setenv ("ethaddr", nid);
238
239         /* print actual board identification */
240         printf ("Ident: %s %s Ser %s Rev %c%c\n",
241                 mhpcRevInfo.board,
242                 (mhpcRevInfo.sensor == 0 ? "color" : "b&w"),
243                 (char *) &mhpcRevInfo.serial, mhpcRevInfo.revision[0],
244                 mhpcRevInfo.revision[1]);
245
246         return (0);
247 }
248
249 /* ------------------------------------------------------------------------- */
250
251 phys_size_t initdram (int board_type)
252 {
253         volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
254         volatile memctl8xx_t *memctl = &immap->im_memctl;
255
256         upmconfig (UPMA, (uint *) sdram_table,
257                    sizeof (sdram_table) / sizeof (uint));
258
259         memctl->memc_mamr = CONFIG_SYS_MAMR & (~(MAMR_PTAE));   /* no refresh yet */
260         memctl->memc_mbmr = MBMR_GPL_B4DIS;     /* should this be mamr? - NTL */
261         memctl->memc_mptpr = MPTPR_PTP_DIV64;
262         memctl->memc_mar = 0x00008800;
263
264         /*
265          * Map controller SDRAM bank 0
266          */
267         memctl->memc_or1 = CONFIG_SYS_OR1_PRELIM;
268         memctl->memc_br1 = CONFIG_SYS_BR1_PRELIM;
269         udelay (200);
270
271         /*
272          * Map controller SDRAM bank 1
273          */
274         memctl->memc_or2 = CONFIG_SYS_OR2;
275         memctl->memc_br2 = CONFIG_SYS_BR2;
276
277         /*
278          * Perform SDRAM initializsation sequence
279          */
280         memctl->memc_mcr = 0x80002105;  /* SDRAM bank 0 */
281         udelay (1);
282         memctl->memc_mcr = 0x80002730;  /* SDRAM bank 0 - execute twice */
283         udelay (1);
284         memctl->memc_mamr |= MAMR_PTAE; /* enable refresh */
285
286         udelay (10000);
287
288         /* leave place for framebuffers */
289         return (SDRAM_MAX_SIZE - SDRAM_RES_SIZE);
290 }
291
292 /* ------------------------------------------------------------------------- */
293
294 static void video_circle (char *center, int radius, int color, int pitch)
295 {
296         int x, y, d, dE, dSE;
297
298         x = 0;
299         y = radius;
300         d = 1 - radius;
301         dE = 3;
302         dSE = -2 * radius + 5;
303
304         *(center + x + y * pitch) = color;
305         *(center + y + x * pitch) = color;
306         *(center + y - x * pitch) = color;
307         *(center + x - y * pitch) = color;
308         *(center - x - y * pitch) = color;
309         *(center - y - x * pitch) = color;
310         *(center - y + x * pitch) = color;
311         *(center - x + y * pitch) = color;
312         while (y > x) {
313                 if (d < 0) {
314                         d += dE;
315                         dE += 2;
316                         dSE += 2;
317                         x++;
318                 } else {
319                         d += dSE;
320                         dE += 2;
321                         dSE += 4;
322                         x++;
323                         y--;
324                 }
325                 *(center + x + y * pitch) = color;
326                 *(center + y + x * pitch) = color;
327                 *(center + y - x * pitch) = color;
328                 *(center + x - y * pitch) = color;
329                 *(center - x - y * pitch) = color;
330                 *(center - y - x * pitch) = color;
331                 *(center - y + x * pitch) = color;
332                 *(center - x + y * pitch) = color;
333         }
334 }
335
336 /* ------------------------------------------------------------------------- */
337
338 static void video_test_image (void)
339 {
340         char *di;
341         int i, n;
342
343         /* draw raster */
344         for (i = 0; i < LCD_VIDEO_ROWS; i += 32) {
345                 memset ((char *) (LCD_VIDEO_ADDR + i * LCD_VIDEO_COLS),
346                         LCD_VIDEO_FG, LCD_VIDEO_COLS);
347                 for (n = i + 1; n < i + 32; n++)
348                         memset ((char *) (LCD_VIDEO_ADDR +
349                                           n * LCD_VIDEO_COLS), LCD_VIDEO_BG,
350                                 LCD_VIDEO_COLS);
351         }
352
353         for (i = 0; i < LCD_VIDEO_COLS; i += 32) {
354                 for (n = 0; n < LCD_VIDEO_ROWS; n++)
355                         *(char *) (LCD_VIDEO_ADDR + n * LCD_VIDEO_COLS + i) =
356                                 LCD_VIDEO_FG;
357         }
358
359         /* draw gray bar */
360         di = (char *) (LCD_VIDEO_ADDR + (LCD_VIDEO_COLS - 256) / 64 * 32 +
361                        97 * LCD_VIDEO_COLS);
362         for (n = 0; n < 63; n++) {
363                 for (i = 0; i < 256; i++) {
364                         *di++ = (char) i;
365                         *(di + LCD_VIDEO_COLS * 64) = (i & 1) * 255;
366                 }
367                 di += LCD_VIDEO_COLS - 256;
368         }
369
370         video_circle ((char *) LCD_VIDEO_ADDR + LCD_VIDEO_COLS / 2 +
371                       LCD_VIDEO_ROWS / 2 * LCD_VIDEO_COLS, LCD_VIDEO_ROWS / 2,
372                       LCD_VIDEO_FG, LCD_VIDEO_COLS);
373 }
374
375 /* ------------------------------------------------------------------------- */
376
377 static void video_default_lut (unsigned int clut_type)
378 {
379         unsigned int i;
380         unsigned char RGB[] = {
381                 0x00, 0x00, 0x00,       /* black */
382                 0x80, 0x80, 0x80,       /* gray */
383                 0xff, 0x00, 0x00,       /* red */
384                 0x00, 0xff, 0x00,       /* green */
385                 0x00, 0x00, 0xff,       /* blue */
386                 0x00, 0xff, 0xff,       /* cyan */
387                 0xff, 0x00, 0xff,       /* magenta */
388                 0xff, 0xff, 0x00,       /* yellow */
389                 0x80, 0x00, 0x00,       /* dark red */
390                 0x00, 0x80, 0x00,       /* dark green */
391                 0x00, 0x00, 0x80,       /* dark blue */
392                 0x00, 0x80, 0x80,       /* dark cyan */
393                 0x80, 0x00, 0x80,       /* dark magenta */
394                 0x80, 0x80, 0x00,       /* dark yellow */
395                 0xc0, 0xc0, 0xc0,       /* light gray */
396                 0xff, 0xff, 0xff,       /* white */
397         };
398
399         switch (clut_type) {
400         case 1:
401                 for (i = 0; i < 240; i++)
402                         video_set_lut (i, i, i, i);
403                 for (i = 0; i < 16; i++)
404                         video_set_lut (i + 240, RGB[i * 3], RGB[i * 3 + 1],
405                                        RGB[i * 3 + 2]);
406                 break;
407         default:
408                 for (i = 0; i < 256; i++)
409                         video_set_lut (i, i, i, i);
410         }
411 }
412
413 /* ------------------------------------------------------------------------- */
414
415 void *video_hw_init (void)
416 {
417         unsigned int clut = 0;
418         unsigned char *penv;
419         immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
420
421         /* enable video only on CLUT value */
422         if ((penv = (uchar *)getenv ("clut")) != NULL)
423                 clut = (u_int) simple_strtoul ((char *)penv, NULL, 10);
424         else
425                 return NULL;
426
427         /* disable graphic before write LCD regs. */
428         immr->im_lcd.lcd_lccr = 0x96000866;
429
430         /* config LCD regs. */
431         immr->im_lcd.lcd_lcfaa = LCD_VIDEO_ADDR;
432         immr->im_lcd.lcd_lchcr = 0x010a0093;
433         immr->im_lcd.lcd_lcvcr = 0x900f0024;
434
435         printf ("Video: 640x480 8Bit Index Lut %s\n",
436                 (clut == 1 ? "240/16 (gray/vga)" : "256(gray)"));
437
438         video_default_lut (clut);
439
440         /* clear framebuffer */
441         memset ((char *) (LCD_VIDEO_ADDR), LCD_VIDEO_BG,
442                 LCD_VIDEO_ROWS * LCD_VIDEO_COLS);
443
444         /* enable graphic */
445         immr->im_lcd.lcd_lccr = 0x96000867;
446
447         /* fill in Graphic Device */
448         gdev.frameAdrs = LCD_VIDEO_ADDR;
449         gdev.winSizeX = LCD_VIDEO_COLS;
450         gdev.winSizeY = LCD_VIDEO_ROWS;
451         gdev.gdfBytesPP = 1;
452         gdev.gdfIndex = GDF__8BIT_INDEX;
453
454         if (clut > 1)
455                 /* return Graphic Device for console */
456                 return (void *) &gdev;
457         else
458                 /* just graphic enabled - draw something beautiful */
459                 video_test_image ();
460
461         return NULL;            /* this disabels cfb - console */
462 }
463
464 /* ------------------------------------------------------------------------- */
465
466 void video_set_lut (unsigned int index,
467                     unsigned char r, unsigned char g, unsigned char b)
468 {
469         unsigned int lum;
470         unsigned short *pLut = (unsigned short *) (CONFIG_SYS_IMMR + 0x0e00);
471
472         /* 16 bit lut values, 12 bit used, xxxx BBGG RRii iiii */
473         /* y = 0.299*R + 0.587*G + 0.114*B */
474         lum = (2990 * r + 5870 * g + 1140 * b) / 10000;
475         pLut[index] =
476                 ((b & 0xc0) << 4) | ((g & 0xc0) << 2) | (r & 0xc0) | (lum &
477                                                                       0x3f);
478 }
479
480 /* ------------------------------------------------------------------------- */