* Patch by Klaus Heydeck, 13 Mar 2003:
[pandora-u-boot.git] / board / kup / kup4k / kup4k.c
similarity index 66%
rename from board/kup4k/kup4k.c
rename to board/kup/kup4k/kup4k.c
index abf5294..8bed3d5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright 2000, 2001, 2002
+ * (C) Copyright 2000-2004
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  * Klaus Heydeck, Kieback & Peter GmbH & Co KG, heydeck@kieback-peter.de
  *
 
 #include <common.h>
 #include <mpc8xx.h>
+#include "../common/kup.h"
 #ifdef CONFIG_KUP4K_LOGO
    #include "s1d13706.h"
 #endif
 
+#undef DEBUG
+#ifdef  DEBUG
+# define debugk(fmt,args...)    printf(fmt ,##args)
+#else
+# define debugk(fmt,args...)
+#endif
+
+typedef struct {
+       volatile unsigned char *VmemAddr;
+       volatile unsigned char *RegAddr;
+} FB_INFO_S1D13xxx;
 
-typedef struct
-{
-    volatile unsigned char *VmemAddr;
-    volatile unsigned char *RegAddr;
-}FB_INFO_S1D13xxx;
 
 /* ------------------------------------------------------------------------- */
 
@@ -42,15 +49,15 @@ static long int dram_size (long int, long int *, long int);
 #endif
 
 #ifdef CONFIG_KUP4K_LOGO
-   void lcd_logo(bd_t *bd);
+void lcd_logo(bd_t *bd);
 #endif
 
+
 /* ------------------------------------------------------------------------- */
 
 #define        _NOT_USED_      0xFFFFFFFF
 
