2 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
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:
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
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.
26 * Author: Alan Hourihane <alanh@tungstengraphics.com>
27 * Author: Jakob Bornecrantz <wallbraker@gmail.com>
32 #include "xorg-server.h"
34 #include "xf86_OSproc.h"
37 #include "xf86PciInfo.h"
39 #include "xf86Resources.h"
40 #include "mipointer.h"
42 #include <X11/extensions/randr.h>
47 #include "miscstruct.h"
48 #include "dixstruct.h"
50 #include <X11/extensions/Xv.h>
51 #ifndef XSERVER_LIBPCIACCESS
52 #error "libpciaccess needed"
55 #include <pciaccess.h>
57 #include "xorg_tracker.h"
58 #include "xorg_winsys.h"
60 static void AdjustFrame(int scrnIndex
, int x
, int y
, int flags
);
61 static Bool
CloseScreen(int scrnIndex
, ScreenPtr pScreen
);
62 static Bool
EnterVT(int scrnIndex
, int flags
);
63 static Bool
SaveHWState(ScrnInfoPtr pScrn
);
64 static Bool
RestoreHWState(ScrnInfoPtr pScrn
);
67 static ModeStatus
ValidMode(int scrnIndex
, DisplayModePtr mode
, Bool verbose
,
69 static void FreeScreen(int scrnIndex
, int flags
);
70 static void LeaveVT(int scrnIndex
, int flags
);
71 static Bool
SwitchMode(int scrnIndex
, DisplayModePtr mode
, int flags
);
72 static Bool
ScreenInit(int scrnIndex
, ScreenPtr pScreen
, int argc
,
74 static Bool
PreInit(ScrnInfoPtr pScrn
, int flags
);
81 static const OptionInfoRec Options
[] = {
82 {OPTION_SW_CURSOR
, "SWcursor", OPTV_BOOLEAN
, {0}, FALSE
},
83 {-1, NULL
, OPTV_NONE
, {0}, FALSE
}
87 * Functions that might be needed
90 static const char *exaSymbols
[] = {
100 static const char *fbSymbols
[] = {
106 static const char *ddcSymbols
[] = {
108 "xf86SetDDCproperties",
113 * Exported Xorg driver functions to winsys
117 xorg_tracker_loader_ref_sym_lists()
119 LoaderRefSymLists(exaSymbols
, fbSymbols
, ddcSymbols
, NULL
);
122 const OptionInfoRec
*
123 xorg_tracker_available_options(int chipid
, int busid
)
129 xorg_tracker_set_functions(ScrnInfoPtr scrn
)
131 scrn
->PreInit
= PreInit
;
132 scrn
->ScreenInit
= ScreenInit
;
133 scrn
->SwitchMode
= SwitchMode
;
134 scrn
->AdjustFrame
= AdjustFrame
;
135 scrn
->EnterVT
= EnterVT
;
136 scrn
->LeaveVT
= LeaveVT
;
137 scrn
->FreeScreen
= FreeScreen
;
138 scrn
->ValidMode
= ValidMode
;
142 * Static Xorg funtctions
146 GetRec(ScrnInfoPtr pScrn
)
148 if (pScrn
->driverPrivate
)
151 pScrn
->driverPrivate
= xnfcalloc(sizeof(modesettingRec
), 1);
157 FreeRec(ScrnInfoPtr pScrn
)
162 if (!pScrn
->driverPrivate
)
165 xfree(pScrn
->driverPrivate
);
167 pScrn
->driverPrivate
= NULL
;
171 ProbeDDC(ScrnInfoPtr pScrn
, int index
)
173 ConfiguredMonitor
= NULL
;
177 CreateFrontBuffer(ScrnInfoPtr pScrn
)
179 modesettingPtr ms
= modesettingPTR(pScrn
);
180 ScreenPtr pScreen
= pScrn
->pScreen
;
181 PixmapPtr rootPixmap
= pScreen
->GetScreenPixmap(pScreen
);
184 pScreen
->ModifyPixmapHeader(rootPixmap
,
185 pScrn
->virtualX
, pScrn
->virtualY
,
186 pScrn
->depth
, pScrn
->bitsPerPixel
,
187 pScrn
->displayWidth
* pScrn
->bitsPerPixel
/ 8,
196 pScrn
->displayWidth
* pScrn
->bitsPerPixel
/ 8,
197 xorg_exa_get_pixmap_handle(rootPixmap
), &ms
->fb_id
);
201 AdjustFrame(pScrn
->scrnIndex
, pScrn
->frameX0
, pScrn
->frameY0
, 0);
207 crtc_resize(ScrnInfoPtr pScrn
, int width
, int height
)
209 modesettingPtr ms
= modesettingPTR(pScrn
);
210 //ScreenPtr pScreen = pScrn->pScreen;
211 //PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
212 //Bool fbAccessDisabled;
215 if (width
== pScrn
->virtualX
&& height
== pScrn
->virtualY
)
218 ErrorF("RESIZING TO %dx%d\n", width
, height
);
220 pScrn
->virtualX
= width
;
221 pScrn
->virtualY
= height
;
223 /* HW dependent - FIXME */
224 pScrn
->displayWidth
= pScrn
->virtualX
;
226 drmModeRmFB(ms
->fd
, ms
->fb_id
);
228 /* now create new frontbuffer */
229 return CreateFrontBuffer(pScrn
);
232 static const xf86CrtcConfigFuncsRec crtc_config_funcs
= {
237 PreInit(ScrnInfoPtr pScrn
, int flags
)
239 xf86CrtcConfigPtr xf86_config
;
241 rgb defaultWeight
= { 0, 0, 0 };
245 int max_width
, max_height
;
247 if (pScrn
->numEntities
!= 1)
250 pEnt
= xf86GetEntityInfo(pScrn
->entityList
[0]);
252 if (flags
& PROBE_DETECT
) {
253 ProbeDDC(pScrn
, pEnt
->index
);
257 /* Allocate driverPrivate */
261 ms
= modesettingPTR(pScrn
);
262 ms
->SaveGeneration
= -1;
265 pScrn
->displayWidth
= 640; /* default it */
267 if (ms
->pEnt
->location
.type
!= BUS_PCI
)
270 ms
->PciInfo
= xf86GetPciInfoForEntity(ms
->pEnt
->index
);
272 /* Allocate an entity private if necessary */
273 if (xf86IsEntityShared(pScrn
->entityList
[0])) {
274 FatalError("Entity");
276 msEnt
= xf86GetEntityPrivate(pScrn
->entityList
[0],
277 modesettingEntityIndex
)->ptr
;
278 ms
->entityPrivate
= msEnt
;
283 ms
->entityPrivate
= NULL
;
285 if (xf86RegisterResources(ms
->pEnt
->index
, NULL
, ResNone
)) {
289 if (xf86IsEntityShared(pScrn
->entityList
[0])) {
290 if (xf86IsPrimInitDone(pScrn
->entityList
[0])) {
293 xf86SetPrimInitDone(pScrn
->entityList
[0]);
298 sprintf(BusID
, "PCI:%d:%d:%d",
299 ((ms
->PciInfo
->domain
<< 8) | ms
->PciInfo
->bus
),
300 ms
->PciInfo
->dev
, ms
->PciInfo
->func
303 ms
->fd
= drmOpen(NULL
, BusID
);
308 pScrn
->racMemFlags
= RAC_FB
| RAC_COLORMAP
;
309 pScrn
->monitor
= pScrn
->confScreen
->monitor
;
310 pScrn
->progClock
= TRUE
;
315 PreferConvert24to32
| SupportConvert24to32
| Support32bppFb
))
318 switch (pScrn
->depth
) {
324 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
325 "Given depth (%d) is not supported by the driver\n",
329 xf86PrintDepthBpp(pScrn
);
331 if (!xf86SetWeight(pScrn
, defaultWeight
, defaultWeight
))
333 if (!xf86SetDefaultVisual(pScrn
, -1))
336 /* Process the options */
337 xf86CollectOptions(pScrn
, NULL
);
338 if (!(ms
->Options
= xalloc(sizeof(Options
))))
340 memcpy(ms
->Options
, Options
, sizeof(Options
));
341 xf86ProcessOptions(pScrn
->scrnIndex
, pScrn
->options
, ms
->Options
);
343 /* Allocate an xf86CrtcConfig */
344 xf86CrtcConfigInit(pScrn
, &crtc_config_funcs
);
345 xf86_config
= XF86_CRTC_CONFIG_PTR(pScrn
);
349 xf86CrtcSetSizeRange(pScrn
, 320, 200, max_width
, max_height
);
351 if (xf86ReturnOptValBool(ms
->Options
, OPTION_SW_CURSOR
, FALSE
)) {
360 if (!xf86InitialConfiguration(pScrn
, TRUE
)) {
361 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
, "No valid modes.\n");
362 RestoreHWState(pScrn
);
366 RestoreHWState(pScrn
);
369 * If the driver can do gamma correction, it should call xf86SetGamma() here.
372 Gamma zeros
= { 0.0, 0.0, 0.0 };
374 if (!xf86SetGamma(pScrn
, zeros
)) {
379 if (pScrn
->modes
== NULL
) {
380 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
, "No modes.\n");
384 pScrn
->currentMode
= pScrn
->modes
;
386 /* Set display resolution */
387 xf86SetDpi(pScrn
, 0, 0);
389 /* Load the required sub modules */
390 if (!xf86LoadSubModule(pScrn
, "fb")) {
394 xf86LoaderReqSymLists(fbSymbols
, NULL
);
396 xf86LoadSubModule(pScrn
, "exa");
399 xf86LoadSubModule(pScrn
, "dri2");
406 SaveHWState(ScrnInfoPtr pScrn
)
408 /*xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);*/
414 RestoreHWState(ScrnInfoPtr pScrn
)
416 /*xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);*/
422 CreateScreenResources(ScreenPtr pScreen
)
424 ScrnInfoPtr pScrn
= xf86Screens
[pScreen
->myNum
];
425 modesettingPtr ms
= modesettingPTR(pScrn
);
426 PixmapPtr rootPixmap
;
431 pScreen
->CreateScreenResources
= ms
->createScreenResources
;
432 ret
= pScreen
->CreateScreenResources(pScreen
);
433 pScreen
->CreateScreenResources
= CreateScreenResources
;
435 rootPixmap
= pScreen
->GetScreenPixmap(pScreen
);
437 if (!pScreen
->ModifyPixmapHeader(rootPixmap
, -1, -1, -1, -1, -1, NULL
))
438 FatalError("Couldn't adjust screen pixmap\n");
447 pScrn
->displayWidth
* pScrn
->bitsPerPixel
/ 8,
448 xorg_exa_get_pixmap_handle(rootPixmap
), &ms
->fb_id
);
450 AdjustFrame(pScrn
->scrnIndex
, pScrn
->frameX0
, pScrn
->frameY0
, 0);
456 ScreenInit(int scrnIndex
, ScreenPtr pScreen
, int argc
, char **argv
)
458 ScrnInfoPtr pScrn
= xf86Screens
[pScreen
->myNum
];
459 modesettingPtr ms
= modesettingPTR(pScrn
);
462 /* deal with server regeneration */
467 sprintf(BusID
, "PCI:%d:%d:%d",
468 ((ms
->PciInfo
->domain
<< 8) | ms
->PciInfo
->bus
),
469 ms
->PciInfo
->dev
, ms
->PciInfo
->func
472 ms
->fd
= drmOpen(NULL
, BusID
);
479 ms
->screen
= drm_api_hooks
.create_screen(ms
->fd
, NULL
);
482 FatalError("Could not init pipe_screen\n");
487 pScrn
->pScreen
= pScreen
;
489 /* HW dependent - FIXME */
490 pScrn
->displayWidth
= pScrn
->virtualX
;
492 miClearVisualTypes();
494 if (!miSetVisualTypes(pScrn
->depth
,
495 miGetDefaultVisualMask(pScrn
->depth
),
496 pScrn
->rgbBits
, pScrn
->defaultVisual
))
499 if (!miSetPixmapDepths())
502 pScrn
->memPhysBase
= 0;
505 if (!fbScreenInit(pScreen
, NULL
,
506 pScrn
->virtualX
, pScrn
->virtualY
,
507 pScrn
->xDpi
, pScrn
->yDpi
,
508 pScrn
->displayWidth
, pScrn
->bitsPerPixel
))
511 if (pScrn
->bitsPerPixel
> 8) {
512 /* Fixup RGB ordering */
513 visual
= pScreen
->visuals
+ pScreen
->numVisuals
;
514 while (--visual
>= pScreen
->visuals
) {
515 if ((visual
->class | DynamicClass
) == DirectColor
) {
516 visual
->offsetRed
= pScrn
->offset
.red
;
517 visual
->offsetGreen
= pScrn
->offset
.green
;
518 visual
->offsetBlue
= pScrn
->offset
.blue
;
519 visual
->redMask
= pScrn
->mask
.red
;
520 visual
->greenMask
= pScrn
->mask
.green
;
521 visual
->blueMask
= pScrn
->mask
.blue
;
526 fbPictureInit(pScreen
, NULL
, 0);
528 ms
->createScreenResources
= pScreen
->CreateScreenResources
;
529 pScreen
->CreateScreenResources
= CreateScreenResources
;
531 xf86SetBlackWhitePixels(pScreen
);
533 ms
->exa
= xorg_exa_init(pScrn
);
535 miInitializeBackingStore(pScreen
);
536 xf86SetBackingStore(pScreen
);
537 xf86SetSilkenMouse(pScreen
);
538 miDCInitialize(pScreen
, xf86GetPointerScreenFuncs());
540 /* Need to extend HWcursor support to handle mask interleave */
542 xf86_cursors_init(pScreen
, 64, 64,
543 HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64
|
544 HARDWARE_CURSOR_ARGB
);
546 /* Must force it before EnterVT, so we are in control of VT and
547 * later memory should be bound when allocating, e.g rotate_mem */
548 pScrn
->vtSema
= TRUE
;
550 pScreen
->SaveScreen
= xf86SaveScreen
;
551 ms
->CloseScreen
= pScreen
->CloseScreen
;
552 pScreen
->CloseScreen
= CloseScreen
;
554 if (!xf86CrtcScreenInit(pScreen
))
557 if (!miCreateDefColormap(pScreen
))
560 xf86DPMSInit(pScreen
, xf86DPMSSet
, 0);
562 if (serverGeneration
== 1)
563 xf86ShowUnusedOptions(pScrn
->scrnIndex
, pScrn
->options
);
567 driScreenInit(pScreen
);
571 return EnterVT(scrnIndex
, 1);
575 AdjustFrame(int scrnIndex
, int x
, int y
, int flags
)
577 ScrnInfoPtr pScrn
= xf86Screens
[scrnIndex
];
578 xf86CrtcConfigPtr config
= XF86_CRTC_CONFIG_PTR(pScrn
);
579 xf86OutputPtr output
= config
->output
[config
->compat_output
];
580 xf86CrtcPtr crtc
= output
->crtc
;
582 if (crtc
&& crtc
->enabled
) {
583 crtc
->funcs
->mode_set(crtc
, pScrn
->currentMode
, pScrn
->currentMode
, x
,
585 crtc
->x
= output
->initial_x
+ x
;
586 crtc
->y
= output
->initial_y
+ y
;
591 FreeScreen(int scrnIndex
, int flags
)
593 FreeRec(xf86Screens
[scrnIndex
]);
598 cursor_destroy(xf86CrtcPtr crtc
);
601 LeaveVT(int scrnIndex
, int flags
)
603 ScrnInfoPtr pScrn
= xf86Screens
[scrnIndex
];
604 modesettingPtr ms
= modesettingPTR(pScrn
);
605 xf86CrtcConfigPtr config
= XF86_CRTC_CONFIG_PTR(pScrn
);
608 for (o
= 0; o
< config
->num_crtc
; o
++) {
609 xf86CrtcPtr crtc
= config
->crtc
[o
];
611 cursor_destroy(crtc
);
613 if (crtc
->rotatedPixmap
|| crtc
->rotatedData
) {
614 crtc
->funcs
->shadow_destroy(crtc
, crtc
->rotatedPixmap
,
616 crtc
->rotatedPixmap
= NULL
;
617 crtc
->rotatedData
= NULL
;
621 drmModeRmFB(ms
->fd
, ms
->fb_id
);
623 RestoreHWState(pScrn
);
625 pScrn
->vtSema
= FALSE
;
629 * This gets called when gaining control of the VT, and from ScreenInit().
632 EnterVT(int scrnIndex
, int flags
)
634 ScrnInfoPtr pScrn
= xf86Screens
[scrnIndex
];
635 modesettingPtr ms
= modesettingPTR(pScrn
);
638 * Only save state once per server generation since that's what most
639 * drivers do. Could change this to save state at each VT enter.
641 if (ms
->SaveGeneration
!= serverGeneration
) {
642 ms
->SaveGeneration
= serverGeneration
;
646 if (!flags
) /* signals startup as we'll do this in CreateScreenResources */
647 CreateFrontBuffer(pScrn
);
649 if (!xf86SetDesiredModes(pScrn
))
656 SwitchMode(int scrnIndex
, DisplayModePtr mode
, int flags
)
658 ScrnInfoPtr pScrn
= xf86Screens
[scrnIndex
];
660 return xf86SetSingleMode(pScrn
, mode
, RR_Rotate_0
);
664 CloseScreen(int scrnIndex
, ScreenPtr pScreen
)
666 ScrnInfoPtr pScrn
= xf86Screens
[scrnIndex
];
667 modesettingPtr ms
= modesettingPTR(pScrn
);
670 LeaveVT(scrnIndex
, 0);
673 driCloseScreen(pScreen
);
676 pScreen
->CreateScreenResources
= ms
->createScreenResources
;
679 xorg_exa_close(pScrn
);
684 pScrn
->vtSema
= FALSE
;
685 pScreen
->CloseScreen
= ms
->CloseScreen
;
686 return (*pScreen
->CloseScreen
) (scrnIndex
, pScreen
);
690 ValidMode(int scrnIndex
, DisplayModePtr mode
, Bool verbose
, int flags
)
695 /* vim: set sw=4 ts=8 sts=4: */