summaryrefslogtreecommitdiff
path: root/src/i830_display.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/i830_display.c')
-rw-r--r--src/i830_display.c164
1 files changed, 78 insertions, 86 deletions
diff --git a/src/i830_display.c b/src/i830_display.c
index 6fe7be74..d8be8d99 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -372,9 +372,11 @@ i830PipeSetBase(xf86CrtcPtr crtc, int x, int y)
I830Ptr pI830 = I830PTR(pScrn);
I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
int pipe = intel_crtc->pipe;
+ int plane = intel_crtc->plane;
unsigned long Start, Offset;
- int dspbase = (pipe == 0 ? DSPABASE : DSPBBASE);
- int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
+ int dspbase = (plane == 0 ? DSPABASE : DSPBBASE);
+ int dspsurf = (plane == 0 ? DSPASURF : DSPBSURF);
+ int dsptileoff = (plane == 0 ? DSPATILEOFF : DSPBTILEOFF);
Offset = ((y * pScrn->displayWidth + x) * pI830->cpp);
if (pI830->front_buffer == NULL) {
@@ -399,6 +401,7 @@ i830PipeSetBase(xf86CrtcPtr crtc, int x, int y)
POSTING_READ(dspbase);
OUTREG(dspsurf, Start);
POSTING_READ(dspsurf);
+ OUTREG(dsptileoff, (y << 16) | x);
} else {
OUTREG(dspbase, Start + Offset);
POSTING_READ(dspbase);
@@ -498,18 +501,37 @@ i830_pipe_a_require_deactivate (ScrnInfoPtr scrn)
return;
}
+/* FIXME: use pixmap private instead if possible */
+static Bool
+i830_display_tiled(xf86CrtcPtr crtc)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
+
+ /* Rotated data is currently linear, allocated either via XAA or EXA */
+ if (crtc->rotatedData)
+ return FALSE;
+
+ if (pI830->front_buffer && pI830->front_buffer->tiling != TILE_NONE)
+ return TRUE;
+
+ return FALSE;
+}
+
static Bool
i830_use_fb_compression(xf86CrtcPtr crtc)
{
ScrnInfoPtr pScrn = crtc->scrn;
I830Ptr pI830 = I830PTR(pScrn);
I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
- int pipe = intel_crtc->pipe;
- int plane = (pipe == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB);
+ int plane = (intel_crtc->plane == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB);
if (!pI830->fb_compression)
return FALSE;
+ if (!i830_display_tiled(crtc))
+ return FALSE;
+
/* Pre-965 only supports plane A */
if (!IS_I965GM(pI830) && plane != FBC_CTL_PLANEA)
return FALSE;
@@ -547,17 +569,15 @@ i830_enable_fb_compression(xf86CrtcPtr crtc)
I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
uint32_t fbc_ctl = 0;
unsigned long compressed_stride;
- int pipe = intel_crtc->pipe;
- /* FIXME: plane & pipe might not always be equal */
- int plane = (pipe == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB);
+ int plane = (intel_crtc->plane == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB);
unsigned long uncompressed_stride = pScrn->displayWidth * pI830->cpp;
unsigned long interval = 1000;
if (INREG(FBC_CONTROL) & FBC_CTL_EN) {
- char cur_pipe = (INREG(FBC_CONTROL2) & 1) ? 'b' : 'a';
+ char cur_plane = (INREG(FBC_CONTROL2) & 1) ? 'b' : 'a';
xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "fbc already enabled on "
- "pipe %c, not enabling on pipe %c\n", cur_pipe, pipe ? 'b' :
- 'a');
+ "plane %c, not enabling on plane %c\n", cur_plane,
+ plane ? 'b' : 'a');
return;
}
@@ -593,7 +613,7 @@ i830_enable_fb_compression(xf86CrtcPtr crtc)
fbc_ctl |= FBC_CTL_UNCOMPRESSIBLE;
OUTREG(FBC_CONTROL, fbc_ctl);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc enabled on plane %c\n", pipe ?
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc enabled on plane %c\n", plane ?
'b' : 'a');
}
@@ -603,7 +623,7 @@ i830_disable_fb_compression(xf86CrtcPtr crtc)
ScrnInfoPtr pScrn = crtc->scrn;
I830Ptr pI830 = I830PTR(pScrn);
uint32_t fbc_ctl;
- char pipe = (INREG(FBC_CONTROL2) & 1) ? 'b' : 'a';
+ char plane = (INREG(FBC_CONTROL2) & 1) ? 'b' : 'a';
/* Disable compression */
fbc_ctl = INREG(FBC_CONTROL);
@@ -613,7 +633,7 @@ i830_disable_fb_compression(xf86CrtcPtr crtc)
/* Wait for compressing bit to clear */
while (INREG(FBC_STATUS) & FBC_STAT_COMPRESSING)
; /* nothing */
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc disabled on pipe %c\n", pipe);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc disabled on pipe %c\n", plane);
}
/**
@@ -629,10 +649,11 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mode)
I830Ptr pI830 = I830PTR(pScrn);
I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
int pipe = intel_crtc->pipe;
+ int plane = intel_crtc->plane;
int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
- int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
- int dspbase_reg = (pipe == 0) ? DSPABASE : DSPBBASE;
int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
+ int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR;
+ int dspbase_reg = (plane == 0) ? DSPABASE : DSPBBASE;
CARD32 temp;
/* XXX: When our outputs are all unaware of DPMS modes other than off and
@@ -847,9 +868,14 @@ i830_get_core_clock_speed(ScrnInfoPtr pScrn)
else if (IS_I945GM(pI830) || IS_845G(pI830))
return 200000;
else if (IS_I915GM(pI830)) {
- CARD16 gcfgc = pciReadWord(pI830->PciTag, I915_GCFGC);
+ uint16_t gcfgc;
- if (gcfgc & I915_LOW_FREQUENCY_ENABLE)
+#if XSERVER_LIBPCIACCESS
+ pci_device_cfg_read_u16 (pI830->PciInfo, &gcfgc, I915_GCFGC);
+#else
+ gcfgc = pciReadWord(pI830->PciTag, I915_GCFGC);
+#endif
+ if (gcfgc & I915_LOW_FREQUENCY_ENABLE)
return 133000;
else {
switch (gcfgc & I915_DISPLAY_CLOCK_MASK) {
@@ -863,8 +889,14 @@ i830_get_core_clock_speed(ScrnInfoPtr pScrn)
} else if (IS_I865G(pI830))
return 266000;
else if (IS_I855(pI830)) {
+#if XSERVER_LIBPCIACCESS
+ struct pci_device *bridge = intel_host_bridge ();
+ uint16_t hpllcc;
+ pci_device_cfg_read_u16 (bridge, &hpllcc, I855_HPLLCC);
+#else
PCITAG bridge = pciTag(0, 0, 0); /* This is always the host bridge */
CARD16 hpllcc = pciReadWord(bridge, I855_HPLLCC);
+#endif
/* Assume that the hardware is in the high speed state. This
* should be the default.
@@ -929,10 +961,10 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
I830Ptr pI830 = I830PTR(pScrn);
I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
int pipe = intel_crtc->pipe;
+ int plane = intel_crtc->plane;
int fp_reg = (pipe == 0) ? FPA0 : FPB0;
int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
- int dpll_md_reg = (intel_crtc->pipe == 0) ? DPLL_A_MD : DPLL_B_MD;
- int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
+ int dpll_md_reg = (pipe == 0) ? DPLL_A_MD : DPLL_B_MD;
int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
@@ -940,10 +972,11 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B;
int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B;
int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
- int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE;
- int dspstride_reg = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
- int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
+ int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR;
+ int dspstride_reg = (plane == 0) ? DSPASTRIDE : DSPBSTRIDE;
+ int dsppos_reg = (plane == 0) ? DSPAPOS : DSPBPOS;
+ int dspsize_reg = (plane == 0) ? DSPASIZE : DSPBSIZE;
int i;
int refclk;
intel_clock_t clock;
@@ -1078,7 +1111,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
else
dspcntr |= DISPPLANE_SEL_PIPE_B;
- if (pI830->tiling)
+ if (IS_I965G(pI830) && i830_display_tiled(crtc))
dspcntr |= DISPLAY_PLANE_TILED;
pipeconf = INREG(pipeconf_reg);
@@ -1269,59 +1302,24 @@ static void *
i830_crtc_shadow_allocate (xf86CrtcPtr crtc, int width, int height)
{
ScrnInfoPtr pScrn = crtc->scrn;
- ScreenPtr pScreen = pScrn->pScreen;
I830Ptr pI830 = I830PTR(pScrn);
I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
unsigned long rotate_pitch;
- unsigned long rotate_offset;
int align = KB(4), size;
rotate_pitch = pScrn->displayWidth * pI830->cpp;
size = rotate_pitch * height;
-#ifdef I830_USE_EXA
- /* We could get close to what we want here by just creating a pixmap like
- * normal, but we have to lock it down in framebuffer, and there is no
- * setter for offscreen area locking in EXA currently. So, we just
- * allocate offscreen memory and fake up a pixmap header for it.
- */
- if (pI830->useEXA) {
- assert(intel_crtc->rotate_mem_exa == NULL);
-
- intel_crtc->rotate_mem_exa = exaOffscreenAlloc(pScreen, size, align,
- TRUE, NULL, NULL);
- if (intel_crtc->rotate_mem_exa == NULL) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Couldn't allocate shadow memory for rotated CRTC\n");
- return NULL;
- }
- rotate_offset = intel_crtc->rotate_mem_exa->offset;
- }
-#endif /* I830_USE_EXA */
-#ifdef I830_USE_XAA
- if (!pI830->useEXA) {
- /* The XFree86 linear allocator operates in units of screen pixels,
- * sadly.
- */
- size = (size + pI830->cpp - 1) / pI830->cpp;
- align = (align + pI830->cpp - 1) / pI830->cpp;
-
- assert(intel_crtc->rotate_mem_xaa == NULL);
-
- intel_crtc->rotate_mem_xaa =
- i830_xf86AllocateOffscreenLinear(pScreen, size, align,
- NULL, NULL, NULL);
- if (intel_crtc->rotate_mem_xaa == NULL) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Couldn't allocate shadow memory for rotated CRTC\n");
- return NULL;
- }
- rotate_offset = pI830->front_buffer->offset +
- intel_crtc->rotate_mem_xaa->offset * pI830->cpp;
+ assert(intel_crtc->rotate_mem == NULL);
+ intel_crtc->rotate_mem = i830_allocate_memory(pScrn, "rotated crtc",
+ size, align, 0);
+ if (intel_crtc->rotate_mem == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Couldn't allocate shadow memory for rotated CRTC\n");
+ return NULL;
}
-#endif /* I830_USE_XAA */
- return pI830->FbBase + rotate_offset;
+ return pI830->FbBase + intel_crtc->rotate_mem->offset;
}
/**
@@ -1358,26 +1356,16 @@ static void
i830_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
{
ScrnInfoPtr pScrn = crtc->scrn;
- I830Ptr pI830 = I830PTR(pScrn);
I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
if (rotate_pixmap)
FreeScratchPixmapHeader(rotate_pixmap);
-
- if (data)
- {
-#ifdef I830_USE_EXA
- if (pI830->useEXA && intel_crtc->rotate_mem_exa != NULL) {
- exaOffscreenFree(pScrn->pScreen, intel_crtc->rotate_mem_exa);
- intel_crtc->rotate_mem_exa = NULL;
- }
-#endif /* I830_USE_EXA */
-#ifdef I830_USE_XAA
- if (!pI830->useEXA) {
- xf86FreeOffscreenLinear(intel_crtc->rotate_mem_xaa);
- intel_crtc->rotate_mem_xaa = NULL;
- }
-#endif /* I830_USE_XAA */
+
+ if (data) {
+ /* Be sure to sync acceleration before the memory gets unbound. */
+ I830Sync(pScrn);
+ i830_free_memory(pScrn, intel_crtc->rotate_mem);
+ intel_crtc->rotate_mem = NULL;
}
}
@@ -1393,8 +1381,11 @@ i830DescribeOutputConfiguration(ScrnInfoPtr pScrn)
for (i = 0; i < xf86_config->num_crtc; i++) {
xf86CrtcPtr crtc = xf86_config->crtc[i];
- CARD32 dspcntr = INREG(DSPACNTR + (DSPBCNTR - DSPACNTR) * i);
- CARD32 pipeconf = INREG(PIPEACONF + (PIPEBCONF - PIPEACONF) * i);
+ I830CrtcPrivatePtr intel_crtc = crtc ? crtc->driver_private : NULL;
+ CARD32 dspcntr = intel_crtc->plane == 0 ? INREG(DSPACNTR) :
+ INREG(DSPBCNTR);
+ CARD32 pipeconf = i == 0 ? INREG(PIPEACONF) :
+ INREG(PIPEBCONF);
Bool hw_plane_enable = (dspcntr & DISPLAY_PLANE_ENABLE) != 0;
Bool hw_pipe_enable = (pipeconf & PIPEACONF_ENABLE) != 0;
@@ -1403,8 +1394,8 @@ i830DescribeOutputConfiguration(ScrnInfoPtr pScrn)
'A' + i, crtc->enabled ? "on" : "off");
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
" Display plane %c is now %s and connected to pipe %c.\n",
- 'A' + i,
- crtc->enabled ? "enabled" : "disabled",
+ 'A' + intel_crtc->plane,
+ hw_plane_enable ? "enabled" : "disabled",
dspcntr & DISPPLANE_SEL_PIPE_MASK ? 'B' : 'A');
if (hw_pipe_enable != crtc->enabled) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
@@ -1708,6 +1699,7 @@ i830_crtc_init(ScrnInfoPtr pScrn, int pipe)
intel_crtc = xnfcalloc (sizeof (I830CrtcPrivateRec), 1);
intel_crtc->pipe = pipe;
intel_crtc->dpms_mode = DPMSModeOff;
+ intel_crtc->plane = pipe;
/* Initialize the LUTs for when we turn on the CRTC. */
for (i = 0; i < 256; i++) {