xorg_crtc.c revision 1e5014f7dfabcaf1f4b5608eb08e97179446eb09
1/* 2 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. 3 * All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sub license, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the 14 * next paragraph) shall be included in all copies or substantial portions 15 * of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 20 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 * 25 * 26 * Author: Alan Hourihane <alanh@tungstengraphics.com> 27 * Author: Jakob Bornecrantz <wallbraker@gmail.com> 28 * 29 */ 30 31#include <unistd.h> 32#include <string.h> 33#include <assert.h> 34#include <stdlib.h> 35#include <math.h> 36#include <stdint.h> 37 38#include "xorg-server.h" 39#include <xf86.h> 40#include <xf86i2c.h> 41#include <xf86Crtc.h> 42#include "xorg_tracker.h" 43#include "xf86Modes.h" 44 45#define DPMS_SERVER 46#include <X11/extensions/dpms.h> 47 48#include "pipe/p_inlines.h" 49#include "util/u_rect.h" 50 51struct crtc_private 52{ 53 drmModeCrtcPtr drm_crtc; 54 55 /* hwcursor */ 56 struct pipe_texture *cursor_tex; 57 unsigned cursor_handle; 58}; 59 60static void 61crtc_dpms(xf86CrtcPtr crtc, int mode) 62{ 63 //ScrnInfoPtr pScrn = crtc->scrn; 64 65 switch (mode) { 66 case DPMSModeOn: 67 case DPMSModeStandby: 68 case DPMSModeSuspend: 69 break; 70 case DPMSModeOff: 71 break; 72 } 73} 74 75static Bool 76crtc_lock(xf86CrtcPtr crtc) 77{ 78 return FALSE; 79} 80 81static void 82crtc_unlock(xf86CrtcPtr crtc) 83{ 84} 85 86static void 87crtc_prepare(xf86CrtcPtr crtc) 88{ 89} 90 91static void 92crtc_commit(xf86CrtcPtr crtc) 93{ 94} 95 96static Bool 97crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode, 98 DisplayModePtr adjusted_mode) 99{ 100 return TRUE; 101} 102 103static void 104crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, 105 DisplayModePtr adjusted_mode, int x, int y) 106{ 107 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn); 108 modesettingPtr ms = modesettingPTR(crtc->scrn); 109 xf86OutputPtr output = config->output[config->compat_output]; 110 drmModeConnectorPtr drm_connector = output->driver_private; 111 struct crtc_private *crtcp = crtc->driver_private; 112 drmModeCrtcPtr drm_crtc = crtcp->drm_crtc; 113 drmModeModeInfo drm_mode; 114 115 drm_mode.clock = mode->Clock; 116 drm_mode.hdisplay = mode->HDisplay; 117 drm_mode.hsync_start = mode->HSyncStart; 118 drm_mode.hsync_end = mode->HSyncEnd; 119 drm_mode.htotal = mode->HTotal; 120 drm_mode.vdisplay = mode->VDisplay; 121 drm_mode.vsync_start = mode->VSyncStart; 122 drm_mode.vsync_end = mode->VSyncEnd; 123 drm_mode.vtotal = mode->VTotal; 124 drm_mode.flags = mode->Flags; 125 drm_mode.hskew = mode->HSkew; 126 drm_mode.vscan = mode->VScan; 127 drm_mode.vrefresh = mode->VRefresh; 128 if (!mode->name) 129 xf86SetModeDefaultName(mode); 130 strncpy(drm_mode.name, mode->name, DRM_DISPLAY_MODE_LEN); 131 132 drmModeSetCrtc(ms->fd, drm_crtc->crtc_id, ms->fb_id, x, y, 133 &drm_connector->connector_id, 1, &drm_mode); 134} 135 136#if 0 137static void 138crtc_load_lut(xf86CrtcPtr crtc) 139{ 140 //ScrnInfoPtr pScrn = crtc->scrn; 141} 142#endif 143 144static void 145crtc_gamma_set(xf86CrtcPtr crtc, CARD16 * red, CARD16 * green, CARD16 * blue, 146 int size) 147{ 148} 149 150static void * 151crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height) 152{ 153 //ScrnInfoPtr pScrn = crtc->scrn; 154 155 return NULL; 156} 157 158static PixmapPtr 159crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) 160{ 161 //ScrnInfoPtr pScrn = crtc->scrn; 162 163 return NULL; 164} 165 166static void 167crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) 168{ 169 //ScrnInfoPtr pScrn = crtc->scrn; 170} 171 172static void 173crtc_destroy(xf86CrtcPtr crtc) 174{ 175 struct crtc_private *crtcp = crtc->driver_private; 176 177 if (crtcp->cursor_tex) 178 pipe_texture_reference(&crtcp->cursor_tex, NULL); 179 180 drmModeFreeCrtc(crtcp->drm_crtc); 181 xfree(crtcp); 182} 183 184static void 185crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 * image) 186{ 187 unsigned char *ptr; 188 modesettingPtr ms = modesettingPTR(crtc->scrn); 189 struct crtc_private *crtcp = crtc->driver_private; 190 struct pipe_transfer *transfer; 191 192 if (!crtcp->cursor_tex) { 193 struct pipe_texture templat; 194 unsigned pitch; 195 196 memset(&templat, 0, sizeof(templat)); 197 templat.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET; 198 templat.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY; 199 templat.target = PIPE_TEXTURE_2D; 200 templat.last_level = 0; 201 templat.depth[0] = 1; 202 templat.format = PIPE_FORMAT_A8R8G8B8_UNORM; 203 templat.width[0] = 64; 204 templat.height[0] = 64; 205 pf_get_block(templat.format, &templat.block); 206 207 crtcp->cursor_tex = ms->screen->texture_create(ms->screen, 208 &templat); 209 ms->api->local_handle_from_texture(ms->api, 210 ms->screen, 211 crtcp->cursor_tex, 212 &pitch, 213 &crtcp->cursor_handle); 214 } 215 216 transfer = ms->screen->get_tex_transfer(ms->screen, crtcp->cursor_tex, 217 0, 0, 0, 218 PIPE_TRANSFER_WRITE, 219 0, 0, 64, 64); 220 ptr = ms->screen->transfer_map(ms->screen, transfer); 221 util_copy_rect(ptr, &crtcp->cursor_tex->block, 222 transfer->stride, 0, 0, 223 64, 64, (void*)image, 64 * 4, 0, 0); 224 ms->screen->transfer_unmap(ms->screen, transfer); 225 ms->screen->tex_transfer_destroy(transfer); 226} 227 228static void 229crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y) 230{ 231 modesettingPtr ms = modesettingPTR(crtc->scrn); 232 struct crtc_private *crtcp = crtc->driver_private; 233 234 drmModeMoveCursor(ms->fd, crtcp->drm_crtc->crtc_id, x, y); 235} 236 237static void 238crtc_show_cursor(xf86CrtcPtr crtc) 239{ 240 modesettingPtr ms = modesettingPTR(crtc->scrn); 241 struct crtc_private *crtcp = crtc->driver_private; 242 243 if (crtcp->cursor_tex) 244 drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id, 245 crtcp->cursor_handle, 64, 64); 246} 247 248static void 249crtc_hide_cursor(xf86CrtcPtr crtc) 250{ 251 modesettingPtr ms = modesettingPTR(crtc->scrn); 252 struct crtc_private *crtcp = crtc->driver_private; 253 254 drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id, 0, 0, 0); 255} 256 257static const xf86CrtcFuncsRec crtc_funcs = { 258 .dpms = crtc_dpms, 259 .save = NULL, 260 .restore = NULL, 261 .lock = crtc_lock, 262 .unlock = crtc_unlock, 263 .mode_fixup = crtc_mode_fixup, 264 .prepare = crtc_prepare, 265 .mode_set = crtc_mode_set, 266 .commit = crtc_commit, 267 .gamma_set = crtc_gamma_set, 268 .shadow_create = crtc_shadow_create, 269 .shadow_allocate = crtc_shadow_allocate, 270 .shadow_destroy = crtc_shadow_destroy, 271 .set_cursor_position = crtc_set_cursor_position, 272 .show_cursor = crtc_show_cursor, 273 .hide_cursor = crtc_hide_cursor, 274 .load_cursor_image = NULL, /* lets convert to argb only */ 275 .set_cursor_colors = NULL, /* using argb only */ 276 .load_cursor_argb = crtc_load_cursor_argb, 277 .destroy = crtc_destroy, 278}; 279 280void 281crtc_cursor_destroy(xf86CrtcPtr crtc) 282{ 283 struct crtc_private *crtcp = crtc->driver_private; 284 285 if (crtcp->cursor_tex) { 286 pipe_texture_reference(&crtcp->cursor_tex, NULL); 287 } 288} 289 290void 291crtc_init(ScrnInfoPtr pScrn) 292{ 293 modesettingPtr ms = modesettingPTR(pScrn); 294 xf86CrtcPtr crtc; 295 drmModeResPtr res; 296 drmModeCrtcPtr drm_crtc = NULL; 297 struct crtc_private *crtcp; 298 int c; 299 300 res = drmModeGetResources(ms->fd); 301 if (res == 0) { 302 ErrorF("Failed drmModeGetResources %d\n", errno); 303 return; 304 } 305 306 for (c = 0; c < res->count_crtcs; c++) { 307 drm_crtc = drmModeGetCrtc(ms->fd, res->crtcs[c]); 308 if (!drm_crtc) 309 continue; 310 311 crtc = xf86CrtcCreate(pScrn, &crtc_funcs); 312 if (crtc == NULL) 313 goto out; 314 315 crtcp = xcalloc(1, sizeof(struct crtc_private)); 316 if (!crtcp) { 317 xf86CrtcDestroy(crtc); 318 goto out; 319 } 320 321 crtcp->drm_crtc = drm_crtc; 322 323 crtc->driver_private = crtcp; 324 325 } 326 327 out: 328 drmModeFreeResources(res); 329} 330 331/* vim: set sw=4 ts=8 sts=4: */ 332