diff options
author | Jesse Barnes <jbarnes@virtuousgeek.org> | 2008-09-22 09:59:52 -0700 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2008-09-22 09:59:52 -0700 |
commit | 9a7da65e624060a37eef989963a9c79f13df30d3 (patch) | |
tree | 2941ded38fabed1f577d2f186de99cc996b2e102 | |
parent | 043b6e71b83eb05339a6f8c4814e6941f8b9695a (diff) | |
parent | 2f93cfbc7e96acc32efb5e1ca49b817a81cba6e3 (diff) |
Merge branch 'master' into xf86-video-intel-2.5-branch
-rw-r--r-- | src/i830_crt.c | 45 | ||||
-rw-r--r-- | src/i830_hdmi.c | 10 | ||||
-rw-r--r-- | src/i830_memory.c | 29 | ||||
-rw-r--r-- | src/i830_video.c | 14 | ||||
-rw-r--r-- | src/i965_render.c | 4 |
5 files changed, 93 insertions, 9 deletions
diff --git a/src/i830_crt.c b/src/i830_crt.c index 8274c0cc..5812e2b7 100644 --- a/src/i830_crt.c +++ b/src/i830_crt.c @@ -410,6 +410,49 @@ i830_crt_get_crtc(xf86OutputPtr output) } #endif +static xf86MonPtr +i830_get_edid(xf86OutputPtr output, int gpio_reg, char *gpio_str) +{ + I830OutputPrivatePtr intel_output = output->driver_private; + xf86MonPtr edid_mon = NULL; + + /* Set up the DDC bus. */ + if (gpio_reg != GPIOA) + I830I2CInit(output->scrn, &intel_output->pDDCBus, gpio_reg, gpio_str); + + edid_mon = xf86OutputGetEDID (output, intel_output->pDDCBus); + + if (!edid_mon || DIGITAL(edid_mon->features.input_type)) { + xf86DestroyI2CBusRec(intel_output->pDDCBus, TRUE, TRUE); + if (edid_mon) { + xfree(edid_mon); + edid_mon = NULL; + } + } + return edid_mon; +} + +static DisplayModePtr +i830_crt_get_modes (xf86OutputPtr output) +{ + DisplayModePtr modes; + xf86MonPtr edid_mon = NULL; + + /* Try to probe normal CRT port, and also digital port for output + in DVI-I mode. */ + if ((edid_mon = i830_get_edid(output, GPIOA, "CRTDDC_A"))) + goto found; + if ((edid_mon = i830_get_edid(output, GPIOD, "CRTDDC_D"))) + goto found; + if ((edid_mon = i830_get_edid(output, GPIOE, "CRTDDC_E"))) + goto found; +found: + xf86OutputSetEDID (output, edid_mon); + + modes = xf86OutputGetEDIDModes (output); + return modes; +} + static const xf86OutputFuncsRec i830_crt_output_funcs = { .dpms = i830_crt_dpms, .save = i830_crt_save, @@ -420,7 +463,7 @@ static const xf86OutputFuncsRec i830_crt_output_funcs = { .mode_set = i830_crt_mode_set, .commit = i830_output_commit, .detect = i830_crt_detect, - .get_modes = i830_ddc_get_modes, + .get_modes = i830_crt_get_modes, .destroy = i830_crt_destroy, #ifdef RANDR_GET_CRTC_INTERFACE .get_crtc = i830_crt_get_crtc, diff --git a/src/i830_hdmi.c b/src/i830_hdmi.c index d56eec90..44e5c056 100644 --- a/src/i830_hdmi.c +++ b/src/i830_hdmi.c @@ -139,6 +139,8 @@ i830_hdmi_detect(xf86OutputPtr output) struct i830_hdmi_priv *dev_priv = intel_output->dev_priv; I830Ptr pI830 = I830PTR(pScrn); uint32_t temp, bit; + xf86OutputStatus status; + xf86MonPtr edid_mon; /* For G4X, PEG_BAND_GAP_DATA 3:0 must first be written 0xd. * Failure to do so will result in spurious interrupts being @@ -171,9 +173,15 @@ i830_hdmi_detect(xf86OutputPtr output) } if ((INREG(PORT_HOTPLUG_STAT) & bit) != 0) - return XF86OutputStatusConnected; + status = XF86OutputStatusConnected; else return XF86OutputStatusDisconnected; + + edid_mon = xf86OutputGetEDID (output, intel_output->pDDCBus); + if (!edid_mon || !DIGITAL(edid_mon->features.input_type)) + status = XF86OutputStatusDisconnected; + xfree(edid_mon); + return status; } static void diff --git a/src/i830_memory.c b/src/i830_memory.c index 2cbdd17a..ecfdf2a2 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -158,6 +158,29 @@ i830_get_fence_size(ScrnInfoPtr pScrn, unsigned long size) } static Bool +i830_check_display_stride(ScrnInfoPtr pScrn, int stride, Bool tiling) +{ + I830Ptr pI830 = I830PTR(pScrn); + int limit = KB(32); + + /* 8xx spec has always 8K limit, but tests show larger limit in + non-tiling mode, which makes large monitor work. */ + if ((IS_845G(pI830) || IS_I85X(pI830)) && tiling) + limit = KB(8); + + if (IS_I915(pI830) && tiling) + limit = KB(8); + + if (IS_I965G(pI830) && tiling) + limit = KB(16); + + if (stride <= limit) + return TRUE; + else + return FALSE; +} + +static Bool i830_bind_memory(ScrnInfoPtr pScrn, i830_memory *mem) { I830Ptr pI830 = I830PTR(pScrn); @@ -1200,6 +1223,12 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, else tiling = pI830->tiling; + if (!i830_check_display_stride(pScrn, pitch, tiling)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Front buffer stride %d kB " + "exceed display limit\n", pitch/1024); + return NULL; + } + /* Attempt to allocate it tiled first if we have page flipping on. */ if (tiling && IsTileable(pScrn, pitch)) { /* XXX: probably not the case on 965 */ diff --git a/src/i830_video.c b/src/i830_video.c index 5e6ebd77..6645daae 100644 --- a/src/i830_video.c +++ b/src/i830_video.c @@ -2245,12 +2245,16 @@ I830PutImage(ScrnInfoPtr pScrn, pI830->entityPrivate->XvInUse = i830_crtc_pipe (pPriv->current_crtc);; } - /* Clamp dst width & height to 7x of src (overlay limit) */ - if(drw_w > (src_w * 7)) - drw_w = src_w * 7; + if (!pPriv->textured) { + /* If dst width and height are less than 1/8th the src size, the + * src/dst scale factor becomes larger than 8 and doesn't fit in + * the scale register. */ + if(src_w >= (drw_w * 8)) + drw_w = src_w/7; - if(drw_h > (src_h * 7)) - drw_h = src_h * 7; + if(src_h >= (drw_h * 8)) + drw_h = src_h/7; + } /* Clip */ x1 = src_x; diff --git a/src/i965_render.c b/src/i965_render.c index a4334c65..7dee5f3f 100644 --- a/src/i965_render.c +++ b/src/i965_render.c @@ -1450,7 +1450,7 @@ gen4_render_state_init(ScrnInfoPtr pScrn) render_state->card_state_offset = pI830->gen4_render_state_mem->offset; - if (pI830->gen4_render_state_mem->bo) { + if (pI830->use_drm_mode) { ret = dri_bo_map(pI830->gen4_render_state_mem->bo, 1); if (ret) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, @@ -1474,7 +1474,7 @@ gen4_render_state_cleanup(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); - if (pI830->gen4_render_state_mem->bo) { + if (pI830->use_drm_mode) { dri_bo_unmap(pI830->gen4_render_state_mem->bo); dri_bo_unreference(pI830->gen4_render_state_mem->bo); } |