From: Jean Guyader Date: Tue, 15 Dec 2009 18:32:52 +0000 (+0000) Subject: intel: Save and restore intel registers. X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=550e66d9224721c7a2fcce08a140b7f87ef28759;p=xenclient%2Fioemu-pq.git intel: Save and restore intel registers. --- diff --git a/master/intel b/master/intel index 4f4dda0..433c9ec 100644 --- a/master/intel +++ b/master/intel @@ -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 +#include +#include @@ -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); +}