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