diff options
Diffstat (limited to 'src/driver.c')
-rw-r--r-- | src/driver.c | 1242 |
1 files changed, 554 insertions, 688 deletions
diff --git a/src/driver.c b/src/driver.c index 05b6176..91049a0 100644 --- a/src/driver.c +++ b/src/driver.c @@ -35,89 +35,33 @@ #include <unistd.h> #include <fcntl.h> + #include "xf86.h" #include "xf86_OSproc.h" #include "compiler.h" -#include "xf86Pci.h" +#include "xf86platformBus.h" #include "mipointer.h" #include "micmap.h" + #include <X11/extensions/randr.h> -#include "fb.h" -#include "edid.h" -#include "xf86i2c.h" -#include "xf86Crtc.h" -#include "miscstruct.h" + #include "dixstruct.h" +#include "scrnintstr.h" + +#include "fb.h" #include "shadow.h" -#include "xf86xv.h" -#include <X11/extensions/Xv.h> -#include <xorg-server.h> -#ifdef XSERVER_PLATFORM_BUS -#include "xf86platformBus.h" -#endif -#if XSERVER_LIBPCIACCESS -#include <pciaccess.h> -#endif + +#include "xorg-server.h" +#include "xf86Crtc.h" +#include "xf86drm.h" +#include "xf86drmMode.h" #include "compat-api.h" #include "driver.h" -static void AdjustFrame(ADJUST_FRAME_ARGS_DECL); -static Bool CloseScreen(CLOSE_SCREEN_ARGS_DECL); -static Bool EnterVT(VT_FUNC_ARGS_DECL); -static void Identify(int flags); -static const OptionInfoRec *AvailableOptions(int chipid, int busid); -static ModeStatus ValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, - int flags); -static void FreeScreen(FREE_SCREEN_ARGS_DECL); -static void LeaveVT(VT_FUNC_ARGS_DECL); -static Bool SwitchMode(SWITCH_MODE_ARGS_DECL); -static Bool ScreenInit(SCREEN_INIT_ARGS_DECL); -static Bool PreInit(ScrnInfoPtr pScrn, int flags); - -static Bool Probe(DriverPtr drv, int flags); -static Bool ms_pci_probe(DriverPtr driver, - int entity_num, struct pci_device *device, - intptr_t match_data); -static Bool ms_driver_func(ScrnInfoPtr scrn, xorgDriverFuncOp op, - void *data); - -#ifdef XSERVER_LIBPCIACCESS -static const struct pci_id_match ms_device_match[] = { - { - PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, - 0x00030000, 0x00ffffff, 0 - }, - - { 0, 0, 0 }, -}; -#endif - -#ifdef XSERVER_PLATFORM_BUS -static Bool ms_platform_probe(DriverPtr driver, - int entity_num, int flags, struct xf86_platform_device *device, - intptr_t match_data); -#endif - -_X_EXPORT DriverRec modesetting = { - 1, - "modesetting", - Identify, - Probe, - AvailableOptions, - NULL, - 0, - ms_driver_func, - ms_device_match, - ms_pci_probe, -#ifdef XSERVER_PLATFORM_BUS - ms_platform_probe, -#endif -}; - static SymTabRec Chipsets[] = { - {0, "kms" }, - {-1, NULL} + { 0, "kms" }, + { -1, NULL } }; typedef enum @@ -125,583 +69,368 @@ typedef enum OPTION_SW_CURSOR, OPTION_DEVICE_PATH, OPTION_SHADOW_FB, -} modesettingOpts; +} TegraOptions; static const OptionInfoRec Options[] = { - {OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE}, - {OPTION_DEVICE_PATH, "kmsdev", OPTV_STRING, {0}, FALSE }, - {OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, - {-1, NULL, OPTV_NONE, {0}, FALSE} + { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, { 0 }, FALSE }, + { OPTION_DEVICE_PATH, "device", OPTV_STRING, { 0 }, FALSE }, + { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, { 0 }, FALSE }, + { -1, NULL, OPTV_NONE, { 0 }, FALSE } }; -int modesettingEntityIndex = -1; +int tegraEntityIndex = -1; -static MODULESETUPPROTO(Setup); - -static XF86ModuleVersionInfo VersRec = { - "modesetting", - 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} -}; - -_X_EXPORT XF86ModuleData modesettingModuleData = { &VersRec, Setup, NULL }; - -static pointer -Setup(pointer module, pointer opts, int *errmaj, int *errmin) +static int +dispatch_dirty_region(ScrnInfoPtr scrn, PixmapPtr pixmap, DamagePtr damage, + int fb_id) { - static Bool setupDone = 0; - - /* This module should be loaded only once, but check to be sure. - */ - if (!setupDone) { - setupDone = 1; - xf86AddDriver(&modesetting, module, HaveDriverFuncs); - - /* - * 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; - } -} + TegraPtr tegra = TegraPTR(scrn); + RegionPtr dirty = DamageRegion(damage); + unsigned num_cliprects = REGION_NUM_RECTS(dirty); -static void -Identify(int flags) -{ - xf86PrintChipsets("modesetting", "Driver for Modesetting Kernel Drivers", - Chipsets); -} + if (num_cliprects) { + drmModeClip *clip = malloc(num_cliprects * sizeof(drmModeClip)); + BoxPtr rect = REGION_RECTS(dirty); + int i, ret; + + if (!clip) + return -ENOMEM; + + /* XXX no need for copy? */ + for (i = 0; i < num_cliprects; i++, rect++) { + clip[i].x1 = rect->x1; + clip[i].y1 = rect->y1; + clip[i].x2 = rect->x2; + clip[i].y2 = rect->y2; + } -static int open_hw(char *dev) -{ - int fd; - if (dev) - fd = open(dev, O_RDWR, 0); - else { - dev = getenv("KMSDEVICE"); - if ((NULL == dev) || ((fd = open(dev, O_RDWR, 0)) == -1)) { - dev = "/dev/dri/card0"; - fd = open(dev,O_RDWR, 0); - } + /* TODO query connector property to see if this is needed */ + ret = drmModeDirtyFB(tegra->fd, fb_id, clip, num_cliprects); + free(clip); + DamageEmpty(damage); + if (ret) { + if (ret == -EINVAL) + return ret; + } } - if (fd == -1) - xf86DrvMsg(-1, X_ERROR,"open %s: %s\n", dev, strerror(errno)); - return fd; + return 0; } -static Bool probe_hw(char *dev) +static void dispatch_dirty(ScreenPtr pScreen) { - int fd = open_hw(dev); - if (fd != -1) { - close(fd); - return TRUE; + ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen); + TegraPtr tegra = TegraPTR(scrn); + PixmapPtr pixmap = pScreen->GetScreenPixmap(pScreen); + int fb_id = tegra->drmmode.fb_id; + int ret; + + ret = dispatch_dirty_region(scrn, pixmap, tegra->damage, fb_id); + if (ret == -EINVAL || ret == -ENOSYS) { + tegra->dirty_enabled = FALSE; + DamageUnregister(&pScreen->GetScreenPixmap(pScreen)->drawable, + tegra->damage); + DamageDestroy(tegra->damage); + tegra->damage = NULL; + xf86DrvMsg(scrn->scrnIndex, X_INFO, "Disabling kernel dirty updates, not required.\n"); + return; } - return FALSE; } -static char * -ms_DRICreatePCIBusID(const struct pci_device *dev) +#ifdef TEGRA_OUTPUT_SLAVE_SUPPORT +static void dispatch_dirty_crtc(ScrnInfoPtr scrn, xf86CrtcPtr crtc) { - char *busID; - - if (asprintf(&busID, "pci:%04x:%02x:%02x.%d", - dev->domain, dev->bus, dev->dev, dev->func) == -1) - return NULL; + TegraPtr tegra = TegraPTR(scrn); + PixmapPtr pixmap = crtc->randr_crtc->scanout_pixmap; + TegraPixmapPrivPtr ppriv = TegraGetPixmapPriv(&tegra->drmmode, pixmap); + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + DamagePtr damage = drmmode_crtc->slave_damage; + int fb_id = ppriv->fb_id; + int ret; - return busID; + ret = dispatch_dirty_region(scrn, pixmap, damage, fb_id); + if (ret) { + } } - -static Bool probe_hw_pci(char *dev, struct pci_device *pdev) +static void dispatch_slave_dirty(ScreenPtr pScreen) { - int fd = open_hw(dev); - char *id, *devid; - drmSetVersion sv; - - if (fd == -1) - return FALSE; - - sv.drm_di_major = 1; - sv.drm_di_minor = 4; - sv.drm_dd_major = -1; - sv.drm_dd_minor = -1; - if (drmSetInterfaceVersion(fd, &sv)) { - close(fd); - return FALSE; - } - - - id = drmGetBusid(fd); - devid = ms_DRICreatePCIBusID(pdev); - close(fd); - - if (!id || !devid) - return FALSE; - - if (!strcmp(id, devid)) - return TRUE; + ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + int c; - return FALSE; -} -static const OptionInfoRec * -AvailableOptions(int chipid, int busid) -{ - return Options; -} + for (c = 0; c < xf86_config->num_crtc; c++) { + xf86CrtcPtr crtc = xf86_config->crtc[c]; -static Bool -ms_driver_func(ScrnInfoPtr scrn, xorgDriverFuncOp op, void *data) -{ - xorgHWFlags *flag; - - switch (op) { - case GET_REQUIRED_HW_INTERFACES: - flag = (CARD32 *)data; - (*flag) = 0; - return TRUE; - default: - return FALSE; - } -} + if (!crtc->randr_crtc) + continue; -#if XSERVER_LIBPCIACCESS -static Bool -ms_pci_probe(DriverPtr driver, - int entity_num, struct pci_device *dev, intptr_t match_data) -{ - ScrnInfoPtr scrn = NULL; + if (!crtc->randr_crtc->scanout_pixmap) + continue; - scrn = xf86ConfigPciEntity(scrn, 0, entity_num, NULL, - NULL, NULL, NULL, NULL, NULL); - if (scrn) { - char *devpath; - GDevPtr devSection = xf86GetDevFromEntity(scrn->entityList[0], - scrn->entityInstanceList[0]); - - devpath = xf86FindOptionValue(devSection->options, "kmsdev"); - if (probe_hw_pci(devpath, dev)) { - scrn->driverVersion = 1; - scrn->driverName = "modesetting"; - scrn->name = "modeset"; - scrn->Probe = NULL; - scrn->PreInit = PreInit; - scrn->ScreenInit = ScreenInit; - scrn->SwitchMode = SwitchMode; - scrn->AdjustFrame = AdjustFrame; - scrn->EnterVT = EnterVT; - scrn->LeaveVT = LeaveVT; - scrn->FreeScreen = FreeScreen; - scrn->ValidMode = ValidMode; - - xf86DrvMsg(scrn->scrnIndex, X_CONFIG, - "claimed PCI slot %d@%d:%d:%d\n", - dev->bus, dev->domain, dev->dev, dev->func); - xf86DrvMsg(scrn->scrnIndex, X_INFO, - "using %s\n", devpath ? devpath : "default device"); - } else - scrn = NULL; + dispatch_dirty_crtc(scrn, crtc); } - return scrn != NULL; } #endif -#ifdef XSERVER_PLATFORM_BUS static Bool -ms_platform_probe(DriverPtr driver, - int entity_num, int flags, struct xf86_platform_device *dev, intptr_t match_data) +GetRec(ScrnInfoPtr pScrn) { - ScrnInfoPtr scrn = NULL; - char *path = xf86_get_platform_device_attrib(dev, ODEV_ATTRIB_PATH); - int scr_flags = 0; - - if (flags & PLATFORM_PROBE_GPU_SCREEN) - scr_flags = XF86_ALLOCATE_GPU_SCREEN; - - if (probe_hw(path)) { - scrn = xf86AllocateScreen(driver, scr_flags); - xf86AddEntityToScreen(scrn, entity_num); + if (pScrn->driverPrivate) + return TRUE; - scrn->driverName = "modesetting"; - scrn->name = "modesetting"; - scrn->PreInit = PreInit; - scrn->ScreenInit = ScreenInit; - scrn->SwitchMode = SwitchMode; - scrn->AdjustFrame = AdjustFrame; - scrn->EnterVT = EnterVT; - scrn->LeaveVT = LeaveVT; - scrn->FreeScreen = FreeScreen; - scrn->ValidMode = ValidMode; - xf86DrvMsg(scrn->scrnIndex, X_INFO, - "using drv %s\n", path ? path : "default device"); - } + pScrn->driverPrivate = xnfcalloc(sizeof(TegraRec), 1); - return scrn != NULL; + return TRUE; } -#endif -static Bool -Probe(DriverPtr drv, int flags) +static void +FreeRec(ScrnInfoPtr pScrn) { - int i, numDevSections; - GDevPtr *devSections; - Bool foundScreen = FALSE; - char *dev; - ScrnInfoPtr scrn = NULL; - - /* For now, just bail out for PROBE_DETECT. */ - if (flags & PROBE_DETECT) - return FALSE; - - /* - * Find the config file Device sections that match this - * driver, and return if there are none. - */ - if ((numDevSections = xf86MatchDevice("modesetting", &devSections)) <= 0) { - return FALSE; - } - - for (i = 0; i < numDevSections; i++) { + if (!pScrn) + return; - dev = xf86FindOptionValue(devSections[i]->options,"kmsdev"); - if (probe_hw(dev)) { - int entity; - entity = xf86ClaimFbSlot(drv, 0, devSections[i], TRUE); - scrn = xf86ConfigFbEntity(scrn, 0, entity, - NULL, NULL, NULL, NULL); - } - - if (scrn) { - foundScreen = TRUE; - scrn->driverVersion = 1; - scrn->driverName = "modesetting"; - scrn->name = "modesetting"; - scrn->Probe = Probe; - scrn->PreInit = PreInit; - scrn->ScreenInit = ScreenInit; - scrn->SwitchMode = SwitchMode; - scrn->AdjustFrame = AdjustFrame; - scrn->EnterVT = EnterVT; - scrn->LeaveVT = LeaveVT; - scrn->FreeScreen = FreeScreen; - scrn->ValidMode = ValidMode; - - xf86DrvMsg(scrn->scrnIndex, X_INFO, - "using %s\n", dev ? dev : "default device"); - } - } + if (!pScrn->driverPrivate) + return; - free(devSections); + free(pScrn->driverPrivate); - return foundScreen; + pScrn->driverPrivate = NULL; } +#ifdef TEGRA_OUTPUT_SLAVE_SUPPORT static Bool -GetRec(ScrnInfoPtr pScrn) +TegraSetSharedPixmapBacking(PixmapPtr ppix, void *fd_handle) { - if (pScrn->driverPrivate) - return TRUE; + ScreenPtr screen = ppix->drawable.pScreen; + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + TegraPtr tegra = TegraPTR(scrn); + Bool ret; + int size = ppix->devKind * ppix->drawable.height; + int ihandle = (int)(long)fd_handle; - pScrn->driverPrivate = xnfcalloc(sizeof(modesettingRec), 1); + ret = drmmode_SetSlaveBO(ppix, &tegra->drmmode, ihandle, ppix->devKind, + size); + if (ret == FALSE) + return ret; return TRUE; } +#endif -static int dispatch_dirty_region(ScrnInfoPtr scrn, - PixmapPtr pixmap, - DamagePtr damage, - int fb_id) +static void +TegraIdentify(int flags) { - modesettingPtr ms = modesettingPTR(scrn); - RegionPtr dirty = DamageRegion(damage); - unsigned num_cliprects = REGION_NUM_RECTS(dirty); - - if (num_cliprects) { - drmModeClip *clip = malloc(num_cliprects * sizeof(drmModeClip)); - BoxPtr rect = REGION_RECTS(dirty); - int i, ret; - - if (!clip) - return -ENOMEM; - - /* XXX no need for copy? */ - for (i = 0; i < num_cliprects; i++, rect++) { - clip[i].x1 = rect->x1; - clip[i].y1 = rect->y1; - clip[i].x2 = rect->x2; - clip[i].y2 = rect->y2; - } - - /* TODO query connector property to see if this is needed */ - ret = drmModeDirtyFB(ms->fd, fb_id, clip, num_cliprects); - free(clip); - DamageEmpty(damage); - if (ret) { - if (ret == -EINVAL) - return ret; - } - } - return 0; + xf86PrintChipsets("opentegra", "Open Source Driver for NVIDIA Tegra", + Chipsets); } -static void dispatch_dirty(ScreenPtr pScreen) +static int +TegraOpenHardware(const char *dev) { - ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen); - modesettingPtr ms = modesettingPTR(scrn); - PixmapPtr pixmap = pScreen->GetScreenPixmap(pScreen); - int fb_id = ms->drmmode.fb_id; - int ret; + int fd; - ret = dispatch_dirty_region(scrn, pixmap, ms->damage, fb_id); - if (ret == -EINVAL || ret == -ENOSYS) { - ms->dirty_enabled = FALSE; - DamageUnregister(&pScreen->GetScreenPixmap(pScreen)->drawable, ms->damage); - DamageDestroy(ms->damage); - ms->damage = NULL; - xf86DrvMsg(scrn->scrnIndex, X_INFO, "Disabling kernel dirty updates, not required.\n"); - return; + if (dev) + fd = open(dev, O_RDWR, 0); + else { + dev = getenv("KMSDEVICE"); + if ((dev == NULL) || ((fd = open(dev, O_RDWR, 0)) == -1)) { + dev = "/dev/dri/card0"; + fd = open(dev,O_RDWR, 0); + } } -} -#ifdef MODESETTING_OUTPUT_SLAVE_SUPPORT -static void dispatch_dirty_crtc(ScrnInfoPtr scrn, xf86CrtcPtr crtc) -{ - modesettingPtr ms = modesettingPTR(scrn); - PixmapPtr pixmap = crtc->randr_crtc->scanout_pixmap; - msPixmapPrivPtr ppriv = msGetPixmapPriv(&ms->drmmode, pixmap); - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - DamagePtr damage = drmmode_crtc->slave_damage; - int fb_id = ppriv->fb_id; - int ret; - - ret = dispatch_dirty_region(scrn, pixmap, damage, fb_id); - if (ret) { + if (fd == -1) + xf86DrvMsg(-1, X_ERROR, "open %s: %s\n", dev, strerror(errno)); - } + return fd; } -static void dispatch_slave_dirty(ScreenPtr pScreen) +static Bool +TegraProbeHardware(const char *dev) { - ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen); - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); - int c; - - for (c = 0; c < xf86_config->num_crtc; c++) { - xf86CrtcPtr crtc = xf86_config->crtc[c]; - - if (!crtc->randr_crtc) - continue; - if (!crtc->randr_crtc->scanout_pixmap) - continue; + int fd; - dispatch_dirty_crtc(scrn, crtc); + fd = TegraOpenHardware(dev); + if (fd != -1) { + close(fd); + return TRUE; } + + return FALSE; } -#endif -static void msBlockHandler(BLOCKHANDLER_ARGS_DECL) +static const OptionInfoRec * +TegraAvailableOptions(int chipid, int busid) { - SCREEN_PTR(arg); - modesettingPtr ms = modesettingPTR(xf86ScreenToScrn(pScreen)); - - pScreen->BlockHandler = ms->BlockHandler; - pScreen->BlockHandler(BLOCKHANDLER_ARGS); - pScreen->BlockHandler = msBlockHandler; -#ifdef MODESETTING_OUTPUT_SLAVE_SUPPORT - if (pScreen->isGPU) - dispatch_slave_dirty(pScreen); - else -#endif - if (ms->dirty_enabled) - dispatch_dirty(pScreen); + return Options; } -static void -FreeRec(ScrnInfoPtr pScrn) +static Bool +TegraDriverFunc(ScrnInfoPtr scrn, xorgDriverFuncOp op, void *data) { - if (!pScrn) - return; - - if (!pScrn->driverPrivate) - return; - - free(pScrn->driverPrivate); + xorgHWFlags *flag; - pScrn->driverPrivate = NULL; + switch (op) { + case GET_REQUIRED_HW_INTERFACES: + flag = (CARD32 *)data; + (*flag) = 0; + return TRUE; + default: + return FALSE; + } } static Bool -PreInit(ScrnInfoPtr pScrn, int flags) +TegraPreInit(ScrnInfoPtr pScrn, int flags) { - modesettingPtr ms; + TegraPtr tegra; rgb defaultWeight = { 0, 0, 0 }; EntityInfoPtr pEnt; - EntPtr msEnt = NULL; - char *BusID = NULL, *devicename; + EntPtr tegraEnt = NULL; + char *devicename; Bool prefer_shadow = TRUE; uint64_t value = 0; int ret; int bppflags; int defaultdepth, defaultbpp; + Gamma zeros = { 0.0, 0.0, 0.0 }; if (pScrn->numEntities != 1) - return FALSE; + return FALSE; pEnt = xf86GetEntityInfo(pScrn->entityList[0]); - if (flags & PROBE_DETECT) { - return FALSE; - } + if (flags & PROBE_DETECT) + return FALSE; /* Allocate driverPrivate */ if (!GetRec(pScrn)) - return FALSE; + return FALSE; - ms = modesettingPTR(pScrn); - ms->SaveGeneration = -1; - ms->pEnt = pEnt; + tegra = TegraPTR(pScrn); + tegra->SaveGeneration = -1; + tegra->pEnt = pEnt; - pScrn->displayWidth = 640; /* default it */ + pScrn->displayWidth = 640; /* default it */ /* Allocate an entity private if necessary */ if (xf86IsEntityShared(pScrn->entityList[0])) { - msEnt = xf86GetEntityPrivate(pScrn->entityList[0], - modesettingEntityIndex)->ptr; - ms->entityPrivate = msEnt; + tegraEnt = xf86GetEntityPrivate(pScrn->entityList[0], + tegraEntityIndex)->ptr; + tegra->entityPrivate = tegraEnt; } else - ms->entityPrivate = NULL; + tegra->entityPrivate = NULL; if (xf86IsEntityShared(pScrn->entityList[0])) { - if (xf86IsPrimInitDone(pScrn->entityList[0])) { - /* do something */ - } else { - xf86SetPrimInitDone(pScrn->entityList[0]); - } + if (xf86IsPrimInitDone(pScrn->entityList[0])) { + /* do something */ + } else { + xf86SetPrimInitDone(pScrn->entityList[0]); + } } pScrn->monitor = pScrn->confScreen->monitor; pScrn->progClock = TRUE; pScrn->rgbBits = 8; -#if XSERVER_PLATFORM_BUS if (pEnt->location.type == BUS_PLATFORM) { - char *path = xf86_get_platform_device_attrib(pEnt->location.id.plat, ODEV_ATTRIB_PATH); - ms->fd = open_hw(path); - } - else -#endif - if (pEnt->location.type == BUS_PCI) { - ms->PciInfo = xf86GetPciInfoForEntity(ms->pEnt->index); - if (ms->PciInfo) { - BusID = malloc(64); - sprintf(BusID, "PCI:%d:%d:%d", -#if XSERVER_LIBPCIACCESS - ((ms->PciInfo->domain << 8) | ms->PciInfo->bus), - ms->PciInfo->dev, ms->PciInfo->func -#else - ((pciConfigPtr) ms->PciInfo->thisCard)->busnum, - ((pciConfigPtr) ms->PciInfo->thisCard)->devnum, - ((pciConfigPtr) ms->PciInfo->thisCard)->funcnum -#endif - ); - } - ms->fd = drmOpen(NULL, BusID); + char *path; + path = xf86_get_platform_device_attrib(pEnt->location.id.plat, + ODEV_ATTRIB_PATH); + tegra->fd = TegraOpenHardware(path); } else { - devicename = xf86FindOptionValue(ms->pEnt->device->options, "kmsdev"); - ms->fd = open_hw(devicename); + devicename = xf86GetOptValString(tegra->pEnt->device->options, + OPTION_DEVICE_PATH); + tegra->fd = TegraOpenHardware(devicename); } - if (ms->fd < 0) - return FALSE; - ms->drmmode.fd = ms->fd; + if (tegra->fd < 0) + return FALSE; + + tegra->drmmode.fd = tegra->fd; -#ifdef MODESETTING_OUTPUT_SLAVE_SUPPORT +#ifdef TEGRA_OUTPUT_SLAVE_SUPPORT pScrn->capabilities = 0; #ifdef DRM_CAP_PRIME - ret = drmGetCap(ms->fd, DRM_CAP_PRIME, &value); + ret = drmGetCap(tegra->fd, DRM_CAP_PRIME, &value); if (ret == 0) { if (value & DRM_PRIME_CAP_IMPORT) pScrn->capabilities |= RR_Capability_SinkOutput; } #endif #endif - drmmode_get_default_bpp(pScrn, &ms->drmmode, &defaultdepth, &defaultbpp); + drmmode_get_default_bpp(pScrn, &tegra->drmmode, &defaultdepth, &defaultbpp); if (defaultdepth == 24 && defaultbpp == 24) - bppflags = Support24bppFb; + bppflags = Support24bppFb; else - bppflags = PreferConvert24to32 | SupportConvert24to32 | Support32bppFb; - - if (!xf86SetDepthBpp - (pScrn, defaultdepth, defaultdepth, defaultbpp, bppflags)) - return FALSE; + bppflags = PreferConvert24to32 | SupportConvert24to32 | Support32bppFb; + + if (!xf86SetDepthBpp(pScrn, defaultdepth, defaultdepth, defaultbpp, + bppflags)) + return FALSE; switch (pScrn->depth) { case 15: case 16: case 24: - break; + break; + default: - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Given depth (%d) is not supported by the driver\n", - pScrn->depth); - return FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Given depth (%d) is not supported by the driver\n", + pScrn->depth); + return FALSE; } + xf86PrintDepthBpp(pScrn); /* Process the options */ xf86CollectOptions(pScrn, NULL); - if (!(ms->Options = malloc(sizeof(Options)))) - return FALSE; - memcpy(ms->Options, Options, sizeof(Options)); - xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, ms->Options); + + tegra->Options = malloc(sizeof(Options)); + if (!tegra->Options) + return FALSE; + + memcpy(tegra->Options, Options, sizeof(Options)); + xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, tegra->Options); if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight)) - return FALSE; + return FALSE; + if (!xf86SetDefaultVisual(pScrn, -1)) - return FALSE; + return FALSE; - if (xf86ReturnOptValBool(ms->Options, OPTION_SW_CURSOR, FALSE)) { - ms->drmmode.sw_cursor = TRUE; - } + if (xf86ReturnOptValBool(tegra->Options, OPTION_SW_CURSOR, FALSE)) + tegra->drmmode.sw_cursor = TRUE; - ret = drmGetCap(ms->fd, DRM_CAP_DUMB_PREFER_SHADOW, &value); - if (!ret) { - prefer_shadow = !!value; - } + ret = drmGetCap(tegra->fd, DRM_CAP_DUMB_PREFER_SHADOW, &value); + if (!ret) + prefer_shadow = !!value; - ms->drmmode.shadow_enable = xf86ReturnOptValBool(ms->Options, OPTION_SHADOW_FB, prefer_shadow); + tegra->drmmode.shadow_enable = xf86ReturnOptValBool(tegra->Options, + OPTION_SHADOW_FB, + prefer_shadow); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ShadowFB: preferred %s, enabled %s\n", prefer_shadow ? "YES" : "NO", ms->drmmode.shadow_enable ? "YES" : "NO"); - if (drmmode_pre_init(pScrn, &ms->drmmode, pScrn->bitsPerPixel / 8) == FALSE) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "KMS setup failed\n"); - goto fail; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "ShadowFB: preferred %s, enabled %s\n", + prefer_shadow ? "YES" : "NO", + tegra->drmmode.shadow_enable ? "YES" : "NO"); + + if (!drmmode_pre_init(pScrn, &tegra->drmmode, pScrn->bitsPerPixel / 8)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "KMS setup failed\n"); + return FALSE; } /* * If the driver can do gamma correction, it should call xf86SetGamma() here. */ - { - Gamma zeros = { 0.0, 0.0, 0.0 }; - - if (!xf86SetGamma(pScrn, zeros)) { - return FALSE; - } - } + if (!xf86SetGamma(pScrn, zeros)) + return FALSE; if (pScrn->modes == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n"); - return FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n"); + return FALSE; } pScrn->currentMode = pScrn->modes; @@ -710,194 +439,255 @@ PreInit(ScrnInfoPtr pScrn, int flags) xf86SetDpi(pScrn, 0, 0); /* Load the required sub modules */ - if (!xf86LoadSubModule(pScrn, "fb")) { - return FALSE; - } + if (!xf86LoadSubModule(pScrn, "fb")) + return FALSE; - if (ms->drmmode.shadow_enable) { - if (!xf86LoadSubModule(pScrn, "shadow")) { - return FALSE; - } + if (tegra->drmmode.shadow_enable) { + if (!xf86LoadSubModule(pScrn, "shadow")) + return FALSE; } return TRUE; - fail: - return FALSE; +} + +/* + * This gets called when gaining control of the VT, and from ScreenInit(). + */ +static Bool +TegraEnterVT(VT_FUNC_ARGS_DECL) +{ + SCRN_INFO_PTR(arg); + TegraPtr tegra = TegraPTR(pScrn); + + pScrn->vtSema = TRUE; + + if (drmSetMaster(tegra->fd)) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "drmSetMaster failed: %s\n", + strerror(errno)); + + if (!drmmode_set_desired_modes(pScrn, &tegra->drmmode)) + return FALSE; + + return TRUE; +} + +static void +TegraLeaveVT(VT_FUNC_ARGS_DECL) +{ + SCRN_INFO_PTR(arg); + TegraPtr tegra = TegraPTR(pScrn); + xf86_hide_cursors(pScrn); + + pScrn->vtSema = FALSE; + + drmDropMaster(tegra->fd); +} + +static Bool +TegraShadowInit(ScreenPtr pScreen) +{ + if (!shadowSetup(pScreen)) + return FALSE; + + return TRUE; } static void * -msShadowWindow(ScreenPtr screen, CARD32 row, CARD32 offset, int mode, - CARD32 *size, void *closure) +TegraShadowWindow(ScreenPtr screen, CARD32 row, CARD32 offset, int mode, + CARD32 *size, void *closure) { ScrnInfoPtr pScrn = xf86ScreenToScrn(screen); - modesettingPtr ms = modesettingPTR(pScrn); + TegraPtr tegra = TegraPTR(pScrn); int stride; stride = (pScrn->displayWidth * pScrn->bitsPerPixel) / 8; *size = stride; - return ((uint8_t *)ms->drmmode.front_bo->ptr + row * stride + offset); + return ((uint8_t *)tegra->drmmode.front_bo->ptr + row * stride + offset); } static Bool -CreateScreenResources(ScreenPtr pScreen) +TegraCreateScreenResources(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); - modesettingPtr ms = modesettingPTR(pScrn); + TegraPtr tegra = TegraPTR(pScrn); PixmapPtr rootPixmap; Bool ret; void *pixels; - pScreen->CreateScreenResources = ms->createScreenResources; + pScreen->CreateScreenResources = tegra->createScreenResources; ret = pScreen->CreateScreenResources(pScreen); - pScreen->CreateScreenResources = CreateScreenResources; + pScreen->CreateScreenResources = TegraCreateScreenResources; - if (!drmmode_set_desired_modes(pScrn, &ms->drmmode)) + if (!drmmode_set_desired_modes(pScrn, &tegra->drmmode)) return FALSE; - drmmode_uevent_init(pScrn, &ms->drmmode); + drmmode_uevent_init(pScrn, &tegra->drmmode); + + if (!tegra->SWCursor) + drmmode_map_cursor_bos(pScrn, &tegra->drmmode); - if (!ms->SWCursor) - drmmode_map_cursor_bos(pScrn, &ms->drmmode); - pixels = drmmode_map_front_bo(&ms->drmmode); + pixels = drmmode_map_front_bo(&tegra->drmmode); if (!pixels) - return FALSE; + return FALSE; rootPixmap = pScreen->GetScreenPixmap(pScreen); - if (ms->drmmode.shadow_enable) - pixels = ms->drmmode.shadow_fb; - + if (tegra->drmmode.shadow_enable) + pixels = tegra->drmmode.shadow_fb; + if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, pixels)) - FatalError("Couldn't adjust screen pixmap\n"); + FatalError("Couldn't adjust screen pixmap\n"); - if (ms->drmmode.shadow_enable) { - if (!shadowAdd(pScreen, rootPixmap, shadowUpdatePackedWeak(), - msShadowWindow, 0, 0)) - return FALSE; + if (tegra->drmmode.shadow_enable) { + if (!shadowAdd(pScreen, rootPixmap, shadowUpdatePackedWeak(), + TegraShadowWindow, 0, 0)) + return FALSE; } - ms->damage = DamageCreate(NULL, NULL, DamageReportNone, TRUE, - pScreen, rootPixmap); - - if (ms->damage) { - DamageRegister(&rootPixmap->drawable, ms->damage); - ms->dirty_enabled = TRUE; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Damage tracking initialized\n"); + tegra->damage = DamageCreate(NULL, NULL, DamageReportNone, TRUE, pScreen, + rootPixmap); + if (tegra->damage) { + DamageRegister(&rootPixmap->drawable, tegra->damage); + tegra->dirty_enabled = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Damage tracking initialized\n"); } else { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to create screen damage record\n"); - return FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to create screen damage record\n"); + return FALSE; } + return ret; } static Bool -msShadowInit(ScreenPtr pScreen) +TegraCloseScreen(CLOSE_SCREEN_ARGS_DECL) { - if (!shadowSetup(pScreen)) { - return FALSE; + ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); + TegraPtr tegra = TegraPTR(pScrn); + + if (tegra->damage) { + DamageUnregister(&pScreen->GetScreenPixmap(pScreen)->drawable, + tegra->damage); + DamageDestroy(tegra->damage); + tegra->damage = NULL; } - return TRUE; -} -#ifdef MODESETTING_OUTPUT_SLAVE_SUPPORT -static Bool -msSetSharedPixmapBacking(PixmapPtr ppix, void *fd_handle) -{ - ScreenPtr screen = ppix->drawable.pScreen; - ScrnInfoPtr scrn = xf86ScreenToScrn(screen); - modesettingPtr ms = modesettingPTR(scrn); - Bool ret; - int size = ppix->devKind * ppix->drawable.height; - int ihandle = (int)(long)fd_handle; + if (tegra->drmmode.shadow_enable) { + shadowRemove(pScreen, pScreen->GetScreenPixmap(pScreen)); + free(tegra->drmmode.shadow_fb); + tegra->drmmode.shadow_fb = NULL; + } - ret = drmmode_SetSlaveBO(ppix, &ms->drmmode, ihandle, ppix->devKind, size); - if (ret == FALSE) - return ret; + drmmode_uevent_fini(pScrn, &tegra->drmmode); + drmmode_free_bos(pScrn, &tegra->drmmode); - return TRUE; + if (pScrn->vtSema) + TegraLeaveVT(VT_FUNC_ARGS); + + pScreen->CreateScreenResources = tegra->createScreenResources; + pScreen->BlockHandler = tegra->BlockHandler; + + pScrn->vtSema = FALSE; + pScreen->CloseScreen = tegra->CloseScreen; + return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS); } + +static void TegraBlockHandler(BLOCKHANDLER_ARGS_DECL) +{ + SCREEN_PTR(arg); + TegraPtr tegra = TegraPTR(xf86ScreenToScrn(pScreen)); + + pScreen->BlockHandler = tegra->BlockHandler; + pScreen->BlockHandler(BLOCKHANDLER_ARGS); + pScreen->BlockHandler = TegraBlockHandler; +#ifdef TEGRA_OUTPUT_SLAVE_SUPPORT + if (pScreen->isGPU) + dispatch_slave_dirty(pScreen); + else #endif + if (tegra->dirty_enabled) + dispatch_dirty(pScreen); +} static Bool -ScreenInit(SCREEN_INIT_ARGS_DECL) +TegraScreenInit(SCREEN_INIT_ARGS_DECL) { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); - modesettingPtr ms = modesettingPTR(pScrn); + TegraPtr tegra = TegraPTR(pScrn); VisualPtr visual; int ret; pScrn->pScreen = pScreen; - ret = drmSetMaster(ms->fd); + ret = drmSetMaster(tegra->fd); if (ret) { ErrorF("Unable to set master\n"); return FALSE; } - + /* HW dependent - FIXME */ pScrn->displayWidth = pScrn->virtualX; - if (!drmmode_create_initial_bos(pScrn, &ms->drmmode)) - return FALSE; - - if (ms->drmmode.shadow_enable) { - ms->drmmode.shadow_fb = calloc(1, pScrn->displayWidth * pScrn->virtualY * - ((pScrn->bitsPerPixel + 7) >> 3)); - if (!ms->drmmode.shadow_fb) - ms->drmmode.shadow_enable = FALSE; - } - + + if (!drmmode_create_initial_bos(pScrn, &tegra->drmmode)) + return FALSE; + + if (tegra->drmmode.shadow_enable) { + tegra->drmmode.shadow_fb = calloc(1, pScrn->displayWidth * pScrn->virtualY * + ((pScrn->bitsPerPixel + 7) >> 3)); + if (!tegra->drmmode.shadow_fb) + tegra->drmmode.shadow_enable = FALSE; + } + miClearVisualTypes(); - if (!miSetVisualTypes(pScrn->depth, - miGetDefaultVisualMask(pScrn->depth), - pScrn->rgbBits, pScrn->defaultVisual)) - return FALSE; + if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth), + pScrn->rgbBits, pScrn->defaultVisual)) + return FALSE; if (!miSetPixmapDepths()) - return FALSE; + return FALSE; -#ifdef MODESETTING_OUTPUT_SLAVE_SUPPORT - if (!dixRegisterScreenSpecificPrivateKey(pScreen, &ms->drmmode.pixmapPrivateKeyRec, - PRIVATE_PIXMAP, sizeof(msPixmapPrivRec))) { - return FALSE; - } +#ifdef TEGRA_OUTPUT_SLAVE_SUPPORT + if (!dixRegisterScreenSpecificPrivateKey(pScreen, + &tegra->drmmode.pixmapPrivateKeyRec, + PRIVATE_PIXMAP, + sizeof(TegraPixmapPrivRec))) + return FALSE; #endif pScrn->memPhysBase = 0; pScrn->fbOffset = 0; - if (!fbScreenInit(pScreen, NULL, - pScrn->virtualX, pScrn->virtualY, - pScrn->xDpi, pScrn->yDpi, - pScrn->displayWidth, pScrn->bitsPerPixel)) - return FALSE; + if (!fbScreenInit(pScreen, NULL, pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth, + pScrn->bitsPerPixel)) + return FALSE; if (pScrn->bitsPerPixel > 8) { - /* Fixup RGB ordering */ - visual = pScreen->visuals + pScreen->numVisuals; - while (--visual >= pScreen->visuals) { - if ((visual->class | DynamicClass) == DirectColor) { - 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; - } - } + /* Fixup RGB ordering */ + visual = pScreen->visuals + pScreen->numVisuals; + + while (--visual >= pScreen->visuals) { + if ((visual->class | DynamicClass) == DirectColor) { + 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; + } + } } fbPictureInit(pScreen, NULL, 0); - if (ms->drmmode.shadow_enable && !msShadowInit(pScreen)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "shadow fb init failed\n"); - return FALSE; + if (tegra->drmmode.shadow_enable && !TegraShadowInit(pScreen)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "shadow fb init failed\n"); + return FALSE; } - - ms->createScreenResources = pScreen->CreateScreenResources; - pScreen->CreateScreenResources = CreateScreenResources; + + tegra->createScreenResources = pScreen->CreateScreenResources; + pScreen->CreateScreenResources = TegraCreateScreenResources; xf86SetBlackWhitePixels(pScreen); @@ -906,42 +696,50 @@ ScreenInit(SCREEN_INIT_ARGS_DECL) miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); /* Need to extend HWcursor support to handle mask interleave */ - if (!ms->drmmode.sw_cursor) - xf86_cursors_init(pScreen, 64, 64, - HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 | - HARDWARE_CURSOR_ARGB); + if (!tegra->drmmode.sw_cursor) + xf86_cursors_init(pScreen, 64, 64, + HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 | + HARDWARE_CURSOR_ARGB); /* Must force it before EnterVT, so we are in control of VT and * later memory should be bound when allocating, e.g rotate_mem */ pScrn->vtSema = TRUE; pScreen->SaveScreen = xf86SaveScreen; - ms->CloseScreen = pScreen->CloseScreen; - pScreen->CloseScreen = CloseScreen; + tegra->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = TegraCloseScreen; - ms->BlockHandler = pScreen->BlockHandler; - pScreen->BlockHandler = msBlockHandler; + tegra->BlockHandler = pScreen->BlockHandler; + pScreen->BlockHandler = TegraBlockHandler; -#ifdef MODESETTING_OUTPUT_SLAVE_SUPPORT - pScreen->SetSharedPixmapBacking = msSetSharedPixmapBacking; +#ifdef TEGRA_OUTPUT_SLAVE_SUPPORT + pScreen->SetSharedPixmapBacking = TegraSetSharedPixmapBacking; #endif if (!xf86CrtcScreenInit(pScreen)) - return FALSE; + return FALSE; if (!miCreateDefColormap(pScreen)) - return FALSE; + return FALSE; xf86DPMSInit(pScreen, xf86DPMSSet, 0); if (serverGeneration == 1) - xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); + xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); + + return TegraEnterVT(VT_FUNC_ARGS); +} + +static Bool +TegraSwitchMode(SWITCH_MODE_ARGS_DECL) +{ + SCRN_INFO_PTR(arg); - return EnterVT(VT_FUNC_ARGS); + return xf86SetSingleMode(pScrn, mode, RR_Rotate_0); } static void -AdjustFrame(ADJUST_FRAME_ARGS_DECL) +TegraAdjustFrame(ADJUST_FRAME_ARGS_DECL) { SCRN_INFO_PTR(arg); xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); @@ -949,97 +747,165 @@ AdjustFrame(ADJUST_FRAME_ARGS_DECL) xf86CrtcPtr crtc = output->crtc; if (crtc && crtc->enabled) { - crtc->funcs->mode_set(crtc, pScrn->currentMode, pScrn->currentMode, x, - y); - crtc->x = output->initial_x + x; - crtc->y = output->initial_y + y; + crtc->funcs->mode_set(crtc, pScrn->currentMode, pScrn->currentMode, x, + y); + crtc->x = output->initial_x + x; + crtc->y = output->initial_y + y; } } static void -FreeScreen(FREE_SCREEN_ARGS_DECL) +TegraFreeScreen(FREE_SCREEN_ARGS_DECL) { SCRN_INFO_PTR(arg); FreeRec(pScrn); } -static void -LeaveVT(VT_FUNC_ARGS_DECL) +static ModeStatus +TegraValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags) { - SCRN_INFO_PTR(arg); - modesettingPtr ms = modesettingPTR(pScrn); - xf86_hide_cursors(pScrn); - - pScrn->vtSema = FALSE; - - drmDropMaster(ms->fd); + return MODE_OK; } -/* - * This gets called when gaining control of the VT, and from ScreenInit(). - */ static Bool -EnterVT(VT_FUNC_ARGS_DECL) +TegraPlatformProbe(DriverPtr driver, int entity_num, int flags, + struct xf86_platform_device *dev, intptr_t match_data) { - SCRN_INFO_PTR(arg); - modesettingPtr ms = modesettingPTR(pScrn); + char *path = xf86_get_platform_device_attrib(dev, ODEV_ATTRIB_PATH); + ScrnInfoPtr scrn = NULL; + int scr_flags = 0; - pScrn->vtSema = TRUE; + if (flags & PLATFORM_PROBE_GPU_SCREEN) + scr_flags = XF86_ALLOCATE_GPU_SCREEN; - if (drmSetMaster(ms->fd)) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "drmSetMaster failed: %s\n", - strerror(errno)); - } + if (TegraProbeHardware(path)) { + scrn = xf86AllocateScreen(driver, scr_flags); - if (!drmmode_set_desired_modes(pScrn, &ms->drmmode)) - return FALSE; + xf86AddEntityToScreen(scrn, entity_num); - return TRUE; -} + scrn->driverName = "opentegra"; + scrn->name = "opentegra"; + scrn->PreInit = TegraPreInit; + scrn->ScreenInit = TegraScreenInit; + scrn->SwitchMode = TegraSwitchMode; + scrn->AdjustFrame = TegraAdjustFrame; + scrn->EnterVT = TegraEnterVT; + scrn->LeaveVT = TegraLeaveVT; + scrn->FreeScreen = TegraFreeScreen; + scrn->ValidMode = TegraValidMode; -static Bool -SwitchMode(SWITCH_MODE_ARGS_DECL) -{ - SCRN_INFO_PTR(arg); + xf86DrvMsg(scrn->scrnIndex, X_INFO, "using %s\n", + path ? path : "default device"); + } - return xf86SetSingleMode(pScrn, mode, RR_Rotate_0); + return scrn != NULL; } static Bool -CloseScreen(CLOSE_SCREEN_ARGS_DECL) +TegraProbe(DriverPtr drv, int flags) { - ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); - modesettingPtr ms = modesettingPTR(pScrn); + int i, numDevSections; + GDevPtr *devSections; + Bool foundScreen = FALSE; + const char *dev; + ScrnInfoPtr scrn = NULL; - if (ms->damage) { - DamageUnregister(&pScreen->GetScreenPixmap(pScreen)->drawable, ms->damage); - DamageDestroy(ms->damage); - ms->damage = NULL; - } + /* For now, just bail out for PROBE_DETECT. */ + if (flags & PROBE_DETECT) + return FALSE; - if (ms->drmmode.shadow_enable) { - shadowRemove(pScreen, pScreen->GetScreenPixmap(pScreen)); - free(ms->drmmode.shadow_fb); - ms->drmmode.shadow_fb = NULL; - } - drmmode_uevent_fini(pScrn, &ms->drmmode); + /* + * Find the config file Device sections that match this + * driver, and return if there are none. + */ + if ((numDevSections = xf86MatchDevice("opentegra", &devSections)) <= 0) + return FALSE; - drmmode_free_bos(pScrn, &ms->drmmode); + for (i = 0; i < numDevSections; i++) { + dev = xf86FindOptionValue(devSections[i]->options, "device"); + if (TegraProbeHardware(dev)) { + int entity = xf86ClaimFbSlot(drv, 0, devSections[i], TRUE); + scrn = xf86ConfigFbEntity(scrn, 0, entity, NULL, NULL, NULL, + NULL); + } - if (pScrn->vtSema) { - LeaveVT(VT_FUNC_ARGS); + if (scrn) { + foundScreen = TRUE; + scrn->driverVersion = 1; + scrn->driverName = "opentegra"; + scrn->name = "opentegra"; + scrn->Probe = TegraProbe; + scrn->PreInit = TegraPreInit; + scrn->ScreenInit = TegraScreenInit; + scrn->SwitchMode = TegraSwitchMode; + scrn->AdjustFrame = TegraAdjustFrame; + scrn->EnterVT = TegraEnterVT; + scrn->LeaveVT = TegraLeaveVT; + scrn->FreeScreen = TegraFreeScreen; + scrn->ValidMode = TegraValidMode; + + xf86DrvMsg(scrn->scrnIndex, X_INFO, "using %s\n", + dev ? dev : "default device"); + } } - pScreen->CreateScreenResources = ms->createScreenResources; - pScreen->BlockHandler = ms->BlockHandler; + free(devSections); - pScrn->vtSema = FALSE; - pScreen->CloseScreen = ms->CloseScreen; - return (*pScreen->CloseScreen) (CLOSE_SCREEN_ARGS); + return foundScreen; } -static ModeStatus -ValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags) +_X_EXPORT DriverRec tegra = { + 1, + "opentegra", + TegraIdentify, + TegraProbe, + TegraAvailableOptions, + NULL, + 0, + TegraDriverFunc, + NULL, + NULL, + TegraPlatformProbe, +}; + +static MODULESETUPPROTO(Setup); + +static pointer +Setup(pointer module, pointer opts, int *errmaj, int *errmin) { - return MODE_OK; + static Bool setupDone = 0; + + /* + * This module should be loaded only once, but check to be sure. + */ + if (!setupDone) { + setupDone = 1; + xf86AddDriver(&tegra, module, HaveDriverFuncs); + + /* + * 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; + } } + +static XF86ModuleVersionInfo VersRec = { + "opentegra", + 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 } +}; + +_X_EXPORT XF86ModuleData opentegraModuleData = { &VersRec, Setup, NULL }; |