]> git.sur5r.net Git - u-boot/blobdiff - board/trab/vfd.c
Patch by Kenneth Johansson, 30 Jun 2003:
[u-boot] / board / trab / vfd.c
index 894e3157d68bd702b89b02c0575aa0e7b884294d..1abc2adc65ad47dd8d2c4f5d4d0b4694e0ca6447 100644 (file)
 #define        FRAME_BUF_SIZE  ((256*4*56)/8)
 #define frame_buf_offs 4
 
+/* defines for starting Timer3 as CPLD-Clk */
+#define START3                 (1 << 16)
+#define UPDATE3                        (1 << 17)
+#define INVERT3                        (1 << 18)
+#define RELOAD3                        (1 << 19)
+
+/* CPLD-Register for controlling vfd-blank-signal */
+#define VFD_DISABLE    (*(volatile uchar *)0x04038000=0x0000)
+#define VFD_ENABLE     (*(volatile uchar *)0x04038000=0x0001)
+
 /* Supported VFD Types */
 #define        VFD_TYPE_T119C          1       /* Noritake T119C VFD */
 #define        VFD_TYPE_MN11236        2
 
+/*#define NEW_CPLD_CLK*/
+
+int vfd_board_id;
+
 /* taken from armboot/common/vfd.c */
 unsigned long adr_vfd_table[112][18][2][4][2];
 unsigned char bit_vfd_table[112][18][2][4][2];
@@ -80,9 +94,7 @@ void init_grid_ctrl(void)
        /*
         * clear frame buffer (logical clear => set to "black")
         */
-       memset ((void *)(gd->fb_base),
-               gd->vfd_inv_data ? 0xFF : 0,
-               FRAME_BUF_SIZE);
+       memset ((void *)(gd->fb_base), 0, FRAME_BUF_SIZE);
 
        switch (gd->vfd_type) {
        case VFD_TYPE_T119C:
@@ -98,10 +110,7 @@ void init_grid_ctrl(void)
                        bit_nr = bit % 8;
                        bit_nr = (bit_nr > 3) ? bit_nr-4 : bit_nr+4;
                        temp=(*(volatile unsigned char*)(adr));
-                       if (gd->vfd_inv_data)
-                               temp &= ~(1<<bit_nr);
-                       else
-                               temp |=  (1<<bit_nr);
+                       temp |=  (1<<bit_nr);
                        (*(volatile unsigned char*)(adr))=temp;
 
                        if(grid_cycle<55)
@@ -115,10 +124,7 @@ void init_grid_ctrl(void)
                        bit_nr = bit%8;
                        bit_nr = (bit_nr>3)?bit_nr-4:bit_nr+4;
                        temp=(*(volatile unsigned char*)(adr));
-                       if (gd->vfd_inv_data)
-                               temp &= ~(1<<bit_nr);
-                       else
-                               temp |=  (1<<bit_nr);
+                       temp |=  (1<<bit_nr);
                        (*(volatile unsigned char*)(adr))=temp;
                }
            }
@@ -136,10 +142,7 @@ void init_grid_ctrl(void)
                        bit_nr = bit % 8;
                        bit_nr = (bit_nr > 3) ? bit_nr-4 : bit_nr+4;
                        temp=(*(volatile unsigned char*)(adr));
-                       if (gd->vfd_inv_data)
-                               temp &= ~(1<<bit_nr);
-                       else
-                               temp |=  (1<<bit_nr);
+                       temp |=  (1<<bit_nr);
                        (*(volatile unsigned char*)(adr))=temp;
 
                        if(grid_cycle<37)
@@ -152,10 +155,7 @@ void init_grid_ctrl(void)
                        bit_nr = bit%8;
                        bit_nr = (bit_nr>3)?bit_nr-4:bit_nr+4;
                        temp=(*(volatile unsigned char*)(adr));
-                       if (gd->vfd_inv_data)
-                               temp &= ~(1<<bit_nr);
-                       else
-                               temp |=  (1<<bit_nr);
+                       temp |=  (1<<bit_nr);
                        (*(volatile unsigned char*)(adr))=temp;
                }
            }
@@ -250,7 +250,7 @@ void create_vfd_table(void)
                        for(entry=0;entry<2;entry++) {
                            unsigned long adr  = gd->fb_base;
                            unsigned int bit_nr = 0;
-                           
+
                            if (vfd_table[x][y][color][display][entry]) {
 
                                pixel  = vfd_table[x][y][color][display][entry] + frame_buf_offs;
@@ -295,18 +295,11 @@ void set_vfd_pixel(unsigned char x, unsigned char y,
        bit_nr = bit_vfd_table[x][y][color][display][0];
        temp=(*(volatile unsigned char*)(adr));
 
-       if (gd->vfd_inv_data) {
-               if (value)
-                       temp &= ~(1<<bit_nr);
-               else
-                       temp |=  (1<<bit_nr);
-       } else {
-               if (value)
-                       temp |=  (1<<bit_nr);
-               else
-                       temp &= ~(1<<bit_nr);
-       }
-       
+       if (value)
+               temp |=  (1<<bit_nr);
+       else
+               temp &= ~(1<<bit_nr);
+
        (*(volatile unsigned char*)(adr))=temp;
 }
 
@@ -353,9 +346,10 @@ void transfer_pic(int display, unsigned char *adr, int height, int width)
                                }
                        }
                }
