vmwgfx_crtc.c revision 3bfa90b6
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 */ 313bfa90b6Smrg 323bfa90b6Smrg#include <unistd.h> 333bfa90b6Smrg#include <string.h> 343bfa90b6Smrg#include <assert.h> 353bfa90b6Smrg#include <stdlib.h> 363bfa90b6Smrg#include <math.h> 373bfa90b6Smrg#include <stdint.h> 383bfa90b6Smrg 393bfa90b6Smrg#include "xorg-server.h" 403bfa90b6Smrg#include <xf86.h> 413bfa90b6Smrg#include <xf86i2c.h> 423bfa90b6Smrg#include <xf86Crtc.h> 433bfa90b6Smrg#include <cursorstr.h> 443bfa90b6Smrg#include "vmwgfx_driver.h" 453bfa90b6Smrg#include "xf86Modes.h" 463bfa90b6Smrg#include "vmwgfx_saa.h" 473bfa90b6Smrg 483bfa90b6Smrg#ifdef HAVE_XEXTPROTO_71 493bfa90b6Smrg#include <X11/extensions/dpmsconst.h> 503bfa90b6Smrg#else 513bfa90b6Smrg#define DPMS_SERVER 523bfa90b6Smrg#include <X11/extensions/dpms.h> 533bfa90b6Smrg#endif 543bfa90b6Smrg 553bfa90b6Smrgstruct crtc_private 563bfa90b6Smrg{ 573bfa90b6Smrg drmModeCrtcPtr drm_crtc; 583bfa90b6Smrg 593bfa90b6Smrg /* hwcursor */ 603bfa90b6Smrg struct vmwgfx_dmabuf *cursor_bo; 613bfa90b6Smrg uint32_t scanout_id; 623bfa90b6Smrg unsigned cursor_handle; 633bfa90b6Smrg 643bfa90b6Smrg /* Scanout info for pixmaps */ 653bfa90b6Smrg struct vmwgfx_screen_entry entry; 663bfa90b6Smrg}; 673bfa90b6Smrg 683bfa90b6Smrgstatic void 693bfa90b6Smrgcrtc_dpms(xf86CrtcPtr crtc, int mode) 703bfa90b6Smrg{ 713bfa90b6Smrg struct crtc_private *crtcp = crtc->driver_private; 723bfa90b6Smrg /* ScrnInfoPtr pScrn = crtc->scrn; */ 733bfa90b6Smrg 743bfa90b6Smrg switch (mode) { 753bfa90b6Smrg case DPMSModeOn: 763bfa90b6Smrg case DPMSModeStandby: 773bfa90b6Smrg case DPMSModeSuspend: 783bfa90b6Smrg break; 793bfa90b6Smrg case DPMSModeOff: 803bfa90b6Smrg 813bfa90b6Smrg /* 823bfa90b6Smrg * The xf86 modesetting code uses DPMS off to turn off 833bfa90b6Smrg * crtcs that are not enabled. However, the DPMS code does the same. 843bfa90b6Smrg * We assume, that if we get this call with the crtc not enabled, 853bfa90b6Smrg * it's a permanent switch off which will only be reversed by a 863bfa90b6Smrg * major modeset. 873bfa90b6Smrg * 883bfa90b6Smrg * If it's a DPMS switch off, (crtc->enabled == TRUE), 893bfa90b6Smrg * the crtc may be turned on again by 903bfa90b6Smrg * another dpms call, so don't release the scanout pixmap ref. 913bfa90b6Smrg */ 923bfa90b6Smrg if (!crtc->enabled && crtcp->entry.pixmap) { 933bfa90b6Smrg vmwgfx_scanout_unref(&crtcp->entry); 943bfa90b6Smrg } 953bfa90b6Smrg break; 963bfa90b6Smrg } 973bfa90b6Smrg} 983bfa90b6Smrg 993bfa90b6Smrg/* 1003bfa90b6Smrg * Disable outputs and crtcs and drop the scanout reference from 1013bfa90b6Smrg * scanout pixmaps. This will essentialy free all kms fb allocations. 1023bfa90b6Smrg */ 1033bfa90b6Smrg 1043bfa90b6Smrgvoid 1053bfa90b6Smrgvmwgfx_disable_scanout(ScrnInfoPtr pScrn) 1063bfa90b6Smrg{ 1073bfa90b6Smrg int i; 1083bfa90b6Smrg Bool save_enabled; 1093bfa90b6Smrg xf86CrtcPtr crtc; 1103bfa90b6Smrg xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); 1113bfa90b6Smrg 1123bfa90b6Smrg xf86DPMSSet(pScrn, DPMSModeOff, 0); 1133bfa90b6Smrg for (i=0; i < config->num_crtc; ++i) { 1143bfa90b6Smrg crtc = config->crtc[i]; 1153bfa90b6Smrg save_enabled = crtc->enabled; 1163bfa90b6Smrg crtc->enabled = FALSE; 1173bfa90b6Smrg crtc_dpms(crtc, DPMSModeOff); 1183bfa90b6Smrg crtc->enabled = save_enabled; 1193bfa90b6Smrg } 1203bfa90b6Smrg xf86RotateFreeShadow(pScrn); 1213bfa90b6Smrg} 1223bfa90b6Smrg 1233bfa90b6Smrgstatic Bool 1243bfa90b6Smrgcrtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, 1253bfa90b6Smrg Rotation rotation, int x, int y) 1263bfa90b6Smrg{ 1273bfa90b6Smrg xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn); 1283bfa90b6Smrg modesettingPtr ms = modesettingPTR(crtc->scrn); 1293bfa90b6Smrg ScreenPtr pScreen = crtc->scrn->pScreen; 1303bfa90b6Smrg xf86OutputPtr output = NULL; 1313bfa90b6Smrg struct crtc_private *crtcp = crtc->driver_private; 1323bfa90b6Smrg drmModeCrtcPtr drm_crtc = crtcp->drm_crtc; 1333bfa90b6Smrg drmModeModeInfo drm_mode; 1343bfa90b6Smrg int i, ret; 1353bfa90b6Smrg unsigned int connector_id; 1363bfa90b6Smrg PixmapPtr pixmap; 1373bfa90b6Smrg 1383bfa90b6Smrg for (i = 0; i < config->num_output; output = NULL, i++) { 1393bfa90b6Smrg output = config->output[i]; 1403bfa90b6Smrg 1413bfa90b6Smrg if (output->crtc == crtc) 1423bfa90b6Smrg break; 1433bfa90b6Smrg } 1443bfa90b6Smrg 1453bfa90b6Smrg if (!output) { 1463bfa90b6Smrg LogMessage(X_ERROR, "No output for this crtc.\n"); 1473bfa90b6Smrg return FALSE; 1483bfa90b6Smrg } 1493bfa90b6Smrg 1503bfa90b6Smrg connector_id = xorg_output_get_id(output); 1513bfa90b6Smrg 1523bfa90b6Smrg drm_mode.clock = mode->Clock; 1533bfa90b6Smrg drm_mode.hdisplay = mode->HDisplay; 1543bfa90b6Smrg drm_mode.hsync_start = mode->HSyncStart; 1553bfa90b6Smrg drm_mode.hsync_end = mode->HSyncEnd; 1563bfa90b6Smrg drm_mode.htotal = mode->HTotal; 1573bfa90b6Smrg drm_mode.vdisplay = mode->VDisplay; 1583bfa90b6Smrg drm_mode.vsync_start = mode->VSyncStart; 1593bfa90b6Smrg drm_mode.vsync_end = mode->VSyncEnd; 1603bfa90b6Smrg drm_mode.vtotal = mode->VTotal; 1613bfa90b6Smrg drm_mode.flags = mode->Flags; 1623bfa90b6Smrg drm_mode.hskew = mode->HSkew; 1633bfa90b6Smrg drm_mode.vscan = mode->VScan; 1643bfa90b6Smrg drm_mode.vrefresh = mode->VRefresh; 1653bfa90b6Smrg if (!mode->name) 1663bfa90b6Smrg xf86SetModeDefaultName(mode); 1673bfa90b6Smrg strncpy(drm_mode.name, mode->name, DRM_DISPLAY_MODE_LEN - 1); 1683bfa90b6Smrg drm_mode.name[DRM_DISPLAY_MODE_LEN - 1] = '\0'; 1693bfa90b6Smrg 1703bfa90b6Smrg /* 1713bfa90b6Smrg * Check if we need to scanout from something else than the root 1723bfa90b6Smrg * pixmap. In that case, xf86CrtcRotate will take care of allocating 1733bfa90b6Smrg * new opaque scanout buffer data "crtc->rotatedData". 1743bfa90b6Smrg * However, it will not wrap 1753bfa90b6Smrg * that data into pixmaps until the first rotated damage composite. 1763bfa90b6Smrg * In out case, the buffer data is actually already a pixmap. 1773bfa90b6Smrg */ 1783bfa90b6Smrg 1793bfa90b6Smrg if (!xf86CrtcRotate(crtc)) 1803bfa90b6Smrg return FALSE; 1813bfa90b6Smrg 1823bfa90b6Smrg if (crtc->transform_in_use && crtc->rotatedData) { 1833bfa90b6Smrg x = 0; 1843bfa90b6Smrg y = 0; 1853bfa90b6Smrg pixmap = (PixmapPtr) crtc->rotatedData; 1863bfa90b6Smrg } else 1873bfa90b6Smrg pixmap = pScreen->GetScreenPixmap(pScreen); 1883bfa90b6Smrg 1893bfa90b6Smrg if (crtcp->entry.pixmap != pixmap) { 1903bfa90b6Smrg if (crtcp->entry.pixmap) 1913bfa90b6Smrg vmwgfx_scanout_unref(&crtcp->entry); 1923bfa90b6Smrg 1933bfa90b6Smrg crtcp->entry.pixmap = pixmap; 1943bfa90b6Smrg crtcp->scanout_id = vmwgfx_scanout_ref(&crtcp->entry); 1953bfa90b6Smrg if (crtcp->scanout_id == -1) { 1963bfa90b6Smrg LogMessage(X_ERROR, "Failed to convert pixmap to scanout.\n"); 1973bfa90b6Smrg return FALSE; 1983bfa90b6Smrg } 1993bfa90b6Smrg } 2003bfa90b6Smrg ret = drmModeSetCrtc(ms->fd, drm_crtc->crtc_id, crtcp->scanout_id, x, y, 2013bfa90b6Smrg &connector_id, 1, &drm_mode); 2023bfa90b6Smrg if (ret) 2033bfa90b6Smrg return FALSE; 2043bfa90b6Smrg 2053bfa90b6Smrg vmwgfx_scanout_refresh(pixmap); 2063bfa90b6Smrg 2073bfa90b6Smrg /* Only set gamma when needed, to avoid unneeded delays. */ 2083bfa90b6Smrg#if defined(XF86_CRTC_VERSION) && XF86_CRTC_VERSION >= 3 2093bfa90b6Smrg if (!crtc->active && crtc->version >= 3) 2103bfa90b6Smrg crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green, 2113bfa90b6Smrg crtc->gamma_blue, crtc->gamma_size); 2123bfa90b6Smrg crtc->active = TRUE; 2133bfa90b6Smrg#endif 2143bfa90b6Smrg 2153bfa90b6Smrg return TRUE; 2163bfa90b6Smrg} 2173bfa90b6Smrg 2183bfa90b6Smrgstatic void 2193bfa90b6Smrgcrtc_gamma_set(xf86CrtcPtr crtc, CARD16 * red, CARD16 * green, CARD16 * blue, 2203bfa90b6Smrg int size) 2213bfa90b6Smrg{ 2223bfa90b6Smrg modesettingPtr ms = modesettingPTR(crtc->scrn); 2233bfa90b6Smrg struct crtc_private *crtcp = crtc->driver_private; 2243bfa90b6Smrg 2253bfa90b6Smrg drmModeCrtcSetGamma(ms->fd, crtcp->drm_crtc->crtc_id, size, red, green, blue); 2263bfa90b6Smrg} 2273bfa90b6Smrg 2283bfa90b6Smrgstatic void * 2293bfa90b6Smrgcrtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height) 2303bfa90b6Smrg{ 2313bfa90b6Smrg ScreenPtr pScreen = crtc->scrn->pScreen; 2323bfa90b6Smrg PixmapPtr rootpix = pScreen->GetScreenPixmap(pScreen); 2333bfa90b6Smrg 2343bfa90b6Smrg /* 2353bfa90b6Smrg * Use the same depth as for the root pixmap. 2363bfa90b6Smrg * The associated kms fb will be created on demand once this pixmap 2373bfa90b6Smrg * is used as scanout by a crtc. 2383bfa90b6Smrg */ 2393bfa90b6Smrg 2403bfa90b6Smrg return pScreen->CreatePixmap(pScreen, width, height, 2413bfa90b6Smrg rootpix->drawable.depth, 0); 2423bfa90b6Smrg} 2433bfa90b6Smrg 2443bfa90b6Smrgstatic PixmapPtr 2453bfa90b6Smrgcrtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) 2463bfa90b6Smrg{ 2473bfa90b6Smrg return (PixmapPtr) data; 2483bfa90b6Smrg} 2493bfa90b6Smrg 2503bfa90b6Smrgstatic void 2513bfa90b6Smrgcrtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) 2523bfa90b6Smrg{ 2533bfa90b6Smrg ScreenPtr pScreen; 2543bfa90b6Smrg 2553bfa90b6Smrg if (rotate_pixmap == NULL) 2563bfa90b6Smrg return; 2573bfa90b6Smrg 2583bfa90b6Smrg pScreen = rotate_pixmap->drawable.pScreen; 2593bfa90b6Smrg pScreen->DestroyPixmap(rotate_pixmap); 2603bfa90b6Smrg} 2613bfa90b6Smrg 2623bfa90b6Smrg 2633bfa90b6Smrg/* 2643bfa90b6Smrg * Cursor functions 2653bfa90b6Smrg */ 2663bfa90b6Smrg 2673bfa90b6Smrgstatic void 2683bfa90b6Smrgcrtc_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg) 2693bfa90b6Smrg{ 2703bfa90b6Smrg /* XXX: See if this one is needed, as we only support ARGB cursors */ 2713bfa90b6Smrg} 2723bfa90b6Smrg 2733bfa90b6Smrgstatic void 2743bfa90b6Smrgcrtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y) 2753bfa90b6Smrg{ 2763bfa90b6Smrg modesettingPtr ms = modesettingPTR(crtc->scrn); 2773bfa90b6Smrg struct crtc_private *crtcp = crtc->driver_private; 2783bfa90b6Smrg 2793bfa90b6Smrg drmModeMoveCursor(ms->fd, crtcp->drm_crtc->crtc_id, x, y); 2803bfa90b6Smrg} 2813bfa90b6Smrg 2823bfa90b6Smrgstatic void 2833bfa90b6Smrgcrtc_load_cursor_argb_kms(xf86CrtcPtr crtc, CARD32 * image) 2843bfa90b6Smrg{ 2853bfa90b6Smrg modesettingPtr ms = modesettingPTR(crtc->scrn); 2863bfa90b6Smrg struct crtc_private *crtcp = crtc->driver_private; 2873bfa90b6Smrg unsigned char *ptr; 2883bfa90b6Smrg xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn); 2893bfa90b6Smrg CursorPtr c = config->cursor; 2903bfa90b6Smrg 2913bfa90b6Smrg if (vmwgfx_cursor_bypass(ms->fd, c->bits->xhot, c->bits->yhot) != 0) { 2923bfa90b6Smrg xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, 2933bfa90b6Smrg "Failed to set VMWare cursor bypass.\n"); 2943bfa90b6Smrg } 2953bfa90b6Smrg 2963bfa90b6Smrg if (!crtcp->cursor_bo) { 2973bfa90b6Smrg size_t size = 64*64*4; 2983bfa90b6Smrg crtcp->cursor_bo = vmwgfx_dmabuf_alloc(ms->fd, size); 2993bfa90b6Smrg if (!crtcp->cursor_bo) 3003bfa90b6Smrg return; 3013bfa90b6Smrg crtcp->cursor_handle = crtcp->cursor_bo->handle; 3023bfa90b6Smrg } 3033bfa90b6Smrg 3043bfa90b6Smrg ptr = vmwgfx_dmabuf_map(crtcp->cursor_bo); 3053bfa90b6Smrg if (ptr) { 3063bfa90b6Smrg memcpy(ptr, image, 64*64*4); 3073bfa90b6Smrg vmwgfx_dmabuf_unmap(crtcp->cursor_bo); 3083bfa90b6Smrg } 3093bfa90b6Smrg 3103bfa90b6Smrg if (crtc->cursor_shown) 3113bfa90b6Smrg drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id, 3123bfa90b6Smrg crtcp->cursor_handle, 64, 64); 3133bfa90b6Smrg 3143bfa90b6Smrg return; 3153bfa90b6Smrg} 3163bfa90b6Smrg 3173bfa90b6Smrgstatic void 3183bfa90b6Smrgcrtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 * image) 3193bfa90b6Smrg{ 3203bfa90b6Smrg xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn); 3213bfa90b6Smrg modesettingPtr ms = modesettingPTR(crtc->scrn); 3223bfa90b6Smrg 3233bfa90b6Smrg /* Older X servers have cursor reference counting bugs leading to use of 3243bfa90b6Smrg * freed memory and consequently random crashes. Should be fixed as of 3253bfa90b6Smrg * xserver 1.8, but this workaround shouldn't hurt anyway. 3263bfa90b6Smrg */ 3273bfa90b6Smrg if (config->cursor) 3283bfa90b6Smrg config->cursor->refcnt++; 3293bfa90b6Smrg 3303bfa90b6Smrg if (ms->cursor) 3313bfa90b6Smrg FreeCursor(ms->cursor, None); 3323bfa90b6Smrg 3333bfa90b6Smrg ms->cursor = config->cursor; 3343bfa90b6Smrg crtc_load_cursor_argb_kms(crtc, image); 3353bfa90b6Smrg} 3363bfa90b6Smrg 3373bfa90b6Smrgstatic void 3383bfa90b6Smrgcrtc_show_cursor(xf86CrtcPtr crtc) 3393bfa90b6Smrg{ 3403bfa90b6Smrg modesettingPtr ms = modesettingPTR(crtc->scrn); 3413bfa90b6Smrg struct crtc_private *crtcp = crtc->driver_private; 3423bfa90b6Smrg 3433bfa90b6Smrg if (crtcp->cursor_bo) 3443bfa90b6Smrg drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id, 3453bfa90b6Smrg crtcp->cursor_handle, 64, 64); 3463bfa90b6Smrg} 3473bfa90b6Smrg 3483bfa90b6Smrgstatic void 3493bfa90b6Smrgcrtc_hide_cursor(xf86CrtcPtr crtc) 3503bfa90b6Smrg{ 3513bfa90b6Smrg modesettingPtr ms = modesettingPTR(crtc->scrn); 3523bfa90b6Smrg struct crtc_private *crtcp = crtc->driver_private; 3533bfa90b6Smrg 3543bfa90b6Smrg drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id, 0, 0, 0); 3553bfa90b6Smrg} 3563bfa90b6Smrg 3573bfa90b6Smrg/** 3583bfa90b6Smrg * Called at vt leave 3593bfa90b6Smrg */ 3603bfa90b6Smrgvoid 3613bfa90b6Smrgxorg_crtc_cursor_destroy(xf86CrtcPtr crtc) 3623bfa90b6Smrg{ 3633bfa90b6Smrg struct crtc_private *crtcp = crtc->driver_private; 3643bfa90b6Smrg 3653bfa90b6Smrg if (crtcp->cursor_bo) { 3663bfa90b6Smrg vmwgfx_dmabuf_destroy(crtcp->cursor_bo); 3673bfa90b6Smrg crtcp->cursor_bo = NULL; 3683bfa90b6Smrg } 3693bfa90b6Smrg} 3703bfa90b6Smrg 3713bfa90b6Smrg/* 3723bfa90b6Smrg * Misc functions 3733bfa90b6Smrg */ 3743bfa90b6Smrg 3753bfa90b6Smrgstatic void 3763bfa90b6Smrgcrtc_destroy(xf86CrtcPtr crtc) 3773bfa90b6Smrg{ 3783bfa90b6Smrg struct crtc_private *crtcp = crtc->driver_private; 3793bfa90b6Smrg 3803bfa90b6Smrg if (!WSBMLISTEMPTY(&crtcp->entry.scanout_head)) 3813bfa90b6Smrg vmwgfx_scanout_unref(&crtcp->entry); 3823bfa90b6Smrg 3833bfa90b6Smrg xorg_crtc_cursor_destroy(crtc); 3843bfa90b6Smrg 3853bfa90b6Smrg drmModeFreeCrtc(crtcp->drm_crtc); 3863bfa90b6Smrg 3873bfa90b6Smrg free(crtcp); 3883bfa90b6Smrg crtc->driver_private = NULL; 3893bfa90b6Smrg} 3903bfa90b6Smrg 3913bfa90b6Smrgstatic const xf86CrtcFuncsRec crtc_funcs = { 3923bfa90b6Smrg .dpms = crtc_dpms, 3933bfa90b6Smrg .set_mode_major = crtc_set_mode_major, 3943bfa90b6Smrg 3953bfa90b6Smrg .set_cursor_colors = crtc_set_cursor_colors, 3963bfa90b6Smrg .set_cursor_position = crtc_set_cursor_position, 3973bfa90b6Smrg .show_cursor = crtc_show_cursor, 3983bfa90b6Smrg .hide_cursor = crtc_hide_cursor, 3993bfa90b6Smrg .load_cursor_argb = crtc_load_cursor_argb, 4003bfa90b6Smrg 4013bfa90b6Smrg .shadow_create = crtc_shadow_create, 4023bfa90b6Smrg .shadow_allocate = crtc_shadow_allocate, 4033bfa90b6Smrg .shadow_destroy = crtc_shadow_destroy, 4043bfa90b6Smrg 4053bfa90b6Smrg .gamma_set = crtc_gamma_set, 4063bfa90b6Smrg .destroy = crtc_destroy, 4073bfa90b6Smrg}; 4083bfa90b6Smrg 4093bfa90b6Smrgvoid 4103bfa90b6Smrgxorg_crtc_init(ScrnInfoPtr pScrn) 4113bfa90b6Smrg{ 4123bfa90b6Smrg modesettingPtr ms = modesettingPTR(pScrn); 4133bfa90b6Smrg xf86CrtcPtr crtc; 4143bfa90b6Smrg drmModeResPtr res; 4153bfa90b6Smrg drmModeCrtcPtr drm_crtc = NULL; 4163bfa90b6Smrg struct crtc_private *crtcp; 4173bfa90b6Smrg int c; 4183bfa90b6Smrg 4193bfa90b6Smrg res = drmModeGetResources(ms->fd); 4203bfa90b6Smrg if (res == 0) { 4213bfa90b6Smrg ErrorF("Failed drmModeGetResources %d\n", errno); 4223bfa90b6Smrg return; 4233bfa90b6Smrg } 4243bfa90b6Smrg 4253bfa90b6Smrg for (c = 0; c < res->count_crtcs; c++) { 4263bfa90b6Smrg drm_crtc = drmModeGetCrtc(ms->fd, res->crtcs[c]); 4273bfa90b6Smrg 4283bfa90b6Smrg if (!drm_crtc) 4293bfa90b6Smrg continue; 4303bfa90b6Smrg 4313bfa90b6Smrg crtc = xf86CrtcCreate(pScrn, &crtc_funcs); 4323bfa90b6Smrg if (crtc == NULL) 4333bfa90b6Smrg goto out; 4343bfa90b6Smrg 4353bfa90b6Smrg crtcp = calloc(1, sizeof(struct crtc_private)); 4363bfa90b6Smrg if (!crtcp) { 4373bfa90b6Smrg xf86CrtcDestroy(crtc); 4383bfa90b6Smrg goto out; 4393bfa90b6Smrg } 4403bfa90b6Smrg 4413bfa90b6Smrg crtcp->drm_crtc = drm_crtc; 4423bfa90b6Smrg crtcp->entry.pixmap = NULL; 4433bfa90b6Smrg WSBMINITLISTHEAD(&crtcp->entry.scanout_head); 4443bfa90b6Smrg 4453bfa90b6Smrg crtc->driver_private = crtcp; 4463bfa90b6Smrg } 4473bfa90b6Smrg 4483bfa90b6Smrg out: 4493bfa90b6Smrg drmModeFreeResources(res); 4503bfa90b6Smrg} 4513bfa90b6Smrg 4523bfa90b6SmrgPixmapPtr 4533bfa90b6Smrgcrtc_get_scanout(xf86CrtcPtr crtc) 4543bfa90b6Smrg{ 4553bfa90b6Smrg struct crtc_private *crtcp = crtc->driver_private; 4563bfa90b6Smrg return crtcp->entry.pixmap; 4573bfa90b6Smrg} 4583bfa90b6Smrg 4593bfa90b6Smrg/* vim: set sw=4 ts=8 sts=4: */ 460