]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/kup/kup4k/kup4k.c
Merge branch 'master' of /home/wd/git/u-boot/master
[karo-tx-uboot.git] / board / kup / kup4k / kup4k.c
1 /*
2  * (C) Copyright 2000-2004
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  * Klaus Heydeck, Kieback & Peter GmbH & Co KG, heydeck@kieback-peter.de
5  *
6  * See file CREDITS for list of people who contributed to this
7  * project.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation; either version 2 of
12  * the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22  * MA 02111-1307 USA
23  */
24
25 #include <common.h>
26 #include <mpc8xx.h>
27 #include "../common/kup.h"
28 #ifdef CONFIG_KUP4K_LOGO
29    #include "s1d13706.h"
30 #endif
31
32 DECLARE_GLOBAL_DATA_PTR;
33
34 #undef DEBUG
35 #ifdef  DEBUG
36 # define debugk(fmt,args...)    printf(fmt ,##args)
37 #else
38 # define debugk(fmt,args...)
39 #endif
40
41 typedef struct {
42         volatile unsigned char *VmemAddr;
43         volatile unsigned char *RegAddr;
44 } FB_INFO_S1D13xxx;
45
46
47 /* ------------------------------------------------------------------------- */
48
49 #ifdef CONFIG_KUP4K_LOGO
50 void lcd_logo(bd_t *bd);
51 #endif
52
53
54 /* ------------------------------------------------------------------------- */
55
56 #define _NOT_USED_      0xFFFFFFFF
57
58 const uint sdram_table[] = {
59         /*
60          * Single Read. (Offset 0 in UPMA RAM)
61          */
62         0x1F07FC04, 0xEEAEFC04, 0x11ADFC04, 0xEFBBBC00,
63         0x1FF77C47, /* last */
64
65         /*
66          * SDRAM Initialization (offset 5 in UPMA RAM)
67          *
68          * This is no UPM entry point. The following definition uses
69          * the remaining space to establish an initialization
70          * sequence, which is executed by a RUN command.
71          *
72          */
73                     0x1FF77C35, 0xEFEABC34, 0x1FB57C35, /* last */
74
75         /*
76          * Burst Read. (Offset 8 in UPMA RAM)
77          */
78         0x1F07FC04, 0xEEAEFC04, 0x10ADFC04, 0xF0AFFC00,
79         0xF0AFFC00, 0xF1AFFC00, 0xEFBBBC00, 0x1FF77C47, /* last */
80         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
81         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
82
83         /*
84          * Single Write. (Offset 18 in UPMA RAM)
85          */
86         0x1F27FC04, 0xEEAEBC00, 0x01B93C04, 0x1FF77C47, /* last */
87         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
88
89         /*
90          * Burst Write. (Offset 20 in UPMA RAM)
91          */
92         0x1F07FC04, 0xEEAEBC00, 0x10AD7C00, 0xF0AFFC00,
93         0xF0AFFC00, 0xE1BBBC04, 0x1FF77C47, /* last */
94                                             _NOT_USED_,
95         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
96         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
97
98         /*
99          * Refresh  (Offset 30 in UPMA RAM)
100          */
101         0x1FF5FC84, 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC04,
102         0xFFFFFC84, 0xFFFFFC07, /* last */
103                                 _NOT_USED_, _NOT_USED_,
104         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
105
106         /*
107          * Exception. (Offset 3c in UPMA RAM)
108          */
109         0x7FFFFC07, /* last */
110                     _NOT_USED_, _NOT_USED_, _NOT_USED_,
111 };
112
113 /* ------------------------------------------------------------------------- */
114
115
116 /*
117  * Check Board Identity:
118  */
119
120 int checkboard (void)
121 {
122         volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
123         uchar *latch,rev,mod;
124
125         /*
126          * Init ChipSelect #4 (CAN + HW-Latch)
127          */
128         immap->im_memctl.memc_or4 = 0xFFFF8926;
129         immap->im_memctl.memc_br4 = 0x90000401;
130         __asm__ ("eieio");
131         latch=(uchar *)0x90000200;
132         rev = (*latch & 0xF8) >> 3;
133         mod=(*latch & 0x03);
134         printf ("Board: KUP4K Rev %d.%d\n",rev,mod);
135         return (0);
136 }
137
138 /* ------------------------------------------------------------------------- */
139
140 phys_size_t initdram (int board_type)
141 {
142         volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
143         volatile memctl8xx_t *memctl = &immap->im_memctl;
144         long int size_b0 = 0;
145         long int size_b1 = 0;
146         long int size_b2 = 0;
147
148         upmconfig (UPMA, (uint *) sdram_table,
149                          sizeof (sdram_table) / sizeof (uint));
150
151         /*
152          * Preliminary prescaler for refresh (depends on number of
153          * banks): This value is selected for four cycles every 62.4 us
154          * with two SDRAM banks or four cycles every 31.2 us with one
155          * bank. It will be adjusted after memory sizing.
156          */
157         memctl->memc_mptpr = CONFIG_SYS_MPTPR;
158
159         memctl->memc_mar = 0x00000088;
160
161         /*
162          * Map controller banks 1 and 2 to the SDRAM banks 2 and 3 at
163          * preliminary addresses - these have to be modified after the
164          * SDRAM size has been determined.
165          */
166 /*      memctl->memc_or1 = CONFIG_SYS_OR1_PRELIM;       */
167 /*      memctl->memc_br1 = CONFIG_SYS_BR1_PRELIM;       */
168
169 /*      memctl->memc_or2 = CONFIG_SYS_OR2_PRELIM;       */
170 /*      memctl->memc_br2 = CONFIG_SYS_BR2_PRELIM;       */
171
172
173         memctl->memc_mamr = CONFIG_SYS_MAMR & (~(MAMR_PTAE));   /* no refresh yet */
174
175         udelay (200);
176
177         /* perform SDRAM initializsation sequence */
178
179         memctl->memc_mcr = 0x80002105;  /* SDRAM bank 0 */
180         udelay (1);
181         memctl->memc_mcr = 0x80002830;  /* SDRAM bank 0 - execute twice */
182         udelay (1);
183         memctl->memc_mcr = 0x80002106;  /* SDRAM bank 0 - RUN MRS Pattern from loc 6 */
184         udelay (1);
185
186         memctl->memc_mcr = 0x80004105;  /* SDRAM bank 1 */
187         udelay (1);
188         memctl->memc_mcr = 0x80004830;  /* SDRAM bank 1 - execute twice */
189         udelay (1);
190         memctl->memc_mcr = 0x80004106;  /* SDRAM bank 1 - RUN MRS Pattern from loc 6 */
191         udelay (1);
192
193         memctl->memc_mcr = 0x80006105;  /* SDRAM bank 2 */
194         udelay (1);
195         memctl->memc_mcr = 0x80006830;  /* SDRAM bank 2 - execute twice */
196         udelay (1);
197         memctl->memc_mcr = 0x80006106;  /* SDRAM bank 2 - RUN MRS Pattern from loc 6 */
198         udelay (1);
199
200         memctl->memc_mamr |= MAMR_PTAE; /* enable refresh */
201         udelay (1000);
202
203 #if 0                                                   /* 3 x 8MB */
204         size_b0 = 0x00800000;
205         size_b1 = 0x00800000;
206         size_b2 = 0x00800000;
207         memctl->memc_mptpr = CONFIG_SYS_MPTPR;
208         udelay (1000);
209         memctl->memc_or1 = 0xFF800A00;
210         memctl->memc_br1 = 0x00000081;
211         memctl->memc_or2 = 0xFF000A00;
212         memctl->memc_br2 = 0x00800081;
213         memctl->memc_or3 = 0xFE000A00;
214         memctl->memc_br3 = 0x01000081;
215 #else                                                   /* 3 x 16 MB */
216         size_b0 = 0x01000000;
217         size_b1 = 0x01000000;
218         size_b2 = 0x01000000;
219         memctl->memc_mptpr = CONFIG_SYS_MPTPR;
220         udelay (1000);
221         memctl->memc_or1 = 0xFF000A00;
222         memctl->memc_br1 = 0x00000081;
223         memctl->memc_or2 = 0xFE000A00;
224         memctl->memc_br2 = 0x01000081;
225         memctl->memc_or3 = 0xFC000A00;
226         memctl->memc_br3 = 0x02000081;
227 #endif
228
229         udelay (10000);
230
231         return (size_b0 + size_b1 + size_b2);
232 }
233
234 /* ------------------------------------------------------------------------- */
235
236 int misc_init_r (void)
237 {
238 #ifdef CONFIG_STATUS_LED
239         volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
240 #endif
241 #ifdef CONFIG_KUP4K_LOGO
242         bd_t *bd = gd->bd;
243
244         lcd_logo (bd);
245 #endif                                                  /* CONFIG_KUP4K_LOGO */
246 #ifdef CONFIG_IDE_LED
247         /* Configure PA8 as output port */
248         immap->im_ioport.iop_padir |= 0x80;
249         immap->im_ioport.iop_paodr |= 0x80;
250         immap->im_ioport.iop_papar &= ~0x80;
251         immap->im_ioport.iop_padat |= 0x80;     /* turn it off */
252 #endif
253         load_sernum_ethaddr();
254         setenv("hw","4k");
255         poweron_key();
256         return (0);
257 }
258
259 #ifdef CONFIG_KUP4K_LOGO
260
261
262 void lcd_logo (bd_t * bd)
263 {
264         FB_INFO_S1D13xxx fb_info;
265         S1D_INDEX s1dReg;
266         S1D_VALUE s1dValue;
267         volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
268         volatile memctl8xx_t *memctl;
269         ushort i;
270         uchar *fb;
271         int rs, gs, bs;
272         int r = 8, g = 8, b = 4;
273         int r1, g1, b1;
274         int n;
275         char tmp[64];           /* long enough for environment variables */
276         int tft = 0;
277
278         immr->im_cpm.cp_pbpar &= ~(PB_LCD_PWM);
279         immr->im_cpm.cp_pbodr &= ~(PB_LCD_PWM);
280         immr->im_cpm.cp_pbdat &= ~(PB_LCD_PWM); /* set to 0 = enabled */
281         immr->im_cpm.cp_pbdir |= (PB_LCD_PWM);
282
283 /*----------------------------------------------------------------------------- */
284 /* Initialize the chip and the frame buffer driver. */
285 /*----------------------------------------------------------------------------- */
286         memctl = &immr->im_memctl;
287
288
289         /*
290          * Init ChipSelect #5 (S1D13768)
291          */
292         memctl->memc_or5 = 0xFFC007F0;  /* 4 MB  17 WS or externel TA */
293         memctl->memc_br5 = 0x80080801;  /* Start at 0x80080000 */
294         __asm__ ("eieio");
295
296         fb_info.VmemAddr = (unsigned char *) (S1D_PHYSICAL_VMEM_ADDR);
297         fb_info.RegAddr = (unsigned char *) (S1D_PHYSICAL_REG_ADDR);
298
299         if ((((S1D_VALUE *) fb_info.RegAddr)[0] != 0x28)
300             || (((S1D_VALUE *) fb_info.RegAddr)[1] != 0x14)) {
301                 printf ("Warning:LCD Controller S1D13706 not found\n");
302                 setenv ("lcd", "none");
303                 return;
304         }
305
306
307         for (i = 0; i < sizeof(aS1DRegs_prelimn) / sizeof(aS1DRegs_prelimn[0]); i++) {
308                 s1dReg = aS1DRegs_prelimn[i].Index;
309                 s1dValue = aS1DRegs_prelimn[i].Value;
310                 debugk ("s13768 reg: %02x value: %02x\n",
311                         aS1DRegs_prelimn[i].Index, aS1DRegs_prelimn[i].Value);
312                 ((S1D_VALUE *) fb_info.RegAddr)[s1dReg / sizeof (S1D_VALUE)] =
313                         s1dValue;
314         }
315
316
317         n = getenv_f("lcd", tmp, sizeof (tmp));
318         if (n > 0) {
319                 if (!strcmp ("tft", tmp))
320                         tft = 1;
321                 else
322                         tft = 0;
323         }
324 #if 0
325         if (((S1D_VALUE *) fb_info.RegAddr)[0xAC] & 0x04)
326                 tft = 0;
327         else
328                 tft = 1;
329 #endif
330
331         debugk ("Port=0x%02x -> TFT=%d\n", tft,
332                 ((S1D_VALUE *) fb_info.RegAddr)[0xAC]);
333
334         /* init controller */
335         if (!tft) {
336                 for (i = 0; i < sizeof(aS1DRegs_stn) / sizeof(aS1DRegs_stn[0]); i++) {
337                         s1dReg = aS1DRegs_stn[i].Index;
338                         s1dValue = aS1DRegs_stn[i].Value;
339                         debugk ("s13768 reg: %02x value: %02x\n",
340                                 aS1DRegs_stn[i].Index,
341                                 aS1DRegs_stn[i].Value);
342                         ((S1D_VALUE *) fb_info.RegAddr)[s1dReg / sizeof(S1D_VALUE)] =
343                                 s1dValue;
344                 }
345                 n = getenv_f("contrast", tmp, sizeof (tmp));
346                 ((S1D_VALUE *) fb_info.RegAddr)[0xB3] =
347                         (n > 0) ? (uchar) simple_strtoul (tmp, NULL, 10) * 255 / 100 : 0xA0;
348                 switch (bd->bi_busfreq) {
349                 case 40000000:
350                         ((S1D_VALUE *) fb_info.RegAddr)[0x05] = 0x32;
351                         ((S1D_VALUE *) fb_info.RegAddr)[0x12] = 0x41;
352                         break;
353                 case 48000000:
354                         ((S1D_VALUE *) fb_info.RegAddr)[0x05] = 0x22;
355                         ((S1D_VALUE *) fb_info.RegAddr)[0x12] = 0x34;
356                         break;
357                 default:
358                         printf ("KUP4K S1D1: unknown busfrequency: %ld assuming 64 MHz\n", bd->bi_busfreq);
359                 case 64000000:
360                         ((S1D_VALUE *) fb_info.RegAddr)[0x05] = 0x32;
361                         ((S1D_VALUE *) fb_info.RegAddr)[0x12] = 0x66;
362                         break;
363                 }
364                 /*   setenv("lcd","stn"); */
365         } else {
366                 for (i = 0; i < sizeof(aS1DRegs_tft) / sizeof(aS1DRegs_tft[0]); i++) {
367                         s1dReg = aS1DRegs_tft[i].Index;
368                         s1dValue = aS1DRegs_tft[i].Value;
369                         debugk ("s13768 reg: %02x value: %02x\n",
370                                 aS1DRegs_tft[i].Index,
371                                 aS1DRegs_tft[i].Value);
372                         ((S1D_VALUE *) fb_info.RegAddr)[s1dReg / sizeof (S1D_VALUE)] =
373                                 s1dValue;
374                 }
375
376                 switch (bd->bi_busfreq) {
377                 default:
378                         printf ("KUP4K S1D1: unknown busfrequency: %ld assuming 64 MHz\n", bd->bi_busfreq);
379                 case 40000000:
380                         ((S1D_VALUE *) fb_info.RegAddr)[0x05] = 0x42;
381                         ((S1D_VALUE *) fb_info.RegAddr)[0x12] = 0x30;
382                         break;
383                 }
384                 /* setenv("lcd","tft"); */
385         }
386
387         /* create and set colormap */
388         rs = 256 / (r - 1);
389         gs = 256 / (g - 1);
390         bs = 256 / (b - 1);
391         for (i = 0; i < 256; i++) {
392                 r1 = (rs * ((i / (g * b)) % r)) * 255;
393                 g1 = (gs * ((i / b) % g)) * 255;
394                 b1 = (bs * ((i) % b)) * 255;
395                 debugk ("%d %04x %04x %04x\n", i, r1 >> 4, g1 >> 4, b1 >> 4);
396                 S1D_WRITE_PALETTE (fb_info.RegAddr, i, (r1 >> 4), (g1 >> 4),
397                                    (b1 >> 4));
398         }
399
400         /* copy bitmap */
401         fb = (uchar *) (fb_info.VmemAddr);
402         memcpy (fb, (uchar *) CONFIG_KUP4K_LOGO, 320 * 240);
403 }
404 #endif  /* CONFIG_KUP4K_LOGO */