blob: a294a6715cdbd741f47ca1b64c6ec2c430397060 [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
Ray Smith3c33c3d2013-03-26 16:06:37 +000041#include "drmmode_driver.h"
42
Rob Clark487687e2011-07-17 17:29:02 -050043Bool omapDebug = 0;
44
45/*
46 * Forward declarations:
47 */
48static const OptionInfoRec *OMAPAvailableOptions(int chipid, int busid);
49static void OMAPIdentify(int flags);
50static Bool OMAPProbe(DriverPtr drv, int flags);
51static Bool OMAPPreInit(ScrnInfoPtr pScrn, int flags);
Cooper Yuana83caa62012-06-28 17:19:06 +020052static Bool OMAPScreenInit(SCREEN_INIT_ARGS_DECL);
Rob Clark487687e2011-07-17 17:29:02 -050053static void OMAPLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
54 LOCO * colors, VisualPtr pVisual);
Cooper Yuana83caa62012-06-28 17:19:06 +020055static Bool OMAPCloseScreen(CLOSE_SCREEN_ARGS_DECL);
Rob Clark487687e2011-07-17 17:29:02 -050056static Bool OMAPCreateScreenResources(ScreenPtr pScreen);
Cooper Yuana83caa62012-06-28 17:19:06 +020057static void OMAPBlockHandler(BLOCKHANDLER_ARGS_DECL);
58static Bool OMAPSwitchMode(SWITCH_MODE_ARGS_DECL);
59static void OMAPAdjustFrame(ADJUST_FRAME_ARGS_DECL);
60static Bool OMAPEnterVT(VT_FUNC_ARGS_DECL);
61static void OMAPLeaveVT(VT_FUNC_ARGS_DECL);
62static void OMAPFreeScreen(FREE_SCREEN_ARGS_DECL);
Rob Clark487687e2011-07-17 17:29:02 -050063
64
65
66/**
67 * A structure used by the XFree86 code when loading this driver, so that it
68 * can access the Probe() function, and other functions/info that it uses
69 * before it calls the Probe() function. The name of this structure must be
70 * the all-upper-case version of the driver name.
71 */
72_X_EXPORT DriverRec OMAP = {
73 OMAP_VERSION,
74 (char *)OMAP_DRIVER_NAME,
75 OMAPIdentify,
76 OMAPProbe,
77 OMAPAvailableOptions,
78 NULL,
79 0,
80 NULL,
81#ifdef XSERVER_LIBPCIACCESS
82 NULL,
83 NULL
84#endif
85};
86
Dave Barnish01b5c172013-04-10 11:01:17 +010087#define MALI_4XX_CHIPSET_ID (0x0400)
88#define MALI_T6XX_CHIPSET_ID (0x0600)
89
Rob Clark487687e2011-07-17 17:29:02 -050090/** Supported "chipsets." */
91static SymTabRec OMAPChipsets[] = {
Dave Barnish01b5c172013-04-10 11:01:17 +010092 { MALI_4XX_CHIPSET_ID, "Mali-4XX" },
93 { MALI_T6XX_CHIPSET_ID, "Mali-T6XX" },
Rob Clark487687e2011-07-17 17:29:02 -050094 {-1, NULL }
95};
96
97/** Supported options, as enum values. */
98typedef enum {
99 OPTION_DEBUG,
Dave Barnishc50baf52012-11-29 14:39:36 +0000100 OPTION_NO_FLIP,
Dave Barnish2742d152013-03-13 13:36:58 +0000101 /* TODO: MIDEGL-1453: probably need to add an option to let user specify bus-id */
Rob Clark487687e2011-07-17 17:29:02 -0500102} OMAPOpts;
103
104/** Supported options. */
105static const OptionInfoRec OMAPOptions[] = {
106 { OPTION_DEBUG, "Debug", OPTV_BOOLEAN, {0}, FALSE },
Dave Barnishc50baf52012-11-29 14:39:36 +0000107 { OPTION_NO_FLIP, "NoFlip", OPTV_BOOLEAN, {0}, FALSE },
Rob Clark487687e2011-07-17 17:29:02 -0500108 { -1, NULL, OPTV_NONE, {0}, FALSE }
109};
110
111/**
112 * Helper function for opening a connection to the DRM.
113 */
114
115static int
116OMAPOpenDRM(int n)
117{
Dave Barnish01b5c172013-04-10 11:01:17 +0100118 return open("/dev/dri/card0", O_RDWR, 0);
Rob Clark487687e2011-07-17 17:29:02 -0500119}
120
121static Bool
122OMAPOpenDRMMaster(ScrnInfoPtr pScrn, int n)
123{
124 OMAPPtr pOMAP = OMAPPTR(pScrn);
125 drmSetVersion sv;
126 int err;
127
128 pOMAP->drmFD = OMAPOpenDRM(n);
129 if (pOMAP->drmFD == -1) {
130 ERROR_MSG("Cannot open a connection with the DRM.");
131 return FALSE;
132 }
133
134 /* Check that what we opened was a master or a master-capable FD,
135 * by setting the version of the interface we'll use to talk to it.
136 * (see DRIOpenDRMMaster() in DRI1)
137 */
138 sv.drm_di_major = 1;
139 sv.drm_di_minor = 1;
140 sv.drm_dd_major = -1;
141 sv.drm_dd_minor = -1;
142 err = drmSetInterfaceVersion(pOMAP->drmFD, &sv);
143 if (err != 0) {
144 ERROR_MSG("Cannot set the DRM interface version.");
145 drmClose(pOMAP->drmFD);
146 pOMAP->drmFD = -1;
147 return FALSE;
148 }
149
Rob Clark4b8f30a2011-08-28 12:51:26 -0500150 pOMAP->deviceName = drmGetDeviceNameFromFd(pOMAP->drmFD);
151
Rob Clark487687e2011-07-17 17:29:02 -0500152 return TRUE;
153}
154
155
156
157/**
158 * Helper function for closing a connection to the DRM.
159 */
160static void
161OMAPCloseDRMMaster(ScrnInfoPtr pScrn)
162{
163 OMAPPtr pOMAP = OMAPPTR(pScrn);
164
165 if (pOMAP && (pOMAP->drmFD > 0)) {
Rob Clark4b8f30a2011-08-28 12:51:26 -0500166 drmFree(pOMAP->deviceName);
Rob Clark487687e2011-07-17 17:29:02 -0500167 drmClose(pOMAP->drmFD);
168 pOMAP->drmFD = -1;
169 }
170}
171
Rob Clark487687e2011-07-17 17:29:02 -0500172static Bool
173OMAPMapMem(ScrnInfoPtr pScrn)
174{
175 OMAPPtr pOMAP = OMAPPTR(pScrn);
Rob Clark487687e2011-07-17 17:29:02 -0500176
David Garbettc5901532012-05-29 13:00:52 +0100177 DEBUG_MSG("allocating new scanout buffer: %dx%d",
178 pScrn->virtualX, pScrn->virtualY);
Rob Clark487687e2011-07-17 17:29:02 -0500179
Sean Paul3e107302012-08-30 12:08:12 -0700180 pOMAP->scanout = omap_bo_new_with_dim(pOMAP->dev, pScrn->virtualX,
181 pScrn->virtualY, pScrn->depth, pScrn->bitsPerPixel,
Dave Barnishf4659732013-03-08 10:11:08 +0000182 OMAP_BO_SCANOUT );
Rob Clark487687e2011-07-17 17:29:02 -0500183 if (!pOMAP->scanout) {
184 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
185 "Error allocating scanout buffer\n");
186 return FALSE;
187 }
188
David Garbettc5901532012-05-29 13:00:52 +0100189 pScrn->displayWidth = omap_bo_pitch(pOMAP->scanout) / (pScrn->bitsPerPixel / 8);
Rob Clark487687e2011-07-17 17:29:02 -0500190
191 return TRUE;
192}
193
194
195static Bool
196OMAPUnmapMem(ScrnInfoPtr pScrn)
197{
Paul Geary34579dc2013-04-03 10:01:15 +0100198 OMAPPtr pOMAP = OMAPPTR(pScrn);
199 omap_bo_unreference(pOMAP->scanout);
200 pOMAP->scanout = NULL;
201 pScrn->displayWidth = 0;
Rob Clark487687e2011-07-17 17:29:02 -0500202 return TRUE;
203}
204
205
206
207/** Let the XFree86 code know the Setup() function. */
208static MODULESETUPPROTO(OMAPSetup);
209
210/** Provide basic version information to the XFree86 code. */
211static XF86ModuleVersionInfo OMAPVersRec =
212{
213 OMAP_DRIVER_NAME,
214 MODULEVENDORSTRING,
215 MODINFOSTRING1,
216 MODINFOSTRING2,
217 XORG_VERSION_CURRENT,
218 OMAP_MAJOR_VERSION, OMAP_MINOR_VERSION, OMAP_PATCHLEVEL,
219 ABI_CLASS_VIDEODRV,
220 ABI_VIDEODRV_VERSION,
221 MOD_CLASS_VIDEODRV,
222 {0, 0, 0, 0}
223};
224
225/** Let the XFree86 code know about the VersRec and Setup() function. */
John Sheu1c8161d2012-05-31 16:26:33 -0700226_X_EXPORT XF86ModuleData armsocModuleData = { &OMAPVersRec, OMAPSetup, NULL };
Rob Clark487687e2011-07-17 17:29:02 -0500227
228
229/**
230 * The first function that the XFree86 code calls, after loading this module.
231 */
232static pointer
233OMAPSetup(pointer module, pointer opts, int *errmaj, int *errmin)
234{
235 static Bool setupDone = FALSE;
236
237 /* This module should be loaded only once, but check to be sure: */
238 if (!setupDone) {
239 setupDone = TRUE;
240 xf86AddDriver(&OMAP, module, 0);
241
242 /* The return value must be non-NULL on success even though there is no
243 * TearDownProc.
244 */
245 return (pointer) 1;
246 } else {
247 if (errmaj)
248 *errmaj = LDR_ONCEONLY;
249 return NULL;
250 }
251}
252
253
254/**
255 * Allocate the driver's Screen-specific, "private" data structure and hook it
256 * into the ScrnInfoRec's driverPrivate field.
257 */
258static Bool
259OMAPGetRec(ScrnInfoPtr pScrn)
260{
261 if (pScrn->driverPrivate != NULL)
262 return TRUE;
263
264 pScrn->driverPrivate = calloc(1, sizeof(OMAPRec));
265 if (pScrn->driverPrivate == NULL)
266 return FALSE;
267
268 return TRUE;
269}
270
271
272/**
273 * Free the driver's Screen-specific, "private" data structure and NULL-out the
274 * ScrnInfoRec's driverPrivate field.
275 */
276static void
277OMAPFreeRec(ScrnInfoPtr pScrn)
278{
279 if (pScrn->driverPrivate == NULL)
280 return;
281 free(pScrn->driverPrivate);
282 pScrn->driverPrivate = NULL;
283}
284
285
286/**
287 * The mandatory AvailableOptions() function. It returns the available driver
288 * options to the "-configure" option, so that an xorg.conf file can be built
289 * and the user can see which options are available for them to use.
290 */
291static const OptionInfoRec *
292OMAPAvailableOptions(int chipid, int busid)
293{
294 return OMAPOptions;
295}
296
297
298
299/**
300 * The mandatory Identify() function. It is run before Probe(), and prints out
301 * an identifying message, which includes the chipset(s) the driver supports.
302 */
303static void
304OMAPIdentify(int flags)
305{
306 xf86PrintChipsets(OMAP_NAME, "Driver for TI OMAP", OMAPChipsets);
307}
308
309
310
311/**
312 * The driver's Probe() function. This function finds all instances of the
313 * TI OMAP hardware that the driver supports (from within the "xorg.conf"
314 * device sections), and for instances not already claimed by another driver,
315 * claim the instances, and allocate a ScrnInfoRec. Only minimal hardware
316 * probing is allowed here.
317 */
318static Bool
319OMAPProbe(DriverPtr drv, int flags)
320{
321 int i;
322 ScrnInfoPtr pScrn;
323 GDevPtr *devSections;
324 int numDevSections;
325 Bool foundScreen = FALSE;
326
Rob Clark487687e2011-07-17 17:29:02 -0500327 /* Get the "xorg.conf" file device sections that match this driver, and
328 * return (error out) if there are none:
329 */
330 numDevSections = xf86MatchDevice(OMAP_DRIVER_NAME, &devSections);
331 if (numDevSections <= 0) {
332 EARLY_ERROR_MSG("Did not find any matching device section in "
333 "configuration file");
Rob Clark83f49e02012-01-08 17:31:59 -0600334 if (flags & PROBE_DETECT) {
335 /* if we are probing, assume one and lets see if we can
336 * open the device to confirm it is there:
337 */
338 numDevSections = 1;
339 } else {
340 return FALSE;
341 }
Rob Clark487687e2011-07-17 17:29:02 -0500342 }
343
344 for (i = 0; i < numDevSections; i++) {
345 int fd = OMAPOpenDRM(i);
346 if (fd != -1) {
Rob Clark83f49e02012-01-08 17:31:59 -0600347
348 if (flags & PROBE_DETECT) {
349 /* just add the device.. we aren't a PCI device, so
350 * call xf86AddBusDeviceToConfigure() directly
351 */
352 xf86AddBusDeviceToConfigure(OMAP_DRIVER_NAME,
353 BUS_NONE, NULL, i);
354 foundScreen = TRUE;
355 continue;
356 }
Rob Clark487687e2011-07-17 17:29:02 -0500357
358 pScrn = xf86AllocateScreen(drv, 0);
Rob Clark83f49e02012-01-08 17:31:59 -0600359
Rob Clark487687e2011-07-17 17:29:02 -0500360 if (!pScrn) {
361 EARLY_ERROR_MSG("Cannot allocate a ScrnInfoPtr");
362 return FALSE;
363 }
Rob Clark83f49e02012-01-08 17:31:59 -0600364
365 if (devSections) {
366 int entity = xf86ClaimNoSlot(drv, 0, devSections[i], TRUE);
367 xf86AddEntityToScreen(pScrn, entity);
368 }
Rob Clark487687e2011-07-17 17:29:02 -0500369
370 foundScreen = TRUE;
371
372 pScrn->driverVersion = OMAP_VERSION;
373 pScrn->driverName = (char *)OMAP_DRIVER_NAME;
374 pScrn->name = (char *)OMAP_NAME;
375 pScrn->Probe = OMAPProbe;
376 pScrn->PreInit = OMAPPreInit;
377 pScrn->ScreenInit = OMAPScreenInit;
378 pScrn->SwitchMode = OMAPSwitchMode;
379 pScrn->AdjustFrame = OMAPAdjustFrame;
380 pScrn->EnterVT = OMAPEnterVT;
381 pScrn->LeaveVT = OMAPLeaveVT;
382 pScrn->FreeScreen = OMAPFreeScreen;
383
384 /* would be nice to be able to keep the connection open.. but
385 * currently we don't allocate the private until PreInit
386 */
387 drmClose(fd);
388 }
389 }
390 free(devSections);
391 return foundScreen;
392}
393
394
395
396/**
397 * The driver's PreInit() function. Additional hardware probing is allowed
398 * now, including display configuration.
399 */
400static Bool
401OMAPPreInit(ScrnInfoPtr pScrn, int flags)
402{
403 OMAPPtr pOMAP;
404 int default_depth, fbbpp;
405 rgb defaultWeight = { 0, 0, 0 };
406 rgb defaultMask = { 0, 0, 0 };
407 Gamma defaultGamma = { 0.0, 0.0, 0.0 };
408 uint64_t value;
409 int i;
410
411 TRACE_ENTER();
412
413 if (flags & PROBE_DETECT) {
414 ERROR_MSG("The %s driver does not support the \"-configure\" or "
415 "\"-probe\" command line arguments.", OMAP_NAME);
416 return FALSE;
417 }
418
419 /* Check the number of entities, and fail if it isn't one. */
420 if (pScrn->numEntities != 1) {
421 ERROR_MSG("Driver expected 1 entity, but found %d for screen %d",
422 pScrn->numEntities, pScrn->scrnIndex);
423 return FALSE;
424 }
425
426 /* Allocate the driver's Screen-specific, "private" data structure: */
427 OMAPGetRec(pScrn);
428 pOMAP = OMAPPTR(pScrn);
429
430 pOMAP->pEntityInfo = xf86GetEntityInfo(pScrn->entityList[0]);
431
432 pScrn->monitor = pScrn->confScreen->monitor;
433
434 /* Get the current depth, and set it for XFree86: */
Dave Barnish2742d152013-03-13 13:36:58 +0000435 default_depth = 24; /* TODO: MIDEGL-1445: get from kernel */
436 fbbpp = 32; /* TODO: MIDEGL-1445: get from kernel */
Rob Clark487687e2011-07-17 17:29:02 -0500437
438 if (!xf86SetDepthBpp(pScrn, default_depth, 0, fbbpp, Support32bppFb)) {
439 /* The above function prints an error message. */
440 goto fail;
441 }
442 xf86PrintDepthBpp(pScrn);
443
444 /* Set the color weight: */
445 if (!xf86SetWeight(pScrn, defaultWeight, defaultMask)) {
446 /* The above function prints an error message. */
447 goto fail;
448 }
449
450 /* Set the gamma: */
451 if (!xf86SetGamma(pScrn, defaultGamma)) {
452 /* The above function prints an error message. */
453 goto fail;
454 }
455
456 /* Visual init: */
457 if (!xf86SetDefaultVisual(pScrn, -1)) {
458 /* The above function prints an error message. */
459 goto fail;
460 }
461
462 /* We don't support 8-bit depths: */
463 if (pScrn->depth < 16) {
464 ERROR_MSG("The requested default visual (%s) has an unsupported "
465 "depth (%d).",
466 xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
467 goto fail;
468 }
469
470 /* Using a programmable clock: */
471 pScrn->progClock = TRUE;
472
473 /* Open a connection to the DRM, so we can communicate with the KMS code: */
474 if (!OMAPOpenDRMMaster(pScrn, 0)) {
475 goto fail;
476 }
477 DEBUG_MSG("Became DRM master.");
478
Ray Smith3c33c3d2013-03-26 16:06:37 +0000479 pOMAP->drmmode = drmmode_interface_get_implementation(pOMAP->drmFD);
480 if (!pOMAP->drmmode)
481 goto fail;
482
Rob Clark487687e2011-07-17 17:29:02 -0500483 /* create DRM device instance: */
Ray Smith3c33c3d2013-03-26 16:06:37 +0000484 pOMAP->dev = omap_device_new(pOMAP->drmFD,
485 pOMAP->drmmode->dumb_scanout_flags,
486 pOMAP->drmmode->dumb_no_scanout_flags);
Rob Clark487687e2011-07-17 17:29:02 -0500487
Rob Clark487687e2011-07-17 17:29:02 -0500488 /* find matching chipset name: */
489 for (i = 0; OMAPChipsets[i].name; i++) {
Dave Barnish01b5c172013-04-10 11:01:17 +0100490 if (OMAPChipsets[i].token == MALI_T6XX_CHIPSET_ID) {
Rob Clark487687e2011-07-17 17:29:02 -0500491 pScrn->chipset = (char *)OMAPChipsets[i].name;
492 break;
493 }
494 }
495
Dave Barnish01b5c172013-04-10 11:01:17 +0100496 INFO_MSG("Chipset: %s", pScrn->chipset);
Rob Clark487687e2011-07-17 17:29:02 -0500497
498 /*
499 * Process the "xorg.conf" file options:
500 */
501 xf86CollectOptions(pScrn, NULL);
502 if (!(pOMAP->pOptionInfo = calloc(1, sizeof(OMAPOptions))))
503 return FALSE;
504 memcpy(pOMAP->pOptionInfo, OMAPOptions, sizeof(OMAPOptions));
505 xf86ProcessOptions(pScrn->scrnIndex, pOMAP->pEntityInfo->device->options,
506 pOMAP->pOptionInfo);
507
508 /* Determine if the user wants debug messages turned on: */
509 omapDebug = xf86ReturnOptValBool(pOMAP->pOptionInfo, OPTION_DEBUG, FALSE);
510
Dave Barnishc50baf52012-11-29 14:39:36 +0000511 /* Determine if user wants to disable buffer flipping: */
512 pOMAP->NoFlip = xf86ReturnOptValBool(pOMAP->pOptionInfo,
513 OPTION_NO_FLIP, FALSE);
514 INFO_MSG("Buffer Flipping is %s", pOMAP->NoFlip ? "Disabled" : "Enabled");
515
Rob Clark487687e2011-07-17 17:29:02 -0500516 /*
517 * Select the video modes:
518 */
519 INFO_MSG("Setting the video modes ...");
520
521 /* Don't call drmCheckModesettingSupported() as its written only for
522 * PCI devices.
523 */
524
525 /* Do initial KMS setup: */
526 if (!drmmode_pre_init(pScrn, pOMAP->drmFD, (pScrn->bitsPerPixel >> 3))) {
527 ERROR_MSG("Cannot get KMS resources");
528 } else {
529 INFO_MSG("Got KMS resources");
530 }
531
532 xf86RandR12PreInit(pScrn);
533
534 /* Let XFree86 calculate or get (from command line) the display DPI: */
535 xf86SetDpi(pScrn, 0, 0);
536
537 /* Ensure we have a supported depth: */
538 switch (pScrn->bitsPerPixel) {
539 case 16:
540 case 24:
541 case 32:
542 break;
543 default:
544 ERROR_MSG("The requested number of bits per pixel (%d) is unsupported.",
545 pScrn->bitsPerPixel);
546 goto fail;
547 }
548
549
550 /* Load external sub-modules now: */
551
552 if (!(xf86LoadSubModule(pScrn, "dri2") &&
553 xf86LoadSubModule(pScrn, "exa") &&
554 xf86LoadSubModule(pScrn, "fb"))) {
555 goto fail;
556 }
557
Rob Clark487687e2011-07-17 17:29:02 -0500558 TRACE_EXIT();
559 return TRUE;
560
561fail:
562 TRACE_EXIT();
563 OMAPFreeRec(pScrn);
564 return FALSE;
565}
566
567
Rob Clarkdc9dfae2012-01-11 18:20:18 -0600568/**
569 * Initialize EXA and DRI2
570 */
571static void
572OMAPAccelInit(ScreenPtr pScreen)
573{
574 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
575 OMAPPtr pOMAP = OMAPPTR(pScrn);
576
Rob Clarkdc9dfae2012-01-11 18:20:18 -0600577 if (!pOMAP->pOMAPEXA) {
Rob Clark0fdd91f2011-10-20 09:56:11 -0500578 pOMAP->pOMAPEXA = InitNullEXA(pScreen, pScrn, pOMAP->drmFD);
Rob Clarkdc9dfae2012-01-11 18:20:18 -0600579 }
580
Dave Barnish01b5c172013-04-10 11:01:17 +0100581 if (pOMAP->pOMAPEXA) {
Rob Clarkdc9dfae2012-01-11 18:20:18 -0600582 pOMAP->dri = OMAPDRI2ScreenInit(pScreen);
583 } else {
584 pOMAP->dri = FALSE;
585 }
586}
Rob Clark487687e2011-07-17 17:29:02 -0500587
588/**
589 * The driver's ScreenInit() function. Fill in pScreen, map the frame buffer,
590 * save state, initialize the mode, etc.
591 */
592static Bool
Cooper Yuana83caa62012-06-28 17:19:06 +0200593OMAPScreenInit(SCREEN_INIT_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -0500594{
595 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
596 OMAPPtr pOMAP = OMAPPTR(pScrn);
597 VisualPtr visual;
598 xf86CrtcConfigPtr xf86_config;
David Garbett82b51832012-07-04 08:29:38 +0100599 int j;
Rob Clark487687e2011-07-17 17:29:02 -0500600
601 TRACE_ENTER();
602
Rob Clark487687e2011-07-17 17:29:02 -0500603 /* Allocate and map memory areas we need */
604 if (!OMAPMapMem(pScrn))
605 return FALSE;
606
607 xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
608
609 /* need to point to new screen on server regeneration */
David Garbett82b51832012-07-04 08:29:38 +0100610 for (j = 0; j < xf86_config->num_crtc; j++)
611 xf86_config->crtc[j]->scrn = pScrn;
612 for (j = 0; j < xf86_config->num_output; j++)
613 xf86_config->output[j]->scrn = pScrn;
Rob Clark487687e2011-07-17 17:29:02 -0500614
615 /*
616 * The next step is to setup the screen's visuals, and initialize the
617 * framebuffer code. In cases where the framebuffer's default
618 * choices for things like visual layouts and bits per RGB are OK,
619 * this may be as simple as calling the framebuffer's ScreenInit()
620 * function. If not, the visuals will need to be setup before calling
621 * a fb ScreenInit() function and fixed up after.
622 *
623 * For most PC hardware at depths >= 8, the defaults that fb uses
624 * are not appropriate. In this driver, we fixup the visuals after.
625 */
626
627 /*
628 * Reset the visual list.
629 */
630
631 miClearVisualTypes();
David Garbettc0bc3fb2012-09-26 14:08:29 +0100632 if (!miSetVisualTypes(pScrn->bitsPerPixel, miGetDefaultVisualMask(pScrn->depth),
Rob Clark487687e2011-07-17 17:29:02 -0500633 pScrn->rgbBits, pScrn->defaultVisual)) {
634 ERROR_MSG("Cannot initialize the visual type for %d bits per pixel!",
635 pScrn->bitsPerPixel);
636 goto fail;
637 }
638
David Garbettef4b7482012-09-26 14:09:01 +0100639 if(pScrn->bitsPerPixel == 32 && pScrn->depth == 24) {
640 /* Also add a 24 bit depth visual */
641 if (!miSetVisualTypes(24, miGetDefaultVisualMask(pScrn->depth),
642 pScrn->rgbBits, pScrn->defaultVisual)) {
643 WARNING_MSG("Cannot initialize a 24 depth visual for 32bpp");
644 }else{
645 INFO_MSG("Initialized a 24 depth visual for 32bpp");
646 }
647 }
648
Rob Clark487687e2011-07-17 17:29:02 -0500649 if (!miSetPixmapDepths()) {
650 ERROR_MSG("Cannot initialize the pixmap depth!");
651 goto fail;
652 }
653
654 /* Initialize some generic 2D drawing functions: */
655 if (!fbScreenInit(pScreen, omap_bo_map(pOMAP->scanout),
656 pScrn->virtualX, pScrn->virtualY,
657 pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
658 pScrn->bitsPerPixel)) {
659 ERROR_MSG("fbScreenInit() failed!");
660 goto fail;
661 }
662
663 /* Fixup RGB ordering: */
664 visual = pScreen->visuals + pScreen->numVisuals;
665 while (--visual >= pScreen->visuals) {
666 if ((visual->class | DynamicClass) == DirectColor) {
667 visual->offsetRed = pScrn->offset.red;
668 visual->offsetGreen = pScrn->offset.green;
669 visual->offsetBlue = pScrn->offset.blue;
670 visual->redMask = pScrn->mask.red;
671 visual->greenMask = pScrn->mask.green;
672 visual->blueMask = pScrn->mask.blue;
David Garbett100928b2012-10-03 14:20:54 +0100673 visual->bitsPerRGBValue = pScrn->rgbBits;
674 visual->ColormapEntries = 1 << pScrn->rgbBits;
Rob Clark487687e2011-07-17 17:29:02 -0500675 }
676 }
677
678 /* Continue initializing the generic 2D drawing functions after fixing the
679 * RGB ordering:
680 */
681 if (!fbPictureInit(pScreen, NULL, 0)) {
682 ERROR_MSG("fbPictureInit() failed!");
683 goto fail;
684 }
685
686 /* Set the initial black & white colormap indices: */
687 xf86SetBlackWhitePixels(pScreen);
688
Rob Clarkdc9dfae2012-01-11 18:20:18 -0600689 /* Initialize external sub-modules for EXA now, this has to be before
690 * miDCInitialize() otherwise stacking order for wrapped ScreenPtr fxns
691 * ends up in the wrong order.
692 */
693 OMAPAccelInit(pScreen);
694
Rob Clark487687e2011-07-17 17:29:02 -0500695 /* Initialize backing store: */
696 miInitializeBackingStore(pScreen);
697 xf86SetBackingStore(pScreen);
698
Rob Clark687c6082012-01-08 19:33:18 -0600699 /* Cause the cursor position to be updated by the mouse signal handler: */
700 xf86SetSilkenMouse(pScreen);
701
Rob Clark487687e2011-07-17 17:29:02 -0500702 /* Initialize the cursor: */
703 miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
704
Dave Barnish01b5c172013-04-10 11:01:17 +0100705 if (!drmmode_cursor_init(pScreen)) {
706 ERROR_MSG("Hardware cursor initialization failed");
Rob Clark687c6082012-01-08 19:33:18 -0600707 }
Rob Clark487687e2011-07-17 17:29:02 -0500708
709 /* 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 */
Mandeep Singh Bainese8a70992012-10-03 10:31:48 -0700717 if (!OMAPEnterVT(VT_FUNC_ARGS(0))) {
718 ERROR_MSG("OMAPEnterVT() failed!");
Rob Clark487687e2011-07-17 17:29:02 -0500719 goto fail;
720 }
721
722 /* Do some XRandR initialization: */
723 if (!xf86CrtcScreenInit(pScreen)) {
724 ERROR_MSG("xf86CrtcScreenInit() failed!");
725 goto fail;
726 }
727
728 if (!miCreateDefColormap(pScreen)) {
729 ERROR_MSG("Cannot create colormap!");
730 goto fail;
731 }
732
David Garbett100928b2012-10-03 14:20:54 +0100733 if (!xf86HandleColormaps(pScreen, 1 << pScrn->rgbBits, pScrn->rgbBits,
734 OMAPLoadPalette, NULL, CMAP_PALETTED_TRUECOLOR)) {
Rob Clark487687e2011-07-17 17:29:02 -0500735 ERROR_MSG("xf86HandleColormaps() failed!");
736 goto fail;
737 }
738
739 /* Setup power management: */
740 xf86DPMSInit(pScreen, xf86DPMSSet, 0);
741
742 pScreen->SaveScreen = xf86SaveScreen;
743
744 /* Wrap some screen functions: */
745 wrap(pOMAP, pScreen, CloseScreen, OMAPCloseScreen);
746 wrap(pOMAP, pScreen, CreateScreenResources, OMAPCreateScreenResources);
747 wrap(pOMAP, pScreen, BlockHandler, OMAPBlockHandler);
748
Rob Clark4b8f30a2011-08-28 12:51:26 -0500749 drmmode_screen_init(pScrn);
Rob Clark487687e2011-07-17 17:29:02 -0500750
751 TRACE_EXIT();
752 return TRUE;
753
754fail:
755 TRACE_EXIT();
756 return FALSE;
757}
758
759
760static void
761OMAPLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
762 LOCO * colors, VisualPtr pVisual)
763{
764 TRACE_ENTER();
765 TRACE_EXIT();
766}
767
768
769/**
770 * The driver's CloseScreen() function. This is called at the end of each
771 * server generation. Restore state, unmap the frame buffer (and any other
772 * mapped memory regions), and free per-Screen data structures (except those
773 * held by pScrn).
774 */
775static Bool
Cooper Yuana83caa62012-06-28 17:19:06 +0200776OMAPCloseScreen(CLOSE_SCREEN_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -0500777{
Cooper Yuana83caa62012-06-28 17:19:06 +0200778 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
Rob Clark487687e2011-07-17 17:29:02 -0500779 OMAPPtr pOMAP = OMAPPTR(pScrn);
780
781 TRACE_ENTER();
782
Rob Clark4b8f30a2011-08-28 12:51:26 -0500783 drmmode_screen_fini(pScrn);
Rob Clark487687e2011-07-17 17:29:02 -0500784
785 if (pScrn->vtSema == TRUE) {
Cooper Yuana83caa62012-06-28 17:19:06 +0200786 OMAPLeaveVT(VT_FUNC_ARGS(0));
Rob Clark487687e2011-07-17 17:29:02 -0500787 }
788
789 if (pOMAP->pOMAPEXA) {
790 if (pOMAP->pOMAPEXA->CloseScreen) {
Cooper Yuana83caa62012-06-28 17:19:06 +0200791 pOMAP->pOMAPEXA->CloseScreen(CLOSE_SCREEN_ARGS);
Rob Clark487687e2011-07-17 17:29:02 -0500792 }
793 }
794
Rob Clark4b8f30a2011-08-28 12:51:26 -0500795 if (pOMAP->dri) {
796 OMAPDRI2CloseScreen(pScreen);
797 }
Rob Clark4b8f30a2011-08-28 12:51:26 -0500798
Rob Clark487687e2011-07-17 17:29:02 -0500799 OMAPUnmapMem(pScrn);
800
801 pScrn->vtSema = FALSE;
802
803 unwrap(pOMAP, pScreen, CloseScreen);
804 unwrap(pOMAP, pScreen, BlockHandler);
805 unwrap(pOMAP, pScreen, CreateScreenResources);
806
807 TRACE_EXIT();
808
Cooper Yuana83caa62012-06-28 17:19:06 +0200809 return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS);
Rob Clark487687e2011-07-17 17:29:02 -0500810}
811
812
813
814/**
815 * Adjust the screen pixmap for the current location of the front buffer.
816 * This is done at EnterVT when buffers are bound as long as the resources
817 * have already been created, but the first EnterVT happens before
818 * CreateScreenResources.
819 */
820static Bool
821OMAPCreateScreenResources(ScreenPtr pScreen)
822{
823 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
824 OMAPPtr pOMAP = OMAPPTR(pScrn);
825
826 swap(pOMAP, pScreen, CreateScreenResources);
827 if (!(*pScreen->CreateScreenResources) (pScreen))
828 return FALSE;
829 swap(pOMAP, pScreen, CreateScreenResources);
830
831 return TRUE;
832}
833
834
835static void
Cooper Yuana83caa62012-06-28 17:19:06 +0200836OMAPBlockHandler(BLOCKHANDLER_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -0500837{
Cooper Yuana83caa62012-06-28 17:19:06 +0200838 SCREEN_PTR(arg);
839 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
Rob Clark487687e2011-07-17 17:29:02 -0500840 OMAPPtr pOMAP = OMAPPTR(pScrn);
841
842 swap(pOMAP, pScreen, BlockHandler);
Cooper Yuana83caa62012-06-28 17:19:06 +0200843 (*pScreen->BlockHandler) (BLOCKHANDLER_ARGS);
Rob Clark487687e2011-07-17 17:29:02 -0500844 swap(pOMAP, pScreen, BlockHandler);
Rob Clark487687e2011-07-17 17:29:02 -0500845}
846
847
848
849/**
850 * The driver's SwitchMode() function. Initialize the new mode for the
851 * Screen.
852 */
853static Bool
Cooper Yuana83caa62012-06-28 17:19:06 +0200854OMAPSwitchMode(SWITCH_MODE_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -0500855{
Cooper Yuana83caa62012-06-28 17:19:06 +0200856 SCRN_INFO_PTR(arg);
Rob Clark487687e2011-07-17 17:29:02 -0500857 return xf86SetSingleMode(pScrn, mode, RR_Rotate_0);
858}
859
860
861
862/**
863 * The driver's AdjustFrame() function. For cases where the frame buffer is
864 * larger than the monitor resolution, this function can pan around the frame
865 * buffer within the "viewport" of the monitor.
866 */
867static void
Cooper Yuana83caa62012-06-28 17:19:06 +0200868OMAPAdjustFrame(ADJUST_FRAME_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -0500869{
Cooper Yuana83caa62012-06-28 17:19:06 +0200870 SCRN_INFO_PTR(arg);
871 drmmode_adjust_frame(pScrn, x, y);
Rob Clark487687e2011-07-17 17:29:02 -0500872}
873
874
875
876/**
877 * The driver's EnterVT() function. This is called at server startup time, and
878 * when the X server takes over the virtual terminal from the console. As
879 * such, it may need to save the current (i.e. console) HW state, and set the
880 * HW state as needed by the X server.
881 */
882static Bool
Cooper Yuana83caa62012-06-28 17:19:06 +0200883OMAPEnterVT(VT_FUNC_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -0500884{
Cooper Yuana83caa62012-06-28 17:19:06 +0200885 SCRN_INFO_PTR(arg);
Rob Clark487687e2011-07-17 17:29:02 -0500886 OMAPPtr pOMAP = OMAPPTR(pScrn);
Ray Smith6ae735f2013-03-21 15:57:18 +0000887 int i, ret;
abhinav.kd4bab322012-07-31 11:29:19 -0700888
Rob Clark487687e2011-07-17 17:29:02 -0500889 TRACE_ENTER();
890
Ray Smith6ae735f2013-03-21 15:57:18 +0000891 for (i = 1; i < currentMaxClients; i++) {
892 if (clients[i])
893 AttendClient(clients[i]);
894 }
895
Rob Clark487687e2011-07-17 17:29:02 -0500896 ret = drmSetMaster(pOMAP->drmFD);
897 if (ret) {
Daniel Kurtz92205962013-02-05 13:50:12 +0800898 ERROR_MSG("Cannot get DRM master: %s", strerror(errno));
Daniel Kurtz01a91f62013-02-05 10:19:51 +0800899 return FALSE;
Rob Clark487687e2011-07-17 17:29:02 -0500900 }
901
902 if (!xf86SetDesiredModes(pScrn)) {
903 ERROR_MSG("xf86SetDesiredModes() failed!");
904 return FALSE;
905 }
906
907 TRACE_EXIT();
908 return TRUE;
909}
910
911
912
913/**
914 * The driver's LeaveVT() function. This is called when the X server
915 * temporarily gives up the virtual terminal to the console. As such, it may
916 * need to restore the console's HW state.
917 */
918static void
Cooper Yuana83caa62012-06-28 17:19:06 +0200919OMAPLeaveVT(VT_FUNC_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -0500920{
Cooper Yuana83caa62012-06-28 17:19:06 +0200921 SCRN_INFO_PTR(arg);
Rob Clark487687e2011-07-17 17:29:02 -0500922 OMAPPtr pOMAP = OMAPPTR(pScrn);
Ray Smith6ae735f2013-03-21 15:57:18 +0000923 int i, ret;
abhinav.kd4bab322012-07-31 11:29:19 -0700924
Rob Clark487687e2011-07-17 17:29:02 -0500925 TRACE_ENTER();
926
Ray Smith6ae735f2013-03-21 15:57:18 +0000927 for (i = 1; i < currentMaxClients; i++) {
928 if (clients[i])
929 IgnoreClient(clients[i]);
930 }
931
Rob Clark487687e2011-07-17 17:29:02 -0500932 ret = drmDropMaster(pOMAP->drmFD);
933 if (ret) {
Daniel Kurtz92205962013-02-05 13:50:12 +0800934 WARNING_MSG("drmDropMaster failed: %s", strerror(errno));
Rob Clark487687e2011-07-17 17:29:02 -0500935 }
936
937 TRACE_EXIT();
938}
939
940
941
942/**
943 * The driver's FreeScreen() function. This is called at the server's end of
944 * life. This should free any driver-allocated data that was allocated
945 * up-to-and-including an unsuccessful ScreenInit() call.
946 */
947static void
Cooper Yuana83caa62012-06-28 17:19:06 +0200948OMAPFreeScreen(FREE_SCREEN_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -0500949{
Cooper Yuana83caa62012-06-28 17:19:06 +0200950 SCRN_INFO_PTR(arg);
Rob Clark487687e2011-07-17 17:29:02 -0500951 OMAPPtr pOMAP = OMAPPTR(pScrn);
952
953 TRACE_ENTER();
954
955 if (!pOMAP) {
956 /* This can happen if a Screen is deleted after Probe(): */
957 return;
958 }
959
960 if (pOMAP->pOMAPEXA) {
961 if (pOMAP->pOMAPEXA->FreeScreen) {
Cooper Yuana83caa62012-06-28 17:19:06 +0200962 pOMAP->pOMAPEXA->FreeScreen(FREE_SCREEN_ARGS(pScrn));
Rob Clark487687e2011-07-17 17:29:02 -0500963 }
964 free(pOMAP->pOMAPEXA);
965 }
966
967 omap_device_del(pOMAP->dev);
968
969 OMAPCloseDRMMaster(pScrn);
970
971 OMAPFreeRec(pScrn);
972
973 TRACE_EXIT();
974}
975