commit 106bea5ad1bdd5795d6ed625fc6351a161bffa6e Author: Alan Hourihane Date: Wed May 28 13:33:07 2008 +0100 Initial commit of new modesetting driver diff --git a/hw/xfree86/drivers/modesetting/COPYING b/hw/xfree86/drivers/modesetting/COPYING new file mode 100644 index 000000000..7f33cbfd2 --- /dev/null +++ b/hw/xfree86/drivers/modesetting/COPYING @@ -0,0 +1,12 @@ +This is a stub file. This package has not yet had its complete licensing +information compiled. Please see the individual source files for details on +your rights to use and modify this software. + +Please submit updated COPYING files to the Xorg bugzilla: + +https://bugs.freedesktop.org/enter_bug.cgi?product=xorg + +All licensing questions regarding this software should be directed at the +Xorg mailing list: + +http://lists.freedesktop.org/mailman/listinfo/xorg diff --git a/hw/xfree86/drivers/modesetting/Makefile.am b/hw/xfree86/drivers/modesetting/Makefile.am new file mode 100644 index 000000000..17d884fde --- /dev/null +++ b/hw/xfree86/drivers/modesetting/Makefile.am @@ -0,0 +1,42 @@ +# Copyright 2005 Adam Jackson. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# on the rights to use, copy, modify, merge, publish, distribute, sub +# license, and/or sell copies of the Software, and to permit persons to whom +# the Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice (including the next +# paragraph) shall be included in all copies or substantial portions of the +# Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +# ADAM JACKSON BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +SUBDIRS = + +# this is obnoxious: +# -module lets us name the module exactly how we want +# -avoid-version prevents gratuitous .0.0.0 version numbers on the end +# _ladir passes a dummy rpath to libtool so the thing will actually link +# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc. + +AM_CFLAGS = @WARN_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ @PCIACCESS_CFLAGS@ \ + @XMODES_CFLAGS@ + +modesetting_drv_la_LTLIBRARIES = modesetting_drv.la +modesetting_drv_la_LDFLAGS = -module -avoid-version -ldrm +modesetting_drv_ladir = @moduledir@/drivers + +modesetting_drv_la_SOURCES = \ + driver.c \ + driver.h \ + output.c \ + crtc.c \ + exa.c + +EXTRA_DIST = diff --git a/hw/xfree86/drivers/modesetting/crtc.c b/hw/xfree86/drivers/modesetting/crtc.c new file mode 100644 index 000000000..f168126fb --- /dev/null +++ b/hw/xfree86/drivers/modesetting/crtc.c @@ -0,0 +1,215 @@ +/* + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * + * Author: Alan Hourihane + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "driver.h" +#include "xf86Modes.h" + +#define DPMS_SERVER +#include + +static void +crtc_dpms(xf86CrtcPtr crtc, int mode) +{ + ScrnInfoPtr pScrn = crtc->scrn; + + switch (mode) { + case DPMSModeOn: + case DPMSModeStandby: + case DPMSModeSuspend: + break; + case DPMSModeOff: + break; + } +} + +static Bool +crtc_lock(xf86CrtcPtr crtc) +{ + return FALSE; +} + +static void +crtc_unlock(xf86CrtcPtr crtc) +{ +} + +static void +crtc_prepare(xf86CrtcPtr crtc) +{ +} + +static void +crtc_commit(xf86CrtcPtr crtc) +{ +} + +static Bool +crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode, + DisplayModePtr adjusted_mode) +{ + return TRUE; +} + +static void +crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, + DisplayModePtr adjusted_mode, int x, int y) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn); + modesettingPtr ms = modesettingPTR(crtc->scrn); + xf86OutputPtr output = config->output[config->compat_output]; + drmModeOutputPtr drm_output = output->driver_private; + drmModeCrtcPtr drm_crtc = crtc->driver_private; + struct drm_mode_modeinfo drm_mode; + + drm_mode.clock = mode->Clock; + drm_mode.hdisplay = mode->HDisplay; + drm_mode.hsync_start = mode->HSyncStart; + drm_mode.hsync_end = mode->HSyncEnd; + drm_mode.htotal = mode->HTotal; + drm_mode.vdisplay = mode->VDisplay; + drm_mode.vsync_start = mode->VSyncStart; + drm_mode.vsync_end = mode->VSyncEnd; + drm_mode.vtotal = mode->VTotal; + drm_mode.flags = mode->Flags; + drm_mode.hskew = mode->HSkew; + drm_mode.vscan = mode->VScan; + drm_mode.vrefresh = mode->VRefresh; + strncpy(drm_mode.name, mode->name, DRM_DISPLAY_MODE_LEN); + + drmModeSetCrtc(ms->fd, drm_crtc->crtc_id, ms->fb_id, x, y, + &drm_output->output_id, 1, &drm_mode); +} + +void +crtc_load_lut(xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; +} + +static void +crtc_gamma_set(xf86CrtcPtr crtc, CARD16 * red, CARD16 * green, CARD16 * blue, + int size) +{ +} + +static void * +crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height) +{ + ScrnInfoPtr pScrn = crtc->scrn; + + return NULL; +} + +static PixmapPtr +crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) +{ + ScrnInfoPtr pScrn = crtc->scrn; + + return NULL; +} + +static void +crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) +{ + ScrnInfoPtr pScrn = crtc->scrn; +} + +static void +crtc_destroy(xf86CrtcPtr crtc) +{ + drmModeFreeCrtc(crtc->driver_private); +} + +static const xf86CrtcFuncsRec crtc_funcs = { + .dpms = crtc_dpms, + .save = NULL, /* XXX */ + .restore = NULL, /* XXX */ + .lock = crtc_lock, + .unlock = crtc_unlock, + .mode_fixup = crtc_mode_fixup, + .prepare = crtc_prepare, + .mode_set = crtc_mode_set, + .commit = crtc_commit, + .gamma_set = crtc_gamma_set, + .shadow_create = crtc_shadow_create, + .shadow_allocate = crtc_shadow_allocate, + .shadow_destroy = crtc_shadow_destroy, +// .set_cursor_colors = crtc_set_cursor_colors, +// .set_cursor_position = crtc_set_cursor_position, +// .show_cursor = crtc_show_cursor, +// .hide_cursor = crtc_hide_cursor, +// .load_cursor_image = crtc_load_cursor_image, +// .load_cursor_argb = crtc_load_cursor_argb, + .destroy = crtc_destroy, /* XXX */ +}; + +void +crtc_init(ScrnInfoPtr pScrn) +{ + modesettingPtr ms = modesettingPTR(pScrn); + xf86CrtcPtr crtc; + drmModeResPtr res; + drmModeCrtcPtr drm_crtc = NULL; + int c, k, p; + + res = drmModeGetResources(ms->fd); + if (res == 0) { + ErrorF("Failed drmModeGetResources %d\n",errno); + return; + } + + for (c = 0; c < res->count_crtcs; c++) { + drm_crtc = drmModeGetCrtc(ms->fd, res->crtcs[c]); + if (!drm_crtc) + continue; + + crtc = xf86CrtcCreate(pScrn, &crtc_funcs); + if (crtc == NULL) + goto out; + + crtc->driver_private = drm_crtc; + } + +out: + drmModeFreeResources(res); +} diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c new file mode 100644 index 000000000..ba6bfdf53 --- /dev/null +++ b/hw/xfree86/drivers/modesetting/driver.c @@ -0,0 +1,1028 @@ +/* + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * + * Author: Alan Hourihane + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "compiler.h" +#include "xf86RAC.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "xf86Resources.h" +#include "mipointer.h" +#include "micmap.h" +#include "shadowfb.h" +#include +#include "fb.h" +#include "edid.h" +#include "xf86i2c.h" +#include "xf86Crtc.h" +#include "miscstruct.h" +#include "dixstruct.h" +#include "xf86xv.h" +#include +#include "shadow.h" +#include +#if XSERVER_LIBPCIACCESS +#include +#endif + +#include "driver.h" + +static void AdjustFrame(int scrnIndex, int x, int y, int flags); +static Bool CloseScreen(int scrnIndex, ScreenPtr pScreen); +static Bool EnterVT(int scrnIndex, int flags); +static Bool SaveHWState(ScrnInfoPtr pScrn); +static Bool RestoreHWState(ScrnInfoPtr pScrn); +static void Identify(int flags); +static const OptionInfoRec *AvailableOptions(int chipid, int busid); +static ModeStatus ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags); +static void FreeScreen(int scrnIndex, int flags); +static void LeaveVT(int scrnIndex, int flags); +static Bool SwitchMode(int scrnIndex, DisplayModePtr mode, int flags); +static Bool ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv); +static Bool PreInit(ScrnInfoPtr pScrn, int flags); +#if XSERVER_LIBPCIACCESS +static Bool +pci_probe(DriverPtr driver, + int entity_num, struct pci_device *device, intptr_t match_data); +#else +static Bool Probe(DriverPtr drv, int flags); +#endif + +#if XSERVER_LIBPCIACCESS +static const struct pci_id_match device_match[] = { + {0x8086, 0x2592, 0xffff, 0xffff, 0, 0, 0}, + {0, 0, 0}, +}; +#endif + +_X_EXPORT DriverRec modesetting = { + 1, + "modesetting", + Identify, +#if XSERVER_LIBPCIACCESS + NULL, +#else + Probe, +#endif + AvailableOptions, + NULL, + 0, + NULL, +#if XSERVER_LIBPCIACCESS + device_match, + pci_probe +#endif +}; + +static SymTabRec Chipsets[] = { + {0x2592, "Intel Graphics Device"}, + {-1, NULL} +}; + +static PciChipsets PciDevices[] = { + {0x2592, 0x2592, RES_SHARED_VGA}, + {-1, -1, RES_UNDEFINED} +}; + +typedef enum +{ + OPTION_NOACCEL, + OPTION_SW_CURSOR, + OPTION_SHADOWFB, +} modesettingOpts; + +static const OptionInfoRec Options[] = { + {OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_SHADOWFB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE}, + {-1, NULL, OPTV_NONE, {0}, FALSE} +}; + +static const char *fbSymbols[] = { + "fbPictureInit", + "fbScreenInit", + NULL +}; + +static const char *ddcSymbols[] = { + "xf86PrintEDID", + "xf86SetDDCproperties", + NULL +}; + +static const char *shadowSymbols[] = { + "shadowInit", + "shadowUpdatePackedWeak", + NULL +}; + +static const char *i2cSymbols[] = { + "xf86CreateI2CBusRec", + "xf86I2CBusInit", + NULL +}; + +int modesettingEntityIndex = -1; + +static MODULESETUPPROTO(Setup); + +static XF86ModuleVersionInfo VersRec = { + "modesetting", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XORG_VERSION_CURRENT, + PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL, + ABI_CLASS_VIDEODRV, + ABI_VIDEODRV_VERSION, + MOD_CLASS_VIDEODRV, + {0, 0, 0, 0} +}; + +_X_EXPORT XF86ModuleData modesettingModuleData = { &VersRec, Setup, NULL }; + +static pointer +Setup(pointer module, pointer opts, int *errmaj, int *errmin) +{ + static Bool setupDone = 0; + + /* This module should be loaded only once, but check to be sure. + */ + if (!setupDone) { + setupDone = 1; + xf86AddDriver(&modesetting, module, HaveDriverFuncs); + + /* + * Tell the loader about symbols from other modules that this module + * might refer to. + */ + LoaderRefSymLists(fbSymbols, + shadowSymbols, ddcSymbols, NULL); + + /* + * The return value must be non-NULL on success even though there + * is no TearDownProc. + */ + return (pointer) 1; + } else { + if (errmaj) + *errmaj = LDR_ONCEONLY; + return NULL; + } +} + +static void +Identify(int flags) +{ + xf86PrintChipsets("modesetting", "Driver for Modesetting Kernel Drivers", + Chipsets); +} + +static const OptionInfoRec * +AvailableOptions(int chipid, int busid) +{ + return Options; +} + +#if XSERVER_LIBPCIACCESS +static Bool +pci_probe(DriverPtr driver, + int entity_num, struct pci_device *device, intptr_t match_data) +{ + ScrnInfoPtr scrn = NULL; + EntityInfoPtr entity; + DevUnion *private; + + scrn = xf86ConfigPciEntity(scrn, 0, entity_num, PciDevices, + NULL, NULL, NULL, NULL, NULL); + if (scrn != NULL) { + scrn->driverVersion = 1; + scrn->driverName = "modesetting"; + scrn->name = "modesetting"; + scrn->Probe = NULL; + + entity = xf86GetEntityInfo(entity_num); + + switch (device->device_id) { + case 0x2592: + scrn->PreInit = PreInit; + scrn->ScreenInit = ScreenInit; + scrn->SwitchMode = SwitchMode; + scrn->AdjustFrame = AdjustFrame; + scrn->EnterVT = EnterVT; + scrn->LeaveVT = LeaveVT; + scrn->FreeScreen = FreeScreen; + scrn->ValidMode = ValidMode; + break; + } + } + return scrn != NULL; +} +#else +static Bool +Probe(DriverPtr drv, int flags) +{ + int i, numUsed, numDevSections, *usedChips; + EntPtr msEnt = NULL; + DevUnion *pPriv; + GDevPtr *devSections; + Bool foundScreen = FALSE; + pciVideoPtr *VideoInfo; + pciVideoPtr *ppPci; + int numDevs; + + /* + * Find the config file Device sections that match this + * driver, and return if there are none. + */ + if ((numDevSections = + xf86MatchDevice("modesetting", &devSections)) <= 0) { + return FALSE; + } + + /* + * This probing is just checking the PCI data the server already + * collected. + */ + if (!(VideoInfo = xf86GetPciVideoInfo())) + return FALSE; + +#if 0 + numUsed = 0; + for (ppPci = VideoInfo; ppPci != NULL && *ppPci != NULL; ppPci++) { + for (numDevs = 0; numDevs < numDevSections; numDevs++) { + if (devSections[numDevs]->busID && *devSections[numDevs]->busID) { + if (xf86ComparePciBusString(devSections[numDevs]->busID, (*ppPci)->bus, (*ppPci)->device, (*ppPci)->func)) { + /* Claim slot */ + if (xf86CheckPciSlot((*ppPci)->bus, (*ppPci)->device, + (*ppPci)->func)) { + usedChips[numUsed++] = xf86ClaimPciSlot((*ppPci)->bus, (*ppPci)->device, + (*ppPci)->func, drv, (*ppPci)->chipType, + NULL, TRUE); + ErrorF("CLAIMED %d %d %d\n",(*ppPci)->bus,(*ppPci)->device, (*ppPci)->func); + } + } + } + } + } +#else + /* Look for Intel i8xx devices. */ + numUsed = xf86MatchPciInstances("modesetting", PCI_VENDOR_INTEL, + Chipsets, PciDevices, + devSections, numDevSections, + drv, &usedChips); +#endif + + if (flags & PROBE_DETECT) { + if (numUsed > 0) + foundScreen = TRUE; + } else { + ErrorF("NUMUSED %d\n",numUsed); + for (i = 0; i < numUsed; i++) { + ScrnInfoPtr pScrn = NULL; + + /* Allocate new ScrnInfoRec and claim the slot */ + if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i], + PciDevices, NULL, NULL, NULL, + NULL, NULL))) { + EntityInfoPtr pEnt; + + pEnt = xf86GetEntityInfo(usedChips[i]); + + pScrn->driverVersion = 1; + pScrn->driverName = "modesetting"; + pScrn->name = "modesetting"; + pScrn->Probe = Probe; + foundScreen = TRUE; + { + /* Allocate an entity private if necessary */ + if (modesettingEntityIndex < 0) + modesettingEntityIndex = xf86AllocateEntityPrivateIndex(); + + pPriv = xf86GetEntityPrivate(pScrn->entityList[0], + modesettingEntityIndex); + if (!pPriv->ptr) { + pPriv->ptr = xnfcalloc(sizeof(EntRec), 1); + msEnt = pPriv->ptr; + msEnt->lastInstance = -1; + } else { + msEnt = pPriv->ptr; + } + + /* + * Set the entity instance for this instance of the driver. + * For dual head per card, instance 0 is the "master" + * instance, driving the primary head, and instance 1 is + * the "slave". + */ + msEnt->lastInstance++; + xf86SetEntityInstanceForScreen(pScrn, + pScrn->entityList[0], + msEnt->lastInstance); + pScrn->PreInit = PreInit; + pScrn->ScreenInit = ScreenInit; + pScrn->SwitchMode = SwitchMode; + pScrn->AdjustFrame = AdjustFrame; + pScrn->EnterVT = EnterVT; + pScrn->LeaveVT = LeaveVT; + pScrn->FreeScreen = FreeScreen; + pScrn->ValidMode = ValidMode; + break; + } + } else + ErrorF("FAILED PSCRN\n"); + } + } + + xfree(usedChips); + xfree(devSections); + + return foundScreen; +} +#endif + +static Bool +GetRec(ScrnInfoPtr pScrn) +{ + if (pScrn->driverPrivate) + return TRUE; + + pScrn->driverPrivate = xnfcalloc(sizeof(modesettingRec), 1); + + return TRUE; +} + +static void +FreeRec(ScrnInfoPtr pScrn) +{ + if (!pScrn) + return; + + if (!pScrn->driverPrivate) + return; + + xfree(pScrn->driverPrivate); + + pScrn->driverPrivate = NULL; +} + +static void +ProbeDDC(ScrnInfoPtr pScrn, int index) +{ + ConfiguredMonitor = NULL; +} + +static Bool +MapMem(ScrnInfoPtr pScrn) +{ + modesettingPtr ms = modesettingPTR(pScrn); + + drmBOMap(ms->fd, + &ms->bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, &ms->virtual); + + return TRUE; +} + +static Bool +UnmapMem(ScrnInfoPtr pScrn) +{ + modesettingPtr ms = modesettingPTR(pScrn); + + drmBOUnmap(ms->fd, &ms->bo); + + return TRUE; +} + +static void +LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, + LOCO * colors, VisualPtr pVisual) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); +} + +static Bool +crtc_resize(ScrnInfoPtr pScrn, int width, int height) +{ + modesettingPtr ms = modesettingPTR(pScrn); + ScreenPtr pScreen = pScrn->pScreen; + PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen); + Bool fbAccessDisabled; + CARD8 *fbstart; + + if (width == pScrn->virtualX && height == pScrn->virtualY) + return TRUE; + + ErrorF("RESIZING TO %dx%d\n",width,height); + + pScrn->virtualX = width; + pScrn->virtualY = height; + pScrn->displayWidth = (pScrn->virtualX + 63) & ~63; + + if (ms->shadowMem) { + xfree(ms->shadowMem); + ms->shadowMem = NULL; + } + + UnmapMem(pScrn); + + /* move old buffer out of the way */ + drmBOSetStatus(ms->fd, &ms->bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_MEM_LOCAL, + DRM_BO_MASK_MEM | DRM_BO_FLAG_NO_EVICT, + DRM_BO_HINT_DONT_FENCE, 0, 0); + + /* unreference it */ + drmBOUnreference(ms->fd, &ms->bo); + + drmBOCreate(ms->fd, + pScrn->virtualY * pScrn->displayWidth * + pScrn->bitsPerPixel / 8, 0, NULL, + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_SHAREABLE + | DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_MAPPABLE | + DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT, DRM_BO_HINT_DONT_FENCE, &ms->bo); + + MapMem(pScrn); + + drmModeAddFB(ms->fd, + pScrn->virtualX, + pScrn->virtualY, + pScrn->depth, + pScrn->bitsPerPixel, + pScrn->displayWidth * pScrn->bitsPerPixel / 8, + ms->bo.handle, + &ms->fb_id); + + if (ms->shadowFB) { + if ((ms->shadowMem = + shadowAlloc(pScrn->displayWidth, pScrn->virtualY, + pScrn->bitsPerPixel)) == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Allocation of shadow memory failed\n"); + return FALSE; + } + fbstart = ms->shadowMem; + } else { + fbstart = ms->virtual; + } + + /* + * If we are in a fb disabled state, the virtual address of the root + * pixmap should always be NULL, and it will be overwritten later + * if we try to set it to something. + * + * Therefore, set it to NULL, and modify the backup copy instead. + */ + + fbAccessDisabled = (rootPixmap->devPrivate.ptr == NULL); + + pScreen->ModifyPixmapHeader(rootPixmap, + pScrn->virtualX, pScrn->virtualY, + pScrn->depth, pScrn->bitsPerPixel, + pScrn->displayWidth * pScrn->bitsPerPixel / 8, + fbstart); + + if (fbAccessDisabled) { + pScrn->pixmapPrivate.ptr = fbstart; + rootPixmap->devPrivate.ptr = NULL; + } + + pScrn->frameX0 = 0; + pScrn->frameY0 = 0; + AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + + return TRUE; +} + +static const xf86CrtcConfigFuncsRec crtc_config_funcs = { + crtc_resize +}; + +static Bool +PreInit(ScrnInfoPtr pScrn, int flags) +{ + xf86CrtcConfigPtr xf86_config; + modesettingPtr ms; + MessageType from = X_PROBED; + rgb defaultWeight = { 0, 0, 0 }; + EntityInfoPtr pEnt; + EntPtr msEnt = NULL; + int flags24; + char *BusID; + int i; + char *s; + int num_pipe; + int max_width, max_height; + + if (pScrn->numEntities != 1) + return FALSE; + + pEnt = xf86GetEntityInfo(pScrn->entityList[0]); + + if (flags & PROBE_DETECT) { + ProbeDDC(pScrn, pEnt->index); + return TRUE; + } + + /* Allocate driverPrivate */ + if (!GetRec(pScrn)) + return FALSE; + + ms = modesettingPTR(pScrn); + ms->SaveGeneration = -1; + ms->pEnt = pEnt; + + pScrn->displayWidth = 640; /* default it */ + + if (ms->pEnt->location.type != BUS_PCI) + return FALSE; + + ms->PciInfo = xf86GetPciInfoForEntity(ms->pEnt->index); + + /* Allocate an entity private if necessary */ + if (xf86IsEntityShared(pScrn->entityList[0])) { + msEnt = xf86GetEntityPrivate(pScrn->entityList[0], + modesettingEntityIndex)->ptr; + ms->entityPrivate = msEnt; + } else + ms->entityPrivate = NULL; + + if (xf86RegisterResources(ms->pEnt->index, NULL, ResNone)) { + return FALSE; + } + + if (xf86IsEntityShared(pScrn->entityList[0])) { + if (xf86IsPrimInitDone(pScrn->entityList[0])) { + /* do something */ + } else { + xf86SetPrimInitDone(pScrn->entityList[0]); + } + } + + BusID = xalloc(64); + sprintf(BusID, "PCI:%d:%d:%d", +#if XSERVER_LIBPCIACCESS + ((ms->PciInfo->domain << 8) | ms->PciInfo->bus), + ms->PciInfo->dev, ms->PciInfo->func +#else + ((pciConfigPtr) ms->PciInfo->thisCard)->busnum, + ((pciConfigPtr) ms->PciInfo->thisCard)->devnum, + ((pciConfigPtr) ms->PciInfo->thisCard)->funcnum +#endif + ); + + ms->fd = drmOpen(NULL, BusID); + + if (ms->fd < 0) + return FALSE; + + pScrn->racMemFlags = RAC_FB | RAC_COLORMAP; + pScrn->monitor = pScrn->confScreen->monitor; + pScrn->progClock = TRUE; + pScrn->rgbBits = 8; + + flags24 = Support32bppFb | PreferConvert24to32 | SupportConvert24to32; + + if (!xf86SetDepthBpp(pScrn, 0, 0, 0, flags24)) + return FALSE; + + switch (pScrn->depth) { + case 8: + case 15: + case 16: + case 24: + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Given depth (%d) is not supported by the driver\n", + pScrn->depth); + return FALSE; + } + xf86PrintDepthBpp(pScrn); + + if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight)) + return FALSE; + if (!xf86SetDefaultVisual(pScrn, -1)) + return FALSE; + + /* Process the options */ + xf86CollectOptions(pScrn, NULL); + if (!(ms->Options = xalloc(sizeof(Options)))) + return FALSE; + memcpy(ms->Options, Options, sizeof(Options)); + xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, ms->Options); + + /* Allocate an xf86CrtcConfig */ + xf86CrtcConfigInit(pScrn, &crtc_config_funcs); + xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + + max_width = 8192; + max_height = 8192; + xf86CrtcSetSizeRange(pScrn, 320, 200, max_width, max_height); + + if (xf86ReturnOptValBool(ms->Options, OPTION_NOACCEL, FALSE)) { + ms->noAccel = TRUE; + } + + if (xf86ReturnOptValBool(ms->Options, OPTION_SW_CURSOR, FALSE)) { + ms->SWCursor = TRUE; + } + + if (xf86ReturnOptValBool(ms->Options, OPTION_SHADOWFB, FALSE)) { + if (!xf86LoadSubModule(pScrn, "shadow")) + return FALSE; + + xf86LoaderReqSymLists(shadowSymbols, NULL); + + ms->shadowFB = TRUE; + } + + SaveHWState(pScrn); + + crtc_init(pScrn); + output_init(pScrn); + + if (!xf86InitialConfiguration(pScrn, TRUE)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n"); + RestoreHWState(pScrn); + return FALSE; + } + + RestoreHWState(pScrn); + + /* + * If the driver can do gamma correction, it should call xf86SetGamma() here. + */ + { + Gamma zeros = { 0.0, 0.0, 0.0 }; + + if (!xf86SetGamma(pScrn, zeros)) { + return FALSE; + } + } + + if (pScrn->modes == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n"); + return FALSE; + } + + pScrn->currentMode = pScrn->modes; + + /* Set display resolution */ + xf86SetDpi(pScrn, 0, 0); + + /* Load the required sub modules */ + if (!xf86LoadSubModule(pScrn, "fb")) { + return FALSE; + } + + xf86LoaderReqSymLists(fbSymbols, NULL); + + return TRUE; +} + +static Bool +SaveHWState(ScrnInfoPtr pScrn) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + + return TRUE; +} + +static Bool +RestoreHWState(ScrnInfoPtr pScrn) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + + return TRUE; +} + +static void * +WindowLinear(ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode, + CARD32 * size, void *closure) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + modesettingPtr ms = modesettingPTR(pScrn); + + if (!pScrn->vtSema) + return NULL; + + *size = pScrn->displayWidth * pScrn->bitsPerPixel / 8; + + return ((CARD8 *) ms->virtual + row * (*size) + offset); +} + +static Bool +CreateScreenResources(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + modesettingPtr ms = modesettingPTR(pScrn); + Bool ret; + + pScreen->CreateScreenResources = ms->createScreenResources; + ret = pScreen->CreateScreenResources(pScreen); + pScreen->CreateScreenResources = CreateScreenResources; + + shadowAdd(pScreen, pScreen->GetScreenPixmap(pScreen), + ms->update, WindowLinear, 0, 0); + + return ret; +} + +static Bool +ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + modesettingPtr ms = modesettingPTR(pScrn); + VisualPtr visual; + unsigned long sys_mem; + int c; + MessageType from; + CARD8 *fbstart; + + pScrn->displayWidth = (pScrn->virtualX + 63) & ~63; + + miClearVisualTypes(); + + if (!miSetVisualTypes(pScrn->depth, + miGetDefaultVisualMask(pScrn->depth), + pScrn->rgbBits, pScrn->defaultVisual)) + return FALSE; + + if (!miSetPixmapDepths()) + return FALSE; + + if (!MapMem(pScrn)) + return FALSE; + + pScrn->memPhysBase = 0; + pScrn->fbOffset = 0; + + drmBOCreate(ms->fd, + pScrn->virtualY * pScrn->displayWidth * + pScrn->bitsPerPixel / 8, 0, NULL, + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_SHAREABLE + | DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_MAPPABLE | + DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT, DRM_BO_HINT_DONT_FENCE, &ms->bo); + + MapMem(pScrn); + + drmModeAddFB(ms->fd, + pScrn->virtualX, + pScrn->virtualY, + pScrn->depth, + pScrn->bitsPerPixel, + pScrn->displayWidth * pScrn->bitsPerPixel / 8, + ms->bo.handle, + &ms->fb_id); + + if (ms->shadowFB) { + if ((ms->shadowMem = + shadowAlloc(pScrn->displayWidth, pScrn->virtualY, + pScrn->bitsPerPixel)) == NULL) { + xf86DrvMsg(scrnIndex, X_ERROR, + "Allocation of shadow memory failed\n"); + return FALSE; + } + fbstart = ms->shadowMem; + } else { + fbstart = ms->virtual; + } + + if (!fbScreenInit(pScreen, fbstart, + pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, + pScrn->displayWidth, pScrn->bitsPerPixel)) + return FALSE; + + if (pScrn->bitsPerPixel > 8) { + /* Fixup RGB ordering */ + visual = pScreen->visuals + pScreen->numVisuals; + while (--visual >= pScreen->visuals) { + if ((visual->class | DynamicClass) == DirectColor) { + visual->offsetRed = pScrn->offset.red; + visual->offsetGreen = pScrn->offset.green; + visual->offsetBlue = pScrn->offset.blue; + visual->redMask = pScrn->mask.red; + visual->greenMask = pScrn->mask.green; + visual->blueMask = pScrn->mask.blue; + } + } + } + + fbPictureInit(pScreen, NULL, 0); + if (ms->shadowFB) { + ms->update = shadowUpdatePackedWeak(); + if (!shadowSetup(pScreen)) { + xf86DrvMsg(scrnIndex, X_ERROR, + "Shadow framebuffer initialization failed.\n"); + return FALSE; + } + + ms->createScreenResources = pScreen->CreateScreenResources; + pScreen->CreateScreenResources = CreateScreenResources; + } + + xf86SetBlackWhitePixels(pScreen); + +#if 0 + glucoseScreenInit(pScreen, 0); +#endif +#if 0 + ms->pExa = ExaInit(pScreen); +#endif + + miInitializeBackingStore(pScreen); + xf86SetBackingStore(pScreen); + xf86SetSilkenMouse(pScreen); + miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); + + /* Must force it before EnterVT, so we are in control of VT and + * later memory should be bound when allocating, e.g rotate_mem */ + pScrn->vtSema = TRUE; + + pScreen->SaveScreen = xf86SaveScreen; + ms->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = CloseScreen; + + if (!xf86CrtcScreenInit(pScreen)) + return FALSE; + + if (!miCreateDefColormap(pScreen)) + return FALSE; + +#if 0 + if (!xf86HandleColormaps(pScreen, 256, 8, LoadPalette, NULL, + CMAP_RELOAD_ON_MODE_SWITCH | + CMAP_PALETTED_TRUECOLOR)) { + return FALSE; + } +#endif + + xf86DPMSInit(pScreen, xf86DPMSSet, 0); + +#if 0 + glucoseInitVideo(pScreen); +#endif + + if (serverGeneration == 1) + xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); + + return EnterVT(scrnIndex, 0); +} + +static void +AdjustFrame(int scrnIndex, int x, int y, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + xf86OutputPtr output = config->output[config->compat_output]; + xf86CrtcPtr crtc = output->crtc; + + if (crtc && crtc->enabled) { + crtc->funcs->mode_set(crtc, pScrn->currentMode, pScrn->currentMode, x, y); + crtc->x = output->initial_x + x; + crtc->y = output->initial_y + y; + } +} + +static void +FreeScreen(int scrnIndex, int flags) +{ + FreeRec(xf86Screens[scrnIndex]); +} + +static void +LeaveVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + modesettingPtr ms = modesettingPTR(pScrn); + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + int o; + + for (o = 0; o < config->num_crtc; o++) { + xf86CrtcPtr crtc = config->crtc[o]; + + if (crtc->rotatedPixmap || crtc->rotatedData) { + crtc->funcs->shadow_destroy(crtc, crtc->rotatedPixmap, + crtc->rotatedData); + crtc->rotatedPixmap = NULL; + crtc->rotatedData = NULL; + } + } + + xf86_hide_cursors(pScrn); + + drmMMLock(ms->fd, DRM_BO_MEM_VRAM, 1, 0); + + RestoreHWState(pScrn); +} + +/* + * This gets called when gaining control of the VT, and from ScreenInit(). + */ +static Bool +EnterVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + modesettingPtr ms = modesettingPTR(pScrn); + + /* + * Only save state once per server generation since that's what most + * drivers do. Could change this to save state at each VT enter. + */ + if (ms->SaveGeneration != serverGeneration) { + ms->SaveGeneration = serverGeneration; + SaveHWState(pScrn); + } + + drmMMUnlock(ms->fd, DRM_BO_MEM_VRAM, 1); + + if (!xf86SetDesiredModes(pScrn)) + return FALSE; + + AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + + return TRUE; +} + +static Bool +SwitchMode(int scrnIndex, DisplayModePtr mode, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + + return xf86SetSingleMode(pScrn, mode, RR_Rotate_0); +} + +static Bool +CloseScreen(int scrnIndex, ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + modesettingPtr ms = modesettingPTR(pScrn); + + if (pScrn->vtSema == TRUE) { + LeaveVT(scrnIndex, 0); + drmMMUnlock(ms->fd, DRM_BO_MEM_VRAM, 1); + } + + UnmapMem(pScrn); + + if (ms->shadowFB) + pScreen->CreateScreenResources = ms->createScreenResources; + + if (ms->shadowMem) { + xfree(ms->shadowMem); + ms->shadowMem = NULL; + } + + if (ms->pExa) + ExaClose(pScrn); + + /* move old buffer out of the way */ + drmBOSetStatus(ms->fd, &ms->bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_MEM_LOCAL, + DRM_BO_MASK_MEM | DRM_BO_FLAG_NO_EVICT, + DRM_BO_HINT_DONT_FENCE, 0, 0); + + drmBOUnreference(ms->fd, &ms->bo); + + drmClose(ms->fd); + + pScrn->vtSema = FALSE; + pScreen->CloseScreen = ms->CloseScreen; + return (*pScreen->CloseScreen) (scrnIndex, pScreen); +} + +static ModeStatus +ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) +{ + return MODE_OK; +} diff --git a/hw/xfree86/drivers/modesetting/driver.h b/hw/xfree86/drivers/modesetting/driver.h new file mode 100644 index 000000000..2a0990312 --- /dev/null +++ b/hw/xfree86/drivers/modesetting/driver.h @@ -0,0 +1,88 @@ +/* + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * + * Author: Alan Hourihane + * + */ + +#include +#include +#include +#include +#include "shadow.h" +#include "exa.h" + +#define DRV_ERROR(msg) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, msg); + +typedef struct { + int lastInstance; + int refCount; + ScrnInfoPtr pScrn_1; + ScrnInfoPtr pScrn_2; +} EntRec, *EntPtr; + +typedef struct _modesettingRec { + int fd; + unsigned int fb_id; + void *virtual; + drmBO bo; + + EntPtr entityPrivate; + + void (*PointerMoved)(int, int, int); + + int Chipset; + EntityInfoPtr pEnt; +#if XSERVER_LIBPCIACCESS + struct pci_device *PciInfo; +#else + pciVideoPtr PciInfo; + PCITAG PciTag; +#endif + + Bool noAccel; + Bool SWCursor; + CloseScreenProcPtr CloseScreen; + + Bool directRenderingDisabled; /* DRI disabled in PreInit. */ + Bool directRenderingEnabled; /* DRI enabled this generation. */ + + /* Broken-out options. */ + OptionInfoPtr Options; + + unsigned int SaveGeneration; + + /* shadowfb */ + CARD8 *shadowMem; + Bool shadowFB; + CreateScreenResourcesProcPtr createScreenResources; + ShadowUpdateProc update; + + /* exa */ + ExaDriverPtr pExa; + drmBO exa_bo; +} modesettingRec, *modesettingPtr; + +#define modesettingPTR(p) ((modesettingPtr)((p)->driverPrivate)) diff --git a/hw/xfree86/drivers/modesetting/exa.c b/hw/xfree86/drivers/modesetting/exa.c new file mode 100644 index 000000000..a9be2c12d --- /dev/null +++ b/hw/xfree86/drivers/modesetting/exa.c @@ -0,0 +1,235 @@ +/* + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * + * Author: Alan Hourihane + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "xf86_OSproc.h" + +#include "driver.h" + +static void +ExaWaitMarker(ScreenPtr pScreen, int marker) +{ +} + +static int +ExaMarkSync(ScreenPtr pScreen) +{ + /* + * See ExaWaitMarker. + */ + + return 1; +} + +Bool +ExaPrepareAccess(PixmapPtr pPix, int index) +{ + ScreenPtr pScreen = pPix->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + + return TRUE; +} + +void +ExaFinishAccess(PixmapPtr pPix, int index) +{ + ScreenPtr pScreen = pPix->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; +} + +static void +ExaDone(PixmapPtr pPixmap) +{ + ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; +} + +static void +ExaDoneComposite(PixmapPtr pPixmap) +{ + ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; +} + +static Bool +ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg) +{ + ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; + + if (!EXA_PM_IS_SOLID(&pPixmap->drawable, planeMask)) + return FALSE; + + /* can't do depth 4 */ + if (pPixmap->drawable.depth == 4) + return FALSE; + + return TRUE; +} + +static void +ExaSolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) +{ + ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; +} + +static Bool +ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, + int ydir, int alu, Pixel planeMask) +{ + ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; + + /* can't do depth 4 */ + if (pSrcPixmap->drawable.depth == 4 || pDstPixmap->drawable.depth == 4) + return FALSE; + + return TRUE; +} + +static void +ExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, + int width, int height) +{ + ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; +} + +static Bool +ExaPrepareComposite(int op, PicturePtr pSrcPicture, + PicturePtr pMaskPicture, PicturePtr pDstPicture, + PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst) +{ + ScreenPtr pScreen = pDst->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + + return FALSE; +} + +static Bool +ExaUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src, + int src_pitch) +{ + ScreenPtr pScreen = pDst->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + + return FALSE; +} + +static void +ExaComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, + int dstX, int dstY, int width, int height) +{ + ScreenPtr pScreen = pDst->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; +} + +static Bool +ExaCheckComposite(int op, + PicturePtr pSrcPicture, PicturePtr pMaskPicture, + PicturePtr pDstPicture) +{ + DrawablePtr pDraw = pSrcPicture->pDrawable; + int w = pDraw->width; + int h = pDraw->height; + + return TRUE; +} + +static Bool +ExaPixmapIsOffscreen(PixmapPtr p) +{ + ScreenPtr pScreen = p->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + + return FALSE; +} + +void +ExaClose(ScrnInfoPtr pScrn) +{ + modesettingPtr ms = modesettingPTR(pScrn); + + exaDriverFini(pScrn->pScreen); + + drmBOUnreference(ms->fd, &ms->exa_bo); +} + +ExaDriverPtr +ExaInit(ScrnInfoPtr pScrn) +{ + modesettingPtr ms = modesettingPTR(pScrn); + ExaDriverPtr pExa; + + pExa = exaDriverAlloc(); + if (!pExa) { + goto out_err; + } + + /* Create a 256KB offscreen area */ + drmBOCreate(ms->fd, 256 * 1024, 0, NULL, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_MEM_TT, DRM_BO_HINT_DONT_FENCE, &ms->exa_bo); + + memset(pExa, 0, sizeof(*pExa)); + pExa->exa_major = 2; + pExa->exa_minor = 2; + pExa->memoryBase = ms->exa_bo.virtual; + pExa->offScreenBase = 0; + pExa->memorySize = ms->exa_bo.size; + pExa->pixmapOffsetAlign = 8; + pExa->pixmapPitchAlign = 32 * 4; + pExa->flags = EXA_OFFSCREEN_PIXMAPS; + pExa->maxX = 8191; /* FIXME */ + pExa->maxY = 8191; /* FIXME */ + pExa->WaitMarker = ExaWaitMarker; + pExa->MarkSync = ExaMarkSync; + pExa->PrepareSolid = ExaPrepareSolid; + pExa->Solid = ExaSolid; + pExa->DoneSolid = ExaDone; + pExa->PrepareCopy = ExaPrepareCopy; + pExa->Copy = ExaCopy; + pExa->DoneCopy = ExaDone; + pExa->CheckComposite = ExaCheckComposite; + pExa->PrepareComposite = ExaPrepareComposite; + pExa->Composite = ExaComposite; + pExa->DoneComposite = ExaDoneComposite; + pExa->PixmapIsOffscreen = ExaPixmapIsOffscreen; + pExa->PrepareAccess = ExaPrepareAccess; + pExa->FinishAccess = ExaFinishAccess; + pExa->UploadToScreen = ExaUploadToScreen; + + if (!exaDriverInit(pScrn->pScreen, pExa)) { + goto out_err; + } + + return pExa; + + out_err: + ExaClose(pScrn); + + return NULL; +} diff --git a/hw/xfree86/drivers/modesetting/modesetting.man b/hw/xfree86/drivers/modesetting/modesetting.man new file mode 100644 index 000000000..e69de29bb diff --git a/hw/xfree86/drivers/modesetting/output.c b/hw/xfree86/drivers/modesetting/output.c new file mode 100644 index 000000000..b25540ee0 --- /dev/null +++ b/hw/xfree86/drivers/modesetting/output.c @@ -0,0 +1,285 @@ +/* + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * + * Author: Alan Hourihane + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DPMS_SERVER +#include + +#include "X11/Xatom.h" + +#include "driver.h" + +static void +dpms(xf86OutputPtr output, int mode) +{ +} + +static void +save(xf86OutputPtr output) +{ +} + +static void +restore(xf86OutputPtr output) +{ +} + +static int +mode_valid(xf86OutputPtr output, DisplayModePtr pMode) +{ + return MODE_OK; +} + +static Bool +mode_fixup(xf86OutputPtr output, DisplayModePtr mode, + DisplayModePtr adjusted_mode) +{ + return TRUE; +} + +static void +prepare(xf86OutputPtr output) +{ + dpms(output, DPMSModeOff); +} + +static void +mode_set(xf86OutputPtr output, DisplayModePtr mode, + DisplayModePtr adjusted_mode) +{ +} + +static void +commit(xf86OutputPtr output) +{ + dpms(output, DPMSModeOn); + + if (output->scrn->pScreen != NULL) + xf86_reload_cursors(output->scrn->pScreen); +} + +static xf86OutputStatus +detect(xf86OutputPtr output) +{ + drmModeOutputPtr drm_output = output->driver_private; + + switch (drm_output->connection) { + case DRM_MODE_CONNECTED: + return XF86OutputStatusConnected; + case DRM_MODE_DISCONNECTED: + return XF86OutputStatusDisconnected; + default: + return XF86OutputStatusUnknown; + } +} + +static DisplayModePtr +get_modes(xf86OutputPtr output) +{ + drmModeOutputPtr drm_output = output->driver_private; + struct drm_mode_modeinfo *drm_mode = NULL; + DisplayModePtr modes = NULL, mode = NULL; + int i; + + for (i = 0; i < drm_output->count_modes; i++) { + drm_mode = &drm_output->modes[i]; + if (drm_mode) { + mode = xcalloc(1, sizeof(DisplayModeRec)); + if (!mode) + continue; + mode->type = 0; + mode->Clock = drm_mode->clock; + mode->HDisplay = drm_mode->hdisplay; + mode->HSyncStart = drm_mode->hsync_start; + mode->HSyncEnd = drm_mode->hsync_end; + mode->HTotal = drm_mode->htotal; + mode->VDisplay = drm_mode->vdisplay; + mode->VSyncStart = drm_mode->vsync_start; + mode->VSyncEnd = drm_mode->vsync_end; + mode->VTotal = drm_mode->vtotal; + mode->Flags = drm_mode->flags; + mode->HSkew = drm_mode->hskew; + mode->VScan = drm_mode->vscan; + mode->VRefresh = xf86ModeVRefresh(mode); + mode->Private = (void *)drm_mode; + xf86SetModeDefaultName(mode); + modes = xf86ModesAdd(modes, mode); + xf86PrintModeline(0, mode); + } + } + + return modes; +} + +static void +destroy(xf86OutputPtr output) +{ + drmModeFreeOutput(output->driver_private); +} + +static void +create_resources(xf86OutputPtr output) +{ +#ifdef RANDR_12_INTERFACE +#endif /* RANDR_12_INTERFACE */ +} + +#ifdef RANDR_12_INTERFACE +static Bool +set_property(xf86OutputPtr output, Atom property, RRPropertyValuePtr value) +{ + return TRUE; +} +#endif /* RANDR_12_INTERFACE */ + +#ifdef RANDR_13_INTERFACE +static Bool +get_property(xf86OutputPtr output, Atom property) +{ + return TRUE; +} +#endif /* RANDR_13_INTERFACE */ + +#ifdef RANDR_GET_CRTC_INTERFACE +static xf86CrtcPtr +get_crtc(xf86OutputPtr output) +{ + return NULL; +} +#endif + +static const xf86OutputFuncsRec output_funcs = { + .create_resources = create_resources, + .dpms = dpms, + .save = save, + .restore = restore, + .mode_valid = mode_valid, + .mode_fixup = mode_fixup, + .prepare = prepare, + .mode_set = mode_set, + .commit = commit, + .detect = detect, + .get_modes = get_modes, +#ifdef RANDR_12_INTERFACE + .set_property = set_property, +#endif +#ifdef RANDR_13_INTERFACE + .get_property = get_property, +#endif + .destroy = destroy, +#ifdef RANDR_GET_CRTC_INTERFACE + .get_crtc = get_crtc, +#endif +}; + +void +output_init(ScrnInfoPtr pScrn) +{ + modesettingPtr ms = modesettingPTR(pScrn); + xf86OutputPtr output; + drmModeResPtr res; + drmModeOutputPtr drm_output = NULL; + drmModeCrtcPtr crtc; + char *name; + int o, v, p; + + res = drmModeGetResources(ms->fd); + if (res == 0) { + DRV_ERROR("Failed drmModeGetResources\n"); + return; + } + + for (o = 0; o < res->count_outputs; o++) { + drm_output = drmModeGetOutput(ms->fd, res->outputs[o]); + if (!drm_output) + goto out; + + for (p = 0; p < drm_output->count_props; p++) { + drmModePropertyPtr prop; + + prop = drmModeGetProperty(ms->fd, drm_output->props[p]); + + name = NULL; + if (prop) { + ErrorF("VALUES %d\n",prop->count_values); + + for (v=0;vcount_values;v++) + ErrorF("%s %lld\n", prop->name, prop->values[v]); + + for (v=0;vcount_enums;v++) { + ErrorF("%s %s\n", prop->name, prop->enums[v].name); + if (drm_output->prop_values[p] == prop->enums[v].value) { + if (!strncmp("Connector Type", prop->name, 14)) { + ErrorF("WE'VE GOT %s\n",prop->enums[v].name); + name = xalloc(strlen(prop->enums[v].name)); + strncpy(name, prop->enums[v].name, strlen(name)); + } + } + if (name) break; + } + if (name) break; + } + } + + if (!name) + continue; + + output = xf86OutputCreate(pScrn, &output_funcs, name); + if (!output) + continue; + + free(name); + + output->possible_crtcs = drm_output->crtcs; + output->possible_clones = drm_output->clones; + output->driver_private = drm_output; + output->subpixel_order = SubPixelHorizontalRGB; + output->interlaceAllowed = FALSE; + output->doubleScanAllowed = FALSE; + } + +out: + drmModeFreeResources(res); +}