2008-05-28 14:33:07 +02:00
|
|
|
/*
|
|
|
|
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
|
2011-09-29 13:34:17 +02:00
|
|
|
* Copyright 2011 Dave Airlie
|
2008-05-28 14:33:07 +02:00
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
*
|
2011-09-29 13:34:17 +02:00
|
|
|
* Original Author: Alan Hourihane <alanh@tungstengraphics.com>
|
2014-10-31 00:45:12 +01:00
|
|
|
* Rewrite: Dave Airlie <airlied@redhat.com>
|
2008-05-28 14:33:07 +02:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2014-08-26 20:06:23 +02:00
|
|
|
#ifdef HAVE_DIX_CONFIG_H
|
|
|
|
#include "dix-config.h"
|
2008-05-28 14:33:07 +02:00
|
|
|
#endif
|
|
|
|
|
2011-09-29 15:13:58 +02:00
|
|
|
#include <unistd.h>
|
2011-09-29 13:28:59 +02:00
|
|
|
#include <fcntl.h>
|
2008-05-28 14:33:07 +02:00
|
|
|
#include "xf86.h"
|
|
|
|
#include "xf86_OSproc.h"
|
|
|
|
#include "compiler.h"
|
|
|
|
#include "xf86Pci.h"
|
|
|
|
#include "mipointer.h"
|
|
|
|
#include "micmap.h"
|
|
|
|
#include <X11/extensions/randr.h>
|
|
|
|
#include "fb.h"
|
|
|
|
#include "edid.h"
|
|
|
|
#include "xf86i2c.h"
|
|
|
|
#include "xf86Crtc.h"
|
|
|
|
#include "miscstruct.h"
|
|
|
|
#include "dixstruct.h"
|
2011-09-29 16:55:36 +02:00
|
|
|
#include "shadow.h"
|
2008-05-28 14:33:07 +02:00
|
|
|
#include "xf86xv.h"
|
|
|
|
#include <X11/extensions/Xv.h>
|
2014-08-26 20:06:23 +02:00
|
|
|
#include <xorg-config.h>
|
2012-06-05 15:43:21 +02:00
|
|
|
#ifdef XSERVER_PLATFORM_BUS
|
|
|
|
#include "xf86platformBus.h"
|
|
|
|
#endif
|
2008-05-28 14:33:07 +02:00
|
|
|
#if XSERVER_LIBPCIACCESS
|
|
|
|
#include <pciaccess.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "driver.h"
|
|
|
|
|
2014-08-26 20:37:46 +02:00
|
|
|
static void AdjustFrame(ScrnInfoPtr pScrn, int x, int y);
|
|
|
|
static Bool CloseScreen(ScreenPtr pScreen);
|
|
|
|
static Bool EnterVT(ScrnInfoPtr pScrn);
|
2008-05-28 14:33:07 +02:00
|
|
|
static void Identify(int flags);
|
|
|
|
static const OptionInfoRec *AvailableOptions(int chipid, int busid);
|
2014-10-08 09:39:15 +02:00
|
|
|
static ModeStatus ValidMode(ScrnInfoPtr pScrn, DisplayModePtr mode,
|
|
|
|
Bool verbose, int flags);
|
2014-08-26 20:37:46 +02:00
|
|
|
static void FreeScreen(ScrnInfoPtr pScrn);
|
|
|
|
static void LeaveVT(ScrnInfoPtr pScrn);
|
|
|
|
static Bool SwitchMode(ScrnInfoPtr pScrn, DisplayModePtr mode);
|
|
|
|
static Bool ScreenInit(ScreenPtr pScreen, int argc, char **argv);
|
2008-05-28 14:33:07 +02:00
|
|
|
static Bool PreInit(ScrnInfoPtr pScrn, int flags);
|
2008-05-28 16:55:36 +02:00
|
|
|
|
2008-05-28 14:33:07 +02:00
|
|
|
static Bool Probe(DriverPtr drv, int flags);
|
2011-09-29 13:28:59 +02:00
|
|
|
static Bool ms_pci_probe(DriverPtr driver,
|
2014-10-08 09:39:15 +02:00
|
|
|
int entity_num, struct pci_device *device,
|
|
|
|
intptr_t match_data);
|
|
|
|
static Bool ms_driver_func(ScrnInfoPtr scrn, xorgDriverFuncOp op, void *data);
|
2011-09-29 13:28:59 +02:00
|
|
|
|
|
|
|
#ifdef XSERVER_LIBPCIACCESS
|
|
|
|
static const struct pci_id_match ms_device_match[] = {
|
|
|
|
{
|
2014-10-08 09:39:15 +02:00
|
|
|
PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY,
|
|
|
|
0x00030000, 0x00ff0000, 0},
|
2011-09-29 13:28:59 +02:00
|
|
|
|
2014-10-08 09:39:15 +02:00
|
|
|
{0, 0, 0},
|
2008-05-28 14:33:07 +02:00
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2012-06-05 15:43:21 +02:00
|
|
|
#ifdef XSERVER_PLATFORM_BUS
|
|
|
|
static Bool ms_platform_probe(DriverPtr driver,
|
2014-10-08 09:39:15 +02:00
|
|
|
int entity_num, int flags,
|
|
|
|
struct xf86_platform_device *device,
|
|
|
|
intptr_t match_data);
|
2012-06-05 15:43:21 +02:00
|
|
|
#endif
|
|
|
|
|
2008-05-28 14:33:07 +02:00
|
|
|
_X_EXPORT DriverRec modesetting = {
|
2008-05-28 16:55:36 +02:00
|
|
|
1,
|
|
|
|
"modesetting",
|
|
|
|
Identify,
|
|
|
|
Probe,
|
|
|
|
AvailableOptions,
|
|
|
|
NULL,
|
|
|
|
0,
|
2012-07-20 00:15:10 +02:00
|
|
|
ms_driver_func,
|
2011-09-29 13:28:59 +02:00
|
|
|
ms_device_match,
|
|
|
|
ms_pci_probe,
|
2012-06-05 15:43:21 +02:00
|
|
|
#ifdef XSERVER_PLATFORM_BUS
|
|
|
|
ms_platform_probe,
|
|
|
|
#endif
|
2008-05-28 14:33:07 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
static SymTabRec Chipsets[] = {
|
2014-10-08 09:39:15 +02:00
|
|
|
{0, "kms"},
|
2008-05-28 16:55:36 +02:00
|
|
|
{-1, NULL}
|
2008-05-28 14:33:07 +02:00
|
|
|
};
|
|
|
|
|
2014-10-08 09:39:15 +02:00
|
|
|
typedef enum {
|
2008-05-28 16:55:36 +02:00
|
|
|
OPTION_SW_CURSOR,
|
2011-09-29 13:28:59 +02:00
|
|
|
OPTION_DEVICE_PATH,
|
2011-09-29 16:55:36 +02:00
|
|
|
OPTION_SHADOW_FB,
|
2013-12-28 20:32:10 +01:00
|
|
|
OPTION_ACCEL_METHOD,
|
2008-05-28 14:33:07 +02:00
|
|
|
} modesettingOpts;
|
|
|
|
|
|
|
|
static const OptionInfoRec Options[] = {
|
2008-05-28 16:55:36 +02:00
|
|
|
{OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE},
|
2014-10-08 09:39:15 +02:00
|
|
|
{OPTION_DEVICE_PATH, "kmsdev", OPTV_STRING, {0}, FALSE},
|
|
|
|
{OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE},
|
2013-12-28 20:32:10 +01:00
|
|
|
{OPTION_ACCEL_METHOD, "AccelMethod", OPTV_STRING, {0}, FALSE},
|
2008-05-28 16:55:36 +02:00
|
|
|
{-1, NULL, OPTV_NONE, {0}, FALSE}
|
2008-05-28 14:33:07 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
int modesettingEntityIndex = -1;
|
|
|
|
|
|
|
|
static MODULESETUPPROTO(Setup);
|
|
|
|
|
|
|
|
static XF86ModuleVersionInfo VersRec = {
|
2008-05-28 16:55:36 +02:00
|
|
|
"modesetting",
|
|
|
|
MODULEVENDORSTRING,
|
|
|
|
MODINFOSTRING1,
|
|
|
|
MODINFOSTRING2,
|
|
|
|
XORG_VERSION_CURRENT,
|
2014-08-26 20:06:23 +02:00
|
|
|
XORG_VERSION_MAJOR,
|
|
|
|
XORG_VERSION_MINOR,
|
|
|
|
XORG_VERSION_PATCH,
|
2008-05-28 16:55:36 +02:00
|
|
|
ABI_CLASS_VIDEODRV,
|
|
|
|
ABI_VIDEODRV_VERSION,
|
|
|
|
MOD_CLASS_VIDEODRV,
|
|
|
|
{0, 0, 0, 0}
|
2008-05-28 14:33:07 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
_X_EXPORT XF86ModuleData modesettingModuleData = { &VersRec, Setup, NULL };
|
|
|
|
|
2014-08-26 20:41:46 +02:00
|
|
|
static void *
|
2014-10-08 09:39:15 +02:00
|
|
|
Setup(void *module, void *opts, int *errmaj, int *errmin)
|
2008-05-28 14:33:07 +02:00
|
|
|
{
|
2008-05-28 16:55:36 +02:00
|
|
|
static Bool setupDone = 0;
|
|
|
|
|
|
|
|
/* This module should be loaded only once, but check to be sure.
|
|
|
|
*/
|
|
|
|
if (!setupDone) {
|
2014-10-08 09:39:15 +02:00
|
|
|
setupDone = 1;
|
|
|
|
xf86AddDriver(&modesetting, module, HaveDriverFuncs);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The return value must be non-NULL on success even though there
|
|
|
|
* is no TearDownProc.
|
|
|
|
*/
|
|
|
|
return (void *) 1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (errmaj)
|
|
|
|
*errmaj = LDR_ONCEONLY;
|
|
|
|
return NULL;
|
2008-05-28 16:55:36 +02:00
|
|
|
}
|
2008-05-28 14:33:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
Identify(int flags)
|
|
|
|
{
|
2008-05-28 16:55:36 +02:00
|
|
|
xf86PrintChipsets("modesetting", "Driver for Modesetting Kernel Drivers",
|
2014-10-08 09:39:15 +02:00
|
|
|
Chipsets);
|
2008-05-28 14:33:07 +02:00
|
|
|
}
|
|
|
|
|
2014-10-08 09:39:15 +02:00
|
|
|
static int
|
|
|
|
open_hw(const char *dev)
|
2011-09-29 13:28:59 +02:00
|
|
|
{
|
|
|
|
int fd;
|
2014-10-08 09:39:15 +02:00
|
|
|
|
2011-09-29 13:28:59 +02:00
|
|
|
if (dev)
|
2014-10-08 09:39:15 +02:00
|
|
|
fd = open(dev, O_RDWR, 0);
|
2011-09-29 13:28:59 +02:00
|
|
|
else {
|
2014-10-08 09:39:15 +02:00
|
|
|
dev = getenv("KMSDEVICE");
|
|
|
|
if ((NULL == dev) || ((fd = open(dev, O_RDWR, 0)) == -1)) {
|
|
|
|
dev = "/dev/dri/card0";
|
|
|
|
fd = open(dev, O_RDWR, 0);
|
|
|
|
}
|
2011-09-29 13:28:59 +02:00
|
|
|
}
|
2012-03-03 14:09:24 +01:00
|
|
|
if (fd == -1)
|
2014-10-08 09:39:15 +02:00
|
|
|
xf86DrvMsg(-1, X_ERROR, "open %s: %s\n", dev, strerror(errno));
|
2011-09-29 13:28:59 +02:00
|
|
|
|
2012-03-03 14:09:24 +01:00
|
|
|
return fd;
|
|
|
|
}
|
|
|
|
|
2014-10-08 09:39:15 +02:00
|
|
|
static int
|
|
|
|
check_outputs(int fd)
|
2013-06-12 14:05:19 +02:00
|
|
|
{
|
|
|
|
drmModeResPtr res = drmModeGetResources(fd);
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (!res)
|
|
|
|
return FALSE;
|
|
|
|
ret = res->count_connectors > 0;
|
|
|
|
drmModeFreeResources(res);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2014-10-08 09:39:15 +02:00
|
|
|
static Bool
|
|
|
|
probe_hw(const char *dev, struct xf86_platform_device *platform_dev)
|
2012-03-03 14:09:24 +01:00
|
|
|
{
|
2014-03-18 15:48:22 +01:00
|
|
|
int fd;
|
|
|
|
|
2014-05-02 05:16:05 +02:00
|
|
|
#if XF86_PDEV_SERVER_FD
|
2014-03-18 15:48:22 +01:00
|
|
|
if (platform_dev && (platform_dev->flags & XF86_PDEV_SERVER_FD)) {
|
2014-08-26 20:43:54 +02:00
|
|
|
fd = xf86_platform_device_odev_attributes(platform_dev)->fd;
|
2014-03-18 15:48:22 +01:00
|
|
|
if (fd == -1)
|
|
|
|
return FALSE;
|
|
|
|
return check_outputs(fd);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
fd = open_hw(dev);
|
2012-03-03 14:09:24 +01:00
|
|
|
if (fd != -1) {
|
2013-06-12 14:05:19 +02:00
|
|
|
int ret = check_outputs(fd);
|
2014-10-08 09:39:15 +02:00
|
|
|
|
2012-03-03 14:09:24 +01:00
|
|
|
close(fd);
|
2013-06-12 14:05:19 +02:00
|
|
|
return ret;
|
2012-03-03 14:09:24 +01:00
|
|
|
}
|
|
|
|
return FALSE;
|
2011-09-29 13:28:59 +02:00
|
|
|
}
|
|
|
|
|
2012-05-09 10:32:05 +02:00
|
|
|
static char *
|
|
|
|
ms_DRICreatePCIBusID(const struct pci_device *dev)
|
|
|
|
{
|
|
|
|
char *busID;
|
|
|
|
|
|
|
|
if (asprintf(&busID, "pci:%04x:%02x:%02x.%d",
|
|
|
|
dev->domain, dev->bus, dev->dev, dev->func) == -1)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return busID;
|
|
|
|
}
|
|
|
|
|
2014-10-08 09:39:15 +02:00
|
|
|
static Bool
|
|
|
|
probe_hw_pci(const char *dev, struct pci_device *pdev)
|
2012-05-09 10:32:05 +02:00
|
|
|
{
|
2013-06-12 14:05:19 +02:00
|
|
|
int ret = FALSE, fd = open_hw(dev);
|
2012-05-09 10:32:05 +02:00
|
|
|
char *id, *devid;
|
2012-06-22 16:26:28 +02:00
|
|
|
drmSetVersion sv;
|
2012-05-09 10:32:05 +02:00
|
|
|
|
|
|
|
if (fd == -1)
|
2014-10-08 09:39:15 +02:00
|
|
|
return FALSE;
|
2012-05-09 10:32:05 +02:00
|
|
|
|
2012-06-22 16:26:28 +02:00
|
|
|
sv.drm_di_major = 1;
|
|
|
|
sv.drm_di_minor = 4;
|
|
|
|
sv.drm_dd_major = -1;
|
|
|
|
sv.drm_dd_minor = -1;
|
|
|
|
if (drmSetInterfaceVersion(fd, &sv)) {
|
|
|
|
close(fd);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2012-05-09 10:32:05 +02:00
|
|
|
id = drmGetBusid(fd);
|
|
|
|
devid = ms_DRICreatePCIBusID(pdev);
|
|
|
|
|
2013-06-12 14:05:19 +02:00
|
|
|
if (id && devid && !strcmp(id, devid))
|
|
|
|
ret = check_outputs(fd);
|
2012-05-09 10:32:05 +02:00
|
|
|
|
2014-02-21 03:48:42 +01:00
|
|
|
close(fd);
|
2013-06-12 14:05:19 +02:00
|
|
|
free(id);
|
|
|
|
free(devid);
|
|
|
|
return ret;
|
2012-05-09 10:32:05 +02:00
|
|
|
}
|
2014-10-08 09:39:15 +02:00
|
|
|
|
2008-05-28 14:33:07 +02:00
|
|
|
static const OptionInfoRec *
|
|
|
|
AvailableOptions(int chipid, int busid)
|
|
|
|
{
|
2008-05-28 16:55:36 +02:00
|
|
|
return Options;
|
2008-05-28 14:33:07 +02:00
|
|
|
}
|
|
|
|
|
2012-07-20 00:15:10 +02:00
|
|
|
static Bool
|
|
|
|
ms_driver_func(ScrnInfoPtr scrn, xorgDriverFuncOp op, void *data)
|
|
|
|
{
|
|
|
|
xorgHWFlags *flag;
|
2014-10-08 09:39:15 +02:00
|
|
|
|
2012-07-20 00:15:10 +02:00
|
|
|
switch (op) {
|
2014-10-08 09:39:15 +02:00
|
|
|
case GET_REQUIRED_HW_INTERFACES:
|
|
|
|
flag = (CARD32 *) data;
|
|
|
|
(*flag) = 0;
|
|
|
|
return TRUE;
|
|
|
|
case SUPPORTS_SERVER_FDS:
|
|
|
|
return TRUE;
|
|
|
|
default:
|
|
|
|
return FALSE;
|
2012-07-20 00:15:10 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-27 01:59:37 +02:00
|
|
|
static void
|
|
|
|
ms_setup_scrn_hooks(ScrnInfoPtr scrn)
|
|
|
|
{
|
|
|
|
scrn->driverVersion = 1;
|
|
|
|
scrn->driverName = "modesetting";
|
|
|
|
scrn->name = "modeset";
|
|
|
|
|
|
|
|
scrn->Probe = NULL;
|
|
|
|
scrn->PreInit = PreInit;
|
|
|
|
scrn->ScreenInit = ScreenInit;
|
|
|
|
scrn->SwitchMode = SwitchMode;
|
|
|
|
scrn->AdjustFrame = AdjustFrame;
|
|
|
|
scrn->EnterVT = EnterVT;
|
|
|
|
scrn->LeaveVT = LeaveVT;
|
|
|
|
scrn->FreeScreen = FreeScreen;
|
|
|
|
scrn->ValidMode = ValidMode;
|
|
|
|
}
|
|
|
|
|
2008-05-28 14:33:07 +02:00
|
|
|
#if XSERVER_LIBPCIACCESS
|
|
|
|
static Bool
|
2011-09-29 13:28:59 +02:00
|
|
|
ms_pci_probe(DriverPtr driver,
|
2014-10-08 09:39:15 +02:00
|
|
|
int entity_num, struct pci_device *dev, intptr_t match_data)
|
2008-05-28 14:33:07 +02:00
|
|
|
{
|
2008-05-28 16:55:36 +02:00
|
|
|
ScrnInfoPtr scrn = NULL;
|
|
|
|
|
2011-09-29 13:28:59 +02:00
|
|
|
scrn = xf86ConfigPciEntity(scrn, 0, entity_num, NULL,
|
2014-10-08 09:39:15 +02:00
|
|
|
NULL, NULL, NULL, NULL, NULL);
|
2011-09-29 13:28:59 +02:00
|
|
|
if (scrn) {
|
2014-10-08 09:39:15 +02:00
|
|
|
const char *devpath;
|
|
|
|
GDevPtr devSection = xf86GetDevFromEntity(scrn->entityList[0],
|
|
|
|
scrn->entityInstanceList[0]);
|
|
|
|
|
|
|
|
devpath = xf86FindOptionValue(devSection->options, "kmsdev");
|
|
|
|
if (probe_hw_pci(devpath, dev)) {
|
2014-08-27 01:59:37 +02:00
|
|
|
ms_setup_scrn_hooks(scrn);
|
2014-10-08 09:39:15 +02:00
|
|
|
|
|
|
|
xf86DrvMsg(scrn->scrnIndex, X_CONFIG,
|
|
|
|
"claimed PCI slot %d@%d:%d:%d\n",
|
|
|
|
dev->bus, dev->domain, dev->dev, dev->func);
|
|
|
|
xf86DrvMsg(scrn->scrnIndex, X_INFO,
|
|
|
|
"using %s\n", devpath ? devpath : "default device");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
scrn = NULL;
|
2008-05-28 16:55:36 +02:00
|
|
|
}
|
|
|
|
return scrn != NULL;
|
2008-05-28 14:33:07 +02:00
|
|
|
}
|
2011-09-29 13:28:59 +02:00
|
|
|
#endif
|
|
|
|
|
2012-06-05 15:43:21 +02:00
|
|
|
#ifdef XSERVER_PLATFORM_BUS
|
|
|
|
static Bool
|
|
|
|
ms_platform_probe(DriverPtr driver,
|
2014-10-08 09:39:15 +02:00
|
|
|
int entity_num, int flags, struct xf86_platform_device *dev,
|
|
|
|
intptr_t match_data)
|
2012-06-05 15:43:21 +02:00
|
|
|
{
|
|
|
|
ScrnInfoPtr scrn = NULL;
|
2014-08-26 20:43:54 +02:00
|
|
|
const char *path = xf86_platform_device_odev_attributes(dev)->path;
|
2012-06-05 15:43:21 +02:00
|
|
|
int scr_flags = 0;
|
|
|
|
|
|
|
|
if (flags & PLATFORM_PROBE_GPU_SCREEN)
|
2014-10-08 09:39:15 +02:00
|
|
|
scr_flags = XF86_ALLOCATE_GPU_SCREEN;
|
2012-06-05 15:43:21 +02:00
|
|
|
|
2014-03-18 15:48:22 +01:00
|
|
|
if (probe_hw(path, dev)) {
|
2012-06-05 15:43:21 +02:00
|
|
|
scrn = xf86AllocateScreen(driver, scr_flags);
|
|
|
|
xf86AddEntityToScreen(scrn, entity_num);
|
|
|
|
|
2014-08-27 01:59:37 +02:00
|
|
|
ms_setup_scrn_hooks(scrn);
|
|
|
|
|
2012-06-05 15:43:21 +02:00
|
|
|
xf86DrvMsg(scrn->scrnIndex, X_INFO,
|
|
|
|
"using drv %s\n", path ? path : "default device");
|
|
|
|
}
|
|
|
|
|
|
|
|
return scrn != NULL;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2008-05-28 14:33:07 +02:00
|
|
|
static Bool
|
|
|
|
Probe(DriverPtr drv, int flags)
|
|
|
|
{
|
2011-09-29 15:13:58 +02:00
|
|
|
int i, numDevSections;
|
2008-05-28 16:55:36 +02:00
|
|
|
GDevPtr *devSections;
|
|
|
|
Bool foundScreen = FALSE;
|
2013-11-15 05:26:36 +01:00
|
|
|
const char *dev;
|
2011-09-29 15:13:58 +02:00
|
|
|
ScrnInfoPtr scrn = NULL;
|
2011-09-29 13:28:59 +02:00
|
|
|
|
|
|
|
/* For now, just bail out for PROBE_DETECT. */
|
|
|
|
if (flags & PROBE_DETECT)
|
2014-10-08 09:39:15 +02:00
|
|
|
return FALSE;
|
2008-05-28 16:55:36 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Find the config file Device sections that match this
|
|
|
|
* driver, and return if there are none.
|
|
|
|
*/
|
|
|
|
if ((numDevSections = xf86MatchDevice("modesetting", &devSections)) <= 0) {
|
2014-10-08 09:39:15 +02:00
|
|
|
return FALSE;
|
2008-05-28 16:55:36 +02:00
|
|
|
}
|
|
|
|
|
2011-09-29 13:28:59 +02:00
|
|
|
for (i = 0; i < numDevSections; i++) {
|
2008-05-28 14:33:07 +02:00
|
|
|
|
2014-10-08 09:39:15 +02:00
|
|
|
dev = xf86FindOptionValue(devSections[i]->options, "kmsdev");
|
|
|
|
if (probe_hw(dev, NULL)) {
|
|
|
|
int entity;
|
|
|
|
|
|
|
|
entity = xf86ClaimFbSlot(drv, 0, devSections[i], TRUE);
|
|
|
|
scrn = xf86ConfigFbEntity(scrn, 0, entity, NULL, NULL, NULL, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (scrn) {
|
|
|
|
foundScreen = TRUE;
|
2014-08-27 01:59:37 +02:00
|
|
|
ms_setup_scrn_hooks(scrn);
|
2014-10-08 09:39:15 +02:00
|
|
|
scrn->Probe = Probe;
|
|
|
|
|
|
|
|
xf86DrvMsg(scrn->scrnIndex, X_INFO,
|
|
|
|
"using %s\n", dev ? dev : "default device");
|
|
|
|
}
|
2008-05-28 16:55:36 +02:00
|
|
|
}
|
2008-05-28 14:33:07 +02:00
|
|
|
|
2011-09-29 12:49:26 +02:00
|
|
|
free(devSections);
|
2008-05-28 14:33:07 +02:00
|
|
|
|
2008-05-28 16:55:36 +02:00
|
|
|
return foundScreen;
|
2008-05-28 14:33:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static Bool
|
|
|
|
GetRec(ScrnInfoPtr pScrn)
|
|
|
|
{
|
2008-05-28 16:55:36 +02:00
|
|
|
if (pScrn->driverPrivate)
|
2014-10-08 09:39:15 +02:00
|
|
|
return TRUE;
|
2008-05-28 14:33:07 +02:00
|
|
|
|
2008-05-28 16:55:36 +02:00
|
|
|
pScrn->driverPrivate = xnfcalloc(sizeof(modesettingRec), 1);
|
2008-05-28 14:33:07 +02:00
|
|
|
|
2008-05-28 16:55:36 +02:00
|
|
|
return TRUE;
|
2008-05-28 14:33:07 +02:00
|
|
|
}
|
|
|
|
|
2014-10-08 09:39:15 +02:00
|
|
|
static int
|
|
|
|
dispatch_dirty_region(ScrnInfoPtr scrn,
|
|
|
|
PixmapPtr pixmap, DamagePtr damage, int fb_id)
|
2011-09-29 13:38:26 +02:00
|
|
|
{
|
|
|
|
modesettingPtr ms = modesettingPTR(scrn);
|
2012-07-19 06:12:59 +02:00
|
|
|
RegionPtr dirty = DamageRegion(damage);
|
2011-09-29 13:38:26 +02:00
|
|
|
unsigned num_cliprects = REGION_NUM_RECTS(dirty);
|
2014-12-20 04:34:34 +01:00
|
|
|
int ret = 0;
|
2011-09-29 13:38:26 +02:00
|
|
|
|
|
|
|
if (num_cliprects) {
|
2014-10-08 09:39:15 +02:00
|
|
|
drmModeClip *clip = malloc(num_cliprects * sizeof(drmModeClip));
|
|
|
|
BoxPtr rect = REGION_RECTS(dirty);
|
2014-12-20 04:34:34 +01:00
|
|
|
int i;
|
2014-10-08 09:39:15 +02:00
|
|
|
|
|
|
|
if (!clip)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
/* XXX no need for copy? */
|
|
|
|
for (i = 0; i < num_cliprects; i++, rect++) {
|
|
|
|
clip[i].x1 = rect->x1;
|
|
|
|
clip[i].y1 = rect->y1;
|
|
|
|
clip[i].x2 = rect->x2;
|
|
|
|
clip[i].y2 = rect->y2;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* TODO query connector property to see if this is needed */
|
|
|
|
ret = drmModeDirtyFB(ms->fd, fb_id, clip, num_cliprects);
|
|
|
|
free(clip);
|
|
|
|
DamageEmpty(damage);
|
2012-07-19 06:12:59 +02:00
|
|
|
}
|
2014-12-20 04:34:34 +01:00
|
|
|
return ret;
|
2012-07-19 06:12:59 +02:00
|
|
|
}
|
|
|
|
|
2014-10-08 09:39:15 +02:00
|
|
|
static void
|
|
|
|
dispatch_dirty(ScreenPtr pScreen)
|
2012-07-19 06:12:59 +02:00
|
|
|
{
|
|
|
|
ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
|
|
|
|
modesettingPtr ms = modesettingPTR(scrn);
|
|
|
|
PixmapPtr pixmap = pScreen->GetScreenPixmap(pScreen);
|
|
|
|
int fb_id = ms->drmmode.fb_id;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = dispatch_dirty_region(scrn, pixmap, ms->damage, fb_id);
|
|
|
|
if (ret == -EINVAL || ret == -ENOSYS) {
|
2014-10-08 09:39:15 +02:00
|
|
|
ms->dirty_enabled = FALSE;
|
|
|
|
DamageUnregister(ms->damage);
|
|
|
|
DamageDestroy(ms->damage);
|
|
|
|
ms->damage = NULL;
|
|
|
|
xf86DrvMsg(scrn->scrnIndex, X_INFO,
|
|
|
|
"Disabling kernel dirty updates, not required.\n");
|
|
|
|
return;
|
2012-07-19 06:12:59 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-08 09:39:15 +02:00
|
|
|
static void
|
|
|
|
dispatch_dirty_crtc(ScrnInfoPtr scrn, xf86CrtcPtr crtc)
|
2012-07-19 06:12:59 +02:00
|
|
|
{
|
|
|
|
modesettingPtr ms = modesettingPTR(scrn);
|
|
|
|
PixmapPtr pixmap = crtc->randr_crtc->scanout_pixmap;
|
|
|
|
msPixmapPrivPtr ppriv = msGetPixmapPriv(&ms->drmmode, pixmap);
|
|
|
|
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
|
|
|
DamagePtr damage = drmmode_crtc->slave_damage;
|
|
|
|
int fb_id = ppriv->fb_id;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = dispatch_dirty_region(scrn, pixmap, damage, fb_id);
|
|
|
|
if (ret) {
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-08 09:39:15 +02:00
|
|
|
static void
|
|
|
|
dispatch_slave_dirty(ScreenPtr pScreen)
|
2012-07-19 06:12:59 +02:00
|
|
|
{
|
|
|
|
ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
|
|
|
|
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
|
|
|
|
int c;
|
|
|
|
|
|
|
|
for (c = 0; c < xf86_config->num_crtc; c++) {
|
2014-10-08 09:39:15 +02:00
|
|
|
xf86CrtcPtr crtc = xf86_config->crtc[c];
|
2012-07-19 06:12:59 +02:00
|
|
|
|
2014-10-08 09:39:15 +02:00
|
|
|
if (!crtc->randr_crtc)
|
|
|
|
continue;
|
|
|
|
if (!crtc->randr_crtc->scanout_pixmap)
|
|
|
|
continue;
|
2012-07-19 06:12:59 +02:00
|
|
|
|
2014-10-08 09:39:15 +02:00
|
|
|
dispatch_dirty_crtc(scrn, crtc);
|
2011-09-29 13:38:26 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-08 09:39:15 +02:00
|
|
|
static void
|
|
|
|
msBlockHandler(ScreenPtr pScreen, void *pTimeout, void *pReadmask)
|
2011-09-29 13:38:26 +02:00
|
|
|
{
|
2012-05-23 12:21:55 +02:00
|
|
|
modesettingPtr ms = modesettingPTR(xf86ScreenToScrn(pScreen));
|
2011-09-29 13:38:26 +02:00
|
|
|
|
|
|
|
pScreen->BlockHandler = ms->BlockHandler;
|
2014-08-26 20:37:46 +02:00
|
|
|
pScreen->BlockHandler(pScreen, pTimeout, pReadmask);
|
2015-01-23 07:28:34 +01:00
|
|
|
ms->BlockHandler = pScreen->BlockHandler;
|
2011-09-29 13:38:26 +02:00
|
|
|
pScreen->BlockHandler = msBlockHandler;
|
2012-07-19 06:12:59 +02:00
|
|
|
if (pScreen->isGPU)
|
|
|
|
dispatch_slave_dirty(pScreen);
|
2014-08-26 20:21:24 +02:00
|
|
|
else if (ms->dirty_enabled)
|
2012-07-19 06:12:59 +02:00
|
|
|
dispatch_dirty(pScreen);
|
2011-09-29 13:38:26 +02:00
|
|
|
}
|
|
|
|
|
2008-05-28 14:33:07 +02:00
|
|
|
static void
|
|
|
|
FreeRec(ScrnInfoPtr pScrn)
|
|
|
|
{
|
2013-03-26 15:19:33 +01:00
|
|
|
modesettingPtr ms;
|
|
|
|
|
2008-05-28 16:55:36 +02:00
|
|
|
if (!pScrn)
|
2013-03-26 15:19:33 +01:00
|
|
|
return;
|
2008-05-28 14:33:07 +02:00
|
|
|
|
2013-03-26 15:19:33 +01:00
|
|
|
ms = modesettingPTR(pScrn);
|
|
|
|
if (!ms)
|
|
|
|
return;
|
|
|
|
pScrn->driverPrivate = NULL;
|
2008-05-28 14:33:07 +02:00
|
|
|
|
2013-03-26 15:19:33 +01:00
|
|
|
if (ms->fd > 0) {
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (ms->pEnt->location.type == BUS_PCI)
|
|
|
|
ret = drmClose(ms->fd);
|
|
|
|
else
|
2014-03-18 15:48:22 +01:00
|
|
|
#ifdef XF86_PDEV_SERVER_FD
|
|
|
|
if (!(ms->pEnt->location.type == BUS_PLATFORM &&
|
2014-10-08 09:39:15 +02:00
|
|
|
(ms->pEnt->location.id.plat->flags & XF86_PDEV_SERVER_FD)))
|
2014-03-18 15:48:22 +01:00
|
|
|
#endif
|
2013-03-26 15:19:33 +01:00
|
|
|
ret = close(ms->fd);
|
2013-11-15 05:26:36 +01:00
|
|
|
(void) ret;
|
2013-03-26 15:19:33 +01:00
|
|
|
}
|
|
|
|
free(ms->Options);
|
|
|
|
free(ms);
|
2008-05-28 14:33:07 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2013-12-28 20:32:10 +01:00
|
|
|
static void
|
|
|
|
try_enable_glamor(ScrnInfoPtr pScrn)
|
|
|
|
{
|
|
|
|
modesettingPtr ms = modesettingPTR(pScrn);
|
|
|
|
const char *accel_method_str = xf86GetOptValString(ms->Options,
|
|
|
|
OPTION_ACCEL_METHOD);
|
|
|
|
Bool do_glamor = (!accel_method_str ||
|
|
|
|
strcmp(accel_method_str, "glamor") == 0);
|
|
|
|
|
2014-11-28 11:20:47 +01:00
|
|
|
ms->drmmode.glamor = FALSE;
|
2013-12-28 20:32:10 +01:00
|
|
|
|
|
|
|
#ifdef GLAMOR
|
|
|
|
if (!do_glamor) {
|
|
|
|
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "glamor disabled\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (xf86LoadSubModule(pScrn, GLAMOR_EGL_MODULE_NAME)) {
|
|
|
|
if (glamor_egl_init(pScrn, ms->fd)) {
|
|
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "glamor initialized\n");
|
2014-11-28 11:20:47 +01:00
|
|
|
ms->drmmode.glamor = TRUE;
|
2013-12-28 20:32:10 +01:00
|
|
|
} else {
|
|
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
|
|
|
"glamor initialization failed\n");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
|
|
|
"Failed to load glamor module.\n");
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
if (do_glamor) {
|
|
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
|
|
|
"No glamor support in the X Server\n");
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2014-02-12 19:06:51 +01:00
|
|
|
#ifndef DRM_CAP_CURSOR_WIDTH
|
|
|
|
#define DRM_CAP_CURSOR_WIDTH 0x8
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef DRM_CAP_CURSOR_HEIGHT
|
|
|
|
#define DRM_CAP_CURSOR_HEIGHT 0x9
|
|
|
|
#endif
|
|
|
|
|
2008-05-28 14:33:07 +02:00
|
|
|
static Bool
|
|
|
|
PreInit(ScrnInfoPtr pScrn, int flags)
|
|
|
|
{
|
2008-05-28 16:55:36 +02:00
|
|
|
modesettingPtr ms;
|
|
|
|
rgb defaultWeight = { 0, 0, 0 };
|
|
|
|
EntityInfoPtr pEnt;
|
|
|
|
EntPtr msEnt = NULL;
|
2013-11-15 05:26:36 +01:00
|
|
|
char *BusID = NULL;
|
|
|
|
const char *devicename;
|
2012-02-16 20:41:40 +01:00
|
|
|
uint64_t value = 0;
|
|
|
|
int ret;
|
2012-05-01 18:12:29 +02:00
|
|
|
int bppflags;
|
|
|
|
int defaultdepth, defaultbpp;
|
2008-05-28 16:55:36 +02:00
|
|
|
|
|
|
|
if (pScrn->numEntities != 1)
|
2014-10-08 09:39:15 +02:00
|
|
|
return FALSE;
|
2008-05-28 16:55:36 +02:00
|
|
|
|
|
|
|
pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
|
|
|
|
|
|
|
|
if (flags & PROBE_DETECT) {
|
2014-10-08 09:39:15 +02:00
|
|
|
return FALSE;
|
2008-05-28 16:55:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Allocate driverPrivate */
|
|
|
|
if (!GetRec(pScrn))
|
2014-10-08 09:39:15 +02:00
|
|
|
return FALSE;
|
2008-05-28 16:55:36 +02:00
|
|
|
|
|
|
|
ms = modesettingPTR(pScrn);
|
|
|
|
ms->SaveGeneration = -1;
|
|
|
|
ms->pEnt = pEnt;
|
|
|
|
|
2014-10-08 09:39:15 +02:00
|
|
|
pScrn->displayWidth = 640; /* default it */
|
2008-05-28 16:55:36 +02:00
|
|
|
|
|
|
|
/* Allocate an entity private if necessary */
|
|
|
|
if (xf86IsEntityShared(pScrn->entityList[0])) {
|
2014-10-08 09:39:15 +02:00
|
|
|
msEnt = xf86GetEntityPrivate(pScrn->entityList[0],
|
|
|
|
modesettingEntityIndex)->ptr;
|
|
|
|
ms->entityPrivate = msEnt;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ms->entityPrivate = NULL;
|
2008-05-28 16:55:36 +02:00
|
|
|
|
|
|
|
if (xf86IsEntityShared(pScrn->entityList[0])) {
|
2014-10-08 09:39:15 +02:00
|
|
|
if (xf86IsPrimInitDone(pScrn->entityList[0])) {
|
|
|
|
/* do something */
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
xf86SetPrimInitDone(pScrn->entityList[0]);
|
|
|
|
}
|
2008-05-28 16:55:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
pScrn->monitor = pScrn->confScreen->monitor;
|
|
|
|
pScrn->progClock = TRUE;
|
|
|
|
pScrn->rgbBits = 8;
|
|
|
|
|
2012-06-05 15:43:21 +02:00
|
|
|
#if XSERVER_PLATFORM_BUS
|
|
|
|
if (pEnt->location.type == BUS_PLATFORM) {
|
2014-03-18 15:48:22 +01:00
|
|
|
#ifdef XF86_PDEV_SERVER_FD
|
|
|
|
if (pEnt->location.id.plat->flags & XF86_PDEV_SERVER_FD)
|
2014-10-08 09:39:15 +02:00
|
|
|
ms->fd =
|
|
|
|
xf86_platform_device_odev_attributes(pEnt->location.id.plat)->
|
|
|
|
fd;
|
2014-03-18 15:48:22 +01:00
|
|
|
else
|
|
|
|
#endif
|
|
|
|
{
|
2014-10-08 09:39:15 +02:00
|
|
|
char *path =
|
|
|
|
xf86_platform_device_odev_attributes(pEnt->location.id.plat)->
|
|
|
|
path;
|
2014-03-18 15:48:22 +01:00
|
|
|
ms->fd = open_hw(path);
|
|
|
|
}
|
2012-06-05 15:43:21 +02:00
|
|
|
}
|
2014-10-08 09:39:15 +02:00
|
|
|
else
|
2012-06-05 15:43:21 +02:00
|
|
|
#endif
|
|
|
|
if (pEnt->location.type == BUS_PCI) {
|
|
|
|
ms->PciInfo = xf86GetPciInfoForEntity(ms->pEnt->index);
|
|
|
|
if (ms->PciInfo) {
|
|
|
|
BusID = malloc(64);
|
|
|
|
sprintf(BusID, "PCI:%d:%d:%d",
|
2012-05-01 17:52:18 +02:00
|
|
|
#if XSERVER_LIBPCIACCESS
|
2012-06-05 15:43:21 +02:00
|
|
|
((ms->PciInfo->domain << 8) | ms->PciInfo->bus),
|
|
|
|
ms->PciInfo->dev, ms->PciInfo->func
|
2012-05-01 17:52:18 +02:00
|
|
|
#else
|
2012-06-05 15:43:21 +02:00
|
|
|
((pciConfigPtr) ms->PciInfo->thisCard)->busnum,
|
|
|
|
((pciConfigPtr) ms->PciInfo->thisCard)->devnum,
|
|
|
|
((pciConfigPtr) ms->PciInfo->thisCard)->funcnum
|
2012-05-01 17:52:18 +02:00
|
|
|
#endif
|
2012-06-05 15:43:21 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
ms->fd = drmOpen(NULL, BusID);
|
2014-10-08 09:39:15 +02:00
|
|
|
}
|
|
|
|
else {
|
2012-06-05 15:43:21 +02:00
|
|
|
devicename = xf86FindOptionValue(ms->pEnt->device->options, "kmsdev");
|
|
|
|
ms->fd = open_hw(devicename);
|
2012-05-01 17:52:18 +02:00
|
|
|
}
|
|
|
|
if (ms->fd < 0)
|
2014-10-08 09:39:15 +02:00
|
|
|
return FALSE;
|
2012-05-01 17:52:18 +02:00
|
|
|
|
2012-05-01 18:12:29 +02:00
|
|
|
ms->drmmode.fd = ms->fd;
|
|
|
|
|
2012-07-19 06:12:59 +02:00
|
|
|
pScrn->capabilities = 0;
|
|
|
|
#ifdef DRM_CAP_PRIME
|
|
|
|
ret = drmGetCap(ms->fd, DRM_CAP_PRIME, &value);
|
|
|
|
if (ret == 0) {
|
|
|
|
if (value & DRM_PRIME_CAP_IMPORT)
|
|
|
|
pScrn->capabilities |= RR_Capability_SinkOutput;
|
|
|
|
}
|
|
|
|
#endif
|
2012-05-01 18:12:29 +02:00
|
|
|
drmmode_get_default_bpp(pScrn, &ms->drmmode, &defaultdepth, &defaultbpp);
|
|
|
|
if (defaultdepth == 24 && defaultbpp == 24)
|
2014-10-08 09:39:15 +02:00
|
|
|
bppflags = SupportConvert32to24 | Support24bppFb;
|
2012-05-01 18:12:29 +02:00
|
|
|
else
|
2014-10-08 09:39:15 +02:00
|
|
|
bppflags = PreferConvert24to32 | SupportConvert24to32 | Support32bppFb;
|
|
|
|
|
2008-06-26 23:27:44 +02:00
|
|
|
if (!xf86SetDepthBpp
|
2014-10-08 09:39:15 +02:00
|
|
|
(pScrn, defaultdepth, defaultdepth, defaultbpp, bppflags))
|
|
|
|
return FALSE;
|
2008-05-28 16:55:36 +02:00
|
|
|
|
|
|
|
switch (pScrn->depth) {
|
|
|
|
case 15:
|
|
|
|
case 16:
|
|
|
|
case 24:
|
2014-10-08 09:39:15 +02:00
|
|
|
break;
|
2008-05-28 16:55:36 +02:00
|
|
|
default:
|
2014-10-08 09:39:15 +02:00
|
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
|
|
|
"Given depth (%d) is not supported by the driver\n",
|
|
|
|
pScrn->depth);
|
|
|
|
return FALSE;
|
2008-05-28 16:55:36 +02:00
|
|
|
}
|
|
|
|
xf86PrintDepthBpp(pScrn);
|
|
|
|
|
|
|
|
/* Process the options */
|
|
|
|
xf86CollectOptions(pScrn, NULL);
|
2011-09-29 12:49:26 +02:00
|
|
|
if (!(ms->Options = malloc(sizeof(Options))))
|
2014-10-08 09:39:15 +02:00
|
|
|
return FALSE;
|
2008-05-28 16:55:36 +02:00
|
|
|
memcpy(ms->Options, Options, sizeof(Options));
|
|
|
|
xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, ms->Options);
|
|
|
|
|
2011-10-05 16:12:43 +02:00
|
|
|
if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight))
|
2014-10-08 09:39:15 +02:00
|
|
|
return FALSE;
|
2011-10-05 16:12:43 +02:00
|
|
|
if (!xf86SetDefaultVisual(pScrn, -1))
|
2014-10-08 09:39:15 +02:00
|
|
|
return FALSE;
|
2011-10-05 16:12:43 +02:00
|
|
|
|
2008-05-28 16:55:36 +02:00
|
|
|
if (xf86ReturnOptValBool(ms->Options, OPTION_SW_CURSOR, FALSE)) {
|
2014-10-08 09:39:15 +02:00
|
|
|
ms->drmmode.sw_cursor = TRUE;
|
2008-05-28 16:55:36 +02:00
|
|
|
}
|
|
|
|
|
2014-02-12 19:06:51 +01:00
|
|
|
ms->cursor_width = 64;
|
|
|
|
ms->cursor_height = 64;
|
|
|
|
ret = drmGetCap(ms->fd, DRM_CAP_CURSOR_WIDTH, &value);
|
|
|
|
if (!ret) {
|
2014-10-08 09:39:15 +02:00
|
|
|
ms->cursor_width = value;
|
2014-02-12 19:06:51 +01:00
|
|
|
}
|
|
|
|
ret = drmGetCap(ms->fd, DRM_CAP_CURSOR_HEIGHT, &value);
|
|
|
|
if (!ret) {
|
2014-10-08 09:39:15 +02:00
|
|
|
ms->cursor_height = value;
|
2014-02-12 19:06:51 +01:00
|
|
|
}
|
|
|
|
|
2013-12-28 20:32:10 +01:00
|
|
|
try_enable_glamor(pScrn);
|
|
|
|
|
2014-11-28 11:20:47 +01:00
|
|
|
if (ms->drmmode.glamor) {
|
modesetting: Add support for DRI2 with glamor.
This is derived from the intel driver DRI2 code, with swapchain and
pageflipping dropped, functions renamed, and vblank event management
shared code moved to a vblank.c for reuse by Present.
This allows AIGLX to load, which means that you get appropriate
visuals exposed in GL, along with many extensions under
direct-rendering that require presence in GLX (which aren't supported
in glxdriswrast.c).
v2: Drop unused header includes in pageflip.c, wrap in #ifdef GLAMOR.
Drop triple-buffering, which was totally broken in practice (I'll
try to fix this later). Fix up some style nits. Document the
general flow of pageflipping and why, rename the DRI2 frame event
type enums to reflect what they're for, and handle them in a
single switch statement so you can understand the state machine
more easily.
v3: Drop pageflipping entirely -- it's unstable on my Intel laptop
(not that the normal 2D driver is stable with pageflipping for
me), and I won't get it fixed before the merge window. It now
passes all of the OML_sync_control tests from Jamey and Theo
(except for occasional warns in timing -fullscreen -divisor 2).
v4: Fix doxygen at the top of vblank.c
Signed-off-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Adam Jackson <ajax@redhat.com>
2013-12-31 02:23:38 +01:00
|
|
|
xf86LoadSubModule(pScrn, "dri2");
|
|
|
|
} else {
|
2013-12-28 20:32:10 +01:00
|
|
|
Bool prefer_shadow = TRUE;
|
|
|
|
|
|
|
|
ret = drmGetCap(ms->fd, DRM_CAP_DUMB_PREFER_SHADOW, &value);
|
|
|
|
if (!ret) {
|
|
|
|
prefer_shadow = !!value;
|
|
|
|
}
|
|
|
|
|
|
|
|
ms->drmmode.shadow_enable = xf86ReturnOptValBool(ms->Options,
|
|
|
|
OPTION_SHADOW_FB,
|
|
|
|
prefer_shadow);
|
|
|
|
|
|
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
|
|
|
"ShadowFB: preferred %s, enabled %s\n",
|
|
|
|
prefer_shadow ? "YES" : "NO",
|
|
|
|
ms->drmmode.shadow_enable ? "YES" : "NO");
|
|
|
|
}
|
2011-09-29 16:55:36 +02:00
|
|
|
|
2011-09-29 12:49:26 +02:00
|
|
|
if (drmmode_pre_init(pScrn, &ms->drmmode, pScrn->bitsPerPixel / 8) == FALSE) {
|
2014-10-08 09:39:15 +02:00
|
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "KMS setup failed\n");
|
|
|
|
goto fail;
|
2008-05-28 16:55:36 +02:00
|
|
|
}
|
2008-05-28 14:33:07 +02:00
|
|
|
|
2008-05-28 16:55:36 +02:00
|
|
|
/*
|
|
|
|
* If the driver can do gamma correction, it should call xf86SetGamma() here.
|
|
|
|
*/
|
|
|
|
{
|
2014-10-08 09:39:15 +02:00
|
|
|
Gamma zeros = { 0.0, 0.0, 0.0 };
|
2008-05-28 14:33:07 +02:00
|
|
|
|
2014-10-08 09:39:15 +02:00
|
|
|
if (!xf86SetGamma(pScrn, zeros)) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
2008-05-28 16:55:36 +02:00
|
|
|
}
|
2008-05-28 14:33:07 +02:00
|
|
|
|
2008-05-28 16:55:36 +02:00
|
|
|
if (pScrn->modes == NULL) {
|
2014-10-08 09:39:15 +02:00
|
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n");
|
|
|
|
return FALSE;
|
2008-05-28 16:55:36 +02:00
|
|
|
}
|
2008-05-28 14:33:07 +02:00
|
|
|
|
2008-05-28 16:55:36 +02:00
|
|
|
pScrn->currentMode = pScrn->modes;
|
2008-05-28 14:33:07 +02:00
|
|
|
|
2008-05-28 16:55:36 +02:00
|
|
|
/* Set display resolution */
|
|
|
|
xf86SetDpi(pScrn, 0, 0);
|
2008-05-28 14:33:07 +02:00
|
|
|
|
2008-05-28 16:55:36 +02:00
|
|
|
/* Load the required sub modules */
|
|
|
|
if (!xf86LoadSubModule(pScrn, "fb")) {
|
2014-10-08 09:39:15 +02:00
|
|
|
return FALSE;
|
2008-05-28 16:55:36 +02:00
|
|
|
}
|
2008-05-28 14:33:07 +02:00
|
|
|
|
2012-02-20 12:00:56 +01:00
|
|
|
if (ms->drmmode.shadow_enable) {
|
2014-10-08 09:39:15 +02:00
|
|
|
if (!xf86LoadSubModule(pScrn, "shadow")) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
2011-09-29 16:55:36 +02:00
|
|
|
}
|
|
|
|
|
2008-05-28 16:55:36 +02:00
|
|
|
return TRUE;
|
2014-10-08 09:39:15 +02:00
|
|
|
fail:
|
2011-09-29 12:49:26 +02:00
|
|
|
return FALSE;
|
2008-05-28 14:33:07 +02:00
|
|
|
}
|
|
|
|
|
2011-09-29 16:55:36 +02:00
|
|
|
static void *
|
|
|
|
msShadowWindow(ScreenPtr screen, CARD32 row, CARD32 offset, int mode,
|
2014-10-08 09:39:15 +02:00
|
|
|
CARD32 *size, void *closure)
|
2011-09-29 16:55:36 +02:00
|
|
|
{
|
2012-05-23 12:21:55 +02:00
|
|
|
ScrnInfoPtr pScrn = xf86ScreenToScrn(screen);
|
2011-09-29 16:55:36 +02:00
|
|
|
modesettingPtr ms = modesettingPTR(pScrn);
|
|
|
|
int stride;
|
|
|
|
|
|
|
|
stride = (pScrn->displayWidth * pScrn->bitsPerPixel) / 8;
|
|
|
|
*size = stride;
|
|
|
|
|
2014-12-10 00:20:44 +01:00
|
|
|
return ((uint8_t *) ms->drmmode.front_bo.dumb->ptr + row * stride + offset);
|
2011-09-29 16:55:36 +02:00
|
|
|
}
|
|
|
|
|
2014-05-21 16:16:39 +02:00
|
|
|
static void
|
|
|
|
msUpdatePacked(ScreenPtr pScreen, shadowBufPtr pBuf)
|
|
|
|
{
|
|
|
|
shadowUpdatePacked(pScreen, pBuf);
|
|
|
|
}
|
|
|
|
|
2008-05-28 14:33:07 +02:00
|
|
|
static Bool
|
|
|
|
CreateScreenResources(ScreenPtr pScreen)
|
|
|
|
{
|
2012-05-23 12:21:55 +02:00
|
|
|
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
|
2008-05-28 16:55:36 +02:00
|
|
|
modesettingPtr ms = modesettingPTR(pScrn);
|
2008-06-26 23:27:44 +02:00
|
|
|
PixmapPtr rootPixmap;
|
2008-05-28 16:55:36 +02:00
|
|
|
Bool ret;
|
2014-12-09 21:43:57 +01:00
|
|
|
void *pixels = NULL;
|
2014-12-20 03:40:19 +01:00
|
|
|
int err;
|
2014-10-08 09:39:15 +02:00
|
|
|
|
2008-05-28 16:55:36 +02:00
|
|
|
pScreen->CreateScreenResources = ms->createScreenResources;
|
|
|
|
ret = pScreen->CreateScreenResources(pScreen);
|
|
|
|
pScreen->CreateScreenResources = CreateScreenResources;
|
2008-05-28 14:33:07 +02:00
|
|
|
|
2011-09-29 12:49:26 +02:00
|
|
|
if (!drmmode_set_desired_modes(pScrn, &ms->drmmode))
|
2014-10-08 09:39:15 +02:00
|
|
|
return FALSE;
|
2008-05-28 14:33:07 +02:00
|
|
|
|
2014-12-10 00:18:39 +01:00
|
|
|
if (!drmmode_glamor_handle_new_screen_pixmap(&ms->drmmode))
|
|
|
|
return FALSE;
|
2013-12-28 20:32:10 +01:00
|
|
|
|
2011-09-29 12:49:26 +02:00
|
|
|
drmmode_uevent_init(pScrn, &ms->drmmode);
|
2008-06-16 16:07:39 +02:00
|
|
|
|
2014-02-25 15:06:55 +01:00
|
|
|
if (!ms->drmmode.sw_cursor)
|
2011-11-03 14:20:18 +01:00
|
|
|
drmmode_map_cursor_bos(pScrn, &ms->drmmode);
|
2014-12-09 21:43:57 +01:00
|
|
|
|
|
|
|
if (!ms->drmmode.gbm) {
|
|
|
|
pixels = drmmode_map_front_bo(&ms->drmmode);
|
|
|
|
if (!pixels)
|
|
|
|
return FALSE;
|
|
|
|
}
|
2008-06-26 23:27:44 +02:00
|
|
|
|
2011-09-29 12:49:26 +02:00
|
|
|
rootPixmap = pScreen->GetScreenPixmap(pScreen);
|
2011-09-29 16:55:36 +02:00
|
|
|
|
2012-02-20 12:00:56 +01:00
|
|
|
if (ms->drmmode.shadow_enable)
|
2014-10-08 09:39:15 +02:00
|
|
|
pixels = ms->drmmode.shadow_fb;
|
|
|
|
|
2011-09-29 12:49:26 +02:00
|
|
|
if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, pixels))
|
2014-10-08 09:39:15 +02:00
|
|
|
FatalError("Couldn't adjust screen pixmap\n");
|
2008-06-16 16:07:39 +02:00
|
|
|
|
2012-02-20 12:00:56 +01:00
|
|
|
if (ms->drmmode.shadow_enable) {
|
2014-10-08 09:39:15 +02:00
|
|
|
if (!shadowAdd(pScreen, rootPixmap, msUpdatePacked,
|
|
|
|
msShadowWindow, 0, 0))
|
|
|
|
return FALSE;
|
2011-09-29 16:55:36 +02:00
|
|
|
}
|
|
|
|
|
2014-12-20 03:40:19 +01:00
|
|
|
err = drmModeDirtyFB(ms->fd, ms->drmmode.fb_id, NULL, 0);
|
2011-09-29 13:38:26 +02:00
|
|
|
|
2014-12-20 03:40:19 +01:00
|
|
|
if (err != -EINVAL && err != -ENOSYS) {
|
|
|
|
ms->damage = DamageCreate(NULL, NULL, DamageReportNone, TRUE,
|
|
|
|
pScreen, rootPixmap);
|
|
|
|
|
|
|
|
if (ms->damage) {
|
|
|
|
DamageRegister(&rootPixmap->drawable, ms->damage);
|
|
|
|
ms->dirty_enabled = TRUE;
|
|
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Damage tracking initialized\n");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
|
|
|
"Failed to create screen damage record\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
2011-09-29 13:38:26 +02:00
|
|
|
}
|
2008-05-28 16:55:36 +02:00
|
|
|
return ret;
|
2008-05-28 14:33:07 +02:00
|
|
|
}
|
|
|
|
|
2011-09-29 16:55:36 +02:00
|
|
|
static Bool
|
|
|
|
msShadowInit(ScreenPtr pScreen)
|
|
|
|
{
|
|
|
|
if (!shadowSetup(pScreen)) {
|
2014-10-08 09:39:15 +02:00
|
|
|
return FALSE;
|
2011-09-29 16:55:36 +02:00
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2012-07-19 06:12:59 +02:00
|
|
|
static Bool
|
|
|
|
msSetSharedPixmapBacking(PixmapPtr ppix, void *fd_handle)
|
|
|
|
{
|
|
|
|
ScreenPtr screen = ppix->drawable.pScreen;
|
|
|
|
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
|
|
|
|
modesettingPtr ms = modesettingPTR(scrn);
|
|
|
|
Bool ret;
|
|
|
|
int size = ppix->devKind * ppix->drawable.height;
|
2014-10-08 09:39:15 +02:00
|
|
|
int ihandle = (int) (long) fd_handle;
|
2012-07-19 06:12:59 +02:00
|
|
|
|
|
|
|
ret = drmmode_SetSlaveBO(ppix, &ms->drmmode, ihandle, ppix->devKind, size);
|
|
|
|
if (ret == FALSE)
|
2014-10-08 09:39:15 +02:00
|
|
|
return ret;
|
2012-07-19 06:12:59 +02:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2014-03-18 15:48:22 +01:00
|
|
|
static Bool
|
|
|
|
SetMaster(ScrnInfoPtr pScrn)
|
|
|
|
{
|
|
|
|
modesettingPtr ms = modesettingPTR(pScrn);
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
#ifdef XF86_PDEV_SERVER_FD
|
|
|
|
if (ms->pEnt->location.type == BUS_PLATFORM &&
|
2014-10-08 09:39:15 +02:00
|
|
|
(ms->pEnt->location.id.plat->flags & XF86_PDEV_SERVER_FD))
|
2014-03-18 15:48:22 +01:00
|
|
|
return TRUE;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
ret = drmSetMaster(ms->fd);
|
|
|
|
if (ret)
|
|
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "drmSetMaster failed: %s\n",
|
|
|
|
strerror(errno));
|
|
|
|
|
|
|
|
return ret == 0;
|
|
|
|
}
|
|
|
|
|
2008-05-28 14:33:07 +02:00
|
|
|
static Bool
|
2014-08-26 20:37:46 +02:00
|
|
|
ScreenInit(ScreenPtr pScreen, int argc, char **argv)
|
2008-05-28 14:33:07 +02:00
|
|
|
{
|
2012-05-23 12:21:55 +02:00
|
|
|
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
|
2008-05-28 16:55:36 +02:00
|
|
|
modesettingPtr ms = modesettingPTR(pScrn);
|
|
|
|
VisualPtr visual;
|
|
|
|
|
2008-06-16 16:07:39 +02:00
|
|
|
pScrn->pScreen = pScreen;
|
|
|
|
|
2014-03-18 15:48:22 +01:00
|
|
|
if (!SetMaster(pScrn))
|
2011-09-29 15:05:43 +02:00
|
|
|
return FALSE;
|
2014-03-18 15:48:22 +01:00
|
|
|
|
2014-12-09 21:43:57 +01:00
|
|
|
#ifdef GLAMOR_HAS_GBM
|
|
|
|
if (ms->drmmode.glamor)
|
|
|
|
ms->drmmode.gbm = glamor_egl_get_gbm_device(pScreen);
|
|
|
|
#endif
|
|
|
|
|
2008-06-26 23:27:44 +02:00
|
|
|
/* HW dependent - FIXME */
|
|
|
|
pScrn->displayWidth = pScrn->virtualX;
|
2011-09-29 12:49:26 +02:00
|
|
|
if (!drmmode_create_initial_bos(pScrn, &ms->drmmode))
|
2014-10-08 09:39:15 +02:00
|
|
|
return FALSE;
|
2008-05-28 16:55:36 +02:00
|
|
|
|
2012-02-20 12:00:56 +01:00
|
|
|
if (ms->drmmode.shadow_enable) {
|
2014-10-08 09:39:15 +02:00
|
|
|
ms->drmmode.shadow_fb =
|
|
|
|
calloc(1,
|
|
|
|
pScrn->displayWidth * pScrn->virtualY *
|
|
|
|
((pScrn->bitsPerPixel + 7) >> 3));
|
|
|
|
if (!ms->drmmode.shadow_fb)
|
|
|
|
ms->drmmode.shadow_enable = FALSE;
|
|
|
|
}
|
|
|
|
|
2008-05-28 16:55:36 +02:00
|
|
|
miClearVisualTypes();
|
|
|
|
|
|
|
|
if (!miSetVisualTypes(pScrn->depth,
|
2014-10-08 09:39:15 +02:00
|
|
|
miGetDefaultVisualMask(pScrn->depth),
|
|
|
|
pScrn->rgbBits, pScrn->defaultVisual))
|
|
|
|
return FALSE;
|
2008-05-28 16:55:36 +02:00
|
|
|
|
|
|
|
if (!miSetPixmapDepths())
|
2014-10-08 09:39:15 +02:00
|
|
|
return FALSE;
|
2008-05-28 16:55:36 +02:00
|
|
|
|
2014-10-08 09:39:15 +02:00
|
|
|
if (!dixRegisterScreenSpecificPrivateKey
|
|
|
|
(pScreen, &ms->drmmode.pixmapPrivateKeyRec, PRIVATE_PIXMAP,
|
|
|
|
sizeof(msPixmapPrivRec))) {
|
|
|
|
return FALSE;
|
2012-07-19 06:12:59 +02:00
|
|
|
}
|
|
|
|
|
2008-05-28 16:55:36 +02:00
|
|
|
pScrn->memPhysBase = 0;
|
|
|
|
pScrn->fbOffset = 0;
|
|
|
|
|
2008-06-26 23:27:44 +02:00
|
|
|
if (!fbScreenInit(pScreen, NULL,
|
2014-10-08 09:39:15 +02:00
|
|
|
pScrn->virtualX, pScrn->virtualY,
|
|
|
|
pScrn->xDpi, pScrn->yDpi,
|
|
|
|
pScrn->displayWidth, pScrn->bitsPerPixel))
|
|
|
|
return FALSE;
|
2008-05-28 16:55:36 +02:00
|
|
|
|
|
|
|
if (pScrn->bitsPerPixel > 8) {
|
2014-10-08 09:39:15 +02:00
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
}
|
2008-05-28 16:55:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
fbPictureInit(pScreen, NULL, 0);
|
2008-05-28 14:33:07 +02:00
|
|
|
|
2013-12-28 20:32:10 +01:00
|
|
|
#ifdef GLAMOR
|
2014-11-28 11:20:47 +01:00
|
|
|
if (ms->drmmode.glamor) {
|
2014-10-30 04:30:12 +01:00
|
|
|
if (!glamor_init(pScreen, GLAMOR_USE_EGL_SCREEN)) {
|
2013-12-28 20:32:10 +01:00
|
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
|
|
|
"Failed to initialize glamor at ScreenInit() time.\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2012-02-20 12:00:56 +01:00
|
|
|
if (ms->drmmode.shadow_enable && !msShadowInit(pScreen)) {
|
2014-10-08 09:39:15 +02:00
|
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "shadow fb init failed\n");
|
|
|
|
return FALSE;
|
2011-09-29 16:55:36 +02:00
|
|
|
}
|
2014-10-08 09:39:15 +02:00
|
|
|
|
2008-06-16 16:07:39 +02:00
|
|
|
ms->createScreenResources = pScreen->CreateScreenResources;
|
|
|
|
pScreen->CreateScreenResources = CreateScreenResources;
|
|
|
|
|
2008-05-28 16:55:36 +02:00
|
|
|
xf86SetBlackWhitePixels(pScreen);
|
2008-05-28 14:33:07 +02:00
|
|
|
|
2008-05-28 16:55:36 +02:00
|
|
|
xf86SetBackingStore(pScreen);
|
|
|
|
xf86SetSilkenMouse(pScreen);
|
|
|
|
miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
|
2008-05-28 14:33:07 +02:00
|
|
|
|
2008-06-16 16:07:39 +02:00
|
|
|
/* Need to extend HWcursor support to handle mask interleave */
|
2011-11-14 12:22:44 +01:00
|
|
|
if (!ms->drmmode.sw_cursor)
|
2014-10-08 09:39:15 +02:00
|
|
|
xf86_cursors_init(pScreen, ms->cursor_width, ms->cursor_height,
|
|
|
|
HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 |
|
2015-01-05 08:27:32 +01:00
|
|
|
HARDWARE_CURSOR_UPDATE_UNHIDDEN |
|
2014-10-08 09:39:15 +02:00
|
|
|
HARDWARE_CURSOR_ARGB);
|
2008-05-28 20:59:38 +02:00
|
|
|
|
2008-05-28 16:55:36 +02:00
|
|
|
/* 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;
|
2008-05-28 14:33:07 +02:00
|
|
|
|
2008-05-28 16:55:36 +02:00
|
|
|
pScreen->SaveScreen = xf86SaveScreen;
|
|
|
|
ms->CloseScreen = pScreen->CloseScreen;
|
|
|
|
pScreen->CloseScreen = CloseScreen;
|
2008-05-28 14:33:07 +02:00
|
|
|
|
2011-09-29 13:38:26 +02:00
|
|
|
ms->BlockHandler = pScreen->BlockHandler;
|
|
|
|
pScreen->BlockHandler = msBlockHandler;
|
|
|
|
|
2012-07-19 06:12:59 +02:00
|
|
|
pScreen->SetSharedPixmapBacking = msSetSharedPixmapBacking;
|
|
|
|
|
2008-05-28 16:55:36 +02:00
|
|
|
if (!xf86CrtcScreenInit(pScreen))
|
2014-10-08 09:39:15 +02:00
|
|
|
return FALSE;
|
2008-05-28 14:33:07 +02:00
|
|
|
|
2008-05-28 16:55:36 +02:00
|
|
|
if (!miCreateDefColormap(pScreen))
|
2014-10-08 09:39:15 +02:00
|
|
|
return FALSE;
|
2008-05-28 14:33:07 +02:00
|
|
|
|
2008-05-28 16:55:36 +02:00
|
|
|
xf86DPMSInit(pScreen, xf86DPMSSet, 0);
|
2008-05-28 14:33:07 +02:00
|
|
|
|
2014-12-14 07:22:30 +01:00
|
|
|
#ifdef GLAMOR
|
|
|
|
if (ms->drmmode.glamor) {
|
|
|
|
XF86VideoAdaptorPtr glamor_adaptor;
|
|
|
|
|
|
|
|
glamor_adaptor = glamor_xv_init(pScreen, 16);
|
|
|
|
if (glamor_adaptor != NULL)
|
|
|
|
xf86XVScreenInit(pScreen, &glamor_adaptor, 1);
|
|
|
|
else
|
|
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
|
|
|
"Failed to initialize XV support.\n");
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2008-05-28 16:55:36 +02:00
|
|
|
if (serverGeneration == 1)
|
2014-10-08 09:39:15 +02:00
|
|
|
xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
|
2008-05-28 14:33:07 +02:00
|
|
|
|
modesetting: Add support for DRI2 with glamor.
This is derived from the intel driver DRI2 code, with swapchain and
pageflipping dropped, functions renamed, and vblank event management
shared code moved to a vblank.c for reuse by Present.
This allows AIGLX to load, which means that you get appropriate
visuals exposed in GL, along with many extensions under
direct-rendering that require presence in GLX (which aren't supported
in glxdriswrast.c).
v2: Drop unused header includes in pageflip.c, wrap in #ifdef GLAMOR.
Drop triple-buffering, which was totally broken in practice (I'll
try to fix this later). Fix up some style nits. Document the
general flow of pageflipping and why, rename the DRI2 frame event
type enums to reflect what they're for, and handle them in a
single switch statement so you can understand the state machine
more easily.
v3: Drop pageflipping entirely -- it's unstable on my Intel laptop
(not that the normal 2D driver is stable with pageflipping for
me), and I won't get it fixed before the merge window. It now
passes all of the OML_sync_control tests from Jamey and Theo
(except for occasional warns in timing -fullscreen -divisor 2).
v4: Fix doxygen at the top of vblank.c
Signed-off-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Adam Jackson <ajax@redhat.com>
2013-12-31 02:23:38 +01:00
|
|
|
if (!ms_vblank_screen_init(pScreen)) {
|
|
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
|
|
|
"Failed to initialize vblank support.\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef GLAMOR
|
2014-11-28 11:20:47 +01:00
|
|
|
if (ms->drmmode.glamor) {
|
modesetting: Add support for DRI2 with glamor.
This is derived from the intel driver DRI2 code, with swapchain and
pageflipping dropped, functions renamed, and vblank event management
shared code moved to a vblank.c for reuse by Present.
This allows AIGLX to load, which means that you get appropriate
visuals exposed in GL, along with many extensions under
direct-rendering that require presence in GLX (which aren't supported
in glxdriswrast.c).
v2: Drop unused header includes in pageflip.c, wrap in #ifdef GLAMOR.
Drop triple-buffering, which was totally broken in practice (I'll
try to fix this later). Fix up some style nits. Document the
general flow of pageflipping and why, rename the DRI2 frame event
type enums to reflect what they're for, and handle them in a
single switch statement so you can understand the state machine
more easily.
v3: Drop pageflipping entirely -- it's unstable on my Intel laptop
(not that the normal 2D driver is stable with pageflipping for
me), and I won't get it fixed before the merge window. It now
passes all of the OML_sync_control tests from Jamey and Theo
(except for occasional warns in timing -fullscreen -divisor 2).
v4: Fix doxygen at the top of vblank.c
Signed-off-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Adam Jackson <ajax@redhat.com>
2013-12-31 02:23:38 +01:00
|
|
|
if (!ms_dri2_screen_init(pScreen)) {
|
|
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
|
|
|
"Failed to initialize the DRI2 extension.\n");
|
|
|
|
}
|
2014-12-11 22:37:14 +01:00
|
|
|
|
|
|
|
if (!ms_present_screen_init(pScreen)) {
|
|
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
|
|
|
"Failed to initialize the Present extension.\n");
|
|
|
|
}
|
modesetting: Add support for DRI2 with glamor.
This is derived from the intel driver DRI2 code, with swapchain and
pageflipping dropped, functions renamed, and vblank event management
shared code moved to a vblank.c for reuse by Present.
This allows AIGLX to load, which means that you get appropriate
visuals exposed in GL, along with many extensions under
direct-rendering that require presence in GLX (which aren't supported
in glxdriswrast.c).
v2: Drop unused header includes in pageflip.c, wrap in #ifdef GLAMOR.
Drop triple-buffering, which was totally broken in practice (I'll
try to fix this later). Fix up some style nits. Document the
general flow of pageflipping and why, rename the DRI2 frame event
type enums to reflect what they're for, and handle them in a
single switch statement so you can understand the state machine
more easily.
v3: Drop pageflipping entirely -- it's unstable on my Intel laptop
(not that the normal 2D driver is stable with pageflipping for
me), and I won't get it fixed before the merge window. It now
passes all of the OML_sync_control tests from Jamey and Theo
(except for occasional warns in timing -fullscreen -divisor 2).
v4: Fix doxygen at the top of vblank.c
Signed-off-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Adam Jackson <ajax@redhat.com>
2013-12-31 02:23:38 +01:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2014-08-26 20:37:46 +02:00
|
|
|
return EnterVT(pScrn);
|
2008-05-28 14:33:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2014-08-26 20:37:46 +02:00
|
|
|
AdjustFrame(ScrnInfoPtr pScrn, int x, int y)
|
2008-05-28 14:33:07 +02:00
|
|
|
{
|
2013-06-11 02:29:25 +02:00
|
|
|
modesettingPtr ms = modesettingPTR(pScrn);
|
2008-05-28 16:55:36 +02:00
|
|
|
|
2013-06-11 02:29:25 +02:00
|
|
|
drmmode_adjust_frame(pScrn, &ms->drmmode, x, y);
|
2008-05-28 14:33:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2014-08-26 20:37:46 +02:00
|
|
|
FreeScreen(ScrnInfoPtr pScrn)
|
2008-05-28 14:33:07 +02:00
|
|
|
{
|
2012-06-01 13:34:42 +02:00
|
|
|
FreeRec(pScrn);
|
2008-05-28 14:33:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2014-08-26 20:37:46 +02:00
|
|
|
LeaveVT(ScrnInfoPtr pScrn)
|
2008-05-28 14:33:07 +02:00
|
|
|
{
|
2012-04-17 12:50:40 +02:00
|
|
|
modesettingPtr ms = modesettingPTR(pScrn);
|
2014-10-08 09:39:15 +02:00
|
|
|
|
2012-04-17 12:48:03 +02:00
|
|
|
xf86_hide_cursors(pScrn);
|
|
|
|
|
2008-06-16 16:07:39 +02:00
|
|
|
pScrn->vtSema = FALSE;
|
2012-04-17 12:50:40 +02:00
|
|
|
|
2014-03-18 15:48:22 +01:00
|
|
|
#ifdef XF86_PDEV_SERVER_FD
|
|
|
|
if (ms->pEnt->location.type == BUS_PLATFORM &&
|
2014-10-08 09:39:15 +02:00
|
|
|
(ms->pEnt->location.id.plat->flags & XF86_PDEV_SERVER_FD))
|
2014-03-18 15:48:22 +01:00
|
|
|
return;
|
|
|
|
#endif
|
|
|
|
|
2012-04-17 12:50:40 +02:00
|
|
|
drmDropMaster(ms->fd);
|
2008-05-28 14:33:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This gets called when gaining control of the VT, and from ScreenInit().
|
|
|
|
*/
|
|
|
|
static Bool
|
2014-08-26 20:37:46 +02:00
|
|
|
EnterVT(ScrnInfoPtr pScrn)
|
2008-05-28 14:33:07 +02:00
|
|
|
{
|
2008-05-28 16:55:36 +02:00
|
|
|
modesettingPtr ms = modesettingPTR(pScrn);
|
2008-05-28 14:33:07 +02:00
|
|
|
|
2011-09-29 15:05:43 +02:00
|
|
|
pScrn->vtSema = TRUE;
|
|
|
|
|
2014-03-18 15:48:22 +01:00
|
|
|
SetMaster(pScrn);
|
2012-04-17 12:50:40 +02:00
|
|
|
|
2011-09-29 15:05:43 +02:00
|
|
|
if (!drmmode_set_desired_modes(pScrn, &ms->drmmode))
|
2014-10-08 09:39:15 +02:00
|
|
|
return FALSE;
|
2008-05-28 14:33:07 +02:00
|
|
|
|
2008-05-28 16:55:36 +02:00
|
|
|
return TRUE;
|
2008-05-28 14:33:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static Bool
|
2014-08-26 20:37:46 +02:00
|
|
|
SwitchMode(ScrnInfoPtr pScrn, DisplayModePtr mode)
|
2008-05-28 14:33:07 +02:00
|
|
|
{
|
2008-05-28 16:55:36 +02:00
|
|
|
return xf86SetSingleMode(pScrn, mode, RR_Rotate_0);
|
2008-05-28 14:33:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static Bool
|
2014-08-26 20:37:46 +02:00
|
|
|
CloseScreen(ScreenPtr pScreen)
|
2008-05-28 14:33:07 +02:00
|
|
|
{
|
2012-06-01 13:34:42 +02:00
|
|
|
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
|
2008-05-28 16:55:36 +02:00
|
|
|
modesettingPtr ms = modesettingPTR(pScrn);
|
2008-05-28 14:33:07 +02:00
|
|
|
|
modesetting: Add support for DRI2 with glamor.
This is derived from the intel driver DRI2 code, with swapchain and
pageflipping dropped, functions renamed, and vblank event management
shared code moved to a vblank.c for reuse by Present.
This allows AIGLX to load, which means that you get appropriate
visuals exposed in GL, along with many extensions under
direct-rendering that require presence in GLX (which aren't supported
in glxdriswrast.c).
v2: Drop unused header includes in pageflip.c, wrap in #ifdef GLAMOR.
Drop triple-buffering, which was totally broken in practice (I'll
try to fix this later). Fix up some style nits. Document the
general flow of pageflipping and why, rename the DRI2 frame event
type enums to reflect what they're for, and handle them in a
single switch statement so you can understand the state machine
more easily.
v3: Drop pageflipping entirely -- it's unstable on my Intel laptop
(not that the normal 2D driver is stable with pageflipping for
me), and I won't get it fixed before the merge window. It now
passes all of the OML_sync_control tests from Jamey and Theo
(except for occasional warns in timing -fullscreen -divisor 2).
v4: Fix doxygen at the top of vblank.c
Signed-off-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Adam Jackson <ajax@redhat.com>
2013-12-31 02:23:38 +01:00
|
|
|
#ifdef GLAMOR
|
2014-11-28 11:20:47 +01:00
|
|
|
if (ms->drmmode.glamor) {
|
modesetting: Add support for DRI2 with glamor.
This is derived from the intel driver DRI2 code, with swapchain and
pageflipping dropped, functions renamed, and vblank event management
shared code moved to a vblank.c for reuse by Present.
This allows AIGLX to load, which means that you get appropriate
visuals exposed in GL, along with many extensions under
direct-rendering that require presence in GLX (which aren't supported
in glxdriswrast.c).
v2: Drop unused header includes in pageflip.c, wrap in #ifdef GLAMOR.
Drop triple-buffering, which was totally broken in practice (I'll
try to fix this later). Fix up some style nits. Document the
general flow of pageflipping and why, rename the DRI2 frame event
type enums to reflect what they're for, and handle them in a
single switch statement so you can understand the state machine
more easily.
v3: Drop pageflipping entirely -- it's unstable on my Intel laptop
(not that the normal 2D driver is stable with pageflipping for
me), and I won't get it fixed before the merge window. It now
passes all of the OML_sync_control tests from Jamey and Theo
(except for occasional warns in timing -fullscreen -divisor 2).
v4: Fix doxygen at the top of vblank.c
Signed-off-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Adam Jackson <ajax@redhat.com>
2013-12-31 02:23:38 +01:00
|
|
|
ms_dri2_close_screen(pScreen);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
ms_vblank_close_screen(pScreen);
|
|
|
|
|
2011-09-29 13:38:26 +02:00
|
|
|
if (ms->damage) {
|
2014-10-08 09:39:15 +02:00
|
|
|
DamageUnregister(ms->damage);
|
|
|
|
DamageDestroy(ms->damage);
|
|
|
|
ms->damage = NULL;
|
2011-09-29 13:38:26 +02:00
|
|
|
}
|
|
|
|
|
2012-02-20 12:00:56 +01:00
|
|
|
if (ms->drmmode.shadow_enable) {
|
2014-10-08 09:39:15 +02:00
|
|
|
shadowRemove(pScreen, pScreen->GetScreenPixmap(pScreen));
|
|
|
|
free(ms->drmmode.shadow_fb);
|
|
|
|
ms->drmmode.shadow_fb = NULL;
|
2011-09-29 16:55:36 +02:00
|
|
|
}
|
2011-09-29 12:49:26 +02:00
|
|
|
drmmode_uevent_fini(pScrn, &ms->drmmode);
|
|
|
|
|
|
|
|
drmmode_free_bos(pScrn, &ms->drmmode);
|
|
|
|
|
2008-06-16 16:07:39 +02:00
|
|
|
if (pScrn->vtSema) {
|
2014-08-26 20:37:46 +02:00
|
|
|
LeaveVT(pScrn);
|
2008-05-28 16:55:36 +02:00
|
|
|
}
|
2008-05-28 14:33:07 +02:00
|
|
|
|
2008-06-16 16:07:39 +02:00
|
|
|
pScreen->CreateScreenResources = ms->createScreenResources;
|
2011-09-29 13:38:26 +02:00
|
|
|
pScreen->BlockHandler = ms->BlockHandler;
|
2011-09-29 15:05:43 +02:00
|
|
|
|
2008-05-28 16:55:36 +02:00
|
|
|
pScrn->vtSema = FALSE;
|
|
|
|
pScreen->CloseScreen = ms->CloseScreen;
|
2014-08-26 20:37:46 +02:00
|
|
|
return (*pScreen->CloseScreen) (pScreen);
|
2008-05-28 14:33:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static ModeStatus
|
2014-08-26 20:37:46 +02:00
|
|
|
ValidMode(ScrnInfoPtr arg, DisplayModePtr mode, Bool verbose, int flags)
|
2008-05-28 14:33:07 +02:00
|
|
|
{
|
2008-05-28 16:55:36 +02:00
|
|
|
return MODE_OK;
|
2008-05-28 14:33:07 +02:00
|
|
|
}
|