X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=board%2Ftrab%2Fvfd.c;h=1abc2adc65ad47dd8d2c4f5d4d0b4694e0ca6447;hb=0d4983930a3559be92452761cfa268ee9d0f2773;hp=5e601ef794750ab2e8894b3cf84603661f4ba08f;hpb=1cb8e980c41e86760fa93de63f4e4cf643bef9d9;p=u-boot diff --git a/board/trab/vfd.c b/board/trab/vfd.c index 5e601ef794..1abc2adc65 100644 --- a/board/trab/vfd.c +++ b/board/trab/vfd.c @@ -55,13 +55,28 @@ #define BLAU 0x0C #define VIOLETT 0X0D -ulong frame_buf_size; +/* MAGIC */ +#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]; @@ -75,19 +90,11 @@ void init_grid_ctrl(void) ulong adr, grid_cycle; unsigned int bit, display; unsigned char temp, bit_nr; - ulong val; /* * clear frame buffer (logical clear => set to "black") */ - if (gd->vfd_inv_data == 0) - val = 0; - else - val = ~0; - - for (adr = gd->fb_base; adr <= (gd->fb_base+7168); adr += 4) { - (*(volatile ulong*)(adr)) = val; - } + memset ((void *)(gd->fb_base), 0, FRAME_BUF_SIZE); switch (gd->vfd_type) { case VFD_TYPE_T119C: @@ -97,16 +104,13 @@ void init_grid_ctrl(void) (grid_cycle + 200) * 4 + frame_buf_offs + display; /* wrap arround if offset (see manual S3C2400) */ - if (bit>=frame_buf_size*8) - bit = bit - (frame_buf_size * 8); + if (bit>=FRAME_BUF_SIZE*8) + bit = bit - (FRAME_BUF_SIZE * 8); adr = gd->fb_base + (bit/32) * 4 + (3 - (bit%32) / 8); 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<=frame_buf_size*8) - bit = bit-(frame_buf_size*8); + if (bit>=FRAME_BUF_SIZE*8) + bit = bit-(FRAME_BUF_SIZE*8); adr = gd->fb_base+(bit/32)*4+(3-(bit%32)/8); 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<=frame_buf_size*8) - bit = bit - (frame_buf_size * 8); + if (bit>=FRAME_BUF_SIZE*8) + bit = bit - (FRAME_BUF_SIZE * 8); adr = gd->fb_base + (bit/32) * 4 + (3 - (bit%32) / 8); 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<=frame_buf_size*8) - bit = bit-(frame_buf_size*8); + if (bit>=FRAME_BUF_SIZE*8) + bit = bit-(FRAME_BUF_SIZE*8); adr = gd->fb_base+(bit/32)*4+(3-(bit%32)/8); 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<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; @@ -263,8 +258,8 @@ void create_vfd_table(void) * wrap arround if offset * (see manual S3C2400) */ - if (pixel>=frame_buf_size*8) - pixel = pixel-(frame_buf_size*8); + if (pixel>=FRAME_BUF_SIZE*8) + pixel = pixel-(FRAME_BUF_SIZE*8); adr = gd->fb_base+(pixel/32)*4+(3-(pixel%32)/8); bit_nr = pixel%8; bit_nr = (bit_nr>3)?bit_nr-4:bit_nr+4; @@ -300,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< 3) - display = 0; + if (display > 0) + display--; + else + display = 3; } } @@ -368,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; } @@ -399,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; @@ -410,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; @@ -433,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(); @@ -463,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)); + 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; - debug ("LCDSADDR1: %lX\n", rLCDSADDR1); - debug ("LCDSADDR2: %lX\n", rLCDSADDR2); - debug ("LCDSADDR3: %lX\n", rLCDSADDR3); + /* 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 */ /************************************************************************/ @@ -490,11 +551,8 @@ ulong vfd_setmem (ulong addr) { ulong size; - /* MAGIC */ - frame_buf_size = (256*4*56)/8; - /* Round up to nearest full page */ - size = (frame_buf_size + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1); + size = (FRAME_BUF_SIZE + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1); debug ("Reserving %ldk for VFD Framebuffer at: %08lx\n", size>>10, addr);