diff options
author | Alan Hourihane <alanh@tungstengraphics.com> | 2008-05-28 13:33:07 +0100 |
---|---|---|
committer | Alan Hourihane <alanh@tungstengraphics.com> | 2008-05-28 13:33:07 +0100 |
commit | b212306ae7bd3a79fb290a32ebd3952c2cba846d (patch) | |
tree | 2fa92e3be1b61b2270338eb3d782796199fd10e6 |
Initial commit of new modesetting driver
-rw-r--r-- | COPYING | 12 | ||||
-rw-r--r-- | Makefile.am | 24 | ||||
-rw-r--r-- | README | 0 | ||||
-rwxr-xr-x | autogen.sh | 12 | ||||
-rw-r--r-- | configure.ac | 200 | ||||
-rw-r--r-- | man/Makefile.am | 69 | ||||
-rw-r--r-- | man/modesetting.man | 0 | ||||
-rw-r--r-- | src/Makefile.am | 42 | ||||
-rw-r--r-- | src/crtc.c | 215 | ||||
-rw-r--r-- | src/driver.c | 1028 | ||||
-rw-r--r-- | src/driver.h | 88 | ||||
-rw-r--r-- | src/exa.c | 235 | ||||
-rw-r--r-- | src/output.c | 285 |
13 files changed, 2210 insertions, 0 deletions
@@ -0,0 +1,12 @@ +This is a stub file. This package has not yet had its complete licensing +information compiled. Please see the individual source files for details on +your rights to use and modify this software. + +Please submit updated COPYING files to the Xorg bugzilla: + +https://bugs.freedesktop.org/enter_bug.cgi?product=xorg + +All licensing questions regarding this software should be directed at the +Xorg mailing list: + +http://lists.freedesktop.org/mailman/listinfo/xorg diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..8cbe4a9 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,24 @@ +# Copyright 2005 Adam Jackson. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# on the rights to use, copy, modify, merge, publish, distribute, sub +# license, and/or sell copies of the Software, and to permit persons to whom +# the Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice (including the next +# paragraph) shall be included in all copies or substantial portions of the +# Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +# ADAM JACKSON BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +AUTOMAKE_OPTIONS = foreign +SUBDIRS = src man + +EXTRA_DIST = README diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..904cd67 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,12 @@ +#! /bin/sh + +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +ORIGDIR=`pwd` +cd $srcdir + +autoreconf -v --install || exit 1 +cd $ORIGDIR || exit $? + +$srcdir/configure --enable-maintainer-mode "$@" diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..6fe4433 --- /dev/null +++ b/configure.ac @@ -0,0 +1,200 @@ +# Copyright 2005 Adam Jackson. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# on the rights to use, copy, modify, merge, publish, distribute, sub +# license, and/or sell copies of the Software, and to permit persons to whom +# the Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice (including the next +# paragraph) shall be included in all copies or substantial portions of the +# Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +# ADAM JACKSON BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Process this file with autoconf to produce a configure script + +AC_PREREQ(2.57) +AC_INIT([xf86-video-modesetting], + 0.1.0, + [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], + xf86-video-modesetting) + +AC_CONFIG_SRCDIR([Makefile.am]) +AM_CONFIG_HEADER([config.h]) +AC_CONFIG_AUX_DIR(.) + +AM_INIT_AUTOMAKE([dist-bzip2]) + +AM_MAINTAINER_MODE + +# Checks for programs. +AC_DISABLE_STATIC +AC_PROG_LIBTOOL +DOLT +AC_PROG_CC +AM_PROG_CC_C_O + +AH_TOP([#include "xorg-server.h"]) + +AC_ARG_WITH(xorg-module-dir, + AC_HELP_STRING([--with-xorg-module-dir=DIR], + [Default xorg module directory [[default=$libdir/xorg/modules]]]), + [moduledir="$withval"], + [moduledir="$libdir/xorg/modules"]) + +AC_ARG_ENABLE(dri, AC_HELP_STRING([--disable-dri], + [Disable DRI support [[default=auto]]]), + [DRI="$enableval"], + [DRI=auto]) + +# Checks for extensions +XORG_DRIVER_CHECK_EXT(XINERAMA, xineramaproto) +XORG_DRIVER_CHECK_EXT(RANDR, randrproto) +XORG_DRIVER_CHECK_EXT(RENDER, renderproto) +XORG_DRIVER_CHECK_EXT(XF86DRI, xextproto x11) +XORG_DRIVER_CHECK_EXT(DPMSExtension, xextproto) + +# Checks for pkg-config packages +PKG_CHECK_MODULES(XORG, [xorg-server xproto xvmc fontsproto $REQUIRED_MODULES]) +sdkdir=$(pkg-config --variable=sdkdir xorg-server) + +# Checks for libraries. + +# Checks for header files. +AC_HEADER_STDC + +AC_MSG_CHECKING([whether to include DRI support]) +if test x$DRI = xauto; then + AC_CHECK_FILE([${sdkdir}/dri.h], + [have_dri_h="yes"], [have_dri_h="no"]) + AC_CHECK_FILE([${sdkdir}/sarea.h], + [have_sarea_h="yes"], [have_sarea_h="no"]) + AC_CHECK_FILE([${sdkdir}/dristruct.h], + [have_dristruct_h="yes"], [have_dristruct_h="no"]) + AC_CHECK_FILE([${sdkdir}/damage.h], + [have_damage_h="yes"], [have_damage_h="no"]) + + if test "$have_dri_h" = yes -a \ + "$have_sarea_h" = yes -a \ + "$have_dristruct_h" = yes; then + DRI="yes" + else + DRI="no" + fi +fi +AC_MSG_RESULT([$DRI]) + +save_CFLAGS="$CFLAGS" +CFLAGS="$XORG_CFLAGS" +AC_CHECK_HEADER(xf86Modes.h,[XMODES=yes],[XMODES=no],[#include "xorg-server.h"]) +AC_CHECK_DECL(XSERVER_LIBPCIACCESS, + [XSERVER_LIBPCIACCESS=yes],[XSERVER_LIBPCIACCESS=no], + [#include "xorg-server.h"]) +CFLAGS="$save_CFLAGS" + +if test x$XSERVER_LIBPCIACCESS = xyes; then + PKG_CHECK_MODULES([PCIACCESS], [pciaccess >= 0.10]) +else + PKG_CHECK_MODULES([PCIACCESS], [pciaccess >= 0.10], + have_libpciaccess=yes, + have_libpciaccess=no) +fi +AM_CONDITIONAL(XSERVER_LIBPCIACCESS, test "x$XSERVER_LIBPCIACCESS" = xyes) +AM_CONDITIONAL(LIBPCIACCESS, + test "x$XSERVER_LIBPCIACCESS" = xyes -o "x$have_libpciaccess" = xyes) +AM_CONDITIONAL(XMODES, test "x$XMODES" = xno) + +if test "x$XSERVER_SOURCE" = x; then + if test -d ../../xserver; then + XSERVER_SOURCE="`cd ../../xserver && pwd`" + fi +fi + +if test -d "$XSERVER_SOURCE"; then + case "$XSERVER_SOURCE" in + /*) + ;; + *) + XSERVER_SOURCE="`cd $XSERVER_SOURCE && pwd`" + ;; + esac + if test -f $srcdir/src/modes/xf86Modes.h; then + : + else + ln -sf $XSERVER_SOURCE/hw/xfree86/modes $srcdir/src/modes + fi + + if test -f $srcdir/src/parser/xf86Parser.h; then + : + else + ln -sf $XSERVER_SOURCE/hw/xfree86/parser $srcdir/src/parser + fi +fi + +if test "x$XMODES" = xyes; then + AC_MSG_NOTICE([X server has new mode code]) + AC_DEFINE(XMODES, 1,[X server has built-in mode code]) + XMODES_CFLAGS= +else + if test -f $srcdir/src/modes/xf86Modes.h -a -f $srcdir/src/parser/xf86Parser.h; then + AC_MSG_NOTICE([X server is missing new mode code, using local copy]) + else + AC_MSG_ERROR([Must have X server >= 1.3 source tree for mode setting code. Please specify --with-xserver-source]) + fi + XMODES_CFLAGS='-DXF86_MODES_RENAME -I$(top_srcdir)/src -I$(top_srcdir)/src/modes -I$(top_srcdir)/src/parser' +fi + +AC_SUBST([XMODES_CFLAGS]) + +dnl Use lots of warning flags with GCC + +WARN_CFLAGS="" + +if test "x$GCC" = "xyes"; then + WARN_CFLAGS="-Wall -Wpointer-arith -Wstrict-prototypes \ + -Wmissing-prototypes -Wmissing-declarations \ + -Wnested-externs -fno-strict-aliasing" +fi + +AM_CONDITIONAL(DRI, test x$DRI = xyes) +if test "$DRI" = yes; then + PKG_CHECK_MODULES(DRI, [libdrm xf86driproto]) + AC_DEFINE(XF86DRI,1,[Enable DRI driver support]) + AC_DEFINE(XF86DRI_DEVEL,1,[Enable developmental DRI driver support]) + PKG_CHECK_MODULES(DRI_MM, [libdrm >= 2.3.1],[DRI_MM=yes], [DRI_MM=no]) + if test "x$DRI_MM" = xyes; then + AC_DEFINE(XF86DRI_MM,1,[Extended DRI memory management]) + fi + if test "$have_damage_h" = yes; then + AC_DEFINE(DAMAGE,1,[Use Damage extension]) + fi + CFLAGS="$XORG_CFLAGS $DRI_CFLAGS" +fi + +AC_SUBST([DRI_CFLAGS]) +AC_SUBST([XORG_CFLAGS]) +AC_SUBST([WARN_CFLAGS]) +AC_SUBST([moduledir]) + +DRIVER_NAME=modesetting +AC_SUBST([DRIVER_NAME]) + +m4_ifndef([XORG_MACROS_VERSION], [AC_FATAL([must install xorg-macros 1.1.3 or later before running autoconf/autogen])]) +XORG_MACROS_VERSION(1.1.3) +XORG_MANPAGE_SECTIONS +XORG_RELEASE_VERSION + +XORG_CHECK_LINUXDOC + +AC_OUTPUT([ + Makefile + src/Makefile + man/Makefile +]) diff --git a/man/Makefile.am b/man/Makefile.am new file mode 100644 index 0000000..89ca862 --- /dev/null +++ b/man/Makefile.am @@ -0,0 +1,69 @@ +# +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation. +# +# The above copyright notice and this permission notice 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 OPEN GROUP 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. +# +# Except as contained in this notice, the name of the copyright holders shall +# not be used in advertising or otherwise to promote the sale, use or +# other dealings in this Software without prior written authorization +# from the copyright holders. +# + +drivermandir = $(DRIVER_MAN_DIR) + +DRIVER_MAN_DIR_SUFFIX = $(DRIVER_MAN_DIR:@mandir@/man%=%) + +driverman_PRE = @DRIVER_NAME@.man + +driverman_DATA = \ + $(driverman_PRE:man=@DRIVER_MAN_SUFFIX@) \ + modesetting.@DRIVER_MAN_SUFFIX@ + +EXTRA_DIST = @DRIVER_NAME@.man + +CLEANFILES = $(driverman_DATA) + +SED = sed + +# Strings to replace in man pages +XORGRELSTRING = @PACKAGE_STRING@ + XORGMANNAME = X Version 11 + +MAN_SUBSTS = \ + -e 's|__vendorversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \ + -e 's|__xorgversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \ + -e 's|__xservername__|Xorg|g' \ + -e 's|__xconfigfile__|xorg.conf|g' \ + -e 's|__projectroot__|$(prefix)|g' \ + -e 's|__appmansuffix__|$(APP_MAN_SUFFIX)|g' \ + -e 's|__drivermansuffix__|$(DRIVER_MAN_SUFFIX)|g' \ + -e 's|__adminmansuffix__|$(ADMIN_MAN_SUFFIX)|g' \ + -e 's|__miscmansuffix__|$(MISC_MAN_SUFFIX)|g' \ + -e 's|__filemansuffix__|$(FILE_MAN_SUFFIX)|g' + +SUFFIXES = .$(DRIVER_MAN_SUFFIX) .man + +.man.$(DRIVER_MAN_SUFFIX): + sed $(MAN_SUBSTS) < $< > $@ + +BUILT_SOURCES = shadows.DONE + +shadows.DONE: + -rm -f modesetting.@DRIVER_MAN_SUFFIX@ + echo .so man$(DRIVER_MAN_DIR_SUFFIX)/modesetting.$(DRIVER_MAN_SUFFIX) > \ + modesetting.@DRIVER_MAN_SUFFIX@ diff --git a/man/modesetting.man b/man/modesetting.man new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/man/modesetting.man diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..17d884f --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,42 @@ +# Copyright 2005 Adam Jackson. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# on the rights to use, copy, modify, merge, publish, distribute, sub +# license, and/or sell copies of the Software, and to permit persons to whom +# the Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice (including the next +# paragraph) shall be included in all copies or substantial portions of the +# Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +# ADAM JACKSON BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +SUBDIRS = + +# this is obnoxious: +# -module lets us name the module exactly how we want +# -avoid-version prevents gratuitous .0.0.0 version numbers on the end +# _ladir passes a dummy rpath to libtool so the thing will actually link +# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc. + +AM_CFLAGS = @WARN_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ @PCIACCESS_CFLAGS@ \ + @XMODES_CFLAGS@ + +modesetting_drv_la_LTLIBRARIES = modesetting_drv.la +modesetting_drv_la_LDFLAGS = -module -avoid-version -ldrm +modesetting_drv_ladir = @moduledir@/drivers + +modesetting_drv_la_SOURCES = \ + driver.c \ + driver.h \ + output.c \ + crtc.c \ + exa.c + +EXTRA_DIST = diff --git a/src/crtc.c b/src/crtc.c new file mode 100644 index 0000000..f168126 --- /dev/null +++ b/src/crtc.c @@ -0,0 +1,215 @@ +/* + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * + * Author: Alan Hourihane <alanh@tungstengraphics.com> + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <unistd.h> +#include <string.h> +#include <assert.h> +#include <stdlib.h> +#include <math.h> +#include <stdint.h> + +#include <xf86.h> +#include <xf86i2c.h> +#include <xf86Crtc.h> +#include "driver.h" +#include "xf86Modes.h" + +#define DPMS_SERVER +#include <X11/extensions/dpms.h> + +static void +crtc_dpms(xf86CrtcPtr crtc, int mode) +{ + ScrnInfoPtr pScrn = crtc->scrn; + + switch (mode) { + case DPMSModeOn: + case DPMSModeStandby: + case DPMSModeSuspend: + break; + case DPMSModeOff: + break; + } +} + +static Bool +crtc_lock(xf86CrtcPtr crtc) +{ + return FALSE; +} + +static void +crtc_unlock(xf86CrtcPtr crtc) +{ +} + +static void +crtc_prepare(xf86CrtcPtr crtc) +{ +} + +static void +crtc_commit(xf86CrtcPtr crtc) +{ +} + +static Bool +crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode, + DisplayModePtr adjusted_mode) +{ + return TRUE; +} + +static void +crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, + DisplayModePtr adjusted_mode, int x, int y) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn); + modesettingPtr ms = modesettingPTR(crtc->scrn); + xf86OutputPtr output = config->output[config->compat_output]; + drmModeOutputPtr drm_output = output->driver_private; + drmModeCrtcPtr drm_crtc = crtc->driver_private; + struct drm_mode_modeinfo drm_mode; + + drm_mode.clock = mode->Clock; + drm_mode.hdisplay = mode->HDisplay; + drm_mode.hsync_start = mode->HSyncStart; + drm_mode.hsync_end = mode->HSyncEnd; + drm_mode.htotal = mode->HTotal; + drm_mode.vdisplay = mode->VDisplay; + drm_mode.vsync_start = mode->VSyncStart; + drm_mode.vsync_end = mode->VSyncEnd; + drm_mode.vtotal = mode->VTotal; + drm_mode.flags = mode->Flags; + drm_mode.hskew = mode->HSkew; + drm_mode.vscan = mode->VScan; + drm_mode.vrefresh = mode->VRefresh; + strncpy(drm_mode.name, mode->name, DRM_DISPLAY_MODE_LEN); + + drmModeSetCrtc(ms->fd, drm_crtc->crtc_id, ms->fb_id, x, y, + &drm_output->output_id, 1, &drm_mode); +} + +void +crtc_load_lut(xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; +} + +static void +crtc_gamma_set(xf86CrtcPtr crtc, CARD16 * red, CARD16 * green, CARD16 * blue, + int size) +{ +} + +static void * +crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height) +{ + ScrnInfoPtr pScrn = crtc->scrn; + + return NULL; +} + +static PixmapPtr +crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) +{ + ScrnInfoPtr pScrn = crtc->scrn; + + return NULL; +} + +static void +crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) +{ + ScrnInfoPtr pScrn = crtc->scrn; +} + +static void +crtc_destroy(xf86CrtcPtr crtc) +{ + drmModeFreeCrtc(crtc->driver_private); +} + +static const xf86CrtcFuncsRec crtc_funcs = { + .dpms = crtc_dpms, + .save = NULL, /* XXX */ + .restore = NULL, /* XXX */ + .lock = crtc_lock, + .unlock = crtc_unlock, + .mode_fixup = crtc_mode_fixup, + .prepare = crtc_prepare, + .mode_set = crtc_mode_set, + .commit = crtc_commit, + .gamma_set = crtc_gamma_set, + .shadow_create = crtc_shadow_create, + .shadow_allocate = crtc_shadow_allocate, + .shadow_destroy = crtc_shadow_destroy, +// .set_cursor_colors = crtc_set_cursor_colors, +// .set_cursor_position = crtc_set_cursor_position, +// .show_cursor = crtc_show_cursor, +// .hide_cursor = crtc_hide_cursor, +// .load_cursor_image = crtc_load_cursor_image, +// .load_cursor_argb = crtc_load_cursor_argb, + .destroy = crtc_destroy, /* XXX */ +}; + +void +crtc_init(ScrnInfoPtr pScrn) +{ + modesettingPtr ms = modesettingPTR(pScrn); + xf86CrtcPtr crtc; + drmModeResPtr res; + drmModeCrtcPtr drm_crtc = NULL; + int c, k, p; + + res = drmModeGetResources(ms->fd); + if (res == 0) { + ErrorF("Failed drmModeGetResources %d\n",errno); + return; + } + + for (c = 0; c < res->count_crtcs; c++) { + drm_crtc = drmModeGetCrtc(ms->fd, res->crtcs[c]); + if (!drm_crtc) + continue; + + crtc = xf86CrtcCreate(pScrn, &crtc_funcs); + if (crtc == NULL) + goto out; + + crtc->driver_private = drm_crtc; + } + +out: + drmModeFreeResources(res); +} diff --git a/src/driver.c b/src/driver.c new file mode 100644 index 0000000..ba6bfdf --- /dev/null +++ b/src/driver.c @@ -0,0 +1,1028 @@ +/* + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * + * Author: Alan Hourihane <alanh@tungstengraphics.com> + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "compiler.h" +#include "xf86RAC.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "xf86Resources.h" +#include "mipointer.h" +#include "micmap.h" +#include "shadowfb.h" +#include <X11/extensions/randr.h> +#include "fb.h" +#include "edid.h" +#include "xf86i2c.h" +#include "xf86Crtc.h" +#include "miscstruct.h" +#include "dixstruct.h" +#include "xf86xv.h" +#include <X11/extensions/Xv.h> +#include "shadow.h" +#include <xorg-server.h> +#if XSERVER_LIBPCIACCESS +#include <pciaccess.h> +#endif + +#include "driver.h" + +static void AdjustFrame(int scrnIndex, int x, int y, int flags); +static Bool CloseScreen(int scrnIndex, ScreenPtr pScreen); +static Bool EnterVT(int scrnIndex, int flags); +static Bool SaveHWState(ScrnInfoPtr pScrn); +static Bool RestoreHWState(ScrnInfoPtr pScrn); +static void Identify(int flags); +static const OptionInfoRec *AvailableOptions(int chipid, int busid); +static ModeStatus ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags); +static void FreeScreen(int scrnIndex, int flags); +static void LeaveVT(int scrnIndex, int flags); +static Bool SwitchMode(int scrnIndex, DisplayModePtr mode, int flags); +static Bool ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv); +static Bool PreInit(ScrnInfoPtr pScrn, int flags); +#if XSERVER_LIBPCIACCESS +static Bool +pci_probe(DriverPtr driver, + int entity_num, struct pci_device *device, intptr_t match_data); +#else +static Bool Probe(DriverPtr drv, int flags); +#endif + +#if XSERVER_LIBPCIACCESS +static const struct pci_id_match device_match[] = { + {0x8086, 0x2592, 0xffff, 0xffff, 0, 0, 0}, + {0, 0, 0}, +}; +#endif + +_X_EXPORT DriverRec modesetting = { + 1, + "modesetting", + Identify, +#if XSERVER_LIBPCIACCESS + NULL, +#else + Probe, +#endif + AvailableOptions, + NULL, + 0, + NULL, +#if XSERVER_LIBPCIACCESS + device_match, + pci_probe +#endif +}; + +static SymTabRec Chipsets[] = { + {0x2592, "Intel Graphics Device"}, + {-1, NULL} +}; + +static PciChipsets PciDevices[] = { + {0x2592, 0x2592, RES_SHARED_VGA}, + {-1, -1, RES_UNDEFINED} +}; + +typedef enum +{ + OPTION_NOACCEL, + OPTION_SW_CURSOR, + OPTION_SHADOWFB, +} modesettingOpts; + +static const OptionInfoRec Options[] = { + {OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_SHADOWFB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE}, + {-1, NULL, OPTV_NONE, {0}, FALSE} +}; + +static const char *fbSymbols[] = { + "fbPictureInit", + "fbScreenInit", + NULL +}; + +static const char *ddcSymbols[] = { + "xf86PrintEDID", + "xf86SetDDCproperties", + NULL +}; + +static const char *shadowSymbols[] = { + "shadowInit", + "shadowUpdatePackedWeak", + NULL +}; + +static const char *i2cSymbols[] = { + "xf86CreateI2CBusRec", + "xf86I2CBusInit", + NULL +}; + +int modesettingEntityIndex = -1; + +static MODULESETUPPROTO(Setup); + +static XF86ModuleVersionInfo VersRec = { + "modesetting", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XORG_VERSION_CURRENT, + PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL, + ABI_CLASS_VIDEODRV, + ABI_VIDEODRV_VERSION, + MOD_CLASS_VIDEODRV, + {0, 0, 0, 0} +}; + +_X_EXPORT XF86ModuleData modesettingModuleData = { &VersRec, Setup, NULL }; + +static pointer +Setup(pointer module, pointer opts, int *errmaj, int *errmin) +{ + static Bool setupDone = 0; + + /* This module should be loaded only once, but check to be sure. + */ + if (!setupDone) { + setupDone = 1; + xf86AddDriver(&modesetting, module, HaveDriverFuncs); + + /* + * Tell the loader about symbols from other modules that this module + * might refer to. + */ + LoaderRefSymLists(fbSymbols, + shadowSymbols, ddcSymbols, NULL); + + /* + * The return value must be non-NULL on success even though there + * is no TearDownProc. + */ + return (pointer) 1; + } else { + if (errmaj) + *errmaj = LDR_ONCEONLY; + return NULL; + } +} + +static void +Identify(int flags) +{ + xf86PrintChipsets("modesetting", "Driver for Modesetting Kernel Drivers", + Chipsets); +} + +static const OptionInfoRec * +AvailableOptions(int chipid, int busid) +{ + return Options; +} + +#if XSERVER_LIBPCIACCESS +static Bool +pci_probe(DriverPtr driver, + int entity_num, struct pci_device *device, intptr_t match_data) +{ + ScrnInfoPtr scrn = NULL; + EntityInfoPtr entity; + DevUnion *private; + + scrn = xf86ConfigPciEntity(scrn, 0, entity_num, PciDevices, + NULL, NULL, NULL, NULL, NULL); + if (scrn != NULL) { + scrn->driverVersion = 1; + scrn->driverName = "modesetting"; + scrn->name = "modesetting"; + scrn->Probe = NULL; + + entity = xf86GetEntityInfo(entity_num); + + switch (device->device_id) { + case 0x2592: + scrn->PreInit = PreInit; + scrn->ScreenInit = ScreenInit; + scrn->SwitchMode = SwitchMode; + scrn->AdjustFrame = AdjustFrame; + scrn->EnterVT = EnterVT; + scrn->LeaveVT = LeaveVT; + scrn->FreeScreen = FreeScreen; + scrn->ValidMode = ValidMode; + break; + } + } + return scrn != NULL; +} +#else +static Bool +Probe(DriverPtr drv, int flags) +{ + int i, numUsed, numDevSections, *usedChips; + EntPtr msEnt = NULL; + DevUnion *pPriv; + GDevPtr *devSections; + Bool foundScreen = FALSE; + pciVideoPtr *VideoInfo; + pciVideoPtr *ppPci; + int numDevs; + + /* + * Find the config file Device sections that match this + * driver, and return if there are none. + */ + if ((numDevSections = + xf86MatchDevice("modesetting", &devSections)) <= 0) { + return FALSE; + } + + /* + * This probing is just checking the PCI data the server already + * collected. + */ + if (!(VideoInfo = xf86GetPciVideoInfo())) + return FALSE; + +#if 0 + numUsed = 0; + for (ppPci = VideoInfo; ppPci != NULL && *ppPci != NULL; ppPci++) { + for (numDevs = 0; numDevs < numDevSections; numDevs++) { + if (devSections[numDevs]->busID && *devSections[numDevs]->busID) { + if (xf86ComparePciBusString(devSections[numDevs]->busID, (*ppPci)->bus, (*ppPci)->device, (*ppPci)->func)) { + /* Claim slot */ + if (xf86CheckPciSlot((*ppPci)->bus, (*ppPci)->device, + (*ppPci)->func)) { + usedChips[numUsed++] = xf86ClaimPciSlot((*ppPci)->bus, (*ppPci)->device, + (*ppPci)->func, drv, (*ppPci)->chipType, + NULL, TRUE); + ErrorF("CLAIMED %d %d %d\n",(*ppPci)->bus,(*ppPci)->device, (*ppPci)->func); + } + } + } + } + } +#else + /* Look for Intel i8xx devices. */ + numUsed = xf86MatchPciInstances("modesetting", PCI_VENDOR_INTEL, + Chipsets, PciDevices, + devSections, numDevSections, + drv, &usedChips); +#endif + + if (flags & PROBE_DETECT) { + if (numUsed > 0) + foundScreen = TRUE; + } else { + ErrorF("NUMUSED %d\n",numUsed); + for (i = 0; i < numUsed; i++) { + ScrnInfoPtr pScrn = NULL; + + /* Allocate new ScrnInfoRec and claim the slot */ + if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i], + PciDevices, NULL, NULL, NULL, + NULL, NULL))) { + EntityInfoPtr pEnt; + + pEnt = xf86GetEntityInfo(usedChips[i]); + + pScrn->driverVersion = 1; + pScrn->driverName = "modesetting"; + pScrn->name = "modesetting"; + pScrn->Probe = Probe; + foundScreen = TRUE; + { + /* Allocate an entity private if necessary */ + if (modesettingEntityIndex < 0) + modesettingEntityIndex = xf86AllocateEntityPrivateIndex(); + + pPriv = xf86GetEntityPrivate(pScrn->entityList[0], + modesettingEntityIndex); + if (!pPriv->ptr) { + pPriv->ptr = xnfcalloc(sizeof(EntRec), 1); + msEnt = pPriv->ptr; + msEnt->lastInstance = -1; + } else { + msEnt = pPriv->ptr; + } + + /* + * Set the entity instance for this instance of the driver. + * For dual head per card, instance 0 is the "master" + * instance, driving the primary head, and instance 1 is + * the "slave". + */ + msEnt->lastInstance++; + xf86SetEntityInstanceForScreen(pScrn, + pScrn->entityList[0], + msEnt->lastInstance); + pScrn->PreInit = PreInit; + pScrn->ScreenInit = ScreenInit; + pScrn->SwitchMode = SwitchMode; + pScrn->AdjustFrame = AdjustFrame; + pScrn->EnterVT = EnterVT; + pScrn->LeaveVT = LeaveVT; + pScrn->FreeScreen = FreeScreen; + pScrn->ValidMode = ValidMode; + break; + } + } else + ErrorF("FAILED PSCRN\n"); + } + } + + xfree(usedChips); + xfree(devSections); + + return foundScreen; +} +#endif + +static Bool +GetRec(ScrnInfoPtr pScrn) +{ + if (pScrn->driverPrivate) + return TRUE; + + pScrn->driverPrivate = xnfcalloc(sizeof(modesettingRec), 1); + + return TRUE; +} + +static void +FreeRec(ScrnInfoPtr pScrn) +{ + if (!pScrn) + return; + + if (!pScrn->driverPrivate) + return; + + xfree(pScrn->driverPrivate); + + pScrn->driverPrivate = NULL; +} + +static void +ProbeDDC(ScrnInfoPtr pScrn, int index) +{ + ConfiguredMonitor = NULL; +} + +static Bool +MapMem(ScrnInfoPtr pScrn) +{ + modesettingPtr ms = modesettingPTR(pScrn); + + drmBOMap(ms->fd, + &ms->bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, &ms->virtual); + + return TRUE; +} + +static Bool +UnmapMem(ScrnInfoPtr pScrn) +{ + modesettingPtr ms = modesettingPTR(pScrn); + + drmBOUnmap(ms->fd, &ms->bo); + + return TRUE; +} + +static void +LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, + LOCO * colors, VisualPtr pVisual) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); +} + +static Bool +crtc_resize(ScrnInfoPtr pScrn, int width, int height) +{ + modesettingPtr ms = modesettingPTR(pScrn); + ScreenPtr pScreen = pScrn->pScreen; + PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen); + Bool fbAccessDisabled; + CARD8 *fbstart; + + if (width == pScrn->virtualX && height == pScrn->virtualY) + return TRUE; + + ErrorF("RESIZING TO %dx%d\n",width,height); + + pScrn->virtualX = width; + pScrn->virtualY = height; + pScrn->displayWidth = (pScrn->virtualX + 63) & ~63; + + if (ms->shadowMem) { + xfree(ms->shadowMem); + ms->shadowMem = NULL; + } + + UnmapMem(pScrn); + + /* move old buffer out of the way */ + drmBOSetStatus(ms->fd, &ms->bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_MEM_LOCAL, + DRM_BO_MASK_MEM | DRM_BO_FLAG_NO_EVICT, + DRM_BO_HINT_DONT_FENCE, 0, 0); + + /* unreference it */ + drmBOUnreference(ms->fd, &ms->bo); + + drmBOCreate(ms->fd, + pScrn->virtualY * pScrn->displayWidth * + pScrn->bitsPerPixel / 8, 0, NULL, + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_SHAREABLE + | DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_MAPPABLE | + DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT, DRM_BO_HINT_DONT_FENCE, &ms->bo); + + MapMem(pScrn); + + drmModeAddFB(ms->fd, + pScrn->virtualX, + pScrn->virtualY, + pScrn->depth, + pScrn->bitsPerPixel, + pScrn->displayWidth * pScrn->bitsPerPixel / 8, + ms->bo.handle, + &ms->fb_id); + + if (ms->shadowFB) { + if ((ms->shadowMem = + shadowAlloc(pScrn->displayWidth, pScrn->virtualY, + pScrn->bitsPerPixel)) == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Allocation of shadow memory failed\n"); + return FALSE; + } + fbstart = ms->shadowMem; + } else { + fbstart = ms->virtual; + } + + /* + * If we are in a fb disabled state, the virtual address of the root + * pixmap should always be NULL, and it will be overwritten later + * if we try to set it to something. + * + * Therefore, set it to NULL, and modify the backup copy instead. + */ + + fbAccessDisabled = (rootPixmap->devPrivate.ptr == NULL); + + pScreen->ModifyPixmapHeader(rootPixmap, + pScrn->virtualX, pScrn->virtualY, + pScrn->depth, pScrn->bitsPerPixel, + pScrn->displayWidth * pScrn->bitsPerPixel / 8, + fbstart); + + if (fbAccessDisabled) { + pScrn->pixmapPrivate.ptr = fbstart; + rootPixmap->devPrivate.ptr = NULL; + } + + pScrn->frameX0 = 0; + pScrn->frameY0 = 0; + AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + + return TRUE; +} + +static const xf86CrtcConfigFuncsRec crtc_config_funcs = { + crtc_resize +}; + +static Bool +PreInit(ScrnInfoPtr pScrn, int flags) +{ + xf86CrtcConfigPtr xf86_config; + modesettingPtr ms; + MessageType from = X_PROBED; + rgb defaultWeight = { 0, 0, 0 }; + EntityInfoPtr pEnt; + EntPtr msEnt = NULL; + int flags24; + char *BusID; + int i; + char *s; + int num_pipe; + int max_width, max_height; + + if (pScrn->numEntities != 1) + return FALSE; + + pEnt = xf86GetEntityInfo(pScrn->entityList[0]); + + if (flags & PROBE_DETECT) { + ProbeDDC(pScrn, pEnt->index); + return TRUE; + } + + /* Allocate driverPrivate */ + if (!GetRec(pScrn)) + return FALSE; + + ms = modesettingPTR(pScrn); + ms->SaveGeneration = -1; + ms->pEnt = pEnt; + + pScrn->displayWidth = 640; /* default it */ + + if (ms->pEnt->location.type != BUS_PCI) + return FALSE; + + ms->PciInfo = xf86GetPciInfoForEntity(ms->pEnt->index); + + /* Allocate an entity private if necessary */ + if (xf86IsEntityShared(pScrn->entityList[0])) { + msEnt = xf86GetEntityPrivate(pScrn->entityList[0], + modesettingEntityIndex)->ptr; + ms->entityPrivate = msEnt; + } else + ms->entityPrivate = NULL; + + if (xf86RegisterResources(ms->pEnt->index, NULL, ResNone)) { + return FALSE; + } + + if (xf86IsEntityShared(pScrn->entityList[0])) { + if (xf86IsPrimInitDone(pScrn->entityList[0])) { + /* do something */ + } else { + xf86SetPrimInitDone(pScrn->entityList[0]); + } + } + + BusID = xalloc(64); + sprintf(BusID, "PCI:%d:%d:%d", +#if XSERVER_LIBPCIACCESS + ((ms->PciInfo->domain << 8) | ms->PciInfo->bus), + ms->PciInfo->dev, ms->PciInfo->func +#else + ((pciConfigPtr) ms->PciInfo->thisCard)->busnum, + ((pciConfigPtr) ms->PciInfo->thisCard)->devnum, + ((pciConfigPtr) ms->PciInfo->thisCard)->funcnum +#endif + ); + + ms->fd = drmOpen(NULL, BusID); + + if (ms->fd < 0) + return FALSE; + + pScrn->racMemFlags = RAC_FB | RAC_COLORMAP; + pScrn->monitor = pScrn->confScreen->monitor; + pScrn->progClock = TRUE; + pScrn->rgbBits = 8; + + flags24 = Support32bppFb | PreferConvert24to32 | SupportConvert24to32; + + if (!xf86SetDepthBpp(pScrn, 0, 0, 0, flags24)) + return FALSE; + + switch (pScrn->depth) { + case 8: + case 15: + case 16: + case 24: + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Given depth (%d) is not supported by the driver\n", + pScrn->depth); + return FALSE; + } + xf86PrintDepthBpp(pScrn); + + if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight)) + return FALSE; + if (!xf86SetDefaultVisual(pScrn, -1)) + return FALSE; + + /* Process the options */ + xf86CollectOptions(pScrn, NULL); + if (!(ms->Options = xalloc(sizeof(Options)))) + return FALSE; + memcpy(ms->Options, Options, sizeof(Options)); + xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, ms->Options); + + /* Allocate an xf86CrtcConfig */ + xf86CrtcConfigInit(pScrn, &crtc_config_funcs); + xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + + max_width = 8192; + max_height = 8192; + xf86CrtcSetSizeRange(pScrn, 320, 200, max_width, max_height); + + if (xf86ReturnOptValBool(ms->Options, OPTION_NOACCEL, FALSE)) { + ms->noAccel = TRUE; + } + + if (xf86ReturnOptValBool(ms->Options, OPTION_SW_CURSOR, FALSE)) { + ms->SWCursor = TRUE; + } + + if (xf86ReturnOptValBool(ms->Options, OPTION_SHADOWFB, FALSE)) { + if (!xf86LoadSubModule(pScrn, "shadow")) + return FALSE; + + xf86LoaderReqSymLists(shadowSymbols, NULL); + + ms->shadowFB = TRUE; + } + + SaveHWState(pScrn); + + crtc_init(pScrn); + output_init(pScrn); + + if (!xf86InitialConfiguration(pScrn, TRUE)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n"); + RestoreHWState(pScrn); + return FALSE; + } + + RestoreHWState(pScrn); + + /* + * If the driver can do gamma correction, it should call xf86SetGamma() here. + */ + { + Gamma zeros = { 0.0, 0.0, 0.0 }; + + if (!xf86SetGamma(pScrn, zeros)) { + return FALSE; + } + } + + if (pScrn->modes == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n"); + return FALSE; + } + + pScrn->currentMode = pScrn->modes; + + /* Set display resolution */ + xf86SetDpi(pScrn, 0, 0); + + /* Load the required sub modules */ + if (!xf86LoadSubModule(pScrn, "fb")) { + return FALSE; + } + + xf86LoaderReqSymLists(fbSymbols, NULL); + + return TRUE; +} + +static Bool +SaveHWState(ScrnInfoPtr pScrn) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + + return TRUE; +} + +static Bool +RestoreHWState(ScrnInfoPtr pScrn) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + + return TRUE; +} + +static void * +WindowLinear(ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode, + CARD32 * size, void *closure) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + modesettingPtr ms = modesettingPTR(pScrn); + + if (!pScrn->vtSema) + return NULL; + + *size = pScrn->displayWidth * pScrn->bitsPerPixel / 8; + + return ((CARD8 *) ms->virtual + row * (*size) + offset); +} + +static Bool +CreateScreenResources(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + modesettingPtr ms = modesettingPTR(pScrn); + Bool ret; + + pScreen->CreateScreenResources = ms->createScreenResources; + ret = pScreen->CreateScreenResources(pScreen); + pScreen->CreateScreenResources = CreateScreenResources; + + shadowAdd(pScreen, pScreen->GetScreenPixmap(pScreen), + ms->update, WindowLinear, 0, 0); + + return ret; +} + +static Bool +ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + modesettingPtr ms = modesettingPTR(pScrn); + VisualPtr visual; + unsigned long sys_mem; + int c; + MessageType from; + CARD8 *fbstart; + + pScrn->displayWidth = (pScrn->virtualX + 63) & ~63; + + miClearVisualTypes(); + + if (!miSetVisualTypes(pScrn->depth, + miGetDefaultVisualMask(pScrn->depth), + pScrn->rgbBits, pScrn->defaultVisual)) + return FALSE; + + if (!miSetPixmapDepths()) + return FALSE; + + if (!MapMem(pScrn)) + return FALSE; + + pScrn->memPhysBase = 0; + pScrn->fbOffset = 0; + + drmBOCreate(ms->fd, + pScrn->virtualY * pScrn->displayWidth * + pScrn->bitsPerPixel / 8, 0, NULL, + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_SHAREABLE + | DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_MAPPABLE | + DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT, DRM_BO_HINT_DONT_FENCE, &ms->bo); + + MapMem(pScrn); + + drmModeAddFB(ms->fd, + pScrn->virtualX, + pScrn->virtualY, + pScrn->depth, + pScrn->bitsPerPixel, + pScrn->displayWidth * pScrn->bitsPerPixel / 8, + ms->bo.handle, + &ms->fb_id); + + if (ms->shadowFB) { + if ((ms->shadowMem = + shadowAlloc(pScrn->displayWidth, pScrn->virtualY, + pScrn->bitsPerPixel)) == NULL) { + xf86DrvMsg(scrnIndex, X_ERROR, + "Allocation of shadow memory failed\n"); + return FALSE; + } + fbstart = ms->shadowMem; + } else { + fbstart = ms->virtual; + } + + if (!fbScreenInit(pScreen, fbstart, + pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, + pScrn->displayWidth, pScrn->bitsPerPixel)) + return FALSE; + + if (pScrn->bitsPerPixel > 8) { + /* Fixup RGB ordering */ + visual = pScreen->visuals + pScreen->numVisuals; + while (--visual >= pScreen->visuals) { + if ((visual->class | DynamicClass) == DirectColor) { + visual->offsetRed = pScrn->offset.red; + visual->offsetGreen = pScrn->offset.green; + visual->offsetBlue = pScrn->offset.blue; + visual->redMask = pScrn->mask.red; + visual->greenMask = pScrn->mask.green; + visual->blueMask = pScrn->mask.blue; + } + } + } + + fbPictureInit(pScreen, NULL, 0); + if (ms->shadowFB) { + ms->update = shadowUpdatePackedWeak(); + if (!shadowSetup(pScreen)) { + xf86DrvMsg(scrnIndex, X_ERROR, + "Shadow framebuffer initialization failed.\n"); + return FALSE; + } + + ms->createScreenResources = pScreen->CreateScreenResources; + pScreen->CreateScreenResources = CreateScreenResources; + } + + xf86SetBlackWhitePixels(pScreen); + +#if 0 + glucoseScreenInit(pScreen, 0); +#endif +#if 0 + ms->pExa = ExaInit(pScreen); +#endif + + miInitializeBackingStore(pScreen); + xf86SetBackingStore(pScreen); + xf86SetSilkenMouse(pScreen); + miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); + + /* Must force it before EnterVT, so we are in control of VT and + * later memory should be bound when allocating, e.g rotate_mem */ + pScrn->vtSema = TRUE; + + pScreen->SaveScreen = xf86SaveScreen; + ms->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = CloseScreen; + + if (!xf86CrtcScreenInit(pScreen)) + return FALSE; + + if (!miCreateDefColormap(pScreen)) + return FALSE; + +#if 0 + if (!xf86HandleColormaps(pScreen, 256, 8, LoadPalette, NULL, + CMAP_RELOAD_ON_MODE_SWITCH | + CMAP_PALETTED_TRUECOLOR)) { + return FALSE; + } +#endif + + xf86DPMSInit(pScreen, xf86DPMSSet, 0); + +#if 0 + glucoseInitVideo(pScreen); +#endif + + if (serverGeneration == 1) + xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); + + return EnterVT(scrnIndex, 0); +} + +static void +AdjustFrame(int scrnIndex, int x, int y, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + xf86OutputPtr output = config->output[config->compat_output]; + xf86CrtcPtr crtc = output->crtc; + + if (crtc && crtc->enabled) { + crtc->funcs->mode_set(crtc, pScrn->currentMode, pScrn->currentMode, x, y); + crtc->x = output->initial_x + x; + crtc->y = output->initial_y + y; + } +} + +static void +FreeScreen(int scrnIndex, int flags) +{ + FreeRec(xf86Screens[scrnIndex]); +} + +static void +LeaveVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + modesettingPtr ms = modesettingPTR(pScrn); + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + int o; + + for (o = 0; o < config->num_crtc; o++) { + xf86CrtcPtr crtc = config->crtc[o]; + + if (crtc->rotatedPixmap || crtc->rotatedData) { + crtc->funcs->shadow_destroy(crtc, crtc->rotatedPixmap, + crtc->rotatedData); + crtc->rotatedPixmap = NULL; + crtc->rotatedData = NULL; + } + } + + xf86_hide_cursors(pScrn); + + drmMMLock(ms->fd, DRM_BO_MEM_VRAM, 1, 0); + + RestoreHWState(pScrn); +} + +/* + * This gets called when gaining control of the VT, and from ScreenInit(). + */ +static Bool +EnterVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + modesettingPtr ms = modesettingPTR(pScrn); + + /* + * Only save state once per server generation since that's what most + * drivers do. Could change this to save state at each VT enter. + */ + if (ms->SaveGeneration != serverGeneration) { + ms->SaveGeneration = serverGeneration; + SaveHWState(pScrn); + } + + drmMMUnlock(ms->fd, DRM_BO_MEM_VRAM, 1); + + if (!xf86SetDesiredModes(pScrn)) + return FALSE; + + AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + + return TRUE; +} + +static Bool +SwitchMode(int scrnIndex, DisplayModePtr mode, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + + return xf86SetSingleMode(pScrn, mode, RR_Rotate_0); +} + +static Bool +CloseScreen(int scrnIndex, ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + modesettingPtr ms = modesettingPTR(pScrn); + + if (pScrn->vtSema == TRUE) { + LeaveVT(scrnIndex, 0); + drmMMUnlock(ms->fd, DRM_BO_MEM_VRAM, 1); + } + + UnmapMem(pScrn); + + if (ms->shadowFB) + pScreen->CreateScreenResources = ms->createScreenResources; + + if (ms->shadowMem) { + xfree(ms->shadowMem); + ms->shadowMem = NULL; + } + + if (ms->pExa) + ExaClose(pScrn); + + /* move old buffer out of the way */ + drmBOSetStatus(ms->fd, &ms->bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_MEM_LOCAL, + DRM_BO_MASK_MEM | DRM_BO_FLAG_NO_EVICT, + DRM_BO_HINT_DONT_FENCE, 0, 0); + + drmBOUnreference(ms->fd, &ms->bo); + + drmClose(ms->fd); + + pScrn->vtSema = FALSE; + pScreen->CloseScreen = ms->CloseScreen; + return (*pScreen->CloseScreen) (scrnIndex, pScreen); +} + +static ModeStatus +ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) +{ + return MODE_OK; +} diff --git a/src/driver.h b/src/driver.h new file mode 100644 index 0000000..2a09903 --- /dev/null +++ b/src/driver.h @@ -0,0 +1,88 @@ +/* + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * + * Author: Alan Hourihane <alanh@tungstengraphics.com> + * + */ + +#include <errno.h> +#include <drm.h> +#include <xf86drm.h> +#include <xf86drmMode.h> +#include "shadow.h" +#include "exa.h" + +#define DRV_ERROR(msg) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, msg); + +typedef struct { + int lastInstance; + int refCount; + ScrnInfoPtr pScrn_1; + ScrnInfoPtr pScrn_2; +} EntRec, *EntPtr; + +typedef struct _modesettingRec { + int fd; + unsigned int fb_id; + void *virtual; + drmBO bo; + + EntPtr entityPrivate; + + void (*PointerMoved)(int, int, int); + + int Chipset; + EntityInfoPtr pEnt; +#if XSERVER_LIBPCIACCESS + struct pci_device *PciInfo; +#else + pciVideoPtr PciInfo; + PCITAG PciTag; +#endif + + Bool noAccel; + Bool SWCursor; + CloseScreenProcPtr CloseScreen; + + Bool directRenderingDisabled; /* DRI disabled in PreInit. */ + Bool directRenderingEnabled; /* DRI enabled this generation. */ + + /* Broken-out options. */ + OptionInfoPtr Options; + + unsigned int SaveGeneration; + + /* shadowfb */ + CARD8 *shadowMem; + Bool shadowFB; + CreateScreenResourcesProcPtr createScreenResources; + ShadowUpdateProc update; + + /* exa */ + ExaDriverPtr pExa; + drmBO exa_bo; +} modesettingRec, *modesettingPtr; + +#define modesettingPTR(p) ((modesettingPtr)((p)->driverPrivate)) diff --git a/src/exa.c b/src/exa.c new file mode 100644 index 0000000..a9be2c1 --- /dev/null +++ b/src/exa.c @@ -0,0 +1,235 @@ +/* + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * + * Author: Alan Hourihane <alanh@tungstengraphics.com> + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "xf86_OSproc.h" + +#include "driver.h" + +static void +ExaWaitMarker(ScreenPtr pScreen, int marker) +{ +} + +static int +ExaMarkSync(ScreenPtr pScreen) +{ + /* + * See ExaWaitMarker. + */ + + return 1; +} + +Bool +ExaPrepareAccess(PixmapPtr pPix, int index) +{ + ScreenPtr pScreen = pPix->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + + return TRUE; +} + +void +ExaFinishAccess(PixmapPtr pPix, int index) +{ + ScreenPtr pScreen = pPix->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; +} + +static void +ExaDone(PixmapPtr pPixmap) +{ + ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; +} + +static void +ExaDoneComposite(PixmapPtr pPixmap) +{ + ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; +} + +static Bool +ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg) +{ + ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; + + if (!EXA_PM_IS_SOLID(&pPixmap->drawable, planeMask)) + return FALSE; + + /* can't do depth 4 */ + if (pPixmap->drawable.depth == 4) + return FALSE; + + return TRUE; +} + +static void +ExaSolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) +{ + ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; +} + +static Bool +ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, + int ydir, int alu, Pixel planeMask) +{ + ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; + + /* can't do depth 4 */ + if (pSrcPixmap->drawable.depth == 4 || pDstPixmap->drawable.depth == 4) + return FALSE; + + return TRUE; +} + +static void +ExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, + int width, int height) +{ + ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; +} + +static Bool +ExaPrepareComposite(int op, PicturePtr pSrcPicture, + PicturePtr pMaskPicture, PicturePtr pDstPicture, + PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst) +{ + ScreenPtr pScreen = pDst->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + + return FALSE; +} + +static Bool +ExaUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src, + int src_pitch) +{ + ScreenPtr pScreen = pDst->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + + return FALSE; +} + +static void +ExaComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, + int dstX, int dstY, int width, int height) +{ + ScreenPtr pScreen = pDst->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; +} + +static Bool +ExaCheckComposite(int op, + PicturePtr pSrcPicture, PicturePtr pMaskPicture, + PicturePtr pDstPicture) +{ + DrawablePtr pDraw = pSrcPicture->pDrawable; + int w = pDraw->width; + int h = pDraw->height; + + return TRUE; +} + +static Bool +ExaPixmapIsOffscreen(PixmapPtr p) +{ + ScreenPtr pScreen = p->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + + return FALSE; +} + +void +ExaClose(ScrnInfoPtr pScrn) +{ + modesettingPtr ms = modesettingPTR(pScrn); + + exaDriverFini(pScrn->pScreen); + + drmBOUnreference(ms->fd, &ms->exa_bo); +} + +ExaDriverPtr +ExaInit(ScrnInfoPtr pScrn) +{ + modesettingPtr ms = modesettingPTR(pScrn); + ExaDriverPtr pExa; + + pExa = exaDriverAlloc(); + if (!pExa) { + goto out_err; + } + + /* Create a 256KB offscreen area */ + drmBOCreate(ms->fd, 256 * 1024, 0, NULL, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_MEM_TT, DRM_BO_HINT_DONT_FENCE, &ms->exa_bo); + + memset(pExa, 0, sizeof(*pExa)); + pExa->exa_major = 2; + pExa->exa_minor = 2; + pExa->memoryBase = ms->exa_bo.virtual; + pExa->offScreenBase = 0; + pExa->memorySize = ms->exa_bo.size; + pExa->pixmapOffsetAlign = 8; + pExa->pixmapPitchAlign = 32 * 4; + pExa->flags = EXA_OFFSCREEN_PIXMAPS; + pExa->maxX = 8191; /* FIXME */ + pExa->maxY = 8191; /* FIXME */ + pExa->WaitMarker = ExaWaitMarker; + pExa->MarkSync = ExaMarkSync; + pExa->PrepareSolid = ExaPrepareSolid; + pExa->Solid = ExaSolid; + pExa->DoneSolid = ExaDone; + pExa->PrepareCopy = ExaPrepareCopy; + pExa->Copy = ExaCopy; + pExa->DoneCopy = ExaDone; + pExa->CheckComposite = ExaCheckComposite; + pExa->PrepareComposite = ExaPrepareComposite; + pExa->Composite = ExaComposite; + pExa->DoneComposite = ExaDoneComposite; + pExa->PixmapIsOffscreen = ExaPixmapIsOffscreen; + pExa->PrepareAccess = ExaPrepareAccess; + pExa->FinishAccess = ExaFinishAccess; + pExa->UploadToScreen = ExaUploadToScreen; + + if (!exaDriverInit(pScrn->pScreen, pExa)) { + goto out_err; + } + + return pExa; + + out_err: + ExaClose(pScrn); + + return NULL; +} diff --git a/src/output.c b/src/output.c new file mode 100644 index 0000000..b25540e --- /dev/null +++ b/src/output.c @@ -0,0 +1,285 @@ +/* + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * + * Author: Alan Hourihane <alanh@tungstengraphics.com> + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <xf86.h> +#include <xf86i2c.h> +#include <xf86Crtc.h> +#include <errno.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <sys/stat.h> +#include <sys/types.h> + +#define DPMS_SERVER +#include <X11/extensions/dpms.h> + +#include "X11/Xatom.h" + +#include "driver.h" + +static void +dpms(xf86OutputPtr output, int mode) +{ +} + +static void +save(xf86OutputPtr output) +{ +} + +static void +restore(xf86OutputPtr output) +{ +} + +static int +mode_valid(xf86OutputPtr output, DisplayModePtr pMode) +{ + return MODE_OK; +} + +static Bool +mode_fixup(xf86OutputPtr output, DisplayModePtr mode, + DisplayModePtr adjusted_mode) +{ + return TRUE; +} + +static void +prepare(xf86OutputPtr output) +{ + dpms(output, DPMSModeOff); +} + +static void +mode_set(xf86OutputPtr output, DisplayModePtr mode, + DisplayModePtr adjusted_mode) +{ +} + +static void +commit(xf86OutputPtr output) +{ + dpms(output, DPMSModeOn); + + if (output->scrn->pScreen != NULL) + xf86_reload_cursors(output->scrn->pScreen); +} + +static xf86OutputStatus +detect(xf86OutputPtr output) +{ + drmModeOutputPtr drm_output = output->driver_private; + + switch (drm_output->connection) { + case DRM_MODE_CONNECTED: + return XF86OutputStatusConnected; + case DRM_MODE_DISCONNECTED: + return XF86OutputStatusDisconnected; + default: + return XF86OutputStatusUnknown; + } +} + +static DisplayModePtr +get_modes(xf86OutputPtr output) +{ + drmModeOutputPtr drm_output = output->driver_private; + struct drm_mode_modeinfo *drm_mode = NULL; + DisplayModePtr modes = NULL, mode = NULL; + int i; + + for (i = 0; i < drm_output->count_modes; i++) { + drm_mode = &drm_output->modes[i]; + if (drm_mode) { + mode = xcalloc(1, sizeof(DisplayModeRec)); + if (!mode) + continue; + mode->type = 0; + mode->Clock = drm_mode->clock; + mode->HDisplay = drm_mode->hdisplay; + mode->HSyncStart = drm_mode->hsync_start; + mode->HSyncEnd = drm_mode->hsync_end; + mode->HTotal = drm_mode->htotal; + mode->VDisplay = drm_mode->vdisplay; + mode->VSyncStart = drm_mode->vsync_start; + mode->VSyncEnd = drm_mode->vsync_end; + mode->VTotal = drm_mode->vtotal; + mode->Flags = drm_mode->flags; + mode->HSkew = drm_mode->hskew; + mode->VScan = drm_mode->vscan; + mode->VRefresh = xf86ModeVRefresh(mode); + mode->Private = (void *)drm_mode; + xf86SetModeDefaultName(mode); + modes = xf86ModesAdd(modes, mode); + xf86PrintModeline(0, mode); + } + } + + return modes; +} + +static void +destroy(xf86OutputPtr output) +{ + drmModeFreeOutput(output->driver_private); +} + +static void +create_resources(xf86OutputPtr output) +{ +#ifdef RANDR_12_INTERFACE +#endif /* RANDR_12_INTERFACE */ +} + +#ifdef RANDR_12_INTERFACE +static Bool +set_property(xf86OutputPtr output, Atom property, RRPropertyValuePtr value) +{ + return TRUE; +} +#endif /* RANDR_12_INTERFACE */ + +#ifdef RANDR_13_INTERFACE +static Bool +get_property(xf86OutputPtr output, Atom property) +{ + return TRUE; +} +#endif /* RANDR_13_INTERFACE */ + +#ifdef RANDR_GET_CRTC_INTERFACE +static xf86CrtcPtr +get_crtc(xf86OutputPtr output) +{ + return NULL; +} +#endif + +static const xf86OutputFuncsRec output_funcs = { + .create_resources = create_resources, + .dpms = dpms, + .save = save, + .restore = restore, + .mode_valid = mode_valid, + .mode_fixup = mode_fixup, + .prepare = prepare, + .mode_set = mode_set, + .commit = commit, + .detect = detect, + .get_modes = get_modes, +#ifdef RANDR_12_INTERFACE + .set_property = set_property, +#endif +#ifdef RANDR_13_INTERFACE + .get_property = get_property, +#endif + .destroy = destroy, +#ifdef RANDR_GET_CRTC_INTERFACE + .get_crtc = get_crtc, +#endif +}; + +void +output_init(ScrnInfoPtr pScrn) +{ + modesettingPtr ms = modesettingPTR(pScrn); + xf86OutputPtr output; + drmModeResPtr res; + drmModeOutputPtr drm_output = NULL; + drmModeCrtcPtr crtc; + char *name; + int o, v, p; + + res = drmModeGetResources(ms->fd); + if (res == 0) { + DRV_ERROR("Failed drmModeGetResources\n"); + return; + } + + for (o = 0; o < res->count_outputs; o++) { + drm_output = drmModeGetOutput(ms->fd, res->outputs[o]); + if (!drm_output) + goto out; + + for (p = 0; p < drm_output->count_props; p++) { + drmModePropertyPtr prop; + + prop = drmModeGetProperty(ms->fd, drm_output->props[p]); + + name = NULL; + if (prop) { + ErrorF("VALUES %d\n",prop->count_values); + + for (v=0;v<prop->count_values;v++) + ErrorF("%s %lld\n", prop->name, prop->values[v]); + + for (v=0;v<prop->count_enums;v++) { + ErrorF("%s %s\n", prop->name, prop->enums[v].name); + if (drm_output->prop_values[p] == prop->enums[v].value) { + if (!strncmp("Connector Type", prop->name, 14)) { + ErrorF("WE'VE GOT %s\n",prop->enums[v].name); + name = xalloc(strlen(prop->enums[v].name)); + strncpy(name, prop->enums[v].name, strlen(name)); + } + } + if (name) break; + } + if (name) break; + } + } + + if (!name) + continue; + + output = xf86OutputCreate(pScrn, &output_funcs, name); + if (!output) + continue; + + free(name); + + output->possible_crtcs = drm_output->crtcs; + output->possible_clones = drm_output->clones; + output->driver_private = drm_output; + output->subpixel_order = SubPixelHorizontalRGB; + output->interlaceAllowed = FALSE; + output->doubleScanAllowed = FALSE; + } + +out: + drmModeFreeResources(res); +} |