| /* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ |
| |
| /* |
| * Copyright © 2011 Texas Instruments, Inc |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a |
| * copy of this software and associated documentation files (the "Software"), |
| * to deal in the Software without restriction, including without limitation |
| * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| * and/or sell copies of the Software, and to permit persons to whom the |
| * Software is furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice (including the next |
| * paragraph) shall be included in all copies or substantial portions of the |
| * Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| * SOFTWARE. |
| * |
| * Authors: |
| * Ian Elliott <ianelliottus@yahoo.com> |
| * Rob Clark <rob@ti.com> |
| */ |
| |
| #include <sys/types.h> |
| #include <sys/stat.h> |
| #include <fcntl.h> |
| #include <unistd.h> |
| |
| #ifdef HAVE_CONFIG_H |
| #include "config.h" |
| #endif |
| |
| #include "omap_driver.h" |
| #include "compat-api.h" |
| |
| Bool omapDebug = 0; |
| |
| /* |
| * Forward declarations: |
| */ |
| static const OptionInfoRec *OMAPAvailableOptions(int chipid, int busid); |
| static void OMAPIdentify(int flags); |
| static Bool OMAPProbe(DriverPtr drv, int flags); |
| static Bool OMAPPreInit(ScrnInfoPtr pScrn, int flags); |
| static Bool OMAPScreenInit(SCREEN_INIT_ARGS_DECL); |
| static void OMAPLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, |
| LOCO * colors, VisualPtr pVisual); |
| static Bool OMAPCloseScreen(CLOSE_SCREEN_ARGS_DECL); |
| static Bool OMAPSwitchMode(SWITCH_MODE_ARGS_DECL); |
| static void OMAPAdjustFrame(ADJUST_FRAME_ARGS_DECL); |
| static Bool OMAPEnterVT(VT_FUNC_ARGS_DECL); |
| static void OMAPLeaveVT(VT_FUNC_ARGS_DECL); |
| static void OMAPFreeScreen(FREE_SCREEN_ARGS_DECL); |
| |
| |
| |
| /** |
| * A structure used by the XFree86 code when loading this driver, so that it |
| * can access the Probe() function, and other functions/info that it uses |
| * before it calls the Probe() function. The name of this structure must be |
| * the all-upper-case version of the driver name. |
| */ |
| _X_EXPORT DriverRec OMAP = { |
| OMAP_VERSION, |
| (char *)OMAP_DRIVER_NAME, |
| OMAPIdentify, |
| OMAPProbe, |
| OMAPAvailableOptions, |
| NULL, |
| 0, |
| NULL, |
| #ifdef XSERVER_LIBPCIACCESS |
| NULL, |
| NULL |
| #endif |
| }; |
| |
| /** Supported "chipsets." */ |
| static SymTabRec OMAPChipsets[] = { |
| { OMAP_CHIPSET_EXYNOS5, "exynos5" }, |
| {-1, NULL } |
| }; |
| |
| /** Supported options, as enum values. */ |
| typedef enum { |
| OPTION_DEBUG, |
| } OMAPOpts; |
| |
| /** Supported options. */ |
| static const OptionInfoRec OMAPOptions[] = { |
| { OPTION_DEBUG, "Debug", OPTV_BOOLEAN, {0}, FALSE }, |
| { -1, NULL, OPTV_NONE, {0}, FALSE } |
| }; |
| |
| /** |
| * Helper function for opening a connection to the DRM. |
| */ |
| |
| static int |
| OMAPOpenDRM(int n) |
| { |
| return open("/dev/dri/card0", O_RDWR, 0); |
| } |
| |
| static Bool |
| OMAPOpenDRMMaster(ScrnInfoPtr pScrn, int n) |
| { |
| OMAPPtr pOMAP = OMAPPTR(pScrn); |
| drmSetVersion sv; |
| int err; |
| |
| pOMAP->drmFD = OMAPOpenDRM(n); |
| if (pOMAP->drmFD == -1) { |
| ERROR_MSG("Cannot open a connection with the DRM."); |
| return FALSE; |
| } |
| |
| /* Check that what we opened was a master or a master-capable FD, |
| * by setting the version of the interface we'll use to talk to it. |
| * (see DRIOpenDRMMaster() in DRI1) |
| */ |
| sv.drm_di_major = 1; |
| sv.drm_di_minor = 1; |
| sv.drm_dd_major = -1; |
| sv.drm_dd_minor = -1; |
| err = drmSetInterfaceVersion(pOMAP->drmFD, &sv); |
| if (err != 0) { |
| ERROR_MSG("Cannot set the DRM interface version."); |
| drmClose(pOMAP->drmFD); |
| pOMAP->drmFD = -1; |
| return FALSE; |
| } |
| |
| pOMAP->deviceName = drmGetDeviceNameFromFd(pOMAP->drmFD); |
| |
| return TRUE; |
| } |
| |
| |
| |
| /** |
| * Helper function for closing a connection to the DRM. |
| */ |
| static void |
| OMAPCloseDRMMaster(ScrnInfoPtr pScrn) |
| { |
| OMAPPtr pOMAP = OMAPPTR(pScrn); |
| |
| if (pOMAP && (pOMAP->drmFD > 0)) { |
| drmFree(pOMAP->deviceName); |
| drmClose(pOMAP->drmFD); |
| pOMAP->drmFD = -1; |
| } |
| } |
| |
| static Bool |
| OMAPMapMem(ScrnInfoPtr pScrn) |
| { |
| OMAPPtr pOMAP = OMAPPTR(pScrn); |
| |
| DEBUG_MSG("allocating new scanout buffer: %dx%d", |
| pScrn->virtualX, pScrn->virtualY); |
| |
| pOMAP->scanout = omap_bo_new_with_depth(pOMAP->dev, pScrn->virtualX, |
| pScrn->virtualY, pScrn->depth, pScrn->bitsPerPixel); |
| if (!pOMAP->scanout) { |
| xf86DrvMsg(pScrn->scrnIndex, X_ERROR, |
| "Error allocating scanout buffer\n"); |
| return FALSE; |
| } |
| |
| pScrn->displayWidth = omap_bo_pitch(pOMAP->scanout) / (pScrn->bitsPerPixel / 8); |
| |
| return TRUE; |
| } |
| |
| |
| static Bool |
| OMAPUnmapMem(ScrnInfoPtr pScrn) |
| { |
| OMAPPtr pOMAP = OMAPPTR(pScrn); |
| omap_bo_unreference(pOMAP->scanout); |
| pOMAP->scanout = NULL; |
| pScrn->displayWidth = 0; |
| return TRUE; |
| } |
| |
| |
| |
| /** Let the XFree86 code know the Setup() function. */ |
| static MODULESETUPPROTO(OMAPSetup); |
| |
| /** Provide basic version information to the XFree86 code. */ |
| static XF86ModuleVersionInfo OMAPVersRec = |
| { |
| OMAP_DRIVER_NAME, |
| MODULEVENDORSTRING, |
| MODINFOSTRING1, |
| MODINFOSTRING2, |
| XORG_VERSION_CURRENT, |
| PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL, |
| ABI_CLASS_VIDEODRV, |
| ABI_VIDEODRV_VERSION, |
| MOD_CLASS_VIDEODRV, |
| {0, 0, 0, 0} |
| }; |
| |
| /** Let the XFree86 code know about the VersRec and Setup() function. */ |
| _X_EXPORT XF86ModuleData armsocModuleData = { &OMAPVersRec, OMAPSetup, NULL }; |
| |
| |
| /** |
| * The first function that the XFree86 code calls, after loading this module. |
| */ |
| static pointer |
| OMAPSetup(pointer module, pointer opts, int *errmaj, int *errmin) |
| { |
| static Bool setupDone = FALSE; |
| |
| /* This module should be loaded only once, but check to be sure: */ |
| if (!setupDone) { |
| setupDone = TRUE; |
| xf86AddDriver(&OMAP, module, 0); |
| |
| /* The return value must be non-NULL on success even though there is no |
| * TearDownProc. |
| */ |
| return (pointer) 1; |
| } else { |
| if (errmaj) |
| *errmaj = LDR_ONCEONLY; |
| return NULL; |
| } |
| } |
| |
| |
| /** |
| * Allocate the driver's Screen-specific, "private" data structure and hook it |
| * into the ScrnInfoRec's driverPrivate field. |
| */ |
| static Bool |
| OMAPGetRec(ScrnInfoPtr pScrn) |
| { |
| OMAPPtr pOMAP = pScrn->driverPrivate; |
| |
| if (pOMAP != NULL) |
| return TRUE; |
| |
| pOMAP = calloc(1, sizeof *pOMAP); |
| if (pOMAP == NULL) |
| return FALSE; |
| |
| pScrn->driverPrivate = pOMAP; |
| |
| return TRUE; |
| } |
| |
| |
| /** |
| * Free the driver's Screen-specific, "private" data structure and NULL-out the |
| * ScrnInfoRec's driverPrivate field. |
| */ |
| static void |
| OMAPFreeRec(ScrnInfoPtr pScrn) |
| { |
| if (pScrn->driverPrivate == NULL) |
| return; |
| free(pScrn->driverPrivate); |
| pScrn->driverPrivate = NULL; |
| } |
| |
| |
| /** |
| * The mandatory AvailableOptions() function. It returns the available driver |
| * options to the "-configure" option, so that an xorg.conf file can be built |
| * and the user can see which options are available for them to use. |
| */ |
| static const OptionInfoRec * |
| OMAPAvailableOptions(int chipid, int busid) |
| { |
| return OMAPOptions; |
| } |
| |
| |
| |
| /** |
| * The mandatory Identify() function. It is run before Probe(), and prints out |
| * an identifying message, which includes the chipset(s) the driver supports. |
| */ |
| static void |
| OMAPIdentify(int flags) |
| { |
| xf86PrintChipsets(OMAP_NAME, "Driver for TI OMAP", OMAPChipsets); |
| } |
| |
| |
| |
| /** |
| * The driver's Probe() function. This function finds all instances of the |
| * TI OMAP hardware that the driver supports (from within the "xorg.conf" |
| * device sections), and for instances not already claimed by another driver, |
| * claim the instances, and allocate a ScrnInfoRec. Only minimal hardware |
| * probing is allowed here. |
| */ |
| static Bool |
| OMAPProbe(DriverPtr drv, int flags) |
| { |
| int i; |
| ScrnInfoPtr pScrn; |
| GDevPtr *devSections = NULL; |
| int numDevSections; |
| Bool foundScreen = FALSE; |
| |
| /* Get the "xorg.conf" file device sections that match this driver, and |
| * return (error out) if there are none: |
| */ |
| numDevSections = xf86MatchDevice(OMAP_DRIVER_NAME, &devSections); |
| if (numDevSections <= 0) { |
| EARLY_ERROR_MSG("Did not find any matching device section in " |
| "configuration file"); |
| if (flags & PROBE_DETECT) { |
| /* if we are probing, assume one and lets see if we can |
| * open the device to confirm it is there: |
| */ |
| numDevSections = 1; |
| } else { |
| goto out; |
| } |
| } |
| |
| for (i = 0; i < numDevSections; i++) { |
| int fd = OMAPOpenDRM(i); |
| if (fd != -1) { |
| |
| if (flags & PROBE_DETECT) { |
| /* just add the device.. we aren't a PCI device, so |
| * call xf86AddBusDeviceToConfigure() directly |
| */ |
| xf86AddBusDeviceToConfigure(OMAP_DRIVER_NAME, |
| BUS_NONE, NULL, i); |
| foundScreen = TRUE; |
| drmClose(fd); |
| continue; |
| } |
| |
| pScrn = xf86AllocateScreen(drv, 0); |
| |
| if (!pScrn) { |
| EARLY_ERROR_MSG("Cannot allocate a ScrnInfoPtr"); |
| drmClose(fd); |
| goto free_sections; |
| } |
| |
| if (devSections) { |
| int entity = xf86ClaimNoSlot(drv, 0, devSections[i], TRUE); |
| xf86AddEntityToScreen(pScrn, entity); |
| } |
| |
| foundScreen = TRUE; |
| |
| pScrn->driverVersion = OMAP_VERSION; |
| pScrn->driverName = (char *)OMAP_DRIVER_NAME; |
| pScrn->name = (char *)OMAP_NAME; |
| pScrn->Probe = OMAPProbe; |
| pScrn->PreInit = OMAPPreInit; |
| pScrn->ScreenInit = OMAPScreenInit; |
| pScrn->SwitchMode = OMAPSwitchMode; |
| pScrn->AdjustFrame = OMAPAdjustFrame; |
| pScrn->EnterVT = OMAPEnterVT; |
| pScrn->LeaveVT = OMAPLeaveVT; |
| pScrn->FreeScreen = OMAPFreeScreen; |
| |
| /* would be nice to be able to keep the connection open.. but |
| * currently we don't allocate the private until PreInit |
| */ |
| drmClose(fd); |
| } |
| } |
| |
| free_sections: |
| free(devSections); |
| |
| out: |
| return foundScreen; |
| } |
| |
| |
| |
| /** |
| * The driver's PreInit() function. Additional hardware probing is allowed |
| * now, including display configuration. |
| */ |
| static Bool |
| OMAPPreInit(ScrnInfoPtr pScrn, int flags) |
| { |
| OMAPPtr pOMAP; |
| int default_depth, fbbpp; |
| rgb defaultWeight = { 0, 0, 0 }; |
| rgb defaultMask = { 0, 0, 0 }; |
| Gamma defaultGamma = { 0.0, 0.0, 0.0 }; |
| |
| TRACE_ENTER(); |
| |
| if (flags & PROBE_DETECT) { |
| ERROR_MSG("The %s driver does not support the \"-configure\" or " |
| "\"-probe\" command line arguments.", OMAP_NAME); |
| return FALSE; |
| } |
| |
| /* Check the number of entities, and fail if it isn't one. */ |
| if (pScrn->numEntities != 1) { |
| ERROR_MSG("Driver expected 1 entity, but found %d for screen %d", |
| pScrn->numEntities, pScrn->scrnIndex); |
| return FALSE; |
| } |
| |
| /* Allocate the driver's Screen-specific, "private" data structure: */ |
| OMAPGetRec(pScrn); |
| pOMAP = OMAPPTR(pScrn); |
| |
| pOMAP->pEntityInfo = xf86GetEntityInfo(pScrn->entityList[0]); |
| |
| pScrn->monitor = pScrn->confScreen->monitor; |
| |
| /* Get the current depth, and set it for XFree86: */ |
| default_depth = 24; /* TODO: get from kernel */ |
| fbbpp = 32; /* TODO: get from kernel */ |
| |
| if (!xf86SetDepthBpp(pScrn, default_depth, 0, fbbpp, Support32bppFb)) { |
| /* The above function prints an error message. */ |
| goto fail; |
| } |
| xf86PrintDepthBpp(pScrn); |
| |
| /* Set the color weight: */ |
| if (!xf86SetWeight(pScrn, defaultWeight, defaultMask)) { |
| /* The above function prints an error message. */ |
| goto fail; |
| } |
| |
| /* Set the gamma: */ |
| if (!xf86SetGamma(pScrn, defaultGamma)) { |
| /* The above function prints an error message. */ |
| goto fail; |
| } |
| |
| /* Visual init: */ |
| if (!xf86SetDefaultVisual(pScrn, -1)) { |
| /* The above function prints an error message. */ |
| goto fail; |
| } |
| |
| /* We don't support 8-bit depths: */ |
| if (pScrn->depth < 16) { |
| ERROR_MSG("The requested default visual (%s) has an unsupported " |
| "depth (%d).", |
| xf86GetVisualName(pScrn->defaultVisual), pScrn->depth); |
| goto fail; |
| } |
| |
| /* Using a programmable clock: */ |
| pScrn->progClock = TRUE; |
| |
| /* Open a connection to the DRM, so we can communicate with the KMS code: */ |
| if (!OMAPOpenDRMMaster(pScrn, 0)) { |
| goto fail; |
| } |
| DEBUG_MSG("Became DRM master."); |
| |
| /* create DRM device instance: */ |
| pOMAP->dev = omap_device_new(pOMAP->drmFD, pScrn); |
| |
| pScrn->chipset = (char *)xf86TokenToString(OMAPChipsets, |
| OMAP_CHIPSET_EXYNOS5); |
| |
| INFO_MSG("Chipset: %s", pScrn->chipset); |
| |
| /* |
| * Process the "xorg.conf" file options: |
| */ |
| xf86CollectOptions(pScrn, NULL); |
| if (!(pOMAP->pOptionInfo = malloc(sizeof(OMAPOptions)))) |
| return FALSE; |
| memcpy(pOMAP->pOptionInfo, OMAPOptions, sizeof(OMAPOptions)); |
| xf86ProcessOptions(pScrn->scrnIndex, pOMAP->pEntityInfo->device->options, |
| pOMAP->pOptionInfo); |
| |
| /* Determine if the user wants debug messages turned on: */ |
| omapDebug = xf86ReturnOptValBool(pOMAP->pOptionInfo, OPTION_DEBUG, FALSE); |
| |
| /* |
| * Select the video modes: |
| */ |
| INFO_MSG("Setting the video modes ..."); |
| |
| /* Don't call drmCheckModesettingSupported() as its written only for |
| * PCI devices. |
| */ |
| |
| /* Do initial KMS setup: */ |
| if (!drmmode_pre_init(pScrn, pOMAP->drmFD)) { |
| ERROR_MSG("Cannot get KMS resources"); |
| } else { |
| INFO_MSG("Got KMS resources"); |
| } |
| |
| xf86RandR12PreInit(pScrn); |
| |
| /* Let XFree86 calculate or get (from command line) the display DPI: */ |
| xf86SetDpi(pScrn, 0, 0); |
| |
| /* Ensure we have a supported depth: */ |
| switch (pScrn->bitsPerPixel) { |
| case 16: |
| case 24: |
| case 32: |
| break; |
| default: |
| ERROR_MSG("The requested number of bits per pixel (%d) is unsupported.", |
| pScrn->bitsPerPixel); |
| goto fail; |
| } |
| |
| |
| /* Load external sub-modules now: */ |
| |
| if (!(xf86LoadSubModule(pScrn, "dri2") && |
| xf86LoadSubModule(pScrn, "exa") && |
| xf86LoadSubModule(pScrn, "fb"))) { |
| goto fail; |
| } |
| |
| |
| TRACE_EXIT(); |
| return TRUE; |
| |
| fail: |
| TRACE_EXIT(); |
| return FALSE; |
| } |
| |
| |
| /** |
| * The driver's ScreenInit() function. Fill in pScreen, map the frame buffer, |
| * save state, initialize the mode, etc. |
| */ |
| static Bool |
| OMAPScreenInit(SCREEN_INIT_ARGS_DECL) |
| { |
| ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); |
| OMAPPtr pOMAP = OMAPPTR(pScrn); |
| VisualPtr visual; |
| xf86CrtcConfigPtr xf86_config; |
| int i; |
| |
| TRACE_ENTER(); |
| |
| /* Allocate a bo for the root window pixmap */ |
| if (!OMAPMapMem(pScrn)) |
| return FALSE; |
| |
| /* For a smooth transition from console to X, copy the current fbcon |
| * contents to the root window. |
| */ |
| drmmode_copy_fb(pScrn); |
| |
| /* The root window pixmap bo (pOMAP->scanout) has valid contents now, |
| * so we start out claiming we're in blit mode. |
| * The root window is displayed when we do: |
| * OMAPEnterVT() -> |
| * xf86SetDesiredModes() -> |
| * drmmode_set_mode_major() -> |
| * drmmode_set_crtc() -> |
| * drmModeSetCrtc() |
| */ |
| pOMAP->flip_mode = OMAP_FLIP_DISABLED; |
| |
| xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); |
| |
| /* need to point to new screen on server regeneration */ |
| for (i = 0; i < xf86_config->num_crtc; i++) |
| xf86_config->crtc[i]->scrn = pScrn; |
| for (i = 0; i < xf86_config->num_output; i++) |
| xf86_config->output[i]->scrn = pScrn; |
| |
| /* |
| * The next step is to setup the screen's visuals, and initialize the |
| * framebuffer code. In cases where the framebuffer's default |
| * choices for things like visual layouts and bits per RGB are OK, |
| * this may be as simple as calling the framebuffer's ScreenInit() |
| * function. If not, the visuals will need to be setup before calling |
| * a fb ScreenInit() function and fixed up after. |
| * |
| * For most PC hardware at depths >= 8, the defaults that fb uses |
| * are not appropriate. In this driver, we fixup the visuals after. |
| */ |
| |
| /* |
| * Reset the visual list. |
| */ |
| |
| miClearVisualTypes(); |
| if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth), |
| pScrn->rgbBits, pScrn->defaultVisual)) { |
| ERROR_MSG("Cannot initialize the visual type for %d bits per pixel!", |
| pScrn->bitsPerPixel); |
| goto fail; |
| } |
| |
| /* Also add a 32-bit depth XRGB8888 visual */ |
| if (!miSetVisualTypes(32, miGetDefaultVisualMask(pScrn->depth), |
| pScrn->rgbBits, pScrn->defaultVisual)) { |
| WARNING_MSG("Cannot initialize a depth-32 visual"); |
| } else { |
| INFO_MSG("Initialized a depth-32 visual for XRGB8888"); |
| } |
| |
| if (!miSetPixmapDepths()) { |
| ERROR_MSG("Cannot initialize the pixmap depth!"); |
| goto fail; |
| } |
| |
| /* Initialize some generic 2D drawing functions: */ |
| if (!fbScreenInit(pScreen, omap_bo_map(pOMAP->scanout), |
| pScrn->virtualX, pScrn->virtualY, |
| pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth, |
| pScrn->bitsPerPixel)) { |
| ERROR_MSG("fbScreenInit() failed!"); |
| goto fail; |
| } |
| |
| /* Fixup RGB ordering: */ |
| visual = pScreen->visuals + pScreen->numVisuals; |
| while (--visual >= pScreen->visuals) { |
| if ((visual->class | DynamicClass) == DirectColor) { |
| unsigned widest_component; |
| unsigned red_width, green_width, blue_width; |
| |
| visual->offsetRed = pScrn->offset.red; |
| visual->offsetGreen = pScrn->offset.green; |
| visual->offsetBlue = pScrn->offset.blue; |
| visual->redMask = pScrn->mask.red; |
| visual->greenMask = pScrn->mask.green; |
| visual->blueMask = pScrn->mask.blue; |
| /* |
| * crbug.com/340790: Override default nplanes and |
| * ColormapEntries computed by mi for our depth 32 |
| * xRGB888 visual. |
| */ |
| visual->nplanes = Ones(visual->redMask | |
| visual->greenMask | visual->blueMask); |
| |
| /* find widest component */ |
| red_width = Ones(visual->redMask); |
| green_width = Ones(visual->greenMask); |
| blue_width = Ones(visual->blueMask); |
| widest_component = max(red_width, |
| max(green_width, blue_width)); |
| visual->ColormapEntries = 1 << widest_component; |
| } |
| } |
| |
| /* Continue initializing the generic 2D drawing functions after fixing the |
| * RGB ordering: |
| */ |
| if (!fbPictureInit(pScreen, NULL, 0)) { |
| ERROR_MSG("fbPictureInit() failed!"); |
| goto fail; |
| } |
| |
| /* Set the initial black & white colormap indices: */ |
| xf86SetBlackWhitePixels(pScreen); |
| |
| /* Initialize external sub-modules for EXA now, this has to be before |
| * miDCInitialize() otherwise stacking order for wrapped ScreenPtr fxns |
| * ends up in the wrong order. |
| */ |
| pOMAP->pOMAPEXA = InitNullEXA(pScreen, pScrn, pOMAP->drmFD); |
| if (!pOMAP->pOMAPEXA) { |
| ERROR_MSG("InitNullEXA() failed!"); |
| goto fail; |
| } |
| |
| if (!OMAPDRI2ScreenInit(pScreen)) { |
| ERROR_MSG("OMAPDRI2ScreenInit() failed!"); |
| goto fail; |
| } |
| |
| /* Initialize backing store: */ |
| miInitializeBackingStore(pScreen); |
| xf86SetBackingStore(pScreen); |
| |
| /* Cause the cursor position to be updated by the mouse signal handler: */ |
| xf86SetSilkenMouse(pScreen); |
| |
| /* Initialize the cursor: */ |
| miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); |
| |
| /* XXX -- Is this the right place for this? The Intel i830 driver says: |
| * "Must force it before EnterVT, so we are in control of VT..." |
| */ |
| pScrn->vtSema = TRUE; |
| |
| /* Take over the virtual terminal from the console, set the desired mode, |
| * etc.: |
| */ |
| if (!OMAPEnterVT(VT_FUNC_ARGS(0))) { |
| ERROR_MSG("OMAPEnterVT() failed!"); |
| goto fail; |
| } |
| |
| /* Do some XRandR initialization: */ |
| if (!xf86CrtcScreenInit(pScreen)) { |
| ERROR_MSG("xf86CrtcScreenInit() failed!"); |
| goto fail; |
| } |
| |
| if (!miCreateDefColormap(pScreen)) { |
| ERROR_MSG("Cannot create colormap!"); |
| goto fail; |
| } |
| |
| /* The default xRGB888 visual uses 8 bits per component */ |
| if (!xf86HandleColormaps(pScreen, 256, 8, OMAPLoadPalette, NULL, |
| CMAP_PALETTED_TRUECOLOR)) { |
| ERROR_MSG("xf86HandleColormaps() failed!"); |
| goto fail; |
| } |
| |
| /* Setup power management: */ |
| xf86DPMSInit(pScreen, xf86DPMSSet, 0); |
| |
| pScreen->SaveScreen = xf86SaveScreen; |
| |
| /* Wrap some screen functions: */ |
| wrap(pOMAP, pScreen, CloseScreen, OMAPCloseScreen); |
| |
| if (!drmmode_screen_init(pScrn)) { |
| ERROR_MSG("drmmode_screen_init() failed!"); |
| goto fail; |
| } |
| |
| TRACE_EXIT(); |
| return TRUE; |
| |
| fail: |
| TRACE_EXIT(); |
| return FALSE; |
| } |
| |
| |
| static void |
| OMAPLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, |
| LOCO * colors, VisualPtr pVisual) |
| { |
| TRACE_ENTER(); |
| TRACE_EXIT(); |
| } |
| |
| |
| /** |
| * The driver's CloseScreen() function. This is called at the end of each |
| * server generation. Restore state, unmap the frame buffer (and any other |
| * mapped memory regions), and free per-Screen data structures (except those |
| * held by pScrn). |
| */ |
| static Bool |
| OMAPCloseScreen(CLOSE_SCREEN_ARGS_DECL) |
| { |
| ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); |
| OMAPPtr pOMAP = OMAPPTR(pScrn); |
| Bool ret; |
| |
| TRACE_ENTER(); |
| |
| drmmode_close_screen(pScrn); |
| |
| if (pScrn->vtSema == TRUE) |
| OMAPLeaveVT(VT_FUNC_ARGS(0)); |
| |
| unwrap(pOMAP, pScreen, CloseScreen); |
| |
| ret = (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS); |
| |
| if (pOMAP->pOMAPEXA->CloseScreen) |
| pOMAP->pOMAPEXA->CloseScreen(CLOSE_SCREEN_ARGS); |
| |
| OMAPDRI2CloseScreen(pScreen); |
| |
| OMAPUnmapMem(pScrn); |
| |
| pScrn->vtSema = FALSE; |
| |
| TRACE_EXIT(); |
| |
| return ret; |
| } |
| |
| |
| /** |
| * The driver's SwitchMode() function. Initialize the new mode for the |
| * Screen. |
| */ |
| static Bool |
| OMAPSwitchMode(SWITCH_MODE_ARGS_DECL) |
| { |
| SCRN_INFO_PTR(arg); |
| return xf86SetSingleMode(pScrn, mode, RR_Rotate_0); |
| } |
| |
| |
| |
| /** |
| * The driver's AdjustFrame() function. For cases where the frame buffer is |
| * larger than the monitor resolution, this function can pan around the frame |
| * buffer within the "viewport" of the monitor. |
| */ |
| static void |
| OMAPAdjustFrame(ADJUST_FRAME_ARGS_DECL) |
| { |
| SCRN_INFO_PTR(arg); |
| drmmode_adjust_frame(pScrn, x, y); |
| } |
| |
| |
| |
| /** |
| * The driver's EnterVT() function. This is called at server startup time, and |
| * when the X server takes over the virtual terminal from the console. As |
| * such, it may need to save the current (i.e. console) HW state, and set the |
| * HW state as needed by the X server. |
| */ |
| static Bool |
| OMAPEnterVT(VT_FUNC_ARGS_DECL) |
| { |
| SCRN_INFO_PTR(arg); |
| OMAPPtr pOMAP = OMAPPTR(pScrn); |
| |
| TRACE_ENTER(); |
| |
| if (geteuid() == 0) { |
| if (drmSetMaster(pOMAP->drmFD)) { |
| ERROR_MSG("Cannot get DRM master: %s", strerror(errno)); |
| return FALSE; |
| } |
| } |
| |
| if (!xf86SetDesiredModes(pScrn)) { |
| ERROR_MSG("xf86SetDesiredModes() failed!"); |
| return FALSE; |
| } |
| |
| TRACE_EXIT(); |
| return TRUE; |
| } |
| |
| |
| |
| /** |
| * The driver's LeaveVT() function. This is called when the X server |
| * temporarily gives up the virtual terminal to the console. As such, it may |
| * need to restore the console's HW state. |
| */ |
| static void |
| OMAPLeaveVT(VT_FUNC_ARGS_DECL) |
| { |
| SCRN_INFO_PTR(arg); |
| OMAPPtr pOMAP = OMAPPTR(pScrn); |
| |
| TRACE_ENTER(); |
| |
| if (geteuid() == 0) { |
| if (drmDropMaster(pOMAP->drmFD)) { |
| WARNING_MSG("drmDropMaster failed: %s", strerror(errno)); |
| } |
| } |
| |
| TRACE_EXIT(); |
| } |
| |
| |
| |
| /** |
| * The driver's FreeScreen() function. It is only called if PreInit() returns |
| * FALSE. It is not called during normal (error free) operation. |
| * Its primary function is to free any data allocated by PreInit that persists |
| * across server generations, such as the ScrnInfoRec driverPrivate field, and |
| * any privates entries that modules may have allocated. |
| * Per-generation data should be freed by the CloseScreen() function. |
| */ |
| static void |
| OMAPFreeScreen(FREE_SCREEN_ARGS_DECL) |
| { |
| SCRN_INFO_PTR(arg); |
| OMAPPtr pOMAP = OMAPPTR(pScrn); |
| |
| TRACE_ENTER(); |
| |
| if (!pOMAP) { |
| /* This can happen if a Screen is deleted after Probe(): */ |
| return; |
| } |
| |
| if (pOMAP->pOMAPEXA) { |
| if (pOMAP->pOMAPEXA->FreeScreen) { |
| pOMAP->pOMAPEXA->FreeScreen(FREE_SCREEN_ARGS(pScrn)); |
| } |
| free(pOMAP->pOMAPEXA); |
| } |
| |
| omap_device_del(pOMAP->dev); |
| |
| OMAPCloseDRMMaster(pScrn); |
| |
| OMAPFreeRec(pScrn); |
| |
| TRACE_EXIT(); |
| } |
| |