blob: 67a6cd0acfb7ab01751ebc19c48b2dafe66c9191 [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
Raymond Smith41ecf3e2012-05-01 14:51:34 +010030#include <sys/types.h>
31#include <sys/stat.h>
32#include <fcntl.h>
33
Rob Clark487687e2011-07-17 17:29:02 -050034#ifdef HAVE_CONFIG_H
35#include "config.h"
36#endif
37
38#include "omap_driver.h"
Cooper Yuana83caa62012-06-28 17:19:06 +020039#include "compat-api.h"
Rob Clark487687e2011-07-17 17:29:02 -050040
41Bool omapDebug = 0;
42
43/*
44 * Forward declarations:
45 */
46static const OptionInfoRec *OMAPAvailableOptions(int chipid, int busid);
47static void OMAPIdentify(int flags);
48static Bool OMAPProbe(DriverPtr drv, int flags);
49static Bool OMAPPreInit(ScrnInfoPtr pScrn, int flags);
Cooper Yuana83caa62012-06-28 17:19:06 +020050static Bool OMAPScreenInit(SCREEN_INIT_ARGS_DECL);
Rob Clark487687e2011-07-17 17:29:02 -050051static void OMAPLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
52 LOCO * colors, VisualPtr pVisual);
Cooper Yuana83caa62012-06-28 17:19:06 +020053static Bool OMAPCloseScreen(CLOSE_SCREEN_ARGS_DECL);
Rob Clark487687e2011-07-17 17:29:02 -050054static Bool OMAPCreateScreenResources(ScreenPtr pScreen);
Cooper Yuana83caa62012-06-28 17:19:06 +020055static void OMAPBlockHandler(BLOCKHANDLER_ARGS_DECL);
56static Bool OMAPSwitchMode(SWITCH_MODE_ARGS_DECL);
57static void OMAPAdjustFrame(ADJUST_FRAME_ARGS_DECL);
58static Bool OMAPEnterVT(VT_FUNC_ARGS_DECL);
59static void OMAPLeaveVT(VT_FUNC_ARGS_DECL);
60static void OMAPFreeScreen(FREE_SCREEN_ARGS_DECL);
Rob Clark487687e2011-07-17 17:29:02 -050061
62
63
64/**
65 * A structure used by the XFree86 code when loading this driver, so that it
66 * can access the Probe() function, and other functions/info that it uses
67 * before it calls the Probe() function. The name of this structure must be
68 * the all-upper-case version of the driver name.
69 */
70_X_EXPORT DriverRec OMAP = {
71 OMAP_VERSION,
72 (char *)OMAP_DRIVER_NAME,
73 OMAPIdentify,
74 OMAPProbe,
75 OMAPAvailableOptions,
76 NULL,
77 0,
78 NULL,
79#ifdef XSERVER_LIBPCIACCESS
80 NULL,
81 NULL
82#endif
83};
84
85/** Supported "chipsets." */
86static SymTabRec OMAPChipsets[] = {
87 /* OMAP2 and earlier not supported */
88 { 0x3430, "OMAP3430 with PowerVR SGX530" },
89 { 0x3630, "OMAP3630 with PowerVR SGX530" },
90 { 0x4430, "OMAP4430 with PowerVR SGX540" },
91 { 0x4460, "OMAP4460 with PowerVR SGX540" },
92 /* { 4470, "OMAP4470 with <redacted> ;-)" }, */
Vincent Stehlé1ae20362012-03-05 10:26:22 +000093 { 0x5430, "OMAP5430 with PowerVR SGX544 MP" },
94 { 0x5432, "OMAP5432 with PowerVR SGX544 MP" },
Cooper Yuan436c9882012-07-01 15:31:19 +020095 { 0x0400, "Mali-T400" },
Raymond Smithbd6dd8d2012-04-02 14:57:28 +010096 { 0x0600, "Mali-T60x" },
Rob Clark487687e2011-07-17 17:29:02 -050097 {-1, NULL }
98};
99
100/** Supported options, as enum values. */
101typedef enum {
102 OPTION_DEBUG,
Rob Clark4b8f30a2011-08-28 12:51:26 -0500103 OPTION_DRI,
Rob Clark487687e2011-07-17 17:29:02 -0500104 OPTION_NO_ACCEL,
Rob Clark687c6082012-01-08 19:33:18 -0600105 OPTION_HW_CURSOR,
Rob Clark487687e2011-07-17 17:29:02 -0500106 /* TODO: probably need to add an option to let user specify bus-id */
107} OMAPOpts;
108
109/** Supported options. */
110static const OptionInfoRec OMAPOptions[] = {
111 { OPTION_DEBUG, "Debug", OPTV_BOOLEAN, {0}, FALSE },
Rob Clark4b8f30a2011-08-28 12:51:26 -0500112 { OPTION_DRI, "DRI", OPTV_BOOLEAN, {0}, FALSE },
Rob Clark487687e2011-07-17 17:29:02 -0500113 { OPTION_NO_ACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
Rob Clark687c6082012-01-08 19:33:18 -0600114 { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE },
Rob Clark487687e2011-07-17 17:29:02 -0500115 { -1, NULL, OPTV_NONE, {0}, FALSE }
116};
117
118/**
119 * Helper function for opening a connection to the DRM.
120 */
121
122static int
123OMAPOpenDRM(int n)
124{
125 char bus_id[32];
126 snprintf(bus_id, sizeof(bus_id), "platform:omapdrm:%02d", n);
David Garbettc79b4f32012-04-19 07:46:11 +0100127 return open("/dev/dri/card0", O_RDWR, 0);/*drmOpen("mali_drm", bus_id);*/
Rob Clark487687e2011-07-17 17:29:02 -0500128}
129
130static Bool
131OMAPOpenDRMMaster(ScrnInfoPtr pScrn, int n)
132{
133 OMAPPtr pOMAP = OMAPPTR(pScrn);
134 drmSetVersion sv;
135 int err;
136
137 pOMAP->drmFD = OMAPOpenDRM(n);
138 if (pOMAP->drmFD == -1) {
139 ERROR_MSG("Cannot open a connection with the DRM.");
140 return FALSE;
141 }
142
143 /* Check that what we opened was a master or a master-capable FD,
144 * by setting the version of the interface we'll use to talk to it.
145 * (see DRIOpenDRMMaster() in DRI1)
146 */
147 sv.drm_di_major = 1;
148 sv.drm_di_minor = 1;
149 sv.drm_dd_major = -1;
150 sv.drm_dd_minor = -1;
151 err = drmSetInterfaceVersion(pOMAP->drmFD, &sv);
152 if (err != 0) {
153 ERROR_MSG("Cannot set the DRM interface version.");
154 drmClose(pOMAP->drmFD);
155 pOMAP->drmFD = -1;
156 return FALSE;
157 }
158
Rob Clark4b8f30a2011-08-28 12:51:26 -0500159 pOMAP->deviceName = drmGetDeviceNameFromFd(pOMAP->drmFD);
160
Rob Clark487687e2011-07-17 17:29:02 -0500161 return TRUE;
162}
163
164
165
166/**
167 * Helper function for closing a connection to the DRM.
168 */
169static void
170OMAPCloseDRMMaster(ScrnInfoPtr pScrn)
171{
172 OMAPPtr pOMAP = OMAPPTR(pScrn);
173
174 if (pOMAP && (pOMAP->drmFD > 0)) {
Rob Clark4b8f30a2011-08-28 12:51:26 -0500175 drmFree(pOMAP->deviceName);
Rob Clark487687e2011-07-17 17:29:02 -0500176 drmClose(pOMAP->drmFD);
177 pOMAP->drmFD = -1;
178 }
179}
180
Rob Clark487687e2011-07-17 17:29:02 -0500181static Bool
182OMAPMapMem(ScrnInfoPtr pScrn)
183{
184 OMAPPtr pOMAP = OMAPPTR(pScrn);
Rob Clark487687e2011-07-17 17:29:02 -0500185
David Garbettc5901532012-05-29 13:00:52 +0100186 DEBUG_MSG("allocating new scanout buffer: %dx%d",
187 pScrn->virtualX, pScrn->virtualY);
Rob Clark487687e2011-07-17 17:29:02 -0500188
David Garbettc5901532012-05-29 13:00:52 +0100189 pOMAP->scanout = omap_bo_new_with_dim(pOMAP->dev, pScrn->virtualX, pScrn->virtualY,
190 pScrn->bitsPerPixel, OMAP_BO_SCANOUT | OMAP_BO_WC);
Rob Clark487687e2011-07-17 17:29:02 -0500191 if (!pOMAP->scanout) {
192 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
193 "Error allocating scanout buffer\n");
194 return FALSE;
195 }
196
David Garbettc5901532012-05-29 13:00:52 +0100197 pScrn->displayWidth = omap_bo_pitch(pOMAP->scanout) / (pScrn->bitsPerPixel / 8);
Rob Clark487687e2011-07-17 17:29:02 -0500198
199 return TRUE;
200}
201
202
203static Bool
204OMAPUnmapMem(ScrnInfoPtr pScrn)
205{
Rob Clark487687e2011-07-17 17:29:02 -0500206 return TRUE;
207}
208
209
210
211/** Let the XFree86 code know the Setup() function. */
212static MODULESETUPPROTO(OMAPSetup);
213
214/** Provide basic version information to the XFree86 code. */
215static XF86ModuleVersionInfo OMAPVersRec =
216{
217 OMAP_DRIVER_NAME,
218 MODULEVENDORSTRING,
219 MODINFOSTRING1,
220 MODINFOSTRING2,
221 XORG_VERSION_CURRENT,
222 OMAP_MAJOR_VERSION, OMAP_MINOR_VERSION, OMAP_PATCHLEVEL,
223 ABI_CLASS_VIDEODRV,
224 ABI_VIDEODRV_VERSION,
225 MOD_CLASS_VIDEODRV,
226 {0, 0, 0, 0}
227};
228
229/** Let the XFree86 code know about the VersRec and Setup() function. */
230_X_EXPORT XF86ModuleData omapModuleData = { &OMAPVersRec, OMAPSetup, NULL };
231
232
233/**
234 * The first function that the XFree86 code calls, after loading this module.
235 */
236static pointer
237OMAPSetup(pointer module, pointer opts, int *errmaj, int *errmin)
238{
239 static Bool setupDone = FALSE;
240
241 /* This module should be loaded only once, but check to be sure: */
242 if (!setupDone) {
243 setupDone = TRUE;
244 xf86AddDriver(&OMAP, module, 0);
245
246 /* The return value must be non-NULL on success even though there is no
247 * TearDownProc.
248 */
249 return (pointer) 1;
250 } else {
251 if (errmaj)
252 *errmaj = LDR_ONCEONLY;
253 return NULL;
254 }
255}
256
257
258/**
259 * Allocate the driver's Screen-specific, "private" data structure and hook it
260 * into the ScrnInfoRec's driverPrivate field.
261 */
262static Bool
263OMAPGetRec(ScrnInfoPtr pScrn)
264{
265 if (pScrn->driverPrivate != NULL)
266 return TRUE;
267
268 pScrn->driverPrivate = calloc(1, sizeof(OMAPRec));
269 if (pScrn->driverPrivate == NULL)
270 return FALSE;
271
272 return TRUE;
273}
274
275
276/**
277 * Free the driver's Screen-specific, "private" data structure and NULL-out the
278 * ScrnInfoRec's driverPrivate field.
279 */
280static void
281OMAPFreeRec(ScrnInfoPtr pScrn)
282{
283 if (pScrn->driverPrivate == NULL)
284 return;
285 free(pScrn->driverPrivate);
286 pScrn->driverPrivate = NULL;
287}
288
289
290/**
291 * The mandatory AvailableOptions() function. It returns the available driver
292 * options to the "-configure" option, so that an xorg.conf file can be built
293 * and the user can see which options are available for them to use.
294 */
295static const OptionInfoRec *
296OMAPAvailableOptions(int chipid, int busid)
297{
298 return OMAPOptions;
299}
300
301
302
303/**
304 * The mandatory Identify() function. It is run before Probe(), and prints out
305 * an identifying message, which includes the chipset(s) the driver supports.
306 */
307static void
308OMAPIdentify(int flags)
309{
310 xf86PrintChipsets(OMAP_NAME, "Driver for TI OMAP", OMAPChipsets);
311}
312
313
314
315/**
316 * The driver's Probe() function. This function finds all instances of the
317 * TI OMAP hardware that the driver supports (from within the "xorg.conf"
318 * device sections), and for instances not already claimed by another driver,
319 * claim the instances, and allocate a ScrnInfoRec. Only minimal hardware
320 * probing is allowed here.
321 */
322static Bool
323OMAPProbe(DriverPtr drv, int flags)
324{
325 int i;
326 ScrnInfoPtr pScrn;
327 GDevPtr *devSections;
328 int numDevSections;
329 Bool foundScreen = FALSE;
330
Rob Clark487687e2011-07-17 17:29:02 -0500331 /* Get the "xorg.conf" file device sections that match this driver, and
332 * return (error out) if there are none:
333 */
334 numDevSections = xf86MatchDevice(OMAP_DRIVER_NAME, &devSections);
335 if (numDevSections <= 0) {
336 EARLY_ERROR_MSG("Did not find any matching device section in "
337 "configuration file");
Rob Clark83f49e02012-01-08 17:31:59 -0600338 if (flags & PROBE_DETECT) {
339 /* if we are probing, assume one and lets see if we can
340 * open the device to confirm it is there:
341 */
342 numDevSections = 1;
343 } else {
344 return FALSE;
345 }
Rob Clark487687e2011-07-17 17:29:02 -0500346 }
347
348 for (i = 0; i < numDevSections; i++) {
349 int fd = OMAPOpenDRM(i);
350 if (fd != -1) {
Rob Clark83f49e02012-01-08 17:31:59 -0600351
352 if (flags & PROBE_DETECT) {
353 /* just add the device.. we aren't a PCI device, so
354 * call xf86AddBusDeviceToConfigure() directly
355 */
356 xf86AddBusDeviceToConfigure(OMAP_DRIVER_NAME,
357 BUS_NONE, NULL, i);
358 foundScreen = TRUE;
359 continue;
360 }
Rob Clark487687e2011-07-17 17:29:02 -0500361
362 pScrn = xf86AllocateScreen(drv, 0);
Rob Clark83f49e02012-01-08 17:31:59 -0600363
Rob Clark487687e2011-07-17 17:29:02 -0500364 if (!pScrn) {
365 EARLY_ERROR_MSG("Cannot allocate a ScrnInfoPtr");
366 return FALSE;
367 }
Rob Clark83f49e02012-01-08 17:31:59 -0600368
369 if (devSections) {
370 int entity = xf86ClaimNoSlot(drv, 0, devSections[i], TRUE);
371 xf86AddEntityToScreen(pScrn, entity);
372 }
Rob Clark487687e2011-07-17 17:29:02 -0500373
374 foundScreen = TRUE;
375
376 pScrn->driverVersion = OMAP_VERSION;
377 pScrn->driverName = (char *)OMAP_DRIVER_NAME;
378 pScrn->name = (char *)OMAP_NAME;
379 pScrn->Probe = OMAPProbe;
380 pScrn->PreInit = OMAPPreInit;
381 pScrn->ScreenInit = OMAPScreenInit;
382 pScrn->SwitchMode = OMAPSwitchMode;
383 pScrn->AdjustFrame = OMAPAdjustFrame;
384 pScrn->EnterVT = OMAPEnterVT;
385 pScrn->LeaveVT = OMAPLeaveVT;
386 pScrn->FreeScreen = OMAPFreeScreen;
387
388 /* would be nice to be able to keep the connection open.. but
389 * currently we don't allocate the private until PreInit
390 */
391 drmClose(fd);
392 }
393 }
394 free(devSections);
395 return foundScreen;
396}
397
398
399
400/**
401 * The driver's PreInit() function. Additional hardware probing is allowed
402 * now, including display configuration.
403 */
404static Bool
405OMAPPreInit(ScrnInfoPtr pScrn, int flags)
406{
407 OMAPPtr pOMAP;
408 int default_depth, fbbpp;
409 rgb defaultWeight = { 0, 0, 0 };
410 rgb defaultMask = { 0, 0, 0 };
411 Gamma defaultGamma = { 0.0, 0.0, 0.0 };
412 uint64_t value;
413 int i;
414
415 TRACE_ENTER();
416
417 if (flags & PROBE_DETECT) {
418 ERROR_MSG("The %s driver does not support the \"-configure\" or "
419 "\"-probe\" command line arguments.", OMAP_NAME);
420 return FALSE;
421 }
422
423 /* Check the number of entities, and fail if it isn't one. */
424 if (pScrn->numEntities != 1) {
425 ERROR_MSG("Driver expected 1 entity, but found %d for screen %d",
426 pScrn->numEntities, pScrn->scrnIndex);
427 return FALSE;
428 }
429
430 /* Allocate the driver's Screen-specific, "private" data structure: */
431 OMAPGetRec(pScrn);
432 pOMAP = OMAPPTR(pScrn);
433
434 pOMAP->pEntityInfo = xf86GetEntityInfo(pScrn->entityList[0]);
435
436 pScrn->monitor = pScrn->confScreen->monitor;
437
438 /* Get the current depth, and set it for XFree86: */
439 default_depth = 24; /* TODO: get from kernel */
440 fbbpp = 32; /* TODO: get from kernel */
441
442 if (!xf86SetDepthBpp(pScrn, default_depth, 0, fbbpp, Support32bppFb)) {
443 /* The above function prints an error message. */
444 goto fail;
445 }
446 xf86PrintDepthBpp(pScrn);
447
448 /* Set the color weight: */
449 if (!xf86SetWeight(pScrn, defaultWeight, defaultMask)) {
450 /* The above function prints an error message. */
451 goto fail;
452 }
453
454 /* Set the gamma: */
455 if (!xf86SetGamma(pScrn, defaultGamma)) {
456 /* The above function prints an error message. */
457 goto fail;
458 }
459
460 /* Visual init: */
461 if (!xf86SetDefaultVisual(pScrn, -1)) {
462 /* The above function prints an error message. */
463 goto fail;
464 }
465
466 /* We don't support 8-bit depths: */
467 if (pScrn->depth < 16) {
468 ERROR_MSG("The requested default visual (%s) has an unsupported "
469 "depth (%d).",
470 xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
471 goto fail;
472 }
473
474 /* Using a programmable clock: */
475 pScrn->progClock = TRUE;
476
477 /* Open a connection to the DRM, so we can communicate with the KMS code: */
478 if (!OMAPOpenDRMMaster(pScrn, 0)) {
479 goto fail;
480 }
481 DEBUG_MSG("Became DRM master.");
482
483 /* create DRM device instance: */
484 pOMAP->dev = omap_device_new(pOMAP->drmFD);
485
486 /* query chip-id: */
487 if (omap_get_param(pOMAP->dev, OMAP_PARAM_CHIPSET_ID, &value)) {
488 ERROR_MSG("Could not read chipset");
489 goto fail;
490 }
491 pOMAP->chipset = value;
492
493 /* find matching chipset name: */
494 for (i = 0; OMAPChipsets[i].name; i++) {
495 if (OMAPChipsets[i].token == pOMAP->chipset) {
496 pScrn->chipset = (char *)OMAPChipsets[i].name;
497 break;
498 }
499 }
500
501 if (!pScrn->chipset) {
502 ERROR_MSG("Unknown chipset: %s", pScrn->chipset);
503 goto fail;
504 }
505
506 INFO_MSG("Found chipset: %s", pScrn->chipset);
507
508 /*
509 * Process the "xorg.conf" file options:
510 */
511 xf86CollectOptions(pScrn, NULL);
512 if (!(pOMAP->pOptionInfo = calloc(1, sizeof(OMAPOptions))))
513 return FALSE;
514 memcpy(pOMAP->pOptionInfo, OMAPOptions, sizeof(OMAPOptions));
515 xf86ProcessOptions(pScrn->scrnIndex, pOMAP->pEntityInfo->device->options,
516 pOMAP->pOptionInfo);
517
518 /* Determine if the user wants debug messages turned on: */
519 omapDebug = xf86ReturnOptValBool(pOMAP->pOptionInfo, OPTION_DEBUG, FALSE);
520
Rob Clark4b8f30a2011-08-28 12:51:26 -0500521 pOMAP->dri = xf86ReturnOptValBool(pOMAP->pOptionInfo, OPTION_DRI, TRUE);
522
Rob Clark687c6082012-01-08 19:33:18 -0600523 /* Determine if user wants to disable hw mouse cursor: */
524 pOMAP->HWCursor = xf86ReturnOptValBool(pOMAP->pOptionInfo,
525 OPTION_HW_CURSOR, TRUE);
526 INFO_MSG("Using %s cursor", pOMAP->HWCursor ? "HW" : "SW");
Rob Clark4b8f30a2011-08-28 12:51:26 -0500527
Rob Clark487687e2011-07-17 17:29:02 -0500528 /* Determine if the user wants to disable acceleration: */
Rob Clark687c6082012-01-08 19:33:18 -0600529 pOMAP->NoAccel = xf86ReturnOptValBool(pOMAP->pOptionInfo,
530 OPTION_NO_ACCEL, FALSE);
Rob Clark487687e2011-07-17 17:29:02 -0500531
532 /*
533 * Select the video modes:
534 */
535 INFO_MSG("Setting the video modes ...");
536
537 /* Don't call drmCheckModesettingSupported() as its written only for
538 * PCI devices.
539 */
540
541 /* Do initial KMS setup: */
542 if (!drmmode_pre_init(pScrn, pOMAP->drmFD, (pScrn->bitsPerPixel >> 3))) {
543 ERROR_MSG("Cannot get KMS resources");
544 } else {
545 INFO_MSG("Got KMS resources");
546 }
547
548 xf86RandR12PreInit(pScrn);
549
550 /* Let XFree86 calculate or get (from command line) the display DPI: */
551 xf86SetDpi(pScrn, 0, 0);
552
553 /* Ensure we have a supported depth: */
554 switch (pScrn->bitsPerPixel) {
555 case 16:
556 case 24:
557 case 32:
558 break;
559 default:
560 ERROR_MSG("The requested number of bits per pixel (%d) is unsupported.",
561 pScrn->bitsPerPixel);
562 goto fail;
563 }
564
565
566 /* Load external sub-modules now: */
567
568 if (!(xf86LoadSubModule(pScrn, "dri2") &&
569 xf86LoadSubModule(pScrn, "exa") &&
570 xf86LoadSubModule(pScrn, "fb"))) {
571 goto fail;
572 }
573
574 switch (pOMAP->chipset) {
575 case 0x3430:
576 case 0x3630:
577 case 0x4430:
578 case 0x4460:
Vincent Stehlé1ae20362012-03-05 10:26:22 +0000579 case 0x5430:
580 case 0x5432:
Rob Clark487687e2011-07-17 17:29:02 -0500581 if (xf86LoadSubModule(pScrn, SUB_MODULE_PVR)) {
582 INFO_MSG("Loaded the %s sub-module", SUB_MODULE_PVR);
583 } else {
584 INFO_MSG("Cannot load the %s sub-module", SUB_MODULE_PVR);
585 /* note that this is not fatal.. since IMG/PVR EXA module
586 * is closed source, it is only optional.
587 */
588 pOMAP->NoAccel = TRUE; /* don't call InitPowerVREXA() */
589 }
590 break;
591 /* case 0x4470: ..; break; */
David Garbettc79b4f32012-04-19 07:46:11 +0100592 case 0x0600:
593 pOMAP->NoAccel = TRUE; /* don't call InitPowerVREXA() */
594 break;
Rob Clark487687e2011-07-17 17:29:02 -0500595 default:
596 ERROR_MSG("Unsupported chipset: %d", pOMAP->chipset);
597 goto fail;
598 }
599
600 TRACE_EXIT();
601 return TRUE;
602
603fail:
604 TRACE_EXIT();
605 OMAPFreeRec(pScrn);
606 return FALSE;
607}
608
609
Rob Clarkdc9dfae2012-01-11 18:20:18 -0600610/**
611 * Initialize EXA and DRI2
612 */
613static void
614OMAPAccelInit(ScreenPtr pScreen)
615{
616 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
617 OMAPPtr pOMAP = OMAPPTR(pScrn);
618
619 if (!pOMAP->NoAccel) {
620 switch (pOMAP->chipset) {
621 case 0x3430:
622 case 0x3630:
623 case 0x4430:
624 case 0x4460:
Vincent Stehlé1ae20362012-03-05 10:26:22 +0000625 case 0x5430:
626 case 0x5432:
Rob Clarkdc9dfae2012-01-11 18:20:18 -0600627 INFO_MSG("Initializing the \"%s\" sub-module ...", SUB_MODULE_PVR);
Rob Clark0fdd91f2011-10-20 09:56:11 -0500628 pOMAP->pOMAPEXA = InitPowerVREXA(pScreen, pScrn, pOMAP->drmFD);
Rob Clarkdc9dfae2012-01-11 18:20:18 -0600629 if (pOMAP->pOMAPEXA) {
630 INFO_MSG("Successfully initialized the \"%s\" sub-module",
631 SUB_MODULE_PVR);
632 } else {
633 INFO_MSG("Could not initialize the \"%s\" sub-module",
634 SUB_MODULE_PVR);
635 pOMAP->NoAccel = TRUE;
636 }
637 break;
638 default:
639 ERROR_MSG("Unsupported chipset: %d", pOMAP->chipset);
640 pOMAP->NoAccel = TRUE;
641 break;
642 }
643 }
644
645 if (!pOMAP->pOMAPEXA) {
Rob Clark0fdd91f2011-10-20 09:56:11 -0500646 pOMAP->pOMAPEXA = InitNullEXA(pScreen, pScrn, pOMAP->drmFD);
Rob Clarkdc9dfae2012-01-11 18:20:18 -0600647 }
648
649 if (pOMAP->dri && pOMAP->pOMAPEXA) {
650 pOMAP->dri = OMAPDRI2ScreenInit(pScreen);
651 } else {
652 pOMAP->dri = FALSE;
653 }
Rob Clark447d4132012-01-22 18:38:24 -0600654
Raymond Smith34fc43f2012-04-03 12:04:24 +0100655#if 0
Rob Clark447d4132012-01-22 18:38:24 -0600656 if (OMAPVideoScreenInit(pScreen)) {
657 INFO_MSG("Initialized XV");
658 } else {
659 ERROR_MSG("Could not initialize XV");
660 }
Raymond Smith34fc43f2012-04-03 12:04:24 +0100661#endif
Rob Clarkdc9dfae2012-01-11 18:20:18 -0600662}
Rob Clark487687e2011-07-17 17:29:02 -0500663
664/**
665 * The driver's ScreenInit() function. Fill in pScreen, map the frame buffer,
666 * save state, initialize the mode, etc.
667 */
668static Bool
Cooper Yuana83caa62012-06-28 17:19:06 +0200669OMAPScreenInit(SCREEN_INIT_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -0500670{
671 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
672 OMAPPtr pOMAP = OMAPPTR(pScrn);
673 VisualPtr visual;
674 xf86CrtcConfigPtr xf86_config;
675 int i;
676
677 TRACE_ENTER();
678
Rob Clark487687e2011-07-17 17:29:02 -0500679 /* Allocate and map memory areas we need */
680 if (!OMAPMapMem(pScrn))
681 return FALSE;
682
683 xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
684
685 /* need to point to new screen on server regeneration */
686 for (i = 0; i < xf86_config->num_crtc; i++)
687 xf86_config->crtc[i]->scrn = pScrn;
688 for (i = 0; i < xf86_config->num_output; i++)
689 xf86_config->output[i]->scrn = pScrn;
690
691 /*
692 * The next step is to setup the screen's visuals, and initialize the
693 * framebuffer code. In cases where the framebuffer's default
694 * choices for things like visual layouts and bits per RGB are OK,
695 * this may be as simple as calling the framebuffer's ScreenInit()
696 * function. If not, the visuals will need to be setup before calling
697 * a fb ScreenInit() function and fixed up after.
698 *
699 * For most PC hardware at depths >= 8, the defaults that fb uses
700 * are not appropriate. In this driver, we fixup the visuals after.
701 */
702
703 /*
704 * Reset the visual list.
705 */
706
707 miClearVisualTypes();
708 if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth),
709 pScrn->rgbBits, pScrn->defaultVisual)) {
710 ERROR_MSG("Cannot initialize the visual type for %d bits per pixel!",
711 pScrn->bitsPerPixel);
712 goto fail;
713 }
714
715 if (!miSetPixmapDepths()) {
716 ERROR_MSG("Cannot initialize the pixmap depth!");
717 goto fail;
718 }
719
720 /* Initialize some generic 2D drawing functions: */
721 if (!fbScreenInit(pScreen, omap_bo_map(pOMAP->scanout),
722 pScrn->virtualX, pScrn->virtualY,
723 pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
724 pScrn->bitsPerPixel)) {
725 ERROR_MSG("fbScreenInit() failed!");
726 goto fail;
727 }
728
729 /* Fixup RGB ordering: */
730 visual = pScreen->visuals + pScreen->numVisuals;
731 while (--visual >= pScreen->visuals) {
732 if ((visual->class | DynamicClass) == DirectColor) {
733 visual->offsetRed = pScrn->offset.red;
734 visual->offsetGreen = pScrn->offset.green;
735 visual->offsetBlue = pScrn->offset.blue;
736 visual->redMask = pScrn->mask.red;
737 visual->greenMask = pScrn->mask.green;
738 visual->blueMask = pScrn->mask.blue;
739 }
740 }
741
742 /* Continue initializing the generic 2D drawing functions after fixing the
743 * RGB ordering:
744 */
745 if (!fbPictureInit(pScreen, NULL, 0)) {
746 ERROR_MSG("fbPictureInit() failed!");
747 goto fail;
748 }
749
750 /* Set the initial black & white colormap indices: */
751 xf86SetBlackWhitePixels(pScreen);
752
Rob Clarkdc9dfae2012-01-11 18:20:18 -0600753 /* Initialize external sub-modules for EXA now, this has to be before
754 * miDCInitialize() otherwise stacking order for wrapped ScreenPtr fxns
755 * ends up in the wrong order.
756 */
757 OMAPAccelInit(pScreen);
758
Rob Clark487687e2011-07-17 17:29:02 -0500759 /* Initialize backing store: */
760 miInitializeBackingStore(pScreen);
761 xf86SetBackingStore(pScreen);
762
Rob Clark687c6082012-01-08 19:33:18 -0600763 /* Cause the cursor position to be updated by the mouse signal handler: */
764 xf86SetSilkenMouse(pScreen);
765
Rob Clark487687e2011-07-17 17:29:02 -0500766 /* Initialize the cursor: */
767 miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
768
Rob Clark687c6082012-01-08 19:33:18 -0600769 if (pOMAP->HWCursor) {
770 if (!drmmode_cursor_init(pScreen)) {
771 ERROR_MSG("Hardware cursor initialization failed");
772 pOMAP->HWCursor = FALSE;
773 }
774 }
Rob Clark487687e2011-07-17 17:29:02 -0500775
776 /* XXX -- Is this the right place for this? The Intel i830 driver says:
777 * "Must force it before EnterVT, so we are in control of VT..."
778 */
779 pScrn->vtSema = TRUE;
780
781 /* Take over the virtual terminal from the console, set the desired mode,
782 * etc.:
783 */
Cooper Yuana83caa62012-06-28 17:19:06 +0200784 OMAPEnterVT(VT_FUNC_ARGS(0));
Rob Clark487687e2011-07-17 17:29:02 -0500785
786 /* Set the desired mode(s): */
787 if (!xf86SetDesiredModes(pScrn)) {
788 ERROR_MSG("xf86SetDesiredModes() failed!");
789 goto fail;
790 }
791
792 /* Do some XRandR initialization: */
793 if (!xf86CrtcScreenInit(pScreen)) {
794 ERROR_MSG("xf86CrtcScreenInit() failed!");
795 goto fail;
796 }
797
798 if (!miCreateDefColormap(pScreen)) {
799 ERROR_MSG("Cannot create colormap!");
800 goto fail;
801 }
802
803 if (!xf86HandleColormaps(pScreen, 256, 8, OMAPLoadPalette, NULL,
804 CMAP_PALETTED_TRUECOLOR)) {
805 ERROR_MSG("xf86HandleColormaps() failed!");
806 goto fail;
807 }
808
809 /* Setup power management: */
810 xf86DPMSInit(pScreen, xf86DPMSSet, 0);
811
812 pScreen->SaveScreen = xf86SaveScreen;
813
814 /* Wrap some screen functions: */
815 wrap(pOMAP, pScreen, CloseScreen, OMAPCloseScreen);
816 wrap(pOMAP, pScreen, CreateScreenResources, OMAPCreateScreenResources);
817 wrap(pOMAP, pScreen, BlockHandler, OMAPBlockHandler);
818
Rob Clark4b8f30a2011-08-28 12:51:26 -0500819 drmmode_screen_init(pScrn);
Rob Clark487687e2011-07-17 17:29:02 -0500820
821 TRACE_EXIT();
822 return TRUE;
823
824fail:
825 TRACE_EXIT();
826 return FALSE;
827}
828
829
830static void
831OMAPLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
832 LOCO * colors, VisualPtr pVisual)
833{
834 TRACE_ENTER();
835 TRACE_EXIT();
836}
837
838
839/**
840 * The driver's CloseScreen() function. This is called at the end of each
841 * server generation. Restore state, unmap the frame buffer (and any other
842 * mapped memory regions), and free per-Screen data structures (except those
843 * held by pScrn).
844 */
845static Bool
Cooper Yuana83caa62012-06-28 17:19:06 +0200846OMAPCloseScreen(CLOSE_SCREEN_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -0500847{
Cooper Yuana83caa62012-06-28 17:19:06 +0200848 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
Rob Clark487687e2011-07-17 17:29:02 -0500849 OMAPPtr pOMAP = OMAPPTR(pScrn);
850
851 TRACE_ENTER();
852
Rob Clark4b8f30a2011-08-28 12:51:26 -0500853 drmmode_screen_fini(pScrn);
Rob Clark487687e2011-07-17 17:29:02 -0500854
855 if (pScrn->vtSema == TRUE) {
Cooper Yuana83caa62012-06-28 17:19:06 +0200856 OMAPLeaveVT(VT_FUNC_ARGS(0));
Rob Clark487687e2011-07-17 17:29:02 -0500857 }
858
859 if (pOMAP->pOMAPEXA) {
860 if (pOMAP->pOMAPEXA->CloseScreen) {
Cooper Yuana83caa62012-06-28 17:19:06 +0200861 pOMAP->pOMAPEXA->CloseScreen(CLOSE_SCREEN_ARGS);
Rob Clark487687e2011-07-17 17:29:02 -0500862 }
863 }
864
Rob Clark4b8f30a2011-08-28 12:51:26 -0500865 if (pOMAP->dri) {
866 OMAPDRI2CloseScreen(pScreen);
867 }
Rob Clark4b8f30a2011-08-28 12:51:26 -0500868
Raymond Smithe553ce82012-04-04 12:44:27 +0100869#if 0
Rob Clark447d4132012-01-22 18:38:24 -0600870 OMAPVideoCloseScreen(pScreen);
Raymond Smithe553ce82012-04-04 12:44:27 +0100871#endif
Rob Clark447d4132012-01-22 18:38:24 -0600872
Rob Clark487687e2011-07-17 17:29:02 -0500873 OMAPUnmapMem(pScrn);
874
875 pScrn->vtSema = FALSE;
876
877 unwrap(pOMAP, pScreen, CloseScreen);
878 unwrap(pOMAP, pScreen, BlockHandler);
879 unwrap(pOMAP, pScreen, CreateScreenResources);
880
881 TRACE_EXIT();
882
Cooper Yuana83caa62012-06-28 17:19:06 +0200883 return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS);
Rob Clark487687e2011-07-17 17:29:02 -0500884}
885
886
887
888/**
889 * Adjust the screen pixmap for the current location of the front buffer.
890 * This is done at EnterVT when buffers are bound as long as the resources
891 * have already been created, but the first EnterVT happens before
892 * CreateScreenResources.
893 */
894static Bool
895OMAPCreateScreenResources(ScreenPtr pScreen)
896{
897 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
898 OMAPPtr pOMAP = OMAPPTR(pScrn);
899
900 swap(pOMAP, pScreen, CreateScreenResources);
901 if (!(*pScreen->CreateScreenResources) (pScreen))
902 return FALSE;
903 swap(pOMAP, pScreen, CreateScreenResources);
904
905 return TRUE;
906}
907
908
909static void
Cooper Yuana83caa62012-06-28 17:19:06 +0200910OMAPBlockHandler(BLOCKHANDLER_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -0500911{
Cooper Yuana83caa62012-06-28 17:19:06 +0200912 SCREEN_PTR(arg);
913 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
Rob Clark487687e2011-07-17 17:29:02 -0500914 OMAPPtr pOMAP = OMAPPTR(pScrn);
915
916 swap(pOMAP, pScreen, BlockHandler);
Cooper Yuana83caa62012-06-28 17:19:06 +0200917 (*pScreen->BlockHandler) (BLOCKHANDLER_ARGS);
Rob Clark487687e2011-07-17 17:29:02 -0500918 swap(pOMAP, pScreen, BlockHandler);
919
920 /* TODO OMAPVideoBlockHandler(), etc.. */
921}
922
923
924
925/**
926 * The driver's SwitchMode() function. Initialize the new mode for the
927 * Screen.
928 */
929static Bool
Cooper Yuana83caa62012-06-28 17:19:06 +0200930OMAPSwitchMode(SWITCH_MODE_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -0500931{
Cooper Yuana83caa62012-06-28 17:19:06 +0200932 SCRN_INFO_PTR(arg);
Rob Clark487687e2011-07-17 17:29:02 -0500933 return xf86SetSingleMode(pScrn, mode, RR_Rotate_0);
934}
935
936
937
938/**
939 * The driver's AdjustFrame() function. For cases where the frame buffer is
940 * larger than the monitor resolution, this function can pan around the frame
941 * buffer within the "viewport" of the monitor.
942 */
943static void
Cooper Yuana83caa62012-06-28 17:19:06 +0200944OMAPAdjustFrame(ADJUST_FRAME_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -0500945{
Cooper Yuana83caa62012-06-28 17:19:06 +0200946 SCRN_INFO_PTR(arg);
947 drmmode_adjust_frame(pScrn, x, y);
Rob Clark487687e2011-07-17 17:29:02 -0500948}
949
950
951
952/**
953 * The driver's EnterVT() function. This is called at server startup time, and
954 * when the X server takes over the virtual terminal from the console. As
955 * such, it may need to save the current (i.e. console) HW state, and set the
956 * HW state as needed by the X server.
957 */
958static Bool
Cooper Yuana83caa62012-06-28 17:19:06 +0200959OMAPEnterVT(VT_FUNC_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -0500960{
Cooper Yuana83caa62012-06-28 17:19:06 +0200961 SCRN_INFO_PTR(arg);
Rob Clark487687e2011-07-17 17:29:02 -0500962 OMAPPtr pOMAP = OMAPPTR(pScrn);
963 int ret;
964
965 TRACE_ENTER();
966
967 ret = drmSetMaster(pOMAP->drmFD);
968 if (ret) {
969 ERROR_MSG("Cannot get DRM master: %s\n", strerror(ret));
970 }
971
972 if (!xf86SetDesiredModes(pScrn)) {
973 ERROR_MSG("xf86SetDesiredModes() failed!");
974 return FALSE;
975 }
976
977 TRACE_EXIT();
978 return TRUE;
979}
980
981
982
983/**
984 * The driver's LeaveVT() function. This is called when the X server
985 * temporarily gives up the virtual terminal to the console. As such, it may
986 * need to restore the console's HW state.
987 */
988static void
Cooper Yuana83caa62012-06-28 17:19:06 +0200989OMAPLeaveVT(VT_FUNC_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -0500990{
Cooper Yuana83caa62012-06-28 17:19:06 +0200991 SCRN_INFO_PTR(arg);
Rob Clark487687e2011-07-17 17:29:02 -0500992 OMAPPtr pOMAP = OMAPPTR(pScrn);
993 int ret;
994
995 TRACE_ENTER();
996
997 ret = drmDropMaster(pOMAP->drmFD);
998 if (ret) {
999 WARNING_MSG("drmDropMaster failed: %s\n", strerror(errno));
1000 }
1001
1002 TRACE_EXIT();
1003}
1004
1005
1006
1007/**
1008 * The driver's FreeScreen() function. This is called at the server's end of
1009 * life. This should free any driver-allocated data that was allocated
1010 * up-to-and-including an unsuccessful ScreenInit() call.
1011 */
1012static void
Cooper Yuana83caa62012-06-28 17:19:06 +02001013OMAPFreeScreen(FREE_SCREEN_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -05001014{
Cooper Yuana83caa62012-06-28 17:19:06 +02001015 SCRN_INFO_PTR(arg);
Rob Clark487687e2011-07-17 17:29:02 -05001016 OMAPPtr pOMAP = OMAPPTR(pScrn);
1017
1018 TRACE_ENTER();
1019
1020 if (!pOMAP) {
1021 /* This can happen if a Screen is deleted after Probe(): */
1022 return;
1023 }
1024
1025 if (pOMAP->pOMAPEXA) {
1026 if (pOMAP->pOMAPEXA->FreeScreen) {
Cooper Yuana83caa62012-06-28 17:19:06 +02001027 pOMAP->pOMAPEXA->FreeScreen(FREE_SCREEN_ARGS(pScrn));
Rob Clark487687e2011-07-17 17:29:02 -05001028 }
1029 free(pOMAP->pOMAPEXA);
1030 }
1031
1032 omap_device_del(pOMAP->dev);
1033
1034 OMAPCloseDRMMaster(pScrn);
1035
1036 OMAPFreeRec(pScrn);
1037
1038 TRACE_EXIT();
1039}
1040