]> git.karo-electronics.de Git - karo-tx-uboot.git/blob - board/hermes/hermes.c
Merge with /home/m8/git/u-boot
[karo-tx-uboot.git] / board / hermes / hermes.c
1 /*
2  * (C) Copyright 2000
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23
24 #include <common.h>
25 #include <commproc.h>
26 #include <mpc8xx.h>
27
28 #ifdef CONFIG_SHOW_BOOT_PROGRESS
29 # include <status_led.h>
30 # define SHOW_BOOT_PROGRESS(arg)        show_boot_progress(arg)
31 #else
32 # define SHOW_BOOT_PROGRESS(arg)
33 #endif
34
35 /* ------------------------------------------------------------------------- */
36
37 static long int dram_size (long int, long int *, long int);
38 static ulong board_init (void);
39 static void send_smi_frame (volatile scc_t * sp, volatile cbd_t * bd,
40                                                         uchar * msg);
41
42 /* ------------------------------------------------------------------------- */
43
44 #define _NOT_USED_      0xFFFFFFFF
45
46 const uint sdram_table[] = {
47         /*
48          * Single Read. (Offset 0 in UPMA RAM)
49          */
50         0x1f07fc04, 0xeeaefc04, 0x11adfc04, 0xefbbbc00,
51         0x1ff77c47,                                     /* last */
52         /*
53          * SDRAM Initialization (offset 5 in UPMA RAM)
54          *
55          * This is no UPM entry point. The following definition uses
56          * the remaining space to establish an initialization
57          * sequence, which is executed by a RUN command.
58          *
59          */
60         0x1fe77c35, 0xffaffc34, 0x1fa57c35,     /* last */
61         /*
62          * Burst Read. (Offset 8 in UPMA RAM)
63          */
64         0x1f07fc04, 0xeeaefc04, 0x10adfc04, 0xf0affc00,
65         0xf0affc00, 0xf1affc00, 0xefbbbc00, 0x1ff77c47, /* last */
66         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
67         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
68         /*
69          * Single Write. (Offset 18 in UPMA RAM)
70          */
71         0x1f27fc04, 0xeeaebc00, 0x01b93c04, 0x1ff77c47, /* last */
72         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
73         /*
74          * Burst Write. (Offset 20 in UPMA RAM)
75          */
76         0x1f07fc04, 0xeeaebc00, 0x10ad4c00, 0xf0afcc00,
77         0xf0afcc00, 0xe1bb8c06, 0x1ff77c47,     /* last */
78         _NOT_USED_,
79         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
80         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
81         /*
82          * Refresh  (Offset 30 in UPMA RAM)
83          */
84         0x1ff5fc84, 0xfffffc04, 0xfffffc04, 0xfffffc04,
85         0xfffffc84, 0xfffffc07,         /* last */
86         _NOT_USED_, _NOT_USED_,
87         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
88         /*
89          * Exception. (Offset 3c in UPMA RAM)
90          */
91         0x7ffffc07,                                     /* last */
92         _NOT_USED_, _NOT_USED_, _NOT_USED_,
93 };
94
95 /* ------------------------------------------------------------------------- */
96
97
98 /*
99  * Check Board Identity:
100  *
101  * Test ID string (HERMES...)
102  *
103  * Return code for board revision and network speed
104  */
105
106 int checkboard (void)
107 {
108         DECLARE_GLOBAL_DATA_PTR;
109
110         char *s = getenv ("serial#");
111         char *e;
112
113         puts ("Board: ");
114
115         if (!s || strncmp (s, "HERMES", 6)) {
116                 puts ("### No HW ID - assuming HERMES-PRO");
117         } else {
118                 for (e = s; *e; ++e) {
119                         if (*e == ' ')
120                                 break;
121                 }
122
123                 for (; s < e; ++s) {
124                         putc (*s);
125                 }
126         }
127
128         gd->board_type = board_init ();
129
130         printf ("  Rev. %ld.x\n", (gd->board_type >> 16));
131
132         return (0);
133 }
134
135 /* ------------------------------------------------------------------------- */
136
137 long int initdram (int board_type)
138 {
139         volatile immap_t *immap = (immap_t *) CFG_IMMR;
140         volatile memctl8xx_t *memctl = &immap->im_memctl;
141         long int size, size8, size9;
142
143         upmconfig (UPMA, (uint *) sdram_table,
144                            sizeof (sdram_table) / sizeof (uint));
145
146         /*
147          * Preliminary prescaler for refresh
148          */
149         memctl->memc_mptpr = 0x0400;
150
151         memctl->memc_mar = 0x00000088;
152
153         /*
154          * Map controller banks 1 to the SDRAM banks at preliminary address
155          */
156         memctl->memc_or1 = CFG_OR1_PRELIM;
157         memctl->memc_br1 = CFG_BR1_PRELIM;
158
159         /* HERMES-PRO boards have only one bank SDRAM */
160
161
162         udelay (200);
163
164         /* perform SDRAM initializsation sequence */
165
166         memctl->memc_mamr = 0xD0802114;
167         memctl->memc_mcr = 0x80002105;
168         udelay (1);
169         memctl->memc_mamr = 0xD0802118;
170         memctl->memc_mcr = 0x80002130;
171         udelay (1);
172         memctl->memc_mamr = 0xD0802114;
173         memctl->memc_mcr = 0x80002106;
174
175         udelay (1000);
176
177         /*
178          * Check Bank 0 Memory Size for re-configuration
179          *
180          * try 8 column mode
181          */
182         size8 = dram_size (CFG_MAMR_8COL, (long *) SDRAM_BASE_PRELIM,
183                                            SDRAM_MAX_SIZE);
184
185         udelay (1000);
186
187         /*
188          * try 9 column mode
189          */
190         size9 = dram_size (CFG_MAMR_9COL, (long *) SDRAM_BASE_PRELIM,
191                                            SDRAM_MAX_SIZE);
192
193         if (size8 < size9) {            /* leave configuration at 9 columns */
194                 size = size9;
195 /*      debug ("SDRAM Bank 0 in 9 column mode: %ld MB\n", size >> 20);  */
196         } else {                                        /* back to 8 columns            */
197                 size = size8;
198                 memctl->memc_mamr = CFG_MAMR_8COL;
199                 udelay (500);
200 /*      debug ("SDRAM Bank 0 in 8 column mode: %ld MB\n", size >> 20);  */
201         }
202
203         udelay (1000);
204
205         memctl->memc_or1 = ((-size) & 0xFFFF0000) | SDRAM_TIMING;
206         memctl->memc_br1 = (CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V;
207
208         udelay (10000);
209
210         return (size);
211 }
212
213 /* ------------------------------------------------------------------------- */
214
215 /*
216  * Check memory range for valid RAM. A simple memory test determines
217  * the actually available RAM size between addresses `base' and
218  * `base + maxsize'. Some (not all) hardware errors are detected:
219  * - short between address lines
220  * - short between data lines
221  */
222
223 static long int dram_size (long int mamr_value, long int *base,
224                                                    long int maxsize)
225 {
226         volatile immap_t *immap = (immap_t *) CFG_IMMR;
227         volatile memctl8xx_t *memctl = &immap->im_memctl;
228
229         memctl->memc_mamr = mamr_value;
230
231         return (get_ram_size(base, maxsize));
232 }
233
234 /* ------------------------------------------------------------------------- */
235
236 #define PB_LED_3        0x00020000      /* Status LED's */
237 #define PB_LED_2        0x00010000
238 #define PB_LED_1        0x00008000
239 #define PB_LED_0        0x00004000
240
241 #define PB_LED_ALL      (PB_LED_0 | PB_LED_1 | PB_LED_2 | PB_LED_3)
242
243 #define PC_REP_SPD1     0x00000800
244 #define PC_REP_SPD0     0x00000400
245
246 #define PB_RESET_2081   0x00000020      /* Reset PEB2081 */
247
248 #define PB_MAI_4        0x00000010      /* Configuration */
249 #define PB_MAI_3        0x00000008
250 #define PB_MAI_2        0x00000004
251 #define PB_MAI_1        0x00000002
252 #define PB_MAI_0        0x00000001
253
254 #define PB_MAI_ALL      (PB_MAI_0 | PB_MAI_1 | PB_MAI_2 | PB_MAI_3 | PB_MAI_4)
255
256
257 #define PC_REP_MGRPRS   0x0200
258 #define PC_REP_SPD      0x0040          /* Select 100 Mbps */
259 #define PC_REP_RES      0x0004
260 #define PC_BIT14        0x0002          /* ??? */
261 #define PC_BIT15        0x0001          /* ??? ENDSL ?? */
262
263 /* ------------------------------------------------------------------------- */
264
265 static ulong board_init (void)
266 {
267         volatile immap_t *immr = (immap_t *) CFG_IMMR;
268         ulong reg, revision, speed = 100;
269         int ethspeed;
270         char *s;
271
272         if ((s = getenv ("ethspeed")) != NULL) {
273                 if (strcmp (s, "100") == 0) {
274                         ethspeed = 100;
275                 } else if (strcmp (s, "10") == 0) {
276                         ethspeed = 10;
277                 } else {
278                         ethspeed = 0;
279                 }
280         } else {
281                 ethspeed = 0;
282         }
283
284         /* Configure Port B Output Pins => 0x0003cc3F */
285         reg = PB_LED_ALL | PC_REP_SPD1 | PC_REP_SPD0 | PB_RESET_2081 |
286                         PB_MAI_ALL;
287         immr->im_cpm.cp_pbpar &= ~reg;
288         immr->im_cpm.cp_pbodr &= ~reg;
289         immr->im_cpm.cp_pbdat &= ~reg;  /* all 0 */
290         immr->im_cpm.cp_pbdir |= reg;
291
292         /* Check hardware revision */
293         if ((immr->im_ioport.iop_pcdat & 0x0003) == 0x0003) {
294                 /*
295                  * Revision 3.x hardware
296                  */
297                 revision = 3;
298
299                 immr->im_ioport.iop_pcdat = 0x0240;
300                 immr->im_ioport.iop_pcdir = (PC_REP_MGRPRS | PC_REP_SPD | PC_REP_RES | PC_BIT14);       /* = 0x0246 */
301                 immr->im_ioport.iop_pcdat |= PC_REP_RES;
302         } else {
303                 immr->im_ioport.iop_pcdat = 0x0002;
304                 immr->im_ioport.iop_pcdir = (PC_REP_MGRPRS | PC_REP_RES | PC_BIT14 | PC_BIT15); /* = 0x0207 */
305
306                 if ((immr->im_ioport.iop_pcdat & PC_REP_SPD) == 0) {
307                         /*
308                          * Revision 2.x hardware: PC9 connected to PB21
309                          */
310                         revision = 2;
311
312                         if (ethspeed == 0) {
313                                 /* both 10 and 100 Mbps allowed:
314                                  * select 10 Mbps and autonegotiation
315                                  */
316                                 puts ("  [10+100]");
317                                 immr->im_cpm.cp_pbdat = 0;      /* SPD1:SPD0 = 0:0 - autonegot. */
318                                 speed = 10;
319                         } else if (ethspeed == 10) {
320                                 /* we are asked for 10 Mbps,
321                                  * so select 10 Mbps
322                                  */
323                                 puts ("  [10]");
324                                 immr->im_cpm.cp_pbdat = 0;      /* ??? */
325                                 speed = 10;
326                         } else {
327                                 /* anything else:
328                                  * select 100 Mbps
329                                  */
330                                 puts ("  [100]");
331                                 immr->im_cpm.cp_pbdat = PC_REP_SPD0 | PC_REP_SPD1;
332                                 /* SPD1:SPD0 = 1:1 - 100 Mbps */
333                                 speed = 100;
334                         }
335                         immr->im_ioport.iop_pcdat |= (PC_REP_RES | PC_BIT14);
336
337                         /* must be run from RAM  */
338                         /* start_lxt980 (speed); */
339                 /*************************/
340                 } else {
341                         /*
342                          * Revision 1.x hardware
343                          */
344                         revision = 1;
345
346                         immr->im_ioport.iop_pcdat = PC_REP_MGRPRS | PC_BIT14;   /* = 0x0202 */
347                         immr->im_ioport.iop_pcdir = (PC_REP_MGRPRS | PC_REP_SPD | PC_REP_RES | PC_BIT14 | PC_BIT15);    /* = 0x0247 */
348
349                         if (ethspeed == 0) {
350                                 /* both 10 and 100 Mbps allowed:
351                                  * select 100 Mbps and autonegotiation
352                                  */
353                                 puts ("  [10+100]");
354                                 immr->im_cpm.cp_pbdat = 0;      /* SPD1:SPD0 = 0:0 - autonegot. */
355                                 immr->im_ioport.iop_pcdat |= PC_REP_SPD;
356                         } else if (ethspeed == 10) {
357                                 /* we are asked for 10 Mbps,
358                                    * so select 10 Mbps
359                                  */
360                                 puts ("  [10]");
361                                 immr->im_cpm.cp_pbdat = PC_REP_SPD0;    /* SPD1:SPD0 = 0:1 - 10 Mbps */
362                         } else {
363                                 /* anything else:
364                                    * select 100 Mbps
365                                  */
366                                 puts ("  [100]");
367                                 immr->im_cpm.cp_pbdat = PC_REP_SPD0 | PC_REP_SPD1;
368                                 /* SPD1:SPD0 = 1:1 - 100 Mbps */
369                                 immr->im_ioport.iop_pcdat |= PC_REP_SPD;
370                         }
371
372                         immr->im_ioport.iop_pcdat |= PC_REP_RES;
373                 }
374         }
375         SHOW_BOOT_PROGRESS (0x00);
376
377         return ((revision << 16) | (speed & 0xFFFF));
378 }
379
380 /* ------------------------------------------------------------------------- */
381
382 #define SCC_SM          1                       /* Index => SCC2 */
383 #define PROFF           PROFF_SCC2
384
385 #define SMI_MSGLEN      8                       /* Length of SMI Messages        */
386
387 #define PHYGPCR_ADDR    0x109   /* Port Enable               */
388 #define PHYPCR_ADDR     0x132           /* PHY Port Control Reg. (port 1)    */
389 #define LEDPCR_ADDR     0x141           /* LED Port Control Reg.         */
390 #define RPRESET_ADDR    0x144   /* Repeater Reset            */
391
392 #define PHYPCR_SPEED    0x2000  /* on for 100 Mbps, off for 10 Mbps  */
393 #define PHYPCR_AN       0x1000          /* on to enable  Auto-Negotiation    */
394 #define PHYPCR_REST_AN  0x0200  /* on to restart Auto-Negotiation    */
395 #define PHYPCR_FDX      0x0100          /* on for Full Duplex, off for HDX   */
396 #define PHYPCR_COLT     0x0080          /* on to enable COL signal test      */
397
398 /* ------------------------------------------------------------------------- */
399
400 /*
401  * Must run from RAM:
402  * uses parameter RAM area which is used for stack while running from ROM
403  */
404 void hermes_start_lxt980 (int speed)
405 {
406         volatile immap_t *immr = (immap_t *) CFG_IMMR;
407         volatile cpm8xx_t *cp = (cpm8xx_t *) & (immr->im_cpm);
408         volatile scc_t *sp = (scc_t *) & (cp->cp_scc[SCC_SM]);
409         volatile cbd_t *bd;
410         volatile hdlc_pram_t *hp;
411         uchar smimsg[SMI_MSGLEN];
412         ushort phypcrval;
413         uint bd_off;
414         int pnr;
415
416         printf ("LXT9880: %3d Mbps\n", speed);
417
418         immr->im_ioport.iop_paodr |= 0x0008;    /* init PAODR: PA12 (TXD2) open drain */
419         immr->im_ioport.iop_papar |= 0x400c;    /* init PAPAR: TXD2, RXD2, BRGO4 */
420         immr->im_ioport.iop_padir &= 0xbff3;    /* init PADIR: BRGO4 */
421         immr->im_ioport.iop_padir |= 0x4000;
422
423         /* get temporary BD; no need for permanent alloc */
424         bd_off = dpram_base_align (8);
425
426         bd = (cbd_t *) (immr->im_cpm.cp_dpmem + bd_off);
427
428         bd->cbd_bufaddr = 0;
429         bd->cbd_datlen = 0;
430         bd->cbd_sc = BD_SC_WRAP | BD_SC_LAST | BD_SC_INTRPT | BD_SC_TC;
431
432         /* init. baudrate generator BRG4 */
433         cp->cp_brgc4 = (0x00010000 | (50 << 1));        /* output 1 MHz */
434
435         cp->cp_sicr &= 0xFFFF00FF;      /* SICR: mask SCC2 */
436         cp->cp_sicr |= 0x00001B00;      /* SICR: SCC2 clk BRG4 */
437
438         /* init SCC_SM register */
439         sp->scc_psmr = 0x0000;          /* init PSMR: no additional flags */
440         sp->scc_todr = 0x0000;
441         sp->scc_dsr = 0x7e7e;
442
443         /* init. SCC_SM parameter area */
444         hp = (hdlc_pram_t *) & cp->cp_dparam[PROFF];
445
446         hp->tbase = bd_off;                     /* offset from beginning of DPRAM */
447
448         hp->rfcr = 0x18;
449         hp->tfcr = 0x18;
450         hp->mrblr = 10;
451
452         hp->c_mask = 0x0000f0b8;
453         hp->c_pres = 0x0000ffff;
454
455         hp->disfc = 0;
456         hp->crcec = 0;
457         hp->abtsc = 0;
458         hp->nmarc = 0;
459         hp->retrc = 0;
460
461         hp->mflr = 10;
462
463         hp->rfthr = 1;
464
465         hp->hmask = 0;
466         hp->haddr1 = 0;
467         hp->haddr2 = 0;
468         hp->haddr3 = 0;
469         hp->haddr4 = 0;
470
471         cp->cp_cpcr = SCC_SM << 6 | 0x0001;     /* SCC_SM: init TX/RX params */
472         while (cp->cp_cpcr & CPM_CR_FLG);
473
474         /* clear all outstanding SCC events */
475         sp->scc_scce = ~0;
476
477         /* enable transmitter: GSMR_L: TPL=2(16bits), TPP=3(all ones), ENT */
478         sp->scc_gsmrh = 0;
479         sp->scc_gsmrl |= SCC_GSMRL_TPL_16 | SCC_GSMRL_TPP_ALL1 |
480                         SCC_GSMRL_ENT | SCC_GSMRL_MODE_HDLC;
481
482 #if 0
483         smimsg[0] = 0x00;                       /* CHIP/HUB ID */
484         smimsg[1] = 0x38;                       /* WRITE CMD */
485         smimsg[2] = (RPRESET_ADDR << 4) & 0xf0;
486         smimsg[3] = RPRESET_ADDR >> 4;
487         smimsg[4] = 0x01;
488         smimsg[5] = 0x00;
489         smimsg[6] = 0x00;
490         smimsg[7] = 0x00;
491
492         send_smi_frame (sp, bd, smimsg);
493 #endif
494
495         smimsg[0] = 0x7f;                       /* BROADCAST */
496         smimsg[1] = 0x34;                       /* ASSIGN HUB ID */
497         smimsg[2] = 0x00;
498         smimsg[3] = 0x00;
499         smimsg[4] = 0x00;                       /* HUB ID = 0 */
500         smimsg[5] = 0x00;
501         smimsg[6] = 0x00;
502         smimsg[7] = 0x00;
503
504         send_smi_frame (sp, bd, smimsg);
505
506         smimsg[0] = 0x7f;                       /* BROADCAST */
507         smimsg[1] = 0x3c;                       /* SET ARBOUT TO 0 */
508         smimsg[2] = 0x00;                       /* ADDRESS = 0 */
509         smimsg[3] = 0x00;
510         smimsg[4] = 0x00;                       /* DATA = 0 */
511         smimsg[5] = 0x00;
512         smimsg[6] = 0x00;
513         smimsg[7] = 0x00;
514
515         send_smi_frame (sp, bd, smimsg);
516
517         if (speed == 100) {
518                 phypcrval = PHYPCR_SPEED;       /* 100 MBIT, disable autoneg. */
519         } else {
520                 phypcrval = 0;                  /* 10 MBIT, disable autoneg. */
521         }
522
523         /* send MSGs */
524         for (pnr = 0; pnr < 8; pnr++) {
525                 smimsg[0] = 0x00;               /* CHIP/HUB ID */
526                 smimsg[1] = 0x38;               /* WRITE CMD */
527                 smimsg[2] = ((PHYPCR_ADDR + pnr) << 4) & 0xf0;
528                 smimsg[3] = (PHYPCR_ADDR + pnr) >> 4;
529                 smimsg[4] = (unsigned char) (phypcrval & 0xff);
530                 smimsg[5] = (unsigned char) (phypcrval >> 8);
531                 smimsg[6] = 0x00;
532                 smimsg[7] = 0x00;
533
534                 send_smi_frame (sp, bd, smimsg);
535         }
536
537         smimsg[0] = 0x00;                       /* CHIP/HUB ID */
538         smimsg[1] = 0x38;                       /* WRITE CMD */
539         smimsg[2] = (PHYGPCR_ADDR << 4) & 0xf0;
540         smimsg[3] = PHYGPCR_ADDR >> 4;
541         smimsg[4] = 0xff;                       /* enable port 1-8 */
542         smimsg[5] = 0x01;                       /* enable MII1 (0x01) */
543         smimsg[6] = 0x00;
544         smimsg[7] = 0x00;
545
546         send_smi_frame (sp, bd, smimsg);
547
548         smimsg[0] = 0x00;                       /* CHIP/HUB ID */
549         smimsg[1] = 0x38;                       /* WRITE CMD */
550         smimsg[2] = (LEDPCR_ADDR << 4) & 0xf0;
551         smimsg[3] = LEDPCR_ADDR >> 4;
552         smimsg[4] = 0xaa;                       /* Port 1-8 Conf.bits = 10 (Hardware control) */
553         smimsg[5] = 0xaa;
554         smimsg[6] = 0x00;
555         smimsg[7] = 0x00;
556
557         send_smi_frame (sp, bd, smimsg);
558
559         /*
560          * Disable Transmitter (so that we can free the BD, too)
561          */
562         sp->scc_gsmrl &= ~SCC_GSMRL_ENT;
563 }
564
565 /* ------------------------------------------------------------------------- */
566
567 static void send_smi_frame (volatile scc_t * sp, volatile cbd_t * bd,
568                                                         uchar * msg)
569 {
570 #ifdef DEBUG
571         unsigned hub, chip, cmd, length, addr;
572
573         hub = msg[0] & 0x1F;
574         chip = msg[0] >> 5;
575         cmd = msg[1] & 0x1F;
576         length = (msg[1] >> 5) | ((msg[2] & 0x0F) << 3);
577         addr = (msg[2] >> 4) | (msg[3] << 4);
578
579         printf ("SMI send: Hub %02x Chip %x Cmd %02x Len %d Addr %03x: "
580                         "%02x %02x %02x %02x\n",
581                         hub, chip, cmd, length, addr, msg[4], msg[5], msg[6], msg[7]);
582 #endif /* DEBUG */
583
584         bd->cbd_bufaddr = (uint) msg;
585         bd->cbd_datlen = SMI_MSGLEN;
586         bd->cbd_sc |= BD_SC_READY;
587
588         /* wait for msg transmitted */
589         while ((sp->scc_scce & 0x0002) == 0);
590         /* clear all events */
591         sp->scc_scce = ~0;
592 }
593
594 /* ------------------------------------------------------------------------- */
595
596 void show_boot_progress (int status)
597 {
598         volatile immap_t *immr = (immap_t *) CFG_IMMR;
599
600         status ^= 0x0F;
601         status = (status & 0x0F) << 14;
602         immr->im_cpm.cp_pbdat = (immr->im_cpm.cp_pbdat & ~PB_LED_ALL) | status;
603 }
604
605 /* ------------------------------------------------------------------------- */