From: Jean Guyader Date: Sun, 19 Apr 2009 17:45:15 +0000 (+0100) Subject: Imporved intel driver: X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=ae04c2e3ba3ea3e00d599b215d8c07fc30dfd5c8;p=xenclient%2Fioemu.git Imporved intel driver: - Now work if only surface B is enabled. - Be a bit more carefull when we setup the linesize. The vga doesn't like weird linesize (0 or -1). --- diff --git a/intel.c b/intel.c index a790d2f5..16c719eb 100644 --- a/intel.c +++ b/intel.c @@ -29,7 +29,8 @@ #define REG_DR_DSPBSTRIDE 0x71188 #define REG_DR_PIPEBCONF 0x71008 -#define REG_DE_PIPEASRC 0x6001c +#define REG_DR_PIPEASRC 0x6001c +#define REG_DR_PIPEBSRC 0x6101c extern int vga_passthrough; uint32_t guest_framebuffer; @@ -61,19 +62,78 @@ static inline unsigned int intel_get_reg(unsigned int reg) return *(unsigned int*)(intel_mmio + reg); } +static inline void intel_get_res(unsigned int *x, unsigned int *y) +{ + unsigned int *pipeaconf = (unsigned int *)(intel_mmio + REG_DR_PIPEACONF); + unsigned int *pipebconf = (unsigned int *)(intel_mmio + REG_DR_PIPEBCONF); + + if ((*pipeaconf & (1 << 30))) + { + *x = ((intel_get_reg(REG_DR_PIPEASRC) >> 16) & 0xfff) + 1; + *y = (intel_get_reg(REG_DR_PIPEASRC) & 0xfff) + 1; + return; + } + if ((*pipebconf & (1 << 30))) + { + *x = ((intel_get_reg(REG_DR_PIPEBSRC) >> 16) & 0xfff) + 1; + *y = (intel_get_reg(REG_DR_PIPEBSRC) & 0xfff) + 1; + return; + } + + INTEL_DEBUG("No pipe available (PIPEACONF=0x%x,PIPEBCONF=0x%x)!!\n", + *pipeaconf, *pipebconf); + exit(2); +} + +static inline unsigned int get_surf(void) +{ + unsigned int *dspacntr = (unsigned int *)(intel_mmio + REG_DR_DSPACNTR); + unsigned int *dspbcntr = (unsigned int *)(intel_mmio + REG_DR_DSPBCNTR); + + if ((*dspacntr & (1 << 31))) + return *(unsigned int *)(intel_mmio + REG_DR_DSPASURF); + if ((*dspbcntr & (1 << 31))) + return *(unsigned int *)(intel_mmio + REG_DR_DSPBSURF); + + INTEL_DEBUG("No surface available (DSPACNTR=0x%x,DSPBCNTR=0x%x)!!\n", + *dspacntr, *dspbcntr); + exit(2); +} + static inline int is_linear(void) { unsigned int *dspacntr = (unsigned int *)(intel_mmio + REG_DR_DSPACNTR); - if (((*dspacntr) & (1 << 10)) == 0) + unsigned int *dspbcntr = (unsigned int *)(intel_mmio + REG_DR_DSPBCNTR); + + if (((*dspacntr & (1 << 31)) && (*dspacntr & (1 << 10) == 0)) || + ((*dspbcntr & (1 << 31)) && (*dspbcntr & (1 << 10)) == 0)) + { + INTEL_DEBUG("Framebuffer is linear\n"); return 1; + } else return 0; } -static inline unsigned int intel_get_pitch(void) +static inline void intel_get_pitch(DisplayState *ds) { - unsigned int *dspastride = (unsigned int *)(intel_mmio + REG_DR_DSPASTRIDE); - return *dspastride; + unsigned int *dspacntr = (unsigned int *)(intel_mmio + REG_DR_DSPACNTR); + unsigned int *dspbcntr = (unsigned int *)(intel_mmio + REG_DR_DSPBCNTR); + + if (*dspacntr != -1 && (*dspacntr & (1 << 31))) + { + ds->linesize = *(unsigned int *)(intel_mmio + REG_DR_DSPASTRIDE); + return; + } + if (*dspbcntr != -1 && (*dspbcntr & (1 << 31))) + { + ds->linesize = *(unsigned int *)(intel_mmio + REG_DR_DSPBSTRIDE); + return; + } + + INTEL_DEBUG("No surface available (DSPACNTR=0x%x,DSPBCNTR=0x%x)!!\n", + *dspacntr, *dspbcntr); + ds->linesize = ds->width * (ds->depth / 8); } static inline unsigned int intel_get_offset(DisplayState *ds, int x, int y) @@ -84,9 +144,10 @@ static inline unsigned int intel_get_offset(DisplayState *ds, int x, int y) static void intel_update_linear(DisplayState *ds, int x, int y, int w, int h) { int i, bpp = lds->depth / 8; - unsigned char *s, *d; + unsigned char *s, *d, *d2; + s = lds->data; - d = (unsigned char *)(intel_mem + intel_get_reg(REG_DR_DSPASURF)); + d = (unsigned char *)(intel_mem + get_surf()); s += (lds->linesize * y) + bpp * x; d += (lds->linesize * y) + bpp * x; for (i = 0; i < h; i++) { @@ -109,21 +170,24 @@ static void intel_force_linear(int linesize) unsigned int *dspbstride = (unsigned int *)(intel_mmio + REG_DR_DSPBSTRIDE); unsigned int surfa, surfb, pipea, pipeb; + char pipeaenabled = !!(*pipeaconf & (1 << 30)); char pipebenabled = !!(*pipebconf & (1 << 30)); + if (pipeaenabled) + { + INTEL_DEBUG("PIPEACONF enabled.\n"); - INTEL_DEBUG("DSPASURF CTRL: 0x%x\n", intel_get_reg(REG_DR_DSPACNTR)); - - /* 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; + /* 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"); @@ -142,13 +206,16 @@ static void intel_force_linear(int linesize) usleep(20000); - *pipeaconf &= ~(0x3 << 18); - /* Enable surface linear mode */ - *dspacntr &= ~(1 << 10); - if (linesize) *dspastride = linesize; - *dspasurf = surfa; - *dspacntr |= (1 << 31); - *pipeaconf |= pipea; + if (pipeaenabled) + { + *pipeaconf &= ~(0x3 << 18); + /* Enable surface linear mode */ + *dspacntr &= ~(1 << 10); + if (linesize) *dspastride = linesize; + *dspasurf = surfa; + *dspacntr |= (1 << 31); + *pipeaconf |= pipea; + } if (pipebenabled) { *pipebconf &= ~(0x3 << 18); @@ -175,20 +242,20 @@ static void set_fb_mapping(void) unsigned long nr_pfn; unset_vga_acc(); - fprintf(stderr, "set_fb_mapping: %x %x\n", (intel_fb_base + intel_get_reg(REG_DR_DSPASURF)), guest_framebuffer); + fprintf(stderr, "set_fb_mapping: %x %x\n", (intel_fb_base + get_surf()), guest_framebuffer); nr_pfn = (lds->linesize * lds->height) >> TARGET_PAGE_BITS; rc = xc_domain_memory_mapping(xc_handle, domid, (guest_framebuffer >> TARGET_PAGE_BITS), - ((intel_fb_base + intel_get_reg(REG_DR_DSPASURF)) >> TARGET_PAGE_BITS), + ((intel_fb_base + get_surf()) >> TARGET_PAGE_BITS), nr_pfn, DPCI_ADD_MAPPING); if (rc) { fprintf(stderr, "xc_domain_memory_mapping failed %d\n", rc); return; } - map_s = ((intel_fb_base + intel_get_reg(REG_DR_DSPASURF)) >> TARGET_PAGE_BITS); + map_s = ((intel_fb_base + get_surf()) >> TARGET_PAGE_BITS); map_d = (guest_framebuffer >> TARGET_PAGE_BITS); map_size = nr_pfn; } @@ -255,12 +322,15 @@ static void intel_resize_shared(DisplayState *ds, int w, int h, int depth, int l static void intel_resize(DisplayState *ds, int w, int h) { - int old_linesize = ds->linesize; - INTEL_DEBUG("intel_resize: no shared buffer, linesize=%d\n", ds->linesize); + int old_linesize; + + INTEL_DEBUG("intel_resize: no shared buffer, w=%d,h=%d,linesize=%d\n", + w, h, ds->linesize); + old_linesize = ds->linesize; ds->width = w; ds->height = h; ds->depth = 32; - ds->linesize = intel_get_pitch(); + intel_get_pitch(ds); if (map_size) { unset_fb_mapping(); unset_data_mappings(1); @@ -281,7 +351,7 @@ static void intel_resize(DisplayState *ds, int w, int h) set_data_pointer(); } if (intel_have_focus) - memset((unsigned char *)(intel_mem + intel_get_reg(REG_DR_DSPASURF)), 0x0, IntelX * IntelY); + memset((unsigned char *)(intel_mem + get_surf()), 0x0, IntelX * IntelY); if (refresh) { if (old_data) { unsigned char *s, *d; @@ -296,6 +366,8 @@ static void intel_resize(DisplayState *ds, int w, int h) } refresh = 0; } + INTEL_DEBUG("intel_resize: done, w=%d,h=%d,linesize=%d\n", + ds->width, ds->height, ds->linesize); } static void intel_refresh(DisplayState *ds) @@ -351,7 +423,7 @@ static void intel_init_mapping(void) static void set_data_pointer(void) { - lds->data = (unsigned char *)(intel_mem + intel_get_reg(REG_DR_DSPASURF)); + lds->data = (unsigned char *)(intel_mem + get_surf()); lds->data = lds->data + lds->linesize * ((IntelY - lds->height) / 2) + 4 * ((IntelX - lds->width) / 2); @@ -375,7 +447,7 @@ static void unset_data_mappings(int mapping) old_data = NULL; lds->data = realloc(lds->data, lds->linesize * lds->height); memcpy(lds->data, - (unsigned char *)(intel_mem + intel_get_reg(REG_DR_DSPASURF)), + (unsigned char *)(intel_mem + get_surf()), lds->linesize * lds->height); memcpy(buffer_pointer, lds->data, @@ -407,8 +479,7 @@ void intel_focus(int focus) if (focus) { if (!is_linear()) { IntelPitch = intel_get_reg(REG_DR_DSPASTRIDE); - IntelX = ((intel_get_reg(REG_DE_PIPEASRC) >> 16) & 0xfff) + 1; - IntelY = (intel_get_reg(REG_DE_PIPEASRC) & 0xfff) + 1; + intel_get_res(&IntelX, &IntelY); INTEL_DEBUG("Resolution is %dx%d\n", IntelX, IntelY); } refresh = 1; @@ -478,12 +549,8 @@ void intel_display_init(DisplayState *ds) { INTEL_DEBUG("\n"); - xenstore_watch_screenshot_node(); - intel_init_mapping(); - INTEL_DEBUG("Frambuffer is at 0x%x\n", intel_get_reg(REG_DR_DSPASURF)); - ds->shared_buf = 0; intel_resize(ds, 640, 480); lds = ds;