summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@virtuousgeek.org>2008-09-22 09:59:52 -0700
committerJesse Barnes <jbarnes@virtuousgeek.org>2008-09-22 09:59:52 -0700
commit9a7da65e624060a37eef989963a9c79f13df30d3 (patch)
tree2941ded38fabed1f577d2f186de99cc996b2e102
parent043b6e71b83eb05339a6f8c4814e6941f8b9695a (diff)
parent2f93cfbc7e96acc32efb5e1ca49b817a81cba6e3 (diff)
Merge branch 'master' into xf86-video-intel-2.5-branch
-rw-r--r--src/i830_crt.c45
-rw-r--r--src/i830_hdmi.c10
-rw-r--r--src/i830_memory.c29
-rw-r--r--src/i830_video.c14
-rw-r--r--src/i965_render.c4
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);
}