blob: f4c80da62653428d0e8c8c36f13867a860f5f2c5 [file] [log] [blame]
Rob Clark487687e2011-07-17 17:29:02 -05001/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
2
3/*
4 * Copyright © 2011 Texas Instruments, Inc
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 *
25 * Authors:
26 * Ian Elliott <ianelliottus@yahoo.com>
27 * Rob Clark <rob@ti.com>
28 */
29
30#ifdef HAVE_CONFIG_H
31#include "config.h"
32#endif
33
34#include "omap_driver.h"
35
36
37Bool omapDebug = 0;
38
39/*
40 * Forward declarations:
41 */
42static const OptionInfoRec *OMAPAvailableOptions(int chipid, int busid);
43static void OMAPIdentify(int flags);
44static Bool OMAPProbe(DriverPtr drv, int flags);
45static Bool OMAPPreInit(ScrnInfoPtr pScrn, int flags);
46static Bool OMAPScreenInit(int scrnIndex, ScreenPtr pScreen, int argc,
47 char **argv);
48static void OMAPLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
49 LOCO * colors, VisualPtr pVisual);
50static Bool OMAPCloseScreen(int scrnIndex, ScreenPtr pScreen);
51static Bool OMAPCreateScreenResources(ScreenPtr pScreen);
52static void OMAPBlockHandler(int i, pointer blockData, pointer pTimeout,
53 pointer pReadmask);
54static Bool OMAPSwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
55static void OMAPAdjustFrame(int scrnIndex, int x, int y, int flags);
56static Bool OMAPEnterVT(int scrnIndex, int flags);
57static void OMAPLeaveVT(int scrnIndex, int flags);
58static void OMAPFreeScreen(int scrnIndex, int flags);
59
60
61
62/**
63 * A structure used by the XFree86 code when loading this driver, so that it
64 * can access the Probe() function, and other functions/info that it uses
65 * before it calls the Probe() function. The name of this structure must be
66 * the all-upper-case version of the driver name.
67 */
68_X_EXPORT DriverRec OMAP = {
69 OMAP_VERSION,
70 (char *)OMAP_DRIVER_NAME,
71 OMAPIdentify,
72 OMAPProbe,
73 OMAPAvailableOptions,
74 NULL,
75 0,
76 NULL,
77#ifdef XSERVER_LIBPCIACCESS
78 NULL,
79 NULL
80#endif
81};
82
83/** Supported "chipsets." */
84static SymTabRec OMAPChipsets[] = {
85 /* OMAP2 and earlier not supported */
86 { 0x3430, "OMAP3430 with PowerVR SGX530" },
87 { 0x3630, "OMAP3630 with PowerVR SGX530" },
88 { 0x4430, "OMAP4430 with PowerVR SGX540" },
89 { 0x4460, "OMAP4460 with PowerVR SGX540" },
90 /* { 4470, "OMAP4470 with <redacted> ;-)" }, */
91 {-1, NULL }
92};
93
94/** Supported options, as enum values. */
95typedef enum {
96 OPTION_DEBUG,
Rob Clark4b8f30a2011-08-28 12:51:26 -050097 OPTION_DRI,
Rob Clark487687e2011-07-17 17:29:02 -050098 OPTION_NO_ACCEL,
99 /* TODO: probably need to add an option to let user specify bus-id */
100} OMAPOpts;
101
102/** Supported options. */
103static const OptionInfoRec OMAPOptions[] = {
104 { OPTION_DEBUG, "Debug", OPTV_BOOLEAN, {0}, FALSE },
Rob Clark4b8f30a2011-08-28 12:51:26 -0500105 { OPTION_DRI, "DRI", OPTV_BOOLEAN, {0}, FALSE },
Rob Clark487687e2011-07-17 17:29:02 -0500106 { OPTION_NO_ACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
107 { -1, NULL, OPTV_NONE, {0}, FALSE }
108};
109
110/**
111 * Helper function for opening a connection to the DRM.
112 */
113
114static int
115OMAPOpenDRM(int n)
116{
117 char bus_id[32];
118 snprintf(bus_id, sizeof(bus_id), "platform:omapdrm:%02d", n);
119 return drmOpen("omapdrm", bus_id);
120}
121
122static Bool
123OMAPOpenDRMMaster(ScrnInfoPtr pScrn, int n)
124{
125 OMAPPtr pOMAP = OMAPPTR(pScrn);
126 drmSetVersion sv;
127 int err;
128
129 pOMAP->drmFD = OMAPOpenDRM(n);
130 if (pOMAP->drmFD == -1) {
131 ERROR_MSG("Cannot open a connection with the DRM.");
132 return FALSE;
133 }
134
135 /* Check that what we opened was a master or a master-capable FD,
136 * by setting the version of the interface we'll use to talk to it.
137 * (see DRIOpenDRMMaster() in DRI1)
138 */
139 sv.drm_di_major = 1;
140 sv.drm_di_minor = 1;
141 sv.drm_dd_major = -1;
142 sv.drm_dd_minor = -1;
143 err = drmSetInterfaceVersion(pOMAP->drmFD, &sv);
144 if (err != 0) {
145 ERROR_MSG("Cannot set the DRM interface version.");
146 drmClose(pOMAP->drmFD);
147 pOMAP->drmFD = -1;
148 return FALSE;
149 }
150
Rob Clark4b8f30a2011-08-28 12:51:26 -0500151 pOMAP->deviceName = drmGetDeviceNameFromFd(pOMAP->drmFD);
152
Rob Clark487687e2011-07-17 17:29:02 -0500153 return TRUE;
154}
155
156
157
158/**
159 * Helper function for closing a connection to the DRM.
160 */
161static void
162OMAPCloseDRMMaster(ScrnInfoPtr pScrn)
163{
164 OMAPPtr pOMAP = OMAPPTR(pScrn);
165
166 if (pOMAP && (pOMAP->drmFD > 0)) {
Rob Clark4b8f30a2011-08-28 12:51:26 -0500167 drmFree(pOMAP->deviceName);
Rob Clark487687e2011-07-17 17:29:02 -0500168 drmClose(pOMAP->drmFD);
169 pOMAP->drmFD = -1;
170 }
171}
172
173
174
175/**
176 * Helper function for calculating the stride of pixmaps.
177 * TODO get stride requirements from kernel driver, or from EXA module,
178 * rather than hard-coding..
179 */
180#define STRIDE_BOUNDARY 32
181unsigned int
182OMAPCalculateStride(unsigned int width, unsigned int bitsPerPixel)
183{
184 unsigned int alignedWidth;
185
186 alignedWidth = (width + (STRIDE_BOUNDARY - 1)) & ~(STRIDE_BOUNDARY - 1);
187 return ((alignedWidth * bitsPerPixel) + 7) / 8;
188}
189
190
191static Bool
192OMAPMapMem(ScrnInfoPtr pScrn)
193{
194 OMAPPtr pOMAP = OMAPPTR(pScrn);
195 int pitch;
196
197 pitch = OMAPCalculateStride(pScrn->virtualX, pScrn->bitsPerPixel);
198
199 DEBUG_MSG("allocating new scanout buffer: %dx%d (%d)",
200 pScrn->virtualX, pScrn->virtualY, pitch);
201
202 pOMAP->scanout = omap_bo_new(pOMAP->dev, pScrn->virtualY * pitch,
203 OMAP_BO_SCANOUT | OMAP_BO_WC);
204 if (!pOMAP->scanout) {
205 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
206 "Error allocating scanout buffer\n");
207 return FALSE;
208 }
209
210 pScrn->displayWidth = pitch / (pScrn->bitsPerPixel / 8);
211
212 return TRUE;
213}
214
215
216static Bool
217OMAPUnmapMem(ScrnInfoPtr pScrn)
218{
219 OMAPPtr pOMAP = OMAPPTR(pScrn);
220 drmmode_remove_fb(pScrn);
221 omap_bo_del(pOMAP->scanout);
222 pOMAP->scanout = NULL;
223 return TRUE;
224}
225
226
227
228/** Let the XFree86 code know the Setup() function. */
229static MODULESETUPPROTO(OMAPSetup);
230
231/** Provide basic version information to the XFree86 code. */
232static XF86ModuleVersionInfo OMAPVersRec =
233{
234 OMAP_DRIVER_NAME,
235 MODULEVENDORSTRING,
236 MODINFOSTRING1,
237 MODINFOSTRING2,
238 XORG_VERSION_CURRENT,
239 OMAP_MAJOR_VERSION, OMAP_MINOR_VERSION, OMAP_PATCHLEVEL,
240 ABI_CLASS_VIDEODRV,
241 ABI_VIDEODRV_VERSION,
242 MOD_CLASS_VIDEODRV,
243 {0, 0, 0, 0}
244};
245
246/** Let the XFree86 code know about the VersRec and Setup() function. */
247_X_EXPORT XF86ModuleData omapModuleData = { &OMAPVersRec, OMAPSetup, NULL };
248
249
250/**
251 * The first function that the XFree86 code calls, after loading this module.
252 */
253static pointer
254OMAPSetup(pointer module, pointer opts, int *errmaj, int *errmin)
255{
256 static Bool setupDone = FALSE;
257
258 /* This module should be loaded only once, but check to be sure: */
259 if (!setupDone) {
260 setupDone = TRUE;
261 xf86AddDriver(&OMAP, module, 0);
262
263 /* The return value must be non-NULL on success even though there is no
264 * TearDownProc.
265 */
266 return (pointer) 1;
267 } else {
268 if (errmaj)
269 *errmaj = LDR_ONCEONLY;
270 return NULL;
271 }
272}
273
274
275/**
276 * Allocate the driver's Screen-specific, "private" data structure and hook it
277 * into the ScrnInfoRec's driverPrivate field.
278 */
279static Bool
280OMAPGetRec(ScrnInfoPtr pScrn)
281{
282 if (pScrn->driverPrivate != NULL)
283 return TRUE;
284
285 pScrn->driverPrivate = calloc(1, sizeof(OMAPRec));
286 if (pScrn->driverPrivate == NULL)
287 return FALSE;
288
289 return TRUE;
290}
291
292
293/**
294 * Free the driver's Screen-specific, "private" data structure and NULL-out the
295 * ScrnInfoRec's driverPrivate field.
296 */
297static void
298OMAPFreeRec(ScrnInfoPtr pScrn)
299{
300 if (pScrn->driverPrivate == NULL)
301 return;
302 free(pScrn->driverPrivate);
303 pScrn->driverPrivate = NULL;
304}
305
306
307/**
308 * The mandatory AvailableOptions() function. It returns the available driver
309 * options to the "-configure" option, so that an xorg.conf file can be built
310 * and the user can see which options are available for them to use.
311 */
312static const OptionInfoRec *
313OMAPAvailableOptions(int chipid, int busid)
314{
315 return OMAPOptions;
316}
317
318
319
320/**
321 * The mandatory Identify() function. It is run before Probe(), and prints out
322 * an identifying message, which includes the chipset(s) the driver supports.
323 */
324static void
325OMAPIdentify(int flags)
326{
327 xf86PrintChipsets(OMAP_NAME, "Driver for TI OMAP", OMAPChipsets);
328}
329
330
331
332/**
333 * The driver's Probe() function. This function finds all instances of the
334 * TI OMAP hardware that the driver supports (from within the "xorg.conf"
335 * device sections), and for instances not already claimed by another driver,
336 * claim the instances, and allocate a ScrnInfoRec. Only minimal hardware
337 * probing is allowed here.
338 */
339static Bool
340OMAPProbe(DriverPtr drv, int flags)
341{
342 int i;
343 ScrnInfoPtr pScrn;
344 GDevPtr *devSections;
345 int numDevSections;
346 Bool foundScreen = FALSE;
347
348 if (flags & PROBE_DETECT) {
349 EARLY_ERROR_MSG("The %s driver does not support the \"-configure\" or "
350 "\"-probe\" command line arguments.", OMAP_NAME);
351 return FALSE;
352 }
353
354 /* Get the "xorg.conf" file device sections that match this driver, and
355 * return (error out) if there are none:
356 */
357 numDevSections = xf86MatchDevice(OMAP_DRIVER_NAME, &devSections);
358 if (numDevSections <= 0) {
359 EARLY_ERROR_MSG("Did not find any matching device section in "
360 "configuration file");
361 return FALSE;
362 }
363
364 for (i = 0; i < numDevSections; i++) {
365 int fd = OMAPOpenDRM(i);
366 if (fd != -1) {
367 int entity = xf86ClaimNoSlot(drv, 0, devSections[i], TRUE);
368
369 pScrn = xf86AllocateScreen(drv, 0);
370 if (!pScrn) {
371 EARLY_ERROR_MSG("Cannot allocate a ScrnInfoPtr");
372 return FALSE;
373 }
374 xf86AddEntityToScreen(pScrn, entity);
375
376 foundScreen = TRUE;
377
378 pScrn->driverVersion = OMAP_VERSION;
379 pScrn->driverName = (char *)OMAP_DRIVER_NAME;
380 pScrn->name = (char *)OMAP_NAME;
381 pScrn->Probe = OMAPProbe;
382 pScrn->PreInit = OMAPPreInit;
383 pScrn->ScreenInit = OMAPScreenInit;
384 pScrn->SwitchMode = OMAPSwitchMode;
385 pScrn->AdjustFrame = OMAPAdjustFrame;
386 pScrn->EnterVT = OMAPEnterVT;
387 pScrn->LeaveVT = OMAPLeaveVT;
388 pScrn->FreeScreen = OMAPFreeScreen;
389
390 /* would be nice to be able to keep the connection open.. but
391 * currently we don't allocate the private until PreInit
392 */
393 drmClose(fd);
394 }
395 }
396 free(devSections);
397 return foundScreen;
398}
399
400
401
402/**
403 * The driver's PreInit() function. Additional hardware probing is allowed
404 * now, including display configuration.
405 */
406static Bool
407OMAPPreInit(ScrnInfoPtr pScrn, int flags)
408{
409 OMAPPtr pOMAP;
410 int default_depth, fbbpp;
411 rgb defaultWeight = { 0, 0, 0 };
412 rgb defaultMask = { 0, 0, 0 };
413 Gamma defaultGamma = { 0.0, 0.0, 0.0 };
414 uint64_t value;
415 int i;
416
417 TRACE_ENTER();
418
419 if (flags & PROBE_DETECT) {
420 ERROR_MSG("The %s driver does not support the \"-configure\" or "
421 "\"-probe\" command line arguments.", OMAP_NAME);
422 return FALSE;
423 }
424
425 /* Check the number of entities, and fail if it isn't one. */
426 if (pScrn->numEntities != 1) {
427 ERROR_MSG("Driver expected 1 entity, but found %d for screen %d",
428 pScrn->numEntities, pScrn->scrnIndex);
429 return FALSE;
430 }
431
432 /* Allocate the driver's Screen-specific, "private" data structure: */
433 OMAPGetRec(pScrn);
434 pOMAP = OMAPPTR(pScrn);
435
436 pOMAP->pEntityInfo = xf86GetEntityInfo(pScrn->entityList[0]);
437
438 pScrn->monitor = pScrn->confScreen->monitor;
439
440 /* Get the current depth, and set it for XFree86: */
441 default_depth = 24; /* TODO: get from kernel */
442 fbbpp = 32; /* TODO: get from kernel */
443
444 if (!xf86SetDepthBpp(pScrn, default_depth, 0, fbbpp, Support32bppFb)) {
445 /* The above function prints an error message. */
446 goto fail;
447 }
448 xf86PrintDepthBpp(pScrn);
449
450 /* Set the color weight: */
451 if (!xf86SetWeight(pScrn, defaultWeight, defaultMask)) {
452 /* The above function prints an error message. */
453 goto fail;
454 }
455
456 /* Set the gamma: */
457 if (!xf86SetGamma(pScrn, defaultGamma)) {
458 /* The above function prints an error message. */
459 goto fail;
460 }
461
462 /* Visual init: */
463 if (!xf86SetDefaultVisual(pScrn, -1)) {
464 /* The above function prints an error message. */
465 goto fail;
466 }
467
468 /* We don't support 8-bit depths: */
469 if (pScrn->depth < 16) {
470 ERROR_MSG("The requested default visual (%s) has an unsupported "
471 "depth (%d).",
472 xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
473 goto fail;
474 }
475
476 /* Using a programmable clock: */
477 pScrn->progClock = TRUE;
478
479 /* Open a connection to the DRM, so we can communicate with the KMS code: */
480 if (!OMAPOpenDRMMaster(pScrn, 0)) {
481 goto fail;
482 }
483 DEBUG_MSG("Became DRM master.");
484
485 /* create DRM device instance: */
486 pOMAP->dev = omap_device_new(pOMAP->drmFD);
487
488 /* query chip-id: */
489 if (omap_get_param(pOMAP->dev, OMAP_PARAM_CHIPSET_ID, &value)) {
490 ERROR_MSG("Could not read chipset");
491 goto fail;
492 }
493 pOMAP->chipset = value;
494
495 /* find matching chipset name: */
496 for (i = 0; OMAPChipsets[i].name; i++) {
497 if (OMAPChipsets[i].token == pOMAP->chipset) {
498 pScrn->chipset = (char *)OMAPChipsets[i].name;
499 break;
500 }
501 }
502
503 if (!pScrn->chipset) {
504 ERROR_MSG("Unknown chipset: %s", pScrn->chipset);
505 goto fail;
506 }
507
508 INFO_MSG("Found chipset: %s", pScrn->chipset);
509
510 /*
511 * Process the "xorg.conf" file options:
512 */
513 xf86CollectOptions(pScrn, NULL);
514 if (!(pOMAP->pOptionInfo = calloc(1, sizeof(OMAPOptions))))
515 return FALSE;
516 memcpy(pOMAP->pOptionInfo, OMAPOptions, sizeof(OMAPOptions));
517 xf86ProcessOptions(pScrn->scrnIndex, pOMAP->pEntityInfo->device->options,
518 pOMAP->pOptionInfo);
519
520 /* Determine if the user wants debug messages turned on: */
521 omapDebug = xf86ReturnOptValBool(pOMAP->pOptionInfo, OPTION_DEBUG, FALSE);
522
Rob Clark4b8f30a2011-08-28 12:51:26 -0500523 pOMAP->dri = xf86ReturnOptValBool(pOMAP->pOptionInfo, OPTION_DRI, TRUE);
524
525
Rob Clark487687e2011-07-17 17:29:02 -0500526 /* Determine if the user wants to disable acceleration: */
527 pOMAP->NoAccel =
528 xf86ReturnOptValBool(pOMAP->pOptionInfo, OPTION_NO_ACCEL, FALSE);
529
530 /*
531 * Select the video modes:
532 */
533 INFO_MSG("Setting the video modes ...");
534
535 /* Don't call drmCheckModesettingSupported() as its written only for
536 * PCI devices.
537 */
538
539 /* Do initial KMS setup: */
540 if (!drmmode_pre_init(pScrn, pOMAP->drmFD, (pScrn->bitsPerPixel >> 3))) {
541 ERROR_MSG("Cannot get KMS resources");
542 } else {
543 INFO_MSG("Got KMS resources");
544 }
545
546 xf86RandR12PreInit(pScrn);
547
548 /* Let XFree86 calculate or get (from command line) the display DPI: */
549 xf86SetDpi(pScrn, 0, 0);
550
551 /* Ensure we have a supported depth: */
552 switch (pScrn->bitsPerPixel) {
553 case 16:
554 case 24:
555 case 32:
556 break;
557 default:
558 ERROR_MSG("The requested number of bits per pixel (%d) is unsupported.",
559 pScrn->bitsPerPixel);
560 goto fail;
561 }
562
563
564 /* Load external sub-modules now: */
565
566 if (!(xf86LoadSubModule(pScrn, "dri2") &&
567 xf86LoadSubModule(pScrn, "exa") &&
568 xf86LoadSubModule(pScrn, "fb"))) {
569 goto fail;
570 }
571
572 switch (pOMAP->chipset) {
573 case 0x3430:
574 case 0x3630:
575 case 0x4430:
576 case 0x4460:
577 if (xf86LoadSubModule(pScrn, SUB_MODULE_PVR)) {
578 INFO_MSG("Loaded the %s sub-module", SUB_MODULE_PVR);
579 } else {
580 INFO_MSG("Cannot load the %s sub-module", SUB_MODULE_PVR);
581 /* note that this is not fatal.. since IMG/PVR EXA module
582 * is closed source, it is only optional.
583 */
584 pOMAP->NoAccel = TRUE; /* don't call InitPowerVREXA() */
585 }
586 break;
587 /* case 0x4470: ..; break; */
588 default:
589 ERROR_MSG("Unsupported chipset: %d", pOMAP->chipset);
590 goto fail;
591 }
592
593 TRACE_EXIT();
594 return TRUE;
595
596fail:
597 TRACE_EXIT();
598 OMAPFreeRec(pScrn);
599 return FALSE;
600}
601
602
603
604/**
605 * The driver's ScreenInit() function. Fill in pScreen, map the frame buffer,
606 * save state, initialize the mode, etc.
607 */
608static Bool
609OMAPScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
610{
611 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
612 OMAPPtr pOMAP = OMAPPTR(pScrn);
613 VisualPtr visual;
614 xf86CrtcConfigPtr xf86_config;
615 int i;
616
617 TRACE_ENTER();
618
Rob Clark487687e2011-07-17 17:29:02 -0500619 /* Allocate and map memory areas we need */
620 if (!OMAPMapMem(pScrn))
621 return FALSE;
622
623 xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
624
625 /* need to point to new screen on server regeneration */
626 for (i = 0; i < xf86_config->num_crtc; i++)
627 xf86_config->crtc[i]->scrn = pScrn;
628 for (i = 0; i < xf86_config->num_output; i++)
629 xf86_config->output[i]->scrn = pScrn;
630
631 /*
632 * The next step is to setup the screen's visuals, and initialize the
633 * framebuffer code. In cases where the framebuffer's default
634 * choices for things like visual layouts and bits per RGB are OK,
635 * this may be as simple as calling the framebuffer's ScreenInit()
636 * function. If not, the visuals will need to be setup before calling
637 * a fb ScreenInit() function and fixed up after.
638 *
639 * For most PC hardware at depths >= 8, the defaults that fb uses
640 * are not appropriate. In this driver, we fixup the visuals after.
641 */
642
643 /*
644 * Reset the visual list.
645 */
646
647 miClearVisualTypes();
648 if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth),
649 pScrn->rgbBits, pScrn->defaultVisual)) {
650 ERROR_MSG("Cannot initialize the visual type for %d bits per pixel!",
651 pScrn->bitsPerPixel);
652 goto fail;
653 }
654
655 if (!miSetPixmapDepths()) {
656 ERROR_MSG("Cannot initialize the pixmap depth!");
657 goto fail;
658 }
659
660 /* Initialize some generic 2D drawing functions: */
661 if (!fbScreenInit(pScreen, omap_bo_map(pOMAP->scanout),
662 pScrn->virtualX, pScrn->virtualY,
663 pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
664 pScrn->bitsPerPixel)) {
665 ERROR_MSG("fbScreenInit() failed!");
666 goto fail;
667 }
668
669 /* Fixup RGB ordering: */
670 visual = pScreen->visuals + pScreen->numVisuals;
671 while (--visual >= pScreen->visuals) {
672 if ((visual->class | DynamicClass) == DirectColor) {
673 visual->offsetRed = pScrn->offset.red;
674 visual->offsetGreen = pScrn->offset.green;
675 visual->offsetBlue = pScrn->offset.blue;
676 visual->redMask = pScrn->mask.red;
677 visual->greenMask = pScrn->mask.green;
678 visual->blueMask = pScrn->mask.blue;
679 }
680 }
681
682 /* Continue initializing the generic 2D drawing functions after fixing the
683 * RGB ordering:
684 */
685 if (!fbPictureInit(pScreen, NULL, 0)) {
686 ERROR_MSG("fbPictureInit() failed!");
687 goto fail;
688 }
689
690 /* Set the initial black & white colormap indices: */
691 xf86SetBlackWhitePixels(pScreen);
692
693 /* Initialize backing store: */
694 miInitializeBackingStore(pScreen);
695 xf86SetBackingStore(pScreen);
696
697 /* Initialize the cursor: */
698 miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
699
700 /* Cause the cursor position to be updated by the mouse signal handler: */
701 xf86SetSilkenMouse(pScreen);
702
Rob Clark4b8f30a2011-08-28 12:51:26 -0500703#ifdef XF86DRI
704 if (pOMAP->dri) {
705 pOMAP->dri = OMAPDRI2ScreenInit(pScreen);
706 }
707#endif
708
Rob Clark487687e2011-07-17 17:29:02 -0500709 /* XXX -- Is this the right place for this? The Intel i830 driver says:
710 * "Must force it before EnterVT, so we are in control of VT..."
711 */
712 pScrn->vtSema = TRUE;
713
714 /* Take over the virtual terminal from the console, set the desired mode,
715 * etc.:
716 */
717 OMAPEnterVT(scrnIndex, 0);
718
719 /* Set the desired mode(s): */
720 if (!xf86SetDesiredModes(pScrn)) {
721 ERROR_MSG("xf86SetDesiredModes() failed!");
722 goto fail;
723 }
724
725 /* Do some XRandR initialization: */
726 if (!xf86CrtcScreenInit(pScreen)) {
727 ERROR_MSG("xf86CrtcScreenInit() failed!");
728 goto fail;
729 }
730
731 if (!miCreateDefColormap(pScreen)) {
732 ERROR_MSG("Cannot create colormap!");
733 goto fail;
734 }
735
736 if (!xf86HandleColormaps(pScreen, 256, 8, OMAPLoadPalette, NULL,
737 CMAP_PALETTED_TRUECOLOR)) {
738 ERROR_MSG("xf86HandleColormaps() failed!");
739 goto fail;
740 }
741
742 /* Setup power management: */
743 xf86DPMSInit(pScreen, xf86DPMSSet, 0);
744
745 pScreen->SaveScreen = xf86SaveScreen;
746
747 /* Wrap some screen functions: */
748 wrap(pOMAP, pScreen, CloseScreen, OMAPCloseScreen);
749 wrap(pOMAP, pScreen, CreateScreenResources, OMAPCreateScreenResources);
750 wrap(pOMAP, pScreen, BlockHandler, OMAPBlockHandler);
751
752 /*
753 * Initialize external sub-modules for EXA now:
754 */
755
756 if (!pOMAP->NoAccel) {
757 switch (pOMAP->chipset) {
758 case 0x3430:
759 case 0x3630:
760 case 0x4430:
761 case 0x4460:
762 INFO_MSG("Initializing the \"%s\" sub-module ...", SUB_MODULE_PVR);
763 pOMAP->pOMAPEXA = InitPowerVREXA(pScreen, pScrn);
764 if (pOMAP->pOMAPEXA) {
765 INFO_MSG("Successfully initialized the \"%s\" sub-module",
766 SUB_MODULE_PVR);
767 } else {
768 INFO_MSG("Could not initialize the \"%s\" sub-module",
769 SUB_MODULE_PVR);
770 pOMAP->NoAccel = TRUE;
771 }
772 break;
773 /* case 4470: ..; break; */
774 default:
775 ERROR_MSG("Unsupported chipset: %d", pOMAP->chipset);
776 pOMAP->NoAccel = TRUE;
777 break;
778 }
779 }
780
781 if (!pOMAP->pOMAPEXA) {
782 pOMAP->pOMAPEXA = InitNullEXA(pScreen, pScrn);
783 }
784
Rob Clark4b8f30a2011-08-28 12:51:26 -0500785 drmmode_screen_init(pScrn);
Rob Clark487687e2011-07-17 17:29:02 -0500786
787 TRACE_EXIT();
788 return TRUE;
789
790fail:
791 TRACE_EXIT();
792 return FALSE;
793}
794
795
796static void
797OMAPLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
798 LOCO * colors, VisualPtr pVisual)
799{
800 TRACE_ENTER();
801 TRACE_EXIT();
802}
803
804
805/**
806 * The driver's CloseScreen() function. This is called at the end of each
807 * server generation. Restore state, unmap the frame buffer (and any other
808 * mapped memory regions), and free per-Screen data structures (except those
809 * held by pScrn).
810 */
811static Bool
812OMAPCloseScreen(int scrnIndex, ScreenPtr pScreen)
813{
814 ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
815 OMAPPtr pOMAP = OMAPPTR(pScrn);
816
817 TRACE_ENTER();
818
Rob Clark4b8f30a2011-08-28 12:51:26 -0500819 drmmode_screen_fini(pScrn);
Rob Clark487687e2011-07-17 17:29:02 -0500820
821 if (pScrn->vtSema == TRUE) {
822 OMAPLeaveVT(scrnIndex, 0);
823 }
824
825 if (pOMAP->pOMAPEXA) {
826 if (pOMAP->pOMAPEXA->CloseScreen) {
827 pOMAP->pOMAPEXA->CloseScreen(scrnIndex, pScreen);
828 }
829 }
830
Rob Clark4b8f30a2011-08-28 12:51:26 -0500831#ifdef XF86DRI
832 if (pOMAP->dri) {
833 OMAPDRI2CloseScreen(pScreen);
834 }
835#endif
836
Rob Clark487687e2011-07-17 17:29:02 -0500837 OMAPUnmapMem(pScrn);
838
839 pScrn->vtSema = FALSE;
840
841 unwrap(pOMAP, pScreen, CloseScreen);
842 unwrap(pOMAP, pScreen, BlockHandler);
843 unwrap(pOMAP, pScreen, CreateScreenResources);
844
845 TRACE_EXIT();
846
847 return (*pScreen->CloseScreen)(scrnIndex, pScreen);
848}
849
850
851
852/**
853 * Adjust the screen pixmap for the current location of the front buffer.
854 * This is done at EnterVT when buffers are bound as long as the resources
855 * have already been created, but the first EnterVT happens before
856 * CreateScreenResources.
857 */
858static Bool
859OMAPCreateScreenResources(ScreenPtr pScreen)
860{
861 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
862 OMAPPtr pOMAP = OMAPPTR(pScrn);
863
864 swap(pOMAP, pScreen, CreateScreenResources);
865 if (!(*pScreen->CreateScreenResources) (pScreen))
866 return FALSE;
867 swap(pOMAP, pScreen, CreateScreenResources);
868
869 return TRUE;
870}
871
872
873static void
874OMAPBlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask)
875{
876 ScreenPtr pScreen = screenInfo.screens[i];
877 ScrnInfoPtr pScrn = xf86Screens[i];
878 OMAPPtr pOMAP = OMAPPTR(pScrn);
879
880 swap(pOMAP, pScreen, BlockHandler);
881 (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
882 swap(pOMAP, pScreen, BlockHandler);
883
884 /* TODO OMAPVideoBlockHandler(), etc.. */
885}
886
887
888
889/**
890 * The driver's SwitchMode() function. Initialize the new mode for the
891 * Screen.
892 */
893static Bool
894OMAPSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
895{
896 ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
897 return xf86SetSingleMode(pScrn, mode, RR_Rotate_0);
898}
899
900
901
902/**
903 * The driver's AdjustFrame() function. For cases where the frame buffer is
904 * larger than the monitor resolution, this function can pan around the frame
905 * buffer within the "viewport" of the monitor.
906 */
907static void
908OMAPAdjustFrame(int scrnIndex, int x, int y, int flags)
909{
910 ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
911 drmmode_adjust_frame(pScrn, x, y, flags);
912}
913
914
915
916/**
917 * The driver's EnterVT() function. This is called at server startup time, and
918 * when the X server takes over the virtual terminal from the console. As
919 * such, it may need to save the current (i.e. console) HW state, and set the
920 * HW state as needed by the X server.
921 */
922static Bool
923OMAPEnterVT(int scrnIndex, int flags)
924{
925 ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
926 OMAPPtr pOMAP = OMAPPTR(pScrn);
927 int ret;
928
929 TRACE_ENTER();
930
931 ret = drmSetMaster(pOMAP->drmFD);
932 if (ret) {
933 ERROR_MSG("Cannot get DRM master: %s\n", strerror(ret));
934 }
935
936 if (!xf86SetDesiredModes(pScrn)) {
937 ERROR_MSG("xf86SetDesiredModes() failed!");
938 return FALSE;
939 }
940
941 TRACE_EXIT();
942 return TRUE;
943}
944
945
946
947/**
948 * The driver's LeaveVT() function. This is called when the X server
949 * temporarily gives up the virtual terminal to the console. As such, it may
950 * need to restore the console's HW state.
951 */
952static void
953OMAPLeaveVT(int scrnIndex, int flags)
954{
955 ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
956 OMAPPtr pOMAP = OMAPPTR(pScrn);
957 int ret;
958
959 TRACE_ENTER();
960
961 ret = drmDropMaster(pOMAP->drmFD);
962 if (ret) {
963 WARNING_MSG("drmDropMaster failed: %s\n", strerror(errno));
964 }
965
966 TRACE_EXIT();
967}
968
969
970
971/**
972 * The driver's FreeScreen() function. This is called at the server's end of
973 * life. This should free any driver-allocated data that was allocated
974 * up-to-and-including an unsuccessful ScreenInit() call.
975 */
976static void
977OMAPFreeScreen(int scrnIndex, int flags)
978{
979 ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
980 OMAPPtr pOMAP = OMAPPTR(pScrn);
981
982 TRACE_ENTER();
983
984 if (!pOMAP) {
985 /* This can happen if a Screen is deleted after Probe(): */
986 return;
987 }
988
989 if (pOMAP->pOMAPEXA) {
990 if (pOMAP->pOMAPEXA->FreeScreen) {
991 pOMAP->pOMAPEXA->FreeScreen(scrnIndex, flags);
992 }
993 free(pOMAP->pOMAPEXA);
994 }
995
996 omap_device_del(pOMAP->dev);
997
998 OMAPCloseDRMMaster(pScrn);
999
1000 OMAPFreeRec(pScrn);
1001
1002 TRACE_EXIT();
1003}
1004