diff --git a/configure.ac b/configure.ac index e707a1a..2b7b540 100644 --- a/configure.ac +++ b/configure.ac @@ -22,7 +22,7 @@ AC_PREREQ(2.57) AC_INIT([xf86-video-intel], - 2.2.0, + 2.2.0.90, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xf86-video-intel) diff --git a/src/ch7017/ch7017.c b/src/ch7017/ch7017.c index 6fc3422..76f9cf7 100644 --- a/src/ch7017/ch7017.c +++ b/src/ch7017/ch7017.c @@ -313,7 +313,7 @@ ch7017_restore(I2CDevPtr d) ch7017_write(priv, CH7017_POWER_MANAGEMENT, priv->save_power_management); } -I830I2CVidOutputRec ch7017_methods = { +_X_EXPORT I830I2CVidOutputRec ch7017_methods = { .init = ch7017_init, .detect = ch7017_detect, .mode_valid = ch7017_mode_valid, diff --git a/src/ch7xxx/ch7xxx.c b/src/ch7xxx/ch7xxx.c index da02ad2..51fa78e 100644 --- a/src/ch7xxx/ch7xxx.c +++ b/src/ch7xxx/ch7xxx.c @@ -306,7 +306,7 @@ ch7xxx_restore(I2CDevPtr d) ch7xxx_write(dev_priv, CH7xxx_PM, dev_priv->save_PM); } -I830I2CVidOutputRec CH7xxxVidOutput = { +_X_EXPORT I830I2CVidOutputRec CH7xxxVidOutput = { .init = ch7xxx_init, .detect = ch7xxx_detect, .mode_valid = ch7xxx_mode_valid, diff --git a/src/i830.h b/src/i830.h index 9adbaf7..87d960b 100644 --- a/src/i830.h +++ b/src/i830.h @@ -616,6 +616,7 @@ typedef struct _I830Rec { CARD32 saveFBC_LL_BASE; CARD32 saveFBC_CONTROL2; CARD32 saveFBC_CONTROL; + CARD32 saveFBC_FENCE_OFF; enum last_3d *last_3d; diff --git a/src/i830_debug.c b/src/i830_debug.c index 8f8ef9b..196fd23 100644 --- a/src/i830_debug.c +++ b/src/i830_debug.c @@ -25,6 +25,8 @@ * */ +#include + #ifdef REG_DUMPER #include "reg_dumper/reg_dumper.h" @@ -191,7 +193,11 @@ DEBUGSTRING(i830_debug_dpll) mode = "LVDS"; p1 = ffs((val & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >> DPLL_FPA01_P1_POST_DIV_SHIFT); - p2 = 14; + if ((INREG(LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP) + p2 = 7; + else + p2 = 14; + } else { mode = "DAC/serial"; if (val & PLL_P1_DIVIDE_BY_TWO) { @@ -689,6 +695,19 @@ void i830DumpRegs (ScrnInfoPtr pScrn) xf86DrvMsg (pScrn->scrnIndex, X_WARNING, "p1 out of range\n"); break; } + + switch ((dpll >> 13) & 0x3) { + case 0: + ref = 96000; + break; + case 3: + ref = 100000; + break; + default: + ref = 0; + xf86DrvMsg (pScrn->scrnIndex, X_WARNING, "ref out of range\n"); + break; + } } else { @@ -726,18 +745,19 @@ void i830DumpRegs (ScrnInfoPtr pScrn) else p1 = ((dpll >> 16) & 0x3f) + 2; } - } - switch ((dpll >> 13) & 0x3) { - case 0: - ref = 96000; - break; - case 3: - ref = 100000; - break; - default: - ref = 0; - xf86DrvMsg (pScrn->scrnIndex, X_WARNING, "ref out of range\n"); - break; + + switch ((dpll >> 13) & 0x3) { + case 0: + ref = 48000; + break; + case 3: + ref = 66000; + break; + default: + ref = 0; + xf86DrvMsg (pScrn->scrnIndex, X_WARNING, "ref out of range\n"); + break; + } } if (IS_I965G(pI830)) { phase = (dpll >> 9) & 0xf; @@ -786,8 +806,8 @@ i830_dump_ring(ScrnInfoPtr pScrn) mask = pI830->LpRing->tail_mask; virt = pI830->LpRing->virtual_start; - ErrorF ("Ring at virtual 0x%x head 0x%x tail 0x%x count %d\n", - (unsigned int) virt, head, tail, (((tail + mask + 1) - head) & mask) >> 2); + ErrorF ("Ring at virtual %p head 0x%x tail 0x%x count %d\n", + virt, head, tail, (((tail + mask + 1) - head) & mask) >> 2); for (ring = (head - 128) & mask; ring != ((head + 4) & mask); ring = (ring + 4) & mask) { @@ -803,25 +823,25 @@ i830_dump_error_state(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); - ErrorF("pgetbl_ctl: 0x%lx pgetbl_err: 0x%lx\n", - (unsigned long)INREG(PGETBL_CTL), (unsigned long)INREG(PGE_ERR)); + ErrorF("pgetbl_ctl: 0x%" PRIx32 "getbl_err: 0x%" PRIx32 "\n", + INREG(PGETBL_CTL), INREG(PGE_ERR)); - ErrorF("ipeir: %lx iphdr: %lx\n", (unsigned long)INREG(IPEIR), - (unsigned long)INREG(IPEHR)); + ErrorF("ipeir: %" PRIx32 " iphdr: %" PRIx32 "\n", INREG(IPEIR), + INREG(IPEHR)); - ErrorF("LP ring tail: %lx head: %lx len: %lx start %lx\n", - (unsigned long)INREG(LP_RING + RING_TAIL), - (unsigned long)INREG(LP_RING + RING_HEAD) & HEAD_ADDR, - (unsigned long)INREG(LP_RING + RING_LEN), - (unsigned long)INREG(LP_RING + RING_START)); + ErrorF("LP ring tail: %" PRIx32 " head: %" PRIx32 " len: %" PRIx32 " start %" PRIx32 "\n", + INREG(LP_RING + RING_TAIL), + INREG(LP_RING + RING_HEAD) & HEAD_ADDR, + INREG(LP_RING + RING_LEN), + INREG(LP_RING + RING_START)); ErrorF("eir: %x esr: %x emr: %x\n", INREG16(EIR), INREG16(ESR), INREG16(EMR)); ErrorF("instdone: %x instpm: %x\n", INREG16(INST_DONE), INREG8(INST_PM)); - ErrorF("memmode: %lx instps: %lx\n", (unsigned long)INREG(MEMMODE), - (unsigned long)INREG(INST_PS)); + ErrorF("memmode: %" PRIx32 " instps: %" PRIx32 "\n", INREG(MEMMODE), + INREG(INST_PS)); ErrorF("hwstam: %x ier: %x imr: %x iir: %x\n", INREG16(HWSTAM), INREG16(IER), INREG16(IMR), INREG16(IIR)); @@ -833,12 +853,12 @@ i965_dump_error_state(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); - ErrorF("pgetbl_ctl: 0x%lx pgetbl_err: 0x%lx\n", + ErrorF("pgetbl_ctl: 0x%" PRIx32 " pgetbl_err: 0x%" PRIx32 "\n", INREG(PGETBL_CTL), INREG(PGE_ERR)); - ErrorF("ipeir: %lx iphdr: %lx\n", INREG(IPEIR_I965), INREG(IPEHR_I965)); + ErrorF("ipeir: %" PRIx32 " iphdr: %" PRIx32 "\n", INREG(IPEIR_I965), INREG(IPEHR_I965)); - ErrorF("LP ring tail: %lx head: %lx len: %lx start %lx\n", + ErrorF("LP ring tail: %" PRIx32 " head: %" PRIx32 " len: %" PRIx32 " start %" PRIx32 "\n", INREG(LP_RING + RING_TAIL), INREG(LP_RING + RING_HEAD) & HEAD_ADDR, INREG(LP_RING + RING_LEN), INREG(LP_RING + RING_START)); @@ -850,15 +870,15 @@ i965_dump_error_state(ScrnInfoPtr pScrn) (int)INREG(INST_DONE_1)); ErrorF("instpm: %x\n", (int)INREG(INST_PM)); - ErrorF("memmode: %lx instps: %lx\n", INREG(MEMMODE), INREG(INST_PS_I965)); + ErrorF("memmode: %" PRIx32 " instps: %" PRIx32 "\n", INREG(MEMMODE), INREG(INST_PS_I965)); ErrorF("HW Status mask (hwstam): %x\nIRQ enable (ier): %x " "imr: %x iir: %x\n", (int)INREG(HWSTAM), (int)INREG(IER), (int)INREG(IMR), (int)INREG(IIR)); - ErrorF("acthd: %lx dma_fadd_p: %lx\n", INREG(ACTHD), INREG(DMA_FADD_P)); - ErrorF("ecoskpd: %lx excc: %lx\n", INREG(ECOSKPD), INREG(EXCC)); + ErrorF("acthd: %" PRIx32 " dma_fadd_p: %" PRIx32 "\n", INREG(ACTHD), INREG(DMA_FADD_P)); + ErrorF("ecoskpd: %" PRIx32 " excc: %" PRIx32 "\n", INREG(ECOSKPD), INREG(EXCC)); ErrorF("cache_mode: %x/%x\n", (int)INREG(CACHE_MODE_0), (int)INREG(CACHE_MODE_1)); diff --git a/src/i830_display.c b/src/i830_display.c index f61d3c4..7a2520d 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -529,36 +529,6 @@ i830_display_tiled(xf86CrtcPtr crtc) 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 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; - - /* Need 15, 16, or 32 (w/alpha) pixel format */ - if (!(pScrn->bitsPerPixel == 16 || /* covers 15 bit mode as well */ - pScrn->bitsPerPixel == 32)) /* mode_set dtrt if fbc is in use */ - return FALSE; - - /* - * No checks for pixel multiply, incl. horizontal, or interlaced modes - * since they're currently unused. - */ - return TRUE; -} - /* * Several restrictions: * - DSP[AB]CNTR - no line duplication && no pixel multiplier @@ -610,6 +580,7 @@ i830_enable_fb_compression(xf86CrtcPtr crtc) OUTREG(FBC_LL_BASE, pI830->compressed_ll_buffer->bus_addr + 6); OUTREG(FBC_CONTROL2, FBC_CTL_FENCE_DBL | FBC_CTL_IDLE_FULL | FBC_CTL_CPU_FENCE | plane); + OUTREG(FBC_FENCE_OFF, crtc->y); /* Zero buffers */ memset(pI830->FbBase + pI830->compressed_front_buffer->offset, 0, @@ -648,6 +619,51 @@ i830_disable_fb_compression(xf86CrtcPtr crtc) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc disabled on plane %c\n", plane); } +static Bool +i830_use_fb_compression(xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + I830Ptr pI830 = I830PTR(pScrn); + I830CrtcPrivatePtr intel_crtc = crtc->driver_private; + int plane = (intel_crtc->plane == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB); + int i, count = 0; + + /* Only available on one pipe at a time */ + for (i = 0; i < xf86_config->num_crtc; i++) { + if (xf86_config->crtc[i]->enabled) + count++; + } + + /* Here we disable it to catch one->two pipe enabled configs */ + if (count > 1) { + if (i830_fb_compression_supported(pI830)) + i830_disable_fb_compression(crtc); + return FALSE; + } + + 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; + + /* Need 15, 16, or 32 (w/alpha) pixel format */ + if (!(pScrn->bitsPerPixel == 16 || /* covers 15 bit mode as well */ + pScrn->bitsPerPixel == 32)) /* mode_set dtrt if fbc is in use */ + return FALSE; + + /* + * No checks for pixel multiply, incl. horizontal, or interlaced modes + * since they're currently unused. + */ + return TRUE; +} + /** * Sets the power management mode of the pipe and plane. * @@ -1623,7 +1639,11 @@ i830_crtc_clock_get(ScrnInfoPtr pScrn, xf86CrtcPtr crtc) if (is_lvds) { clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >> DPLL_FPA01_P1_POST_DIV_SHIFT); - clock.p2 = 14; + + if ((INREG(LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP) + clock.p2 = I8XX_P2_LVDS_SLOW; + else + clock.p2 = I8XX_P2_LVDS_FAST; if ((dpll & PLL_REF_INPUT_MASK) == PLLB_REF_INPUT_SPREADSPECTRUMIN) i8xx_clock(66000, &clock); /* XXX: might not be 66MHz */ diff --git a/src/i830_driver.c b/src/i830_driver.c index dffc630..f9c1dfd 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -1932,6 +1932,7 @@ SaveHWState(ScrnInfoPtr pScrn) pI830->saveFBC_LL_BASE = INREG(FBC_LL_BASE); pI830->saveFBC_CONTROL2 = INREG(FBC_CONTROL2); pI830->saveFBC_CONTROL = INREG(FBC_CONTROL); + pI830->saveFBC_FENCE_OFF = INREG(FBC_FENCE_OFF); } /* Save video mode information for native mode-setting. */ @@ -2212,6 +2213,7 @@ RestoreHWState(ScrnInfoPtr pScrn) if (pI830->fb_compression) { OUTREG(FBC_CFB_BASE, pI830->saveFBC_CFB_BASE); OUTREG(FBC_LL_BASE, pI830->saveFBC_LL_BASE); + OUTREG(FBC_FENCE_OFF, pI830->saveFBC_FENCE_OFF); OUTREG(FBC_CONTROL2, pI830->saveFBC_CONTROL2); OUTREG(FBC_CONTROL, pI830->saveFBC_CONTROL); } diff --git a/src/i830_dvo.c b/src/i830_dvo.c index e6ff6af..e7342b0 100644 --- a/src/i830_dvo.c +++ b/src/i830_dvo.c @@ -83,7 +83,7 @@ struct _I830DVODriver i830_dvo_drivers[] = .type = I830_OUTPUT_DVO_LVDS, .modulename = "ivch", .fntablename = "ivch_methods", - .dvo_reg = DVOA, + .dvo_reg = DVOB, .address = 0x04, /* Might also be 0x44, 0x84, 0xc4 */ .symbols = ivch_symbols }, diff --git a/src/i830_memory.c b/src/i830_memory.c index 85b6528..77ec301 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -97,8 +97,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #endif #include +#include #include #include +#include #include #include "xf86.h" @@ -273,12 +275,16 @@ i830_free_memory(ScrnInfoPtr pScrn, i830_memory *mem) I830Ptr pI830 = I830PTR(pScrn); drmBOUnreference(pI830->drmSubFD, &mem->bo); - if (pI830->bo_list == mem) + if (pI830->bo_list == mem) { pI830->bo_list = mem->next; - if (mem->next) - mem->next->prev = NULL; - if (mem->prev) - mem->prev->next = NULL; + if (mem->next) + mem->next->prev = NULL; + } else { + if (mem->prev) + mem->prev->next = mem->next; + if (mem->next) + mem->next->prev = mem->prev; + } xfree(mem->name); xfree(mem); return; @@ -595,8 +601,8 @@ i830_get_stolen_physical(ScrnInfoPtr pScrn, unsigned long offset, if ((scan - offset) != (scan_physical - physical)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Non-contiguous GTT entries: (%ld,0x16%llx) vs " - "(%ld,0x%16llx)\n", + "Non-contiguous GTT entries: (%ld,0x16%" PRIx64 ") vs " + "(%ld,0x%" PRIx64 ")\n", scan, scan_physical, offset, physical); return -1; } @@ -944,7 +950,7 @@ i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity, const char *prefix) if (mem->bus_addr != 0) snprintf(phys_suffix, sizeof(phys_suffix), - ", 0x%016llx physical\n", mem->bus_addr); + ", 0x%016" PRIx64 " physical\n", mem->bus_addr); if (mem->tiling == TILE_XMAJOR) tile_suffix = " X tiled"; else if (mem->tiling == TILE_YMAJOR) @@ -1929,7 +1935,8 @@ i830_bind_all_memory(ScrnInfoPtr pScrn) } #endif } - i830_update_cursor_offsets(pScrn); + if (!pI830->SWCursor) + i830_update_cursor_offsets(pScrn); return TRUE; } diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c index 4b04994..c7cbfac 100644 --- a/src/i830_sdvo.c +++ b/src/i830_sdvo.c @@ -1100,8 +1100,10 @@ i830_sdvo_get_modes(xf86OutputPtr output) { ScrnInfoPtr pScrn = output->scrn; xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - DisplayModePtr modes; + DisplayModePtr modes = NULL; xf86OutputPtr crt; + I830OutputPrivatePtr intel_output; + xf86MonPtr edid_mon = NULL; modes = i830_ddc_get_modes(output); if (modes != NULL) @@ -1113,11 +1115,17 @@ i830_sdvo_get_modes(xf86OutputPtr output) * analog when we fail at finding it the right way. */ crt = xf86_config->output[0]; - if (crt->funcs->detect(crt) == XF86OutputStatusDisconnected) { - return crt->funcs->get_modes(crt); + intel_output = crt->driver_private; + if (intel_output->type == I830_OUTPUT_ANALOG && + crt->funcs->detect(crt) == XF86OutputStatusDisconnected) { + edid_mon = xf86OutputGetEDID(crt, intel_output->pDDCBus); + } + if (edid_mon) { + xf86OutputSetEDID(output, edid_mon); + modes = xf86OutputGetEDIDModes(output); } - return NULL; + return modes; } static void diff --git a/src/i830_video.c b/src/i830_video.c index 9688aaa..a0e40ad 100644 --- a/src/i830_video.c +++ b/src/i830_video.c @@ -50,6 +50,7 @@ #include "config.h" #endif +#include #include #include #include @@ -462,7 +463,8 @@ i830_overlay_continue(ScrnInfoPtr pScrn, Bool update_filter) flip_addr = pI830->overlay_regs->bus_addr; if (update_filter) flip_addr |= OFC_UPDATE; - OVERLAY_DEBUG ("overlay_continue cmd 0x%08lx -> 0x%08lx sta 0x%08lx\n", + OVERLAY_DEBUG ("overlay_continue cmd 0x%08" PRIx32 " -> 0x%08" PRIx32 + " sta 0x%08" PRIx32 "\n", overlay->OCMD, INREG(OCMD_REGISTER), INREG(DOVSTA)); BEGIN_LP_RING(4); OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE); @@ -502,7 +504,7 @@ i830_overlay_off(ScrnInfoPtr pScrn) */ { overlay->OCMD &= ~OVERLAY_ENABLE; - OVERLAY_DEBUG ("overlay_off cmd 0x%08lx -> 0x%08lx sta 0x%08lx\n", + OVERLAY_DEBUG ("overlay_off cmd 0x%08" PRIx32 " -> 0x%08" PRIx32 " sta 0x%08" PRIx32 "\n", overlay->OCMD, INREG(OCMD_REGISTER), INREG(DOVSTA)); BEGIN_LP_RING(6); OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE); @@ -674,7 +676,7 @@ I830ResetVideo(ScrnInfoPtr pScrn) { int i; for (i = 0x30000; i < 0x31000; i += 4) - ErrorF("0x%x 0x%lx\n", i, INREG(i)); + ErrorF("0x%x 0x%" PRIx32 "\n", i, INREG(i)); } #endif } @@ -1904,7 +1906,7 @@ i830_display_video(ScrnInfoPtr pScrn, xf86CrtcPtr crtc, overlay->OBUF_1V = pPriv->VBuf1offset; } - OVERLAY_DEBUG("pos: 0x%lx, size: 0x%lx\n", + OVERLAY_DEBUG("pos: 0x%" PRIx32 ", size: 0x%" PRIx32 "\n", overlay->DWINPOS, overlay->DWINSZ); OVERLAY_DEBUG("dst: %d x %d, src: %d x %d\n", drw_w, drw_h, src_w, src_h); @@ -2066,7 +2068,7 @@ i830_display_video(ScrnInfoPtr pScrn, xf86CrtcPtr crtc, OCMD |= BUFFER1; overlay->OCMD = OCMD; - OVERLAY_DEBUG("OCMD is 0x%lx\n", OCMD); + OVERLAY_DEBUG("OCMD is 0x%" PRIx32 "\n", OCMD); /* make sure the overlay is on */ i830_overlay_on (pScrn); diff --git a/src/ivch/ivch.c b/src/ivch/ivch.c index eb5dc21..820919f 100644 --- a/src/ivch/ivch.c +++ b/src/ivch/ivch.c @@ -358,7 +358,7 @@ ivch_restore(I2CDevPtr d) } -I830I2CVidOutputRec ivch_methods = { +_X_EXPORT I830I2CVidOutputRec ivch_methods = { .init = ivch_init, .dpms = ivch_dpms, .save = ivch_save, diff --git a/src/sil164/sil164.c b/src/sil164/sil164.c index 12fe8e2..f7d414a 100644 --- a/src/sil164/sil164.c +++ b/src/sil164/sil164.c @@ -237,7 +237,7 @@ sil164_restore(I2CDevPtr d) } -I830I2CVidOutputRec SIL164VidOutput = { +_X_EXPORT I830I2CVidOutputRec SIL164VidOutput = { .init = sil164_init, .detect = sil164_detect, .mode_valid = sil164_mode_valid, diff --git a/src/tfp410/tfp410.c b/src/tfp410/tfp410.c index b79fd2a..bb038cd 100644 --- a/src/tfp410/tfp410.c +++ b/src/tfp410/tfp410.c @@ -259,7 +259,7 @@ tfp410_restore(I2CDevPtr d) tfp410WriteByte(tfp, TFP410_CTL_1, tfp->SavedReg.ctl1); } -I830I2CVidOutputRec TFP410VidOutput = { +_X_EXPORT I830I2CVidOutputRec TFP410VidOutput = { .init = tfp410_init, .detect = tfp410_detect, .mode_valid = tfp410_mode_valid,