diff --git a/hw/xfree86/drivers/modesetting/Makefile.am b/hw/xfree86/drivers/modesetting/Makefile.am index 23e78b753..4337977b0 100644 --- a/hw/xfree86/drivers/modesetting/Makefile.am +++ b/hw/xfree86/drivers/modesetting/Makefile.am @@ -25,19 +25,16 @@ SUBDIRS = # _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@ \ - -I@GALLIUM_DIR@/src/gallium/include \ - -I@GALLIUM_DIR@/src/gallium/auxiliary +AM_CFLAGS = @XORG_CFLAGS@ @DRM_CFLAGS@ @UDEV_CFLAGS@ modesetting_drv_la_LTLIBRARIES = modesetting_drv.la -modesetting_drv_la_LDFLAGS = -module -avoid-version -ldrm +modesetting_drv_la_LDFLAGS = -module -avoid-version +modesetting_drv_la_LIBADD = @UDEV_LIBS@ @DRM_LIBS@ modesetting_drv_ladir = @moduledir@/drivers modesetting_drv_la_SOURCES = \ driver.c \ driver.h \ - output.c \ - crtc.c \ - dri2.c + drmmode_display.c EXTRA_DIST = diff --git a/hw/xfree86/drivers/modesetting/crtc.c b/hw/xfree86/drivers/modesetting/crtc.c deleted file mode 100644 index d4f449bb4..000000000 --- a/hw/xfree86/drivers/modesetting/crtc.c +++ /dev/null @@ -1,307 +0,0 @@ -/* - * 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 - -struct crtc_private -{ - drmModeCrtcPtr drm_crtc; - - /* hwcursor */ - drmBO cursor_bo; -}; - -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]; - drmModeConnectorPtr drm_connector = output->driver_private; - struct crtc_private *crtcp = crtc->driver_private; - drmModeCrtcPtr drm_crtc = crtcp->drm_crtc; - 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; - if (!mode->name) - xf86SetModeDefaultName(mode); - strncpy(drm_mode.name, mode->name, DRM_DISPLAY_MODE_LEN); - - drmModeSetCrtc(ms->fd, drm_crtc->crtc_id, ms->fb_id, x, y, - &drm_connector->connector_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) -{ - modesettingPtr ms = modesettingPTR(crtc->scrn); - struct crtc_private *crtcp = crtc->driver_private; - - if (crtcp->cursor_bo.handle) - drmBOUnreference(ms->fd, &crtcp->cursor_bo); - - drmModeFreeCrtc(crtcp->drm_crtc); - xfree(crtcp); -} - -static void -crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 * image) -{ - unsigned char *ptr; - modesettingPtr ms = modesettingPTR(crtc->scrn); - struct crtc_private *crtcp = crtc->driver_private; - - if (!crtcp->cursor_bo.handle) - drmBOCreate(ms->fd, 64 * 64 * 4, 0, NULL, - DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE - | DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_MAPPABLE | - DRM_BO_FLAG_MEM_VRAM, - DRM_BO_HINT_DONT_FENCE, &crtcp->cursor_bo); - - drmBOMap(ms->fd, &crtcp->cursor_bo, DRM_BO_FLAG_WRITE, - DRM_BO_HINT_DONT_FENCE, (void **)&ptr); - - if (ptr) - memcpy(ptr, image, 64 * 64 * 4); - - drmBOUnmap(ms->fd, &crtcp->cursor_bo); -} - -static void -crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y) -{ - modesettingPtr ms = modesettingPTR(crtc->scrn); - struct crtc_private *crtcp = crtc->driver_private; - - drmModeMoveCursor(ms->fd, crtcp->drm_crtc->crtc_id, x, y); -} - -static void -crtc_show_cursor(xf86CrtcPtr crtc) -{ - modesettingPtr ms = modesettingPTR(crtc->scrn); - struct crtc_private *crtcp = crtc->driver_private; - - if (crtcp->cursor_bo.handle) - drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id, - crtcp->cursor_bo.handle, 64, 64); -} - -static void -crtc_hide_cursor(xf86CrtcPtr crtc) -{ - modesettingPtr ms = modesettingPTR(crtc->scrn); - struct crtc_private *crtcp = crtc->driver_private; - - drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id, 0, 0, 0); -} - -static const xf86CrtcFuncsRec crtc_funcs = { - .dpms = crtc_dpms, - .save = NULL, - .restore = NULL, - .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_position = crtc_set_cursor_position, - .show_cursor = crtc_show_cursor, - .hide_cursor = crtc_hide_cursor, - .load_cursor_image = NULL, /* lets convert to argb only */ - .set_cursor_colors = NULL, /* using argb only */ - .load_cursor_argb = crtc_load_cursor_argb, - .destroy = crtc_destroy, -}; - -void -cursor_destroy(xf86CrtcPtr crtc) -{ - modesettingPtr ms = modesettingPTR(crtc->scrn); - struct crtc_private *crtcp = crtc->driver_private; - - if (crtcp->cursor_bo.handle) { - drmBOSetStatus(ms->fd, &crtcp->cursor_bo, 0, 0, 0, 0, 0); - drmBOUnreference(ms->fd, &crtcp->cursor_bo); - } -} - -void -crtc_init(ScrnInfoPtr pScrn) -{ - modesettingPtr ms = modesettingPTR(pScrn); - xf86CrtcPtr crtc; - drmModeResPtr res; - drmModeCrtcPtr drm_crtc = NULL; - struct crtc_private *crtcp; - 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; - - crtcp = xcalloc(1, sizeof(struct crtc_private)); - if (!crtcp) { - xf86CrtcDestroy(crtc); - goto out; - } - - crtcp->drm_crtc = drm_crtc; - - crtc->driver_private = crtcp; - - } - - out: - drmModeFreeResources(res); -} diff --git a/hw/xfree86/drivers/modesetting/dri2.c b/hw/xfree86/drivers/modesetting/dri2.c deleted file mode 100644 index 7fd9fcae3..000000000 --- a/hw/xfree86/drivers/modesetting/dri2.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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" - -#include "dri2.h" - -extern unsigned int -driGetPixmapHandle(PixmapPtr pPixmap, unsigned int *flags); - -void -driLock(ScreenPtr pScreen) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - modesettingPtr ms = modesettingPTR(pScrn); - - if (!ms->lock_held) - DRM_LOCK(ms->fd, ms->lock, ms->context, 0); - - ms->lock_held = 1; -} - -void -driUnlock(ScreenPtr pScreen) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - modesettingPtr ms = modesettingPTR(pScrn); - - if (ms->lock_held) - DRM_UNLOCK(ms->fd, ms->lock, ms->context); - - ms->lock_held = 0; -} - -static void -driBeginClipNotify(ScreenPtr pScreen) -{ - driLock(pScreen); -} - -static void -driEndClipNotify(ScreenPtr pScreen) -{ - driUnlock(pScreen); -} - -struct __DRILock -{ - unsigned int block_header; - drm_hw_lock_t lock; - unsigned int next_id; -}; - -#define DRI2_SAREA_BLOCK_HEADER(type, size) (((type) << 16) | (size)) -#define DRI2_SAREA_BLOCK_LOCK 0x0001 - -void -driScreenInit(ScreenPtr pScreen) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - modesettingPtr ms = modesettingPTR(pScrn); - DRI2InfoRec dri2info; - const char *driverName; - unsigned int sarea_handle; - struct __DRILock *DRILock; - void *p; - - dri2info.version = 1; - dri2info.fd = ms->fd; - dri2info.driverSareaSize = sizeof(struct __DRILock); - dri2info.driverName = "i915"; /* FIXME */ - dri2info.getPixmapHandle = driGetPixmapHandle; - dri2info.beginClipNotify = driBeginClipNotify; - dri2info.endClipNotify = driEndClipNotify; - - p = DRI2ScreenInit(pScreen, &dri2info); - if (!p) - return; - - DRILock = p; - DRILock->block_header = - DRI2_SAREA_BLOCK_HEADER(DRI2_SAREA_BLOCK_LOCK, sizeof *DRILock); - ms->lock = &DRILock->lock; - ms->context = 1; - DRILock->next_id = 2; - driLock(pScreen); - - DRI2Connect(pScreen, &ms->fd, &driverName, &sarea_handle); -} - -void -driCloseScreen(ScreenPtr pScreen) -{ - driUnlock(pScreen); - DRI2CloseScreen(pScreen); -} diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c index 6b70d4b09..47ffb07b7 100644 --- a/hw/xfree86/drivers/modesetting/driver.c +++ b/hw/xfree86/drivers/modesetting/driver.c @@ -34,10 +34,8 @@ #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 @@ -59,8 +57,6 @@ 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, @@ -82,7 +78,7 @@ static Bool Probe(DriverPtr drv, int flags); #if XSERVER_LIBPCIACCESS static const struct pci_id_match device_match[] = { - {0x8086, 0x2592, 0xffff, 0xffff, 0, 0, 0}, + {0x8086, 0x0046, 0xffff, 0xffff, 0, 0, 0}, {0, 0, 0}, }; #endif @@ -107,12 +103,12 @@ _X_EXPORT DriverRec modesetting = { }; static SymTabRec Chipsets[] = { - {0x2592, "Intel Graphics Device"}, + {0x0046, "Intel Graphics Device"}, {-1, NULL} }; static PciChipsets PciDevices[] = { - {0x2592, 0x2592, RES_SHARED_VGA}, + {0x2592, 0x0046, RES_SHARED_VGA}, {-1, -1, RES_UNDEFINED} }; @@ -126,24 +122,6 @@ static const OptionInfoRec Options[] = { {-1, NULL, OPTV_NONE, {0}, FALSE} }; -static const char *fbSymbols[] = { - "fbPictureInit", - "fbScreenInit", - NULL -}; - -static const char *ddcSymbols[] = { - "xf86PrintEDID", - "xf86SetDDCproperties", - NULL -}; - -static const char *i2cSymbols[] = { - "xf86CreateI2CBusRec", - "xf86I2CBusInit", - NULL -}; - int modesettingEntityIndex = -1; static MODULESETUPPROTO(Setup); @@ -174,12 +152,6 @@ Setup(pointer module, pointer opts, int *errmaj, int *errmin) setupDone = 1; xf86AddDriver(&modesetting, module, HaveDriverFuncs); - /* - * Tell the loader about symbols from other modules that this module - * might refer to. - */ - LoaderRefSymLists(fbSymbols, ddcSymbols, NULL); - /* * The return value must be non-NULL on success even though there * is no TearDownProc. @@ -225,7 +197,7 @@ pci_probe(DriverPtr driver, entity = xf86GetEntityInfo(entity_num); switch (device->device_id) { - case 0x2592: + case 0x0046: scrn->PreInit = PreInit; scrn->ScreenInit = ScreenInit; scrn->SwitchMode = SwitchMode; @@ -358,8 +330,8 @@ Probe(DriverPtr drv, int flags) } } - xfree(usedChips); - xfree(devSections); + free(usedChips); + free(devSections); return foundScreen; } @@ -385,76 +357,11 @@ FreeRec(ScrnInfoPtr pScrn) if (!pScrn->driverPrivate) return; - xfree(pScrn->driverPrivate); + free(pScrn->driverPrivate); pScrn->driverPrivate = NULL; } -static void -ProbeDDC(ScrnInfoPtr pScrn, int index) -{ - ConfiguredMonitor = NULL; -} - -static Bool -CreateFrontBuffer(ScrnInfoPtr pScrn) -{ - modesettingPtr ms = modesettingPTR(pScrn); - ScreenPtr pScreen = pScrn->pScreen; - PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen); - Bool fbAccessDisabled; - int flags; - - pScreen->ModifyPixmapHeader(rootPixmap, - pScrn->virtualX, pScrn->virtualY, - pScrn->depth, pScrn->bitsPerPixel, - pScrn->displayWidth * pScrn->bitsPerPixel / 8, - NULL); - drmModeAddFB(ms->fd, - pScrn->virtualX, - pScrn->virtualY, - pScrn->depth, - pScrn->bitsPerPixel, - pScrn->displayWidth * pScrn->bitsPerPixel / 8, - driGetPixmapHandle(rootPixmap, &flags), &ms->fb_id); - - pScrn->frameX0 = 0; - pScrn->frameY0 = 0; - AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); - - return TRUE; -} - -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; - - /* HW dependent - FIXME */ - pScrn->displayWidth = pScrn->virtualX; - - drmModeRmFB(ms->fd, ms->fb_id); - - /* now create new frontbuffer */ - return CreateFrontBuffer(pScrn); -} - -static const xf86CrtcConfigFuncsRec crtc_config_funcs = { - crtc_resize -}; - static Bool PreInit(ScrnInfoPtr pScrn, int flags) { @@ -476,8 +383,7 @@ PreInit(ScrnInfoPtr pScrn, int flags) pEnt = xf86GetEntityInfo(pScrn->entityList[0]); if (flags & PROBE_DETECT) { - ProbeDDC(pScrn, pEnt->index); - return TRUE; + return FALSE; } /* Allocate driverPrivate */ @@ -503,10 +409,6 @@ PreInit(ScrnInfoPtr pScrn, int flags) } 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 */ @@ -515,7 +417,7 @@ PreInit(ScrnInfoPtr pScrn, int flags) } } - BusID = xalloc(64); + BusID = malloc(64); sprintf(BusID, "PCI:%d:%d:%d", #if XSERVER_LIBPCIACCESS ((ms->PciInfo->domain << 8) | ms->PciInfo->bus), @@ -528,11 +430,9 @@ PreInit(ScrnInfoPtr pScrn, int flags) ); 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; @@ -562,36 +462,21 @@ PreInit(ScrnInfoPtr pScrn, int flags) /* Process the options */ xf86CollectOptions(pScrn, NULL); - if (!(ms->Options = xalloc(sizeof(Options)))) + if (!(ms->Options = malloc(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_SW_CURSOR, FALSE)) { ms->SWCursor = 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; + ms->drmmode.fd = ms->fd; + if (drmmode_pre_init(pScrn, &ms->drmmode, pScrn->bitsPerPixel / 8) == FALSE) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "KMS setup failed\n"); + goto fail; } - RestoreHWState(pScrn); - /* * If the driver can do gamma correction, it should call xf86SetGamma() here. */ @@ -618,29 +503,13 @@ PreInit(ScrnInfoPtr pScrn, int flags) return FALSE; } - xf86LoaderReqSymLists(fbSymbols, NULL); - #ifdef DRI2 xf86LoadSubModule(pScrn, "dri2"); #endif 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; + fail: + return FALSE; } static Bool @@ -651,26 +520,25 @@ CreateScreenResources(ScreenPtr pScreen) PixmapPtr rootPixmap; Bool ret; int flags; - + void *pixels; pScreen->CreateScreenResources = ms->createScreenResources; ret = pScreen->CreateScreenResources(pScreen); pScreen->CreateScreenResources = CreateScreenResources; + if (!drmmode_set_desired_modes(pScrn, &ms->drmmode)) + return FALSE; + + drmmode_uevent_init(pScrn, &ms->drmmode); + + drmmode_map_cursor_bos(pScrn, &ms->drmmode); + pixels = drmmode_map_front_bo(&ms->drmmode); + if (!pixels) + return FALSE; + rootPixmap = pScreen->GetScreenPixmap(pScreen); - - if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, NULL)) + if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, pixels)) FatalError("Couldn't adjust screen pixmap\n"); - drmModeAddFB(ms->fd, - pScrn->virtualX, - pScrn->virtualY, - pScrn->depth, - pScrn->bitsPerPixel, - pScrn->displayWidth * pScrn->bitsPerPixel / 8, - driGetPixmapHandle(rootPixmap, &flags), &ms->fb_id); - - AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); - return ret; } @@ -688,7 +556,7 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (ms->fd < 0) { char *BusID; - BusID = xalloc(64); + BusID = malloc(64); sprintf(BusID, "PCI:%d:%d:%d", #if XSERVER_LIBPCIACCESS ((ms->PciInfo->domain << 8) | ms->PciInfo->bus), @@ -710,6 +578,8 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) /* HW dependent - FIXME */ pScrn->displayWidth = pScrn->virtualX; + if (!drmmode_create_initial_bos(pScrn, &ms->drmmode)) + return FALSE; miClearVisualTypes(); @@ -782,10 +652,6 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (serverGeneration == 1) xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); -#ifdef DRI2 - driScreenInit(pScreen); -#endif - return EnterVT(scrnIndex, 1); } @@ -822,7 +688,7 @@ LeaveVT(int scrnIndex, int flags) for (o = 0; o < config->num_crtc; o++) { xf86CrtcPtr crtc = config->crtc[o]; - cursor_destroy(crtc); + // cursor_destroy(crtc); if (crtc->rotatedPixmap || crtc->rotatedData) { crtc->funcs->shadow_destroy(crtc, crtc->rotatedPixmap, @@ -834,16 +700,6 @@ LeaveVT(int scrnIndex, int flags) drmModeRmFB(ms->fd, ms->fb_id); - RestoreHWState(pScrn); - -#if 0 - drmMMLock(ms->fd, DRM_BO_MEM_VRAM, 1, 0); - drmMMLock(ms->fd, DRM_BO_MEM_TT, 1, 0); -#endif -#ifdef DRI2 - driLock(pScrn->pScreen); -#endif - pScrn->vtSema = FALSE; } @@ -856,29 +712,6 @@ EnterVT(int scrnIndex, int flags) ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; modesettingPtr ms = modesettingPTR(pScrn); -#if 0 - if (pScrn->vtSema) { - drmMMUnlock(ms->fd, DRM_BO_MEM_VRAM, 1); - drmMMUnlock(ms->fd, DRM_BO_MEM_TT, 1); - } -#endif - -#ifdef DRI2 - driUnlock(pScrn->pScreen); -#endif - - /* - * 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); - } - - if (!flags) /* signals startup as we'll do this in CreateScreenResources */ - CreateFrontBuffer(pScrn); - if (!xf86SetDesiredModes(pScrn)) return FALSE; @@ -899,16 +732,13 @@ CloseScreen(int scrnIndex, ScreenPtr pScreen) ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; modesettingPtr ms = modesettingPTR(pScrn); + drmmode_uevent_fini(pScrn, &ms->drmmode); + + drmmode_free_bos(pScrn, &ms->drmmode); + if (pScrn->vtSema) { LeaveVT(scrnIndex, 0); -#if 0 - drmMMUnlock(ms->fd, DRM_BO_MEM_VRAM, 1); - drmMMUnlock(ms->fd, DRM_BO_MEM_TT, 1); -#endif } -#ifdef DRI2 - driCloseScreen(pScreen); -#endif pScreen->CreateScreenResources = ms->createScreenResources; diff --git a/hw/xfree86/drivers/modesetting/driver.h b/hw/xfree86/drivers/modesetting/driver.h index a673f8fd9..255dedef1 100644 --- a/hw/xfree86/drivers/modesetting/driver.h +++ b/hw/xfree86/drivers/modesetting/driver.h @@ -30,9 +30,8 @@ #include #include #include -#include -#include +#include "drmmode_display.h" #define DRV_ERROR(msg) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, msg); typedef struct @@ -72,10 +71,7 @@ typedef struct _modesettingRec void *driver; - /* dri2 */ - drm_context_t context; - drm_hw_lock_t *lock; - int lock_held; + drmmode_rec drmmode; } modesettingRec, *modesettingPtr; #define modesettingPTR(p) ((modesettingPtr)((p)->driverPrivate)) diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c new file mode 100644 index 000000000..d94ce03e0 --- /dev/null +++ b/hw/xfree86/drivers/modesetting/drmmode_display.c @@ -0,0 +1,1340 @@ +/* + * Copyright © 2007 Red Hat, Inc. + * + * 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, sublicense, + * 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + * Authors: + * Dave Airlie + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include "xf86str.h" +#include "X11/Xatom.h" +#include "micmap.h" +#include "xf86cmap.h" +#include "xf86DDC.h" + +#include +#include "xf86Crtc.h" +#include "drmmode_display.h" + +/* DPMS */ +#ifdef HAVE_XEXTPROTO_71 +#include +#else +#define DPMS_SERVER +#include +#endif + +static struct dumb_bo *dumb_bo_create(int fd, + const unsigned width, const unsigned height, + const unsigned bpp) +{ + struct drm_mode_create_dumb arg; + struct dumb_bo *bo; + int ret; + + bo = calloc(1, sizeof(*bo)); + if (!bo) + return NULL; + + memset(&arg, 0, sizeof(arg)); + arg.width = width; + arg.height = height; + arg.bpp = bpp; + + ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &arg); + if (ret) + goto err_free; + + bo->handle = arg.handle; + bo->size = arg.size; + bo->pitch = arg.pitch; + + return bo; + err_free: + free(bo); + return NULL; +} + +static int dumb_bo_map(int fd, struct dumb_bo *bo) +{ + struct drm_mode_map_dumb arg; + int ret; + void *map; + + if (bo->ptr) { + bo->map_count++; + return 0; + } + + memset(&arg, 0, sizeof(arg)); + arg.handle = bo->handle; + + ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &arg); + if (ret) + return ret; + + map = mmap(0, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED, + fd, arg.offset); + if (map == MAP_FAILED) + return -errno; + + bo->ptr = map; + return 0; +} + +static int dumb_bo_unmap(int fd, struct dumb_bo *bo) +{ + bo->map_count--; + return 0; +} + +static int dumb_bo_destroy(int fd, struct dumb_bo *bo) +{ + struct drm_mode_destroy_dumb arg; + int ret; + + if (bo->ptr) { + munmap(bo->ptr, bo->size); + bo->ptr = NULL; + } + + memset(&arg, 0, sizeof(arg)); + arg.handle = bo->handle; + ret = drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &arg); + if (ret) + return -errno; + + free(bo); + return 0; +} + +static void +drmmode_ConvertFromKMode(ScrnInfoPtr scrn, + drmModeModeInfo *kmode, + DisplayModePtr mode) +{ + memset(mode, 0, sizeof(DisplayModeRec)); + mode->status = MODE_OK; + + mode->Clock = kmode->clock; + + mode->HDisplay = kmode->hdisplay; + mode->HSyncStart = kmode->hsync_start; + mode->HSyncEnd = kmode->hsync_end; + mode->HTotal = kmode->htotal; + mode->HSkew = kmode->hskew; + + mode->VDisplay = kmode->vdisplay; + mode->VSyncStart = kmode->vsync_start; + mode->VSyncEnd = kmode->vsync_end; + mode->VTotal = kmode->vtotal; + mode->VScan = kmode->vscan; + + mode->Flags = kmode->flags; //& FLAG_BITS; + mode->name = strdup(kmode->name); + + if (kmode->type & DRM_MODE_TYPE_DRIVER) + mode->type = M_T_DRIVER; + if (kmode->type & DRM_MODE_TYPE_PREFERRED) + mode->type |= M_T_PREFERRED; + xf86SetModeCrtc (mode, scrn->adjustFlags); +} + +static void +drmmode_ConvertToKMode(ScrnInfoPtr scrn, + drmModeModeInfo *kmode, + DisplayModePtr mode) +{ + memset(kmode, 0, sizeof(*kmode)); + + kmode->clock = mode->Clock; + kmode->hdisplay = mode->HDisplay; + kmode->hsync_start = mode->HSyncStart; + kmode->hsync_end = mode->HSyncEnd; + kmode->htotal = mode->HTotal; + kmode->hskew = mode->HSkew; + + kmode->vdisplay = mode->VDisplay; + kmode->vsync_start = mode->VSyncStart; + kmode->vsync_end = mode->VSyncEnd; + kmode->vtotal = mode->VTotal; + kmode->vscan = mode->VScan; + + kmode->flags = mode->Flags; //& FLAG_BITS; + if (mode->name) + strncpy(kmode->name, mode->name, DRM_DISPLAY_MODE_LEN); + kmode->name[DRM_DISPLAY_MODE_LEN-1] = 0; + +} + +static void +drmmode_crtc_dpms(xf86CrtcPtr crtc, int mode) +{ +#if 0 + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); +// drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; +// drmmode_ptr drmmode = drmmode_crtc->drmmode; + + /* bonghits in the randr 1.2 - uses dpms to disable crtc - bad buzz */ + if (mode == DPMSModeOff) { +// drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, +// 0, 0, 0, NULL, 0, NULL); + } +#endif +} + +#if 0 +static PixmapPtr +create_pixmap_for_fbcon(drmmode_ptr drmmode, + ScrnInfoPtr pScrn, int crtc_id) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + drmmode_crtc_private_ptr drmmode_crtc; + ScreenPtr pScreen = pScrn->pScreen; + PixmapPtr pixmap; + struct radeon_bo *bo; + drmModeFBPtr fbcon; + struct drm_gem_flink flink; + + drmmode_crtc = xf86_config->crtc[crtc_id]->driver_private; + + fbcon = drmModeGetFB(drmmode->fd, drmmode_crtc->mode_crtc->buffer_id); + if (fbcon == NULL) + return NULL; + + flink.handle = fbcon->handle; + if (ioctl(drmmode->fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Couldn't flink fbcon handle\n"); + return NULL; + } + + bo = radeon_bo_open(drmmode->bufmgr, flink.name, 0, 0, 0, 0); + if (bo == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Couldn't allocate bo for fbcon handle\n"); + return NULL; + } + + pixmap = drmmode_create_bo_pixmap(pScreen, fbcon->width, fbcon->height, + fbcon->depth, fbcon->bpp, + fbcon->pitch, bo); + if (!pixmap) + return NULL; + + radeon_bo_unref(bo); + drmModeFreeFB(fbcon); + return pixmap; +} + +#endif + +static Bool +drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, + Rotation rotation, int x, int y) +{ + ScrnInfoPtr pScrn = crtc->scrn; + // RADEONInfoPtr info = RADEONPTR(pScrn); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + drmmode_ptr drmmode = drmmode_crtc->drmmode; + int saved_x, saved_y; + Rotation saved_rotation; + DisplayModeRec saved_mode; + uint32_t *output_ids; + int output_count = 0; + Bool ret = TRUE; + int i; + int fb_id; + drmModeModeInfo kmode; + int pitch; + uint32_t tiling_flags = 0; + int height; + + pitch = pScrn->displayWidth; + height = pScrn->virtualY; + + if (drmmode->fb_id == 0) { + ret = drmModeAddFB(drmmode->fd, + pScrn->virtualX, height, + pScrn->depth, pScrn->bitsPerPixel, + drmmode->front_bo->pitch, + drmmode->front_bo->handle, + &drmmode->fb_id); + if (ret < 0) { + ErrorF("failed to add fb %d\n", ret); + return FALSE; + } + } + + saved_mode = crtc->mode; + saved_x = crtc->x; + saved_y = crtc->y; + saved_rotation = crtc->rotation; + + if (mode) { + crtc->mode = *mode; + crtc->x = x; + crtc->y = y; + crtc->rotation = rotation; +#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,5,99,0,0) + crtc->transformPresent = FALSE; +#endif + } + + output_ids = calloc(sizeof(uint32_t), xf86_config->num_output); + if (!output_ids) { + ret = FALSE; + goto done; + } + + if (mode) { + for (i = 0; i < xf86_config->num_output; i++) { + xf86OutputPtr output = xf86_config->output[i]; + drmmode_output_private_ptr drmmode_output; + + if (output->crtc != crtc) + continue; + + drmmode_output = output->driver_private; + output_ids[output_count] = drmmode_output->mode_output->connector_id; + output_count++; + } + + if (!xf86CrtcRotate(crtc)) { + goto done; + } +#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,7,0,0,0) + crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green, + crtc->gamma_blue, crtc->gamma_size); +#endif + + drmmode_ConvertToKMode(crtc->scrn, &kmode, mode); + + fb_id = drmmode->fb_id; + if (drmmode_crtc->rotate_fb_id) { + fb_id = drmmode_crtc->rotate_fb_id; + x = y = 0; + } + ret = drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, + fb_id, x, y, output_ids, output_count, &kmode); + if (ret) + xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, + "failed to set mode: %s", strerror(-ret)); + else + ret = TRUE; + + if (crtc->scrn->pScreen) + xf86CrtcSetScreenSubpixelOrder(crtc->scrn->pScreen); + /* go through all the outputs and force DPMS them back on? */ + for (i = 0; i < xf86_config->num_output; i++) { + xf86OutputPtr output = xf86_config->output[i]; + + if (output->crtc != crtc) + continue; + + output->funcs->dpms(output, DPMSModeOn); + } + } + +#if 0 + if (pScrn->pScreen && + !xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) + xf86_reload_cursors(pScrn->pScreen); +#endif +done: + if (!ret) { + crtc->x = saved_x; + crtc->y = saved_y; + crtc->rotation = saved_rotation; + crtc->mode = saved_mode; + } +#if defined(XF86_CRTC_VERSION) && XF86_CRTC_VERSION >= 3 + else + crtc->active = TRUE; +#endif + + return ret; +} + +static void +drmmode_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg) +{ + +} + +static void +drmmode_set_cursor_position (xf86CrtcPtr crtc, int x, int y) +{ + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + drmmode_ptr drmmode = drmmode_crtc->drmmode; + + drmModeMoveCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, x, y); +} + +static void +drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) +{ + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + int i; + uint32_t *ptr; + + /* cursor should be mapped already */ + ptr = (uint32_t *)(drmmode_crtc->cursor_bo->ptr); + + for (i = 0; i < 64 * 64; i++) + ptr[i] = image[i];// cpu_to_le32(image[i]); +} + + +static void +drmmode_hide_cursor (xf86CrtcPtr crtc) +{ + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + drmmode_ptr drmmode = drmmode_crtc->drmmode; + + drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 0, 64, 64); + +} + +static void +drmmode_show_cursor (xf86CrtcPtr crtc) +{ + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + drmmode_ptr drmmode = drmmode_crtc->drmmode; + uint32_t handle = drmmode_crtc->cursor_bo->handle; + + drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, handle, 64, 64); +} + +static void +drmmode_crtc_gamma_set(xf86CrtcPtr crtc, uint16_t *red, uint16_t *green, + uint16_t *blue, int size) +{ + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + drmmode_ptr drmmode = drmmode_crtc->drmmode; + + drmModeCrtcSetGamma(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, + size, red, green, blue); +} + +static const xf86CrtcFuncsRec drmmode_crtc_funcs = { + .dpms = drmmode_crtc_dpms, + .set_mode_major = drmmode_set_mode_major, + .set_cursor_colors = drmmode_set_cursor_colors, + .set_cursor_position = drmmode_set_cursor_position, + .show_cursor = drmmode_show_cursor, + .hide_cursor = drmmode_hide_cursor, + .load_cursor_argb = drmmode_load_cursor_argb, + + .gamma_set = drmmode_crtc_gamma_set, + .destroy = NULL, /* XXX */ +}; + +int drmmode_get_crtc_id(xf86CrtcPtr crtc) +{ + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + return drmmode_crtc->hw_id; +} + +static void +drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num) +{ + xf86CrtcPtr crtc; + drmmode_crtc_private_ptr drmmode_crtc; + + crtc = xf86CrtcCreate(pScrn, &drmmode_crtc_funcs); + if (crtc == NULL) + return; + + drmmode_crtc = xnfcalloc(sizeof(drmmode_crtc_private_rec), 1); + drmmode_crtc->mode_crtc = drmModeGetCrtc(drmmode->fd, drmmode->mode_res->crtcs[num]); + drmmode_crtc->drmmode = drmmode; + crtc->driver_private = drmmode_crtc; +} + +static xf86OutputStatus +drmmode_output_detect(xf86OutputPtr output) +{ + /* go to the hw and retrieve a new output struct */ + drmmode_output_private_ptr drmmode_output = output->driver_private; + drmmode_ptr drmmode = drmmode_output->drmmode; + xf86OutputStatus status; + drmModeFreeConnector(drmmode_output->mode_output); + + drmmode_output->mode_output = drmModeGetConnector(drmmode->fd, drmmode_output->output_id); + + switch (drmmode_output->mode_output->connection) { + case DRM_MODE_CONNECTED: + status = XF86OutputStatusConnected; + break; + case DRM_MODE_DISCONNECTED: + status = XF86OutputStatusDisconnected; + break; + default: + case DRM_MODE_UNKNOWNCONNECTION: + status = XF86OutputStatusUnknown; + break; + } + return status; +} + +static Bool +drmmode_output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes) +{ + return MODE_OK; +} + +static DisplayModePtr +drmmode_output_get_modes(xf86OutputPtr output) +{ + drmmode_output_private_ptr drmmode_output = output->driver_private; + drmModeConnectorPtr koutput = drmmode_output->mode_output; + drmmode_ptr drmmode = drmmode_output->drmmode; + int i; + DisplayModePtr Modes = NULL, Mode; + drmModePropertyPtr props; + xf86MonPtr mon = NULL; + + /* look for an EDID property */ + for (i = 0; i < koutput->count_props; i++) { + props = drmModeGetProperty(drmmode->fd, koutput->props[i]); + if (props && (props->flags & DRM_MODE_PROP_BLOB)) { + if (!strcmp(props->name, "EDID")) { + if (drmmode_output->edid_blob) + drmModeFreePropertyBlob(drmmode_output->edid_blob); + drmmode_output->edid_blob = drmModeGetPropertyBlob(drmmode->fd, koutput->prop_values[i]); + } + drmModeFreeProperty(props); + } + } + + if (drmmode_output->edid_blob) { + mon = xf86InterpretEDID(output->scrn->scrnIndex, + drmmode_output->edid_blob->data); + if (mon && drmmode_output->edid_blob->length > 128) + mon->flags |= MONITOR_EDID_COMPLETE_RAWDATA; + } + xf86OutputSetEDID(output, mon); + + /* modes should already be available */ + for (i = 0; i < koutput->count_modes; i++) { + Mode = xnfalloc(sizeof(DisplayModeRec)); + + drmmode_ConvertFromKMode(output->scrn, &koutput->modes[i], Mode); + Modes = xf86ModesAdd(Modes, Mode); + + } + return Modes; +} + +static void +drmmode_output_destroy(xf86OutputPtr output) +{ + drmmode_output_private_ptr drmmode_output = output->driver_private; + int i; + + if (drmmode_output->edid_blob) + drmModeFreePropertyBlob(drmmode_output->edid_blob); + for (i = 0; i < drmmode_output->num_props; i++) { + drmModeFreeProperty(drmmode_output->props[i].mode_prop); + free(drmmode_output->props[i].atoms); + } + for (i = 0; i < drmmode_output->mode_output->count_encoders; i++) { + drmModeFreeEncoder(drmmode_output->mode_encoders[i]); + free(drmmode_output->mode_encoders); + } + free(drmmode_output->props); + drmModeFreeConnector(drmmode_output->mode_output); + free(drmmode_output); + output->driver_private = NULL; +} + +static void +drmmode_output_dpms(xf86OutputPtr output, int mode) +{ + drmmode_output_private_ptr drmmode_output = output->driver_private; + drmModeConnectorPtr koutput = drmmode_output->mode_output; + drmmode_ptr drmmode = drmmode_output->drmmode; + + drmModeConnectorSetProperty(drmmode->fd, koutput->connector_id, + drmmode_output->dpms_enum_id, mode); + return; +} + + +static Bool +drmmode_property_ignore(drmModePropertyPtr prop) +{ + if (!prop) + return TRUE; + /* ignore blob prop */ + if (prop->flags & DRM_MODE_PROP_BLOB) + return TRUE; + /* ignore standard property */ + if (!strcmp(prop->name, "EDID") || + !strcmp(prop->name, "DPMS")) + return TRUE; + + return FALSE; +} + +static void +drmmode_output_create_resources(xf86OutputPtr output) +{ + drmmode_output_private_ptr drmmode_output = output->driver_private; + drmModeConnectorPtr mode_output = drmmode_output->mode_output; + drmmode_ptr drmmode = drmmode_output->drmmode; + drmModePropertyPtr drmmode_prop; + int i, j, err; + + drmmode_output->props = calloc(mode_output->count_props, sizeof(drmmode_prop_rec)); + if (!drmmode_output->props) + return; + + drmmode_output->num_props = 0; + for (i = 0, j = 0; i < mode_output->count_props; i++) { + drmmode_prop = drmModeGetProperty(drmmode->fd, mode_output->props[i]); + if (drmmode_property_ignore(drmmode_prop)) { + drmModeFreeProperty(drmmode_prop); + continue; + } + drmmode_output->props[j].mode_prop = drmmode_prop; + drmmode_output->props[j].value = mode_output->prop_values[i]; + drmmode_output->num_props++; + j++; + } + + for (i = 0; i < drmmode_output->num_props; i++) { + drmmode_prop_ptr p = &drmmode_output->props[i]; + drmmode_prop = p->mode_prop; + + if (drmmode_prop->flags & DRM_MODE_PROP_RANGE) { + INT32 range[2]; + INT32 value = p->value; + + p->num_atoms = 1; + p->atoms = calloc(p->num_atoms, sizeof(Atom)); + if (!p->atoms) + continue; + p->atoms[0] = MakeAtom(drmmode_prop->name, strlen(drmmode_prop->name), TRUE); + range[0] = drmmode_prop->values[0]; + range[1] = drmmode_prop->values[1]; + err = RRConfigureOutputProperty(output->randr_output, p->atoms[0], + FALSE, TRUE, + drmmode_prop->flags & DRM_MODE_PROP_IMMUTABLE ? TRUE : FALSE, + 2, range); + if (err != 0) { + xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, + "RRConfigureOutputProperty error, %d\n", err); + } + err = RRChangeOutputProperty(output->randr_output, p->atoms[0], + XA_INTEGER, 32, PropModeReplace, 1, &value, FALSE, TRUE); + if (err != 0) { + xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, + "RRChangeOutputProperty error, %d\n", err); + } + } else if (drmmode_prop->flags & DRM_MODE_PROP_ENUM) { + p->num_atoms = drmmode_prop->count_enums + 1; + p->atoms = calloc(p->num_atoms, sizeof(Atom)); + if (!p->atoms) + continue; + p->atoms[0] = MakeAtom(drmmode_prop->name, strlen(drmmode_prop->name), TRUE); + for (j = 1; j <= drmmode_prop->count_enums; j++) { + struct drm_mode_property_enum *e = &drmmode_prop->enums[j-1]; + p->atoms[j] = MakeAtom(e->name, strlen(e->name), TRUE); + } + err = RRConfigureOutputProperty(output->randr_output, p->atoms[0], + FALSE, FALSE, + drmmode_prop->flags & DRM_MODE_PROP_IMMUTABLE ? TRUE : FALSE, + p->num_atoms - 1, (INT32 *)&p->atoms[1]); + if (err != 0) { + xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, + "RRConfigureOutputProperty error, %d\n", err); + } + for (j = 0; j < drmmode_prop->count_enums; j++) + if (drmmode_prop->enums[j].value == p->value) + break; + /* there's always a matching value */ + err = RRChangeOutputProperty(output->randr_output, p->atoms[0], + XA_ATOM, 32, PropModeReplace, 1, &p->atoms[j+1], FALSE, TRUE); + if (err != 0) { + xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, + "RRChangeOutputProperty error, %d\n", err); + } + } + } +} + +static Bool +drmmode_output_set_property(xf86OutputPtr output, Atom property, + RRPropertyValuePtr value) +{ + drmmode_output_private_ptr drmmode_output = output->driver_private; + drmmode_ptr drmmode = drmmode_output->drmmode; + int i; + + for (i = 0; i < drmmode_output->num_props; i++) { + drmmode_prop_ptr p = &drmmode_output->props[i]; + + if (p->atoms[0] != property) + continue; + + if (p->mode_prop->flags & DRM_MODE_PROP_RANGE) { + uint32_t val; + + if (value->type != XA_INTEGER || value->format != 32 || + value->size != 1) + return FALSE; + val = *(uint32_t *)value->data; + + drmModeConnectorSetProperty(drmmode->fd, drmmode_output->output_id, + p->mode_prop->prop_id, (uint64_t)val); + return TRUE; + } else if (p->mode_prop->flags & DRM_MODE_PROP_ENUM) { + Atom atom; + const char *name; + int j; + + if (value->type != XA_ATOM || value->format != 32 || value->size != 1) + return FALSE; + memcpy(&atom, value->data, 4); + name = NameForAtom(atom); + + /* search for matching name string, then set its value down */ + for (j = 0; j < p->mode_prop->count_enums; j++) { + if (!strcmp(p->mode_prop->enums[j].name, name)) { + drmModeConnectorSetProperty(drmmode->fd, drmmode_output->output_id, + p->mode_prop->prop_id, p->mode_prop->enums[j].value); + return TRUE; + } + } + } + } + + return TRUE; +} + +static Bool +drmmode_output_get_property(xf86OutputPtr output, Atom property) +{ + return TRUE; +} + +static const xf86OutputFuncsRec drmmode_output_funcs = { + .dpms = drmmode_output_dpms, + .create_resources = drmmode_output_create_resources, +#ifdef RANDR_12_INTERFACE + .set_property = drmmode_output_set_property, + .get_property = drmmode_output_get_property, +#endif + .detect = drmmode_output_detect, + .mode_valid = drmmode_output_mode_valid, + + .get_modes = drmmode_output_get_modes, + .destroy = drmmode_output_destroy +}; + +static int subpixel_conv_table[7] = { 0, SubPixelUnknown, + SubPixelHorizontalRGB, + SubPixelHorizontalBGR, + SubPixelVerticalRGB, + SubPixelVerticalBGR, + SubPixelNone }; + +const char *output_names[] = { "None", + "VGA", + "DVI", + "DVI", + "DVI", + "Composite", + "S-video", + "LVDS", + "CTV", + "DIN", + "DisplayPort", + "HDMI", + "HDMI", + "TV", + "eDP" +}; + +static void +drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num, int *num_dvi, int *num_hdmi) +{ + xf86OutputPtr output; + drmModeConnectorPtr koutput; + drmModeEncoderPtr *kencoders = NULL; + drmmode_output_private_ptr drmmode_output; + drmModePropertyPtr props; + char name[32]; + int i; + const char *s; + + koutput = drmModeGetConnector(drmmode->fd, drmmode->mode_res->connectors[num]); + if (!koutput) + return; + + kencoders = calloc(sizeof(drmModeEncoderPtr), koutput->count_encoders); + if (!kencoders) { + goto out_free_encoders; + } + + for (i = 0; i < koutput->count_encoders; i++) { + kencoders[i] = drmModeGetEncoder(drmmode->fd, koutput->encoders[i]); + if (!kencoders[i]) { + goto out_free_encoders; + } + } + + /* need to do smart conversion here for compat with non-kms ATI driver */ + snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], koutput->connector_type_id - 1); + + output = xf86OutputCreate (pScrn, &drmmode_output_funcs, name); + if (!output) { + goto out_free_encoders; + } + + drmmode_output = calloc(sizeof(drmmode_output_private_rec), 1); + if (!drmmode_output) { + xf86OutputDestroy(output); + goto out_free_encoders; + } + + drmmode_output->output_id = drmmode->mode_res->connectors[num]; + drmmode_output->mode_output = koutput; + drmmode_output->mode_encoders = kencoders; + drmmode_output->drmmode = drmmode; + output->mm_width = koutput->mmWidth; + output->mm_height = koutput->mmHeight; + + output->subpixel_order = subpixel_conv_table[koutput->subpixel]; + output->interlaceAllowed = TRUE; + output->doubleScanAllowed = TRUE; + output->driver_private = drmmode_output; + + output->possible_crtcs = 0x7f; + for (i = 0; i < koutput->count_encoders; i++) { + output->possible_crtcs &= kencoders[i]->possible_crtcs; + } + /* work out the possible clones later */ + output->possible_clones = 0; + + for (i = 0; i < koutput->count_props; i++) { + props = drmModeGetProperty(drmmode->fd, koutput->props[i]); + if (props && (props->flags & DRM_MODE_PROP_ENUM)) { + if (!strcmp(props->name, "DPMS")) { + drmmode_output->dpms_enum_id = koutput->props[i]; + drmModeFreeProperty(props); + break; + } + drmModeFreeProperty(props); + } + } + + return; +out_free_encoders: + if (kencoders){ + for (i = 0; i < koutput->count_encoders; i++) + drmModeFreeEncoder(kencoders[i]); + free(kencoders); + } + drmModeFreeConnector(koutput); + +} + +uint32_t find_clones(ScrnInfoPtr scrn, xf86OutputPtr output) +{ + drmmode_output_private_ptr drmmode_output = output->driver_private, clone_drmout; + int i; + xf86OutputPtr clone_output; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + int index_mask = 0; + + if (drmmode_output->enc_clone_mask == 0) + return index_mask; + + for (i = 0; i < xf86_config->num_output; i++) { + clone_output = xf86_config->output[i]; + clone_drmout = clone_output->driver_private; + if (output == clone_output) + continue; + + if (clone_drmout->enc_mask == 0) + continue; + if (drmmode_output->enc_clone_mask == clone_drmout->enc_mask) + index_mask |= (1 << i); + } + return index_mask; +} + + +static void +drmmode_clones_init(ScrnInfoPtr scrn, drmmode_ptr drmmode) +{ + int i, j; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + + for (i = 0; i < xf86_config->num_output; i++) { + xf86OutputPtr output = xf86_config->output[i]; + drmmode_output_private_ptr drmmode_output; + + drmmode_output = output->driver_private; + drmmode_output->enc_clone_mask = 0xff; + /* and all the possible encoder clones for this output together */ + for (j = 0; j < drmmode_output->mode_output->count_encoders; j++) + { + int k; + for (k = 0; k < drmmode->mode_res->count_encoders; k++) { + if (drmmode->mode_res->encoders[k] == drmmode_output->mode_encoders[j]->encoder_id) + drmmode_output->enc_mask |= (1 << k); + } + + drmmode_output->enc_clone_mask &= drmmode_output->mode_encoders[j]->possible_clones; + } + } + + for (i = 0; i < xf86_config->num_output; i++) { + xf86OutputPtr output = xf86_config->output[i]; + output->possible_clones = find_clones(scrn, output); + } +} + +static Bool +drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + drmmode_crtc_private_ptr + drmmode_crtc = xf86_config->crtc[0]->driver_private; + drmmode_ptr drmmode = drmmode_crtc->drmmode; + struct dumb_bo *old_front = NULL; + Bool ret; + ScreenPtr screen = screenInfo.screens[scrn->scrnIndex]; + uint32_t old_fb_id; + int i, pitch, old_width, old_height, old_pitch; + int screen_size; + int cpp = (scrn->bitsPerPixel + 1) / 8; + struct dumb_bo *front_bo; + uint32_t tiling_flags = 0; + PixmapPtr ppix = screen->GetScreenPixmap(screen); + void *new_pixels; + + if (scrn->virtualX == width && scrn->virtualY == height) + return TRUE; + + xf86DrvMsg(scrn->scrnIndex, X_INFO, + "Allocate new frame buffer %dx%d stride %d\n", + width, height, pitch / cpp); + + old_width = scrn->virtualX; + old_height = scrn->virtualY; + old_pitch = scrn->displayWidth; + old_fb_id = drmmode->fb_id; + old_front = drmmode->front_bo; + + drmmode->front_bo = dumb_bo_create(drmmode->fd, width, height, scrn->bitsPerPixel); + if (!drmmode->front_bo) + goto fail; + + pitch = drmmode->front_bo->pitch; + + scrn->virtualX = width; + scrn->virtualY = height; + scrn->displayWidth = pitch / cpp; + + ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth, + scrn->bitsPerPixel, pitch, + drmmode->front_bo->handle, + &drmmode->fb_id); + if (ret) + goto fail; + + new_pixels = drmmode_map_front_bo(drmmode); + if (!new_pixels) + goto fail; + + screen->ModifyPixmapHeader(ppix, width, height, -1, -1, + pitch, new_pixels); + +#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,9,99,1,0) + scrn->pixmapPrivate.ptr = ppix->devPrivate.ptr; +#endif + + for (i = 0; i < xf86_config->num_crtc; i++) { + xf86CrtcPtr crtc = xf86_config->crtc[i]; + + if (!crtc->enabled) + continue; + + drmmode_set_mode_major(crtc, &crtc->mode, + crtc->rotation, crtc->x, crtc->y); + } + + if (old_fb_id) { + drmModeRmFB(drmmode->fd, old_fb_id); + dumb_bo_destroy(drmmode->fd, old_front); + } + + return TRUE; + + fail: + if (drmmode->front_bo) + dumb_bo_destroy(drmmode->fd, drmmode->front_bo); + drmmode->front_bo = old_front; + scrn->virtualX = old_width; + scrn->virtualY = old_height; + scrn->displayWidth = old_pitch; + drmmode->fb_id = old_fb_id; + + return FALSE; +} + +static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = { + drmmode_xf86crtc_resize +}; + +Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp) +{ + xf86CrtcConfigPtr xf86_config; + int i, num_dvi = 0, num_hdmi = 0; + + xf86CrtcConfigInit(pScrn, &drmmode_xf86crtc_config_funcs); + xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + + drmmode->scrn = pScrn; + drmmode->cpp = cpp; + drmmode->mode_res = drmModeGetResources(drmmode->fd); + if (!drmmode->mode_res) + return FALSE; + + xf86CrtcSetSizeRange(pScrn, 320, 200, drmmode->mode_res->max_width, drmmode->mode_res->max_height); + for (i = 0; i < drmmode->mode_res->count_crtcs; i++) + if (!xf86IsEntityShared(pScrn->entityList[0]) || pScrn->confScreen->device->screen == i) + drmmode_crtc_init(pScrn, drmmode, i); + + for (i = 0; i < drmmode->mode_res->count_connectors; i++) + drmmode_output_init(pScrn, drmmode, i, &num_dvi, &num_hdmi); + + /* workout clones */ + drmmode_clones_init(pScrn, drmmode); + + xf86InitialConfiguration(pScrn, TRUE); + + return TRUE; +} + +void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, struct dumb_bo *bo) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + xf86CrtcPtr crtc = xf86_config->crtc[id]; + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + + drmmode_crtc->cursor_bo = bo; +} + +void drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y, int flags) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + xf86OutputPtr output = config->output[config->compat_output]; + xf86CrtcPtr crtc = output->crtc; + + if (crtc && crtc->enabled) { + drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation, + x, y); + } +} + +Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + int c; + + for (c = 0; c < config->num_crtc; c++) { + xf86CrtcPtr crtc = config->crtc[c]; + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + xf86OutputPtr output = NULL; + int o; + + /* Skip disabled CRTCs */ + if (!crtc->enabled) { + drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, + 0, 0, 0, NULL, 0, NULL); + continue; + } + + if (config->output[config->compat_output]->crtc == crtc) + output = config->output[config->compat_output]; + else + { + for (o = 0; o < config->num_output; o++) + if (config->output[o]->crtc == crtc) + { + output = config->output[o]; + break; + } + } + /* paranoia */ + if (!output) + continue; + + /* Mark that we'll need to re-set the mode for sure */ + memset(&crtc->mode, 0, sizeof(crtc->mode)); + if (!crtc->desiredMode.CrtcHDisplay) + { + DisplayModePtr mode = xf86OutputFindClosestMode (output, pScrn->currentMode); + + if (!mode) + return FALSE; + crtc->desiredMode = *mode; + crtc->desiredRotation = RR_Rotate_0; + crtc->desiredX = 0; + crtc->desiredY = 0; + } + + if (!crtc->funcs->set_mode_major(crtc, &crtc->desiredMode, crtc->desiredRotation, + crtc->desiredX, crtc->desiredY)) + return FALSE; + } + return TRUE; +} + +static void drmmode_load_palette(ScrnInfoPtr pScrn, int numColors, + int *indices, LOCO *colors, VisualPtr pVisual) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + uint16_t lut_r[256], lut_g[256], lut_b[256]; + int index, j, i; + int c; + + for (c = 0; c < xf86_config->num_crtc; c++) { + xf86CrtcPtr crtc = xf86_config->crtc[c]; + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + + for (i = 0 ; i < 256; i++) { + lut_r[i] = drmmode_crtc->lut_r[i] << 6; + lut_g[i] = drmmode_crtc->lut_g[i] << 6; + lut_b[i] = drmmode_crtc->lut_b[i] << 6; + } + + switch(pScrn->depth) { + case 15: + for (i = 0; i < numColors; i++) { + index = indices[i]; + for (j = 0; j < 8; j++) { + lut_r[index * 8 + j] = colors[index].red << 6; + lut_g[index * 8 + j] = colors[index].green << 6; + lut_b[index * 8 + j] = colors[index].blue << 6; + } + } + break; + case 16: + for (i = 0; i < numColors; i++) { + index = indices[i]; + + if (i <= 31) { + for (j = 0; j < 8; j++) { + lut_r[index * 8 + j] = colors[index].red << 6; + lut_b[index * 8 + j] = colors[index].blue << 6; + } + } + + for (j = 0; j < 4; j++) { + lut_g[index * 4 + j] = colors[index].green << 6; + } + } + break; + default: + for (i = 0; i < numColors; i++) { + index = indices[i]; + lut_r[index] = colors[index].red << 6; + lut_g[index] = colors[index].green << 6; + lut_b[index] = colors[index].blue << 6; + } + break; + } + + /* Make the change through RandR */ +#ifdef RANDR_12_INTERFACE + if (crtc->randr_crtc) + RRCrtcGammaSet(crtc->randr_crtc, lut_r, lut_g, lut_b); + else +#endif + crtc->funcs->gamma_set(crtc, lut_r, lut_g, lut_b, 256); + } +} + +Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn) +{ + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0, + "Initializing kms color map\n"); + if (!miCreateDefColormap(pScreen)) + return FALSE; + /* all radeons support 10 bit CLUTs */ + if (!xf86HandleColormaps(pScreen, 256, 10, + drmmode_load_palette, NULL, + CMAP_PALETTED_TRUECOLOR +#if 0 /* This option messes up text mode! (eich@suse.de) */ + | CMAP_LOAD_EVEN_IF_OFFSCREEN +#endif + | CMAP_RELOAD_ON_MODE_SWITCH)) + return FALSE; + return TRUE; +} + +#ifdef HAVE_UDEV +static void +drmmode_handle_uevents(int fd, void *closure) +{ + drmmode_ptr drmmode = closure; + ScrnInfoPtr scrn = drmmode->scrn; + struct udev_device *dev; + dev = udev_monitor_receive_device(drmmode->uevent_monitor); + if (!dev) + return; + + RRGetInfo(screenInfo.screens[scrn->scrnIndex], TRUE); + udev_device_unref(dev); +} +#endif + +void drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode) +{ +#ifdef HAVE_UDEV + struct udev *u; + struct udev_monitor *mon; + + u = udev_new(); + if (!u) + return; + mon = udev_monitor_new_from_netlink(u, "udev"); + if (!mon) { + udev_unref(u); + return; + } + + if (udev_monitor_filter_add_match_subsystem_devtype(mon, + "drm", + "drm_minor") < 0 || + udev_monitor_enable_receiving(mon) < 0) { + udev_monitor_unref(mon); + udev_unref(u); + return; + } + + drmmode->uevent_handler = + xf86AddGeneralHandler(udev_monitor_get_fd(mon), + drmmode_handle_uevents, + drmmode); + + drmmode->uevent_monitor = mon; +#endif +} + +void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode) +{ +#ifdef HAVE_UDEV + if (drmmode->uevent_handler) { + struct udev *u = udev_monitor_get_udev(drmmode->uevent_monitor); + xf86RemoveGeneralHandler(drmmode->uevent_handler); + + udev_monitor_unref(drmmode->uevent_monitor); + udev_unref(u); + } +#endif +} + +/* create front and cursor BOs */ +Bool drmmode_create_initial_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int width; + int height; + int bpp; + int i; + + width = pScrn->virtualX; + height = pScrn->virtualY; + bpp = pScrn->bitsPerPixel; + drmmode->front_bo = dumb_bo_create(drmmode->fd, width, height, bpp); + if (!drmmode->front_bo) + return FALSE; + + + width = height = 64; + bpp = 32; + for (i = 0; i < xf86_config->num_crtc; i++) { + xf86CrtcPtr crtc = xf86_config->crtc[i]; + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + drmmode_crtc->cursor_bo = dumb_bo_create(drmmode->fd, width, height, bpp); + } + return TRUE; +} + +void *drmmode_map_front_bo(drmmode_ptr drmmode) +{ + int ret; + + if (drmmode->front_bo->ptr) + return drmmode->front_bo->ptr; + + ret = dumb_bo_map(drmmode->fd, drmmode->front_bo); + if (ret) + return NULL; + + return drmmode->front_bo->ptr; + +} + +Bool drmmode_map_cursor_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int i, ret; + for (i = 0; i < xf86_config->num_crtc; i++) { + xf86CrtcPtr crtc = xf86_config->crtc[i]; + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + ret = dumb_bo_map(drmmode->fd, drmmode_crtc->cursor_bo); + if (ret) + return FALSE; + } + return TRUE; +} + +void drmmode_free_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int i; + dumb_bo_destroy(drmmode->fd, drmmode->front_bo); + drmmode->front_bo = NULL; + + for (i = 0; i < xf86_config->num_crtc; i++) { + xf86CrtcPtr crtc = xf86_config->crtc[i]; + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + dumb_bo_destroy(drmmode->fd, drmmode_crtc->cursor_bo); + } +} diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h new file mode 100644 index 000000000..2d7250568 --- /dev/null +++ b/hw/xfree86/drivers/modesetting/drmmode_display.h @@ -0,0 +1,125 @@ +/* + * Copyright © 2007 Red Hat, Inc. + * + * 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, sublicense, + * 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + * Authors: + * Dave Airlie + * + */ +#ifndef DRMMODE_DISPLAY_H +#define DRMMODE_DISPLAY_H + +#include "xf86drmMode.h" +#ifdef HAVE_UDEV +#include "libudev.h" +#endif + +struct dumb_bo { + uint32_t handle; + uint32_t size; + void *ptr; + int map_count; + uint32_t pitch; +}; + +typedef struct { + int fd; + unsigned fb_id; + drmModeResPtr mode_res; + drmModeFBPtr mode_fb; + int cpp; + ScrnInfoPtr scrn; +#ifdef HAVE_UDEV + struct udev_monitor *uevent_monitor; + InputHandlerProc uevent_handler; +#endif + drmEventContext event_context; + struct dumb_bo *front_bo; +} drmmode_rec, *drmmode_ptr; + +typedef struct { + drmmode_ptr drmmode; + unsigned old_fb_id; + int flip_count; + void *event_data; + unsigned int fe_frame; + unsigned int fe_tv_sec; + unsigned int fe_tv_usec; +} drmmode_flipdata_rec, *drmmode_flipdata_ptr; + +typedef struct { + drmmode_flipdata_ptr flipdata; + Bool dispatch_me; +} drmmode_flipevtcarrier_rec, *drmmode_flipevtcarrier_ptr; + +typedef struct { + drmmode_ptr drmmode; + drmModeCrtcPtr mode_crtc; + int hw_id; + struct dumb_bo *cursor_bo; + // struct radeon_bo *rotate_bo; + unsigned rotate_fb_id; + uint16_t lut_r[256], lut_g[256], lut_b[256]; +} drmmode_crtc_private_rec, *drmmode_crtc_private_ptr; + +typedef struct { + drmModePropertyPtr mode_prop; + uint64_t value; + int num_atoms; /* if range prop, num_atoms == 1; if enum prop, num_atoms == num_enums + 1 */ + Atom *atoms; +} drmmode_prop_rec, *drmmode_prop_ptr; + + +typedef struct { + drmmode_ptr drmmode; + int output_id; + drmModeConnectorPtr mode_output; + drmModeEncoderPtr *mode_encoders; + drmModePropertyBlobPtr edid_blob; + int dpms_enum_id; + int num_props; + drmmode_prop_ptr props; + int enc_mask; + int enc_clone_mask; +} drmmode_output_private_rec, *drmmode_output_private_ptr; + + +extern Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp); +//extern Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode, struct radeon_bo_manager *bufmgr); +//extern void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, struct radeon_bo *bo); +void drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y, int flags); +extern Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode); +extern void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode); +extern Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn); + +extern void drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode); +extern void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode); + +extern int drmmode_get_height_align(ScrnInfoPtr scrn, uint32_t tiling); +extern int drmmode_get_pitch_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling); +extern int drmmode_get_base_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling); + +//Bool radeon_do_pageflip(ScrnInfoPtr scrn, struct radeon_bo *new_front, void *data, int ref_crtc_hw_id); +Bool drmmode_create_initial_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode); +void *drmmode_map_front_bo(drmmode_ptr drmmode); +Bool drmmode_map_cursor_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode); +void drmmode_free_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode); +#endif diff --git a/hw/xfree86/drivers/modesetting/output.c b/hw/xfree86/drivers/modesetting/output.c deleted file mode 100644 index 1f95a2f1c..000000000 --- a/hw/xfree86/drivers/modesetting/output.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - * 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 char *connector_enum_list[] = { - "Unknown", - "VGA", - "DVI-I", - "DVI-D", - "DVI-A", - "Composite", - "SVIDEO", - "LVDS", - "Component", - "9-pin DIN", - "DisplayPort", - "HDMI Type A", - "HDMI Type B", -}; - -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) -{ - drmModeConnectorPtr drm_connector = output->driver_private; - - switch (drm_connector->connection) { - case DRM_MODE_CONNECTED: - return XF86OutputStatusConnected; - case DRM_MODE_DISCONNECTED: - return XF86OutputStatusDisconnected; - default: - return XF86OutputStatusUnknown; - } -} - -static DisplayModePtr -get_modes(xf86OutputPtr output) -{ - drmModeConnectorPtr drm_connector = output->driver_private; - struct drm_mode_modeinfo *drm_mode = NULL; - DisplayModePtr modes = NULL, mode = NULL; - int i; - - for (i = 0; i < drm_connector->count_modes; i++) { - drm_mode = &drm_connector->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) -{ - drmModeFreeConnector(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; - drmModeConnectorPtr drm_connector = NULL; - drmModeEncoderPtr drm_encoder = NULL; - drmModeCrtcPtr crtc; - char *name; - int c, v, p; - - res = drmModeGetResources(ms->fd); - if (res == 0) { - DRV_ERROR("Failed drmModeGetResources\n"); - return; - } - - for (c = 0; c < res->count_connectors; c++) { - drm_connector = drmModeGetConnector(ms->fd, res->connectors[c]); - if (!drm_connector) - goto out; - - for (p = 0; p < drm_connector->count_props; p++) { - drmModePropertyPtr prop; - - prop = drmModeGetProperty(ms->fd, drm_connector->props[p]); - - name = NULL; - if (prop) { - ErrorF("VALUES %d\n", prop->count_values); - - for (v = 0; v < prop->count_values; v++) - ErrorF("%s %lld\n", prop->name, prop->values[v]); - } - } - - name = connector_enum_list[drm_connector->connector_type]; - - output = xf86OutputCreate(pScrn, &output_funcs, name); - if (!output) - continue; - - drm_encoder = drmModeGetEncoder(ms->fd, drm_connector->encoders[0]); - if (drm_encoder) { - output->possible_crtcs = drm_encoder->crtcs; - output->possible_clones = drm_encoder->clones; - } else { - output->possible_crtcs = 0; - output->possible_clones = 0; - } - output->driver_private = drm_connector; - output->subpixel_order = SubPixelHorizontalRGB; - output->interlaceAllowed = FALSE; - output->doubleScanAllowed = FALSE; - } - - out: - drmModeFreeResources(res); -}