13bfa90b6Smrg/* 23bfa90b6Smrg * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. 33bfa90b6Smrg * Copyright 2011 VMWare, Inc. 43bfa90b6Smrg * All Rights Reserved. 53bfa90b6Smrg * 63bfa90b6Smrg * Permission is hereby granted, free of charge, to any person obtaining a 73bfa90b6Smrg * copy of this software and associated documentation files (the 83bfa90b6Smrg * "Software"), to deal in the Software without restriction, including 93bfa90b6Smrg * without limitation the rights to use, copy, modify, merge, publish, 103bfa90b6Smrg * distribute, sub license, and/or sell copies of the Software, and to 113bfa90b6Smrg * permit persons to whom the Software is furnished to do so, subject to 123bfa90b6Smrg * the following conditions: 133bfa90b6Smrg * 143bfa90b6Smrg * The above copyright notice and this permission notice (including the 153bfa90b6Smrg * next paragraph) shall be included in all copies or substantial portions 163bfa90b6Smrg * of the Software. 173bfa90b6Smrg * 183bfa90b6Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 193bfa90b6Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 203bfa90b6Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 213bfa90b6Smrg * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 223bfa90b6Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 233bfa90b6Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 243bfa90b6Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 253bfa90b6Smrg * 263bfa90b6Smrg * 273bfa90b6Smrg * Author: Alan Hourihane <alanh@tungstengraphics.com> 283bfa90b6Smrg * Author: Jakob Bornecrantz <wallbraker@gmail.com> 293bfa90b6Smrg * Author: Thomas Hellstrom <thellstrom@vmware.com> 303bfa90b6Smrg */ 3134a0776dSmrg#ifdef HAVE_CONFIG_H 3234a0776dSmrg#include "config.h" 3334a0776dSmrg#endif 343bfa90b6Smrg 353bfa90b6Smrg#include <unistd.h> 363bfa90b6Smrg#include <string.h> 373bfa90b6Smrg#include <assert.h> 383bfa90b6Smrg#include <stdlib.h> 393bfa90b6Smrg#include <math.h> 403bfa90b6Smrg#include <stdint.h> 413bfa90b6Smrg 423bfa90b6Smrg#include "xorg-server.h" 433bfa90b6Smrg#include <xf86.h> 443bfa90b6Smrg#include <xf86i2c.h> 453bfa90b6Smrg#include <xf86Crtc.h> 463bfa90b6Smrg#include <cursorstr.h> 473bfa90b6Smrg#include "vmwgfx_driver.h" 483bfa90b6Smrg#include "xf86Modes.h" 493bfa90b6Smrg#include "vmwgfx_saa.h" 503bfa90b6Smrg 513bfa90b6Smrg#ifdef HAVE_XEXTPROTO_71 523bfa90b6Smrg#include <X11/extensions/dpmsconst.h> 533bfa90b6Smrg#else 543bfa90b6Smrg#define DPMS_SERVER 553bfa90b6Smrg#include <X11/extensions/dpms.h> 563bfa90b6Smrg#endif 573bfa90b6Smrg 583bfa90b6Smrgstruct crtc_private 593bfa90b6Smrg{ 603bfa90b6Smrg drmModeCrtcPtr drm_crtc; 613bfa90b6Smrg 623bfa90b6Smrg /* hwcursor */ 633bfa90b6Smrg struct vmwgfx_dmabuf *cursor_bo; 643bfa90b6Smrg uint32_t scanout_id; 653bfa90b6Smrg unsigned cursor_handle; 663bfa90b6Smrg 673bfa90b6Smrg /* Scanout info for pixmaps */ 683bfa90b6Smrg struct vmwgfx_screen_entry entry; 693bfa90b6Smrg}; 703bfa90b6Smrg 713bfa90b6Smrgstatic void 723bfa90b6Smrgcrtc_dpms(xf86CrtcPtr crtc, int mode) 733bfa90b6Smrg{ 743bfa90b6Smrg struct crtc_private *crtcp = crtc->driver_private; 753bfa90b6Smrg /* ScrnInfoPtr pScrn = crtc->scrn; */ 763bfa90b6Smrg 773bfa90b6Smrg switch (mode) { 783bfa90b6Smrg case DPMSModeOn: 793bfa90b6Smrg case DPMSModeStandby: 803bfa90b6Smrg case DPMSModeSuspend: 813bfa90b6Smrg break; 823bfa90b6Smrg case DPMSModeOff: 833bfa90b6Smrg 843bfa90b6Smrg /* 853bfa90b6Smrg * The xf86 modesetting code uses DPMS off to turn off 863bfa90b6Smrg * crtcs that are not enabled. However, the DPMS code does the same. 873bfa90b6Smrg * We assume, that if we get this call with the crtc not enabled, 883bfa90b6Smrg * it's a permanent switch off which will only be reversed by a 893bfa90b6Smrg * major modeset. 903bfa90b6Smrg * 913bfa90b6Smrg * If it's a DPMS switch off, (crtc->enabled == TRUE), 923bfa90b6Smrg * the crtc may be turned on again by 933bfa90b6Smrg * another dpms call, so don't release the scanout pixmap ref. 943bfa90b6Smrg */ 953bfa90b6Smrg if (!crtc->enabled && crtcp->entry.pixmap) { 963bfa90b6Smrg vmwgfx_scanout_unref(&crtcp->entry); 973bfa90b6Smrg } 983bfa90b6Smrg break; 993bfa90b6Smrg } 1003bfa90b6Smrg} 1013bfa90b6Smrg 1023bfa90b6Smrg/* 1033bfa90b6Smrg * Disable outputs and crtcs and drop the scanout reference from 10425dbecb6Smrg * scanout pixmaps. This will essentially free all kms fb allocations. 1053bfa90b6Smrg */ 1063bfa90b6Smrg 1073bfa90b6Smrgvoid 1083bfa90b6Smrgvmwgfx_disable_scanout(ScrnInfoPtr pScrn) 1093bfa90b6Smrg{ 1103bfa90b6Smrg int i; 1113bfa90b6Smrg Bool save_enabled; 1123bfa90b6Smrg xf86CrtcPtr crtc; 1133bfa90b6Smrg xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); 1143bfa90b6Smrg 1153bfa90b6Smrg xf86DPMSSet(pScrn, DPMSModeOff, 0); 1163bfa90b6Smrg for (i=0; i < config->num_crtc; ++i) { 1173bfa90b6Smrg crtc = config->crtc[i]; 1183bfa90b6Smrg save_enabled = crtc->enabled; 1193bfa90b6Smrg crtc->enabled = FALSE; 1203bfa90b6Smrg crtc_dpms(crtc, DPMSModeOff); 1213bfa90b6Smrg crtc->enabled = save_enabled; 1223bfa90b6Smrg } 1233bfa90b6Smrg xf86RotateFreeShadow(pScrn); 1243bfa90b6Smrg} 1253bfa90b6Smrg 12634a0776dSmrgstatic Bool 12734a0776dSmrgvmwgfx_scanout_equals_pixmap(DisplayModePtr mode, PixmapPtr pixmap, 12834a0776dSmrg int x, int y) 12934a0776dSmrg{ 13034a0776dSmrg return x == 0 && y == 0; 13134a0776dSmrg/* 13234a0776dSmrg * Mode test is disabled for now, since the X server has a tendency to first 13334a0776dSmrg * change the pixmap dimensions, then change the mode, keeping the pixmap. 13434a0776dSmrg * This would lead to a lot of false non-equals, or flickering if we were to 13534a0776dSmrg * kill the drm fb in between. 13634a0776dSmrg * However, currently we prefer false equals as long as x == 0 and y == 0. 13734a0776dSmrg * The false equals will then typically correspond to the primary screen in a 13834a0776dSmrg * multimon setup. Let's live with that for now. 13934a0776dSmrg */ 14034a0776dSmrg#if 0 14134a0776dSmrg && mode->HDisplay == pixmap->drawable.width && 14234a0776dSmrg mode->VDisplay == pixmap->drawable.height; 14334a0776dSmrg#endif 14434a0776dSmrg} 14534a0776dSmrg 1463bfa90b6Smrgstatic Bool 1473bfa90b6Smrgcrtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, 1483bfa90b6Smrg Rotation rotation, int x, int y) 1493bfa90b6Smrg{ 1503bfa90b6Smrg xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn); 1513bfa90b6Smrg modesettingPtr ms = modesettingPTR(crtc->scrn); 1523bfa90b6Smrg ScreenPtr pScreen = crtc->scrn->pScreen; 1533bfa90b6Smrg xf86OutputPtr output = NULL; 1543bfa90b6Smrg struct crtc_private *crtcp = crtc->driver_private; 1553bfa90b6Smrg drmModeCrtcPtr drm_crtc = crtcp->drm_crtc; 1563bfa90b6Smrg drmModeModeInfo drm_mode; 1573bfa90b6Smrg int i, ret; 1583bfa90b6Smrg unsigned int connector_id; 1593bfa90b6Smrg PixmapPtr pixmap; 1603bfa90b6Smrg 1613bfa90b6Smrg for (i = 0; i < config->num_output; output = NULL, i++) { 1623bfa90b6Smrg output = config->output[i]; 1633bfa90b6Smrg 1643bfa90b6Smrg if (output->crtc == crtc) 1653bfa90b6Smrg break; 1663bfa90b6Smrg } 1673bfa90b6Smrg 1683bfa90b6Smrg if (!output) { 1693bfa90b6Smrg LogMessage(X_ERROR, "No output for this crtc.\n"); 1703bfa90b6Smrg return FALSE; 1713bfa90b6Smrg } 1723bfa90b6Smrg 1733bfa90b6Smrg connector_id = xorg_output_get_id(output); 1743bfa90b6Smrg 17525dbecb6Smrg memset(&drm_mode, 0, sizeof(drm_mode)); 1763bfa90b6Smrg drm_mode.clock = mode->Clock; 1773bfa90b6Smrg drm_mode.hdisplay = mode->HDisplay; 1783bfa90b6Smrg drm_mode.hsync_start = mode->HSyncStart; 1793bfa90b6Smrg drm_mode.hsync_end = mode->HSyncEnd; 1803bfa90b6Smrg drm_mode.htotal = mode->HTotal; 1813bfa90b6Smrg drm_mode.vdisplay = mode->VDisplay; 1823bfa90b6Smrg drm_mode.vsync_start = mode->VSyncStart; 1833bfa90b6Smrg drm_mode.vsync_end = mode->VSyncEnd; 1843bfa90b6Smrg drm_mode.vtotal = mode->VTotal; 1853bfa90b6Smrg drm_mode.flags = mode->Flags; 1863bfa90b6Smrg drm_mode.hskew = mode->HSkew; 1873bfa90b6Smrg drm_mode.vscan = mode->VScan; 1883bfa90b6Smrg drm_mode.vrefresh = mode->VRefresh; 1893bfa90b6Smrg if (!mode->name) 1903bfa90b6Smrg xf86SetModeDefaultName(mode); 1913bfa90b6Smrg strncpy(drm_mode.name, mode->name, DRM_DISPLAY_MODE_LEN - 1); 1923bfa90b6Smrg drm_mode.name[DRM_DISPLAY_MODE_LEN - 1] = '\0'; 1933bfa90b6Smrg 1943bfa90b6Smrg /* 1953bfa90b6Smrg * Check if we need to scanout from something else than the root 1963bfa90b6Smrg * pixmap. In that case, xf86CrtcRotate will take care of allocating 1973bfa90b6Smrg * new opaque scanout buffer data "crtc->rotatedData". 1983bfa90b6Smrg * However, it will not wrap 1993bfa90b6Smrg * that data into pixmaps until the first rotated damage composite. 2003bfa90b6Smrg * In out case, the buffer data is actually already a pixmap. 2013bfa90b6Smrg */ 2023bfa90b6Smrg 2033bfa90b6Smrg if (!xf86CrtcRotate(crtc)) 2043bfa90b6Smrg return FALSE; 2053bfa90b6Smrg 2063bfa90b6Smrg if (crtc->transform_in_use && crtc->rotatedData) { 2073bfa90b6Smrg x = 0; 2083bfa90b6Smrg y = 0; 2093bfa90b6Smrg pixmap = (PixmapPtr) crtc->rotatedData; 2103bfa90b6Smrg } else 2113bfa90b6Smrg pixmap = pScreen->GetScreenPixmap(pScreen); 2123bfa90b6Smrg 2133bfa90b6Smrg if (crtcp->entry.pixmap != pixmap) { 2143bfa90b6Smrg if (crtcp->entry.pixmap) 2153bfa90b6Smrg vmwgfx_scanout_unref(&crtcp->entry); 2163bfa90b6Smrg 2173bfa90b6Smrg crtcp->entry.pixmap = pixmap; 21834a0776dSmrg crtcp->scanout_id = vmwgfx_scanout_ref 21934a0776dSmrg (&crtcp->entry, vmwgfx_scanout_equals_pixmap(mode, pixmap, x, y)); 2203bfa90b6Smrg if (crtcp->scanout_id == -1) { 221591e32d7Ssnj crtcp->entry.pixmap = NULL; 2223bfa90b6Smrg LogMessage(X_ERROR, "Failed to convert pixmap to scanout.\n"); 2233bfa90b6Smrg return FALSE; 2243bfa90b6Smrg } 2253bfa90b6Smrg } 2263bfa90b6Smrg ret = drmModeSetCrtc(ms->fd, drm_crtc->crtc_id, crtcp->scanout_id, x, y, 2273bfa90b6Smrg &connector_id, 1, &drm_mode); 2283bfa90b6Smrg if (ret) 2293bfa90b6Smrg return FALSE; 2303bfa90b6Smrg 2313bfa90b6Smrg vmwgfx_scanout_refresh(pixmap); 2323bfa90b6Smrg 2333bfa90b6Smrg /* Only set gamma when needed, to avoid unneeded delays. */ 2343bfa90b6Smrg#if defined(XF86_CRTC_VERSION) && XF86_CRTC_VERSION >= 3 2353bfa90b6Smrg if (!crtc->active && crtc->version >= 3) 2363bfa90b6Smrg crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green, 2373bfa90b6Smrg crtc->gamma_blue, crtc->gamma_size); 2383bfa90b6Smrg crtc->active = TRUE; 2393bfa90b6Smrg#endif 2403bfa90b6Smrg 241591e32d7Ssnj /* 242591e32d7Ssnj * Strictly, this needs to be done only once per configuration change, 243591e32d7Ssnj * not once per crtc, but there's no better place to put this. Since 244591e32d7Ssnj * Intel wrote the crtc code, let's do what the xf86-video-intel driver 245591e32d7Ssnj * does. 246591e32d7Ssnj */ 24725dbecb6Smrg#if (GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 23) 248591e32d7Ssnj if (pScreen) 249591e32d7Ssnj xf86_reload_cursors(pScreen); 25025dbecb6Smrg#endif 251591e32d7Ssnj 2523bfa90b6Smrg return TRUE; 2533bfa90b6Smrg} 2543bfa90b6Smrg 2553bfa90b6Smrgstatic void 2563bfa90b6Smrgcrtc_gamma_set(xf86CrtcPtr crtc, CARD16 * red, CARD16 * green, CARD16 * blue, 2573bfa90b6Smrg int size) 2583bfa90b6Smrg{ 2593bfa90b6Smrg modesettingPtr ms = modesettingPTR(crtc->scrn); 2603bfa90b6Smrg struct crtc_private *crtcp = crtc->driver_private; 2613bfa90b6Smrg 2623bfa90b6Smrg drmModeCrtcSetGamma(ms->fd, crtcp->drm_crtc->crtc_id, size, red, green, blue); 2633bfa90b6Smrg} 2643bfa90b6Smrg 2653bfa90b6Smrgstatic void * 2663bfa90b6Smrgcrtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height) 2673bfa90b6Smrg{ 2683bfa90b6Smrg ScreenPtr pScreen = crtc->scrn->pScreen; 2693bfa90b6Smrg PixmapPtr rootpix = pScreen->GetScreenPixmap(pScreen); 2703bfa90b6Smrg 2713bfa90b6Smrg /* 2723bfa90b6Smrg * Use the same depth as for the root pixmap. 2733bfa90b6Smrg * The associated kms fb will be created on demand once this pixmap 2743bfa90b6Smrg * is used as scanout by a crtc. 2753bfa90b6Smrg */ 2763bfa90b6Smrg 2773bfa90b6Smrg return pScreen->CreatePixmap(pScreen, width, height, 2783bfa90b6Smrg rootpix->drawable.depth, 0); 2793bfa90b6Smrg} 2803bfa90b6Smrg 2813bfa90b6Smrgstatic PixmapPtr 2823bfa90b6Smrgcrtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) 2833bfa90b6Smrg{ 2843bfa90b6Smrg return (PixmapPtr) data; 2853bfa90b6Smrg} 2863bfa90b6Smrg 2873bfa90b6Smrgstatic void 2883bfa90b6Smrgcrtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) 2893bfa90b6Smrg{ 2903bfa90b6Smrg ScreenPtr pScreen; 2913bfa90b6Smrg 2923bfa90b6Smrg if (rotate_pixmap == NULL) 2933bfa90b6Smrg return; 2943bfa90b6Smrg 2953bfa90b6Smrg pScreen = rotate_pixmap->drawable.pScreen; 2963bfa90b6Smrg pScreen->DestroyPixmap(rotate_pixmap); 2973bfa90b6Smrg} 2983bfa90b6Smrg 2993bfa90b6Smrg 3003bfa90b6Smrg/* 3013bfa90b6Smrg * Cursor functions 3023bfa90b6Smrg */ 3033bfa90b6Smrg 3043bfa90b6Smrgstatic void 3053bfa90b6Smrgcrtc_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg) 3063bfa90b6Smrg{ 3073bfa90b6Smrg /* XXX: See if this one is needed, as we only support ARGB cursors */ 3083bfa90b6Smrg} 3093bfa90b6Smrg 3103bfa90b6Smrgstatic void 3113bfa90b6Smrgcrtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y) 3123bfa90b6Smrg{ 3133bfa90b6Smrg modesettingPtr ms = modesettingPTR(crtc->scrn); 3143bfa90b6Smrg struct crtc_private *crtcp = crtc->driver_private; 3153bfa90b6Smrg 316591e32d7Ssnj /* Seems like newer X servers try to move cursors without images */ 317591e32d7Ssnj if (!crtcp->cursor_bo) 318591e32d7Ssnj return; 319591e32d7Ssnj 3203bfa90b6Smrg drmModeMoveCursor(ms->fd, crtcp->drm_crtc->crtc_id, x, y); 3213bfa90b6Smrg} 3223bfa90b6Smrg 3233bfa90b6Smrgstatic void 3243bfa90b6Smrgcrtc_load_cursor_argb_kms(xf86CrtcPtr crtc, CARD32 * image) 3253bfa90b6Smrg{ 3263bfa90b6Smrg modesettingPtr ms = modesettingPTR(crtc->scrn); 3273bfa90b6Smrg struct crtc_private *crtcp = crtc->driver_private; 3283bfa90b6Smrg unsigned char *ptr; 3293bfa90b6Smrg xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn); 3303bfa90b6Smrg CursorPtr c = config->cursor; 3313bfa90b6Smrg 3323bfa90b6Smrg if (vmwgfx_cursor_bypass(ms->fd, c->bits->xhot, c->bits->yhot) != 0) { 3333bfa90b6Smrg xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, 3343bfa90b6Smrg "Failed to set VMWare cursor bypass.\n"); 3353bfa90b6Smrg } 3363bfa90b6Smrg 3373bfa90b6Smrg if (!crtcp->cursor_bo) { 3383bfa90b6Smrg size_t size = 64*64*4; 3393bfa90b6Smrg crtcp->cursor_bo = vmwgfx_dmabuf_alloc(ms->fd, size); 340591e32d7Ssnj if (!crtcp->cursor_bo) { 341591e32d7Ssnj xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, 342591e32d7Ssnj "Failed to create a dmabuf for cursor.\n"); 3433bfa90b6Smrg return; 344591e32d7Ssnj } 3453bfa90b6Smrg crtcp->cursor_handle = crtcp->cursor_bo->handle; 3463bfa90b6Smrg } 3473bfa90b6Smrg 3483bfa90b6Smrg ptr = vmwgfx_dmabuf_map(crtcp->cursor_bo); 3493bfa90b6Smrg if (ptr) { 3503bfa90b6Smrg memcpy(ptr, image, 64*64*4); 3513bfa90b6Smrg vmwgfx_dmabuf_unmap(crtcp->cursor_bo); 352591e32d7Ssnj } else { 353591e32d7Ssnj xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, 354591e32d7Ssnj "Failed to map cursor dmabuf.\n"); 3553bfa90b6Smrg } 3563bfa90b6Smrg 3573bfa90b6Smrg if (crtc->cursor_shown) 3583bfa90b6Smrg drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id, 3593bfa90b6Smrg crtcp->cursor_handle, 64, 64); 3603bfa90b6Smrg 3613bfa90b6Smrg return; 3623bfa90b6Smrg} 3633bfa90b6Smrg 3643bfa90b6Smrgstatic void 3653bfa90b6Smrgcrtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 * image) 3663bfa90b6Smrg{ 3673bfa90b6Smrg xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn); 3683bfa90b6Smrg modesettingPtr ms = modesettingPTR(crtc->scrn); 3693bfa90b6Smrg 3703bfa90b6Smrg /* Older X servers have cursor reference counting bugs leading to use of 3713bfa90b6Smrg * freed memory and consequently random crashes. Should be fixed as of 3723bfa90b6Smrg * xserver 1.8, but this workaround shouldn't hurt anyway. 3733bfa90b6Smrg */ 3743bfa90b6Smrg if (config->cursor) 3753bfa90b6Smrg config->cursor->refcnt++; 3763bfa90b6Smrg 3773bfa90b6Smrg if (ms->cursor) 3783bfa90b6Smrg FreeCursor(ms->cursor, None); 3793bfa90b6Smrg 3803bfa90b6Smrg ms->cursor = config->cursor; 3813bfa90b6Smrg crtc_load_cursor_argb_kms(crtc, image); 3823bfa90b6Smrg} 3833bfa90b6Smrg 3843bfa90b6Smrgstatic void 3853bfa90b6Smrgcrtc_show_cursor(xf86CrtcPtr crtc) 3863bfa90b6Smrg{ 3873bfa90b6Smrg modesettingPtr ms = modesettingPTR(crtc->scrn); 3883bfa90b6Smrg struct crtc_private *crtcp = crtc->driver_private; 3893bfa90b6Smrg 3903bfa90b6Smrg if (crtcp->cursor_bo) 3913bfa90b6Smrg drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id, 3923bfa90b6Smrg crtcp->cursor_handle, 64, 64); 3933bfa90b6Smrg} 3943bfa90b6Smrg 3953bfa90b6Smrgstatic void 3963bfa90b6Smrgcrtc_hide_cursor(xf86CrtcPtr crtc) 3973bfa90b6Smrg{ 3983bfa90b6Smrg modesettingPtr ms = modesettingPTR(crtc->scrn); 3993bfa90b6Smrg struct crtc_private *crtcp = crtc->driver_private; 4003bfa90b6Smrg 4013bfa90b6Smrg drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id, 0, 0, 0); 4023bfa90b6Smrg} 4033bfa90b6Smrg 4043bfa90b6Smrg/** 4053bfa90b6Smrg * Called at vt leave 4063bfa90b6Smrg */ 4073bfa90b6Smrgvoid 4083bfa90b6Smrgxorg_crtc_cursor_destroy(xf86CrtcPtr crtc) 4093bfa90b6Smrg{ 4103bfa90b6Smrg struct crtc_private *crtcp = crtc->driver_private; 4113bfa90b6Smrg 4123bfa90b6Smrg if (crtcp->cursor_bo) { 4133bfa90b6Smrg vmwgfx_dmabuf_destroy(crtcp->cursor_bo); 4143bfa90b6Smrg crtcp->cursor_bo = NULL; 4153bfa90b6Smrg } 4163bfa90b6Smrg} 4173bfa90b6Smrg 4183bfa90b6Smrg/* 4193bfa90b6Smrg * Misc functions 4203bfa90b6Smrg */ 4213bfa90b6Smrg 4223bfa90b6Smrgstatic void 4233bfa90b6Smrgcrtc_destroy(xf86CrtcPtr crtc) 4243bfa90b6Smrg{ 4253bfa90b6Smrg struct crtc_private *crtcp = crtc->driver_private; 4263bfa90b6Smrg 4273bfa90b6Smrg if (!WSBMLISTEMPTY(&crtcp->entry.scanout_head)) 4283bfa90b6Smrg vmwgfx_scanout_unref(&crtcp->entry); 4293bfa90b6Smrg 4303bfa90b6Smrg xorg_crtc_cursor_destroy(crtc); 4313bfa90b6Smrg 4323bfa90b6Smrg drmModeFreeCrtc(crtcp->drm_crtc); 4333bfa90b6Smrg 4343bfa90b6Smrg free(crtcp); 4353bfa90b6Smrg crtc->driver_private = NULL; 4363bfa90b6Smrg} 4373bfa90b6Smrg 4383bfa90b6Smrgstatic const xf86CrtcFuncsRec crtc_funcs = { 4393bfa90b6Smrg .dpms = crtc_dpms, 4403bfa90b6Smrg .set_mode_major = crtc_set_mode_major, 4413bfa90b6Smrg 4423bfa90b6Smrg .set_cursor_colors = crtc_set_cursor_colors, 4433bfa90b6Smrg .set_cursor_position = crtc_set_cursor_position, 4443bfa90b6Smrg .show_cursor = crtc_show_cursor, 4453bfa90b6Smrg .hide_cursor = crtc_hide_cursor, 4463bfa90b6Smrg .load_cursor_argb = crtc_load_cursor_argb, 4473bfa90b6Smrg 4483bfa90b6Smrg .shadow_create = crtc_shadow_create, 4493bfa90b6Smrg .shadow_allocate = crtc_shadow_allocate, 4503bfa90b6Smrg .shadow_destroy = crtc_shadow_destroy, 4513bfa90b6Smrg 4523bfa90b6Smrg .gamma_set = crtc_gamma_set, 4533bfa90b6Smrg .destroy = crtc_destroy, 4543bfa90b6Smrg}; 4553bfa90b6Smrg 4563bfa90b6Smrgvoid 4573bfa90b6Smrgxorg_crtc_init(ScrnInfoPtr pScrn) 4583bfa90b6Smrg{ 4593bfa90b6Smrg modesettingPtr ms = modesettingPTR(pScrn); 4603bfa90b6Smrg xf86CrtcPtr crtc; 4613bfa90b6Smrg drmModeResPtr res; 4623bfa90b6Smrg drmModeCrtcPtr drm_crtc = NULL; 4633bfa90b6Smrg struct crtc_private *crtcp; 4643bfa90b6Smrg int c; 4653bfa90b6Smrg 4663bfa90b6Smrg res = drmModeGetResources(ms->fd); 4673bfa90b6Smrg if (res == 0) { 4683bfa90b6Smrg ErrorF("Failed drmModeGetResources %d\n", errno); 4693bfa90b6Smrg return; 4703bfa90b6Smrg } 4713bfa90b6Smrg 4723bfa90b6Smrg for (c = 0; c < res->count_crtcs; c++) { 4733bfa90b6Smrg drm_crtc = drmModeGetCrtc(ms->fd, res->crtcs[c]); 4743bfa90b6Smrg 4753bfa90b6Smrg if (!drm_crtc) 4763bfa90b6Smrg continue; 4773bfa90b6Smrg 4783bfa90b6Smrg crtc = xf86CrtcCreate(pScrn, &crtc_funcs); 4793bfa90b6Smrg if (crtc == NULL) 4803bfa90b6Smrg goto out; 4813bfa90b6Smrg 4823bfa90b6Smrg crtcp = calloc(1, sizeof(struct crtc_private)); 4833bfa90b6Smrg if (!crtcp) { 4843bfa90b6Smrg xf86CrtcDestroy(crtc); 4853bfa90b6Smrg goto out; 4863bfa90b6Smrg } 4873bfa90b6Smrg 4883bfa90b6Smrg crtcp->drm_crtc = drm_crtc; 4893bfa90b6Smrg crtcp->entry.pixmap = NULL; 4903bfa90b6Smrg WSBMINITLISTHEAD(&crtcp->entry.scanout_head); 4913bfa90b6Smrg 4923bfa90b6Smrg crtc->driver_private = crtcp; 4933bfa90b6Smrg } 4943bfa90b6Smrg 4953bfa90b6Smrg out: 4963bfa90b6Smrg drmModeFreeResources(res); 4973bfa90b6Smrg} 4983bfa90b6Smrg 4993bfa90b6SmrgPixmapPtr 5003bfa90b6Smrgcrtc_get_scanout(xf86CrtcPtr crtc) 5013bfa90b6Smrg{ 5023bfa90b6Smrg struct crtc_private *crtcp = crtc->driver_private; 5033bfa90b6Smrg return crtcp->entry.pixmap; 5043bfa90b6Smrg} 5053bfa90b6Smrg 5063bfa90b6Smrg/* vim: set sw=4 ts=8 sts=4: */ 507