]>
Commit | Line | Data |
---|---|---|
56f94be3 | 1 | /* |
0608e04d | 2 | * (C) Copyright 2000-2004 |
56f94be3 WD |
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> | |
0608e04d | 27 | #include "../common/kup.h" |
56f94be3 WD |
28 | #ifdef CONFIG_KUP4K_LOGO |
29 | #include "s1d13706.h" | |
30 | #endif | |
31 | ||
d87080b7 WD |
32 | DECLARE_GLOBAL_DATA_PTR; |
33 | ||
0608e04d WD |
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; | |
56f94be3 | 45 | |
56f94be3 WD |
46 | |
47 | /* ------------------------------------------------------------------------- */ | |
48 | ||
56f94be3 | 49 | #ifdef CONFIG_KUP4K_LOGO |
0608e04d | 50 | void lcd_logo(bd_t *bd); |
56f94be3 WD |
51 | #endif |
52 | ||
0608e04d | 53 | |
56f94be3 WD |
54 | /* ------------------------------------------------------------------------- */ |
55 | ||
56 | #define _NOT_USED_ 0xFFFFFFFF | |
57 | ||
0608e04d | 58 | const uint sdram_table[] = { |
56f94be3 WD |
59 | /* |
60 | * Single Read. (Offset 0 in UPMA RAM) | |
61 | */ | |
682011ff | 62 | 0x1F07FC04, 0xEEAEFC04, 0x11ADFC04, 0xEFBBBC00, |
56f94be3 WD |
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 | */ | |
682011ff | 73 | 0x1FF77C35, 0xEFEABC34, 0x1FB57C35, /* last */ |
56f94be3 WD |
74 | |
75 | /* | |
76 | * Burst Read. (Offset 8 in UPMA RAM) | |
77 | */ | |
682011ff WD |
78 | 0x1F07FC04, 0xEEAEFC04, 0x10ADFC04, 0xF0AFFC00, |
79 | 0xF0AFFC00, 0xF1AFFC00, 0xEFBBBC00, 0x1FF77C47, /* last */ | |
56f94be3 WD |
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 | */ | |
682011ff | 86 | 0x1F27FC04, 0xEEAEBC00, 0x01B93C04, 0x1FF77C47, /* last */ |
56f94be3 WD |
87 | _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, |
88 | ||
89 | /* | |
90 | * Burst Write. (Offset 20 in UPMA RAM) | |
91 | */ | |
682011ff WD |
92 | 0x1F07FC04, 0xEEAEBC00, 0x10AD7C00, 0xF0AFFC00, |
93 | 0xF0AFFC00, 0xE1BBBC04, 0x1FF77C47, /* last */ | |
94 | _NOT_USED_, | |
56f94be3 WD |
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 | */ | |
682011ff WD |
101 | 0x1FF5FC84, 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC04, |
102 | 0xFFFFFC84, 0xFFFFFC07, /* last */ | |
103 | _NOT_USED_, _NOT_USED_, | |
56f94be3 WD |
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 | { | |
6d0f6bcf | 122 | volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; |
0608e04d | 123 | uchar *latch,rev,mod; |
56f94be3 | 124 | |
0608e04d WD |
125 | /* |
126 | * Init ChipSelect #4 (CAN + HW-Latch) | |
127 | */ | |
128 | immap->im_memctl.memc_or4 = 0xFFFF8926; | |
129 | immap->im_memctl.memc_br4 = 0x90000401; | |
02b11f8e | 130 | __asm__ ("eieio"); |
0608e04d WD |
131 | latch=(uchar *)0x90000200; |
132 | rev = (*latch & 0xF8) >> 3; | |
133 | mod=(*latch & 0x03); | |
02b11f8e | 134 | printf ("Board: KUP4K Rev %d.%d\n",rev,mod); |
56f94be3 WD |
135 | return (0); |
136 | } | |
137 | ||
138 | /* ------------------------------------------------------------------------- */ | |
139 | ||
9973e3c6 | 140 | phys_size_t initdram (int board_type) |
56f94be3 | 141 | { |
6d0f6bcf | 142 | volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; |
682011ff WD |
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; | |
56f94be3 | 147 | |
682011ff WD |
148 | upmconfig (UPMA, (uint *) sdram_table, |
149 | sizeof (sdram_table) / sizeof (uint)); | |
56f94be3 | 150 | |
682011ff WD |
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 | */ | |
6d0f6bcf | 157 | memctl->memc_mptpr = CONFIG_SYS_MPTPR; |
56f94be3 | 158 | |
682011ff | 159 | memctl->memc_mar = 0x00000088; |
56f94be3 | 160 | |
682011ff WD |
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 | */ | |
6d0f6bcf JCPV |
166 | /* memctl->memc_or1 = CONFIG_SYS_OR1_PRELIM; */ |
167 | /* memctl->memc_br1 = CONFIG_SYS_BR1_PRELIM; */ | |
682011ff | 168 | |
6d0f6bcf JCPV |
169 | /* memctl->memc_or2 = CONFIG_SYS_OR2_PRELIM; */ |
170 | /* memctl->memc_br2 = CONFIG_SYS_BR2_PRELIM; */ | |
56f94be3 | 171 | |
56f94be3 | 172 | |
6d0f6bcf | 173 | memctl->memc_mamr = CONFIG_SYS_MAMR & (~(MAMR_PTAE)); /* no refresh yet */ |
56f94be3 | 174 | |
682011ff | 175 | udelay (200); |
56f94be3 | 176 | |
682011ff | 177 | /* perform SDRAM initializsation sequence */ |
56f94be3 | 178 | |
682011ff WD |
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); | |
56f94be3 | 185 | |
682011ff WD |
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); | |
56f94be3 | 192 | |
682011ff WD |
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); | |
56f94be3 | 199 | |
682011ff WD |
200 | memctl->memc_mamr |= MAMR_PTAE; /* enable refresh */ |
201 | udelay (1000); | |
56f94be3 | 202 | |
682011ff WD |
203 | #if 0 /* 3 x 8MB */ |
204 | size_b0 = 0x00800000; | |
205 | size_b1 = 0x00800000; | |
206 | size_b2 = 0x00800000; | |
6d0f6bcf | 207 | memctl->memc_mptpr = CONFIG_SYS_MPTPR; |
682011ff | 208 | udelay (1000); |
56f94be3 WD |
209 | memctl->memc_or1 = 0xFF800A00; |
210 | memctl->memc_br1 = 0x00000081; | |
682011ff WD |
211 | memctl->memc_or2 = 0xFF000A00; |
212 | memctl->memc_br2 = 0x00800081; | |
56f94be3 WD |
213 | memctl->memc_or3 = 0xFE000A00; |
214 | memctl->memc_br3 = 0x01000081; | |
682011ff WD |
215 | #else /* 3 x 16 MB */ |
216 | size_b0 = 0x01000000; | |
217 | size_b1 = 0x01000000; | |
218 | size_b2 = 0x01000000; | |
6d0f6bcf | 219 | memctl->memc_mptpr = CONFIG_SYS_MPTPR; |
682011ff WD |
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 | |
56f94be3 | 228 | |
682011ff | 229 | udelay (10000); |
56f94be3 | 230 | |
682011ff | 231 | return (size_b0 + size_b1 + size_b2); |
56f94be3 WD |
232 | } |
233 | ||
234 | /* ------------------------------------------------------------------------- */ | |
235 | ||
56f94be3 WD |
236 | int misc_init_r (void) |
237 | { | |
1f53a416 | 238 | #ifdef CONFIG_STATUS_LED |
6d0f6bcf | 239 | volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; |
1f53a416 | 240 | #endif |
56f94be3 WD |
241 | #ifdef CONFIG_KUP4K_LOGO |
242 | bd_t *bd = gd->bd; | |
243 | ||
682011ff WD |
244 | lcd_logo (bd); |
245 | #endif /* CONFIG_KUP4K_LOGO */ | |
1f53a416 WD |
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; | |
682011ff | 251 | immap->im_ioport.iop_padat |= 0x80; /* turn it off */ |
1f53a416 | 252 | #endif |
0608e04d WD |
253 | setenv("hw","4k"); |
254 | poweron_key(); | |
682011ff | 255 | return (0); |
56f94be3 WD |
256 | } |
257 | ||
258 | #ifdef CONFIG_KUP4K_LOGO | |
56f94be3 | 259 | |
682011ff | 260 | |
682011ff WD |
261 | void lcd_logo (bd_t * bd) |
262 | { | |
682011ff WD |
263 | FB_INFO_S1D13xxx fb_info; |
264 | S1D_INDEX s1dReg; | |
265 | S1D_VALUE s1dValue; | |
6d0f6bcf | 266 | volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; |
682011ff | 267 | volatile memctl8xx_t *memctl; |
56f94be3 WD |
268 | ushort i; |
269 | uchar *fb; | |
682011ff WD |
270 | int rs, gs, bs; |
271 | int r = 8, g = 8, b = 4; | |
272 | int r1, g1, b1; | |
0608e04d | 273 | int n; |
77ddac94 | 274 | char tmp[64]; /* long enough for environment variables */ |
0608e04d | 275 | int tft = 0; |
682011ff | 276 | |
0608e04d WD |
277 | immr->im_cpm.cp_pbpar &= ~(PB_LCD_PWM); |
278 | immr->im_cpm.cp_pbodr &= ~(PB_LCD_PWM); | |
279 | immr->im_cpm.cp_pbdat &= ~(PB_LCD_PWM); /* set to 0 = enabled */ | |
280 | immr->im_cpm.cp_pbdir |= (PB_LCD_PWM); | |
56f94be3 WD |
281 | |
282 | /*----------------------------------------------------------------------------- */ | |
56f94be3 | 283 | /* Initialize the chip and the frame buffer driver. */ |
56f94be3 | 284 | /*----------------------------------------------------------------------------- */ |
0608e04d | 285 | memctl = &immr->im_memctl; |
56f94be3 | 286 | |
56f94be3 | 287 | |
0608e04d WD |
288 | /* |
289 | * Init ChipSelect #5 (S1D13768) | |
290 | */ | |
291 | memctl->memc_or5 = 0xFFC007F0; /* 4 MB 17 WS or externel TA */ | |
292 | memctl->memc_br5 = 0x80080801; /* Start at 0x80080000 */ | |
02b11f8e | 293 | __asm__ ("eieio"); |
56f94be3 | 294 | |
682011ff WD |
295 | fb_info.VmemAddr = (unsigned char *) (S1D_PHYSICAL_VMEM_ADDR); |
296 | fb_info.RegAddr = (unsigned char *) (S1D_PHYSICAL_REG_ADDR); | |
56f94be3 | 297 | |
682011ff | 298 | if ((((S1D_VALUE *) fb_info.RegAddr)[0] != 0x28) |
0608e04d | 299 | || (((S1D_VALUE *) fb_info.RegAddr)[1] != 0x14)) { |
682011ff | 300 | printf ("Warning:LCD Controller S1D13706 not found\n"); |
0608e04d | 301 | setenv ("lcd", "none"); |
682011ff WD |
302 | return; |
303 | } | |
56f94be3 | 304 | |
0608e04d WD |
305 | |
306 | for (i = 0; i < sizeof(aS1DRegs_prelimn) / sizeof(aS1DRegs_prelimn[0]); i++) { | |
307 | s1dReg = aS1DRegs_prelimn[i].Index; | |
308 | s1dValue = aS1DRegs_prelimn[i].Value; | |
309 | debugk ("s13768 reg: %02x value: %02x\n", | |
310 | aS1DRegs_prelimn[i].Index, aS1DRegs_prelimn[i].Value); | |
682011ff | 311 | ((S1D_VALUE *) fb_info.RegAddr)[s1dReg / sizeof (S1D_VALUE)] = |
0608e04d | 312 | s1dValue; |
682011ff | 313 | } |
56f94be3 | 314 | |
0608e04d WD |
315 | |
316 | n = getenv_r ("lcd", tmp, sizeof (tmp)); | |
317 | if (n > 0) { | |
318 | if (!strcmp ("tft", tmp)) | |
319 | tft = 1; | |
320 | else | |
321 | tft = 0; | |
56f94be3 | 322 | } |
56f94be3 | 323 | #if 0 |
0608e04d WD |
324 | if (((S1D_VALUE *) fb_info.RegAddr)[0xAC] & 0x04) |
325 | tft = 0; | |
326 | else | |
327 | tft = 1; | |
56f94be3 WD |
328 | #endif |
329 | ||
0608e04d WD |
330 | debugk ("Port=0x%02x -> TFT=%d\n", tft, |
331 | ((S1D_VALUE *) fb_info.RegAddr)[0xAC]); | |
332 | ||
333 | /* init controller */ | |
334 | if (!tft) { | |
335 | for (i = 0; i < sizeof(aS1DRegs_stn) / sizeof(aS1DRegs_stn[0]); i++) { | |
336 | s1dReg = aS1DRegs_stn[i].Index; | |
337 | s1dValue = aS1DRegs_stn[i].Value; | |
338 | debugk ("s13768 reg: %02x value: %02x\n", | |
339 | aS1DRegs_stn[i].Index, | |
340 | aS1DRegs_stn[i].Value); | |
341 | ((S1D_VALUE *) fb_info.RegAddr)[s1dReg / sizeof(S1D_VALUE)] = | |
342 | s1dValue; | |
343 | } | |
344 | n = getenv_r ("contrast", tmp, sizeof (tmp)); | |
345 | ((S1D_VALUE *) fb_info.RegAddr)[0xB3] = | |
346 | (n > 0) ? (uchar) simple_strtoul (tmp, NULL, 10) * 255 / 100 : 0xA0; | |
347 | switch (bd->bi_busfreq) { | |
348 | case 40000000: | |
349 | ((S1D_VALUE *) fb_info.RegAddr)[0x05] = 0x32; | |
350 | ((S1D_VALUE *) fb_info.RegAddr)[0x12] = 0x41; | |
351 | break; | |
352 | case 48000000: | |
353 | ((S1D_VALUE *) fb_info.RegAddr)[0x05] = 0x22; | |
354 | ((S1D_VALUE *) fb_info.RegAddr)[0x12] = 0x34; | |
355 | break; | |
356 | default: | |
357 | printf ("KUP4K S1D1: unknown busfrequency: %ld assuming 64 MHz\n", bd->bi_busfreq); | |
358 | case 64000000: | |
359 | ((S1D_VALUE *) fb_info.RegAddr)[0x05] = 0x32; | |
360 | ((S1D_VALUE *) fb_info.RegAddr)[0x12] = 0x66; | |
361 | break; | |
362 | } | |
363 | /* setenv("lcd","stn"); */ | |
364 | } else { | |
365 | for (i = 0; i < sizeof(aS1DRegs_tft) / sizeof(aS1DRegs_tft[0]); i++) { | |
366 | s1dReg = aS1DRegs_tft[i].Index; | |
367 | s1dValue = aS1DRegs_tft[i].Value; | |
368 | debugk ("s13768 reg: %02x value: %02x\n", | |
369 | aS1DRegs_tft[i].Index, | |
370 | aS1DRegs_tft[i].Value); | |
371 | ((S1D_VALUE *) fb_info.RegAddr)[s1dReg / sizeof (S1D_VALUE)] = | |
372 | s1dValue; | |
373 | } | |
374 | ||
375 | switch (bd->bi_busfreq) { | |
376 | default: | |
377 | printf ("KUP4K S1D1: unknown busfrequency: %ld assuming 64 MHz\n", bd->bi_busfreq); | |
378 | case 40000000: | |
379 | ((S1D_VALUE *) fb_info.RegAddr)[0x05] = 0x42; | |
380 | ((S1D_VALUE *) fb_info.RegAddr)[0x12] = 0x30; | |
381 | break; | |
382 | } | |
383 | /* setenv("lcd","tft"); */ | |
384 | } | |
682011ff WD |
385 | |
386 | /* create and set colormap */ | |
387 | rs = 256 / (r - 1); | |
388 | gs = 256 / (g - 1); | |
389 | bs = 256 / (b - 1); | |
390 | for (i = 0; i < 256; i++) { | |
391 | r1 = (rs * ((i / (g * b)) % r)) * 255; | |
392 | g1 = (gs * ((i / b) % g)) * 255; | |
393 | b1 = (bs * ((i) % b)) * 255; | |
0608e04d | 394 | debugk ("%d %04x %04x %04x\n", i, r1 >> 4, g1 >> 4, b1 >> 4); |
682011ff | 395 | S1D_WRITE_PALETTE (fb_info.RegAddr, i, (r1 >> 4), (g1 >> 4), |
0608e04d | 396 | (b1 >> 4)); |
682011ff | 397 | } |
56f94be3 | 398 | |
682011ff | 399 | /* copy bitmap */ |
77ddac94 | 400 | fb = (uchar *) (fb_info.VmemAddr); |
682011ff | 401 | memcpy (fb, (uchar *) CONFIG_KUP4K_LOGO, 320 * 240); |
56f94be3 | 402 | } |
0608e04d | 403 | #endif /* CONFIG_KUP4K_LOGO */ |