]> xenbits.xen.org Git - xenclient/ioemu-pq.git/commitdiff
intel: Save and restore intel registers.
authorJean Guyader <jean.guyader@eu.citrix.com>
Tue, 15 Dec 2009 18:32:52 +0000 (18:32 +0000)
committerJean Guyader <jean.guyader@eu.citrix.com>
Tue, 15 Dec 2009 18:32:52 +0000 (18:32 +0000)
master/intel

index 4f4dda028b9871a3635daa154313783525ba3edb..433c9ecc96ff499c36bbe5155254299036106b37 100644 (file)
@@ -201,10 +201,10 @@ index 90bd544..e4e27a9 100644
      vga_update_display(s);
 diff --git a/intel.c b/intel.c
 new file mode 100644
-index 0000000..8f2a225
+index 0000000..c1a8c45
 --- /dev/null
 +++ b/intel.c
-@@ -0,0 +1,528 @@
+@@ -0,0 +1,663 @@
 +#include <stdio.h>
 +#include <stdlib.h>
 +#include <stdint.h>
@@ -251,6 +251,12 @@ index 0000000..8f2a225
 +static void set_data_pointer(DisplaySurface *surf);
 +static void intel_resize(DisplayState *ds);
 +
++static char             intel_was_compressed;
++static char             intel_b_was_tiled;
++static uint32_t         intel_b_stride;
++static char             intel_a_was_tiled;
++static uint32_t         intel_a_stride;
++
 +static inline unsigned int intel_get_reg(unsigned int reg)
 +{
 +    return *(unsigned int*)(intel_mmio + reg);
@@ -295,8 +301,6 @@ index 0000000..8f2a225
 +    }
 +}
 +
-+
-+
 +static void intel_force_linear(int linesize)
 +{
 +    unsigned int *dspacntr = (unsigned int *)(intel_mmio + REG_DR_DSPACNTR);
@@ -390,6 +394,130 @@ index 0000000..8f2a225
 +    }
 +}
 +
