From: Nils Date: Sat, 14 Jan 2012 17:11:41 +0000 (-0500) Subject: vgabios: Make the naming in the LX code generic to Geode. X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=seabios.git;a=commitdiff_plain;h=31eabf9ba842612e7c525489ab2a6b60bba10ea0 vgabios: Make the naming in the LX code generic to Geode. Signed-off-by: Nils Jacobs --- diff --git a/Makefile b/Makefile index 8395247..79f9b54 100644 --- a/Makefile +++ b/Makefile @@ -171,7 +171,7 @@ $(OUT)bios.bin.elf $(OUT)bios.bin: $(OUT)rom.o tools/checkrom.py # VGA src files SRCVGA=src/output.c src/util.c vgasrc/vgabios.c vgasrc/vgafb.c \ vgasrc/vgatables.c vgasrc/vgafonts.c vgasrc/vbe.c \ - vgasrc/stdvga.c vgasrc/clext.c vgasrc/bochsvga.c vgasrc/geodelx.c + vgasrc/stdvga.c vgasrc/clext.c vgasrc/bochsvga.c vgasrc/geodevga.c CFLAGS16VGA = $(CFLAGS16INC) -g -Isrc diff --git a/src/Kconfig b/src/Kconfig index bd4550e..100ab92 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -341,7 +341,7 @@ menu "VGA ROM" bool "GeodeLX interface VGA BIOS" default n help - Build support for Geode vga + Build support for Geode LX vga config VGA_PCI bool "PCI ROM Headers" diff --git a/vgasrc/geodelx.c b/vgasrc/geodelx.c index 8b03444..e69de29 100644 --- a/vgasrc/geodelx.c +++ b/vgasrc/geodelx.c @@ -1,374 +0,0 @@ -// Geode LX VGA functions -// -// Copyright (C) 2009 Chris Kindt -// -// Written for Google Summer of Code 2009 for the coreboot project -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#include "geodelx.h" // geodelx_init -#include "ioport.h" // outb -#include "farptr.h" // SET_FARVAR -#include "biosvar.h" // GET_BDA -#include "vgabios.h" // VGAREG_* -#include "util.h" // memset -#include "stdvga.h" // VGAREG_VGA_CRTC_ADDRESS - - -/**************************************************************** -* MSR and High Mem access through VSA Virtual Register -****************************************************************/ - -static union u64_u32_u lx_msrRead(u32 msrAddr) -{ - union u64_u32_u val; - asm __volatile__ ( - "movw $0x0AC1C, %%dx \n" - "movl $0xFC530007, %%eax \n" - "outl %%eax, %%dx \n" - "addb $2, %%dl \n" - "inw %%dx, %%ax \n" - : "=a" (val.lo), "=d"(val.hi) - : "c"(msrAddr) - : "cc" - ); - return val; -} - -static void lx_msrWrite(u32 msrAddr,u32 andhi, u32 andlo, u32 orhi, u32 orlo) -{ - asm __volatile__ ( - "push %%eax \n" - "movw $0x0AC1C, %%dx \n" - "movl $0xFC530007, %%eax \n" - "outl %%eax, %%dx \n" - "addb $2, %%dl \n" - "pop %%eax \n" - "outw %%ax, %%dx \n" - : - : "c"(msrAddr), "S" (andhi), "D" (andlo), "b" (orhi), "a" (orlo) - : "%edx","cc" - ); -} - -static u32 lx_memRead(u32 addr) -{ - u32 val; - asm __volatile__ ( - "movw $0x0AC1C, %%dx \n" - "movl $0xFC530001, %%eax \n" - "outl %%eax, %%dx \n" - "addb $2, %%dl \n" - "inw %%dx, %%ax \n" - : "=a" (val) - : "b"(addr) - : "cc" - ); - - return val; -} - -static void lx_memWrite(u32 addr, u32 and, u32 or ) -{ - asm __volatile__ ( - "movw $0x0AC1C, %%dx \n" - "movl $0xFC530001, %%eax \n" - "outl %%eax, %%dx \n" - "addb $2, %%dl \n" - "outw %%ax, %%dx \n" - : - : "b"(addr), "S" (and), "D" (or) - : "%eax","cc" - ); -} - -static int legacyio_check(void) -{ - int ret=0; - union u64_u32_u val; - - val=lx_msrRead(MSR_GLIU0_BASE4); - if (val.lo != 0x0A0fffe0) - ret|=1; - - val=lx_msrRead(GLIU0_IOD_BM_0); - if (val.lo != 0x3c0ffff0) - ret|=2; - - val=lx_msrRead(GLIU0_IOD_BM_1); - if (val.lo != 0x3d0ffff0) - ret|=4; - - return ret; -} - -/**************************************************************** -* Extened CRTC Register functions -****************************************************************/ -static void crtce_lock(void) -{ - outb(EXTENDED_REGISTER_LOCK , VGAREG_VGA_CRTC_ADDRESS); - outb(CRTCE_LOCK, VGAREG_VGA_CRTC_DATA); -} - -static void crtce_unlock(void) -{ - outb(EXTENDED_REGISTER_LOCK , VGAREG_VGA_CRTC_ADDRESS); - outb(CRTCE_UNLOCK, VGAREG_VGA_CRTC_DATA); -} - -static u8 crtce_read(u8 reg) -{ - u8 val; - - crtce_unlock(); - outb(reg , VGAREG_VGA_CRTC_ADDRESS); - val = inb(VGAREG_VGA_CRTC_DATA); - crtce_lock(); - - return val; -} - -static void crtce_write(u8 reg, u8 val) -{ - crtce_unlock(); - outb(reg , VGAREG_VGA_CRTC_ADDRESS); - outb(val, VGAREG_VGA_CRTC_DATA); - crtce_lock(); -} - -/**************************************************************** -* Display Controller Functions -****************************************************************/ -static u32 dc_read(u16 seg, u32 reg) -{ - u32 val, *dest_far = (void*)reg; - val = GET_FARVAR(seg,*dest_far); - return val; -} - -static void dc_write(u16 seg, u32 reg, u32 val) -{ - u32 *dest_far = (void*)reg; - SET_FARVAR(seg,*dest_far,val); -} - -static void dc_set(u16 seg, u32 reg, u32 and, u32 or) -{ - u32 val = dc_read(seg,reg); - val &=and; - val |=or; - dc_write(seg,reg,val); -} - -static void dc_unlock(u16 seg) -{ - dc_write(seg,DC_UNLOCK,DC_LOCK_UNLOCK); -} - -static void dc_lock(u16 seg) -{ - dc_write(seg,DC_UNLOCK,DC_LOCK_LOCK); -} - -static u16 dc_map(u16 seg) -{ - u8 reg; - - reg = crtce_read(EXTENDED_MODE_CONTROL); - reg &= 0xf9; - switch (seg) { - case SEG_GRAPH: - reg |= 0x02; - break; - case SEG_MTEXT: - reg |= 0x04; - break; - case SEG_CTEXT: - reg |= 0x06; - break; - default: - seg=0; - break; - } - - crtce_write(EXTENDED_MODE_CONTROL,reg); - return seg; -} - -static void dc_unmap(void) -{ - dc_map(0); -} - - -/**************************************************************** -* Init Functions -****************************************************************/ - -/* Set up the dc (display controller) portion of the geodelx -* The dc provides hardware support for VGA graphics -* for features not accessible from the VGA registers, -* the dc's pci bar can be mapped to a vga memory segment -*/ -static int dc_setup(void) -{ - u32 fb, dc_fb; - u16 seg; - - dprintf(2, "DC_SETUP\n"); - - seg = dc_map(SEG_GRAPH); - dc_unlock(seg); - - /* zero memory config */ - dc_write(seg,DC_FB_ST_OFFSET,0x0); - dc_write(seg,DC_CB_ST_OFFSET,0x0); - dc_write(seg,DC_CURS_ST_OFFSET,0x0); - - /* read fb-bar from pci, then point dc to the fb base */ - dc_fb = dc_read(seg,DC_GLIU0_MEM_OFFSET); - outl(LX_PCI_FB,PORT_PCI_CMD); - fb = inl(PORT_PCI_DATA); - if (fb!=dc_fb) { - dc_write(seg,DC_GLIU0_MEM_OFFSET,fb); - } - - dc_set(seg,DC_DISPLAY_CFG,DC_CFG_MSK,DC_GDEN+DC_TRUP); - dc_set(seg,DC_GENERAL_CFG,0,DC_VGAE); - - dc_lock(seg); - dc_unmap(); - - return 0; -} - -/* Setup the vp (video processor) portion of the geodelx -* Under VGA modes the vp was handled by softvg from inside VSA2. -* Without a softvg module, access is only available through a pci bar. -* The High Mem Access virtual register is used to configure the -* pci mmio bar from 16bit friendly io space. -*/ -int vp_setup(void) -{ - u32 reg,vp; - - dprintf(2,"VP_SETUP\n"); - /* set output to crt and RGB/YUV */ - lx_msrWrite(VP_MSR_CONFIG,~0 ,~0xf8,0,0); - - /* get vp register base from pci */ - outl(LX_PCI_VP,PORT_PCI_CMD); - vp = inl(PORT_PCI_DATA); - - /* Set mmio registers - * there may be some timing issues here, the reads seem - * to slow things down enough work reliably - */ - - reg = lx_memRead(vp+VP_MISC); - dprintf(1,"VP_SETUP VP_MISC=0x%08x\n",reg); - lx_memWrite(vp+VP_MISC,0,VP_BYP_BOTH); - reg = lx_memRead(vp+VP_MISC); - dprintf(1,"VP_SETUP VP_MISC=0x%08x\n",reg); - - reg = lx_memRead(vp+VP_DCFG); - dprintf(1,"VP_SETUP VP_DCFG=0x%08x\n",reg); - lx_memWrite(vp+VP_DCFG, ~0,VP_CRT_EN+VP_HSYNC_EN+VP_VSYNC_EN+VP_DAC_BL_EN+VP_CRT_SKEW); - reg = lx_memRead(vp+VP_DCFG); - dprintf(1,"VP_SETUP VP_DCFG=0x%08x\n",reg); - - return 0; -} - -static u8 lx_crtc_01[] VAR16 = { - 0x2d, 0x27, 0x28, 0x90, 0x29, 0x8e, 0xbf, 0x1f, - 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, - 0x9b, 0x8d, 0x8f, 0x14, 0x1f, 0x97, 0xb9, 0xa3, - 0xff }; -static u8 lx_crtc_03[] VAR16 = { - 0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0xbf, 0x1f, - 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, - 0x9b, 0x8d, 0x8f, 0x28, 0x1f, 0x97, 0xb9, 0xa3, - 0xff }; -static u8 lx_crtc_04[] VAR16 = { - 0x2d, 0x27, 0x28, 0x90, 0x29, 0x8e, 0xbf, 0x1f, - 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x9b, 0x8d, 0x8f, 0x14, 0x00, 0x97, 0xb9, 0xa2, - 0xff }; -static u8 lx_crtc_05[] VAR16 = { - 0x2d, 0x27, 0x28, 0x90, 0x29, 0x8e, 0xbf, 0x1f, - 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x9b, 0x8e, 0x8f, 0x14, 0x00, 0x97, 0xb9, 0xa2, - 0xff }; -static u8 lx_crtc_06[] VAR16 = { - 0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0xbf, 0x1f, - 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x9b, 0x8d, 0x8f, 0x28, 0x00, 0x97, 0xb9, 0xc2, - 0xff }; -static u8 lx_crtc_07[] VAR16 = { - 0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0xbf, 0x1f, - 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, - 0x9b, 0x8d, 0x8f, 0x28, 0x0f, 0x97, 0xb9, 0xa3, - 0xff }; -static u8 lx_crtc_0d[] VAR16 = { - 0x2d, 0x27, 0x28, 0x90, 0x29, 0x8e, 0xbf, 0x1f, - 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x9b, 0x8d, 0x8f, 0x14, 0x00, 0x97, 0xb9, 0xe3, - 0xff }; -static u8 lx_crtc_0e[] VAR16 = { - 0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0xbf, 0x1f, - 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x9b, 0x8d, 0x8f, 0x28, 0x00, 0x97, 0xb9, 0xe3, - 0xff }; -static u8 lx_crtc_0f[] VAR16 = { - 0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0xbf, 0x1f, - 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x83, 0x85, 0x5d, 0x28, 0x0f, 0x65, 0xb9, 0xe3, - 0xff }; -static u8 lx_crtc_11[] VAR16 = { - 0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0x0b, 0x3e, - 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe9, 0x8b, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3, - 0xff }; -static u8 lx_crtc_13[] VAR16 = { - 0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0xbf, 0x1f, - 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x9b, 0x8d, 0x8f, 0x28, 0x40, 0x98, 0xb9, 0xa3, - 0xff }; - -int geodelx_init(void) -{ - int ret = stdvga_init(); - if (ret) - return ret; - - dprintf(1,"GEODELX_INIT\n"); - - if ((ret=legacyio_check())) { - dprintf(1,"GEODELX_INIT legacyio_check=0x%x\n",ret); - } - - // Updated timings from geode datasheets, table 6-53 in particular - static u8 *new_crtc[] VAR16 = { - lx_crtc_01, lx_crtc_01, lx_crtc_03, lx_crtc_03, - lx_crtc_04, lx_crtc_05, lx_crtc_06, lx_crtc_07, - 0, 0, 0, 0, 0, - lx_crtc_0d, lx_crtc_0e, lx_crtc_0f, lx_crtc_0f, - lx_crtc_11, lx_crtc_11, lx_crtc_13 }; - int i; - for (i=0; icrtc_regs, crtc); - } - - ret |= vp_setup(); - ret |= dc_setup(); - - return ret; -} diff --git a/vgasrc/geodelx.h b/vgasrc/geodelx.h index 8ce07bb..e69de29 100644 --- a/vgasrc/geodelx.h +++ b/vgasrc/geodelx.h @@ -1,81 +0,0 @@ -// Geode LX VGA functions -// -// Copyright (C) 2009 Chris Kindt -// -// Writen for Google Summer of Code 2009 for the coreboot project -// -// This file may be distributed under the terms of the GNU LGPLv3 license. - -#ifndef GEODELX_H -#define GEODELX_H - -#define VRC_INDEX 0xAC1C // Index register -#define VRC_DATA 0xAC1E // Data register -#define VR_UNLOCK 0xFC53 // Virtual register unlock code - -#define EXTENDED_REGISTER_LOCK 0x30 -#define EXTENDED_MODE_CONTROL 0x43 -#define EXTENDED_START_ADDR 0x44 - -#define CRTCE_UNLOCK 0x4c -#define CRTCE_LOCK 0xff - -// Graphics-specific registers: -#define OEM_BAR0 0x50 -#define OEM_BAR1 0x54 -#define OEM_BAR2 0x58 -#define OEM_BAR3 0x5C - -#define LX_PCI_ADDR 0x80000900 -#define LX_PCI_CMD (LX_PCI_ADDR + 0x04) -#define LX_PCI_FB (LX_PCI_ADDR + 0x10) -#define LX_PCI_DC (LX_PCI_ADDR + 0x18) -#define LX_PCI_VP (LX_PCI_ADDR + 0x1c) - -#define DC_LOCK_LOCK 0x00000000 -#define DC_LOCK_UNLOCK 0x00004758 - -/* LX MSRs */ -#define MSR_GLIU0 (1 << 28) -#define MSR_GLIU0_BASE4 (MSR_GLIU0 + 0x23) -#define GLIU0_IOD_BM_0 (MSR_GLIU0 + 0xE0) -#define GLIU0_IOD_BM_1 (MSR_GLIU0 + 0xE1) -#define DC_SPARE 0x80000011 -#define VP_MSR_CONFIG 0x48002001 - -/* DC REG OFFSET */ -#define DC_UNLOCK 0x0 -#define DC_GENERAL_CFG 0x4 -#define DC_DISPLAY_CFG 0x8 -#define DC_ARB_CFG 0xc -#define DC_FB_ST_OFFSET 0x10 -#define DC_CB_ST_OFFSET 0x14 -#define DC_CURS_ST_OFFSET 0x18 -#define DC_GLIU0_MEM_OFFSET 0x84 - -/* VP REG OFFSET */ -#define VP_VCFG 0x0 -#define VP_DCFG 0x8 -#define VP_MISC 0x50 - - -/* DC bits */ -#define DC_VGAE (1 << 7) -#define DC_GDEN (1 << 3) -#define DC_TRUP (1 << 6) - -/* VP bits */ -#define VP_CRT_EN (1 << 0) -#define VP_HSYNC_EN (1 << 1) -#define VP_VSYNC_EN (1 << 2) -#define VP_DAC_BL_EN (1 << 3) -#define VP_CRT_SKEW (1 << 16) -#define VP_BYP_BOTH (1 << 0) - -/* Masks */ -#define VP_MSR_CFG_MSK 0x0 -#define DC_CFG_MSK 0xf000a6 - -int geodelx_init(); - -#endif diff --git a/vgasrc/geodevga.c b/vgasrc/geodevga.c new file mode 100644 index 0000000..0008abe --- /dev/null +++ b/vgasrc/geodevga.c @@ -0,0 +1,374 @@ +// Geode GX2/LX VGA functions +// +// Copyright (C) 2009 Chris Kindt +// +// Written for Google Summer of Code 2009 for the coreboot project +// +// This file may be distributed under the terms of the GNU LGPLv3 license. + +#include "geodevga.h" // geodevga_init +#include "ioport.h" // outb +#include "farptr.h" // SET_FARVAR +#include "biosvar.h" // GET_BDA +#include "vgabios.h" // VGAREG_* +#include "util.h" // memset +#include "stdvga.h" // VGAREG_VGA_CRTC_ADDRESS + + +/**************************************************************** +* MSR and High Mem access through VSA Virtual Register +****************************************************************/ + +static union u64_u32_u geode_msrRead(u32 msrAddr) +{ + union u64_u32_u val; + asm __volatile__ ( + "movw $0x0AC1C, %%dx \n" + "movl $0xFC530007, %%eax \n" + "outl %%eax, %%dx \n" + "addb $2, %%dl \n" + "inw %%dx, %%ax \n" + : "=a" (val.lo), "=d"(val.hi) + : "c"(msrAddr) + : "cc" + ); + return val; +} + +static void geode_msrWrite(u32 msrAddr,u32 andhi, u32 andlo, u32 orhi, u32 orlo) +{ + asm __volatile__ ( + "push %%eax \n" + "movw $0x0AC1C, %%dx \n" + "movl $0xFC530007, %%eax \n" + "outl %%eax, %%dx \n" + "addb $2, %%dl \n" + "pop %%eax \n" + "outw %%ax, %%dx \n" + : + : "c"(msrAddr), "S" (andhi), "D" (andlo), "b" (orhi), "a" (orlo) + : "%edx","cc" + ); +} + +static u32 geode_memRead(u32 addr) +{ + u32 val; + asm __volatile__ ( + "movw $0x0AC1C, %%dx \n" + "movl $0xFC530001, %%eax \n" + "outl %%eax, %%dx \n" + "addb $2, %%dl \n" + "inw %%dx, %%ax \n" + : "=a" (val) + : "b"(addr) + : "cc" + ); + + return val; +} + +static void geode_memWrite(u32 addr, u32 and, u32 or ) +{ + asm __volatile__ ( + "movw $0x0AC1C, %%dx \n" + "movl $0xFC530001, %%eax \n" + "outl %%eax, %%dx \n" + "addb $2, %%dl \n" + "outw %%ax, %%dx \n" + : + : "b"(addr), "S" (and), "D" (or) + : "%eax","cc" + ); +} + +static int legacyio_check(void) +{ + int ret=0; + union u64_u32_u val; + + val=geode_msrRead(MSR_GLIU0_BASE4); + if (val.lo != 0x0A0fffe0) + ret|=1; + + val=geode_msrRead(GLIU0_IOD_BM_0); + if (val.lo != 0x3c0ffff0) + ret|=2; + + val=geode_msrRead(GLIU0_IOD_BM_1); + if (val.lo != 0x3d0ffff0) + ret|=4; + + return ret; +} + +/**************************************************************** +* Extened CRTC Register functions +****************************************************************/ +static void crtce_lock(void) +{ + outb(EXTENDED_REGISTER_LOCK , VGAREG_VGA_CRTC_ADDRESS); + outb(CRTCE_LOCK, VGAREG_VGA_CRTC_DATA); +} + +static void crtce_unlock(void) +{ + outb(EXTENDED_REGISTER_LOCK , VGAREG_VGA_CRTC_ADDRESS); + outb(CRTCE_UNLOCK, VGAREG_VGA_CRTC_DATA); +} + +static u8 crtce_read(u8 reg) +{ + u8 val; + + crtce_unlock(); + outb(reg , VGAREG_VGA_CRTC_ADDRESS); + val = inb(VGAREG_VGA_CRTC_DATA); + crtce_lock(); + + return val; +} + +static void crtce_write(u8 reg, u8 val) +{ + crtce_unlock(); + outb(reg , VGAREG_VGA_CRTC_ADDRESS); + outb(val, VGAREG_VGA_CRTC_DATA); + crtce_lock(); +} + +/**************************************************************** +* Display Controller Functions +****************************************************************/ +static u32 dc_read(u16 seg, u32 reg) +{ + u32 val, *dest_far = (void*)reg; + val = GET_FARVAR(seg,*dest_far); + return val; +} + +static void dc_write(u16 seg, u32 reg, u32 val) +{ + u32 *dest_far = (void*)reg; + SET_FARVAR(seg,*dest_far,val); +} + +static void dc_set(u16 seg, u32 reg, u32 and, u32 or) +{ + u32 val = dc_read(seg,reg); + val &=and; + val |=or; + dc_write(seg,reg,val); +} + +static void dc_unlock(u16 seg) +{ + dc_write(seg,DC_UNLOCK,DC_LOCK_UNLOCK); +} + +static void dc_lock(u16 seg) +{ + dc_write(seg,DC_UNLOCK,DC_LOCK_LOCK); +} + +static u16 dc_map(u16 seg) +{ + u8 reg; + + reg = crtce_read(EXTENDED_MODE_CONTROL); + reg &= 0xf9; + switch (seg) { + case SEG_GRAPH: + reg |= 0x02; + break; + case SEG_MTEXT: + reg |= 0x04; + break; + case SEG_CTEXT: + reg |= 0x06; + break; + default: + seg=0; + break; + } + + crtce_write(EXTENDED_MODE_CONTROL,reg); + return seg; +} + +static void dc_unmap(void) +{ + dc_map(0); +} + + +/**************************************************************** +* Init Functions +****************************************************************/ + +/* Set up the dc (display controller) portion of the geodelx +* The dc provides hardware support for VGA graphics +* for features not accessible from the VGA registers, +* the dc's pci bar can be mapped to a vga memory segment +*/ +static int dc_setup(void) +{ + u32 fb, dc_fb; + u16 seg; + + dprintf(2, "DC_SETUP\n"); + + seg = dc_map(SEG_GRAPH); + dc_unlock(seg); + + /* zero memory config */ + dc_write(seg,DC_FB_ST_OFFSET,0x0); + dc_write(seg,DC_CB_ST_OFFSET,0x0); + dc_write(seg,DC_CURS_ST_OFFSET,0x0); + + /* read fb-bar from pci, then point dc to the fb base */ + dc_fb = dc_read(seg,DC_GLIU0_MEM_OFFSET); + outl(GEODE_PCI_FB,PORT_PCI_CMD); + fb = inl(PORT_PCI_DATA); + if (fb!=dc_fb) { + dc_write(seg,DC_GLIU0_MEM_OFFSET,fb); + } + + dc_set(seg,DC_DISPLAY_CFG,DC_CFG_MSK,DC_GDEN+DC_TRUP); + dc_set(seg,DC_GENERAL_CFG,0,DC_VGAE); + + dc_lock(seg); + dc_unmap(); + + return 0; +} + +/* Setup the vp (video processor) portion of the geodelx +* Under VGA modes the vp was handled by softvg from inside VSA2. +* Without a softvg module, access is only available through a pci bar. +* The High Mem Access virtual register is used to configure the +* pci mmio bar from 16bit friendly io space. +*/ +int vp_setup(void) +{ + u32 reg,vp; + + dprintf(2,"VP_SETUP\n"); + /* set output to crt and RGB/YUV */ + geode_msrWrite(VP_MSR_CONFIG,~0 ,~0xf8,0,0); + + /* get vp register base from pci */ + outl(GEODE_PCI_VP,PORT_PCI_CMD); + vp = inl(PORT_PCI_DATA); + + /* Set mmio registers + * there may be some timing issues here, the reads seem + * to slow things down enough work reliably + */ + + reg = geode_memRead(vp+VP_MISC); + dprintf(1,"VP_SETUP VP_MISC=0x%08x\n",reg); + geode_memWrite(vp+VP_MISC,0,VP_BYP_BOTH); + reg = geode_memRead(vp+VP_MISC); + dprintf(1,"VP_SETUP VP_MISC=0x%08x\n",reg); + + reg = geode_memRead(vp+VP_DCFG); + dprintf(1,"VP_SETUP VP_DCFG=0x%08x\n",reg); + geode_memWrite(vp+VP_DCFG, ~0,VP_CRT_EN+VP_HSYNC_EN+VP_VSYNC_EN+VP_DAC_BL_EN+VP_CRT_SKEW); + reg = geode_memRead(vp+VP_DCFG); + dprintf(1,"VP_SETUP VP_DCFG=0x%08x\n",reg); + + return 0; +} + +static u8 geode_crtc_01[] VAR16 = { + 0x2d, 0x27, 0x28, 0x90, 0x29, 0x8e, 0xbf, 0x1f, + 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x9b, 0x8d, 0x8f, 0x14, 0x1f, 0x97, 0xb9, 0xa3, + 0xff }; +static u8 geode_crtc_03[] VAR16 = { + 0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0xbf, 0x1f, + 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x9b, 0x8d, 0x8f, 0x28, 0x1f, 0x97, 0xb9, 0xa3, + 0xff }; +static u8 geode_crtc_04[] VAR16 = { + 0x2d, 0x27, 0x28, 0x90, 0x29, 0x8e, 0xbf, 0x1f, + 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9b, 0x8d, 0x8f, 0x14, 0x00, 0x97, 0xb9, 0xa2, + 0xff }; +static u8 geode_crtc_05[] VAR16 = { + 0x2d, 0x27, 0x28, 0x90, 0x29, 0x8e, 0xbf, 0x1f, + 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9b, 0x8e, 0x8f, 0x14, 0x00, 0x97, 0xb9, 0xa2, + 0xff }; +static u8 geode_crtc_06[] VAR16 = { + 0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0xbf, 0x1f, + 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9b, 0x8d, 0x8f, 0x28, 0x00, 0x97, 0xb9, 0xc2, + 0xff }; +static u8 geode_crtc_07[] VAR16 = { + 0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0xbf, 0x1f, + 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x9b, 0x8d, 0x8f, 0x28, 0x0f, 0x97, 0xb9, 0xa3, + 0xff }; +static u8 geode_crtc_0d[] VAR16 = { + 0x2d, 0x27, 0x28, 0x90, 0x29, 0x8e, 0xbf, 0x1f, + 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9b, 0x8d, 0x8f, 0x14, 0x00, 0x97, 0xb9, 0xe3, + 0xff }; +static u8 geode_crtc_0e[] VAR16 = { + 0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0xbf, 0x1f, + 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9b, 0x8d, 0x8f, 0x28, 0x00, 0x97, 0xb9, 0xe3, + 0xff }; +static u8 geode_crtc_0f[] VAR16 = { + 0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0xbf, 0x1f, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x83, 0x85, 0x5d, 0x28, 0x0f, 0x65, 0xb9, 0xe3, + 0xff }; +static u8 geode_crtc_11[] VAR16 = { + 0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0x0b, 0x3e, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe9, 0x8b, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3, + 0xff }; +static u8 geode_crtc_13[] VAR16 = { + 0x5f, 0x4f, 0x50, 0x82, 0x51, 0x9e, 0xbf, 0x1f, + 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9b, 0x8d, 0x8f, 0x28, 0x40, 0x98, 0xb9, 0xa3, + 0xff }; + +int geodevga_init(void) +{ + int ret = stdvga_init(); + if (ret) + return ret; + + dprintf(1,"GEODEVGA_INIT\n"); + + if ((ret=legacyio_check())) { + dprintf(1,"GEODEVGA_INIT legacyio_check=0x%x\n",ret); + } + + // Updated timings from geode datasheets, table 6-53 in particular + static u8 *new_crtc[] VAR16 = { + geode_crtc_01, geode_crtc_01, geode_crtc_03, geode_crtc_03, + geode_crtc_04, geode_crtc_05, geode_crtc_06, geode_crtc_07, + 0, 0, 0, 0, 0, + geode_crtc_0d, geode_crtc_0e, geode_crtc_0f, geode_crtc_0f, + geode_crtc_11, geode_crtc_11, geode_crtc_13 }; + int i; + for (i=0; icrtc_regs, crtc); + } + + ret |= vp_setup(); + ret |= dc_setup(); + + return ret; +} diff --git a/vgasrc/geodevga.h b/vgasrc/geodevga.h new file mode 100644 index 0000000..1e51e1c --- /dev/null +++ b/vgasrc/geodevga.h @@ -0,0 +1,81 @@ +// Geode GX2/LX VGA functions +// +// Copyright (C) 2009 Chris Kindt +// +// Writen for Google Summer of Code 2009 for the coreboot project +// +// This file may be distributed under the terms of the GNU LGPLv3 license. + +#ifndef GEODEVGA_H +#define GEODEVGA_H + +#define VRC_INDEX 0xAC1C // Index register +#define VRC_DATA 0xAC1E // Data register +#define VR_UNLOCK 0xFC53 // Virtual register unlock code + +#define EXTENDED_REGISTER_LOCK 0x30 +#define EXTENDED_MODE_CONTROL 0x43 +#define EXTENDED_START_ADDR 0x44 + +#define CRTCE_UNLOCK 0x4c +#define CRTCE_LOCK 0xff + +// Graphics-specific registers: +#define OEM_BAR0 0x50 +#define OEM_BAR1 0x54 +#define OEM_BAR2 0x58 +#define OEM_BAR3 0x5C + +#define GEODE_PCI_ADDR 0x80000900 +#define GEODE_PCI_CMD (GEODE_PCI_ADDR + 0x04) +#define GEODE_PCI_FB (GEODE_PCI_ADDR + 0x10) +#define GEODE_PCI_DC (GEODE_PCI_ADDR + 0x18) +#define GEODE_PCI_VP (GEODE_PCI_ADDR + 0x1c) + +#define DC_LOCK_LOCK 0x00000000 +#define DC_LOCK_UNLOCK 0x00004758 + +/* LX MSRs */ +#define MSR_GLIU0 (1 << 28) +#define MSR_GLIU0_BASE4 (MSR_GLIU0 + 0x23) +#define GLIU0_IOD_BM_0 (MSR_GLIU0 + 0xE0) +#define GLIU0_IOD_BM_1 (MSR_GLIU0 + 0xE1) +#define DC_SPARE 0x80000011 +#define VP_MSR_CONFIG 0x48002001 + +/* DC REG OFFSET */ +#define DC_UNLOCK 0x0 +#define DC_GENERAL_CFG 0x4 +#define DC_DISPLAY_CFG 0x8 +#define DC_ARB_CFG 0xc +#define DC_FB_ST_OFFSET 0x10 +#define DC_CB_ST_OFFSET 0x14 +#define DC_CURS_ST_OFFSET 0x18 +#define DC_GLIU0_MEM_OFFSET 0x84 + +/* VP REG OFFSET */ +#define VP_VCFG 0x0 +#define VP_DCFG 0x8 +#define VP_MISC 0x50 + + +/* DC bits */ +#define DC_VGAE (1 << 7) +#define DC_GDEN (1 << 3) +#define DC_TRUP (1 << 6) + +/* VP bits */ +#define VP_CRT_EN (1 << 0) +#define VP_HSYNC_EN (1 << 1) +#define VP_VSYNC_EN (1 << 2) +#define VP_DAC_BL_EN (1 << 3) +#define VP_CRT_SKEW (1 << 16) +#define VP_BYP_BOTH (1 << 0) + +/* Masks */ +#define VP_MSR_CFG_MSK 0x0 +#define DC_CFG_MSK 0xf000a6 + +int geodevga_init(); + +#endif diff --git a/vgasrc/vgabios.c b/vgasrc/vgabios.c index 7d558c1..063a2fd 100644 --- a/vgasrc/vgabios.c +++ b/vgasrc/vgabios.c @@ -18,7 +18,7 @@ #include "optionroms.h" // struct pci_data #include "config.h" // CONFIG_* #include "stdvga.h" // stdvga_set_mode -#include "geodelx.h" // geodelx_init +#include "geodevga.h" // geodevga_init #include "bochsvga.h" // bochsvga_init #include "clext.h" // clext_init #include "vgahw.h" // vgahw_set_mode diff --git a/vgasrc/vgahw.h b/vgasrc/vgahw.h index d34b0e7..fea041a 100644 --- a/vgasrc/vgahw.h +++ b/vgasrc/vgahw.h @@ -7,7 +7,7 @@ #include "clext.h" // clext_set_mode #include "bochsvga.h" // bochsvga_set_mode #include "stdvga.h" // stdvga_set_mode -#include "geodelx.h" // geodelx_init +#include "geodevga.h" // geodevga_init static inline int vgahw_set_mode(int mode, int flags) { if (CONFIG_VGA_CIRRUS) @@ -23,7 +23,7 @@ static inline int vgahw_init(void) { if (CONFIG_VGA_BOCHS) return bochsvga_init(); if (CONFIG_VGA_GEODELX) - return geodelx_init(); + return geodevga_init(); return stdvga_init(); }