-const uint sdram_table[] =
-{
+const uint sdram_table[] = {
        /*
         * Single Read. (Offset 0 in UPMA RAM)
         */
@@ -114,8 +121,19 @@ const uint sdram_table[] =
 
 int checkboard (void)
 {
+       volatile immap_t *immap = (immap_t *) CFG_IMMR;
+       uchar *latch,rev,mod;
 
-       printf ("### No HW ID - assuming KUP4K-Color\n");
+       /*
+        * Init ChipSelect #4 (CAN + HW-Latch)
+        */
+       immap->im_memctl.memc_or4 = 0xFFFF8926;
+       immap->im_memctl.memc_br4 = 0x90000401;
+
+       latch=(uchar *)0x90000200;
+       rev = (*latch & 0xF8) >> 3;
+       mod=(*latch & 0x03);
+       printf ("Board: KUP4K Rev %d.%d SN: %s\n",rev,mod,getenv("ethaddr"));
        return (0);
 }
 
@@ -230,10 +248,42 @@ static long int dram_size (long int mamr_value, long int *base,
 {
        volatile immap_t *immap = (immap_t *) CFG_IMMR;
        volatile memctl8xx_t *memctl = &immap->im_memctl;
+       volatile long int *addr;
+       ulong cnt, val;
+       ulong save[32];                         /* to make test non-destructive */
+       unsigned char i = 0;
 
        memctl->memc_mamr = mamr_value;
 
-       return(get_ram_size(base, maxsize));
+       for (cnt = maxsize / sizeof (long); cnt > 0; cnt >>= 1) {
+               addr = base + cnt;              /* pointer arith! */
+
+               save[i++] = *addr;
+               *addr = ~cnt;
+       }
+
+       /* write 0 to base address */
+       addr = base;
+       save[i] = *addr;
+       *addr = 0;
+
+       /* check at base address */
+       if ((val = *addr) != 0) {
+               *addr = save[i];
+               return (0);
+       }
+
+       for (cnt = 1; cnt <= maxsize / sizeof (long); cnt <<= 1) {
+               addr = base + cnt;              /* pointer arith! */
+
+               val = *addr;
+               *addr = save[--i];
+
+               if (val != (~cnt)) {
+                       return (cnt * sizeof (long));
+               }
+       }
+       return (maxsize);
 }
 #endif
 
@@ -247,7 +297,6 @@ int misc_init_r (void)
 #ifdef CONFIG_KUP4K_LOGO
        bd_t *bd = gd->bd;
 
-
        lcd_logo (bd);
 #endif                                                 /* CONFIG_KUP4K_LOGO */
 #ifdef CONFIG_IDE_LED
@@ -257,14 +306,14 @@ int misc_init_r (void)
        immap->im_ioport.iop_papar &= ~0x80;
        immap->im_ioport.iop_padat |= 0x80;     /* turn it off */
 #endif
+       setenv("hw","4k");
+       poweron_key();
        return (0);
 }
 
 #ifdef CONFIG_KUP4K_LOGO
 
 
-#define PB_LCD_PWM     ((uint)0x00004000)      /* PB 17 */
-
 void lcd_logo (bd_t * bd)
 {
        FB_INFO_S1D13xxx fb_info;
@@ -277,104 +326,117 @@ void lcd_logo (bd_t * bd)
        int rs, gs, bs;
        int r = 8, g = 8, b = 4;
        int r1, g1, b1;
+       int n;
+       uchar tmp[64];          /* long enough for environment variables */
+       int tft = 0;
 
-       immr->im_cpm.cp_pbpar &= ~PB_LCD_PWM;
-       immr->im_cpm.cp_pbodr &= ~PB_LCD_PWM;
-       immr->im_cpm.cp_pbdat &= ~PB_LCD_PWM;   /* set to 0 = enabled */
-       immr->im_cpm.cp_pbdir |= PB_LCD_PWM;
-
+       immr->im_cpm.cp_pbpar &= ~(PB_LCD_PWM);
+       immr->im_cpm.cp_pbodr &= ~(PB_LCD_PWM);
+       immr->im_cpm.cp_pbdat &= ~(PB_LCD_PWM); /* set to 0 = enabled */
+       immr->im_cpm.cp_pbdir |= (PB_LCD_PWM);
 
 /*----------------------------------------------------------------------------- */
-        /**/
 /* Initialize the chip and the frame buffer driver. */
-                        /**/
 /*----------------------------------------------------------------------------- */
-                       memctl = &immr->im_memctl;
-/*     memctl->memc_or5 = 0xFFC007F0;    / * 4 MB  17 WS or externel TA */
-/*     memctl->memc_br5 = 0x80000801;    / * Start at 0x80000000 */
+       memctl = &immr->im_memctl;
 
-       memctl->memc_or5 = 0xFFC00708;  /* 4 MB  17 WS or externel TA */
-       memctl->memc_br5 = 0x80080801;  /* Start at 0x80080000 */
 
+       /*
+        * Init ChipSelect #5 (S1D13768)
+        */
+       memctl->memc_or5 = 0xFFC007F0;  /* 4 MB  17 WS or externel TA */
+       memctl->memc_br5 = 0x80080801;  /* Start at 0x80080000 */
 
        fb_info.VmemAddr = (unsigned char *) (S1D_PHYSICAL_VMEM_ADDR);
        fb_info.RegAddr = (unsigned char *) (S1D_PHYSICAL_REG_ADDR);
 
        if ((((S1D_VALUE *) fb_info.RegAddr)[0] != 0x28)
-               || (((S1D_VALUE *) fb_info.RegAddr)[1] != 0x14)) {
+           || (((S1D_VALUE *) fb_info.RegAddr)[1] != 0x14)) {
                printf ("Warning:LCD Controller S1D13706 not found\n");
+               setenv ("lcd", "none");
                return;
        }
 
-       /* init controller */
-       for (i = 0; i < sizeof (aS1DRegs) / sizeof (aS1DRegs[0]); i++) {
-               s1dReg = aS1DRegs[i].Index;
-               s1dValue = aS1DRegs[i].Value;
-/*      printf("sid1 Index: %02x Register: %02x Wert: %02x\n",i, aS1DRegs[i].Index, aS1DRegs[i].Value); */
+
+       for (i = 0; i < sizeof(aS1DRegs_prelimn) / sizeof(aS1DRegs_prelimn[0]); i++) {
+               s1dReg = aS1DRegs_prelimn[i].Index;
+               s1dValue = aS1DRegs_prelimn[i].Value;
+               debugk ("s13768 reg: %02x value: %02x\n",
+                       aS1DRegs_prelimn[i].Index, aS1DRegs_prelimn[i].Value);
                ((S1D_VALUE *) fb_info.RegAddr)[s1dReg / sizeof (S1D_VALUE)] =
-                               s1dValue;
+                       s1dValue;
        }
 
-#undef MONOCHROME
-#ifdef MONOCHROME
-       switch (bd->bi_busfreq) {
-#if 0
-       case 24000000:
-               ((S1D_VALUE *) fb_info.RegAddr)[0x05] = 0x32;
-               ((S1D_VALUE *) fb_info.RegAddr)[0x12] = 0x28;
-               break;
-       case 32000000:
-               ((S1D_VALUE *) fb_info.RegAddr)[0x05] = 0x32;
-               ((S1D_VALUE *) fb_info.RegAddr)[0x12] = 0x33;
-               break;
-#endif
-       case 40000000:
-               ((S1D_VALUE *) fb_info.RegAddr)[0x05] = 0x32;
-               ((S1D_VALUE *) fb_info.RegAddr)[0x12] = 0x40;
-               break;
-       case 48000000:
-               ((S1D_VALUE *) fb_info.RegAddr)[0x05] = 0x32;
-               ((S1D_VALUE *) fb_info.RegAddr)[0x12] = 0x4C;
-               break;
-       default:
-               printf ("KUP4K S1D1: unknown busfrequency: %ld assuming 64 MHz\n",
-                               bd->bi_busfreq);
-       case 64000000:
-               ((S1D_VALUE *) fb_info.RegAddr)[0x05] = 0x32;
-               ((S1D_VALUE *) fb_info.RegAddr)[0x12] = 0x69;
-               break;
+
+       n = getenv_r ("lcd", tmp, sizeof (tmp));
+       if (n > 0) {
+               if (!strcmp ("tft", tmp))
+                       tft = 1;
+               else
+                       tft = 0;
        }
-       ((S1D_VALUE *) fb_info.RegAddr)[0x10] = 0x00;
-#else
-       switch (bd->bi_busfreq) {
 #if 0
-       case 24000000:
-               ((S1D_VALUE *) fb_info.RegAddr)[0x05] = 0x22;
-               ((S1D_VALUE *) fb_info.RegAddr)[0x12] = 0x34;
-               break;
-       case 32000000:
-               ((S1D_VALUE *) fb_info.RegAddr)[0x05] = 0x32;
-               ((S1D_VALUE *) fb_info.RegAddr)[0x12] = 0x34;
-               break;
-#endif
-       case 40000000:
-               ((S1D_VALUE *) fb_info.RegAddr)[0x05] = 0x32;
-               ((S1D_VALUE *) fb_info.RegAddr)[0x12] = 0x41;
-               break;
-       case 48000000:
-               ((S1D_VALUE *) fb_info.RegAddr)[0x05] = 0x22;
-               ((S1D_VALUE *) fb_info.RegAddr)[0x12] = 0x34;
-               break;
-       default:
-               printf ("KUP4K S1D1: unknown busfrequency: %ld assuming 64 MHz\n",
-                               bd->bi_busfreq);
-       case 64000000:
-               ((S1D_VALUE *) fb_info.RegAddr)[0x05] = 0x32;
-               ((S1D_VALUE *) fb_info.RegAddr)[0x12] = 0x66;
-               break;
-       }
+       if (((S1D_VALUE *) fb_info.RegAddr)[0xAC] & 0x04)
+               tft = 0;
+       else
+               tft = 1;
 #endif
 
+       debugk ("Port=0x%02x -> TFT=%d\n", tft,
+               ((S1D_VALUE *) fb_info.RegAddr)[0xAC]);
+
+       /* init controller */
+       if (!tft) {
+               for (i = 0; i < sizeof(aS1DRegs_stn) / sizeof(aS1DRegs_stn[0]); i++) {
+                       s1dReg = aS1DRegs_stn[i].Index;
+                       s1dValue = aS1DRegs_stn[i].Value;
+                       debugk ("s13768 reg: %02x value: %02x\n",
+                               aS1DRegs_stn[i].Index,
+                               aS1DRegs_stn[i].Value);
+                       ((S1D_VALUE *) fb_info.RegAddr)[s1dReg / sizeof(S1D_VALUE)] =
+                               s1dValue;
+               }
+               n = getenv_r ("contrast", tmp, sizeof (tmp));
+               ((S1D_VALUE *) fb_info.RegAddr)[0xB3] =
+                       (n > 0) ? (uchar) simple_strtoul (tmp, NULL, 10) * 255 / 100 : 0xA0;
+               switch (bd->bi_busfreq) {
+               case 40000000:
+                       ((S1D_VALUE *) fb_info.RegAddr)[0x05] = 0x32;
+                       ((S1D_VALUE *) fb_info.RegAddr)[0x12] = 0x41;
+                       break;
+               case 48000000:
+                       ((S1D_VALUE *) fb_info.RegAddr)[0x05] = 0x22;
+                       ((S1D_VALUE *) fb_info.RegAddr)[0x12] = 0x34;
+                       break;
+               default:
+                       printf ("KUP4K S1D1: unknown busfrequency: %ld assuming 64 MHz\n", bd->bi_busfreq);
+               case 64000000:
+                       ((S1D_VALUE *) fb_info.RegAddr)[0x05] = 0x32;
+                       ((S1D_VALUE *) fb_info.RegAddr)[0x12] = 0x66;
+                       break;
+               }
+               /*   setenv("lcd","stn"); */
+       } else {
+               for (i = 0; i < sizeof(aS1DRegs_tft) / sizeof(aS1DRegs_tft[0]); i++) {
+                       s1dReg = aS1DRegs_tft[i].Index;
+                       s1dValue = aS1DRegs_tft[i].Value;
+                       debugk ("s13768 reg: %02x value: %02x\n",
+                               aS1DRegs_tft[i].Index,
+                               aS1DRegs_tft[i].Value);
+                       ((S1D_VALUE *) fb_info.RegAddr)[s1dReg / sizeof (S1D_VALUE)] =
+                               s1dValue;
+               }
+
+               switch (bd->bi_busfreq) {
+               default:
+                       printf ("KUP4K S1D1: unknown busfrequency: %ld assuming 64 MHz\n", bd->bi_busfreq);
+               case 40000000:
+                       ((S1D_VALUE *) fb_info.RegAddr)[0x05] = 0x42;
+                       ((S1D_VALUE *) fb_info.RegAddr)[0x12] = 0x30;
+                       break;
+               }
+               /* setenv("lcd","tft"); */
+       }
 
        /* create and set colormap */
        rs = 256 / (r - 1);
@@ -384,27 +446,13 @@ void lcd_logo (bd_t * bd)
                r1 = (rs * ((i / (g * b)) % r)) * 255;
                g1 = (gs * ((i / b) % g)) * 255;
                b1 = (bs * ((i) % b)) * 255;
-/*     printf("%d %04x %04x %04x\n",i,r1>>4,g1>>4,b1>>4); */
+               debugk ("%d %04x %04x %04x\n", i, r1 >> 4, g1 >> 4, b1 >> 4);
                S1D_WRITE_PALETTE (fb_info.RegAddr, i, (r1 >> 4), (g1 >> 4),
-                                                  (b1 >> 4));
+                                  (b1 >> 4));
        }
 
        /* copy bitmap */
        fb = (char *) (fb_info.VmemAddr);
        memcpy (fb, (uchar *) CONFIG_KUP4K_LOGO, 320 * 240);
 }
-#endif                                                 /* CONFIG_KUP4K_LOGO */
-
-#ifdef CONFIG_IDE_LED
-void ide_led (uchar led, uchar status)
-{
-       volatile immap_t *immap = (immap_t *) CFG_IMMR;
-
-       /* We have one led for both pcmcia slots */
-       if (status) {                           /* led on */
-               immap->im_ioport.iop_padat &= ~0x80;
-       } else {
-               immap->im_ioport.iop_padat |= 0x80;
-       }
-}
-#endif
+#endif /* CONFIG_KUP4K_LOGO */