/* Check pitch constriants for all chips & tiling formats */ static bool i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) { int tile_width; /* Linear is always fine */ if (tiling_mode == I915_TILING_NONE) return true; if (IS_GEN2(dev) || (tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev))) tile_width = 128; else tile_width = 512; /* check maximum stride & object size */ if (INTEL_INFO(dev)->gen >= 4) { /* i965 stores the end address of the gtt mapping in the fence * reg, so dont bother to check the size */ if (stride / 128 > I965_FENCE_MAX_PITCH_VAL) return false; } else { if (stride > 8192) return false; if (IS_GEN3(dev)) { if (size > I830_FENCE_MAX_SIZE_VAL << 20) return false; } else { if (size > I830_FENCE_MAX_SIZE_VAL << 19) return false; } } /* 965+ just needs multiples of tile width */ if (INTEL_INFO(dev)->gen >= 4) { if (stride & (tile_width - 1)) return false; return true; } /* Pre-965 needs power of two tile widths */ if (stride < tile_width) return false; if (stride & (stride - 1)) return false; return true; }
static void i8xx_fbc_enable(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; struct drm_framebuffer *fb = crtc->base.primary->fb; struct drm_i915_gem_object *obj = intel_fb_obj(fb); int cfb_pitch; int i; u32 fbc_ctl; dev_priv->fbc.enabled = true; /* Note: fbc.threshold == 1 for i8xx */ cfb_pitch = dev_priv->fbc.uncompressed_size / FBC_LL_SIZE; if (fb->pitches[0] < cfb_pitch) cfb_pitch = fb->pitches[0]; /* FBC_CTL wants 32B or 64B units */ if (IS_GEN2(dev_priv)) cfb_pitch = (cfb_pitch / 32) - 1; else cfb_pitch = (cfb_pitch / 64) - 1; /* Clear old tags */ for (i = 0; i < (FBC_LL_SIZE / 32) + 1; i++) I915_WRITE(FBC_TAG(i), 0); if (IS_GEN4(dev_priv)) { u32 fbc_ctl2; /* Set it up... */ fbc_ctl2 = FBC_CTL_FENCE_DBL | FBC_CTL_IDLE_IMM | FBC_CTL_CPU_FENCE; fbc_ctl2 |= FBC_CTL_PLANE(crtc->plane); I915_WRITE(FBC_CONTROL2, fbc_ctl2); I915_WRITE(FBC_FENCE_OFF, get_crtc_fence_y_offset(crtc)); } /* enable it... */ fbc_ctl = I915_READ(FBC_CONTROL); fbc_ctl &= 0x3fff << FBC_CTL_INTERVAL_SHIFT; fbc_ctl |= FBC_CTL_EN | FBC_CTL_PERIODIC; if (IS_I945GM(dev_priv)) fbc_ctl |= FBC_CTL_C3_IDLE; /* 945 needs special SR handling */ fbc_ctl |= (cfb_pitch & 0xff) << FBC_CTL_STRIDE_SHIFT; fbc_ctl |= obj->fence_reg; I915_WRITE(FBC_CONTROL, fbc_ctl); DRM_DEBUG_KMS("enabled FBC, pitch %d, yoff %d, plane %c\n", cfb_pitch, crtc->base.y, plane_name(crtc->plane)); }
static int get_new_crc_ctl_reg(struct drm_i915_private *dev_priv, enum pipe pipe, enum intel_pipe_crc_source *source, u32 *val) { if (IS_GEN2(dev_priv)) return i8xx_pipe_crc_ctl_reg(source, val); else if (INTEL_GEN(dev_priv) < 5) return i9xx_pipe_crc_ctl_reg(dev_priv, pipe, source, val); else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) return vlv_pipe_crc_ctl_reg(dev_priv, pipe, source, val); else if (IS_GEN5(dev_priv) || IS_GEN6(dev_priv)) return ilk_pipe_crc_ctl_reg(source, val); else return ivb_pipe_crc_ctl_reg(dev_priv, pipe, source, val); }
static void i8xx_fbc_activate(struct drm_i915_private *dev_priv) { struct intel_fbc_reg_params *params = &dev_priv->fbc.params; int cfb_pitch; int i; u32 fbc_ctl; dev_priv->fbc.active = true; /* Note: fbc.threshold == 1 for i8xx */ cfb_pitch = params->cfb_size / FBC_LL_SIZE; if (params->fb.stride < cfb_pitch) cfb_pitch = params->fb.stride; /* FBC_CTL wants 32B or 64B units */ if (IS_GEN2(dev_priv)) cfb_pitch = (cfb_pitch / 32) - 1; else cfb_pitch = (cfb_pitch / 64) - 1; /* Clear old tags */ for (i = 0; i < (FBC_LL_SIZE / 32) + 1; i++) I915_WRITE(FBC_TAG(i), 0); if (IS_GEN4(dev_priv)) { u32 fbc_ctl2; /* Set it up... */ fbc_ctl2 = FBC_CTL_FENCE_DBL | FBC_CTL_IDLE_IMM | FBC_CTL_CPU_FENCE; fbc_ctl2 |= FBC_CTL_PLANE(params->crtc.plane); I915_WRITE(FBC_CONTROL2, fbc_ctl2); I915_WRITE(FBC_FENCE_OFF, params->crtc.fence_y_offset); } /* enable it... */ fbc_ctl = I915_READ(FBC_CONTROL); fbc_ctl &= 0x3fff << FBC_CTL_INTERVAL_SHIFT; fbc_ctl |= FBC_CTL_EN | FBC_CTL_PERIODIC; if (IS_I945GM(dev_priv)) fbc_ctl |= FBC_CTL_C3_IDLE; /* 945 needs special SR handling */ fbc_ctl |= (cfb_pitch & 0xff) << FBC_CTL_STRIDE_SHIFT; fbc_ctl |= params->fb.fence_reg; I915_WRITE(FBC_CONTROL, fbc_ctl); }
int main(int argc, char** argv) { struct pci_device *pci_dev; uint32_t devid; int mmio_bar; pci_dev = intel_get_pci_device(); devid = pci_dev->device_id; intel_get_mmio(pci_dev); if (IS_GEN2(devid)) mmio_bar = 1; else mmio_bar = 0; write(1, mmio, pci_dev->regions[mmio_bar].size); return 0; }
static bool pixel_format_is_valid(struct drm_i915_private *dev_priv, uint32_t pixel_format) { switch (pixel_format) { case DRM_FORMAT_XRGB8888: case DRM_FORMAT_XBGR8888: return true; case DRM_FORMAT_XRGB1555: case DRM_FORMAT_RGB565: /* 16bpp not supported on gen2 */ if (IS_GEN2(dev_priv)) return false; /* WaFbcOnly1to1Ratio:ctg */ if (IS_G4X(dev_priv)) return false; return true; default: return false; } }
static bool stride_is_valid(struct drm_i915_private *dev_priv, unsigned int stride) { /* These should have been caught earlier. */ WARN_ON(stride < 512); WARN_ON((stride & (64 - 1)) != 0); /* Below are the additional FBC restrictions. */ if (IS_GEN2(dev_priv) || IS_GEN3(dev_priv)) return stride == 4096 || stride == 8192; if (IS_GEN4(dev_priv) && !IS_G4X(dev_priv) && stride < 2048) return false; if (stride > 16384) return false; return true; }
Bool intel_check_display_stride(ScrnInfoPtr scrn, int stride, Bool tiling) { intel_screen_private *intel = intel_get_screen_private(scrn); int limit; /* 8xx spec has always 8K limit, but tests show larger limit in non-tiling mode, which makes large monitor work. */ if (tiling) { if (IS_GEN2(intel)) limit = KB(8); else if (IS_GEN3(intel)) limit = KB(8); else if (IS_GEN4(intel)) limit = KB(16); else limit = KB(32); } else limit = KB(32); return stride <= limit; }
static void render_copyfunc(struct scratch_buf *src, unsigned src_x, unsigned src_y, struct scratch_buf *dst, unsigned dst_x, unsigned dst_y, unsigned logical_tile_no) { if (IS_GEN2(devid)) gen2_render_copyfunc(src, src_x, src_y, dst, dst_x, dst_y, logical_tile_no); else if (IS_GEN3(devid)) gen3_render_copyfunc(src, src_x, src_y, dst, dst_x, dst_y, logical_tile_no); else if (IS_GEN6(devid)) gen6_render_copyfunc(src, src_x, src_y, dst, dst_x, dst_y, logical_tile_no); else blitter_copyfunc(src, src_x, src_y, dst, dst_x, dst_y, logical_tile_no); }
int main(int argc, char **argv) { int fd; int i, iter = 100; uint32_t tiling, swizzle; uint32_t handle; uint32_t devid; fd = drm_open_any(); handle = create_bo(fd); gem_get_tiling(fd, handle, &tiling, &swizzle); devid = intel_get_drm_devid(fd); if (IS_GEN2(devid)) { tile_height = 16; tile_width = 128; tile_size = 2048; } else { tile_height = 8; tile_width = 512; tile_size = PAGE_SIZE; } /* Read a bunch of random subsets of the data and check that they come * out right. */ for (i = 0; i < iter; i++) { int size = WIDTH * HEIGHT * 4; int offset = (random() % size) & ~3; int len = (random() % size) & ~3; int j; if (len == 0) len = 4; if (offset + len > size) len = size - offset; if (i == 0) { offset = 0; len = size; } gem_read(fd, handle, offset, linear, len); /* Translate from offsets in the read buffer to the swizzled * address that it corresponds to. This is the opposite of * what Mesa does (calculate offset to be read given the linear * offset it's looking for). */ for (j = offset; j < offset + len; j += 4) { uint32_t expected_val, found_val; int swizzled_offset; const char *swizzle_str; switch (swizzle) { case I915_BIT_6_SWIZZLE_NONE: swizzled_offset = j; swizzle_str = "none"; break; case I915_BIT_6_SWIZZLE_9: swizzled_offset = j ^ swizzle_bit(9, j); swizzle_str = "bit9"; break; case I915_BIT_6_SWIZZLE_9_10: swizzled_offset = j ^ swizzle_bit(9, j) ^ swizzle_bit(10, j); swizzle_str = "bit9^10"; break; case I915_BIT_6_SWIZZLE_9_11: swizzled_offset = j ^ swizzle_bit(9, j) ^ swizzle_bit(11, j); swizzle_str = "bit9^11"; break; case I915_BIT_6_SWIZZLE_9_10_11: swizzled_offset = j ^ swizzle_bit(9, j) ^ swizzle_bit(10, j) ^ swizzle_bit(11, j); swizzle_str = "bit9^10^11"; break; default: fprintf(stderr, "Bad swizzle bits; %d\n", swizzle); abort(); } expected_val = calculate_expected(swizzled_offset); found_val = linear[(j - offset) / 4]; if (expected_val != found_val) { fprintf(stderr, "Bad read [%d]: %d instead of %d at 0x%08x " "for read from 0x%08x to 0x%08x, swizzle=%s\n", i, found_val, expected_val, j, offset, offset + len, swizzle_str); abort(); } } } close(fd); return 0; }
/** * Detects bit 6 swizzling of address lookup between IGD access and CPU * access through main memory. */ void i915_gem_detect_bit_6_swizzle(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; uint32_t swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN; uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; if (IS_GEN5(dev) || IS_GEN6(dev)) { /* On Ironlake whatever DRAM config, GPU always do * same swizzling setup. */ swizzle_x = I915_BIT_6_SWIZZLE_9_10; swizzle_y = I915_BIT_6_SWIZZLE_9; } else if (IS_GEN2(dev)) { /* As far as we know, the 865 doesn't have these bit 6 * swizzling issues. */ swizzle_x = I915_BIT_6_SWIZZLE_NONE; swizzle_y = I915_BIT_6_SWIZZLE_NONE; } else if (IS_MOBILE(dev)) { uint32_t dcc; /* On mobile 9xx chipsets, channel interleave by the CPU is * determined by DCC. For single-channel, neither the CPU * nor the GPU do swizzling. For dual channel interleaved, * the GPU's interleave is bit 9 and 10 for X tiled, and bit * 9 for Y tiled. The CPU's interleave is independent, and * can be based on either bit 11 (haven't seen this yet) or * bit 17 (common). */ dcc = I915_READ(DCC); switch (dcc & DCC_ADDRESSING_MODE_MASK) { case DCC_ADDRESSING_MODE_SINGLE_CHANNEL: case DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC: swizzle_x = I915_BIT_6_SWIZZLE_NONE; swizzle_y = I915_BIT_6_SWIZZLE_NONE; break; case DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED: if (dcc & DCC_CHANNEL_XOR_DISABLE) { /* This is the base swizzling by the GPU for * tiled buffers. */ swizzle_x = I915_BIT_6_SWIZZLE_9_10; swizzle_y = I915_BIT_6_SWIZZLE_9; } else if ((dcc & DCC_CHANNEL_XOR_BIT_17) == 0) { /* Bit 11 swizzling by the CPU in addition. */ swizzle_x = I915_BIT_6_SWIZZLE_9_10_11; swizzle_y = I915_BIT_6_SWIZZLE_9_11; } else { /* Bit 17 swizzling by the CPU in addition. */ swizzle_x = I915_BIT_6_SWIZZLE_9_10_17; swizzle_y = I915_BIT_6_SWIZZLE_9_17; } break; } if (dcc == 0xffffffff) { DRM_ERROR("Couldn't read from MCHBAR. " "Disabling tiling.\n"); swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN; swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; } } else { /* The 965, G33, and newer, have a very flexible memory * configuration. It will enable dual-channel mode * (interleaving) on as much memory as it can, and the GPU * will additionally sometimes enable different bit 6 * swizzling for tiled objects from the CPU. * * Here's what I found on the G965: * slot fill memory size swizzling * 0A 0B 1A 1B 1-ch 2-ch * 512 0 0 0 512 0 O * 512 0 512 0 16 1008 X * 512 0 0 512 16 1008 X * 0 512 0 512 16 1008 X * 1024 1024 1024 0 2048 1024 O * * We could probably detect this based on either the DRB * matching, which was the case for the swizzling required in * the table above, or from the 1-ch value being less than * the minimum size of a rank. */ if (I915_READ16(C0DRB3) != I915_READ16(C1DRB3)) { swizzle_x = I915_BIT_6_SWIZZLE_NONE; swizzle_y = I915_BIT_6_SWIZZLE_NONE; } else { swizzle_x = I915_BIT_6_SWIZZLE_9_10; swizzle_y = I915_BIT_6_SWIZZLE_9; } } dev_priv->mm.bit_6_swizzle_x = swizzle_x; dev_priv->mm.bit_6_swizzle_y = swizzle_y; }
/* Check pitch constriants for all chips & tiling formats */ static bool i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) { int tile_width, tile_height; /* Linear is always fine */ if (tiling_mode == I915_TILING_NONE) return true; if (IS_GEN2(dev) || (tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev))) tile_width = 128; else tile_width = 512; /* check maximum stride & object size */ if (INTEL_INFO(dev)->gen >= 4) { /* i965 stores the end address of the gtt mapping in the fence * reg, so dont bother to check the size */ if (stride / 128 > I965_FENCE_MAX_PITCH_VAL) return false; } else { if (stride > 8192) return false; if (IS_GEN3(dev)) { if (size > I830_FENCE_MAX_SIZE_VAL << 20) return false; } else { if (size > I830_FENCE_MAX_SIZE_VAL << 19) return false; } } if (IS_GEN2(dev) || (tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev))) tile_height = 32; else tile_height = 8; /* i8xx is strange: It has 2 interleaved rows of tiles, so needs an even * number of tile rows. */ if (IS_GEN2(dev)) tile_height *= 2; /* Size needs to be aligned to a full tile row */ if (size & (tile_height * stride - 1)) return false; /* 965+ just needs multiples of tile width */ if (INTEL_INFO(dev)->gen >= 4) { if (stride & (tile_width - 1)) return false; return true; } /* Pre-965 needs power of two tile widths */ if (stride < tile_width) return false; if (stride & (stride - 1)) return false; return true; }
static void i915_restore_modeset_reg(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; int dpll_a_reg, fpa0_reg, fpa1_reg; int dpll_b_reg, fpb0_reg, fpb1_reg; int i; if (drm_core_check_feature(dev, DRIVER_MODESET)) return; /* Fences */ switch (INTEL_INFO(dev)->gen) { case 7: case 6: for (i = 0; i < 16; i++) I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (i * 8), dev_priv->saveFENCE[i]); break; case 5: case 4: for (i = 0; i < 16; i++) I915_WRITE64(FENCE_REG_965_0 + (i * 8), dev_priv->saveFENCE[i]); break; case 3: case 2: if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) for (i = 0; i < 8; i++) I915_WRITE(FENCE_REG_945_8 + (i * 4), dev_priv->saveFENCE[i+8]); for (i = 0; i < 8; i++) I915_WRITE(FENCE_REG_830_0 + (i * 4), dev_priv->saveFENCE[i]); break; } if (HAS_PCH_SPLIT(dev)) { dpll_a_reg = _PCH_DPLL_A; dpll_b_reg = _PCH_DPLL_B; fpa0_reg = _PCH_FPA0; fpb0_reg = _PCH_FPB0; fpa1_reg = _PCH_FPA1; fpb1_reg = _PCH_FPB1; } else { dpll_a_reg = _DPLL_A; dpll_b_reg = _DPLL_B; fpa0_reg = _FPA0; fpb0_reg = _FPB0; fpa1_reg = _FPA1; fpb1_reg = _FPB1; } if (HAS_PCH_SPLIT(dev)) { I915_WRITE(PCH_DREF_CONTROL, dev_priv->savePCH_DREF_CONTROL); I915_WRITE(DISP_ARB_CTL, dev_priv->saveDISP_ARB_CTL); } /* Pipe & plane A info */ /* Prime the clock */ if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A & ~DPLL_VCO_ENABLE); POSTING_READ(dpll_a_reg); DRM_UDELAY(150); } I915_WRITE(fpa0_reg, dev_priv->saveFPA0); I915_WRITE(fpa1_reg, dev_priv->saveFPA1); /* Actually enable it */ I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A); POSTING_READ(dpll_a_reg); DRM_UDELAY(150); if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) { I915_WRITE(_DPLL_A_MD, dev_priv->saveDPLL_A_MD); POSTING_READ(_DPLL_A_MD); } DRM_UDELAY(150); /* Restore mode */ I915_WRITE(_HTOTAL_A, dev_priv->saveHTOTAL_A); I915_WRITE(_HBLANK_A, dev_priv->saveHBLANK_A); I915_WRITE(_HSYNC_A, dev_priv->saveHSYNC_A); I915_WRITE(_VTOTAL_A, dev_priv->saveVTOTAL_A); I915_WRITE(_VBLANK_A, dev_priv->saveVBLANK_A); I915_WRITE(_VSYNC_A, dev_priv->saveVSYNC_A); if (!HAS_PCH_SPLIT(dev)) I915_WRITE(_BCLRPAT_A, dev_priv->saveBCLRPAT_A); if (HAS_PCH_SPLIT(dev)) { I915_WRITE(_PIPEA_DATA_M1, dev_priv->savePIPEA_DATA_M1); I915_WRITE(_PIPEA_DATA_N1, dev_priv->savePIPEA_DATA_N1); I915_WRITE(_PIPEA_LINK_M1, dev_priv->savePIPEA_LINK_M1); I915_WRITE(_PIPEA_LINK_N1, dev_priv->savePIPEA_LINK_N1); I915_WRITE(_FDI_RXA_CTL, dev_priv->saveFDI_RXA_CTL); I915_WRITE(_FDI_TXA_CTL, dev_priv->saveFDI_TXA_CTL); I915_WRITE(_PFA_CTL_1, dev_priv->savePFA_CTL_1); I915_WRITE(_PFA_WIN_SZ, dev_priv->savePFA_WIN_SZ); I915_WRITE(_PFA_WIN_POS, dev_priv->savePFA_WIN_POS); I915_WRITE(_TRANSACONF, dev_priv->saveTRANSACONF); I915_WRITE(_TRANS_HTOTAL_A, dev_priv->saveTRANS_HTOTAL_A); I915_WRITE(_TRANS_HBLANK_A, dev_priv->saveTRANS_HBLANK_A); I915_WRITE(_TRANS_HSYNC_A, dev_priv->saveTRANS_HSYNC_A); I915_WRITE(_TRANS_VTOTAL_A, dev_priv->saveTRANS_VTOTAL_A); I915_WRITE(_TRANS_VBLANK_A, dev_priv->saveTRANS_VBLANK_A); I915_WRITE(_TRANS_VSYNC_A, dev_priv->saveTRANS_VSYNC_A); } /* Restore plane info */ I915_WRITE(_DSPASIZE, dev_priv->saveDSPASIZE); I915_WRITE(_DSPAPOS, dev_priv->saveDSPAPOS); I915_WRITE(_PIPEASRC, dev_priv->savePIPEASRC); I915_WRITE(_DSPAADDR, dev_priv->saveDSPAADDR); I915_WRITE(_DSPASTRIDE, dev_priv->saveDSPASTRIDE); if (INTEL_INFO(dev)->gen >= 4) { I915_WRITE(_DSPASURF, dev_priv->saveDSPASURF); I915_WRITE(_DSPATILEOFF, dev_priv->saveDSPATILEOFF); } I915_WRITE(_PIPEACONF, dev_priv->savePIPEACONF); i915_restore_palette(dev, PIPE_A); /* Enable the plane */ I915_WRITE(_DSPACNTR, dev_priv->saveDSPACNTR); I915_WRITE(_DSPAADDR, I915_READ(_DSPAADDR)); /* Pipe & plane B info */ if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) { I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B & ~DPLL_VCO_ENABLE); POSTING_READ(dpll_b_reg); DRM_UDELAY(150); } I915_WRITE(fpb0_reg, dev_priv->saveFPB0); I915_WRITE(fpb1_reg, dev_priv->saveFPB1); /* Actually enable it */ I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B); POSTING_READ(dpll_b_reg); DRM_UDELAY(150); if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) { I915_WRITE(_DPLL_B_MD, dev_priv->saveDPLL_B_MD); POSTING_READ(_DPLL_B_MD); } DRM_UDELAY(150); /* Restore mode */ I915_WRITE(_HTOTAL_B, dev_priv->saveHTOTAL_B); I915_WRITE(_HBLANK_B, dev_priv->saveHBLANK_B); I915_WRITE(_HSYNC_B, dev_priv->saveHSYNC_B); I915_WRITE(_VTOTAL_B, dev_priv->saveVTOTAL_B); I915_WRITE(_VBLANK_B, dev_priv->saveVBLANK_B); I915_WRITE(_VSYNC_B, dev_priv->saveVSYNC_B); if (!HAS_PCH_SPLIT(dev)) I915_WRITE(_BCLRPAT_B, dev_priv->saveBCLRPAT_B); if (HAS_PCH_SPLIT(dev)) { I915_WRITE(_PIPEB_DATA_M1, dev_priv->savePIPEB_DATA_M1); I915_WRITE(_PIPEB_DATA_N1, dev_priv->savePIPEB_DATA_N1); I915_WRITE(_PIPEB_LINK_M1, dev_priv->savePIPEB_LINK_M1); I915_WRITE(_PIPEB_LINK_N1, dev_priv->savePIPEB_LINK_N1); I915_WRITE(_FDI_RXB_CTL, dev_priv->saveFDI_RXB_CTL); I915_WRITE(_FDI_TXB_CTL, dev_priv->saveFDI_TXB_CTL); I915_WRITE(_PFB_CTL_1, dev_priv->savePFB_CTL_1); I915_WRITE(_PFB_WIN_SZ, dev_priv->savePFB_WIN_SZ); I915_WRITE(_PFB_WIN_POS, dev_priv->savePFB_WIN_POS); I915_WRITE(_TRANSBCONF, dev_priv->saveTRANSBCONF); I915_WRITE(_TRANS_HTOTAL_B, dev_priv->saveTRANS_HTOTAL_B); I915_WRITE(_TRANS_HBLANK_B, dev_priv->saveTRANS_HBLANK_B); I915_WRITE(_TRANS_HSYNC_B, dev_priv->saveTRANS_HSYNC_B); I915_WRITE(_TRANS_VTOTAL_B, dev_priv->saveTRANS_VTOTAL_B); I915_WRITE(_TRANS_VBLANK_B, dev_priv->saveTRANS_VBLANK_B); I915_WRITE(_TRANS_VSYNC_B, dev_priv->saveTRANS_VSYNC_B); } /* Restore plane info */ I915_WRITE(_DSPBSIZE, dev_priv->saveDSPBSIZE); I915_WRITE(_DSPBPOS, dev_priv->saveDSPBPOS); I915_WRITE(_PIPEBSRC, dev_priv->savePIPEBSRC); I915_WRITE(_DSPBADDR, dev_priv->saveDSPBADDR); I915_WRITE(_DSPBSTRIDE, dev_priv->saveDSPBSTRIDE); if (INTEL_INFO(dev)->gen >= 4) { I915_WRITE(_DSPBSURF, dev_priv->saveDSPBSURF); I915_WRITE(_DSPBTILEOFF, dev_priv->saveDSPBTILEOFF); } I915_WRITE(_PIPEBCONF, dev_priv->savePIPEBCONF); i915_restore_palette(dev, PIPE_B); /* Enable the plane */ I915_WRITE(_DSPBCNTR, dev_priv->saveDSPBCNTR); I915_WRITE(_DSPBADDR, I915_READ(_DSPBADDR)); /* Cursor state */ I915_WRITE(_CURAPOS, dev_priv->saveCURAPOS); I915_WRITE(_CURACNTR, dev_priv->saveCURACNTR); I915_WRITE(_CURABASE, dev_priv->saveCURABASE); I915_WRITE(_CURBPOS, dev_priv->saveCURBPOS); I915_WRITE(_CURBCNTR, dev_priv->saveCURBCNTR); I915_WRITE(_CURBBASE, dev_priv->saveCURBBASE); if (IS_GEN2(dev)) I915_WRITE(CURSIZE, dev_priv->saveCURSIZE); return; }
static void i915_save_modeset_reg(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; int i; if (drm_core_check_feature(dev, DRIVER_MODESET)) return; /* Cursor state */ dev_priv->saveCURACNTR = I915_READ(_CURACNTR); dev_priv->saveCURAPOS = I915_READ(_CURAPOS); dev_priv->saveCURABASE = I915_READ(_CURABASE); dev_priv->saveCURBCNTR = I915_READ(_CURBCNTR); dev_priv->saveCURBPOS = I915_READ(_CURBPOS); dev_priv->saveCURBBASE = I915_READ(_CURBBASE); if (IS_GEN2(dev)) dev_priv->saveCURSIZE = I915_READ(CURSIZE); if (HAS_PCH_SPLIT(dev)) { dev_priv->savePCH_DREF_CONTROL = I915_READ(PCH_DREF_CONTROL); dev_priv->saveDISP_ARB_CTL = I915_READ(DISP_ARB_CTL); } /* Pipe & plane A info */ dev_priv->savePIPEACONF = I915_READ(_PIPEACONF); dev_priv->savePIPEASRC = I915_READ(_PIPEASRC); if (HAS_PCH_SPLIT(dev)) { dev_priv->saveFPA0 = I915_READ(_PCH_FPA0); dev_priv->saveFPA1 = I915_READ(_PCH_FPA1); dev_priv->saveDPLL_A = I915_READ(_PCH_DPLL_A); } else { dev_priv->saveFPA0 = I915_READ(_FPA0); dev_priv->saveFPA1 = I915_READ(_FPA1); dev_priv->saveDPLL_A = I915_READ(_DPLL_A); } if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) dev_priv->saveDPLL_A_MD = I915_READ(_DPLL_A_MD); dev_priv->saveHTOTAL_A = I915_READ(_HTOTAL_A); dev_priv->saveHBLANK_A = I915_READ(_HBLANK_A); dev_priv->saveHSYNC_A = I915_READ(_HSYNC_A); dev_priv->saveVTOTAL_A = I915_READ(_VTOTAL_A); dev_priv->saveVBLANK_A = I915_READ(_VBLANK_A); dev_priv->saveVSYNC_A = I915_READ(_VSYNC_A); if (!HAS_PCH_SPLIT(dev)) dev_priv->saveBCLRPAT_A = I915_READ(_BCLRPAT_A); if (HAS_PCH_SPLIT(dev)) { dev_priv->savePIPEA_DATA_M1 = I915_READ(_PIPEA_DATA_M1); dev_priv->savePIPEA_DATA_N1 = I915_READ(_PIPEA_DATA_N1); dev_priv->savePIPEA_LINK_M1 = I915_READ(_PIPEA_LINK_M1); dev_priv->savePIPEA_LINK_N1 = I915_READ(_PIPEA_LINK_N1); dev_priv->saveFDI_TXA_CTL = I915_READ(_FDI_TXA_CTL); dev_priv->saveFDI_RXA_CTL = I915_READ(_FDI_RXA_CTL); dev_priv->savePFA_CTL_1 = I915_READ(_PFA_CTL_1); dev_priv->savePFA_WIN_SZ = I915_READ(_PFA_WIN_SZ); dev_priv->savePFA_WIN_POS = I915_READ(_PFA_WIN_POS); dev_priv->saveTRANSACONF = I915_READ(_TRANSACONF); dev_priv->saveTRANS_HTOTAL_A = I915_READ(_TRANS_HTOTAL_A); dev_priv->saveTRANS_HBLANK_A = I915_READ(_TRANS_HBLANK_A); dev_priv->saveTRANS_HSYNC_A = I915_READ(_TRANS_HSYNC_A); dev_priv->saveTRANS_VTOTAL_A = I915_READ(_TRANS_VTOTAL_A); dev_priv->saveTRANS_VBLANK_A = I915_READ(_TRANS_VBLANK_A); dev_priv->saveTRANS_VSYNC_A = I915_READ(_TRANS_VSYNC_A); } dev_priv->saveDSPACNTR = I915_READ(_DSPACNTR); dev_priv->saveDSPASTRIDE = I915_READ(_DSPASTRIDE); dev_priv->saveDSPASIZE = I915_READ(_DSPASIZE); dev_priv->saveDSPAPOS = I915_READ(_DSPAPOS); dev_priv->saveDSPAADDR = I915_READ(_DSPAADDR); if (INTEL_INFO(dev)->gen >= 4) { dev_priv->saveDSPASURF = I915_READ(_DSPASURF); dev_priv->saveDSPATILEOFF = I915_READ(_DSPATILEOFF); } i915_save_palette(dev, PIPE_A); dev_priv->savePIPEASTAT = I915_READ(_PIPEASTAT); /* Pipe & plane B info */ dev_priv->savePIPEBCONF = I915_READ(_PIPEBCONF); dev_priv->savePIPEBSRC = I915_READ(_PIPEBSRC); if (HAS_PCH_SPLIT(dev)) { dev_priv->saveFPB0 = I915_READ(_PCH_FPB0); dev_priv->saveFPB1 = I915_READ(_PCH_FPB1); dev_priv->saveDPLL_B = I915_READ(_PCH_DPLL_B); } else { dev_priv->saveFPB0 = I915_READ(_FPB0); dev_priv->saveFPB1 = I915_READ(_FPB1); dev_priv->saveDPLL_B = I915_READ(_DPLL_B); } if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) dev_priv->saveDPLL_B_MD = I915_READ(_DPLL_B_MD); dev_priv->saveHTOTAL_B = I915_READ(_HTOTAL_B); dev_priv->saveHBLANK_B = I915_READ(_HBLANK_B); dev_priv->saveHSYNC_B = I915_READ(_HSYNC_B); dev_priv->saveVTOTAL_B = I915_READ(_VTOTAL_B); dev_priv->saveVBLANK_B = I915_READ(_VBLANK_B); dev_priv->saveVSYNC_B = I915_READ(_VSYNC_B); if (!HAS_PCH_SPLIT(dev)) dev_priv->saveBCLRPAT_B = I915_READ(_BCLRPAT_B); if (HAS_PCH_SPLIT(dev)) { dev_priv->savePIPEB_DATA_M1 = I915_READ(_PIPEB_DATA_M1); dev_priv->savePIPEB_DATA_N1 = I915_READ(_PIPEB_DATA_N1); dev_priv->savePIPEB_LINK_M1 = I915_READ(_PIPEB_LINK_M1); dev_priv->savePIPEB_LINK_N1 = I915_READ(_PIPEB_LINK_N1); dev_priv->saveFDI_TXB_CTL = I915_READ(_FDI_TXB_CTL); dev_priv->saveFDI_RXB_CTL = I915_READ(_FDI_RXB_CTL); dev_priv->savePFB_CTL_1 = I915_READ(_PFB_CTL_1); dev_priv->savePFB_WIN_SZ = I915_READ(_PFB_WIN_SZ); dev_priv->savePFB_WIN_POS = I915_READ(_PFB_WIN_POS); dev_priv->saveTRANSBCONF = I915_READ(_TRANSBCONF); dev_priv->saveTRANS_HTOTAL_B = I915_READ(_TRANS_HTOTAL_B); dev_priv->saveTRANS_HBLANK_B = I915_READ(_TRANS_HBLANK_B); dev_priv->saveTRANS_HSYNC_B = I915_READ(_TRANS_HSYNC_B); dev_priv->saveTRANS_VTOTAL_B = I915_READ(_TRANS_VTOTAL_B); dev_priv->saveTRANS_VBLANK_B = I915_READ(_TRANS_VBLANK_B); dev_priv->saveTRANS_VSYNC_B = I915_READ(_TRANS_VSYNC_B); } dev_priv->saveDSPBCNTR = I915_READ(_DSPBCNTR); dev_priv->saveDSPBSTRIDE = I915_READ(_DSPBSTRIDE); dev_priv->saveDSPBSIZE = I915_READ(_DSPBSIZE); dev_priv->saveDSPBPOS = I915_READ(_DSPBPOS); dev_priv->saveDSPBADDR = I915_READ(_DSPBADDR); if (INTEL_INFO(dev)->gen >= 4) { dev_priv->saveDSPBSURF = I915_READ(_DSPBSURF); dev_priv->saveDSPBTILEOFF = I915_READ(_DSPBTILEOFF); } i915_save_palette(dev, PIPE_B); dev_priv->savePIPEBSTAT = I915_READ(_PIPEBSTAT); /* Fences */ switch (INTEL_INFO(dev)->gen) { case 7: case 6: for (i = 0; i < 16; i++) dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); break; case 5: case 4: for (i = 0; i < 16; i++) dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_965_0 + (i * 8)); break; case 3: if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) for (i = 0; i < 8; i++) dev_priv->saveFENCE[i+8] = I915_READ(FENCE_REG_945_8 + (i * 4)); case 2: for (i = 0; i < 8; i++) dev_priv->saveFENCE[i] = I915_READ(FENCE_REG_830_0 + (i * 4)); break; } return; }
static unsigned int intel_uxa_pixmap_compute_size(PixmapPtr pixmap, int w, int h, uint32_t *tiling, int *stride, unsigned usage) { ScrnInfoPtr scrn = xf86Screens[pixmap->drawable.pScreen->myNum]; intel_screen_private *intel = intel_get_screen_private(scrn); int pitch, size; if (*tiling != I915_TILING_NONE) { /* First check whether tiling is necessary. */ pitch = (w * pixmap->drawable.bitsPerPixel + 7) / 8; pitch = ALIGN(pitch, 64); size = pitch * ALIGN (h, 2); if (INTEL_INFO(intel)->gen < 40) { /* Gen 2/3 has a maximum stride for tiling of * 8192 bytes. */ if (pitch > KB(8)) *tiling = I915_TILING_NONE; /* Narrower than half a tile? */ if (pitch < 256) *tiling = I915_TILING_NONE; /* Older hardware requires fences to be pot size * aligned with a minimum of 1 MiB, so causes * massive overallocation for small textures. */ if (size < 1024*1024/2 && !intel->has_relaxed_fencing) *tiling = I915_TILING_NONE; } else if (!(usage & INTEL_CREATE_PIXMAP_DRI2) && size <= 4096) { /* Disable tiling beneath a page size, we will not see * any benefit from reducing TLB misses and instead * just incur extra cost when we require a fence. */ *tiling = I915_TILING_NONE; } } pitch = (w * pixmap->drawable.bitsPerPixel + 7) / 8; if (!(usage & INTEL_CREATE_PIXMAP_DRI2) && pitch <= 256) *tiling = I915_TILING_NONE; if (*tiling != I915_TILING_NONE) { int aligned_h, tile_height; if (IS_GEN2(intel)) tile_height = 16; else if (*tiling == I915_TILING_X) tile_height = 8; else tile_height = 32; aligned_h = ALIGN(h, tile_height); *stride = intel_get_fence_pitch(intel, ALIGN(pitch, 512), *tiling); /* Round the object up to the size of the fence it will live in * if necessary. We could potentially make the kernel allocate * a larger aperture space and just bind the subset of pages in, * but this is easier and also keeps us out of trouble (as much) * with drm_intel_bufmgr_check_aperture(). */ size = intel_get_fence_size(intel, *stride * aligned_h); if (size > intel->max_tiling_size) *tiling = I915_TILING_NONE; } if (*tiling == I915_TILING_NONE) { /* Round the height up so that the GPU's access to a 2x2 aligned * subspan doesn't address an invalid page offset beyond the * end of the GTT. */ *stride = ALIGN(pitch, 64); size = *stride * ALIGN(h, 2); } return size; }
static int intelfb_create(struct intel_fbdev *ifbdev, struct drm_fb_helper_surface_size *sizes) { struct drm_device *dev = ifbdev->helper.dev; struct fb_info *info; struct drm_framebuffer *fb; struct drm_mode_fb_cmd mode_cmd; struct drm_i915_gem_object *obj; struct device *device = &dev->pdev->dev; int size, ret; /* we don't do packed 24bpp */ if (sizes->surface_bpp == 24) sizes->surface_bpp = 32; mode_cmd.width = sizes->surface_width; mode_cmd.height = sizes->surface_height; mode_cmd.bpp = sizes->surface_bpp; mode_cmd.pitch = ALIGN(mode_cmd.width * ((mode_cmd.bpp + 7) / 8), 64); mode_cmd.depth = sizes->surface_depth; size = mode_cmd.pitch * mode_cmd.height; size = ALIGN(size, PAGE_SIZE); obj = i915_gem_alloc_object(dev, size); if (!obj) { DRM_ERROR("failed to allocate framebuffer\n"); ret = -ENOMEM; goto out; } mutex_lock(&dev->struct_mutex); /* Flush everything out, we'll be doing GTT only from now on */ ret = intel_pin_and_fence_fb_obj(dev, obj, false); if (ret) { DRM_ERROR("failed to pin fb: %d\n", ret); goto out_unref; } info = framebuffer_alloc(0, device); if (!info) { ret = -ENOMEM; goto out_unpin; } info->par = ifbdev; ret = intel_framebuffer_init(dev, &ifbdev->ifb, &mode_cmd, obj); if (ret) goto out_unpin; fb = &ifbdev->ifb.base; ifbdev->helper.fb = fb; ifbdev->helper.fbdev = info; strcpy(info->fix.id, "inteldrmfb"); info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT; info->fbops = &intelfb_ops; ret = fb_alloc_cmap(&info->cmap, 256, 0); if (ret) { ret = -ENOMEM; goto out_unpin; } /* setup aperture base/size for vesafb takeover */ info->aperture_base = dev->mode_config.fb_base; if (!IS_GEN2(dev)) info->aperture_size = pci_resource_len(dev->pdev, 2); else info->aperture_size = pci_resource_len(dev->pdev, 0); info->fix.smem_start = dev->mode_config.fb_base + obj->gtt_offset; info->fix.smem_len = size; info->screen_base = ioremap_wc(dev->agp->base + obj->gtt_offset, size); if (!info->screen_base) { ret = -ENOSPC; goto out_unpin; } info->screen_size = size; // memset(info->screen_base, 0, size); drm_fb_helper_fill_fix(info, fb->pitch, fb->depth); drm_fb_helper_fill_var(info, &ifbdev->helper, sizes->fb_width, sizes->fb_height); info->pixmap.size = 64*1024; info->pixmap.buf_align = 8; info->pixmap.access_align = 32; info->pixmap.flags = FB_PIXMAP_SYSTEM; info->pixmap.scan_align = 1; DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08x, bo %p\n", fb->width, fb->height, obj->gtt_offset, obj); mutex_unlock(&dev->struct_mutex); vga_switcheroo_client_fb_set(dev->pdev, info); return 0; out_unpin: i915_gem_object_unpin(obj); out_unref: drm_gem_object_unreference(&obj->base); mutex_unlock(&dev->struct_mutex); out: return ret; }
/** * Detects bit 6 swizzling of address lookup between IGD access and CPU * access through main memory. */ void i915_gem_detect_bit_6_swizzle(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; uint32_t swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN; uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; if (INTEL_INFO(dev)->gen >= 8 || IS_VALLEYVIEW(dev)) { /* * On BDW+, swizzling is not used. We leave the CPU memory * controller in charge of optimizing memory accesses without * the extra address manipulation GPU side. * * VLV and CHV don't have GPU swizzling. */ swizzle_x = I915_BIT_6_SWIZZLE_NONE; swizzle_y = I915_BIT_6_SWIZZLE_NONE; } else if (INTEL_INFO(dev)->gen >= 6) { uint32_t dimm_c0, dimm_c1; dimm_c0 = I915_READ(MAD_DIMM_C0); dimm_c1 = I915_READ(MAD_DIMM_C1); dimm_c0 &= MAD_DIMM_A_SIZE_MASK | MAD_DIMM_B_SIZE_MASK; dimm_c1 &= MAD_DIMM_A_SIZE_MASK | MAD_DIMM_B_SIZE_MASK; /* Enable swizzling when the channels are populated with * identically sized dimms. We don't need to check the 3rd * channel because no cpu with gpu attached ships in that * configuration. Also, swizzling only makes sense for 2 * channels anyway. */ if (dimm_c0 == dimm_c1) { swizzle_x = I915_BIT_6_SWIZZLE_9_10; swizzle_y = I915_BIT_6_SWIZZLE_9; } else { swizzle_x = I915_BIT_6_SWIZZLE_NONE; swizzle_y = I915_BIT_6_SWIZZLE_NONE; } } else if (IS_GEN5(dev)) { /* On Ironlake whatever DRAM config, GPU always do * same swizzling setup. */ swizzle_x = I915_BIT_6_SWIZZLE_9_10; swizzle_y = I915_BIT_6_SWIZZLE_9; } else if (IS_GEN2(dev)) { /* As far as we know, the 865 doesn't have these bit 6 * swizzling issues. */ swizzle_x = I915_BIT_6_SWIZZLE_NONE; swizzle_y = I915_BIT_6_SWIZZLE_NONE; } else if (IS_MOBILE(dev) || (IS_GEN3(dev) && !IS_G33(dev))) { uint32_t dcc; /* On 9xx chipsets, channel interleave by the CPU is * determined by DCC. For single-channel, neither the CPU * nor the GPU do swizzling. For dual channel interleaved, * the GPU's interleave is bit 9 and 10 for X tiled, and bit * 9 for Y tiled. The CPU's interleave is independent, and * can be based on either bit 11 (haven't seen this yet) or * bit 17 (common). */ dcc = I915_READ(DCC); switch (dcc & DCC_ADDRESSING_MODE_MASK) { case DCC_ADDRESSING_MODE_SINGLE_CHANNEL: case DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC: swizzle_x = I915_BIT_6_SWIZZLE_NONE; swizzle_y = I915_BIT_6_SWIZZLE_NONE; break; case DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED: if (dcc & DCC_CHANNEL_XOR_DISABLE) { /* This is the base swizzling by the GPU for * tiled buffers. */ swizzle_x = I915_BIT_6_SWIZZLE_9_10; swizzle_y = I915_BIT_6_SWIZZLE_9; } else if ((dcc & DCC_CHANNEL_XOR_BIT_17) == 0) { /* Bit 11 swizzling by the CPU in addition. */ swizzle_x = I915_BIT_6_SWIZZLE_9_10_11; swizzle_y = I915_BIT_6_SWIZZLE_9_11; } else { /* Bit 17 swizzling by the CPU in addition. */ swizzle_x = I915_BIT_6_SWIZZLE_9_10_17; swizzle_y = I915_BIT_6_SWIZZLE_9_17; } break; } if (dcc == 0xffffffff) { DRM_ERROR("Couldn't read from MCHBAR. " "Disabling tiling.\n"); swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN; swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; } } else { /* The 965, G33, and newer, have a very flexible memory * configuration. It will enable dual-channel mode * (interleaving) on as much memory as it can, and the GPU * will additionally sometimes enable different bit 6 * swizzling for tiled objects from the CPU. * * Here's what I found on the G965: * slot fill memory size swizzling * 0A 0B 1A 1B 1-ch 2-ch * 512 0 0 0 512 0 O * 512 0 512 0 16 1008 X * 512 0 0 512 16 1008 X * 0 512 0 512 16 1008 X * 1024 1024 1024 0 2048 1024 O * * We could probably detect this based on either the DRB * matching, which was the case for the swizzling required in * the table above, or from the 1-ch value being less than * the minimum size of a rank. */ if (I915_READ16(C0DRB3) != I915_READ16(C1DRB3)) { swizzle_x = I915_BIT_6_SWIZZLE_NONE; swizzle_y = I915_BIT_6_SWIZZLE_NONE; } else { swizzle_x = I915_BIT_6_SWIZZLE_9_10; swizzle_y = I915_BIT_6_SWIZZLE_9; } } dev_priv->mm.bit_6_swizzle_x = swizzle_x; dev_priv->mm.bit_6_swizzle_y = swizzle_y; }
void init_instdone_definitions(uint32_t devid) { if (IS_GEN7(devid)) { init_gen7_instdone(); } else if (IS_GEN6(devid)) { /* Now called INSTDONE_1 in the docs. */ gen6_instdone1_bit(GEN6_MA_3_DONE, "Message Arbiter 3"); gen6_instdone1_bit(GEN6_EU_32_DONE, "EU 32"); gen6_instdone1_bit(GEN6_EU_31_DONE, "EU 31"); gen6_instdone1_bit(GEN6_EU_30_DONE, "EU 30"); gen6_instdone1_bit(GEN6_MA_3_DONE, "Message Arbiter 2"); gen6_instdone1_bit(GEN6_EU_22_DONE, "EU 22"); gen6_instdone1_bit(GEN6_EU_21_DONE, "EU 21"); gen6_instdone1_bit(GEN6_EU_20_DONE, "EU 20"); gen6_instdone1_bit(GEN6_MA_3_DONE, "Message Arbiter 1"); gen6_instdone1_bit(GEN6_EU_12_DONE, "EU 12"); gen6_instdone1_bit(GEN6_EU_11_DONE, "EU 11"); gen6_instdone1_bit(GEN6_EU_10_DONE, "EU 10"); gen6_instdone1_bit(GEN6_MA_3_DONE, "Message Arbiter 0"); gen6_instdone1_bit(GEN6_EU_02_DONE, "EU 02"); gen6_instdone1_bit(GEN6_EU_01_DONE, "EU 01"); gen6_instdone1_bit(GEN6_EU_00_DONE, "EU 00"); gen6_instdone1_bit(GEN6_IC_3_DONE, "IC 3"); gen6_instdone1_bit(GEN6_IC_2_DONE, "IC 2"); gen6_instdone1_bit(GEN6_IC_1_DONE, "IC 1"); gen6_instdone1_bit(GEN6_IC_0_DONE, "IC 0"); gen6_instdone1_bit(GEN6_ISC_10_DONE, "ISC 1/0"); gen6_instdone1_bit(GEN6_ISC_32_DONE, "ISC 3/2"); gen6_instdone1_bit(GEN6_VSC_DONE, "VSC"); gen6_instdone1_bit(GEN6_IEF_DONE, "IEF"); gen6_instdone1_bit(GEN6_VFE_DONE, "VFE"); gen6_instdone1_bit(GEN6_TD_DONE, "TD"); gen6_instdone1_bit(GEN6_TS_DONE, "TS"); gen6_instdone1_bit(GEN6_GW_DONE, "GW"); gen6_instdone1_bit(GEN6_HIZ_DONE, "HIZ"); gen6_instdone1_bit(GEN6_AVS_DONE, "AVS"); /* Now called INSTDONE_2 in the docs. */ gen6_instdone2_bit(GEN6_GAM_DONE, "GAM"); gen6_instdone2_bit(GEN6_CS_DONE, "CS"); gen6_instdone2_bit(GEN6_WMBE_DONE, "WMBE"); gen6_instdone2_bit(GEN6_SVRW_DONE, "SVRW"); gen6_instdone2_bit(GEN6_RCC_DONE, "RCC"); gen6_instdone2_bit(GEN6_SVG_DONE, "SVG"); gen6_instdone2_bit(GEN6_ISC_DONE, "ISC"); gen6_instdone2_bit(GEN6_MT_DONE, "MT"); gen6_instdone2_bit(GEN6_RCPFE_DONE, "RCPFE"); gen6_instdone2_bit(GEN6_RCPBE_DONE, "RCPBE"); gen6_instdone2_bit(GEN6_VDI_DONE, "VDI"); gen6_instdone2_bit(GEN6_RCZ_DONE, "RCZ"); gen6_instdone2_bit(GEN6_DAP_DONE, "DAP"); gen6_instdone2_bit(GEN6_PSD_DONE, "PSD"); gen6_instdone2_bit(GEN6_IZ_DONE, "IZ"); gen6_instdone2_bit(GEN6_WMFE_DONE, "WMFE"); gen6_instdone2_bit(GEN6_SVSM_DONE, "SVSM"); gen6_instdone2_bit(GEN6_QC_DONE, "QC"); gen6_instdone2_bit(GEN6_FL_DONE, "FL"); gen6_instdone2_bit(GEN6_SC_DONE, "SC"); gen6_instdone2_bit(GEN6_DM_DONE, "DM"); gen6_instdone2_bit(GEN6_FT_DONE, "FT"); gen6_instdone2_bit(GEN6_DG_DONE, "DG"); gen6_instdone2_bit(GEN6_SI_DONE, "SI"); gen6_instdone2_bit(GEN6_SO_DONE, "SO"); gen6_instdone2_bit(GEN6_PL_DONE, "PL"); gen6_instdone2_bit(GEN6_VME_DONE, "VME"); gen6_instdone2_bit(GEN6_SF_DONE, "SF"); gen6_instdone2_bit(GEN6_CL_DONE, "CL"); gen6_instdone2_bit(GEN6_GS_DONE, "GS"); gen6_instdone2_bit(GEN6_VS0_DONE, "VS0"); gen6_instdone2_bit(GEN6_VF_DONE, "VF"); } else if (IS_GEN5(devid)) { gen4_instdone_bit(ILK_ROW_0_EU_0_DONE, "Row 0, EU 0"); gen4_instdone_bit(ILK_ROW_0_EU_1_DONE, "Row 0, EU 1"); gen4_instdone_bit(ILK_ROW_0_EU_2_DONE, "Row 0, EU 2"); gen4_instdone_bit(ILK_ROW_0_EU_3_DONE, "Row 0, EU 3"); gen4_instdone_bit(ILK_ROW_1_EU_0_DONE, "Row 1, EU 0"); gen4_instdone_bit(ILK_ROW_1_EU_1_DONE, "Row 1, EU 1"); gen4_instdone_bit(ILK_ROW_1_EU_2_DONE, "Row 1, EU 2"); gen4_instdone_bit(ILK_ROW_1_EU_3_DONE, "Row 1, EU 3"); gen4_instdone_bit(ILK_ROW_2_EU_0_DONE, "Row 2, EU 0"); gen4_instdone_bit(ILK_ROW_2_EU_1_DONE, "Row 2, EU 1"); gen4_instdone_bit(ILK_ROW_2_EU_2_DONE, "Row 2, EU 2"); gen4_instdone_bit(ILK_ROW_2_EU_3_DONE, "Row 2, EU 3"); gen4_instdone_bit(ILK_VCP_DONE, "VCP"); gen4_instdone_bit(ILK_ROW_0_MATH_DONE, "Row 0 math"); gen4_instdone_bit(ILK_ROW_1_MATH_DONE, "Row 1 math"); gen4_instdone_bit(ILK_ROW_2_MATH_DONE, "Row 2 math"); gen4_instdone_bit(ILK_VC1_DONE, "VC1"); gen4_instdone_bit(ILK_ROW_0_MA_DONE, "Row 0 MA"); gen4_instdone_bit(ILK_ROW_1_MA_DONE, "Row 1 MA"); gen4_instdone_bit(ILK_ROW_2_MA_DONE, "Row 2 MA"); gen4_instdone_bit(ILK_ROW_0_ISC_DONE, "Row 0 ISC"); gen4_instdone_bit(ILK_ROW_1_ISC_DONE, "Row 1 ISC"); gen4_instdone_bit(ILK_ROW_2_ISC_DONE, "Row 2 ISC"); gen4_instdone_bit(ILK_VFE_DONE, "VFE"); gen4_instdone_bit(ILK_TD_DONE, "TD"); gen4_instdone_bit(ILK_SVTS_DONE, "SVTS"); gen4_instdone_bit(ILK_TS_DONE, "TS"); gen4_instdone_bit(ILK_GW_DONE, "GW"); gen4_instdone_bit(ILK_AI_DONE, "AI"); gen4_instdone_bit(ILK_AC_DONE, "AC"); gen4_instdone_bit(ILK_AM_DONE, "AM"); init_g4x_instdone1(); } else if (IS_GEN4(devid)) { gen4_instdone_bit(I965_ROW_0_EU_0_DONE, "Row 0, EU 0"); gen4_instdone_bit(I965_ROW_0_EU_1_DONE, "Row 0, EU 1"); gen4_instdone_bit(I965_ROW_0_EU_2_DONE, "Row 0, EU 2"); gen4_instdone_bit(I965_ROW_0_EU_3_DONE, "Row 0, EU 3"); gen4_instdone_bit(I965_ROW_1_EU_0_DONE, "Row 1, EU 0"); gen4_instdone_bit(I965_ROW_1_EU_1_DONE, "Row 1, EU 1"); gen4_instdone_bit(I965_ROW_1_EU_2_DONE, "Row 1, EU 2"); gen4_instdone_bit(I965_ROW_1_EU_3_DONE, "Row 1, EU 3"); gen4_instdone_bit(I965_SF_DONE, "Strips and Fans"); gen4_instdone_bit(I965_SE_DONE, "Setup Engine"); gen4_instdone_bit(I965_WM_DONE, "Windowizer"); gen4_instdone_bit(I965_DISPATCHER_DONE, "Dispatcher"); gen4_instdone_bit(I965_PROJECTION_DONE, "Projection and LOD"); gen4_instdone_bit(I965_DG_DONE, "Dependent address generator"); gen4_instdone_bit(I965_QUAD_CACHE_DONE, "Texture fetch"); gen4_instdone_bit(I965_TEXTURE_FETCH_DONE, "Texture fetch"); gen4_instdone_bit(I965_TEXTURE_DECOMPRESS_DONE, "Texture decompress"); gen4_instdone_bit(I965_SAMPLER_CACHE_DONE, "Sampler cache"); gen4_instdone_bit(I965_FILTER_DONE, "Filtering"); gen4_instdone_bit(I965_BYPASS_DONE, "Bypass FIFO"); gen4_instdone_bit(I965_PS_DONE, "Pixel shader"); gen4_instdone_bit(I965_CC_DONE, "Color calculator"); gen4_instdone_bit(I965_MAP_FILTER_DONE, "Map filter"); gen4_instdone_bit(I965_MAP_L2_IDLE, "Map L2"); gen4_instdone_bit(I965_MA_ROW_0_DONE, "Message Arbiter row 0"); gen4_instdone_bit(I965_MA_ROW_1_DONE, "Message Arbiter row 1"); gen4_instdone_bit(I965_IC_ROW_0_DONE, "Instruction cache row 0"); gen4_instdone_bit(I965_IC_ROW_1_DONE, "Instruction cache row 1"); gen4_instdone_bit(I965_CP_DONE, "Command Processor"); if (IS_G4X(devid)) { init_g4x_instdone1(); } else { init_g965_instdone1(); } } else if (IS_GEN3(devid)) { gen3_instdone_bit(IDCT_DONE, "IDCT"); gen3_instdone_bit(IQ_DONE, "IQ"); gen3_instdone_bit(PR_DONE, "PR"); gen3_instdone_bit(VLD_DONE, "VLD"); gen3_instdone_bit(IP_DONE, "Instruction parser"); gen3_instdone_bit(FBC_DONE, "Framebuffer Compression"); gen3_instdone_bit(BINNER_DONE, "Binner"); gen3_instdone_bit(SF_DONE, "Strips and fans"); gen3_instdone_bit(SE_DONE, "Setup engine"); gen3_instdone_bit(WM_DONE, "Windowizer"); gen3_instdone_bit(IZ_DONE, "Intermediate Z"); gen3_instdone_bit(PERSPECTIVE_INTERP_DONE, "Perspective interpolation"); gen3_instdone_bit(DISPATCHER_DONE, "Dispatcher"); gen3_instdone_bit(PROJECTION_DONE, "Projection and LOD"); gen3_instdone_bit(DEPENDENT_ADDRESS_DONE, "Dependent address calculation"); gen3_instdone_bit(TEXTURE_FETCH_DONE, "Texture fetch"); gen3_instdone_bit(TEXTURE_DECOMPRESS_DONE, "Texture decompression"); gen3_instdone_bit(SAMPLER_CACHE_DONE, "Sampler Cache"); gen3_instdone_bit(FILTER_DONE, "Filtering"); gen3_instdone_bit(BYPASS_FIFO_DONE, "Bypass FIFO"); gen3_instdone_bit(PS_DONE, "Pixel shader"); gen3_instdone_bit(CC_DONE, "Color calculator"); gen3_instdone_bit(MAP_FILTER_DONE, "Map filter"); gen3_instdone_bit(MAP_L2_IDLE, "Map L2"); } else { assert(IS_GEN2(devid)); gen3_instdone_bit(I830_GMBUS_DONE, "GMBUS"); gen3_instdone_bit(I830_FBC_DONE, "FBC"); gen3_instdone_bit(I830_BINNER_DONE, "BINNER"); gen3_instdone_bit(I830_MPEG_DONE, "MPEG"); gen3_instdone_bit(I830_MECO_DONE, "MECO"); gen3_instdone_bit(I830_MCD_DONE, "MCD"); gen3_instdone_bit(I830_MCSTP_DONE, "MCSTP"); gen3_instdone_bit(I830_CC_DONE, "CC"); gen3_instdone_bit(I830_DG_DONE, "DG"); gen3_instdone_bit(I830_DCMP_DONE, "DCMP"); gen3_instdone_bit(I830_FTCH_DONE, "FTCH"); gen3_instdone_bit(I830_IT_DONE, "IT"); gen3_instdone_bit(I830_MG_DONE, "MG"); gen3_instdone_bit(I830_MEC_DONE, "MEC"); gen3_instdone_bit(I830_PC_DONE, "PC"); gen3_instdone_bit(I830_QCC_DONE, "QCC"); gen3_instdone_bit(I830_TB_DONE, "TB"); gen3_instdone_bit(I830_WM_DONE, "WM"); gen3_instdone_bit(I830_EF_DONE, "EF"); gen3_instdone_bit(I830_BLITTER_DONE, "Blitter"); gen3_instdone_bit(I830_MAP_L2_DONE, "Map L2 cache"); gen3_instdone_bit(I830_SECONDARY_RING_3_DONE, "Secondary ring 3"); gen3_instdone_bit(I830_SECONDARY_RING_2_DONE, "Secondary ring 2"); gen3_instdone_bit(I830_SECONDARY_RING_1_DONE, "Secondary ring 1"); gen3_instdone_bit(I830_SECONDARY_RING_0_DONE, "Secondary ring 0"); gen3_instdone_bit(I830_PRIMARY_RING_1_DONE, "Primary ring 1"); gen3_instdone_bit(I830_PRIMARY_RING_0_DONE, "Primary ring 0"); } }
void i915_save_display_reg(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; int i; /* Cursor state */ dev_priv->regfile.saveCURACNTR = I915_READ(_CURACNTR); dev_priv->regfile.saveCURAPOS = I915_READ(_CURAPOS); dev_priv->regfile.saveCURABASE = I915_READ(_CURABASE); dev_priv->regfile.saveCURBCNTR = I915_READ(_CURBCNTR); dev_priv->regfile.saveCURBPOS = I915_READ(_CURBPOS); dev_priv->regfile.saveCURBBASE = I915_READ(_CURBBASE); if (IS_GEN2(dev)) dev_priv->regfile.saveCURSIZE = I915_READ(CURSIZE); if (HAS_PCH_SPLIT(dev)) { dev_priv->regfile.savePCH_DREF_CONTROL = I915_READ(PCH_DREF_CONTROL); dev_priv->regfile.saveDISP_ARB_CTL = I915_READ(DISP_ARB_CTL); } /* Pipe & plane A info */ dev_priv->regfile.savePIPEACONF = I915_READ(_PIPEACONF); dev_priv->regfile.savePIPEASRC = I915_READ(_PIPEASRC); if (HAS_PCH_SPLIT(dev)) { dev_priv->regfile.saveFPA0 = I915_READ(_PCH_FPA0); dev_priv->regfile.saveFPA1 = I915_READ(_PCH_FPA1); dev_priv->regfile.saveDPLL_A = I915_READ(_PCH_DPLL_A); } else { dev_priv->regfile.saveFPA0 = I915_READ(_FPA0); dev_priv->regfile.saveFPA1 = I915_READ(_FPA1); dev_priv->regfile.saveDPLL_A = I915_READ(_DPLL_A); } if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) dev_priv->regfile.saveDPLL_A_MD = I915_READ(_DPLL_A_MD); dev_priv->regfile.saveHTOTAL_A = I915_READ(_HTOTAL_A); dev_priv->regfile.saveHBLANK_A = I915_READ(_HBLANK_A); dev_priv->regfile.saveHSYNC_A = I915_READ(_HSYNC_A); dev_priv->regfile.saveVTOTAL_A = I915_READ(_VTOTAL_A); dev_priv->regfile.saveVBLANK_A = I915_READ(_VBLANK_A); dev_priv->regfile.saveVSYNC_A = I915_READ(_VSYNC_A); if (!HAS_PCH_SPLIT(dev)) dev_priv->regfile.saveBCLRPAT_A = I915_READ(_BCLRPAT_A); if (HAS_PCH_SPLIT(dev)) { dev_priv->regfile.savePIPEA_DATA_M1 = I915_READ(_PIPEA_DATA_M1); dev_priv->regfile.savePIPEA_DATA_N1 = I915_READ(_PIPEA_DATA_N1); dev_priv->regfile.savePIPEA_LINK_M1 = I915_READ(_PIPEA_LINK_M1); dev_priv->regfile.savePIPEA_LINK_N1 = I915_READ(_PIPEA_LINK_N1); dev_priv->regfile.saveFDI_TXA_CTL = I915_READ(_FDI_TXA_CTL); dev_priv->regfile.saveFDI_RXA_CTL = I915_READ(_FDI_RXA_CTL); dev_priv->regfile.savePFA_CTL_1 = I915_READ(_PFA_CTL_1); dev_priv->regfile.savePFA_WIN_SZ = I915_READ(_PFA_WIN_SZ); dev_priv->regfile.savePFA_WIN_POS = I915_READ(_PFA_WIN_POS); dev_priv->regfile.saveTRANSACONF = I915_READ(_PCH_TRANSACONF); dev_priv->regfile.saveTRANS_HTOTAL_A = I915_READ(_PCH_TRANS_HTOTAL_A); dev_priv->regfile.saveTRANS_HBLANK_A = I915_READ(_PCH_TRANS_HBLANK_A); dev_priv->regfile.saveTRANS_HSYNC_A = I915_READ(_PCH_TRANS_HSYNC_A); dev_priv->regfile.saveTRANS_VTOTAL_A = I915_READ(_PCH_TRANS_VTOTAL_A); dev_priv->regfile.saveTRANS_VBLANK_A = I915_READ(_PCH_TRANS_VBLANK_A); dev_priv->regfile.saveTRANS_VSYNC_A = I915_READ(_PCH_TRANS_VSYNC_A); } dev_priv->regfile.saveDSPACNTR = I915_READ(_DSPACNTR); dev_priv->regfile.saveDSPASTRIDE = I915_READ(_DSPASTRIDE); dev_priv->regfile.saveDSPASIZE = I915_READ(_DSPASIZE); dev_priv->regfile.saveDSPAPOS = I915_READ(_DSPAPOS); dev_priv->regfile.saveDSPAADDR = I915_READ(_DSPAADDR); if (INTEL_INFO(dev)->gen >= 4) { dev_priv->regfile.saveDSPASURF = I915_READ(_DSPASURF); dev_priv->regfile.saveDSPATILEOFF = I915_READ(_DSPATILEOFF); } i915_save_palette(dev, PIPE_A); dev_priv->regfile.savePIPEASTAT = I915_READ(_PIPEASTAT); /* Pipe & plane B info */ dev_priv->regfile.savePIPEBCONF = I915_READ(_PIPEBCONF); dev_priv->regfile.savePIPEBSRC = I915_READ(_PIPEBSRC); if (HAS_PCH_SPLIT(dev)) { dev_priv->regfile.saveFPB0 = I915_READ(_PCH_FPB0); dev_priv->regfile.saveFPB1 = I915_READ(_PCH_FPB1); dev_priv->regfile.saveDPLL_B = I915_READ(_PCH_DPLL_B); } else { dev_priv->regfile.saveFPB0 = I915_READ(_FPB0); dev_priv->regfile.saveFPB1 = I915_READ(_FPB1); dev_priv->regfile.saveDPLL_B = I915_READ(_DPLL_B); } if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) dev_priv->regfile.saveDPLL_B_MD = I915_READ(_DPLL_B_MD); dev_priv->regfile.saveHTOTAL_B = I915_READ(_HTOTAL_B); dev_priv->regfile.saveHBLANK_B = I915_READ(_HBLANK_B); dev_priv->regfile.saveHSYNC_B = I915_READ(_HSYNC_B); dev_priv->regfile.saveVTOTAL_B = I915_READ(_VTOTAL_B); dev_priv->regfile.saveVBLANK_B = I915_READ(_VBLANK_B); dev_priv->regfile.saveVSYNC_B = I915_READ(_VSYNC_B); if (!HAS_PCH_SPLIT(dev)) dev_priv->regfile.saveBCLRPAT_B = I915_READ(_BCLRPAT_B); if (HAS_PCH_SPLIT(dev)) { dev_priv->regfile.savePIPEB_DATA_M1 = I915_READ(_PIPEB_DATA_M1); dev_priv->regfile.savePIPEB_DATA_N1 = I915_READ(_PIPEB_DATA_N1); dev_priv->regfile.savePIPEB_LINK_M1 = I915_READ(_PIPEB_LINK_M1); dev_priv->regfile.savePIPEB_LINK_N1 = I915_READ(_PIPEB_LINK_N1); dev_priv->regfile.saveFDI_TXB_CTL = I915_READ(_FDI_TXB_CTL); dev_priv->regfile.saveFDI_RXB_CTL = I915_READ(_FDI_RXB_CTL); dev_priv->regfile.savePFB_CTL_1 = I915_READ(_PFB_CTL_1); dev_priv->regfile.savePFB_WIN_SZ = I915_READ(_PFB_WIN_SZ); dev_priv->regfile.savePFB_WIN_POS = I915_READ(_PFB_WIN_POS); dev_priv->regfile.saveTRANSBCONF = I915_READ(_PCH_TRANSBCONF); dev_priv->regfile.saveTRANS_HTOTAL_B = I915_READ(_PCH_TRANS_HTOTAL_B); dev_priv->regfile.saveTRANS_HBLANK_B = I915_READ(_PCH_TRANS_HBLANK_B); dev_priv->regfile.saveTRANS_HSYNC_B = I915_READ(_PCH_TRANS_HSYNC_B); dev_priv->regfile.saveTRANS_VTOTAL_B = I915_READ(_PCH_TRANS_VTOTAL_B); dev_priv->regfile.saveTRANS_VBLANK_B = I915_READ(_PCH_TRANS_VBLANK_B); dev_priv->regfile.saveTRANS_VSYNC_B = I915_READ(_PCH_TRANS_VSYNC_B); } dev_priv->regfile.saveDSPBCNTR = I915_READ(_DSPBCNTR); dev_priv->regfile.saveDSPBSTRIDE = I915_READ(_DSPBSTRIDE); dev_priv->regfile.saveDSPBSIZE = I915_READ(_DSPBSIZE); dev_priv->regfile.saveDSPBPOS = I915_READ(_DSPBPOS); dev_priv->regfile.saveDSPBADDR = I915_READ(_DSPBADDR); if (INTEL_INFO(dev)->gen >= 4) { dev_priv->regfile.saveDSPBSURF = I915_READ(_DSPBSURF); dev_priv->regfile.saveDSPBTILEOFF = I915_READ(_DSPBTILEOFF); } i915_save_palette(dev, PIPE_B); dev_priv->regfile.savePIPEBSTAT = I915_READ(_PIPEBSTAT); /* Fences */ switch (INTEL_INFO(dev)->gen) { case 7: case 6: for (i = 0; i < 16; i++) dev_priv->regfile.saveFENCE[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); break; case 5: case 4: for (i = 0; i < 16; i++) dev_priv->regfile.saveFENCE[i] = I915_READ64(FENCE_REG_965_0 + (i * 8)); break; case 3: if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) for (i = 0; i < 8; i++) dev_priv->regfile.saveFENCE[i+8] = I915_READ(FENCE_REG_945_8 + (i * 4)); case 2: for (i = 0; i < 8; i++) dev_priv->regfile.saveFENCE[i] = I915_READ(FENCE_REG_830_0 + (i * 4)); break; } /* CRT state */ if (HAS_PCH_SPLIT(dev)) dev_priv->regfile.saveADPA = I915_READ(PCH_ADPA); else dev_priv->regfile.saveADPA = I915_READ(ADPA); /* Display Port state */ if (SUPPORTS_INTEGRATED_DP(dev)) { dev_priv->regfile.saveDP_B = I915_READ(DP_B); dev_priv->regfile.saveDP_C = I915_READ(DP_C); dev_priv->regfile.saveDP_D = I915_READ(DP_D); dev_priv->regfile.savePIPEA_GMCH_DATA_M = I915_READ(_PIPEA_DATA_M_G4X); dev_priv->regfile.savePIPEB_GMCH_DATA_M = I915_READ(_PIPEB_DATA_M_G4X); dev_priv->regfile.savePIPEA_GMCH_DATA_N = I915_READ(_PIPEA_DATA_N_G4X); dev_priv->regfile.savePIPEB_GMCH_DATA_N = I915_READ(_PIPEB_DATA_N_G4X); dev_priv->regfile.savePIPEA_DP_LINK_M = I915_READ(_PIPEA_LINK_M_G4X); dev_priv->regfile.savePIPEB_DP_LINK_M = I915_READ(_PIPEB_LINK_M_G4X); dev_priv->regfile.savePIPEA_DP_LINK_N = I915_READ(_PIPEA_LINK_N_G4X); dev_priv->regfile.savePIPEB_DP_LINK_N = I915_READ(_PIPEB_LINK_N_G4X); } /* FIXME: regfile.save TV & SDVO state */ /* Backlight */ if (HAS_PCH_SPLIT(dev)) { dev_priv->regfile.saveBLC_PWM_CTL = I915_READ(BLC_PWM_PCH_CTL1); dev_priv->regfile.saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_PCH_CTL2); dev_priv->regfile.saveBLC_CPU_PWM_CTL = I915_READ(BLC_PWM_CPU_CTL); dev_priv->regfile.saveBLC_CPU_PWM_CTL2 = I915_READ(BLC_PWM_CPU_CTL2); } else { dev_priv->regfile.saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL); if (INTEL_INFO(dev)->gen >= 4) dev_priv->regfile.saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2); } return; }
void i915_restore_display_reg(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; int dpll_a_reg, fpa0_reg, fpa1_reg; int dpll_b_reg, fpb0_reg, fpb1_reg; int i; /* Backlight */ if (HAS_PCH_SPLIT(dev)) { I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->regfile.saveBLC_PWM_CTL); I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->regfile.saveBLC_PWM_CTL2); /* NOTE: BLC_PWM_CPU_CTL must be written after BLC_PWM_CPU_CTL2; * otherwise we get blank eDP screen after S3 on some machines */ I915_WRITE(BLC_PWM_CPU_CTL2, dev_priv->regfile.saveBLC_CPU_PWM_CTL2); I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->regfile.saveBLC_CPU_PWM_CTL); } else { if (INTEL_INFO(dev)->gen >= 4) I915_WRITE(BLC_PWM_CTL2, dev_priv->regfile.saveBLC_PWM_CTL2); I915_WRITE(BLC_PWM_CTL, dev_priv->regfile.saveBLC_PWM_CTL); } /* Display port ratios (must be done before clock is set) */ if (SUPPORTS_INTEGRATED_DP(dev)) { I915_WRITE(_PIPEA_DATA_M_G4X, dev_priv->regfile.savePIPEA_GMCH_DATA_M); I915_WRITE(_PIPEB_DATA_M_G4X, dev_priv->regfile.savePIPEB_GMCH_DATA_M); I915_WRITE(_PIPEA_DATA_N_G4X, dev_priv->regfile.savePIPEA_GMCH_DATA_N); I915_WRITE(_PIPEB_DATA_N_G4X, dev_priv->regfile.savePIPEB_GMCH_DATA_N); I915_WRITE(_PIPEA_LINK_M_G4X, dev_priv->regfile.savePIPEA_DP_LINK_M); I915_WRITE(_PIPEB_LINK_M_G4X, dev_priv->regfile.savePIPEB_DP_LINK_M); I915_WRITE(_PIPEA_LINK_N_G4X, dev_priv->regfile.savePIPEA_DP_LINK_N); I915_WRITE(_PIPEB_LINK_N_G4X, dev_priv->regfile.savePIPEB_DP_LINK_N); } /* Fences */ switch (INTEL_INFO(dev)->gen) { case 7: case 6: for (i = 0; i < 16; i++) I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (i * 8), dev_priv->regfile.saveFENCE[i]); break; case 5: case 4: for (i = 0; i < 16; i++) I915_WRITE64(FENCE_REG_965_0 + (i * 8), dev_priv->regfile.saveFENCE[i]); break; case 3: case 2: if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) for (i = 0; i < 8; i++) I915_WRITE(FENCE_REG_945_8 + (i * 4), dev_priv->regfile.saveFENCE[i+8]); for (i = 0; i < 8; i++) I915_WRITE(FENCE_REG_830_0 + (i * 4), dev_priv->regfile.saveFENCE[i]); break; } if (HAS_PCH_SPLIT(dev)) { dpll_a_reg = _PCH_DPLL_A; dpll_b_reg = _PCH_DPLL_B; fpa0_reg = _PCH_FPA0; fpb0_reg = _PCH_FPB0; fpa1_reg = _PCH_FPA1; fpb1_reg = _PCH_FPB1; } else { dpll_a_reg = _DPLL_A; dpll_b_reg = _DPLL_B; fpa0_reg = _FPA0; fpb0_reg = _FPB0; fpa1_reg = _FPA1; fpb1_reg = _FPB1; } if (HAS_PCH_SPLIT(dev)) { I915_WRITE(PCH_DREF_CONTROL, dev_priv->regfile.savePCH_DREF_CONTROL); I915_WRITE(DISP_ARB_CTL, dev_priv->regfile.saveDISP_ARB_CTL); } /* Pipe & plane A info */ /* Prime the clock */ if (dev_priv->regfile.saveDPLL_A & DPLL_VCO_ENABLE) { I915_WRITE(dpll_a_reg, dev_priv->regfile.saveDPLL_A & ~DPLL_VCO_ENABLE); POSTING_READ(dpll_a_reg); udelay(150); } I915_WRITE(fpa0_reg, dev_priv->regfile.saveFPA0); I915_WRITE(fpa1_reg, dev_priv->regfile.saveFPA1); /* Actually enable it */ I915_WRITE(dpll_a_reg, dev_priv->regfile.saveDPLL_A); POSTING_READ(dpll_a_reg); udelay(150); if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) { I915_WRITE(_DPLL_A_MD, dev_priv->regfile.saveDPLL_A_MD); POSTING_READ(_DPLL_A_MD); } udelay(150); /* Restore mode */ I915_WRITE(_HTOTAL_A, dev_priv->regfile.saveHTOTAL_A); I915_WRITE(_HBLANK_A, dev_priv->regfile.saveHBLANK_A); I915_WRITE(_HSYNC_A, dev_priv->regfile.saveHSYNC_A); I915_WRITE(_VTOTAL_A, dev_priv->regfile.saveVTOTAL_A); I915_WRITE(_VBLANK_A, dev_priv->regfile.saveVBLANK_A); I915_WRITE(_VSYNC_A, dev_priv->regfile.saveVSYNC_A); if (!HAS_PCH_SPLIT(dev)) I915_WRITE(_BCLRPAT_A, dev_priv->regfile.saveBCLRPAT_A); if (HAS_PCH_SPLIT(dev)) { I915_WRITE(_PIPEA_DATA_M1, dev_priv->regfile.savePIPEA_DATA_M1); I915_WRITE(_PIPEA_DATA_N1, dev_priv->regfile.savePIPEA_DATA_N1); I915_WRITE(_PIPEA_LINK_M1, dev_priv->regfile.savePIPEA_LINK_M1); I915_WRITE(_PIPEA_LINK_N1, dev_priv->regfile.savePIPEA_LINK_N1); I915_WRITE(_FDI_RXA_CTL, dev_priv->regfile.saveFDI_RXA_CTL); I915_WRITE(_FDI_TXA_CTL, dev_priv->regfile.saveFDI_TXA_CTL); I915_WRITE(_PFA_CTL_1, dev_priv->regfile.savePFA_CTL_1); I915_WRITE(_PFA_WIN_SZ, dev_priv->regfile.savePFA_WIN_SZ); I915_WRITE(_PFA_WIN_POS, dev_priv->regfile.savePFA_WIN_POS); I915_WRITE(_PCH_TRANSACONF, dev_priv->regfile.saveTRANSACONF); I915_WRITE(_PCH_TRANS_HTOTAL_A, dev_priv->regfile.saveTRANS_HTOTAL_A); I915_WRITE(_PCH_TRANS_HBLANK_A, dev_priv->regfile.saveTRANS_HBLANK_A); I915_WRITE(_PCH_TRANS_HSYNC_A, dev_priv->regfile.saveTRANS_HSYNC_A); I915_WRITE(_PCH_TRANS_VTOTAL_A, dev_priv->regfile.saveTRANS_VTOTAL_A); I915_WRITE(_PCH_TRANS_VBLANK_A, dev_priv->regfile.saveTRANS_VBLANK_A); I915_WRITE(_PCH_TRANS_VSYNC_A, dev_priv->regfile.saveTRANS_VSYNC_A); } /* Restore plane info */ I915_WRITE(_DSPASIZE, dev_priv->regfile.saveDSPASIZE); I915_WRITE(_DSPAPOS, dev_priv->regfile.saveDSPAPOS); I915_WRITE(_PIPEASRC, dev_priv->regfile.savePIPEASRC); I915_WRITE(_DSPAADDR, dev_priv->regfile.saveDSPAADDR); I915_WRITE(_DSPASTRIDE, dev_priv->regfile.saveDSPASTRIDE); if (INTEL_INFO(dev)->gen >= 4) { I915_WRITE(_DSPASURF, dev_priv->regfile.saveDSPASURF); I915_WRITE(_DSPATILEOFF, dev_priv->regfile.saveDSPATILEOFF); } I915_WRITE(_PIPEACONF, dev_priv->regfile.savePIPEACONF); i915_restore_palette(dev, PIPE_A); /* Enable the plane */ I915_WRITE(_DSPACNTR, dev_priv->regfile.saveDSPACNTR); I915_WRITE(_DSPAADDR, I915_READ(_DSPAADDR)); /* Pipe & plane B info */ if (dev_priv->regfile.saveDPLL_B & DPLL_VCO_ENABLE) { I915_WRITE(dpll_b_reg, dev_priv->regfile.saveDPLL_B & ~DPLL_VCO_ENABLE); POSTING_READ(dpll_b_reg); udelay(150); } I915_WRITE(fpb0_reg, dev_priv->regfile.saveFPB0); I915_WRITE(fpb1_reg, dev_priv->regfile.saveFPB1); /* Actually enable it */ I915_WRITE(dpll_b_reg, dev_priv->regfile.saveDPLL_B); POSTING_READ(dpll_b_reg); udelay(150); if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) { I915_WRITE(_DPLL_B_MD, dev_priv->regfile.saveDPLL_B_MD); POSTING_READ(_DPLL_B_MD); } udelay(150); /* Restore mode */ I915_WRITE(_HTOTAL_B, dev_priv->regfile.saveHTOTAL_B); I915_WRITE(_HBLANK_B, dev_priv->regfile.saveHBLANK_B); I915_WRITE(_HSYNC_B, dev_priv->regfile.saveHSYNC_B); I915_WRITE(_VTOTAL_B, dev_priv->regfile.saveVTOTAL_B); I915_WRITE(_VBLANK_B, dev_priv->regfile.saveVBLANK_B); I915_WRITE(_VSYNC_B, dev_priv->regfile.saveVSYNC_B); if (!HAS_PCH_SPLIT(dev)) I915_WRITE(_BCLRPAT_B, dev_priv->regfile.saveBCLRPAT_B); if (HAS_PCH_SPLIT(dev)) { I915_WRITE(_PIPEB_DATA_M1, dev_priv->regfile.savePIPEB_DATA_M1); I915_WRITE(_PIPEB_DATA_N1, dev_priv->regfile.savePIPEB_DATA_N1); I915_WRITE(_PIPEB_LINK_M1, dev_priv->regfile.savePIPEB_LINK_M1); I915_WRITE(_PIPEB_LINK_N1, dev_priv->regfile.savePIPEB_LINK_N1); I915_WRITE(_FDI_RXB_CTL, dev_priv->regfile.saveFDI_RXB_CTL); I915_WRITE(_FDI_TXB_CTL, dev_priv->regfile.saveFDI_TXB_CTL); I915_WRITE(_PFB_CTL_1, dev_priv->regfile.savePFB_CTL_1); I915_WRITE(_PFB_WIN_SZ, dev_priv->regfile.savePFB_WIN_SZ); I915_WRITE(_PFB_WIN_POS, dev_priv->regfile.savePFB_WIN_POS); I915_WRITE(_PCH_TRANSBCONF, dev_priv->regfile.saveTRANSBCONF); I915_WRITE(_PCH_TRANS_HTOTAL_B, dev_priv->regfile.saveTRANS_HTOTAL_B); I915_WRITE(_PCH_TRANS_HBLANK_B, dev_priv->regfile.saveTRANS_HBLANK_B); I915_WRITE(_PCH_TRANS_HSYNC_B, dev_priv->regfile.saveTRANS_HSYNC_B); I915_WRITE(_PCH_TRANS_VTOTAL_B, dev_priv->regfile.saveTRANS_VTOTAL_B); I915_WRITE(_PCH_TRANS_VBLANK_B, dev_priv->regfile.saveTRANS_VBLANK_B); I915_WRITE(_PCH_TRANS_VSYNC_B, dev_priv->regfile.saveTRANS_VSYNC_B); } /* Restore plane info */ I915_WRITE(_DSPBSIZE, dev_priv->regfile.saveDSPBSIZE); I915_WRITE(_DSPBPOS, dev_priv->regfile.saveDSPBPOS); I915_WRITE(_PIPEBSRC, dev_priv->regfile.savePIPEBSRC); I915_WRITE(_DSPBADDR, dev_priv->regfile.saveDSPBADDR); I915_WRITE(_DSPBSTRIDE, dev_priv->regfile.saveDSPBSTRIDE); if (INTEL_INFO(dev)->gen >= 4) { I915_WRITE(_DSPBSURF, dev_priv->regfile.saveDSPBSURF); I915_WRITE(_DSPBTILEOFF, dev_priv->regfile.saveDSPBTILEOFF); } I915_WRITE(_PIPEBCONF, dev_priv->regfile.savePIPEBCONF); i915_restore_palette(dev, PIPE_B); /* Enable the plane */ I915_WRITE(_DSPBCNTR, dev_priv->regfile.saveDSPBCNTR); I915_WRITE(_DSPBADDR, I915_READ(_DSPBADDR)); /* Cursor state */ I915_WRITE(_CURAPOS, dev_priv->regfile.saveCURAPOS); I915_WRITE(_CURACNTR, dev_priv->regfile.saveCURACNTR); I915_WRITE(_CURABASE, dev_priv->regfile.saveCURABASE); I915_WRITE(_CURBPOS, dev_priv->regfile.saveCURBPOS); I915_WRITE(_CURBCNTR, dev_priv->regfile.saveCURBCNTR); I915_WRITE(_CURBBASE, dev_priv->regfile.saveCURBBASE); if (IS_GEN2(dev)) I915_WRITE(CURSIZE, dev_priv->regfile.saveCURSIZE); /* CRT state */ if (HAS_PCH_SPLIT(dev)) I915_WRITE(PCH_ADPA, dev_priv->regfile.saveADPA); else I915_WRITE(ADPA, dev_priv->regfile.saveADPA); /* Display Port state */ if (SUPPORTS_INTEGRATED_DP(dev)) { I915_WRITE(DP_B, dev_priv->regfile.saveDP_B); I915_WRITE(DP_C, dev_priv->regfile.saveDP_C); I915_WRITE(DP_D, dev_priv->regfile.saveDP_D); } /* FIXME: restore TV & SDVO state */ return; }
int i915_driver_load(struct drm_device *dev, unsigned long flags) { struct drm_i915_private *dev_priv; struct intel_device_info *info, *device_info; int ret = 0, mmio_bar, mmio_size; uint32_t aperture_size; info = (struct intel_device_info *) flags; /* Refuse to load on gen6+ without kms enabled. */ if (info->gen >= 6 && !drm_core_check_feature(dev, DRIVER_MODESET)) { DRM_INFO("Your hardware requires kernel modesetting (KMS)\n"); DRM_INFO("See CONFIG_DRM_I915_KMS, nomodeset, and i915.modeset parameters\n"); return -ENODEV; } /* UMS needs agp support. */ if (!drm_core_check_feature(dev, DRIVER_MODESET) && !dev->agp) return -EINVAL; dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL); if (dev_priv == NULL) return -ENOMEM; dev->dev_private = (void *)dev_priv; gpu_perf_dev_priv = (void *)dev_priv; dev_priv->dev = dev; /* Setup the write-once "constant" device info */ device_info = (struct intel_device_info *)&dev_priv->info; memcpy(device_info, info, sizeof(dev_priv->info)); device_info->device_id = dev->pdev->device; spin_lock_init(&dev_priv->irq_lock); spin_lock_init(&dev_priv->gpu_error.lock); mutex_init(&dev_priv->backlight_lock); spin_lock_init(&dev_priv->uncore.lock); spin_lock_init(&dev_priv->mm.object_stat_lock); spin_lock_init(&dev_priv->mmio_flip_lock); mutex_init(&dev_priv->dpio_lock); mutex_init(&dev_priv->modeset_restore_lock); intel_pm_setup(dev); intel_display_crc_init(dev); i915_dump_device_info(dev_priv); /* Not all pre-production machines fall into this category, only the * very first ones. Almost everything should work, except for maybe * suspend/resume. And we don't implement workarounds that affect only * pre-production machines. */ if (IS_HSW_EARLY_SDV(dev)) DRM_INFO("This is an early pre-production Haswell machine. " "It may not be fully functional.\n"); if (i915_get_bridge_dev(dev)) { ret = -EIO; goto free_priv; } mmio_bar = IS_GEN2(dev) ? 1 : 0; /* Before gen4, the registers and the GTT are behind different BARs. * However, from gen4 onwards, the registers and the GTT are shared * in the same BAR, so we want to restrict this ioremap from * clobbering the GTT which we want ioremap_wc instead. Fortunately, * the register BAR remains the same size for all the earlier * generations up to Ironlake. */ if (info->gen < 5) mmio_size = 512*1024; else mmio_size = 2*1024*1024; dev_priv->regs = pci_iomap(dev->pdev, mmio_bar, mmio_size); if (!dev_priv->regs) { DRM_ERROR("failed to map registers\n"); ret = -EIO; goto put_bridge; } /* This must be called before any calls to HAS_PCH_* */ intel_detect_pch(dev); intel_uncore_init(dev); if (i915_start_vgt(dev->pdev)) i915_host_mediate = true; printk("i915_start_vgt: %s\n", i915_host_mediate ? "success" : "fail"); i915_check_vgt(dev_priv); if (USES_VGT(dev)) i915.enable_fbc = 0; ret = i915_gem_gtt_init(dev); if (ret) goto out_regs; if (drm_core_check_feature(dev, DRIVER_MODESET)) { /* WARNING: Apparently we must kick fbdev drivers before vgacon, * otherwise the vga fbdev driver falls over. */ ret = i915_kick_out_firmware_fb(dev_priv); if (ret) { DRM_ERROR("failed to remove conflicting framebuffer drivers\n"); goto out_gtt; } ret = i915_kick_out_vgacon(dev_priv); if (ret) { DRM_ERROR("failed to remove conflicting VGA console\n"); goto out_gtt; } } pci_set_master(dev->pdev); /* overlay on gen2 is broken and can't address above 1G */ if (IS_GEN2(dev)) dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(30)); /* 965GM sometimes incorrectly writes to hardware status page (HWS) * using 32bit addressing, overwriting memory if HWS is located * above 4GB. * * The documentation also mentions an issue with undefined * behaviour if any general state is accessed within a page above 4GB, * which also needs to be handled carefully. */ if (IS_BROADWATER(dev) || IS_CRESTLINE(dev)) dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(32)); aperture_size = dev_priv->gtt.mappable_end; dev_priv->gtt.mappable = io_mapping_create_wc(dev_priv->gtt.mappable_base, aperture_size); if (dev_priv->gtt.mappable == NULL) { ret = -EIO; goto out_gtt; } dev_priv->gtt.mtrr = arch_phys_wc_add(dev_priv->gtt.mappable_base, aperture_size); /* The i915 workqueue is primarily used for batched retirement of * requests (and thus managing bo) once the task has been completed * by the GPU. i915_gem_retire_requests() is called directly when we * need high-priority retirement, such as waiting for an explicit * bo. * * It is also used for periodic low-priority events, such as * idle-timers and recording error state. * * All tasks on the workqueue are expected to acquire the dev mutex * so there is no point in running more than one instance of the * workqueue at any time. Use an ordered one. */ dev_priv->wq = alloc_ordered_workqueue("i915", 0); if (dev_priv->wq == NULL) { DRM_ERROR("Failed to create our workqueue.\n"); ret = -ENOMEM; goto out_mtrrfree; } dev_priv->dp_wq = alloc_ordered_workqueue("i915-dp", 0); if (dev_priv->dp_wq == NULL) { DRM_ERROR("Failed to create our dp workqueue.\n"); ret = -ENOMEM; goto out_freewq; } intel_irq_init(dev_priv); intel_uncore_sanitize(dev); /* Try to make sure MCHBAR is enabled before poking at it */ intel_setup_mchbar(dev); intel_setup_gmbus(dev); intel_opregion_setup(dev); intel_setup_bios(dev); i915_gem_load(dev); /* On the 945G/GM, the chipset reports the MSI capability on the * integrated graphics even though the support isn't actually there * according to the published specs. It doesn't appear to function * correctly in testing on 945G. * This may be a side effect of MSI having been made available for PEG * and the registers being closely associated. * * According to chipset errata, on the 965GM, MSI interrupts may * be lost or delayed, but we use them anyways to avoid * stuck interrupts on some machines. */ if (!IS_I945G(dev) && !IS_I945GM(dev)) pci_enable_msi(dev->pdev); intel_device_info_runtime_init(dev); if (INTEL_INFO(dev)->num_pipes) { ret = drm_vblank_init(dev, INTEL_INFO(dev)->num_pipes); if (ret) goto out_gem_unload; } intel_power_domains_init(dev_priv); if (drm_core_check_feature(dev, DRIVER_MODESET)) { ret = i915_load_modeset_init(dev); if (ret < 0) { DRM_ERROR("failed to init modeset\n"); goto out_power_well; } #ifdef DRM_I915_VGT_SUPPORT if (USES_VGT(dev)) { /* * Tell VGT that we have a valid surface to show * after modesetting. We doesn't distinguish DOM0 and * Linux guest here, The PVINFO write handler will * handle this. */ I915_WRITE(vgt_info_off(display_ready), 1); } #endif } i915_setup_sysfs(dev); if (INTEL_INFO(dev)->num_pipes) { /* Must be done after probing outputs */ intel_opregion_init(dev); acpi_video_register(); } if (IS_GEN5(dev)) intel_gpu_ips_init(dev_priv); intel_runtime_pm_enable(dev_priv); return 0; out_power_well: intel_power_domains_fini(dev_priv); drm_vblank_cleanup(dev); out_gem_unload: WARN_ON(unregister_oom_notifier(&dev_priv->mm.oom_notifier)); unregister_shrinker(&dev_priv->mm.shrinker); if (dev->pdev->msi_enabled) pci_disable_msi(dev->pdev); intel_teardown_gmbus(dev); intel_teardown_mchbar(dev); pm_qos_remove_request(&dev_priv->pm_qos); destroy_workqueue(dev_priv->dp_wq); out_freewq: destroy_workqueue(dev_priv->wq); out_mtrrfree: arch_phys_wc_del(dev_priv->gtt.mtrr); io_mapping_free(dev_priv->gtt.mappable); out_gtt: i915_global_gtt_cleanup(dev); out_regs: intel_uncore_fini(dev); pci_iounmap(dev->pdev, dev_priv->regs); put_bridge: pci_dev_put(dev_priv->bridge_dev); free_priv: if (dev_priv->slab) kmem_cache_destroy(dev_priv->slab); kfree(dev_priv); return ret; }
static void parse_options(int argc, char **argv) { int c, tmp; int option_index = 0; static struct option long_options[] = { {"no-hw", 0, 0, 'd'}, {"buf-size", 1, 0, 's'}, {"gpu-busy-load", 1, 0, 'g'}, {"no-signals", 0, 0, 'S'}, {"buffer-count", 1, 0, 'c'}, {"trace-tile", 1, 0, 't'}, {"disable-blt", 0, 0, 'b'}, {"disable-render", 0, 0, 'r'}, {"untiled", 0, 0, 'u'}, {"x-tiled", 0, 0, 'x'}, {"use-cpu-maps", 0, 0, 'm'}, {"rounds", 1, 0, 'o'}, {"no-fail", 0, 0, 'f'}, {"tiles-per-buf", 0, 0, 'p'}, #define DUCTAPE 0xdead0001 {"remove-duct-tape", 0, 0, DUCTAPE}, #define TILESZ 0xdead0002 {"tile-size", 1, 0, TILESZ}, #define CHCK_RENDER 0xdead0003 {"check-render-cpyfn", 0, 0, CHCK_RENDER}, }; options.scratch_buf_size = 256*4096; options.no_hw = 0; options.use_signal_helper = 1; options.gpu_busy_load = 0; options.num_buffers = 0; options.trace_tile = -1; options.use_render = 1; options.use_blt = 1; options.forced_tiling = -1; options.use_cpu_maps = 0; options.total_rounds = 512; options.fail = 1; options.ducttape = 1; options.tile_size = 16; options.tiles_per_buf = options.scratch_buf_size / TILE_BYTES(options.tile_size); options.check_render_cpyfn = 0; while((c = getopt_long(argc, argv, "ds:g:c:t:rbuxmo:fp:", long_options, &option_index)) != -1) { switch(c) { case 'd': options.no_hw = 1; printf("no-hw debug mode\n"); break; case 'S': options.use_signal_helper = 0; printf("disabling that pesky nuisance who keeps interrupting us\n"); break; case 's': tmp = atoi(optarg); if (tmp < options.tile_size*8192) printf("scratch buffer size needs to be at least %i\n", options.tile_size*8192); else if (tmp & (tmp - 1)) { printf("scratch buffer size needs to be a power-of-two\n"); } else { printf("fixed scratch buffer size to %u\n", tmp); options.scratch_buf_size = tmp; sanitize_tiles_per_buf(); } break; case 'g': tmp = atoi(optarg); if (tmp < 0 || tmp > 10) printf("gpu busy load needs to be bigger than 0 and smaller than 10\n"); else { printf("gpu busy load factor set to %i\n", tmp); gpu_busy_load = options.gpu_busy_load = tmp; } break; case 'c': options.num_buffers = atoi(optarg); printf("buffer count set to %i\n", options.num_buffers); break; case 't': options.trace_tile = atoi(optarg); printf("tracing tile %i\n", options.trace_tile); break; case 'r': options.use_render = 0; printf("disabling render copy\n"); break; case 'b': options.use_blt = 0; printf("disabling blt copy\n"); break; case 'u': options.forced_tiling = I915_TILING_NONE; printf("disabling tiling\n"); break; case 'x': if (options.use_cpu_maps) { printf("tiling not possible with cpu maps\n"); } else { options.forced_tiling = I915_TILING_X; printf("using only X-tiling\n"); } break; case 'm': options.use_cpu_maps = 1; options.forced_tiling = I915_TILING_NONE; printf("disabling tiling\n"); break; case 'o': options.total_rounds = atoi(optarg); printf("total rounds %i\n", options.total_rounds); break; case 'f': options.fail = 0; printf("not failing when detecting errors\n"); break; case 'p': options.tiles_per_buf = atoi(optarg); printf("tiles per buffer %i\n", options.tiles_per_buf); break; case DUCTAPE: options.ducttape = 0; printf("applying duct-tape\n"); break; case TILESZ: options.tile_size = atoi(optarg); sanitize_tiles_per_buf(); printf("til size %i\n", options.tile_size); break; case CHCK_RENDER: options.check_render_cpyfn = 1; printf("checking render copy function\n"); break; default: printf("unkown command options\n"); break; } } if (optind < argc) printf("unkown command options\n"); /* actually 32767, according to docs, but that kills our nice pot calculations. */ options.max_dimension = 16*1024; if (options.use_render) { if (IS_GEN2(devid) || IS_GEN3(devid)) options.max_dimension = 2048; else options.max_dimension = 8192; } printf("Limiting buffer to %dx%d\n", options.max_dimension, options.max_dimension); }