++static void intel_save(void)
++{
++    volatile unsigned int *dspacntr = (unsigned int *)(intel_mmio + REG_DR_DSPACNTR);
++    volatile unsigned int *pipeaconf = (unsigned int *)(intel_mmio + REG_DR_PIPEACONF);
++    volatile unsigned int *dspastride = (unsigned int *)(intel_mmio + REG_DR_DSPASTRIDE);
++    volatile unsigned int *dspbcntr = (unsigned int *)(intel_mmio + REG_DR_DSPBCNTR);
++    volatile unsigned int *pipebconf = (unsigned int *)(intel_mmio + REG_DR_PIPEBCONF);
++    volatile unsigned int *dspbstride = (unsigned int *)(intel_mmio + REG_DR_DSPBSTRIDE);
++    volatile unsigned int *fbc_ctl = (unsigned int *)(intel_mmio + REG_FBC_CONTROL);
++    unsigned int surfa = 0, surfb = 0, pipea = 0, pipeb = 0;
++    char pipeaenabled = !!(*pipeaconf & (1 << 30));
++    char pipebenabled = !!(*pipebconf & (1 << 30));
++
++    INTEL_DEBUG("save intel registers\n");
++    if (pipeaenabled)
++    {
++        intel_a_was_tiled = !!(*dspacntr & (1 << 10));
++        intel_a_stride = *dspastride;
++    }
++    if (pipebenabled)
++    {
++        intel_b_was_tiled = !!(*dspbcntr & (1 << 10));
++        intel_b_stride = *dspbstride;
++    }
++    intel_was_compressed = *fbc_ctl & (1 << 31);
++    INTEL_DEBUG("   intel_a_was_tiled: %d, (0x%x)\n", !!intel_a_was_tiled, *dspacntr);
++    INTEL_DEBUG("   intel_b_was_tiled: %d, (0x%x)\n", !!intel_b_was_tiled, *dspbcntr);
++}
++
++static void intel_restore(void)
++{
++    volatile unsigned int *dspacntr = (unsigned int *)(intel_mmio + REG_DR_DSPACNTR);
++    volatile unsigned int *pipeaconf = (unsigned int *)(intel_mmio + REG_DR_PIPEACONF);
++    volatile unsigned int *dspasurf = (unsigned int *)(intel_mmio + REG_DR_DSPASURF);
++    volatile unsigned int *dspastride = (unsigned int *)(intel_mmio + REG_DR_DSPASTRIDE);
++
++    volatile unsigned int *dspbcntr = (unsigned int *)(intel_mmio + REG_DR_DSPBCNTR);
++    volatile unsigned int *pipebconf = (unsigned int *)(intel_mmio + REG_DR_PIPEBCONF);
++    volatile unsigned int *dspbsurf = (unsigned int *)(intel_mmio + REG_DR_DSPBSURF);
++    volatile unsigned int *dspbstride = (unsigned int *)(intel_mmio + REG_DR_DSPBSTRIDE);
++    volatile unsigned int *fbc_ctl = (unsigned int *)(intel_mmio + REG_FBC_CONTROL);
++
++    struct timeval start_compress;
++
++    unsigned int surfa = 0, surfb = 0, pipea = 0, pipeb = 0;
++    char pipeaenabled = !!(*pipeaconf & (1 << 30));
++    char pipebenabled = !!(*pipebconf & (1 << 30));
++
++    INTEL_DEBUG("restore intel registers\n");
++    INTEL_DEBUG("   intel_a_was_tiled: %d\n", !!intel_a_was_tiled);
++    INTEL_DEBUG("   intel_b_was_tiled: %d\n", !!intel_b_was_tiled);
++    INTEL_DEBUG("DSPASURF CTRL: 0x%x\n", intel_get_reg(REG_DR_DSPACNTR));
++
++    if (pipeaenabled)
++    {
++        INTEL_DEBUG("PIPEACONF enabled.\n");
++        /* Disable surface */
++        pipea = *pipeaconf & (0x3 << 18);
++        *pipeaconf &= ~(0x3 << 18);
++        *dspacntr |= (1 << 31);
++        /* Address of the surface to map to */
++        surfa = *dspasurf;
++        *dspasurf = 0x00000000;
++        *dspacntr &= ~(1 << 31);
++        *dspasurf = 0x00000000;
++        *pipeaconf |= pipea;
++    }
++
++    if (pipebenabled) {
++        INTEL_DEBUG("PIPEBCONF enabled.\n");
++
++        /* Disable surface */
++        pipeb = *pipebconf & (0x3 << 18);
++        *pipebconf &= ~(0x3 << 18);
++        *dspbcntr |= (1 << 31);
++        /* Address of the surface to map to */
++        surfb = *dspbsurf;
++        *dspbsurf = 0x00000000;
++        *dspbcntr &= ~(1 << 31);
++        *dspbsurf = 0x00000000;
++        *pipebconf |= pipeb;
++    }
++
++    usleep(50 * 1000); /* 50 ms */
++
++    if (pipeaenabled)
++    {
++        *pipeaconf &= ~(0x3 << 18);
++        /* If surface was tiled enable tiled mode */
++        *dspacntr |= (!!intel_a_was_tiled << 10);
++        *dspastride = intel_a_stride;
++        *dspasurf = surfa;
++        *dspacntr |= (1 << 31);
++        *pipeaconf |= pipea;
++    }
++
++    if (pipebenabled) {
++        *pipebconf &= ~(0x3 << 18);
++        /* If surface was tiled enable tiled mode */
++        *dspbcntr |= (!!intel_b_was_tiled << 10);
++        *dspbstride = intel_b_stride;
++        *dspbsurf = surfb;
++        *dspbcntr |= (1 << 31);
++        *pipebconf |= pipeb;
++    }
++
++    usleep(50 * 1000); /* 50 ms */
++
++    /* enabled compression if it was enabled */
++    *fbc_ctl &= ~(!!intel_was_compressed << 31);
++
++    gettimeofday(&start_compress,NULL);
++    /* Wait for the status register */
++
++    while (intel_get_reg(REG_FBC_STATUS) & (!!intel_was_compressed << 31)) {
++      struct timeval now,diff;
++      gettimeofday(&now,NULL);
++      timersub(&now,&start_compress,&diff);
++
++      if (diff.tv_sec || diff.tv_usec>500000) break;
++      usleep(1000);
++    }
++}
++
 +static void set_fb_mapping(void)
 +{
 +    DisplaySurface *surf = lds->surface;
@@ -611,6 +739,9 @@ index 0000000..8f2a225
 +
 +static void intel_focus(int focus)
 +{
++    if (intel_have_focus == 0 && focus)
++        intel_save();
++
 +    if (intel_have_focus == focus ||
 +            !intel_gfx_enabled())
 +        return;
@@ -629,6 +760,10 @@ index 0000000..8f2a225
 +    vga_hw_update();
 +    intel_check_linear();
 +
++    /* leaving restore the registers */
++    if (focus == 0)
++        intel_restore();
++
 +    INTEL_DEBUG("intel_focus %d, x=%d, y=%d, stride=%d\n",
 +            focus, IntelX, IntelY, IntelPitch);
 +}