diff options
Diffstat (limited to 'qemu/roms/seabios/vgasrc/geodevga.c')
-rw-r--r-- | qemu/roms/seabios/vgasrc/geodevga.c | 433 |
1 files changed, 0 insertions, 433 deletions
diff --git a/qemu/roms/seabios/vgasrc/geodevga.c b/qemu/roms/seabios/vgasrc/geodevga.c deleted file mode 100644 index f8f61c3a1..000000000 --- a/qemu/roms/seabios/vgasrc/geodevga.c +++ /dev/null @@ -1,433 +0,0 @@ -// 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 "biosvar.h" // GET_BDA -#include "farptr.h" // SET_FARVAR -#include "geodevga.h" // geodevga_setup -#include "hw/pci.h" // pci_config_readl -#include "hw/pci_regs.h" // PCI_BASE_ADDRESS_0 -#include "output.h" // dprintf -#include "stdvga.h" // stdvga_crtc_write -#include "vgabios.h" // VGAREG_* - - -/**************************************************************** -* MSR and High Mem access through VSA Virtual Register -****************************************************************/ - -static u64 geode_msr_read(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" - ); - - dprintf(4, "%s(0x%08x) = 0x%08x-0x%08x\n" - , __func__, msrAddr, val.hi, val.lo); - return val.val; -} - -static void geode_msr_mask(u32 msrAddr, u64 off, u64 on) -{ - union u64_u32_u uand, uor; - uand.val = ~off; - uor.val = on; - - dprintf(4, "%s(0x%08x, 0x%016llx, 0x%016llx)\n" - , __func__, msrAddr, off, on); - - 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" (uand.hi), "D" (uand.lo), "b" (uor.hi), "a" (uor.lo) - : "%edx","cc" - ); -} - -static u32 geode_mem_read(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_mem_mask(u32 addr, u32 off, 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" (~off), "D" (or) - : "%eax","cc" - ); -} - -#define VP_FP_START 0x400 - -static u32 GeodeFB VAR16; -static u32 GeodeDC VAR16; -static u32 GeodeVP VAR16; - -static u32 geode_dc_read(int reg) -{ - u32 val = geode_mem_read(GET_GLOBAL(GeodeDC) + reg); - dprintf(4, "%s(0x%08x) = 0x%08x\n" - , __func__, GET_GLOBAL(GeodeDC) + reg, val); - return val; -} - -static void geode_dc_write(int reg, u32 val) -{ - dprintf(4, "%s(0x%08x, 0x%08x)\n" - , __func__, GET_GLOBAL(GeodeDC) + reg, val); - geode_mem_mask(GET_GLOBAL(GeodeDC) + reg, ~0, val); -} - -static void geode_dc_mask(int reg, u32 off, u32 on) -{ - dprintf(4, "%s(0x%08x, 0x%08x, 0x%08x)\n" - , __func__, GET_GLOBAL(GeodeDC) + reg, off, on); - geode_mem_mask(GET_GLOBAL(GeodeDC) + reg, off, on); -} - -static u32 geode_vp_read(int reg) -{ - u32 val = geode_mem_read(GET_GLOBAL(GeodeVP) + reg); - dprintf(4, "%s(0x%08x) = 0x%08x\n" - , __func__, GET_GLOBAL(GeodeVP) + reg, val); - return val; -} - -static void geode_vp_write(int reg, u32 val) -{ - dprintf(4, "%s(0x%08x, 0x%08x)\n" - , __func__, GET_GLOBAL(GeodeVP) + reg, val); - geode_mem_mask(GET_GLOBAL(GeodeVP) + reg, ~0, val); -} - -static void geode_vp_mask(int reg, u32 off, u32 on) -{ - dprintf(4, "%s(0x%08x, 0x%08x, 0x%08x)\n" - , __func__, GET_GLOBAL(GeodeVP) + reg, off, on); - geode_mem_mask(GET_GLOBAL(GeodeVP) + reg, off, on); -} - -static u32 geode_fp_read(int reg) -{ - u32 val = geode_mem_read(GET_GLOBAL(GeodeVP) + VP_FP_START + reg); - dprintf(4, "%s(0x%08x) = 0x%08x\n" - , __func__, GET_GLOBAL(GeodeVP) + VP_FP_START + reg, val); - return val; -} - -static void geode_fp_write(int reg, u32 val) -{ - dprintf(4, "%s(0x%08x, 0x%08x)\n" - , __func__, GET_GLOBAL(GeodeVP) + VP_FP_START + reg, val); - geode_mem_mask(GET_GLOBAL(GeodeVP) + VP_FP_START + reg, ~0, val); -} - -/**************************************************************** - * Helper functions - ****************************************************************/ - -static int legacyio_check(void) -{ - int ret=0; - u64 val; - - if (CONFIG_VGA_GEODEGX2) - val = geode_msr_read(GLIU0_P2D_BM_4); - else - val = geode_msr_read(MSR_GLIU0_BASE4); - if ((val & 0xffffffff) != 0x0A0fffe0) - ret|=1; - - val = geode_msr_read(GLIU0_IOD_BM_0); - if ((val & 0xffffffff) != 0x3c0ffff0) - ret|=2; - - val = geode_msr_read(GLIU0_IOD_BM_1); - if ((val & 0xffffffff) != 0x3d0ffff0) - ret|=4; - - return ret; -} - -static u32 framebuffer_size(void) -{ - /* We use the P2D_R0 msr to read out the number of pages. - * One page has a size of 4k - * - * Bit Name Description - * 39:20 PMAX Physical Memory Address Max - * 19:0 PMIX Physical Memory Address Min - * - */ - u64 msr = geode_msr_read(GLIU0_P2D_RO); - - u32 pmax = (msr >> 20) & 0x000fffff; - u32 pmin = msr & 0x000fffff; - - u32 val = pmax - pmin; - val += 1; - - /* The page size is 4k */ - return (val << 12); -} - -/**************************************************************** -* Init Functions -****************************************************************/ - -static void geodevga_set_output_mode(void) -{ - u64 msr_addr; - u64 msr; - - /* set output to crt and RGB/YUV */ - if (CONFIG_VGA_GEODEGX2) - msr_addr = VP_MSR_CONFIG_GX2; - else - msr_addr = VP_MSR_CONFIG_LX; - - /* set output mode (RGB/YUV) */ - msr = geode_msr_read(msr_addr); - msr &= ~VP_MSR_CONFIG_FMT; // mask out FMT (bits 5:3) - - if (CONFIG_VGA_OUTPUT_PANEL || CONFIG_VGA_OUTPUT_CRT_PANEL) { - msr |= VP_MSR_CONFIG_FMT_FP; // flat panel - - if (CONFIG_VGA_OUTPUT_CRT_PANEL) { - msr |= VP_MSR_CONFIG_FPC; // simultaneous Flat Panel and CRT - dprintf(1, "output: simultaneous Flat Panel and CRT\n"); - } else { - msr &= ~VP_MSR_CONFIG_FPC; // no simultaneous Flat Panel and CRT - dprintf(1, "ouput: flat panel\n"); - } - } else { - msr |= VP_MSR_CONFIG_FMT_CRT; // CRT only - dprintf(1, "output: CRT\n"); - } - geode_msr_mask(msr_addr, ~msr, msr); -} - -/* Set up the dc (display controller) portion of the geodelx -* The dc provides hardware support for VGA graphics. -*/ -static void dc_setup(void) -{ - dprintf(2, "DC_SETUP\n"); - - geode_dc_write(DC_UNLOCK, DC_LOCK_UNLOCK); - - /* zero memory config */ - geode_dc_write(DC_FB_ST_OFFSET, 0x0); - geode_dc_write(DC_CB_ST_OFFSET, 0x0); - geode_dc_write(DC_CURS_ST_OFFSET, 0x0); - - geode_dc_mask(DC_DISPLAY_CFG, ~DC_CFG_MSK, DC_DISPLAY_CFG_GDEN|DC_DISPLAY_CFG_TRUP); - geode_dc_write(DC_GENERAL_CFG, DC_GENERAL_CFG_VGAE); - - geode_dc_write(DC_UNLOCK, DC_LOCK_LOCK); -} - -/* 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. -*/ -static void vp_setup(void) -{ - dprintf(2,"VP_SETUP\n"); - - geodevga_set_output_mode(); - - /* Set mmio registers - * there may be some timing issues here, the reads seem - * to slow things down enough work reliably - */ - - u32 reg = geode_vp_read(VP_MISC); - dprintf(1,"VP_SETUP VP_MISC=0x%08x\n",reg); - geode_vp_write(VP_MISC, VP_DCFG_BYP_BOTH); - reg = geode_vp_read(VP_MISC); - dprintf(1,"VP_SETUP VP_MISC=0x%08x\n",reg); - - reg = geode_vp_read(VP_DCFG); - dprintf(1,"VP_SETUP VP_DCFG=0x%08x\n",reg); - geode_vp_mask(VP_DCFG, 0, VP_DCFG_CRT_EN|VP_DCFG_HSYNC_EN|VP_DCFG_VSYNC_EN|VP_DCFG_DAC_BL_EN|VP_DCFG_CRT_SKEW); - reg = geode_vp_read(VP_DCFG); - dprintf(1,"VP_SETUP VP_DCFG=0x%08x\n",reg); - - /* setup flat panel */ - if (CONFIG_VGA_OUTPUT_PANEL || CONFIG_VGA_OUTPUT_CRT_PANEL) { - u64 msr; - - dprintf(1, "Setting up flat panel\n"); - /* write timing register */ - geode_fp_write(FP_PT1, 0x0); - geode_fp_write(FP_PT2, FP_PT2_SCRC); - - /* set pad select for TFT/LVDS */ - msr = VP_MSR_PADSEL_TFT_SEL_HIGH; - msr = msr << 32; - msr |= VP_MSR_PADSEL_TFT_SEL_LOW; - geode_msr_mask(VP_MSR_PADSEL, ~msr, msr); - - /* turn the panel on (if it isn't already) */ - reg = geode_fp_read(FP_PM); - reg |= FP_PM_P; - geode_fp_write(FP_PM, reg); - } -} - -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_setup(void) -{ - int ret = stdvga_setup(); - if (ret) - return ret; - - dprintf(1,"GEODEVGA_SETUP\n"); - - if ((ret=legacyio_check())) { - dprintf(1,"GEODEVGA_SETUP 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; i<ARRAY_SIZE(new_crtc); i++) { - u8 *crtc = GET_GLOBAL(new_crtc[i]); - if (crtc) - stdvga_override_crtc(i, crtc); - } - - if (GET_GLOBAL(VgaBDF) < 0) - // Device should be at 00:01.1 - SET_VGA(VgaBDF, pci_to_bdf(0, 1, 1)); - - // setup geode struct which is used for register access - SET_VGA(GeodeFB, pci_config_readl(GET_GLOBAL(VgaBDF), PCI_BASE_ADDRESS_0)); - SET_VGA(GeodeDC, pci_config_readl(GET_GLOBAL(VgaBDF), PCI_BASE_ADDRESS_2)); - SET_VGA(GeodeVP, pci_config_readl(GET_GLOBAL(VgaBDF), PCI_BASE_ADDRESS_3)); - - dprintf(1, "fb addr: 0x%08x\n", GET_GLOBAL(GeodeFB)); - dprintf(1, "dc addr: 0x%08x\n", GET_GLOBAL(GeodeDC)); - dprintf(1, "vp addr: 0x%08x\n", GET_GLOBAL(GeodeVP)); - - /* setup framebuffer */ - geode_dc_write(DC_UNLOCK, DC_LOCK_UNLOCK); - - /* read fb-bar from pci, then point dc to the fb base */ - u32 fb = GET_GLOBAL(GeodeFB); - if (geode_dc_read(DC_GLIU0_MEM_OFFSET) != fb) - geode_dc_write(DC_GLIU0_MEM_OFFSET, fb); - - geode_dc_write(DC_UNLOCK, DC_LOCK_LOCK); - - u32 fb_size = framebuffer_size(); // in byte - dprintf(1, "%d KB of video memory at 0x%08x\n", fb_size / 1024, fb); - - /* update VBE variables */ - SET_VGA(VBE_framebuffer, fb); - SET_VGA(VBE_total_memory, fb_size / 1024 / 64); // number of 64K blocks - - vp_setup(); - dc_setup(); - - return 0; -} |