2 * Copyright (C) 2011 glevand <geoffrey.levand@mail.ru>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer,
10 * without modification, immediately at the beginning of the file.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include "xf86_OSproc.h"
36 #include "xf86Cursor.h"
40 #include <sys/types.h>
43 #include <sys/ioctl.h>
48 #include "ps3gpu_ctl.h"
51 #include "ps3gpu_cursor.h"
52 #include "ps3gpu_accel.h"
54 #define PS3GPU_VERSION 4000
55 #define PS3GPU_NAME "ps3gpu"
56 #define PS3GPU_DRIVER_NAME "ps3gpu"
57 #define PS3GPU_MAJOR_VERSION 0
58 #define PS3GPU_MINOR_VERSION 1
59 #define PS3GPU_PATCHLEVEL 0
61 #define PS3GPU_DEVICE_PATH "/dev/ps3gpu"
65 static pointer
Ps3GpuSetup(pointer module
, pointer opts
,
66 int *errmaj
, int *errmin
);
67 static const OptionInfoRec
*Ps3GpuAvailableOptions(int chipid
, int busid
);
68 static void Ps3GpuIdentify(int flags
);
69 static Bool
Ps3GpuProbe(DriverPtr drv
, int flags
);
70 static Bool
Ps3GpuPreInit(ScrnInfoPtr pScrn
, int flags
);
71 static Bool
Ps3GpuScreenInit(int scrnIndex
, ScreenPtr pScreen
,
72 int argc
, char **argv
);
73 static Bool
Ps3GpuCloseScreen(int scrnIndex
, ScreenPtr pScreen
);
74 static void Ps3GpuFreeScreen(int scrnIndex
, int flags
);
75 static Bool
Ps3GpuSaveScreen(ScreenPtr pScreen
, int mode
);
76 static ModeStatus
Ps3GpuValidMode(int scrnIndex
, DisplayModePtr mode
,
77 Bool verbose
, int flags
);
78 static Bool
Ps3GpuSwitchMode(int scrnIndex
, DisplayModePtr mode
, int flags
);
79 static Bool
Ps3GpuSetMode(ScrnInfoPtr pScrn
, DisplayModePtr mode
);
80 static void Ps3GpuAdjustFrame(int scrnIndex
, int x
, int y
, int flags
);
81 static Bool
Ps3GpuEnterVT(int scrnIndex
, int flags
);
82 static void Ps3GpuLeaveVT(int scrnIndex
, int flags
);
83 static void Ps3GpuSave(ScrnInfoPtr pScrn
);
84 static void Ps3GpuRestore(ScrnInfoPtr pScrn
);
85 static Bool
Ps3GpuMapMem(ScrnInfoPtr pScrn
);
86 static Bool
Ps3GpuUnmapMem(ScrnInfoPtr pScrn
);
87 static Bool
Ps3GpuDriverFunc(ScrnInfoPtr pScrn
, xorgDriverFuncOp op
,
90 #endif /* XFree86LOADER */
92 _X_EXPORT DriverRec PS3GPU
= {
97 Ps3GpuAvailableOptions
,
103 static SymTabRec Ps3GpuChipsets
[] = {
114 static const OptionInfoRec Ps3GpuOptions
[] = {
115 { OPTION_SHADOW_FB
, "ShadowFB", OPTV_BOOLEAN
, { 0 }, FALSE
},
116 { OPTION_SW_CURSOR
, "SWcursor", OPTV_BOOLEAN
, { 0 }, FALSE
},
117 { OPTION_NOACCEL
, "NoAccel", OPTV_BOOLEAN
, { 0 }, FALSE
},
118 { -1, NULL
, OPTV_NONE
, { 0 }, FALSE
}
123 static XF86ModuleVersionInfo Ps3GpuVersRec
= {
128 XORG_VERSION_CURRENT
,
129 PS3GPU_MAJOR_VERSION
,
130 PS3GPU_MINOR_VERSION
,
133 ABI_VIDEODRV_VERSION
,
138 _X_EXPORT XF86ModuleData ps3gpuModuleData
= { &Ps3GpuVersRec
, Ps3GpuSetup
, NULL
};
141 Ps3GpuSetup(pointer module
, pointer opts
,
142 int *errmaj
, int *errmin
)
144 static Bool setupDone
= FALSE
;
148 xf86AddDriver(&PS3GPU
, module
, HaveDriverFuncs
);
149 return ((pointer
) 1);
152 *errmaj
= LDR_ONCEONLY
;
157 #endif /* XFree86LOADER */
160 Ps3GpuGetRec(ScrnInfoPtr pScrn
)
162 if (pScrn
->driverPrivate
)
165 pScrn
->driverPrivate
= xnfcalloc(sizeof(Ps3GpuRec
), 1);
171 Ps3GpuFreeRec(ScrnInfoPtr pScrn
)
173 if (!pScrn
->driverPrivate
)
176 xfree(pScrn
->driverPrivate
);
178 pScrn
->driverPrivate
= NULL
;
181 static const OptionInfoRec
*
182 Ps3GpuAvailableOptions(int chipid
, int busid
)
184 return (Ps3GpuOptions
);
188 Ps3GpuIdentify(int flags
)
190 xf86PrintChipsets(PS3GPU_NAME
, "driver for PS3 GPU", Ps3GpuChipsets
);
194 Ps3GpuProbe(DriverPtr drv
, int flags
)
196 ScrnInfoPtr pScrn
= NULL
;
197 GDevPtr
*devSections
;
199 Bool foundScreen
= FALSE
;
202 if (flags
& PROBE_DETECT
)
205 numDevSections
= xf86MatchDevice(PS3GPU_DRIVER_NAME
, &devSections
);
206 if (numDevSections
<= 0)
209 if (numDevSections
> 1) {
210 xf86Msg(X_ERROR
, "Ignoring additional device sections\n");
214 for (i
= 0; i
< numDevSections
; i
++) {
215 int entityIndex
= xf86ClaimFbSlot(drv
, 0, devSections
[i
],
218 pScrn
= xf86ConfigFbEntity(NULL
, 0, entityIndex
,
219 NULL
, NULL
, NULL
, NULL
);
221 pScrn
->driverVersion
= PS3GPU_VERSION
;
222 pScrn
->driverName
= PS3GPU_DRIVER_NAME
;
223 pScrn
->name
= PS3GPU_NAME
;
224 pScrn
->Probe
= Ps3GpuProbe
;
225 pScrn
->PreInit
= Ps3GpuPreInit
;
226 pScrn
->ScreenInit
= Ps3GpuScreenInit
;
227 pScrn
->FreeScreen
= Ps3GpuFreeScreen
;
228 pScrn
->SwitchMode
= Ps3GpuSwitchMode
;
229 pScrn
->AdjustFrame
= Ps3GpuAdjustFrame
;
230 pScrn
->EnterVT
= Ps3GpuEnterVT
;
231 pScrn
->LeaveVT
= Ps3GpuLeaveVT
;
232 pScrn
->ValidMode
= Ps3GpuValidMode
;
240 return (foundScreen
);
244 Ps3GpuPreInit(ScrnInfoPtr pScrn
, int flags
)
247 GDevPtr device
= xf86GetEntityInfo(pScrn
->entityList
[0])->device
;
248 rgb rgbZeros
= { 0, 0, 0 };
249 rgb rgbMasks
= { 0x00ff0000, 0x0000ff00, 0x000000ff };
250 Gamma gammaZeroes
= { 0.0, 0.0, 0.0 };
254 if (flags
& PROBE_DETECT
)
257 pScrn
->monitor
= pScrn
->confScreen
->monitor
;
259 if (!Ps3GpuGetRec(pScrn
))
262 gPtr
= PS3GPUPTR(pScrn
);
264 pScrn
->monitor
= pScrn
->confScreen
->monitor
;
266 if (pScrn
->numEntities
> 1)
269 gPtr
->pEnt
= xf86GetEntityInfo(pScrn
->entityList
[0]);
271 pScrn
->chipset
= (char *) xf86TokenToString(Ps3GpuChipsets
,
272 gPtr
->pEnt
->chipset
);
274 xf86DrvMsg(pScrn
->scrnIndex
, X_INFO
, "Chipset is a %s\n",
277 if (!xf86SetDepthBpp(pScrn
, 0, 0, 0, Support32bppFb
)) {
280 switch (pScrn
->depth
) {
284 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
285 "Given depth (%d) is not supported by this driver\n",
291 xf86PrintDepthBpp(pScrn
);
293 if (pScrn
->depth
== 8)
296 if (!xf86SetWeight(pScrn
, rgbZeros
, rgbMasks
))
299 if (!xf86SetDefaultVisual(pScrn
, -1))
302 if (!xf86SetGamma(pScrn
, gammaZeroes
))
305 xf86CollectOptions(pScrn
, device
->options
);
307 if (!(gPtr
->options
= xalloc(sizeof(Ps3GpuOptions
))))
310 memcpy(gPtr
->options
, Ps3GpuOptions
, sizeof(Ps3GpuOptions
));
312 xf86ProcessOptions(pScrn
->scrnIndex
, pScrn
->options
, gPtr
->options
);
314 if (device
->videoRam
!= 0) {
315 pScrn
->videoRam
= device
->videoRam
;
316 xf86DrvMsg(pScrn
->scrnIndex
, X_CONFIG
, "VideoRAM: %d kByte\n",
319 pScrn
->videoRam
= 64 * 1024;
320 xf86DrvMsg(pScrn
->scrnIndex
, X_PROBED
, "VideoRAM: %d kByte\n",
324 xf86GetOptValBool(gPtr
->options
, OPTION_SHADOW_FB
, &gPtr
->shadowFB
);
325 xf86GetOptValBool(gPtr
->options
, OPTION_SW_CURSOR
, &gPtr
->swCursor
);
326 xf86GetOptValBool(gPtr
->options
, OPTION_NOACCEL
, &gPtr
->noAccel
);
328 if (gPtr
->shadowFB
) {
329 xf86DrvMsg(pScrn
->scrnIndex
, X_CONFIG
,
330 "Using Shadow Framebuffer\n");
333 if (gPtr
->swCursor
) {
334 xf86DrvMsg(pScrn
->scrnIndex
, X_CONFIG
,
335 "Using Software Cursor\n");
338 if (!gPtr
->noAccel
) {
339 xf86DrvMsg(pScrn
->scrnIndex
, X_CONFIG
,
340 "Acceleration disabled\n");
343 pScrn
->progClock
= TRUE
;
345 mode
= (DisplayModePtr
) xalloc(sizeof(DisplayModeRec
));
348 mode
->name
= "ps3gpu current mode";
349 mode
->status
= MODE_OK
;
350 mode
->type
= M_T_BUILTIN
;
352 mode
->HDisplay
= 1920;
353 mode
->HSyncStart
= 0;
357 mode
->VDisplay
= 1080;
358 mode
->VSyncStart
= 0;
364 if (pScrn
->modes
!= NULL
) {
365 xf86DrvMsg(pScrn
->scrnIndex
, X_INFO
,
366 "Ignoring mode specification from screen section\n");
369 pScrn
->currentMode
= pScrn
->modes
= mode
;
371 pScrn
->virtualX
= mode
->HDisplay
;
372 pScrn
->virtualY
= mode
->VDisplay
;
373 pScrn
->displayWidth
= pScrn
->virtualX
;
375 xf86PrintModes(pScrn
);
377 xf86SetDpi(pScrn
, 0, 0);
379 if (gPtr
->shadowFB
) {
380 if (!xf86LoadSubModule(pScrn
, "shadow")) {
381 Ps3GpuFreeRec(pScrn
);
386 if (!xf86LoadSubModule(pScrn
, "fb")) {
387 Ps3GpuFreeRec(pScrn
);
391 if (!gPtr
->noAccel
) {
392 if (!xf86LoadSubModule(pScrn
, "exa")) {
393 Ps3GpuFreeRec(pScrn
);
402 Ps3GpuScreenInit(int scrnIndex
, ScreenPtr pScreen
,
403 int argc
, char **argv
)
409 pScrn
= xf86Screens
[pScreen
->myNum
];
410 gPtr
= PS3GPUPTR(pScrn
);
412 if (!Ps3GpuMapMem(pScrn
))
415 if (!Ps3GpuSetMode(pScrn
, pScrn
->currentMode
))
418 Ps3GpuAdjustFrame(scrnIndex
, pScrn
->frameX0
, pScrn
->frameY0
, 0);
420 miClearVisualTypes();
422 err
= miSetVisualTypes(pScrn
->depth
,
423 miGetDefaultVisualMask(pScrn
->depth
),
424 pScrn
->rgbBits
, pScrn
->defaultVisual
);
428 if (!miSetPixmapDepths())
431 err
= fbScreenInit(pScreen
, gPtr
->fbBase
, pScrn
->virtualX
,
432 pScrn
->virtualY
, pScrn
->xDpi
, pScrn
->yDpi
, pScrn
->displayWidth
,
433 pScrn
->bitsPerPixel
);
437 if (pScrn
->depth
> 8) {
438 VisualPtr visual
= pScreen
->visuals
+ pScreen
->numVisuals
;
440 while (--visual
>= pScreen
->visuals
) {
441 if ((visual
->class | DynamicClass
) == DirectColor
) {
442 visual
->offsetRed
= pScrn
->offset
.red
;
443 visual
->offsetGreen
= pScrn
->offset
.green
;
444 visual
->offsetBlue
= pScrn
->offset
.blue
;
445 visual
->redMask
= pScrn
->mask
.red
;
446 visual
->greenMask
= pScrn
->mask
.green
;
447 visual
->blueMask
= pScrn
->mask
.blue
;
452 fbPictureInit(pScreen
, 0, 0);
454 xf86SetBlackWhitePixels(pScreen
);
456 miInitializeBackingStore(pScreen
);
457 xf86SetBackingStore(pScreen
);
458 xf86SetSilkenMouse(pScreen
);
460 miDCInitialize(pScreen
, xf86GetPointerScreenFuncs());
463 Ps3GpuCursorInit(pScreen
);
466 Ps3GpuAccelInit(pScreen
);
468 if(!miCreateDefColormap(pScreen
))
471 pScreen
->SaveScreen
= Ps3GpuSaveScreen
;
473 gPtr
->closeScreen
= pScreen
->CloseScreen
;
474 pScreen
->CloseScreen
= Ps3GpuCloseScreen
;
476 if (serverGeneration
== 1)
477 xf86ShowUnusedOptions(pScrn
->scrnIndex
, pScrn
->options
);
483 Ps3GpuCloseScreen(int scrnIndex
, ScreenPtr pScreen
)
485 ScrnInfoPtr pScrn
= xf86Screens
[scrnIndex
];
486 Ps3GpuPtr gPtr
= PS3GPUPTR(pScrn
);
489 Ps3GpuRestore(pScrn
);
490 Ps3GpuUnmapMem(pScrn
);
493 if (gPtr
->cursorInfo
)
494 xf86DestroyCursorInfoRec(gPtr
->cursorInfo
);
496 pScrn
->vtSema
= FALSE
;
498 pScreen
->CloseScreen
= gPtr
->closeScreen
;
500 return (*pScreen
->CloseScreen
)(scrnIndex
, pScreen
);
504 Ps3GpuFreeScreen(int scrnIndex
, int flags
)
506 Ps3GpuFreeRec(xf86Screens
[scrnIndex
]);
510 Ps3GpuSaveScreen(ScreenPtr pScreen
, int mode
)
516 Ps3GpuValidMode(int scrnIndex
, DisplayModePtr mode
,
517 Bool verbose
, int flags
)
523 Ps3GpuSwitchMode(int scrnIndex
, DisplayModePtr mode
, int flags
)
529 Ps3GpuSetMode(ScrnInfoPtr pScrn
, DisplayModePtr mode
)
531 Ps3GpuPtr gPtr
= PS3GPUPTR(pScrn
);
532 struct ps3gpu_ctl_flip flip
;
535 pScrn
->vtSema
= TRUE
;
537 flip
.context_id
= gPtr
->gpuContextId
;
538 flip
.head
= PS3GPU_CTL_HEAD_A
;
539 flip
.offset
= gPtr
->fbHandle
;
541 err
= ioctl(gPtr
->fd
, PS3GPU_CTL_FLIP
, &flip
);
543 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
544 "Failed to flip head A\n");
548 flip
.context_id
= gPtr
->gpuContextId
;
549 flip
.head
= PS3GPU_CTL_HEAD_B
;
550 flip
.offset
= gPtr
->fbHandle
;
552 err
= ioctl(gPtr
->fd
, PS3GPU_CTL_FLIP
, &flip
);
554 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
555 "Failed to flip head B\n");
563 Ps3GpuAdjustFrame(int scrnIndex
, int x
, int y
, int flags
)
568 Ps3GpuEnterVT(int scrnIndex
, int flags
)
570 ScrnInfoPtr pScrn
= xf86Screens
[scrnIndex
];
572 if (!Ps3GpuSetMode(pScrn
, pScrn
->currentMode
))
579 Ps3GpuLeaveVT(int scrnIndex
, int flags
)
584 Ps3GpuSave(ScrnInfoPtr pScrn
)
589 Ps3GpuRestore(ScrnInfoPtr pScrn
)
594 Ps3GpuMapMem(ScrnInfoPtr pScrn
)
596 Ps3GpuPtr gPtr
= PS3GPUPTR(pScrn
);
597 struct ps3gpu_ctl_context_allocate contextAllocate
;
598 struct ps3gpu_ctl_memory_allocate memoryAllocate
;
601 gPtr
->fd
= open(PS3GPU_DEVICE_PATH
, O_RDWR
| O_NONBLOCK
);
603 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
604 "Failed to open GPU device\n");
608 gPtr
->fbSize
= (pScrn
->videoRam
- 1024) * 1024;
610 contextAllocate
.vram_size
= pScrn
->videoRam
/ 1024;
612 err
= ioctl(gPtr
->fd
, PS3GPU_CTL_CONTEXT_ALLOCATE
,
615 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
616 "Failed to allocate GPU context\n");
620 gPtr
->gpuContextId
= contextAllocate
.context_id
;
621 gPtr
->gpuControlHandle
= contextAllocate
.control_handle
;
622 gPtr
->gpuControlSize
= contextAllocate
.control_size
;
624 memoryAllocate
.context_id
= contextAllocate
.context_id
;
625 memoryAllocate
.type
= PS3GPU_CTL_MEMORY_TYPE_VIDEO
;
626 memoryAllocate
.size
= gPtr
->fbSize
;
627 memoryAllocate
.align
= 12;
629 err
= ioctl(gPtr
->fd
, PS3GPU_CTL_MEMORY_ALLOCATE
,
632 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
633 "Failed to allocate framebuffer memory\n");
637 gPtr
->fbHandle
= memoryAllocate
.handle
;
638 gPtr
->fbGpuAddress
= memoryAllocate
.gpu_addr
;
640 gPtr
->fbBase
= (pointer
) mmap(NULL
, gPtr
->fbSize
,
641 PROT_READ
| PROT_WRITE
, MAP_SHARED
, gPtr
->fd
,
643 if (gPtr
->fbBase
== (pointer
*) MAP_FAILED
) {
644 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
645 "Failed to map framebuffer memory\n");
653 Ps3GpuUnmapMem(ScrnInfoPtr pScrn
)
655 Ps3GpuPtr gPtr
= PS3GPUPTR(pScrn
);
665 Ps3GpuDriverFunc(ScrnInfoPtr pScrn
, xorgDriverFuncOp op
,
671 case GET_REQUIRED_HW_INTERFACES
:
672 flag
= (CARD32
*) ptr
;