-               display++;
-               if (display > 3)
-                       display = 0;
+               if (display > 0)
+                       display--;
+               else
+                       display = 3;
        }
 }
 
@@ -363,22 +357,62 @@ void transfer_pic(int display, unsigned char *adr, int height, int width)
  * This function initializes VFD clock that is needed for the CPLD that
  * manages the keyboard.
  */
-int vfd_init_clocks(void)
+int vfd_init_clocks (void)
 {
-       /* Port-Pins als LCD-Ausgang */
-       rPCCON =   (rPCCON & 0xFFFFFF00)| 0x000000AA;
-       /* Port-Pins als LCD-Ausgang */
-       rPDCON =   (rPDCON & 0xFFFFFF03)| 0x000000A8;
-#ifdef CFG_WITH_VFRAME
-       /* mit VFRAME zum Messen */
-       rPDCON =   (rPDCON & 0xFFFFFF00)| 0x000000AA;
-#endif
+       S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
+       S3C24X0_TIMERS * const timers = S3C24X0_GetBase_TIMERS();
+       S3C24X0_LCD * const lcd = S3C24X0_GetBase_LCD();
 
-       rLCDCON2 = 0x000DC000;
-       rLCDCON3 = 0x0051000A;
-       rLCDCON4 = 0x00000001;
-       rLCDCON5 = 0x00000440;
-       rLCDCON1 = 0x00000B75;
+       /* try to determine display type from the value
+        * defined by pull-ups
+        */
+       gpio->PCUP = (gpio->PCUP & 0xFFF0);     /* activate  GPC0...GPC3 pullups */
+       gpio->PCCON = (gpio->PCCON & 0xFFFFFF00);       /* configure GPC0...GPC3 as inputs */
+       udelay (10);                            /* allow signals to settle */
+       vfd_board_id = (~gpio->PCDAT) & 0x000F; /* read GPC0...GPC3 port pins */
+
+       VFD_DISABLE;                            /* activate blank for the vfd */
+
+#define        NEW_CPLD_CLK
+
+#ifdef NEW_CPLD_CLK
+       if (vfd_board_id) {
+               /* If new board revision, then use PWM 3 as cpld-clock */
+               /* Enable 500 Hz timer for fill level sensor to operate properly */
+               /* Configure TOUT3 as functional pin, disable pull-up */
+               gpio->PDCON &= ~0x30000;
+               gpio->PDCON |= 0x20000;
+               gpio->PDUP |= (1 << 8);
+
+               /* Configure the prescaler */
+               timers->TCFG0 &= ~0xff00;
+               timers->TCFG0 |= 0x0f00;
+
+               /* Select MUX input (divider) for timer3 (1/16) */
+               timers->TCFG1 &= ~0xf000;
+               timers->TCFG1 |= 0x3000;
+
+               /* Enable autoreload and set the counter and compare
+                * registers to values for the 500 Hz clock
+                * (for a given  prescaler (15) and divider (16)):
+                * counter = (66000000 / 500) >> 9;
+                */
+               timers->ch[3].TCNTB = 0x101;
+               timers->ch[3].TCMPB = 0x101 / 2;
+
+               /* Start timer */
+               timers->TCON = (timers->TCON | UPDATE3 | RELOAD3) & ~INVERT3;
+               timers->TCON = (timers->TCON | START3) & ~UPDATE3;
+       }
+#endif
+       /* If old board revision, then use vm-signal as cpld-clock */
+       lcd->LCDCON2 = 0x00FFC000;
+       lcd->LCDCON3 = 0x0007FF00;
+       lcd->LCDCON4 = 0x00000000;
+       lcd->LCDCON5 = 0x00000400;
+       lcd->LCDCON1 = 0x00000B75;
+       /* VM (GPD1) is used as clock for the CPLD */
+       gpio->PDCON = (gpio->PDCON & 0xFFFFFFF3) | 0x00000008;
 
        return 0;
 }
