]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/eltec/mhpc/mhpc.c
* The PS/2 mux on the BMS2003 board needs 450 ms after power on
[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 /* imports from common/main.c */
39 extern char console_buffer[CFG_CBSIZE];
40
41 extern void eeprom_init  (void);
42 extern int  eeprom_read  (unsigned dev_addr, unsigned offset,
43                           unsigned char *buffer, unsigned cnt);
44 extern int  eeprom_write (unsigned dev_addr, unsigned offset,
45                           unsigned char *buffer, unsigned cnt);
46
47 /* globals */
48 void *video_hw_init(void);
49 void video_set_lut (unsigned int index,     /* color number */
50                     unsigned char r,        /* red */
51                     unsigned char g,        /* green */
52                     unsigned char b         /* blue */
53                     );
54
55 GraphicDevice gdev;
56
57 /* locals */
58 static void video_circle (char *center, int radius, int color, int pitch);
59 static void video_test_image (void);
60 static void video_default_lut (unsigned int clut_type);
61
62 /* revision info foer MHPC EEPROM offset 480 */
63 typedef struct  {
64     char    board[12];      /* 000 - Board Revision information */
65     char    sensor;         /* 012 - Sensor Type information */
66     char    serial[8];      /* 013 - Board serial number */
67     char    etheraddr[6];   /* 021 - Ethernet node addresse */
68     char    revision[2];    /* 027 - Revision code */
69     char    option[3];      /* 029 - resevered for options */
70 } revinfo;
71
72 /* ------------------------------------------------------------------------- */
73
74 static const unsigned int sdram_table[] =
75 {
76     /* read single beat cycle */
77     0xef0efc04, 0x0e2dac04, 0x01ba5c04, 0x1ff5fc00,
78     0xfffffc05, 0xeffafc34, 0x0ff0bc34, 0x1ff57c35,
79
80     /* read burst cycle */
81     0xef0efc04, 0x0e3dac04, 0x10ff5c04, 0xf0fffc00,
82     0xf0fffc00, 0xf1fffc00, 0xfffffc00, 0xfffffc05,
83     0xfffffc04, 0xfffffc04, 0xfffffc04, 0xfffffc04,
84     0xfffffc04, 0xfffffc04, 0xfffffc04, 0xfffffc04,
85
86     /* write single beat cycle */
87     0xef0efc04, 0x0e29ac00, 0x01b25c04, 0x1ff5fc05,
88     0xfffffc04, 0xfffffc04, 0xfffffc04, 0xfffffc04,
89
90     /* write burst cycle */
91     0xef0ef804, 0x0e39a000, 0x10f75000, 0xf0fff440,
92     0xf0fffc40, 0xf1fffc04, 0xfffffc05, 0xfffffc04,
93     0xfffffc04, 0xfffffc04, 0xfffffc04, 0xfffffc04,
94     0xfffffc04, 0xfffffc04, 0xfffffc04, 0xfffffc04,
95
96     /* periodic timer expired */
97     0xeffebc84, 0x1ffd7c04, 0xfffffc04, 0xfffffc84,
98     0xeffebc04, 0x1ffd7c04, 0xfffffc04, 0xfffffc05,
99     0xfffffc04, 0xfffffc04, 0xfffffc04, 0xfffffc04,
100
101     /* exception */
102     0xfffffc04, 0xfffffc05, 0xfffffc04, 0xfffffc04
103 };
104
105 /* ------------------------------------------------------------------------- */
106
107 int board_early_init_f (void)
108 {
109     volatile immap_t  *im = (immap_t *)CFG_IMMR;
110     volatile cpm8xx_t *cp = &(im->im_cpm);
111     volatile iop8xx_t *ip = (iop8xx_t *)&(im->im_ioport);
112
113     /* reset the port A s.a. cpm-routines */
114     ip->iop_padat = 0x0000;
115     ip->iop_papar = 0x0000;
116     ip->iop_padir = 0x0800;
117     ip->iop_paodr = 0x0000;
118
119     /* reset the port B for digital and LCD output */
120     cp->cp_pbdat  = 0x0300;
121     cp->cp_pbpar  = 0x5001;
122     cp->cp_pbdir  = 0x5301;
123     cp->cp_pbodr  = 0x0000;
124
125     /* reset the port C configured for SMC1 serial port and aqc. control */
126     ip->iop_pcdat = 0x0800;
127     ip->iop_pcpar = 0x0000;
128     ip->iop_pcdir = 0x0e30;
129     ip->iop_pcso  = 0x0000;
130
131     /* Config port D for LCD output */
132     ip->iop_pdpar = 0x1fff;
133     ip->iop_pddir = 0x1fff;
134
135     return (0);
136 }
137
138 /* ------------------------------------------------------------------------- */
139
140 /*
141  * Check Board Identity
142  */
143 int checkboard (void)
144 {
145     puts ("Board: ELTEC miniHiperCam\n");
146     return(0);
147 }
148
149 /* ------------------------------------------------------------------------- */
150
151 int misc_init_r(void)
152 {
153     revinfo  mhpcRevInfo;
154     char     nid[32];
155     char     *mhpcSensorTypes[] = { "OMNIVISON OV7610/7620 color",
156                                     "OMNIVISON OV7110 b&w", NULL };
157     char     hex[23] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0,
158                          0, 0, 0, 0, 10, 11, 12, 13, 14, 15 };
159     int      i;
160
161     /* check revision data */
162     eeprom_read (CFG_I2C_EEPROM_ADDR, 480, (char*)&mhpcRevInfo, 32);
163
164     if (strncmp((char *)&mhpcRevInfo.board[2], "MHPC", 4) != 0)
165     {
166     printf ("Enter revision number (0-9): %c  ", mhpcRevInfo.revision[0]);
167     if (0 != readline (NULL))
168     {
169         mhpcRevInfo.revision[0] = (char)toupper(console_buffer[0]);
170     }
171
172     printf ("Enter revision character (A-Z): %c  ", mhpcRevInfo.revision[1]);
173     if (1 == readline (NULL))
174     {
175         mhpcRevInfo.revision[1] = (char)toupper(console_buffer[0]);
176     }
177
178     printf("Enter board name (V-XXXX-XXXX): %s  ", (char *)&mhpcRevInfo.board);
179     if (11 == readline (NULL))
180     {
181         for (i=0; i<11; i++)
182         {
183             mhpcRevInfo.board[i] =  (char)toupper(console_buffer[i]);
184             mhpcRevInfo.board[11] = '\0';
185         }
186     }
187
188     printf("Supported sensor types:\n");
189     i=0;
190     do
191     {
192         printf("\n    \'%d\' : %s\n", i, mhpcSensorTypes[i]);
193     } while ( mhpcSensorTypes[++i] != NULL );
194
195     do
196     {
197         printf("\nEnter sensor number (0-255): %d  ", (int)mhpcRevInfo.sensor );
198         if (0 != readline (NULL))
199         {
200         mhpcRevInfo.sensor = (unsigned char)simple_strtoul(console_buffer, NULL, 10);
201         }
202     } while ( mhpcRevInfo.sensor >= i );
203
204     printf("Enter serial number: %s ", (char *)&mhpcRevInfo.serial );
205     if (6 == readline (NULL))
206     {
207         for (i=0; i<6; i++)
208         {
209         mhpcRevInfo.serial[i] = console_buffer[i];
210         }
211         mhpcRevInfo.serial[6] = '\0';
212     }
213
214     printf("Enter ether node ID with leading zero (HEX): %02x%02x%02x%02x%02x%02x  ",
215               mhpcRevInfo.etheraddr[0], mhpcRevInfo.etheraddr[1],
216               mhpcRevInfo.etheraddr[2], mhpcRevInfo.etheraddr[3],
217               mhpcRevInfo.etheraddr[4], mhpcRevInfo.etheraddr[5]  );
218     if (12 == readline (NULL))
219     {
220         for (i=0; i<12; i+=2)
221         {
222         mhpcRevInfo.etheraddr[i>>1] = (char)(16*hex[toupper(console_buffer[i])-'0'] +
223                              hex[toupper(console_buffer[i+1])-'0']);
224         }
225     }
226
227     /* setup new revision data */
228     eeprom_write (CFG_I2C_EEPROM_ADDR, 480, (char*)&mhpcRevInfo, 32);
229     }
230
231     /* set environment */
232     sprintf( nid, "%02x:%02x:%02x:%02x:%02x:%02x",
233                   mhpcRevInfo.etheraddr[0], mhpcRevInfo.etheraddr[1],
234                   mhpcRevInfo.etheraddr[2], mhpcRevInfo.etheraddr[3],
235                   mhpcRevInfo.etheraddr[4], mhpcRevInfo.etheraddr[5]);
236     setenv("ethaddr", nid);
237
238     /* print actual board identification */
239     printf("Ident: %s %s Ser %s Rev %c%c\n",
240             mhpcRevInfo.board, (mhpcRevInfo.sensor==0?"color":"b&w"),
241             (char *)&mhpcRevInfo.serial,
242             mhpcRevInfo.revision[0], mhpcRevInfo.revision[1]);
243
244     return (0);
245 }
246
247 /* ------------------------------------------------------------------------- */
248
249 long int initdram (int board_type)
250 {
251     volatile immap_t     *immap  = (immap_t *)CFG_IMMR;
252     volatile memctl8xx_t *memctl = &immap->im_memctl;
253
254     upmconfig(UPMA, (uint *)sdram_table, sizeof(sdram_table)/sizeof(uint));
255
256     memctl->memc_mamr  = CFG_MAMR & (~(MAMR_PTAE)); /* no refresh yet */
257     memctl->memc_mbmr  = MBMR_GPL_B4DIS;        /* should this be mamr? - NTL */
258     memctl->memc_mptpr = MPTPR_PTP_DIV64;
259     memctl->memc_mar   = 0x00008800;
260
261     /*
262      * Map controller SDRAM bank 0
263      */
264     memctl->memc_or1 = CFG_OR1_PRELIM;
265     memctl->memc_br1 = CFG_BR1_PRELIM;
266     udelay(200);
267
268     /*
269      * Map controller SDRAM bank 1
270      */
271     memctl->memc_or2 = CFG_OR2;
272     memctl->memc_br2 = CFG_BR2;
273
274     /*
275      * Perform SDRAM initializsation sequence
276      */
277     memctl->memc_mcr  = 0x80002105;    /* SDRAM bank 0 */
278     udelay(1);
279     memctl->memc_mcr  = 0x80002730;    /* SDRAM bank 0 - execute twice */
280     udelay(1);
281     memctl->memc_mamr |= MAMR_PTAE;    /* enable refresh */
282
283     udelay(10000);
284
285     /* leave place for framebuffers */
286     return (SDRAM_MAX_SIZE-SDRAM_RES_SIZE);
287 }
288
289 /* ------------------------------------------------------------------------- */
290
291 static void video_circle (char *center, int radius, int color, int pitch)
292 {
293     int x,y,d,dE,dSE;
294
295     x   = 0;
296     y   = radius;
297     d   = 1-radius;
298     dE  = 3;
299     dSE = -2*radius+5;
300
301     *(center+x+y*pitch) = color;
302     *(center+y+x*pitch) = color;
303     *(center+y-x*pitch) = color;
304     *(center+x-y*pitch) = color;
305     *(center-x-y*pitch) = color;
306     *(center-y-x*pitch) = color;
307     *(center-y+x*pitch) = color;
308     *(center-x+y*pitch) = color;
309     while(y>x)
310     {
311         if (d<0)
312         {
313             d   += dE;
314             dE  += 2;
315             dSE += 2;
316             x++;
317         }
318         else
319         {
320             d   += dSE;
321             dE  += 2;
322             dSE += 4;
323             x++;
324             y--;
325         }
326         *(center+x+y*pitch) = color;
327         *(center+y+x*pitch) = color;
328         *(center+y-x*pitch) = color;
329         *(center+x-y*pitch) = color;
330         *(center-x-y*pitch) = color;
331         *(center-y-x*pitch) = color;
332         *(center-y+x*pitch) = color;
333         *(center-x+y*pitch) = color;
334     }
335 }
336
337 /* ------------------------------------------------------------------------- */
338
339 static void video_test_image(void)
340 {
341     char *di;
342     int i, n;
343
344     /* draw raster */
345     for (i=0; i<LCD_VIDEO_ROWS; i+=32)
346     {
347         memset((char*)(LCD_VIDEO_ADDR+i*LCD_VIDEO_COLS), LCD_VIDEO_FG, LCD_VIDEO_COLS);
348         for (n=i+1;n<i+32;n++)
349             memset((char*)(LCD_VIDEO_ADDR+n*LCD_VIDEO_COLS), LCD_VIDEO_BG, LCD_VIDEO_COLS);
350     }
351
352     for (i=0; i<LCD_VIDEO_COLS; i+=32)
353     {
354         for (n=0; n<LCD_VIDEO_ROWS; n++)
355             *(char*)(LCD_VIDEO_ADDR+n*LCD_VIDEO_COLS+i) = LCD_VIDEO_FG;
356     }
357
358     /* draw gray bar */
359     di = (char *)(LCD_VIDEO_ADDR + (LCD_VIDEO_COLS-256)/64*32 + 97*LCD_VIDEO_COLS);
360     for (n=0; n<63; n++)
361     {
362         for (i=0; i<256; i++)
363         {
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+LCD_VIDEO_ROWS/2*LCD_VIDEO_COLS,
371                   LCD_VIDEO_ROWS/2,LCD_VIDEO_FG, LCD_VIDEO_COLS);
372 }
373
374 /* ------------------------------------------------------------------------- */
375
376 static void video_default_lut (unsigned int clut_type)
377 {
378     unsigned int i;
379     unsigned char RGB[] =
380         {
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     {
401     case 1:
402         for (i=0; i<240; i++)
403             video_set_lut (i, i, i, i);
404         for (i=0; i<16; i++)
405             video_set_lut (i+240, RGB[i*3], RGB[i*3+1], 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 *) CFG_IMMR;
420
421     /* enable video only on CLUT value */
422     if ((penv = getenv ("clut")) != NULL)
423         clut = (u_int)simple_strtoul (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, LCD_VIDEO_ROWS*LCD_VIDEO_COLS );
442
443     /* enable graphic */
444     immr->im_lcd.lcd_lccr = 0x96000867;
445
446     /* fill in Graphic Device */
447     gdev.frameAdrs = LCD_VIDEO_ADDR;
448     gdev.winSizeX = LCD_VIDEO_COLS;
449     gdev.winSizeY = LCD_VIDEO_ROWS;
450     gdev.gdfBytesPP = 1;
451     gdev.gdfIndex = GDF__8BIT_INDEX;
452
453     if (clut > 1)
454         /* return Graphic Device for console */
455         return (void *)&gdev;
456     else
457         /* just graphic enabled - draw something beautiful */
458         video_test_image();
459
460     return NULL;            /* this disabels cfb - console */
461 }
462
463 /* ------------------------------------------------------------------------- */
464
465 void video_set_lut (unsigned int index,
466                     unsigned char r, unsigned char g, unsigned char b)
467 {
468     unsigned int lum;
469     unsigned short *pLut = (unsigned short *)(CFG_IMMR + 0x0e00);
470
471     /* 16 bit lut values, 12 bit used, xxxx BBGG RRii iiii */
472     /* y = 0.299*R + 0.587*G + 0.114*B */
473     lum = (2990*r + 5870*g + 1140*b)/10000;
474     pLut[index] = ((b & 0xc0)<<4) | ((g & 0xc0)<<2) | (r & 0xc0) | (lum & 0x3f);
475 }
476
477 /* ------------------------------------------------------------------------- */