I finally got the epia 800 (vt8601 chipset) direct register vga working. The diff is short, so I attached it.
A few issues remain. For some reason or other, a warm reset (reboot from Linux) leaves the VGA is a scrambled state. But a hardware reset or cold start is fine. I could not get the current ide to work, so I backed up to the following revisions on ide:
$Id: ide.c,v 1.5 2002/11/11 21:30:45 pyro9 Exp $
$Id: ide.h,v 1.3 2002/12/16 17:57:45 rminnich Exp $
(since my config loads from hda1). It sure appears to me that the repository code for ide is broken, but I did not have time to pin it down.
The main issues preventing the vga from being done much sooner are basically a bunch of extended registers that Via uses, that do not initialize to a useable condition on power-on. Takes a while to find which ones, there are hundreds.
I would not want to do this without a datasheet, so I don't have much hope for the CLE266 unless the VGA is identical or we get a datasheet for it.
-Steve
diff --exclude-from exclude_epia --recursive --unified -P freebios/src/mainboard/via/epia/Config freebios_epia_works/src/mainboard/via/epia/Config --- freebios/src/mainboard/via/epia/Config Sun Sep 7 18:22:01 2003 +++ freebios_epia_works/src/mainboard/via/epia/Config Sun Sep 7 17:24:15 2003 @@ -6,6 +6,7 @@ mainboardinit cpu/i386/reset16.inc ldscript cpu/i386/reset16.lds
+option VGA_HARDWARE_FIXUP=1 mainboardinit superio/via/vt8231/setup_ethernet.inc mainboardinit superio/via/vt8231/setup_serial.inc mainboardinit pc80/serial.inc diff --exclude-from exclude_epia --recursive --unified -P freebios/src/mainboard/via/epia/mainboard.c freebios_epia_works/src/mainboard/via/epia/mainboard.c --- freebios/src/mainboard/via/epia/mainboard.c Sun Sep 7 18:22:01 2003 +++ freebios_epia_works/src/mainboard/via/epia/mainboard.c Sun Sep 7 18:34:15 2003 @@ -2,9 +2,18 @@ #include <pci.h> #include <pci_ids.h> #include <cpu/p5/io.h> +#include <pc80/vga.h>
#include <types.h>
+void northbridge_fixup(); +void southbridge_fixup(); +void video_init(); +void nvram_on(); +void keyboard_on(); +void pci_assign_irqs(unsigned bus, unsigned slot, const unsigned char pIntAtoD[4]); + + static const unsigned char southbridgeIrqs[4] = { 11, 5, 10, 12 }; static const unsigned char enetIrqs[4] = { 11, 5, 10, 12 }; static const unsigned char slotIrqs[4] = { 5, 10, 12, 11 }; @@ -65,6 +74,15 @@
nvram_on(); keyboard_on(); + southbridge_fixup(); + +#ifdef VIDEO_CONSOLE + vga_hardware_fixup(); + // this has to be done here due to pci not always being up + // earlier and pci resources are not ready + video_init(); +#endif + pci_routing_fixup(); }
diff --exclude-from exclude_epia --recursive --unified -P freebios/src/northbridge/via/vt8601/Config freebios_epia_works/src/northbridge/via/vt8601/Config --- freebios/src/northbridge/via/vt8601/Config Sun Sep 7 18:22:01 2003 +++ freebios_epia_works/src/northbridge/via/vt8601/Config Fri Sep 5 10:27:10 2003 @@ -1 +1,2 @@ object northbridge.o +object via_vga.o VIDEO_CONSOLE diff --exclude-from exclude_epia --recursive --unified -P freebios/src/northbridge/via/vt8601/vgainit.inc freebios_epia_works/src/northbridge/via/vt8601/vgainit.inc --- freebios/src/northbridge/via/vt8601/vgainit.inc Sun Sep 7 18:29:59 2003 +++ freebios_epia_works/src/northbridge/via/vt8601/vgainit.inc Sun Sep 7 18:40:42 2003 @@ -21,3 +21,32 @@
#endif
+#if VIDEO_CONSOLE + +/* + * by Steve M. Gehlbach, Ph.D. + * steve @ kesa . com + * + * 9/7/03 smg + * minor chipset settings for vga + * more work needed for init, since reboot + * from linux has problems (hdwr reset okay) + * + */ + // set shadow ram to award settings + + CS_WRITE($0x61, $0x2a) + CS_WRITE($0x62, $0x00) + CS_WRITE($0x63, $0x20) + + // turn off GA + + CS_WRITE($0x88,$0x00) + + // enable vga, fb + + CS_WRITE($0xF9,$0x42) + CS_WRITE($0xFB,$0xb0) + +#endif + diff --exclude-from exclude_epia --recursive --unified -P freebios/src/northbridge/via/vt8601/via_vga.c freebios_epia_works/src/northbridge/via/vt8601/via_vga.c --- freebios/src/northbridge/via/vt8601/via_vga.c Wed Dec 31 16:00:00 1969 +++ freebios_epia_works/src/northbridge/via/vt8601/via_vga.c Sun Sep 7 16:11:37 2003 @@ -0,0 +1,168 @@ +/* + * + * By + * Steve M. Gehlbach <steve @ kesa . com> + * + * vga initialization specific for + * via vt8601 chipset + * + * The font load code follows technique used + * in the tiara project, which came from + * the Universal Talkware Boot Loader, + * http://www.talkware.net. + */ + +#include <video_subr.h> +#include <subr.h> +#include <string.h> +#include <pc80/vga.h> +#include <cpu/p5/io.h> +#include <subr.h> +#include <printk.h> + +#define VGA_FONT_BASE 0xa0000; +#define VGA_GRAFIX_BASE 0xa0000; +#define CHAR_HEIGHT 16 + +// splash_done is a global to avoid putting up splash screen twice. +// Kind of a hack, but the problem is that the vga pci resources +// are sometimes ready early, sort of, and the initial call to +// vga_hardware_fixup puts up the splash screen; then a later call +// to it from hardware_main does it again; but this does not always +// happen, sometimes it fails the first call. It is either a timing or initialization +// problem that needs to be tracked down and fixed. Note that both calls (fixup) are necessary +// since some vga boards are not ready early, but some are, and of course, the epia is sometimes ready +// and sometimes not ready. +// +int splash_done = 0; + +extern unsigned char fontdata_8x16[]; +extern void beep (int msec); +extern void udelay (int usec); + +// The screeninfo structure is in pc80/vga_load_regs.c and has the vga +// parameters for screen size etc. +// This is _not_ the struct used in the zero_page +// for linux init. It is only used for vga init. +extern struct screeninfo vga_settings; + +// prototypes +int vga_decode_var(struct screeninfo *var, struct vga_par *par); +int vga_set_regs(struct vga_par *par); + + +void vga_set_amode(void); +void vga_set_gmode(void); +void delay(int secs); +void mdelay(int msecs); +void vga_font_load(unsigned char *vidmem, unsigned char *font, int height, int num_chars); +int vga_load_pcx( char * pcx_file, int pcx_file_length); + +void vt8601_video_init(void) { + int res; + u8 byte; + struct vga_par vga_params; + + + // convert the general vga parameters in screeninfo structure + // to actual vga register settings + + res = vga_decode_var(&vga_settings, &vga_params); + if ( res < 0 ) { post_code (0xFD); } //no error return for now + + // enable vga system + outb(0x01, 0x3c3); // enable VGA + + // write the registers + res = vga_set_regs( &vga_params ); + if ( res < 0 ) { post_code(0xFE); } //no error return for now + byte = inb(MIS_R); // get 3c2 value by reading 3cc + outb(byte & ~0xc,MIS_W); // clear last bits to set 25Mhz clock + + // enable epia extended regs + write_seq(0x92,0x11); + + // setup the video clocks + // -follows award settings + // not all of these are necessary + write_seq(0xbd,0x18); + write_seq(0xcc,0x19); + write_seq(0xff,0x1a); + write_seq(0xff,0x1b); + write_seq(0x46,0x1c); + write_seq(0xbf,0x1d); + write_seq(0xff,0x1e); + write_seq(0xcc,0x1f); + write_seq(0x04,0x20); + write_seq(0x4f,0x24); + + // setup extended crtc regs + // -follows award settings + // not all of these are necessary + write_crtc(0x64,0x1f); + write_crtc(0x20,0x20); + write_crtc(0x0,0x21); + write_crtc(0x7,0x25); + write_crtc(0x4,0x29); + write_crtc(0x1f,0x2a); + write_crtc(0x0,0x2b); + write_crtc(0xdf,0x2f); + write_crtc(0x10,0x38); + + +} + +#ifdef VGA_HARDWARE_FIXUP +void vga_hardware_fixup(void) { + u8 *font_mem, *vga_mem, *pcx_file; + int *file_size; + +#ifdef PCX_FILE_LOCATION + pcx_file = (u8 *) PCX_FILE_LOCATION; +#else + pcx_file = (u8 *) 0xfffe0000; +#endif + file_size = (int *) pcx_file; + + vga_mem = (u8 *) VGA_GRAFIX_BASE; + font_mem = (u8 *) VGA_FONT_BASE; + + outb(0x01, 0x3b8); // enable VGA + outb(0x01, 0x3c3); // enable VGA + outb(0x08, 0x46e8); // enable VGA (does not appear to be used) + + if (inb(0x3c3) != 1) { + printk_info("VGA not ready yet.\n"); + return; + } + printk_info("Initializing vt8601 vga..."); + post_code(0xa0); + + vt8601_video_init(); + + printk_info("done.\n"); + +#ifdef VIDEO_SHOW_LOGO + if (!splash_done) { + printk_debug("Setting graphics mode...\n"); + vga_set_gmode(); // set graphics mode + + // + // the pcx_file is in flash at an address set + // in the config file with PCX_FILE_LOCATION + // the length of the file is at offset 0, file starts at 4 + // + + printk_debug("pcx file at %x length %d\n",&pcx_file[4], *file_size); + vga_load_pcx( &pcx_file[4], *file_size); + delay(VIDEO_SHOW_LOGO); + +#endif + vga_set_amode(); + vga_font_load(font_mem,fontdata_8x16,CHAR_HEIGHT,256); + splash_done++; // mark done + printk_debug("alpha mode set.\n"); + post_code(0xa1); + } +} +#endif diff --exclude-from exclude_epia --recursive --unified -P freebios/util/config/epia800.config freebios_epia_works/util/config/epia800.config --- freebios/util/config/epia800.config Wed Dec 31 16:00:00 1969 +++ freebios_epia_works/util/config/epia800.config Sun Sep 7 16:48:42 2003 @@ -0,0 +1,63 @@ +# +# LinuxBIOS config file for: VIA epia mini-itx +# + +target /usr/src/epia + +# via epia +mainboard via/epia +biosbase 0xffff0000 + +# setup delay using TSC +option CONFIG_UDELAY_TSC=1 + +# Enable Serial Console for debugging +option CONFIG_COMPRESS=0 +option SERIAL_CONSOLE=1 +option VIDEO_CONSOLE=1 +option TTYS0_BAUD=115200 + +# For printk_debug, set level to 8 +# for printk_info, set level to 7 +#option DEFAULT_CONSOLE_LOGLEVEL=8 +#option DEFAULT_CONSOLE_LOGLEVEL=7 +option DEFAULT_CONSOLE_LOGLEVEL=6 + +#option DEBUG=1 + +option BOOT_IDE=1 +option IDE_BOOT_DRIVE=0 +#need to know size of partition table for ide +#option ONE_TRACK=32 +option ONE_TRACK=63 + + +# the logo is displayed for VIDEO_SHOW_LOGO seconds. +# Need to have to have a 128k rom since the logo image is at the +# beginning (0xfffe0000) +option VIDEO_SHOW_LOGO=10 +option ROM_IMAGE_SIZE=131072 +option PCX_FILE_LOCATION=0xfffe0000 + + +# Use 256KB Standard Flash as Normal BIOS +option RAMTEST=1 + +linux /usr/src/linux +commandline root=/dev/hda2 ro console=ttyS0,115200n8 console=tty1 + +# +# these actions put the pcx image file on the front of the bios. +# the image size is placed in the first 4 bytes then the pcx file +# important that ROM_IMAGE_SIZE be set to 128K or larger. +# The logo file is called linuxbioslogo.pcx and is by default located at +# src/pc80/linuxbioslogo.pcx. +# Change the variable LOGOFILE below if you want to use your own file. +# See the file src/pc80/vga_load_pcx.c for details on the file format. +# +option LOGOFILE=$(TOP)/src/pc80/linuxbioslogo.pcx +addaction linuxbios.rom dd if=$(LOGOFILE) of=linuxbios.rom bs=1 seek=4 conv=notrunc; +addaction linuxbios.rom perl -e '@a=stat "$(LOGOFILE)";$$a=pack("L",$$a[7]); print $$a' | dd of=linuxbios.rom bs=1 conv=notrunc + +# copy to home dir where flash programmer can reach. +addaction linuxbios.rom /bin/cp -f linuxbios.rom $(HOME)/cti/software/bios/exp/linuxbios_epia.bin