sna_driver.c revision 42542f5f
103b705cfSriastradh/************************************************************************** 203b705cfSriastradh 303b705cfSriastradhCopyright 2001 VA Linux Systems Inc., Fremont, California. 403b705cfSriastradhCopyright © 2002 by David Dawes 503b705cfSriastradh 603b705cfSriastradhAll Rights Reserved. 703b705cfSriastradh 803b705cfSriastradhPermission is hereby granted, free of charge, to any person obtaining a 903b705cfSriastradhcopy of this software and associated documentation files (the "Software"), 1003b705cfSriastradhto deal in the Software without restriction, including without limitation 1103b705cfSriastradhon the rights to use, copy, modify, merge, publish, distribute, sub 1203b705cfSriastradhlicense, and/or sell copies of the Software, and to permit persons to whom 1303b705cfSriastradhthe Software is furnished to do so, subject to the following conditions: 1403b705cfSriastradh 1503b705cfSriastradhThe above copyright notice and this permission notice (including the next 1603b705cfSriastradhparagraph) shall be included in all copies or substantial portions of the 1703b705cfSriastradhSoftware. 1803b705cfSriastradh 1903b705cfSriastradhTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 2003b705cfSriastradhIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 2103b705cfSriastradhFITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 2203b705cfSriastradhTHE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 2303b705cfSriastradhDAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 2403b705cfSriastradhOTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 2503b705cfSriastradhUSE OR OTHER DEALINGS IN THE SOFTWARE. 2603b705cfSriastradh 2703b705cfSriastradh**************************************************************************/ 2803b705cfSriastradh 2903b705cfSriastradh/* 3003b705cfSriastradh * Authors: Jeff Hartmann <jhartmann@valinux.com> 3103b705cfSriastradh * Abraham van der Merwe <abraham@2d3d.co.za> 3203b705cfSriastradh * David Dawes <dawes@xfree86.org> 3303b705cfSriastradh * Alan Hourihane <alanh@tungstengraphics.com> 3403b705cfSriastradh */ 3503b705cfSriastradh 3603b705cfSriastradh#ifdef HAVE_CONFIG_H 3703b705cfSriastradh#include "config.h" 3803b705cfSriastradh#endif 3903b705cfSriastradh 4003b705cfSriastradh#include <assert.h> 4103b705cfSriastradh#include <string.h> 4203b705cfSriastradh#include <stdio.h> 4303b705cfSriastradh#include <unistd.h> 4403b705cfSriastradh#include <stdlib.h> 4503b705cfSriastradh#include <stdio.h> 4603b705cfSriastradh#include <errno.h> 4703b705cfSriastradh 4803b705cfSriastradh#include "sna.h" 4903b705cfSriastradh#include "sna_module.h" 5003b705cfSriastradh#include "sna_video.h" 5103b705cfSriastradh 5203b705cfSriastradh#include "intel_driver.h" 5303b705cfSriastradh#include "intel_options.h" 5403b705cfSriastradh 5542542f5fSchristos#include <xf86cmap.h> 5642542f5fSchristos#include <xf86drm.h> 5742542f5fSchristos#include <xf86RandR12.h> 5842542f5fSchristos#include <mi.h> 5942542f5fSchristos#include <micmap.h> 6042542f5fSchristos 6103b705cfSriastradh#include <sys/ioctl.h> 6203b705cfSriastradh#include <sys/fcntl.h> 6303b705cfSriastradh#include "i915_drm.h" 6403b705cfSriastradh 6503b705cfSriastradh#ifdef HAVE_VALGRIND 6603b705cfSriastradh#include <valgrind.h> 6703b705cfSriastradh#include <memcheck.h> 6803b705cfSriastradh#endif 6903b705cfSriastradh 7003b705cfSriastradh#if HAVE_DOT_GIT 7103b705cfSriastradh#include "git_version.h" 7203b705cfSriastradh#endif 7303b705cfSriastradh 7442542f5fSchristos#ifdef TEARFREE 7542542f5fSchristos#define ENABLE_TEAR_FREE TRUE 7642542f5fSchristos#else 7742542f5fSchristos#define ENABLE_TEAR_FREE FALSE 7842542f5fSchristos#endif 7942542f5fSchristos 8003b705cfSriastradhDevPrivateKeyRec sna_pixmap_key; 8103b705cfSriastradhDevPrivateKeyRec sna_gc_key; 8203b705cfSriastradhDevPrivateKeyRec sna_window_key; 8303b705cfSriastradhDevPrivateKeyRec sna_glyph_key; 8403b705cfSriastradhDevPrivateKeyRec sna_client_key; 8503b705cfSriastradh 8603b705cfSriastradhstatic void 8703b705cfSriastradhsna_load_palette(ScrnInfoPtr scrn, int numColors, int *indices, 8803b705cfSriastradh LOCO * colors, VisualPtr pVisual) 8903b705cfSriastradh{ 9003b705cfSriastradh xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); 9142542f5fSchristos int p, n, i, j; 9203b705cfSriastradh uint16_t lut_r[256], lut_g[256], lut_b[256]; 9303b705cfSriastradh 9403b705cfSriastradh DBG(("%s\n", __FUNCTION__)); 9503b705cfSriastradh 9603b705cfSriastradh for (p = 0; p < xf86_config->num_crtc; p++) { 9703b705cfSriastradh xf86CrtcPtr crtc = xf86_config->crtc[p]; 9803b705cfSriastradh 9942542f5fSchristos#define C(I,RGB) (colors[I].RGB << 8 | colors[I].RGB) 10003b705cfSriastradh switch (scrn->depth) { 10103b705cfSriastradh case 15: 10242542f5fSchristos for (n = 0; n < numColors; n++) { 10342542f5fSchristos i = indices[n]; 10403b705cfSriastradh for (j = 0; j < 8; j++) { 10542542f5fSchristos lut_r[8*i + j] = C(i, red); 10642542f5fSchristos lut_g[8*i + j] = C(i, green); 10742542f5fSchristos lut_b[8*i + j] = C(i, blue); 10803b705cfSriastradh } 10903b705cfSriastradh } 11003b705cfSriastradh break; 11103b705cfSriastradh case 16: 11242542f5fSchristos for (n = 0; n < numColors; n++) { 11342542f5fSchristos i = indices[n]; 11403b705cfSriastradh 11542542f5fSchristos if (i <= 31) { 11603b705cfSriastradh for (j = 0; j < 8; j++) { 11742542f5fSchristos lut_r[8*i + j] = C(i, red); 11842542f5fSchristos lut_b[8*i + j] = C(i, blue); 11903b705cfSriastradh } 12003b705cfSriastradh } 12103b705cfSriastradh 12242542f5fSchristos for (j = 0; j < 4; j++) 12342542f5fSchristos lut_g[4*i + j] = C(i, green); 12403b705cfSriastradh } 12503b705cfSriastradh break; 12603b705cfSriastradh default: 12742542f5fSchristos for (n = 0; n < numColors; n++) { 12842542f5fSchristos i = indices[n]; 12942542f5fSchristos lut_r[i] = C(i, red); 13042542f5fSchristos lut_g[i] = C(i, green); 13142542f5fSchristos lut_b[i] = C(i, blue); 13203b705cfSriastradh } 13303b705cfSriastradh break; 13403b705cfSriastradh } 13542542f5fSchristos#undef C 13603b705cfSriastradh 13703b705cfSriastradh /* Make the change through RandR */ 13803b705cfSriastradh#ifdef RANDR_12_INTERFACE 13903b705cfSriastradh RRCrtcGammaSet(crtc->randr_crtc, lut_r, lut_g, lut_b); 14003b705cfSriastradh#else 14103b705cfSriastradh crtc->funcs->gamma_set(crtc, lut_r, lut_g, lut_b, 256); 14203b705cfSriastradh#endif 14303b705cfSriastradh } 14403b705cfSriastradh} 14503b705cfSriastradh 14603b705cfSriastradhstatic void 14703b705cfSriastradhsna_set_fallback_mode(ScrnInfoPtr scrn) 14803b705cfSriastradh{ 14903b705cfSriastradh xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); 15003b705cfSriastradh xf86OutputPtr output = NULL; 15103b705cfSriastradh xf86CrtcPtr crtc = NULL; 15203b705cfSriastradh int n; 15303b705cfSriastradh 15403b705cfSriastradh if ((unsigned)config->compat_output < config->num_output) { 15503b705cfSriastradh output = config->output[config->compat_output]; 15603b705cfSriastradh crtc = output->crtc; 15703b705cfSriastradh } 15803b705cfSriastradh 15903b705cfSriastradh for (n = 0; n < config->num_output; n++) 16003b705cfSriastradh config->output[n]->crtc = NULL; 16103b705cfSriastradh for (n = 0; n < config->num_crtc; n++) 16203b705cfSriastradh config->crtc[n]->enabled = FALSE; 16303b705cfSriastradh 16403b705cfSriastradh if (output && crtc) { 16503b705cfSriastradh DisplayModePtr mode; 16603b705cfSriastradh 16703b705cfSriastradh output->crtc = crtc; 16803b705cfSriastradh 16903b705cfSriastradh mode = xf86OutputFindClosestMode(output, scrn->currentMode); 17003b705cfSriastradh if (mode && 17103b705cfSriastradh xf86CrtcSetModeTransform(crtc, mode, RR_Rotate_0, NULL, 0, 0)) { 17203b705cfSriastradh crtc->desiredMode = *mode; 17303b705cfSriastradh crtc->desiredMode.prev = crtc->desiredMode.next = NULL; 17403b705cfSriastradh crtc->desiredMode.name = NULL; 17503b705cfSriastradh crtc->desiredMode.PrivSize = 0; 17603b705cfSriastradh crtc->desiredMode.PrivFlags = 0; 17703b705cfSriastradh crtc->desiredMode.Private = NULL; 17803b705cfSriastradh crtc->desiredRotation = RR_Rotate_0; 17903b705cfSriastradh crtc->desiredTransformPresent = FALSE; 18003b705cfSriastradh crtc->desiredX = 0; 18103b705cfSriastradh crtc->desiredY = 0; 18203b705cfSriastradh crtc->enabled = TRUE; 18303b705cfSriastradh } 18403b705cfSriastradh } 18503b705cfSriastradh 18603b705cfSriastradh xf86DisableUnusedFunctions(scrn); 18703b705cfSriastradh#ifdef RANDR_12_INTERFACE 18803b705cfSriastradh if (get_root_window(scrn->pScreen)) 18903b705cfSriastradh xf86RandR12TellChanged(scrn->pScreen); 19003b705cfSriastradh#endif 19103b705cfSriastradh} 19203b705cfSriastradh 19342542f5fSchristosstatic Bool sna_set_desired_mode(struct sna *sna) 19403b705cfSriastradh{ 19503b705cfSriastradh ScrnInfoPtr scrn = sna->scrn; 19603b705cfSriastradh 19703b705cfSriastradh DBG(("%s\n", __FUNCTION__)); 19803b705cfSriastradh 19903b705cfSriastradh if (!xf86SetDesiredModes(scrn)) { 20003b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_WARNING, 20103b705cfSriastradh "failed to restore desired modes on VT switch\n"); 20203b705cfSriastradh sna_set_fallback_mode(scrn); 20303b705cfSriastradh } 20403b705cfSriastradh 20542542f5fSchristos sna_mode_check(sna); 20603b705cfSriastradh return TRUE; 20703b705cfSriastradh} 20803b705cfSriastradh 20903b705cfSriastradh/** 21003b705cfSriastradh * Adjust the screen pixmap for the current location of the front buffer. 21103b705cfSriastradh * This is done at EnterVT when buffers are bound as long as the resources 21203b705cfSriastradh * have already been created, but the first EnterVT happens before 21303b705cfSriastradh * CreateScreenResources. 21403b705cfSriastradh */ 21503b705cfSriastradhstatic Bool sna_create_screen_resources(ScreenPtr screen) 21603b705cfSriastradh{ 21703b705cfSriastradh struct sna *sna = to_sna_from_screen(screen); 21842542f5fSchristos PixmapPtr new_front; 21942542f5fSchristos unsigned hint; 22003b705cfSriastradh 22103b705cfSriastradh DBG(("%s(%dx%d@%d)\n", __FUNCTION__, 22203b705cfSriastradh screen->width, screen->height, screen->rootDepth)); 22303b705cfSriastradh 22403b705cfSriastradh assert(sna->scrn == xf86ScreenToScrn(screen)); 22503b705cfSriastradh assert(sna->scrn->pScreen == screen); 22603b705cfSriastradh 22742542f5fSchristos /* free the data used during miInitScreen */ 22803b705cfSriastradh free(screen->devPrivate); 22903b705cfSriastradh screen->devPrivate = NULL; 23003b705cfSriastradh 23103b705cfSriastradh sna_accel_create(sna); 23203b705cfSriastradh 23342542f5fSchristos hint = SNA_CREATE_FB; 23442542f5fSchristos if (sna->flags & SNA_IS_HOSTED) 23542542f5fSchristos hint = 0; 23642542f5fSchristos 23742542f5fSchristos new_front = screen->CreatePixmap(screen, 23842542f5fSchristos screen->width, 23942542f5fSchristos screen->height, 24042542f5fSchristos screen->rootDepth, 24142542f5fSchristos hint); 24242542f5fSchristos if (!new_front) { 24303b705cfSriastradh xf86DrvMsg(screen->myNum, X_ERROR, 24403b705cfSriastradh "[intel] Unable to create front buffer %dx%d at depth %d\n", 24503b705cfSriastradh screen->width, 24603b705cfSriastradh screen->height, 24703b705cfSriastradh screen->rootDepth); 24803b705cfSriastradh 24903b705cfSriastradh return FALSE; 25003b705cfSriastradh } 25103b705cfSriastradh 25242542f5fSchristos if (!sna_pixmap_force_to_gpu(new_front, MOVE_READ)) { 25303b705cfSriastradh xf86DrvMsg(screen->myNum, X_ERROR, 25403b705cfSriastradh "[intel] Failed to allocate video resources for front buffer %dx%d at depth %d\n", 25503b705cfSriastradh screen->width, 25603b705cfSriastradh screen->height, 25703b705cfSriastradh screen->rootDepth); 25842542f5fSchristos screen->DestroyPixmap(new_front); 25942542f5fSchristos return FALSE; 26003b705cfSriastradh } 26103b705cfSriastradh 26242542f5fSchristos screen->SetScreenPixmap(new_front); 26342542f5fSchristos assert(screen->GetScreenPixmap(screen) == new_front); 26442542f5fSchristos assert(sna->front == new_front); 26542542f5fSchristos screen->DestroyPixmap(new_front); /* transfer ownership to screen */ 26642542f5fSchristos 26742542f5fSchristos if (intel_get_master(sna->scrn)) { 26842542f5fSchristos xf86DrvMsg(screen->myNum, X_ERROR, 26942542f5fSchristos "[intel] Failed to become DRM master\n"); 27042542f5fSchristos screen->DestroyPixmap(sna->front); 27142542f5fSchristos sna->front = NULL; 27242542f5fSchristos return FALSE; 27342542f5fSchristos } 27442542f5fSchristos 27542542f5fSchristos sna_mode_set_primary(sna); 27603b705cfSriastradh 27703b705cfSriastradh /* Only preserve the fbcon, not any subsequent server regens */ 27842542f5fSchristos if (serverGeneration == 1 && (sna->flags & SNA_IS_HOSTED) == 0) 27903b705cfSriastradh sna_copy_fbcon(sna); 28003b705cfSriastradh 28142542f5fSchristos if (!sna_set_desired_mode(sna)) { 28203b705cfSriastradh xf86DrvMsg(screen->myNum, X_ERROR, 28342542f5fSchristos "[intel] Failed to set initial mode\n"); 28442542f5fSchristos screen->DestroyPixmap(sna->front); 28542542f5fSchristos sna->front = NULL; 28642542f5fSchristos return FALSE; 28703b705cfSriastradh } 28803b705cfSriastradh 28903b705cfSriastradh return TRUE; 29003b705cfSriastradh} 29103b705cfSriastradh 29242542f5fSchristosstatic Bool sna_save_screen(ScreenPtr screen, int mode) 29303b705cfSriastradh{ 29442542f5fSchristos ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 29542542f5fSchristos 29642542f5fSchristos DBG(("%s(mode=%d)\n", __FUNCTION__, mode)); 29742542f5fSchristos if (!scrn->vtSema) 29842542f5fSchristos return FALSE; 29942542f5fSchristos 30042542f5fSchristos xf86SaveScreen(screen, mode); 30142542f5fSchristos sna_crtc_config_notify(screen); 30242542f5fSchristos return TRUE; 30303b705cfSriastradh} 30403b705cfSriastradh 30542542f5fSchristosstatic void sna_dpms_set(ScrnInfoPtr scrn, int mode, int flags) 30603b705cfSriastradh{ 30742542f5fSchristos DBG(("%s(mode=%d, flags=%d)\n", __FUNCTION__, mode)); 30842542f5fSchristos if (!scrn->vtSema) 30942542f5fSchristos return; 31003b705cfSriastradh 31142542f5fSchristos xf86DPMSSet(scrn, mode, flags); 31242542f5fSchristos sna_crtc_config_notify(xf86ScrnToScreen(scrn)); 31342542f5fSchristos} 31403b705cfSriastradh 31542542f5fSchristosstatic void sna_selftest(void) 31642542f5fSchristos{ 31742542f5fSchristos sna_damage_selftest(); 31842542f5fSchristos} 31903b705cfSriastradh 32042542f5fSchristosstatic bool has_vsync(struct sna *sna) 32142542f5fSchristos{ 32242542f5fSchristos if (sna->flags & SNA_IS_HOSTED) 32303b705cfSriastradh return false; 32403b705cfSriastradh 32542542f5fSchristos return true; 32603b705cfSriastradh} 32703b705cfSriastradh 32803b705cfSriastradhstatic void sna_setup_capabilities(ScrnInfoPtr scrn, int fd) 32903b705cfSriastradh{ 33003b705cfSriastradh#if HAS_PIXMAP_SHARING && defined(DRM_CAP_PRIME) 33103b705cfSriastradh uint64_t value; 33203b705cfSriastradh 33303b705cfSriastradh scrn->capabilities = 0; 33403b705cfSriastradh if (drmGetCap(fd, DRM_CAP_PRIME, &value) == 0) { 33503b705cfSriastradh if (value & DRM_PRIME_CAP_EXPORT) 33603b705cfSriastradh scrn->capabilities |= RR_Capability_SourceOutput | RR_Capability_SinkOffload; 33703b705cfSriastradh if (value & DRM_PRIME_CAP_IMPORT) 33803b705cfSriastradh scrn->capabilities |= RR_Capability_SinkOutput; 33903b705cfSriastradh } 34003b705cfSriastradh#endif 34103b705cfSriastradh} 34203b705cfSriastradh 34342542f5fSchristosstatic int 34442542f5fSchristosnamecmp(const char *s1, const char *s2) 34542542f5fSchristos{ 34642542f5fSchristos char c1, c2; 34742542f5fSchristos 34842542f5fSchristos if (!s1 || *s1 == 0) { 34942542f5fSchristos if (!s2 || *s2 == 0) 35042542f5fSchristos return 0; 35142542f5fSchristos else 35242542f5fSchristos return 1; 35342542f5fSchristos } 35442542f5fSchristos 35542542f5fSchristos while (*s1 == '_' || *s1 == ' ' || *s1 == '\t') 35642542f5fSchristos s1++; 35742542f5fSchristos 35842542f5fSchristos while (*s2 == '_' || *s2 == ' ' || *s2 == '\t') 35942542f5fSchristos s2++; 36042542f5fSchristos 36142542f5fSchristos c1 = isupper(*s1) ? tolower(*s1) : *s1; 36242542f5fSchristos c2 = isupper(*s2) ? tolower(*s2) : *s2; 36342542f5fSchristos while (c1 == c2) { 36442542f5fSchristos if (c1 == '\0') 36542542f5fSchristos return 0; 36642542f5fSchristos 36742542f5fSchristos s1++; 36842542f5fSchristos while (*s1 == '_' || *s1 == ' ' || *s1 == '\t') 36942542f5fSchristos s1++; 37042542f5fSchristos 37142542f5fSchristos s2++; 37242542f5fSchristos while (*s2 == '_' || *s2 == ' ' || *s2 == '\t') 37342542f5fSchristos s2++; 37442542f5fSchristos 37542542f5fSchristos c1 = isupper(*s1) ? tolower(*s1) : *s1; 37642542f5fSchristos c2 = isupper(*s2) ? tolower(*s2) : *s2; 37742542f5fSchristos } 37842542f5fSchristos 37942542f5fSchristos return c1 - c2; 38042542f5fSchristos} 38142542f5fSchristos 38203b705cfSriastradhstatic Bool sna_option_cast_to_bool(struct sna *sna, int id, Bool val) 38303b705cfSriastradh{ 38442542f5fSchristos const char *str = xf86GetOptValString(sna->Options, id); 38542542f5fSchristos 38642542f5fSchristos if (str == NULL) 38742542f5fSchristos return val; 38842542f5fSchristos 38942542f5fSchristos if (*str == '\0') 39042542f5fSchristos return TRUE; 39142542f5fSchristos 39242542f5fSchristos if (namecmp(str, "1") == 0) 39342542f5fSchristos return TRUE; 39442542f5fSchristos if (namecmp(str, "on") == 0) 39542542f5fSchristos return TRUE; 39642542f5fSchristos if (namecmp(str, "true") == 0) 39742542f5fSchristos return TRUE; 39842542f5fSchristos if (namecmp(str, "yes") == 0) 39942542f5fSchristos return TRUE; 40042542f5fSchristos 40142542f5fSchristos if (namecmp(str, "0") == 0) 40242542f5fSchristos return FALSE; 40342542f5fSchristos if (namecmp(str, "off") == 0) 40442542f5fSchristos return FALSE; 40542542f5fSchristos if (namecmp(str, "false") == 0) 40642542f5fSchristos return FALSE; 40742542f5fSchristos if (namecmp(str, "no") == 0) 40842542f5fSchristos return FALSE; 40942542f5fSchristos 41042542f5fSchristos return val; 41142542f5fSchristos} 41242542f5fSchristos 41342542f5fSchristosstatic unsigned sna_option_cast_to_unsigned(struct sna *sna, int id, unsigned val) 41442542f5fSchristos{ 41542542f5fSchristos const char *str = xf86GetOptValString(sna->Options, id); 41642542f5fSchristos unsigned v; 41742542f5fSchristos 41842542f5fSchristos if (str == NULL || *str == '\0') 41942542f5fSchristos return val; 42042542f5fSchristos 42142542f5fSchristos if (namecmp(str, "on") == 0) 42242542f5fSchristos return val; 42342542f5fSchristos if (namecmp(str, "true") == 0) 42442542f5fSchristos return val; 42542542f5fSchristos if (namecmp(str, "yes") == 0) 42642542f5fSchristos return val; 42742542f5fSchristos 42842542f5fSchristos if (namecmp(str, "0") == 0) 42942542f5fSchristos return 0; 43042542f5fSchristos if (namecmp(str, "off") == 0) 43142542f5fSchristos return 0; 43242542f5fSchristos if (namecmp(str, "false") == 0) 43342542f5fSchristos return 0; 43442542f5fSchristos if (namecmp(str, "no") == 0) 43542542f5fSchristos return 0; 43642542f5fSchristos 43742542f5fSchristos v = atoi(str); 43842542f5fSchristos if (v) 43942542f5fSchristos return v; 44042542f5fSchristos 44103b705cfSriastradh return val; 44203b705cfSriastradh} 44303b705cfSriastradh 44403b705cfSriastradhstatic Bool fb_supports_depth(int fd, int depth) 44503b705cfSriastradh{ 44603b705cfSriastradh struct drm_i915_gem_create create; 44703b705cfSriastradh struct drm_mode_fb_cmd fb; 44842542f5fSchristos struct drm_mode_card_res res; 44903b705cfSriastradh Bool ret; 45003b705cfSriastradh 45142542f5fSchristos memset(&res, 0, sizeof(res)); 45242542f5fSchristos (void)drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res); 45342542f5fSchristos if (res.count_crtcs == 0) 45442542f5fSchristos return TRUE; 45542542f5fSchristos 45603b705cfSriastradh VG_CLEAR(create); 45703b705cfSriastradh create.handle = 0; 45803b705cfSriastradh create.size = 4096; 45903b705cfSriastradh if (drmIoctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create)) 46003b705cfSriastradh return FALSE; 46103b705cfSriastradh 46203b705cfSriastradh VG_CLEAR(fb); 46303b705cfSriastradh fb.width = 64; 46403b705cfSriastradh fb.height = 16; 46503b705cfSriastradh fb.pitch = 256; 46603b705cfSriastradh fb.bpp = depth <= 8 ? 8 : depth <= 16 ? 16 : 32; 46703b705cfSriastradh fb.depth = depth; 46803b705cfSriastradh fb.handle = create.handle; 46903b705cfSriastradh 47003b705cfSriastradh ret = drmIoctl(fd, DRM_IOCTL_MODE_ADDFB, &fb) == 0; 47103b705cfSriastradh drmModeRmFB(fd, fb.fb_id); 47203b705cfSriastradh 47342542f5fSchristos (void)drmIoctl(fd, DRM_IOCTL_GEM_CLOSE, &create.handle); 47403b705cfSriastradh 47503b705cfSriastradh return ret; 47603b705cfSriastradh} 47703b705cfSriastradh 47842542f5fSchristosstatic void setup_dri(struct sna *sna) 47942542f5fSchristos{ 48042542f5fSchristos unsigned level; 48142542f5fSchristos 48242542f5fSchristos sna->dri2.available = false; 48342542f5fSchristos sna->dri3.available = false; 48442542f5fSchristos 48542542f5fSchristos level = sna_option_cast_to_unsigned(sna, OPTION_DRI, ~0); 48642542f5fSchristos#if HAVE_DRI3 48742542f5fSchristos if (level >= 3) 48842542f5fSchristos sna->dri3.available = !!xf86LoadSubModule(sna->scrn, "dri3"); 48942542f5fSchristos#endif 49042542f5fSchristos#if HAVE_DRI2 49142542f5fSchristos if (level >= 2) 49242542f5fSchristos sna->dri2.available = !!xf86LoadSubModule(sna->scrn, "dri2"); 49342542f5fSchristos#endif 49442542f5fSchristos} 49542542f5fSchristos 49642542f5fSchristosstatic bool enable_tear_free(struct sna *sna) 49742542f5fSchristos{ 49842542f5fSchristos if (sna->flags & SNA_LINEAR_FB) 49942542f5fSchristos return false; 50042542f5fSchristos 50142542f5fSchristos /* Under certain conditions, we should enable TearFree by default, 50242542f5fSchristos * for example when the hardware requires pageflipping to run within 50342542f5fSchristos * its power/performance budget. 50442542f5fSchristos */ 50542542f5fSchristos if (sna_mode_wants_tear_free(sna)) 50642542f5fSchristos return true; 50742542f5fSchristos 50842542f5fSchristos return ENABLE_TEAR_FREE; 50942542f5fSchristos} 51042542f5fSchristos 51142542f5fSchristosstatic void setup_tear_free(struct sna *sna) 51242542f5fSchristos{ 51342542f5fSchristos MessageType from; 51442542f5fSchristos Bool enable; 51542542f5fSchristos 51642542f5fSchristos if (sna->flags & SNA_LINEAR_FB) 51742542f5fSchristos return; 51842542f5fSchristos 51942542f5fSchristos if ((sna->flags & SNA_HAS_FLIP) == 0) { 52042542f5fSchristos from = X_PROBED; 52142542f5fSchristos goto done; 52242542f5fSchristos } 52342542f5fSchristos 52442542f5fSchristos if (!xf86GetOptValBool(sna->Options, OPTION_TEAR_FREE, &enable)) { 52542542f5fSchristos enable = enable_tear_free(sna); 52642542f5fSchristos from = X_DEFAULT; 52742542f5fSchristos } else 52842542f5fSchristos from = X_CONFIG; 52942542f5fSchristos 53042542f5fSchristos if (enable) 53142542f5fSchristos sna->flags |= SNA_TEAR_FREE; 53242542f5fSchristos 53342542f5fSchristosdone: 53442542f5fSchristos xf86DrvMsg(sna->scrn->scrnIndex, from, "TearFree %sabled\n", 53542542f5fSchristos sna->flags & SNA_TEAR_FREE ? "en" : "dis"); 53642542f5fSchristos} 53742542f5fSchristos 53803b705cfSriastradh/** 53903b705cfSriastradh * This is called before ScreenInit to do any require probing of screen 54003b705cfSriastradh * configuration. 54103b705cfSriastradh * 54203b705cfSriastradh * This code generally covers probing, module loading, option handling 54303b705cfSriastradh * card mapping, and RandR setup. 54403b705cfSriastradh * 54503b705cfSriastradh * Since xf86InitialConfiguration ends up requiring that we set video modes 54603b705cfSriastradh * in order to detect configuration, we end up having to do a lot of driver 54703b705cfSriastradh * setup (talking to the DRM, mapping the device, etc.) in this function. 54803b705cfSriastradh * As a result, we want to set up that server initialization once rather 54903b705cfSriastradh * that doing it per generation. 55003b705cfSriastradh */ 55142542f5fSchristosstatic Bool sna_pre_init(ScrnInfoPtr scrn, int probe) 55203b705cfSriastradh{ 55303b705cfSriastradh struct sna *sna; 55403b705cfSriastradh char buf[1024]; 55503b705cfSriastradh rgb defaultWeight = { 0, 0, 0 }; 55603b705cfSriastradh EntityInfoPtr pEnt; 55703b705cfSriastradh Gamma zeros = { 0.0, 0.0, 0.0 }; 55803b705cfSriastradh int fd; 55903b705cfSriastradh 56003b705cfSriastradh DBG(("%s flags=%x, numEntities=%d\n", 56142542f5fSchristos __FUNCTION__, probe, scrn->numEntities)); 56203b705cfSriastradh 56303b705cfSriastradh if (scrn->numEntities != 1) 56403b705cfSriastradh return FALSE; 56503b705cfSriastradh 56603b705cfSriastradh pEnt = xf86GetEntityInfo(scrn->entityList[0]); 56742542f5fSchristos if (pEnt == NULL) { 56842542f5fSchristos ERR(("%s: no EntityInfo found for scrn\n", __FUNCTION__)); 56903b705cfSriastradh return FALSE; 57042542f5fSchristos } 57103b705cfSriastradh 57203b705cfSriastradh if (pEnt->location.type != BUS_PCI 57303b705cfSriastradh#ifdef XSERVER_PLATFORM_BUS 57403b705cfSriastradh && pEnt->location.type != BUS_PLATFORM 57503b705cfSriastradh#endif 57642542f5fSchristos ) { 57742542f5fSchristos ERR(("%s: invalid EntityInfo found for scrn, location=%d\n", __FUNCTION__, pEnt->location.type)); 57803b705cfSriastradh return FALSE; 57942542f5fSchristos } 58003b705cfSriastradh 58142542f5fSchristos if (probe & PROBE_DETECT) 58203b705cfSriastradh return TRUE; 58303b705cfSriastradh 58403b705cfSriastradh sna_selftest(); 58503b705cfSriastradh 58642542f5fSchristos probe = 0; 58742542f5fSchristos if (((uintptr_t)scrn->driverPrivate) & 3) { 58803b705cfSriastradh if (posix_memalign((void **)&sna, 4096, sizeof(*sna))) 58903b705cfSriastradh return FALSE; 59003b705cfSriastradh 59103b705cfSriastradh memset(sna, 0, sizeof(*sna)); /* should be unnecessary */ 59242542f5fSchristos probe = (uintptr_t)scrn->driverPrivate & 1; 59342542f5fSchristos sna->info = (void *)((uintptr_t)scrn->driverPrivate & ~3); 59403b705cfSriastradh scrn->driverPrivate = sna; 59503b705cfSriastradh 59603b705cfSriastradh sna->cpu_features = sna_cpu_detect(); 59742542f5fSchristos sna->acpi.fd = sna_acpi_open(); 59803b705cfSriastradh } 59903b705cfSriastradh sna = to_sna(scrn); 60003b705cfSriastradh sna->scrn = scrn; 60103b705cfSriastradh sna->pEnt = pEnt; 60242542f5fSchristos sna->flags = probe; 60303b705cfSriastradh 60403b705cfSriastradh scrn->displayWidth = 640; /* default it */ 60503b705cfSriastradh 60603b705cfSriastradh scrn->monitor = scrn->confScreen->monitor; 60703b705cfSriastradh scrn->progClock = TRUE; 60803b705cfSriastradh scrn->rgbBits = 8; 60903b705cfSriastradh 61003b705cfSriastradh fd = intel_get_device(scrn); 61103b705cfSriastradh if (fd == -1) { 61203b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_ERROR, 61303b705cfSriastradh "Failed to claim DRM device.\n"); 61403b705cfSriastradh goto cleanup; 61503b705cfSriastradh } 61603b705cfSriastradh 61703b705cfSriastradh /* Sanity check */ 61803b705cfSriastradh if (hosted() && (sna->flags & SNA_IS_HOSTED) == 0) { 61903b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_ERROR, 62003b705cfSriastradh "Failed to setup hosted device.\n"); 62103b705cfSriastradh goto cleanup; 62203b705cfSriastradh } 62303b705cfSriastradh 62442542f5fSchristos intel_detect_chipset(scrn, pEnt); 62542542f5fSchristos xf86DrvMsg(scrn->scrnIndex, X_PROBED, "CPU: %s\n", 62642542f5fSchristos sna_cpu_features_to_string(sna->cpu_features, buf)); 62703b705cfSriastradh 62842542f5fSchristos if (!xf86SetDepthBpp(scrn, 24, 0, 0, 62903b705cfSriastradh Support32bppFb | 63003b705cfSriastradh SupportConvert24to32 | PreferConvert24to32)) 63103b705cfSriastradh goto cleanup; 63203b705cfSriastradh 63303b705cfSriastradh switch (scrn->depth) { 63403b705cfSriastradh case 8: 63503b705cfSriastradh case 15: 63603b705cfSriastradh case 16: 63703b705cfSriastradh case 24: 63803b705cfSriastradh case 30: 63942542f5fSchristos if ((sna->flags & SNA_IS_HOSTED) || 64042542f5fSchristos fb_supports_depth(fd, scrn->depth)) 64103b705cfSriastradh break; 64203b705cfSriastradh default: 64303b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_ERROR, 64403b705cfSriastradh "Given depth (%d) is not supported by the Intel driver and this chipset.\n", 64503b705cfSriastradh scrn->depth); 64603b705cfSriastradh goto cleanup; 64703b705cfSriastradh } 64803b705cfSriastradh xf86PrintDepthBpp(scrn); 64903b705cfSriastradh 65003b705cfSriastradh if (!xf86SetWeight(scrn, defaultWeight, defaultWeight)) 65103b705cfSriastradh goto cleanup; 65203b705cfSriastradh if (!xf86SetDefaultVisual(scrn, -1)) 65303b705cfSriastradh goto cleanup; 65403b705cfSriastradh 65503b705cfSriastradh sna->Options = intel_options_get(scrn); 65603b705cfSriastradh if (sna->Options == NULL) 65703b705cfSriastradh goto cleanup; 65803b705cfSriastradh 65903b705cfSriastradh sna_setup_capabilities(scrn, fd); 66003b705cfSriastradh 66142542f5fSchristos kgem_init(&sna->kgem, fd, 66242542f5fSchristos xf86GetPciInfoForEntity(pEnt->index), 66342542f5fSchristos sna->info->gen); 66403b705cfSriastradh if (xf86ReturnOptValBool(sna->Options, OPTION_ACCEL_DISABLE, FALSE) || 66503b705cfSriastradh !sna_option_cast_to_bool(sna, OPTION_ACCEL_METHOD, TRUE)) { 66603b705cfSriastradh xf86DrvMsg(sna->scrn->scrnIndex, X_CONFIG, 66703b705cfSriastradh "Disabling hardware acceleration.\n"); 66803b705cfSriastradh sna->kgem.wedged = true; 66903b705cfSriastradh } 67003b705cfSriastradh 67103b705cfSriastradh if (xf86ReturnOptValBool(sna->Options, OPTION_TILING_FB, FALSE)) 67242542f5fSchristos sna->flags |= SNA_LINEAR_FB; 67342542f5fSchristos 67442542f5fSchristos if (xf86ReturnOptValBool(sna->Options, OPTION_DELETE_DP12, FALSE)) 67542542f5fSchristos sna->flags |= SNA_REMOVE_OUTPUTS; 67603b705cfSriastradh 67703b705cfSriastradh if (!xf86ReturnOptValBool(sna->Options, OPTION_SWAPBUFFERS_WAIT, TRUE)) 67803b705cfSriastradh sna->flags |= SNA_NO_WAIT; 67942542f5fSchristos DBG(("%s: swapbuffer wait? %s\n", __FUNCTION__, sna->flags & SNA_NO_WAIT ? "disabled" : "enabled")); 68042542f5fSchristos 68142542f5fSchristos if (!has_vsync(sna) || 68242542f5fSchristos !xf86ReturnOptValBool(sna->Options, OPTION_VSYNC, TRUE)) 68342542f5fSchristos sna->flags |= SNA_NO_VSYNC; 68442542f5fSchristos DBG(("%s: vsync? %s\n", __FUNCTION__, sna->flags & SNA_NO_VSYNC ? "disabled" : "enabled")); 68542542f5fSchristos 68642542f5fSchristos if (sna->flags & SNA_IS_HOSTED || 68742542f5fSchristos !xf86ReturnOptValBool(sna->Options, OPTION_PAGEFLIP, TRUE)) 68803b705cfSriastradh sna->flags |= SNA_NO_FLIP; 68942542f5fSchristos DBG(("%s: page flips? %s\n", __FUNCTION__, sna->flags & SNA_NO_FLIP ? "disabled" : "enabled")); 69003b705cfSriastradh 69142542f5fSchristos if ((sna->flags & (SNA_NO_VSYNC | SNA_NO_FLIP | SNA_NO_WAIT)) == 0 && 69242542f5fSchristos xf86ReturnOptValBool(sna->Options, OPTION_TRIPLE_BUFFER, TRUE)) 69342542f5fSchristos sna->flags |= SNA_TRIPLE_BUFFER; 69442542f5fSchristos DBG(("%s: triple buffer? %s\n", __FUNCTION__, sna->flags & SNA_TRIPLE_BUFFER ? "enabled" : "disabled")); 69503b705cfSriastradh 69642542f5fSchristos if (xf86ReturnOptValBool(sna->Options, OPTION_CRTC_PIXMAPS, FALSE)) { 69742542f5fSchristos xf86DrvMsg(scrn->scrnIndex, X_CONFIG, "Forcing per-crtc-pixmaps.\n"); 69842542f5fSchristos sna->flags |= SNA_FORCE_SHADOW; 69942542f5fSchristos } 70003b705cfSriastradh 70103b705cfSriastradh if (!sna_mode_pre_init(scrn, sna)) { 70203b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_ERROR, 70303b705cfSriastradh "No outputs and no modes.\n"); 70403b705cfSriastradh goto cleanup; 70503b705cfSriastradh } 70603b705cfSriastradh scrn->currentMode = scrn->modes; 70703b705cfSriastradh 70842542f5fSchristos setup_tear_free(sna); 70942542f5fSchristos 71003b705cfSriastradh xf86SetGamma(scrn, zeros); 71103b705cfSriastradh xf86SetDpi(scrn, 0, 0); 71203b705cfSriastradh 71342542f5fSchristos setup_dri(sna); 71442542f5fSchristos 71542542f5fSchristos sna->present.available = false; 71642542f5fSchristos if (xf86ReturnOptValBool(sna->Options, OPTION_PRESENT, TRUE)) { 71742542f5fSchristos#if HAVE_PRESENT 71842542f5fSchristos sna->present.available = !!xf86LoadSubModule(scrn, "present"); 71942542f5fSchristos#endif 72042542f5fSchristos } 72142542f5fSchristos 72242542f5fSchristos sna_acpi_init(sna); 72303b705cfSriastradh 72403b705cfSriastradh return TRUE; 72503b705cfSriastradh 72603b705cfSriastradhcleanup: 72742542f5fSchristos scrn->driverPrivate = (void *)((uintptr_t)sna->info | (sna->flags & SNA_IS_SLAVED) | 2); 72803b705cfSriastradh free(sna); 72903b705cfSriastradh return FALSE; 73003b705cfSriastradh} 73103b705cfSriastradh 73242542f5fSchristosstatic bool has_shadow(struct sna *sna) 73342542f5fSchristos{ 73442542f5fSchristos if (!sna->mode.shadow_damage) 73542542f5fSchristos return false; 73642542f5fSchristos 73742542f5fSchristos if (RegionNil(DamageRegion(sna->mode.shadow_damage))) 73842542f5fSchristos return false; 73942542f5fSchristos 74042542f5fSchristos return sna->mode.flip_active == 0; 74142542f5fSchristos} 74242542f5fSchristos 74303b705cfSriastradhstatic void 74403b705cfSriastradhsna_block_handler(BLOCKHANDLER_ARGS_DECL) 74503b705cfSriastradh{ 74603b705cfSriastradh#ifndef XF86_SCRN_INTERFACE 74703b705cfSriastradh struct sna *sna = to_sna(xf86Screens[arg]); 74803b705cfSriastradh#else 74903b705cfSriastradh struct sna *sna = to_sna_from_screen(arg); 75003b705cfSriastradh#endif 75103b705cfSriastradh struct timeval **tv = timeout; 75203b705cfSriastradh 75303b705cfSriastradh DBG(("%s (tv=%ld.%06ld)\n", __FUNCTION__, 75403b705cfSriastradh *tv ? (*tv)->tv_sec : -1, *tv ? (*tv)->tv_usec : 0)); 75503b705cfSriastradh 75603b705cfSriastradh sna->BlockHandler(BLOCKHANDLER_ARGS); 75703b705cfSriastradh 75842542f5fSchristos if (*tv == NULL || ((*tv)->tv_usec | (*tv)->tv_sec) || has_shadow(sna)) 75903b705cfSriastradh sna_accel_block_handler(sna, tv); 76003b705cfSriastradh} 76103b705cfSriastradh 76203b705cfSriastradhstatic void 76303b705cfSriastradhsna_wakeup_handler(WAKEUPHANDLER_ARGS_DECL) 76403b705cfSriastradh{ 76503b705cfSriastradh#ifndef XF86_SCRN_INTERFACE 76603b705cfSriastradh struct sna *sna = to_sna(xf86Screens[arg]); 76703b705cfSriastradh#else 76803b705cfSriastradh struct sna *sna = to_sna_from_screen(arg); 76903b705cfSriastradh#endif 77003b705cfSriastradh 77103b705cfSriastradh DBG(("%s\n", __FUNCTION__)); 77203b705cfSriastradh 77303b705cfSriastradh /* despite all appearances, result is just a signed int */ 77403b705cfSriastradh if ((int)result < 0) 77503b705cfSriastradh return; 77603b705cfSriastradh 77742542f5fSchristos sna_acpi_wakeup(sna, read_mask); 77842542f5fSchristos 77903b705cfSriastradh sna->WakeupHandler(WAKEUPHANDLER_ARGS); 78003b705cfSriastradh 78103b705cfSriastradh sna_accel_wakeup_handler(sna); 78203b705cfSriastradh 78303b705cfSriastradh if (FD_ISSET(sna->kgem.fd, (fd_set*)read_mask)) 78403b705cfSriastradh sna_mode_wakeup(sna); 78503b705cfSriastradh} 78603b705cfSriastradh 78703b705cfSriastradh#if HAVE_UDEV 78803b705cfSriastradhstatic void 78903b705cfSriastradhsna_handle_uevents(int fd, void *closure) 79003b705cfSriastradh{ 79142542f5fSchristos struct sna *sna = closure; 79203b705cfSriastradh struct udev_device *dev; 79342542f5fSchristos const char *str; 79403b705cfSriastradh struct stat s; 79503b705cfSriastradh dev_t udev_devnum; 79603b705cfSriastradh 79703b705cfSriastradh DBG(("%s\n", __FUNCTION__)); 79803b705cfSriastradh 79903b705cfSriastradh dev = udev_monitor_receive_device(sna->uevent_monitor); 80003b705cfSriastradh if (!dev) 80103b705cfSriastradh return; 80203b705cfSriastradh 80303b705cfSriastradh udev_devnum = udev_device_get_devnum(dev); 80442542f5fSchristos if (fstat(sna->kgem.fd, &s) || memcmp(&s.st_rdev, &udev_devnum, sizeof (dev_t))) { 80503b705cfSriastradh udev_device_unref(dev); 80603b705cfSriastradh return; 80703b705cfSriastradh } 80803b705cfSriastradh 80942542f5fSchristos str = udev_device_get_property_value(dev, "HOTPLUG"); 81042542f5fSchristos if (str && atoi(str) == 1) { 81142542f5fSchristos ScrnInfoPtr scrn = sna->scrn; 81203b705cfSriastradh 81342542f5fSchristos DBG(("%s: hotplug event (vtSema?=%d)\n", __FUNCTION__, scrn->vtSema)); 81403b705cfSriastradh 81542542f5fSchristos if (scrn->vtSema) { 81642542f5fSchristos sna_mode_discover(sna); 81742542f5fSchristos sna_mode_check(sna); 81803b705cfSriastradh RRGetInfo(xf86ScrnToScreen(scrn), TRUE); 81903b705cfSriastradh } else 82003b705cfSriastradh sna->flags |= SNA_REPROBE; 82103b705cfSriastradh } 82203b705cfSriastradh 82303b705cfSriastradh udev_device_unref(dev); 82403b705cfSriastradh} 82503b705cfSriastradh 82603b705cfSriastradhstatic void 82742542f5fSchristossna_uevent_init(struct sna *sna) 82803b705cfSriastradh{ 82903b705cfSriastradh struct udev *u; 83003b705cfSriastradh struct udev_monitor *mon; 83103b705cfSriastradh MessageType from = X_CONFIG; 83203b705cfSriastradh 83303b705cfSriastradh if (sna->flags & SNA_IS_HOSTED) 83403b705cfSriastradh return; 83503b705cfSriastradh 83603b705cfSriastradh DBG(("%s\n", __FUNCTION__)); 83703b705cfSriastradh 83803b705cfSriastradh /* RandR will be disabled if Xinerama is active, and so generating 83903b705cfSriastradh * RR hotplug events is then verboten. 84003b705cfSriastradh */ 84103b705cfSriastradh if (!dixPrivateKeyRegistered(rrPrivKey)) 84242542f5fSchristos goto out; 84303b705cfSriastradh 84442542f5fSchristos u = NULL; 84542542f5fSchristos if (xf86ReturnOptValBool(sna->Options, OPTION_HOTPLUG, TRUE)) 84642542f5fSchristos u = udev_new(); 84703b705cfSriastradh if (!u) 84842542f5fSchristos goto out; 84942542f5fSchristos 85042542f5fSchristos from = X_DEFAULT; 85103b705cfSriastradh 85203b705cfSriastradh mon = udev_monitor_new_from_netlink(u, "udev"); 85342542f5fSchristos if (!mon) 85442542f5fSchristos goto err_dev; 85503b705cfSriastradh 85642542f5fSchristos if (udev_monitor_filter_add_match_subsystem_devtype(mon, "drm", "drm_minor") < 0) 85742542f5fSchristos goto err_monitor; 85803b705cfSriastradh 85942542f5fSchristos if (udev_monitor_enable_receiving(mon) < 0) 86042542f5fSchristos goto err_monitor; 86103b705cfSriastradh 86242542f5fSchristos sna->uevent_handler = xf86AddGeneralHandler(udev_monitor_get_fd(mon), 86342542f5fSchristos sna_handle_uevents, sna); 86442542f5fSchristos if (!sna->uevent_handler) 86542542f5fSchristos goto err_monitor; 86603b705cfSriastradh 86742542f5fSchristos sna->uevent_monitor = mon; 86842542f5fSchristosout: 86942542f5fSchristos xf86DrvMsg(sna->scrn->scrnIndex, from, "display hotplug detection %s\n", 87042542f5fSchristos sna->uevent_monitor ? "enabled" : "disabled"); 87142542f5fSchristos return; 87242542f5fSchristos 87342542f5fSchristoserr_monitor: 87442542f5fSchristos udev_monitor_unref(mon); 87542542f5fSchristoserr_dev: 87642542f5fSchristos udev_unref(u); 87742542f5fSchristos goto out; 87803b705cfSriastradh} 87903b705cfSriastradh 88003b705cfSriastradhstatic void 88142542f5fSchristossna_uevent_fini(struct sna *sna) 88203b705cfSriastradh{ 88303b705cfSriastradh struct udev *u; 88403b705cfSriastradh 88503b705cfSriastradh if (sna->uevent_handler == NULL) 88603b705cfSriastradh return; 88703b705cfSriastradh 88803b705cfSriastradh xf86RemoveGeneralHandler(sna->uevent_handler); 88903b705cfSriastradh 89003b705cfSriastradh u = udev_monitor_get_udev(sna->uevent_monitor); 89103b705cfSriastradh udev_monitor_unref(sna->uevent_monitor); 89203b705cfSriastradh udev_unref(u); 89303b705cfSriastradh 89403b705cfSriastradh sna->uevent_handler = NULL; 89503b705cfSriastradh sna->uevent_monitor = NULL; 89603b705cfSriastradh 89703b705cfSriastradh DBG(("%s: removed uvent handler\n", __FUNCTION__)); 89803b705cfSriastradh} 89903b705cfSriastradh#else 90042542f5fSchristosstatic void sna_uevent_init(struct sna *sna) { } 90142542f5fSchristosstatic void sna_uevent_fini(struct sna *sna) { } 90203b705cfSriastradh#endif /* HAVE_UDEV */ 90303b705cfSriastradh 90403b705cfSriastradhstatic void sna_leave_vt(VT_FUNC_ARGS_DECL) 90503b705cfSriastradh{ 90603b705cfSriastradh SCRN_INFO_PTR(arg); 90742542f5fSchristos struct sna *sna = to_sna(scrn); 90803b705cfSriastradh 90903b705cfSriastradh DBG(("%s\n", __FUNCTION__)); 91003b705cfSriastradh 91142542f5fSchristos sna_accel_leave(sna); 91242542f5fSchristos sna_mode_reset(sna); 91303b705cfSriastradh 91403b705cfSriastradh if (intel_put_master(scrn)) 91503b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_WARNING, 91603b705cfSriastradh "drmDropMaster failed: %s\n", strerror(errno)); 91703b705cfSriastradh} 91803b705cfSriastradh 91903b705cfSriastradhstatic Bool sna_early_close_screen(CLOSE_SCREEN_ARGS_DECL) 92003b705cfSriastradh{ 92103b705cfSriastradh ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 92203b705cfSriastradh struct sna *sna = to_sna(scrn); 92303b705cfSriastradh 92403b705cfSriastradh DBG(("%s\n", __FUNCTION__)); 92503b705cfSriastradh 92603b705cfSriastradh /* XXX Note that we will leak kernel resources if !vtSema */ 92703b705cfSriastradh 92842542f5fSchristos sna_uevent_fini(sna); 92903b705cfSriastradh sna_mode_close(sna); 93003b705cfSriastradh 93142542f5fSchristos if (sna->present.open) { 93242542f5fSchristos sna_present_close(sna, screen); 93342542f5fSchristos sna->present.open = false; 93442542f5fSchristos } 93542542f5fSchristos 93642542f5fSchristos if (sna->dri3.open) { 93742542f5fSchristos sna_dri3_close(sna, screen); 93842542f5fSchristos sna->dri3.open = false; 93942542f5fSchristos } 94042542f5fSchristos 94142542f5fSchristos if (sna->dri2.open) { 94242542f5fSchristos sna_dri2_close(sna, screen); 94342542f5fSchristos sna->dri2.open = false; 94403b705cfSriastradh } 94503b705cfSriastradh 94603b705cfSriastradh if (sna->front) { 94703b705cfSriastradh screen->DestroyPixmap(sna->front); 94803b705cfSriastradh sna->front = NULL; 94903b705cfSriastradh } 95003b705cfSriastradh 95103b705cfSriastradh if (scrn->vtSema) { 95203b705cfSriastradh intel_put_master(scrn); 95303b705cfSriastradh scrn->vtSema = FALSE; 95403b705cfSriastradh } 95503b705cfSriastradh 95603b705cfSriastradh return sna->CloseScreen(CLOSE_SCREEN_ARGS); 95703b705cfSriastradh} 95803b705cfSriastradh 95903b705cfSriastradhstatic Bool sna_late_close_screen(CLOSE_SCREEN_ARGS_DECL) 96003b705cfSriastradh{ 96103b705cfSriastradh struct sna *sna = to_sna_from_screen(screen); 96203b705cfSriastradh DepthPtr depths; 96303b705cfSriastradh int d; 96403b705cfSriastradh 96503b705cfSriastradh DBG(("%s\n", __FUNCTION__)); 96603b705cfSriastradh 96703b705cfSriastradh sna_accel_close(sna); 96842542f5fSchristos sna_video_close(sna); 96903b705cfSriastradh 97003b705cfSriastradh depths = screen->allowedDepths; 97103b705cfSriastradh for (d = 0; d < screen->numDepths; d++) 97203b705cfSriastradh free(depths[d].vids); 97303b705cfSriastradh free(depths); 97403b705cfSriastradh 97503b705cfSriastradh free(screen->visuals); 97603b705cfSriastradh 97703b705cfSriastradh return TRUE; 97803b705cfSriastradh} 97903b705cfSriastradh 98003b705cfSriastradhstatic Bool 98103b705cfSriastradhsna_register_all_privates(void) 98203b705cfSriastradh{ 98303b705cfSriastradh#if HAS_DIXREGISTERPRIVATEKEY 98403b705cfSriastradh if (!dixRegisterPrivateKey(&sna_pixmap_key, PRIVATE_PIXMAP, 98503b705cfSriastradh 3*sizeof(void *))) 98603b705cfSriastradh return FALSE; 98703b705cfSriastradh 98803b705cfSriastradh if (!dixRegisterPrivateKey(&sna_gc_key, PRIVATE_GC, 98903b705cfSriastradh sizeof(FbGCPrivate))) 99003b705cfSriastradh return FALSE; 99103b705cfSriastradh 99203b705cfSriastradh if (!dixRegisterPrivateKey(&sna_glyph_key, PRIVATE_GLYPH, 99303b705cfSriastradh sizeof(struct sna_glyph))) 99403b705cfSriastradh return FALSE; 99503b705cfSriastradh 99603b705cfSriastradh if (!dixRegisterPrivateKey(&sna_window_key, PRIVATE_WINDOW, 99703b705cfSriastradh 3*sizeof(void *))) 99803b705cfSriastradh return FALSE; 99903b705cfSriastradh 100003b705cfSriastradh if (!dixRegisterPrivateKey(&sna_client_key, PRIVATE_CLIENT, 100103b705cfSriastradh sizeof(struct sna_client))) 100203b705cfSriastradh return FALSE; 100303b705cfSriastradh#else 100403b705cfSriastradh if (!dixRequestPrivate(&sna_pixmap_key, 3*sizeof(void *))) 100503b705cfSriastradh return FALSE; 100603b705cfSriastradh 100703b705cfSriastradh if (!dixRequestPrivate(&sna_gc_key, sizeof(FbGCPrivate))) 100803b705cfSriastradh return FALSE; 100903b705cfSriastradh 101003b705cfSriastradh if (!dixRequestPrivate(&sna_glyph_key, sizeof(struct sna_glyph))) 101103b705cfSriastradh return FALSE; 101203b705cfSriastradh 101303b705cfSriastradh if (!dixRequestPrivate(&sna_window_key, 3*sizeof(void *))) 101403b705cfSriastradh return FALSE; 101503b705cfSriastradh 101603b705cfSriastradh if (!dixRequestPrivate(&sna_client_key, sizeof(struct sna_client))) 101703b705cfSriastradh return FALSE; 101803b705cfSriastradh#endif 101903b705cfSriastradh 102003b705cfSriastradh return TRUE; 102103b705cfSriastradh} 102203b705cfSriastradh 102342542f5fSchristosstatic void sna_dri_init(struct sna *sna, ScreenPtr screen) 102442542f5fSchristos{ 102542542f5fSchristos char str[128] = ""; 102642542f5fSchristos 102742542f5fSchristos if (sna->dri2.available) 102842542f5fSchristos sna->dri2.open = sna_dri2_open(sna, screen); 102942542f5fSchristos if (sna->dri2.open) 103042542f5fSchristos strcat(str, "DRI2 "); 103142542f5fSchristos 103242542f5fSchristos if (sna->dri3.available) 103342542f5fSchristos sna->dri3.open = sna_dri3_open(sna, screen); 103442542f5fSchristos if (sna->dri3.open) 103542542f5fSchristos strcat(str, "DRI3 "); 103642542f5fSchristos 103742542f5fSchristos if (*str) 103842542f5fSchristos xf86DrvMsg(sna->scrn->scrnIndex, X_INFO, 103942542f5fSchristos "direct rendering: %senabled\n", str); 104042542f5fSchristos} 104142542f5fSchristos 104203b705cfSriastradhstatic size_t 104303b705cfSriastradhagp_aperture_size(struct pci_device *dev, int gen) 104403b705cfSriastradh{ 104503b705cfSriastradh return dev->regions[gen < 030 ? 0 : 2].size; 104603b705cfSriastradh} 104703b705cfSriastradh 104803b705cfSriastradhstatic Bool 104903b705cfSriastradhsna_screen_init(SCREEN_INIT_ARGS_DECL) 105003b705cfSriastradh{ 105103b705cfSriastradh ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 105203b705cfSriastradh struct sna *sna = to_sna(scrn); 105342542f5fSchristos struct pci_device *pci; 105403b705cfSriastradh VisualPtr visuals; 105503b705cfSriastradh DepthPtr depths; 105603b705cfSriastradh int nvisuals; 105703b705cfSriastradh int ndepths; 105803b705cfSriastradh int rootdepth; 105903b705cfSriastradh VisualID defaultVisual; 106003b705cfSriastradh 106103b705cfSriastradh DBG(("%s\n", __FUNCTION__)); 106203b705cfSriastradh 106303b705cfSriastradh assert(sna->scrn == scrn); 106403b705cfSriastradh assert(scrn->pScreen == NULL); /* set afterwards */ 106503b705cfSriastradh 106603b705cfSriastradh assert(sna->freed_pixmap == NULL); 106703b705cfSriastradh 106803b705cfSriastradh if (!sna_register_all_privates()) 106903b705cfSriastradh return FALSE; 107003b705cfSriastradh 107142542f5fSchristos pci = xf86GetPciInfoForEntity(sna->pEnt->index); 107242542f5fSchristos if (pci != NULL) 107342542f5fSchristos scrn->videoRam = agp_aperture_size(pci, sna->kgem.gen) / 1024; 107442542f5fSchristos else 107542542f5fSchristos scrn->videoRam = 256; 107603b705cfSriastradh 107703b705cfSriastradh miClearVisualTypes(); 107803b705cfSriastradh if (!miSetVisualTypes(scrn->depth, 107903b705cfSriastradh miGetDefaultVisualMask(scrn->depth), 108003b705cfSriastradh scrn->rgbBits, scrn->defaultVisual)) 108103b705cfSriastradh return FALSE; 108203b705cfSriastradh if (!miSetPixmapDepths()) 108303b705cfSriastradh return FALSE; 108403b705cfSriastradh 108503b705cfSriastradh rootdepth = 0; 108603b705cfSriastradh if (!miInitVisuals(&visuals, &depths, &nvisuals, &ndepths, &rootdepth, 108703b705cfSriastradh &defaultVisual, 108803b705cfSriastradh ((unsigned long)1 << (scrn->bitsPerPixel - 1)), 108903b705cfSriastradh 8, -1)) 109003b705cfSriastradh return FALSE; 109103b705cfSriastradh 109203b705cfSriastradh if (!miScreenInit(screen, NULL, 109303b705cfSriastradh scrn->virtualX, scrn->virtualY, 109403b705cfSriastradh scrn->xDpi, scrn->yDpi, 0, 109503b705cfSriastradh rootdepth, ndepths, depths, 109603b705cfSriastradh defaultVisual, nvisuals, visuals)) 109703b705cfSriastradh return FALSE; 109803b705cfSriastradh 109903b705cfSriastradh if (scrn->bitsPerPixel > 8) { 110003b705cfSriastradh /* Fixup RGB ordering */ 110103b705cfSriastradh VisualPtr visual = screen->visuals + screen->numVisuals; 110203b705cfSriastradh while (--visual >= screen->visuals) { 110303b705cfSriastradh if ((visual->class | DynamicClass) == DirectColor) { 110403b705cfSriastradh visual->offsetRed = scrn->offset.red; 110503b705cfSriastradh visual->offsetGreen = scrn->offset.green; 110603b705cfSriastradh visual->offsetBlue = scrn->offset.blue; 110703b705cfSriastradh visual->redMask = scrn->mask.red; 110803b705cfSriastradh visual->greenMask = scrn->mask.green; 110903b705cfSriastradh visual->blueMask = scrn->mask.blue; 111003b705cfSriastradh } 111103b705cfSriastradh } 111203b705cfSriastradh } 111303b705cfSriastradh 111403b705cfSriastradh assert(screen->CloseScreen == NULL); 111503b705cfSriastradh screen->CloseScreen = sna_late_close_screen; 111603b705cfSriastradh if (!sna_accel_init(screen, sna)) { 111703b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_ERROR, 111803b705cfSriastradh "Hardware acceleration initialization failed\n"); 111903b705cfSriastradh return FALSE; 112003b705cfSriastradh } 112103b705cfSriastradh 112203b705cfSriastradh xf86SetBlackWhitePixels(screen); 112303b705cfSriastradh 112403b705cfSriastradh xf86SetBackingStore(screen); 112503b705cfSriastradh xf86SetSilkenMouse(screen); 112603b705cfSriastradh if (!miDCInitialize(screen, xf86GetPointerScreenFuncs())) 112703b705cfSriastradh return FALSE; 112803b705cfSriastradh 112942542f5fSchristos if (sna_cursors_init(screen, sna)) 113003b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_INFO, "HW Cursor enabled\n"); 113103b705cfSriastradh 113203b705cfSriastradh /* Must force it before EnterVT, so we are in control of VT and 113303b705cfSriastradh * later memory should be bound when allocating, e.g rotate_mem */ 113403b705cfSriastradh scrn->vtSema = TRUE; 113503b705cfSriastradh 113603b705cfSriastradh sna->BlockHandler = screen->BlockHandler; 113703b705cfSriastradh screen->BlockHandler = sna_block_handler; 113803b705cfSriastradh 113903b705cfSriastradh sna->WakeupHandler = screen->WakeupHandler; 114003b705cfSriastradh screen->WakeupHandler = sna_wakeup_handler; 114103b705cfSriastradh 114242542f5fSchristos screen->SaveScreen = sna_save_screen; 114303b705cfSriastradh screen->CreateScreenResources = sna_create_screen_resources; 114403b705cfSriastradh 114503b705cfSriastradh sna->CloseScreen = screen->CloseScreen; 114603b705cfSriastradh screen->CloseScreen = sna_early_close_screen; 114703b705cfSriastradh 114803b705cfSriastradh if (!xf86CrtcScreenInit(screen)) 114903b705cfSriastradh return FALSE; 115003b705cfSriastradh 115142542f5fSchristos xf86RandR12SetRotations(screen, RR_Rotate_All | RR_Reflect_All); 115203b705cfSriastradh xf86RandR12SetTransformSupport(screen, TRUE); 115303b705cfSriastradh 115403b705cfSriastradh if (!miCreateDefColormap(screen)) 115503b705cfSriastradh return FALSE; 115603b705cfSriastradh 115742542f5fSchristos if (sna->mode.num_real_crtc && 115842542f5fSchristos !xf86HandleColormaps(screen, 256, 8, sna_load_palette, NULL, 115903b705cfSriastradh CMAP_RELOAD_ON_MODE_SWITCH | 116042542f5fSchristos CMAP_PALETTED_TRUECOLOR)) 116103b705cfSriastradh return FALSE; 116203b705cfSriastradh 116342542f5fSchristos xf86DPMSInit(screen, sna_dpms_set, 0); 116403b705cfSriastradh 116503b705cfSriastradh sna_video_init(sna, screen); 116642542f5fSchristos sna_dri_init(sna, screen); 116742542f5fSchristos 116842542f5fSchristos if (sna->present.available) 116942542f5fSchristos sna->present.open = sna_present_open(sna, screen); 117042542f5fSchristos if (sna->present.open) 117142542f5fSchristos xf86DrvMsg(sna->scrn->scrnIndex, X_INFO, 117242542f5fSchristos "hardware support for Present enabled\n"); 117303b705cfSriastradh 117403b705cfSriastradh if (serverGeneration == 1) 117503b705cfSriastradh xf86ShowUnusedOptions(scrn->scrnIndex, scrn->options); 117603b705cfSriastradh 117703b705cfSriastradh sna->suspended = FALSE; 117803b705cfSriastradh 117942542f5fSchristos sna_uevent_init(sna); 118003b705cfSriastradh 118103b705cfSriastradh return TRUE; 118203b705cfSriastradh} 118303b705cfSriastradh 118403b705cfSriastradhstatic void sna_adjust_frame(ADJUST_FRAME_ARGS_DECL) 118503b705cfSriastradh{ 118603b705cfSriastradh SCRN_INFO_PTR(arg); 118703b705cfSriastradh DBG(("%s(%d, %d)\n", __FUNCTION__, x, y)); 118803b705cfSriastradh sna_mode_adjust_frame(to_sna(scrn), x, y); 118903b705cfSriastradh} 119003b705cfSriastradh 119103b705cfSriastradhstatic void sna_free_screen(FREE_SCREEN_ARGS_DECL) 119203b705cfSriastradh{ 119303b705cfSriastradh SCRN_INFO_PTR(arg); 119403b705cfSriastradh struct sna *sna = to_sna(scrn); 119503b705cfSriastradh 119642542f5fSchristos DBG(("%s [scrn=%p, sna=%p]\n", __FUNCTION__, scrn, sna)); 119742542f5fSchristos if (sna == NULL || (uintptr_t)sna & 3) /* beware thieves */ 119803b705cfSriastradh return; 119903b705cfSriastradh 120042542f5fSchristos scrn->driverPrivate = (void *)((uintptr_t)sna->info | (sna->flags & SNA_IS_SLAVED) | 2); 120103b705cfSriastradh 120203b705cfSriastradh sna_mode_fini(sna); 120342542f5fSchristos sna_acpi_fini(sna); 120403b705cfSriastradh free(sna); 120503b705cfSriastradh 120603b705cfSriastradh intel_put_device(scrn); 120703b705cfSriastradh} 120803b705cfSriastradh 120903b705cfSriastradhstatic Bool sna_enter_vt(VT_FUNC_ARGS_DECL) 121003b705cfSriastradh{ 121103b705cfSriastradh SCRN_INFO_PTR(arg); 121203b705cfSriastradh struct sna *sna = to_sna(scrn); 121303b705cfSriastradh 121403b705cfSriastradh DBG(("%s\n", __FUNCTION__)); 121542542f5fSchristos if (intel_get_master(scrn)) 121603b705cfSriastradh return FALSE; 121703b705cfSriastradh 121803b705cfSriastradh if (sna->flags & SNA_REPROBE) { 121942542f5fSchristos DBG(("%s: reporting deferred hotplug event\n", 122042542f5fSchristos __FUNCTION__)); 122142542f5fSchristos sna_mode_discover(sna); 122203b705cfSriastradh RRGetInfo(xf86ScrnToScreen(scrn), TRUE); 122303b705cfSriastradh sna->flags &= ~SNA_REPROBE; 122403b705cfSriastradh } 122503b705cfSriastradh 122642542f5fSchristos if (!sna_set_desired_mode(sna)) { 122742542f5fSchristos intel_put_master(scrn); 122842542f5fSchristos return FALSE; 122942542f5fSchristos } 123042542f5fSchristos 123142542f5fSchristos sna_accel_enter(sna); 123203b705cfSriastradh return TRUE; 123303b705cfSriastradh} 123403b705cfSriastradh 123503b705cfSriastradhstatic Bool sna_switch_mode(SWITCH_MODE_ARGS_DECL) 123603b705cfSriastradh{ 123703b705cfSriastradh SCRN_INFO_PTR(arg); 123803b705cfSriastradh DBG(("%s\n", __FUNCTION__)); 123903b705cfSriastradh return xf86SetSingleMode(scrn, mode, RR_Rotate_0); 124003b705cfSriastradh} 124103b705cfSriastradh 124203b705cfSriastradhstatic ModeStatus 124303b705cfSriastradhsna_valid_mode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags) 124403b705cfSriastradh{ 124503b705cfSriastradh return MODE_OK; 124603b705cfSriastradh} 124703b705cfSriastradh 124803b705cfSriastradh#ifndef SUSPEND_SLEEP 124903b705cfSriastradh#define SUSPEND_SLEEP 0 125003b705cfSriastradh#endif 125103b705cfSriastradh#ifndef RESUME_SLEEP 125203b705cfSriastradh#define RESUME_SLEEP 0 125303b705cfSriastradh#endif 125403b705cfSriastradh 125503b705cfSriastradh/* 125603b705cfSriastradh * This function is only required if we need to do anything differently from 125703b705cfSriastradh * DoApmEvent() in common/xf86PM.c, including if we want to see events other 125803b705cfSriastradh * than suspend/resume. 125903b705cfSriastradh */ 126003b705cfSriastradhstatic Bool sna_pm_event(SCRN_ARG_TYPE arg, pmEvent event, Bool undo) 126103b705cfSriastradh{ 126203b705cfSriastradh SCRN_INFO_PTR(arg); 126303b705cfSriastradh struct sna *sna = to_sna(scrn); 126403b705cfSriastradh 126503b705cfSriastradh DBG(("%s\n", __FUNCTION__)); 126603b705cfSriastradh 126703b705cfSriastradh switch (event) { 126803b705cfSriastradh case XF86_APM_SYS_SUSPEND: 126903b705cfSriastradh case XF86_APM_CRITICAL_SUSPEND: /*do we want to delay a critical suspend? */ 127003b705cfSriastradh case XF86_APM_USER_SUSPEND: 127103b705cfSriastradh case XF86_APM_SYS_STANDBY: 127203b705cfSriastradh case XF86_APM_USER_STANDBY: 127303b705cfSriastradh if (!undo && !sna->suspended) { 127403b705cfSriastradh scrn->LeaveVT(VT_FUNC_ARGS(0)); 127503b705cfSriastradh sna->suspended = TRUE; 127603b705cfSriastradh sleep(SUSPEND_SLEEP); 127703b705cfSriastradh } else if (undo && sna->suspended) { 127803b705cfSriastradh sleep(RESUME_SLEEP); 127903b705cfSriastradh scrn->EnterVT(VT_FUNC_ARGS(0)); 128003b705cfSriastradh sna->suspended = FALSE; 128103b705cfSriastradh } 128203b705cfSriastradh break; 128303b705cfSriastradh case XF86_APM_STANDBY_RESUME: 128403b705cfSriastradh case XF86_APM_NORMAL_RESUME: 128503b705cfSriastradh case XF86_APM_CRITICAL_RESUME: 128603b705cfSriastradh if (sna->suspended) { 128703b705cfSriastradh sleep(RESUME_SLEEP); 128803b705cfSriastradh scrn->EnterVT(VT_FUNC_ARGS(0)); 128903b705cfSriastradh sna->suspended = FALSE; 129003b705cfSriastradh /* 129103b705cfSriastradh * Turn the screen saver off when resuming. This seems to be 129203b705cfSriastradh * needed to stop xscreensaver kicking in (when used). 129303b705cfSriastradh * 129403b705cfSriastradh * XXX DoApmEvent() should probably call this just like 129503b705cfSriastradh * xf86VTSwitch() does. Maybe do it here only in 4.2 129603b705cfSriastradh * compatibility mode. 129703b705cfSriastradh */ 129803b705cfSriastradh SaveScreens(SCREEN_SAVER_FORCER, ScreenSaverReset); 129903b705cfSriastradh } 130003b705cfSriastradh break; 130103b705cfSriastradh /* This is currently used for ACPI */ 130203b705cfSriastradh case XF86_APM_CAPABILITY_CHANGED: 130303b705cfSriastradh SaveScreens(SCREEN_SAVER_FORCER, ScreenSaverReset); 130403b705cfSriastradh break; 130503b705cfSriastradh 130603b705cfSriastradh default: 130742542f5fSchristos ERR(("sna_pm_event: received APM event %d\n", event)); 130803b705cfSriastradh } 130903b705cfSriastradh return TRUE; 131003b705cfSriastradh} 131103b705cfSriastradh 131203b705cfSriastradhstatic Bool sna_enter_vt__hosted(VT_FUNC_ARGS_DECL) 131303b705cfSriastradh{ 131403b705cfSriastradh return TRUE; 131503b705cfSriastradh} 131603b705cfSriastradh 131703b705cfSriastradhstatic void sna_leave_vt__hosted(VT_FUNC_ARGS_DECL) 131803b705cfSriastradh{ 131903b705cfSriastradh} 132003b705cfSriastradh 132142542f5fSchristosstatic void describe_kms(ScrnInfoPtr scrn) 132242542f5fSchristos{ 132342542f5fSchristos int fd = __intel_peek_fd(scrn); 132442542f5fSchristos drm_version_t version; 132542542f5fSchristos char name[128] = ""; 132642542f5fSchristos char date[128] = ""; 132742542f5fSchristos 132842542f5fSchristos memset(&version, 0, sizeof(version)); 132942542f5fSchristos version.name_len = sizeof(name) - 1; 133042542f5fSchristos version.name = name; 133142542f5fSchristos version.date_len = sizeof(date) - 1; 133242542f5fSchristos version.date = date; 133342542f5fSchristos 133442542f5fSchristos if (drmIoctl(fd, DRM_IOCTL_VERSION, &version)) 133542542f5fSchristos return; 133642542f5fSchristos 133742542f5fSchristos xf86DrvMsg(scrn->scrnIndex, X_INFO, 133842542f5fSchristos "Using Kernel Mode Setting driver: %s, version %d.%d.%d %s\n", 133942542f5fSchristos version.name, 134042542f5fSchristos version.version_major, version.version_minor, version.version_patchlevel, 134142542f5fSchristos version.date); 134242542f5fSchristos} 134342542f5fSchristos 134442542f5fSchristosstatic void describe_sna(ScrnInfoPtr scrn) 134503b705cfSriastradh{ 134603b705cfSriastradh#if defined(USE_GIT_DESCRIBE) 134703b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_INFO, 134803b705cfSriastradh "SNA compiled from %s\n", git_version); 134903b705cfSriastradh#elif defined(BUILDER_DESCRIPTION) 135003b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_INFO, 135103b705cfSriastradh "SNA compiled: %s\n", BUILDER_DESCRIPTION); 135203b705cfSriastradh#endif 135303b705cfSriastradh#if !NDEBUG 135403b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_INFO, 135503b705cfSriastradh "SNA compiled with assertions enabled\n"); 135603b705cfSriastradh#endif 135703b705cfSriastradh#if DEBUG_SYNC 135803b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_INFO, 135903b705cfSriastradh "SNA compiled with synchronous rendering\n"); 136003b705cfSriastradh#endif 136103b705cfSriastradh#if DEBUG_MEMORY 136203b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_INFO, 136303b705cfSriastradh "SNA compiled with memory allocation reporting enabled\n"); 136403b705cfSriastradh#endif 136503b705cfSriastradh#if DEBUG_PIXMAP 136603b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_INFO, 136703b705cfSriastradh "SNA compiled with extra pixmap/damage validation\n"); 136842542f5fSchristos#endif 136942542f5fSchristos#ifdef HAVE_VALGRIND 137042542f5fSchristos xf86DrvMsg(scrn->scrnIndex, X_INFO, 137142542f5fSchristos "SNA compiled for use with valgrind\n"); 137242542f5fSchristos VALGRIND_PRINTF("SNA compiled for use with valgrind\n"); 137303b705cfSriastradh#endif 137403b705cfSriastradh DBG(("pixman version: %s\n", pixman_version_string())); 137542542f5fSchristos} 137642542f5fSchristos 137742542f5fSchristosBool sna_init_scrn(ScrnInfoPtr scrn, int entity_num) 137842542f5fSchristos{ 137942542f5fSchristos DBG(("%s: entity_num=%d\n", __FUNCTION__, entity_num)); 138042542f5fSchristos describe_kms(scrn); 138142542f5fSchristos describe_sna(scrn); 138203b705cfSriastradh 138303b705cfSriastradh scrn->PreInit = sna_pre_init; 138403b705cfSriastradh scrn->ScreenInit = sna_screen_init; 138503b705cfSriastradh if (!hosted()) { 138603b705cfSriastradh scrn->SwitchMode = sna_switch_mode; 138703b705cfSriastradh scrn->AdjustFrame = sna_adjust_frame; 138803b705cfSriastradh scrn->EnterVT = sna_enter_vt; 138903b705cfSriastradh scrn->LeaveVT = sna_leave_vt; 139003b705cfSriastradh scrn->ValidMode = sna_valid_mode; 139103b705cfSriastradh scrn->PMEvent = sna_pm_event; 139203b705cfSriastradh } else { 139303b705cfSriastradh scrn->EnterVT = sna_enter_vt__hosted; 139403b705cfSriastradh scrn->LeaveVT = sna_leave_vt__hosted; 139503b705cfSriastradh } 139603b705cfSriastradh scrn->FreeScreen = sna_free_screen; 139703b705cfSriastradh 139803b705cfSriastradh xf86SetEntitySharable(entity_num); 139903b705cfSriastradh xf86SetEntityInstanceForScreen(scrn, entity_num, 140003b705cfSriastradh xf86GetNumEntityInstances(entity_num)-1); 140103b705cfSriastradh 140203b705cfSriastradh sna_threads_init(); 140303b705cfSriastradh 140403b705cfSriastradh return TRUE; 140503b705cfSriastradh} 140642542f5fSchristos 140742542f5fSchristos#if HAS_DEBUG_FULL 140842542f5fSchristos_X_ATTRIBUTE_PRINTF(1, 0) void LogF(const char *f, ...) 140942542f5fSchristos{ 141042542f5fSchristos va_list ap; 141142542f5fSchristos 141242542f5fSchristos /* As we not only may be called from any context, we may also 141342542f5fSchristos * be called from a thread whilst the main thread is handling 141442542f5fSchristos * signals, therefore we have to use the signal-safe variants 141542542f5fSchristos * or else we trip over false positive assertions. 141642542f5fSchristos */ 141742542f5fSchristos 141842542f5fSchristos va_start(ap, f); 141942542f5fSchristos#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,12,99,901,0) 142042542f5fSchristos LogVMessageVerbSigSafe(X_NONE, 1, f, ap); 142142542f5fSchristos#else 142242542f5fSchristos LogVMessageVerb(X_NONE, 1, f, ap); 142342542f5fSchristos#endif 142442542f5fSchristos va_end(ap); 142542542f5fSchristos} 142642542f5fSchristos#endif 1427