summaryrefslogtreecommitdiff
path: root/board/trab
diff options
context:
space:
mode:
authorwdenk <wdenk>2003-02-28 00:49:47 +0000
committerwdenk <wdenk>2003-02-28 00:49:47 +0000
commit6069ff265362ef6239749b5f598b137f407b821e (patch)
tree991432052f2aa7da45d8c1d51db9f80478d7e75d /board/trab
parent2a9e02ead3024f33658f1f4110834d0601dd6b2f (diff)
* Add support for 16 MB flash configuration of TRAB boardLABEL_2003_02_28_0150
* Patch by Erwin Rol, 27 Feb 2003: Add support for RTEMS * Add image information to README * Fix dual PCMCIA slot support (when running with just one slot populated) * Add VFD type detection to trab board * extend drivers/cs8900.c driver to synchronize ethaddr environment variable with value in the EEPROM * Start adding MIPS support files
Diffstat (limited to 'board/trab')
-rw-r--r--board/trab/flash.c133
-rw-r--r--board/trab/trab.c26
-rw-r--r--board/trab/vfd.c450
3 files changed, 373 insertions, 236 deletions
diff --git a/board/trab/flash.c b/board/trab/flash.c
index 2443777ae18..a4f164b469b 100644
--- a/board/trab/flash.c
+++ b/board/trab/flash.c
@@ -26,12 +26,7 @@
#include <common.h>
#include <environment.h>
-ulong myflush (void);
-
-
-#define FLASH_BANK_SIZE 0x800000 /* 8 MB */
-/* this varies depending on the sector */
-#define MAIN_SECT_SIZE 0x20000 /* 2 x 64 kB */
+static ulong flash_get_size (vu_long *addr, flash_info_t *info);
flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
@@ -43,6 +38,7 @@ flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
#define CMD_ERASE_CONFIRM 0x00300030
#define CMD_PROGRAM 0x00A000A0
#define CMD_UNLOCK_BYPASS 0x00200020
+#define CMD_READ_MANF_ID 0x00900090
#define MEM_FLASH_ADDR1 (*(volatile u32 *)(CFG_FLASH_BASE + (0x00000555 << 2)))
#define MEM_FLASH_ADDR2 (*(volatile u32 *)(CFG_FLASH_BASE + (0x000002AA << 2)))
@@ -64,27 +60,38 @@ ulong flash_init (void)
int i, j;
ulong size = 0;
- for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
+ for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
ulong flashbase = 0;
+ flash_info_t *info = &flash_info[i];
+
+ /* Init: no FLASHes known */
+ info->flash_id = FLASH_UNKNOWN;
+
+ size += flash_get_size (CFG_FLASH_BASE, info);
- flash_info[i].flash_id =
- (AMD_MANUFACT & FLASH_VENDMASK) |
- (AMD_ID_LV320B & FLASH_TYPEMASK);
- flash_info[i].size = FLASH_BANK_SIZE;
- flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
- memset (flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
if (i == 0)
- flashbase = PHYS_FLASH_1;
+ flashbase = CFG_FLASH_BASE;
else
panic ("configured too many flash banks!\n");
- for (j = 0; j < flash_info[i].sector_count; j++) {
-
- flash_info[i].start[j] = flashbase;
-
- /* the first 8 sectors are 8 kB */
- flashbase += (j < 8) ? 0x4000 : MAIN_SECT_SIZE;
+ for (j = 0; j < info->sector_count; j++) {
+
+ info->protect[j] = 0;
+ info->start[j] = flashbase;
+
+ switch (info->flash_id & FLASH_TYPEMASK) {
+ case (FLASH_AM320B & FLASH_TYPEMASK):
+ /* Boot sector type: 8 x 8 + N x 128 kB */
+ flashbase += (j < 8) ? 0x4000 : 0x20000;
+ break;
+ case (FLASH_AM640U & FLASH_TYPEMASK):
+ /* Uniform sector type: 128 kB */
+ flashbase += 0x20000;
+ break;
+ default:
+ printf ("## Bad flash chip type 0x%04lX\n",
+ info->flash_id & FLASH_TYPEMASK);
+ }
}
- size += flash_info[i].size;
}
/*
@@ -116,7 +123,7 @@ void flash_print_info (flash_info_t * info)
int i;
switch (info->flash_id & FLASH_VENDMASK) {
- case (AMD_MANUFACT & FLASH_VENDMASK):
+ case (FLASH_MAN_AMD & FLASH_VENDMASK):
printf ("AMD: ");
break;
default:
@@ -125,9 +132,12 @@ void flash_print_info (flash_info_t * info)
}
switch (info->flash_id & FLASH_TYPEMASK) {
- case (AMD_ID_LV320B & FLASH_TYPEMASK):
+ case (FLASH_AM320B & FLASH_TYPEMASK):
printf ("2x Am29LV320DB (32Mbit)\n");
break;
+ case (FLASH_AM640U & FLASH_TYPEMASK):
+ printf ("2x Am29LV640D (64Mbit)\n");
+ break;
default:
printf ("Unknown Chip Type\n");
goto Done;
@@ -177,7 +187,7 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
}
if ((info->flash_id & FLASH_VENDMASK) !=
- (AMD_MANUFACT & FLASH_VENDMASK)) {
+ (FLASH_MAN_AMD & FLASH_VENDMASK)) {
return ERR_UNKNOWN_FLASH_VENDOR;
}
@@ -265,13 +275,6 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
rc = ERR_TIMOUT;
goto outahere;
}
-
-#if 0
- printf ("ok.\n");
- } else { /* it was protected */
-
- printf ("protected!\n");
-#endif
}
}
@@ -453,3 +456,71 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
return write_word (info, wp, data);
}
+
+/*-----------------------------------------------------------------------
+ */
+
+static ulong flash_get_size (vu_long *addr, flash_info_t *info)
+{
+ ulong value;
+
+ /* Write auto select command sequence and read Manufacturer ID */
+ addr[0x0555] = CMD_UNLOCK1;
+ addr[0x02AA] = CMD_UNLOCK2;
+ addr[0x0555] = CMD_READ_MANF_ID;
+
+ value = addr[0];
+
+ debug ("Manuf. ID @ 0x%08lx: 0x%08lx\n", (ulong)addr, value);
+
+ switch (value) {
+ case AMD_MANUFACT:
+ info->flash_id = FLASH_MAN_AMD;
+ break;
+
+ default:
+ info->flash_id = FLASH_UNKNOWN;
+ info->sector_count = 0;
+ info->size = 0;
+ addr[0] = 0x00FF00FF; /* restore read mode */
+ debug ("## flash_init: unknown manufacturer\n");
+ return (0); /* no or unknown flash */
+ }
+
+ value = addr[1]; /* device ID */
+
+ debug ("Device ID @ 0x%08lx: 0x%08lx\n", (ulong)(&addr[1]), value);
+
+ switch (value) {
+ case AMD_ID_LV320B:
+ info->flash_id += FLASH_AM320B;
+ info->sector_count = 71;
+ info->size = 0x00800000;
+
+ addr[0] = 0x00FF00FF; /* restore read mode */
+ break; /* => 8 MB */
+
+ case AMD_ID_LV640U:
+ info->flash_id += FLASH_AM640U;
+ info->sector_count = 128;
+ info->size = 0x01000000;
+
+ addr[0] = 0x00F000F0; /* restore read mode */
+ break; /* => 16 MB */
+
+ default:
+ debug ("## flash_init: unknown flash chip\n");
+ info->flash_id = FLASH_UNKNOWN;
+ addr[0] = 0x00FF00FF; /* restore read mode */
+ return (0); /* => no or unknown flash */
+
+ }
+
+ if (info->sector_count > CFG_MAX_FLASH_SECT) {
+ printf ("** ERROR: sector count %d > max (%d) **\n",
+ info->sector_count, CFG_MAX_FLASH_SECT);
+ info->sector_count = CFG_MAX_FLASH_SECT;
+ }
+
+ return (info->size);
+}
diff --git a/board/trab/trab.c b/board/trab/trab.c
index 32f27efaeb9..111c861410b 100644
--- a/board/trab/trab.c
+++ b/board/trab/trab.c
@@ -60,11 +60,8 @@ static void udelay_no_timer (int usec)
int board_init ()
{
-#if defined(CONFIG_MODEM_SUPPORT) && defined(CONFIG_VFD)
- ulong size;
- unsigned long addr;
- extern void mem_malloc_init (ulong);
- extern int drv_vfd_init(void);
+#if defined(CONFIG_VFD)
+ extern int vfd_init_clocks(void);
#endif
DECLARE_GLOBAL_DATA_PTR;
@@ -107,26 +104,11 @@ int board_init ()
/* adress of boot parameters */
gd->bd->bi_boot_params = 0x0c000100;
-#ifdef CONFIG_MODEM_SUPPORT
#ifdef CONFIG_VFD
-#ifndef PAGE_SIZE
-#define PAGE_SIZE 4096
-#endif
- /*
- * reserve memory for VFD display (always full pages)
- */
- /* armboot_real_end is defined in the board-specific linker script */
- addr = (_armboot_real_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
- size = vfd_setmem (addr);
- gd->fb_base = addr;
- /* round to the next page boundary */
- addr += size;
- addr = (addr + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
- mem_malloc_init (addr);
- /* must do this after the framebuffer is allocated */
- drv_vfd_init();
+ vfd_init_clocks();
#endif /* CONFIG_VFD */
+#ifdef CONFIG_MODEM_SUPPORT
udelay_no_timer (KBD_MDELAY);
if (key_pressed()) {
diff --git a/board/trab/vfd.c b/board/trab/vfd.c
index 234a9d4c027..fa1194ca7fb 100644
--- a/board/trab/vfd.c
+++ b/board/trab/vfd.c
@@ -55,12 +55,16 @@
#define BLAU 0x0C
#define VIOLETT 0X0D
-ulong vfdbase;
-ulong frame_buf_size;
+ulong vfdbase;
+ulong frame_buf_size;
#define frame_buf_offs 4
+/* Supported VFD Types */
+#define VFD_TYPE_T119C 1 /* Noritake T119C VFD */
+#define VFD_TYPE_MN11236 2
+
/* taken from armboot/common/vfd.c */
-ulong adr_vfd_table[112][18][2][4][2];
+unsigned long adr_vfd_table[112][18][2][4][2];
unsigned char bit_vfd_table[112][18][2][4][2];
/*
@@ -68,26 +72,42 @@ unsigned char bit_vfd_table[112][18][2][4][2];
*/
void init_grid_ctrl(void)
{
+ DECLARE_GLOBAL_DATA_PTR;
ulong adr, grid_cycle;
unsigned int bit, display;
unsigned char temp, bit_nr;
+ ulong val;
- for (adr=vfdbase; adr<=(vfdbase+7168); adr+=4) /*clear frame buffer */
- (*(volatile ulong*)(adr))=0;
+ /*
+ * clear frame buffer (logical clear => set to "black")
+ */
+ if (gd->vfd_inv_data == 0)
+ val = 0;
+ else
+ val = ~0;
- for(display=0;display<=3;display++)
- {
- for(grid_cycle=0;grid_cycle<=55;grid_cycle++)
- {
- bit = grid_cycle*256*4+(grid_cycle+200)*4+frame_buf_offs+display;
+ for (adr = vfdbase; adr <= (vfdbase+7168); adr += 4) {
+ (*(volatile ulong*)(adr)) = val;
+ }
+
+ switch (gd->vfd_type) {
+ case VFD_TYPE_T119C:
+ for (display=0; display<4; display++) {
+ for(grid_cycle=0; grid_cycle<56; grid_cycle++) {
+ bit = grid_cycle * 256 * 4 +
+ (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);
- adr = vfdbase+(bit/32)*4+(3-(bit%32)/8);
- bit_nr = bit%8;
- bit_nr = (bit_nr>3)?bit_nr-4:bit_nr+4;
+ bit = bit - (frame_buf_size * 8);
+ adr = vfdbase + (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));
- temp|=(1<<bit_nr);
+ if (gd->vfd_inv_data)
+ temp &= ~(1<<bit_nr);
+ else
+ temp |= (1<<bit_nr);
(*(volatile unsigned char*)(adr))=temp;
if(grid_cycle<55)
@@ -101,9 +121,54 @@ 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));
- temp|=(1<<bit_nr);
+ if (gd->vfd_inv_data)
+ temp &= ~(1<<bit_nr);
+ else
+ temp |= (1<<bit_nr);
+ (*(volatile unsigned char*)(adr))=temp;
+ }
+ }
+ break;
+ case VFD_TYPE_MN11236:
+ for (display=0; display<4; display++) {
+ for (grid_cycle=0; grid_cycle<38; grid_cycle++) {
+ bit = grid_cycle * 256 * 4 +
+ (253 - grid_cycle) * 4 +
+ frame_buf_offs + display;
+ /* wrap arround if offset (see manual S3C2400) */
+ if (bit>=frame_buf_size*8)
+ bit = bit - (frame_buf_size * 8);
+ adr = vfdbase + (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<<bit_nr);
+ else
+ temp |= (1<<bit_nr);
+ (*(volatile unsigned char*)(adr))=temp;
+
+ if(grid_cycle<37)
+ bit = grid_cycle*256*4+(252-grid_cycle)*4+frame_buf_offs+display;
+
+ /* wrap arround if offset (see manual S3C2400) */
+ if (bit>=frame_buf_size*8)
+ bit = bit-(frame_buf_size*8);
+ adr = vfdbase+(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<<bit_nr);
+ else
+ temp |= (1<<bit_nr);
(*(volatile unsigned char*)(adr))=temp;
}
+ }
+ break;
+ default:
+ printf ("Warning: unknown display type\n");
+ break;
}
}
@@ -113,175 +178,142 @@ void init_grid_ctrl(void)
*/
void create_vfd_table(void)
{
- unsigned int vfd_table[112][18][2][4][2];
- ulong adr;
- unsigned int x, y, color, display, entry, pixel, bit_nr;
-
- /*
- * Create translation table for Noritake-T119C-VFD-specific
- * organized frame-buffer.
- * Created is the number of the bit in the framebuffer (the
- * first transferred pixel of each frame is bit 0).
- */
- for(y=0;y<=17;y++) /* Zeile */
- {
- for(x=0;x<=111;x++) /* Spalten */
- {
- /*Display 0 blaue Pixel Eintrag 1 */
- vfd_table[x][y][0][0][0]=((x%4)*4+y*16+(x/4)*2048);
- /*Display 0 rote Pixel Eintrag 1 */
- vfd_table[x][y][1][0][0]=((x%4)*4+y*16+(x/4)*2048+512);
- if(x<=1)
- {
- /*Display 0 blaue Pixel Eintrag 2 */
- vfd_table[x][y][0][0][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+1024);
- /*Display 0 rote Pixel Eintrag 2 */
- vfd_table[x][y][1][0][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+512+1024);
- }
- else
- {
- /*Display 0 blaue Pixel Eintrag 2 */
- vfd_table[x][y][0][0][1]=((x%4)*4+y*16+((x-2)/4)*2048+1024);
- /*Display 0 rote Pixel Eintrag 2 */
- vfd_table[x][y][1][0][1]=((x%4)*4+y*16+((x-2)/4)*2048+512+1024);
- }
- /*Display 1 blaue Pixel Eintrag 1 */
- vfd_table[x][y][0][1][0]=((x%4)*4+y*16+(x/4)*2048+1);
- /*Display 1 rote Pixel Eintrag 1 */
- vfd_table[x][y][1][1][0]=((x%4)*4+y*16+(x/4)*2048+512+1);
- if(x<=1)
- {
- /*Display 1 blaue Pixel Eintrag 2 */
- vfd_table[x][y][0][1][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+1+1024);
- /*Display 1 rote Pixel Eintrag 2 */
- vfd_table[x][y][1][1][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+512+1+1024);
- }
- else
- {
- /*Display 1 blaue Pixel Eintrag 2 */
- vfd_table[x][y][0][1][1]=((x%4)*4+y*16+((x-2)/4)*2048+1+1024);
- /*Display 1 rote Pixel Eintrag 2 */
- vfd_table[x][y][1][1][1]=((x%4)*4+y*16+((x-2)/4)*2048+512+1+1024);
- }
- /*Display 2 blaue Pixel Eintrag 1 */
- vfd_table[x][y][0][2][0]=((x%4)*4+y*16+(x/4)*2048+2);
- /*Display 2 rote Pixel Eintrag 1 */
- vfd_table[x][y][1][2][0]=((x%4)*4+y*16+(x/4)*2048+512+2);
- if(x<=1)
- {
- /*Display 2 blaue Pixel Eintrag 2 */
- vfd_table[x][y][0][2][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+2+1024);
- /*Display 2 rote Pixel Eintrag 2 */
- vfd_table[x][y][1][2][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+512+2+1024);
- }
- else
- {
- /*Display 2 blaue Pixel Eintrag 2 */
- vfd_table[x][y][0][2][1]=((x%4)*4+y*16+((x-2)/4)*2048+2+1024);
- /*Display 2 rote Pixel Eintrag 2 */
- vfd_table[x][y][1][2][1]=((x%4)*4+y*16+((x-2)/4)*2048+512+2+1024);
- }
- /*Display 3 blaue Pixel Eintrag 1 */
- vfd_table[x][y][0][3][0]=((x%4)*4+y*16+(x/4)*2048+3);
- /*Display 3 rote Pixel Eintrag 1 */
- vfd_table[x][y][1][3][0]=((x%4)*4+y*16+(x/4)*2048+512+3);
- if(x<=1)
- {
- /*Display 3 blaue Pixel Eintrag 2 */
- vfd_table[x][y][0][3][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+3+1024);
- /*Display 3 rote Pixel Eintrag 2 */
- vfd_table[x][y][1][3][1]=(((x+112)%4)*4+y*16+((x+110)/4)*2048+512+3+1024);
- }
- else
- {
- /*Display 3 blaue Pixel Eintrag 2 */
- vfd_table[x][y][0][3][1]=((x%4)*4+y*16+((x-2)/4)*2048+3+1024);
- /*Display 3 rote Pixel Eintrag 2 */
- vfd_table[x][y][1][3][1]=((x%4)*4+y*16+((x-2)/4)*2048+512+3+1024);
- }
+ DECLARE_GLOBAL_DATA_PTR;
+ unsigned long vfd_table[112][18][2][4][2];
+ unsigned int x, y, color, display, entry, pixel;
+ unsigned int x_abcdef = 0;
+
+ switch (gd->vfd_type) {
+ case VFD_TYPE_T119C:
+ for(y=0; y<=17; y++) { /* Line */
+ for(x=0; x<=111; x++) { /* Column */
+ for(display=0; display <=3; display++) {
+
+ /* Display 0 blue pixels */
+ vfd_table[x][y][0][display][0] =
+ (x==0) ? y*16+display
+ : (x%4)*4+y*16+((x-1)/2)*1024+display;
+ /* Display 0 red pixels */
+ vfd_table[x][y][1][display][0] =
+ (x==0) ? y*16+512+display
+ : (x%4)*4+y*16+((x-1)/2)*1024+512+display;
+ }
+ }
+ }
+ break;
+ case VFD_TYPE_MN11236:
+ for(y=0; y<=17; y++) { /* Line */
+ for(x=0; x<=111; x++) { /* Column */
+ for(display=0; display <=3; display++) {
+
+ vfd_table[x][y][0][display][0]=0;
+ vfd_table[x][y][0][display][1]=0;
+ vfd_table[x][y][1][display][0]=0;
+ vfd_table[x][y][1][display][1]=0;
+
+ switch (x%6) {
+ case 0: x_abcdef=0; break; /* a -> a */
+ case 1: x_abcdef=2; break; /* b -> c */
+ case 2: x_abcdef=4; break; /* c -> e */
+ case 3: x_abcdef=5; break; /* d -> f */
+ case 4: x_abcdef=3; break; /* e -> d */
+ case 5: x_abcdef=1; break; /* f -> b */
+ }
+
+ /* blue pixels */
+ vfd_table[x][y][0][display][0] =
+ (x>1) ? x_abcdef*4+((x-1)/3)*1024+y*48+display
+ : x_abcdef*4+ 0+y*48+display;
+ /* blue pixels */
+ if (x>1 && (x-1)%3)
+ vfd_table[x][y][0][display][1] = x_abcdef*4+((x-1)/3+1)*1024+y*48+display;
+
+ /* red pixels */
+ vfd_table[x][y][1][display][0] =
+ (x>1) ? x_abcdef*4+24+((x-1)/3)*1024+y*48+display
+ : x_abcdef*4+24+ 0+y*48+display;
+ /* red pixels */
+ if (x>1 && (x-1)%3)
+ vfd_table[x][y][1][display][1] = x_abcdef*4+24+((x-1)/3+1)*1024+y*48+display;
+ }
}
+ }
+ break;
+ default:
+ /* do nothing */
+ return;
}
/*
- * Create translation table for Noritake-T119C-VFD-specific
- * organized frame-buffer
* Create table with entries for physical byte adresses and
* bit-number within the byte
* from table with bit-numbers within the total framebuffer
*/
- for(y=0;y<=17;y++)
- {
- for(x=0;x<=111;x++)
- {
- for(color=0;color<=1;color++)
- {
- for(display=0;display<=3;display++)
- {
- for(entry=0;entry<=1;entry++)
- {
- pixel = vfd_table[x][y][color][display][entry] + frame_buf_offs;
- /*
- * wrap arround if offset
- * (see manual S3C2400)
- */
- if (pixel>=frame_buf_size*8)
- pixel = pixel-(frame_buf_size*8);
- adr = vfdbase+(pixel/32)*4+(3-(pixel%32)/8);
- bit_nr = pixel%8;
- bit_nr = (bit_nr>3)?bit_nr-4:bit_nr+4;
- adr_vfd_table[x][y][color][display][entry] = adr;
- bit_vfd_table[x][y][color][display][entry] = bit_nr;
- }
- }
+ for(y=0;y<18;y++) {
+ for(x=0;x<112;x++) {
+ for(color=0;color<2;color++) {
+ for(display=0;display<4;display++) {
+ for(entry=0;entry<2;entry++) {
+ unsigned long adr = vfdbase;
+ unsigned int bit_nr = 0;
+
+ if (vfd_table[x][y][color][display][entry]) {
+
+ pixel = vfd_table[x][y][color][display][entry] + frame_buf_offs;
+ /*
+ * wrap arround if offset
+ * (see manual S3C2400)
+ */
+ if (pixel>=frame_buf_size*8)
+ pixel = pixel-(frame_buf_size*8);
+ adr = vfdbase+(pixel/32)*4+(3-(pixel%32)/8);
+ bit_nr = pixel%8;
+ bit_nr = (bit_nr>3)?bit_nr-4:bit_nr+4;
+ }
+ adr_vfd_table[x][y][color][display][entry] = adr;
+ bit_vfd_table[x][y][color][display][entry] = bit_nr;
}
+ }
}
+ }
}
}
/*
* Set/clear pixel of the VFDs
*/
-void set_vfd_pixel(unsigned char x, unsigned char y, unsigned char color, unsigned char display, unsigned char value)
+void set_vfd_pixel(unsigned char x, unsigned char y,
+ unsigned char color, unsigned char display,
+ unsigned char value)
{
+ DECLARE_GLOBAL_DATA_PTR;
ulong adr;
unsigned char bit_nr, temp;
- if (value!=0)
- {
- /* Pixel-Eintrag Nr. 1 */
- adr = adr_vfd_table[x][y][color][display][0];
- /* Pixel-Eintrag Nr. 1 */
- bit_nr = bit_vfd_table[x][y][color][display][0];
- temp=(*(volatile unsigned char*)(adr));
- temp|=1<<bit_nr;
- (*(volatile unsigned char*)(adr))=temp;
-
- /* Pixel-Eintrag Nr. 2 */
- adr = adr_vfd_table[x][y][color][display][1];
- /* Pixel-Eintrag Nr. 2 */
- bit_nr = bit_vfd_table[x][y][color][display][1];
- temp=(*(volatile unsigned char*)(adr));
- temp|=1<<bit_nr;
- (*(volatile unsigned char*)(adr))=temp;
+ if (! gd->vfd_type) {
+ /* Unknown type. */
+ return;
}
- else
- {
- /* Pixel-Eintrag Nr. 1 */
- adr = adr_vfd_table[x][y][color][display][0];
- /* Pixel-Eintrag Nr. 1 */
- bit_nr = bit_vfd_table[x][y][color][display][0];
- temp=(*(volatile unsigned char*)(adr));
- temp&=~(1<<bit_nr);
- (*(volatile unsigned char*)(adr))=temp;
-
- /* Pixel-Eintrag Nr. 2 */
- adr = adr_vfd_table[x][y][color][display][1];
- /* Pixel-Eintrag Nr. 2 */
- bit_nr = bit_vfd_table[x][y][color][display][1];
- temp=(*(volatile unsigned char*)(adr));
- temp&=~(1<<bit_nr);
- (*(volatile unsigned char*)(adr))=temp;
+
+ /* Pixel-Eintrag Nr. 1 */
+ adr = adr_vfd_table[x][y][color][display][0];
+ /* Pixel-Eintrag Nr. 1 */
+ 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);
}
+
+ (*(volatile unsigned char*)(adr))=temp;
}
/*
@@ -334,12 +366,36 @@ 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)
+{
+ /* Port-Pins als LCD-Ausgang */
+ rPCCON = (rPCCON & 0xFFFFFF00)| 0x000000AA;
+ /* Port-Pins als LCD-Ausgang */
+ rPDCON = (rPDCON & 0xFFFFFF03)| 0x000000A8;
+#ifdef WITH_VFRAME
+ /* mit VFRAME zum Messen */
+ rPDCON = (rPDCON & 0xFFFFFF00)| 0x000000AA;
+#endif
+
+ rLCDCON2 = 0x000DC000;
+ rLCDCON3 = 0x0051000A;
+ rLCDCON4 = 0x00000001;
+ rLCDCON5 = 0x00000440;
+ rLCDCON1 = 0x00000B75;
+}
+
+/*
* initialize LCD-Controller of the S3C2400 for using VFDs
*/
int drv_vfd_init(void)
{
+ char *tmp;
ulong palette;
static int vfd_init_done = 0;
+ int vfd_id;
DECLARE_GLOBAL_DATA_PTR;
@@ -347,10 +403,58 @@ 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 | 0x000F); /* activate GPC0...GPC3 pullups */
+ rPCCON = (rPCCON & 0xFFFFFF00); /* configure GPC0...GPC3 as inputs */
+
+ vfd_id = (~rPCDAT) & 0x000F; /* read GPC0...GPC3 port pins */
+ debug("Detecting Revison of WA4-VFD: ID=0x%X\n", vfd_id);
+
+ switch (vfd_id) {
+ case 0: /* board revision <= Rev.100 */
+/*-----*/
+ gd->vfd_inv_data = 0;
+ if (0)
+ gd->vfd_type = VFD_TYPE_MN11236;
+ else
+ gd->vfd_type = VFD_TYPE_T119C;
+/*-----*/
+ if ((tmp = getenv ("vfd_type")) == NULL) {
+ break;
+ }
+ if (strcmp(tmp, "T119C") == 0) {
+ gd->vfd_type = VFD_TYPE_T119C;
+ } else if (strcmp(tmp, "MN11236") == 0) {
+ gd->vfd_type = VFD_TYPE_MN11236;
+ } else {
+ /* 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;
+ 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" : "");
+
vfdbase = gd->fb_base;
create_vfd_table();
init_grid_ctrl();
+ for (palette=0; palette < 16; palette++)
+ (*(volatile unsigned int*)(PALETTE+(palette*4)))=palette;
+ for (palette=16; palette < 256; palette++)
+ (*(volatile unsigned int*)(PALETTE+(palette*4)))=0x00;
+
/*
* Hinweis: Der Framebuffer ist um genau ein Nibble verschoben
* Das erste angezeigte Pixel wird aus dem zweiten Nibble geholt
@@ -364,30 +468,10 @@ int drv_vfd_init(void)
rLCDSADDR2 = (vfdbase + frame_buf_size) >> 1;
rLCDSADDR3 = ((256/4));
- /* Port-Pins als LCD-Ausgang */
- rPCCON = (rPCCON & 0xFFFFFF00)| 0x000000AA;
- /* Port-Pins als LCD-Ausgang */
- rPDCON = (rPDCON & 0xFFFFFF03)| 0x000000A8;
-#ifdef WITH_VFRAME
- /* mit VFRAME zum Messen */
- rPDCON = (rPDCON & 0xFFFFFF00)| 0x000000AA;
-#endif
-
- rLCDCON2 = 0x000DC000;
- rLCDCON3 = 0x0051000A;
- rLCDCON4 = 0x00000001;
- rLCDCON5 = 0x00000440;
- rLCDCON1 = 0x00000B75;
-
debug ("LCDSADDR1: %lX\n", rLCDSADDR1);
debug ("LCDSADDR2: %lX\n", rLCDSADDR2);
debug ("LCDSADDR3: %lX\n", rLCDSADDR3);
- for(palette=0;palette<=15;palette++)
- (*(volatile unsigned int*)(PALETTE+(palette*4)))=palette;
- for(palette=16;palette<=255;palette++)
- (*(volatile unsigned int*)(PALETTE+(palette*4)))=0x00;
-
return 0;
}