diff --git a/configure.ac b/configure.ac index b24a154..6120227 100644 --- a/configure.ac +++ b/configure.ac @@ -101,6 +101,10 @@ if test x$DRI = xauto; then [have_dristruct_h="yes"], [have_dristruct_h="no"]) AC_CHECK_FILE([${sdkdir}/damage.h], [have_damage_h="yes"], [have_damage_h="no"]) + AC_CHECK_HEADER(xf86drmMode.h,[DRM_MODE=yes],[DRM_MODE=no],[#include "stdint.h"]) + if test "x$DRM_MODE" = xyes; then + AC_DEFINE(XF86DRM_MODE,1,[DRM kernel modesetting]) + fi if test "$have_dri_h" = yes -a \ "$have_sarea_h" = yes -a \ diff --git a/src/Makefile.am b/src/Makefile.am index dd92c8d..1b1b67c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -130,7 +130,9 @@ intel_drv_la_SOURCES = \ i830_xaa.c \ i830_render.c \ i915_render.c \ - i965_render.c + i965_render.c \ + drmmode_display.c \ + drmmode_display.h INTEL_G4A = \ packed_yuv_sf.g4a \ diff --git a/src/common.h b/src/common.h index f2ae502..ece1def 100644 --- a/src/common.h +++ b/src/common.h @@ -370,7 +370,9 @@ extern int I810_DEBUG; /* mark chipsets without overlay hw */ #define OVERLAY_NOEXIST(pI810) (IS_GM45(pI810) || IS_G4X(pI810)) /* chipsets require graphics mem for hardware status page */ -#define HWS_NEED_GFX(pI810) (IS_G33CLASS(pI810) || IS_GM45(pI810) || IS_G4X(pI810)) +#define HWS_NEED_GFX(pI810) (!pI810->use_drm_mode && \ + (IS_G33CLASS(pI810) || IS_GM45(pI810) || \ + IS_G4X(pI810))) /* chipsets require status page in non stolen memory */ #define HWS_NEED_NONSTOLEN(pI810) (IS_GM45(pI810) || IS_G4X(pI810)) #define SUPPORTS_INTEGRATED_HDMI(pI810) (IS_GM45(pI810) || IS_G4X(pI810)) diff --git a/src/i830.h b/src/i830.h index e2b4885..769fd52 100644 --- a/src/i830.h +++ b/src/i830.h @@ -77,6 +77,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifdef DAMAGE #include "damage.h" #endif +#include "drmmode_display.h" #endif #include "dri_bufmgr.h" #include "intel_bufmgr.h" @@ -702,6 +703,12 @@ typedef struct _I830Rec { enum last_3d *last_3d; + Bool use_drm_mode; +#ifdef XF86DRM_MODE + drmmode_rec drmmode; + int drm_mm_init; +#endif + /** Enables logging of debug output related to mode switching. */ Bool debug_modes; unsigned int quirk_flag; @@ -832,7 +839,9 @@ void i830_init_bufmgr(ScrnInfoPtr pScrn); Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name, i830_memory **buffer, unsigned long size, int flags); #endif - +extern void i830_update_front_offset(ScrnInfoPtr pScrn); +extern uint32_t i830_create_new_fb(ScrnInfoPtr pScrn, int width, int height, + int *pitch); extern Bool I830IsPrimary(ScrnInfoPtr pScrn); extern Bool I830I2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg, diff --git a/src/i830_bios.c b/src/i830_bios.c index fe55d23..ff49025 100644 --- a/src/i830_bios.c +++ b/src/i830_bios.c @@ -180,11 +180,17 @@ i830_bios_init(ScrnInfoPtr pScrn) int vbt_off, bdb_off; unsigned char *bios; vbeInfoPtr pVbe; + pointer pVBEModule = NULL; bios = xalloc(INTEL_VBIOS_SIZE); if (bios == NULL) return -1; + /* Load vbe module */ + if (!(pVBEModule = xf86LoadSubModule(pScrn, "vbe"))) + return FALSE; + xf86LoaderReqSymLists(I810vbeSymbols, NULL); + pVbe = VBEInit(NULL, pI830->pEnt->index); if (pVbe != NULL) { memcpy(bios, xf86int10Addr(pVbe->pInt10, diff --git a/src/i830_dri.c b/src/i830_dri.c index d40ada5..9d7271e 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -766,20 +766,22 @@ I830InitTextureHeap(ScrnInfoPtr pScrn) } } -/** - * Sets up mappings for static, lifetime-fixed allocations, and inital SAREA - * setup. +/* + * Map registers & ring buffer */ -Bool -I830DRIDoMappings(ScreenPtr pScreen) +static Bool +I830DRIMapHW(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; I830Ptr pI830 = I830PTR(pScrn); DRIInfoPtr pDRIInfo = pI830->pDRIInfo; I830DRIPtr pI830DRI = pDRIInfo->devPrivate; - drmI830Sarea *sarea = (drmI830Sarea *) DRIGetSAREAPrivate(pScreen); - DPRINTF(PFX, "I830DRIDoMappings\n"); + /* Kernel deals with direct hw access in this case */ + if (pI830->use_drm_mode) + return TRUE; + + DPRINTF(PFX, "I830DRIMapHW\n"); pI830DRI->regsSize = I830_REG_SIZE; if (drmAddMap(pI830->drmSubFD, (drm_handle_t)pI830->MMIOAddr, pI830DRI->regsSize, DRM_REGISTERS, 0, @@ -806,6 +808,27 @@ I830DRIDoMappings(ScreenPtr pScreen) (int)pI830->ring_map); } + return TRUE; +} + +/** + * Sets up mappings for static, lifetime-fixed allocations, and inital SAREA + * setup. + */ +Bool +I830DRIDoMappings(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + DRIInfoPtr pDRIInfo = pI830->pDRIInfo; + I830DRIPtr pI830DRI = pDRIInfo->devPrivate; + drmI830Sarea *sarea = (drmI830Sarea *) DRIGetSAREAPrivate(pScreen); + + if (!I830DRIMapHW(pScreen)) { + DRICloseScreen(pScreen); + return FALSE; + } + if (!I830InitDma(pScrn)) { DRICloseScreen(pScreen); return FALSE; diff --git a/src/i830_driver.c b/src/i830_driver.c index 8ea05af..01073fe 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -177,6 +177,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "xf86_OSproc.h" #include "xf86Resources.h" #include "xf86RAC.h" +#include "xf86Priv.h" #include "xf86cmap.h" #include "compiler.h" #include "mibstore.h" @@ -426,17 +427,6 @@ I830FreeRec(ScrnInfoPtr pScrn) pScrn->driverPrivate = NULL; } -static void -I830ProbeDDC(ScrnInfoPtr pScrn, int index) -{ - vbeInfoPtr pVbe; - - /* The vbe module gets loaded in PreInit(), so no need to load it here. */ - - pVbe = VBEInit(NULL, index); - ConfiguredMonitor = vbeDoEDID(pVbe, NULL); -} - static int I830DetectMemory(ScrnInfoPtr pScrn) { @@ -835,11 +825,12 @@ I830LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, } } -static void +void i830_update_front_offset(ScrnInfoPtr pScrn) { ScreenPtr pScreen = pScrn->pScreen; I830Ptr pI830 = I830PTR(pScrn); + int pitch = pScrn->displayWidth * pI830->cpp; /* Update buffer locations, which may have changed as a result of * i830_bind_all_memory(). @@ -851,9 +842,9 @@ i830_update_front_offset(ScrnInfoPtr pScrn) */ if (!pI830->starting && pI830->accel != ACCEL_UXA) { if (!pScreen->ModifyPixmapHeader(pScreen->GetScreenPixmap(pScreen), - -1, -1, -1, -1, -1, - (pointer)(pI830->FbBase + - pScrn->fbOffset))) + pScrn->virtualX, pScrn->virtualY, -1, -1, + pitch, (pointer)(pI830->FbBase + + pScrn->fbOffset))) FatalError("Couldn't adjust screen pixmap\n"); } } @@ -1116,6 +1107,10 @@ i830SetHotkeyControl(ScrnInfoPtr pScrn, int mode) I830Ptr pI830 = I830PTR(pScrn); uint8_t gr18; + /* Don't mess with kernel settings... */ + if (pI830->use_drm_mode) + return; + gr18 = pI830->readControl(pI830, GRX, 0x18); if (mode == HOTKEY_BIOS_SWITCH) gr18 &= ~HOTKEY_VBIOS_SWITCH_BLOCK; @@ -1124,6 +1119,45 @@ i830SetHotkeyControl(ScrnInfoPtr pScrn, int mode) pI830->writeControl(pI830, GRX, 0x18, gr18); } +#ifdef XF86DRM_MODE +/* + * DRM mode setting Linux only at this point... later on we could + * add a wrapper here. + */ +#include + +static Bool i830_kernel_mode_enabled(ScrnInfoPtr pScrn) +{ +#if XSERVER_LIBPCIACCESS + struct pci_device *PciInfo; +#else + pciVideoPtr PciInfo; +#endif + EntityInfoPtr pEnt; + char *busIdString; + int ret; + + pEnt = xf86GetEntityInfo(pScrn->entityList[0]); + PciInfo = xf86GetPciInfoForEntity(pEnt->index); + + if (!xf86LoaderCheckSymbol("DRICreatePCIBusID")) + return FALSE; + + busIdString = DRICreatePCIBusID(PciInfo); + + ret = drmCheckModesettingSupported(busIdString); + xfree(busIdString); + if (ret) + return FALSE; + + ioctl(xf86Info.consoleFd, KDSETMODE, KD_TEXT); + + return TRUE; +} +#else +#define i830_kernel_mode_enabled(x) FALSE +#endif + static Bool i830_detect_chipset(ScrnInfoPtr pScrn) { @@ -1133,6 +1167,11 @@ i830_detect_chipset(ScrnInfoPtr pScrn) uint32_t capid; int fb_bar, mmio_bar; + + /* We have to use PIO to probe, because we haven't mapped yet. */ + if (!pI830->use_drm_mode) + I830SetPIOAccess(pI830); + switch (DEVICE_ID(pI830->PciInfo)) { case PCI_CHIP_I830_M: chipname = "830M"; @@ -1260,6 +1299,19 @@ i830_detect_chipset(ScrnInfoPtr pScrn) xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", (pScrn->chipset != NULL) ? pScrn->chipset : "Unknown i8xx"); + /* Check if the HW cursor needs physical address. */ + if (IS_MOBILE(pI830) || IS_I9XX(pI830)) + pI830->CursorNeedsPhysical = TRUE; + else + pI830->CursorNeedsPhysical = FALSE; + + if (IS_I965G(pI830) || IS_G33CLASS(pI830)) + pI830->CursorNeedsPhysical = FALSE; + + /* Skip the rest if the kernel is taking care of things */ + if (pI830->use_drm_mode) + return TRUE; + /* Now that we know the chipset, figure out the resource base addrs */ if (IS_I9XX(pI830)) { fb_bar = 2; @@ -1347,6 +1399,342 @@ static const char *accel_name[] = "UXA", }; +static Bool +I830LoadSyms(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + + if (pI830->use_drm_mode) + return TRUE; + + /* Load int10 module */ + if (!xf86LoadSubModule(pScrn, "int10")) + return FALSE; + xf86LoaderReqSymLists(I810int10Symbols, NULL); + + /* The vgahw module should be loaded here when needed */ + if (!xf86LoadSubModule(pScrn, "vgahw")) + return FALSE; + xf86LoaderReqSymLists(I810vgahwSymbols, NULL); + + return TRUE; +} + +static Bool +I830GetEarlyOptions(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + + /* Process the options */ + xf86CollectOptions(pScrn, NULL); + if (!(pI830->Options = xalloc(sizeof(I830Options)))) + return FALSE; + memcpy(pI830->Options, I830Options, sizeof(I830Options)); + xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pI830->Options); + + if (xf86ReturnOptValBool(pI830->Options, OPTION_MODEDEBUG, FALSE)) { + pI830->debug_modes = TRUE; + } else { + pI830->debug_modes = FALSE; + } + + if (xf86ReturnOptValBool(pI830->Options, OPTION_LVDS24BITMODE, FALSE)) { + pI830->lvds_24_bit_mode = TRUE; + } else { + pI830->lvds_24_bit_mode = FALSE; + } + + if (xf86ReturnOptValBool(pI830->Options, OPTION_LVDSFIXEDMODE, TRUE)) { + pI830->skip_panel_detect = TRUE; + } else { + pI830->skip_panel_detect = FALSE; + } + + if (xf86ReturnOptValBool(pI830->Options, OPTION_FORCEENABLEPIPEA, FALSE)) + pI830->quirk_flag |= QUIRK_PIPEA_FORCE; + + return TRUE; +} + +static void +I830PreInitCrtcConfig(ScrnInfoPtr pScrn) +{ + xf86CrtcConfigPtr xf86_config; + I830Ptr pI830 = I830PTR(pScrn); + int max_width, max_height; + + if (pI830->use_drm_mode) + return; + + /* check quirks */ + i830_fixup_devices(pScrn); + + /* Allocate an xf86CrtcConfig */ + xf86CrtcConfigInit (pScrn, &i830_xf86crtc_config_funcs); + xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + + /* See i830_exa.c comments for why we limit the framebuffer size like this. + */ + if (IS_I965G(pI830)) { + max_width = 8192; + max_height = 8192; + } else { + max_width = 2048; + max_height = 2048; + } + xf86CrtcSetSizeRange (pScrn, 320, 200, max_width, max_height); +} + +static Bool +I830AccelMethodInit(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + MessageType from = X_PROBED; + char *s; + int i, num_pipe; + + if (xf86ReturnOptValBool(pI830->Options, OPTION_NOACCEL, FALSE)) { + pI830->accel = ACCEL_NONE; + } + + /* + * The ugliness below: + * If either XAA or EXA (exclusive) is compiled in, default to it. + * + * If both are compiled in, and the user didn't specify noAccel, use the + * config option AccelMethod to determine which to use, defaulting to EXA + * if none is specified, or if the string was unrecognized. + * + * All this *could* go away if we removed XAA support from this driver, + * for example. :) + */ + if (!(pI830->accel == ACCEL_NONE)) { +#ifdef I830_USE_UXA + pI830->accel = ACCEL_UXA; +#endif +#ifdef I830_USE_EXA + pI830->accel = ACCEL_EXA; +#endif +#if I830_USE_XAA + I830_USE_EXA + I830_USE_UXA >= 2 + from = X_DEFAULT; + if ((s = (char *)xf86GetOptValString(pI830->Options, + OPTION_ACCELMETHOD))) { + if (!xf86NameCmp(s, "EXA")) { + from = X_CONFIG; + pI830->accel = ACCEL_EXA; + } + else if (!xf86NameCmp(s, "XAA")) { + from = X_CONFIG; + pI830->accel = ACCEL_XAA; + } + else if (!xf86NameCmp(s, "UXA")) { + from = X_CONFIG; + pI830->accel = ACCEL_UXA; + } + } +#endif + xf86DrvMsg(pScrn->scrnIndex, from, "Using %s for acceleration\n", + accel_name[pI830->accel]); + } + + if (xf86ReturnOptValBool(pI830->Options, OPTION_SW_CURSOR, FALSE)) { + pI830->SWCursor = TRUE; + } + + pI830->directRenderingDisabled = + !xf86ReturnOptValBool(pI830->Options, OPTION_DRI, TRUE); + +#ifdef XF86DRI + if (!pI830->directRenderingDisabled) { + if ((pI830->accel == ACCEL_NONE) || pI830->SWCursor) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "DRI is disabled because it " + "needs HW cursor and 2D acceleration.\n"); + pI830->directRenderingDisabled = TRUE; + } else if (pScrn->depth != 16 && pScrn->depth != 24) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "DRI is disabled because it " + "runs only at depths 16 and 24.\n"); + pI830->directRenderingDisabled = TRUE; + } + + if (!pI830->directRenderingDisabled) { + pI830->allocate_classic_textures = TRUE; + + from = X_PROBED; + +#ifdef XF86DRI_MM + if (!IS_I965G(pI830)) { + Bool tmp; + + if (xf86GetOptValBool(pI830->Options, + OPTION_INTELTEXPOOL, &tmp)) { + from = X_CONFIG; + if (!tmp) + pI830->allocate_classic_textures = FALSE; + } + } +#endif /* XF86DRI_MM */ + } + } +#endif /* XF86DRI */ + + I830MapMMIO(pScrn); + + if (pI830->debug_modes) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Hardware state on X startup:\n"); + i830DumpRegs (pScrn); + } + + i830TakeRegSnapshot(pScrn); + + if (DEVICE_ID(pI830->PciInfo) == PCI_CHIP_E7221_G) + num_pipe = 1; + else + if (IS_MOBILE(pI830) || IS_I9XX(pI830)) + num_pipe = 2; + else + num_pipe = 1; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%d display pipe%s available.\n", + num_pipe, num_pipe > 1 ? "s" : ""); + + I830PreInitDDC(pScrn); + for (i = 0; i < num_pipe; i++) { + i830_crtc_init(pScrn, i); + } + I830SetupOutputs(pScrn); + + SaveHWState(pScrn); + if (!xf86InitialConfiguration (pScrn, FALSE)) + { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n"); + RestoreHWState(pScrn); + PreInitCleanup(pScrn); + return FALSE; + } + RestoreHWState(pScrn); + + /* XXX This should go away, replaced by xf86Crtc.c support for it */ + pI830->rotation = RR_Rotate_0; + + /* + * Let's setup the mobile systems to check the lid status + */ + if (IS_MOBILE(pI830)) { + pI830->checkDevices = TRUE; + + if (!xf86ReturnOptValBool(pI830->Options, OPTION_CHECKDEVICES, TRUE)) { + pI830->checkDevices = FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitoring connected displays disabled\n"); + } else + if (pI830->entityPrivate && !I830IsPrimary(pScrn) && + !I830PTR(pI830->entityPrivate->pScrn_1)->checkDevices) { + /* If checklid is off, on the primary head, then + * turn it off on the secondary*/ + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitoring connected displays disabled\n"); + pI830->checkDevices = FALSE; + } else + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitoring connected displays enabled\n"); + } else + pI830->checkDevices = FALSE; + + pI830->stolen_size = I830DetectMemory(pScrn); + + return TRUE; +} + +static Bool +I830DrmModeInit(ScrnInfoPtr pScrn) +{ +#ifdef XF86DRM_MODE + I830Ptr pI830 = I830PTR(pScrn); + char *bus_id; + + bus_id = DRICreatePCIBusID(pI830->PciInfo); + if (drmmode_pre_init(pScrn, &pI830->drmmode, bus_id, "i915", + pI830->cpp) == FALSE) { + xfree(bus_id); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Kernel modesetting setup failed\n"); + PreInitCleanup(pScrn); + return FALSE; + } + + pI830->drmmode.create_new_fb = i830_create_new_fb; + + pI830->drmSubFD = pI830->drmmode.fd; + xfree(bus_id); + + pI830->accel = ACCEL_EXA; + pI830->directRenderingDisabled = FALSE; + pI830->allocate_classic_textures = FALSE; + + I830InitBufMgr(pScrn); +#endif + + return TRUE; +} + +static void +I830XvInit(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + MessageType from = X_PROBED; + + pI830->XvDisabled = + !xf86ReturnOptValBool(pI830->Options, OPTION_XVIDEO, TRUE); + +#ifdef I830_XV + if (xf86GetOptValInteger(pI830->Options, OPTION_VIDEO_KEY, + &(pI830->colorKey))) { + from = X_CONFIG; + } else if (xf86GetOptValInteger(pI830->Options, OPTION_COLOR_KEY, + &(pI830->colorKey))) { + from = X_CONFIG; + } else { + pI830->colorKey = + (1 << pScrn->offset.red) | (1 << pScrn->offset.green) | + (((pScrn->mask.blue >> pScrn->offset.blue) - 1) << + pScrn->offset.blue); + from = X_DEFAULT; + } + xf86DrvMsg(pScrn->scrnIndex, from, "video overlay key set to 0x%x\n", + pI830->colorKey); +#endif +#ifdef INTEL_XVMC + pI830->XvMCEnabled = FALSE; + from = (!pI830->directRenderingDisabled && + xf86GetOptValBool(pI830->Options, OPTION_XVMC, + &pI830->XvMCEnabled)) ? X_CONFIG : X_DEFAULT; + xf86DrvMsg(pScrn->scrnIndex, from, "Intel XvMC decoder %sabled\n", + pI830->XvMCEnabled ? "en" : "dis"); +#endif +} + +static void +I830DriOptsInit(ScrnInfoPtr pScrn) +{ +#ifdef XF86DRI + I830Ptr pI830 = I830PTR(pScrn); + MessageType from = X_PROBED; + + pI830->allowPageFlip = FALSE; + from = (!pI830->directRenderingDisabled && + xf86GetOptValBool(pI830->Options, OPTION_PAGEFLIP, + &pI830->allowPageFlip)) ? X_CONFIG : X_DEFAULT; + + xf86DrvMsg(pScrn->scrnIndex, from, "Will%s try to enable page flipping\n", + pI830->allowPageFlip ? "" : " not"); + + pI830->TripleBuffer = FALSE; + from = (!pI830->directRenderingDisabled && + xf86GetOptValBool(pI830->Options, OPTION_TRIPLEBUFFER, + &pI830->TripleBuffer)) ? X_CONFIG : X_DEFAULT; + + xf86DrvMsg(pScrn->scrnIndex, from, "Triple buffering %sabled\n", + pI830->TripleBuffer ? "en" : "dis"); +#endif /* XF86DRI */ +} + /** * This is called per zaphod head (so usually just once) to do initialization * before the Screen is created. @@ -1357,48 +1745,24 @@ static const char *accel_name[] = static Bool I830PreInit(ScrnInfoPtr pScrn, int flags) { - xf86CrtcConfigPtr xf86_config; vgaHWPtr hwp; I830Ptr pI830; - MessageType from = X_PROBED; rgb defaultWeight = { 0, 0, 0 }; EntityInfoPtr pEnt; - I830EntPtr pI830Ent = NULL; + I830EntPtr pI830Ent = NULL; int flags24; - int i; - char *s; - pointer pVBEModule = NULL; - int num_pipe; - int max_width, max_height; + Gamma zeros = { 0.0, 0.0, 0.0 }; + int drm_mode_setting; if (pScrn->numEntities != 1) return FALSE; - /* Load int10 module */ - if (!xf86LoadSubModule(pScrn, "int10")) - return FALSE; - xf86LoaderReqSymLists(I810int10Symbols, NULL); - - /* Load vbe module */ - if (!(pVBEModule = xf86LoadSubModule(pScrn, "vbe"))) - return FALSE; - xf86LoaderReqSymLists(I810vbeSymbols, NULL); + drm_mode_setting = i830_kernel_mode_enabled(pScrn); pEnt = xf86GetEntityInfo(pScrn->entityList[0]); - if (flags & PROBE_DETECT) { - I830ProbeDDC(pScrn, pEnt->index); - return TRUE; - } - - /* The vgahw module should be loaded here when needed */ - if (!xf86LoadSubModule(pScrn, "vgahw")) - return FALSE; - xf86LoaderReqSymLists(I810vgahwSymbols, NULL); - - /* Allocate a vgaHWRec */ - if (!vgaHWGetHWRec(pScrn)) - return FALSE; + if (flags & PROBE_DETECT) + return TRUE; /* Allocate driverPrivate */ if (!I830GetRec(pScrn)) @@ -1407,6 +1771,17 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) pI830 = I830PTR(pScrn); pI830->SaveGeneration = -1; pI830->pEnt = pEnt; + pI830->use_drm_mode = drm_mode_setting; + + if (!I830LoadSyms(pScrn)) + return FALSE; + + if (!drm_mode_setting) { + /* Allocate a vgaHWRec */ + if (!vgaHWGetHWRec(pScrn)) + return FALSE; + hwp = VGAHWPTR(pScrn); + } pScrn->displayWidth = 640; /* default it */ @@ -1424,7 +1799,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) pI830Ent = xf86GetEntityPrivate(pScrn->entityList[0], I830EntityIndex)->ptr; pI830->entityPrivate = pI830Ent; - } else + } else pI830->entityPrivate = NULL; if (xf86RegisterResources(pI830->pEnt->index, NULL, ResNone)) { @@ -1490,284 +1865,31 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) pI830->preinit = TRUE; - /* Process the options */ - xf86CollectOptions(pScrn, NULL); - if (!(pI830->Options = xalloc(sizeof(I830Options)))) - return FALSE; - memcpy(pI830->Options, I830Options, sizeof(I830Options)); - xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pI830->Options); - - if (xf86ReturnOptValBool(pI830->Options, OPTION_MODEDEBUG, FALSE)) { - pI830->debug_modes = TRUE; - } else { - pI830->debug_modes = FALSE; - } - - if (xf86ReturnOptValBool(pI830->Options, OPTION_LVDS24BITMODE, FALSE)) { - pI830->lvds_24_bit_mode = TRUE; - } else { - pI830->lvds_24_bit_mode = FALSE; - } - - if (xf86ReturnOptValBool(pI830->Options, OPTION_LVDSFIXEDMODE, TRUE)) { - pI830->skip_panel_detect = TRUE; - } else { - pI830->skip_panel_detect = FALSE; - } - - if (xf86ReturnOptValBool(pI830->Options, OPTION_FORCEENABLEPIPEA, FALSE)) - pI830->quirk_flag |= QUIRK_PIPEA_FORCE; - - /* We have to use PIO to probe, because we haven't mapped yet. */ - I830SetPIOAccess(pI830); + if (!I830GetEarlyOptions(pScrn)) + return FALSE; if (!i830_detect_chipset(pScrn)) return FALSE; - /* check quirks */ - i830_fixup_devices(pScrn); - - /* Allocate an xf86CrtcConfig */ - xf86CrtcConfigInit (pScrn, &i830_xf86crtc_config_funcs); - xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - - /* See i830_exa.c comments for why we limit the framebuffer size like this. - */ - if (IS_I965G(pI830)) { - max_width = 8192; - max_height = 8192; - } else { - max_width = 2048; - max_height = 2048; - } - xf86CrtcSetSizeRange (pScrn, 320, 200, max_width, max_height); - - /* Some of the probing needs MMIO access, so map it here. */ - I830MapMMIO(pScrn); + I830PreInitCrtcConfig(pScrn); - if (pI830->debug_modes) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hardware state on X startup:\n"); - i830DumpRegs (pScrn); - } - - i830TakeRegSnapshot(pScrn); + if (pI830->use_drm_mode && !I830DrmModeInit(pScrn)) + return FALSE; + else if (!I830AccelMethodInit(pScrn)) + return FALSE; - if (DEVICE_ID(pI830->PciInfo) == PCI_CHIP_E7221_G) - num_pipe = 1; - else - if (IS_MOBILE(pI830) || IS_I9XX(pI830)) - num_pipe = 2; - else - num_pipe = 1; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%d display pipe%s available.\n", - num_pipe, num_pipe > 1 ? "s" : ""); + I830XvInit(pScrn); - if (xf86ReturnOptValBool(pI830->Options, OPTION_NOACCEL, FALSE)) { - pI830->accel = ACCEL_NONE; - } + I830DriOptsInit(pScrn); - /* - * The ugliness below: - * If either XAA or EXA (exclusive) is compiled in, default to it. - * - * If both are compiled in, and the user didn't specify noAccel, use the - * config option AccelMethod to determine which to use, defaulting to EXA - * if none is specified, or if the string was unrecognized. - * - * All this *could* go away if we removed XAA support from this driver, - * for example. :) - */ - if (pI830->accel == ACCEL_UNINIT) { - pI830->accel = ACCEL_NONE; -#ifdef I830_USE_XAA - pI830->accel = ACCEL_XAA; -#endif -#ifdef I830_USE_UXA - pI830->accel = ACCEL_UXA; -#endif -#ifdef I830_USE_EXA - pI830->accel = ACCEL_EXA; -#endif -#if I830_USE_XAA + I830_USE_EXA + I830_USE_UXA >= 2 - from = X_DEFAULT; - if ((s = (char *)xf86GetOptValString(pI830->Options, - OPTION_ACCELMETHOD))) { - if (!xf86NameCmp(s, "EXA")) { - from = X_CONFIG; - pI830->accel = ACCEL_EXA; - } - else if (!xf86NameCmp(s, "XAA")) { - from = X_CONFIG; - pI830->accel = ACCEL_XAA; - } - else if (!xf86NameCmp(s, "UXA")) { - from = X_CONFIG; - pI830->accel = ACCEL_UXA; - } - } -#endif - } - xf86DrvMsg(pScrn->scrnIndex, from, "Using %s acceleration\n", - accel_name[pI830->accel]); - - if (xf86ReturnOptValBool(pI830->Options, OPTION_SW_CURSOR, FALSE)) { - pI830->SWCursor = TRUE; + if (!xf86SetGamma(pScrn, zeros)) { + PreInitCleanup(pScrn); + return FALSE; } - pI830->directRenderingDisabled = - !xf86ReturnOptValBool(pI830->Options, OPTION_DRI, TRUE); - -#ifdef XF86DRI - if (!pI830->directRenderingDisabled) { - if (pI830->accel == ACCEL_NONE || pI830->SWCursor) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "DRI is disabled because it " - "needs HW cursor and 2D acceleration.\n"); - pI830->directRenderingDisabled = TRUE; - } else if (pScrn->depth != 16 && pScrn->depth != 24) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "DRI is disabled because it " - "runs only at depths 16 and 24.\n"); - pI830->directRenderingDisabled = TRUE; - } - - if (!pI830->directRenderingDisabled) { - pI830->allocate_classic_textures = TRUE; - - from = X_PROBED; - -#ifdef XF86DRI - if (!IS_I965G(pI830)) { - Bool tmp; - - if (xf86GetOptValBool(pI830->Options, - OPTION_INTELTEXPOOL, &tmp)) { - from = X_CONFIG; - if (!tmp) - pI830->allocate_classic_textures = FALSE; - } - } -#endif - } - } - -#endif - if (i830_bios_init(pScrn)) - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "VBIOS initialization failed.\n"); - - I830PreInitDDC(pScrn); - for (i = 0; i < num_pipe; i++) { - i830_crtc_init(pScrn, i); - } - I830SetupOutputs(pScrn); - - SaveHWState(pScrn); - if (!xf86InitialConfiguration (pScrn, FALSE)) - { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n"); - RestoreHWState(pScrn); - PreInitCleanup(pScrn); - return FALSE; - } - RestoreHWState(pScrn); - - /* XXX This should go away, replaced by xf86Crtc.c support for it */ - pI830->rotation = RR_Rotate_0; - - /* - * Let's setup the mobile systems to check the lid status - */ - if (IS_MOBILE(pI830)) { - pI830->checkDevices = TRUE; - - if (!xf86ReturnOptValBool(pI830->Options, OPTION_CHECKDEVICES, TRUE)) { - pI830->checkDevices = FALSE; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitoring connected displays disabled\n"); - } else - if (pI830->entityPrivate && !I830IsPrimary(pScrn) && - !I830PTR(pI830->entityPrivate->pScrn_1)->checkDevices) { - /* If checklid is off, on the primary head, then - * turn it off on the secondary*/ - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitoring connected displays disabled\n"); - pI830->checkDevices = FALSE; - } else - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitoring connected displays enabled\n"); - } else - pI830->checkDevices = FALSE; - - pI830->stolen_size = I830DetectMemory(pScrn); - - pI830->XvDisabled = - !xf86ReturnOptValBool(pI830->Options, OPTION_XVIDEO, TRUE); - -#ifdef I830_XV - if (xf86GetOptValInteger(pI830->Options, OPTION_VIDEO_KEY, - &(pI830->colorKey))) { - from = X_CONFIG; - } else if (xf86GetOptValInteger(pI830->Options, OPTION_COLOR_KEY, - &(pI830->colorKey))) { - from = X_CONFIG; - } else { - pI830->colorKey = (1 << pScrn->offset.red) | - (1 << pScrn->offset.green) | - (((pScrn->mask.blue >> pScrn->offset.blue) - 1) << - pScrn->offset.blue); - from = X_DEFAULT; - } - xf86DrvMsg(pScrn->scrnIndex, from, "video overlay key set to 0x%x\n", - pI830->colorKey); -#endif - -#ifdef XF86DRI - pI830->allowPageFlip = FALSE; - from = (!pI830->directRenderingDisabled && - xf86GetOptValBool(pI830->Options, OPTION_PAGEFLIP, - &pI830->allowPageFlip)) ? X_CONFIG : X_DEFAULT; - - xf86DrvMsg(pScrn->scrnIndex, from, "Will%s try to enable page flipping\n", - pI830->allowPageFlip ? "" : " not"); -#endif - -#ifdef XF86DRI - pI830->TripleBuffer = FALSE; - from = (!pI830->directRenderingDisabled && - xf86GetOptValBool(pI830->Options, OPTION_TRIPLEBUFFER, - &pI830->TripleBuffer)) ? X_CONFIG : X_DEFAULT; - - xf86DrvMsg(pScrn->scrnIndex, from, "Triple buffering %sabled\n", - pI830->TripleBuffer ? "en" : "dis"); -#endif - -#ifdef INTEL_XVMC - pI830->XvMCEnabled = FALSE; - from = (!pI830->directRenderingDisabled && - xf86GetOptValBool(pI830->Options, OPTION_XVMC, - &pI830->XvMCEnabled)) ? X_CONFIG : X_DEFAULT; - xf86DrvMsg(pScrn->scrnIndex, from, "Intel XvMC decoder %sabled\n", - pI830->XvMCEnabled ? "en" : "dis"); -#endif - - /* - * If the driver can do gamma correction, it should call xf86SetGamma() here. - */ - - { - Gamma zeros = { 0.0, 0.0, 0.0 }; - - if (!xf86SetGamma(pScrn, zeros)) { - PreInitCleanup(pScrn); - return FALSE; - } - } - - /* Check if the HW cursor needs physical address. */ - if (IS_MOBILE(pI830) || IS_I9XX(pI830)) - pI830->CursorNeedsPhysical = TRUE; - else - pI830->CursorNeedsPhysical = FALSE; - - if (IS_I965G(pI830) || IS_G33CLASS(pI830)) - pI830->CursorNeedsPhysical = FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "VBIOS initialization failed.\n"); /* * XXX If we knew the pre-initialised GTT format for certain, we could @@ -1780,8 +1902,8 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) "Using HW Cursor because it's enabled on primary head.\n"); pI830->SWCursor = FALSE; } - } else - if (pI830->StolenOnly && pI830->CursorNeedsPhysical && !pI830->SWCursor) { + } else if (pI830->StolenOnly && pI830->CursorNeedsPhysical && + !pI830->SWCursor) { xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "HW Cursor disabled because it needs agpgart memory.\n"); pI830->SWCursor = TRUE; @@ -1854,21 +1976,16 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) xf86LoaderReqSymLists(I810ramdacSymbols, NULL); } - i830CompareRegsToSnapshot(pScrn, "After PreInit"); + if (!pI830->use_drm_mode) { + i830CompareRegsToSnapshot(pScrn, "After PreInit"); - I830UnmapMMIO(pScrn); - - /* We won't be using the VGA access after the probe. */ - I830SetMMIOAccess(pI830); - xf86SetOperatingState(resVgaIo, pI830->pEnt->index, ResUnusedOpr); - xf86SetOperatingState(resVgaMem, pI830->pEnt->index, ResDisableOpr); + I830UnmapMMIO(pScrn); -#if 0 - if (I830IsPrimary(pScrn)) { - vbeFree(pI830->pVbe); + /* We won't be using the VGA access after the probe. */ + I830SetMMIOAccess(pI830); + xf86SetOperatingState(resVgaIo, pI830->pEnt->index, ResUnusedOpr); + xf86SetOperatingState(resVgaMem, pI830->pEnt->index, ResDisableOpr); } - pI830->pVbe = NULL; -#endif #if defined(XF86DRI) /* Load the dri module if requested. */ @@ -2819,68 +2936,16 @@ i830_init_bufmgr(ScrnInfoPtr pScrn) } -static Bool -I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) +static void +I830AdjustMemory(ScreenPtr pScreen) { ScrnInfoPtr pScrn; - vgaHWPtr hwp; I830Ptr pI830; - VisualPtr visual; - I830Ptr pI8301 = NULL; unsigned long sys_mem; - int c; MessageType from; -#ifdef XF86DRI - xf86CrtcConfigPtr config; -#endif pScrn = xf86Screens[pScreen->myNum]; pI830 = I830PTR(pScrn); - hwp = VGAHWPTR(pScrn); - - pScrn->displayWidth = (pScrn->virtualX + 63) & ~63; - - /* - * The "VideoRam" config file parameter specifies the maximum amount of - * memory that will be used/allocated. When not present, we allow the - * driver to allocate as much memory as it wishes to satisfy its - * allocations, but if agpgart support isn't available, it gets limited - * to the amount of pre-allocated ("stolen") memory. - * - * Note that in using this value for allocator initialization, we're - * limiting aperture allocation to the VideoRam option, rather than limiting - * actual memory allocation, so alignment and things will cause less than - * VideoRam to be actually used. - */ - if (pI830->pEnt->device->videoRam == 0) { - from = X_DEFAULT; - pScrn->videoRam = pI830->FbMapSize / KB(1); - } else { -#if 0 - from = X_CONFIG; - pScrn->videoRam = pI830->pEnt->device->videoRam; -#else - /* Disable VideoRam configuration, at least for now. Previously, - * VideoRam was necessary to avoid overly low limits on allocated - * memory, so users created larger, yet still small, fixed allocation - * limits in their config files. Now, the driver wants to allocate more, - * and the old intention of the VideoRam lines that had been entered is - * obsolete. - */ - from = X_DEFAULT; - pScrn->videoRam = pI830->FbMapSize / KB(1); - - if (pScrn->videoRam != pI830->pEnt->device->videoRam) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "VideoRam configuration found, which is no longer " - "recommended.\n"); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Continuing with default %dkB VideoRam instead of %d " - "kB.\n", - pScrn->videoRam, pI830->pEnt->device->videoRam); - } -#endif - } /* Limit videoRam to how much we might be able to allocate from AGP */ sys_mem = I830CheckAvailableMemory(pScrn); @@ -2931,6 +2996,129 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) "Cannot support DRI with frame buffer width > 2048.\n"); pI830->directRenderingDisabled = TRUE; } +} + +static void +I830SwapPipes(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + xf86CrtcConfigPtr config; + int c; + + config = XF86_CRTC_CONFIG_PTR(pScrn); + + /* + * If an LVDS display is present, swap the plane/pipe mappings so we can + * use FBC on the builtin display. + * Note: 965+ chips can compress either plane, so we leave the mapping + * alone in that case. + * Also make sure the DRM can handle the swap. + */ + if (I830LVDSPresent(pScrn) && !IS_I965GM(pI830) && !IS_GM45(pI830) && + (!pI830->directRenderingEnabled || + (pI830->directRenderingEnabled && pI830->drmMinor >= 10))) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "adjusting plane->pipe mappings " + "to allow for framebuffer compression\n"); + for (c = 0; c < config->num_crtc; c++) { + xf86CrtcPtr crtc = config->crtc[c]; + I830CrtcPrivatePtr intel_crtc = crtc->driver_private; + + if (intel_crtc->pipe == 0) + intel_crtc->plane = 1; + else if (intel_crtc->pipe == 1) + intel_crtc->plane = 0; + } + } +} + +static Bool +I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) +{ + ScrnInfoPtr pScrn; + vgaHWPtr hwp; + I830Ptr pI830; + VisualPtr visual; + I830Ptr pI8301 = NULL; + MessageType from; + + pScrn = xf86Screens[pScreen->myNum]; + pI830 = I830PTR(pScrn); + + if (!pI830->use_drm_mode) + hwp = VGAHWPTR(pScrn); + + pScrn->displayWidth = (pScrn->virtualX + 63) & ~63; + + /* + * The "VideoRam" config file parameter specifies the maximum amount of + * memory that will be used/allocated. When not present, we allow the + * driver to allocate as much memory as it wishes to satisfy its + * allocations, but if agpgart support isn't available, it gets limited + * to the amount of pre-allocated ("stolen") memory. + * + * Note that in using this value for allocator initialization, we're + * limiting aperture allocation to the VideoRam option, rather than limiting + * actual memory allocation, so alignment and things will cause less than + * VideoRam to be actually used. + */ + if (pI830->pEnt->device->videoRam == 0) { + from = X_DEFAULT; + pScrn->videoRam = pI830->FbMapSize / KB(1); + } else { +#if 0 + from = X_CONFIG; + pScrn->videoRam = pI830->pEnt->device->videoRam; +#else + /* Disable VideoRam configuration, at least for now. Previously, + * VideoRam was necessary to avoid overly low limits on allocated + * memory, so users created larger, yet still small, fixed allocation + * limits in their config files. Now, the driver wants to allocate more, + * and the old intention of the VideoRam lines that had been entered is + * obsolete. + */ + from = X_DEFAULT; + pScrn->videoRam = pI830->FbMapSize / KB(1); + + if (pScrn->videoRam != pI830->pEnt->device->videoRam) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "VideoRam configuration found, which is no longer " + "recommended.\n"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Continuing with default %dkB VideoRam instead of %d " + "kB.\n", + pScrn->videoRam, pI830->pEnt->device->videoRam); + } +#endif + } + + if (pI830->use_drm_mode) { +#ifdef XF86DRM_MODE + uint64_t size; + int ret; + ret = drmMMInfo(pI830->drmSubFD, DRM_BO_MEM_VRAM, &size); + if (ret) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Kernel memory manager has no VRAM allocation\n"); + return FALSE; + } + pI830->stolen_size = size * GTT_PAGE_SIZE; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Kernel stolen allocator is %dkb\n", + pI830->stolen_size / KB(1)); + + ret = drmMMInfo(pI830->drmSubFD, DRM_BO_MEM_TT, &size); + if (ret) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Kernel memory manager has no TT allocation\n"); + return FALSE; + } + pScrn->videoRam = (size * GTT_PAGE_SIZE) / KB(1); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Kernel AGP allocator is %dkb\n", pScrn->videoRam); +#endif + } else { + I830AdjustMemory(pScreen); + } #ifdef XF86DRI /* If DRI hasn't been explicitly disabled, try to initialize it. @@ -2969,6 +3157,12 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->fb_compression = FALSE; } + if (pI830->use_drm_mode && pI830->fb_compression == TRUE) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Kernel mode setting active, disabling FBC.\n"); + pI830->fb_compression = FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Framebuffer compression %sabled\n", pI830->fb_compression ? "en" : "dis"); xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Tiling %sabled\n", pI830->tiling ? @@ -3010,7 +3204,8 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) /* Need MMIO mapped to do GTT lookups during memory allocation. */ - I830MapMMIO(pScrn); + if (!pI830->use_drm_mode) + I830MapMMIO(pScrn); if (!i830_memory_init(pScrn)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, @@ -3051,7 +3246,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->XvEnabled = FALSE; #endif - if (pI830->accel != ACCEL_NONE) { + if (pI830->accel != ACCEL_NONE && !pI830->use_drm_mode) { if (pI830->memory_manager == NULL && pI830->LpRing->mem->size == 0) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Disabling acceleration because the ring buffer " @@ -3092,69 +3287,49 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } if (pI830->directRenderingEnabled) - pI830->directRenderingEnabled = I830DRIDoMappings(pScreen); + pI830->directRenderingEnabled = I830DRIDoMappings(pScreen); /* If we failed for any reason, free DRI memory. */ if (!pI830->directRenderingEnabled) - i830_free_3d_memory(pScrn); - - config = XF86_CRTC_CONFIG_PTR(pScrn); - - /* - * If an LVDS display is present, swap the plane/pipe mappings so we can - * use FBC on the builtin display. - * Note: 965+ chips can compress either plane, so we leave the mapping - * alone in that case. - * Also make sure the DRM can handle the swap. - */ - if (I830LVDSPresent(pScrn) && !IS_I965GM(pI830) && !IS_GM45(pI830) && - (!pI830->directRenderingEnabled || - (pI830->directRenderingEnabled && pI830->drmMinor >= 10))) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "adjusting plane->pipe mappings " - "to allow for framebuffer compression\n"); - for (c = 0; c < config->num_crtc; c++) { - xf86CrtcPtr crtc = config->crtc[c]; - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - - if (intel_crtc->pipe == 0) - intel_crtc->plane = 1; - else if (intel_crtc->pipe == 1) - intel_crtc->plane = 0; - } - } + i830_free_3d_memory(pScrn); + if (!pI830->use_drm_mode) + I830SwapPipes(pScrn); #else pI830->directRenderingEnabled = FALSE; #endif #ifdef XF86DRI - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Page Flipping %sabled\n", pI830->allowPageFlip ? "en" : "dis"); #endif - DPRINTF(PFX, "assert( if(!I830MapMem(pScrn)) )\n"); - if (!I830MapMem(pScrn)) - return FALSE; + if (!pI830->use_drm_mode) { + DPRINTF(PFX, "assert( if(!I830MapMem(pScrn)) )\n"); + if (!I830MapMem(pScrn)) + return FALSE; - pScrn->memPhysBase = (unsigned long)pI830->FbBase; + pScrn->memPhysBase = (unsigned long)pI830->FbBase; + } if (I830IsPrimary(pScrn)) { - pScrn->fbOffset = pI830->front_buffer->offset; + pScrn->fbOffset = pI830->front_buffer->offset; } else { - pScrn->fbOffset = pI8301->front_buffer_2->offset; + pScrn->fbOffset = pI8301->front_buffer_2->offset; } pI830->xoffset = (pScrn->fbOffset / pI830->cpp) % pScrn->displayWidth; pI830->yoffset = (pScrn->fbOffset / pI830->cpp) / pScrn->displayWidth; - i830_init_bufmgr(pScrn); + if (!pI830->use_drm_mode) { + vgaHWSetMmioFuncs(hwp, pI830->MMIOBase, 0); + vgaHWGetIOBase(hwp); + DPRINTF(PFX, "assert( if(!vgaHWMapMem(pScrn)) )\n"); + if (!vgaHWMapMem(pScrn)) + return FALSE; + } - vgaHWSetMmioFuncs(hwp, pI830->MMIOBase, 0); - vgaHWGetIOBase(hwp); - DPRINTF(PFX, "assert( if(!vgaHWMapMem(pScrn)) )\n"); - if (!vgaHWMapMem(pScrn)) - return FALSE; + i830_init_bufmgr(pScrn); DPRINTF(PFX, "assert( if(!I830EnterVT(scrnIndex, 0)) )\n"); @@ -3395,21 +3570,22 @@ I830LeaveVT(int scrnIndex, int flags) I830Sync(pScrn); - RestoreHWState(pScrn); - - /* Evict everything from the bufmgr, as we're about to lose ownership of - * the graphics memory. - */ - if (!pI830->memory_manager) - intel_bufmgr_fake_evict_all(pI830->bufmgr); - intel_batch_teardown(pScrn); + if (!pI830->use_drm_mode) { + RestoreHWState(pScrn); + /* Evict everything from the bufmgr, as we're about to lose ownership of + * the graphics memory. + */ + if (!pI830->memory_manager) + intel_bufmgr_fake_evict_all(pI830->bufmgr); + intel_batch_teardown(pScrn); - if (!pI830->memory_manager) - i830_stop_ring(pScrn, TRUE); + if (!pI830->memory_manager) + i830_stop_ring(pScrn, TRUE); - if (pI830->debug_modes) { - i830CompareRegsToSnapshot(pScrn, "After LeaveVT"); - i830DumpRegs (pScrn); + if (pI830->debug_modes) { + i830CompareRegsToSnapshot(pScrn, "After LeaveVT"); + i830DumpRegs (pScrn); + } } if (I830IsPrimary(pScrn)) @@ -3452,7 +3628,8 @@ I830EnterVT(int scrnIndex, int flags) */ if (pI830->SaveGeneration != serverGeneration) { pI830->SaveGeneration = serverGeneration; - SaveHWState(pScrn); + if (!pI830->use_drm_mode) + SaveHWState(pScrn); } pI830->leaving = FALSE; @@ -3484,39 +3661,43 @@ I830EnterVT(int scrnIndex, int flags) if ((pI830->accel == ACCEL_EXA || pI830->accel == ACCEL_UXA) && IS_I965G(pI830)) gen4_render_state_init(pScrn); - if (i830_check_error_state(pScrn)) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Existing errors found in hardware state.\n"); - } + if (!pI830->use_drm_mode) { + if (i830_check_error_state(pScrn)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Existing errors found in hardware state.\n"); + } - /* Re-set up the ring. */ - if (!pI830->memory_manager) { - i830_stop_ring(pScrn, FALSE); - i830_start_ring(pScrn); - } - if (!pI830->SWCursor) - I830InitHWCursor(pScrn); + /* Re-set up the ring. */ + if (!pI830->memory_manager) { + i830_stop_ring(pScrn, FALSE); + i830_start_ring(pScrn); + } + if (!pI830->SWCursor) + I830InitHWCursor(pScrn); - /* Tell the BIOS that we're in control of mode setting now. */ - i830_init_bios_control(pScrn); + /* Tell the BIOS that we're in control of mode setting now. */ + i830_init_bios_control(pScrn); - i830_init_clock_gating(pScrn); + i830_init_clock_gating(pScrn); - if (pI830->power_context) - OUTREG(PWRCTXA, pI830->power_context->offset | PWRCTX_EN); + if (pI830->power_context) + OUTREG(PWRCTXA, pI830->power_context->offset | PWRCTX_EN); - /* Clear the framebuffer */ - memset(pI830->FbBase + pScrn->fbOffset, 0, - pScrn->virtualY * pScrn->displayWidth * pI830->cpp); + /* Clear the framebuffer */ + memset(pI830->FbBase + pScrn->fbOffset, 0, + pScrn->virtualY * pScrn->displayWidth * pI830->cpp); + } if (!xf86SetDesiredModes (pScrn)) return FALSE; - - if (pI830->debug_modes) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hardware state at EnterVT:\n"); - i830DumpRegs (pScrn); + + if (!pI830->use_drm_mode) { + if (pI830->debug_modes) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hardware state at EnterVT:\n"); + i830DumpRegs (pScrn); + } + i830DescribeOutputConfiguration(pScrn); } - i830DescribeOutputConfiguration(pScrn); #ifdef XF86DRI if (pI830->directRenderingEnabled) { @@ -3614,9 +3795,11 @@ I830CloseScreen(int scrnIndex, ScreenPtr pScreen) TimerCancel(pI830->devicesTimer); pI830->devicesTimer = NULL; - DPRINTF(PFX, "\nUnmapping memory\n"); - I830UnmapMem(pScrn); - vgaHWUnmapMem(pScrn); + if (!pI830->use_drm_mode) { + DPRINTF(PFX, "\nUnmapping memory\n"); + I830UnmapMem(pScrn); + vgaHWUnmapMem(pScrn); + } if (pI830->ScanlineColorExpandBuffers) { xfree(pI830->ScanlineColorExpandBuffers); diff --git a/src/i830_memory.c b/src/i830_memory.c index ff5def6..57b9d27 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -184,7 +184,7 @@ i830_bind_memory(ScrnInfoPtr pScrn, i830_memory *mem) if (!pI830->gtt_acquired) return TRUE; - if (mem->key != -1 && + if (mem->key != -1 && !xf86BindGARTMemory(pScrn->scrnIndex, mem->key, mem->agp_offset)) { return FALSE; @@ -193,7 +193,7 @@ i830_bind_memory(ScrnInfoPtr pScrn, i830_memory *mem) mem->bound = TRUE; } - if (mem->tiling != TILE_NONE) { + if (mem->tiling != TILE_NONE && pI830->use_drm_mode) { mem->fence_nr = i830_set_tiling(pScrn, mem->offset, mem->pitch, mem->allocated_size, mem->tiling); } @@ -204,10 +204,12 @@ i830_bind_memory(ScrnInfoPtr pScrn, i830_memory *mem) static Bool i830_unbind_memory(ScrnInfoPtr pScrn, i830_memory *mem) { + I830Ptr pI830 = I830PTR(pScrn); + if (mem == NULL || !mem->bound) return TRUE; - if (mem->tiling != TILE_NONE) + if (mem->tiling != TILE_NONE && !pI830->use_drm_mode) i830_clear_tiling(pScrn, mem->fence_nr); #ifdef XF86DRI @@ -460,22 +462,24 @@ i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, unsigned long size) ALIGN_BOTH_ENDS | NEED_NON_STOLEN); if (pI830->memory_manager != NULL) { - struct drm_i915_gem_init init; - int ret; - - init.gtt_start = pI830->memory_manager->offset; - init.gtt_end = pI830->memory_manager->offset + - pI830->memory_manager->size; - - /* Tell the kernel to manage it */ - ret = ioctl(pI830->drmSubFD, DRM_IOCTL_I915_GEM_INIT, &init); - if (ret != 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to initialize kernel memory manager\n"); - i830_free_memory(pScrn, pI830->memory_manager); - pI830->memory_manager = NULL; + if (!pI830->use_drm_mode) { + struct drm_i915_gem_init init; + int ret; + + init.gtt_start = pI830->memory_manager->offset; + init.gtt_end = pI830->memory_manager->offset + + pI830->memory_manager->size; + + /* Tell the kernel to manage it */ + ret = ioctl(pI830->drmSubFD, DRM_IOCTL_I915_GEM_INIT, &init); + if (ret != 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to initialize kernel memory manager\n"); + i830_free_memory(pScrn, pI830->memory_manager); + pI830->memory_manager = NULL; + } + i830_init_bufmgr(pScrn); } - i830_init_bufmgr(pScrn); } else { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate space for kernel memory manager\n"); @@ -800,8 +804,9 @@ i830_allocate_memory(ScrnInfoPtr pScrn, const char *name, #ifdef XF86DRI I830Ptr pI830 = I830PTR(pScrn); - if (pI830->memory_manager && !(flags & NEED_PHYSICAL_ADDR) && - !(flags & NEED_LIFETIME_FIXED)) + if (pI830->use_drm_mode || (pI830->memory_manager && + !(flags & NEED_PHYSICAL_ADDR) && + !(flags & NEED_LIFETIME_FIXED))) { return i830_allocate_memory_bo(pScrn, name, size, alignment, flags); } else @@ -1025,6 +1030,7 @@ i830_allocate_overlay(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); int flags = 0; + int mem_space = DRM_BO_FLAG_MEM_TT; /* Only allocate if overlay is going to be enabled. */ if (!pI830->XvEnabled) @@ -1045,6 +1051,10 @@ i830_allocate_overlay(ScrnInfoPtr pScrn) /* This failure isn't fatal. */ } + if (flags & NEED_PHYSICAL_ADDR) + if (pI830->use_drm_mode) + mem_space = DRM_BO_FLAG_MEM_VRAM; + return TRUE; } #endif @@ -1122,7 +1132,7 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, /* We'll allocate the fb such that the root window will fit regardless of * rotation. */ - if (pScrn->virtualX > pScrn->virtualY) + if (!pI830->use_drm_mode && pScrn->virtualX > pScrn->virtualY) fb_height = pScrn->virtualX; else fb_height = pScrn->virtualY; @@ -1186,7 +1196,7 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, * acceleration operations (non-XY COLOR_BLT) can't be done to tiled * buffers. */ - if (pI830->accel <= ACCEL_XAA && IS_I965G(pI830)) + if ((pI830->accel <= ACCEL_XAA && IS_I965G(pI830)) || pI830->use_drm_mode) tiling = FALSE; else tiling = pI830->tiling; @@ -1215,8 +1225,14 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, return NULL; } - if (pI830->FbBase) + if (pI830->use_drm_mode) { +#ifdef XF86DRM_MODE + drmmode_set_fb(pScrn, &pI830->drmmode, pScrn->virtualX, fb_height, + pScrn->displayWidth * pI830->cpp, &front_buffer->bo); +#endif + } else if (pI830->FbBase) memset (pI830->FbBase + front_buffer->offset, 0, size); + return front_buffer; } @@ -1225,10 +1241,15 @@ i830_allocate_cursor_buffers(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - int flags = pI830->CursorNeedsPhysical ? NEED_PHYSICAL_ADDR : 0; + int flags; int i; long size; + if (pI830->use_drm_mode) + pI830->CursorNeedsPhysical = FALSE; + + flags = pI830->CursorNeedsPhysical ? NEED_PHYSICAL_ADDR : 0; + /* Try to allocate one big blob for our cursor memory. This works * around a limitation in the FreeBSD AGP driver that allows only one * physical allocation larger than a page, and could allow us @@ -1341,18 +1362,20 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn) unsigned int pitch = pScrn->displayWidth * pI830->cpp; long size; - if (!pI830->StolenOnly && - (!xf86AgpGARTSupported() || !xf86AcquireGART(pScrn->scrnIndex))) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "AGP GART support is either not available or cannot " - "be used.\n" - "\tMake sure your kernel has agpgart support or has\n" - "\tthe agpgart module loaded.\n"); - return FALSE; - } + if (!pI830->use_drm_mode) { + if (!pI830->StolenOnly && + (!xf86AgpGARTSupported() || !xf86AcquireGART(pScrn->scrnIndex))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "AGP GART support is either not available or cannot " + "be used.\n" + "\tMake sure your kernel has agpgart support or has\n" + "\tthe agpgart module loaded.\n"); + return FALSE; + } - /* Allocate the ring buffer first, so it ends up in stolen mem. */ - i830_allocate_ringbuffer(pScrn); + /* Allocate the ring buffer first, so it ends up in stolen mem. */ + i830_allocate_ringbuffer(pScrn); + } if (pI830->fb_compression) i830_setup_fb_compression(pScrn); @@ -1950,13 +1973,15 @@ i830_bind_all_memory(ScrnInfoPtr pScrn) if (pI830->StolenOnly == TRUE || pI830->memory_list == NULL) return TRUE; - if (xf86AgpGARTSupported() && !pI830->gtt_acquired) { + if (pI830->use_drm_mode || (xf86AgpGARTSupported() && + !pI830->gtt_acquired)) { i830_memory *mem; - if (!xf86AcquireGART(pScrn->scrnIndex)) - return FALSE; - - pI830->gtt_acquired = TRUE; + if (!pI830->use_drm_mode) { + if (!xf86AcquireGART(pScrn->scrnIndex)) + return FALSE; + pI830->gtt_acquired = TRUE; + } for (mem = pI830->memory_list->next; mem->next != NULL; mem = mem->next) @@ -1971,7 +1996,7 @@ i830_bind_all_memory(ScrnInfoPtr pScrn) FatalError("Couldn't bind memory for BO %s\n", mem->name); } } - if (!pI830->SWCursor) + if (!pI830->SWCursor && !pI830->use_drm_mode) i830_update_cursor_offsets(pScrn); return TRUE; @@ -1986,7 +2011,8 @@ i830_unbind_all_memory(ScrnInfoPtr pScrn) if (pI830->StolenOnly == TRUE) return TRUE; - if (xf86AgpGARTSupported() && pI830->gtt_acquired) { + if (pI830->use_drm_mode || (xf86AgpGARTSupported() && + pI830->gtt_acquired)) { i830_memory *mem; for (mem = pI830->memory_list->next; mem->next != NULL; @@ -2002,10 +2028,12 @@ i830_unbind_all_memory(ScrnInfoPtr pScrn) i830_unbind_memory(pScrn, mem); } - pI830->gtt_acquired = FALSE; + if (!pI830->use_drm_mode) { + pI830->gtt_acquired = FALSE; - if (!xf86ReleaseGART(pScrn->scrnIndex)) - return FALSE; + if (!xf86ReleaseGART(pScrn->scrnIndex)) + return FALSE; + } } return TRUE; @@ -2057,3 +2085,118 @@ Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name, return TRUE; } #endif + +#ifdef XF86DRI_MM +#if 0 +static i830_memory * +i830_allocate_framebuffer_new(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox) +{ + unsigned int pitch = pScrn->displayWidth * pI830->cpp; + unsigned long minspace, avail; + int cacheLines; + int align; + long size, fb_height; + char *name; + int flags; + i830_memory *front_buffer = NULL; + Bool tiling; + + flags = ALLOW_SHARING; + + /* Clear everything first. */ + memset(FbMemBox, 0, sizeof(*FbMemBox)); + + fb_height = pScrn->virtualY; + + FbMemBox->x1 = 0; + FbMemBox->x2 = pScrn->displayWidth; + FbMemBox->y1 = 0; + FbMemBox->y2 = fb_height; + + /* Calculate how much framebuffer memory to allocate. For the + * initial allocation, calculate a reasonable minimum. This is + * enough for the virtual screen size, plus some pixmap cache + * space if we're using XAA. + */ + minspace = pitch * pScrn->virtualY; + avail = pScrn->videoRam * 1024; + cacheLines = 0; + + size = pitch * (fb_height + cacheLines); + size = ROUND_TO_PAGE(size); + + name = "front buffer"; + + /* Front buffer tiling has to be disabled with G965 XAA because some of the + * acceleration operations (non-XY COLOR_BLT) can't be done to tiled + * buffers. + */ + if (!(pI830->accel == ACCEL_EXA) && IS_I965G(pI830)) + tiling = FALSE; + else + tiling = pI830->tiling; + + if (pI830->use_drm_mode) + tiling = FALSE; + + /* Attempt to allocate it tiled first if we have page flipping on. */ + if (tiling && IsTileable(pScrn, pitch)) { + /* XXX: probably not the case on 965 */ + if (IS_I9XX(pI830)) + align = MB(1); + else + align = KB(512); + front_buffer = i830_allocate_memory_tiled(pScrn, name, size, + pitch, align, flags, + TILE_XMAJOR); + } + + /* If not, attempt it linear */ + if (front_buffer == NULL) { + front_buffer = i830_allocate_memory(pScrn, name, size, KB(64), flags); + } + + if (front_buffer == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate " + "framebuffer. Is your VideoRAM set too low?\n"); + + return NULL; + } + + return front_buffer; +} +#endif +uint32_t +i830_create_new_fb(ScrnInfoPtr pScrn, int width, int height, int *pitch) +{ + return 0; + +#if 0 + I830Ptr pI830 = I830PTR(pScrn); + i830_memory *old_buffer; + + pScrn->virtualX = width; + pScrn->virtualY = height; + pScrn->displayWidth = (pScrn->virtualX + 63) & ~63; + + *pitch = pScrn->displayWidth * pI830->cpp; + + old_buffer = pI830->front_buffer; + + pI830->front_buffer = + i830_allocate_framebuffer_new(pScrn, pI830, &pI830->FbMemBox); + + ErrorF("old front size %08lx, new front size %08lx\n", + old_buffer->bo->size, pI830->front_buffer->bo->size); + ErrorF("old front offset %08lx, new front offset %08lx\n", + old_buffer->bo->offset, pI830->front_buffer->bo->offset); + + i830_free_memory(pScrn, old_buffer); + + i830_update_front_offset(pScrn); + + return pI830->front_buffer->bo->handle; +#endif +} + +#endif diff --git a/src/i830_video.c b/src/i830_video.c index 1719835..5e6ebd7 100644 --- a/src/i830_video.c +++ b/src/i830_video.c @@ -2394,7 +2394,7 @@ I830PutImage(ScrnInfoPtr pScrn, /* fixup pointers */ #ifdef INTEL_XVMC if (id == FOURCC_XVMC && IS_I915(pI830)) { - pPriv->YBuf0offset = (uint32_t)buf; + pPriv->YBuf0offset = (uint32_t)((uint64_t)buf); pPriv->VBuf0offset = pPriv->YBuf0offset + (dstPitch2 * height); pPriv->UBuf0offset = pPriv->VBuf0offset + (dstPitch * height / 2); destId = FOURCC_YV12; diff --git a/src/reg_dumper/reg_dumper.h b/src/reg_dumper/reg_dumper.h index 241b241..9f24d5c 100644 --- a/src/reg_dumper/reg_dumper.h +++ b/src/reg_dumper/reg_dumper.h @@ -52,6 +52,7 @@ struct pci_info_rec { typedef struct _i830 { /* Fields in common with the real pI830 */ struct pci_info_rec *PciInfo; + Bool use_drm_mode; /* Fields used for setting up reg_dumper */ struct pci_device *pci_dev;