blob: 1e488b115e31843fb3d25de6eb26f8c7a5bb9dfa [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,
Dave Barnishc50baf52012-11-29 14:39:36 +0000106 OPTION_NO_FLIP,
Dave Barnish2742d152013-03-13 13:36:58 +0000107 /* TODO: MIDEGL-1453: probably need to add an option to let user specify bus-id */
Rob Clark487687e2011-07-17 17:29:02 -0500108} OMAPOpts;
109
110/** Supported options. */
111static const OptionInfoRec OMAPOptions[] = {
112 { OPTION_DEBUG, "Debug", OPTV_BOOLEAN, {0}, FALSE },
Rob Clark4b8f30a2011-08-28 12:51:26 -0500113 { OPTION_DRI, "DRI", OPTV_BOOLEAN, {0}, FALSE },
Rob Clark487687e2011-07-17 17:29:02 -0500114 { OPTION_NO_ACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
Rob Clark687c6082012-01-08 19:33:18 -0600115 { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE },
Dave Barnishc50baf52012-11-29 14:39:36 +0000116 { OPTION_NO_FLIP, "NoFlip", OPTV_BOOLEAN, {0}, FALSE },
Rob Clark487687e2011-07-17 17:29:02 -0500117 { -1, NULL, OPTV_NONE, {0}, FALSE }
118};
119
120/**
121 * Helper function for opening a connection to the DRM.
122 */
123
124static int
125OMAPOpenDRM(int n)
126{
127 char bus_id[32];
128 snprintf(bus_id, sizeof(bus_id), "platform:omapdrm:%02d", n);
David Garbettc79b4f32012-04-19 07:46:11 +0100129 return open("/dev/dri/card0", O_RDWR, 0);/*drmOpen("mali_drm", bus_id);*/
Rob Clark487687e2011-07-17 17:29:02 -0500130}
131
132static Bool
133OMAPOpenDRMMaster(ScrnInfoPtr pScrn, int n)
134{
135 OMAPPtr pOMAP = OMAPPTR(pScrn);
136 drmSetVersion sv;
137 int err;
138
139 pOMAP->drmFD = OMAPOpenDRM(n);
140 if (pOMAP->drmFD == -1) {
141 ERROR_MSG("Cannot open a connection with the DRM.");
142 return FALSE;
143 }
144
145 /* Check that what we opened was a master or a master-capable FD,
146 * by setting the version of the interface we'll use to talk to it.
147 * (see DRIOpenDRMMaster() in DRI1)
148 */
149 sv.drm_di_major = 1;
150 sv.drm_di_minor = 1;
151 sv.drm_dd_major = -1;
152 sv.drm_dd_minor = -1;
153 err = drmSetInterfaceVersion(pOMAP->drmFD, &sv);
154 if (err != 0) {
155 ERROR_MSG("Cannot set the DRM interface version.");
156 drmClose(pOMAP->drmFD);
157 pOMAP->drmFD = -1;
158 return FALSE;
159 }
160
Rob Clark4b8f30a2011-08-28 12:51:26 -0500161 pOMAP->deviceName = drmGetDeviceNameFromFd(pOMAP->drmFD);
162
Rob Clark487687e2011-07-17 17:29:02 -0500163 return TRUE;
164}
165
166
167
168/**
169 * Helper function for closing a connection to the DRM.
170 */
171static void
172OMAPCloseDRMMaster(ScrnInfoPtr pScrn)
173{
174 OMAPPtr pOMAP = OMAPPTR(pScrn);
175
176 if (pOMAP && (pOMAP->drmFD > 0)) {
Rob Clark4b8f30a2011-08-28 12:51:26 -0500177 drmFree(pOMAP->deviceName);
Rob Clark487687e2011-07-17 17:29:02 -0500178 drmClose(pOMAP->drmFD);
179 pOMAP->drmFD = -1;
180 }
181}
182
Rob Clark487687e2011-07-17 17:29:02 -0500183static Bool
184OMAPMapMem(ScrnInfoPtr pScrn)
185{
186 OMAPPtr pOMAP = OMAPPTR(pScrn);
Rob Clark487687e2011-07-17 17:29:02 -0500187
David Garbettc5901532012-05-29 13:00:52 +0100188 DEBUG_MSG("allocating new scanout buffer: %dx%d",
189 pScrn->virtualX, pScrn->virtualY);
Rob Clark487687e2011-07-17 17:29:02 -0500190
Sean Paul3e107302012-08-30 12:08:12 -0700191 pOMAP->scanout = omap_bo_new_with_dim(pOMAP->dev, pScrn->virtualX,
192 pScrn->virtualY, pScrn->depth, pScrn->bitsPerPixel,
Dave Barnishf4659732013-03-08 10:11:08 +0000193 OMAP_BO_SCANOUT );
Rob Clark487687e2011-07-17 17:29:02 -0500194 if (!pOMAP->scanout) {
195 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
196 "Error allocating scanout buffer\n");
197 return FALSE;
198 }
199
David Garbettc5901532012-05-29 13:00:52 +0100200 pScrn->displayWidth = omap_bo_pitch(pOMAP->scanout) / (pScrn->bitsPerPixel / 8);
Rob Clark487687e2011-07-17 17:29:02 -0500201
202 return TRUE;
203}
204
205
206static Bool
207OMAPUnmapMem(ScrnInfoPtr pScrn)
208{
Rob Clark487687e2011-07-17 17:29:02 -0500209 return TRUE;
210}
211
212
213
214/** Let the XFree86 code know the Setup() function. */
215static MODULESETUPPROTO(OMAPSetup);
216
217/** Provide basic version information to the XFree86 code. */
218static XF86ModuleVersionInfo OMAPVersRec =
219{
220 OMAP_DRIVER_NAME,
221 MODULEVENDORSTRING,
222 MODINFOSTRING1,
223 MODINFOSTRING2,
224 XORG_VERSION_CURRENT,
225 OMAP_MAJOR_VERSION, OMAP_MINOR_VERSION, OMAP_PATCHLEVEL,
226 ABI_CLASS_VIDEODRV,
227 ABI_VIDEODRV_VERSION,
228 MOD_CLASS_VIDEODRV,
229 {0, 0, 0, 0}
230};
231
232/** Let the XFree86 code know about the VersRec and Setup() function. */
John Sheu1c8161d2012-05-31 16:26:33 -0700233_X_EXPORT XF86ModuleData armsocModuleData = { &OMAPVersRec, OMAPSetup, NULL };
Rob Clark487687e2011-07-17 17:29:02 -0500234
235
236/**
237 * The first function that the XFree86 code calls, after loading this module.
238 */
239static pointer
240OMAPSetup(pointer module, pointer opts, int *errmaj, int *errmin)
241{
242 static Bool setupDone = FALSE;
243
244 /* This module should be loaded only once, but check to be sure: */
245 if (!setupDone) {
246 setupDone = TRUE;
247 xf86AddDriver(&OMAP, module, 0);
248
249 /* The return value must be non-NULL on success even though there is no
250 * TearDownProc.
251 */
252 return (pointer) 1;
253 } else {
254 if (errmaj)
255 *errmaj = LDR_ONCEONLY;
256 return NULL;
257 }
258}
259
260
261/**
262 * Allocate the driver's Screen-specific, "private" data structure and hook it
263 * into the ScrnInfoRec's driverPrivate field.
264 */
265static Bool
266OMAPGetRec(ScrnInfoPtr pScrn)
267{
268 if (pScrn->driverPrivate != NULL)
269 return TRUE;
270
271 pScrn->driverPrivate = calloc(1, sizeof(OMAPRec));
272 if (pScrn->driverPrivate == NULL)
273 return FALSE;
274
275 return TRUE;
276}
277
278
279/**
280 * Free the driver's Screen-specific, "private" data structure and NULL-out the
281 * ScrnInfoRec's driverPrivate field.
282 */
283static void
284OMAPFreeRec(ScrnInfoPtr pScrn)
285{
286 if (pScrn->driverPrivate == NULL)
287 return;
288 free(pScrn->driverPrivate);
289 pScrn->driverPrivate = NULL;
290}
291
292
293/**
294 * The mandatory AvailableOptions() function. It returns the available driver
295 * options to the "-configure" option, so that an xorg.conf file can be built
296 * and the user can see which options are available for them to use.
297 */
298static const OptionInfoRec *
299OMAPAvailableOptions(int chipid, int busid)
300{
301 return OMAPOptions;
302}
303
304
305
306/**
307 * The mandatory Identify() function. It is run before Probe(), and prints out
308 * an identifying message, which includes the chipset(s) the driver supports.
309 */
310static void
311OMAPIdentify(int flags)
312{
313 xf86PrintChipsets(OMAP_NAME, "Driver for TI OMAP", OMAPChipsets);
314}
315
316
317
318/**
319 * The driver's Probe() function. This function finds all instances of the
320 * TI OMAP hardware that the driver supports (from within the "xorg.conf"
321 * device sections), and for instances not already claimed by another driver,
322 * claim the instances, and allocate a ScrnInfoRec. Only minimal hardware
323 * probing is allowed here.
324 */
325static Bool
326OMAPProbe(DriverPtr drv, int flags)
327{
328 int i;
329 ScrnInfoPtr pScrn;
330 GDevPtr *devSections;
331 int numDevSections;
332 Bool foundScreen = FALSE;
333
Rob Clark487687e2011-07-17 17:29:02 -0500334 /* Get the "xorg.conf" file device sections that match this driver, and
335 * return (error out) if there are none:
336 */
337 numDevSections = xf86MatchDevice(OMAP_DRIVER_NAME, &devSections);
338 if (numDevSections <= 0) {
339 EARLY_ERROR_MSG("Did not find any matching device section in "
340 "configuration file");
Rob Clark83f49e02012-01-08 17:31:59 -0600341 if (flags & PROBE_DETECT) {
342 /* if we are probing, assume one and lets see if we can
343 * open the device to confirm it is there:
344 */
345 numDevSections = 1;
346 } else {
347 return FALSE;
348 }
Rob Clark487687e2011-07-17 17:29:02 -0500349 }
350
351 for (i = 0; i < numDevSections; i++) {
352 int fd = OMAPOpenDRM(i);
353 if (fd != -1) {
Rob Clark83f49e02012-01-08 17:31:59 -0600354
355 if (flags & PROBE_DETECT) {
356 /* just add the device.. we aren't a PCI device, so
357 * call xf86AddBusDeviceToConfigure() directly
358 */
359 xf86AddBusDeviceToConfigure(OMAP_DRIVER_NAME,
360 BUS_NONE, NULL, i);
361 foundScreen = TRUE;
362 continue;
363 }
Rob Clark487687e2011-07-17 17:29:02 -0500364
365 pScrn = xf86AllocateScreen(drv, 0);
Rob Clark83f49e02012-01-08 17:31:59 -0600366
Rob Clark487687e2011-07-17 17:29:02 -0500367 if (!pScrn) {
368 EARLY_ERROR_MSG("Cannot allocate a ScrnInfoPtr");
369 return FALSE;
370 }
Rob Clark83f49e02012-01-08 17:31:59 -0600371
372 if (devSections) {
373 int entity = xf86ClaimNoSlot(drv, 0, devSections[i], TRUE);
374 xf86AddEntityToScreen(pScrn, entity);
375 }
Rob Clark487687e2011-07-17 17:29:02 -0500376
377 foundScreen = TRUE;
378
379 pScrn->driverVersion = OMAP_VERSION;
380 pScrn->driverName = (char *)OMAP_DRIVER_NAME;
381 pScrn->name = (char *)OMAP_NAME;
382 pScrn->Probe = OMAPProbe;
383 pScrn->PreInit = OMAPPreInit;
384 pScrn->ScreenInit = OMAPScreenInit;
385 pScrn->SwitchMode = OMAPSwitchMode;
386 pScrn->AdjustFrame = OMAPAdjustFrame;
387 pScrn->EnterVT = OMAPEnterVT;
388 pScrn->LeaveVT = OMAPLeaveVT;
389 pScrn->FreeScreen = OMAPFreeScreen;
390
391 /* would be nice to be able to keep the connection open.. but
392 * currently we don't allocate the private until PreInit
393 */
394 drmClose(fd);
395 }
396 }
397 free(devSections);
398 return foundScreen;
399}
400
401
402
403/**
404 * The driver's PreInit() function. Additional hardware probing is allowed
405 * now, including display configuration.
406 */
407static Bool
408OMAPPreInit(ScrnInfoPtr pScrn, int flags)
409{
410 OMAPPtr pOMAP;
411 int default_depth, fbbpp;
412 rgb defaultWeight = { 0, 0, 0 };
413 rgb defaultMask = { 0, 0, 0 };
414 Gamma defaultGamma = { 0.0, 0.0, 0.0 };
415 uint64_t value;
416 int i;
417
418 TRACE_ENTER();
419
420 if (flags & PROBE_DETECT) {
421 ERROR_MSG("The %s driver does not support the \"-configure\" or "
422 "\"-probe\" command line arguments.", OMAP_NAME);
423 return FALSE;
424 }
425
426 /* Check the number of entities, and fail if it isn't one. */
427 if (pScrn->numEntities != 1) {
428 ERROR_MSG("Driver expected 1 entity, but found %d for screen %d",
429 pScrn->numEntities, pScrn->scrnIndex);
430 return FALSE;
431 }
432
433 /* Allocate the driver's Screen-specific, "private" data structure: */
434 OMAPGetRec(pScrn);
435 pOMAP = OMAPPTR(pScrn);
436
437 pOMAP->pEntityInfo = xf86GetEntityInfo(pScrn->entityList[0]);
438
439 pScrn->monitor = pScrn->confScreen->monitor;
440
441 /* Get the current depth, and set it for XFree86: */
Dave Barnish2742d152013-03-13 13:36:58 +0000442 default_depth = 24; /* TODO: MIDEGL-1445: get from kernel */
443 fbbpp = 32; /* TODO: MIDEGL-1445: get from kernel */
Rob Clark487687e2011-07-17 17:29:02 -0500444
445 if (!xf86SetDepthBpp(pScrn, default_depth, 0, fbbpp, Support32bppFb)) {
446 /* The above function prints an error message. */
447 goto fail;
448 }
449 xf86PrintDepthBpp(pScrn);
450
451 /* Set the color weight: */
452 if (!xf86SetWeight(pScrn, defaultWeight, defaultMask)) {
453 /* The above function prints an error message. */
454 goto fail;
455 }
456
457 /* Set the gamma: */
458 if (!xf86SetGamma(pScrn, defaultGamma)) {
459 /* The above function prints an error message. */
460 goto fail;
461 }
462
463 /* Visual init: */
464 if (!xf86SetDefaultVisual(pScrn, -1)) {
465 /* The above function prints an error message. */
466 goto fail;
467 }
468
469 /* We don't support 8-bit depths: */
470 if (pScrn->depth < 16) {
471 ERROR_MSG("The requested default visual (%s) has an unsupported "
472 "depth (%d).",
473 xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
474 goto fail;
475 }
476
477 /* Using a programmable clock: */
478 pScrn->progClock = TRUE;
479
480 /* Open a connection to the DRM, so we can communicate with the KMS code: */
481 if (!OMAPOpenDRMMaster(pScrn, 0)) {
482 goto fail;
483 }
484 DEBUG_MSG("Became DRM master.");
485
486 /* create DRM device instance: */
487 pOMAP->dev = omap_device_new(pOMAP->drmFD);
488
489 /* query chip-id: */
490 if (omap_get_param(pOMAP->dev, OMAP_PARAM_CHIPSET_ID, &value)) {
491 ERROR_MSG("Could not read chipset");
492 goto fail;
493 }
494 pOMAP->chipset = value;
495
496 /* find matching chipset name: */
497 for (i = 0; OMAPChipsets[i].name; i++) {
498 if (OMAPChipsets[i].token == pOMAP->chipset) {
499 pScrn->chipset = (char *)OMAPChipsets[i].name;
500 break;
501 }
502 }
503
504 if (!pScrn->chipset) {
505 ERROR_MSG("Unknown chipset: %s", pScrn->chipset);
506 goto fail;
507 }
508
509 INFO_MSG("Found chipset: %s", pScrn->chipset);
510
511 /*
512 * Process the "xorg.conf" file options:
513 */
514 xf86CollectOptions(pScrn, NULL);
515 if (!(pOMAP->pOptionInfo = calloc(1, sizeof(OMAPOptions))))
516 return FALSE;
517 memcpy(pOMAP->pOptionInfo, OMAPOptions, sizeof(OMAPOptions));
518 xf86ProcessOptions(pScrn->scrnIndex, pOMAP->pEntityInfo->device->options,
519 pOMAP->pOptionInfo);
520
521 /* Determine if the user wants debug messages turned on: */
522 omapDebug = xf86ReturnOptValBool(pOMAP->pOptionInfo, OPTION_DEBUG, FALSE);
523
Rob Clark4b8f30a2011-08-28 12:51:26 -0500524 pOMAP->dri = xf86ReturnOptValBool(pOMAP->pOptionInfo, OPTION_DRI, TRUE);
525
Rob Clark687c6082012-01-08 19:33:18 -0600526 /* Determine if user wants to disable hw mouse cursor: */
527 pOMAP->HWCursor = xf86ReturnOptValBool(pOMAP->pOptionInfo,
528 OPTION_HW_CURSOR, TRUE);
529 INFO_MSG("Using %s cursor", pOMAP->HWCursor ? "HW" : "SW");
Rob Clark4b8f30a2011-08-28 12:51:26 -0500530
Dave Barnishc50baf52012-11-29 14:39:36 +0000531 /* Determine if user wants to disable buffer flipping: */
532 pOMAP->NoFlip = xf86ReturnOptValBool(pOMAP->pOptionInfo,
533 OPTION_NO_FLIP, FALSE);
534 INFO_MSG("Buffer Flipping is %s", pOMAP->NoFlip ? "Disabled" : "Enabled");
535
Rob Clark487687e2011-07-17 17:29:02 -0500536 /* Determine if the user wants to disable acceleration: */
Rob Clark687c6082012-01-08 19:33:18 -0600537 pOMAP->NoAccel = xf86ReturnOptValBool(pOMAP->pOptionInfo,
538 OPTION_NO_ACCEL, FALSE);
Rob Clark487687e2011-07-17 17:29:02 -0500539
540 /*
541 * Select the video modes:
542 */
543 INFO_MSG("Setting the video modes ...");
544
545 /* Don't call drmCheckModesettingSupported() as its written only for
546 * PCI devices.
547 */
548
549 /* Do initial KMS setup: */
550 if (!drmmode_pre_init(pScrn, pOMAP->drmFD, (pScrn->bitsPerPixel >> 3))) {
551 ERROR_MSG("Cannot get KMS resources");
552 } else {
553 INFO_MSG("Got KMS resources");
554 }
555
556 xf86RandR12PreInit(pScrn);
557
558 /* Let XFree86 calculate or get (from command line) the display DPI: */
559 xf86SetDpi(pScrn, 0, 0);
560
561 /* Ensure we have a supported depth: */
562 switch (pScrn->bitsPerPixel) {
563 case 16:
564 case 24:
565 case 32:
566 break;
567 default:
568 ERROR_MSG("The requested number of bits per pixel (%d) is unsupported.",
569 pScrn->bitsPerPixel);
570 goto fail;
571 }
572
573
574 /* Load external sub-modules now: */
575
576 if (!(xf86LoadSubModule(pScrn, "dri2") &&
577 xf86LoadSubModule(pScrn, "exa") &&
578 xf86LoadSubModule(pScrn, "fb"))) {
579 goto fail;
580 }
581
582 switch (pOMAP->chipset) {
583 case 0x3430:
584 case 0x3630:
585 case 0x4430:
586 case 0x4460:
Vincent Stehlé1ae20362012-03-05 10:26:22 +0000587 case 0x5430:
588 case 0x5432:
Rob Clark487687e2011-07-17 17:29:02 -0500589 if (xf86LoadSubModule(pScrn, SUB_MODULE_PVR)) {
590 INFO_MSG("Loaded the %s sub-module", SUB_MODULE_PVR);
591 } else {
592 INFO_MSG("Cannot load the %s sub-module", SUB_MODULE_PVR);
593 /* note that this is not fatal.. since IMG/PVR EXA module
594 * is closed source, it is only optional.
595 */
596 pOMAP->NoAccel = TRUE; /* don't call InitPowerVREXA() */
597 }
598 break;
599 /* case 0x4470: ..; break; */
David Garbettc79b4f32012-04-19 07:46:11 +0100600 case 0x0600:
601 pOMAP->NoAccel = TRUE; /* don't call InitPowerVREXA() */
602 break;
Rob Clark487687e2011-07-17 17:29:02 -0500603 default:
604 ERROR_MSG("Unsupported chipset: %d", pOMAP->chipset);
605 goto fail;
606 }
607
608 TRACE_EXIT();
609 return TRUE;
610
611fail:
612 TRACE_EXIT();
613 OMAPFreeRec(pScrn);
614 return FALSE;
615}
616
617
Rob Clarkdc9dfae2012-01-11 18:20:18 -0600618/**
619 * Initialize EXA and DRI2
620 */
621static void
622OMAPAccelInit(ScreenPtr pScreen)
623{
624 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
625 OMAPPtr pOMAP = OMAPPTR(pScrn);
626
627 if (!pOMAP->NoAccel) {
628 switch (pOMAP->chipset) {
629 case 0x3430:
630 case 0x3630:
631 case 0x4430:
632 case 0x4460:
Vincent Stehlé1ae20362012-03-05 10:26:22 +0000633 case 0x5430:
634 case 0x5432:
Rob Clarkdc9dfae2012-01-11 18:20:18 -0600635 INFO_MSG("Initializing the \"%s\" sub-module ...", SUB_MODULE_PVR);
Rob Clark0fdd91f2011-10-20 09:56:11 -0500636 pOMAP->pOMAPEXA = InitPowerVREXA(pScreen, pScrn, pOMAP->drmFD);
Rob Clarkdc9dfae2012-01-11 18:20:18 -0600637 if (pOMAP->pOMAPEXA) {
638 INFO_MSG("Successfully initialized the \"%s\" sub-module",
639 SUB_MODULE_PVR);
640 } else {
641 INFO_MSG("Could not initialize the \"%s\" sub-module",
642 SUB_MODULE_PVR);
643 pOMAP->NoAccel = TRUE;
644 }
645 break;
646 default:
647 ERROR_MSG("Unsupported chipset: %d", pOMAP->chipset);
648 pOMAP->NoAccel = TRUE;
649 break;
650 }
651 }
652
653 if (!pOMAP->pOMAPEXA) {
Rob Clark0fdd91f2011-10-20 09:56:11 -0500654 pOMAP->pOMAPEXA = InitNullEXA(pScreen, pScrn, pOMAP->drmFD);
Rob Clarkdc9dfae2012-01-11 18:20:18 -0600655 }
656
657 if (pOMAP->dri && pOMAP->pOMAPEXA) {
658 pOMAP->dri = OMAPDRI2ScreenInit(pScreen);
659 } else {
660 pOMAP->dri = FALSE;
661 }
Rob Clark447d4132012-01-22 18:38:24 -0600662
Raymond Smith34fc43f2012-04-03 12:04:24 +0100663#if 0
Rob Clark447d4132012-01-22 18:38:24 -0600664 if (OMAPVideoScreenInit(pScreen)) {
665 INFO_MSG("Initialized XV");
666 } else {
667 ERROR_MSG("Could not initialize XV");
668 }
Raymond Smith34fc43f2012-04-03 12:04:24 +0100669#endif
Rob Clarkdc9dfae2012-01-11 18:20:18 -0600670}
Rob Clark487687e2011-07-17 17:29:02 -0500671
672/**
673 * The driver's ScreenInit() function. Fill in pScreen, map the frame buffer,
674 * save state, initialize the mode, etc.
675 */
676static Bool
Cooper Yuana83caa62012-06-28 17:19:06 +0200677OMAPScreenInit(SCREEN_INIT_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -0500678{
679 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
680 OMAPPtr pOMAP = OMAPPTR(pScrn);
681 VisualPtr visual;
682 xf86CrtcConfigPtr xf86_config;
David Garbett82b51832012-07-04 08:29:38 +0100683 int j;
Rob Clark487687e2011-07-17 17:29:02 -0500684
685 TRACE_ENTER();
686
Rob Clark487687e2011-07-17 17:29:02 -0500687 /* Allocate and map memory areas we need */
688 if (!OMAPMapMem(pScrn))
689 return FALSE;
690
691 xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
692
693 /* need to point to new screen on server regeneration */
David Garbett82b51832012-07-04 08:29:38 +0100694 for (j = 0; j < xf86_config->num_crtc; j++)
695 xf86_config->crtc[j]->scrn = pScrn;
696 for (j = 0; j < xf86_config->num_output; j++)
697 xf86_config->output[j]->scrn = pScrn;
Rob Clark487687e2011-07-17 17:29:02 -0500698
699 /*
700 * The next step is to setup the screen's visuals, and initialize the
701 * framebuffer code. In cases where the framebuffer's default
702 * choices for things like visual layouts and bits per RGB are OK,
703 * this may be as simple as calling the framebuffer's ScreenInit()
704 * function. If not, the visuals will need to be setup before calling
705 * a fb ScreenInit() function and fixed up after.
706 *
707 * For most PC hardware at depths >= 8, the defaults that fb uses
708 * are not appropriate. In this driver, we fixup the visuals after.
709 */
710
711 /*
712 * Reset the visual list.
713 */
714
715 miClearVisualTypes();
David Garbettc0bc3fb2012-09-26 14:08:29 +0100716 if (!miSetVisualTypes(pScrn->bitsPerPixel, miGetDefaultVisualMask(pScrn->depth),
Rob Clark487687e2011-07-17 17:29:02 -0500717 pScrn->rgbBits, pScrn->defaultVisual)) {
718 ERROR_MSG("Cannot initialize the visual type for %d bits per pixel!",
719 pScrn->bitsPerPixel);
720 goto fail;
721 }
722
David Garbettef4b7482012-09-26 14:09:01 +0100723 if(pScrn->bitsPerPixel == 32 && pScrn->depth == 24) {
724 /* Also add a 24 bit depth visual */
725 if (!miSetVisualTypes(24, miGetDefaultVisualMask(pScrn->depth),
726 pScrn->rgbBits, pScrn->defaultVisual)) {
727 WARNING_MSG("Cannot initialize a 24 depth visual for 32bpp");
728 }else{
729 INFO_MSG("Initialized a 24 depth visual for 32bpp");
730 }
731 }
732
Rob Clark487687e2011-07-17 17:29:02 -0500733 if (!miSetPixmapDepths()) {
734 ERROR_MSG("Cannot initialize the pixmap depth!");
735 goto fail;
736 }
737
738 /* Initialize some generic 2D drawing functions: */
739 if (!fbScreenInit(pScreen, omap_bo_map(pOMAP->scanout),
740 pScrn->virtualX, pScrn->virtualY,
741 pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
742 pScrn->bitsPerPixel)) {
743 ERROR_MSG("fbScreenInit() failed!");
744 goto fail;
745 }
746
747 /* Fixup RGB ordering: */
748 visual = pScreen->visuals + pScreen->numVisuals;
749 while (--visual >= pScreen->visuals) {
750 if ((visual->class | DynamicClass) == DirectColor) {
751 visual->offsetRed = pScrn->offset.red;
752 visual->offsetGreen = pScrn->offset.green;
753 visual->offsetBlue = pScrn->offset.blue;
754 visual->redMask = pScrn->mask.red;
755 visual->greenMask = pScrn->mask.green;
756 visual->blueMask = pScrn->mask.blue;
David Garbett100928b2012-10-03 14:20:54 +0100757 visual->bitsPerRGBValue = pScrn->rgbBits;
758 visual->ColormapEntries = 1 << pScrn->rgbBits;
Rob Clark487687e2011-07-17 17:29:02 -0500759 }
760 }
761
762 /* Continue initializing the generic 2D drawing functions after fixing the
763 * RGB ordering:
764 */
765 if (!fbPictureInit(pScreen, NULL, 0)) {
766 ERROR_MSG("fbPictureInit() failed!");
767 goto fail;
768 }
769
770 /* Set the initial black & white colormap indices: */
771 xf86SetBlackWhitePixels(pScreen);
772
Rob Clarkdc9dfae2012-01-11 18:20:18 -0600773 /* Initialize external sub-modules for EXA now, this has to be before
774 * miDCInitialize() otherwise stacking order for wrapped ScreenPtr fxns
775 * ends up in the wrong order.
776 */
777 OMAPAccelInit(pScreen);
778
Rob Clark487687e2011-07-17 17:29:02 -0500779 /* Initialize backing store: */
780 miInitializeBackingStore(pScreen);
781 xf86SetBackingStore(pScreen);
782
Rob Clark687c6082012-01-08 19:33:18 -0600783 /* Cause the cursor position to be updated by the mouse signal handler: */
784 xf86SetSilkenMouse(pScreen);
785
Rob Clark487687e2011-07-17 17:29:02 -0500786 /* Initialize the cursor: */
787 miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
788
Rob Clark687c6082012-01-08 19:33:18 -0600789 if (pOMAP->HWCursor) {
790 if (!drmmode_cursor_init(pScreen)) {
791 ERROR_MSG("Hardware cursor initialization failed");
792 pOMAP->HWCursor = FALSE;
793 }
794 }
Rob Clark487687e2011-07-17 17:29:02 -0500795
796 /* XXX -- Is this the right place for this? The Intel i830 driver says:
797 * "Must force it before EnterVT, so we are in control of VT..."
798 */
799 pScrn->vtSema = TRUE;
800
801 /* Take over the virtual terminal from the console, set the desired mode,
802 * etc.:
803 */
Mandeep Singh Bainese8a70992012-10-03 10:31:48 -0700804 if (!OMAPEnterVT(VT_FUNC_ARGS(0))) {
805 ERROR_MSG("OMAPEnterVT() failed!");
Rob Clark487687e2011-07-17 17:29:02 -0500806 goto fail;
807 }
808
809 /* Do some XRandR initialization: */
810 if (!xf86CrtcScreenInit(pScreen)) {
811 ERROR_MSG("xf86CrtcScreenInit() failed!");
812 goto fail;
813 }
814
815 if (!miCreateDefColormap(pScreen)) {
816 ERROR_MSG("Cannot create colormap!");
817 goto fail;
818 }
819
David Garbett100928b2012-10-03 14:20:54 +0100820 if (!xf86HandleColormaps(pScreen, 1 << pScrn->rgbBits, pScrn->rgbBits,
821 OMAPLoadPalette, NULL, CMAP_PALETTED_TRUECOLOR)) {
Rob Clark487687e2011-07-17 17:29:02 -0500822 ERROR_MSG("xf86HandleColormaps() failed!");
823 goto fail;
824 }
825
826 /* Setup power management: */
827 xf86DPMSInit(pScreen, xf86DPMSSet, 0);
828
829 pScreen->SaveScreen = xf86SaveScreen;
830
831 /* Wrap some screen functions: */
832 wrap(pOMAP, pScreen, CloseScreen, OMAPCloseScreen);
833 wrap(pOMAP, pScreen, CreateScreenResources, OMAPCreateScreenResources);
834 wrap(pOMAP, pScreen, BlockHandler, OMAPBlockHandler);
835
Rob Clark4b8f30a2011-08-28 12:51:26 -0500836 drmmode_screen_init(pScrn);
Rob Clark487687e2011-07-17 17:29:02 -0500837
838 TRACE_EXIT();
839 return TRUE;
840
841fail:
842 TRACE_EXIT();
843 return FALSE;
844}
845
846
847static void
848OMAPLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
849 LOCO * colors, VisualPtr pVisual)
850{
851 TRACE_ENTER();
852 TRACE_EXIT();
853}
854
855
856/**
857 * The driver's CloseScreen() function. This is called at the end of each
858 * server generation. Restore state, unmap the frame buffer (and any other
859 * mapped memory regions), and free per-Screen data structures (except those
860 * held by pScrn).
861 */
862static Bool
Cooper Yuana83caa62012-06-28 17:19:06 +0200863OMAPCloseScreen(CLOSE_SCREEN_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -0500864{
Cooper Yuana83caa62012-06-28 17:19:06 +0200865 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
Rob Clark487687e2011-07-17 17:29:02 -0500866 OMAPPtr pOMAP = OMAPPTR(pScrn);
867
868 TRACE_ENTER();
869
Rob Clark4b8f30a2011-08-28 12:51:26 -0500870 drmmode_screen_fini(pScrn);
Rob Clark487687e2011-07-17 17:29:02 -0500871
872 if (pScrn->vtSema == TRUE) {
Cooper Yuana83caa62012-06-28 17:19:06 +0200873 OMAPLeaveVT(VT_FUNC_ARGS(0));
Rob Clark487687e2011-07-17 17:29:02 -0500874 }
875
876 if (pOMAP->pOMAPEXA) {
877 if (pOMAP->pOMAPEXA->CloseScreen) {
Cooper Yuana83caa62012-06-28 17:19:06 +0200878 pOMAP->pOMAPEXA->CloseScreen(CLOSE_SCREEN_ARGS);
Rob Clark487687e2011-07-17 17:29:02 -0500879 }
880 }
881
Rob Clark4b8f30a2011-08-28 12:51:26 -0500882 if (pOMAP->dri) {
883 OMAPDRI2CloseScreen(pScreen);
884 }
Rob Clark4b8f30a2011-08-28 12:51:26 -0500885
Raymond Smithe553ce82012-04-04 12:44:27 +0100886#if 0
Rob Clark447d4132012-01-22 18:38:24 -0600887 OMAPVideoCloseScreen(pScreen);
Raymond Smithe553ce82012-04-04 12:44:27 +0100888#endif
Rob Clark447d4132012-01-22 18:38:24 -0600889
Rob Clark487687e2011-07-17 17:29:02 -0500890 OMAPUnmapMem(pScrn);
891
892 pScrn->vtSema = FALSE;
893
894 unwrap(pOMAP, pScreen, CloseScreen);
895 unwrap(pOMAP, pScreen, BlockHandler);
896 unwrap(pOMAP, pScreen, CreateScreenResources);
897
898 TRACE_EXIT();
899
Cooper Yuana83caa62012-06-28 17:19:06 +0200900 return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS);
Rob Clark487687e2011-07-17 17:29:02 -0500901}
902
903
904
905/**
906 * Adjust the screen pixmap for the current location of the front buffer.
907 * This is done at EnterVT when buffers are bound as long as the resources
908 * have already been created, but the first EnterVT happens before
909 * CreateScreenResources.
910 */
911static Bool
912OMAPCreateScreenResources(ScreenPtr pScreen)
913{
914 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
915 OMAPPtr pOMAP = OMAPPTR(pScrn);
916
917 swap(pOMAP, pScreen, CreateScreenResources);
918 if (!(*pScreen->CreateScreenResources) (pScreen))
919 return FALSE;
920 swap(pOMAP, pScreen, CreateScreenResources);
921
922 return TRUE;
923}
924
925
926static void
Cooper Yuana83caa62012-06-28 17:19:06 +0200927OMAPBlockHandler(BLOCKHANDLER_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -0500928{
Cooper Yuana83caa62012-06-28 17:19:06 +0200929 SCREEN_PTR(arg);
930 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
Rob Clark487687e2011-07-17 17:29:02 -0500931 OMAPPtr pOMAP = OMAPPTR(pScrn);
932
933 swap(pOMAP, pScreen, BlockHandler);
Cooper Yuana83caa62012-06-28 17:19:06 +0200934 (*pScreen->BlockHandler) (BLOCKHANDLER_ARGS);
Rob Clark487687e2011-07-17 17:29:02 -0500935 swap(pOMAP, pScreen, BlockHandler);
Rob Clark487687e2011-07-17 17:29:02 -0500936}
937
938
939
940/**
941 * The driver's SwitchMode() function. Initialize the new mode for the
942 * Screen.
943 */
944static Bool
Cooper Yuana83caa62012-06-28 17:19:06 +0200945OMAPSwitchMode(SWITCH_MODE_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -0500946{
Cooper Yuana83caa62012-06-28 17:19:06 +0200947 SCRN_INFO_PTR(arg);
Rob Clark487687e2011-07-17 17:29:02 -0500948 return xf86SetSingleMode(pScrn, mode, RR_Rotate_0);
949}
950
951
952
953/**
954 * The driver's AdjustFrame() function. For cases where the frame buffer is
955 * larger than the monitor resolution, this function can pan around the frame
956 * buffer within the "viewport" of the monitor.
957 */
958static void
Cooper Yuana83caa62012-06-28 17:19:06 +0200959OMAPAdjustFrame(ADJUST_FRAME_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -0500960{
Cooper Yuana83caa62012-06-28 17:19:06 +0200961 SCRN_INFO_PTR(arg);
962 drmmode_adjust_frame(pScrn, x, y);
Rob Clark487687e2011-07-17 17:29:02 -0500963}
964
965
966
967/**
968 * The driver's EnterVT() function. This is called at server startup time, and
969 * when the X server takes over the virtual terminal from the console. As
970 * such, it may need to save the current (i.e. console) HW state, and set the
971 * HW state as needed by the X server.
972 */
973static Bool
Cooper Yuana83caa62012-06-28 17:19:06 +0200974OMAPEnterVT(VT_FUNC_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -0500975{
Cooper Yuana83caa62012-06-28 17:19:06 +0200976 SCRN_INFO_PTR(arg);
Rob Clark487687e2011-07-17 17:29:02 -0500977 OMAPPtr pOMAP = OMAPPTR(pScrn);
Ray Smith6ae735f2013-03-21 15:57:18 +0000978 int i, ret;
abhinav.kd4bab322012-07-31 11:29:19 -0700979
Rob Clark487687e2011-07-17 17:29:02 -0500980 TRACE_ENTER();
981
Ray Smith6ae735f2013-03-21 15:57:18 +0000982 for (i = 1; i < currentMaxClients; i++) {
983 if (clients[i])
984 AttendClient(clients[i]);
985 }
986
Rob Clark487687e2011-07-17 17:29:02 -0500987 ret = drmSetMaster(pOMAP->drmFD);
988 if (ret) {
Daniel Kurtz92205962013-02-05 13:50:12 +0800989 ERROR_MSG("Cannot get DRM master: %s", strerror(errno));
Daniel Kurtz01a91f62013-02-05 10:19:51 +0800990 return FALSE;
Rob Clark487687e2011-07-17 17:29:02 -0500991 }
992
993 if (!xf86SetDesiredModes(pScrn)) {
994 ERROR_MSG("xf86SetDesiredModes() failed!");
995 return FALSE;
996 }
997
998 TRACE_EXIT();
999 return TRUE;
1000}
1001
1002
1003
1004/**
1005 * The driver's LeaveVT() function. This is called when the X server
1006 * temporarily gives up the virtual terminal to the console. As such, it may
1007 * need to restore the console's HW state.
1008 */
1009static void
Cooper Yuana83caa62012-06-28 17:19:06 +02001010OMAPLeaveVT(VT_FUNC_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -05001011{
Cooper Yuana83caa62012-06-28 17:19:06 +02001012 SCRN_INFO_PTR(arg);
Rob Clark487687e2011-07-17 17:29:02 -05001013 OMAPPtr pOMAP = OMAPPTR(pScrn);
Ray Smith6ae735f2013-03-21 15:57:18 +00001014 int i, ret;
abhinav.kd4bab322012-07-31 11:29:19 -07001015
Rob Clark487687e2011-07-17 17:29:02 -05001016 TRACE_ENTER();
1017
Ray Smith6ae735f2013-03-21 15:57:18 +00001018 for (i = 1; i < currentMaxClients; i++) {
1019 if (clients[i])
1020 IgnoreClient(clients[i]);
1021 }
1022
Rob Clark487687e2011-07-17 17:29:02 -05001023 ret = drmDropMaster(pOMAP->drmFD);
1024 if (ret) {
Daniel Kurtz92205962013-02-05 13:50:12 +08001025 WARNING_MSG("drmDropMaster failed: %s", strerror(errno));
Rob Clark487687e2011-07-17 17:29:02 -05001026 }
1027
1028 TRACE_EXIT();
1029}
1030
1031
1032
1033/**
1034 * The driver's FreeScreen() function. This is called at the server's end of
1035 * life. This should free any driver-allocated data that was allocated
1036 * up-to-and-including an unsuccessful ScreenInit() call.
1037 */
1038static void
Cooper Yuana83caa62012-06-28 17:19:06 +02001039OMAPFreeScreen(FREE_SCREEN_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -05001040{
Cooper Yuana83caa62012-06-28 17:19:06 +02001041 SCRN_INFO_PTR(arg);
Rob Clark487687e2011-07-17 17:29:02 -05001042 OMAPPtr pOMAP = OMAPPTR(pScrn);
1043
1044 TRACE_ENTER();
1045
1046 if (!pOMAP) {
1047 /* This can happen if a Screen is deleted after Probe(): */
1048 return;
1049 }
1050
1051 if (pOMAP->pOMAPEXA) {
1052 if (pOMAP->pOMAPEXA->FreeScreen) {
Cooper Yuana83caa62012-06-28 17:19:06 +02001053 pOMAP->pOMAPEXA->FreeScreen(FREE_SCREEN_ARGS(pScrn));
Rob Clark487687e2011-07-17 17:29:02 -05001054 }
1055 free(pOMAP->pOMAPEXA);
1056 }
1057
1058 omap_device_del(pOMAP->dev);
1059
1060 OMAPCloseDRMMaster(pScrn);
1061
1062 OMAPFreeRec(pScrn);
1063
1064 TRACE_EXIT();
1065}
1066