@@ -394,10 +428,12 @@ int vfd_init_clocks(void)
  */
 int drv_vfd_init(void)
 {
+       S3C24X0_LCD * const lcd = S3C24X0_GetBase_LCD();
+       S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
        char *tmp;
        ulong palette;
        static int vfd_init_done = 0;
-       int vfd_id;
+       int vfd_inv_data = 0;
 
        DECLARE_GLOBAL_DATA_PTR;
 
@@ -405,17 +441,9 @@ int drv_vfd_init(void)
                return (0);
        vfd_init_done = 1;
 
-       /* try to determine display type from the value
-        * defined by pull-ups
-        */
-       rPCUP  = (rPCUP & 0xFFF0);      /* activate  GPC0...GPC3 pullups */
-       rPCCON = (rPCCON & 0xFFFFFF00); /* configure GPC0...GPC3 as inputs */
-       udelay(10);                     /* allow signals to settle */
-
-       vfd_id = (~rPCDAT) & 0x000F;    /* read GPC0...GPC3 port pins */
-       debug("Detecting Revison of WA4-VFD: ID=0x%X\n", vfd_id);
+       debug("Detecting Revison of WA4-VFD: ID=0x%X\n", vfd_board_id);
 
-       switch (vfd_id) {
+       switch (vfd_board_id) {
        case 0:                 /* board revision < Rev.200 */
                if ((tmp = getenv ("vfd_type")) == NULL) {
                        break;
@@ -428,19 +456,18 @@ int drv_vfd_init(void)
                        /* cannot use printf for a warning here */
                        gd->vfd_type = 0;       /* unknown */
                }
-               gd->vfd_inv_data = 0;
 
                break;
        default:                /* default to MN11236, data inverted */
                gd->vfd_type = VFD_TYPE_MN11236;
-               gd->vfd_inv_data = 1;
+               vfd_inv_data = 1;
                setenv ("vfd_type", "MN11236");
        }
        debug ("VFD type: %s%s\n",
                (gd->vfd_type == VFD_TYPE_T119C)   ? "T119C" :
                (gd->vfd_type == VFD_TYPE_MN11236) ? "MN11236" :
                "unknown",
-               gd->vfd_inv_data ? ", inverted data" : "");
+               vfd_inv_data ? ", inverted data" : "");
 
        gd->fb_base = gd->fb_base;
        create_vfd_table();
@@ -458,19 +485,58 @@ int drv_vfd_init(void)
         * (wrap around)
         * see manual S3C2400
         */
+       /* Stopp LCD-Controller */
+       lcd->LCDCON1 = 0x00000000;
        /* frame buffer startadr */
-       rLCDSADDR1 = gd->fb_base >> 1;
+       lcd->LCDSADDR1 = gd->fb_base >> 1;
        /* frame buffer endadr */
-       rLCDSADDR2 = (gd->fb_base + FRAME_BUF_SIZE) >> 1;
-       rLCDSADDR3 = ((256/4));
-
-       debug ("LCDSADDR1: %lX\n", rLCDSADDR1);
-       debug ("LCDSADDR2: %lX\n", rLCDSADDR2);
-       debug ("LCDSADDR3: %lX\n", rLCDSADDR3);
+       lcd->LCDSADDR2 = (gd->fb_base + FRAME_BUF_SIZE) >> 1;
+       lcd->LCDSADDR3 = ((256/4));
+       lcd->LCDCON2 = 0x000DC000;
+       if(gd->vfd_type == VFD_TYPE_MN11236)
+               lcd->LCDCON2 = 37 << 14;        /* MN11236: 38 lines */
+       else
+               lcd->LCDCON2 = 55 << 14;        /* T119C:   56 lines */
+       lcd->LCDCON3 = 0x0051000A;
+       lcd->LCDCON4 = 0x00000001;
+       if (gd->vfd_type && vfd_inv_data)
+               lcd->LCDCON5 = 0x000004C0;
+       else
+               lcd->LCDCON5 = 0x00000440;
+
+       /* Port pins as LCD output */
+       gpio->PCCON =   (gpio->PCCON & 0xFFFFFF00)| 0x000000AA;
+       gpio->PDCON =   (gpio->PDCON & 0xFFFFFF03)| 0x000000A8;
+
+       /* Synchronize VFD enable with LCD controller to avoid flicker  */
+       lcd->LCDCON1 = 0x00000B75;                      /* Start LCD-Controller */
+       while((lcd->LCDCON5 & 0x180000)!=0x100000);     /* Wait for end of VSYNC */
+       while((lcd->LCDCON5 & 0x060000)!=0x040000);     /* Wait for next HSYNC  */
+       while((lcd->LCDCON5 & 0x060000)==0x040000);
+       while((lcd->LCDCON5 & 0x060000)!=0x000000);
+       if(gd->vfd_type)
+               VFD_ENABLE;
+
+       debug ("LCDSADDR1: %lX\n", lcd->LCDSADDR1);
+       debug ("LCDSADDR2: %lX\n", lcd->LCDSADDR2);
+       debug ("LCDSADDR3: %lX\n", lcd->LCDSADDR3);
 
        return 0;
 }
 
+/*
+ * Disable VFD: should be run before resetting the system:
+ * disable VM, enable pull-up
+ */
+void disable_vfd (void)
+{
+       S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
+
+       VFD_DISABLE;
+       gpio->PDCON &= ~0xC;
+       gpio->PDUP  &= ~0x2;
+}
+
 /************************************************************************/
 /* ** ROM capable initialization part - needed to reserve FB memory    */
 /************************************************************************/